]> source.dussan.org Git - sonarqube.git/blob
997c6e7ef14a917a617474a6545ddf295d1e81cd
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 import { screen } from '@testing-library/react';
21 import userEvent from '@testing-library/user-event';
22 import { addGlobalSuccessMessage } from 'design-system/lib';
23 import React from 'react';
24 import { byLabelText, byRole, byTestId, byText } from '~sonar-aligned/helpers/testSelector';
25 import SystemServiceMock from '../../../../../api/mocks/SystemServiceMock';
26 import * as settingsApi from '../../../../../api/settings';
27 import * as api from '../../../../../api/system';
28 import { CurrentUserContext } from '../../../../../app/components/current-user/CurrentUserContext';
29 import { mockEmailConfiguration } from '../../../../../helpers/mocks/system';
30 import { mockCurrentUser } from '../../../../../helpers/testMocks';
31 import { renderComponent } from '../../../../../helpers/testReactTestingUtils';
32 import { Permissions } from '../../../../../types/permissions';
33 import { AuthMethod } from '../../../../../types/system';
34 import EmailNotification from '../EmailNotification';
35
36 jest.mock('../../../../../api/system');
37 jest.mock('../../../../../api/settings');
38
39 jest.mock('design-system', () => ({
40   ...jest.requireActual('design-system'),
41   addGlobalSuccessMessage: jest.fn(),
42 }));
43
44 const systemHandler = new SystemServiceMock();
45
46 beforeEach(() => {
47   jest.clearAllMocks();
48   systemHandler.reset();
49 });
50
51 const ui = {
52   editSubheading1: byText('email_notification.subheading.1'),
53
54   // common fields
55   selectorBasicAuth: byRole('radio', {
56     name: 'email_notification.form.basic_auth.title email_notification.form.basic_auth.description',
57   }),
58   selectorOAuthAuth: byRole('radio', {
59     name: 'email_notification.form.oauth_auth.title email_notification.form.oauth_auth.description email_notification.form.oauth_auth.supported recommended email_notification.form.oauth_auth.recommended_reason',
60   }),
61   host: byRole('textbox', {
62     name: 'email_notification.form.host field_required',
63   }),
64   port: byRole('spinbutton', {
65     name: 'email_notification.form.port field_required',
66   }),
67   securityProtocol: byRole('searchbox', {
68     name: 'email_notification.form.security_protocol field_required',
69   }),
70   fromAddress: byRole('textbox', {
71     name: 'email_notification.form.from_address field_required',
72   }),
73   fromName: byRole('textbox', {
74     name: 'email_notification.form.from_name field_required',
75   }),
76   subjectPrefix: byRole('textbox', {
77     name: 'email_notification.form.subject_prefix field_required',
78   }),
79   username: byRole('textbox', {
80     name: 'email_notification.form.username field_required',
81   }),
82
83   // basic authentication
84   basic_password: byLabelText('email_notification.form.basic_password*'),
85
86   // oauth
87   oauth_auth_host: byRole('textbox', {
88     name: 'email_notification.form.oauth_authentication_host field_required',
89   }),
90   oauth_client_id: byLabelText('email_notification.form.oauth_client_id*'),
91   oauth_client_id_edit: byTestId('email_notification.form.oauth_client_id-edit'),
92   oauth_client_id_reset: byTestId('email_notification.form.oauth_client_id-reset'),
93   oauth_client_secret: byLabelText('email_notification.form.oauth_client_secret*'),
94   oauth_tenant: byRole('textbox', { name: 'email_notification.form.oauth_tenant field_required' }),
95
96   save: byRole('button', {
97     name: 'email_notification.form.save_configuration',
98   }),
99
100   // overview values
101   overviewHeading: byText('email_notification.overview.heading'),
102   overview_auth_mode: byTestId('email_notification.overview.authentication_type.value'),
103   overview_username: byTestId('email_notification.form.username.value'),
104   overview_basic_password: byTestId('email_notification.form.basic_password.value'),
105   overview_oauth_auth_host: byTestId('email_notification.form.oauth_authentication_host.value'),
106   overview_oauth_client_id: byTestId('email_notification.form.oauth_client_id.value'),
107   overview_oauth_client_secret: byTestId('email_notification.form.oauth_client_secret.value'),
108   overview_oauth_tenant: byTestId('email_notification.form.oauth_tenant.value'),
109   overview_host: byTestId('email_notification.form.host.value'),
110   overview_port: byTestId('email_notification.form.port.value'),
111   overview_security_protocol: byTestId('email_notification.form.security_protocol.value'),
112   overview_from_address: byTestId('email_notification.form.from_address.value'),
113   overview_from_name: byTestId('email_notification.form.from_name.value'),
114   overview_subject_prefix: byTestId('email_notification.form.subject_prefix.value'),
115
116   edit: byRole('button', {
117     name: 'edit',
118   }),
119
120   // test modal
121   test_email: byRole('button', { name: 'email_notification.test.create_test_email' }),
122   test_email_title: byRole('heading', { name: 'email_notification.test.modal_title' }),
123   test_email_to_address: byRole('textbox', {
124     name: 'email_notification.test.to_address required',
125   }),
126   test_email_subject: byRole('textbox', { name: 'email_notification.test.subject' }),
127   test_email_message: byRole('textbox', { name: 'email_notification.test.message required' }),
128   test_email_submit: byRole('button', { name: 'email_notification.test.submit' }),
129 };
130
131 describe('Email Basic Configuration', () => {
132   it('can save the basic configuration', async () => {
133     jest.spyOn(api, 'postEmailConfiguration');
134     const user = userEvent.setup();
135     renderEmailNotifications();
136     expect(await ui.editSubheading1.find()).toBeInTheDocument();
137
138     expect(ui.save.get()).toBeDisabled();
139
140     expect(ui.selectorBasicAuth.get()).toBeChecked();
141     expect(ui.username.get()).toHaveValue('');
142     expect(ui.basic_password.get()).toHaveValue('');
143     expect(ui.host.get()).toHaveValue('');
144     expect(ui.port.get()).toHaveValue(587);
145     expect(ui.securityProtocol.get()).toHaveValue('');
146     expect(ui.fromAddress.get()).toHaveValue('');
147     expect(ui.fromName.get()).toHaveValue('SonarQube');
148     expect(ui.subjectPrefix.get()).toHaveValue('[SonarQube]');
149
150     await user.type(ui.basic_password.get(), 'password');
151     await user.type(ui.host.get(), 'host');
152     await user.clear(ui.port.get());
153     await user.type(ui.port.get(), '1234');
154     await user.click(ui.securityProtocol.get());
155     await user.click(screen.getByText('SSLTLS'));
156     await user.type(ui.fromAddress.get(), 'admin@localhost.com');
157     await user.clear(ui.fromName.get());
158     await user.type(ui.fromName.get(), 'fromName');
159     await user.clear(ui.subjectPrefix.get());
160     await user.type(ui.subjectPrefix.get(), 'prefix');
161     await user.type(ui.username.get(), 'username');
162
163     expect(ui.selectorBasicAuth.get()).toBeChecked();
164     expect(ui.username.get()).toHaveValue('username');
165     expect(ui.basic_password.get()).toHaveValue('password');
166     expect(ui.host.get()).toHaveValue('host');
167     expect(ui.port.get()).toHaveValue(1234);
168     expect(ui.securityProtocol.get()).toHaveValue('SSLTLS');
169     expect(ui.fromAddress.get()).toHaveValue('admin@localhost.com');
170     expect(ui.fromName.get()).toHaveValue('fromName');
171     expect(ui.subjectPrefix.get()).toHaveValue('prefix');
172
173     expect(await ui.save.find()).toBeEnabled();
174     await user.click(ui.save.get());
175
176     expect(api.postEmailConfiguration).toHaveBeenCalledTimes(1);
177     expect(api.postEmailConfiguration).toHaveBeenCalledWith({
178       authMethod: 'BASIC',
179       basicPassword: 'password',
180       fromAddress: 'admin@localhost.com',
181       fromName: 'fromName',
182       host: 'host',
183       port: '1234',
184       securityProtocol: 'SSLTLS',
185       subjectPrefix: 'prefix',
186       username: 'username',
187     });
188
189     expect(addGlobalSuccessMessage).toHaveBeenCalledWith(
190       'email_notification.form.save_configuration.create_success',
191     );
192
193     expect(await ui.overviewHeading.find()).toBeInTheDocument();
194
195     expect(ui.overview_auth_mode.get()).toHaveTextContent(AuthMethod.Basic);
196     expect(ui.overview_username.get()).toHaveTextContent('username');
197     expect(ui.overview_basic_password.get()).toHaveTextContent(
198       'email_notification.overview.private',
199     );
200     expect(ui.overview_host.get()).toHaveTextContent('host');
201     expect(ui.overview_port.get()).toHaveTextContent('1234');
202     expect(ui.overview_security_protocol.get()).toHaveTextContent('SSLTLS');
203     expect(ui.overview_from_address.get()).toHaveTextContent('admin@localhost.com');
204     expect(ui.overview_from_name.get()).toHaveTextContent('fromName');
205     expect(ui.overview_subject_prefix.get()).toHaveTextContent('prefix');
206   });
207
208   it('renders the overview after loading configuration', async () => {
209     systemHandler.addEmailConfiguration(
210       mockEmailConfiguration(AuthMethod.Basic, { id: 'email-1' }),
211     );
212
213     renderEmailNotifications();
214
215     expect(await ui.overviewHeading.find()).toBeInTheDocument();
216     expect(ui.overview_auth_mode.get()).toHaveTextContent(AuthMethod.Basic);
217     expect(ui.overview_username.get()).toHaveTextContent('username');
218     expect(ui.overview_basic_password.get()).toHaveTextContent(
219       'email_notification.overview.private',
220     );
221     expect(ui.overview_host.get()).toHaveTextContent('host');
222     expect(ui.overview_port.get()).toHaveTextContent('port');
223     expect(ui.overview_security_protocol.get()).toHaveTextContent('SSLTLS');
224     expect(ui.overview_from_address.get()).toHaveTextContent('from_address');
225     expect(ui.overview_from_name.get()).toHaveTextContent('from_name');
226     expect(ui.overview_subject_prefix.get()).toHaveTextContent('subject_prefix');
227   });
228
229   it('can edit an existing configuration', async () => {
230     systemHandler.addEmailConfiguration(
231       mockEmailConfiguration(AuthMethod.Basic, { id: 'email-1' }),
232     );
233     jest.spyOn(api, 'patchEmailConfiguration');
234     const user = userEvent.setup();
235     renderEmailNotifications();
236
237     expect(await ui.overviewHeading.find()).toBeInTheDocument();
238
239     await user.click(ui.edit.get());
240
241     expect(await ui.editSubheading1.find()).toBeInTheDocument();
242
243     expect(ui.save.get()).toBeDisabled();
244     await user.type(ui.basic_password.get(), 'updated');
245     await user.type(ui.host.get(), '-updated');
246     await user.type(ui.port.get(), '5678');
247     await user.click(ui.securityProtocol.get());
248     await user.click(screen.getByText('STARTTLS'));
249     await user.clear(ui.fromAddress.get());
250     await user.type(ui.fromAddress.get(), 'updated@email.com');
251     await user.type(ui.fromName.get(), '-updated');
252     await user.type(ui.subjectPrefix.get(), '-updated');
253     await user.type(ui.username.get(), '-updated');
254
255     expect(await ui.save.find()).toBeEnabled();
256     await user.click(ui.save.get());
257
258     expect(api.patchEmailConfiguration).toHaveBeenCalledTimes(1);
259     expect(api.patchEmailConfiguration).toHaveBeenCalledWith('email-1', {
260       authMethod: 'BASIC',
261       basicPassword: 'updated',
262       fromAddress: 'updated@email.com',
263       fromName: 'from_name-updated',
264       host: 'host-updated',
265       id: 'email-1',
266       isBasicPasswordSet: true,
267       port: '5678',
268       securityProtocol: 'STARTTLS',
269       subjectPrefix: 'subject_prefix-updated',
270       username: 'username-updated',
271     });
272
273     expect(addGlobalSuccessMessage).toHaveBeenCalledWith(
274       'email_notification.form.save_configuration.update_success',
275     );
276
277     expect(await ui.overviewHeading.find()).toBeInTheDocument();
278
279     expect(ui.overview_auth_mode.get()).toHaveTextContent(AuthMethod.Basic);
280     expect(ui.overview_username.get()).toHaveTextContent('username-updated');
281     expect(ui.overview_basic_password.get()).toHaveTextContent(
282       'email_notification.overview.private',
283     );
284     expect(ui.overview_host.get()).toHaveTextContent('host-updated');
285     expect(ui.overview_port.get()).toHaveTextContent('5678');
286     expect(ui.overview_security_protocol.get()).toHaveTextContent('STARTTLS');
287     expect(ui.overview_from_address.get()).toHaveTextContent('updated@email.com');
288     expect(ui.overview_from_name.get()).toHaveTextContent('from_name-updated');
289     expect(ui.overview_subject_prefix.get()).toHaveTextContent('subject_prefix-updated');
290   });
291 });
292
293 describe('Email Oauth Configuration', () => {
294   it('can save the oauth configuration', async () => {
295     jest.spyOn(api, 'postEmailConfiguration');
296     const user = userEvent.setup();
297     renderEmailNotifications();
298     expect(await ui.editSubheading1.find()).toBeInTheDocument();
299     await user.click(ui.selectorOAuthAuth.get());
300
301     expect(ui.save.get()).toBeDisabled();
302
303     expect(ui.selectorOAuthAuth.get()).toBeChecked();
304     expect(ui.oauth_auth_host.get()).toHaveValue('');
305     expect(ui.oauth_client_id.get()).toHaveValue('');
306     expect(ui.oauth_client_secret.get()).toHaveValue('');
307     expect(ui.oauth_tenant.get()).toHaveValue('');
308     expect(ui.host.get()).toHaveValue('');
309     expect(ui.port.get()).toHaveValue(587);
310     expect(ui.securityProtocol.get()).toHaveValue('');
311     expect(ui.fromAddress.get()).toHaveValue('');
312     expect(ui.fromName.get()).toHaveValue('SonarQube');
313     expect(ui.subjectPrefix.get()).toHaveValue('[SonarQube]');
314
315     await user.type(ui.oauth_auth_host.get(), 'oauth_auth_host');
316     await user.type(ui.oauth_client_id.get(), 'oauth_client_id');
317     await user.type(ui.oauth_client_secret.get(), 'oauth_client_secret');
318     await user.type(ui.oauth_tenant.get(), 'oauth_tenant');
319     await user.type(ui.host.get(), 'host');
320     await user.clear(ui.port.get());
321     await user.type(ui.port.get(), '1234');
322     await user.click(ui.securityProtocol.get());
323     await user.click(screen.getByText('SSLTLS'));
324     await user.type(ui.fromAddress.get(), 'admin@localhost.com');
325     await user.clear(ui.fromName.get());
326     await user.type(ui.fromName.get(), 'fromName');
327     await user.clear(ui.subjectPrefix.get());
328     await user.type(ui.subjectPrefix.get(), 'prefix');
329     await user.type(ui.username.get(), 'username');
330
331     expect(ui.selectorOAuthAuth.get()).toBeChecked();
332     expect(ui.username.get()).toHaveValue('username');
333     expect(ui.oauth_auth_host.get()).toHaveValue('oauth_auth_host');
334     expect(ui.oauth_client_id.get()).toHaveValue('oauth_client_id');
335     expect(ui.oauth_client_secret.get()).toHaveValue('oauth_client_secret');
336     expect(ui.oauth_tenant.get()).toHaveValue('oauth_tenant');
337     expect(ui.host.get()).toHaveValue('host');
338     expect(ui.port.get()).toHaveValue(1234);
339     expect(ui.securityProtocol.get()).toHaveValue('SSLTLS');
340     expect(ui.fromAddress.get()).toHaveValue('admin@localhost.com');
341     expect(ui.fromName.get()).toHaveValue('fromName');
342     expect(ui.subjectPrefix.get()).toHaveValue('prefix');
343
344     expect(await ui.save.find()).toBeEnabled();
345     await user.click(ui.save.get());
346
347     expect(api.postEmailConfiguration).toHaveBeenCalledTimes(1);
348     expect(api.postEmailConfiguration).toHaveBeenCalledWith({
349       authMethod: 'OAUTH',
350       basicPassword: '',
351       oauthAuthenticationHost: 'oauth_auth_host',
352       oauthClientId: 'oauth_client_id',
353       oauthClientSecret: 'oauth_client_secret',
354       oauthTenant: 'oauth_tenant',
355       fromAddress: 'admin@localhost.com',
356       fromName: 'fromName',
357       host: 'host',
358       port: '1234',
359       securityProtocol: 'SSLTLS',
360       subjectPrefix: 'prefix',
361       username: 'username',
362     });
363
364     expect(addGlobalSuccessMessage).toHaveBeenCalledWith(
365       'email_notification.form.save_configuration.create_success',
366     );
367
368     expect(await ui.overviewHeading.find()).toBeInTheDocument();
369
370     expect(ui.overview_auth_mode.get()).toHaveTextContent(AuthMethod.OAuth);
371     expect(ui.overview_oauth_auth_host.get()).toHaveTextContent('oauth_auth_host');
372     expect(ui.overview_oauth_client_id.get()).toHaveTextContent(
373       'email_notification.overview.private',
374     );
375     expect(ui.overview_oauth_client_secret.get()).toHaveTextContent(
376       'email_notification.overview.private',
377     );
378     expect(ui.overview_oauth_tenant.get()).toHaveTextContent('oauth_tenant');
379     expect(ui.overview_host.get()).toHaveTextContent('host');
380     expect(ui.overview_port.get()).toHaveTextContent('1234');
381     expect(ui.overview_security_protocol.get()).toHaveTextContent('SSLTLS');
382     expect(ui.overview_from_address.get()).toHaveTextContent('admin@localhost.com');
383     expect(ui.overview_from_name.get()).toHaveTextContent('fromName');
384     expect(ui.overview_subject_prefix.get()).toHaveTextContent('prefix');
385     expect(ui.overview_username.get()).toHaveTextContent('username');
386   });
387
388   it('renders the overview after loading configuration', async () => {
389     systemHandler.addEmailConfiguration(
390       mockEmailConfiguration(AuthMethod.OAuth, { id: 'email-2' }),
391     );
392
393     renderEmailNotifications();
394
395     expect(await ui.overviewHeading.find()).toBeInTheDocument();
396     expect(ui.overview_auth_mode.get()).toHaveTextContent(AuthMethod.OAuth);
397     expect(ui.overview_oauth_auth_host.get()).toHaveTextContent('oauth_auth_host');
398     expect(ui.overview_oauth_client_id.get()).toHaveTextContent(
399       'email_notification.overview.private',
400     );
401     expect(ui.overview_oauth_client_secret.get()).toHaveTextContent(
402       'email_notification.overview.private',
403     );
404     expect(ui.overview_oauth_tenant.get()).toHaveTextContent('oauth_tenant');
405     expect(ui.overview_host.get()).toHaveTextContent('host');
406     expect(ui.overview_port.get()).toHaveTextContent('port');
407     expect(ui.overview_security_protocol.get()).toHaveTextContent('SSLTLS');
408     expect(ui.overview_from_address.get()).toHaveTextContent('from_address');
409     expect(ui.overview_from_name.get()).toHaveTextContent('from_name');
410     expect(ui.overview_subject_prefix.get()).toHaveTextContent('subject_prefix');
411   });
412
413   it('can edit the configuration', async () => {
414     systemHandler.addEmailConfiguration(
415       mockEmailConfiguration(AuthMethod.OAuth, { id: 'email-1' }),
416     );
417     jest.spyOn(api, 'patchEmailConfiguration');
418     const user = userEvent.setup();
419     renderEmailNotifications();
420
421     expect(await ui.overviewHeading.find()).toBeInTheDocument();
422     await user.click(ui.edit.get());
423
424     expect(await ui.editSubheading1.find()).toBeInTheDocument();
425     await user.click(ui.selectorOAuthAuth.get());
426
427     expect(ui.save.get()).toBeDisabled();
428
429     await user.type(ui.oauth_auth_host.get(), '-updated');
430     await user.click(ui.oauth_client_id_edit.get());
431     await user.type(ui.oauth_client_id.get(), 'updated_id');
432     await user.type(ui.oauth_client_secret.get(), 'updated_secret');
433     await user.type(ui.oauth_tenant.get(), '-updated');
434     await user.type(ui.host.get(), '-updated');
435     await user.type(ui.port.get(), '5678');
436     await user.click(ui.securityProtocol.get());
437     await user.click(screen.getByText('STARTTLS'));
438     await user.clear(ui.fromAddress.get());
439     await user.type(ui.fromAddress.get(), 'updated@email.com');
440     await user.type(ui.fromName.get(), '-updated');
441     await user.type(ui.subjectPrefix.get(), '-updated');
442     await user.type(ui.username.get(), '-updated');
443
444     expect(await ui.save.find()).toBeEnabled();
445     await user.click(ui.save.get());
446
447     expect(api.patchEmailConfiguration).toHaveBeenCalledTimes(1);
448     expect(api.patchEmailConfiguration).toHaveBeenCalledWith('email-1', {
449       authMethod: 'OAUTH',
450       oauthAuthenticationHost: 'oauth_auth_host-updated',
451       oauthClientId: 'updated_id',
452       oauthClientSecret: 'updated_secret',
453       oauthTenant: 'oauth_tenant-updated',
454       fromAddress: 'updated@email.com',
455       fromName: 'from_name-updated',
456       host: 'host-updated',
457       id: 'email-1',
458       isOauthClientIdSet: true,
459       isOauthClientSecretSet: true,
460       port: '5678',
461       securityProtocol: 'STARTTLS',
462       subjectPrefix: 'subject_prefix-updated',
463       username: 'username-updated',
464     });
465
466     expect(addGlobalSuccessMessage).toHaveBeenCalledWith(
467       'email_notification.form.save_configuration.update_success',
468     );
469
470     expect(await ui.overviewHeading.find()).toBeInTheDocument();
471
472     expect(ui.overview_auth_mode.get()).toHaveTextContent(AuthMethod.OAuth);
473     expect(ui.overview_oauth_auth_host.get()).toHaveTextContent('oauth_auth_host');
474     expect(ui.overview_oauth_client_id.get()).toHaveTextContent(
475       'email_notification.overview.private',
476     );
477     expect(ui.overview_oauth_client_secret.get()).toHaveTextContent(
478       'email_notification.overview.private',
479     );
480     expect(ui.overview_oauth_tenant.get()).toHaveTextContent('oauth_tenant');
481     expect(ui.overview_host.get()).toHaveTextContent('host');
482     expect(ui.overview_port.get()).toHaveTextContent('5678');
483     expect(ui.overview_security_protocol.get()).toHaveTextContent('STARTTLS');
484     expect(ui.overview_from_address.get()).toHaveTextContent('updated@email.com');
485     expect(ui.overview_from_name.get()).toHaveTextContent('from_name-updated');
486     expect(ui.overview_subject_prefix.get()).toHaveTextContent('subject_prefix-updated');
487     expect(ui.overview_username.get()).toHaveTextContent('username-updated');
488   });
489 });
490
491 describe('EmailNotification send test email', () => {
492   it('should render the EmailTestModal', async () => {
493     const user = userEvent.setup();
494     systemHandler.addEmailConfiguration(
495       mockEmailConfiguration(AuthMethod.Basic, { id: 'email-1' }),
496     );
497
498     renderEmailNotifications();
499     expect(await ui.overviewHeading.find()).toBeInTheDocument();
500
501     await user.click(ui.test_email.get());
502
503     expect(ui.test_email_title.get()).toBeVisible();
504     expect(ui.test_email_to_address.get()).toBeVisible();
505     expect(ui.test_email_to_address.get()).toHaveValue('');
506     expect(ui.test_email_subject.get()).toBeVisible();
507     expect(ui.test_email_subject.get()).toHaveValue('email_notification.test.subject');
508     expect(ui.test_email_message.get()).toBeVisible();
509     expect(ui.test_email_message.get()).toHaveValue('email_notification.test.message_text');
510   });
511
512   it('should be possible to send a test email', async () => {
513     jest.spyOn(settingsApi, 'sendTestEmail');
514     const user = userEvent.setup();
515     systemHandler.addEmailConfiguration(
516       mockEmailConfiguration(AuthMethod.Basic, { id: 'email-1' }),
517     );
518
519     renderEmailNotifications();
520     expect(await ui.overviewHeading.find()).toBeInTheDocument();
521
522     await user.click(ui.test_email.get());
523
524     expect(ui.test_email_submit.get()).toBeDisabled();
525     await user.type(ui.test_email_to_address.get(), 'test@test.com');
526     expect(ui.test_email_submit.get()).toBeEnabled();
527
528     await user.clear(ui.test_email_subject.get());
529     await user.type(ui.test_email_subject.get(), 'Test subject');
530     await user.clear(ui.test_email_message.get());
531     await user.type(ui.test_email_message.get(), 'This is a test message');
532
533     await user.click(ui.test_email_submit.get());
534     expect(settingsApi.sendTestEmail).toHaveBeenCalledTimes(1);
535     expect(settingsApi.sendTestEmail).toHaveBeenCalledWith(
536       'test@test.com',
537       'Test subject',
538       'This is a test message',
539     );
540   });
541 });
542
543 function renderEmailNotifications() {
544   return renderComponent(
545     <CurrentUserContext.Provider
546       value={{
547         currentUser: mockCurrentUser({
548           isLoggedIn: true,
549           permissions: { global: [Permissions.Admin] },
550         }),
551         updateCurrentUserHomepage: () => {},
552         updateDismissedNotices: () => {},
553       }}
554     >
555       <EmailNotification />
556     </CurrentUserContext.Provider>,
557   );
558 }