From f78b919bf093fd3f1d462f61c587a018b88878bd Mon Sep 17 00:00:00 2001 From: Benjamin Janssens Date: Mon, 10 Jun 2024 13:10:44 +0200 Subject: [PATCH] test: add tests for BitbucketRepoPicker Signed-off-by: Benjamin Janssens --- .../src/BitbucketCloudClient.test.ts | 2 +- .../BitbucketRepoPicker.test.tsx | 133 +++++++++++++++++- .../RepoUrlPicker/BitbucketRepoPicker.tsx | 54 +++---- 3 files changed, 160 insertions(+), 29 deletions(-) diff --git a/plugins/bitbucket-cloud-common/src/BitbucketCloudClient.test.ts b/plugins/bitbucket-cloud-common/src/BitbucketCloudClient.test.ts index 92e3261410..f625f0daf8 100644 --- a/plugins/bitbucket-cloud-common/src/BitbucketCloudClient.test.ts +++ b/plugins/bitbucket-cloud-common/src/BitbucketCloudClient.test.ts @@ -116,7 +116,7 @@ describe('BitbucketCloudClient', () => { const response = { values: [ { - type: 'repository', + type: 'project', slug: 'project1', } as Models.Project, ], diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx index f799d68c2d..9dae5b24a6 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx @@ -16,7 +16,13 @@ import React from 'react'; import { BitbucketRepoPicker } from './BitbucketRepoPicker'; -import { render, fireEvent } from '@testing-library/react'; +import { render, fireEvent, waitFor } from '@testing-library/react'; +import { setupServer } from 'msw/node'; +import { rest } from 'msw'; +import { Models } from '@backstage/plugin-bitbucket-cloud-common'; +import userEvent from '@testing-library/user-event'; + +const server = setupServer(); describe('BitbucketRepoPicker', () => { it('renders a select if there is a list of allowed owners', async () => { @@ -136,4 +142,129 @@ describe('BitbucketRepoPicker', () => { expect(await findByText('project2')).toBeInTheDocument(); }); }); + + describe('autocompletion', () => { + beforeAll(() => server.listen({ onUnhandledRequest: 'error' })); + beforeEach(() => { + // BitbucketCloudClient.listWorkspaces() + server.use( + rest.get('https://api.bitbucket.org/2.0/workspaces', (_, res, ctx) => { + const response = { + values: [ + { + type: 'workspace', + slug: 'workspace1', + } as Models.Workspace, + ], + }; + return res(ctx.json(response)); + }), + ); + + // BitbucketCloudClient.listProjectsByWorkspace() + server.use( + rest.get( + 'https://api.bitbucket.org/2.0/workspaces/workspace1/projects', + (_, res, ctx) => { + const response = { + values: [ + { + type: 'project', + key: 'project1', + } as Models.Project, + ], + }; + return res(ctx.json(response)); + }, + ), + ); + + // BitbucketCloudClient.listRepositoriesByWorkspace() + server.use( + rest.get( + 'https://api.bitbucket.org/2.0/repositories/workspace1', + (_, res, ctx) => { + const response = { + values: [ + { + type: 'repository', + slug: 'repo1', + } as Models.Repository, + ], + }; + return res(ctx.json(response)); + }, + ), + ); + }); + afterAll(() => server.close()); + afterEach(() => server.resetHandlers()); + + it('should populate workspaces if host is set and accessToken is provided', async () => { + const onChange = jest.fn(); + const { getAllByRole, getByText } = render( + , + ); + + // Open the Autcomplete dropdown + const workspaceInput = getAllByRole('textbox')[0]; + await userEvent.click(workspaceInput); + + // Verify that the available workspaces are shown + await waitFor(() => expect(getByText('workspace1')).toBeInTheDocument()); + + // Verify that selecting an option calls onChange + await userEvent.click(getByText('workspace1')); + expect(onChange).toHaveBeenCalledWith({ workspace: 'workspace1' }); + }); + + it('should populate projects if host and workspace are set and accessToken is provided', async () => { + const onChange = jest.fn(); + const { getAllByRole, getByText } = render( + , + ); + + // Open the Autcomplete dropdown + const projectInput = getAllByRole('textbox')[1]; + await userEvent.click(projectInput); + + // Verify that the available projects are shown + await waitFor(() => expect(getByText('project1')).toBeInTheDocument()); + + // Verify that selecting an option calls onChange + await userEvent.click(getByText('project1')); + expect(onChange).toHaveBeenCalledWith({ project: 'project1' }); + }); + + it('should populate repositories if host, workspace and project are set and accessToken is provided', async () => { + const onChange = jest.fn(); + render( + , + ); + + // Verify that the available repos are updated + await waitFor(() => + expect(onChange).toHaveBeenCalledWith({ availableRepos: ['repo1'] }), + ); + }); + }); }); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx index a56e1ad9ad..67e82abc3f 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx @@ -103,6 +103,33 @@ export const BitbucketRepoPicker = (props: { [client, host], ); + // Update available projects when workspace changes + useDebounce( + () => { + const updateAvailableProjects = async () => { + if (client) + if (!workspace) { + setAvailableProjects([]); + } else { + const result: string[] = []; + + for await (const page of client + .listProjectsByWorkspace(workspace) + .iteratePages()) { + const keys = [...page.values!].map(p => p.key!); + result.push(...keys); + } + + setAvailableProjects(result); + } + }; + + updateAvailableProjects().catch(() => setAvailableProjects([])); + }, + 500, + [client, workspace], + ); + // Update available repositories when workspace or project changes useDebounce( () => { @@ -134,33 +161,6 @@ export const BitbucketRepoPicker = (props: { [client, workspace, project, onChange], ); - // Update available projects when workspace changes - useDebounce( - () => { - const updateAvailableProjects = async () => { - if (client) - if (!workspace) { - setAvailableProjects([]); - } else { - const result: string[] = []; - - for await (const page of client - .listProjectsByWorkspace(workspace) - .iteratePages()) { - const keys = [...page.values!].map(p => p.key!); - result.push(...keys); - } - - setAvailableProjects(result); - } - }; - - updateAvailableProjects().catch(() => setAvailableProjects([])); - }, - 500, - [client, workspace], - ); - return ( <> {host === 'bitbucket.org' && (