Skip to content

Commit 57254ce

Browse files
committed
frontend: fix test setup
1 parent b76c4b0 commit 57254ce

File tree

2 files changed

+140
-26
lines changed

2 files changed

+140
-26
lines changed

frontend/src/test-setup.ts

Lines changed: 132 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,83 @@ interface DropdownButtonProps extends MockComponentProps {
2525

2626
// Mock react-bootstrap components with simple HTML elements
2727
vi.mock('react-bootstrap', () => {
28-
const Modal = ({ children, show, ...props }: ModalProps) =>
29-
show ? h('div', { ...props, role: 'dialog' }, children) : null;
28+
const Form = ({ children, ...props }: MockComponentProps) =>
29+
h('form', { ...props, 'data-testid': 'form' }, children);
30+
31+
Form.Group = ({ children, controlId, ...props }: MockComponentProps) => {
32+
if (children && Array.isArray(children)) {
33+
children = children.map((child) => {
34+
child.props = { ...child.props, controlId };
35+
return child;
36+
})
37+
}
38+
39+
return h('div', { ...props, 'data-testid': 'form-group' }, children);
40+
}
41+
42+
Form.Label = ({ children, controlId, ...props }: MockComponentProps) =>
43+
h('label', { ...props, htmlFor: controlId }, children);
44+
45+
Form.Control = ({ onChange, value, isInvalid, type, as, controlId, ...props }: any) => {
46+
if (as === 'textarea') {
47+
return h('textarea', {
48+
...props,
49+
role: 'textbox',
50+
value,
51+
onChange,
52+
id: controlId,
53+
className: isInvalid ? 'invalid' : '',
54+
'data-testid': `${type || 'textarea'}-input`
55+
});
56+
}
57+
return h('input', {
58+
...props,
59+
type,
60+
value,
61+
onChange,
62+
id: controlId,
63+
className: isInvalid ? 'invalid' : '',
64+
'data-testid': `${type}-input`
65+
});
66+
};
67+
68+
Form.Check = ({ checked, label, isInvalid, ...props }: any) =>
69+
h('div', {}, [
70+
h('input', {
71+
...props,
72+
type: 'checkbox',
73+
checked,
74+
className: isInvalid ? 'invalid' : '',
75+
'data-testid': 'checkbox'
76+
}),
77+
h('label', {}, label)
78+
]);
79+
80+
(Form.Control as any).Feedback = ({ children, type, ...props }: any) =>
81+
h('div', { ...props, 'data-testid': `${type}-feedback` }, children);
82+
83+
const Modal = ({ children, show, onHide, ...props }: any) =>
84+
show ? h('div', { ...props, 'data-testid': 'modal' }, [
85+
h('div', { className: 'modal-content' }, [
86+
children,
87+
h('button', { onClick: onHide, 'data-testid': 'modal-close' }, 'Close')
88+
])
89+
]) : null;
90+
91+
Modal.Header = ({ children, closeButton, ...props }: any) =>
92+
h('div', { ...props, 'data-testid': 'modal-header' }, [
93+
children,
94+
closeButton && h('button', { 'data-testid': 'modal-close' }, 'x')
95+
]);
96+
97+
Modal.Title = ({ children, ...props }: MockComponentProps) =>
98+
h('h4', { ...props, 'data-testid': 'modal-title' }, children);
3099

31-
Modal.Header = ({ children, ...props }: MockComponentProps) =>
32-
h('div', { ...props, className: 'modal-header' }, children);
33100
Modal.Body = ({ children, ...props }: MockComponentProps) =>
34-
h('div', { ...props, className: 'modal-body' }, children);
101+
h('div', { ...props, 'data-testid': 'modal-body' }, children);
102+
35103
Modal.Footer = ({ children, ...props }: MockComponentProps) =>
36-
h('div', { ...props, className: 'modal-footer' }, children);
104+
h('div', { ...props, 'data-testid': 'modal-footer' }, children);
37105

38106
const Card = ({ children, ...props }: MockComponentProps) =>
39107
h('div', { ...props, className: 'card' }, children);
@@ -43,29 +111,66 @@ vi.mock('react-bootstrap', () => {
43111
Card.Body = ({ children, ...props }: MockComponentProps) =>
44112
h('div', { ...props, className: 'card-body' }, children);
45113

46-
const Form = ({ children, ...props }: MockComponentProps) =>
47-
h('form', { ...props }, children);
48-
49-
Form.Control = ({ as, ...props }: FormControlProps) =>
50-
as === 'textarea' ? h('textarea', { ...props, role: 'textbox' }) : h('input', { ...props });
51-
52114
const Dropdown = {
53115
Item: ({ children, ...props }: MockComponentProps) => h('button', { ...props }, children),
54116
};
55117

118+
const Nav = ({ children, ...props }: MockComponentProps) =>
119+
h('nav', { ...props }, children);
120+
121+
Nav.Link = ({ children, ...props }: MockComponentProps) =>
122+
h('a', { ...props }, children);
123+
124+
const Navbar = ({ children, ...props }: MockComponentProps) =>
125+
h('nav', { ...props, className: 'navbar' }, children);
126+
127+
Navbar.Brand = ({ children, ...props }: MockComponentProps) =>
128+
h('a', { ...props, className: 'navbar-brand' }, children);
129+
130+
Navbar.Toggle = ({ children, ...props }: MockComponentProps) =>
131+
h('button', { ...props, className: 'navbar-toggle' }, children);
132+
133+
Navbar.Collapse = ({ children, ...props }: MockComponentProps) =>
134+
h('div', { ...props, className: 'navbar-collapse' }, children);
135+
136+
const InputGroup = ({ children, ...props }: MockComponentProps) =>
137+
h('div', { ...props, className: 'input-group' }, children);
138+
139+
InputGroup.Text = ({ children, ...props }: MockComponentProps) =>
140+
h('span', { ...props, className: 'input-group-text' }, children);
141+
142+
const Tabs = ({ children, activeKey, onSelect, ...props }: any) =>
143+
h('div', { ...props, className: 'tabs' }, children);
144+
145+
const Tab = ({ children, eventKey, title, ...props }: any) =>
146+
h('div', { ...props, className: 'tab-pane' }, children);
147+
148+
const Alert = ({ children, variant, ...props }: any) =>
149+
h('div', { ...props, className: `alert alert-${variant || 'primary'}` }, children);
150+
151+
const Spinner = ({ ...props }: MockComponentProps) =>
152+
h('div', { ...props, className: 'spinner' }, 'Loading...');
153+
56154
return {
57-
Container: ({ children, ...props }: MockComponentProps) => h('div', { ...props, 'data-testid': 'container' }, children),
58-
Table: ({ children, ...props }: MockComponentProps) => h('table', { ...props }, children),
59-
Modal,
60-
Button: ({ children, ...props }: MockComponentProps) => h('button', { ...props }, children),
61-
Form,
155+
Alert,
156+
Button: ({ children, type, ...props }: any) => h('button', { ...props, type, 'data-testid': 'submit-button' }, children),
157+
ButtonGroup: ({ children, ...props }: MockComponentProps) => h('div', { ...props }, children),
62158
Card,
63-
Row: ({ children, ...props }: MockComponentProps) => h('div', { ...props, className: 'row' }, children),
64159
Col: ({ children, ...props }: MockComponentProps) => h('div', { ...props, className: 'col' }, children),
65-
ButtonGroup: ({ children, ...props }: MockComponentProps) => h('div', { ...props }, children),
160+
Collapse: ({ children, in: inProp, ...props }: CollapseProps) => inProp ? h('div', { ...props }, children) : null,
161+
Container: ({ children, ...props }: MockComponentProps) => h('div', { ...props, 'data-testid': 'container' }, children),
66162
Dropdown,
67163
DropdownButton: ({ title, ...props }: DropdownButtonProps) => h('button', { ...props }, title),
68-
Collapse: ({ children, in: inProp, ...props }: CollapseProps) => inProp ? h('div', { ...props }, children) : null,
164+
Form,
165+
InputGroup,
166+
Modal,
167+
Nav,
168+
Navbar,
169+
Row: ({ children, ...props }: MockComponentProps) => h('div', { ...props, className: 'row' }, children),
170+
Spinner,
171+
Tab,
172+
Table: ({ children, ...props }: MockComponentProps) => h('table', { ...props }, children),
173+
Tabs,
69174
};
70175
});
71176

@@ -74,6 +179,7 @@ vi.mock('react-feather', () => ({
74179
ChevronDown: () => h('svg', { 'data-testid': 'chevron-down' }),
75180
ChevronUp: () => h('svg', { 'data-testid': 'chevron-up' }),
76181
Edit: () => h('svg', { 'data-testid': 'edit-icon' }),
182+
Eye: () => h('svg', { 'data-testid': 'eye-icon' }),
77183
Monitor: () => h('svg', { 'data-testid': 'monitor-icon' }),
78184
Trash2: () => h('svg', { 'data-testid': 'trash-icon', className: 'feather-trash-2' }),
79185
}));
@@ -99,6 +205,10 @@ vi.mock('libsodium-wrappers', () => ({
99205
default: {
100206
crypto_box_seal_open: vi.fn(),
101207
crypto_box_seal: vi.fn(),
208+
crypto_box_keypair: vi.fn(),
209+
crypto_secretbox_easy: vi.fn(),
210+
crypto_secretbox_NONCEBYTES: 24,
211+
crypto_secretbox_KEYBYTES: 32,
102212
},
103213
}));
104214

@@ -147,7 +257,7 @@ vi.mock('median-js-bridge', () => ({
147257
}));
148258

149259
// Mock i18n
150-
vi.mock('../i18n', () => ({
260+
vi.mock('./i18n', () => ({
151261
default: {
152262
t: (key: string, options?: Record<string, unknown>) => {
153263
if (options && typeof options === 'object') {
@@ -159,6 +269,7 @@ vi.mock('../i18n', () => ({
159269
}
160270
return key;
161271
},
272+
language: 'en',
162273
},
163274
}));
164275

frontend/vitest.config.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { defineConfig } from 'vitest/config';
22
import preact from '@preact/preset-vite';
3+
import { resolve } from 'node:path';
34

45
export default defineConfig({
56
plugins: [preact()],
@@ -14,12 +15,14 @@ export default defineConfig({
1415
alias: {
1516
"react": "preact/compat",
1617
"react-dom": "preact/compat",
18+
"react-dom/test-utils": "preact/test-utils",
19+
"react/jsx-runtime": "preact/jsx-runtime",
1720
"argon2-browser": "argon2-browser/dist/argon2-bundled.min.js",
18-
"logo": "src/assets/warp_logo.png",
19-
"favicon": "src/assets/warp_favicon.png",
20-
"links": "src/links/warp.ts",
21-
"translations-de": "src/locales/branding/warp_de.ts",
22-
"translations-en": "src/locales/branding/warp_en.ts",
21+
"logo": resolve(__dirname, "src/assets/warp_logo.png"),
22+
"favicon": resolve(__dirname, "src/assets/warp_favicon.png"),
23+
"links": resolve(__dirname, "src/links/warp.ts"),
24+
"translations-de": resolve(__dirname, "src/locales/branding/warp_de.ts"),
25+
"translations-en": resolve(__dirname, "src/locales/branding/warp_en.ts"),
2326
}
2427
},
2528
});

0 commit comments

Comments
 (0)