]> source.dussan.org Git - sonarqube.git/blob
f0671e05cfb26518913b87aaf00b699d7d86d951
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 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 React from 'react';
23 import AuthenticationServiceMock from '../../../../../api/mocks/AuthenticationServiceMock';
24 import { AvailableFeaturesContext } from '../../../../../app/components/available-features/AvailableFeaturesContext';
25 import { mockDefinition } from '../../../../../helpers/mocks/settings';
26 import { renderComponent } from '../../../../../helpers/testReactTestingUtils';
27 import { Feature } from '../../../../../types/features';
28 import { ExtendedSettingDefinition, SettingType } from '../../../../../types/settings';
29 import Authentication from '../Authentication';
30
31 jest.mock('../../../../../api/settings');
32
33 const mockDefinitionFields = [
34   mockDefinition({
35     key: 'test1',
36     category: 'authentication',
37     subCategory: 'saml',
38     name: 'test1',
39     description: 'desc1',
40   }),
41   mockDefinition({
42     key: 'test2',
43     category: 'authentication',
44     subCategory: 'saml',
45     name: 'test2',
46     description: 'desc2',
47   }),
48   mockDefinition({
49     key: 'sonar.auth.saml.certificate.secured',
50     category: 'authentication',
51     subCategory: 'saml',
52     name: 'Certificate',
53     description: 'Secured certificate',
54     type: SettingType.PASSWORD,
55   }),
56   mockDefinition({
57     key: 'sonar.auth.saml.enabled',
58     category: 'authentication',
59     subCategory: 'saml',
60     name: 'Enabled',
61     description: 'To enable the flag',
62     type: SettingType.BOOLEAN,
63   }),
64 ];
65
66 let handler: AuthenticationServiceMock;
67
68 beforeEach(() => {
69   handler = new AuthenticationServiceMock();
70 });
71
72 afterEach(() => handler.resetValues());
73
74 it('should render tabs and allow navigation', async () => {
75   const user = userEvent.setup();
76   renderAuthentication([]);
77
78   expect(screen.getAllByRole('tab')).toHaveLength(4);
79
80   expect(screen.getByRole('tab', { name: 'SAML' })).toHaveAttribute('aria-selected', 'true');
81
82   await user.click(screen.getByRole('tab', { name: 'github GitHub' }));
83
84   expect(screen.getByRole('tab', { name: 'SAML' })).toHaveAttribute('aria-selected', 'false');
85   expect(screen.getByRole('tab', { name: 'github GitHub' })).toHaveAttribute(
86     'aria-selected',
87     'true'
88   );
89 });
90
91 describe('SAML tab', () => {
92   it('should allow user to test the configuration', async () => {
93     const user = userEvent.setup();
94
95     const definitions = [
96       mockDefinition({
97         key: 'sonar.auth.saml.certificate.secured',
98         category: 'authentication',
99         subCategory: 'saml',
100         name: 'Certificate',
101         description: 'Secured certificate',
102         type: SettingType.PASSWORD,
103       }),
104       mockDefinition({
105         key: 'sonar.auth.saml.enabled',
106         category: 'authentication',
107         subCategory: 'saml',
108         name: 'Enabled',
109         description: 'To enable the flag',
110         type: SettingType.BOOLEAN,
111       }),
112     ];
113
114     renderAuthentication(definitions);
115
116     await user.click(await screen.findByText('settings.almintegration.form.secret.update_field'));
117
118     await user.click(screen.getByRole('textbox', { name: 'Certificate' }));
119     await user.keyboard('new certificate');
120
121     expect(screen.getByText('settings.authentication.saml.form.test')).toHaveClass('disabled');
122
123     await user.click(
124       screen.getByRole('button', { name: 'settings.authentication.saml.form.save' })
125     );
126
127     expect(screen.getByText('settings.authentication.saml.form.test')).not.toHaveClass('disabled');
128   });
129
130   it('should allow user to edit fields and save configuration', async () => {
131     const user = userEvent.setup();
132     const definitions = mockDefinitionFields;
133     renderAuthentication(definitions);
134
135     expect(screen.getByRole('button', { name: 'off' })).toHaveAttribute('aria-disabled', 'true');
136     // update fields
137     await user.click(screen.getByRole('textbox', { name: 'test1' }));
138     await user.keyboard('new test1');
139
140     await user.click(screen.getByRole('textbox', { name: 'test2' }));
141     await user.keyboard('new test2');
142     // check if enable is allowed after updating
143     expect(screen.getByRole('button', { name: 'off' })).toHaveAttribute('aria-disabled', 'false');
144
145     // reset value
146     await user.click(screen.getByRole('textbox', { name: 'test2' }));
147     await user.keyboard('{Control>}a{/Control}{Backspace}');
148     await user.click(
149       screen.getByRole('button', { name: 'settings.authentication.saml.form.save' })
150     );
151     expect(screen.getByRole('button', { name: 'off' })).toHaveAttribute('aria-disabled', 'true');
152
153     await user.click(screen.getByRole('textbox', { name: 'test2' }));
154     await user.keyboard('new test2');
155     expect(screen.getByRole('button', { name: 'off' })).toHaveAttribute('aria-disabled', 'false');
156
157     expect(
158       screen.getByRole('button', { name: 'settings.almintegration.form.secret.update_field' })
159     ).toBeInTheDocument();
160     await user.click(
161       screen.getByRole('button', { name: 'settings.almintegration.form.secret.update_field' })
162     );
163     // check for secure fields
164     expect(screen.getByRole('textbox', { name: 'Certificate' })).toBeInTheDocument();
165     await user.click(screen.getByRole('textbox', { name: 'Certificate' }));
166     await user.keyboard('new certificate');
167     // enable the configuration
168     await user.click(screen.getByRole('button', { name: 'off' }));
169     expect(screen.getByRole('button', { name: 'on' })).toBeInTheDocument();
170
171     await user.click(
172       screen.getByRole('button', { name: 'settings.authentication.saml.form.save' })
173     );
174     expect(screen.getByText('settings.authentication.saml.form.save_success')).toBeInTheDocument();
175     // check after switching tab that the flag is still enabled
176     await user.click(screen.getByRole('tab', { name: 'github GitHub' }));
177     await user.click(screen.getByRole('tab', { name: 'SAML' }));
178
179     expect(screen.getByRole('button', { name: 'on' })).toBeInTheDocument();
180   });
181
182   it('should handle and show errors to the user', async () => {
183     const user = userEvent.setup();
184     const definitions = mockDefinitionFields;
185     renderAuthentication(definitions);
186
187     await user.click(screen.getByRole('textbox', { name: 'test1' }));
188     await user.keyboard('value');
189     await user.click(screen.getByRole('textbox', { name: 'test2' }));
190     await user.keyboard('{Control>}a{/Control}error');
191     await user.click(
192       screen.getByRole('button', { name: 'settings.authentication.saml.form.save' })
193     );
194     expect(screen.getByText('settings.authentication.saml.form.save_partial')).toBeInTheDocument();
195   });
196
197   it('should not display the login message feature info box', () => {
198     renderAuthentication([]);
199
200     expect(
201       screen.queryByText('settings.authentication.custom_message_information')
202     ).not.toBeInTheDocument();
203   });
204
205   it('should display the login message feature info box', () => {
206     renderAuthentication([], [Feature.LoginMessage]);
207
208     expect(
209       screen.getByText('settings.authentication.custom_message_information')
210     ).toBeInTheDocument();
211   });
212 });
213
214 function renderAuthentication(definitions: ExtendedSettingDefinition[], features: Feature[] = []) {
215   renderComponent(
216     <AvailableFeaturesContext.Provider value={features}>
217       <Authentication definitions={definitions} />
218     </AvailableFeaturesContext.Provider>
219   );
220 }