diff options
author | Kevin Silva <kevin.silva@sonarsource.com> | 2022-12-01 17:46:44 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-12-07 20:02:57 +0000 |
commit | ce5964a9d875a72814e20c81db3782c9fbc35926 (patch) | |
tree | d08ed3b8426220d7a628c17374aa4a4d8dfe39b1 | |
parent | f235dcec41d3fad489d16318bb59b8869f064ac0 (diff) | |
download | sonarqube-ce5964a9d875a72814e20c81db3782c9fbc35926.tar.gz sonarqube-ce5964a9d875a72814e20c81db3782c9fbc35926.zip |
SONAR-17615 Add RTL test for 'project/create' Azure pages and remove the enzyme tests
13 files changed, 151 insertions, 1527 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 337a739873b..3ab27ae48af 100644 --- a/server/sonar-web/src/main/js/api/mocks/AlmIntegrationsServiceMock.ts +++ b/server/sonar-web/src/main/js/api/mocks/AlmIntegrationsServiceMock.ts @@ -18,24 +18,38 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { cloneDeep } from 'lodash'; -import { mockGitlabProject } from '../../helpers/mocks/alm-integrations'; -import { GitlabProject } from '../../types/alm-integration'; +import { + mockAzureProject, + mockAzureRepository, + mockGitlabProject, +} from '../../helpers/mocks/alm-integrations'; +import { AzureProject, AzureRepository, GitlabProject } from '../../types/alm-integration'; import { checkPersonalAccessTokenIsValid, + getAzureProjects, + getAzureRepositories, getGithubClientId, getGithubOrganizations, getGitlabProjects, + importAzureRepository, + searchAzureRepositories, setAlmPersonalAccessToken, } from '../alm-integrations'; +import { ProjectBase } from '../components'; export default class AlmIntegrationsServiceMock { almInstancePATMap: { [key: string]: boolean } = {}; gitlabProjects: GitlabProject[]; + azureProjects: AzureProject[]; + azureRepositories: AzureRepository[]; defaultAlmInstancePATMap: { [key: string]: boolean } = { 'conf-final-1': false, 'conf-final-2': true, 'conf-github-1': false, 'conf-github-2': true, + 'conf-azure-1': false, + 'conf-azure-2': true, + 'config-reject': false, }; defaultGitlabProjects: GitlabProject[] = [ @@ -49,6 +63,16 @@ export default class AlmIntegrationsServiceMock { mockGitlabProject({ name: 'Gitlab project 3', id: '3' }), ]; + defaultAzureProjects: AzureProject[] = [ + mockAzureProject({ name: 'Azure project', description: 'Description project 1' }), + mockAzureProject({ name: 'Azure project 2', description: 'Description project 2' }), + ]; + + defaultAzureRepositories: AzureRepository[] = [ + mockAzureRepository({ sqProjectKey: 'random' }), + mockAzureRepository({ name: 'Azure repo 2' }), + ]; + defaultOrganizations = { paging: { pageIndex: 1, @@ -66,6 +90,8 @@ 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 ); @@ -73,6 +99,10 @@ export default class AlmIntegrationsServiceMock { (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); } checkPersonalAccessTokenIsValid = (conf: string) => { @@ -84,13 +114,48 @@ export default class AlmIntegrationsServiceMock { return Promise.resolve(); }; + getAzureProjects = (): Promise<{ projects: AzureProject[] }> => { + return Promise.resolve({ projects: this.azureProjects }); + }; + + getAzureRepositories = (): Promise<{ repositories: AzureRepository[] }> => { + return Promise.resolve({ + repositories: this.azureRepositories, + }); + }; + + searchAzureRepositories = (): Promise<{ repositories: AzureRepository[] }> => { + return Promise.resolve({ + repositories: this.azureRepositories, + }); + }; + + setSearchAzureRepositories = (azureRepositories: AzureRepository[]) => { + this.azureRepositories = azureRepositories; + }; + + importAzureRepository = (): Promise<{ project: ProjectBase }> => { + return Promise.resolve({ + project: { + key: 'key', + name: 'name', + qualifier: 'qualifier', + visibility: 'private', + }, + }); + }; + + setAzureProjects = (azureProjects: AzureProject[]) => { + this.azureProjects = azureProjects; + }; + getGitlabProjects = () => { return Promise.resolve({ projects: this.gitlabProjects, projectsPaging: { pageIndex: 1, pageSize: 30, - total: 3, + total: this.gitlabProjects.length, }, }); }; @@ -110,5 +175,6 @@ export default class AlmIntegrationsServiceMock { reset = () => { this.almInstancePATMap = cloneDeep(this.defaultAlmInstancePATMap); this.gitlabProjects = cloneDeep(this.defaultGitlabProjects); + this.azureRepositories = cloneDeep(this.defaultAzureRepositories); }; } 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 d42e24c6570..c5e32cb41f0 100644 --- a/server/sonar-web/src/main/js/api/mocks/AlmSettingsServiceMock.ts +++ b/server/sonar-web/src/main/js/api/mocks/AlmSettingsServiceMock.ts @@ -29,6 +29,8 @@ export default class AlmSettingsServiceMock { mockAlmSettingsInstance({ key: 'conf-final-2', alm: AlmKeys.GitLab }), mockAlmSettingsInstance({ key: 'conf-github-1', alm: AlmKeys.GitHub, url: 'url' }), 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' }), ]; constructor() { diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/AzurePersonalAccessTokenForm-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/AzurePersonalAccessTokenForm-test.tsx deleted file mode 100644 index fd3ac131e87..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/AzurePersonalAccessTokenForm-test.tsx +++ /dev/null @@ -1,78 +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 React from 'react'; -import { SubmitButton } from '../../../../components/controls/buttons'; -import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; -import { change, submit } from '../../../../helpers/testUtils'; -import { AlmKeys } from '../../../../types/alm-settings'; -import AzurePersonalAccessTokenForm, { - AzurePersonalAccessTokenFormProps, -} from '../AzurePersonalAccessTokenForm'; - -jest.mock('react', () => { - return { - ...jest.requireActual('react'), - useEffect: jest.fn(), - }; -}); - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot('default'); - expect(shallowRender({ submitting: true })).toMatchSnapshot('submitting'); - expect(shallowRender({ validationFailed: true })).toMatchSnapshot('validation failed'); -}); - -it('should correctly handle form interactions', () => { - const onPersonalAccessTokenCreate = jest.fn(); - const wrapper = shallowRender({ onPersonalAccessTokenCreate }); - - // 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(onPersonalAccessTokenCreate).toHaveBeenCalled(); - - // If validation fails, we toggle the submitting flag and call useEffect() - // to set the `touched` flag to false again. Trigger a re-render, and mock - // useEffect(). This should de-activate the submit button again. - (React.useEffect as jest.Mock).mockImplementationOnce((f) => f()); - wrapper.setProps({ submitting: false }); - expect(wrapper.find(SubmitButton).prop('disabled')).toBe(true); -}); - -function shallowRender(props: Partial<AzurePersonalAccessTokenFormProps> = {}) { - return shallow<AzurePersonalAccessTokenFormProps>( - <AzurePersonalAccessTokenForm - almSetting={mockAlmSettingsInstance({ - alm: AlmKeys.Azure, - url: 'http://www.example.com', - })} - onPersonalAccessTokenCreate={jest.fn()} - validationFailed={false} - {...props} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectAccordion-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectAccordion-test.tsx deleted file mode 100644 index 5c8f5d507ec..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectAccordion-test.tsx +++ /dev/null @@ -1,113 +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 BoxedGroupAccordion from '../../../../components/controls/BoxedGroupAccordion'; -import Radio from '../../../../components/controls/Radio'; -import { mockAzureProject, mockAzureRepository } from '../../../../helpers/mocks/alm-integrations'; -import { mockEvent } from '../../../../helpers/testUtils'; -import AzureProjectAccordion, { AzureProjectAccordionProps } from '../AzureProjectAccordion'; - -it('should render correctly', () => { - expect(shallowRender({ loading: true })).toMatchSnapshot('loading'); - expect(shallowRender({ startsOpen: false })).toMatchSnapshot('closed'); - expect( - shallowRender({ - repositories: [ - mockAzureRepository(), - mockAzureRepository({ sqProjectKey: 'sq-key', sqProjectName: 'SQ Name' }), - ], - }) - ).toMatchSnapshot('with repositories'); - expect(shallowRender({ importing: true, repositories: [mockAzureRepository()] })).toMatchSnapshot( - 'importing' - ); - expect( - shallowRender({ - repositories: [ - mockAzureRepository({ name: 'this repo is the best' }), - mockAzureRepository({ - name: 'This is a repo with class', - sqProjectKey: 'sq-key', - sqProjectName: 'SQ Name', - }), - ], - searchQuery: 'repo', - }) - ).toMatchSnapshot('search results'); -}); - -it('should open when clicked', () => { - const onOpen = jest.fn(); - - const wrapper = shallowRender({ - onOpen, - repositories: [mockAzureRepository()], - startsOpen: false, - }); - expect(wrapper.find(BoxedGroupAccordion).children().exists()).toBe(false); - - wrapper.find(BoxedGroupAccordion).props().onClick(); - - expect(onOpen).toHaveBeenCalled(); - - expect(wrapper.find(BoxedGroupAccordion).children().exists()).toBe(true); -}); - -it('should close when clicked', () => { - const onOpen = jest.fn(); - - const wrapper = shallowRender({ - onOpen, - repositories: [mockAzureRepository()], - }); - - expect(wrapper.find(BoxedGroupAccordion).children().exists()).toBe(true); - - wrapper.find(BoxedGroupAccordion).props().onClick(); - - expect(onOpen).not.toHaveBeenCalled(); - - expect(wrapper.find(BoxedGroupAccordion).children().exists()).toBe(false); -}); - -it('should trigger selection when repo is clicked', () => { - const onSelectRepository = jest.fn(); - const repo = mockAzureRepository(); - const wrapper = shallowRender({ onSelectRepository, repositories: [repo] }); - - wrapper.find(Radio).props().onCheck(mockEvent()); - - expect(onSelectRepository).toHaveBeenCalledWith(repo); -}); - -function shallowRender(overrides: Partial<AzureProjectAccordionProps> = {}) { - return shallow( - <AzureProjectAccordion - importing={false} - loading={false} - onSelectRepository={jest.fn()} - onOpen={jest.fn()} - project={mockAzureProject()} - startsOpen={true} - {...overrides} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectCreate-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectCreate-test.tsx deleted file mode 100644 index c033380802a..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectCreate-test.tsx +++ /dev/null @@ -1,228 +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, - getAzureProjects, - getAzureRepositories, - importAzureRepository, - searchAzureRepositories, - setAlmPersonalAccessToken, -} from '../../../../api/alm-integrations'; -import { mockAzureProject, mockAzureRepository } 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 AzureProjectCreate from '../AzureProjectCreate'; - -jest.mock('../../../../api/alm-integrations', () => { - return { - checkPersonalAccessTokenIsValid: jest.fn().mockResolvedValue({ status: true }), - setAlmPersonalAccessToken: jest.fn().mockResolvedValue(null), - getAzureProjects: jest.fn().mockResolvedValue({ projects: [] }), - getAzureRepositories: jest.fn().mockResolvedValue({ repositories: [] }), - searchAzureRepositories: jest.fn().mockResolvedValue({ repositories: [] }), - importAzureRepository: jest.fn().mockResolvedValue({ project: { key: 'baz' } }), - }; -}); - -beforeEach(jest.clearAllMocks); - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot(); -}); - -it('should correctly fetch binding info on mount', async () => { - const wrapper = shallowRender(); - await waitAndUpdate(wrapper); - expect(checkPersonalAccessTokenIsValid).toHaveBeenCalledWith('foo'); -}); - -it('should correctly handle a valid PAT', async () => { - (checkPersonalAccessTokenIsValid as jest.Mock).mockResolvedValueOnce({ status: true }); - const wrapper = shallowRender(); - await waitAndUpdate(wrapper); - expect(checkPersonalAccessTokenIsValid).toHaveBeenCalled(); - expect(wrapper.state().patIsValid).toBe(true); -}); - -it('should correctly handle an invalid PAT', async () => { - (checkPersonalAccessTokenIsValid as jest.Mock).mockResolvedValueOnce({ status: false }); - const wrapper = shallowRender(); - await waitAndUpdate(wrapper); - expect(checkPersonalAccessTokenIsValid).toHaveBeenCalled(); - expect(wrapper.state().patIsValid).toBe(false); -}); - -it('should correctly handle setting a new PAT', async () => { - const router = mockRouter(); - const wrapper = shallowRender({ router }); - wrapper.instance().handlePersonalAccessTokenCreate('token'); - expect(setAlmPersonalAccessToken).toHaveBeenCalledWith('foo', 'token'); - expect(wrapper.state().submittingToken).toBe(true); - - (checkPersonalAccessTokenIsValid as jest.Mock).mockResolvedValueOnce({ status: false }); - await waitAndUpdate(wrapper); - expect(checkPersonalAccessTokenIsValid).toHaveBeenCalled(); - expect(wrapper.state().submittingToken).toBe(false); - expect(wrapper.state().tokenValidationFailed).toBe(true); - - // Try again, this time with a correct token: - - wrapper.instance().handlePersonalAccessTokenCreate('correct token'); - await waitAndUpdate(wrapper); - expect(wrapper.state().tokenValidationFailed).toBe(false); - expect(router.replace).toHaveBeenCalled(); -}); - -it('should correctly fetch projects and repositories on mount', async () => { - const project = mockAzureProject(); - (getAzureProjects as jest.Mock).mockResolvedValueOnce({ projects: [project] }); - (getAzureRepositories as jest.Mock).mockResolvedValueOnce({ - repositories: [mockAzureRepository()], - }); - - const wrapper = shallowRender(); - await waitAndUpdate(wrapper); - expect(getAzureProjects).toHaveBeenCalled(); - expect(getAzureRepositories).toHaveBeenCalledTimes(1); - expect(getAzureRepositories).toHaveBeenCalledWith('foo', project.name); -}); - -it('should handle opening a project', async () => { - const projects = [ - mockAzureProject(), - mockAzureProject({ name: 'project2', description: 'Project to open' }), - ]; - - const firstProjectRepos = [mockAzureRepository()]; - const secondProjectRepos = [mockAzureRepository({ projectName: projects[1].name })]; - - (getAzureProjects as jest.Mock).mockResolvedValueOnce({ projects }); - (getAzureRepositories as jest.Mock) - .mockResolvedValueOnce({ - repositories: firstProjectRepos, - }) - .mockResolvedValueOnce({ - repositories: secondProjectRepos, - }); - - const wrapper = shallowRender(); - await waitAndUpdate(wrapper); - - wrapper.instance().handleOpenProject(projects[1].name); - await waitAndUpdate(wrapper); - - expect(getAzureRepositories).toHaveBeenCalledWith('foo', projects[1].name); - - expect(wrapper.state().repositories).toEqual({ - [projects[0].name]: firstProjectRepos, - [projects[1].name]: secondProjectRepos, - }); -}); - -it('should handle searching for repositories', async () => { - const wrapper = shallowRender(); - await waitAndUpdate(wrapper); - - const query = 'repo'; - const repositories = [mockAzureRepository({ projectName: 'p2' })]; - (searchAzureRepositories as jest.Mock).mockResolvedValueOnce({ - repositories, - }); - wrapper.instance().handleSearchRepositories(query); - expect(wrapper.state().searching).toBe(true); - - expect(searchAzureRepositories).toHaveBeenCalledWith('foo', query); - await waitAndUpdate(wrapper); - expect(wrapper.state().searching).toBe(false); - expect(wrapper.state().searchResults).toEqual(repositories); - expect(wrapper.state().searchQuery).toBe(query); - - // Ignore opening a project when search results are displayed - (getAzureRepositories as jest.Mock).mockClear(); - wrapper.instance().handleOpenProject('whatever'); - expect(getAzureRepositories).not.toHaveBeenCalled(); - - // and reset the search field - (searchAzureRepositories as jest.Mock).mockClear(); - - wrapper.instance().handleSearchRepositories(''); - expect(searchAzureRepositories).not.toHaveBeenCalled(); - expect(wrapper.state().searchResults).toBeUndefined(); - expect(wrapper.state().searchQuery).toBeUndefined(); -}); - -it('should select and import a repository', async () => { - const onProjectCreate = jest.fn(); - const repository = mockAzureRepository(); - const wrapper = shallowRender({ onProjectCreate }); - await waitAndUpdate(wrapper); - - expect(wrapper.state().selectedRepository).toBeUndefined(); - wrapper.instance().handleSelectRepository(repository); - expect(wrapper.state().selectedRepository).toBe(repository); - - wrapper.instance().handleImportRepository(); - expect(wrapper.state().importing).toBe(true); - expect(importAzureRepository).toHaveBeenCalledWith( - 'foo', - repository.projectName, - repository.name - ); - await waitAndUpdate(wrapper); - - expect(onProjectCreate).toHaveBeenCalledWith('baz'); - expect(wrapper.state().importing).toBe(false); -}); - -it('should handle no almInstances', () => { - const wrapper = shallowRender({ almInstances: [] }); - - wrapper.instance().fetchAzureProjects(); - wrapper.instance().fetchAzureRepositories('whatever'); - wrapper.instance().handleSearchRepositories('query'); - wrapper.instance().handleImportRepository(); - wrapper.instance().checkPersonalAccessToken(); - wrapper.instance().handlePersonalAccessTokenCreate(''); - - expect(getAzureProjects).not.toHaveBeenCalled(); - expect(getAzureRepositories).not.toHaveBeenCalled(); - expect(searchAzureRepositories).not.toHaveBeenCalled(); - expect(importAzureRepository).not.toHaveBeenCalled(); - expect(checkPersonalAccessTokenIsValid).not.toHaveBeenCalled(); - expect(setAlmPersonalAccessToken).not.toHaveBeenCalled(); -}); - -function shallowRender(overrides: Partial<AzureProjectCreate['props']> = {}) { - return shallow<AzureProjectCreate>( - <AzureProjectCreate - canAdmin={true} - loadingBindings={false} - location={mockLocation()} - onProjectCreate={jest.fn()} - router={mockRouter()} - almInstances={[mockAlmSettingsInstance({ alm: AlmKeys.Azure, key: 'foo' })]} - {...overrides} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectCreateRenderer-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectCreateRenderer-test.tsx deleted file mode 100644 index a5b7f00bde1..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectCreateRenderer-test.tsx +++ /dev/null @@ -1,90 +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 { mockAzureProject, mockAzureRepository } from '../../../../helpers/mocks/alm-integrations'; -import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings'; -import { AlmKeys } from '../../../../types/alm-settings'; -import AzureProjectCreateRenderer, { - AzureProjectCreateRendererProps, -} from '../AzureProjectCreateRenderer'; - -it('should render correctly', () => { - expect(shallowRender({ loading: true })).toMatchSnapshot('loading'); - expect(shallowRender({ almInstances: undefined })).toMatchSnapshot('no settings'); - expect(shallowRender({ showPersonalAccessTokenForm: true })).toMatchSnapshot('token form'); - expect( - shallowRender({ - almInstances: [ - mockAlmSettingsInstance({ alm: AlmKeys.Azure, url: 'https://azure.company.com' }), - mockAlmSettingsInstance({ - alm: AlmKeys.Azure, - url: 'https://azure.company.com', - key: 'key2', - }), - ], - selectedAlmInstance: mockAlmSettingsInstance({ - alm: AlmKeys.Azure, - url: 'https://azure.company.com', - }), - }) - ).toMatchSnapshot('project list'); - - expect( - shallowRender({ - almInstances: [mockAlmSettingsInstance({ alm: AlmKeys.Azure })], - showPersonalAccessTokenForm: true, - }) - ).toMatchSnapshot('setting missing url, admin'); - expect( - shallowRender({ - canAdmin: false, - almInstances: [mockAlmSettingsInstance({ alm: AlmKeys.Azure })], - }) - ).toMatchSnapshot('setting missing url, not admin'); -}); - -function shallowRender(overrides: Partial<AzureProjectCreateRendererProps> = {}) { - const project = mockAzureProject(); - - return shallow( - <AzureProjectCreateRenderer - canAdmin={true} - importing={false} - loading={false} - loadingRepositories={{}} - onImportRepository={jest.fn()} - onOpenProject={jest.fn()} - onPersonalAccessTokenCreate={jest.fn()} - onSearch={jest.fn()} - onSelectRepository={jest.fn()} - projects={[project]} - repositories={{ [project.name]: [mockAzureRepository()] }} - tokenValidationFailed={false} - almInstances={[ - mockAlmSettingsInstance({ alm: AlmKeys.Azure, url: 'https://azure.company.com' }), - ]} - showPersonalAccessTokenForm={false} - submittingToken={false} - onSelectedAlmInstanceChange={jest.fn()} - {...overrides} - /> - ); -} diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectsList-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectsList-test.tsx deleted file mode 100644 index 74a374d780c..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/AzureProjectsList-test.tsx +++ /dev/null @@ -1,81 +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 ListFooter from '../../../../components/controls/ListFooter'; -import { mockAzureProject, mockAzureRepository } from '../../../../helpers/mocks/alm-integrations'; -import AzureProjectAccordion from '../AzureProjectAccordion'; -import AzureProjectsList, { AzureProjectsListProps } from '../AzureProjectsList'; - -it('should render correctly', () => { - expect(shallowRender({})).toMatchSnapshot('default'); - expect(shallowRender({ projects: [] })).toMatchSnapshot('empty'); -}); - -it('should render search results correctly', () => { - const projects = [ - mockAzureProject({ name: 'p1', description: 'p1' }), - mockAzureProject({ name: 'p2', description: 'p2' }), - mockAzureProject({ name: 'p3', description: 'p3' }), - ]; - const searchResults = [mockAzureRepository({ projectName: 'p2' })]; - expect(shallowRender({ searchResults, projects })).toMatchSnapshot('default'); - expect(shallowRender({ searchResults: [], projects })).toMatchSnapshot('empty'); - expect( - shallowRender({ - searchResults: [ - mockAzureRepository({ projectName: 'p2' }), - mockAzureRepository({ name: 'Unknown repository 1', projectName: 'u1' }), - mockAzureRepository({ name: 'Unknown repository 2', projectName: 'u2' }), - ], - projects, - }) - ).toMatchSnapshot('search results belonging to unknown projects'); -}); - -it('should handle pagination', () => { - const projects = new Array(21) - .fill(1) - .map((_, i) => mockAzureProject({ name: `project-${i}`, description: `Project #${i}` })); - - const wrapper = shallowRender({ projects }); - - expect(wrapper.find(AzureProjectAccordion)).toHaveLength(10); - - wrapper.find(ListFooter).props().loadMore!(); - - expect(wrapper.find(AzureProjectAccordion)).toHaveLength(20); -}); - -function shallowRender(overrides: Partial<AzureProjectsListProps> = {}) { - const project = mockAzureProject(); - - return shallow( - <AzureProjectsList - importing={false} - loadingRepositories={{}} - onOpenProject={jest.fn()} - onSelectRepository={jest.fn()} - projects={[project]} - repositories={{ [project.name]: [] }} - {...overrides} - /> - ); -} 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 index 286d02862e3..89c35d0eda4 100644 --- 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 @@ -22,6 +22,7 @@ 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'; @@ -38,6 +39,7 @@ 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', }), @@ -53,7 +55,8 @@ beforeAll(() => { almSettingsHandler = new AlmSettingsServiceMock(); }); -afterEach(() => { +beforeEach(() => { + jest.clearAllMocks(); almIntegrationHandler.reset(); almSettingsHandler.reset(); }); @@ -131,6 +134,82 @@ describe('Github onboarding page', () => { }); }); +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__/__snapshots__/AzurePersonalAccessTokenForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzurePersonalAccessTokenForm-test.tsx.snap deleted file mode 100644 index 0c3af3883bb..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzurePersonalAccessTokenForm-test.tsx.snap +++ /dev/null @@ -1,211 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: default 1`] = ` -<div - className="boxed-group abs-width-600" -> - <div - className="boxed-group-inner" - > - <h2> - onboarding.create_project.pat_form.title.azure - </h2> - <div - className="big-spacer-top big-spacer-bottom" - > - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.instructions.azure" - id="onboarding.create_project.pat_help.instructions" - values={ - Object { - "link": <ForwardRef(Link) - className="link-no-underline" - target="_blank" - to="http://www.example.com/_usersSettings/tokens" - > - onboarding.create_project.pat_help.instructions.link.azure - </ForwardRef(Link)>, - "scope": <strong> - <em> - Code (Read & Write) - </em> - </strong>, - } - } - /> - </div> - <form - onSubmit={[Function]} - > - <ValidationInput - error="onboarding.create_project.pat_form.pat_required" - id="personal_access_token" - isInvalid={false} - isValid={false} - label="onboarding.create_project.enter_pat" - required={true} - > - <input - autoFocus={true} - className="width-100 little-spacer-bottom" - id="personal_access_token" - minLength={1} - name="personal_access_token" - onChange={[Function]} - type="text" - value="" - /> - </ValidationInput> - <SubmitButton - disabled={true} - > - onboarding.create_project.pat_form.list_repositories - </SubmitButton> - <DeferredSpinner - className="spacer-left" - loading={false} - /> - </form> - </div> -</div> -`; - -exports[`should render correctly: submitting 1`] = ` -<div - className="boxed-group abs-width-600" -> - <div - className="boxed-group-inner" - > - <h2> - onboarding.create_project.pat_form.title.azure - </h2> - <div - className="big-spacer-top big-spacer-bottom" - > - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.instructions.azure" - id="onboarding.create_project.pat_help.instructions" - values={ - Object { - "link": <ForwardRef(Link) - className="link-no-underline" - target="_blank" - to="http://www.example.com/_usersSettings/tokens" - > - onboarding.create_project.pat_help.instructions.link.azure - </ForwardRef(Link)>, - "scope": <strong> - <em> - Code (Read & Write) - </em> - </strong>, - } - } - /> - </div> - <form - onSubmit={[Function]} - > - <ValidationInput - error="onboarding.create_project.pat_form.pat_required" - id="personal_access_token" - isInvalid={false} - isValid={false} - label="onboarding.create_project.enter_pat" - required={true} - > - <input - autoFocus={true} - className="width-100 little-spacer-bottom" - id="personal_access_token" - minLength={1} - name="personal_access_token" - onChange={[Function]} - type="text" - value="" - /> - </ValidationInput> - <SubmitButton - disabled={true} - > - onboarding.create_project.pat_form.list_repositories - </SubmitButton> - <DeferredSpinner - className="spacer-left" - loading={true} - /> - </form> - </div> -</div> -`; - -exports[`should render correctly: validation failed 1`] = ` -<div - className="boxed-group abs-width-600" -> - <div - className="boxed-group-inner" - > - <h2> - onboarding.create_project.pat_form.title.azure - </h2> - <div - className="big-spacer-top big-spacer-bottom" - > - <FormattedMessage - defaultMessage="onboarding.create_project.pat_help.instructions.azure" - id="onboarding.create_project.pat_help.instructions" - values={ - Object { - "link": <ForwardRef(Link) - className="link-no-underline" - target="_blank" - to="http://www.example.com/_usersSettings/tokens" - > - onboarding.create_project.pat_help.instructions.link.azure - </ForwardRef(Link)>, - "scope": <strong> - <em> - Code (Read & Write) - </em> - </strong>, - } - } - /> - </div> - <form - onSubmit={[Function]} - > - <ValidationInput - error="onboarding.create_project.pat_form.pat_required" - id="personal_access_token" - isInvalid={true} - isValid={false} - label="onboarding.create_project.enter_pat" - required={true} - > - <input - autoFocus={true} - className="width-100 little-spacer-bottom is-invalid" - id="personal_access_token" - minLength={1} - name="personal_access_token" - onChange={[Function]} - type="text" - value="" - /> - </ValidationInput> - <SubmitButton - disabled={true} - > - onboarding.create_project.pat_form.list_repositories - </SubmitButton> - <DeferredSpinner - className="spacer-left" - loading={false} - /> - </form> - </div> -</div> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectAccordion-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectAccordion-test.tsx.snap deleted file mode 100644 index 3dbc8f46c8f..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectAccordion-test.tsx.snap +++ /dev/null @@ -1,258 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: closed 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom" - onClick={[Function]} - open={false} - title={ - <h3 - title="Azure Project" - > - azure-project-1 - </h3> - } -/> -`; - -exports[`should render correctly: importing 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom open" - onClick={[Function]} - open={true} - title={ - <h3 - title="Azure Project" - > - azure-project-1 - </h3> - } -> - <DeferredSpinner - loading={false} - > - <div - className="display-flex-wrap" - > - <div - className="create-project-azdo-repo display-flex-start spacer-bottom padded-right" - key="Azure repo 1" - > - <Radio - alignLabel={true} - checked={false} - className="overflow-hidden" - disabled={true} - onCheck={[Function]} - value="Azure repo 1" - > - <span - title="Azure repo 1" - > - Azure repo 1 - </span> - </Radio> - </div> - </div> - <ListFooter - count={1} - loadMore={[Function]} - total={1} - /> - </DeferredSpinner> -</BoxedGroupAccordion> -`; - -exports[`should render correctly: loading 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom open" - onClick={[Function]} - open={true} - title={ - <h3 - title="Azure Project" - > - azure-project-1 - </h3> - } -> - <DeferredSpinner - loading={true} - > - <div - className="display-flex-wrap" - /> - <ListFooter - count={0} - loadMore={[Function]} - total={0} - /> - </DeferredSpinner> -</BoxedGroupAccordion> -`; - -exports[`should render correctly: search results 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom open" - onClick={[Function]} - open={true} - title={ - <h3 - title="Azure Project" - > - azure-project-1 - </h3> - } -> - <DeferredSpinner - loading={false} - > - <div - className="display-flex-wrap" - > - <div - className="create-project-azdo-repo display-flex-start spacer-bottom padded-right" - key="this repo is the best" - > - <Radio - alignLabel={true} - checked={false} - className="overflow-hidden" - disabled={false} - onCheck={[Function]} - value="this repo is the best" - > - <span - title="this repo is the best" - > - this - <strong - className="" - > - repo - </strong> - is the best - </span> - </Radio> - </div> - <div - className="create-project-azdo-repo display-flex-start spacer-bottom padded-right" - key="This is a repo with class" - > - <CheckIcon - className="spacer-right" - fill="#00aa00" - size={14} - /> - <div - className="overflow-hidden" - > - <div - className="little-spacer-bottom text-ellipsis" - > - <ForwardRef(Link) - title="SQ Name" - to={ - Object { - "pathname": "/dashboard", - "search": "?id=sq-key", - } - } - > - SQ Name - </ForwardRef(Link)> - </div> - <em> - onboarding.create_project.repository_imported - </em> - </div> - </div> - </div> - <ListFooter - count={2} - loadMore={[Function]} - total={2} - /> - </DeferredSpinner> -</BoxedGroupAccordion> -`; - -exports[`should render correctly: with repositories 1`] = ` -<BoxedGroupAccordion - className="big-spacer-bottom open" - onClick={[Function]} - open={true} - title={ - <h3 - title="Azure Project" - > - azure-project-1 - </h3> - } -> - <DeferredSpinner - loading={false} - > - <div - className="display-flex-wrap" - > - <div - className="create-project-azdo-repo display-flex-start spacer-bottom padded-right" - key="Azure repo 1" - > - <Radio - alignLabel={true} - checked={false} - className="overflow-hidden" - disabled={false} - onCheck={[Function]} - value="Azure repo 1" - > - <span - title="Azure repo 1" - > - Azure repo 1 - </span> - </Radio> - </div> - <div - className="create-project-azdo-repo display-flex-start spacer-bottom padded-right" - key="Azure repo 1" - > - <CheckIcon - className="spacer-right" - fill="#00aa00" - size={14} - /> - <div - className="overflow-hidden" - > - <div - className="little-spacer-bottom text-ellipsis" - > - <ForwardRef(Link) - title="SQ Name" - to={ - Object { - "pathname": "/dashboard", - "search": "?id=sq-key", - } - } - > - SQ Name - </ForwardRef(Link)> - </div> - <em> - onboarding.create_project.repository_imported - </em> - </div> - </div> - </div> - <ListFooter - count={2} - loadMore={[Function]} - total={2} - /> - </DeferredSpinner> -</BoxedGroupAccordion> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectCreate-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectCreate-test.tsx.snap deleted file mode 100644 index eb3a7ab08aa..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectCreate-test.tsx.snap +++ /dev/null @@ -1,33 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` -<AzureProjectCreateRenderer - almInstances={ - Array [ - Object { - "alm": "azure", - "key": "foo", - }, - ] - } - canAdmin={true} - importing={false} - loading={true} - loadingRepositories={Object {}} - onImportRepository={[Function]} - onOpenProject={[Function]} - onPersonalAccessTokenCreate={[Function]} - onSearch={[Function]} - onSelectRepository={[Function]} - onSelectedAlmInstanceChange={[Function]} - repositories={Object {}} - selectedAlmInstance={ - Object { - "alm": "azure", - "key": "foo", - } - } - showPersonalAccessTokenForm={true} - tokenValidationFailed={false} -/> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectCreateRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectCreateRenderer-test.tsx.snap deleted file mode 100644 index 7b81cd8f129..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectCreateRenderer-test.tsx.snap +++ /dev/null @@ -1,262 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: loading 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/azure.svg" - /> - onboarding.create_project.azure.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "azure", - "key": "key", - "url": "https://azure.company.com", - }, - ] - } - almKey="azure" - onChangeConfig={[MockFunction]} - /> - <i - className="spinner" - /> -</Fragment> -`; - -exports[`should render correctly: no settings 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/azure.svg" - /> - onboarding.create_project.azure.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almKey="azure" - onChangeConfig={[MockFunction]} - /> - <WrongBindingCountAlert - alm="azure" - canAdmin={true} - /> -</Fragment> -`; - -exports[`should render correctly: project list 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/azure.svg" - /> - onboarding.create_project.azure.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "azure", - "key": "key", - "url": "https://azure.company.com", - }, - Object { - "alm": "azure", - "key": "key2", - "url": "https://azure.company.com", - }, - ] - } - almKey="azure" - onChangeConfig={[MockFunction]} - selectedAlmInstance={ - Object { - "alm": "azure", - "key": "key", - "url": "https://azure.company.com", - } - } - /> - <div - className="huge-spacer-bottom" - > - <SearchBox - onChange={[MockFunction]} - placeholder="onboarding.create_project.search_projects_repositories" - /> - </div> - <DeferredSpinner - loading={false} - > - <AzureProjectsList - importing={false} - loadingRepositories={Object {}} - onOpenProject={[MockFunction]} - onSelectRepository={[MockFunction]} - projects={ - Array [ - Object { - "description": "Azure Project", - "name": "azure-project-1", - }, - ] - } - repositories={ - Object { - "azure-project-1": Array [ - Object { - "name": "Azure repo 1", - "projectName": "Azure Project", - }, - ], - } - } - /> - </DeferredSpinner> -</Fragment> -`; - -exports[`should render correctly: setting missing url, admin 1`] = ` -<Fragment> - <CreateProjectPageHeader - additionalActions={false} - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/azure.svg" - /> - onboarding.create_project.azure.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "azure", - "key": "key", - }, - ] - } - almKey="azure" - onChangeConfig={[MockFunction]} - /> -</Fragment> -`; - -exports[`should render correctly: setting missing url, not admin 1`] = ` -<Fragment> - <CreateProjectPageHeader - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/azure.svg" - /> - onboarding.create_project.azure.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "azure", - "key": "key", - }, - ] - } - almKey="azure" - onChangeConfig={[MockFunction]} - /> -</Fragment> -`; - -exports[`should render correctly: token form 1`] = ` -<Fragment> - <CreateProjectPageHeader - additionalActions={false} - title={ - <span - className="text-middle" - > - <img - alt="" - className="spacer-right" - height="24" - src="/images/alm/azure.svg" - /> - onboarding.create_project.azure.title - </span> - } - /> - <AlmSettingsInstanceDropdown - almInstances={ - Array [ - Object { - "alm": "azure", - "key": "key", - "url": "https://azure.company.com", - }, - ] - } - almKey="azure" - onChangeConfig={[MockFunction]} - /> -</Fragment> -`; diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectsList-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectsList-test.tsx.snap deleted file mode 100644 index fa72ffea21b..00000000000 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/__snapshots__/AzureProjectsList-test.tsx.snap +++ /dev/null @@ -1,169 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly: default 1`] = ` -<div> - <AzureProjectAccordion - importing={false} - key="azure-project-1" - loading={false} - onOpen={[MockFunction]} - onSelectRepository={[MockFunction]} - project={ - Object { - "description": "Azure Project", - "name": "azure-project-1", - } - } - repositories={Array []} - startsOpen={true} - /> - <ListFooter - count={1} - loadMore={[Function]} - total={1} - /> -</div> -`; - -exports[`should render correctly: empty 1`] = ` -<Alert - className="spacer-top" - variant="warning" -> - <FormattedMessage - defaultMessage="onboarding.create_project.azure.no_projects" - id="onboarding.create_project.azure.no_projects" - values={ - Object { - "link": <ForwardRef(Link) - to={ - Object { - "pathname": "/projects/create", - "search": "?mode=azure&resetPat=1", - } - } - > - onboarding.create_project.update_your_token - </ForwardRef(Link)>, - } - } - /> -</Alert> -`; - -exports[`should render search results correctly: default 1`] = ` -<div> - <AzureProjectAccordion - importing={false} - key="p2 - result" - loading={false} - onOpen={[MockFunction]} - onSelectRepository={[MockFunction]} - project={ - Object { - "description": "p2", - "name": "p2", - } - } - repositories={ - Array [ - Object { - "name": "Azure repo 1", - "projectName": "p2", - }, - ] - } - startsOpen={true} - /> - <ListFooter - count={1} - loadMore={[Function]} - total={1} - /> -</div> -`; - -exports[`should render search results correctly: empty 1`] = ` -<Alert - className="spacer-top" - variant="warning" -> - onboarding.create_project.azure.no_results -</Alert> -`; - -exports[`should render search results correctly: search results belonging to unknown projects 1`] = ` -<div> - <AzureProjectAccordion - importing={false} - key="p2 - result" - loading={false} - onOpen={[MockFunction]} - onSelectRepository={[MockFunction]} - project={ - Object { - "description": "p2", - "name": "p2", - } - } - repositories={ - Array [ - Object { - "name": "Azure repo 1", - "projectName": "p2", - }, - ] - } - startsOpen={true} - /> - <AzureProjectAccordion - importing={false} - key="u1 - result" - loading={false} - onOpen={[MockFunction]} - onSelectRepository={[MockFunction]} - project={ - Object { - "description": "onboarding.create_project.azure.search_results_for_project_X.u1", - "name": "u1", - } - } - repositories={ - Array [ - Object { - "name": "Unknown repository 1", - "projectName": "u1", - }, - ] - } - startsOpen={true} - /> - <AzureProjectAccordion - importing={false} - key="u2 - result" - loading={false} - onOpen={[MockFunction]} - onSelectRepository={[MockFunction]} - project={ - Object { - "description": "onboarding.create_project.azure.search_results_for_project_X.u2", - "name": "u2", - } - } - repositories={ - Array [ - Object { - "name": "Unknown repository 2", - "projectName": "u2", - }, - ] - } - startsOpen={true} - /> - <ListFooter - count={3} - loadMore={[Function]} - total={3} - /> -</div> -`; |