diff options
author | Kevin Silva <kevin.silva@sonarsource.com> | 2022-12-07 14:51:33 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-12-13 20:03:18 +0000 |
commit | cae72b1b49abfc394f56e0b5b8df860b669c6083 (patch) | |
tree | a59f449db1d0822f1e798929d3354b541e0ad658 /server/sonar-web/src/main | |
parent | 08db4d01505a2cc63664bbc3abaa38af7518e2e8 (diff) | |
download | sonarqube-cae72b1b49abfc394f56e0b5b8df860b669c6083.tar.gz sonarqube-cae72b1b49abfc394f56e0b5b8df860b669c6083.zip |
SONAR-17740 Add RTL test for 'project/create' bitbucket and gitlab pages and remove the enzyme tests
Diffstat (limited to 'server/sonar-web/src/main')
50 files changed, 1001 insertions, 6833 deletions
diff --git a/server/sonar-web/src/main/js/api/mocks/AlmIntegrationsServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/AlmIntegrationsServiceMock.ts index 3ab27ae48af..1a3f06b3f5e 100644 --- a/server/sonar-web/src/main/js/api/mocks/AlmIntegrationsServiceMock.ts +++ b/server/sonar-web/src/main/js/api/mocks/AlmIntegrationsServiceMock.ts @@ -17,31 +17,53 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { cloneDeep } from 'lodash'; +import { cloneDeep, uniqueId } from 'lodash'; import { mockAzureProject, mockAzureRepository, + mockBitbucketCloudRepository, + mockBitbucketProject, + mockBitbucketRepository, mockGitlabProject, } from '../../helpers/mocks/alm-integrations'; -import { AzureProject, AzureRepository, GitlabProject } from '../../types/alm-integration'; +import { + AzureProject, + AzureRepository, + BitbucketCloudRepository, + BitbucketProject, + BitbucketRepository, + GitlabProject, +} from '../../types/alm-integration'; +import { Visibility } from '../../types/component'; import { checkPersonalAccessTokenIsValid, getAzureProjects, getAzureRepositories, + getBitbucketServerProjects, + getBitbucketServerRepositories, getGithubClientId, getGithubOrganizations, getGitlabProjects, importAzureRepository, + importBitbucketCloudRepository, + importBitbucketServerProject, + importGitlabProject, searchAzureRepositories, + searchForBitbucketCloudRepositories, + searchForBitbucketServerRepositories, setAlmPersonalAccessToken, } from '../alm-integrations'; -import { ProjectBase } from '../components'; export default class AlmIntegrationsServiceMock { almInstancePATMap: { [key: string]: boolean } = {}; gitlabProjects: GitlabProject[]; azureProjects: AzureProject[]; azureRepositories: AzureRepository[]; + gitlabPagination; + bitbucketCloudRepositories: BitbucketCloudRepository[]; + bitbucketIsLastPage: boolean; + bitbucketRepositories: BitbucketRepository[]; + bitbucketProjects: BitbucketProject[]; defaultAlmInstancePATMap: { [key: string]: boolean } = { 'conf-final-1': false, 'conf-final-2': true, @@ -49,7 +71,10 @@ export default class AlmIntegrationsServiceMock { 'conf-github-2': true, 'conf-azure-1': false, 'conf-azure-2': true, - 'config-reject': false, + 'conf-bitbucketcloud-1': false, + 'conf-bitbucketcloud-2': true, + 'conf-bitbucketserver-1': false, + 'conf-bitbucketserver-2': true, }; defaultGitlabProjects: GitlabProject[] = [ @@ -63,11 +88,51 @@ export default class AlmIntegrationsServiceMock { mockGitlabProject({ name: 'Gitlab project 3', id: '3' }), ]; + defaultGitlabPagination = { + pageIndex: 1, + pageSize: 30, + total: this.defaultGitlabProjects.length, + }; + defaultAzureProjects: AzureProject[] = [ mockAzureProject({ name: 'Azure project', description: 'Description project 1' }), mockAzureProject({ name: 'Azure project 2', description: 'Description project 2' }), ]; + defaultBitbucketCloudRepositories: BitbucketCloudRepository[] = [ + mockBitbucketCloudRepository({ + uuid: 1000, + name: 'BitbucketCloud Repo 1', + slug: 'bitbucketcloud_repo_1', + sqProjectKey: 'key', + }), + mockBitbucketCloudRepository({ + uuid: 10001, + name: 'BitbucketCloud Repo 2', + slug: 'bitbucketcloud_repo_2', + }), + ]; + + defaultBitbucketRepositories: BitbucketRepository[] = [ + mockBitbucketRepository({ + name: 'Bitbucket Repo 1', + slug: 'bitbucket_repo_1', + projectKey: 'bitbucket_project_1', + sqProjectKey: 'key', + }), + mockBitbucketRepository({ + id: 2, + name: 'Bitbucket Repo 2', + slug: 'bitbucket_repo_2', + projectKey: 'bitbucket_project_1', + }), + ]; + + defaultBitbucketProjects: BitbucketProject[] = [ + mockBitbucketProject({ name: 'Bitbucket Project 1', key: 'bitbucket_project_1' }), + mockBitbucketProject({ name: 'Bitbucket Project 2', key: 'bitbucket_project_2' }), + ]; + defaultAzureRepositories: AzureRepository[] = [ mockAzureRepository({ sqProjectKey: 'random' }), mockAzureRepository({ name: 'Azure repo 2' }), @@ -89,20 +154,38 @@ export default class AlmIntegrationsServiceMock { constructor() { this.almInstancePATMap = cloneDeep(this.defaultAlmInstancePATMap); - this.gitlabProjects = cloneDeep(this.defaultGitlabProjects); this.azureProjects = cloneDeep(this.defaultAzureProjects); this.azureRepositories = cloneDeep(this.defaultAzureRepositories); - (checkPersonalAccessTokenIsValid as jest.Mock).mockImplementation( - this.checkPersonalAccessTokenIsValid - ); - (setAlmPersonalAccessToken as jest.Mock).mockImplementation(this.setAlmPersonalAccessToken); - (getGitlabProjects as jest.Mock).mockImplementation(this.getGitlabProjects); - (getGithubClientId as jest.Mock).mockImplementation(this.getGithubClientId); - (getGithubOrganizations as jest.Mock).mockImplementation(this.getGithubOrganizations); - (getAzureProjects as jest.Mock).mockImplementation(this.getAzureProjects); - (getAzureRepositories as jest.Mock).mockImplementation(this.getAzureRepositories); - (searchAzureRepositories as jest.Mock).mockImplementation(this.searchAzureRepositories); - (importAzureRepository as jest.Mock).mockImplementation(this.importAzureRepository); + this.bitbucketCloudRepositories = cloneDeep(this.defaultBitbucketCloudRepositories); + this.gitlabProjects = cloneDeep(this.defaultGitlabProjects); + this.gitlabPagination = cloneDeep(this.defaultGitlabPagination); + this.bitbucketRepositories = cloneDeep(this.defaultBitbucketRepositories); + this.bitbucketProjects = cloneDeep(this.defaultBitbucketProjects); + this.bitbucketIsLastPage = true; + jest + .mocked(checkPersonalAccessTokenIsValid) + .mockImplementation(this.checkPersonalAccessTokenIsValid); + jest.mocked(setAlmPersonalAccessToken).mockImplementation(this.setAlmPersonalAccessToken); + jest.mocked(getGitlabProjects).mockImplementation(this.getGitlabProjects); + jest.mocked(importGitlabProject).mockImplementation(this.importProject); + jest.mocked(importBitbucketCloudRepository).mockImplementation(this.importProject); + jest.mocked(getGithubClientId).mockImplementation(this.getGithubClientId); + jest.mocked(getGithubOrganizations).mockImplementation(this.getGithubOrganizations); + jest.mocked(getAzureProjects).mockImplementation(this.getAzureProjects); + jest.mocked(getAzureRepositories).mockImplementation(this.getAzureRepositories); + jest.mocked(searchAzureRepositories).mockImplementation(this.searchAzureRepositories); + jest.mocked(importAzureRepository).mockImplementation(this.importAzureRepository); + jest + .mocked(searchForBitbucketCloudRepositories) + .mockImplementation(this.searchForBitbucketCloudRepositories); + jest.mocked(getBitbucketServerProjects).mockImplementation(this.getBitbucketServerProjects); + jest + .mocked(getBitbucketServerRepositories) + .mockImplementation(this.getBitbucketServerRepositories); + jest.mocked(importBitbucketServerProject).mockImplementation(this.importBitbucketServerProject); + jest + .mocked(searchForBitbucketServerRepositories) + .mockImplementation(this.searchForBitbucketServerRepositories); } checkPersonalAccessTokenIsValid = (conf: string) => { @@ -114,17 +197,17 @@ export default class AlmIntegrationsServiceMock { return Promise.resolve(); }; - getAzureProjects = (): Promise<{ projects: AzureProject[] }> => { + getAzureProjects = () => { return Promise.resolve({ projects: this.azureProjects }); }; - getAzureRepositories = (): Promise<{ repositories: AzureRepository[] }> => { + getAzureRepositories = () => { return Promise.resolve({ repositories: this.azureRepositories, }); }; - searchAzureRepositories = (): Promise<{ repositories: AzureRepository[] }> => { + searchAzureRepositories = () => { return Promise.resolve({ repositories: this.azureRepositories, }); @@ -134,32 +217,66 @@ export default class AlmIntegrationsServiceMock { this.azureRepositories = azureRepositories; }; - importAzureRepository = (): Promise<{ project: ProjectBase }> => { + importAzureRepository = () => { return Promise.resolve({ project: { key: 'key', name: 'name', qualifier: 'qualifier', - visibility: 'private', + visibility: Visibility.Private, }, }); }; - setAzureProjects = (azureProjects: AzureProject[]) => { - this.azureProjects = azureProjects; + searchForBitbucketCloudRepositories = () => { + return Promise.resolve({ + isLastPage: this.bitbucketIsLastPage, + repositories: this.bitbucketCloudRepositories, + }); }; + setBitbucketCloudRepositories(bitbucketCloudRepositories: BitbucketCloudRepository[]) { + this.bitbucketCloudRepositories = bitbucketCloudRepositories; + } + getGitlabProjects = () => { return Promise.resolve({ projects: this.gitlabProjects, - projectsPaging: { - pageIndex: 1, - pageSize: 30, - total: this.gitlabProjects.length, + projectsPaging: this.gitlabPagination, + }); + }; + + importProject = () => { + return Promise.resolve({ + project: { + key: 'key', + name: 'name', + qualifier: 'qualifier', + visibility: Visibility.Private, }, }); }; + createRandomGitlabProjectsWithLoadMore(quantity: number, total: number) { + const generatedProjects = Array.from(Array(quantity).keys()).map((index) => { + return mockGitlabProject({ name: `Gitlab project ${index}`, id: uniqueId() }); + }); + this.gitlabProjects = generatedProjects; + this.gitlabPagination = { ...this.defaultGitlabPagination, total }; + } + + createRandomBitbucketCloudProjectsWithLoadMore(quantity: number, total: number) { + const generatedRepositories = Array.from(Array(quantity).keys()).map((index) => { + return mockBitbucketCloudRepository({ + name: `Gitlab project ${index}`, + uuid: Math.floor(Math.random() * 100000), + }); + }); + + this.bitbucketCloudRepositories = generatedRepositories; + this.bitbucketIsLastPage = quantity >= total; + } + setGitlabProjects(gitlabProjects: GitlabProject[]) { this.gitlabProjects = gitlabProjects; } @@ -172,9 +289,47 @@ export default class AlmIntegrationsServiceMock { return Promise.resolve(this.defaultOrganizations); }; + getBitbucketServerProjects = () => { + return Promise.resolve({ projects: this.bitbucketProjects }); + }; + + getBitbucketServerRepositories = () => { + return Promise.resolve({ + isLastPage: this.bitbucketIsLastPage, + repositories: this.bitbucketRepositories, + }); + }; + + setBitbucketServerProjects = (bitbucketProjects: BitbucketProject[]) => { + this.bitbucketProjects = bitbucketProjects; + }; + + importBitbucketServerProject = () => { + return Promise.resolve({ + project: { + key: 'key', + name: 'name', + qualifier: 'qualifier', + visibility: Visibility.Private, + }, + }); + }; + + searchForBitbucketServerRepositories = () => { + return Promise.resolve({ + isLastPage: this.bitbucketIsLastPage, + repositories: this.bitbucketRepositories, + }); + }; + reset = () => { this.almInstancePATMap = cloneDeep(this.defaultAlmInstancePATMap); this.gitlabProjects = cloneDeep(this.defaultGitlabProjects); this.azureRepositories = cloneDeep(this.defaultAzureRepositories); + this.gitlabPagination = cloneDeep(this.defaultGitlabPagination); + this.bitbucketCloudRepositories = cloneDeep(this.defaultBitbucketCloudRepositories); + this.bitbucketRepositories = cloneDeep(this.defaultBitbucketRepositories); + this.bitbucketProjects = cloneDeep(this.defaultBitbucketProjects); + this.bitbucketIsLastPage = true; }; } diff --git a/server/sonar-web/src/main/js/api/mocks/AlmSettingsServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/AlmSettingsServiceMock.ts index c5e32cb41f0..ea2f1f01f8b 100644 --- a/server/sonar-web/src/main/js/api/mocks/AlmSettingsServiceMock.ts +++ b/server/sonar-web/src/main/js/api/mocks/AlmSettingsServiceMock.ts @@ -31,11 +31,31 @@ export default class AlmSettingsServiceMock { mockAlmSettingsInstance({ key: 'conf-github-2', alm: AlmKeys.GitHub, url: 'url' }), mockAlmSettingsInstance({ key: 'conf-azure-1', alm: AlmKeys.Azure, url: 'url' }), mockAlmSettingsInstance({ key: 'conf-azure-2', alm: AlmKeys.Azure, url: 'url' }), + mockAlmSettingsInstance({ + key: 'conf-bitbucketcloud-1', + alm: AlmKeys.BitbucketCloud, + url: 'url', + }), + mockAlmSettingsInstance({ + key: 'conf-bitbucketcloud-2', + alm: AlmKeys.BitbucketCloud, + url: 'url', + }), + mockAlmSettingsInstance({ + key: 'conf-bitbucketserver-1', + alm: AlmKeys.BitbucketServer, + url: 'url', + }), + mockAlmSettingsInstance({ + key: 'conf-bitbucketserver-2', + alm: AlmKeys.BitbucketServer, + url: 'url', + }), ]; constructor() { this.almSettings = cloneDeep(this.defaultSetting); - (getAlmSettings as jest.Mock).mockImplementation(this.getAlmSettingsHandler); + jest.mocked(getAlmSettings).mockImplementation(this.getAlmSettingsHandler); } getAlmSettingsHandler = () => { diff --git a/server/sonar-web/src/main/js/apps/create/project/AzurePersonalAccessTokenForm.tsx b/server/sonar-web/src/main/js/apps/create/project/AzurePersonalAccessTokenForm.tsx index 1de8de0ac52..c38dd39c971 100644 --- a/server/sonar-web/src/main/js/apps/create/project/AzurePersonalAccessTokenForm.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/AzurePersonalAccessTokenForm.tsx @@ -95,7 +95,7 @@ export default function AzurePersonalAccessTokenForm(props: AzurePersonalAccessT > <ValidationInput error={errorMessage} - id="personal_access_token" + labelHtmlFor="personal_access_token" isInvalid={isInvalid} isValid={false} label={translate('onboarding.create_project.enter_pat')} diff --git a/server/sonar-web/src/main/js/apps/create/project/ManualProjectCreate.tsx b/server/sonar-web/src/main/js/apps/create/project/ManualProjectCreate.tsx index a731e0f7fbe..b41e6afcb32 100644 --- a/server/sonar-web/src/main/js/apps/create/project/ManualProjectCreate.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/ManualProjectCreate.tsx @@ -242,7 +242,7 @@ export default class ManualProjectCreate extends React.PureComponent<Props, Stat className="form-field" description={translate('onboarding.create_project.display_name.description')} error={projectNameError} - id="project-name" + labelHtmlFor="project-name" isInvalid={projectNameIsInvalid} isValid={projectNameIsValid} label={translate('onboarding.create_project.display_name')} @@ -287,7 +287,7 @@ export default class ManualProjectCreate extends React.PureComponent<Props, Stat /> } error={mainBranchNameError} - id="main-branch-name" + labelHtmlFor="main-branch-name" isInvalid={mainBranchNameIsInvalid} isValid={mainBranchNameIsValid} label={translate('onboarding.create_project.main_branch_name')} diff --git a/server/sonar-web/src/main/js/apps/create/project/PersonalAccessTokenForm.tsx b/server/sonar-web/src/main/js/apps/create/project/PersonalAccessTokenForm.tsx index d3b501776c0..14258e02b1c 100644 --- a/server/sonar-web/src/main/js/apps/create/project/PersonalAccessTokenForm.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/PersonalAccessTokenForm.tsx @@ -355,7 +355,7 @@ export default class PersonalAccessTokenForm extends React.PureComponent<Props, {alm === AlmKeys.BitbucketCloud && ( <ValidationInput error={undefined} - id="enter_username_validation" + labelHtmlFor="enter_username_validation" isInvalid={false} isValid={false} label={translate('onboarding.create_project.enter_username')} @@ -366,7 +366,7 @@ export default class PersonalAccessTokenForm extends React.PureComponent<Props, className={classNames('input-super-large', { 'is-invalid': isInvalid, })} - id="username" + id="enter_username_validation" minLength={1} name="username" value={username} @@ -378,7 +378,7 @@ export default class PersonalAccessTokenForm extends React.PureComponent<Props, <ValidationInput error={errorMessage} - id="personal_access_token_validation" + labelHtmlFor="personal_access_token_validation" isInvalid={false} isValid={false} label={translate(`onboarding.create_project.enter_pat${suffixTranslationKey}`)} @@ -399,7 +399,7 @@ export default class PersonalAccessTokenForm extends React.PureComponent<Props, <ValidationInput error={errorMessage} - id="personal_access_token_submit" + labelHtmlFor="personal_access_token_submit" isInvalid={isInvalid} isValid={false} label={null} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/Azure-it.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/Azure-it.tsx new file mode 100644 index 00000000000..259293d9cfa --- /dev/null +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/Azure-it.tsx @@ -0,0 +1,133 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { act, screen } from '@testing-library/react'; + +import userEvent from '@testing-library/user-event'; +import * as React from 'react'; +import selectEvent from 'react-select-event'; +import { byLabelText, byRole, byText } from 'testing-library-selector'; +import { searchAzureRepositories } from '../../../../api/alm-integrations'; +import AlmIntegrationsServiceMock from '../../../../api/mocks/AlmIntegrationsServiceMock'; +import AlmSettingsServiceMock from '../../../../api/mocks/AlmSettingsServiceMock'; +import { renderApp } from '../../../../helpers/testReactTestingUtils'; +import CreateProjectPage, { CreateProjectPageProps } from '../CreateProjectPage'; + +jest.mock('../../../../api/alm-integrations'); +jest.mock('../../../../api/alm-settings'); + +let almIntegrationHandler: AlmIntegrationsServiceMock; +let almSettingsHandler: AlmSettingsServiceMock; + +const ui = { + azureCreateProjectButton: byText('onboarding.create_project.select_method.azure'), + personalAccessTokenInput: byRole('textbox', { + name: /onboarding.create_project.enter_pat/, + }), + instanceSelector: byLabelText(/alm.configuration.selector.label/), +}; + +beforeAll(() => { + almIntegrationHandler = new AlmIntegrationsServiceMock(); + almSettingsHandler = new AlmSettingsServiceMock(); +}); + +beforeEach(() => { + jest.clearAllMocks(); + almIntegrationHandler.reset(); + almSettingsHandler.reset(); +}); + +it('should ask for PAT when it is not set yet and show the import project feature afterwards', async () => { + const user = userEvent.setup(); + renderCreateProject(); + expect(ui.azureCreateProjectButton.get()).toBeInTheDocument(); + + await user.click(ui.azureCreateProjectButton.get()); + + expect(screen.getByText('onboarding.create_project.azure.title')).toBeInTheDocument(); + expect(screen.getByText('alm.configuration.selector.label.alm.azure.long')).toBeInTheDocument(); + + expect(screen.getByText('onboarding.create_project.enter_pat')).toBeInTheDocument(); + expect(screen.getByText('onboarding.create_project.pat_form.title.azure')).toBeInTheDocument(); + expect( + screen.getByRole('button', { name: 'onboarding.create_project.pat_form.list_repositories' }) + ).toBeInTheDocument(); + + await user.click(ui.personalAccessTokenInput.get()); + await user.keyboard('secret'); + await user.click( + screen.getByRole('button', { name: 'onboarding.create_project.pat_form.list_repositories' }) + ); + + expect(screen.getByText('Azure project')).toBeInTheDocument(); + expect(screen.getByText('Azure project 2')).toBeInTheDocument(); + // eslint-disable-next-line jest-dom/prefer-in-document + expect(screen.getAllByText('onboarding.create_project.repository_imported')).toHaveLength(1); +}); + +it('should show import project feature when PAT is already set', async () => { + const user = userEvent.setup(); + renderCreateProject(); + + await act(async () => { + await user.click(ui.azureCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-azure-2/]); + }); + + expect(screen.getByText('Azure project 2')).toBeInTheDocument(); + const importButton = screen.getByText('onboarding.create_project.import_selected_repo'); + const radioButton = screen.getByRole('radio', { name: 'Azure repo 2' }); + + expect(radioButton).toBeInTheDocument(); + expect(importButton).toBeDisabled(); + await user.click(radioButton); + expect(importButton).toBeEnabled(); + await user.click(importButton); + + expect(await screen.findByText('/dashboard?id=key')).toBeInTheDocument(); +}); + +it('should show search filter when PAT is already set', async () => { + const user = userEvent.setup(); + renderCreateProject(); + + await act(async () => { + await user.click(ui.azureCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-azure-2/]); + }); + + // Should search with positive results + const inputSearch = screen.getByPlaceholderText( + 'onboarding.create_project.search_projects_repositories' + ); + await user.click(inputSearch); + await user.keyboard('s'); + + expect(searchAzureRepositories).toHaveBeenCalledWith('conf-azure-2', 's'); + + // Should search with empty results + almIntegrationHandler.setSearchAzureRepositories([]); + await user.keyboard('f'); + expect(screen.getByRole('alert')).toHaveTextContent('onboarding.create_project.azure.no_results'); +}); + +function renderCreateProject(props: Partial<CreateProjectPageProps> = {}) { + renderApp('project/create', <CreateProjectPage {...props} />); +} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/Bitbucket-it.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/Bitbucket-it.tsx new file mode 100644 index 00000000000..9c460d8f324 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/Bitbucket-it.tsx @@ -0,0 +1,162 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { act, screen, within } from '@testing-library/react'; + +import userEvent from '@testing-library/user-event'; +import * as React from 'react'; +import selectEvent from 'react-select-event'; +import { byLabelText, byRole, byText } from 'testing-library-selector'; +import { searchForBitbucketServerRepositories } from '../../../../api/alm-integrations'; +import AlmIntegrationsServiceMock from '../../../../api/mocks/AlmIntegrationsServiceMock'; +import AlmSettingsServiceMock from '../../../../api/mocks/AlmSettingsServiceMock'; +import { renderApp } from '../../../../helpers/testReactTestingUtils'; +import CreateProjectPage, { CreateProjectPageProps } from '../CreateProjectPage'; + +jest.mock('../../../../api/alm-integrations'); +jest.mock('../../../../api/alm-settings'); + +let almIntegrationHandler: AlmIntegrationsServiceMock; +let almSettingsHandler: AlmSettingsServiceMock; + +const ui = { + bitbucketServerCreateProjectButton: byText('onboarding.create_project.select_method.bitbucket'), + personalAccessTokenInput: byRole('textbox', { + name: /onboarding.create_project.enter_pat/, + }), + instanceSelector: byLabelText(/alm.configuration.selector.label/), +}; + +beforeAll(() => { + almIntegrationHandler = new AlmIntegrationsServiceMock(); + almSettingsHandler = new AlmSettingsServiceMock(); +}); + +beforeEach(() => { + jest.clearAllMocks(); + almIntegrationHandler.reset(); + almSettingsHandler.reset(); +}); + +it('should ask for PAT when it is not set yet and show the import project feature afterwards', async () => { + const user = userEvent.setup(); + renderCreateProject(); + expect(ui.bitbucketServerCreateProjectButton.get()).toBeInTheDocument(); + + await user.click(ui.bitbucketServerCreateProjectButton.get()); + expect(screen.getByText('onboarding.create_project.from_bbs')).toBeInTheDocument(); + expect(ui.instanceSelector.get()).toBeInTheDocument(); + + expect( + screen.getByText('onboarding.create_project.pat_form.title.bitbucket') + ).toBeInTheDocument(); + + expect(screen.getByRole('button', { name: 'save' })).toBeDisabled(); + + await user.click( + screen.getByRole('textbox', { + name: /onboarding.create_project.enter_pat/, + }) + ); + + await user.keyboard('password'); + + expect(screen.getByRole('button', { name: 'save' })).toBeEnabled(); + await user.click(screen.getByRole('button', { name: 'save' })); + + expect(screen.getByText('Bitbucket Project 1')).toBeInTheDocument(); + expect(screen.getByText('Bitbucket Project 2')).toBeInTheDocument(); +}); + +it('should show import project feature when PAT is already set', async () => { + const user = userEvent.setup(); + renderCreateProject(); + await act(async () => { + await user.click(ui.bitbucketServerCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-bitbucketserver-2/]); + }); + + expect(screen.getByText('Bitbucket Project 1')).toBeInTheDocument(); + + await user.click(screen.getByRole('button', { name: 'expand_all' })); + + expect(screen.getByRole('button', { name: 'collapse_all' })).toBeInTheDocument(); + + const projectItem = screen.getByRole('region', { name: /Bitbucket Project 1/ }); + + expect( + within(projectItem).getByText('onboarding.create_project.repository_imported') + ).toBeInTheDocument(); + + expect(within(projectItem).getByRole('link', { name: /Bitbucket Repo 1/ })).toBeInTheDocument(); + expect(within(projectItem).getByRole('link', { name: /Bitbucket Repo 1/ })).toHaveAttribute( + 'href', + '/dashboard?id=key' + ); + + await user.click(projectItem); + const radioButton = within(projectItem).getByRole('radio', { + name: 'Bitbucket Repo 2', + }); + const importButton = screen.getByText('onboarding.create_project.import_selected_repo'); + + expect(radioButton).toBeInTheDocument(); + expect(importButton).toBeDisabled(); + await user.click(radioButton); + expect(importButton).toBeEnabled(); + await user.click(importButton); + expect(await screen.findByText('/dashboard?id=key')).toBeInTheDocument(); +}); + +it('should show search filter when PAT is already set', async () => { + const user = userEvent.setup(); + renderCreateProject(); + + await act(async () => { + await user.click(ui.bitbucketServerCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-bitbucketserver-2/]); + }); + + const inputSearch = screen.getByRole('searchbox', { + name: 'search_verb', + }); + await user.click(inputSearch); + await user.keyboard('search'); + + expect(searchForBitbucketServerRepositories).toHaveBeenLastCalledWith( + 'conf-bitbucketserver-2', + 'search' + ); +}); + +it('should show no result message when there are no projects', async () => { + const user = userEvent.setup(); + almIntegrationHandler.setBitbucketServerProjects([]); + renderCreateProject(); + await act(async () => { + await user.click(ui.bitbucketServerCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-bitbucketserver-2/]); + }); + + expect(screen.getByRole('alert')).toHaveTextContent('onboarding.create_project.no_bbs_projects'); +}); + +function renderCreateProject(props: Partial<CreateProjectPageProps> = {}) { + renderApp('project/create', <CreateProjectPage {...props} />); +} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloud-it.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloud-it.tsx new file mode 100644 index 00000000000..1398e60f657 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloud-it.tsx @@ -0,0 +1,212 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { act, screen, within } from '@testing-library/react'; + +import userEvent from '@testing-library/user-event'; +import * as React from 'react'; +import selectEvent from 'react-select-event'; +import { byLabelText, byRole, byText } from 'testing-library-selector'; +import { searchForBitbucketCloudRepositories } from '../../../../api/alm-integrations'; +import AlmIntegrationsServiceMock from '../../../../api/mocks/AlmIntegrationsServiceMock'; +import AlmSettingsServiceMock from '../../../../api/mocks/AlmSettingsServiceMock'; +import { renderApp } from '../../../../helpers/testReactTestingUtils'; +import CreateProjectPage, { CreateProjectPageProps } from '../CreateProjectPage'; + +jest.mock('../../../../api/alm-integrations'); +jest.mock('../../../../api/alm-settings'); + +let almIntegrationHandler: AlmIntegrationsServiceMock; +let almSettingsHandler: AlmSettingsServiceMock; + +const ui = { + bitbucketCloudCreateProjectButton: byText( + 'onboarding.create_project.select_method.bitbucketcloud' + ), + personalAccessTokenInput: byRole('textbox', { + name: /onboarding.create_project.enter_pat/, + }), + instanceSelector: byLabelText(/alm.configuration.selector.label/), +}; + +beforeAll(() => { + almIntegrationHandler = new AlmIntegrationsServiceMock(); + almSettingsHandler = new AlmSettingsServiceMock(); +}); + +beforeEach(() => { + jest.clearAllMocks(); + almIntegrationHandler.reset(); + almSettingsHandler.reset(); +}); + +it('should ask for PAT when it is not set yet and show the import project feature afterwards', async () => { + const user = userEvent.setup(); + renderCreateProject(); + expect(ui.bitbucketCloudCreateProjectButton.get()).toBeInTheDocument(); + + await user.click(ui.bitbucketCloudCreateProjectButton.get()); + expect( + screen.getByRole('heading', { name: 'onboarding.create_project.bitbucketcloud.title' }) + ).toBeInTheDocument(); + expect(ui.instanceSelector.get()).toBeInTheDocument(); + + expect( + screen.getByText('onboarding.create_project.enter_pat.bitbucketcloud') + ).toBeInTheDocument(); + expect( + screen.getByText( + 'onboarding.create_project.pat_help.instructions_username.bitbucketcloud.title' + ) + ).toBeInTheDocument(); + + expect(screen.getByRole('button', { name: 'save' })).toBeDisabled(); + + await user.click( + screen.getByRole('textbox', { + name: /onboarding.create_project.enter_username/, + }) + ); + + await user.keyboard('username'); + + await user.click( + screen.getByRole('textbox', { + name: /onboarding.create_project.enter_pat.bitbucketcloud/, + }) + ); + + await user.keyboard('password'); + + expect(screen.getByRole('button', { name: 'save' })).toBeEnabled(); + await user.click(screen.getByRole('button', { name: 'save' })); + + expect(screen.getByText('BitbucketCloud Repo 1')).toBeInTheDocument(); + expect(screen.getByText('BitbucketCloud Repo 2')).toBeInTheDocument(); +}); + +it('should show import project feature when PAT is already set', async () => { + const user = userEvent.setup(); + let projectItem; + renderCreateProject(); + await act(async () => { + await user.click(ui.bitbucketCloudCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-bitbucketcloud-2/]); + }); + + expect(screen.getByText('BitbucketCloud Repo 1')).toBeInTheDocument(); + expect(screen.getByText('BitbucketCloud Repo 2')).toBeInTheDocument(); + + projectItem = screen.getByRole('row', { name: /BitbucketCloud Repo 1/ }); + expect( + within(projectItem).getByText('onboarding.create_project.repository_imported') + ).toBeInTheDocument(); + + expect( + within(projectItem).getByRole('link', { name: /BitbucketCloud Repo 1/ }) + ).toBeInTheDocument(); + expect(within(projectItem).getByRole('link', { name: /BitbucketCloud Repo 1/ })).toHaveAttribute( + 'href', + '/dashboard?id=key' + ); + + projectItem = screen.getByRole('row', { name: /BitbucketCloud Repo 2/ }); + const importProjectButton = within(projectItem).getByRole('button', { + name: 'onboarding.create_project.set_up', + }); + + await user.click(importProjectButton); + expect(await screen.findByText('/dashboard?id=key')).toBeInTheDocument(); +}); + +it('should show search filter when PAT is already set', async () => { + const user = userEvent.setup(); + renderCreateProject(); + + await act(async () => { + await user.click(ui.bitbucketCloudCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-bitbucketcloud-2/]); + }); + + expect(searchForBitbucketCloudRepositories).toHaveBeenLastCalledWith( + 'conf-bitbucketcloud-2', + '', + 30, + 1 + ); + + const inputSearch = screen.getByRole('searchbox', { + name: 'search_verb', + }); + await user.click(inputSearch); + await user.keyboard('search'); + + expect(searchForBitbucketCloudRepositories).toHaveBeenLastCalledWith( + 'conf-bitbucketcloud-2', + 'search', + 30, + 1 + ); +}); + +it('should show no result message when there are no projects', async () => { + const user = userEvent.setup(); + almIntegrationHandler.setBitbucketCloudRepositories([]); + renderCreateProject(); + await act(async () => { + await user.click(ui.bitbucketCloudCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-bitbucketcloud-2/]); + }); + + expect(screen.getByRole('alert')).toHaveTextContent( + 'onboarding.create_project.bitbucketcloud.no_projects' + ); +}); + +it('should have load more', async () => { + const user = userEvent.setup(); + almIntegrationHandler.createRandomBitbucketCloudProjectsWithLoadMore(2, 4); + renderCreateProject(); + await act(async () => { + await user.click(ui.bitbucketCloudCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-bitbucketcloud-2/]); + }); + + const loadMore = screen.getByRole('button', { name: 'show_more' }); + expect(loadMore).toBeInTheDocument(); + + /* + * Next api call response will simulate reaching the last page so we can test the + * loadmore button disapperance. + */ + almIntegrationHandler.createRandomBitbucketCloudProjectsWithLoadMore(4, 4); + await user.click(loadMore); + + expect(searchForBitbucketCloudRepositories).toHaveBeenLastCalledWith( + 'conf-bitbucketcloud-2', + '', + 30, + 2 + ); + expect(loadMore).not.toBeInTheDocument(); +}); + +function renderCreateProject(props: Partial<CreateProjectPageProps> = {}) { + renderApp('project/create', <CreateProjectPage {...props} />); +} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloudProjectCreate-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloudProjectCreate-test.tsx deleted file mode 100644 index 4aee42212ca..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloudProjectCreate-test.tsx +++ /dev/null @@ -1,181 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { - importBitbucketCloudRepository, - searchForBitbucketCloudRepositories, -} from '../../../../api/alm-integrations'; -import { mockBitbucketCloudRepository } from '../../../../helpers/mocks/alm-integrations'; -import { mockBitbucketCloudAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; -import { mockLocation, mockRouter } from '../../../../helpers/testMocks'; -import { waitAndUpdate } from '../../../../helpers/testUtils'; -import BitbucketCloudProjectCreate, { - BITBUCKET_CLOUD_PROJECTS_PAGESIZE, -} from '../BitbucketCloudProjectCreate'; - -jest.mock('../../../../api/alm-integrations', () => { - const { mockProject } = jest.requireActual('../../../../helpers/mocks/projects'); - return { - importBitbucketCloudRepository: jest - .fn() - .mockResolvedValue({ project: mockProject({ key: 'project-key' }) }), - searchForBitbucketCloudRepositories: jest - .fn() - .mockResolvedValue({ isLastPage: true, repositories: [] }), - checkPersonalAccessTokenIsValid: jest.fn().mockResolvedValue({ status: true }), - setAlmPersonalAccessToken: jest.fn().mockResolvedValue(null), - }; -}); - -it('Should render correctly', async () => { - const wrapper = shallowRender({ almInstances: [] }); - await waitAndUpdate(wrapper); - expect(wrapper).toMatchSnapshot(); - wrapper.setProps({ almInstances: [mockBitbucketCloudAlmSettingsInstance()] }); - await waitAndUpdate(wrapper); - expect(wrapper).toMatchSnapshot('Setting changeds'); -}); - -it('Should handle app password correctly', async () => { - const wrapper = shallowRender(); - - await waitAndUpdate(wrapper); - await wrapper.instance().handlePersonalAccessTokenCreated(); - expect(wrapper.state().showPersonalAccessTokenForm).toBe(false); -}); - -it('Should handle error correctly', async () => { - (searchForBitbucketCloudRepositories as jest.Mock).mockRejectedValueOnce({}); - - const wrapper = shallowRender(); - wrapper.setState({ - showPersonalAccessTokenForm: false, - repositories: [mockBitbucketCloudRepository()], - projectsPaging: { pageIndex: 2, pageSize: BITBUCKET_CLOUD_PROJECTS_PAGESIZE }, - }); - await wrapper.instance().handlePersonalAccessTokenCreated(); - expect(wrapper.state().repositories).toHaveLength(0); - expect(wrapper.state().projectsPaging.pageIndex).toBe(1); - expect(wrapper.state().showPersonalAccessTokenForm).toBe(true); - expect(wrapper.state().resetPat).toBe(true); -}); - -it('Should load repository', async () => { - (searchForBitbucketCloudRepositories as jest.Mock).mockResolvedValueOnce({ - isLastPage: true, - repositories: [ - mockBitbucketCloudRepository(), - mockBitbucketCloudRepository({ sqProjectKey: 'sq-key' }), - ], - }); - - const wrapper = shallowRender(); - await wrapper.instance().handlePersonalAccessTokenCreated(); - expect(wrapper.state().repositories).toHaveLength(2); -}); - -it('Should load more repository', async () => { - (searchForBitbucketCloudRepositories as jest.Mock).mockResolvedValueOnce({ - isLastPage: true, - repositories: [ - mockBitbucketCloudRepository(), - mockBitbucketCloudRepository({ sqProjectKey: 'sq-key' }), - ], - }); - - const wrapper = shallowRender(); - wrapper.setState({ showPersonalAccessTokenForm: false, isLastPage: false }); - wrapper.instance().handleLoadMore(); - await waitAndUpdate(wrapper); - expect(wrapper.state().repositories).toHaveLength(2); - expect(wrapper.state().projectsPaging.pageIndex).toBe(2); -}); - -it('Should handle search repository', async () => { - (searchForBitbucketCloudRepositories as jest.Mock).mockResolvedValueOnce({ - isLastPage: true, - repositories: [ - mockBitbucketCloudRepository(), - mockBitbucketCloudRepository({ sqProjectKey: 'sq-key' }), - ], - }); - - const wrapper = shallowRender(); - wrapper.setState({ - isLastPage: false, - showPersonalAccessTokenForm: false, - projectsPaging: { pageIndex: 2, pageSize: BITBUCKET_CLOUD_PROJECTS_PAGESIZE }, - repositories: [mockBitbucketCloudRepository()], - }); - wrapper.instance().handleSearch('test'); - await waitAndUpdate(wrapper); - expect(wrapper.state().repositories).toHaveLength(2); - expect(wrapper.state().projectsPaging.pageIndex).toBe(1); - expect(searchForBitbucketCloudRepositories).toHaveBeenLastCalledWith( - 'key', - 'test', - BITBUCKET_CLOUD_PROJECTS_PAGESIZE, - 1 - ); -}); - -it('Should import repository', async () => { - const onProjectCreate = jest.fn(); - const wrapper = shallowRender({ onProjectCreate }); - wrapper.setState({ - isLastPage: false, - showPersonalAccessTokenForm: false, - projectsPaging: { pageIndex: 1, pageSize: BITBUCKET_CLOUD_PROJECTS_PAGESIZE }, - repositories: [mockBitbucketCloudRepository({ slug: 'slug-test' })], - }); - await wrapper.instance().handleImport('slug-test'); - expect(importBitbucketCloudRepository).toHaveBeenCalledWith('key', 'slug-test'); - expect(onProjectCreate).toHaveBeenCalledWith('project-key'); -}); - -it('Should behave correctly when import fail', async () => { - (importBitbucketCloudRepository as jest.Mock).mockRejectedValueOnce({}); - const onProjectCreate = jest.fn(); - const wrapper = shallowRender({ onProjectCreate }); - wrapper.setState({ - isLastPage: false, - showPersonalAccessTokenForm: false, - projectsPaging: { pageIndex: 1, pageSize: BITBUCKET_CLOUD_PROJECTS_PAGESIZE }, - repositories: [mockBitbucketCloudRepository({ slug: 'slug-test' })], - }); - await wrapper.instance().handleImport('slug-test'); - expect(importBitbucketCloudRepository).toHaveBeenCalledWith('key', 'slug-test'); - expect(onProjectCreate).not.toHaveBeenCalled(); -}); - -function shallowRender(props?: Partial<BitbucketCloudProjectCreate['props']>) { - return shallow<BitbucketCloudProjectCreate>( - <BitbucketCloudProjectCreate - onProjectCreate={jest.fn()} - loadingBindings={false} - location={mockLocation()} - canAdmin={true} - router={mockRouter()} - almInstances={[mockBitbucketCloudAlmSettingsInstance()]} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloudProjectCreateRender-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloudProjectCreateRender-test.tsx deleted file mode 100644 index 43c4f5c6b80..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloudProjectCreateRender-test.tsx +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { mockBitbucketCloudAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; -import BitbucketCloudProjectCreateRenderer, { - BitbucketCloudProjectCreateRendererProps, -} from '../BitbucketCloudProjectCreateRender'; - -it('Should render correctly', () => { - expect(shallowRender()).toMatchSnapshot(); - expect(shallowRender({ selectedAlmInstance: undefined })).toMatchSnapshot('Wrong config'); - expect(shallowRender({ loading: true })).toMatchSnapshot('Loading...'); - expect( - shallowRender({ - showPersonalAccessTokenForm: true, - }) - ).toMatchSnapshot('Need App password'); -}); - -function shallowRender(props?: Partial<BitbucketCloudProjectCreateRendererProps>) { - return shallow( - <BitbucketCloudProjectCreateRenderer - onImport={jest.fn()} - isLastPage={true} - loading={false} - loadingMore={false} - onLoadMore={jest.fn()} - onPersonalAccessTokenCreated={jest.fn()} - onSearch={jest.fn()} - resetPat={false} - searching={false} - searchQuery="" - selectedAlmInstance={mockBitbucketCloudAlmSettingsInstance()} - almInstances={[mockBitbucketCloudAlmSettingsInstance()]} - onSelectedAlmInstanceChange={jest.fn()} - showPersonalAccessTokenForm={false} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloudSearchForm-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloudSearchForm-test.tsx deleted file mode 100644 index 253442d7b0a..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketCloudSearchForm-test.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { mockBitbucketCloudRepository } from '../../../../helpers/mocks/alm-integrations'; -import BitbucketCloudSearchForm, { - BitbucketCloudSearchFormProps, -} from '../BitbucketCloudSearchForm'; - -it('Should render correctly', () => { - expect(shallowRender()).toMatchSnapshot(); - expect( - shallowRender({ - repositories: [ - mockBitbucketCloudRepository(), - mockBitbucketCloudRepository({ sqProjectKey: 'sq-key' }), - ], - isLastPage: false, - }) - ).toMatchSnapshot('Show more'); - expect( - shallowRender({ - repositories: [mockBitbucketCloudRepository()], - isLastPage: true, - }) - ).toMatchSnapshot('Show no more'); - expect( - shallowRender({ - repositories: [mockBitbucketCloudRepository()], - isLastPage: false, - loadingMore: true, - }) - ).toMatchSnapshot('Loading more'); - expect( - shallowRender({ - repositories: [], - isLastPage: false, - searching: true, - }) - ).toMatchSnapshot('Searching'); - expect( - shallowRender({ - importingSlug: 'import-slug', - repositories: [ - mockBitbucketCloudRepository({ slug: 'import-slug' }), - mockBitbucketCloudRepository({ sqProjectKey: 'sq-key' }), - ], - isLastPage: false, - }) - ).toMatchSnapshot('Importing'); -}); - -function shallowRender(props?: Partial<BitbucketCloudSearchFormProps>) { - return shallow( - <BitbucketCloudSearchForm - onImport={jest.fn()} - isLastPage={true} - loadingMore={false} - onLoadMore={jest.fn()} - onSearch={jest.fn()} - searchQuery="" - searching={false} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketImportRepositoryForm-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketImportRepositoryForm-test.tsx deleted file mode 100644 index ecf054c6f33..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketImportRepositoryForm-test.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import SearchBox from '../../../../components/controls/SearchBox'; -import { - mockBitbucketProject, - mockBitbucketRepository, -} from '../../../../helpers/mocks/alm-integrations'; -import { change } from '../../../../helpers/testUtils'; -import BitbucketImportRepositoryForm, { - BitbucketImportRepositoryFormProps, -} from '../BitbucketImportRepositoryForm'; - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot('default'); - expect(shallowRender({ projects: undefined })).toMatchSnapshot('no projects'); - expect(shallowRender({ searching: true })).toMatchSnapshot('searching'); - expect(shallowRender({ searchResults: [mockBitbucketRepository()] })).toMatchSnapshot( - 'search results' - ); -}); - -it('should correctly handle search', () => { - const onSearch = jest.fn(); - const wrapper = shallowRender({ onSearch }); - change(wrapper.find(SearchBox), 'foo'); - expect(onSearch).toHaveBeenCalledWith('foo'); -}); - -function shallowRender(props: Partial<BitbucketImportRepositoryFormProps> = {}) { - return shallow<BitbucketImportRepositoryFormProps>( - <BitbucketImportRepositoryForm - disableRepositories={false} - onSearch={jest.fn()} - onSelectRepository={jest.fn()} - projectRepositories={{ - project: { - allShown: true, - repositories: [ - mockBitbucketRepository(), - mockBitbucketRepository({ id: 2, slug: 'bar', name: 'Bar', sqProjectKey: 'bar' }), - ], - }, - }} - projects={[ - mockBitbucketProject(), - mockBitbucketProject({ id: 2, key: 'project2', name: 'Project 2' }), - ]} - searching={false} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectAccordion-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectAccordion-test.tsx deleted file mode 100644 index 1a238bad84a..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectAccordion-test.tsx +++ /dev/null @@ -1,72 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import Radio from '../../../../components/controls/Radio'; -import { - mockBitbucketProject, - mockBitbucketRepository, -} from '../../../../helpers/mocks/alm-integrations'; -import BitbucketProjectAccordion, { - BitbucketProjectAccordionProps, -} from '../BitbucketProjectAccordion'; - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot('default'); - expect(shallowRender({ disableRepositories: true })).toMatchSnapshot('disable options'); - expect(shallowRender({ open: false })).toMatchSnapshot('closed'); - expect(shallowRender({ onClick: undefined })).toMatchSnapshot('no click handler'); - expect(shallowRender({ repositories: [] })).toMatchSnapshot('no repos'); - expect(shallowRender({ selectedRepository: mockBitbucketRepository() })).toMatchSnapshot( - 'selected repo' - ); - expect(shallowRender({ showingAllRepositories: false })).toMatchSnapshot('not showing all repos'); - expect(shallowRender({ project: undefined })).toMatchSnapshot('no project info'); -}); - -it('should correctly handle selecting repos', () => { - const onSelectRepository = jest.fn(); - const repo = mockBitbucketRepository(); - const wrapper = shallowRender({ - onSelectRepository, - repositories: [repo], - }); - - wrapper.find(Radio).at(0).props().onCheck(''); - expect(onSelectRepository).toHaveBeenCalledWith(repo); -}); - -function shallowRender(props: Partial<BitbucketProjectAccordionProps> = {}) { - return shallow<BitbucketProjectAccordionProps>( - <BitbucketProjectAccordion - disableRepositories={false} - onClick={jest.fn()} - onSelectRepository={jest.fn()} - open={true} - project={mockBitbucketProject()} - repositories={[ - mockBitbucketRepository(), - mockBitbucketRepository({ id: 2, slug: 'bar', name: 'Bar', sqProjectKey: 'bar' }), - ]} - showingAllRepositories={true} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreate-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreate-test.tsx deleted file mode 100644 index 91a6ea85605..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreate-test.tsx +++ /dev/null @@ -1,155 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { - getBitbucketServerProjects, - getBitbucketServerRepositories, - importBitbucketServerProject, - searchForBitbucketServerRepositories, -} from '../../../../api/alm-integrations'; -import { - mockBitbucketProject, - mockBitbucketRepository, -} from '../../../../helpers/mocks/alm-integrations'; -import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; -import { mockLocation, mockRouter } from '../../../../helpers/testMocks'; -import { waitAndUpdate } from '../../../../helpers/testUtils'; -import { AlmKeys } from '../../../../types/alm-settings'; -import BitbucketProjectCreate from '../BitbucketProjectCreate'; - -jest.mock('../../../../api/alm-integrations', () => { - const { mockBitbucketProject, mockBitbucketRepository } = jest.requireActual( - '../../../../helpers/mocks/alm-integrations' - ); - return { - getBitbucketServerProjects: jest.fn().mockResolvedValue({ - projects: [ - mockBitbucketProject({ key: 'project1', name: 'Project 1' }), - mockBitbucketProject({ id: 2, key: 'project2' }), - ], - }), - getBitbucketServerRepositories: jest.fn().mockResolvedValue({ - repositories: [ - mockBitbucketRepository({ projectKey: 'project1' }), - mockBitbucketRepository({ id: 2, projectKey: 'project1', slug: 'project__repo2' }), - ], - }), - importBitbucketServerProject: jest.fn().mockResolvedValue({ project: { key: 'baz' } }), - searchForBitbucketServerRepositories: jest.fn().mockResolvedValue({ - repositories: [ - mockBitbucketRepository(), - mockBitbucketRepository({ id: 2, slug: 'project__repo2' }), - ], - }), - }; -}); - -beforeEach(jest.clearAllMocks); - -it('should render correctly', async () => { - expect(shallowRender()).toMatchSnapshot(); - expect(shallowRender({ almInstances: [] })).toMatchSnapshot('No setting'); - - const wrapper = shallowRender(); - (getBitbucketServerRepositories as jest.Mock).mockRejectedValueOnce({}); - await wrapper.instance().handlePersonalAccessTokenCreated(); - expect(wrapper).toMatchSnapshot('No repository'); -}); - -it('should correctly fetch projects and repos', async () => { - const wrapper = shallowRender(); - await wrapper.instance().handlePersonalAccessTokenCreated(); - - // Opens first project on mount. - expect(getBitbucketServerProjects).toHaveBeenCalledWith('foo'); - expect(wrapper.state().projects).toHaveLength(2); - - // Check repos got loaded. - await waitAndUpdate(wrapper); - expect(getBitbucketServerRepositories).toHaveBeenCalledWith('foo', 'Project 1'); - expect(wrapper.state().projectRepositories).toEqual( - expect.objectContaining({ - project1: expect.objectContaining({ - repositories: expect.arrayContaining([ - expect.objectContaining({ id: 1 }), - expect.objectContaining({ id: 2 }), - ]), - }), - }) - ); - expect(wrapper.state().projectRepositories).toBeDefined(); -}); - -it('should correctly import a repo', async () => { - const onProjectCreate = jest.fn(); - const repo = mockBitbucketRepository(); - const wrapper = shallowRender({ onProjectCreate }); - const instance = wrapper.instance(); - - instance.handleSelectRepository(repo); - instance.handleImportRepository(); - expect(importBitbucketServerProject).toHaveBeenCalledWith('foo', repo.projectKey, repo.slug); - await waitAndUpdate(wrapper); - expect(onProjectCreate).toHaveBeenCalledWith('baz'); -}); - -it('should correctly handle search', async () => { - const wrapper = shallowRender(); - const instance = wrapper.instance(); - - // Don't trigger search on empty query. - instance.handleSearch(''); - expect(searchForBitbucketServerRepositories).not.toHaveBeenCalled(); - expect(wrapper.state().searching).toBe(false); - expect(wrapper.state().searchResults).toBeUndefined(); - - instance.handleSearch('bar'); - expect(searchForBitbucketServerRepositories).toHaveBeenCalledWith('foo', 'bar'); - expect(wrapper.state().searching).toBe(true); - await waitAndUpdate(wrapper); - expect(wrapper.state().searching).toBe(false); - expect(wrapper.state().searchResults).toHaveLength(2); -}); - -it('should behave correctly when no setting', async () => { - const wrapper = shallowRender({ almInstances: [] }); - await wrapper.instance().handleSearch(''); - await wrapper.instance().handleImportRepository(); - await wrapper.instance().fetchBitbucketRepositories([mockBitbucketProject()]); - - expect(searchForBitbucketServerRepositories).not.toHaveBeenCalled(); - expect(importBitbucketServerProject).not.toHaveBeenCalled(); - expect(getBitbucketServerRepositories).not.toHaveBeenCalled(); -}); - -function shallowRender(props: Partial<BitbucketProjectCreate['props']> = {}) { - return shallow<BitbucketProjectCreate>( - <BitbucketProjectCreate - canAdmin={false} - almInstances={[mockAlmSettingsInstance({ alm: AlmKeys.BitbucketServer, key: 'foo' })]} - loadingBindings={false} - location={mockLocation()} - router={mockRouter()} - onProjectCreate={jest.fn()} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreateRenderer-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreateRenderer-test.tsx deleted file mode 100644 index 41dc80e94e2..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketProjectCreateRenderer-test.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { - mockBitbucketProject, - mockBitbucketRepository, -} from '../../../../helpers/mocks/alm-integrations'; -import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; -import { AlmKeys } from '../../../../types/alm-settings'; -import BitbucketProjectCreateRenderer, { - BitbucketProjectCreateRendererProps, -} from '../BitbucketProjectCreateRenderer'; - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot('default'); - expect(shallowRender({ showPersonalAccessTokenForm: true })).toMatchSnapshot('pat form'); - expect(shallowRender({ loading: true })).toMatchSnapshot('loading'); - expect(shallowRender({ importing: true })).toMatchSnapshot('importing'); - expect(shallowRender({ selectedRepository: mockBitbucketRepository() })).toMatchSnapshot( - 'selected repo' - ); - expect(shallowRender({ selectedAlmInstance: undefined })).toMatchSnapshot( - 'invalid config, regular user' - ); - expect(shallowRender({ selectedAlmInstance: undefined, canAdmin: true })).toMatchSnapshot( - 'invalid config, admin user' - ); -}); - -function shallowRender(props: Partial<BitbucketProjectCreateRendererProps> = {}) { - return shallow<BitbucketProjectCreateRendererProps>( - <BitbucketProjectCreateRenderer - selectedAlmInstance={mockAlmSettingsInstance({ alm: AlmKeys.BitbucketServer })} - almInstances={[mockAlmSettingsInstance({ alm: AlmKeys.BitbucketServer })]} - onSelectedAlmInstanceChange={jest.fn()} - importing={false} - loading={false} - onImportRepository={jest.fn()} - onPersonalAccessTokenCreated={jest.fn()} - onSearch={jest.fn()} - onSelectRepository={jest.fn()} - projectRepositories={{ foo: { allShown: true, repositories: [mockBitbucketRepository()] } }} - projects={[mockBitbucketProject({ key: 'foo' })]} - resetPat={false} - searching={false} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketRepositories-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketRepositories-test.tsx deleted file mode 100644 index 137468f862b..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketRepositories-test.tsx +++ /dev/null @@ -1,65 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { - mockBitbucketProject, - mockBitbucketRepository, -} from '../../../../helpers/mocks/alm-integrations'; -import { click } from '../../../../helpers/testUtils'; -import BitbucketProjectAccordion from '../BitbucketProjectAccordion'; -import BitbucketRepositories, { BitbucketRepositoriesProps } from '../BitbucketRepositories'; - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot('default'); - expect(shallowRender({ projectRepositories: {} })).toMatchSnapshot('no repos'); - expect(shallowRender({ selectedRepository: mockBitbucketRepository() })).toMatchSnapshot( - 'selected repo' - ); -}); - -it('should correctly handle opening/closing accordions', () => { - const wrapper = shallowRender(); - click(wrapper.find(BitbucketProjectAccordion).at(1)); - expect(wrapper).toMatchSnapshot('2nd opened'); -}); - -function shallowRender(props: Partial<BitbucketRepositoriesProps> = {}) { - return shallow<BitbucketRepositoriesProps>( - <BitbucketRepositories - disableRepositories={false} - onSelectRepository={jest.fn()} - projectRepositories={{ - project: { - allShown: true, - repositories: [ - mockBitbucketRepository(), - mockBitbucketRepository({ id: 2, slug: 'bar', name: 'Bar', sqProjectKey: 'bar' }), - ], - }, - }} - projects={[ - mockBitbucketProject(), - mockBitbucketProject({ id: 2, key: 'project2', name: 'Project 2' }), - ]} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketSearchResults-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketSearchResults-test.tsx deleted file mode 100644 index 2bb40e32c2c..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/BitbucketSearchResults-test.tsx +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { - mockBitbucketProject, - mockBitbucketRepository, -} from '../../../../helpers/mocks/alm-integrations'; -import BitbucketSearchResults, { BitbucketSearchResultsProps } from '../BitbucketSearchResults'; - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot('default'); - expect( - shallowRender({ searching: true, projects: [], searchResults: undefined }) - ).toMatchSnapshot('searching'); - expect(shallowRender({ searchResults: undefined })).toMatchSnapshot('no results'); - expect( - shallowRender({ - searchResults: [ - mockBitbucketRepository(), - mockBitbucketRepository({ projectKey: 'unknown' }), - ], - }) - ).toMatchSnapshot('unknown project in search results'); -}); - -function shallowRender(props: Partial<BitbucketSearchResultsProps> = {}) { - return shallow<BitbucketSearchResultsProps>( - <BitbucketSearchResults - disableRepositories={false} - onSelectRepository={jest.fn()} - projects={[mockBitbucketProject()]} - searchResults={[mockBitbucketRepository()]} - searching={false} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProject-it.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProject-it.tsx deleted file mode 100644 index 89c35d0eda4..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProject-it.tsx +++ /dev/null @@ -1,215 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { act, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import * as React from 'react'; -import selectEvent from 'react-select-event'; -import { byLabelText, byRole, byText } from 'testing-library-selector'; -import { searchAzureRepositories } from '../../../../api/alm-integrations'; -import AlmIntegrationsServiceMock from '../../../../api/mocks/AlmIntegrationsServiceMock'; -import AlmSettingsServiceMock from '../../../../api/mocks/AlmSettingsServiceMock'; -import { renderApp } from '../../../../helpers/testReactTestingUtils'; -import CreateProjectPage, { CreateProjectPageProps } from '../CreateProjectPage'; - -jest.mock('../../../../api/alm-integrations'); -jest.mock('../../../../api/alm-settings'); - -const original = window.location; - -let almIntegrationHandler: AlmIntegrationsServiceMock; -let almSettingsHandler: AlmSettingsServiceMock; - -const ui = { - gitlabCreateProjectButton: byText('onboarding.create_project.select_method.gitlab'), - githubCreateProjectButton: byText('onboarding.create_project.select_method.github'), - azureCreateProjectButton: byText('onboarding.create_project.select_method.azure'), - personalAccessTokenInput: byRole('textbox', { - name: 'onboarding.create_project.enter_pat field_required', - }), - instanceSelector: byLabelText(/alm.configuration.selector.label/), -}; - -beforeAll(() => { - Object.defineProperty(window, 'location', { - configurable: true, - value: { replace: jest.fn() }, - }); - almIntegrationHandler = new AlmIntegrationsServiceMock(); - almSettingsHandler = new AlmSettingsServiceMock(); -}); - -beforeEach(() => { - jest.clearAllMocks(); - almIntegrationHandler.reset(); - almSettingsHandler.reset(); -}); - -afterAll(() => { - Object.defineProperty(window, 'location', { configurable: true, value: original }); -}); - -describe('Gitlab onboarding page', () => { - it('should ask for PAT when it is not set yet and show the import project feature afterwards', async () => { - const user = userEvent.setup(); - renderCreateProject(); - expect(ui.gitlabCreateProjectButton.get()).toBeInTheDocument(); - - await user.click(ui.gitlabCreateProjectButton.get()); - expect(screen.getByText('onboarding.create_project.gitlab.title')).toBeInTheDocument(); - expect(ui.instanceSelector.get()).toBeInTheDocument(); - - expect(screen.getByText('onboarding.create_project.enter_pat')).toBeInTheDocument(); - expect(screen.getByText('onboarding.create_project.pat_help.title')).toBeInTheDocument(); - expect(screen.getByRole('button', { name: 'save' })).toBeInTheDocument(); - - await user.click(ui.personalAccessTokenInput.get()); - await user.keyboard('secret'); - await user.click(screen.getByRole('button', { name: 'save' })); - - expect(screen.getByText('Gitlab project 1')).toBeInTheDocument(); - expect(screen.getByText('Gitlab project 2')).toBeInTheDocument(); - expect(screen.getAllByText('onboarding.create_project.set_up')).toHaveLength(2); - expect(screen.getByText('onboarding.create_project.repository_imported')).toBeInTheDocument(); - }); - - it('should show import project feature when PAT is already set', async () => { - const user = userEvent.setup(); - renderCreateProject(); - await act(async () => { - await user.click(ui.gitlabCreateProjectButton.get()); - await selectEvent.select(ui.instanceSelector.get(), [/conf-final-2/]); - }); - - expect(screen.getByText('Gitlab project 1')).toBeInTheDocument(); - expect(screen.getByText('Gitlab project 2')).toBeInTheDocument(); - }); - - it('should show no result message when there are no projects', async () => { - const user = userEvent.setup(); - almIntegrationHandler.setGitlabProjects([]); - renderCreateProject(); - await act(async () => { - await user.click(ui.gitlabCreateProjectButton.get()); - await selectEvent.select(ui.instanceSelector.get(), [/conf-final-2/]); - }); - - expect(screen.getByText('onboarding.create_project.gitlab.no_projects')).toBeInTheDocument(); - }); -}); - -describe('Github onboarding page', () => { - it('should redirect to github authorization page when not already authorized', async () => { - const user = userEvent.setup(); - renderCreateProject(); - expect(ui.githubCreateProjectButton.get()).toBeInTheDocument(); - - await user.click(ui.githubCreateProjectButton.get()); - expect(screen.getByText('onboarding.create_project.github.title')).toBeInTheDocument(); - expect(screen.getByText('alm.configuration.selector.placeholder')).toBeInTheDocument(); - expect(ui.instanceSelector.get()).toBeInTheDocument(); - - await selectEvent.select(ui.instanceSelector.get(), [/conf-github-1/]); - - expect(window.location.replace).toHaveBeenCalled(); - expect( - screen.getByText('onboarding.create_project.github.choose_organization') - ).toBeInTheDocument(); - }); -}); - -describe('Azure onboarding page', () => { - it('should ask for PAT when it is not set yet and show the import project feature afterwards', async () => { - const user = userEvent.setup(); - renderCreateProject(); - expect(ui.azureCreateProjectButton.get()).toBeInTheDocument(); - - await user.click(ui.azureCreateProjectButton.get()); - - expect(screen.getByText('onboarding.create_project.azure.title')).toBeInTheDocument(); - expect(screen.getByText('alm.configuration.selector.label.alm.azure.long')).toBeInTheDocument(); - - expect(screen.getByText('onboarding.create_project.enter_pat')).toBeInTheDocument(); - expect(screen.getByText('onboarding.create_project.pat_form.title.azure')).toBeInTheDocument(); - expect( - screen.getByRole('button', { name: 'onboarding.create_project.pat_form.list_repositories' }) - ).toBeInTheDocument(); - - await user.click(ui.personalAccessTokenInput.get()); - await user.keyboard('secret'); - await user.click( - screen.getByRole('button', { name: 'onboarding.create_project.pat_form.list_repositories' }) - ); - - expect(screen.getByText('Azure project')).toBeInTheDocument(); - expect(screen.getByText('Azure project 2')).toBeInTheDocument(); - // eslint-disable-next-line jest-dom/prefer-in-document - expect(screen.getAllByText('onboarding.create_project.repository_imported')).toHaveLength(1); - }); - - it('should show import project feature when PAT is already set', async () => { - const user = userEvent.setup(); - renderCreateProject(); - - await act(async () => { - await user.click(ui.azureCreateProjectButton.get()); - await selectEvent.select(ui.instanceSelector.get(), [/conf-azure-2/]); - }); - - expect(screen.getByText('Azure project 2')).toBeInTheDocument(); - const importButton = screen.getByText('onboarding.create_project.import_selected_repo'); - const radioButton = screen.getByRole('radio', { name: 'Azure repo 2' }); - - expect(radioButton).toBeInTheDocument(); - expect(importButton).toBeDisabled(); - await user.click(radioButton); - expect(importButton).toBeEnabled(); - await user.click(importButton); - - expect(await screen.findByText('/dashboard?id=key')).toBeInTheDocument(); - }); - - it('should show search filter when PAT is already set', async () => { - const user = userEvent.setup(); - renderCreateProject(); - - await act(async () => { - await user.click(ui.azureCreateProjectButton.get()); - await selectEvent.select(ui.instanceSelector.get(), [/conf-azure-2/]); - }); - - // Should search with positive results - const inputSearch = screen.getByPlaceholderText( - 'onboarding.create_project.search_projects_repositories' - ); - await user.click(inputSearch); - await user.keyboard('s'); - - expect(searchAzureRepositories).toHaveBeenCalledWith('conf-azure-2', 's'); - - // Should search with empty results - almIntegrationHandler.setSearchAzureRepositories([]); - await user.keyboard('f'); - expect(screen.getByText('onboarding.create_project.azure.no_results')).toBeInTheDocument(); - }); -}); - -function renderCreateProject(props: Partial<CreateProjectPageProps> = {}) { - renderApp('project/create', <CreateProjectPage {...props} />); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectModeSelection-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectModeSelection-test.tsx deleted file mode 100644 index e677e2a580d..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectModeSelection-test.tsx +++ /dev/null @@ -1,159 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { mockAppState } from '../../../../helpers/testMocks'; -import { click } from '../../../../helpers/testUtils'; -import { AlmKeys } from '../../../../types/alm-settings'; -import { - CreateProjectModeSelection, - CreateProjectModeSelectionProps, -} from '../CreateProjectModeSelection'; -import { CreateProjectModes } from '../types'; - -it('should render correctly', () => { - expect(shallowRender({ loadingBindings: true })).toMatchSnapshot('loading instances'); - expect(shallowRender()).toMatchSnapshot('default'); - expect(shallowRender({}, { [AlmKeys.BitbucketServer]: 0, [AlmKeys.GitHub]: 2 })).toMatchSnapshot( - 'invalid configs, not admin' - ); - expect( - shallowRender( - { appState: mockAppState({ canAdmin: true }) }, - { [AlmKeys.BitbucketServer]: 0, [AlmKeys.GitHub]: 2 } - ) - ).toMatchSnapshot('invalid configs, admin'); - expect( - shallowRender( - { appState: mockAppState({ canAdmin: true }) }, - { [AlmKeys.BitbucketServer]: 0, [AlmKeys.BitbucketCloud]: 0, [AlmKeys.GitHub]: 2 } - ) - ).toMatchSnapshot('invalid configs, admin'); - expect( - shallowRender( - { appState: mockAppState({ canAdmin: true }) }, - { - [AlmKeys.Azure]: 0, - [AlmKeys.BitbucketCloud]: 0, - [AlmKeys.BitbucketServer]: 0, - [AlmKeys.GitHub]: 0, - [AlmKeys.GitLab]: 0, - } - ) - ).toMatchSnapshot('no alm conf yet, admin'); -}); - -it('should correctly pass the selected mode up', () => { - const onSelectMode = jest.fn(); - let wrapper = shallowRender({ onSelectMode }); - - const almButton = 'button.create-project-mode-type-alm'; - - click(wrapper.find('button.create-project-mode-type-manual')); - expect(onSelectMode).toHaveBeenCalledWith(CreateProjectModes.Manual); - onSelectMode.mockClear(); - - click(wrapper.find(almButton).at(0)); - expect(onSelectMode).toHaveBeenCalledWith(CreateProjectModes.AzureDevOps); - onSelectMode.mockClear(); - - click(wrapper.find(almButton).at(1)); - expect(onSelectMode).toHaveBeenCalledWith(CreateProjectModes.BitbucketServer); - onSelectMode.mockClear(); - - click(wrapper.find(almButton).at(2)); - expect(onSelectMode).toHaveBeenCalledWith(CreateProjectModes.BitbucketCloud); - onSelectMode.mockClear(); - - click(wrapper.find(almButton).at(3)); - expect(onSelectMode).toHaveBeenCalledWith(CreateProjectModes.GitHub); - onSelectMode.mockClear(); - - click(wrapper.find(almButton).at(4)); - expect(onSelectMode).toHaveBeenCalledWith(CreateProjectModes.GitLab); - onSelectMode.mockClear(); - - wrapper = shallowRender( - { onSelectMode }, - { [AlmKeys.BitbucketCloud]: 1, [AlmKeys.BitbucketServer]: 0 } - ); - - click(wrapper.find(almButton).at(2)); - expect(onSelectMode).toHaveBeenCalledWith(CreateProjectModes.BitbucketCloud); - onSelectMode.mockClear(); -}); - -it('should call the proper click handler', () => { - const almButton = 'button.create-project-mode-type-alm'; - - const onSelectMode = jest.fn(); - const onConfigMode = jest.fn(); - - let wrapper = shallowRender({ onSelectMode, onConfigMode }, { [AlmKeys.Azure]: 0 }); - - click(wrapper.find(almButton).at(0)); - expect(onConfigMode).not.toHaveBeenCalled(); - expect(onSelectMode).not.toHaveBeenCalled(); - onConfigMode.mockClear(); - onSelectMode.mockClear(); - - wrapper = shallowRender({ onSelectMode, onConfigMode }); - - click(wrapper.find(almButton).at(0)); - expect(onConfigMode).not.toHaveBeenCalled(); - expect(onSelectMode).toHaveBeenCalledWith(CreateProjectModes.AzureDevOps); - onConfigMode.mockClear(); - onSelectMode.mockClear(); - - wrapper = shallowRender( - { onSelectMode, onConfigMode, appState: mockAppState({ canAdmin: true }) }, - { [AlmKeys.Azure]: 0 } - ); - - click(wrapper.find(almButton).at(0)); - expect(onConfigMode).toHaveBeenCalledWith(CreateProjectModes.AzureDevOps); - expect(onSelectMode).not.toHaveBeenCalled(); - onConfigMode.mockClear(); - onSelectMode.mockClear(); -}); - -function shallowRender( - props: Partial<CreateProjectModeSelectionProps> = {}, - almCountOverrides = {} -) { - const almCounts = { - [AlmKeys.Azure]: 1, - [AlmKeys.BitbucketCloud]: 1, - [AlmKeys.BitbucketServer]: 1, - [AlmKeys.GitHub]: 1, - [AlmKeys.GitLab]: 1, - ...almCountOverrides, - }; - return shallow<CreateProjectModeSelectionProps>( - <CreateProjectModeSelection - almCounts={almCounts} - appState={mockAppState({ canAdmin: false })} - loadingBindings={false} - onSelectMode={jest.fn()} - onConfigMode={jest.fn()} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPage-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPage-test.tsx deleted file mode 100644 index 146f6bb91de..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/CreateProjectPage-test.tsx +++ /dev/null @@ -1,116 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { getAlmSettings } from '../../../../api/alm-settings'; -import { mockAppState, mockLocation, mockRouter } from '../../../../helpers/testMocks'; -import { waitAndUpdate } from '../../../../helpers/testUtils'; -import { AlmKeys } from '../../../../types/alm-settings'; -import AlmBindingDefinitionForm from '../../../settings/components/almIntegration/AlmBindingDefinitionForm'; -import CreateProjectModeSelection from '../CreateProjectModeSelection'; -import { CreateProjectPage } from '../CreateProjectPage'; -import { CreateProjectModes } from '../types'; - -jest.mock('../../../../api/alm-settings', () => { - const { AlmKeys } = jest.requireActual('../../../../types/alm-settings'); - return { - getAlmSettings: jest.fn().mockResolvedValue([{ alm: AlmKeys.BitbucketServer, key: 'foo' }]), - }; -}); - -beforeEach(jest.clearAllMocks); - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot(); - expect(getAlmSettings).toHaveBeenCalled(); -}); - -it.each([ - [CreateProjectModes.Manual], - [CreateProjectModes.AzureDevOps], - [CreateProjectModes.BitbucketServer], - [CreateProjectModes.BitbucketCloud], - [CreateProjectModes.GitHub], - [CreateProjectModes.GitLab], -])('should render correctly for %s mode', (mode: CreateProjectModes) => { - expect( - shallowRender({ - location: mockLocation({ query: { mode } }), - }) - ).toMatchSnapshot(); -}); - -it('should render alm configuration creation correctly', () => { - const wrapper = shallowRender(); - - wrapper.find(CreateProjectModeSelection).props().onConfigMode(AlmKeys.Azure); - expect(wrapper).toMatchSnapshot(); -}); - -it('should cancel alm configuration creation properly', () => { - const wrapper = shallowRender(); - - wrapper.find(CreateProjectModeSelection).props().onConfigMode(AlmKeys.Azure); - expect(wrapper.state().creatingAlmDefinition).toBe(AlmKeys.Azure); - - wrapper.find(AlmBindingDefinitionForm).props().onCancel(); - expect(wrapper.state().creatingAlmDefinition).toBeUndefined(); -}); - -it('should submit alm configuration creation properly', async () => { - const push = jest.fn(); - const wrapper = shallowRender({ router: mockRouter({ push }) }); - - wrapper.find(CreateProjectModeSelection).props().onConfigMode(AlmKeys.Azure); - expect(wrapper.state().creatingAlmDefinition).toBe(AlmKeys.Azure); - - wrapper.find(AlmBindingDefinitionForm).props().afterSubmit({ key: 'test-key' }); - await waitAndUpdate(wrapper); - expect(wrapper.state().creatingAlmDefinition).toBeUndefined(); - expect(getAlmSettings).toHaveBeenCalled(); - expect(push).toHaveBeenCalledWith({ pathname: '/path', query: { mode: AlmKeys.Azure } }); -}); - -it('should submit alm configuration creation properly for BBC', async () => { - const push = jest.fn(); - const wrapper = shallowRender({ router: mockRouter({ push }) }); - - wrapper.find(CreateProjectModeSelection).props().onConfigMode(AlmKeys.BitbucketServer); - expect(wrapper.state().creatingAlmDefinition).toBe(AlmKeys.BitbucketServer); - - (getAlmSettings as jest.Mock).mockResolvedValueOnce([{ alm: AlmKeys.BitbucketCloud }]); - wrapper.find(AlmBindingDefinitionForm).props().afterSubmit({ key: 'test-key' }); - await waitAndUpdate(wrapper); - expect(wrapper.state().creatingAlmDefinition).toBeUndefined(); - expect(getAlmSettings).toHaveBeenCalled(); - expect(push).toHaveBeenCalledWith({ pathname: '/path', query: { mode: AlmKeys.BitbucketCloud } }); -}); - -function shallowRender(props: Partial<CreateProjectPage['props']> = {}) { - return shallow<CreateProjectPage>( - <CreateProjectPage - appState={mockAppState()} - hasFeature={jest.fn().mockReturnValue(false)} - location={mockLocation()} - router={mockRouter()} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitHub-it.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/GitHub-it.tsx new file mode 100644 index 00000000000..63f933ab800 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/GitHub-it.tsx @@ -0,0 +1,86 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { screen } from '@testing-library/react'; + +import userEvent from '@testing-library/user-event'; +import * as React from 'react'; +import selectEvent from 'react-select-event'; +import { byLabelText, byRole, byText } from 'testing-library-selector'; +import AlmIntegrationsServiceMock from '../../../../api/mocks/AlmIntegrationsServiceMock'; +import AlmSettingsServiceMock from '../../../../api/mocks/AlmSettingsServiceMock'; +import { renderApp } from '../../../../helpers/testReactTestingUtils'; +import CreateProjectPage, { CreateProjectPageProps } from '../CreateProjectPage'; + +jest.mock('../../../../api/alm-integrations'); +jest.mock('../../../../api/alm-settings'); + +const original = window.location; + +let almIntegrationHandler: AlmIntegrationsServiceMock; +let almSettingsHandler: AlmSettingsServiceMock; + +const ui = { + githubCreateProjectButton: byText('onboarding.create_project.select_method.github'), + personalAccessTokenInput: byRole('textbox', { + name: /onboarding.create_project.enter_pat/, + }), + instanceSelector: byLabelText(/alm.configuration.selector.label/), +}; + +beforeAll(() => { + Object.defineProperty(window, 'location', { + configurable: true, + value: { replace: jest.fn() }, + }); + almIntegrationHandler = new AlmIntegrationsServiceMock(); + almSettingsHandler = new AlmSettingsServiceMock(); +}); + +beforeEach(() => { + jest.clearAllMocks(); + almIntegrationHandler.reset(); + almSettingsHandler.reset(); +}); + +afterAll(() => { + Object.defineProperty(window, 'location', { configurable: true, value: original }); +}); + +it('should redirect to github authorization page when not already authorized', async () => { + const user = userEvent.setup(); + renderCreateProject(); + expect(ui.githubCreateProjectButton.get()).toBeInTheDocument(); + + await user.click(ui.githubCreateProjectButton.get()); + expect(screen.getByText('onboarding.create_project.github.title')).toBeInTheDocument(); + expect(screen.getByText('alm.configuration.selector.placeholder')).toBeInTheDocument(); + expect(ui.instanceSelector.get()).toBeInTheDocument(); + + await selectEvent.select(ui.instanceSelector.get(), [/conf-github-1/]); + + expect(window.location.replace).toHaveBeenCalled(); + expect( + screen.getByText('onboarding.create_project.github.choose_organization') + ).toBeInTheDocument(); +}); + +function renderCreateProject(props: Partial<CreateProjectPageProps> = {}) { + renderApp('project/create', <CreateProjectPage {...props} />); +} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitLab-it.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/GitLab-it.tsx new file mode 100644 index 00000000000..91c3adc4b8e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/GitLab-it.tsx @@ -0,0 +1,177 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { act, screen, within } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import * as React from 'react'; +import selectEvent from 'react-select-event'; +import { byLabelText, byRole, byText } from 'testing-library-selector'; +import { getGitlabProjects } from '../../../../api/alm-integrations'; +import AlmIntegrationsServiceMock from '../../../../api/mocks/AlmIntegrationsServiceMock'; +import AlmSettingsServiceMock from '../../../../api/mocks/AlmSettingsServiceMock'; +import { renderApp } from '../../../../helpers/testReactTestingUtils'; +import CreateProjectPage, { CreateProjectPageProps } from '../CreateProjectPage'; + +jest.mock('../../../../api/alm-integrations'); +jest.mock('../../../../api/alm-settings'); + +let almIntegrationHandler: AlmIntegrationsServiceMock; +let almSettingsHandler: AlmSettingsServiceMock; + +const ui = { + gitlabCreateProjectButton: byText('onboarding.create_project.select_method.gitlab'), + + personalAccessTokenInput: byRole('textbox', { + name: /onboarding.create_project.enter_pat/, + }), + instanceSelector: byLabelText(/alm.configuration.selector.label/), +}; + +beforeAll(() => { + almIntegrationHandler = new AlmIntegrationsServiceMock(); + almSettingsHandler = new AlmSettingsServiceMock(); +}); + +beforeEach(() => { + jest.clearAllMocks(); + almIntegrationHandler.reset(); + almSettingsHandler.reset(); +}); + +it('should ask for PAT when it is not set yet and show the import project feature afterwards', async () => { + const user = userEvent.setup(); + renderCreateProject(); + expect(ui.gitlabCreateProjectButton.get()).toBeInTheDocument(); + + await user.click(ui.gitlabCreateProjectButton.get()); + expect(screen.getByText('onboarding.create_project.gitlab.title')).toBeInTheDocument(); + expect(ui.instanceSelector.get()).toBeInTheDocument(); + + expect(screen.getByText('onboarding.create_project.enter_pat')).toBeInTheDocument(); + expect(screen.getByText('onboarding.create_project.pat_help.title')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'save' })).toBeInTheDocument(); + + await user.click(ui.personalAccessTokenInput.get()); + await user.keyboard('secret'); + await user.click(screen.getByRole('button', { name: 'save' })); + + expect(screen.getByText('Gitlab project 1')).toBeInTheDocument(); + expect(screen.getByText('Gitlab project 2')).toBeInTheDocument(); + expect(screen.getAllByText('onboarding.create_project.set_up')).toHaveLength(2); + expect(screen.getByText('onboarding.create_project.repository_imported')).toBeInTheDocument(); +}); + +it('should show import project feature when PAT is already set', async () => { + const user = userEvent.setup(); + let projectItem; + renderCreateProject(); + await act(async () => { + await user.click(ui.gitlabCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-final-2/]); + }); + + expect(screen.getByText('Gitlab project 1')).toBeInTheDocument(); + expect(screen.getByText('Gitlab project 2')).toBeInTheDocument(); + + projectItem = screen.getByRole('row', { name: /Gitlab project 1/ }); + expect( + within(projectItem).getByText('onboarding.create_project.repository_imported') + ).toBeInTheDocument(); + expect(within(projectItem).getByRole('link', { name: /Gitlab project 1/ })).toBeInTheDocument(); + expect(within(projectItem).getByRole('link', { name: /Gitlab project 1/ })).toHaveAttribute( + 'href', + '/dashboard?id=key' + ); + + projectItem = screen.getByRole('row', { name: /Gitlab project 2/ }); + const importProjectButton = within(projectItem).getByRole('button', { + name: 'onboarding.create_project.set_up', + }); + + await user.click(importProjectButton); + expect(await screen.findByText('/dashboard?id=key')).toBeInTheDocument(); +}); + +it('should show search filter when PAT is already set', async () => { + const user = userEvent.setup(); + renderCreateProject(); + + await act(async () => { + await user.click(ui.gitlabCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-final-2/]); + }); + + const inputSearch = screen.getByRole('searchbox', { + name: 'search_verb', + }); + await user.click(inputSearch); + await user.keyboard('sea'); + + expect(getGitlabProjects).toHaveBeenLastCalledWith({ + almSetting: 'conf-final-2', + page: 1, + pageSize: 30, + query: 'sea', + }); +}); + +it('should have load more', async () => { + const user = userEvent.setup(); + almIntegrationHandler.createRandomGitlabProjectsWithLoadMore(10, 20); + renderCreateProject(); + await act(async () => { + await user.click(ui.gitlabCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-final-2/]); + }); + const loadMore = screen.getByRole('button', { name: 'show_more' }); + expect(loadMore).toBeInTheDocument(); + + /* + * Next api call response will simulate reaching the last page so we can test the + * loadmore button disapperance. + */ + almIntegrationHandler.createRandomGitlabProjectsWithLoadMore(20, 20); + await user.click(loadMore); + expect(getGitlabProjects).toHaveBeenLastCalledWith({ + almSetting: 'conf-final-2', + page: 2, + pageSize: 30, + query: '', + }); + expect(loadMore).not.toBeInTheDocument(); +}); + +it('should show no result message when there are no projects', async () => { + const user = userEvent.setup(); + almIntegrationHandler.setGitlabProjects([]); + renderCreateProject(); + await act(async () => { + await user.click(ui.gitlabCreateProjectButton.get()); + await selectEvent.select(ui.instanceSelector.get(), [/conf-final-2/]); + }); + + expect(screen.getByRole('alert')).toHaveTextContent( + 'onboarding.create_project.gitlab.no_projects' + ); +}); + +function renderCreateProject(props: Partial<CreateProjectPageProps> = {}) { + renderApp('project/create', <CreateProjectPage {...props} />); +} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectCreate-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectCreate-test.tsx deleted file mode 100644 index 4293a00e936..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectCreate-test.tsx +++ /dev/null @@ -1,211 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { getGitlabProjects, importGitlabProject } from '../../../../api/alm-integrations'; -import { mockGitlabProject } from '../../../../helpers/mocks/alm-integrations'; -import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; -import { mockLocation, mockRouter } from '../../../../helpers/testMocks'; -import { waitAndUpdate } from '../../../../helpers/testUtils'; -import { AlmKeys } from '../../../../types/alm-settings'; -import GitlabProjectCreate from '../GitlabProjectCreate'; - -jest.mock('../../../../api/alm-integrations', () => ({ - getGitlabProjects: jest.fn().mockRejectedValue('error'), - importGitlabProject: jest.fn().mockRejectedValue('error'), -})); - -beforeEach(jest.clearAllMocks); - -const almSettingKey = 'gitlab-setting'; - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot(); -}); - -it('should fetch more projects and preserve search', async () => { - const projects = [ - mockGitlabProject({ id: '1' }), - mockGitlabProject({ id: '2' }), - mockGitlabProject({ id: '3' }), - mockGitlabProject({ id: '4' }), - mockGitlabProject({ id: '5' }), - mockGitlabProject({ id: '6' }), - ]; - (getGitlabProjects as jest.Mock) - .mockResolvedValueOnce({ - projects: projects.slice(0, 5), - projectsPaging: { - pageIndex: 1, - pageSize: 4, - total: 6, - }, - }) - .mockResolvedValueOnce({ - projects: projects.slice(5), - projectsPaging: { - pageIndex: 2, - pageSize: 4, - total: 6, - }, - }); - - const wrapper = shallowRender(); - - await wrapper.instance().handlePersonalAccessTokenCreated(); - wrapper.setState({ searchQuery: 'query' }); - - wrapper.instance().handleLoadMore(); - expect(wrapper.state().loadingMore).toBe(true); - - await waitAndUpdate(wrapper); - expect(wrapper.state().loadingMore).toBe(false); - expect(wrapper.state().projects).toEqual(projects); - - expect(getGitlabProjects).toHaveBeenCalledWith(expect.objectContaining({ query: 'query' })); -}); - -it('should search for projects', async () => { - const projects = [ - mockGitlabProject({ id: '1' }), - mockGitlabProject({ id: '2' }), - mockGitlabProject({ id: '3' }), - mockGitlabProject({ id: '4' }), - mockGitlabProject({ id: '5' }), - mockGitlabProject({ id: '6' }), - ]; - (getGitlabProjects as jest.Mock) - .mockResolvedValueOnce({ - projects, - projectsPaging: { - pageIndex: 1, - pageSize: 6, - total: 6, - }, - }) - .mockResolvedValueOnce({ - projects: projects.slice(3, 5), - projectsPaging: { - pageIndex: 1, - pageSize: 6, - total: 2, - }, - }); - const query = 'query'; - - const wrapper = shallowRender(); - await wrapper.instance().handlePersonalAccessTokenCreated(); - - wrapper.instance().handleSearch(query); - expect(wrapper.state().searching).toBe(true); - await waitAndUpdate(wrapper); - expect(wrapper.state().searching).toBe(false); - expect(wrapper.state().searchQuery).toBe(query); - expect(wrapper.state().projects).toEqual([projects[3], projects[4]]); - - expect(getGitlabProjects).toHaveBeenCalledWith(expect.objectContaining({ query })); -}); - -it('should import', async () => { - const projects = [mockGitlabProject({ id: '1' }), mockGitlabProject({ id: '2' })]; - (getGitlabProjects as jest.Mock).mockResolvedValueOnce({ - projects, - projectsPaging: { - pageIndex: 1, - pageSize: 6, - total: 2, - }, - }); - const createdProjectkey = 'imported_project_key'; - - (importGitlabProject as jest.Mock).mockResolvedValueOnce({ - project: { key: createdProjectkey }, - }); - - const onProjectCreate = jest.fn(); - - const wrapper = shallowRender({ onProjectCreate }); - await wrapper.instance().handlePersonalAccessTokenCreated(); - - wrapper.instance().handleImport(projects[1].id); - expect(wrapper.state().importingGitlabProjectId).toBe(projects[1].id); - - await waitAndUpdate(wrapper); - - expect(wrapper.state().importingGitlabProjectId).toBeUndefined(); - expect(onProjectCreate).toHaveBeenCalledWith(createdProjectkey); -}); - -it('should do nothing with missing settings', async () => { - const wrapper = shallowRender({ almInstances: [] }); - - await wrapper.instance().handleLoadMore(); - await wrapper.instance().handleSearch('whatever'); - await wrapper.instance().handlePersonalAccessTokenCreated(); - await wrapper.instance().handleImport('gitlab project id'); - - expect(getGitlabProjects).not.toHaveBeenCalled(); - expect(importGitlabProject).not.toHaveBeenCalled(); -}); - -it('should handle errors when fetching projects', async () => { - (getGitlabProjects as jest.Mock).mockRejectedValueOnce({}); - - const wrapper = shallowRender(); - await waitAndUpdate(wrapper); - await wrapper.instance().handlePersonalAccessTokenCreated(); - - expect(wrapper.state().resetPat).toBe(true); - expect(wrapper.state().showPersonalAccessTokenForm).toBe(true); -}); - -it('should handle errors when importing a project', async () => { - (importGitlabProject as jest.Mock).mockRejectedValueOnce({}); - (getGitlabProjects as jest.Mock).mockResolvedValueOnce({ - projects: [mockGitlabProject()], - projectsPaging: { - pageIndex: 1, - pageSize: 10, - total: 1, - }, - }); - - const wrapper = shallowRender(); - await wrapper.instance().handlePersonalAccessTokenCreated(); - - await wrapper.instance().handleImport('gitlabId'); - await waitAndUpdate(wrapper); - - expect(wrapper.state().showPersonalAccessTokenForm).toBe(true); -}); - -function shallowRender(props: Partial<GitlabProjectCreate['props']> = {}) { - return shallow<GitlabProjectCreate>( - <GitlabProjectCreate - canAdmin={false} - loadingBindings={false} - location={mockLocation()} - onProjectCreate={jest.fn()} - router={mockRouter()} - almInstances={[mockAlmSettingsInstance({ alm: AlmKeys.GitLab, key: almSettingKey })]} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectCreateRenderer-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectCreateRenderer-test.tsx deleted file mode 100644 index 3422a875696..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectCreateRenderer-test.tsx +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; -import { AlmKeys } from '../../../../types/alm-settings'; -import GitlabProjectCreateRenderer, { - GitlabProjectCreateRendererProps, -} from '../GitlabProjectCreateRenderer'; - -it('should render correctly', () => { - expect(shallowRender({ loading: true })).toMatchSnapshot('loading'); - expect(shallowRender({ almInstances: undefined })).toMatchSnapshot('invalid settings'); - expect(shallowRender({ almInstances: undefined })).toMatchSnapshot( - 'invalid settings, admin user' - ); - expect(shallowRender()).toMatchSnapshot('pat form'); - expect(shallowRender({ showPersonalAccessTokenForm: false })).toMatchSnapshot( - 'project selection form' - ); -}); - -function shallowRender(props: Partial<GitlabProjectCreateRendererProps> = {}) { - return shallow<GitlabProjectCreateRendererProps>( - <GitlabProjectCreateRenderer - canAdmin={false} - loading={false} - loadingMore={false} - onImport={jest.fn()} - onLoadMore={jest.fn()} - onPersonalAccessTokenCreated={jest.fn()} - onSearch={jest.fn()} - onSelectedAlmInstanceChange={jest.fn()} - projects={undefined} - projectsPaging={{ pageIndex: 1, pageSize: 30, total: 0 }} - searching={false} - searchQuery="" - resetPat={false} - showPersonalAccessTokenForm={true} - almInstances={[ - mockAlmSettingsInstance({ alm: AlmKeys.GitLab }), - mockAlmSettingsInstance({ alm: AlmKeys.GitLab }), - mockAlmSettingsInstance({ alm: AlmKeys.GitHub }), - ]} - selectedAlmInstance={mockAlmSettingsInstance({ alm: AlmKeys.GitLab })} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectSelectionForm-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectSelectionForm-test.tsx deleted file mode 100644 index b464e947bc0..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectSelectionForm-test.tsx +++ /dev/null @@ -1,98 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { Button } from '../../../../components/controls/buttons'; -import ListFooter from '../../../../components/controls/ListFooter'; -import SearchBox from '../../../../components/controls/SearchBox'; -import { mockGitlabProject } from '../../../../helpers/mocks/alm-integrations'; -import GitlabProjectSelectionForm, { - GitlabProjectSelectionFormProps, -} from '../GitlabProjectSelectionForm'; - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot('projects'); - - expect(shallowRender({ projects: undefined, projectsPaging: mockPaging() })).toMatchSnapshot( - 'undefined projects' - ); - expect(shallowRender({ projects: [], projectsPaging: mockPaging() })).toMatchSnapshot( - 'no projects' - ); - expect( - shallowRender({ projects: [], projectsPaging: mockPaging(), searchQuery: 'findme' }) - ).toMatchSnapshot('no projects when searching'); - - expect(shallowRender({ importingGitlabProjectId: '2' })).toMatchSnapshot('importing'); -}); - -describe('appropriate callback', () => { - const onImport = jest.fn(); - const onLoadMore = jest.fn(); - const onSearch = jest.fn(); - const wrapper = shallowRender({ onImport, onLoadMore, onSearch }); - - it('should be called when clicking to import', () => { - wrapper.find(Button).first().simulate('click'); - - expect(onImport).toHaveBeenCalled(); - }); - - it('should be assigned to the list footer', () => { - const { loadMore } = wrapper.find(ListFooter).first().props(); - - expect(loadMore).toBe(onLoadMore); - }); - - it('should be assigned to the search box', () => { - const { onChange } = wrapper.find(SearchBox).first().props(); - - expect(onChange).toBe(onSearch); - }); -}); - -function shallowRender(props: Partial<GitlabProjectSelectionFormProps> = {}) { - const projects = [ - mockGitlabProject(), - mockGitlabProject({ - id: '2', - sqProjectKey: 'already-imported', - sqProjectName: 'Already Imported', - }), - ]; - - return shallow<GitlabProjectSelectionFormProps>( - <GitlabProjectSelectionForm - loadingMore={false} - onImport={jest.fn()} - onLoadMore={jest.fn()} - onSearch={jest.fn()} - projects={projects} - projectsPaging={mockPaging(projects.length)} - searching={false} - searchQuery="" - {...props} - /> - ); -} - -function mockPaging(total = 0) { - return { total, pageIndex: 1, pageSize: 30 }; -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/PersonalAccessTokenForm-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/PersonalAccessTokenForm-test.tsx deleted file mode 100644 index 5ab0fec34d5..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/PersonalAccessTokenForm-test.tsx +++ /dev/null @@ -1,144 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { - checkPersonalAccessTokenIsValid, - setAlmPersonalAccessToken, -} from '../../../../api/alm-integrations'; -import { SubmitButton } from '../../../../components/controls/buttons'; -import { - mockAlmSettingsInstance, - mockBitbucketCloudAlmSettingsInstance, -} from '../../../../helpers/mocks/alm-settings'; -import { change, submit, waitAndUpdate } from '../../../../helpers/testUtils'; -import { AlmKeys } from '../../../../types/alm-settings'; -import PersonalAccessTokenForm from '../PersonalAccessTokenForm'; - -jest.mock('../../../../api/alm-integrations', () => ({ - checkPersonalAccessTokenIsValid: jest.fn().mockResolvedValue({ status: true }), - setAlmPersonalAccessToken: jest.fn().mockResolvedValue({}), -})); - -it('should render correctly', async () => { - expect(shallowRender()).toMatchSnapshot('no token needed'); - - (checkPersonalAccessTokenIsValid as jest.Mock).mockResolvedValueOnce({ status: false }); - let wrapper = shallowRender(); - await waitAndUpdate(wrapper); - expect(wrapper).toMatchSnapshot('bitbucket'); - - (checkPersonalAccessTokenIsValid as jest.Mock).mockResolvedValueOnce({ status: false }); - wrapper = shallowRender({ almSetting: mockBitbucketCloudAlmSettingsInstance() }); - await waitAndUpdate(wrapper); - expect(wrapper).toMatchSnapshot('bitbucket cloud'); - - (checkPersonalAccessTokenIsValid as jest.Mock).mockResolvedValueOnce({ status: false }); - wrapper = shallowRender({ - almSetting: mockAlmSettingsInstance({ alm: AlmKeys.GitLab, url: 'https://gitlab.com/api/v4' }), - }); - await waitAndUpdate(wrapper); - expect(wrapper).toMatchSnapshot('gitlab'); - - (checkPersonalAccessTokenIsValid as jest.Mock).mockResolvedValueOnce({ status: false }); - wrapper = shallowRender({ - almSetting: mockAlmSettingsInstance({ - alm: AlmKeys.GitLab, - url: 'https://gitlabapi.unexpectedurl.org', - }), - }); - await waitAndUpdate(wrapper); - expect(wrapper).toMatchSnapshot('gitlab with non-standard api path'); -}); - -it('should correctly handle form interactions', async () => { - const onPersonalAccessTokenCreated = jest.fn(); - const wrapper = shallowRender({ onPersonalAccessTokenCreated }); - - await waitAndUpdate(wrapper); - // Submit button disabled by default. - expect(wrapper.find(SubmitButton).prop('disabled')).toBe(true); - - // Submit button enabled if there's a value. - change(wrapper.find('input'), 'token'); - expect(wrapper.find(SubmitButton).prop('disabled')).toBe(false); - - // Expect correct calls to be made when submitting. - submit(wrapper.find('form')); - expect(onPersonalAccessTokenCreated).toHaveBeenCalled(); - expect(setAlmPersonalAccessToken).toHaveBeenCalledWith('key', 'token', undefined); -}); - -it('should correctly handle form for bitbucket interactions', async () => { - const onPersonalAccessTokenCreated = jest.fn(); - const wrapper = shallowRender({ - almSetting: mockBitbucketCloudAlmSettingsInstance(), - onPersonalAccessTokenCreated, - }); - - await waitAndUpdate(wrapper); - // Submit button disabled by default. - expect(wrapper.find(SubmitButton).prop('disabled')).toBe(true); - - change(wrapper.find('input#personal_access_token_validation'), 'token'); - expect(wrapper.find(SubmitButton).prop('disabled')).toBe(true); - - // Submit button enabled if there's a value. - change(wrapper.find('#username'), 'username'); - expect(wrapper.find(SubmitButton).prop('disabled')).toBe(false); - - // Expect correct calls to be made when submitting. - submit(wrapper.find('form')); - expect(onPersonalAccessTokenCreated).toHaveBeenCalled(); - expect(setAlmPersonalAccessToken).toHaveBeenCalledWith('key', 'token', 'username'); -}); - -it('should show error when issue', async () => { - (checkPersonalAccessTokenIsValid as jest.Mock).mockRejectedValueOnce({}); - const wrapper = shallowRender({ - almSetting: mockBitbucketCloudAlmSettingsInstance(), - }); - - await waitAndUpdate(wrapper); - - (checkPersonalAccessTokenIsValid as jest.Mock).mockRejectedValueOnce({}); - - change(wrapper.find('input#personal_access_token_validation'), 'token'); - change(wrapper.find('#username'), 'username'); - - // Expect correct calls to be made when submitting. - submit(wrapper.find('form')); - await waitAndUpdate(wrapper); - expect(wrapper).toMatchSnapshot('issue submitting token'); -}); - -function shallowRender(props: Partial<PersonalAccessTokenForm['props']> = {}) { - return shallow<PersonalAccessTokenForm>( - <PersonalAccessTokenForm - almSetting={mockAlmSettingsInstance({ - alm: AlmKeys.BitbucketServer, - url: 'http://www.example.com', - })} - onPersonalAccessTokenCreated={jest.fn()} - resetPat={false} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/WrongBindingCountAlert-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/WrongBindingCountAlert-test.tsx deleted file mode 100644 index 5d9b687841f..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/WrongBindingCountAlert-test.tsx +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { AlmKeys } from '../../../../types/alm-settings'; -import WrongBindingCountAlert, { WrongBindingCountAlertProps } from '../WrongBindingCountAlert'; - -it('should render correctly', () => { - expect(shallowRender({ canAdmin: true })).toMatchSnapshot('for admin'); - expect(shallowRender({ alm: AlmKeys.BitbucketServer })).toMatchSnapshot('bitbucket'); - expect(shallowRender({ alm: AlmKeys.GitLab })).toMatchSnapshot('gitlab'); -}); - -function shallowRender(props: Partial<WrongBindingCountAlertProps> = {}) { - return shallow( - <WrongBindingCountAlert alm={AlmKeys.BitbucketServer} canAdmin={false} {...props} /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketCloudProjectCreate-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketCloudProjectCreate-test.tsx.snap deleted file mode 100644 index efaf694bc72..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketCloudProjectCreate-test.tsx.snap +++ /dev/null @@ -1,54 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Should render correctly 1`] = ` -<BitbucketCloudProjectCreateRenderer - almInstances={Array []} - canAdmin={true} - isLastPage={true} - loading={false} - loadingMore={false} - onImport={[Function]} - onLoadMore={[Function]} - onPersonalAccessTokenCreated={[Function]} - onSearch={[Function]} - onSelectedAlmInstanceChange={[Function]} - repositories={Array []} - resetPat={false} - searchQuery="" - searching={false} - showPersonalAccessTokenForm={true} -/> -`; - -exports[`Should render correctly: Setting changeds 1`] = ` -<BitbucketCloudProjectCreateRenderer - almInstances={ - Array [ - Object { - "alm": "bitbucketcloud", - "key": "key", - }, - ] - } - canAdmin={true} - isLastPage={true} - loading={false} - loadingMore={false} - onImport={[Function]} - onLoadMore={[Function]} - onPersonalAccessTokenCreated={[Function]} - onSearch={[Function]} - onSelectedAlmInstanceChange={[Function]} - repositories={Array []} - resetPat={false} - searchQuery="" - searching={false} - selectedAlmInstance={ - Object { - "alm": "bitbucketcloud", - "key": "key", - } - } - showPersonalAccessTokenForm={true} -/> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketCloudProjectCreateRender-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketCloudProjectCreateRender-test.tsx.snap deleted file mode 100644 index d5d68483133..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketCloudProjectCreateRender-test.tsx.snap +++ /dev/null @@ -1,173 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Should render correctly 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/bitbucket.svg" - /> - onboarding.create_project.bitbucketcloud.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "bitbucketcloud", - "key": "key", - }, - ] - } - almKey="bitbucketcloud" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "bitbucketcloud", - "key": "key", - } - } - /> - <BitbucketCloudSearchForm - isLastPage={true} - loadingMore={false} - onImport={[MockFunction]} - onLoadMore={[MockFunction]} - onSearch={[MockFunction]} - searchQuery="" - searching={false} - /> -</Fragment> -`; - -exports[`Should render correctly: Loading... 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/bitbucket.svg" - /> - onboarding.create_project.bitbucketcloud.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "bitbucketcloud", - "key": "key", - }, - ] - } - almKey="bitbucketcloud" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "bitbucketcloud", - "key": "key", - } - } - /> - <i - className="spinner" - /> -</Fragment> -`; - -exports[`Should render correctly: Need App password 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/bitbucket.svg" - /> - onboarding.create_project.bitbucketcloud.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "bitbucketcloud", - "key": "key", - }, - ] - } - almKey="bitbucketcloud" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "bitbucketcloud", - "key": "key", - } - } - /> - <PersonalAccessTokenForm - almSetting={ - Object { - "alm": "bitbucketcloud", - "key": "key", - } - } - onPersonalAccessTokenCreated={[MockFunction]} - resetPat={false} - /> -</Fragment> -`; - -exports[`Should render correctly: Wrong config 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/bitbucket.svg" - /> - onboarding.create_project.bitbucketcloud.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "bitbucketcloud", - "key": "key", - }, - ] - } - almKey="bitbucketcloud" - onChangeConfig={[MockFunction]} - /> - <WrongBindingCountAlert - alm="bitbucketcloud" - canAdmin={false} - /> -</Fragment> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketCloudSearchForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketCloudSearchForm-test.tsx.snap deleted file mode 100644 index a788d858535..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketCloudSearchForm-test.tsx.snap +++ /dev/null @@ -1,482 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Should render correctly 1`] = ` -<Alert - className="spacer-top" - variant="warning" -> - <FormattedMessage - defaultMessage="onboarding.create_project.bitbucketcloud.no_projects" - id="onboarding.create_project.bitbucketcloud.no_projects" - values={ - Object { - "link": <ForwardRef(Link) - to={ - Object { - "pathname": "/projects/create", - "search": "?mode=bitbucketcloud&resetPat=1", - } - } - > - onboarding.create_project.update_your_token - </ForwardRef(Link)>, - } - } - /> -</Alert> -`; - -exports[`Should render correctly: Importing 1`] = ` -<div - className="boxed-group big-padded create-project-import" -> - <SearchBox - className="spacer" - loading={false} - minLength={3} - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_prompt" - /> - <hr /> - <table - className="data zebra zebra-hover" - > - <tbody> - <tr - key="1" - > - <td> - <Tooltip - overlay="import-slug" - > - <strong - className="project-name display-inline-block text-ellipsis" - > - Repo - </strong> - </Tooltip> - <br /> - <Tooltip - overlay="project" - > - <span - className="text-muted project-path display-inline-block text-ellipsis" - > - project - </span> - </Tooltip> - </td> - <td> - <ForwardRef(Link) - className="display-inline-flex-center big-spacer-right" - target="_blank" - to="https://bitbucket.org/worksapce/import-slug" - > - onboarding.create_project.bitbucketcloud.link - </ForwardRef(Link)> - </td> - <td - className="text-right" - > - <Button - disabled={true} - onClick={[Function]} - > - onboarding.create_project.set_up - <DeferredSpinner - className="spacer-left" - /> - </Button> - </td> - </tr> - <tr - key="1" - > - <td> - <Tooltip - overlay="project__repo" - > - <strong - className="project-name display-inline-block text-ellipsis" - > - <ForwardRef(Link) - to={ - Object { - "pathname": "/dashboard", - "search": "?id=sq-key", - } - } - > - <QualifierIcon - className="spacer-right" - qualifier="TRK" - /> - Repo - </ForwardRef(Link)> - </strong> - </Tooltip> - <br /> - <Tooltip - overlay="project" - > - <span - className="text-muted project-path display-inline-block text-ellipsis" - > - project - </span> - </Tooltip> - </td> - <td> - <ForwardRef(Link) - className="display-inline-flex-center big-spacer-right" - target="_blank" - to="https://bitbucket.org/worksapce/project__repo" - > - onboarding.create_project.bitbucketcloud.link - </ForwardRef(Link)> - </td> - <td> - <span - className="display-flex-center display-flex-justify-end already-set-up" - > - <CheckIcon - className="little-spacer-right" - size={12} - /> - onboarding.create_project.repository_imported - </span> - </td> - </tr> - </tbody> - </table> - <footer - className="spacer-top note text-center" - > - <Button - className="spacer-left" - data-test="show-more" - disabled={false} - onClick={[MockFunction]} - > - show_more - </Button> - </footer> -</div> -`; - -exports[`Should render correctly: Loading more 1`] = ` -<div - className="boxed-group big-padded create-project-import" -> - <SearchBox - className="spacer" - loading={false} - minLength={3} - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_prompt" - /> - <hr /> - <table - className="data zebra zebra-hover" - > - <tbody> - <tr - key="1" - > - <td> - <Tooltip - overlay="project__repo" - > - <strong - className="project-name display-inline-block text-ellipsis" - > - Repo - </strong> - </Tooltip> - <br /> - <Tooltip - overlay="project" - > - <span - className="text-muted project-path display-inline-block text-ellipsis" - > - project - </span> - </Tooltip> - </td> - <td> - <ForwardRef(Link) - className="display-inline-flex-center big-spacer-right" - target="_blank" - to="https://bitbucket.org/worksapce/project__repo" - > - onboarding.create_project.bitbucketcloud.link - </ForwardRef(Link)> - </td> - <td - className="text-right" - > - <Button - disabled={false} - onClick={[Function]} - > - onboarding.create_project.set_up - </Button> - </td> - </tr> - </tbody> - </table> - <footer - className="spacer-top note text-center" - > - <Button - className="spacer-left" - data-test="show-more" - disabled={true} - onClick={[MockFunction]} - > - show_more - </Button> - <DeferredSpinner - className="text-bottom spacer-left position-absolute" - /> - </footer> -</div> -`; - -exports[`Should render correctly: Searching 1`] = ` -<div - className="boxed-group big-padded create-project-import" -> - <SearchBox - className="spacer" - loading={true} - minLength={3} - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_prompt" - /> - <hr /> - <div - className="padded" - > - no_results - </div> - <footer - className="spacer-top note text-center" - > - <Button - className="spacer-left" - data-test="show-more" - disabled={false} - onClick={[MockFunction]} - > - show_more - </Button> - </footer> -</div> -`; - -exports[`Should render correctly: Show more 1`] = ` -<div - className="boxed-group big-padded create-project-import" -> - <SearchBox - className="spacer" - loading={false} - minLength={3} - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_prompt" - /> - <hr /> - <table - className="data zebra zebra-hover" - > - <tbody> - <tr - key="1" - > - <td> - <Tooltip - overlay="project__repo" - > - <strong - className="project-name display-inline-block text-ellipsis" - > - Repo - </strong> - </Tooltip> - <br /> - <Tooltip - overlay="project" - > - <span - className="text-muted project-path display-inline-block text-ellipsis" - > - project - </span> - </Tooltip> - </td> - <td> - <ForwardRef(Link) - className="display-inline-flex-center big-spacer-right" - target="_blank" - to="https://bitbucket.org/worksapce/project__repo" - > - onboarding.create_project.bitbucketcloud.link - </ForwardRef(Link)> - </td> - <td - className="text-right" - > - <Button - disabled={false} - onClick={[Function]} - > - onboarding.create_project.set_up - </Button> - </td> - </tr> - <tr - key="1" - > - <td> - <Tooltip - overlay="project__repo" - > - <strong - className="project-name display-inline-block text-ellipsis" - > - <ForwardRef(Link) - to={ - Object { - "pathname": "/dashboard", - "search": "?id=sq-key", - } - } - > - <QualifierIcon - className="spacer-right" - qualifier="TRK" - /> - Repo - </ForwardRef(Link)> - </strong> - </Tooltip> - <br /> - <Tooltip - overlay="project" - > - <span - className="text-muted project-path display-inline-block text-ellipsis" - > - project - </span> - </Tooltip> - </td> - <td> - <ForwardRef(Link) - className="display-inline-flex-center big-spacer-right" - target="_blank" - to="https://bitbucket.org/worksapce/project__repo" - > - onboarding.create_project.bitbucketcloud.link - </ForwardRef(Link)> - </td> - <td> - <span - className="display-flex-center display-flex-justify-end already-set-up" - > - <CheckIcon - className="little-spacer-right" - size={12} - /> - onboarding.create_project.repository_imported - </span> - </td> - </tr> - </tbody> - </table> - <footer - className="spacer-top note text-center" - > - <Button - className="spacer-left" - data-test="show-more" - disabled={false} - onClick={[MockFunction]} - > - show_more - </Button> - </footer> -</div> -`; - -exports[`Should render correctly: Show no more 1`] = ` -<div - className="boxed-group big-padded create-project-import" -> - <SearchBox - className="spacer" - loading={false} - minLength={3} - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_prompt" - /> - <hr /> - <table - className="data zebra zebra-hover" - > - <tbody> - <tr - key="1" - > - <td> - <Tooltip - overlay="project__repo" - > - <strong - className="project-name display-inline-block text-ellipsis" - > - Repo - </strong> - </Tooltip> - <br /> - <Tooltip - overlay="project" - > - <span - className="text-muted project-path display-inline-block text-ellipsis" - > - project - </span> - </Tooltip> - </td> - <td> - <ForwardRef(Link) - className="display-inline-flex-center big-spacer-right" - target="_blank" - to="https://bitbucket.org/worksapce/project__repo" - > - onboarding.create_project.bitbucketcloud.link - </ForwardRef(Link)> - </td> - <td - className="text-right" - > - <Button - disabled={false} - onClick={[Function]} - > - onboarding.create_project.set_up - </Button> - </td> - </tr> - </tbody> - </table> - <footer - className="spacer-top note text-center" - > - x_of_y_shown.1.1 - </footer> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketImportRepositoryForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketImportRepositoryForm-test.tsx.snap deleted file mode 100644 index 8292bfe2bba..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketImportRepositoryForm-test.tsx.snap +++ /dev/null @@ -1,148 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: default 1`] = ` -<div - className="create-project-import-bbs" -> - <SearchBox - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_repositories_by_name" - /> - <BitbucketRepositories - disableRepositories={false} - onSelectRepository={[MockFunction]} - projectRepositories={ - Object { - "project": Object { - "allShown": true, - "repositories": Array [ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - }, - Object { - "id": 2, - "name": "Bar", - "projectKey": "project", - "slug": "bar", - "sqProjectKey": "bar", - }, - ], - }, - } - } - projects={ - Array [ - Object { - "id": 1, - "key": "project", - "name": "Project", - }, - Object { - "id": 2, - "key": "project2", - "name": "Project 2", - }, - ] - } - /> -</div> -`; - -exports[`should render correctly: no projects 1`] = ` -<Alert - className="spacer-top" - variant="warning" -> - <FormattedMessage - defaultMessage="onboarding.create_project.no_bbs_projects" - id="onboarding.create_project.no_bbs_projects" - values={ - Object { - "link": <ForwardRef(Link) - to={ - Object { - "pathname": "/projects/create", - "search": "?mode=bitbucket&resetPat=1", - } - } - > - onboarding.create_project.update_your_token - </ForwardRef(Link)>, - } - } - /> -</Alert> -`; - -exports[`should render correctly: search results 1`] = ` -<div - className="create-project-import-bbs" -> - <SearchBox - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_repositories_by_name" - /> - <BitbucketSearchResults - disableRepositories={false} - onSelectRepository={[MockFunction]} - projects={ - Array [ - Object { - "id": 1, - "key": "project", - "name": "Project", - }, - Object { - "id": 2, - "key": "project2", - "name": "Project 2", - }, - ] - } - searchResults={ - Array [ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - }, - ] - } - searching={false} - /> -</div> -`; - -exports[`should render correctly: searching 1`] = ` -<div - className="create-project-import-bbs" -> - <SearchBox - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_repositories_by_name" - /> - <BitbucketSearchResults - disableRepositories={false} - onSelectRepository={[MockFunction]} - projects={ - Array [ - Object { - "id": 1, - "key": "project", - "name": "Project", - }, - Object { - "id": 2, - "key": "project2", - "name": "Project 2", - }, - ] - } - searching={true} - /> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectAccordion-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectAccordion-test.tsx.snap deleted file mode 100644 index 5c21a64e4e9..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectAccordion-test.tsx.snap +++ /dev/null @@ -1,455 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: closed 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom" - onClick={[MockFunction]} - open={false} - title={ - <h3> - Project - </h3> - } -/> -`; - -exports[`should render correctly: default 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom open" - onClick={[MockFunction]} - open={true} - title={ - <h3> - Project - </h3> - } -> - <div - className="display-flex-wrap" - > - <Radio - checked={false} - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo overflow-hidden" - key="1" - onCheck={[Function]} - value="1" - > - <strong - title="Repo" - > - Repo - </strong> - </Radio> - <div - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo" - key="2" - > - <CheckIcon - className="spacer-right" - fill="#00aa00" - size={14} - /> - <div - className="overflow-hidden" - > - <div - className="little-spacer-bottom" - > - <strong - title="Bar" - > - <ForwardRef(Link) - to={ - Object { - "pathname": "/dashboard", - "search": "?id=bar", - } - } - > - Bar - </ForwardRef(Link)> - </strong> - </div> - <em> - onboarding.create_project.repository_imported - </em> - </div> - </div> - </div> -</BoxedGroupAccordion> -`; - -exports[`should render correctly: disable options 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom open" - onClick={[MockFunction]} - open={true} - title={ - <h3> - Project - </h3> - } -> - <div - className="display-flex-wrap" - > - <Radio - checked={false} - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo overflow-hidden disabled" - key="1" - onCheck={[Function]} - value="1" - > - <strong - title="Repo" - > - Repo - </strong> - </Radio> - <div - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo" - key="2" - > - <CheckIcon - className="spacer-right" - fill="#00aa00" - size={14} - /> - <div - className="overflow-hidden" - > - <div - className="little-spacer-bottom" - > - <strong - title="Bar" - > - <ForwardRef(Link) - to={ - Object { - "pathname": "/dashboard", - "search": "?id=bar", - } - } - > - Bar - </ForwardRef(Link)> - </strong> - </div> - <em> - onboarding.create_project.repository_imported - </em> - </div> - </div> - </div> -</BoxedGroupAccordion> -`; - -exports[`should render correctly: no click handler 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom open not-clickable no-hover" - onClick={[Function]} - open={true} - title={ - <h3> - Project - </h3> - } -> - <div - className="display-flex-wrap" - > - <Radio - checked={false} - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo overflow-hidden" - key="1" - onCheck={[Function]} - value="1" - > - <strong - title="Repo" - > - Repo - </strong> - </Radio> - <div - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo" - key="2" - > - <CheckIcon - className="spacer-right" - fill="#00aa00" - size={14} - /> - <div - className="overflow-hidden" - > - <div - className="little-spacer-bottom" - > - <strong - title="Bar" - > - <ForwardRef(Link) - to={ - Object { - "pathname": "/dashboard", - "search": "?id=bar", - } - } - > - Bar - </ForwardRef(Link)> - </strong> - </div> - <em> - onboarding.create_project.repository_imported - </em> - </div> - </div> - </div> -</BoxedGroupAccordion> -`; - -exports[`should render correctly: no project info 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom open" - onClick={[MockFunction]} - open={true} - title={ - <h3> - search_results - </h3> - } -> - <div - className="display-flex-wrap" - > - <Radio - checked={false} - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo overflow-hidden" - key="1" - onCheck={[Function]} - value="1" - > - <strong - title="Repo" - > - Repo - </strong> - </Radio> - <div - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo" - key="2" - > - <CheckIcon - className="spacer-right" - fill="#00aa00" - size={14} - /> - <div - className="overflow-hidden" - > - <div - className="little-spacer-bottom" - > - <strong - title="Bar" - > - <ForwardRef(Link) - to={ - Object { - "pathname": "/dashboard", - "search": "?id=bar", - } - } - > - Bar - </ForwardRef(Link)> - </strong> - </div> - <em> - onboarding.create_project.repository_imported - </em> - </div> - </div> - </div> -</BoxedGroupAccordion> -`; - -exports[`should render correctly: no repos 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom open" - onClick={[MockFunction]} - open={true} - title={ - <h3> - Project - </h3> - } -> - <div - className="display-flex-wrap" - > - <Alert - variant="warning" - > - <FormattedMessage - defaultMessage="onboarding.create_project.no_bbs_repos" - id="onboarding.create_project.no_bbs_repos" - values={ - Object { - "link": <ForwardRef(Link) - to={ - Object { - "pathname": "/projects/create", - "search": "?mode=bitbucket&resetPat=1", - } - } - > - onboarding.create_project.update_your_token - </ForwardRef(Link)>, - } - } - /> - </Alert> - </div> -</BoxedGroupAccordion> -`; - -exports[`should render correctly: not showing all repos 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom open" - onClick={[MockFunction]} - open={true} - title={ - <h3> - Project - </h3> - } -> - <div - className="display-flex-wrap" - > - <Radio - checked={false} - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo overflow-hidden" - key="1" - onCheck={[Function]} - value="1" - > - <strong - title="Repo" - > - Repo - </strong> - </Radio> - <div - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo" - key="2" - > - <CheckIcon - className="spacer-right" - fill="#00aa00" - size={14} - /> - <div - className="overflow-hidden" - > - <div - className="little-spacer-bottom" - > - <strong - title="Bar" - > - <ForwardRef(Link) - to={ - Object { - "pathname": "/dashboard", - "search": "?id=bar", - } - } - > - Bar - </ForwardRef(Link)> - </strong> - </div> - <em> - onboarding.create_project.repository_imported - </em> - </div> - </div> - </div> - <Alert - variant="warning" - > - onboarding.create_project.only_showing_X_first_repos.2 - </Alert> -</BoxedGroupAccordion> -`; - -exports[`should render correctly: selected repo 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom open" - onClick={[MockFunction]} - open={true} - title={ - <h3> - Project - </h3> - } -> - <div - className="display-flex-wrap" - > - <Radio - checked={true} - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo overflow-hidden" - key="1" - onCheck={[Function]} - value="1" - > - <strong - title="Repo" - > - Repo - </strong> - </Radio> - <div - className="display-flex-start spacer-right spacer-bottom create-project-import-bbs-repo" - key="2" - > - <CheckIcon - className="spacer-right" - fill="#00aa00" - size={14} - /> - <div - className="overflow-hidden" - > - <div - className="little-spacer-bottom" - > - <strong - title="Bar" - > - <ForwardRef(Link) - to={ - Object { - "pathname": "/dashboard", - "search": "?id=bar", - } - } - > - Bar - </ForwardRef(Link)> - </strong> - </div> - <em> - onboarding.create_project.repository_imported - </em> - </div> - </div> - </div> -</BoxedGroupAccordion> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectCreate-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectCreate-test.tsx.snap deleted file mode 100644 index e168e70e45b..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectCreate-test.tsx.snap +++ /dev/null @@ -1,92 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` -<BitbucketProjectCreateRenderer - almInstances={ - Array [ - Object { - "alm": "bitbucket", - "key": "foo", - }, - ] - } - canAdmin={false} - importing={false} - loading={false} - onImportRepository={[Function]} - onPersonalAccessTokenCreated={[Function]} - onSearch={[Function]} - onSelectRepository={[Function]} - onSelectedAlmInstanceChange={[Function]} - resetPat={false} - searching={false} - selectedAlmInstance={ - Object { - "alm": "bitbucket", - "key": "foo", - } - } - showPersonalAccessTokenForm={true} -/> -`; - -exports[`should render correctly: No repository 1`] = ` -<BitbucketProjectCreateRenderer - almInstances={ - Array [ - Object { - "alm": "bitbucket", - "key": "foo", - }, - ] - } - canAdmin={false} - importing={false} - loading={false} - onImportRepository={[Function]} - onPersonalAccessTokenCreated={[Function]} - onSearch={[Function]} - onSelectRepository={[Function]} - onSelectedAlmInstanceChange={[Function]} - projects={ - Array [ - Object { - "id": 1, - "key": "project1", - "name": "Project 1", - }, - Object { - "id": 2, - "key": "project2", - "name": "Project", - }, - ] - } - resetPat={false} - searching={false} - selectedAlmInstance={ - Object { - "alm": "bitbucket", - "key": "foo", - } - } - showPersonalAccessTokenForm={false} -/> -`; - -exports[`should render correctly: No setting 1`] = ` -<BitbucketProjectCreateRenderer - almInstances={Array []} - canAdmin={false} - importing={false} - loading={false} - onImportRepository={[Function]} - onPersonalAccessTokenCreated={[Function]} - onSearch={[Function]} - onSelectRepository={[Function]} - onSelectedAlmInstanceChange={[Function]} - resetPat={false} - searching={false} - showPersonalAccessTokenForm={true} -/> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectCreateRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectCreateRenderer-test.tsx.snap deleted file mode 100644 index 6047821c001..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketProjectCreateRenderer-test.tsx.snap +++ /dev/null @@ -1,477 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: default 1`] = ` -<Fragment> - <CreateProjectPageHeader - additionalActions={ - <div - className="display-flex-center pull-right" - > - <DeferredSpinner - className="spacer-right" - loading={false} - /> - <Button - className="button-large button-primary" - disabled={true} - onClick={[MockFunction]} - > - onboarding.create_project.import_selected_repo - </Button> - </div> - } - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/bitbucket.svg" - /> - onboarding.create_project.from_bbs - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "bitbucket", - "key": "key", - }, - ] - } - almKey="bitbucket" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "bitbucket", - "key": "key", - } - } - /> - <BitbucketImportRepositoryForm - disableRepositories={false} - onSearch={[MockFunction]} - onSelectRepository={[MockFunction]} - projectRepositories={ - Object { - "foo": Object { - "allShown": true, - "repositories": Array [ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - }, - ], - }, - } - } - projects={ - Array [ - Object { - "id": 1, - "key": "foo", - "name": "Project", - }, - ] - } - searching={false} - /> -</Fragment> -`; - -exports[`should render correctly: importing 1`] = ` -<Fragment> - <CreateProjectPageHeader - additionalActions={ - <div - className="display-flex-center pull-right" - > - <DeferredSpinner - className="spacer-right" - loading={true} - /> - <Button - className="button-large button-primary" - disabled={true} - onClick={[MockFunction]} - > - onboarding.create_project.import_selected_repo - </Button> - </div> - } - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/bitbucket.svg" - /> - onboarding.create_project.from_bbs - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "bitbucket", - "key": "key", - }, - ] - } - almKey="bitbucket" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "bitbucket", - "key": "key", - } - } - /> - <BitbucketImportRepositoryForm - disableRepositories={true} - onSearch={[MockFunction]} - onSelectRepository={[MockFunction]} - projectRepositories={ - Object { - "foo": Object { - "allShown": true, - "repositories": Array [ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - }, - ], - }, - } - } - projects={ - Array [ - Object { - "id": 1, - "key": "foo", - "name": "Project", - }, - ] - } - searching={false} - /> -</Fragment> -`; - -exports[`should render correctly: invalid config, admin user 1`] = ` -<Fragment> - <CreateProjectPageHeader - additionalActions={ - <div - className="display-flex-center pull-right" - > - <DeferredSpinner - className="spacer-right" - loading={false} - /> - <Button - className="button-large button-primary" - disabled={true} - onClick={[MockFunction]} - > - onboarding.create_project.import_selected_repo - </Button> - </div> - } - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/bitbucket.svg" - /> - onboarding.create_project.from_bbs - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "bitbucket", - "key": "key", - }, - ] - } - almKey="bitbucket" - onChangeConfig={[MockFunction]} - /> - <WrongBindingCountAlert - alm="bitbucket" - canAdmin={true} - /> -</Fragment> -`; - -exports[`should render correctly: invalid config, regular user 1`] = ` -<Fragment> - <CreateProjectPageHeader - additionalActions={ - <div - className="display-flex-center pull-right" - > - <DeferredSpinner - className="spacer-right" - loading={false} - /> - <Button - className="button-large button-primary" - disabled={true} - onClick={[MockFunction]} - > - onboarding.create_project.import_selected_repo - </Button> - </div> - } - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/bitbucket.svg" - /> - onboarding.create_project.from_bbs - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "bitbucket", - "key": "key", - }, - ] - } - almKey="bitbucket" - onChangeConfig={[MockFunction]} - /> - <WrongBindingCountAlert - alm="bitbucket" - canAdmin={false} - /> -</Fragment> -`; - -exports[`should render correctly: loading 1`] = ` -<Fragment> - <CreateProjectPageHeader - additionalActions={ - <div - className="display-flex-center pull-right" - > - <DeferredSpinner - className="spacer-right" - loading={false} - /> - <Button - className="button-large button-primary" - disabled={true} - onClick={[MockFunction]} - > - onboarding.create_project.import_selected_repo - </Button> - </div> - } - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/bitbucket.svg" - /> - onboarding.create_project.from_bbs - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "bitbucket", - "key": "key", - }, - ] - } - almKey="bitbucket" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "bitbucket", - "key": "key", - } - } - /> - <i - className="spinner" - /> -</Fragment> -`; - -exports[`should render correctly: pat form 1`] = ` -<Fragment> - <CreateProjectPageHeader - additionalActions={false} - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/bitbucket.svg" - /> - onboarding.create_project.from_bbs - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "bitbucket", - "key": "key", - }, - ] - } - almKey="bitbucket" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "bitbucket", - "key": "key", - } - } - /> - <PersonalAccessTokenForm - almSetting={ - Object { - "alm": "bitbucket", - "key": "key", - } - } - onPersonalAccessTokenCreated={[MockFunction]} - resetPat={false} - /> -</Fragment> -`; - -exports[`should render correctly: selected repo 1`] = ` -<Fragment> - <CreateProjectPageHeader - additionalActions={ - <div - className="display-flex-center pull-right" - > - <DeferredSpinner - className="spacer-right" - loading={false} - /> - <Button - className="button-large button-primary" - disabled={false} - onClick={[MockFunction]} - > - onboarding.create_project.import_selected_repo - </Button> - </div> - } - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/bitbucket.svg" - /> - onboarding.create_project.from_bbs - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "bitbucket", - "key": "key", - }, - ] - } - almKey="bitbucket" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "bitbucket", - "key": "key", - } - } - /> - <BitbucketImportRepositoryForm - disableRepositories={false} - onSearch={[MockFunction]} - onSelectRepository={[MockFunction]} - projectRepositories={ - Object { - "foo": Object { - "allShown": true, - "repositories": Array [ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - }, - ], - }, - } - } - projects={ - Array [ - Object { - "id": 1, - "key": "foo", - "name": "Project", - }, - ] - } - searching={false} - selectedRepository={ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - } - } - /> -</Fragment> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketRepositories-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketRepositories-test.tsx.snap deleted file mode 100644 index 44c85577219..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketRepositories-test.tsx.snap +++ /dev/null @@ -1,248 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should correctly handle opening/closing accordions: 2nd opened 1`] = ` -<Fragment> - <div - className="overflow-hidden spacer-bottom" - > - <ButtonLink - className="pull-right" - onClick={[Function]} - > - collapse_all - </ButtonLink> - </div> - <BitbucketProjectAccordion - disableRepositories={false} - key="project" - onClick={[Function]} - onSelectRepository={[MockFunction]} - open={true} - project={ - Object { - "id": 1, - "key": "project", - "name": "Project", - } - } - repositories={ - Array [ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - }, - Object { - "id": 2, - "name": "Bar", - "projectKey": "project", - "slug": "bar", - "sqProjectKey": "bar", - }, - ] - } - showingAllRepositories={true} - /> - <BitbucketProjectAccordion - disableRepositories={false} - key="project2" - onClick={[Function]} - onSelectRepository={[MockFunction]} - open={true} - project={ - Object { - "id": 2, - "key": "project2", - "name": "Project 2", - } - } - repositories={Array []} - /> -</Fragment> -`; - -exports[`should render correctly: default 1`] = ` -<Fragment> - <div - className="overflow-hidden spacer-bottom" - > - <ButtonLink - className="pull-right" - onClick={[Function]} - > - expand_all - </ButtonLink> - </div> - <BitbucketProjectAccordion - disableRepositories={false} - key="project" - onClick={[Function]} - onSelectRepository={[MockFunction]} - open={true} - project={ - Object { - "id": 1, - "key": "project", - "name": "Project", - } - } - repositories={ - Array [ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - }, - Object { - "id": 2, - "name": "Bar", - "projectKey": "project", - "slug": "bar", - "sqProjectKey": "bar", - }, - ] - } - showingAllRepositories={true} - /> - <BitbucketProjectAccordion - disableRepositories={false} - key="project2" - onClick={[Function]} - onSelectRepository={[MockFunction]} - open={false} - project={ - Object { - "id": 2, - "key": "project2", - "name": "Project 2", - } - } - repositories={Array []} - /> -</Fragment> -`; - -exports[`should render correctly: no repos 1`] = ` -<Fragment> - <div - className="overflow-hidden spacer-bottom" - > - <ButtonLink - className="pull-right" - onClick={[Function]} - > - expand_all - </ButtonLink> - </div> - <BitbucketProjectAccordion - disableRepositories={false} - key="project" - onClick={[Function]} - onSelectRepository={[MockFunction]} - open={true} - project={ - Object { - "id": 1, - "key": "project", - "name": "Project", - } - } - repositories={Array []} - /> - <BitbucketProjectAccordion - disableRepositories={false} - key="project2" - onClick={[Function]} - onSelectRepository={[MockFunction]} - open={false} - project={ - Object { - "id": 2, - "key": "project2", - "name": "Project 2", - } - } - repositories={Array []} - /> -</Fragment> -`; - -exports[`should render correctly: selected repo 1`] = ` -<Fragment> - <div - className="overflow-hidden spacer-bottom" - > - <ButtonLink - className="pull-right" - onClick={[Function]} - > - expand_all - </ButtonLink> - </div> - <BitbucketProjectAccordion - disableRepositories={false} - key="project" - onClick={[Function]} - onSelectRepository={[MockFunction]} - open={true} - project={ - Object { - "id": 1, - "key": "project", - "name": "Project", - } - } - repositories={ - Array [ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - }, - Object { - "id": 2, - "name": "Bar", - "projectKey": "project", - "slug": "bar", - "sqProjectKey": "bar", - }, - ] - } - selectedRepository={ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - } - } - showingAllRepositories={true} - /> - <BitbucketProjectAccordion - disableRepositories={false} - key="project2" - onClick={[Function]} - onSelectRepository={[MockFunction]} - open={false} - project={ - Object { - "id": 2, - "key": "project2", - "name": "Project 2", - } - } - repositories={Array []} - selectedRepository={ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - } - } - /> -</Fragment> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketSearchResults-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketSearchResults-test.tsx.snap deleted file mode 100644 index b9f80fb1ed6..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/BitbucketSearchResults-test.tsx.snap +++ /dev/null @@ -1,106 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: default 1`] = ` -<div - className="big-spacer-top" -> - <DeferredSpinner - loading={false} - > - <BitbucketProjectAccordion - disableRepositories={false} - key="project" - onSelectRepository={[MockFunction]} - open={true} - project={ - Object { - "id": 1, - "key": "project", - "name": "Project", - } - } - repositories={ - Array [ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - }, - ] - } - showingAllRepositories={true} - /> - </DeferredSpinner> -</div> -`; - -exports[`should render correctly: no results 1`] = ` -<Alert - className="big-spacer-top" - variant="warning" -> - onboarding.create_project.no_bbs_repos.filter -</Alert> -`; - -exports[`should render correctly: searching 1`] = ` -<div - className="big-spacer-top" -> - <DeferredSpinner - loading={true} - /> -</div> -`; - -exports[`should render correctly: unknown project in search results 1`] = ` -<div - className="big-spacer-top" -> - <DeferredSpinner - loading={false} - > - <BitbucketProjectAccordion - disableRepositories={false} - onSelectRepository={[MockFunction]} - open={true} - repositories={ - Array [ - Object { - "id": 1, - "name": "Repo", - "projectKey": "unknown", - "slug": "project__repo", - }, - ] - } - showingAllRepositories={true} - /> - <BitbucketProjectAccordion - disableRepositories={false} - key="project" - onSelectRepository={[MockFunction]} - open={true} - project={ - Object { - "id": 1, - "key": "project", - "name": "Project", - } - } - repositories={ - Array [ - Object { - "id": 1, - "name": "Repo", - "projectKey": "project", - "slug": "project__repo", - }, - ] - } - showingAllRepositories={true} - /> - </DeferredSpinner> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/CreateProjectModeSelection-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/CreateProjectModeSelection-test.tsx.snap deleted file mode 100644 index 36a8a852f6b..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/CreateProjectModeSelection-test.tsx.snap +++ /dev/null @@ -1,972 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: default 1`] = ` -<Fragment> - <h1 - className="huge-spacer-top huge-spacer-bottom" - > - onboarding.create_project.select_method - </h1> - <p> - onboarding.create_project.select_method.devops_platform - </p> - <div - className="big-spacer-top huge-spacer-bottom display-flex-center" - > - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/azure.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.azure - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucket - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucketcloud - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/github.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.github - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/gitlab.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.gitlab - </div> - </button> - </div> - </div> - <p - className="big-spacer-bottom" - > - onboarding.create_project.select_method.manually - </p> - <button - className="button button-huge display-flex-column create-project-mode-type-manual" - onClick={[Function]} - type="button" - > - <ChevronsIcon - size={50} - /> - <div - className="medium big-spacer-top" - > - onboarding.create_project.select_method.manual - </div> - </button> -</Fragment> -`; - -exports[`should render correctly: invalid configs, admin 1`] = ` -<Fragment> - <h1 - className="huge-spacer-top huge-spacer-bottom" - > - onboarding.create_project.select_method - </h1> - <p> - onboarding.create_project.select_method.devops_platform - </p> - <div - className="big-spacer-top huge-spacer-bottom display-flex-center" - > - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/azure.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.azure - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucket - </div> - <p - className="text-muted small spacer-top" - style={ - Object { - "lineHeight": 1.5, - } - } - > - onboarding.create_project.alm_not_configured.admin - </p> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucketcloud - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/github.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.github - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/gitlab.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.gitlab - </div> - </button> - </div> - </div> - <p - className="big-spacer-bottom" - > - onboarding.create_project.select_method.manually - </p> - <button - className="button button-huge display-flex-column create-project-mode-type-manual" - onClick={[Function]} - type="button" - > - <ChevronsIcon - size={50} - /> - <div - className="medium big-spacer-top" - > - onboarding.create_project.select_method.manual - </div> - </button> -</Fragment> -`; - -exports[`should render correctly: invalid configs, admin 2`] = ` -<Fragment> - <h1 - className="huge-spacer-top huge-spacer-bottom" - > - onboarding.create_project.select_method - </h1> - <p> - onboarding.create_project.select_method.devops_platform - </p> - <div - className="big-spacer-top huge-spacer-bottom display-flex-center" - > - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/azure.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.azure - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucket - </div> - <p - className="text-muted small spacer-top" - style={ - Object { - "lineHeight": 1.5, - } - } - > - onboarding.create_project.alm_not_configured.admin - </p> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucketcloud - </div> - <p - className="text-muted small spacer-top" - style={ - Object { - "lineHeight": 1.5, - } - } - > - onboarding.create_project.alm_not_configured.admin - </p> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/github.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.github - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/gitlab.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.gitlab - </div> - </button> - </div> - </div> - <p - className="big-spacer-bottom" - > - onboarding.create_project.select_method.manually - </p> - <button - className="button button-huge display-flex-column create-project-mode-type-manual" - onClick={[Function]} - type="button" - > - <ChevronsIcon - size={50} - /> - <div - className="medium big-spacer-top" - > - onboarding.create_project.select_method.manual - </div> - </button> -</Fragment> -`; - -exports[`should render correctly: invalid configs, not admin 1`] = ` -<Fragment> - <h1 - className="huge-spacer-top huge-spacer-bottom" - > - onboarding.create_project.select_method - </h1> - <p> - onboarding.create_project.select_method.devops_platform - </p> - <div - className="big-spacer-top huge-spacer-bottom display-flex-center" - > - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/azure.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.azure - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm disabled big-spacer-right" - disabled={true} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucket - </div> - <p - className="text-muted small spacer-top" - style={ - Object { - "lineHeight": 1.5, - } - } - > - onboarding.create_project.alm_not_configured - </p> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucketcloud - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/github.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.github - </div> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/gitlab.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.gitlab - </div> - </button> - </div> - </div> - <p - className="big-spacer-bottom" - > - onboarding.create_project.select_method.manually - </p> - <button - className="button button-huge display-flex-column create-project-mode-type-manual" - onClick={[Function]} - type="button" - > - <ChevronsIcon - size={50} - /> - <div - className="medium big-spacer-top" - > - onboarding.create_project.select_method.manual - </div> - </button> -</Fragment> -`; - -exports[`should render correctly: loading instances 1`] = ` -<Fragment> - <h1 - className="huge-spacer-top huge-spacer-bottom" - > - onboarding.create_project.select_method - </h1> - <p> - onboarding.create_project.select_method.devops_platform - </p> - <div - className="big-spacer-top huge-spacer-bottom display-flex-center" - > - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm disabled big-spacer-right" - disabled={true} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/azure.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.azure - </div> - <span> - onboarding.create_project.check_alm_supported - <i - className="little-spacer-left spinner" - /> - </span> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm disabled big-spacer-right" - disabled={true} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucket - </div> - <span> - onboarding.create_project.check_alm_supported - <i - className="little-spacer-left spinner" - /> - </span> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm disabled big-spacer-right" - disabled={true} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucketcloud - </div> - <span> - onboarding.create_project.check_alm_supported - <i - className="little-spacer-left spinner" - /> - </span> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm disabled big-spacer-right" - disabled={true} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/github.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.github - </div> - <span> - onboarding.create_project.check_alm_supported - <i - className="little-spacer-left spinner" - /> - </span> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm disabled" - disabled={true} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/gitlab.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.gitlab - </div> - <span> - onboarding.create_project.check_alm_supported - <i - className="little-spacer-left spinner" - /> - </span> - </button> - </div> - </div> - <p - className="big-spacer-bottom" - > - onboarding.create_project.select_method.manually - </p> - <button - className="button button-huge display-flex-column create-project-mode-type-manual" - onClick={[Function]} - type="button" - > - <ChevronsIcon - size={50} - /> - <div - className="medium big-spacer-top" - > - onboarding.create_project.select_method.manual - </div> - </button> -</Fragment> -`; - -exports[`should render correctly: no alm conf yet, admin 1`] = ` -<Fragment> - <h1 - className="huge-spacer-top huge-spacer-bottom" - > - onboarding.create_project.select_method - </h1> - <p> - onboarding.create_project.select_method.devops_platform - </p> - <p - className="spacer-top" - > - onboarding.create_project.select_method.no_alm_yet.admin - </p> - <div - className="big-spacer-top huge-spacer-bottom display-flex-center" - > - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/azure.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.azure - </div> - <p - className="text-muted small spacer-top" - style={ - Object { - "lineHeight": 1.5, - } - } - > - onboarding.create_project.alm_not_configured.admin - </p> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucket - </div> - <p - className="text-muted small spacer-top" - style={ - Object { - "lineHeight": 1.5, - } - } - > - onboarding.create_project.alm_not_configured.admin - </p> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/bitbucket.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.bitbucketcloud - </div> - <p - className="text-muted small spacer-top" - style={ - Object { - "lineHeight": 1.5, - } - } - > - onboarding.create_project.alm_not_configured.admin - </p> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm big-spacer-right" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/github.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.github - </div> - <p - className="text-muted small spacer-top" - style={ - Object { - "lineHeight": 1.5, - } - } - > - onboarding.create_project.alm_not_configured.admin - </p> - </button> - </div> - <div - className="display-flex-column" - > - <button - className="button button-huge display-flex-column create-project-mode-type-alm" - disabled={false} - onClick={[Function]} - type="button" - > - <img - alt="" - height={50} - src="/images/alm/gitlab.svg" - /> - <div - className="medium big-spacer-top abs-height-50 display-flex-center" - > - onboarding.create_project.select_method.gitlab - </div> - <p - className="text-muted small spacer-top" - style={ - Object { - "lineHeight": 1.5, - } - } - > - onboarding.create_project.alm_not_configured.admin - </p> - </button> - </div> - </div> - <p - className="big-spacer-bottom" - > - onboarding.create_project.select_method.manually - </p> - <button - className="button button-huge display-flex-column create-project-mode-type-manual" - onClick={[Function]} - type="button" - > - <ChevronsIcon - size={50} - /> - <div - className="medium big-spacer-top" - > - onboarding.create_project.select_method.manual - </div> - </button> -</Fragment> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/CreateProjectPage-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/CreateProjectPage-test.tsx.snap deleted file mode 100644 index 6ec13628e53..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/CreateProjectPage-test.tsx.snap +++ /dev/null @@ -1,355 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render alm configuration creation correctly 1`] = ` -<Fragment> - <Helmet - defer={true} - encodeSpecialCharacters={true} - prioritizeSeoTags={false} - title="onboarding.create_project.select_method" - titleTemplate="%s" - /> - <A11ySkipTarget - anchor="create_project_main" - /> - <div - className="page page-limited huge-spacer-bottom position-relative" - id="create-project" - > - <withAppStateContext(CreateProjectModeSelection) - almCounts={ - Object { - "azure": 0, - "bitbucket": 0, - "bitbucketcloud": 0, - "github": 0, - "gitlab": 0, - } - } - loadingBindings={true} - onConfigMode={[Function]} - onSelectMode={[Function]} - /> - <AlmBindingDefinitionForm - afterSubmit={[Function]} - alm="azure" - alreadyHaveInstanceConfigured={false} - enforceValidation={true} - onCancel={[Function]} - /> - </div> -</Fragment> -`; - -exports[`should render correctly 1`] = ` -<Fragment> - <Helmet - defer={true} - encodeSpecialCharacters={true} - prioritizeSeoTags={false} - title="onboarding.create_project.select_method" - titleTemplate="%s" - /> - <A11ySkipTarget - anchor="create_project_main" - /> - <div - className="page page-limited huge-spacer-bottom position-relative" - id="create-project" - > - <withAppStateContext(CreateProjectModeSelection) - almCounts={ - Object { - "azure": 0, - "bitbucket": 0, - "bitbucketcloud": 0, - "github": 0, - "gitlab": 0, - } - } - loadingBindings={true} - onConfigMode={[Function]} - onSelectMode={[Function]} - /> - </div> -</Fragment> -`; - -exports[`should render correctly for azure mode 1`] = ` -<Fragment> - <Helmet - defer={true} - encodeSpecialCharacters={true} - prioritizeSeoTags={false} - title="onboarding.create_project.select_method" - titleTemplate="%s" - /> - <A11ySkipTarget - anchor="create_project_main" - /> - <div - className="page page-limited huge-spacer-bottom position-relative" - id="create-project" - > - <AzureProjectCreate - almInstances={Array []} - canAdmin={false} - loadingBindings={true} - location={ - Object { - "hash": "", - "key": "key", - "pathname": "/path", - "query": Object { - "mode": "azure", - }, - "search": "", - "state": Object {}, - } - } - onProjectCreate={[Function]} - router={ - Object { - "createHref": [MockFunction], - "createPath": [MockFunction], - "go": [MockFunction], - "goBack": [MockFunction], - "goForward": [MockFunction], - "isActive": [MockFunction], - "push": [MockFunction], - "replace": [MockFunction], - "setRouteLeaveHook": [MockFunction], - } - } - /> - </div> -</Fragment> -`; - -exports[`should render correctly for bitbucket mode 1`] = ` -<Fragment> - <Helmet - defer={true} - encodeSpecialCharacters={true} - prioritizeSeoTags={false} - title="onboarding.create_project.select_method" - titleTemplate="%s" - /> - <A11ySkipTarget - anchor="create_project_main" - /> - <div - className="page page-limited huge-spacer-bottom position-relative" - id="create-project" - > - <BitbucketProjectCreate - almInstances={Array []} - canAdmin={false} - loadingBindings={true} - location={ - Object { - "hash": "", - "key": "key", - "pathname": "/path", - "query": Object { - "mode": "bitbucket", - }, - "search": "", - "state": Object {}, - } - } - onProjectCreate={[Function]} - router={ - Object { - "createHref": [MockFunction], - "createPath": [MockFunction], - "go": [MockFunction], - "goBack": [MockFunction], - "goForward": [MockFunction], - "isActive": [MockFunction], - "push": [MockFunction], - "replace": [MockFunction], - "setRouteLeaveHook": [MockFunction], - } - } - /> - </div> -</Fragment> -`; - -exports[`should render correctly for bitbucketcloud mode 1`] = ` -<Fragment> - <Helmet - defer={true} - encodeSpecialCharacters={true} - prioritizeSeoTags={false} - title="onboarding.create_project.select_method" - titleTemplate="%s" - /> - <A11ySkipTarget - anchor="create_project_main" - /> - <div - className="page page-limited huge-spacer-bottom position-relative" - id="create-project" - > - <BitbucketCloudProjectCreate - almInstances={Array []} - canAdmin={false} - loadingBindings={true} - location={ - Object { - "hash": "", - "key": "key", - "pathname": "/path", - "query": Object { - "mode": "bitbucketcloud", - }, - "search": "", - "state": Object {}, - } - } - onProjectCreate={[Function]} - router={ - Object { - "createHref": [MockFunction], - "createPath": [MockFunction], - "go": [MockFunction], - "goBack": [MockFunction], - "goForward": [MockFunction], - "isActive": [MockFunction], - "push": [MockFunction], - "replace": [MockFunction], - "setRouteLeaveHook": [MockFunction], - } - } - /> - </div> -</Fragment> -`; - -exports[`should render correctly for github mode 1`] = ` -<Fragment> - <Helmet - defer={true} - encodeSpecialCharacters={true} - prioritizeSeoTags={false} - title="onboarding.create_project.select_method" - titleTemplate="%s" - /> - <A11ySkipTarget - anchor="create_project_main" - /> - <div - className="page page-limited huge-spacer-bottom position-relative" - id="create-project" - > - <GitHubProjectCreate - almInstances={Array []} - canAdmin={false} - loadingBindings={true} - location={ - Object { - "hash": "", - "key": "key", - "pathname": "/path", - "query": Object { - "mode": "github", - }, - "search": "", - "state": Object {}, - } - } - onProjectCreate={[Function]} - router={ - Object { - "createHref": [MockFunction], - "createPath": [MockFunction], - "go": [MockFunction], - "goBack": [MockFunction], - "goForward": [MockFunction], - "isActive": [MockFunction], - "push": [MockFunction], - "replace": [MockFunction], - "setRouteLeaveHook": [MockFunction], - } - } - /> - </div> -</Fragment> -`; - -exports[`should render correctly for gitlab mode 1`] = ` -<Fragment> - <Helmet - defer={true} - encodeSpecialCharacters={true} - prioritizeSeoTags={false} - title="onboarding.create_project.select_method" - titleTemplate="%s" - /> - <A11ySkipTarget - anchor="create_project_main" - /> - <div - className="page page-limited huge-spacer-bottom position-relative" - id="create-project" - > - <GitlabProjectCreate - almInstances={Array []} - canAdmin={false} - loadingBindings={true} - location={ - Object { - "hash": "", - "key": "key", - "pathname": "/path", - "query": Object { - "mode": "gitlab", - }, - "search": "", - "state": Object {}, - } - } - onProjectCreate={[Function]} - router={ - Object { - "createHref": [MockFunction], - "createPath": [MockFunction], - "go": [MockFunction], - "goBack": [MockFunction], - "goForward": [MockFunction], - "isActive": [MockFunction], - "push": [MockFunction], - "replace": [MockFunction], - "setRouteLeaveHook": [MockFunction], - } - } - /> - </div> -</Fragment> -`; - -exports[`should render correctly for manual mode 1`] = ` -<Fragment> - <Helmet - defer={true} - encodeSpecialCharacters={true} - prioritizeSeoTags={false} - title="onboarding.create_project.select_method" - titleTemplate="%s" - /> - <A11ySkipTarget - anchor="create_project_main" - /> - <div - className="page page-limited huge-spacer-bottom position-relative" - id="create-project" - > - <ManualProjectCreate - branchesEnabled={false} - onProjectCreate={[Function]} - /> - </div> -</Fragment> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/GitlabProjectCreate-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/GitlabProjectCreate-test.tsx.snap deleted file mode 100644 index 1fe927da52e..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/GitlabProjectCreate-test.tsx.snap +++ /dev/null @@ -1,39 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` -<GitlabProjectCreateRenderer - almInstances={ - Array [ - Object { - "alm": "gitlab", - "key": "gitlab-setting", - }, - ] - } - canAdmin={false} - loading={false} - loadingMore={false} - onImport={[Function]} - onLoadMore={[Function]} - onPersonalAccessTokenCreated={[Function]} - onSearch={[Function]} - onSelectedAlmInstanceChange={[Function]} - projectsPaging={ - Object { - "pageIndex": 1, - "pageSize": 30, - "total": 0, - } - } - resetPat={false} - searchQuery="" - searching={false} - selectedAlmInstance={ - Object { - "alm": "gitlab", - "key": "gitlab-setting", - } - } - showPersonalAccessTokenForm={true} -/> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/GitlabProjectCreateRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/GitlabProjectCreateRenderer-test.tsx.snap deleted file mode 100644 index 6f4f4831744..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/GitlabProjectCreateRenderer-test.tsx.snap +++ /dev/null @@ -1,247 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: invalid settings 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/gitlab.svg" - /> - onboarding.create_project.gitlab.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almKey="gitlab" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "gitlab", - "key": "key", - } - } - /> - <PersonalAccessTokenForm - almSetting={ - Object { - "alm": "gitlab", - "key": "key", - } - } - onPersonalAccessTokenCreated={[MockFunction]} - resetPat={false} - /> -</Fragment> -`; - -exports[`should render correctly: invalid settings, admin user 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/gitlab.svg" - /> - onboarding.create_project.gitlab.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almKey="gitlab" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "gitlab", - "key": "key", - } - } - /> - <PersonalAccessTokenForm - almSetting={ - Object { - "alm": "gitlab", - "key": "key", - } - } - onPersonalAccessTokenCreated={[MockFunction]} - resetPat={false} - /> -</Fragment> -`; - -exports[`should render correctly: loading 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/gitlab.svg" - /> - onboarding.create_project.gitlab.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "gitlab", - "key": "key", - }, - Object { - "alm": "gitlab", - "key": "key", - }, - Object { - "alm": "github", - "key": "key", - }, - ] - } - almKey="gitlab" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "gitlab", - "key": "key", - } - } - /> - <i - className="spinner" - /> -</Fragment> -`; - -exports[`should render correctly: pat form 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/gitlab.svg" - /> - onboarding.create_project.gitlab.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "gitlab", - "key": "key", - }, - Object { - "alm": "gitlab", - "key": "key", - }, - Object { - "alm": "github", - "key": "key", - }, - ] - } - almKey="gitlab" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "gitlab", - "key": "key", - } - } - /> - <PersonalAccessTokenForm - almSetting={ - Object { - "alm": "gitlab", - "key": "key", - } - } - onPersonalAccessTokenCreated={[MockFunction]} - resetPat={false} - /> -</Fragment> -`; - -exports[`should render correctly: project selection form 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/gitlab.svg" - /> - onboarding.create_project.gitlab.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "gitlab", - "key": "key", - }, - Object { - "alm": "gitlab", - "key": "key", - }, - Object { - "alm": "github", - "key": "key", - }, - ] - } - almKey="gitlab" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "gitlab", - "key": "key", - } - } - /> - <GitlabProjectSelectionForm - loadingMore={false} - onImport={[MockFunction]} - onLoadMore={[MockFunction]} - onSearch={[MockFunction]} - projectsPaging={ - Object { - "pageIndex": 1, - "pageSize": 30, - "total": 0, - } - } - searchQuery="" - searching={false} - /> -</Fragment> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/GitlabProjectSelectionForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/GitlabProjectSelectionForm-test.tsx.snap deleted file mode 100644 index 35a35f027d0..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/GitlabProjectSelectionForm-test.tsx.snap +++ /dev/null @@ -1,340 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: importing 1`] = ` -<div - className="boxed-group big-padded create-project-import" -> - <SearchBox - className="spacer" - loading={false} - minLength={3} - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_prompt" - /> - <hr /> - <table - className="data zebra zebra-hover" - > - <tbody> - <tr - key="id1234" - > - <td> - <Tooltip - overlay="awesome-project-exclamation" - > - <strong - className="project-name display-inline-block text-ellipsis" - > - Awesome Project ! - </strong> - </Tooltip> - <br /> - <Tooltip - overlay="company/best-projects" - > - <span - className="text-muted project-path display-inline-block text-ellipsis" - > - Company / Best Projects - </span> - </Tooltip> - </td> - <td> - <ForwardRef(Link) - className="display-inline-flex-center big-spacer-right" - target="_blank" - to="https://gitlab.company.com/best-projects/awesome-project-exclamation" - > - onboarding.create_project.gitlab.link - </ForwardRef(Link)> - </td> - <td - className="text-right" - > - <Button - disabled={true} - onClick={[Function]} - > - onboarding.create_project.set_up - </Button> - </td> - </tr> - <tr - key="2" - > - <td> - <Tooltip - overlay="awesome-project-exclamation" - > - <strong - className="project-name display-inline-block text-ellipsis" - > - <ForwardRef(Link) - to={ - Object { - "pathname": "/dashboard", - "search": "?id=already-imported", - } - } - > - <QualifierIcon - className="spacer-right" - qualifier="TRK" - /> - Already Imported - </ForwardRef(Link)> - </strong> - </Tooltip> - <br /> - <Tooltip - overlay="company/best-projects" - > - <span - className="text-muted project-path display-inline-block text-ellipsis" - > - Company / Best Projects - </span> - </Tooltip> - </td> - <td> - <ForwardRef(Link) - className="display-inline-flex-center big-spacer-right" - target="_blank" - to="https://gitlab.company.com/best-projects/awesome-project-exclamation" - > - onboarding.create_project.gitlab.link - </ForwardRef(Link)> - </td> - <td> - <span - className="display-flex-center display-flex-justify-end already-set-up" - > - <CheckIcon - className="little-spacer-right" - size={12} - /> - onboarding.create_project.repository_imported - </span> - </td> - </tr> - </tbody> - </table> - <ListFooter - count={2} - loadMore={[MockFunction]} - loading={false} - pageSize={30} - total={2} - /> -</div> -`; - -exports[`should render correctly: no projects 1`] = ` -<Alert - className="spacer-top" - variant="warning" -> - <FormattedMessage - defaultMessage="onboarding.create_project.gitlab.no_projects" - id="onboarding.create_project.gitlab.no_projects" - values={ - Object { - "link": <ForwardRef(Link) - to={ - Object { - "pathname": "/projects/create", - "search": "?mode=gitlab&resetPat=1", - } - } - > - onboarding.create_project.update_your_token - </ForwardRef(Link)>, - } - } - /> -</Alert> -`; - -exports[`should render correctly: no projects when searching 1`] = ` -<div - className="boxed-group big-padded create-project-import" -> - <SearchBox - className="spacer" - loading={false} - minLength={3} - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_prompt" - /> - <hr /> - <div - className="padded" - > - no_results - </div> - <ListFooter - count={0} - loadMore={[MockFunction]} - loading={false} - pageSize={30} - total={0} - /> -</div> -`; - -exports[`should render correctly: projects 1`] = ` -<div - className="boxed-group big-padded create-project-import" -> - <SearchBox - className="spacer" - loading={false} - minLength={3} - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_prompt" - /> - <hr /> - <table - className="data zebra zebra-hover" - > - <tbody> - <tr - key="id1234" - > - <td> - <Tooltip - overlay="awesome-project-exclamation" - > - <strong - className="project-name display-inline-block text-ellipsis" - > - Awesome Project ! - </strong> - </Tooltip> - <br /> - <Tooltip - overlay="company/best-projects" - > - <span - className="text-muted project-path display-inline-block text-ellipsis" - > - Company / Best Projects - </span> - </Tooltip> - </td> - <td> - <ForwardRef(Link) - className="display-inline-flex-center big-spacer-right" - target="_blank" - to="https://gitlab.company.com/best-projects/awesome-project-exclamation" - > - onboarding.create_project.gitlab.link - </ForwardRef(Link)> - </td> - <td - className="text-right" - > - <Button - disabled={false} - onClick={[Function]} - > - onboarding.create_project.set_up - </Button> - </td> - </tr> - <tr - key="2" - > - <td> - <Tooltip - overlay="awesome-project-exclamation" - > - <strong - className="project-name display-inline-block text-ellipsis" - > - <ForwardRef(Link) - to={ - Object { - "pathname": "/dashboard", - "search": "?id=already-imported", - } - } - > - <QualifierIcon - className="spacer-right" - qualifier="TRK" - /> - Already Imported - </ForwardRef(Link)> - </strong> - </Tooltip> - <br /> - <Tooltip - overlay="company/best-projects" - > - <span - className="text-muted project-path display-inline-block text-ellipsis" - > - Company / Best Projects - </span> - </Tooltip> - </td> - <td> - <ForwardRef(Link) - className="display-inline-flex-center big-spacer-right" - target="_blank" - to="https://gitlab.company.com/best-projects/awesome-project-exclamation" - > - onboarding.create_project.gitlab.link - </ForwardRef(Link)> - </td> - <td> - <span - className="display-flex-center display-flex-justify-end already-set-up" - > - <CheckIcon - className="little-spacer-right" - size={12} - /> - onboarding.create_project.repository_imported - </span> - </td> - </tr> - </tbody> - </table> - <ListFooter - count={2} - loadMore={[MockFunction]} - loading={false} - pageSize={30} - total={2} - /> -</div> -`; - -exports[`should render correctly: undefined projects 1`] = ` -<Alert - className="spacer-top" - variant="warning" -> - <FormattedMessage - defaultMessage="onboarding.create_project.gitlab.no_projects" - id="onboarding.create_project.gitlab.no_projects" - values={ - Object { - "link": <ForwardRef(Link) - to={ - Object { - "pathname": "/projects/create", - "search": "?mode=gitlab&resetPat=1", - } - } - > - onboarding.create_project.update_your_token - </ForwardRef(Link)>, - } - } - /> -</Alert> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/PersonalAccessTokenForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/PersonalAccessTokenForm-test.tsx.snap deleted file mode 100644 index d569b0fb97b..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/PersonalAccessTokenForm-test.tsx.snap +++ /dev/null @@ -1,679 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: bitbucket 1`] = ` -<div - className="display-flex-start" -> - <form - className="width-50" - onSubmit={[Function]} - > - <h2 - className="big" - > - onboarding.create_project.pat_form.title.bitbucket - </h2> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_form.help.bitbucket - </p> - <ValidationInput - error="onboarding.create_project.pat_incorrect.bitbucket" - id="personal_access_token_validation" - isInvalid={false} - isValid={false} - label="onboarding.create_project.enter_pat" - required={true} - > - <input - autoFocus={true} - className="input-super-large is-invalid" - id="personal_access_token_validation" - minLength={1} - onChange={[Function]} - type="text" - value="" - /> - </ValidationInput> - <ValidationInput - error="onboarding.create_project.pat_incorrect.bitbucket" - id="personal_access_token_submit" - isInvalid={true} - isValid={false} - label={null} - > - <SubmitButton - disabled={true} - > - save - </SubmitButton> - <DeferredSpinner - className="spacer-left" - loading={false} - /> - </ValidationInput> - </form> - <Alert - className="big-spacer-left width-50" - display="block" - variant="info" - > - <h3> - onboarding.create_project.pat_help.title - </h3> - <p - className="big-spacer-top big-spacer-bottom" - > - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.bitbucket.instructions" - id="onboarding.create_project.pat_help.instructions" - values={ - Object { - "button": <strong> - onboarding.create_project.pat_help.bitbucket.instructions.button - </strong>, - "menu": <strong> - onboarding.create_project.pat_help.bitbucket.instructions.menu - </strong>, - } - } - /> - </p> - <div - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="16" - src="/images/alm/bitbucket.svg" - /> - <a - href="http://www.example.com/account" - rel="noopener noreferrer" - target="_blank" - > - onboarding.create_project.pat_help.link - </a> - </div> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_help.instructions2.bitbucket - </p> - <ul> - <li> - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.bbs_permission_projects" - id="onboarding.create_project.pat_help.bbs_permission_projects" - values={ - Object { - "perm": <strong> - onboarding.create_project.pat_help.read_permission - </strong>, - } - } - /> - </li> - <li> - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.bbs_permission_repos" - id="onboarding.create_project.pat_help.bbs_permission_repos" - values={ - Object { - "perm": <strong> - onboarding.create_project.pat_help.read_permission - </strong>, - } - } - /> - </li> - </ul> - </Alert> -</div> -`; - -exports[`should render correctly: bitbucket cloud 1`] = ` -<div - className="display-flex-start" -> - <form - className="width-50" - onSubmit={[Function]} - > - <h2 - className="big" - > - onboarding.create_project.pat_form.title.bitbucketcloud - </h2> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_form.help.bitbucketcloud - </p> - <ValidationInput - id="enter_username_validation" - isInvalid={false} - isValid={false} - label="onboarding.create_project.enter_username" - required={true} - > - <input - autoFocus={true} - className="input-super-large is-invalid" - id="username" - minLength={1} - name="username" - onChange={[Function]} - type="text" - /> - </ValidationInput> - <ValidationInput - error="onboarding.create_project.pat_incorrect.bitbucketcloud" - id="personal_access_token_validation" - isInvalid={false} - isValid={false} - label="onboarding.create_project.enter_pat.bitbucketcloud" - required={true} - > - <input - autoFocus={false} - className="input-super-large is-invalid" - id="personal_access_token_validation" - minLength={1} - onChange={[Function]} - type="text" - value="" - /> - </ValidationInput> - <ValidationInput - error="onboarding.create_project.pat_incorrect.bitbucketcloud" - id="personal_access_token_submit" - isInvalid={true} - isValid={false} - label={null} - > - <SubmitButton - disabled={true} - > - save - </SubmitButton> - <DeferredSpinner - className="spacer-left" - loading={false} - /> - </ValidationInput> - </form> - <Alert - className="big-spacer-left width-50" - display="block" - variant="info" - > - <h3> - onboarding.create_project.pat_help.instructions_username.bitbucketcloud.title - </h3> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_help.instructions_username.bitbucketcloud - </p> - <div - className="text-middle big-spacer-bottom" - > - <img - alt="" - className="spacer-right" - height="16" - src="/images/alm/bitbucket.svg" - /> - <a - href="https://bitbucket.org/account/settings/" - rel="noopener noreferrer" - target="_blank" - > - onboarding.create_project.pat_help.instructions_username.bitbucketcloud.link - </a> - </div> - <h3> - onboarding.create_project.pat_help.bitbucketcloud.title - </h3> - <p - className="big-spacer-top big-spacer-bottom" - > - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.bitbucketcloud.instructions" - id="onboarding.create_project.pat_help.instructions" - values={ - Object { - "alm": "onboarding.alm.bitbucketcloud", - } - } - /> - </p> - <div - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="16" - src="/images/alm/bitbucket.svg" - /> - <a - href="https://bitbucket.org/account/settings/app-passwords/new" - rel="noopener noreferrer" - target="_blank" - > - onboarding.create_project.pat_help.bitbucketcloud.link - </a> - </div> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_help.instructions2.bitbucketcloud - </p> - <ul> - <li> - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.bbs_permission_repos" - id="onboarding.create_project.pat_help.bbs_permission_repos" - values={ - Object { - "perm": <strong> - onboarding.create_project.pat_help.read_permission - </strong>, - } - } - /> - </li> - </ul> - </Alert> -</div> -`; - -exports[`should render correctly: gitlab 1`] = ` -<div - className="display-flex-start" -> - <form - className="width-50" - onSubmit={[Function]} - > - <h2 - className="big" - > - onboarding.create_project.pat_form.title.gitlab - </h2> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_form.help.gitlab - </p> - <ValidationInput - error="onboarding.create_project.pat_incorrect.gitlab" - id="personal_access_token_validation" - isInvalid={false} - isValid={false} - label="onboarding.create_project.enter_pat" - required={true} - > - <input - autoFocus={true} - className="input-super-large is-invalid" - id="personal_access_token_validation" - minLength={1} - onChange={[Function]} - type="text" - value="" - /> - </ValidationInput> - <ValidationInput - error="onboarding.create_project.pat_incorrect.gitlab" - id="personal_access_token_submit" - isInvalid={true} - isValid={false} - label={null} - > - <SubmitButton - disabled={true} - > - save - </SubmitButton> - <DeferredSpinner - className="spacer-left" - loading={false} - /> - </ValidationInput> - </form> - <Alert - className="big-spacer-left width-50" - display="block" - variant="info" - > - <h3> - onboarding.create_project.pat_help.title - </h3> - <p - className="big-spacer-top big-spacer-bottom" - > - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.instructions" - id="onboarding.create_project.pat_help.instructions" - values={ - Object { - "alm": "onboarding.alm.gitlab", - } - } - /> - </p> - <div - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="16" - src="/images/alm/gitlab.svg" - /> - <a - href="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html" - rel="noopener noreferrer" - target="_blank" - > - onboarding.create_project.pat_help.link - </a> - </div> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_help.instructions2.gitlab - </p> - <ul> - <li - className="spacer-bottom" - > - <strong> - onboarding.create_project.pat_help.gitlab.read_api_permission - </strong> - </li> - </ul> - </Alert> -</div> -`; - -exports[`should render correctly: gitlab with non-standard api path 1`] = ` -<div - className="display-flex-start" -> - <form - className="width-50" - onSubmit={[Function]} - > - <h2 - className="big" - > - onboarding.create_project.pat_form.title.gitlab - </h2> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_form.help.gitlab - </p> - <ValidationInput - error="onboarding.create_project.pat_incorrect.gitlab" - id="personal_access_token_validation" - isInvalid={false} - isValid={false} - label="onboarding.create_project.enter_pat" - required={true} - > - <input - autoFocus={true} - className="input-super-large is-invalid" - id="personal_access_token_validation" - minLength={1} - onChange={[Function]} - type="text" - value="" - /> - </ValidationInput> - <ValidationInput - error="onboarding.create_project.pat_incorrect.gitlab" - id="personal_access_token_submit" - isInvalid={true} - isValid={false} - label={null} - > - <SubmitButton - disabled={true} - > - save - </SubmitButton> - <DeferredSpinner - className="spacer-left" - loading={false} - /> - </ValidationInput> - </form> - <Alert - className="big-spacer-left width-50" - display="block" - variant="info" - > - <h3> - onboarding.create_project.pat_help.title - </h3> - <p - className="big-spacer-top big-spacer-bottom" - > - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.instructions" - id="onboarding.create_project.pat_help.instructions" - values={ - Object { - "alm": "onboarding.alm.gitlab", - } - } - /> - </p> - <div - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="16" - src="/images/alm/gitlab.svg" - /> - <a - href="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html" - rel="noopener noreferrer" - target="_blank" - > - onboarding.create_project.pat_help.link - </a> - </div> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_help.instructions2.gitlab - </p> - <ul> - <li - className="spacer-bottom" - > - <strong> - onboarding.create_project.pat_help.gitlab.read_api_permission - </strong> - </li> - </ul> - </Alert> -</div> -`; - -exports[`should render correctly: no token needed 1`] = ` -<DeferredSpinner - className="spacer-left" - loading={true} -/> -`; - -exports[`should show error when issue: issue submitting token 1`] = ` -<div - className="display-flex-start" -> - <form - className="width-50" - onSubmit={[Function]} - > - <h2 - className="big" - > - onboarding.create_project.pat_form.title.bitbucketcloud - </h2> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_form.help.bitbucketcloud - </p> - <ValidationInput - id="enter_username_validation" - isInvalid={false} - isValid={false} - label="onboarding.create_project.enter_username" - required={true} - > - <input - autoFocus={true} - className="input-super-large is-invalid" - id="username" - minLength={1} - name="username" - onChange={[Function]} - type="text" - value="username" - /> - </ValidationInput> - <ValidationInput - error="default_error_message" - id="personal_access_token_validation" - isInvalid={false} - isValid={false} - label="onboarding.create_project.enter_pat.bitbucketcloud" - required={true} - > - <input - autoFocus={false} - className="input-super-large is-invalid" - id="personal_access_token_validation" - minLength={1} - onChange={[Function]} - type="text" - value="token" - /> - </ValidationInput> - <ValidationInput - error="default_error_message" - id="personal_access_token_submit" - isInvalid={true} - isValid={false} - label={null} - > - <SubmitButton - disabled={true} - > - save - </SubmitButton> - <DeferredSpinner - className="spacer-left" - loading={false} - /> - </ValidationInput> - </form> - <Alert - className="big-spacer-left width-50" - display="block" - variant="info" - > - <h3> - onboarding.create_project.pat_help.instructions_username.bitbucketcloud.title - </h3> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_help.instructions_username.bitbucketcloud - </p> - <div - className="text-middle big-spacer-bottom" - > - <img - alt="" - className="spacer-right" - height="16" - src="/images/alm/bitbucket.svg" - /> - <a - href="https://bitbucket.org/account/settings/" - rel="noopener noreferrer" - target="_blank" - > - onboarding.create_project.pat_help.instructions_username.bitbucketcloud.link - </a> - </div> - <h3> - onboarding.create_project.pat_help.bitbucketcloud.title - </h3> - <p - className="big-spacer-top big-spacer-bottom" - > - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.bitbucketcloud.instructions" - id="onboarding.create_project.pat_help.instructions" - values={ - Object { - "alm": "onboarding.alm.bitbucketcloud", - } - } - /> - </p> - <div - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="16" - src="/images/alm/bitbucket.svg" - /> - <a - href="https://bitbucket.org/account/settings/app-passwords/new" - rel="noopener noreferrer" - target="_blank" - > - onboarding.create_project.pat_help.bitbucketcloud.link - </a> - </div> - <p - className="big-spacer-top big-spacer-bottom" - > - onboarding.create_project.pat_help.instructions2.bitbucketcloud - </p> - <ul> - <li> - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.bbs_permission_repos" - id="onboarding.create_project.pat_help.bbs_permission_repos" - values={ - Object { - "perm": <strong> - onboarding.create_project.pat_help.read_permission - </strong>, - } - } - /> - </li> - </ul> - </Alert> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/WrongBindingCountAlert-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/WrongBindingCountAlert-test.tsx.snap deleted file mode 100644 index a1b89ceab0e..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/WrongBindingCountAlert-test.tsx.snap +++ /dev/null @@ -1,59 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: bitbucket 1`] = ` -<Alert - variant="error" -> - <FormattedMessage - defaultMessage="onboarding.create_project.wrong_binding_count" - id="onboarding.create_project.wrong_binding_count" - values={ - Object { - "alm": "onboarding.alm.bitbucket", - } - } - /> -</Alert> -`; - -exports[`should render correctly: for admin 1`] = ` -<Alert - variant="error" -> - <FormattedMessage - defaultMessage="onboarding.create_project.wrong_binding_count.admin" - id="onboarding.create_project.wrong_binding_count.admin" - values={ - Object { - "alm": "onboarding.alm.bitbucket", - "url": <ForwardRef(Link) - to={ - Object { - "pathname": "/admin/settings", - "search": "?category=almintegration", - } - } - > - settings.page - </ForwardRef(Link)>, - } - } - /> -</Alert> -`; - -exports[`should render correctly: gitlab 1`] = ` -<Alert - variant="error" -> - <FormattedMessage - defaultMessage="onboarding.create_project.wrong_binding_count" - id="onboarding.create_project.wrong_binding_count" - values={ - Object { - "alm": "onboarding.alm.gitlab", - } - } - /> -</Alert> -`; diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingDays.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingDays.tsx index b4fa182eca3..c982f37b95c 100644 --- a/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingDays.tsx +++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingDays.tsx @@ -53,7 +53,7 @@ export default function BaselineSettingDays(props: Props) { <ValidationInput error={undefined} - id="baseline_number_of_days" + labelHtmlFor="baseline_number_of_days" isInvalid={isChanged && !isValid} isValid={isChanged && isValid} label={translate('baseline.specify_days')} diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingDays-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingDays-test.tsx.snap index 5b8599e0aba..b8ac429ca80 100644 --- a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingDays-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingDays-test.tsx.snap @@ -13,10 +13,10 @@ exports[`should render correctly 1`] = ` </p> <MandatoryFieldsExplanation /> <ValidationInput - id="baseline_number_of_days" isInvalid={false} isValid={false} label="baseline.specify_days" + labelHtmlFor="baseline_number_of_days" required={true} > <input @@ -41,10 +41,10 @@ exports[`should render correctly 2`] = ` </p> <MandatoryFieldsExplanation /> <ValidationInput - id="baseline_number_of_days" isInvalid={false} isValid={true} label="baseline.specify_days" + labelHtmlFor="baseline_number_of_days" required={true} > <input @@ -69,10 +69,10 @@ exports[`should render correctly 3`] = ` </p> <MandatoryFieldsExplanation /> <ValidationInput - id="baseline_number_of_days" isInvalid={true} isValid={false} label="baseline.specify_days" + labelHtmlFor="baseline_number_of_days" required={true} > <input diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx index 2752d361f5c..534a620c265 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx @@ -255,7 +255,7 @@ export default class CreateProfileForm extends React.PureComponent<Props, State> <ValidationInput className="form-field" - id="create-profile-language-input" + labelHtmlFor="create-profile-language-input" label={translate('language')} required={true} isInvalid={isValidLanguage !== undefined && !isValidLanguage} @@ -275,7 +275,7 @@ export default class CreateProfileForm extends React.PureComponent<Props, State> {action !== undefined && ( <ValidationInput className="form-field" - id="create-profile-parent-input" + labelHtmlFor="create-profile-parent-input" label={translate( action === ProfileActionModals.Copy ? 'quality_profiles.creation.choose_copy_quality_profile' @@ -299,7 +299,7 @@ export default class CreateProfileForm extends React.PureComponent<Props, State> )} <ValidationInput className="form-field" - id="create-profile-name" + labelHtmlFor="create-profile-name" label={translate('name')} error={translate('quality_profiles.name_invalid')} required={true} diff --git a/server/sonar-web/src/main/js/components/common/ProjectKeyInput.tsx b/server/sonar-web/src/main/js/components/common/ProjectKeyInput.tsx index 28f344f98ac..22d85f9868d 100644 --- a/server/sonar-web/src/main/js/components/common/ProjectKeyInput.tsx +++ b/server/sonar-web/src/main/js/components/common/ProjectKeyInput.tsx @@ -56,7 +56,7 @@ export default function ProjectKeyInput(props: ProjectKeyInputProps) { description={translate('onboarding.create_project.project_key.description')} error={error} help={help} - id="project-key" + labelHtmlFor="project-key" isInvalid={isInvalid} isValid={isValid} label={label} diff --git a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ProjectKeyInput-test.tsx.snap b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ProjectKeyInput-test.tsx.snap index db373049426..a0d05c68aaf 100644 --- a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ProjectKeyInput-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ProjectKeyInput-test.tsx.snap @@ -4,9 +4,9 @@ exports[`should render correctly: autofocus 1`] = ` <ValidationInput className="form-field" description="onboarding.create_project.project_key.description" - id="project-key" isInvalid={false} isValid={false} + labelHtmlFor="project-key" required={false} > <input @@ -25,9 +25,9 @@ exports[`should render correctly: default 1`] = ` <ValidationInput className="form-field" description="onboarding.create_project.project_key.description" - id="project-key" isInvalid={false} isValid={false} + labelHtmlFor="project-key" required={false} > <input @@ -47,9 +47,9 @@ exports[`should render correctly: invalid 1`] = ` className="form-field" description="onboarding.create_project.project_key.description" error="bar.baz" - id="project-key" isInvalid={true} isValid={false} + labelHtmlFor="project-key" required={false} > <input @@ -68,9 +68,9 @@ exports[`should render correctly: valid 1`] = ` <ValidationInput className="form-field" description="onboarding.create_project.project_key.description" - id="project-key" isInvalid={false} isValid={true} + labelHtmlFor="project-key" required={false} > <input @@ -89,9 +89,9 @@ exports[`should render correctly: validating 1`] = ` <ValidationInput className="form-field" description="onboarding.create_project.project_key.description" - id="project-key" isInvalid={false} isValid={false} + labelHtmlFor="project-key" required={false} > <input @@ -111,10 +111,10 @@ exports[`should render correctly: with label, help, and placeholder 1`] = ` className="form-field" description="onboarding.create_project.project_key.description" help="foo.help" - id="project-key" isInvalid={false} isValid={false} label="foo.label" + labelHtmlFor="project-key" required={true} > <input @@ -134,9 +134,9 @@ exports[`should render correctly: with value 1`] = ` <ValidationInput className="form-field" description="onboarding.create_project.project_key.description" - id="project-key" isInvalid={false} isValid={false} + labelHtmlFor="project-key" required={false} > <input diff --git a/server/sonar-web/src/main/js/components/controls/ValidationInput.tsx b/server/sonar-web/src/main/js/components/controls/ValidationInput.tsx index 673db9eea54..87de01aa0dd 100644 --- a/server/sonar-web/src/main/js/components/controls/ValidationInput.tsx +++ b/server/sonar-web/src/main/js/components/controls/ValidationInput.tsx @@ -31,7 +31,7 @@ export interface ValidationInputProps { error?: string; errorPlacement?: ValidationInputErrorPlacement; help?: string; - id?: string; + labelHtmlFor?: string; isInvalid: boolean; isValid: boolean; label?: React.ReactNode; @@ -51,7 +51,7 @@ export default function ValidationInput(props: ValidationInputProps) { error, errorPlacement = ValidationInputErrorPlacement.Right, help, - id, + labelHtmlFor, isInvalid, isValid, label, @@ -94,8 +94,8 @@ export default function ValidationInput(props: ValidationInputProps) { return ( <div className={className}> - {id && label && ( - <label htmlFor={id}> + {labelHtmlFor && label && ( + <label htmlFor={labelHtmlFor}> <span className="text-middle"> <strong>{label}</strong> {required && <MandatoryFieldMarker />} diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/ValidationInput-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/ValidationInput-test.tsx index e3eaa5b7cf9..123c05153c4 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/ValidationInput-test.tsx +++ b/server/sonar-web/src/main/js/components/controls/__tests__/ValidationInput-test.tsx @@ -44,7 +44,7 @@ it('should render correctly', () => { isValid: false, }) ).toMatchSnapshot('error under the input'); - expect(shallowRender({ id: undefined, label: undefined })).toMatchSnapshot('no label'); + expect(shallowRender({ labelHtmlFor: undefined, label: undefined })).toMatchSnapshot('no label'); }); function shallowRender(props: Partial<ValidationInputProps> = {}) { @@ -52,7 +52,7 @@ function shallowRender(props: Partial<ValidationInputProps> = {}) { <ValidationInput description="My description" error={undefined} - id="field-id" + labelHtmlFor="field-id" isInvalid={false} isValid={true} label="Field label" |