Skip to content

Commit f0654ca

Browse files
committed
Added UserEditor unit test
1 parent 786d07a commit f0654ca

File tree

2 files changed

+252
-3
lines changed

2 files changed

+252
-3
lines changed

__tests__/v2/UserEditor.test.js

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
import { describe, it, beforeEach, expect, vi } from 'vitest';
2+
import { render, screen } from '@testing-library/svelte';
3+
import userEvent from '@testing-library/user-event';
4+
import { readable } from 'svelte/store';
5+
6+
// Mocking fetch
7+
global.fetch = vi.fn();
8+
9+
// Mocking the page store
10+
vi.mock('$app/stores', () => {
11+
return {
12+
page: readable({
13+
data: {
14+
userInfo: {
15+
id: 2
16+
}
17+
}
18+
})
19+
};
20+
});
21+
22+
// The component to be tested must be imported after the mock setup
23+
import UserEditor from '../../src/lib/components/v2/admin/UserEditor.svelte';
24+
25+
describe('UserEditor', () => {
26+
beforeEach(() => {
27+
fetch.mockClear();
28+
});
29+
30+
const selectedUser = {
31+
id: 1,
32+
group_ids: []
33+
};
34+
35+
const initialSettings = {
36+
id: 1,
37+
slurm_accounts: [],
38+
slurm_user: null,
39+
cache_dir: null,
40+
ssh_host: null,
41+
ssh_username: null,
42+
ssh_private_key_path: null,
43+
ssh_tasks_dir: null,
44+
ssh_jobs_dir: null
45+
};
46+
47+
it('Update settings with slurm runner backend - success', async () => {
48+
const user = userEvent.setup();
49+
50+
render(UserEditor, {
51+
props: {
52+
runnerBackend: 'slurm',
53+
user: selectedUser,
54+
settings: { ...initialSettings },
55+
save: () => {}
56+
}
57+
});
58+
59+
const mockRequest = fetch.mockResolvedValue({
60+
ok: true,
61+
status: 200,
62+
json: () =>
63+
new Promise((resolve) =>
64+
resolve({
65+
...initialSettings,
66+
slurm_user: 'user',
67+
cache_dir: '/path/to/cache/dir'
68+
})
69+
)
70+
});
71+
72+
await user.type(screen.getByRole('textbox', { name: 'SLURM user' }), 'user');
73+
await user.type(screen.getByRole('textbox', { name: 'Cache dir' }), '/path/to/cache/dir');
74+
await user.click(screen.getAllByRole('button', { name: 'Save' })[1]);
75+
await screen.findByText('Settings successfully updated');
76+
77+
expect(mockRequest).toHaveBeenCalledWith(
78+
expect.anything(),
79+
expect.objectContaining({
80+
body: JSON.stringify({
81+
slurm_user: 'user',
82+
cache_dir: '/path/to/cache/dir',
83+
slurm_accounts: []
84+
})
85+
})
86+
);
87+
});
88+
89+
it('Update settings with slurm runner backend - validation error', async () => {
90+
const user = userEvent.setup();
91+
92+
render(UserEditor, {
93+
props: {
94+
runnerBackend: 'slurm',
95+
user: selectedUser,
96+
settings: { ...initialSettings },
97+
save: () => {}
98+
}
99+
});
100+
101+
const mockRequest = fetch.mockResolvedValue({
102+
ok: false,
103+
status: 422,
104+
json: () =>
105+
new Promise((resolve) =>
106+
resolve({
107+
detail: [
108+
{
109+
loc: ['body', 'cache_dir'],
110+
msg: 'mocked_error',
111+
type: 'value_error'
112+
}
113+
]
114+
})
115+
)
116+
});
117+
118+
await user.type(screen.getByRole('textbox', { name: 'Cache dir' }), 'xxx');
119+
await user.click(screen.getAllByRole('button', { name: 'Save' })[1]);
120+
await screen.findByText('mocked_error');
121+
122+
expect(mockRequest).toHaveBeenCalledWith(
123+
expect.anything(),
124+
expect.objectContaining({
125+
body: JSON.stringify({
126+
cache_dir: 'xxx',
127+
slurm_accounts: []
128+
})
129+
})
130+
);
131+
});
132+
133+
it('Update settings with slurm_ssh runner backend - success', async () => {
134+
const user = userEvent.setup();
135+
136+
render(UserEditor, {
137+
props: {
138+
runnerBackend: 'slurm_ssh',
139+
user: selectedUser,
140+
settings: { ...initialSettings },
141+
save: () => {}
142+
}
143+
});
144+
145+
const mockRequest = fetch.mockResolvedValue({
146+
ok: true,
147+
status: 200,
148+
json: () =>
149+
new Promise((resolve) =>
150+
resolve({
151+
...initialSettings,
152+
ssh_host: 'localhost',
153+
ssh_username: 'username',
154+
ssh_private_key_path: '/path/to/private/key',
155+
ssh_tasks_dir: '/path/to/tasks/dir',
156+
ssh_jobs_dir: '/path/to/jobs/dir'
157+
})
158+
)
159+
});
160+
161+
await user.type(screen.getByRole('textbox', { name: 'SSH host' }), 'localhost');
162+
await user.type(screen.getByRole('textbox', { name: 'SSH username' }), 'username');
163+
await user.type(screen.getByRole('textbox', { name: 'SSH Private Key Path' }), 'xxx');
164+
await user.type(screen.getByRole('textbox', { name: 'SSH Tasks Dir' }), 'yyy');
165+
await user.type(screen.getByRole('textbox', { name: 'SSH Jobs Dir' }), 'zzz');
166+
await user.click(screen.getAllByRole('button', { name: 'Save' })[1]);
167+
await screen.findByText('Settings successfully updated');
168+
169+
expect(mockRequest).toHaveBeenCalledWith(
170+
expect.anything(),
171+
expect.objectContaining({
172+
body: JSON.stringify({
173+
ssh_host: 'localhost',
174+
ssh_username: 'username',
175+
ssh_private_key_path: 'xxx',
176+
ssh_tasks_dir: 'yyy',
177+
ssh_jobs_dir: 'zzz',
178+
slurm_accounts: []
179+
})
180+
})
181+
);
182+
});
183+
184+
it('Update settings with slurm_ssh runner backend - validation error', async () => {
185+
const user = userEvent.setup();
186+
187+
render(UserEditor, {
188+
props: {
189+
runnerBackend: 'slurm_ssh',
190+
user: selectedUser,
191+
settings: { ...initialSettings },
192+
save: () => {}
193+
}
194+
});
195+
196+
const mockRequest = fetch.mockResolvedValue({
197+
ok: false,
198+
status: 422,
199+
json: () =>
200+
new Promise((resolve) =>
201+
resolve({
202+
detail: [
203+
{
204+
loc: ['body', 'ssh_private_key_path'],
205+
msg: 'mock_error_ssh_private_key_path',
206+
type: 'value_error'
207+
},
208+
{
209+
loc: ['body', 'ssh_tasks_dir'],
210+
msg: 'mock_error_ssh_tasks_dir',
211+
type: 'value_error'
212+
},
213+
{
214+
loc: ['body', 'ssh_jobs_dir'],
215+
msg: 'mock_error_ssh_jobs_dir',
216+
type: 'value_error'
217+
}
218+
]
219+
})
220+
)
221+
});
222+
223+
await user.type(screen.getByRole('textbox', { name: 'SSH host' }), 'localhost');
224+
await user.type(screen.getByRole('textbox', { name: 'SSH username' }), 'username');
225+
await user.type(
226+
screen.getByRole('textbox', { name: 'SSH Private Key Path' }),
227+
'/path/to/private/key'
228+
);
229+
await user.type(screen.getByRole('textbox', { name: 'SSH Tasks Dir' }), '/path/to/tasks/dir');
230+
await user.type(screen.getByRole('textbox', { name: 'SSH Jobs Dir' }), '/path/to/jobs/dir');
231+
await user.click(screen.getAllByRole('button', { name: 'Save' })[1]);
232+
await screen.findByText('mock_error_ssh_private_key_path');
233+
await screen.findByText('mock_error_ssh_tasks_dir');
234+
await screen.findByText('mock_error_ssh_jobs_dir');
235+
236+
expect(mockRequest).toHaveBeenCalledWith(
237+
expect.anything(),
238+
expect.objectContaining({
239+
body: JSON.stringify({
240+
ssh_host: 'localhost',
241+
ssh_username: 'username',
242+
ssh_private_key_path: '/path/to/private/key',
243+
ssh_tasks_dir: '/path/to/tasks/dir',
244+
ssh_jobs_dir: '/path/to/jobs/dir',
245+
slurm_accounts: []
246+
})
247+
})
248+
);
249+
});
250+
});

src/lib/components/v2/admin/UserEditor.svelte

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,9 +510,8 @@
510510
class:is-invalid={settingsFormSubmitted && $settingsValidationErrors['slurm_user']}
511511
/>
512512
<div class="form-text">
513-
The user on the local SLURM cluster who will be impersonated by Fractal through <code
514-
>sudo -u</code
515-
>
513+
The user on the local SLURM cluster who will be impersonated by Fractal through
514+
<code>sudo -u</code>
516515
</div>
517516
<span class="invalid-feedback">{$settingsValidationErrors['slurm_user']}</span>
518517
</div>

0 commit comments

Comments
 (0)