Skip to content

Commit 0c4bdf9

Browse files
committed
test for email and password field
1 parent 8d5a99f commit 0c4bdf9

2 files changed

Lines changed: 129 additions & 0 deletions

File tree

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import VueRouter from 'vue-router';
2+
import { render, screen, fireEvent } from '@testing-library/vue';
3+
import StudioEmailField from '../StudioEmailField.vue';
4+
5+
const renderComponent = (props = {}) =>
6+
render(StudioEmailField, {
7+
router: new VueRouter(),
8+
props: {
9+
value: '',
10+
...props,
11+
},
12+
});
13+
14+
describe('StudioEmailField', () => {
15+
describe('rendering', () => {
16+
it('renders with the default "Email address" label', () => {
17+
renderComponent();
18+
expect(screen.getByLabelText(/email address/i)).toBeInTheDocument();
19+
});
20+
21+
it('renders with a custom label when provided', () => {
22+
renderComponent({ label: 'Work email' });
23+
expect(screen.getByLabelText(/work email/i)).toBeInTheDocument();
24+
});
25+
26+
it('is disabled when the disabled prop is true', () => {
27+
renderComponent({ disabled: true });
28+
expect(screen.getByLabelText(/email address/i)).toBeDisabled();
29+
});
30+
});
31+
32+
describe('input handling', () => {
33+
it('emits trimmed value — strips leading and trailing whitespace', async () => {
34+
const { emitted } = renderComponent();
35+
const input = screen.getByLabelText(/email address/i);
36+
await fireEvent.update(input, ' test@example.com ');
37+
expect(emitted().input).toBeTruthy();
38+
expect(emitted().input[0][0]).toBe('test@example.com');
39+
});
40+
41+
it('emits blur event when the field loses focus', async () => {
42+
const { emitted } = renderComponent();
43+
const input = screen.getByLabelText(/email address/i);
44+
await fireEvent.blur(input);
45+
expect(emitted().blur).toBeTruthy();
46+
});
47+
});
48+
49+
describe('error display', () => {
50+
it('shows the first error message when errorMessages is non-empty', () => {
51+
renderComponent({ errorMessages: ['Please enter a valid email address'] });
52+
expect(screen.getByText('Please enter a valid email address')).toBeVisible();
53+
});
54+
55+
it('shows no error text when errorMessages is empty', () => {
56+
renderComponent({ errorMessages: [] });
57+
expect(screen.queryByText('Please enter a valid email address')).not.toBeInTheDocument();
58+
});
59+
60+
it('shows only the first error when multiple messages are provided', () => {
61+
renderComponent({ errorMessages: ['First error', 'Second error'] });
62+
expect(screen.getByText('First error')).toBeVisible();
63+
expect(screen.queryByText('Second error')).not.toBeInTheDocument();
64+
});
65+
});
66+
});
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import VueRouter from 'vue-router';
2+
import { render, screen, fireEvent } from '@testing-library/vue';
3+
import StudioPasswordField from '../StudioPasswordField.vue';
4+
5+
const renderComponent = (props = {}) =>
6+
render(StudioPasswordField, {
7+
router: new VueRouter(),
8+
props: {
9+
value: '',
10+
...props,
11+
},
12+
});
13+
14+
describe('StudioPasswordField', () => {
15+
describe('rendering', () => {
16+
it('renders with the default "Password" label', () => {
17+
renderComponent();
18+
expect(screen.getByLabelText(/^password$/i)).toBeInTheDocument();
19+
});
20+
21+
it('renders with a custom label when provided', () => {
22+
renderComponent({ label: 'Confirm password' });
23+
expect(screen.getByLabelText(/confirm password/i)).toBeInTheDocument();
24+
});
25+
});
26+
27+
describe('input handling', () => {
28+
it('emits raw value without trimming whitespace', async () => {
29+
const { emitted } = renderComponent();
30+
const input = screen.getByLabelText(/^password$/i);
31+
await fireEvent.update(input, ' mypassword ');
32+
expect(emitted().input).toBeTruthy();
33+
expect(emitted().input[0][0]).toBe(' mypassword ');
34+
});
35+
36+
it('emits blur event when the field loses focus', async () => {
37+
const { emitted } = renderComponent();
38+
const input = screen.getByLabelText(/^password$/i);
39+
await fireEvent.blur(input);
40+
expect(emitted().blur).toBeTruthy();
41+
});
42+
});
43+
44+
describe('error display', () => {
45+
it('shows the first error message when errorMessages is non-empty', () => {
46+
renderComponent({ errorMessages: ['Password should be at least 8 characters long'] });
47+
expect(screen.getByText('Password should be at least 8 characters long')).toBeVisible();
48+
});
49+
50+
it('shows no error text when errorMessages is empty', () => {
51+
renderComponent({ errorMessages: [] });
52+
expect(
53+
screen.queryByText('Password should be at least 8 characters long'),
54+
).not.toBeInTheDocument();
55+
});
56+
57+
it('shows only the first error when multiple messages are provided', () => {
58+
renderComponent({ errorMessages: ['First error', 'Second error'] });
59+
expect(screen.getByText('First error')).toBeVisible();
60+
expect(screen.queryByText('Second error')).not.toBeInTheDocument();
61+
});
62+
});
63+
});

0 commit comments

Comments
 (0)