Skip to content

Commit 3bc2947

Browse files
feat: added the validation test (#1303)
* feat: added the validation test * fix: address CodeRabbit review - isolate button state via avatar pre-selection and use fireEvent * fix: format nameValidation test file with prettier * style: apply black formatting to images.py files * style: format images.py with black * test: split name validation into per-component test files under components/__tests__ * style: fix prettier formatting in component test files * undo settings page test file movement --------- Co-authored-by: ROHAN PANDEY <95585299+rohan-pandeyy@users.noreply.github.com>
1 parent c71d3e4 commit 3bc2947

3 files changed

Lines changed: 100 additions & 1 deletion

File tree

backend/app/routes/images.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from app.database.images import db_toggle_image_favourite_status, db_get_image_by_id
88
from app.logging.setup_logging import get_logger
99

10-
1110
# Initialize logger
1211
logger = get_logger(__name__)
1312
router = APIRouter()
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { render, screen } from '@/test-utils';
2+
import userEvent from '@testing-library/user-event';
3+
import AccountSettingsCard from '@/pages/SettingsPage/components/AccountSettingsCard';
4+
5+
const VALID_30 = 'a'.repeat(30);
6+
const INVALID_31 = 'a'.repeat(31);
7+
const ERROR_MSG = 'A single word in your name cannot exceed 30 characters.';
8+
9+
beforeEach(() => localStorage.clear());
10+
11+
describe('Name validation - AccountSettingsCard', () => {
12+
const setup = () => {
13+
const user = userEvent.setup();
14+
render(<AccountSettingsCard />);
15+
const input = screen.getByPlaceholderText('Enter your name');
16+
return { user, input };
17+
};
18+
19+
test('30-character word is valid - no error shown', async () => {
20+
const { user, input } = setup();
21+
await user.type(input, VALID_30);
22+
expect(screen.queryByText(ERROR_MSG)).not.toBeInTheDocument();
23+
});
24+
25+
test('31-character word shows error and disables Save Changes button', async () => {
26+
const { user, input } = setup();
27+
await user.type(input, INVALID_31);
28+
expect(screen.getByText(ERROR_MSG)).toBeInTheDocument();
29+
expect(
30+
screen.getByRole('button', { name: /save changes/i }),
31+
).toBeDisabled();
32+
});
33+
34+
test('multi-space input is handled gracefully - no error', async () => {
35+
const { user, input } = setup();
36+
await user.type(input, 'John Doe');
37+
expect(screen.queryByText(ERROR_MSG)).not.toBeInTheDocument();
38+
});
39+
40+
test('recovery - valid input after invalid clears error', async () => {
41+
const { user, input } = setup();
42+
await user.type(input, INVALID_31);
43+
expect(screen.getByText(ERROR_MSG)).toBeInTheDocument();
44+
await user.clear(input);
45+
await user.type(input, 'John');
46+
expect(screen.queryByText(ERROR_MSG)).not.toBeInTheDocument();
47+
});
48+
});
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { render, screen } from '@/test-utils';
2+
import userEvent from '@testing-library/user-event';
3+
import { AvatarSelectionStep } from '@/components/OnboardingSteps/AvatarSelectionStep';
4+
5+
const VALID_30 = 'a'.repeat(30);
6+
const INVALID_31 = 'a'.repeat(31);
7+
const ERROR_MSG = 'A single word in your name cannot exceed 30 characters.';
8+
9+
beforeEach(() => localStorage.clear());
10+
11+
describe('Name validation - AvatarSelectionStep', () => {
12+
const setup = () => {
13+
const user = userEvent.setup();
14+
render(
15+
<AvatarSelectionStep
16+
stepIndex={0}
17+
totalSteps={4}
18+
currentStepDisplayIndex={0}
19+
/>,
20+
);
21+
const input = screen.getByPlaceholderText('Enter your name');
22+
return { user, input };
23+
};
24+
25+
test('30-character word is valid - no error shown', async () => {
26+
const { user, input } = setup();
27+
await user.type(input, VALID_30);
28+
expect(screen.queryByText(ERROR_MSG)).not.toBeInTheDocument();
29+
});
30+
31+
test('31-character word shows error and disables Next button', async () => {
32+
const { user, input } = setup();
33+
await user.type(input, INVALID_31);
34+
expect(screen.getByText(ERROR_MSG)).toBeInTheDocument();
35+
expect(screen.getByRole('button', { name: /next/i })).toBeDisabled();
36+
});
37+
38+
test('multi-space input is handled gracefully - no error', async () => {
39+
const { user, input } = setup();
40+
await user.type(input, 'John Doe');
41+
expect(screen.queryByText(ERROR_MSG)).not.toBeInTheDocument();
42+
});
43+
44+
test('recovery - valid input after invalid clears error', async () => {
45+
const { user, input } = setup();
46+
await user.type(input, INVALID_31);
47+
expect(screen.getByText(ERROR_MSG)).toBeInTheDocument();
48+
await user.clear(input);
49+
await user.type(input, 'John');
50+
expect(screen.queryByText(ERROR_MSG)).not.toBeInTheDocument();
51+
});
52+
});

0 commit comments

Comments
 (0)