From 0acf455cfdae95c19d75eb7ea1d2a47201a70362 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 20 Sep 2024 15:41:20 -0300 Subject: [PATCH 01/13] chore: Update layouts/ToastNotifications to Vitest (#3217) --- ...otifications.spec.jsx => ToastNotifications.test.jsx} | 9 +++++---- src/layouts/ToastNotifications/{index.js => index.ts} | 0 2 files changed, 5 insertions(+), 4 deletions(-) rename src/layouts/ToastNotifications/{ToastNotifications.spec.jsx => ToastNotifications.test.jsx} (88%) rename src/layouts/ToastNotifications/{index.js => index.ts} (100%) diff --git a/src/layouts/ToastNotifications/ToastNotifications.spec.jsx b/src/layouts/ToastNotifications/ToastNotifications.test.jsx similarity index 88% rename from src/layouts/ToastNotifications/ToastNotifications.spec.jsx rename to src/layouts/ToastNotifications/ToastNotifications.test.jsx index 5715c1367b..00271007f6 100644 --- a/src/layouts/ToastNotifications/ToastNotifications.spec.jsx +++ b/src/layouts/ToastNotifications/ToastNotifications.test.jsx @@ -1,4 +1,5 @@ import { render, screen } from '@testing-library/react' +import { vi } from 'vitest' import { useNotifications, @@ -22,10 +23,10 @@ const notifications = [ }, ] -jest.mock('services/toastNotification') +vi.mock('services/toastNotification') describe('ToastNotifications', () => { - const removeNotification = jest.fn() + const removeNotification = vi.fn() function setup() { useNotifications.mockReturnValue(notifications) @@ -35,7 +36,7 @@ describe('ToastNotifications', () => { describe('when rendered', () => { beforeEach(() => { - jest.useFakeTimers() + vi.useFakeTimers() removeNotification.mockReset() setup() }) @@ -47,7 +48,7 @@ describe('ToastNotifications', () => { describe('when enough time passes', () => { beforeEach(() => { - jest.runOnlyPendingTimers() + vi.runOnlyPendingTimers() }) it('calls removeNotification with the notification that disappear', () => { diff --git a/src/layouts/ToastNotifications/index.js b/src/layouts/ToastNotifications/index.ts similarity index 100% rename from src/layouts/ToastNotifications/index.js rename to src/layouts/ToastNotifications/index.ts From e414d3e3924a36c4a33cb049d491150a9e486305 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Fri, 20 Sep 2024 16:07:15 -0300 Subject: [PATCH 02/13] chore: Update ui/VirtualFileRenderer test to Vitest (#3218) --- .../{ColorBar.spec.tsx => ColorBar.test.tsx} | 10 +++++-- ....spec.tsx => VirtualFileRenderer.test.tsx} | 30 +++++++++++-------- 2 files changed, 25 insertions(+), 15 deletions(-) rename src/ui/VirtualFileRenderer/{ColorBar.spec.tsx => ColorBar.test.tsx} (92%) rename src/ui/VirtualFileRenderer/{VirtualFileRenderer.spec.tsx => VirtualFileRenderer.test.tsx} (94%) diff --git a/src/ui/VirtualFileRenderer/ColorBar.spec.tsx b/src/ui/VirtualFileRenderer/ColorBar.test.tsx similarity index 92% rename from src/ui/VirtualFileRenderer/ColorBar.spec.tsx rename to src/ui/VirtualFileRenderer/ColorBar.test.tsx index 3ea0134632..d26ea777f3 100644 --- a/src/ui/VirtualFileRenderer/ColorBar.spec.tsx +++ b/src/ui/VirtualFileRenderer/ColorBar.test.tsx @@ -3,11 +3,15 @@ import { render, screen } from '@testing-library/react' import { ColorBar, findCoverage } from './ColorBar' -jest.mock('@sentry/react', () => { - const originalModule = jest.requireActual('@sentry/react') +const mocks = vi.hoisted(() => ({ + captureMessage: vi.fn(), +})) + +vi.mock('@sentry/react', async () => { + const originalModule = vi.importActual('@sentry/react') return { ...originalModule, - captureMessage: jest.fn(), + captureMessage: mocks.captureMessage, } }) diff --git a/src/ui/VirtualFileRenderer/VirtualFileRenderer.spec.tsx b/src/ui/VirtualFileRenderer/VirtualFileRenderer.test.tsx similarity index 94% rename from src/ui/VirtualFileRenderer/VirtualFileRenderer.spec.tsx rename to src/ui/VirtualFileRenderer/VirtualFileRenderer.test.tsx index bd7150d65f..edc38d0956 100644 --- a/src/ui/VirtualFileRenderer/VirtualFileRenderer.spec.tsx +++ b/src/ui/VirtualFileRenderer/VirtualFileRenderer.test.tsx @@ -10,15 +10,21 @@ import { userEvent } from '@testing-library/user-event' // eslint-disable-next-line no-restricted-imports import { type Dictionary } from 'lodash' import { MemoryRouter, Route, useLocation } from 'react-router-dom' +import { type MockInstance } from 'vitest' import { VirtualFileRenderer } from './VirtualFileRenderer' -jest.mock('@sentry/react', () => { - const originalModule = jest.requireActual('@sentry/react') +const mocks = vi.hoisted(() => ({ + withProfiler: (component: any) => component, + captureMessage: vi.fn(), +})) + +vi.mock('@sentry/react', () => { + const originalModule = vi.importActual('@sentry/react') return { ...originalModule, - withProfiler: (component: any) => component, - captureMessage: jest.fn(), + withProfiler: mocks.withProfiler, + captureMessage: mocks.captureMessage, } }) @@ -28,7 +34,7 @@ window.requestAnimationFrame = (cb) => { } window.cancelAnimationFrame = () => {} -const scrollToMock = jest.fn() +const scrollToMock = vi.fn() window.scrollTo = scrollToMock window.scrollY = 100 @@ -286,21 +292,21 @@ describe('VirtualFileRenderer', () => { }) describe('toggling pointer events', () => { - let requestAnimationFrameSpy: jest.SpyInstance - let cancelAnimationFrameSpy: jest.SpyInstance - let dateNowSpy: jest.SpyInstance + let requestAnimationFrameSpy: MockInstance + let cancelAnimationFrameSpy: MockInstance + let dateNowSpy: MockInstance beforeEach(() => { - requestAnimationFrameSpy = jest.spyOn(window, 'requestAnimationFrame') - cancelAnimationFrameSpy = jest.spyOn(window, 'cancelAnimationFrame') - dateNowSpy = jest.spyOn(Date, 'now') + requestAnimationFrameSpy = vi.spyOn(window, 'requestAnimationFrame') + cancelAnimationFrameSpy = vi.spyOn(window, 'cancelAnimationFrame') + dateNowSpy = vi.spyOn(Date, 'now') }) afterEach(() => { requestAnimationFrameSpy.mockRestore() cancelAnimationFrameSpy.mockRestore() dateNowSpy.mockRestore() - jest.clearAllMocks() + vi.clearAllMocks() }) it('disables pointer events on scroll and resets after timeout', async () => { From a22d678d81aece161c42372ced6ca76c46ba8078 Mon Sep 17 00:00:00 2001 From: nicholas-codecov Date: Mon, 23 Sep 2024 07:11:27 -0300 Subject: [PATCH 03/13] chore: Update pages/AccountSettings to Vitest (#3227) --- ...ings.spec.jsx => AccountSettings.test.jsx} | 52 +++++++------- ...c.jsx => AccountSettingsSideMenu.test.jsx} | 31 ++++---- .../{Header.spec.jsx => Header.test.jsx} | 2 +- .../{Access.spec.tsx => Access.test.tsx} | 19 ++--- ...dal.spec.jsx => CreateTokenModal.test.jsx} | 8 +-- ...sTable.spec.tsx => SessionsTable.test.tsx} | 20 +++--- ...ensTable.spec.tsx => TokensTable.test.tsx} | 9 +-- .../Admin/{Admin.spec.jsx => Admin.test.jsx} | 30 +++++--- ...ionCard.spec.tsx => DeletionCard.test.tsx} | 0 ...ction.spec.jsx => DetailsSection.test.jsx} | 41 ++++++----- ....jsx => GithubIntegrationSection.test.jsx} | 37 +++++----- ...{AddAdmins.spec.jsx => AddAdmins.test.jsx} | 32 ++++----- ...dminTable.spec.tsx => AdminTable.test.tsx} | 45 ++++++------ ...Card.spec.jsx => ManageAdminCard.test.jsx} | 72 +++++++++---------- ...ction.spec.jsx => StudentSection.test.jsx} | 0 ....tsx => AdminAuthorizationBanner.test.tsx} | 0 ...ktaAccess.spec.tsx => OktaAccess.test.tsx} | 30 ++++---- ...gForm.spec.tsx => OktaConfigForm.test.tsx} | 41 +++++------ .../OktaConfigForm/OktaConfigForm.tsx | 2 + ...Config.spec.tsx => useOktaConfig.test.tsx} | 23 +++--- ....spec.tsx => useUpdateOktaConfig.test.tsx} | 36 +++++++--- ...Token.spec.jsx => OrgUploadToken.test.jsx} | 65 ++++++++--------- ...ner.spec.jsx => ActivationBanner.test.jsx} | 18 ++--- ....js => useSelfActivationMutation.test.jsx} | 43 ++++++----- ...inBanner.spec.jsx => AdminBanner.test.jsx} | 23 +++--- ...ionCard.spec.tsx => DeletionCard.test.tsx} | 0 ...ilCard.spec.jsx => NameEmailCard.test.jsx} | 22 +++--- .../{Profile.spec.jsx => Profile.test.jsx} | 45 ++++++------ ...ssModal.spec.jsx => SuccessModal.test.jsx} | 12 ++-- .../YAML/{YAML.spec.jsx => YAML.test.jsx} | 54 +++++++------- ...amlEditor.spec.jsx => YamlEditor.test.jsx} | 0 31 files changed, 418 insertions(+), 394 deletions(-) rename src/pages/AccountSettings/{AccountSettings.spec.jsx => AccountSettings.test.jsx} (89%) rename src/pages/AccountSettings/{AccountSettingsSideMenu.spec.jsx => AccountSettingsSideMenu.test.jsx} (96%) rename src/pages/AccountSettings/shared/Header/{Header.spec.jsx => Header.test.jsx} (99%) rename src/pages/AccountSettings/tabs/Access/{Access.spec.tsx => Access.test.tsx} (93%) rename src/pages/AccountSettings/tabs/Access/{CreateTokenModal.spec.jsx => CreateTokenModal.test.jsx} (97%) rename src/pages/AccountSettings/tabs/Access/{SessionsTable.spec.tsx => SessionsTable.test.tsx} (93%) rename src/pages/AccountSettings/tabs/Access/{TokensTable.spec.tsx => TokensTable.test.tsx} (96%) rename src/pages/AccountSettings/tabs/Admin/{Admin.spec.jsx => Admin.test.jsx} (83%) rename src/pages/AccountSettings/tabs/Admin/DeletionCard/{DeletionCard.spec.tsx => DeletionCard.test.tsx} (100%) rename src/pages/AccountSettings/tabs/Admin/DetailsSection/{DetailsSection.spec.jsx => DetailsSection.test.jsx} (91%) rename src/pages/AccountSettings/tabs/Admin/GithubIntegrationSection/{GithubIntegrationSection.spec.jsx => GithubIntegrationSection.test.jsx} (85%) rename src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AddAdmins/{AddAdmins.spec.jsx => AddAdmins.test.jsx} (87%) rename src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AdminTable/{AdminTable.spec.tsx => AdminTable.test.tsx} (89%) rename src/pages/AccountSettings/tabs/Admin/ManageAdminCard/{ManageAdminCard.spec.jsx => ManageAdminCard.test.jsx} (79%) rename src/pages/AccountSettings/tabs/Admin/StudentSection/{StudentSection.spec.jsx => StudentSection.test.jsx} (100%) rename src/pages/AccountSettings/tabs/OktaAccess/AdminAuthorizationBanner/{AdminAuthorizationBanner.spec.tsx => AdminAuthorizationBanner.test.tsx} (100%) rename src/pages/AccountSettings/tabs/OktaAccess/{OktaAccess.spec.tsx => OktaAccess.test.tsx} (86%) rename src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/{OktaConfigForm.spec.tsx => OktaConfigForm.test.tsx} (95%) rename src/pages/AccountSettings/tabs/OktaAccess/hooks/{useOktaConfig.spec.tsx => useOktaConfig.test.tsx} (85%) rename src/pages/AccountSettings/tabs/OktaAccess/hooks/{useUpdateOktaConfig.spec.tsx => useUpdateOktaConfig.test.tsx} (88%) rename src/pages/AccountSettings/tabs/OrgUploadToken/{OrgUploadToken.spec.jsx => OrgUploadToken.test.jsx} (92%) rename src/pages/AccountSettings/tabs/Profile/ActivationBanner/{ActivationBanner.spec.jsx => ActivationBanner.test.jsx} (91%) rename src/pages/AccountSettings/tabs/Profile/ActivationBanner/{useSelfActivationMutation.spec.js => useSelfActivationMutation.test.jsx} (82%) rename src/pages/AccountSettings/tabs/Profile/AdminBanner/{AdminBanner.spec.jsx => AdminBanner.test.jsx} (70%) rename src/pages/AccountSettings/tabs/Profile/DeletionCard/{DeletionCard.spec.tsx => DeletionCard.test.tsx} (100%) rename src/pages/AccountSettings/tabs/Profile/NameEmailCard/{NameEmailCard.spec.jsx => NameEmailCard.test.jsx} (94%) rename src/pages/AccountSettings/tabs/Profile/{Profile.spec.jsx => Profile.test.jsx} (57%) rename src/pages/AccountSettings/tabs/YAML/SuccessModal/{SuccessModal.spec.jsx => SuccessModal.test.jsx} (88%) rename src/pages/AccountSettings/tabs/YAML/{YAML.spec.jsx => YAML.test.jsx} (84%) rename src/pages/AccountSettings/tabs/YAML/YamlEditor/{YamlEditor.spec.jsx => YamlEditor.test.jsx} (100%) diff --git a/src/pages/AccountSettings/AccountSettings.spec.jsx b/src/pages/AccountSettings/AccountSettings.test.jsx similarity index 89% rename from src/pages/AccountSettings/AccountSettings.spec.jsx rename to src/pages/AccountSettings/AccountSettings.test.jsx index d3e65ae6c6..71454fdd3c 100644 --- a/src/pages/AccountSettings/AccountSettings.spec.jsx +++ b/src/pages/AccountSettings/AccountSettings.test.jsx @@ -1,7 +1,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen, waitFor } from '@testing-library/react' -import { graphql } from 'msw' -import { setupServer } from 'msw/node' +import { graphql, HttpResponse } from 'msw2' +import { setupServer } from 'msw2/node' import { Suspense } from 'react' import { MemoryRouter, Route } from 'react-router-dom' @@ -9,18 +9,19 @@ import config from 'config' import AccountSettings from './AccountSettings' -jest.mock('config') +vi.mock('config') -jest.mock('./shared/Header', () => () => 'Header') -jest.mock('./AccountSettingsSideMenu', () => () => 'AccountSettingsSideMenu') - -jest.mock('./tabs/Access', () => () => 'Access') -jest.mock('./tabs/Admin', () => () => 'Admin') -jest.mock('../NotFound', () => () => 'NotFound') -jest.mock('./tabs/OrgUploadToken', () => () => 'OrgUploadToken') -jest.mock('./tabs/Profile', () => () => 'Profile') -jest.mock('./tabs/YAML', () => () => 'YAML') -jest.mock('./tabs/OktaAccess', () => () => 'OktaAccess') +vi.mock('./shared/Header', () => ({ default: () => 'Header' })) +vi.mock('./AccountSettingsSideMenu', () => ({ + default: () => 'AccountSettingsSideMenu', +})) +vi.mock('./tabs/Access', () => ({ default: () => 'Access' })) +vi.mock('./tabs/Admin', () => ({ default: () => 'Admin' })) +vi.mock('../NotFound', () => ({ default: () => 'NotFound' })) +vi.mock('./tabs/OrgUploadToken', () => ({ default: () => 'OrgUploadToken' })) +vi.mock('./tabs/Profile', () => ({ default: () => 'Profile' })) +vi.mock('./tabs/YAML', () => ({ default: () => 'YAML' })) +vi.mock('./tabs/OktaAccess', () => ({ default: () => 'OktaAccess' })) const mockPlanData = { baseUnitPrice: 10, @@ -142,16 +143,17 @@ describe('AccountSettings', () => { config.HIDE_ACCESS_TAB = hideAccessTab server.use( - graphql.query('CurrentUser', (req, res, ctx) => { - return res(ctx.status(200), ctx.data(mockCurrentUser(username))) + graphql.query('CurrentUser', (info) => { + return HttpResponse.json({ data: mockCurrentUser(username) }) + }), + graphql.query('DetailOwner', (info) => { + return HttpResponse.json({ + data: { owner: { username: owner, isAdmin } }, + }) }), - graphql.query('DetailOwner', (req, res, ctx) => - res(ctx.status(200), ctx.data({ owner: { username: owner, isAdmin } })) - ), - graphql.query('GetPlanData', (req, res, ctx) => - res( - ctx.status(200), - ctx.data({ + graphql.query('GetPlanData', (info) => { + return HttpResponse.json({ + data: { owner: { hasPrivateRepos: true, plan: { @@ -159,9 +161,9 @@ describe('AccountSettings', () => { value: planValue, }, }, - }) - ) - ) + }, + }) + }) ) } diff --git a/src/pages/AccountSettings/AccountSettingsSideMenu.spec.jsx b/src/pages/AccountSettings/AccountSettingsSideMenu.test.jsx similarity index 96% rename from src/pages/AccountSettings/AccountSettingsSideMenu.spec.jsx rename to src/pages/AccountSettings/AccountSettingsSideMenu.test.jsx index 294106e6ba..4f21b210a4 100644 --- a/src/pages/AccountSettings/AccountSettingsSideMenu.spec.jsx +++ b/src/pages/AccountSettings/AccountSettingsSideMenu.test.jsx @@ -1,7 +1,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen, waitFor } from '@testing-library/react' -import { graphql } from 'msw' -import { setupServer } from 'msw/node' +import { graphql, HttpResponse } from 'msw2' +import { setupServer } from 'msw2/node' import { Suspense } from 'react' import { MemoryRouter, Route } from 'react-router-dom' @@ -9,7 +9,7 @@ import config from 'config' import AccountSettingsSideMenu from './AccountSettingsSideMenu' -jest.mock('config') +vi.mock('config') const mockPlanData = { baseUnitPrice: 10, @@ -131,16 +131,17 @@ describe('AccountSettingsSideMenu', () => { config.HIDE_ACCESS_TAB = hideAccessTab server.use( - graphql.query('CurrentUser', (req, res, ctx) => { - return res(ctx.status(200), ctx.data(mockCurrentUser(username))) + graphql.query('CurrentUser', (info) => { + return HttpResponse.json({ data: mockCurrentUser(username) }) }), - graphql.query('DetailOwner', (req, res, ctx) => - res(ctx.status(200), ctx.data({ owner: { username: owner, isAdmin } })) - ), - graphql.query('GetPlanData', (req, res, ctx) => - res( - ctx.status(200), - ctx.data({ + graphql.query('DetailOwner', (info) => { + return HttpResponse.json({ + data: { owner: { username: owner, isAdmin } }, + }) + }), + graphql.query('GetPlanData', (info) => { + return HttpResponse.json({ + data: { owner: { hasPrivateRepos: true, plan: { @@ -148,9 +149,9 @@ describe('AccountSettingsSideMenu', () => { value: planValue, }, }, - }) - ) - ) + }, + }) + }) ) } diff --git a/src/pages/AccountSettings/shared/Header/Header.spec.jsx b/src/pages/AccountSettings/shared/Header/Header.test.jsx similarity index 99% rename from src/pages/AccountSettings/shared/Header/Header.spec.jsx rename to src/pages/AccountSettings/shared/Header/Header.test.jsx index d85bbb8773..480752fc23 100644 --- a/src/pages/AccountSettings/shared/Header/Header.spec.jsx +++ b/src/pages/AccountSettings/shared/Header/Header.test.jsx @@ -7,7 +7,7 @@ import config from 'config' import Header from './Header' -jest.mock('config') +vi.mock('config') const queryClient = new QueryClient() const server = setupServer() diff --git a/src/pages/AccountSettings/tabs/Access/Access.spec.tsx b/src/pages/AccountSettings/tabs/Access/Access.test.tsx similarity index 93% rename from src/pages/AccountSettings/tabs/Access/Access.spec.tsx rename to src/pages/AccountSettings/tabs/Access/Access.test.tsx index 152527ceb4..31058d623c 100644 --- a/src/pages/AccountSettings/tabs/Access/Access.spec.tsx +++ b/src/pages/AccountSettings/tabs/Access/Access.test.tsx @@ -2,14 +2,14 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { subDays } from 'date-fns' -import { graphql } from 'msw' -import { setupServer } from 'msw/node' +import { graphql, HttpResponse } from 'msw2' +import { setupServer } from 'msw2/node' import { Suspense } from 'react' import { MemoryRouter, Route, useLocation } from 'react-router-dom' import Access from './Access' -window.confirm = jest.fn(() => true) +window.confirm = vi.fn(() => true) const mockSignedInUser = { me: { @@ -85,7 +85,6 @@ const queryClient = new QueryClient({ }, }, }) -const server = setupServer() let testLocation: ReturnType const wrapper: (initialEntries?: string) => React.FC = @@ -107,6 +106,7 @@ const wrapper: (initialEntries?: string) => React.FC = ) +const server = setupServer() beforeAll(() => { server.listen() }) @@ -125,11 +125,14 @@ describe('AccessTab', () => { const user = userEvent.setup() server.use( - graphql.query('MySessions', (req, res, ctx) => { - return res(ctx.status(200), ctx.data(mockSessionInfo)) + graphql.query('MySessions', (info) => { + return HttpResponse.json({ data: mockSessionInfo }) + }), + graphql.query('CurrentUser', (info) => { + return HttpResponse.json({ data: mockSignedInUser }) }), - graphql.query('CurrentUser', (req, res, ctx) => { - return res(ctx.status(200), ctx.data(mockSignedInUser)) + graphql.mutation('DeleteSession', (info) => { + return HttpResponse.json({ data: {} }) }) ) diff --git a/src/pages/AccountSettings/tabs/Access/CreateTokenModal.spec.jsx b/src/pages/AccountSettings/tabs/Access/CreateTokenModal.test.jsx similarity index 97% rename from src/pages/AccountSettings/tabs/Access/CreateTokenModal.spec.jsx rename to src/pages/AccountSettings/tabs/Access/CreateTokenModal.test.jsx index e170b9f0d5..6e8f706af5 100644 --- a/src/pages/AccountSettings/tabs/Access/CreateTokenModal.spec.jsx +++ b/src/pages/AccountSettings/tabs/Access/CreateTokenModal.test.jsx @@ -6,12 +6,12 @@ import { useGenerateUserToken } from 'services/access' import CreateTokenModal from './CreateTokenModal' -jest.mock('services/access') +vi.mock('services/access') describe('CreateTokenModal', () => { function setup() { const user = userEvent.setup() - const closeModal = jest.fn() + const closeModal = vi.fn() const success = { data: { createUserToken: { @@ -19,7 +19,7 @@ describe('CreateTokenModal', () => { }, }, } - const mutate = jest.fn((_, { onSuccess }) => { + const mutate = vi.fn((_, { onSuccess }) => { return onSuccess(success) }) useGenerateUserToken.mockReturnValue({ @@ -129,7 +129,7 @@ describe('CreateTokenModal', () => { expect(label).toBeInTheDocument() const copyElements = screen.getByTestId('clipboard-copy-token') expect(copyElements).toBeInTheDocument() - window.prompt = jest.fn() + window.prompt = vi.fn() await user.click(copyElements) expect(window.prompt).toHaveBeenCalled() diff --git a/src/pages/AccountSettings/tabs/Access/SessionsTable.spec.tsx b/src/pages/AccountSettings/tabs/Access/SessionsTable.test.tsx similarity index 93% rename from src/pages/AccountSettings/tabs/Access/SessionsTable.spec.tsx rename to src/pages/AccountSettings/tabs/Access/SessionsTable.test.tsx index ecb9322aa3..6509a0c7b5 100644 --- a/src/pages/AccountSettings/tabs/Access/SessionsTable.spec.tsx +++ b/src/pages/AccountSettings/tabs/Access/SessionsTable.test.tsx @@ -1,17 +1,18 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen, waitFor } from '@testing-library/react' import { userEvent } from '@testing-library/user-event' -import { graphql } from 'msw' -import { setupServer } from 'msw/node' +import { graphql, HttpResponse } from 'msw2' +import { setupServer } from 'msw2/node' import { MemoryRouter, Route } from 'react-router-dom' +import { type Mock } from 'vitest' import { Session } from 'services/access' import { formatTimeToNow } from 'shared/utils/dates' import SessionsTable from './SessionsTable' -jest.mock('shared/utils/dates') -const mockedFormatTimeToNow = formatTimeToNow as jest.Mock +vi.mock('shared/utils/dates') +const mockedFormatTimeToNow = formatTimeToNow as Mock window.confirm = () => true @@ -55,18 +56,19 @@ describe('SessionsTable', () => { function setup() { const user = userEvent.setup() mockedFormatTimeToNow.mockReturnValue('18 minutes ago') - const mutation = jest.fn() + const mutation = vi.fn() server.use( - graphql.mutation('DeleteSession', async (req, res, ctx) => { - mutation((await req.json()).variables.input) - return res(ctx.status(200), ctx.data({ owner: null })) + graphql.mutation('DeleteSession', async (info) => { + mutation(info.variables.input) + + return HttpResponse.json({ data: { owner: null } }) }) ) return { mutation, user } } afterEach(() => { - jest.resetAllMocks() + vi.resetAllMocks() }) describe('when rendering SessionsTable', () => { diff --git a/src/pages/AccountSettings/tabs/Access/TokensTable.spec.tsx b/src/pages/AccountSettings/tabs/Access/TokensTable.test.tsx similarity index 96% rename from src/pages/AccountSettings/tabs/Access/TokensTable.spec.tsx rename to src/pages/AccountSettings/tabs/Access/TokensTable.test.tsx index 52a97bd4fb..5d61d81539 100644 --- a/src/pages/AccountSettings/tabs/Access/TokensTable.spec.tsx +++ b/src/pages/AccountSettings/tabs/Access/TokensTable.test.tsx @@ -1,13 +1,14 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { MemoryRouter, Route } from 'react-router-dom' +import { type Mock } from 'vitest' import { useRevokeUserToken } from 'services/access' import TokensTable from './TokensTable' -jest.mock('services/access') -const mockedUseRevokeUserToken = useRevokeUserToken as jest.Mock +vi.mock('services/access') +const mockedUseRevokeUserToken = useRevokeUserToken as Mock window.confirm = () => true @@ -20,14 +21,14 @@ const wrapper: React.FC = ({ children }) => ( describe('TokensTable', () => { function setup() { const user = userEvent.setup() - const mutate = jest.fn() + const mutate = vi.fn() mockedUseRevokeUserToken.mockReturnValue({ mutate }) return { mutate, user } } afterEach(() => { - jest.resetAllMocks() + vi.clearAllMocks() }) describe('when rendering TokensTable', () => { diff --git a/src/pages/AccountSettings/tabs/Admin/Admin.spec.jsx b/src/pages/AccountSettings/tabs/Admin/Admin.test.jsx similarity index 83% rename from src/pages/AccountSettings/tabs/Admin/Admin.spec.jsx rename to src/pages/AccountSettings/tabs/Admin/Admin.test.jsx index 6bc134526e..31ec1d3a6d 100644 --- a/src/pages/AccountSettings/tabs/Admin/Admin.spec.jsx +++ b/src/pages/AccountSettings/tabs/Admin/Admin.test.jsx @@ -1,16 +1,18 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen } from '@testing-library/react' -import { graphql } from 'msw' -import { setupServer } from 'msw/node' +import { graphql, HttpResponse } from 'msw2' +import { setupServer } from 'msw2/node' import { MemoryRouter, Route } from 'react-router-dom' import Admin from './Admin' -jest.mock('./DetailsSection', () => () => 'DetailsSection') -jest.mock('./StudentSection', () => () => 'StudentSection') -jest.mock('./GithubIntegrationSection', () => () => 'GithubIntegrationSection') -jest.mock('./ManageAdminCard', () => () => 'ManageAdminCard') -jest.mock('./DeletionCard', () => () => 'DeletionCard') +vi.mock('./DetailsSection', () => ({ default: () => 'DetailsSection' })) +vi.mock('./StudentSection', () => ({ default: () => 'StudentSection' })) +vi.mock('./GithubIntegrationSection', () => ({ + default: () => 'GithubIntegrationSection', +})) +vi.mock('./ManageAdminCard', () => ({ default: () => 'ManageAdminCard' })) +vi.mock('./DeletionCard', () => ({ default: () => 'DeletionCard' })) const user = { me: { @@ -70,18 +72,24 @@ const wrapper = ({ children }) => ( const server = setupServer() -beforeAll(() => server.listen()) +beforeAll(() => { + server.listen() +}) + beforeEach(() => { server.resetHandlers() queryClient.clear() }) -afterAll(() => server.close()) + +afterAll(() => { + server.close() +}) describe('AdminTab', () => { function setup() { server.use( - graphql.query('CurrentUser', (req, res, ctx) => { - return res(ctx.status(200), ctx.data(user)) + graphql.query('CurrentUser', (info) => { + return HttpResponse.json({ data: user }) }) ) } diff --git a/src/pages/AccountSettings/tabs/Admin/DeletionCard/DeletionCard.spec.tsx b/src/pages/AccountSettings/tabs/Admin/DeletionCard/DeletionCard.test.tsx similarity index 100% rename from src/pages/AccountSettings/tabs/Admin/DeletionCard/DeletionCard.spec.tsx rename to src/pages/AccountSettings/tabs/Admin/DeletionCard/DeletionCard.test.tsx diff --git a/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.spec.jsx b/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.test.jsx similarity index 91% rename from src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.spec.jsx rename to src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.test.jsx index fad2b5e2c0..f955fb17cb 100644 --- a/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.spec.jsx +++ b/src/pages/AccountSettings/tabs/Admin/DetailsSection/DetailsSection.test.jsx @@ -1,15 +1,15 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { graphql } from 'msw' -import { setupServer } from 'msw/node' +import { graphql, HttpResponse } from 'msw2' +import { setupServer } from 'msw2/node' import { MemoryRouter, Route } from 'react-router-dom' import { useAddNotification } from 'services/toastNotification' import DetailsSection from './DetailsSection' -jest.mock('services/toastNotification') +vi.mock('services/toastNotification') const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } }, @@ -24,42 +24,47 @@ const wrapper = ({ children }) => ( ) -beforeAll(() => server.listen()) +beforeAll(() => { + server.listen() +}) + beforeEach(() => { queryClient.clear() server.resetHandlers() }) -afterAll(() => server.close()) + +afterAll(() => { + server.close() +}) describe('DetailsSection', () => { function setup() { const user = userEvent.setup() - const mutate = jest.fn() - const addNotification = jest.fn() + const mutate = vi.fn() + const addNotification = vi.fn() useAddNotification.mockReturnValue(addNotification) server.use( - graphql.mutation('UpdateProfile', (req, res, ctx) => { - mutate(req.variables) + graphql.mutation('UpdateProfile', (info) => { + mutate(info.variables) - return res( - ctx.status(200), - ctx.data({ + return HttpResponse.json({ + data: { updateProfile: { me: { username: 'donald duck', - email: req.variables.input.email - ? req.variables.input.email + email: info.variables.input.email + ? info.variables.input.email : 'donald@duck.com', - name: req.variables.input.name - ? req.variables.input.name + name: info.variables.input.name + ? info.variables.input.name : 'donald duck', avatarUrl: 'http://127.0.0.1/avatar-url', onboardingCompleted: false, }, }, - }) - ) + }, + }) }) ) diff --git a/src/pages/AccountSettings/tabs/Admin/GithubIntegrationSection/GithubIntegrationSection.spec.jsx b/src/pages/AccountSettings/tabs/Admin/GithubIntegrationSection/GithubIntegrationSection.test.jsx similarity index 85% rename from src/pages/AccountSettings/tabs/Admin/GithubIntegrationSection/GithubIntegrationSection.spec.jsx rename to src/pages/AccountSettings/tabs/Admin/GithubIntegrationSection/GithubIntegrationSection.test.jsx index a5c762e6e2..e66896f894 100644 --- a/src/pages/AccountSettings/tabs/Admin/GithubIntegrationSection/GithubIntegrationSection.spec.jsx +++ b/src/pages/AccountSettings/tabs/Admin/GithubIntegrationSection/GithubIntegrationSection.test.jsx @@ -1,7 +1,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen } from '@testing-library/react' -import { rest } from 'msw' -import { setupServer } from 'msw/node' +import { http, HttpResponse } from 'msw2' +import { setupServer } from 'msw2/node' import { MemoryRouter, Route } from 'react-router-dom' import config from 'config' @@ -31,10 +31,12 @@ const wrapper = beforeAll(() => { server.listen() }) + afterEach(() => { queryClient.clear() server.resetHandlers() }) + afterAll(() => { server.close() }) @@ -49,23 +51,20 @@ describe('GithubIntegrationSection', () => { config.IS_SELF_HOSTED = isSelfHosted server.use( - rest.get(`/internal/gh/codecov/account-details/`, (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ - plan: { - marketingName: 'users-basic', - baseUnitPrice: 12, - benefits: ['Configurable # of users', 'Unlimited repos'], - quantity: 5, - value: 'users-inappm', - }, - activatedUserCount: 2, - inactiveUserCount: 1, - integrationId: 2, - ...accountDetails, - }) - ) + http.get(`/internal/gh/codecov/account-details/`, (info) => { + return HttpResponse.json({ + plan: { + marketingName: 'users-basic', + baseUnitPrice: 12, + benefits: ['Configurable # of users', 'Unlimited repos'], + quantity: 5, + value: 'users-inappm', + }, + activatedUserCount: 2, + inactiveUserCount: 1, + integrationId: 2, + ...accountDetails, + }) }) ) } diff --git a/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AddAdmins/AddAdmins.spec.jsx b/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AddAdmins/AddAdmins.test.jsx similarity index 87% rename from src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AddAdmins/AddAdmins.spec.jsx rename to src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AddAdmins/AddAdmins.test.jsx index b8e7d5563c..79a4c3f166 100644 --- a/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AddAdmins/AddAdmins.spec.jsx +++ b/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AddAdmins/AddAdmins.test.jsx @@ -6,7 +6,7 @@ import { useUsers } from 'services/users' import AddAdmins from './AddAdmins' -jest.mock('services/users') +vi.mock('services/users') const wrapper = ({ children }) => ( @@ -32,21 +32,21 @@ describe('AddAdmins', () => { beforeEach(() => setup([])) it('renders an empty input', () => { - render(, { wrapper }) + render(, { wrapper }) const textbox = screen.getByRole('combobox') expect(textbox).toHaveValue('') }) it(`doesn't render any dropdown`, () => { - render(, { wrapper }) + render(, { wrapper }) const listBox = screen.getByRole('listbox') expect(listBox).toHaveClass('hidden') }) it(`doesn't call the API`, () => { - render(, { wrapper }) + render(, { wrapper }) expect(useUsers.mock.calls[0][0].opts.enabled).toBeFalsy() }) @@ -55,7 +55,7 @@ describe('AddAdmins', () => { describe('when typing and the api is loading', () => { it('renders the dropdown', async () => { const { user } = setup([], true) - render(, { wrapper }) + render(, { wrapper }) const textbox = screen.getByRole('combobox') await user.type(textbox, 'hello') @@ -66,7 +66,7 @@ describe('AddAdmins', () => { it('renders the loading state', async () => { const { user } = setup([], true) - render(, { wrapper }) + render(, { wrapper }) expect(await screen.findByRole('combobox')).toBeTruthy() const textbox = screen.getByRole('combobox') @@ -81,7 +81,7 @@ describe('AddAdmins', () => { describe('when typing and the api returns no data', () => { it('renders the dropdown', async () => { const { user } = setup([]) - render(, { wrapper }) + render(, { wrapper }) const textbox = screen.getByRole('combobox') await user.type(textbox, 'hello') @@ -92,7 +92,7 @@ describe('AddAdmins', () => { it('renders the empty state', async () => { const { user } = setup([]) - render(, { wrapper }) + render(, { wrapper }) const textbox = screen.getByRole('combobox') await user.type(textbox, 'hello') @@ -106,7 +106,7 @@ describe('AddAdmins', () => { const { user } = setup([ { username: 'launda', email: 'c3@cr.io', name: 'laudna' }, ]) - render(, { wrapper }) + render(, { wrapper }) const textbox = screen.getByRole('combobox') await user.type(textbox, 'hello') @@ -118,7 +118,7 @@ describe('AddAdmins', () => { const { user } = setup([ { username: 'funspooky', email: 'c3@cr.io', name: 'laudna' }, ]) - render(, { wrapper }) + render(, { wrapper }) const textbox = screen.getByRole('combobox') await user.type(textbox, 'hello') @@ -138,7 +138,7 @@ describe('AddAdmins', () => { it('calls the setAdminStatus with the user', async () => { const users = [{ username: 'launda', email: 'c3@cr.io', name: 'laudna' }] const { user } = setup(users) - const setAdminStatus = jest.fn() + const setAdminStatus = vi.fn() render(, { wrapper }) let textbox = screen.getByRole('combobox') @@ -156,7 +156,7 @@ describe('AddAdmins', () => { const { user } = setup([ { username: 'launda', email: 'c3@cr.io', name: 'laudna' }, ]) - render(, { wrapper }) + render(, { wrapper }) let textbox = screen.getByRole('combobox') await user.type(textbox, 'hello') @@ -174,7 +174,7 @@ describe('AddAdmins', () => { const { user } = setup([ { username: 'launda', email: 'c3@cr.io', name: 'laudna' }, ]) - render(, { wrapper }) + render(, { wrapper }) const textbox = screen.getByRole('combobox') await user.type(textbox, 'hello') @@ -193,7 +193,7 @@ describe('AddAdmins', () => { it('calls the setAdminStatus with the user', async () => { const users = [{ username: 'launda', email: 'c3@cr.io', name: 'laudna' }] const { user } = setup(users) - const setAdminStatus = jest.fn() + const setAdminStatus = vi.fn() render(, { wrapper }) let textbox = screen.getByRole('combobox') @@ -212,7 +212,7 @@ describe('AddAdmins', () => { const { user } = setup([ { username: 'launda', email: 'c3@cr.io', name: 'laudna' }, ]) - render(, { wrapper }) + render(, { wrapper }) let textbox = screen.getByRole('combobox') await user.type(textbox, 'hello') @@ -231,7 +231,7 @@ describe('AddAdmins', () => { const { user } = setup([ { username: 'launda', email: 'c3@cr.io', name: 'laudna' }, ]) - render(, { wrapper }) + render(, { wrapper }) const textbox = screen.getByRole('combobox') await user.type(textbox, 'hello') diff --git a/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AdminTable/AdminTable.spec.tsx b/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AdminTable/AdminTable.test.tsx similarity index 89% rename from src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AdminTable/AdminTable.spec.tsx rename to src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AdminTable/AdminTable.test.tsx index b2a39213d5..053f15de1e 100644 --- a/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AdminTable/AdminTable.spec.tsx +++ b/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/AdminTable/AdminTable.test.tsx @@ -1,8 +1,8 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen, waitFor } from '@testing-library/react' import { userEvent } from '@testing-library/user-event' -import { rest } from 'msw' -import { setupServer } from 'msw/node' +import { http, HttpResponse } from 'msw2' +import { setupServer } from 'msw2/node' import { mockAllIsIntersecting } from 'react-intersection-observer/test-utils' import { MemoryRouter, Route } from 'react-router-dom' @@ -82,12 +82,18 @@ const queryClient = new QueryClient({ }, }) -beforeAll(() => server.listen()) +beforeAll(() => { + server.listen() +}) + afterEach(() => { queryClient.clear() server.resetHandlers() }) -afterAll(() => server.close()) + +afterAll(() => { + server.close() +}) const wrapper: React.FC = ({ children }) => ( @@ -109,32 +115,31 @@ describe('AdminTable', () => { function setup({ nullUsername = false, emptyAdmins = false }: SetupArgs) { const user = userEvent.setup({}) server.use( - rest.patch( - '/internal/:provider/codecov/users/:userId', - (req, res, ctx) => { - patchRequest = { - userId: req.params.userId as string, - body: req.json(), - } - return res(ctx.status(204)) + http.patch('/internal/:provider/codecov/users/:userId', (info) => { + patchRequest = { + userId: info.params.userId as string, + body: info?.request?.json(), } - ), - rest.get('/internal/:provider/codecov/users', (req, res, ctx) => { + + return HttpResponse.text('no content', { status: 200 }) + }), + http.get('/internal/:provider/codecov/users', (info) => { if (nullUsername) { - return res(ctx.status(200), ctx.json(mockedNullUsername)) + return HttpResponse.json(mockedNullUsername) } if (emptyAdmins) { - return res(ctx.status(200), ctx.json(mockedEmptyAdmins)) + return HttpResponse.json(mockedEmptyAdmins) } - requestSearchParams = req.url.searchParams - const pageNum = Number(requestSearchParams.get('page')) + const url = new URL(info.request.url) + requestSearchParams = url.searchParams + const pageNum = Number(url.searchParams.get('page')) if (pageNum > 1) { - return res(ctx.status(200), ctx.json(mockedSecondResponse)) + return HttpResponse.json(mockedSecondResponse) } - return res(ctx.status(200), ctx.json(mockedFirstResponse)) + return HttpResponse.json(mockedFirstResponse) }) ) mockAllIsIntersecting(false) diff --git a/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/ManageAdminCard.spec.jsx b/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/ManageAdminCard.test.jsx similarity index 79% rename from src/pages/AccountSettings/tabs/Admin/ManageAdminCard/ManageAdminCard.spec.jsx rename to src/pages/AccountSettings/tabs/Admin/ManageAdminCard/ManageAdminCard.test.jsx index fb9067045f..25b15981a7 100644 --- a/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/ManageAdminCard.spec.jsx +++ b/src/pages/AccountSettings/tabs/Admin/ManageAdminCard/ManageAdminCard.test.jsx @@ -1,8 +1,8 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { rest } from 'msw' -import { setupServer } from 'msw/node' +import { http, HttpResponse } from 'msw2' +import { setupServer } from 'msw2/node' import { MemoryRouter, Route } from 'react-router-dom' import ManageAdminCard from './ManageAdminCard' @@ -55,54 +55,48 @@ const wrapper = ({ children }) => ( describe('ManageAdminCard', () => { function setup(adminResults = []) { const user = userEvent.setup() - const refetch = jest.fn() - const mutate = jest.fn() - const searchParams = jest.fn() + const refetch = vi.fn() + const mutate = vi.fn() + const searchParams = vi.fn() server.use( - rest.get('/internal/gh/codecov/users', (req, res, ctx) => { - const searchParam = req.url.searchParams.get('search') + http.get('/internal/gh/codecov/users', (info) => { + const url = new URL(info.request.url) + const searchParam = url.searchParams.get('search') if (searchParam !== null && searchParam !== '') { searchParams(searchParam) - - return res( - ctx.status(200), - ctx.json({ - count: 1, - next: null, - previous: null, - results: [ - { - activated: true, - is_admin: false, - username: 'searched-user', - email: 'searched-user@codecov.io', - ownerid: 10, - student: false, - name: 'searching-user', - last_pull_timestamp: null, - }, - ], - total_pages: 1, - }) - ) + return HttpResponse.json({ + count: 1, + next: null, + previous: null, + results: [ + { + activated: true, + is_admin: false, + username: 'searched-user', + email: 'searched-user@codecov.io', + ownerid: 10, + student: false, + name: 'searching-user', + last_pull_timestamp: null, + }, + ], + total_pages: 1, + }) } - return res( - ctx.status(200), - ctx.json({ - ...mockUsersRequest, - results: adminResults, - }) - ) + return HttpResponse.json({ + ...mockUsersRequest, + results: adminResults, + }) }), - rest.patch('/internal/gh/codecov/users/:userId/', (req, res, ctx) => { - const userId = req.params.userId + http.patch('/internal/gh/codecov/users/:userId/', (info) => { + const userId = info.params.userId mutate(userId) - return res(ctx.status(200), ctx.json({})) + return HttpResponse.json({}) }) ) diff --git a/src/pages/AccountSettings/tabs/Admin/StudentSection/StudentSection.spec.jsx b/src/pages/AccountSettings/tabs/Admin/StudentSection/StudentSection.test.jsx similarity index 100% rename from src/pages/AccountSettings/tabs/Admin/StudentSection/StudentSection.spec.jsx rename to src/pages/AccountSettings/tabs/Admin/StudentSection/StudentSection.test.jsx diff --git a/src/pages/AccountSettings/tabs/OktaAccess/AdminAuthorizationBanner/AdminAuthorizationBanner.spec.tsx b/src/pages/AccountSettings/tabs/OktaAccess/AdminAuthorizationBanner/AdminAuthorizationBanner.test.tsx similarity index 100% rename from src/pages/AccountSettings/tabs/OktaAccess/AdminAuthorizationBanner/AdminAuthorizationBanner.spec.tsx rename to src/pages/AccountSettings/tabs/OktaAccess/AdminAuthorizationBanner/AdminAuthorizationBanner.test.tsx diff --git a/src/pages/AccountSettings/tabs/OktaAccess/OktaAccess.spec.tsx b/src/pages/AccountSettings/tabs/OktaAccess/OktaAccess.test.tsx similarity index 86% rename from src/pages/AccountSettings/tabs/OktaAccess/OktaAccess.spec.tsx rename to src/pages/AccountSettings/tabs/OktaAccess/OktaAccess.test.tsx index a303217375..f9cbe43387 100644 --- a/src/pages/AccountSettings/tabs/OktaAccess/OktaAccess.spec.tsx +++ b/src/pages/AccountSettings/tabs/OktaAccess/OktaAccess.test.tsx @@ -1,13 +1,12 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen } from '@testing-library/react' -import { graphql } from 'msw' -import { setupServer } from 'msw/node' +import { graphql, HttpResponse } from 'msw2' +import { setupServer } from 'msw2/node' import { Suspense } from 'react' import { MemoryRouter, Route } from 'react-router-dom' import OktaAccess from './OktaAccess' -const server = setupServer() const queryClient = new QueryClient({ defaultOptions: { queries: { suspense: true, retry: false } }, }) @@ -22,6 +21,7 @@ const wrapper: React.FC = ({ children }) => ( ) +const server = setupServer() beforeAll(() => { server.listen({ onUnhandledRequest: 'warn' }) }) @@ -38,16 +38,14 @@ afterAll(() => { describe('OktaAccess', () => { function setup({ isAdmin = false } = {}) { server.use( - graphql.query('DetailOwner', (req, res, ctx) => - res( - ctx.status(200), - ctx.data({ owner: { username: 'codecov', isAdmin } }) - ) - ), - graphql.query('GetOktaConfig', (req, res, ctx) => - res( - ctx.status(200), - ctx.data({ + graphql.query('DetailOwner', (info) => { + return HttpResponse.json({ + data: { owner: { username: 'codecov', isAdmin } }, + }) + }), + graphql.query('GetOktaConfig', (info) => { + return HttpResponse.json({ + data: { owner: { isUserOktaAuthenticated: true, account: { @@ -60,9 +58,9 @@ describe('OktaAccess', () => { }, }, }, - }) - ) - ) + }, + }) + }) ) } diff --git a/src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.spec.tsx b/src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx similarity index 95% rename from src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.spec.tsx rename to src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx index 3b83198e8d..3cd689dfb7 100644 --- a/src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.spec.tsx +++ b/src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.test.tsx @@ -1,8 +1,8 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { graphql } from 'msw' -import { setupServer } from 'msw/node' +import { graphql, HttpResponse } from 'msw2' +import { setupServer } from 'msw2/node' import { Suspense } from 'react' import { MemoryRouter, Route } from 'react-router-dom' @@ -47,33 +47,30 @@ const wrapper: React.FC = ({ children }) => ( describe('OktaConfigForm', () => { function setup() { const user = userEvent.setup() - const mutate = jest.fn() + const mutate = vi.fn() server.use( - graphql.query('GetOktaConfig', (req, res, ctx) => - res( - ctx.status(200), - ctx.data({ + graphql.query('GetOktaConfig', (info) => { + return HttpResponse.json({ + data: { owner: { isUserOktaAuthenticated: true, account: { oktaConfig: oktaConfigMock, }, }, - }) - ) - ), - graphql.mutation('SaveOktaConfig', (req, res, ctx) => { - mutate(req.variables) - - return res( - ctx.status(200), - ctx.data({ + }, + }) + }), + graphql.mutation('SaveOktaConfig', (info) => { + mutate(info.variables) + return HttpResponse.json({ + data: { saveOktaConfig: { error: null, }, - }) - ) + }, + }) }) ) return { user, mutate } @@ -142,9 +139,7 @@ describe('OktaConfigForm', () => { const clientSecretInput = await screen.findByLabelText(/Client Secret/) await userEvent.type(clientSecretInput, 'clientSecret') - const eyeIcon = await screen.findByRole('button', { - name: /eye/, - }) + const eyeIcon = await screen.findByTestId('toggle-password') await userEvent.click(eyeIcon) expect(clientSecretInput).toHaveAttribute('type', 'text') @@ -157,9 +152,7 @@ describe('OktaConfigForm', () => { const clientSecretInput = await screen.findByLabelText(/Client Secret/) await userEvent.type(clientSecretInput, 'clientSecret') - const eyeIcon = await screen.findByRole('button', { - name: /eye/, - }) + const eyeIcon = await screen.findByTestId('toggle-password') await userEvent.click(eyeIcon) await userEvent.click(eyeIcon) diff --git a/src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.tsx b/src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.tsx index 120d6bd89f..6f985ce347 100644 --- a/src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.tsx +++ b/src/pages/AccountSettings/tabs/OktaAccess/OktaConfigForm/OktaConfigForm.tsx @@ -120,11 +120,13 @@ export function OktaConfigForm() { />