3 * Copyright (C) 2009-2023 SonarSource SA
4 * mailto:info AT sonarsource DOT com
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.
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.
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.
20 import userEvent from '@testing-library/user-event';
21 import React from 'react';
22 import selectEvent from 'react-select-event';
23 import { byRole, byText } from 'testing-library-selector';
24 import AlmSettingsServiceMock from '../../../../../api/mocks/AlmSettingsServiceMock';
25 import CurrentUserContextProvider from '../../../../../app/components/current-user/CurrentUserContextProvider';
26 import { mockComponent } from '../../../../../helpers/mocks/component';
27 import { mockCurrentUser } from '../../../../../helpers/testMocks';
28 import { renderComponent } from '../../../../../helpers/testReactTestingUtils';
31 ProjectAlmBindingConfigurationErrorScope,
32 } from '../../../../../types/alm-settings';
33 import { Component } from '../../../../../types/types';
34 import { CurrentUser } from '../../../../../types/users';
35 import PRDecorationBinding from '../PRDecorationBinding';
37 jest.mock('../../../../../api/alm-settings');
39 let almSettings: AlmSettingsServiceMock;
42 almSettings = new AlmSettingsServiceMock();
50 [AlmKeys.GitLab]: { 'gitlab.repository': 'Repository', monorepo: false },
52 'github.repository': 'Repository',
53 'github.summary_comment_setting': false,
57 'azure.repository': 'Repository',
58 'azure.project': 'Project',
61 [AlmKeys.BitbucketCloud]: { 'bitbucketcloud.repository': 'Repository', monorepo: false },
62 [AlmKeys.BitbucketServer]: {
63 'bitbucket.repository': 'Repository',
64 'bitbucket.slug': 'Slug',
83 key: 'conf-bitbucketcloud-1',
84 alm: AlmKeys.BitbucketCloud,
87 key: 'conf-bitbucketserver-1',
88 alm: AlmKeys.BitbucketServer,
91 'should get, set, delete and validate binding for $alm',
92 async ({ key, alm }: { key: string; alm: AlmKeys }) => {
93 const { ui, user } = getPageObjects();
94 almSettings.setProjectBindingConfigurationErrors({
95 scope: ProjectAlmBindingConfigurationErrorScope.Global,
96 errors: [{ msg: 'cute error' }],
98 const { rerender } = renderPRDecorationBinding();
99 expect(await ui.mainTitle.find()).toBeInTheDocument();
102 await selectEvent.select(ui.input('name', 'combobox').get(), (content) =>
103 content.includes(key)
106 const list = inputsList[alm];
107 for (const [inputId, value] of Object.entries(list)) {
108 // eslint-disable-next-line no-await-in-loop
109 await ui.setInput(inputId, value);
111 // Save form and check for errors
112 await user.click(ui.saveButton.get());
113 expect(ui.validationMsg('cute error').get()).toBeInTheDocument();
115 // Check validation with errors
116 await user.click(ui.validateButton.get());
117 expect(ui.validationMsg('cute error').get()).toBeInTheDocument();
119 // Save form and check for errors
120 almSettings.setProjectBindingConfigurationErrors(undefined);
122 Object.keys(list).find((key) => key.endsWith('.repository')) as string,
125 await user.click(ui.saveButton.get());
127 await ui.validationMsg('settings.pr_decoration.binding.check_configuration.success').find()
128 ).toBeInTheDocument();
130 await user.click(ui.validateButton.get());
132 ui.validationMsg('settings.pr_decoration.binding.check_configuration.success').get()
133 ).toBeInTheDocument();
135 // Rerender and verify that validation is done for binding
137 <MockedPRDecorationBinding component={mockComponent()} currentUser={mockCurrentUser()} />
140 await ui.validationMsg('settings.pr_decoration.binding.check_configuration.success').find()
141 ).toBeInTheDocument();
142 expect(ui.saveButton.query()).not.toBeInTheDocument();
145 await user.click(ui.resetButton.get());
146 expect(ui.input('', 'textbox').query()).not.toBeInTheDocument();
147 expect(ui.input('', 'switch').query()).not.toBeInTheDocument();
151 function getPageObjects() {
152 const user = userEvent.setup();
154 async function setInput(inputId: string, value: string | boolean) {
155 if (typeof value === 'boolean') {
157 await user.click(ui.input(inputId, 'switch').get());
160 const input = ui.input(inputId, 'textbox').get();
161 await user.clear(input);
162 await user.type(input, value);
167 mainTitle: byRole('heading', { name: 'settings.pr_decoration.binding.title' }),
168 input: (id: string, role: 'combobox' | 'switch' | 'textbox') =>
169 byRole(role, { name: new RegExp(`settings.pr_decoration.binding.form.${id}`) }),
170 saveButton: byRole('button', { name: 'save' }),
171 resetButton: byRole('button', { name: 'reset_verb' }),
172 validateButton: byRole('button', {
173 name: 'settings.pr_decoration.binding.check_configuration',
175 validationMsg: (text: string) => byText(text),
185 function MockedPRDecorationBinding({
189 component: Component;
190 currentUser: CurrentUser;
193 <CurrentUserContextProvider currentUser={currentUser}>
194 <PRDecorationBinding component={component} />
195 </CurrentUserContextProvider>
199 function renderPRDecorationBinding(
200 component: Component = mockComponent(),
201 currentUser: CurrentUser = mockCurrentUser()
203 return renderComponent(
204 <MockedPRDecorationBinding component={component} currentUser={currentUser} />