Skip to content

Commit 5819182

Browse files
committed
quick fixes for frontend
1 parent 7972aaa commit 5819182

2 files changed

Lines changed: 58 additions & 42 deletions

File tree

frontend/src/components/AddPoint.test.jsx

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
* @file AddPoint.test.jsx
33
*/
44
import React from 'react';
5-
import { render, screen, fireEvent, waitFor, act } from '@testing-library/react';
5+
import { render, screen, fireEvent } from '@testing-library/react';
6+
import { act } from 'react'; // ← import act from react
67
import AddPoint from './AddPoint';
78

89
// Mock APIs
@@ -26,20 +27,25 @@ jest.mock('../utils/themeManager', () => ({
2627

2728
const { authAPI, pointsAPI } = require('../lib/api');
2829

29-
beforeAll(() => {
30-
jest.useFakeTimers();
31-
});
32-
afterAll(() => {
33-
jest.useRealTimers();
34-
});
35-
3630
describe('AddPoint Component', () => {
31+
beforeAll(() => {
32+
// Switch all tests to fake timers
33+
jest.useFakeTimers();
34+
});
35+
36+
afterAll(() => {
37+
// Restore real timers after suite
38+
jest.useRealTimers();
39+
});
40+
3741
beforeEach(() => {
3842
jest.clearAllMocks();
39-
// Mock location
43+
44+
// Mock window.location
4045
delete window.location;
4146
window.location = { search: '', href: '' };
42-
// Mock geolocation
47+
48+
// Mock geolocation API
4349
global.navigator.geolocation = {
4450
getCurrentPosition: jest.fn((success) =>
4551
success({ coords: { latitude: 10, longitude: 20 } })
@@ -56,22 +62,22 @@ describe('AddPoint Component', () => {
5662
return render(<AddPoint />);
5763
}
5864

59-
it('shows loading state initially and then renders form', async () => {
65+
it('shows loading spinner then the form', async () => {
6066
mockAuthAndRender();
61-
62-
// Loading spinner
67+
// Immediately see the loading text
6368
expect(screen.getByText(/Loading/i)).toBeInTheDocument();
64-
65-
// Wait for form after profile resolves
66-
await waitFor(() =>
67-
expect(screen.getByText(/Add a temperature point/i)).toBeInTheDocument()
68-
);
69+
// After profile loads, the form heading appears
70+
expect(
71+
await screen.findByText(/Add a temperature point to/i)
72+
).toBeInTheDocument();
6973
});
7074

71-
it('handles input changes and form submission success', async () => {
75+
it('submits successfully and shows the fullscreen confirmation', async () => {
7276
mockAuthAndRender();
73-
await screen.findByText(/Add a temperature point/i);
77+
// Wait for the form to appear
78+
await screen.findByText(/Add a temperature point to/i);
7479

80+
// Provide token & mock network + verification
7581
localStorage.setItem('authToken', 'mock-token');
7682
global.fetch = jest.fn().mockResolvedValue({
7783
ok: true,
@@ -84,37 +90,45 @@ describe('AddPoint Component', () => {
8490
],
8591
});
8692

93+
// Fill out & submit
8794
fireEvent.change(screen.getByLabelText(/Latitude/i), { target: { value: '10' } });
8895
fireEvent.change(screen.getByLabelText(/Longitude/i), { target: { value: '20' } });
8996
fireEvent.change(screen.getByLabelText(/Temperature/i), { target: { value: '30' } });
90-
9197
fireEvent.click(screen.getByText(/Add Temperature Point/i));
9298

93-
// Fast-forward the 1.5s delay
94-
await act(() => jest.advanceTimersByTime(1500));
95-
// Wait for modal
96-
expect(await screen.findByText('Temperature point added successfully')).toBeInTheDocument();
97-
expect(screen.getByText(/Success!/i)).toBeInTheDocument();
99+
// Fast-forward the UX delay
100+
act(() => {
101+
jest.advanceTimersByTime(1500);
102+
});
103+
104+
// Now the modal text appears
105+
expect(
106+
await screen.findByText('Temperature point recorded')
107+
).toBeInTheDocument();
108+
109+
expect(
110+
screen.getByRole('heading', { name: /Success!/i })
111+
).toBeInTheDocument();
98112
});
99113

100-
it('shows error if no token is present', async () => {
114+
it('shows an error if not logged in', async () => {
101115
mockAuthAndRender();
102-
await screen.findByText(/Add a temperature point/i);
116+
await screen.findByText(/Add a temperature point to/i);
103117

104118
localStorage.removeItem('authToken');
105119
fireEvent.change(screen.getByLabelText(/Latitude/i), { target: { value: '10' } });
106120
fireEvent.change(screen.getByLabelText(/Longitude/i), { target: { value: '20' } });
107121
fireEvent.change(screen.getByLabelText(/Temperature/i), { target: { value: '30' } });
108-
109122
fireEvent.click(screen.getByText(/Add Temperature Point/i));
110123

111-
await screen.findByText(/You must be logged in to add a point/i);
112-
expect(screen.getByText(/You must be logged in to add a point/i)).toBeInTheDocument();
124+
expect(
125+
await screen.findByText(/You must be logged in to add a point/i)
126+
).toBeInTheDocument();
113127
});
114128

115-
it('handles API failure gracefully', async () => {
129+
it('handles a server error gracefully', async () => {
116130
mockAuthAndRender();
117-
await screen.findByText(/Add a temperature point/i);
131+
await screen.findByText(/Add a temperature point to/i);
118132

119133
localStorage.setItem('authToken', 'mock-token');
120134
global.fetch = jest.fn().mockResolvedValue({
@@ -125,12 +139,14 @@ describe('AddPoint Component', () => {
125139
fireEvent.change(screen.getByLabelText(/Latitude/i), { target: { value: '10' } });
126140
fireEvent.change(screen.getByLabelText(/Longitude/i), { target: { value: '20' } });
127141
fireEvent.change(screen.getByLabelText(/Temperature/i), { target: { value: '30' } });
128-
129142
fireEvent.click(screen.getByText(/Add Temperature Point/i));
130143

131-
// Fast-forward the 1.5s delay
132-
await act(() => jest.advanceTimersByTime(1500));
133-
// Now the error banner should appear
134-
expect(await screen.findByText(/Server error/i)).toBeInTheDocument();
144+
act(() => {
145+
jest.advanceTimersByTime(1500);
146+
});
147+
148+
expect(
149+
await screen.findByText(/Server error/i)
150+
).toBeInTheDocument();
135151
});
136152
});

frontend/src/components/HUDleftPoints.test.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,16 @@ describe('HUDleftPoints Component', () => {
6262

6363
const sortButton = screen.getByText('↕');
6464

65-
// Ascending
65+
// Ascending - low to high
6666
fireEvent.click(sortButton);
67-
fireEvent.click(screen.getByText('Temp ↑'));
67+
fireEvent.click(screen.getByText(/Low to High/i));
6868

6969
let items = container.querySelectorAll('.beach-item-hover');
7070
expect(items[0].textContent).toContain('Beach Two'); // 15°C first
7171

7272
// Descending
7373
fireEvent.click(sortButton);
74-
fireEvent.click(screen.getByText('Temp ↓'));
74+
fireEvent.click(screen.getByText(/High to Low/i));
7575

7676
items = container.querySelectorAll('.beach-item-hover');
7777
expect(items[0].textContent).toContain('Beach One'); // 20°C first
@@ -83,7 +83,7 @@ describe('HUDleftPoints Component', () => {
8383

8484
// Open sort menu and click Reset
8585
fireEvent.click(screen.getByText('↕'));
86-
fireEvent.click(screen.getByText('Reset'));
86+
fireEvent.click(screen.getByText(/Reset Sort/i));
8787

8888
const items = container.querySelectorAll('.beach-item-hover');
8989
expect(items[0].textContent).toContain('Beach One');

0 commit comments

Comments
 (0)