From c82e842926146e477a37108da5ef5f088c6abfb1 Mon Sep 17 00:00:00 2001 From: Nick Grosenbacher Date: Thu, 29 Feb 2024 11:58:41 -0500 Subject: [PATCH] temp --- apps/synapse-oauth-signin/package.json | 2 +- .../src/mocks/handlers.ts | 28 +- .../src/test/App.test.tsx | 24 +- packages/synapse-react-client/jest.config.cjs | 2 + .../synapse-react-client/jest.polyfills.js | 29 ++ .../synapse-react-client/jest.resolver.js | 16 + packages/synapse-react-client/package.json | 3 +- ...onditionsForUseButton.integration.test.tsx | 6 +- ...poseRestrictionDialog.integration.test.tsx | 6 +- .../AccessRequirementList.stories.tsx | 107 +++--- ...ccessRequestAccessorsFilesForm.stories.tsx | 5 +- .../SelfSignAccessRequirementItem.stories.tsx | 44 +-- ...woFactorAuthEnabledRequirement.stories.tsx | 8 +- ...anagedACTAccessRequirementItem.stories.tsx | 30 +- ...sRequirementRelatedProjectsList.stories.ts | 8 +- .../CertificationQuiz.integration.test.tsx | 9 +- ...CreateTableViewWizard.integration.test.tsx | 26 +- .../DirectDownload.integration.test.tsx | 13 +- ...AccessRequirementCard.integration.test.tsx | 9 +- .../RequestDownloadCard.integration.test.tsx | 9 +- .../EvaluationEditor.integration.test.tsx | 37 +- .../EvaluationEditorPage.stories.ts | 49 ++- .../FileEntityPreview.integration.test.tsx | 11 +- ...HandleContentRenderer.integration.test.tsx | 11 +- .../HtmlPreview.integration.test.tsx | 8 +- .../DiscussionThread.integration.test.tsx | 39 +- .../GoogleMap/GoogleMap.integration.test.tsx | 16 +- .../HasAccessV2.integration.test.tsx | 9 +- .../IDUReport/IDUReport.integration.test.tsx | 9 +- .../CreateOAuthClient.integration.test.tsx | 15 +- ...rammaticTableDownload.integration.test.tsx | 7 +- .../ProvenanceGraph.integration.test.tsx | 23 +- ...ivenAnnotationsEditor.integration.test.tsx | 63 ++-- .../SynapseFormSubmissionsGrid.stories.tsx | 10 +- .../SynapseTable.integration.test.tsx | 43 +-- .../SynapseTable/SynapseTable.stories.tsx | 8 +- .../SynapseTableCell.integration.test.tsx | 34 +- .../DatasetItemsEditor.integration.test.tsx | 14 +- .../DownloadOptions.integration.test.tsx | 8 +- .../TableColumnSchemaEditor.stories.ts | 8 +- .../TimelinePlot/TimelinePlot.stories.tsx | 6 +- .../UserCard/UserCard.integration.test.tsx | 9 +- .../AccessApprovalsTable.integration.test.tsx | 11 +- ...ccessHistoryDashboard.integration.test.tsx | 21 +- ...equestSubmissionTable.integration.test.tsx | 9 +- ...sRequirementSearchBox.integration.test.tsx | 12 +- ...ccessRequirementTable.integration.test.tsx | 9 +- ...ssSubmissionDashboard.integration.test.tsx | 15 +- ...ataAccessRequestModal.integration.test.tsx | 9 +- .../ReviewerDashboard.integration.test.tsx | 9 +- .../SubmissionPage.integration.test.tsx | 39 +- .../dataaccess/SubmissionPage.stories.tsx | 28 +- .../AnnotationsTable.integration.test.tsx | 6 +- .../TitleBarProperties.integration.test.tsx | 12 +- .../FavoriteButton.integration.test.tsx | 79 +--- .../trash/TrashCanList.integration.test.tsx | 126 ++----- .../src/mocks/mockTrashCan.ts | 37 ++ .../src/mocks/msw/handlers.ts | 23 +- .../msw/handlers/accessRequirementHandlers.ts | 71 ++-- .../mocks/msw/handlers/asyncJobHandlers.ts | 169 ++++----- .../mocks/msw/handlers/challengeHandlers.ts | 66 ++-- .../msw/handlers/dataAccessRequestHandlers.ts | 51 +-- .../mocks/msw/handlers/discussionHandlers.ts | 134 +++---- .../src/mocks/msw/handlers/entityHandlers.ts | 259 +++++++------ .../mocks/msw/handlers/evaluationHandlers.ts | 33 +- .../mocks/msw/handlers/favoritesHandlers.ts | 52 +++ .../src/mocks/msw/handlers/fileHandlers.ts | 42 ++- .../handlers/personalAccessTokenHandlers.ts | 38 +- .../msw/handlers/researchProjectHandlers.ts | 22 +- .../msw/handlers/subscriptionHandlers.ts | 73 ++-- .../mocks/msw/handlers/tableQueryHandlers.ts | 33 +- .../src/mocks/msw/handlers/teamHandlers.ts | 79 ++-- .../mocks/msw/handlers/trashCanHandlers.ts | 55 +++ .../mocks/msw/handlers/userProfileHandlers.ts | 230 ++++++------ .../src/mocks/msw/handlers/wikiHandlers.ts | 30 +- .../src/mocks/msw/server.ts | 4 +- .../SynapseClient.integration.test.ts | 41 +-- .../usePreFetchResource.integration.test.tsx | 18 +- .../EntityBadgeIcons.integration.test.tsx | 50 +-- .../details/DetailsView.integration.test.tsx | 6 +- .../tree/EntityTree.integration.test.tsx | 26 +- .../MarkdownSynapse.integration.test.tsx | 6 +- pnpm-lock.yaml | 340 +++++++++--------- 83 files changed, 1684 insertions(+), 1510 deletions(-) create mode 100644 packages/synapse-react-client/jest.polyfills.js create mode 100644 packages/synapse-react-client/jest.resolver.js create mode 100644 packages/synapse-react-client/src/mocks/mockTrashCan.ts create mode 100644 packages/synapse-react-client/src/mocks/msw/handlers/favoritesHandlers.ts create mode 100644 packages/synapse-react-client/src/mocks/msw/handlers/trashCanHandlers.ts diff --git a/apps/synapse-oauth-signin/package.json b/apps/synapse-oauth-signin/package.json index bf7a57d1af..231413dcf1 100644 --- a/apps/synapse-oauth-signin/package.json +++ b/apps/synapse-oauth-signin/package.json @@ -62,7 +62,7 @@ "markdown-it-synapse-math": "^3.0.5", "markdown-it-synapse-table": "^1.0.6", "memfs": "^3.5.3", - "msw": "^1.2.2", + "msw": "^2.2.2", "object-assign": "^4.1.1", "path-browserify": "^1.0.1", "pluralize": "^8.0.0", diff --git a/apps/synapse-oauth-signin/src/mocks/handlers.ts b/apps/synapse-oauth-signin/src/mocks/handlers.ts index 484fcc2727..22b3a69c43 100644 --- a/apps/synapse-oauth-signin/src/mocks/handlers.ts +++ b/apps/synapse-oauth-signin/src/mocks/handlers.ts @@ -1,24 +1,24 @@ -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import mockOauthClient from './MockOAuthClient' export const handlers = [ - rest.get( + http.get( 'https://repo-prod.prod.sagebase.org/repo/v1/userProfile', - (req, res, ctx) => { + ({ request, params }) => { return res(ctx.status(200), ctx.json({})) }, ), - rest.get( + http.get( 'https://repo-prod.prod.sagebase.org/auth/v1/oauth2/client/:id', - (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockOauthClient)) + ({ request, params }) => { + return HttpResponse.json(mockOauthClient, { status: 200 }) }, ), - rest.post( + http.post( 'https://repo-prod.prod.sagebase.org/auth/v1/oauth2/description', - (req, res, ctx) => { + ({ request, params }) => { return res( ctx.status(200), ctx.json({ @@ -32,9 +32,9 @@ export const handlers = [ }, ), - rest.post( + http.post( 'https://repo-prod.prod.sagebase.org/auth/v1/login2', - (req, res, ctx) => { + ({ request, params }) => { return res( ctx.status(200), ctx.json({ @@ -45,9 +45,9 @@ export const handlers = [ }, ), - rest.post( + http.post( 'https://repo-prod.prod.sagebase.org/auth/v1/oauth2/consentcheck', - (req, res, ctx) => { + ({ request, params }) => { return res( ctx.status(200), ctx.json({ @@ -57,9 +57,9 @@ export const handlers = [ }, ), - rest.post( + http.post( 'https://repo-prod.prod.sagebase.org/auth/v1/oauth2/consent', - (req, res, ctx) => { + ({ request, params }) => { return res( ctx.status(200), ctx.json({ diff --git a/apps/synapse-oauth-signin/src/test/App.test.tsx b/apps/synapse-oauth-signin/src/test/App.test.tsx index d7a6a6ffcf..ab7bfd9202 100644 --- a/apps/synapse-oauth-signin/src/test/App.test.tsx +++ b/apps/synapse-oauth-signin/src/test/App.test.tsx @@ -1,6 +1,6 @@ import { render, screen, waitFor } from '@testing-library/react' import { server } from '../mocks/server' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import React from 'react' import { SynapseClient, SynapseConstants } from 'synapse-react-client' import App from '../App' @@ -75,9 +75,9 @@ describe('App integration tests', () => { document.cookie = `${ACCESS_TOKEN_COOKIE_KEY}=expired` // Backend should return with an invalid_token response server.use( - rest.get( + http.get( 'https://repo-prod.prod.sagebase.org/repo/v1/userProfile', - (req, res, ctx) => { + ({ request, params }) => { return res( ctx.status(401), ctx.json({ @@ -204,9 +204,9 @@ describe('App integration tests', () => { // Consent has already been granted: const hasGrantedConsent = true server.use( - rest.post( + http.post( 'https://repo-prod.prod.sagebase.org/auth/v1/oauth2/consentcheck', - (req, res, ctx) => { + ({ request, params }) => { return res( ctx.status(200), ctx.json({ @@ -252,10 +252,10 @@ describe('App integration tests', () => { const authenticationReciept = 'imv890vm0ewvmim3' server.use( - rest.post( + http.post( 'https://repo-prod.prod.sagebase.org/auth/v1/oauth2/session2', - async (req, res, ctx) => { - const requestBody = await req.json() + async ({ request, params }) => { + const requestBody = await request.json() onOAuthSignIn(requestBody) return res( @@ -271,17 +271,17 @@ describe('App integration tests', () => { ) }, ), - rest.post( + http.post( 'https://repo-prod.prod.sagebase.org/auth/v1/2fa/token', - async (req, res, ctx) => { - const requestBody = await req.json() + async ({ request, params }) => { + const requestBody = await request.json() on2FASignIn(requestBody) const responseBody: LoginResponse = { accessToken: accessToken, authenticationReceipt: authenticationReciept, acceptsTermsOfUse: true, } - return res(ctx.status(201), ctx.json(responseBody)) + return HttpResponse.json(responseBody, { status: 201 }) }, ), ) diff --git a/packages/synapse-react-client/jest.config.cjs b/packages/synapse-react-client/jest.config.cjs index 38dca017c9..446bff2693 100644 --- a/packages/synapse-react-client/jest.config.cjs +++ b/packages/synapse-react-client/jest.config.cjs @@ -16,6 +16,7 @@ const shared = { transformIgnorePatterns: [ `node_modules/(?!(?:.pnpm/)?(${esModules.join('|')}))`, ], + setupFiles: ['./jest.polyfills.js'], setupFilesAfterEnv: ['/test/setupTests.ts'], resetMocks: false, } @@ -51,4 +52,5 @@ module.exports = { ], ], coverageReporters: ['text-summary', 'html'], + resolver: './jest.resolver.js' } diff --git a/packages/synapse-react-client/jest.polyfills.js b/packages/synapse-react-client/jest.polyfills.js new file mode 100644 index 0000000000..f543669381 --- /dev/null +++ b/packages/synapse-react-client/jest.polyfills.js @@ -0,0 +1,29 @@ +/** + * @note The block below contains polyfills for Node.js globals + * required for Jest to function when running JSDOM tests. + * These HAVE to be require's and HAVE to be in this exact + * order, since "undici" depends on the "TextEncoder" global API. + * + * Consider migrating to a more modern test runner if + * you don't want to deal with this. + */ +const { TextDecoder, TextEncoder, ReadableStream } = require('node:util') + +Object.defineProperties(globalThis, { + TextDecoder: { value: TextDecoder }, + TextEncoder: { value: TextEncoder }, + ReadableStream: { value: ReadableStream }, +}) + +const { Blob, File } = require('node:buffer') +const { fetch, Headers, FormData, Request, Response } = require('undici') + +Object.defineProperties(globalThis, { + fetch: { value: fetch, writable: true }, + Blob: { value: Blob }, + File: { value: File }, + Headers: { value: Headers }, + FormData: { value: FormData }, + Request: { value: Request }, + Response: { value: Response }, +}) diff --git a/packages/synapse-react-client/jest.resolver.js b/packages/synapse-react-client/jest.resolver.js new file mode 100644 index 0000000000..adeb54da26 --- /dev/null +++ b/packages/synapse-react-client/jest.resolver.js @@ -0,0 +1,16 @@ +module.exports = (path, options) => { + // Jest + jsdom acts like a browser (i.e., it looks for "browser" imports + // under pkg.exports), but msw knows that you're operating in a Node + // environment: + // + // https://github.com/mswjs/msw/issues/1786#issuecomment-1782559851 + // + // The MSW project's recommended workaround is to disable Jest's + // customExportConditions completely, so no packages use their browser's + // versions. We'll instead clear export conditions only for MSW. + if (/^(msw|@mswjs\/interceptors)(\/|$)/.test(path)) { + return options.defaultResolver(path, { ...options, conditions: [] }) + } + + return options.defaultResolver(path, options) +} diff --git a/packages/synapse-react-client/package.json b/packages/synapse-react-client/package.json index 1d9873ad5a..d608ba2a38 100644 --- a/packages/synapse-react-client/package.json +++ b/packages/synapse-react-client/package.json @@ -217,7 +217,7 @@ "jotai-devtools": "^0.6.2", "jsdom": "^21.1.2", "memfs": "^3.5.3", - "msw": "^1.2.2", + "msw": "^2.2.2", "msw-storybook-addon": "^1.10.0", "path-browserify": "^1.0.1", "postcss-normalize": "^10.0.1", @@ -235,6 +235,7 @@ "tsup": "^6.7.0", "type-fest": "^3.13.0", "typescript": "5.1.6", + "undici": "^6.6.2", "util": "^0.12.5", "vite": "^4.5.2", "vite-plugin-svgr": "^3.2.0", diff --git a/packages/synapse-react-client/src/components/AccessRequirement/AddConditionsForUseButton/AddConditionsForUseButton.integration.test.tsx b/packages/synapse-react-client/src/components/AccessRequirement/AddConditionsForUseButton/AddConditionsForUseButton.integration.test.tsx index 9bcf54286f..2deebfe85b 100644 --- a/packages/synapse-react-client/src/components/AccessRequirement/AddConditionsForUseButton/AddConditionsForUseButton.integration.test.tsx +++ b/packages/synapse-react-client/src/components/AccessRequirement/AddConditionsForUseButton/AddConditionsForUseButton.integration.test.tsx @@ -28,14 +28,14 @@ const mockCallback = jest.fn() // Adding this mock service worker handler will make the component recognize the caller as an ACT member function setIsCurrentUserMemberOfACT(isActMember: boolean) { server.use( - rest.get( + http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${USER_BUNDLE}`, - async (req, res, ctx) => { + async ({ request, params }) => { const result: UserBundle = { ...mockUserBundle, isACTMember: isActMember, } - return res(ctx.status(200), ctx.json(result)) + return HttpResponse.json(result, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/AccessRequirement/ImposeRestrictionDialog/ImposeRestrictionDialog.integration.test.tsx b/packages/synapse-react-client/src/components/AccessRequirement/ImposeRestrictionDialog/ImposeRestrictionDialog.integration.test.tsx index 7e3f8e1339..f0c7d9f10a 100644 --- a/packages/synapse-react-client/src/components/AccessRequirement/ImposeRestrictionDialog/ImposeRestrictionDialog.integration.test.tsx +++ b/packages/synapse-react-client/src/components/AccessRequirement/ImposeRestrictionDialog/ImposeRestrictionDialog.integration.test.tsx @@ -28,13 +28,13 @@ function renderComponent() { const onApplyLock = jest.fn() server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/entity/:id/lockAccessRequirement`, - async (req, res, ctx) => { + async ({ request, params }) => { onApplyLock() - return res(ctx.status(201), ctx.json(mockLockAccessRequirement)) + return HttpResponse.json(mockLockAccessRequirement, { status: 201 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/AccessRequirementList/AccessRequirementList.stories.tsx b/packages/synapse-react-client/src/components/AccessRequirementList/AccessRequirementList.stories.tsx index 953805088d..fd7f6a98f7 100644 --- a/packages/synapse-react-client/src/components/AccessRequirementList/AccessRequirementList.stories.tsx +++ b/packages/synapse-react-client/src/components/AccessRequirementList/AccessRequirementList.stories.tsx @@ -1,6 +1,6 @@ import React from 'react' import { Meta, StoryObj } from '@storybook/react' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { MOCK_REPO_ORIGIN } from '../../utils/functions/getEndpoint' import { ACCESS_APPROVAL } from '../../utils/APIConstants' import { @@ -69,15 +69,15 @@ type Story = StoryObj function getTwoFactorAuthStatusHandler(enabled: boolean) { return [ - rest.get( + http.get( `${MOCK_REPO_ORIGIN}/auth/v1/2fa`, - async (req, res, ctx) => { + async () => { const status = 200 const response: TwoFactorAuthStatus = { status: enabled ? 'ENABLED' : 'DISABLED', } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status: status }) }, ), ] @@ -196,24 +196,21 @@ export const HasUnmetRequirements: Story = { ]), ...getWikiHandlers(MOCK_REPO_ORIGIN), ...getResearchProjectHandlers(MOCK_REPO_ORIGIN), - rest.post( - `${MOCK_REPO_ORIGIN}${ACCESS_APPROVAL}`, - async (req, res, ctx) => { - const response: AccessApproval = { - requirementId: mockACTAccessRequirement.id, - submitterId: MOCK_USER_ID.toString(), - accessorId: MOCK_USER_ID.toString(), - state: ApprovalState.APPROVED, - id: 123, - etag: 'etag', - createdOn: new Date().toISOString(), - modifiedOn: new Date().toISOString(), - createdBy: String(MOCK_USER_ID), - modifiedBy: String(MOCK_USER_ID), - } - return res(ctx.status(201), ctx.json(response)) - }, - ), + http.post(`${MOCK_REPO_ORIGIN}${ACCESS_APPROVAL}`, async () => { + const response: AccessApproval = { + requirementId: mockACTAccessRequirement.id, + submitterId: MOCK_USER_ID.toString(), + accessorId: MOCK_USER_ID.toString(), + state: ApprovalState.APPROVED, + id: 123, + etag: 'etag', + createdOn: new Date().toISOString(), + modifiedOn: new Date().toISOString(), + createdBy: String(MOCK_USER_ID), + modifiedBy: String(MOCK_USER_ID), + } + return HttpResponse.json(response, { status: 201 }) + }), ], }, }, @@ -242,24 +239,21 @@ export const NotValidated: Story = { }, ]), ...getWikiHandlers(MOCK_REPO_ORIGIN), - rest.post( - `${MOCK_REPO_ORIGIN}${ACCESS_APPROVAL}`, - async (req, res, ctx) => { - const response: AccessApproval = { - requirementId: mockSelfSignAccessRequirement.id, - submitterId: MOCK_USER_ID.toString(), - accessorId: MOCK_USER_ID.toString(), - state: ApprovalState.APPROVED, - id: 123, - etag: 'etag', - createdOn: new Date().toISOString(), - modifiedOn: new Date().toISOString(), - createdBy: String(MOCK_USER_ID), - modifiedBy: String(MOCK_USER_ID), - } - return res(ctx.status(201), ctx.json(response)) - }, - ), + http.post(`${MOCK_REPO_ORIGIN}${ACCESS_APPROVAL}`, async () => { + const response: AccessApproval = { + requirementId: mockSelfSignAccessRequirement.id, + submitterId: MOCK_USER_ID.toString(), + accessorId: MOCK_USER_ID.toString(), + state: ApprovalState.APPROVED, + id: 123, + etag: 'etag', + createdOn: new Date().toISOString(), + modifiedOn: new Date().toISOString(), + createdBy: String(MOCK_USER_ID), + modifiedBy: String(MOCK_USER_ID), + } + return HttpResponse.json(response, { status: 201 }) + }), ], }, }, @@ -288,24 +282,21 @@ export const NotCertified: Story = { }, ]), ...getWikiHandlers(MOCK_REPO_ORIGIN), - rest.post( - `${MOCK_REPO_ORIGIN}${ACCESS_APPROVAL}`, - async (req, res, ctx) => { - const response: AccessApproval = { - requirementId: mockSelfSignAccessRequirement.id, - submitterId: MOCK_USER_ID.toString(), - accessorId: MOCK_USER_ID.toString(), - state: ApprovalState.APPROVED, - id: 123, - etag: 'etag', - createdOn: new Date().toISOString(), - modifiedOn: new Date().toISOString(), - createdBy: String(MOCK_USER_ID), - modifiedBy: String(MOCK_USER_ID), - } - return res(ctx.status(201), ctx.json(response)) - }, - ), + http.post(`${MOCK_REPO_ORIGIN}${ACCESS_APPROVAL}`, async () => { + const response: AccessApproval = { + requirementId: mockSelfSignAccessRequirement.id, + submitterId: MOCK_USER_ID.toString(), + accessorId: MOCK_USER_ID.toString(), + state: ApprovalState.APPROVED, + id: 123, + etag: 'etag', + createdOn: new Date().toISOString(), + modifiedOn: new Date().toISOString(), + createdBy: String(MOCK_USER_ID), + modifiedBy: String(MOCK_USER_ID), + } + return HttpResponse.json(response, { status: 201 }) + }), ], }, }, diff --git a/packages/synapse-react-client/src/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.stories.tsx b/packages/synapse-react-client/src/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.stories.tsx index 63c6ebcbd3..98776c10b8 100644 --- a/packages/synapse-react-client/src/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.stories.tsx +++ b/packages/synapse-react-client/src/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.stories.tsx @@ -34,10 +34,7 @@ const meta: Meta< ...getFileHandlers(MOCK_REPO_ORIGIN), ...getWikiHandlers(MOCK_REPO_ORIGIN), ...getAccessRequirementHandlers(MOCK_REPO_ORIGIN), - ...getDataAccessRequestHandlers( - MOCK_REPO_ORIGIN, - MOCK_DATA_ACCESS_REQUEST, - ), + ...getDataAccessRequestHandlers(MOCK_REPO_ORIGIN), ], }, }, diff --git a/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/SelfSignAccessRequirementItem.stories.tsx b/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/SelfSignAccessRequirementItem.stories.tsx index 3d28f0d3ca..5af94fbc78 100644 --- a/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/SelfSignAccessRequirementItem.stories.tsx +++ b/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/SelfSignAccessRequirementItem.stories.tsx @@ -11,7 +11,7 @@ import { mockToUAccessRequirementWithWiki, } from '../../../mocks/mockAccessRequirements' import { MOCK_REPO_ORIGIN } from '../../../utils/functions/getEndpoint' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { ACCESS_APPROVAL, ACCESS_REQUIREMENT_STATUS, @@ -75,22 +75,22 @@ export const RequiresUnmetCertificationAndValidation: Story = { ...getAccessRequirementHandlers(MOCK_REPO_ORIGIN), ...getWikiHandlers(MOCK_REPO_ORIGIN), getCurrentUserCertifiedValidatedHandler(MOCK_REPO_ORIGIN, false, false), - rest.get( + http.get( `${MOCK_REPO_ORIGIN}${ACCESS_REQUIREMENT_STATUS(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: AccessRequirementStatus = { - accessRequirementId: req.params.id as string, + accessRequirementId: params.id as string, concreteType: 'org.sagebionetworks.repo.model.dataaccess.BasicAccessRequirementStatus', isApproved: false, } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), - rest.post( + http.post( `${MOCK_REPO_ORIGIN}${ACCESS_APPROVAL}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: AccessApproval = { requirementId: mockSelfSignAccessRequirement.id, submitterId: MOCK_USER_ID.toString(), @@ -103,7 +103,7 @@ export const RequiresUnmetCertificationAndValidation: Story = { createdBy: String(MOCK_USER_ID), modifiedBy: String(MOCK_USER_ID), } - return res(ctx.status(201), ctx.json(response)) + return HttpResponse.json(response, { status: 201 }) }, ), ], @@ -122,22 +122,22 @@ export const LegacyTermsOfUse: Story = { ...getAccessRequirementHandlers(MOCK_REPO_ORIGIN), ...getWikiHandlers(MOCK_REPO_ORIGIN), getCurrentUserCertifiedValidatedHandler(MOCK_REPO_ORIGIN, false, false), - rest.get( + http.get( `${MOCK_REPO_ORIGIN}${ACCESS_REQUIREMENT_STATUS(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: AccessRequirementStatus = { - accessRequirementId: req.params.id as string, + accessRequirementId: params.id as string, concreteType: 'org.sagebionetworks.repo.model.dataaccess.BasicAccessRequirementStatus', isApproved: false, } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), - rest.post( + http.post( `${MOCK_REPO_ORIGIN}${ACCESS_APPROVAL}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: AccessApproval = { requirementId: mockToUAccessRequirement.id, submitterId: MOCK_USER_ID.toString(), @@ -150,7 +150,7 @@ export const LegacyTermsOfUse: Story = { createdBy: String(MOCK_USER_ID), modifiedBy: String(MOCK_USER_ID), } - return res(ctx.status(201), ctx.json(response)) + return HttpResponse.json(response, { status: 201 }) }, ), ], @@ -169,22 +169,22 @@ export const LegacyTermsOfUseWithWiki: Story = { ...getAccessRequirementHandlers(MOCK_REPO_ORIGIN), ...getWikiHandlers(MOCK_REPO_ORIGIN), getCurrentUserCertifiedValidatedHandler(MOCK_REPO_ORIGIN, false, false), - rest.get( + http.get( `${MOCK_REPO_ORIGIN}${ACCESS_REQUIREMENT_STATUS(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: AccessRequirementStatus = { - accessRequirementId: req.params.id as string, + accessRequirementId: params.id as string, concreteType: 'org.sagebionetworks.repo.model.dataaccess.BasicAccessRequirementStatus', isApproved: false, } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), - rest.post( + http.post( `${MOCK_REPO_ORIGIN}${ACCESS_APPROVAL}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: AccessApproval = { requirementId: mockToUAccessRequirementWithWiki.id, submitterId: MOCK_USER_ID.toString(), @@ -197,7 +197,7 @@ export const LegacyTermsOfUseWithWiki: Story = { createdBy: String(MOCK_USER_ID), modifiedBy: String(MOCK_USER_ID), } - return res(ctx.status(201), ctx.json(response)) + return HttpResponse.json(response, { status: 201 }) }, ), ], diff --git a/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/TwoFactorAuthEnabledRequirement.stories.tsx b/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/TwoFactorAuthEnabledRequirement.stories.tsx index 9769f93f6c..b29f5199cd 100644 --- a/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/TwoFactorAuthEnabledRequirement.stories.tsx +++ b/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/TwoFactorAuthEnabledRequirement.stories.tsx @@ -1,6 +1,6 @@ import React from 'react' import { Meta, StoryObj } from '@storybook/react' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { MOCK_REPO_ORIGIN } from '../../../utils/functions/getEndpoint' import TwoFactorAuthEnabledRequirement from './TwoFactorAuthEnabledRequirement' import { TwoFactorAuthStatus } from '@sage-bionetworks/synapse-types' @@ -33,15 +33,15 @@ export default meta type Story = StoryObj function getTwoFactorAuthStatusHandler(enabled: boolean) { return [ - rest.get( + http.get( `${MOCK_REPO_ORIGIN}/auth/v1/2fa`, - async (req, res, ctx) => { + async ({ request, params }) => { const status = 200 const response: TwoFactorAuthStatus = { status: enabled ? 'ENABLED' : 'DISABLED', } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), ] diff --git a/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/UnmanagedACTAccessRequirementItem.stories.tsx b/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/UnmanagedACTAccessRequirementItem.stories.tsx index 1b5612caa1..6cd766fc5e 100644 --- a/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/UnmanagedACTAccessRequirementItem.stories.tsx +++ b/packages/synapse-react-client/src/components/AccessRequirementList/RequirementItem/UnmanagedACTAccessRequirementItem.stories.tsx @@ -11,7 +11,7 @@ import { mockToUAccessRequirementWithWiki, } from '../../../mocks/mockAccessRequirements' import { MOCK_REPO_ORIGIN } from '../../../utils/functions/getEndpoint' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { ACCESS_APPROVAL, ACCESS_REQUIREMENT_STATUS, @@ -72,22 +72,22 @@ export const LegacyACTAccessRequirement: Story = { ...getAccessRequirementHandlers(MOCK_REPO_ORIGIN), ...getWikiHandlers(MOCK_REPO_ORIGIN), getCurrentUserCertifiedValidatedHandler(MOCK_REPO_ORIGIN, false, false), - rest.get( + http.get( `${MOCK_REPO_ORIGIN}${ACCESS_REQUIREMENT_STATUS(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: AccessRequirementStatus = { - accessRequirementId: req.params.id as string, + accessRequirementId: params.id as string, concreteType: 'org.sagebionetworks.repo.model.dataaccess.BasicAccessRequirementStatus', isApproved: false, } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), - rest.post( + http.post( `${MOCK_REPO_ORIGIN}${ACCESS_APPROVAL}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: AccessApproval = { requirementId: mockToUAccessRequirement.id, submitterId: MOCK_USER_ID.toString(), @@ -100,7 +100,7 @@ export const LegacyACTAccessRequirement: Story = { createdBy: String(MOCK_USER_ID), modifiedBy: String(MOCK_USER_ID), } - return res(ctx.status(201), ctx.json(response)) + return HttpResponse.json(response, { status: 201 }) }, ), ], @@ -119,22 +119,22 @@ export const LegacyACTAccessRequirementWithWiki: Story = { ...getAccessRequirementHandlers(MOCK_REPO_ORIGIN), ...getWikiHandlers(MOCK_REPO_ORIGIN), getCurrentUserCertifiedValidatedHandler(MOCK_REPO_ORIGIN, false, false), - rest.get( + http.get( `${MOCK_REPO_ORIGIN}${ACCESS_REQUIREMENT_STATUS(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: AccessRequirementStatus = { - accessRequirementId: req.params.id as string, + accessRequirementId: params.id as string, concreteType: 'org.sagebionetworks.repo.model.dataaccess.BasicAccessRequirementStatus', isApproved: false, } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), - rest.post( + http.post( `${MOCK_REPO_ORIGIN}${ACCESS_APPROVAL}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: AccessApproval = { requirementId: mockToUAccessRequirementWithWiki.id, submitterId: MOCK_USER_ID.toString(), @@ -147,7 +147,7 @@ export const LegacyACTAccessRequirementWithWiki: Story = { createdBy: String(MOCK_USER_ID), modifiedBy: String(MOCK_USER_ID), } - return res(ctx.status(201), ctx.json(response)) + return HttpResponse.json(response, { status: 201 }) }, ), ], diff --git a/packages/synapse-react-client/src/components/AccessRequirementRelatedProjectsList/AccessRequirementRelatedProjectsList.stories.ts b/packages/synapse-react-client/src/components/AccessRequirementRelatedProjectsList/AccessRequirementRelatedProjectsList.stories.ts index 660fb959ef..7574adce5b 100644 --- a/packages/synapse-react-client/src/components/AccessRequirementRelatedProjectsList/AccessRequirementRelatedProjectsList.stories.ts +++ b/packages/synapse-react-client/src/components/AccessRequirementRelatedProjectsList/AccessRequirementRelatedProjectsList.stories.ts @@ -1,7 +1,7 @@ import { Meta, StoryObj } from '@storybook/react' import { AccessRequirementRelatedProjectsList } from './AccessRequirementRelatedProjectsList' import { MOCK_REPO_ORIGIN } from '../../utils/functions/getEndpoint' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { ACCESS_REQUIREMENT_SEARCH } from '../../utils/APIConstants' const meta = { @@ -33,10 +33,10 @@ export const ZeroProjectsMock: Story = { msw: { handlers: [ // searchAccessRequirements - rest.post( + http.post( `${MOCK_REPO_ORIGIN}${ACCESS_REQUIREMENT_SEARCH}`, - async (req, res, ctx) => { + async () => { const zeroRelatedProjects = { results: [ { @@ -51,7 +51,7 @@ export const ZeroProjectsMock: Story = { }, ], } - return res(ctx.status(200), ctx.json(zeroRelatedProjects)) + return HttpResponse.json(zeroRelatedProjects, { status: 200 }) }, ), ], diff --git a/packages/synapse-react-client/src/components/CertificationQuiz/CertificationQuiz.integration.test.tsx b/packages/synapse-react-client/src/components/CertificationQuiz/CertificationQuiz.integration.test.tsx index f66685a354..a71363b49d 100644 --- a/packages/synapse-react-client/src/components/CertificationQuiz/CertificationQuiz.integration.test.tsx +++ b/packages/synapse-react-client/src/components/CertificationQuiz/CertificationQuiz.integration.test.tsx @@ -20,7 +20,8 @@ import { BackendDestinationEnum, getEndpoint, } from '../../utils/functions/getEndpoint' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { useGetCurrentUserBundle } from '../../synapse-queries/user/useUserBundle' import { mockUserBundle } from '../../mocks/user/mock_user_profile' import { formatDate } from '../../utils/functions/DateFormatter' @@ -51,12 +52,12 @@ const mockToastFn = jest const gettingStartedUrl = 'https://help.synapse.org/docs/Getting-Started.2055471150.html' -const getQuizHandler = rest.get( +const getQuizHandler = http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/certifiedUserTest`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockQuiz)) + async ({ request, params }) => { + return HttpResponse.json(mockQuiz, { status: 200 }) }, ) diff --git a/packages/synapse-react-client/src/components/CreateTableViewWizard/CreateTableViewWizard.integration.test.tsx b/packages/synapse-react-client/src/components/CreateTableViewWizard/CreateTableViewWizard.integration.test.tsx index 71c00a5170..b970735f05 100644 --- a/packages/synapse-react-client/src/components/CreateTableViewWizard/CreateTableViewWizard.integration.test.tsx +++ b/packages/synapse-react-client/src/components/CreateTableViewWizard/CreateTableViewWizard.integration.test.tsx @@ -26,7 +26,7 @@ import { } from '../../mocks/MockSynapseContext' import { EntityFinderModal } from '../EntityFinder/EntityFinderModal' import defaultFileViewColumnModels from '../../mocks/query/defaultFileViewColumnModels' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { BackendDestinationEnum } from '../../utils/functions' import { getEndpoint } from '../../utils/functions/getEndpoint' import { MOCK_ANNOTATION_COLUMNS } from '../../mocks/mockAnnotationColumns' @@ -674,16 +674,16 @@ describe('CreateTableWizard integration tests', () => { it('Shows an error when column model creation fails', async () => { const errorMessage = 'Mocked error in POST /column/batch' server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/column/batch`, - async (req, res, ctx) => { - return res( - ctx.status(400), - ctx.json({ + async () => { + return HttpResponse.json( + { reason: errorMessage, - }), + }, + { status: 400 }, ) }, ), @@ -746,14 +746,14 @@ describe('CreateTableWizard integration tests', () => { it('Shows an error when entity creation fails', async () => { const errorMessage = 'Mocked error in POST /entity' server.use( - rest.post( + http.post( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}/repo/v1/entity`, - async (req, res, ctx) => { - return res( - ctx.status(400), - ctx.json({ + async () => { + return HttpResponse.json( + { reason: errorMessage, - }), + }, + { status: 400 }, ) }, ), diff --git a/packages/synapse-react-client/src/components/DirectDownload/DirectDownload.integration.test.tsx b/packages/synapse-react-client/src/components/DirectDownload/DirectDownload.integration.test.tsx index f5fdd89867..6260c53b29 100644 --- a/packages/synapse-react-client/src/components/DirectDownload/DirectDownload.integration.test.tsx +++ b/packages/synapse-react-client/src/components/DirectDownload/DirectDownload.integration.test.tsx @@ -13,7 +13,8 @@ import { S3FileHandle, } from '@sage-bionetworks/synapse-types' import mockFileEntityData from '../../mocks/entity/mockFileEntity' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { MOCK_USER_ID } from '../../mocks/user/mock_user_profile' const MOCK_FILE_ENTITY_ID = mockFileEntityData.id @@ -57,13 +58,13 @@ describe('DirectDownload: basic functionality', () => { } it('render direct download component without crashing', async () => { server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/file/v1/fileHandle/batch`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(batchFileResponse)) + async ({ request, params }) => { + return HttpResponse.json(batchFileResponse, { status: 200 }) }, ), ) @@ -77,12 +78,12 @@ describe('DirectDownload: basic functionality', () => { it('file handle fetch failure should display nothing', () => { server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/file/v1/fileHandle/batch`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.json({ diff --git a/packages/synapse-react-client/src/components/DownloadCart/MeetAccessRequirementCard.integration.test.tsx b/packages/synapse-react-client/src/components/DownloadCart/MeetAccessRequirementCard.integration.test.tsx index 8f9372be97..66a4c94c8e 100644 --- a/packages/synapse-react-client/src/components/DownloadCart/MeetAccessRequirementCard.integration.test.tsx +++ b/packages/synapse-react-client/src/components/DownloadCart/MeetAccessRequirementCard.integration.test.tsx @@ -10,7 +10,8 @@ import { } from './MeetAccessRequirementCard' import { createWrapper } from '../../testutils/TestingLibraryUtils' import { SynapseContextType } from '../../utils/context/SynapseContext' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { mockToUAccessRequirement, mockLockAccessRequirement, @@ -34,13 +35,13 @@ const setupAccessRequirementResponse = ( accessRequirement: AccessRequirement, ) => { server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_BY_ID(ACCESS_REQUIREMENT_ID)}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(accessRequirement)) + async ({ request, params }) => { + return HttpResponse.json(accessRequirement, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/DownloadCart/RequestDownloadCard.integration.test.tsx b/packages/synapse-react-client/src/components/DownloadCart/RequestDownloadCard.integration.test.tsx index e50b8910b5..bfb9568db3 100644 --- a/packages/synapse-react-client/src/components/DownloadCart/RequestDownloadCard.integration.test.tsx +++ b/packages/synapse-react-client/src/components/DownloadCart/RequestDownloadCard.integration.test.tsx @@ -2,7 +2,8 @@ import { render, screen } from '@testing-library/react' import React from 'react' import { createWrapper } from '../../testutils/TestingLibraryUtils' import { SynapseContextType } from '../../utils/context/SynapseContext' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { ENTITY_HEADERS } from '../../utils/APIConstants' import { BackendDestinationEnum, @@ -25,10 +26,10 @@ const defaultProps: RequestDownloadCardProps = { const mockEntityHeaderResult = { results: [{ id: ENTITY_ID }] } const setupEntityHeaderResponse = () => { server.use( - rest.post( + http.post( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_HEADERS}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockEntityHeaderResult)) + async ({ request, params }) => { + return HttpResponse.json(mockEntityHeaderResult, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/Evaluation/EvaluationEditor.integration.test.tsx b/packages/synapse-react-client/src/components/Evaluation/EvaluationEditor.integration.test.tsx index 51ad80569d..96f197e453 100644 --- a/packages/synapse-react-client/src/components/Evaluation/EvaluationEditor.integration.test.tsx +++ b/packages/synapse-react-client/src/components/Evaluation/EvaluationEditor.integration.test.tsx @@ -10,7 +10,8 @@ import { getEndpoint, } from '../../utils/functions/getEndpoint' import { Evaluation } from '@sage-bionetworks/synapse-types' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { MOCK_USER_ID } from '../../mocks/user/mock_user_profile' describe('test EvaluationEditor', () => { @@ -54,40 +55,40 @@ describe('test EvaluationEditor', () => { server.use( // getEvaluation - rest.get( + http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${EVALUATION_BY_ID( ':evalId', )}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(evaluation)) + async ({ request, params }) => { + return HttpResponse.json(evaluation, { status: 200 }) }, ), // updateEvaluation - rest.put( + http.put( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${EVALUATION_BY_ID( ':evalId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { onUpdateEvaluation() - return res(ctx.status(200), ctx.json(evaluation)) + return HttpResponse.json(evaluation, { status: 200 }) }, ), // createEvaluation - rest.post( + http.post( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${EVALUATION}`, - async (req, res, ctx) => { + async ({ request, params }) => { onCreateEvaluation() - return res(ctx.status(201), ctx.json(evaluation)) + return HttpResponse.json(evaluation, { status: 201 }) }, ), // deleteEvaluation - rest.delete( + http.delete( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${EVALUATION_BY_ID( ':evalId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { onDeleteEvaluation() return res(ctx.status(202)) }, @@ -125,11 +126,11 @@ describe('test EvaluationEditor', () => { test('retrieve evaluation from API failed', async () => { server.use( - rest.get( + http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${EVALUATION_BY_ID( ':evalId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(400), ctx.json({ reason: 'GetEvaluation error' }), @@ -207,11 +208,11 @@ describe('test EvaluationEditor', () => { test('save button clicked - save failure', async () => { server.use( - rest.put( + http.put( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${EVALUATION_BY_ID( ':evalId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { onUpdateEvaluation() return res( ctx.status(404), @@ -297,11 +298,11 @@ describe('test EvaluationEditor', () => { test('dropdown menu evaluation has id - delete failed', async () => { server.use( - rest.delete( + http.delete( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${EVALUATION_BY_ID( ':evalId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { onDeleteEvaluation() return res( ctx.status(400), diff --git a/packages/synapse-react-client/src/components/Evaluation/EvaluationEditorPage.stories.ts b/packages/synapse-react-client/src/components/Evaluation/EvaluationEditorPage.stories.ts index bc8c6fce83..b19047a3dc 100644 --- a/packages/synapse-react-client/src/components/Evaluation/EvaluationEditorPage.stories.ts +++ b/packages/synapse-react-client/src/components/Evaluation/EvaluationEditorPage.stories.ts @@ -1,7 +1,7 @@ import { Meta, StoryObj } from '@storybook/react' import { EvaluationEditorPage } from './EvaluationEditorPage' import { MOCK_REPO_ORIGIN } from '../../utils/functions/getEndpoint' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { getUserProfileHandlers } from '../../mocks/msw/handlers/userProfileHandlers' import { MOCK_USER_ID } from '../../mocks/user/mock_user_profile' import dayjs from 'dayjs' @@ -25,31 +25,27 @@ export const Evaluation: Story = { msw: { handlers: [ ...getUserProfileHandlers(MOCK_REPO_ORIGIN), - rest.get( - `${MOCK_REPO_ORIGIN}/repo/v1/evaluation/:id`, - async (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ - id: '9614712', - etag: 'a2b871cb-faa4-471a-8c23-b917c77fecb2', - name: 'a', - description: 'b', - ownerId: MOCK_USER_ID.toString(), - createdOn: '2021-03-02T22:16:14.552Z', - contentSource: 'syn5585645', - submissionInstructionsMessage: 'c', - submissionReceiptMessage: 'c', - }), - ) - }, - ), - rest.post( + http.get(`${MOCK_REPO_ORIGIN}/repo/v1/evaluation/:id`, async () => { + return HttpResponse.json( + { + id: '9614712', + etag: 'a2b871cb-faa4-471a-8c23-b917c77fecb2', + name: 'a', + description: 'b', + ownerId: MOCK_USER_ID.toString(), + createdOn: '2021-03-02T22:16:14.552Z', + contentSource: 'syn5585645', + submissionInstructionsMessage: 'c', + submissionReceiptMessage: 'c', + }, + { status: 200 }, + ) + }), + http.post( `${MOCK_REPO_ORIGIN}/repo/v1/evaluation/:id/round/list`, - async (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ + async () => { + return HttpResponse.json( + { page: [ // Ended { @@ -76,7 +72,8 @@ export const Evaluation: Story = { roundEnd: dayjs().add(2, 'week').toISOString(), }, ], - }), + }, + { status: 200 }, ) }, ), diff --git a/packages/synapse-react-client/src/components/FilePreview/FileEntityPreview.integration.test.tsx b/packages/synapse-react-client/src/components/FilePreview/FileEntityPreview.integration.test.tsx index fc2d8842f0..118fb9fbb4 100644 --- a/packages/synapse-react-client/src/components/FilePreview/FileEntityPreview.integration.test.tsx +++ b/packages/synapse-react-client/src/components/FilePreview/FileEntityPreview.integration.test.tsx @@ -18,7 +18,8 @@ import { } from '@sage-bionetworks/synapse-types' import mockFileEntityData from '../../mocks/entity/mockFileEntity' import { MOCK_FILE_HANDLE_ID } from '../../mocks/mock_file_handle' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import mockDatasetData from '../../mocks/entity/mockDataset' import { SynapseContextType } from '../../utils/context/SynapseContext' import { MOCK_CONTEXT_VALUE } from '../../mocks/MockSynapseContext' @@ -113,11 +114,11 @@ describe('FileHandleContentRenderer tests', () => { beforeEach(() => { server.use( // Handler to return the presigned URL for the requested file - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/file/v1/fileHandle/batch`, - (req, res, ctx) => { + ({ request, params }) => { const result: BatchFileResult = { requestedFiles: [ { @@ -126,11 +127,11 @@ describe('FileHandleContentRenderer tests', () => { }, ], } - return res(ctx.status(200), ctx.json(result)) + return HttpResponse.json(result, { status: 200 }) }, ), // Handler for the presigned URL to return the file contents - rest.get(PRESIGNED_URL, (req, res, ctx) => { + http.get(PRESIGNED_URL, ({ request, params }) => { return res(ctx.status(200), ctx.text('file contents here')) }), ) diff --git a/packages/synapse-react-client/src/components/FilePreview/FileHandleContentRenderer.integration.test.tsx b/packages/synapse-react-client/src/components/FilePreview/FileHandleContentRenderer.integration.test.tsx index 7a00d103f9..50e7f6bb45 100644 --- a/packages/synapse-react-client/src/components/FilePreview/FileHandleContentRenderer.integration.test.tsx +++ b/packages/synapse-react-client/src/components/FilePreview/FileHandleContentRenderer.integration.test.tsx @@ -19,7 +19,8 @@ import { } from '@sage-bionetworks/synapse-types' import mockFileEntityData from '../../mocks/entity/mockFileEntity' import { MOCK_FILE_HANDLE_ID } from '../../mocks/mock_file_handle' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' jest.spyOn(HtmlPreviewModule, 'default').mockImplementation(() => { return
@@ -44,11 +45,11 @@ describe('FileHandleContentRenderer tests', () => { beforeEach(() => { server.use( // Handler to return the presigned URL for the requested file - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/file/v1/fileHandle/batch`, - (req, res, ctx) => { + ({ request, params }) => { const result: BatchFileResult = { requestedFiles: [ { @@ -57,11 +58,11 @@ describe('FileHandleContentRenderer tests', () => { }, ], } - return res(ctx.status(200), ctx.json(result)) + return HttpResponse.json(result, { status: 200 }) }, ), // Handler for the presigned URL to return the file contents - rest.get(PRESIGNED_URL, (req, res, ctx) => { + http.get(PRESIGNED_URL, ({ request, params }) => { return res(ctx.status(200), ctx.text('file contents here')) }), ) diff --git a/packages/synapse-react-client/src/components/FilePreview/HtmlPreview/HtmlPreview.integration.test.tsx b/packages/synapse-react-client/src/components/FilePreview/HtmlPreview/HtmlPreview.integration.test.tsx index f38fdc0109..499ba6105c 100644 --- a/packages/synapse-react-client/src/components/FilePreview/HtmlPreview/HtmlPreview.integration.test.tsx +++ b/packages/synapse-react-client/src/components/FilePreview/HtmlPreview/HtmlPreview.integration.test.tsx @@ -40,18 +40,18 @@ describe('HTML Preview tests', () => { } server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${TEAM_ID_MEMBER_ID(TRUSTED_HTML_USERS_TEAM_ID, ':userId')}`, - (req, res, ctx) => { + ({ request, params }) => { let status = 404 let result: TeamMember | null = null - if (req.params.userId === MOCK_USER_ID.toString()) { + if (params.userId === MOCK_USER_ID.toString()) { status = 200 result = htmlTeamMembership } - return res(ctx.status(status), ctx.json(result)) + return HttpResponse.json(result, { status: status }) }, ), ) diff --git a/packages/synapse-react-client/src/components/Forum/DiscussionThread.integration.test.tsx b/packages/synapse-react-client/src/components/Forum/DiscussionThread.integration.test.tsx index a55ac9d674..b302963811 100644 --- a/packages/synapse-react-client/src/components/Forum/DiscussionThread.integration.test.tsx +++ b/packages/synapse-react-client/src/components/Forum/DiscussionThread.integration.test.tsx @@ -21,7 +21,8 @@ import { mockDiscussionThreadBundle, } from '../../mocks/discussion/mock_discussion' import { MOCK_ACCESS_TOKEN } from '../../mocks/MockSynapseContext' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { mockUserProfileData, mockUserProfileData2, @@ -41,11 +42,11 @@ const mockDeleteSubscription = jest.mocked(SynapseClient.deleteSubscription) mockDeleteSubscription.mockImplementation(() => { // When the subscription is deleted, update the server to return nothing. server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/subscription/list`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.json({ results: [], totalNumberOfResults: 0 }), @@ -113,51 +114,51 @@ describe.skip('Discussion Thread test', () => { }) beforeEach(() => { server.use( - rest.get( + http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${THREAD_ID( MOCK_THREAD_ID, )}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockDiscussionThreadBundle)) + async ({ request, params }) => { + return HttpResponse.json(mockDiscussionThreadBundle, { status: 200 }) }, ), - rest.get( + http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${THREAD_REPLIES( MOCK_THREAD_ID, )}`, - async (req, res, ctx) => { + async ({ request, params }) => { const offset = req.url.searchParams.get('offset') ?? '0' return res(ctx.status(200), ctx.json(mockThread[parseInt(offset)])) }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${THREAD}/messageUrl`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockMessageUrl)) + async ({ request, params }) => { + return HttpResponse.json(mockMessageUrl, { status: 200 }) }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/reply/messageUrl`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockMessageUrl)) + async ({ request, params }) => { + return HttpResponse.json(mockMessageUrl, { status: 200 }) }, ), - rest.get( + http.get( `http://localhost/${mockMessageUrl.messageUrl}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res(ctx.status(200), ctx.json('message')) }, ), - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/subscription/list`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockSubscriptionPagedResult)) + async ({ request, params }) => { + return HttpResponse.json(mockSubscriptionPagedResult, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/GoogleMap/GoogleMap.integration.test.tsx b/packages/synapse-react-client/src/components/GoogleMap/GoogleMap.integration.test.tsx index 18722cc152..8850a6b6bf 100644 --- a/packages/synapse-react-client/src/components/GoogleMap/GoogleMap.integration.test.tsx +++ b/packages/synapse-react-client/src/components/GoogleMap/GoogleMap.integration.test.tsx @@ -5,7 +5,7 @@ import React, { MouseEventHandler } from 'react' import { GeoData } from '../../synapse-client' import GoogleMap, { MapProps } from './GoogleMap' import { createWrapper } from '../../testutils/TestingLibraryUtils' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' import { MOCK_USER_ID, MOCK_USER_ID_2, @@ -55,21 +55,21 @@ const mockGeoData: GeoData[] = [ ] const geoDataHandlers = [ - rest.get( + http.get( 'https://s3.amazonaws.com/geoloc.sagebase.org/googlemap.txt', - (req, res, ctx) => { + ({ request, params }) => { return res(ctx.status(200), ctx.text('mockApiKey')) }, ), - rest.get( + http.get( 'https://s3.amazonaws.com/geoloc.sagebase.org/allPoints.json', - (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockGeoData)) + ({ request, params }) => { + return HttpResponse.json(mockGeoData, { status: 200 }) }, ), - rest.get( + http.get( `https://s3.amazonaws.com/geoloc.sagebase.org/${MOCK_TEAM_ID}.json`, - (req, res, ctx) => { + ({ request, params }) => { return res(ctx.status(200), ctx.json([mockGeoData[0]])) }, ), diff --git a/packages/synapse-react-client/src/components/HasAccess/HasAccessV2.integration.test.tsx b/packages/synapse-react-client/src/components/HasAccess/HasAccessV2.integration.test.tsx index 575b3b70f9..6089cf8572 100644 --- a/packages/synapse-react-client/src/components/HasAccess/HasAccessV2.integration.test.tsx +++ b/packages/synapse-react-client/src/components/HasAccess/HasAccessV2.integration.test.tsx @@ -22,7 +22,8 @@ import { mockUnmetControlledDataRestrictionInformationACT, mockUnmetControlledDataRestrictionInformationRestricted, } from '../../mocks/mock_has_access_data' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { getEntityBundleHandler } from '../../mocks/msw/handlers/entityHandlers' const entityId = mockFileEntityData.id @@ -71,13 +72,13 @@ function useMswRestrictionInformation( restrictionInformation: RestrictionInformationResponse, ) { server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/restrictionInformation`, - async (req, res, ctx) => { + async ({ request, params }) => { onGetRestrictionInformation(req.body) - return res(ctx.status(200), ctx.json(restrictionInformation)) + return HttpResponse.json(restrictionInformation, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/IDUReport/IDUReport.integration.test.tsx b/packages/synapse-react-client/src/components/IDUReport/IDUReport.integration.test.tsx index 2066211e66..3ee04c99b9 100644 --- a/packages/synapse-react-client/src/components/IDUReport/IDUReport.integration.test.tsx +++ b/packages/synapse-react-client/src/components/IDUReport/IDUReport.integration.test.tsx @@ -11,7 +11,8 @@ import { MOCK_USER_ID, MOCK_USER_ID_2, } from '../../mocks/user/mock_user_profile' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { APPROVED_SUBMISSION_INFO } from '../../utils/APIConstants' import { BackendDestinationEnum, @@ -52,16 +53,16 @@ describe('IDUReport tests', () => { beforeAll(() => { server.listen() server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${APPROVED_SUBMISSION_INFO(':arId')}`, - async (req, res, ctx) => { + async ({ request, params }) => { let page = page1 if ((req.body as SubmissionInfoPageRequest).nextPageToken) { page = page2 } - return res(ctx.status(200), ctx.json(page)) + return HttpResponse.json(page, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/OAuthClientManagement/CreateOAuthClient.integration.test.tsx b/packages/synapse-react-client/src/components/OAuthClientManagement/CreateOAuthClient.integration.test.tsx index 06a1a7d7a6..f6216a42e1 100644 --- a/packages/synapse-react-client/src/components/OAuthClientManagement/CreateOAuthClient.integration.test.tsx +++ b/packages/synapse-react-client/src/components/OAuthClientManagement/CreateOAuthClient.integration.test.tsx @@ -4,7 +4,8 @@ import userEvent from '@testing-library/user-event' import React from 'react' import { createWrapper } from '../../testutils/TestingLibraryUtils' import { MOCK_ACCESS_TOKEN } from '../../mocks/MockSynapseContext' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { CreateOAuthModal, CreateOAuthModalProps, @@ -82,11 +83,11 @@ function setUp(props: CreateOAuthModalProps = defaultProps) { } function mockVerificationPrecheckService(reverificationRequired: boolean) { - return rest.put( + return http.put( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/auth/v1/oauth2/client/${mockClient.client_id!}/verificationPrecheck`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.json({ reverificationRequired: reverificationRequired }), @@ -99,19 +100,19 @@ describe('Create OAuth Client', () => { beforeAll(() => server.listen()) beforeEach(() => { server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/auth/v1/oauth2/client`, - async (req, res, ctx) => { + async ({ request, params }) => { return res(ctx.status(200), ctx.json(req.body)) }, ), - rest.put( + http.put( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/auth/v1/oauth2/client/${mockClient.client_id!}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res(ctx.status(200), ctx.json(req.body)) }, ), diff --git a/packages/synapse-react-client/src/components/ProgrammaticTableDownload/ProgrammaticTableDownload.integration.test.tsx b/packages/synapse-react-client/src/components/ProgrammaticTableDownload/ProgrammaticTableDownload.integration.test.tsx index 5255f029fa..ec06135f38 100644 --- a/packages/synapse-react-client/src/components/ProgrammaticTableDownload/ProgrammaticTableDownload.integration.test.tsx +++ b/packages/synapse-react-client/src/components/ProgrammaticTableDownload/ProgrammaticTableDownload.integration.test.tsx @@ -8,7 +8,8 @@ import { import { QueryBundleRequest } from '@sage-bionetworks/synapse-types' import { TABLE_QUERY_ASYNC_START } from '../../utils/APIConstants' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { SynapseContextType } from '../../utils/context/SynapseContext' import { MOCK_CONTEXT_VALUE } from '../../mocks/MockSynapseContext' import ProgrammaticTableDownload, { @@ -44,11 +45,11 @@ const COMBINED_SQL_RESULT = 'SELECT * FROM syn12345' function getErrorMSWHandler() { return [ - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${TABLE_QUERY_ASYNC_START(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res(ctx.status(401), ctx.text('Unable to start query')) }, ), diff --git a/packages/synapse-react-client/src/components/ProvenanceGraph/ProvenanceGraph.integration.test.tsx b/packages/synapse-react-client/src/components/ProvenanceGraph/ProvenanceGraph.integration.test.tsx index cfd80fcd91..725ee1a4af 100644 --- a/packages/synapse-react-client/src/components/ProvenanceGraph/ProvenanceGraph.integration.test.tsx +++ b/packages/synapse-react-client/src/components/ProvenanceGraph/ProvenanceGraph.integration.test.tsx @@ -9,7 +9,8 @@ import { } from '../../utils/functions/getEndpoint' import { mockActivity } from '../../mocks/provenance/mockActivity' import mockFileEntityData from '../../mocks/entity/mockFileEntity' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { SynapseApiResponse } from '../../mocks/msw/handlers' import { Activity } from '@sage-bionetworks/synapse-types' import { MOCK_TABLE_ENTITY_ID } from '../../mocks/entity/mockTableEntity' @@ -22,37 +23,37 @@ describe('ProvenanceGraph', () => { beforeAll(() => server.listen()) beforeEach(() => { server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACTIVITY_FOR_ENTITY( mockFileEntityData.id, `${mockFileEntityData.entity.versionNumber}`, )}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockActivity)) + async ({ request, params }) => { + return HttpResponse.json(mockActivity, { status: 200 }) }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACTIVITY_FOR_ENTITY(MOCK_TABLE_ENTITY_ID)}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: SynapseApiResponse = { reason: `Mock Service worker was not configured to return an Activity for ${MOCK_TABLE_ENTITY_ID}`, } - return res(ctx.status(404), ctx.json(response)) + return HttpResponse.json(response, { status: 404 }) }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACTIVITY_FOR_ENTITY(MOCK_TABLE_ENTITY_ID, ':version')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: SynapseApiResponse = { - reason: `Mock Service worker was not configured to return an Activity for ${MOCK_TABLE_ENTITY_ID}.${req.params.version}`, + reason: `Mock Service worker was not configured to return an Activity for ${MOCK_TABLE_ENTITY_ID}.${params.version}`, } - return res(ctx.status(404), ctx.json(response)) + return HttpResponse.json(response, { status: 404 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationsEditor.integration.test.tsx b/packages/synapse-react-client/src/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationsEditor.integration.test.tsx index 85a94d64b6..cd16aba1fb 100644 --- a/packages/synapse-react-client/src/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationsEditor.integration.test.tsx +++ b/packages/synapse-react-client/src/components/SchemaDrivenAnnotationEditor/SchemaDrivenAnnotationsEditor.integration.test.tsx @@ -30,7 +30,8 @@ import { import { SynapseContextType } from '../../utils/context/SynapseContext' import mockFileEntity from '../../mocks/entity/mockFileEntity' import { mockSchemaBinding, mockValidationSchema } from '../../mocks/mockSchema' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { cloneDeep } from 'lodash-es' async function chooseAutocompleteOption(el: HTMLElement, option: string) { @@ -111,28 +112,28 @@ describe('SchemaDrivenAnnotationEditor tests', () => { }) afterAll(() => server.close()) - const noAnnotationsHandler = rest.get( + const noAnnotationsHandler = http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_JSON( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response = cloneDeep(mockFileEntity).json // Delete the annotation keys in the mock--we aren't using them in this suite delete response.myStringKey delete response.myIntegerKey delete response.myFloatKey - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ) // Returns an entity with annotations that match the schema - const annotationsWithSchemaHandler = rest.get( + const annotationsWithSchemaHandler = http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_JSON( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response = cloneDeep(mockFileEntity).json // Delete the other annotation keys delete response.myStringKey @@ -143,18 +144,18 @@ describe('SchemaDrivenAnnotationEditor tests', () => { response.country = 'USA' response.state = 'Washington' - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ) // Returns an entity with annotations equivalent to the `annotationsWithSchemaHandler`, but with the annotations // returned as if there is no bound schema - const annotationsWithoutSchemaHandler = rest.get( + const annotationsWithoutSchemaHandler = http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_JSON( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response = cloneDeep(mockFileEntity).json // Delete the other annotation keys delete response.myStringKey @@ -165,16 +166,16 @@ describe('SchemaDrivenAnnotationEditor tests', () => { response.country = ['USA'] response.state = ['Washington'] - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ) - const stringArrayAnnotationsHandler = rest.get( + const stringArrayAnnotationsHandler = http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_JSON( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response = cloneDeep(mockFileEntity).json // Delete the other annotation keys delete response.myStringKey @@ -185,16 +186,16 @@ describe('SchemaDrivenAnnotationEditor tests', () => { response.showStringArray = true response.stringArray = ['one', 'two', 'three'] - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ) - const emptyArrayAnnotationsHandler = rest.get( + const emptyArrayAnnotationsHandler = http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_JSON( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response = cloneDeep(mockFileEntity).json // Delete the other annotation keys delete response.myStringKey @@ -204,41 +205,41 @@ describe('SchemaDrivenAnnotationEditor tests', () => { // Fill in annotations that match the schema in this test suite response.showStringArray = true delete response.stringArray - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ) - const noSchemaHandler = rest.get( + const noSchemaHandler = http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_SCHEMA_BINDING(':entityId')}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res(ctx.status(404), ctx.json({})) }, ) const schemaHandlers = [ - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_SCHEMA_BINDING(':entityId')}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockSchemaBinding)) + async ({ request, params }) => { + return HttpResponse.json(mockSchemaBinding, { status: 200 }) }, ), - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${SCHEMA_VALIDATION_START}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res(ctx.status(201), ctx.json({ token: mockAsyncTokenId })) }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${SCHEMA_VALIDATION_GET(mockAsyncTokenId)}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.json({ validationSchema: mockValidationSchema }), @@ -246,11 +247,11 @@ describe('SchemaDrivenAnnotationEditor tests', () => { }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ASYNCHRONOUS_JOB_TOKEN(String(mockAsyncTokenId))}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.json({ @@ -261,21 +262,21 @@ describe('SchemaDrivenAnnotationEditor tests', () => { ), ] - const successfulUpdateHandler = rest.put( + const successfulUpdateHandler = http.put( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_JSON( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { updatedJsonCaptor(req.body) return res(ctx.status(200), ctx.json(req.body)) }, ) - const unsuccessfulUpdateHandler = rest.put( + const unsuccessfulUpdateHandler = http.put( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_JSON( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(412), ctx.json({ diff --git a/packages/synapse-react-client/src/components/SynapseForm/SynapseFormSubmissionsGrid.stories.tsx b/packages/synapse-react-client/src/components/SynapseForm/SynapseFormSubmissionsGrid.stories.tsx index 98b0971a73..9e047e7601 100644 --- a/packages/synapse-react-client/src/components/SynapseForm/SynapseFormSubmissionsGrid.stories.tsx +++ b/packages/synapse-react-client/src/components/SynapseForm/SynapseFormSubmissionsGrid.stories.tsx @@ -1,6 +1,6 @@ import React from 'react' import { Meta, StoryObj } from '@storybook/react' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { MOCK_REPO_ORIGIN } from '../../utils/functions/getEndpoint' import SynapseFormSubmissionGrid, { SynapseFormSubmissionGridProps, @@ -62,9 +62,9 @@ type Story = StoryObj function listFormDataHandlers() { return [ - rest.post( + http.post( `${MOCK_REPO_ORIGIN}/repo/v1/form/data/list`, - async (req, res, ctx) => { + async ({ request, params }) => { const listRequest = req.body as ListRequest const status = ctx.status(200) if ( @@ -83,9 +83,9 @@ export const NoSubmissions: Story = { msw: { handlers: [ getHandlers(MOCK_REPO_ORIGIN), - rest.post( + http.post( `${MOCK_REPO_ORIGIN}/repo/v1/form/data/list`, - async (req, res, ctx) => { + async ({ request, params }) => { return res(ctx.status(200), ctx.json({ page: [] })) }, ), diff --git a/packages/synapse-react-client/src/components/SynapseTable/SynapseTable.integration.test.tsx b/packages/synapse-react-client/src/components/SynapseTable/SynapseTable.integration.test.tsx index be5b892088..dccc955908 100644 --- a/packages/synapse-react-client/src/components/SynapseTable/SynapseTable.integration.test.tsx +++ b/packages/synapse-react-client/src/components/SynapseTable/SynapseTable.integration.test.tsx @@ -29,7 +29,8 @@ import { RestrictionLevel, Table, } from '@sage-bionetworks/synapse-types' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import queryResultBundle from '../../mocks/query/syn16787123' import { MOCK_USER_ID } from '../../mocks/user/mock_user_profile' import * as HasAccessModule from '../HasAccess/HasAccessV2' @@ -152,10 +153,10 @@ describe('SynapseTable tests', () => { server.use( ...getHandlersForTableQuery(queryResultBundle), - rest.post( + http.post( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_HEADERS}`, - async (req, res, ctx) => { - const requestBody: ReferenceList = (await req.json()) + async ({ request, params }) => { + const requestBody: ReferenceList = (await request.json()) .references as ReferenceList const responseBody: PaginatedResults = { results: requestBody.map((reference: Reference, index) => { @@ -172,19 +173,19 @@ describe('SynapseTable tests', () => { } }), } - return res(ctx.status(200), ctx.json(responseBody)) + return HttpResponse.json(responseBody, { status: 200 }) }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_ID_VERSION(':id', ':version')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const responseBody: FileEntity = { - id: `${req.params.id!}`, - name: `Mock Entity with Id ${req.params.id}`, - versionNumber: parseInt(req.params.version as string), - versionLabel: `v${req.params.version}`, + id: `${params.id!}`, + name: `Mock Entity with Id ${params.id}`, + versionNumber: parseInt(params.version as string), + versionLabel: `v${params.version}`, versionComment: 'test', modifiedOn: '2021-03-31T18:30:00.000Z', modifiedBy: MOCK_USER_ID.toString(), @@ -192,19 +193,19 @@ describe('SynapseTable tests', () => { etag: 'etag', concreteType: 'org.sagebionetworks.repo.model.FileEntity', } - return res(ctx.status(200), ctx.json(responseBody)) + return HttpResponse.json(responseBody, { status: 200 }) }, ), - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/restrictionInformation`, - async (req, res, ctx) => { + async ({ request, params }) => { const responseBody: RestrictionInformationResponse = { restrictionLevel: RestrictionLevel.OPEN, hasUnmetAccessRequirement: false, } - return res(ctx.status(200), ctx.json(responseBody)) + return HttpResponse.json(responseBody, { status: 200 }) }, ), ) @@ -469,12 +470,12 @@ describe('SynapseTable tests', () => { // Return a file view entity, so the download column would be shown if not for the missing row IDs server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/entity/${synapseTableEntityId}`, - (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockFileViewEntity)) + ({ request, params }) => { + return HttpResponse.json(mockFileViewEntity, { status: 200 }) }, ), ...getHandlersForTableQuery(queryResultBundleWithoutRowIds), @@ -512,12 +513,12 @@ describe('SynapseTable tests', () => { } server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/entity/${synapseTableEntityId}`, - (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockFileViewEntity)) + ({ request, params }) => { + return HttpResponse.json(mockFileViewEntity, { status: 200 }) }, ), ...getHandlersForTableQuery(queryResultBundleWithRenamedColumn), diff --git a/packages/synapse-react-client/src/components/SynapseTable/SynapseTable.stories.tsx b/packages/synapse-react-client/src/components/SynapseTable/SynapseTable.stories.tsx index ea33a0ab8f..7528602682 100644 --- a/packages/synapse-react-client/src/components/SynapseTable/SynapseTable.stories.tsx +++ b/packages/synapse-react-client/src/components/SynapseTable/SynapseTable.stories.tsx @@ -1,7 +1,7 @@ import { getHandlersForTableQuery } from '../../mocks/msw/handlers/tableQueryHandlers' import React from 'react' import { Meta, StoryObj } from '@storybook/react' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { MOCK_REPO_ORIGIN } from '../../utils/functions/getEndpoint' import queryResultBundleJson from '../../mocks/query/syn16787123' import SynapseTable from './SynapseTable' @@ -77,10 +77,10 @@ export const SynapseTableDemo: Story = { parameters: { msw: { handlers: [ - rest.get( + http.get( MOCK_REPO_ORIGIN + '/repo/v1/entity/syn16787123', - (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockTableEntity)) + ({ request, params }) => { + return HttpResponse.json(mockTableEntity, { status: 200 }) }, ), ...getHandlersForTableQuery(queryResultBundleJson, MOCK_REPO_ORIGIN), diff --git a/packages/synapse-react-client/src/components/SynapseTable/SynapseTableCell/SynapseTableCell.integration.test.tsx b/packages/synapse-react-client/src/components/SynapseTable/SynapseTableCell/SynapseTableCell.integration.test.tsx index 66ce69bf9a..bbb769504e 100644 --- a/packages/synapse-react-client/src/components/SynapseTable/SynapseTableCell/SynapseTableCell.integration.test.tsx +++ b/packages/synapse-react-client/src/components/SynapseTable/SynapseTableCell/SynapseTableCell.integration.test.tsx @@ -116,19 +116,19 @@ describe('SynapseTableCell tests', () => { server.listen() server.use( ...getHandlersForTableQuery(queryResultBundle), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/entity/syn16787123`, - (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockTableEntity)) + ({ request, params }) => { + return HttpResponse.json(mockTableEntity, { status: 200 }) }, ), - rest.post( + http.post( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_HEADERS}`, - async (req, res, ctx) => { - const requestBody: ReferenceList = (await req.json()) + async ({ request, params }) => { + const requestBody: ReferenceList = (await request.json()) .references as ReferenceList const responseBody: PaginatedResults = { results: requestBody.map((reference: Reference) => { @@ -145,26 +145,26 @@ describe('SynapseTableCell tests', () => { } }), } - return res(ctx.status(200), ctx.json(responseBody)) + return HttpResponse.json(responseBody, { status: 200 }) }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_ID_VERSION(':id', ':version')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const responseBody: VersionableEntity = { - id: req.params.id as string, - name: `Mock Entity with Id ${req.params.id}`, - versionNumber: parseInt(req.params.version as string), - versionLabel: `v${req.params.version}`, + id: params.id as string, + name: `Mock Entity with Id ${params.id}`, + versionNumber: parseInt(params.version as string), + versionLabel: `v${params.version}`, versionComment: 'test', modifiedOn: '2021-03-31T18:30:00.000Z', modifiedBy: MOCK_USER_ID.toString(), etag: 'etag', concreteType: 'org.sagebionetworks.repo.model.FileEntity', } - return res(ctx.status(200), ctx.json(responseBody)) + return HttpResponse.json(responseBody, { status: 200 }) }, ), ) @@ -213,12 +213,12 @@ describe('SynapseTableCell tests', () => { it('PORTALS-2095: renders an entity link for name column in EntityView', async () => { server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/entity/syn16787123`, - (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockFileViewEntity)) + ({ request, params }) => { + return HttpResponse.json(mockFileViewEntity, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/SynapseTable/datasets/DatasetItemsEditor.integration.test.tsx b/packages/synapse-react-client/src/components/SynapseTable/datasets/DatasetItemsEditor.integration.test.tsx index 82f808d468..4ff42238f7 100644 --- a/packages/synapse-react-client/src/components/SynapseTable/datasets/DatasetItemsEditor.integration.test.tsx +++ b/packages/synapse-react-client/src/components/SynapseTable/datasets/DatasetItemsEditor.integration.test.tsx @@ -203,38 +203,38 @@ function getDatasetHandlerWithItems( type: 'dataset' | 'datasetcollection', items?: Array, ) { - return rest.get( + return http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_ID( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response = cloneDeep( type === 'dataset' ? mockDatasetEntityData.entity : mockDatasetCollectionData.entity, ) response.items = items - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ) } -const successfulUpdateHandler = rest.put( +const successfulUpdateHandler = http.put( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_ID( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { updatedEntityCaptor(req.body) return res(ctx.status(200), ctx.json(req.body)) }, ) -const unsuccessfulUpdateHandler = rest.put( +const unsuccessfulUpdateHandler = http.put( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_ID( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { const status = 500 return res( ctx.status(status), diff --git a/packages/synapse-react-client/src/components/SynapseTable/table-top/DownloadOptions.integration.test.tsx b/packages/synapse-react-client/src/components/SynapseTable/table-top/DownloadOptions.integration.test.tsx index 987726c195..0a5085ce84 100644 --- a/packages/synapse-react-client/src/components/SynapseTable/table-top/DownloadOptions.integration.test.tsx +++ b/packages/synapse-react-client/src/components/SynapseTable/table-top/DownloadOptions.integration.test.tsx @@ -179,11 +179,11 @@ describe('Download Options tests', () => { it('Shows correct options for a stable version of a dataset', async () => { const isStableVersion = true server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/entity/${mockDatasetEntity.id!}`, - (req, res, ctx) => { + ({ request, params }) => { return res( ctx.status(200), ctx.json({ @@ -221,11 +221,11 @@ describe('Download Options tests', () => { it('Shows correct options for a draft Dataset', async () => { const isStableVersion = false server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/entity/${mockDatasetEntity.id!}`, - (req, res, ctx) => { + ({ request, params }) => { return res( ctx.status(200), ctx.json({ diff --git a/packages/synapse-react-client/src/components/TableColumnSchemaEditor/TableColumnSchemaEditor.stories.ts b/packages/synapse-react-client/src/components/TableColumnSchemaEditor/TableColumnSchemaEditor.stories.ts index cc80c1198f..75ad98a1e7 100644 --- a/packages/synapse-react-client/src/components/TableColumnSchemaEditor/TableColumnSchemaEditor.stories.ts +++ b/packages/synapse-react-client/src/components/TableColumnSchemaEditor/TableColumnSchemaEditor.stories.ts @@ -7,7 +7,7 @@ import { import { mockQueryResultBundle } from '../../mocks/mockFileViewQuery' import { MOCK_REPO_ORIGIN } from '../../utils/functions/getEndpoint' import { TableBundle } from '@sage-bionetworks/synapse-types' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { ENTITY_BUNDLE_V2 } from '../../utils/APIConstants' import mockTableEntityData from '../../mocks/entity/mockTableEntity' import mockEntities from '../../mocks/entity' @@ -36,11 +36,11 @@ export const Demo: Story = { MOCK_ANNOTATION_COLUMNS, MOCK_REPO_ORIGIN, ), - rest.post( + http.post( `${MOCK_REPO_ORIGIN}${ENTITY_BUNDLE_V2(':entityId')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const entity = - mockEntities.find(entity => entity.id === req.params.entityId) || + mockEntities.find(entity => entity.id === params.entityId) || mockTableEntityData return res( ctx.status(200), diff --git a/packages/synapse-react-client/src/components/TimelinePlot/TimelinePlot.stories.tsx b/packages/synapse-react-client/src/components/TimelinePlot/TimelinePlot.stories.tsx index 1b5bbce94d..d6d1245264 100644 --- a/packages/synapse-react-client/src/components/TimelinePlot/TimelinePlot.stories.tsx +++ b/packages/synapse-react-client/src/components/TimelinePlot/TimelinePlot.stories.tsx @@ -1,6 +1,6 @@ import { Meta, StoryObj } from '@storybook/react' import TimelinePlot from './TimelinePlot' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { MOCK_REPO_ORIGIN } from '../../utils/functions/getEndpoint' import { getHandlersForTableQuery } from '../../mocks/msw/handlers/tableQueryHandlers' import { mockTableEntity } from '../../mocks/entity/mockTableEntity' @@ -28,9 +28,9 @@ export const Demo: Story = { parameters: { msw: { handlers: [ - rest.get( + http.get( MOCK_REPO_ORIGIN + '/repo/v1/entity/syn51735464', - (req, res, ctx) => { + ({ request, params }) => { return res( ctx.status(200), ctx.json({ ...mockTableEntity, id: 'syn51735464' }), diff --git a/packages/synapse-react-client/src/components/UserCard/UserCard.integration.test.tsx b/packages/synapse-react-client/src/components/UserCard/UserCard.integration.test.tsx index fb8c421ad2..0524fa4a3e 100644 --- a/packages/synapse-react-client/src/components/UserCard/UserCard.integration.test.tsx +++ b/packages/synapse-react-client/src/components/UserCard/UserCard.integration.test.tsx @@ -20,7 +20,8 @@ import { MEDIUM_USER_CARD, SEPERATOR, } from '../../utils/SynapseConstants' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { mockUserProfileData } from '../../mocks/user/mock_user_profile' const { firstName } = mockUserProfileData @@ -134,11 +135,11 @@ describe('UserCard tests', () => { const IMAGE_URL = 'http://some-image-url.notarealurl/image.jpg' server.use( // Synapse provides the presigned URL for the profile image - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${PROFILE_IMAGE_PREVIEW(':userId')}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.set('Content-Type', 'text/plain'), @@ -147,7 +148,7 @@ describe('UserCard tests', () => { }, ), // Handler for the "presigned" URL itself: - rest.get(IMAGE_URL, async (req, res, ctx) => { + http.get(IMAGE_URL, async ({ request, params }) => { return res( ctx.status(200), ctx.set('Content-Type', 'image/jpeg'), diff --git a/packages/synapse-react-client/src/components/dataaccess/AccessApprovalsTable.integration.test.tsx b/packages/synapse-react-client/src/components/dataaccess/AccessApprovalsTable.integration.test.tsx index ddf2e4bd23..1dd192d74e 100644 --- a/packages/synapse-react-client/src/components/dataaccess/AccessApprovalsTable.integration.test.tsx +++ b/packages/synapse-react-client/src/components/dataaccess/AccessApprovalsTable.integration.test.tsx @@ -1,5 +1,6 @@ import React from 'react' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { render, screen } from '@testing-library/react' import { AccessApprovalSearchRequest, @@ -34,12 +35,12 @@ describe('AccessApprovalsTable tests', () => { beforeAll(() => { server.listen() server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/accessApproval/search`, - async (req, res, ctx) => { - const requestBody: AccessApprovalSearchRequest = await req.json() + async ({ request, params }) => { + const requestBody: AccessApprovalSearchRequest = await request.json() let responseBody: AccessApprovalSearchResponse = { results: mockApprovalSearchResponse.results, nextPageToken: mockApprovalSearchResponse.nextPageToken, @@ -51,7 +52,7 @@ describe('AccessApprovalsTable tests', () => { nextPageToken: undefined, } } - return res(ctx.status(200), ctx.json(responseBody)) + return HttpResponse.json(responseBody, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/dataaccess/AccessHistoryDashboard.integration.test.tsx b/packages/synapse-react-client/src/components/dataaccess/AccessHistoryDashboard.integration.test.tsx index 18557c7e8a..68676a51f8 100644 --- a/packages/synapse-react-client/src/components/dataaccess/AccessHistoryDashboard.integration.test.tsx +++ b/packages/synapse-react-client/src/components/dataaccess/AccessHistoryDashboard.integration.test.tsx @@ -4,7 +4,8 @@ import { UserHistoryDashboard } from './AccessHistoryDashboard' import { createMemoryHistory, MemoryHistory } from 'history' import { createWrapper } from '../../testutils/TestingLibraryUtils' import { Router } from 'react-router-dom' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { BackendDestinationEnum, getEndpoint, @@ -46,15 +47,15 @@ const mockAccessRequestSubmissionTable = jest const onServiceReceivedRequest = jest.fn() function getUserBundleHandler(isACTMember: boolean, isARReviewer: boolean) { - return rest.get( + return http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${USER_BUNDLE}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: UserBundle = { userId: MOCK_USER_ID.toString(), isACTMember: isACTMember, isARReviewer: isARReviewer, } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ) } @@ -85,25 +86,25 @@ describe('AccessHistoryDashboard tests', () => { server.use( getUserBundleHandler(isACTMember, isARReviewer), - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_SEARCH}`, - async (req, res, ctx) => { + async ({ request, params }) => { onServiceReceivedRequest(req.body) - return res(ctx.status(200), ctx.json(mockSearchResults)) + return HttpResponse.json(mockSearchResults, { status: 200 }) }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_BY_ID(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { onServiceReceivedRequest(req.body) - return res(ctx.status(200), ctx.json(mockAccessRequirement)) + return HttpResponse.json(mockAccessRequirement, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/dataaccess/AccessRequestSubmissionTable.integration.test.tsx b/packages/synapse-react-client/src/components/dataaccess/AccessRequestSubmissionTable.integration.test.tsx index 04bcbc548e..42c7b6ef25 100644 --- a/packages/synapse-react-client/src/components/dataaccess/AccessRequestSubmissionTable.integration.test.tsx +++ b/packages/synapse-react-client/src/components/dataaccess/AccessRequestSubmissionTable.integration.test.tsx @@ -12,7 +12,8 @@ import { SubmissionSearchResponse, } from '@sage-bionetworks/synapse-types' import { AccessType, SubmissionState } from '@sage-bionetworks/synapse-types' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { BackendDestinationEnum, getEndpoint, @@ -74,12 +75,12 @@ describe('Access Request Submission Table tests', () => { // Configure MSW server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUEST_SUBMISSION_SEARCH}`, - async (req, res, ctx) => { + async ({ request, params }) => { onServiceReceivedRequest(req.body) let response if ( @@ -94,7 +95,7 @@ describe('Access Request Submission Table tests', () => { nextPageToken: nextPageToken, } } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/dataaccess/AccessRequirementSearchBox/AccessRequirementSearchBox.integration.test.tsx b/packages/synapse-react-client/src/components/dataaccess/AccessRequirementSearchBox/AccessRequirementSearchBox.integration.test.tsx index 83816cbf36..84467bfa5f 100644 --- a/packages/synapse-react-client/src/components/dataaccess/AccessRequirementSearchBox/AccessRequirementSearchBox.integration.test.tsx +++ b/packages/synapse-react-client/src/components/dataaccess/AccessRequirementSearchBox/AccessRequirementSearchBox.integration.test.tsx @@ -42,25 +42,25 @@ describe('Access Requirement Search Box tests', () => { // Configure MSW server.use( // Return mocked access requirement search results - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_SEARCH}`, - async (req, res, ctx) => { + async ({ request, params }) => { onServiceRecievedRequest(req.body) - return res(ctx.status(200), ctx.json(mockSearchResults)) + return HttpResponse.json(mockSearchResults, { status: 200 }) }, ), // Return an access requirement specified by ID - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_BY_ID(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { onServiceRecievedRequest(req.body) - return res(ctx.status(200), ctx.json(mockAccessRequirement)) + return HttpResponse.json(mockAccessRequirement, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/dataaccess/AccessRequirementTable.integration.test.tsx b/packages/synapse-react-client/src/components/dataaccess/AccessRequirementTable.integration.test.tsx index e13f0f0f1c..146070fbfe 100644 --- a/packages/synapse-react-client/src/components/dataaccess/AccessRequirementTable.integration.test.tsx +++ b/packages/synapse-react-client/src/components/dataaccess/AccessRequirementTable.integration.test.tsx @@ -37,7 +37,8 @@ import { mockSelfSignAccessRequirement, mockToUAccessRequirement, } from '../../mocks/mockAccessRequirements' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { MOCK_USER_NAME } from '../../mocks/user/mock_user_profile' const MOCK_PROJECT_ID = mockProjectData.id @@ -87,12 +88,12 @@ describe('Access Requirement Table tests', () => { // Configure MSW server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_SEARCH}`, - async (req, res, ctx) => { + async ({ request, params }) => { onServiceRecievedRequest(req.body) let response if ( @@ -108,7 +109,7 @@ describe('Access Requirement Table tests', () => { } } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/dataaccess/AccessSubmissionDashboard.integration.test.tsx b/packages/synapse-react-client/src/components/dataaccess/AccessSubmissionDashboard.integration.test.tsx index e73f20f8a6..2c000c4b9e 100644 --- a/packages/synapse-react-client/src/components/dataaccess/AccessSubmissionDashboard.integration.test.tsx +++ b/packages/synapse-react-client/src/components/dataaccess/AccessSubmissionDashboard.integration.test.tsx @@ -9,7 +9,8 @@ import { getReviewerFilterID, } from './AccessSubmissionDashboard' import { createWrapper } from '../../testutils/TestingLibraryUtils' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { MOCK_USER_ID, MOCK_USER_NAME, @@ -62,25 +63,25 @@ describe('AccessSubmissionDashboard tests', () => { server.listen() server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_SEARCH}`, - async (req, res, ctx) => { + async ({ request, params }) => { onServiceReceivedRequest(req.body) - return res(ctx.status(200), ctx.json(mockSearchResults)) + return HttpResponse.json(mockSearchResults, { status: 200 }) }, ), // Return an access requirement specified by ID - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_BY_ID(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { onServiceReceivedRequest(req.body) - return res(ctx.status(200), ctx.json(mockAccessRequirement)) + return HttpResponse.json(mockAccessRequirement, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/dataaccess/RejectDataAccessRequestModal.integration.test.tsx b/packages/synapse-react-client/src/components/dataaccess/RejectDataAccessRequestModal.integration.test.tsx index 75374ee66f..8a897db1b6 100644 --- a/packages/synapse-react-client/src/components/dataaccess/RejectDataAccessRequestModal.integration.test.tsx +++ b/packages/synapse-react-client/src/components/dataaccess/RejectDataAccessRequestModal.integration.test.tsx @@ -4,7 +4,8 @@ import { createWrapper } from '../../testutils/TestingLibraryUtils' import RejectDataAccessRequestModal, { RejectDataAccessRequestModalProps, } from './RejectDataAccessRequestModal' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { getHandlersForTableQuery } from '../../mocks/msw/handlers/tableQueryHandlers' import mockRejectionReasonsTableQueryResultBundle from '../../mocks/query/mockRejectionReasonsTableQueryResultBundle' import userEvent from '@testing-library/user-event' @@ -38,12 +39,12 @@ describe('RejectDataAccessRequestModal', () => { server.listen() server.use( ...getHandlersForTableQuery(mockRejectionReasonsTableQueryResultBundle), - rest.put( + http.put( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${DATA_ACCESS_SUBMISSION_BY_ID(':id')}`, - async (req, res, ctx) => { - onServerReceivedUpdate(await req.json()) + async ({ request, params }) => { + onServerReceivedUpdate(await request.json()) return res(ctx.status(200)) }, ), diff --git a/packages/synapse-react-client/src/components/dataaccess/ReviewerDashboard.integration.test.tsx b/packages/synapse-react-client/src/components/dataaccess/ReviewerDashboard.integration.test.tsx index 569126e1ae..acc66b079b 100644 --- a/packages/synapse-react-client/src/components/dataaccess/ReviewerDashboard.integration.test.tsx +++ b/packages/synapse-react-client/src/components/dataaccess/ReviewerDashboard.integration.test.tsx @@ -9,7 +9,8 @@ import { getEndpoint, } from '../../utils/functions/getEndpoint' import { UserBundle } from '@sage-bionetworks/synapse-types' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { MOCK_USER_ID } from '../../mocks/user/mock_user_profile' import * as AccessRequirementDashboardModule from './AccessRequirementDashboard' import * as AccessRequestSubmissionDashboardModule from './AccessSubmissionDashboard' @@ -46,15 +47,15 @@ function renderComponent( isARReviewer: boolean = true, ) { server.use( - rest.get( + http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${USER_BUNDLE}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: UserBundle = { userId: MOCK_USER_ID.toString(), isACTMember: isACTMember, isARReviewer: isARReviewer, } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/dataaccess/SubmissionPage.integration.test.tsx b/packages/synapse-react-client/src/components/dataaccess/SubmissionPage.integration.test.tsx index feca50e324..86de535add 100644 --- a/packages/synapse-react-client/src/components/dataaccess/SubmissionPage.integration.test.tsx +++ b/packages/synapse-react-client/src/components/dataaccess/SubmissionPage.integration.test.tsx @@ -32,7 +32,8 @@ import { mockSubmittedSubmission, } from '../../mocks/dataaccess/MockSubmission' import { mockManagedACTAccessRequirement } from '../../mocks/mockAccessRequirements' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' +import { http, HttpResponse } from 'msw' import { MOCK_USER_ID, MOCK_USER_NAME, @@ -85,46 +86,48 @@ describe('Submission Page tests', () => { // Configure MSW server.use( // Return submission based on ID - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${DATA_ACCESS_SUBMISSION_BY_ID(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const submission = mockSubmissions.find( - submission => req.params.id === submission.id, + submission => params.id === submission.id, ) - return res(ctx.status(200), ctx.json(submission)) + return HttpResponse.json(submission, { status: 200 }) }, ), // Return a mocked access requirement - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_BY_ID(':id')}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockManagedACTAccessRequirement)) + async ({ request, params }) => { + return HttpResponse.json(mockManagedACTAccessRequirement, { + status: 200, + }) }, ), // Return a 404 for the AR's ACL (there are no designated reviewers) - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_ACL(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res(ctx.status(404), ctx.json({ status: 'Not Found' })) }, ), // Return a wiki page key for the AR (we'll mock out the actual wiki part) - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_WIKI_PAGE_KEY(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.json({ @@ -135,12 +138,12 @@ describe('Submission Page tests', () => { ) }, ), - rest.put( + http.put( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${DATA_ACCESS_SUBMISSION_BY_ID(':id')}`, - async (req, res, ctx) => { - onServerReceivedUpdate(await req.json()) + async ({ request, params }) => { + onServerReceivedUpdate(await request.json()) return res(ctx.status(200)) }, ), @@ -300,12 +303,12 @@ describe('Submission Page tests', () => { it.skip('Renders a user card if the AR has an ACL', async () => { // Fetching the AR's ACL will yield a designated reviewer server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ACCESS_REQUIREMENT_ACL(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const responseBody: AccessControlList = { id: '1234', resourceAccess: [ @@ -315,7 +318,7 @@ describe('Submission Page tests', () => { }, ], } - return res(ctx.status(200), ctx.json(responseBody)) + return HttpResponse.json(responseBody, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/dataaccess/SubmissionPage.stories.tsx b/packages/synapse-react-client/src/components/dataaccess/SubmissionPage.stories.tsx index 7a2b515070..8808096136 100644 --- a/packages/synapse-react-client/src/components/dataaccess/SubmissionPage.stories.tsx +++ b/packages/synapse-react-client/src/components/dataaccess/SubmissionPage.stories.tsx @@ -1,5 +1,5 @@ import { Meta, StoryObj } from '@storybook/react' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { ACCESS_REQUIREMENT_BY_ID, ACCESS_REQUIREMENT_WIKI_PAGE_KEY, @@ -30,31 +30,31 @@ export const Demo: Story = { ...getUserProfileHandlers(MOCK_REPO_ORIGIN), ...getWikiHandlers(MOCK_REPO_ORIGIN), // Return submission based on ID - rest.get( + http.get( `${MOCK_REPO_ORIGIN}${DATA_ACCESS_SUBMISSION_BY_ID(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { const submission = mockSubmissions.find( - submission => req.params.id === submission.id, + submission => params.id === submission.id, ) - return res(ctx.status(200), ctx.json(submission)) + return HttpResponse.json(submission, { status: 200 }) }, ), // Return a mocked access requirement - rest.get( + http.get( `${MOCK_REPO_ORIGIN}${ACCESS_REQUIREMENT_BY_ID(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.json(mockManagedACTAccessRequirement), ) }, ), - rest.get( + http.get( `${MOCK_REPO_ORIGIN}${ACCESS_REQUIREMENT_WIKI_PAGE_KEY(':id')}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.json({ @@ -65,9 +65,9 @@ export const Demo: Story = { ) }, ), - rest.get( + http.get( `${MOCK_REPO_ORIGIN}/repo/v1/accessRequirement/:id/acl`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.json({ @@ -85,11 +85,11 @@ export const Demo: Story = { }, ), ...getHandlersForTableQuery(mockRejectionReasonsTableQueryResultBundle), - rest.put( + http.put( `${MOCK_REPO_ORIGIN}${DATA_ACCESS_SUBMISSION_BY_ID(':id')}`, - async (req, res, ctx) => { - return res(ctx.status(201), ctx.json(await req.json())) + async ({ request, params }) => { + return res(ctx.status(201), ctx.json(await request.json())) }, ), ], diff --git a/packages/synapse-react-client/src/components/entity/metadata/AnnotationsTable.integration.test.tsx b/packages/synapse-react-client/src/components/entity/metadata/AnnotationsTable.integration.test.tsx index 6d48b198ef..f238fb9f05 100644 --- a/packages/synapse-react-client/src/components/entity/metadata/AnnotationsTable.integration.test.tsx +++ b/packages/synapse-react-client/src/components/entity/metadata/AnnotationsTable.integration.test.tsx @@ -57,18 +57,18 @@ describe('AnnotationsTable tests', () => { it('Displays a placeholder when there are no annotations', async () => { server.use( - rest.get( + http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_JSON( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { const response = mockFileEntityJson // Delete the annotation keys delete response.myStringKey delete response.myIntegerKey delete response.myFloatKey - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/entity/page/title_bar/TitleBarProperties.integration.test.tsx b/packages/synapse-react-client/src/components/entity/page/title_bar/TitleBarProperties.integration.test.tsx index ff488f3068..d29f78b151 100644 --- a/packages/synapse-react-client/src/components/entity/page/title_bar/TitleBarProperties.integration.test.tsx +++ b/packages/synapse-react-client/src/components/entity/page/title_bar/TitleBarProperties.integration.test.tsx @@ -58,14 +58,14 @@ function useEntityBundleOverride(bundle: EntityBundle) { function useDoiAssociationOverride(doiAssociation: DoiAssociation | null) { server.use( - rest.get( + http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${DOI_ASSOCIATION}`, - async (req, res, ctx) => { + async ({ request, params }) => { if (doiAssociation == null) { return res(ctx.status(404), ctx.json({})) } - return res(ctx.status(200), ctx.json(doiAssociation)) + return HttpResponse.json(doiAssociation, { status: 200 }) }, ), ) @@ -375,17 +375,17 @@ describe('TitleBarProperties', () => { }) server.use( - rest.post( + http.post( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/entity/children`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: EntityChildrenResponse = { page: [], totalChildCount: 55, nextPageToken: 'npt', } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/src/components/favorites/FavoriteButton.integration.test.tsx b/packages/synapse-react-client/src/components/favorites/FavoriteButton.integration.test.tsx index 9a84e4358a..864e9b2425 100644 --- a/packages/synapse-react-client/src/components/favorites/FavoriteButton.integration.test.tsx +++ b/packages/synapse-react-client/src/components/favorites/FavoriteButton.integration.test.tsx @@ -2,18 +2,13 @@ import React from 'react' import { render, screen, waitFor } from '@testing-library/react' import { createWrapper } from '../../testutils/TestingLibraryUtils' import FavoriteButton from './FavoriteButton' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' import mockFileEntityData from '../../mocks/entity/mockFileEntity' -import { FAVORITES } from '../../utils/APIConstants' -import { - BackendDestinationEnum, - getEndpoint, -} from '../../utils/functions/getEndpoint' -import { EntityHeader, PaginatedResults } from '@sage-bionetworks/synapse-types' import userEvent from '@testing-library/user-event' import { SynapseContextType } from '../../utils/context/SynapseContext' import { MOCK_CONTEXT_VALUE } from '../../mocks/MockSynapseContext' import { DeferredPromise } from '@open-draft/deferred-promise' +import { setCurrentFavoritesOnServer } from '../../mocks/msw/handlers/favoritesHandlers' function renderComponent(wrapperProps?: SynapseContextType) { return render(, { @@ -24,64 +19,16 @@ function renderComponent(wrapperProps?: SynapseContextType) { const onAddFavoriteCalled = jest.fn() const onDeleteFavoriteCalled = jest.fn() -function useIsInFavorites() { - server.use( - rest.get( - `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${FAVORITES}`, - - async (req, res, ctx) => { - const response: PaginatedResults = { - results: [mockFileEntityData.entityHeader], - } - - return res(ctx.status(200), ctx.json(response)) - }, - ), - ) -} -function useIsNotInFavorites() { - server.use( - rest.get( - `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${FAVORITES}`, - - async (req, res, ctx) => { - const response: PaginatedResults = { - results: [], - } - - return res(ctx.status(200), ctx.json(response)) - }, - ), - ) -} - -server.use( - rest.post( - `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${FAVORITES}/:id`, - async (req, res, ctx) => { - onAddFavoriteCalled(req.params.id) - useIsInFavorites() - return res(ctx.status(201), ctx.json(mockFileEntityData.entityHeader)) - }, - ), - rest.delete( - `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${FAVORITES}/:id`, - async (req, res, ctx) => { - onDeleteFavoriteCalled(req.params.id) - useIsNotInFavorites() - return res(ctx.status(200)) - }, - ), -) - describe('FavoriteButton tests', () => { beforeAll(() => server.listen()) + beforeEach(() => { + // Reset the server state before each test + setCurrentFavoritesOnServer(new Set()) + }) afterEach(() => server.restoreHandlers()) afterAll(() => server.close()) it('Clicking the button adds/removes from favorites', async () => { - useIsNotInFavorites() - renderComponent() await screen.findByLabelText('Add to Favorites') @@ -111,20 +58,6 @@ describe('FavoriteButton tests', () => { it('Disables the button while toggling the favorite', async () => { // Create a function that we'll use to delay the response from the mock server const deferResponse = new DeferredPromise() - server.use( - rest.post( - `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${FAVORITES}/:id`, - async (req, res, ctx) => { - onAddFavoriteCalled(req.params.id) - useIsInFavorites() - await deferResponse - return res(ctx.status(201), ctx.json(mockFileEntityData.entityHeader)) - }, - ), - ) - - // Start with the button not in favorites - useIsNotInFavorites() renderComponent() diff --git a/packages/synapse-react-client/src/components/trash/TrashCanList.integration.test.tsx b/packages/synapse-react-client/src/components/trash/TrashCanList.integration.test.tsx index 32131673db..fe76824130 100644 --- a/packages/synapse-react-client/src/components/trash/TrashCanList.integration.test.tsx +++ b/packages/synapse-react-client/src/components/trash/TrashCanList.integration.test.tsx @@ -3,93 +3,23 @@ import userEvent from '@testing-library/user-event' import React from 'react' import { TrashCanList } from './TrashCanList' import { createWrapper } from '../../testutils/TestingLibraryUtils' -import { - TRASHCAN_PURGE, - TRASHCAN_RESTORE, - TRASHCAN_VIEW, -} from '../../utils/APIConstants' -import { - BackendDestinationEnum, - getEndpoint, -} from '../../utils/functions/getEndpoint' -import { - PaginatedResults, - TrashedEntity, - EntityType, -} from '@sage-bionetworks/synapse-types' -import mockDatasetData from '../../mocks/entity/mockDataset' -import mockFileEntityData from '../../mocks/entity/mockFileEntity' -import { rest, server } from '../../mocks/msw/server' -import { MOCK_USER_ID } from '../../mocks/user/mock_user_profile' +import { BackendDestinationEnum, getEndpoint } from '../../utils/functions' +import { server } from '../../mocks/msw/server' +import { trashCanPages } from '../../mocks/mockTrashCan' +import SynapseClient from '../../synapse-client' +import { MOCK_ACCESS_TOKEN } from '../../mocks/MockSynapseContext' +import { getTrashCanRestoreErrorHandler } from '../../mocks/msw/handlers/trashCanHandlers' function renderComponent() { return render(, { wrapper: createWrapper() }) } -const trashCanPages: PaginatedResults[] = [ - { - totalNumberOfResults: 2, - results: [ - { - entityId: mockFileEntityData.id, - entityName: mockFileEntityData.name, - entityType: EntityType.FILE, - deletedByPrincipalId: MOCK_USER_ID.toString(), - deletedOn: '2020-01-01T00:00:00.000Z', - originalParentId: mockFileEntityData.entity.parentId!, - }, - ], - }, - { - totalNumberOfResults: 2, - results: [ - { - entityId: mockDatasetData.id, - entityName: mockDatasetData.name, - entityType: EntityType.FILE, - deletedByPrincipalId: MOCK_USER_ID.toString(), - deletedOn: '2020-01-01T00:00:00.000Z', - originalParentId: mockDatasetData.entity.parentId!, - }, - ], - }, -] - -const onServerReceivedRestore = jest.fn() -const onServerReceivedPurge = jest.fn() +const restoreFromTrashCanSpy = jest.spyOn(SynapseClient, 'restoreFromTrashCan') +const purgeFromTrashCanSpy = jest.spyOn(SynapseClient, 'purgeFromTrashCan') describe('TrashCanList', () => { beforeAll(() => server.listen()) - beforeEach(() => { - server.use( - rest.get( - `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${TRASHCAN_VIEW}`, - async (req, res, ctx) => { - const offset = req.url.searchParams.get('offset') ?? '0' - const result = trashCanPages[parseInt(offset)] - return res(ctx.status(200), ctx.json(result)) - }, - ), - rest.put( - `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${TRASHCAN_RESTORE( - ':entityId', - )}`, - async (req, res, ctx) => { - onServerReceivedRestore(req.params.entityId) - return res(ctx.status(200)) - }, - ), - rest.put( - `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${TRASHCAN_PURGE( - ':entityId', - )}`, - async (req, res, ctx) => { - onServerReceivedPurge(req.params.entityId) - return res(ctx.status(200)) - }, - ), - ) - }) + beforeEach(() => jest.clearAllMocks()) afterEach(() => server.restoreHandlers()) afterAll(() => server.close()) @@ -186,8 +116,9 @@ describe('TrashCanList', () => { await userEvent.click(restoreButton) await waitFor(() => - expect(onServerReceivedRestore).toHaveBeenCalledWith( + expect(restoreFromTrashCanSpy).toHaveBeenCalledWith( trashCanPages[0].results[0].entityId, + MOCK_ACCESS_TOKEN, ), ) }) @@ -221,11 +152,13 @@ describe('TrashCanList', () => { // Restore should have been called for each item await waitFor(() => { - expect(onServerReceivedRestore).toHaveBeenCalledWith( + expect(restoreFromTrashCanSpy).toHaveBeenCalledWith( trashCanPages[0].results[0].entityId, + MOCK_ACCESS_TOKEN, ) - expect(onServerReceivedRestore).toHaveBeenCalledWith( + expect(restoreFromTrashCanSpy).toHaveBeenCalledWith( trashCanPages[1].results[0].entityId, + MOCK_ACCESS_TOKEN, ) }) @@ -236,21 +169,8 @@ describe('TrashCanList', () => { test('Bulk restore with an error', async () => { // For only one of the items, the restore should fail server.use( - rest.put( - `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${TRASHCAN_RESTORE( - ':entityId', - )}`, - async (req, res, ctx) => { - onServerReceivedRestore(req.params.entityId) - if (req.params.entityId === mockFileEntityData.id) { - return res( - ctx.status(400), - ctx.json({ reason: 'Some error returned by the server' }), - ) - } else { - return res(ctx.status(200)) - } - }, + getTrashCanRestoreErrorHandler( + getEndpoint(BackendDestinationEnum.REPO_ENDPOINT), ), ) @@ -282,11 +202,13 @@ describe('TrashCanList', () => { // Restore should have been called for each item await waitFor(() => { - expect(onServerReceivedRestore).toHaveBeenCalledWith( + expect(restoreFromTrashCanSpy).toHaveBeenCalledWith( trashCanPages[0].results[0].entityId, + MOCK_ACCESS_TOKEN, ) - expect(onServerReceivedRestore).toHaveBeenCalledWith( + expect(restoreFromTrashCanSpy).toHaveBeenCalledWith( trashCanPages[1].results[0].entityId, + MOCK_ACCESS_TOKEN, ) }) @@ -331,11 +253,13 @@ describe('TrashCanList', () => { // Purge should have been called for each item await waitFor(() => { - expect(onServerReceivedPurge).toHaveBeenCalledWith( + expect(purgeFromTrashCanSpy).toHaveBeenCalledWith( trashCanPages[0].results[0].entityId, + MOCK_ACCESS_TOKEN, ) - expect(onServerReceivedPurge).toHaveBeenCalledWith( + expect(purgeFromTrashCanSpy).toHaveBeenCalledWith( trashCanPages[1].results[0].entityId, + MOCK_ACCESS_TOKEN, ) }) diff --git a/packages/synapse-react-client/src/mocks/mockTrashCan.ts b/packages/synapse-react-client/src/mocks/mockTrashCan.ts new file mode 100644 index 0000000000..bd884367a0 --- /dev/null +++ b/packages/synapse-react-client/src/mocks/mockTrashCan.ts @@ -0,0 +1,37 @@ +import { + EntityType, + PaginatedResults, + TrashedEntity, +} from '@sage-bionetworks/synapse-types' +import mockFileEntityData from './entity/mockFileEntity' +import { MOCK_USER_ID } from './user/mock_user_profile' +import mockDatasetData from './entity/mockDataset' + +export const trashCanPages: PaginatedResults[] = [ + { + totalNumberOfResults: 2, + results: [ + { + entityId: mockFileEntityData.id, + entityName: mockFileEntityData.name, + entityType: EntityType.FILE, + deletedByPrincipalId: MOCK_USER_ID.toString(), + deletedOn: '2020-01-01T00:00:00.000Z', + originalParentId: mockFileEntityData.entity.parentId!, + }, + ], + }, + { + totalNumberOfResults: 2, + results: [ + { + entityId: mockDatasetData.id, + entityName: mockDatasetData.name, + entityType: EntityType.FILE, + deletedByPrincipalId: MOCK_USER_ID.toString(), + deletedOn: '2020-01-01T00:00:00.000Z', + originalParentId: mockDatasetData.entity.parentId!, + }, + ], + }, +] diff --git a/packages/synapse-react-client/src/mocks/msw/handlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers.ts index 4469ca3fdb..62c1b15bca 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers.ts @@ -1,4 +1,4 @@ -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { getEntityHandlers } from './handlers/entityHandlers' import { getCurrentUserCertifiedValidatedHandler, @@ -26,23 +26,21 @@ import { MOCK_ANNOTATION_COLUMNS } from '../mockAnnotationColumns' import { getPersonalAccessTokenHandlers } from './handlers/personalAccessTokenHandlers' import getAllChallengeHandlers from './handlers/challengeHandlers' import getAllTeamHandlers from './handlers/teamHandlers' +import getTrashCanHandlers from './handlers/trashCanHandlers' // Simple utility type that just indicates that the response body could be an error like the Synapse backend may send. export type SynapseApiResponse = T | SynapseError const getHandlers = (backendOrigin: string) => [ - rest.options('*', async (req, res, ctx) => { - return res(ctx.status(200)) + http.options('*', () => { + return HttpResponse.json(null, { status: 200 }) + }), + http.get(`${backendOrigin}/auth/v1/authenticatedOn`, () => { + return HttpResponse.json( + { authenticatedOn: new Date().toISOString() }, + { status: 200 }, + ) }), - rest.get( - `${backendOrigin}/auth/v1/authenticatedOn`, - async (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ authenticatedOn: new Date().toISOString() }), - ) - }, - ), ...getEntityHandlers(backendOrigin), ...getUserProfileHandlers(backendOrigin), getCurrentUserCertifiedValidatedHandler(backendOrigin, true, true), @@ -60,6 +58,7 @@ const getHandlers = (backendOrigin: string) => [ ...getPersonalAccessTokenHandlers(backendOrigin), ...getAllTeamHandlers(backendOrigin), ...getAllChallengeHandlers(backendOrigin), + ...getTrashCanHandlers(backendOrigin), ] const handlers = getHandlers(getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)) diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/accessRequirementHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/accessRequirementHandlers.ts index 77671c5026..4cf674d2f7 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/accessRequirementHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/accessRequirementHandlers.ts @@ -1,4 +1,4 @@ -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { ACCESS_REQUIREMENT_BY_ID, ACCESS_REQUIREMENT_STATUS, @@ -29,16 +29,16 @@ const accessRequirementStatuses: Map = new Map() export const getAccessRequirementHandlers = (backendOrigin: string) => [ - rest.get( + http.get<{ id: string }, never, SynapseApiResponse>( `${backendOrigin}${ACCESS_REQUIREMENT_BY_ID(':id')}`, - async (req, res, ctx) => { + ({ params }) => { let status = 404 let response: SynapseApiResponse = { - reason: `Mock Service worker could not find an access requirement with ID ${req.params.id}`, + reason: `Mock Service worker could not find an access requirement with ID ${params.id}`, } const ar = mockAccessRequirements.find( - ar => ar.id.toString() === req.params.id, + ar => ar.id.toString() === params.id, ) if (ar) { @@ -46,20 +46,20 @@ export const getAccessRequirementHandlers = (backendOrigin: string) => [ status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), - rest.get( + http.get<{ id: string }, never, SynapseApiResponse>( `${backendOrigin}${ACCESS_REQUIREMENT_WIKI_PAGE_KEY(':id')}`, - async (req, res, ctx) => { + ({ params }) => { let status = 404 let response: SynapseApiResponse = { - reason: `Mock Service worker could not find an access requirement wiki page key with AR ID ${req.params.id}`, + reason: `Mock Service worker could not find an access requirement wiki page key with AR ID ${params.id}`, } const wikiPageKey = mockAccessRequirementWikiPageKeys.find( wpk => wpk.ownerObjectType === ObjectType.ACCESS_REQUIREMENT && - String(wpk.ownerObjectId) === req.params.id, + String(wpk.ownerObjectId) === params.id, ) if (wikiPageKey) { @@ -67,7 +67,7 @@ export const getAccessRequirementHandlers = (backendOrigin: string) => [ status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), ] @@ -76,16 +76,20 @@ export const getAccessRequirementEntityBindingHandlers = ( entityId = ':entityId', accessRequirements: AccessRequirement[] = mockAccessRequirements, ) => [ - rest.get( + http.get< + { entityId: string }, + never, + SynapseApiResponse> + >( `${backendOrigin}${ENTITY_ACCESS_REQUIREMENTS(entityId)}`, - async (req, res, ctx) => { + () => { const status = 200 const response: PaginatedResults = { results: accessRequirements, totalNumberOfResults: accessRequirements.length, } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), ] @@ -94,16 +98,20 @@ export const getAccessRequirementsBoundToTeamHandler = ( backendOrigin: string, accessRequirements: AccessRequirement[] = [mockSelfSignAccessRequirement], ) => - rest.get( + http.get< + { teamId: string }, + never, + SynapseApiResponse> + >( `${backendOrigin}/repo/v1/team/:teamId/accessRequirement`, - async (req, res, ctx) => { + () => { const status = 200 const response: PaginatedResults = { results: accessRequirements, totalNumberOfResults: accessRequirements.length, } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ) @@ -117,16 +125,19 @@ export const getAccessRequirementStatusHandlers = ( }) } return [ - rest.get( + http.get< + { id: string }, + never, + SynapseApiResponse + >( `${backendOrigin}${ACCESS_REQUIREMENT_STATUS(':id')}`, - async (req, res, ctx) => { + ({ params }) => { let response: AccessRequirementStatus | undefined const accessRequirement = mockAccessRequirements.find( - accessRequirement => - req.params.id === accessRequirement.id.toString(), + accessRequirement => params.id === accessRequirement.id.toString(), ) - let override = accessRequirementStatuses.get(req.params.id as string) + let override = accessRequirementStatuses.get(params.id) if (override) { response = override } @@ -135,7 +146,7 @@ export const getAccessRequirementStatusHandlers = ( accessRequirement.concreteType === MANAGED_ACT_ACCESS_REQUIREMENT_CONCRETE_TYPE_VALUE response = { - accessRequirementId: req.params.id as string, + accessRequirementId: params.id as string, concreteType: isManagedACTAR ? 'org.sagebionetworks.repo.model.dataaccess.ManagedACTAccessRequirementStatus' : 'org.sagebionetworks.repo.model.dataaccess.BasicAccessRequirementStatus', @@ -151,18 +162,22 @@ export const getAccessRequirementStatusHandlers = ( } } const status = response ? 200 : 404 - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), ] } export function getCreateAccessApprovalHandler(backendOrigin: string) { - return rest.post( + return http.post< + never, + CreateAccessApprovalRequest, + SynapseApiResponse + >( `${backendOrigin}/repo/v1/accessApproval`, - async (req, res, ctx) => { - const requestBody: CreateAccessApprovalRequest = await req.json() + async ({ request }) => { + const requestBody = await request.json() const status = 200 const response: AccessApproval = { ...requestBody, @@ -183,7 +198,7 @@ export function getCreateAccessApprovalHandler(backendOrigin: string) { isApproved: true, }) - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ) } diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/asyncJobHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/asyncJobHandlers.ts index ab47b27db6..d199cc51a7 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/asyncJobHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/asyncJobHandlers.ts @@ -1,8 +1,5 @@ -import { DefaultBodyType, rest } from 'msw' -import { - BackendDestinationEnum, - getEndpoint, -} from '../../../utils/functions/getEndpoint' +import { DefaultBodyType, http, HttpResponse } from 'msw' +import { BackendDestinationEnum, getEndpoint } from '../../../utils/functions' import { uniqueId } from 'lodash-es' import { AsynchJobState, @@ -11,6 +8,7 @@ import { } from '@sage-bionetworks/synapse-types' import { ASYNCHRONOUS_JOB_TOKEN } from '../../../utils/APIConstants' import { SynapseError } from '../../../utils/SynapseError' +import { SynapseApiResponse } from '../handlers' /** * Global mapping between async job token and request/response. This sort of acts as an in-memory database for asynchronous jobs. @@ -48,92 +46,95 @@ export function generateAsyncJobHandlers< ) { return [ // Handler for the asynchronous job request endpoint. - rest.post(`${backendOrigin}${requestPath}`, async (req, res, ctx) => { - const asyncJobId = uniqueId() - mapOfAsyncJobs.set(asyncJobId, { - request: await req.json(), - response: responseBody, - }) - return res( - ctx.status(201), - ctx.json({ - token: asyncJobId, - }), - ) - }), + http.post>( + `${backendOrigin}${requestPath}`, + async ({ request }) => { + const asyncJobId = uniqueId() + mapOfAsyncJobs.set(asyncJobId, { + request: await request.json(), + response: responseBody, + }) + return HttpResponse.json({ token: asyncJobId }, { status: 201 }) + }, + ), // Generic async job response handler. Since this implementation is the same for all services and references the global map, it's fine if this is overridden. - rest.get( - `${backendOrigin}${ASYNCHRONOUS_JOB_TOKEN(':id')}`, - async (req, res, ctx) => { - const id = req.params.id as string - const asyncJobDetails = mapOfAsyncJobs.get(id) - if (!id || !asyncJobDetails) { - return res( - ctx.status(404), - ctx.json({ message: 'The mocked asynchronous job was not found' }), - ) - } - const { request, response } = asyncJobDetails as { - request: TRequestBody - response: TResponseBody - } - const responseObject: TResponseBody = - typeof response === 'function' ? response(request) : response + http.get< + { id: string }, + never, + SynapseApiResponse> + >(`${backendOrigin}${ASYNCHRONOUS_JOB_TOKEN(':id')}`, ({ params }) => { + const id = params.id + const asyncJobDetails = mapOfAsyncJobs.get(id) + if (!id || !asyncJobDetails) { + const response: SynapseApiResponse< + AsynchronousJobStatus + > = { reason: 'The mocked asynchronous job was not found' } + return HttpResponse.json(response, { status: 404 }) + } + const { request, response } = asyncJobDetails as { + request: TRequestBody + response: TResponseBody + } + const jobResult: TResponseBody = + typeof response === 'function' ? response(request) : response - const jobState: AsynchJobState = - serviceSpecificEndpointResponseStatus < 400 ? 'COMPLETE' : 'FAILED' + const jobState: AsynchJobState = + serviceSpecificEndpointResponseStatus < 400 ? 'COMPLETE' : 'FAILED' - return res( - // This endpoint returns a successful status code regardless of the job status - ctx.status(200), - ctx.json>({ - jobState, - jobCanceling: false, - requestBody: request, - etag: '00000000-0000-0000-0000-000000000000', - jobId: id, - responseBody: responseObject, - startedByUserId: 0, - startedOn: '', - changedOn: '', - progressMessage: '', - progressCurrent: 100, - progressTotal: 100, - exception: '', - errorMessage: '', - errorDetails: '', - runtimeMS: 100, - }), - ) - }, - ), + const jobStatusResponseBody: AsynchronousJobStatus< + TRequestBody, + TResponseBody + > = { + jobState, + jobCanceling: false, + requestBody: request, + etag: '00000000-0000-0000-0000-000000000000', + jobId: id, + responseBody: jobResult, + startedByUserId: 0, + startedOn: '', + changedOn: '', + progressMessage: '', + progressCurrent: 100, + progressTotal: 100, + exception: '', + errorMessage: '', + errorDetails: '', + runtimeMS: 100, + } + + return HttpResponse.json(jobStatusResponseBody, { + // This endpoint returns a successful status code regardless of the job status + status: 200, + }) + }), // Service-specific response endpoint - rest.get( - `${backendOrigin}${responsePath(':asyncJobToken')}`, - async (req, res, ctx) => { - const asyncJobToken = req.params.asyncJobToken as string - const asyncJobDetails = mapOfAsyncJobs.get(asyncJobToken) - if (!asyncJobToken || !asyncJobDetails) { - return res( - ctx.status(404), - ctx.json({ message: 'The mocked asynchronous job was not found' }), - ) - } + http.get< + { asyncJobToken: string }, + never, + SynapseApiResponse + >(`${backendOrigin}${responsePath(':asyncJobToken')}`, ({ params }) => { + const asyncJobToken = params.asyncJobToken + const asyncJobDetails = mapOfAsyncJobs.get(asyncJobToken) + if (!asyncJobToken || !asyncJobDetails) { + return HttpResponse.json( + { reason: 'The mocked asynchronous job was not found' }, + { status: 404 }, + ) + } - const { request, response } = asyncJobDetails as { - request: TRequestBody - response: TResponseBody - } - const responseObject: TResponseBody = - typeof response === 'function' ? response(request) : response + const { request, response } = asyncJobDetails as { + request: TRequestBody + response: TResponseBody + } + const responseObject: TResponseBody = + typeof response === 'function' ? response(request) : response - return res( - ctx.status(serviceSpecificEndpointResponseStatus), - ctx.json(responseObject), - ) - }, - ), + return HttpResponse.json(responseObject, { + status: serviceSpecificEndpointResponseStatus, + }) + }), ] } diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/challengeHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/challengeHandlers.ts index b29688658a..6d397b2082 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/challengeHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/challengeHandlers.ts @@ -6,7 +6,7 @@ import { PaginatedIds, } from '@sage-bionetworks/synapse-types' import { SynapseApiResponse } from '../handlers' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { MOCK_CHALLENGE_ID, mockChallengeTeam, @@ -35,60 +35,66 @@ const registeredChallengeTeams = [ ] export function getChallengeHandler(backendOrigin: string) { - return rest.get( + return http.get<{ id: string }, never, SynapseApiResponse>( `${backendOrigin}/repo/v1/entity/:id/challenge`, - async (req, res, ctx) => { + ({ params }) => { const response: SynapseApiResponse = { id: MOCK_CHALLENGE_ID, etag: 'f5e9df54-360b-4ede-9a17-f7f5680c8dd4', - projectId: req.params.id as string, + projectId: params.id, participantTeamId: String(MOCK_CHALLENGE_PARTICIPANT_TEAM_ID), } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ) } export function getRegisteredChallengeTeamsHandler(backendOrigin: string) { - return rest.get( - `${backendOrigin}/repo/v1/challenge/:challengeId/challengeTeam`, - async (req, res, ctx) => { - const response: SynapseApiResponse = { - results: registeredChallengeTeams, - totalNumberOfResults: registeredChallengeTeams.length, - } - return res(ctx.status(200), ctx.json(response)) - }, - ) + return http.get< + { challengeId: string }, + never, + SynapseApiResponse + >(`${backendOrigin}/repo/v1/challenge/:challengeId/challengeTeam`, () => { + const response: SynapseApiResponse = { + results: registeredChallengeTeams, + totalNumberOfResults: registeredChallengeTeams.length, + } + return HttpResponse.json(response, { status: 200 }) + }) } export function getRegisterTeamForChallengeHandler(backendOrigin: string) { - return rest.post( + return http.post< + { challengeId: string }, + CreateChallengeTeamRequest, + SynapseApiResponse + >( `${backendOrigin}/repo/v1/challenge/:challengeId/challengeTeam`, - async (req, res, ctx) => { - const request: CreateChallengeTeamRequest = await req.json() + async ({ request }) => { + const requestBody = await request.json() const response: SynapseApiResponse = { - ...request, + ...requestBody, id: uniqueId(), etag: 'abcdef0987654321', } registeredChallengeTeams.push(response) - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ) } export function getSubmissionTeamsHandler(backendOrigin: string) { - return rest.get( - `${backendOrigin}/repo/v1/challenge/:challengeId/submissionTeams`, - async (req, res, ctx) => { - const response: SynapseApiResponse = { - results: [], - totalNumberOfResults: 0, - } - return res(ctx.status(200), ctx.json(response)) - }, - ) + return http.get< + { challengeId: string }, + never, + SynapseApiResponse + >(`${backendOrigin}/repo/v1/challenge/:challengeId/submissionTeams`, () => { + const response: SynapseApiResponse = { + results: [], + totalNumberOfResults: 0, + } + return HttpResponse.json(response, { status: 200 }) + }) } export default function getAllChallengeHandlers(backendOrigin: string) { diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/dataAccessRequestHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/dataAccessRequestHandlers.ts index 49fa7b9a1c..6467e62754 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/dataAccessRequestHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/dataAccessRequestHandlers.ts @@ -1,38 +1,47 @@ -import { Renewal, Request } from '@sage-bionetworks/synapse-types' -import { rest } from 'msw' +import { + CreateSubmissionRequest, + Renewal, + Request, + StatusEnum, + SubmissionStatus, +} from '@sage-bionetworks/synapse-types' +import { http, HttpResponse } from 'msw' import { ACCESS_REQUIREMENT_DATA_ACCESS_REQUEST_FOR_UPDATE, DATA_ACCESS_REQUEST, DATA_ACCESS_REQUEST_SUBMISSION, } from '../../../utils/APIConstants' -import { MOCK_DATA_ACCESS_REQUEST } from '../../dataaccess/MockDataAccessRequest' +import { SynapseApiResponse } from '../handlers' -export function getDataAccessRequestHandlers( - backendOrigin: string, - request: Request | Renewal = MOCK_DATA_ACCESS_REQUEST, -) { +export function getDataAccessRequestHandlers(backendOrigin: string) { return [ - rest.get( + http.get<{ id: string }, never, SynapseApiResponse>( `${backendOrigin}${ACCESS_REQUIREMENT_DATA_ACCESS_REQUEST_FOR_UPDATE( ':id', )}`, - async (req, res, ctx) => { - const response: Request | Renewal = request - return res(ctx.status(200), ctx.json(response)) + async ({ request }) => { + const response = await request.json() + return HttpResponse.json(response, { status: 200 }) }, ), - rest.post( + http.post>( `${backendOrigin}${DATA_ACCESS_REQUEST}`, - async (req, res, ctx) => { - const resp = await req.json() - return res(ctx.status(201), ctx.json(resp)) - }, - ), - rest.post( - `${backendOrigin}${DATA_ACCESS_REQUEST_SUBMISSION(':id')}`, - async (req, res, ctx) => { - return res(ctx.status(201), ctx.json({})) + async ({ request }) => { + const resp = await request.json() + return HttpResponse.json(resp, { status: 201 }) }, ), + http.post< + { id: string }, + CreateSubmissionRequest, + SynapseApiResponse + >(`${backendOrigin}${DATA_ACCESS_REQUEST_SUBMISSION(':id')}`, () => { + return HttpResponse.json( + { + state: StatusEnum.SUBMITTED_WAITING_FOR_REVIEW, + }, + { status: 201 }, + ) + }), ] } diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/discussionHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/discussionHandlers.ts index 44c586c521..ba1a100f9e 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/discussionHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/discussionHandlers.ts @@ -1,4 +1,4 @@ -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { FORUM, FORUM_THREAD, THREAD } from '../../../utils/APIConstants' import { CreateDiscussionThread, @@ -38,50 +38,60 @@ function getAllThreadsMatchingForum(forumId: string, filter: DiscussionFilter) { export function getDiscussionHandlers(backendOrigin: string) { return [ - rest.get(`${backendOrigin}${FORUM}/:id`, async (req, res, ctx) => { - let status = 404 - let resp: SynapseApiResponse = { - reason: `MSW could not find a mock forum object with ID ${req.params.id}`, - } + http.get<{ id: string }, never, SynapseApiResponse>( + `${backendOrigin}${FORUM}/:id`, + ({ params }) => { + let status = 404 + let resp: SynapseApiResponse = { + reason: `MSW could not find a mock forum object with ID ${params.id}`, + } - const match = forums.find(f => f.id === req.params.id) - if (match) { - status = 200 - resp = match - } + const match = forums.find(f => f.id === params.id) + if (match) { + status = 200 + resp = match + } - return res(ctx.status(status), ctx.json(resp)) - }), + return HttpResponse.json(resp, { status: status }) + }, + ), - rest.get(`${backendOrigin}${THREAD}/:id`, async (req, res, ctx) => { - let status = 404 - let resp: SynapseApiResponse = { - reason: `MSW could not find a mock discussion thread bundle object with ID ${req.params.id}`, - } - if (req.params.id === 'messageUrl') { - // This is a different endpoint - resp = { - reason: 'GET /thread/messageUrl is not yet implemented', + http.get<{ id: string }, never, SynapseApiResponse>( + `${backendOrigin}${THREAD}/:id`, + ({ params }) => { + let status = 404 + let resp: SynapseApiResponse = { + reason: `MSW could not find a mock discussion thread bundle object with ID ${params.id}`, + } + if (params.id === 'messageUrl') { + // This is a different endpoint + resp = { + reason: 'GET /thread/messageUrl is not yet implemented', + } } - } - const match = threads.find(dtb => dtb.id === req.params.id) - if (match) { - status = 200 - resp = match - } + const match = threads.find(dtb => dtb.id === params.id) + if (match) { + status = 200 + resp = match + } - return res(ctx.status(status), ctx.json(resp)) - }), + return HttpResponse.json(resp, { status: status }) + }, + ), - rest.post(`${backendOrigin}${THREAD}`, async (req, res, ctx) => { - const request: CreateDiscussionThread = await req.json() + http.post< + never, + CreateDiscussionThread, + SynapseApiResponse + >(`${backendOrigin}${THREAD}`, async ({ request }) => { + const requestBody: CreateDiscussionThread = await request.json() const newDiscussionThreadBundle: DiscussionThreadBundle = { id: uniqueId(), - forumId: request.forumId, + forumId: requestBody.forumId, projectId: mockProject.id, - title: request.title, + title: requestBody.title, createdOn: new Date().toISOString(), createdBy: String(MOCK_USER_ID), modifiedOn: new Date().toISOString(), @@ -97,42 +107,44 @@ export function getDiscussionHandlers(backendOrigin: string) { } threads.push(newDiscussionThreadBundle) - return res(ctx.status(201), ctx.json(newDiscussionThreadBundle)) + return HttpResponse.json(newDiscussionThreadBundle, { status: 201 }) }), - rest.get( - `${backendOrigin}${FORUM_THREAD(':forumId')}`, - async (req, res, ctx) => { - const offsetParam = req.url.searchParams.get('offset') - const offset = offsetParam ? parseInt(offsetParam) : 0 - const limitParam = req.url.searchParams.get('limit') - const limit = limitParam ? parseInt(limitParam) : 10 - const filter: DiscussionFilter = - (req.params.filter as DiscussionFilter) ?? - DiscussionFilter.EXCLUDE_DELETED + http.get< + { forumId: string }, + never, + SynapseApiResponse> + >(`${backendOrigin}${FORUM_THREAD(':forumId')}`, ({ request, params }) => { + const url = new URL(request.url) + const offsetParam = url.searchParams.get('offset') + const offset = offsetParam ? parseInt(offsetParam) : 0 + const limitParam = url.searchParams.get('limit') + const limit = limitParam ? parseInt(limitParam) : 10 + const filter: DiscussionFilter = + (url.searchParams.get('filter') as DiscussionFilter) ?? + DiscussionFilter.EXCLUDE_DELETED - const matchingThreads = getAllThreadsMatchingForum( - req.params.forumId as string, - filter, - ) + const matchingThreads = getAllThreadsMatchingForum( + params.forumId as string, + filter, + ) - const response: SynapseApiResponse< - PaginatedResults - > = { - results: matchingThreads.slice(offset, offset + limit), - totalNumberOfResults: matchingThreads.length, - } - return res(ctx.status(200), ctx.json(response)) - }, - ), - rest.get( + const response: SynapseApiResponse< + PaginatedResults + > = { + results: matchingThreads.slice(offset, offset + limit), + totalNumberOfResults: matchingThreads.length, + } + return HttpResponse.json(response, { status: 200 }) + }), + http.get<{ id: string }, never, SynapseApiResponse>( `${backendOrigin}${FORUM}/:id/moderators`, - async (req, res, ctx) => { + () => { const resp: PaginatedIds = { results: [String(MOCK_USER_ID)], totalNumberOfResults: 1, } - return res(ctx.status(200), ctx.json(resp)) + return HttpResponse.json(resp, { status: 200 }) }, ), ] diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/entityHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/entityHandlers.ts index cb14b91bd4..995e3ec516 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/entityHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/entityHandlers.ts @@ -1,4 +1,4 @@ -import { rest } from 'msw' +import { HttpResponse, http } from 'msw' import { ENTITY, ENTITY_BUNDLE_V2, @@ -12,9 +12,11 @@ import { import { Entity, EntityBundle, + EntityBundleRequest, EntityHeader, EntityJson, EntityPath, + JsonSchemaObjectBinding, PaginatedResults, ProjectHeaderList, Reference, @@ -35,39 +37,44 @@ export function getEntityBundleHandler( backendOrigin: string, bundle?: Partial, ) { - return rest.post( - `${backendOrigin}${ENTITY_BUNDLE_V2(':entityId')}`, - async (req, res, ctx) => { - let status = 404 - let response: SynapseApiResponse = { - reason: `Mock Service worker could not find a mock entity bundle with ID ${req.params.entityId}`, - } - if (bundle) { - response = bundle as EntityBundle + return http.post< + { entityId: string }, + EntityBundleRequest, + SynapseApiResponse + >(`${backendOrigin}${ENTITY_BUNDLE_V2(':entityId')}`, ({ params }) => { + let status = 404 + let response: SynapseApiResponse = { + reason: `Mock Service worker could not find a mock entity bundle with ID ${params.entityId}`, + } + if (bundle) { + response = bundle as EntityBundle + status = 200 + } else { + const entityData = mockEntities.find( + entity => entity.id === params.entityId, + ) + if (entityData?.bundle) { + response = entityData.bundle status = 200 - } else { - const entityData = mockEntities.find( - entity => entity.id === req.params.entityId, - ) - if (entityData?.bundle) { - response = entityData.bundle - status = 200 - } } - return res(ctx.status(status), ctx.json(response)) - }, - ) + } + return HttpResponse.json(response, { status }) + }) } export function getVersionedEntityBundleHandler( backendOrigin: string, bundle?: Partial, ) { - return rest.post( + return http.post< + { entityId: string; versionNumber: string }, + EntityBundleRequest, + SynapseApiResponse + >( `${backendOrigin}${ENTITY_BUNDLE_V2(':entityId', ':versionNumber')}`, - async (req, res, ctx) => { - const entityId = req.params.entityId - const versionNumber = parseInt(req.params.versionNumber as string) + ({ params }) => { + const entityId = params.entityId + const versionNumber = parseInt(params.versionNumber) let status = 404 let response: SynapseApiResponse = { reason: `Mock Service worker could not find a mock entity bundle with ID ${entityId}`, @@ -90,7 +97,7 @@ export function getVersionedEntityBundleHandler( status = 200 } } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ) } @@ -99,76 +106,84 @@ export const getEntityHandlers = (backendOrigin: string) => [ /** * Create a new entity */ - rest.post(`${backendOrigin}${ENTITY}`, async (req, res, ctx) => { - let status = 200 - const requestBody = await req.json() - let response: SynapseApiResponse = { reason: '...' } - if (!requestBody) { - status = 400 - response = { - reason: `Mock service worker received the following malformed body for PUT ${ENTITY} : ${JSON.stringify( - requestBody, - )}`, - } - } else { - if (requestBody.name === MOCK_INVALID_PROJECT_NAME) { - response.reason = 'Invalid project name' - status = 403 + http.post>( + `${backendOrigin}${ENTITY}`, + async ({ request }) => { + let status = 200 + const requestBody = await request.json() + let response: SynapseApiResponse = { reason: '...' } + if (!requestBody) { + status = 400 + response = { + reason: `Mock service worker received the following malformed body for PUT ${ENTITY} : ${JSON.stringify( + requestBody, + )}`, + } } else { - response = { id: uniqueId('syn'), ...requestBody } + if (requestBody.name === MOCK_INVALID_PROJECT_NAME) { + response.reason = 'Invalid project name' + status = 403 + } else { + response = { id: uniqueId('syn'), ...requestBody } + } } - } - return res(ctx.status(status), ctx.json(response)) - }), + return HttpResponse.json(response, { status }) + }, + ), /** * Get entity by ID */ - rest.get( + http.get<{ entityId: string }, never, SynapseApiResponse>( `${backendOrigin}${ENTITY_ID(':entityId')}`, - async (req, res, ctx) => { + ({ params }) => { let status = 404 let response: SynapseApiResponse = { - reason: `Mock Service worker could not find a mock entity with ID ${req.params.entityId}`, + reason: `Mock Service worker could not find a mock entity with ID ${params.entityId}`, } const entityData = mockEntities.find( - entity => entity.id === req.params.entityId, + entity => entity.id === params.entityId, ) if (entityData) { response = entityData.entity status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), - rest.get( - `${backendOrigin}${ENTITY_ID_VERSIONS(':entityId')}`, - async (req, res, ctx) => { - let status = 404 - let response: SynapseApiResponse> = { - reason: `Mock Service worker could not find mock entity versions for ID ${req.params.entityId}`, - } + http.get< + { entityId: string }, + never, + SynapseApiResponse> + >(`${backendOrigin}${ENTITY_ID_VERSIONS(':entityId')}`, ({ params }) => { + let status = 404 + let response: SynapseApiResponse> = { + reason: `Mock Service worker could not find mock entity versions for ID ${params.entityId}`, + } - const entityData = mockEntities.find( - entity => entity.id === req.params.entityId, - ) - if (entityData && entityData.versionInfo) { - response = { results: entityData.versionInfo } - status = 200 - } - return res(ctx.status(status), ctx.json(response)) - }, - ), + const entityData = mockEntities.find( + entity => entity.id === params.entityId, + ) + if (entityData && entityData.versionInfo) { + response = { results: entityData.versionInfo } + status = 200 + } + return HttpResponse.json(response, { status }) + }), - rest.get( + http.get< + { entityId: string; versionNumber: string }, + never, + SynapseApiResponse + >( `${backendOrigin}${ENTITY_ID_VERSION(':entityId', ':versionNumber')}`, - async (req, res, ctx) => { + ({ params }) => { let status = 404 - const entityId = req.params.entityId - const versionNumber = req.params.versionNumber.toString() + const entityId = params.entityId + const versionNumber = String(params.versionNumber) const requestedVersionNumber = parseInt(versionNumber) let response: SynapseApiResponse = { @@ -176,7 +191,7 @@ export const getEntityHandlers = (backendOrigin: string) => [ } const entityData = mockEntities.find( - entity => entity.id === req.params.entityId, + entity => entity.id === params.entityId, ) if ( entityData && @@ -188,49 +203,58 @@ export const getEntityHandlers = (backendOrigin: string) => [ ] as VersionableEntity status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), getEntityBundleHandler(backendOrigin), getVersionedEntityBundleHandler(backendOrigin), - rest.get( - `${backendOrigin}${ENTITY_SCHEMA_BINDING(':entityId')}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockSchemaBinding)) - }, - ), - rest.get( + http.get< + { entityId: string }, + never, + SynapseApiResponse + >(`${backendOrigin}${ENTITY_SCHEMA_BINDING(':entityId')}`, () => { + return HttpResponse.json(mockSchemaBinding, { status: 200 }) + }), + http.get<{ entityId: string }, never, SynapseApiResponse>( `${backendOrigin}${ENTITY_JSON(':entityId')}`, - async (req, res, ctx) => { + ({ params }) => { let status = 404 let response: SynapseApiResponse = { - reason: `Mock Service worker could not find a mock entity bundle with ID ${req.params.entityId}`, + reason: `Mock Service worker could not find a mock entity bundle with ID ${params.entityId}`, } const entityData = mockEntities.find( - entity => entity.id === req.params.entityId, + entity => entity.id === params.entityId, ) if (entityData?.json) { response = entityData.json status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), - rest.post( + http.post< + { entityId: string }, + { + references: Reference[] + }, + SynapseApiResponse> + >( `${backendOrigin}${ENTITY_HEADERS}`, - async (req, res, ctx) => { + async ({ params, request }) => { let status = 404 let response: SynapseApiResponse> = { - reason: `Mock Service worker could not find a mock entity bundle with ID ${req.params.entityId}`, + reason: `Mock Service worker could not find a mock entity bundle with ID ${params.entityId}`, } - const referenceList = req.body as { references: Reference[] } + const referenceList = (await request.json()) as { + references: Reference[] + } const entityData = mockEntities .filter(entity => referenceList.references.find(ref => ref.targetId === entity.id), @@ -243,51 +267,55 @@ export const getEntityHandlers = (backendOrigin: string) => [ status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), - rest.get( + http.get<{ entityId: string }, never, SynapseApiResponse>( `${backendOrigin}${ENTITY_ID(':entityId')}/path`, - async (req, res, ctx) => { + ({ params }) => { let status = 404 let response: SynapseApiResponse = { - reason: `Mock Service worker could not find a mock entity path using ID ${req.params.entityId}`, + reason: `Mock Service worker could not find a mock entity path using ID ${params.entityId}`, } - const entityData = mockEntities.find(e => req.params.entityId === e.id) + const entityData = mockEntities.find(e => params.entityId === e.id) if (entityData && entityData.path) { response = entityData.path status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), - rest.get( + http.get<{ id: string }, never, SynapseApiResponse>( `${backendOrigin}/file/v1/entity/:id/uploadDestination`, - async (req, res, ctx) => { + () => { const response: UploadDestination = { banner: '', storageLocationId: 1, uploadType: UploadType.S3, concreteType: 'org.sagebionetworks.repo.model.file.S3UploadDestination', } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), - rest.get( + http.get< + { id: string; storageLocationId: string }, + never, + SynapseApiResponse + >( `${backendOrigin}/file/v1/entity/:id/uploadDestination/:storageLocationId`, - async (req, res, ctx) => { + ({ params }) => { let status = 404 let response: SynapseApiResponse = { - reason: `Mock Service worker could not find an uploadDestination using storageLocationId ${req.params.storageLocationId}`, + reason: `Mock Service worker could not find an uploadDestination using storageLocationId ${params.storageLocationId}`, } const uploadDestination = mockUploadDestinations.find( - e => Number(req.params.storageLocationId) === e.storageLocationId, + e => Number(params.storageLocationId) === e.storageLocationId, ) if (uploadDestination) { @@ -295,20 +323,23 @@ export const getEntityHandlers = (backendOrigin: string) => [ status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), - rest.get(`${backendOrigin}/repo/v1/projects`, async (req, res, ctx) => { - const response: ProjectHeaderList = { - results: mockProjectsEntityData.map(p => ({ - name: p.name, - id: p.id, - lastActivity: '2024-01-04T21:11:59.000Z', - modifiedBy: parseInt(p.entity.modifiedBy!), - modifiedOn: p.entity.modifiedOn!, - })), - } - return res(ctx.status(200), ctx.json(response)) - }), + http.get>( + `${backendOrigin}/repo/v1/projects`, + () => { + const response: ProjectHeaderList = { + results: mockProjectsEntityData.map(p => ({ + name: p.name, + id: p.id, + lastActivity: '2024-01-04T21:11:59.000Z', + modifiedBy: parseInt(p.entity.modifiedBy!), + modifiedOn: p.entity.modifiedOn!, + })), + } + return HttpResponse.json(response, { status: 200 }) + }, + ), ] diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/evaluationHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/evaluationHandlers.ts index ef96e4fc13..185d29aa75 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/evaluationHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/evaluationHandlers.ts @@ -1,4 +1,4 @@ -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { EVALUATION, EVALUATION_BY_ID } from '../../../utils/APIConstants' import { Evaluation, PaginatedResults } from '@sage-bionetworks/synapse-types' import { SynapseApiResponse } from '../handlers' @@ -9,38 +9,41 @@ export function getEvaluationHandlers(backendOrigin: string) { /** * Get by ID */ - rest.get( + http.get<{ evaluationId: string }, never, SynapseApiResponse>( `${backendOrigin}${EVALUATION_BY_ID(':evaluationId')}`, - async (req, res, ctx) => { + ({ params }) => { let status = 404 let response: SynapseApiResponse = { - reason: `Mock Service worker could not find a mock evaluation queue with ID ${req.params.evaluationId}`, + reason: `Mock Service worker could not find a mock evaluation queue with ID ${params.evaluationId}`, } const match = mockEvaluations.find( - evaluation => evaluation.id === req.params.entityId, + evaluation => evaluation.id === params.evaluationId, ) if (match) { response = match status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), /** * Get paginated list */ - rest.get(`${backendOrigin}${EVALUATION}`, async (req, res, ctx) => { - let status = 200 - let response: SynapseApiResponse> = { - results: mockEvaluations, - totalNumberOfResults: mockEvaluations.length, - } + http.get>>( + `${backendOrigin}${EVALUATION}`, + () => { + let status = 200 + let response: SynapseApiResponse> = { + results: mockEvaluations, + totalNumberOfResults: mockEvaluations.length, + } - // TODO: Filtering + // TODO: Filtering - return res(ctx.status(status), ctx.json(response)) - }), + return HttpResponse.json(response, { status }) + }, + ), ] } diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/favoritesHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/favoritesHandlers.ts new file mode 100644 index 0000000000..2694f1387b --- /dev/null +++ b/packages/synapse-react-client/src/mocks/msw/handlers/favoritesHandlers.ts @@ -0,0 +1,52 @@ +import { http, HttpResponse } from 'msw' +import { FAVORITES } from '../../../utils/APIConstants' +import mockFileEntityData from '../../entity/mockFileEntity' +import { SynapseApiResponse } from '../handlers' +import { EntityHeader, PaginatedResults } from '@sage-bionetworks/synapse-types' +import { BackendDestinationEnum, getEndpoint } from '../../../utils/functions' +import mockEntities from '../../entity' + +const favorites: Set = new Set() + +export function setCurrentFavoritesOnServer(newFavorites: Set) { + favorites.clear() + newFavorites.forEach(id => favorites.add(id)) +} + +export default function getFavoritesHandlers(backendOrigin: string) { + return [ + http.get>( + `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${FAVORITES}`, + + () => { + const headerFavs = mockEntities + .filter(entity => favorites.has(entity.id)) + .map(entity => entity.entityHeader) + .filter((eh): eh is EntityHeader => Boolean(eh)) + const response: PaginatedResults = { + results: headerFavs, + totalNumberOfResults: headerFavs.length, + } + + return HttpResponse.json(response, { status: 200 }) + }, + ), + http.post<{ id: string }, never, SynapseApiResponse>( + `${backendOrigin}${FAVORITES}/:id`, + ({ params }) => { + favorites.add(params.id) + return HttpResponse.json(mockFileEntityData.entityHeader, { + status: 201, + }) + }, + ), + http.delete<{ id: string }, never, SynapseApiResponse<''>>( + `${backendOrigin}${FAVORITES}/:id`, + ({ params }) => { + favorites.delete(params.id) + + return HttpResponse.text('', { status: 200 }) + }, + ), + ] +} diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/fileHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/fileHandlers.ts index bc9e32d6bc..97ef8a429c 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/fileHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/fileHandlers.ts @@ -2,32 +2,36 @@ import { BatchFileRequest, BatchFileResult, } from '@sage-bionetworks/synapse-types' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { FILE_HANDLE_BATCH } from '../../../utils/APIConstants' import { mockFileHandles } from '../../mock_file_handle' +import { SynapseApiResponse } from '../handlers' export function getFileHandlers(backendOrigin: string) { return [ - rest.post(`${backendOrigin}${FILE_HANDLE_BATCH}`, async (req, res, ctx) => { - const request: BatchFileRequest = await req.json() + http.post>( + `${backendOrigin}${FILE_HANDLE_BATCH}`, + async ({ request }) => { + const requestBody = await request.json() - const response: BatchFileResult = { - requestedFiles: [], - } - - request.requestedFiles.forEach(fileHandleAssociation => { - const fileHandle = mockFileHandles.find( - fh => fh.id === fileHandleAssociation.fileHandleId, - ) - if (fileHandle) { - response.requestedFiles.push({ - fileHandleId: fileHandle.id, - fileHandle, - }) + const response: BatchFileResult = { + requestedFiles: [], } - }) - return res(ctx.status(201), ctx.json(response)) - }), + requestBody.requestedFiles.forEach(fileHandleAssociation => { + const fileHandle = mockFileHandles.find( + fh => fh.id === fileHandleAssociation.fileHandleId, + ) + if (fileHandle) { + response.requestedFiles.push({ + fileHandleId: fileHandle.id, + fileHandle, + }) + } + }) + + return HttpResponse.json(response, { status: 201 }) + }, + ), ] } diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/personalAccessTokenHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/personalAccessTokenHandlers.ts index f97f35fdb3..bf8b0b7443 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/personalAccessTokenHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/personalAccessTokenHandlers.ts @@ -1,46 +1,50 @@ -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { mockAccessTokenRecordListPageOne, mockAccessTokenRecordListPageTwo, } from '../../personalAccessToken/mockPersonalAccessToken' import { + AccessTokenGenerationRequest, AccessTokenGenerationResponse, AccessTokenRecordList, } from '@sage-bionetworks/synapse-types' +import { SynapseApiResponse } from '../handlers' export function getPersonalAccessTokenHandlers( backendOrigin: string, tokenRecordOverride?: AccessTokenRecordList, ) { return [ - rest.get( + http.get( `${backendOrigin}/auth/v1/personalAccessToken`, - async (req, res, ctx) => { + ({ request }) => { + const url = new URL(request.url) let response = mockAccessTokenRecordListPageOne if (tokenRecordOverride) { response = tokenRecordOverride - } else if (req.url.searchParams.get('nextPageToken')) { + } else if (url.searchParams.get('nextPageToken')) { response = mockAccessTokenRecordListPageTwo } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), - rest.delete( + http.delete<{ id: string }, never, SynapseApiResponse<''>>( `${backendOrigin}/auth/v1/personalAccessToken/:id`, - async (req, res, ctx) => { - return res(ctx.status(202)) + () => { + return HttpResponse.text('', { status: 202 }) }, ), - rest.post( - `${backendOrigin}/auth/v1/personalAccessToken`, - async (req, res, ctx) => { - const responseBody: AccessTokenGenerationResponse = { - token: 'your-token-here', - } - return res(ctx.status(201), ctx.json(responseBody)) - }, - ), + http.post< + never, + AccessTokenGenerationRequest, + SynapseApiResponse + >(`${backendOrigin}/auth/v1/personalAccessToken`, () => { + const responseBody: AccessTokenGenerationResponse = { + token: 'your-token-here', + } + return HttpResponse.json(responseBody, { status: 201 }) + }), ] } diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/researchProjectHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/researchProjectHandlers.ts index 15d135c1db..8fe5d0ef43 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/researchProjectHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/researchProjectHandlers.ts @@ -1,27 +1,31 @@ -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { ACCESS_REQUIREMENT_RESEARCH_PROJECT_FOR_UPDATE, RESEARCH_PROJECT, } from '../../../utils/APIConstants' import { ResearchProject } from '@sage-bionetworks/synapse-types' import { MOCK_RESEARCH_PROJECT } from '../../dataaccess/MockResearchProject' +import { SynapseApiResponse } from '../handlers' export function getResearchProjectHandlers(backendOrigin: string) { return [ - rest.post(`${backendOrigin}${RESEARCH_PROJECT}`, async (req, res, ctx) => { - const resp = await req.json() - return res(ctx.status(201), ctx.json(resp)) - }), - rest.get( + http.post>( + `${backendOrigin}${RESEARCH_PROJECT}`, + async ({ request }) => { + const resp = await request.json() + return HttpResponse.json(resp, { status: 201 }) + }, + ), + http.get<{ id: string }, never, SynapseApiResponse>( `${backendOrigin}${ACCESS_REQUIREMENT_RESEARCH_PROJECT_FOR_UPDATE( ':id', )}`, - async (req, res, ctx) => { + ({ params }) => { const response: ResearchProject = { ...MOCK_RESEARCH_PROJECT, - accessRequirementId: req.params.id.toString(), + accessRequirementId: params.id.toString(), } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), ] diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/subscriptionHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/subscriptionHandlers.ts index ec4e93765a..71fa6d40bd 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/subscriptionHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/subscriptionHandlers.ts @@ -1,4 +1,4 @@ -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { SortDirection, SubscriberPagedResults, @@ -54,18 +54,18 @@ function getSubscriptions( export function getSubscriptionHandlers(backendOrigin: string) { return [ - rest.get( + http.get>( `${backendOrigin}/repo/v1/subscription/all`, - async (req, res, ctx) => { + ({ request }) => { + const url = new URL(request.url) const objectType = - (req.url.searchParams.get('objectType') as SubscriptionObjectType) ?? + (url.searchParams.get('objectType') as SubscriptionObjectType) ?? undefined const sortDirection = - (req.url.searchParams.get('sortDirection') as SortDirection) ?? - undefined - const offsetParam = req.url.searchParams.get('offset') + (url.searchParams.get('sortDirection') as SortDirection) ?? undefined + const offsetParam = url.searchParams.get('offset') const offset = offsetParam ? parseInt(offsetParam) : undefined - const limitParam = req.url.searchParams.get('limit') + const limitParam = url.searchParams.get('limit') const limit = limitParam ? parseInt(limitParam) : undefined const resp: SynapseApiResponse = @@ -76,30 +76,31 @@ export function getSubscriptionHandlers(backendOrigin: string) { limit, ) - return res(ctx.status(200), ctx.json(resp)) + return HttpResponse.json(resp, { status: 200 }) }, ), - rest.post( - `${backendOrigin}/repo/v1/subscription/list`, - async (req, res, ctx) => { - const request: SubscriptionRequest = await req.json() + http.post< + never, + SubscriptionRequest, + SynapseApiResponse + >(`${backendOrigin}/repo/v1/subscription/list`, async ({ request }) => { + const requestBody = await request.json() - const resp: SynapseApiResponse = - getSubscriptions( - request.objectType, - request.sortDirection, - undefined, - undefined, - request.idList, - ) + const resp: SynapseApiResponse = + getSubscriptions( + requestBody.objectType, + requestBody.sortDirection, + undefined, + undefined, + requestBody.idList, + ) - return res(ctx.status(200), ctx.json(resp)) - }, - ), - rest.post( + return HttpResponse.json(resp, { status: 200 }) + }), + http.post>( `${backendOrigin}/repo/v1/subscription`, - async (req, res, ctx) => { - const requestBody: Topic = await req.json() + async ({ request }) => { + const requestBody: Topic = await request.json() const newSubscription: Subscription = { subscriptionId: uniqueId(), @@ -110,21 +111,21 @@ export function getSubscriptionHandlers(backendOrigin: string) { } subscriptions.push(newSubscription) - return res(ctx.status(201), ctx.json(newSubscription)) + return HttpResponse.json(newSubscription, { status: 201 }) }, ), - rest.delete( + http.delete<{ id: string }, never, SynapseApiResponse<''>>( `${backendOrigin}/repo/v1/subscription/:id`, - async (req, res, ctx) => { - const subscriptionId = req.params.id as string + ({ params }) => { + const subscriptionId = params.id remove(subscriptions, s => s.subscriptionId === subscriptionId) - return res(ctx.status(200), ctx.body('')) + return HttpResponse.text('', { status: 200 }) }, ), - rest.post( + http.post>( `${backendOrigin}/repo/v1/subscription/subscribers`, - async (req, res, ctx) => { - const topic: Topic = await req.json() + async ({ request }) => { + const topic = await request.json() const matchingSubscriptions = subscriptions.filter( s => @@ -134,7 +135,7 @@ export function getSubscriptionHandlers(backendOrigin: string) { const resp: SubscriberPagedResults = { subscribers: matchingSubscriptions.map(s => s.subscriberId), } - return res(ctx.status(200), ctx.json(resp)) + return HttpResponse.json(resp, { status: 200 }) }, ), ] diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/tableQueryHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/tableQueryHandlers.ts index 2274a21fe3..100a30fec6 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/tableQueryHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/tableQueryHandlers.ts @@ -1,13 +1,10 @@ import { cloneDeep, uniqueId } from 'lodash-es' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { TABLE_QUERY_ASYNC_GET, TABLE_QUERY_ASYNC_START, } from '../../../utils/APIConstants' -import { - BackendDestinationEnum, - getEndpoint, -} from '../../../utils/functions/getEndpoint' +import { BackendDestinationEnum, getEndpoint } from '../../../utils/functions' import { BUNDLE_MASK_LAST_UPDATED_ON, BUNDLE_MASK_QUERY_COLUMN_MODELS, @@ -86,15 +83,15 @@ export function getDefaultColumnHandlers( backendOrigin = getEndpoint(BackendDestinationEnum.REPO_ENDPOINT), ) { return [ - rest.get( + http.get( `${backendOrigin}/repo/v1/column/tableview/defaults`, - async (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ + () => { + return HttpResponse.json( + { concreteType: 'org.sagebionetworks.repo.model.table.ColumnModel', list: defaultFileViewColumnModels, - }), + }, + { status: 200 }, ) }, ), @@ -104,21 +101,21 @@ export function getDefaultColumnHandlers( export function getCreateColumnModelBatchHandler( backendOrigin = getEndpoint(BackendDestinationEnum.REPO_ENDPOINT), ) { - return rest.post( + return http.post( `${backendOrigin}/repo/v1/column/batch`, - async (req, res, ctx) => { - const { list: columnModels } = await req.json<{ list: ColumnModel[] }>() + async ({ request }) => { + const { list: columnModels } = await request.json() columnModels.forEach(cm => { if (!cm.id) { cm.id = uniqueId() } }) - return res( - ctx.status(201), - ctx.json({ + return HttpResponse.json( + { concreteType: 'org.sagebionetworks.repo.model.table.ColumnModel', list: columnModels, - }), + }, + { status: 201 }, ) }, ) diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/teamHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/teamHandlers.ts index 8538bc0ef0..0d06962d14 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/teamHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/teamHandlers.ts @@ -1,6 +1,6 @@ import { Team, TeamMembershipStatus } from '@sage-bionetworks/synapse-types' import { SynapseApiResponse } from '../handlers' -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { mockTeamMembershipStatuses, mockTeams } from '../../team/mockTeam' const teams: Team[] = [...mockTeams] @@ -25,11 +25,15 @@ function addTeamMembershipStatus(teamMembershipStatus: TeamMembershipStatus) { } export function getTeamMembershipStatusHandler(backendOrigin: string) { - return rest.get( + return http.get< + { teamId: string; memberId: string }, + never, + SynapseApiResponse + >( `${backendOrigin}/repo/v1/team/:teamId/member/:memberId/membershipStatus`, - async (req, res, ctx) => { - const teamId = req.params.teamId as string - const memberId = req.params.memberId as string + ({ params }) => { + const teamId = params.teamId + const memberId = params.memberId let response: SynapseApiResponse let status: number @@ -56,45 +60,46 @@ export function getTeamMembershipStatusHandler(backendOrigin: string) { response = membershipStatus status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ) } export function getUpdateTeamMembershipStatusHandler(backendOrigin: string) { - return rest.put( - `${backendOrigin}/repo/v1/team/:teamId/member/:memberId`, - async (req, res, ctx) => { - const teamId = req.params.teamId as string - const memberId = req.params.memberId as string - let response: SynapseApiResponse | '' - let status: number + return http.put< + { teamId: string; memberId: string }, + never, + SynapseApiResponse<''> + >(`${backendOrigin}/repo/v1/team/:teamId/member/:memberId`, ({ params }) => { + const teamId = params.teamId + const memberId = params.memberId + let response: SynapseApiResponse<''> + let status: number - const team = getMockTeamById(teamId) - if (!team) { - response = { - reason: `getTeamMembershipStatusHandler could not locate a team with ID ${teamId}`, - } - status = 404 - } else { - const membershipStatus: TeamMembershipStatus = { - teamId: teamId, - userId: memberId, - isMember: true, - hasOpenInvitation: false, // TODO - hasOpenRequest: false, // TODO - canJoin: true, // TODO - membershipApprovalRequired: false, // TODO - hasUnmetAccessRequirement: false, // TODO - canSendEmail: false, // TODO - } - addTeamMembershipStatus(membershipStatus) - response = '' - status = 201 + const team = getMockTeamById(teamId) + if (!team) { + response = { + reason: `getTeamMembershipStatusHandler could not locate a team with ID ${teamId}`, } - return res(ctx.status(status), ctx.json(response)) - }, - ) + status = 404 + } else { + const membershipStatus: TeamMembershipStatus = { + teamId: teamId, + userId: memberId, + isMember: true, + hasOpenInvitation: false, // TODO + hasOpenRequest: false, // TODO + canJoin: true, // TODO + membershipApprovalRequired: false, // TODO + hasUnmetAccessRequirement: false, // TODO + canSendEmail: false, // TODO + } + addTeamMembershipStatus(membershipStatus) + response = '' + status = 201 + } + return HttpResponse.json(response, { status }) + }) } export default function getAllTeamHandlers(backendOrigin: string) { diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/trashCanHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/trashCanHandlers.ts new file mode 100644 index 0000000000..98f8fdd5d0 --- /dev/null +++ b/packages/synapse-react-client/src/mocks/msw/handlers/trashCanHandlers.ts @@ -0,0 +1,55 @@ +import { http, HttpResponse } from 'msw' +import { + TRASHCAN_PURGE, + TRASHCAN_RESTORE, + TRASHCAN_VIEW, +} from '../../../utils/APIConstants' +import { trashCanPages } from '../../mockTrashCan' +import mockFileEntityData from '../../entity/mockFileEntity' +import { SynapseApiResponse } from '../handlers' +import { + PaginatedResults, + TrashedEntity, +} from '@sage-bionetworks/synapse-types' + +export function getTrashCanRestoreErrorHandler(backendOrigin: string) { + return http.put<{ entityId: string }, never, SynapseApiResponse<''>>( + `${backendOrigin}${TRASHCAN_RESTORE(':entityId')}`, + ({ params }) => { + if (params.entityId === mockFileEntityData.id) { + return HttpResponse.json( + { reason: 'Some error returned by the server' }, + { status: 400 }, + ) + } else { + return HttpResponse.text('', { status: 200 }) + } + }, + ) +} + +export default function getTrashCanHandlers(backendOrigin: string) { + return [ + http.get>>( + `${backendOrigin}${TRASHCAN_VIEW}`, + ({ request }) => { + const url = new URL(request.url) + const offset = url.searchParams.get('offset') ?? '0' + const result = trashCanPages[parseInt(offset)] + return HttpResponse.json(result, { status: 200 }) + }, + ), + http.put<{ entityId: string }, never, SynapseApiResponse<''>>( + `${backendOrigin}${TRASHCAN_RESTORE(':entityId')}`, + () => { + return HttpResponse.text('', { status: 200 }) + }, + ), + http.put<{ entityId: string }, never, SynapseApiResponse<''>>( + `${backendOrigin}${TRASHCAN_PURGE(':entityId')}`, + () => { + return HttpResponse.text('', { status: 200 }) + }, + ), + ] +} diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/userProfileHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/userProfileHandlers.ts index 7963a3e9da..feb98a9296 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/userProfileHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/userProfileHandlers.ts @@ -1,4 +1,4 @@ -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { FAVORITES, NOTIFICATION_EMAIL, @@ -10,11 +10,11 @@ import { USER_PROFILE, USER_PROFILE_ID, } from '../../../utils/APIConstants' +import { BackendDestinationEnum, getEndpoint } from '../../../utils/functions' import { - BackendDestinationEnum, - getEndpoint, -} from '../../../utils/functions/getEndpoint' -import { + EntityHeader, + NotificationEmail, + PaginatedResults, TwoFactorAuthStatus, TYPE_FILTER, UserBundle, @@ -28,175 +28,194 @@ import { mockUserProfileData, } from '../../user/mock_user_profile' import { SynapseApiResponse } from '../handlers' -import { UserProfileList } from '../../../synapse-client/SynapseClient' +import { UserProfileList } from '../../../synapse-client' import { mockUserGroupData } from '../../usergroup/mockUserGroup' export const getUserProfileHandlers = (backendOrigin: string) => [ /** * Get User Profile by ID */ - rest.get( + http.get<{ id: string }, never, SynapseApiResponse>( `${backendOrigin}${USER_PROFILE_ID(':id')}`, - async (req, res, ctx) => { + ({ params }) => { let status = 404 let response: SynapseApiResponse = { - reason: `Mock Service worker could not find a user profile with ID ${req.params.id}`, + reason: `Mock Service worker could not find a user profile with ID ${params.id}`, } const match = mockUserData.find( - userData => userData.id.toString() === req.params.id, + userData => userData.id.toString() === params.id, ) if (match && match.userProfile) { response = match.userProfile status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), /** * Get the caller's user profile */ - rest.get(`${backendOrigin}${USER_PROFILE}`, async (req, res, ctx) => { - // default return a mock UserProfile. - const response: UserProfile = mockUserProfileData - const status = 200 - return res(ctx.status(status), ctx.json(response)) - }), + http.get>( + `${backendOrigin}${USER_PROFILE}`, + () => { + // default return a mock UserProfile. + const response: UserProfile = mockUserProfileData + const status = 200 + return HttpResponse.json(response, { status }) + }, + ), /** * Get the caller's user bundle */ - rest.get( + http.get>( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${USER_BUNDLE}`, - async (req, res, ctx) => { - const result: UserBundle = mockUserBundle - return res(ctx.status(200), ctx.json(result)) + () => { + return HttpResponse.json(mockUserBundle, { status: 200 }) }, ), /** * Get a user bundle by ID */ - rest.get( + http.get<{ id: string }, never, SynapseApiResponse>( `${backendOrigin}${USER_ID_BUNDLE(':id')}`, - async (req, res, ctx) => { + ({ params }) => { let status = 404 let response: SynapseApiResponse = { - reason: `Mock Service worker could not find a user bundle with ID ${req.params.id}`, + reason: `Mock Service worker could not find a user bundle with ID ${params.id}`, } const match = mockUserData.find( - userData => userData.id.toString() === req.params.id, + userData => userData.id.toString() === params.id, ) if (match && match.userBundle) { response = match.userBundle status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), /** * Get the caller's favorites */ - rest.get(`${backendOrigin}${FAVORITES}`, async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockPaginatedEntityHeaders)) - }), + http.get>>( + `${backendOrigin}${FAVORITES}`, + () => { + return HttpResponse.json(mockPaginatedEntityHeaders, { status: 200 }) + }, + ), /** * Get a batch of user group headers */ - rest.get( + http.get>( `${backendOrigin}${USER_GROUP_HEADERS_BATCH}`, - async (req, res, ctx) => { - const ids = req.url.searchParams.get('ids')!.split(',') + ({ request }) => { + const url = new URL(request.url) + const ids = url.searchParams.get('ids')!.split(',') const responsePage: UserGroupHeaderResponsePage = { children: mockUserGroupData .filter(userData => ids.includes(userData.id.toString())) .map(userData => userData.userGroupHeader), } - return res(ctx.status(200), ctx.json(responsePage)) + return HttpResponse.json(responsePage, { status: 200 }) }, ), /** * Get a batch of user profiles */ - rest.post(`${backendOrigin}${USER_PROFILE}`, async (req, res, ctx) => { - const requestedList = (await req.json()).list as string[] - const responsePage: UserProfileList = { - list: mockUserData - .filter(userData => requestedList.includes(userData.id.toString())) - .map(userData => userData.userProfile) - .filter( - (userProfile): userProfile is UserProfile => userProfile != null, - ), - } - return res(ctx.status(200), ctx.json(responsePage)) - }), + http.post>( + `${backendOrigin}${USER_PROFILE}`, + async ({ request }) => { + const requestedList = (await request.json()).list + const responsePage: UserProfileList = { + list: mockUserData + .filter(userData => requestedList.includes(userData.id.toString())) + .map(userData => userData.userProfile) + .filter( + (userProfile): userProfile is UserProfile => userProfile != null, + ), + } + return HttpResponse.json(responsePage, { status: 200 }) + }, + ), /** * Get userGroupHeaders by prefix */ - rest.get(`${backendOrigin}${USER_GROUP_HEADERS}`, async (req, res, ctx) => { - const prefix = (req.url.searchParams.get('prefix') ?? '').toLowerCase() - const typeFilter = req.url.searchParams.get('typeFilter') as TYPE_FILTER - const responsePage: UserGroupHeaderResponsePage = { - children: mockUserGroupData - .filter(userData => { - if (!typeFilter || typeFilter === TYPE_FILTER.ALL) { - return true - } else if (typeFilter === TYPE_FILTER.USERS_ONLY) { - return userData.userGroupHeader.isIndividual - } else { - return !userData.userGroupHeader.isIndividual - } - }) - .filter( - userData => - userData.userGroupHeader.userName - .toLowerCase() - .startsWith(prefix) || - (userData.userGroupHeader.firstName || '') - .toLowerCase() - .startsWith(prefix) || - (userData.userGroupHeader.displayName || '') - .toLowerCase() - .startsWith(prefix) || - (userData.userGroupHeader.lastName || '') - .toLowerCase() - .startsWith(prefix), - ) - .map(userData => userData.userGroupHeader), - } - return res(ctx.status(200), ctx.json(responsePage)) - }), + http.get>( + `${backendOrigin}${USER_GROUP_HEADERS}`, + ({ request }) => { + const url = new URL(request.url) + const prefix = (url.searchParams.get('prefix') ?? '').toLowerCase() + const typeFilter = url.searchParams.get('typeFilter') as TYPE_FILTER + const responsePage: UserGroupHeaderResponsePage = { + children: mockUserGroupData + .filter(userData => { + if (!typeFilter || typeFilter === TYPE_FILTER.ALL) { + return true + } else if (typeFilter === TYPE_FILTER.USERS_ONLY) { + return userData.userGroupHeader.isIndividual + } else { + return !userData.userGroupHeader.isIndividual + } + }) + .filter( + userData => + userData.userGroupHeader.userName + .toLowerCase() + .startsWith(prefix) || + (userData.userGroupHeader.firstName || '') + .toLowerCase() + .startsWith(prefix) || + (userData.userGroupHeader.displayName || '') + .toLowerCase() + .startsWith(prefix) || + (userData.userGroupHeader.lastName || '') + .toLowerCase() + .startsWith(prefix), + ) + .map(userData => userData.userGroupHeader), + } + return HttpResponse.json(responsePage, { status: 200 }) + }, + ), /** * Return a 404 when fetching the profile image */ - rest.get( + http.get<{ userId: string }, never, SynapseApiResponse>( `${backendOrigin}${PROFILE_IMAGE_PREVIEW(':userId')}`, - async (req, res, ctx) => { - return res( - ctx.status(404), - ctx.json({ reason: 'user has no profile image' }), + () => { + return HttpResponse.json( + { reason: 'user has no profile image' }, + { status: 404 }, ) }, ), - rest.get(`${backendOrigin}${NOTIFICATION_EMAIL}`, async (req, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ email: mockUserBundle.userProfile?.email }), - ) - }), + http.get>( + `${backendOrigin}${NOTIFICATION_EMAIL}`, + () => { + return HttpResponse.json( + { email: mockUserBundle.userProfile!.email! }, + { status: 200 }, + ) + }, + ), - rest.get(`${backendOrigin}/auth/v1/2fa`, async (req, res, ctx) => { - const response: TwoFactorAuthStatus = { - status: 'ENABLED', - } - return res(ctx.status(200), ctx.json(response)) - }), + http.get>( + `${backendOrigin}/auth/v1/2fa`, + () => { + const response: TwoFactorAuthStatus = { + status: 'ENABLED', + } + return HttpResponse.json(response, { status: 200 }) + }, + ), ] export function getCurrentUserCertifiedValidatedHandler( @@ -204,13 +223,16 @@ export function getCurrentUserCertifiedValidatedHandler( isCertified: boolean, isValidated: boolean, ) { - return rest.get(`${backendOrigin}${USER_BUNDLE}`, async (req, res, ctx) => { - const status = 200 - const response: UserBundle = { - ...mockUserBundle, - isCertified: isCertified, - isVerified: isValidated, - } - return res(ctx.status(status), ctx.json(response)) - }) + return http.get>( + `${backendOrigin}${USER_BUNDLE}`, + () => { + const status = 200 + const response: UserBundle = { + ...mockUserBundle, + isCertified: isCertified, + isVerified: isValidated, + } + return HttpResponse.json(response, { status: status }) + }, + ) } diff --git a/packages/synapse-react-client/src/mocks/msw/handlers/wikiHandlers.ts b/packages/synapse-react-client/src/mocks/msw/handlers/wikiHandlers.ts index a22ace0729..53129a317f 100644 --- a/packages/synapse-react-client/src/mocks/msw/handlers/wikiHandlers.ts +++ b/packages/synapse-react-client/src/mocks/msw/handlers/wikiHandlers.ts @@ -1,34 +1,42 @@ -import { rest } from 'msw' +import { http, HttpResponse } from 'msw' import { ACCESS_REQUIREMENT_WIKI_PAGE } from '../../../utils/APIConstants' import { FileHandleResults, WikiPage } from '@sage-bionetworks/synapse-types' import { SynapseApiResponse } from '../handlers' import { mockWikiPages } from '../../mockWiki' export const getWikiHandlers = (backendOrigin: string) => [ - rest.get( + http.get< + { arId: string; wikiId: string }, + never, + SynapseApiResponse + >( `${backendOrigin}${ACCESS_REQUIREMENT_WIKI_PAGE(':arId', ':wikiId')}`, - async (req, res, ctx) => { + ({ params }) => { let status = 404 let response: SynapseApiResponse = { - reason: `Mock Service worker could not find a wiki page with ID ${req.params.wikiId}`, + reason: `Mock Service worker could not find a wiki page with ID ${params.wikiId}`, } - const wikiPage = mockWikiPages.find(wp => wp.id === req.params.wikiId) + const wikiPage = mockWikiPages.find(wp => wp.id === params.wikiId) if (wikiPage) { response = wikiPage status = 200 } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), - rest.get( + http.get< + { objectType: string; objectId: string; wikiId: string }, + never, + SynapseApiResponse + >( `${backendOrigin}/repo/v1/:objectType/:objectId/wiki2/:wikiId/attachmenthandles`, - async (req, res, ctx) => { - let status = 200 - let response: SynapseApiResponse = { + () => { + const status = 200 + const response: SynapseApiResponse = { list: [], } - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), ] diff --git a/packages/synapse-react-client/src/mocks/msw/server.ts b/packages/synapse-react-client/src/mocks/msw/server.ts index c2688a2486..7398946752 100644 --- a/packages/synapse-react-client/src/mocks/msw/server.ts +++ b/packages/synapse-react-client/src/mocks/msw/server.ts @@ -1,7 +1,7 @@ -import { rest } from 'msw' +import { http } from 'msw' import { setupServer } from 'msw/node' import { handlers } from './handlers' const server = setupServer(...handlers) -export { server, rest } +export { server, http } diff --git a/packages/synapse-react-client/src/synapse-client/SynapseClient.integration.test.ts b/packages/synapse-react-client/src/synapse-client/SynapseClient.integration.test.ts index 839eaf91ab..3cdc094672 100644 --- a/packages/synapse-react-client/src/synapse-client/SynapseClient.integration.test.ts +++ b/packages/synapse-react-client/src/synapse-client/SynapseClient.integration.test.ts @@ -1,11 +1,9 @@ import SynapseClient from './index' import { ASYNCHRONOUS_JOB_TOKEN } from '../utils/APIConstants' -import { - BackendDestinationEnum, - getEndpoint, -} from '../utils/functions/getEndpoint' +import { BackendDestinationEnum, getEndpoint } from '../utils/functions' import { AsynchronousJobStatus } from '@sage-bionetworks/synapse-types' -import { rest, server } from '../mocks/msw/server' +import { server } from '../mocks/msw/server' +import { http, HttpResponse } from 'msw' describe('SynapseClient integration tests', () => { beforeAll(() => server.listen()) @@ -42,16 +40,16 @@ describe('SynapseClient integration tests', () => { it('Returns a complete response', async () => { // The first call returns a successful response. server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ASYNCHRONOUS_JOB_TOKEN(':jobId')}`, - (req, res, ctx) => { - requestCaptor(req) + ({ request }) => { + requestCaptor(request) const status = 200 const response = completeJob - return res(ctx.status(status), ctx.json(response)) + return HttpResponse.json(response, { status }) }, ), ) @@ -80,21 +78,21 @@ describe('SynapseClient integration tests', () => { it('Re-fetches a processing response until complete', async () => { // The first two calls return "PROCESSING" response, and the third call will return a "COMPLETE" response. server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ASYNCHRONOUS_JOB_TOKEN(':jobId')}`, // Use a generator to simulate returning a processing result twice followed by a complete result - function* (req, res, ctx) { + function* ({ request }) { const status = 200 let count = 0 while (count < 2) { count++ - requestCaptor(req) - yield res(ctx.status(status), ctx.json(processingJob)) + requestCaptor(request) + yield HttpResponse.json(processingJob, { status }) } - requestCaptor(req) - yield res(ctx.status(status), ctx.json(completeJob)) + requestCaptor(request) + yield HttpResponse.json(completeJob, { status }) }, ), ) @@ -128,22 +126,21 @@ describe('SynapseClient integration tests', () => { const errorObject = { reason: 'bad request' } server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ASYNCHRONOUS_JOB_TOKEN(':jobId')}`, - function (req, res, ctx) { + function () { const status = 200 - return res(ctx.status(status), ctx.json(failedJob)) + return HttpResponse.json(failedJob, { status: status }) }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${responseBodyServerEndpoint}`, - function (req, res, ctx) { - const status = errorStatus - return res(ctx.status(status), ctx.json(errorObject)) + function () { + return HttpResponse.json(errorObject, { status: errorStatus }) }, ), ) diff --git a/packages/synapse-react-client/src/utils/hooks/usePreFetchResource.integration.test.tsx b/packages/synapse-react-client/src/utils/hooks/usePreFetchResource.integration.test.tsx index 63917dcf8d..dc5bc68fe9 100644 --- a/packages/synapse-react-client/src/utils/hooks/usePreFetchResource.integration.test.tsx +++ b/packages/synapse-react-client/src/utils/hooks/usePreFetchResource.integration.test.tsx @@ -1,7 +1,8 @@ import { cleanup, renderHook, waitFor } from '@testing-library/react' import usePreFetchResource from './usePreFetchResource' -import { rest, server } from '../../mocks/msw/server' +import { server } from '../../mocks/msw/server' import { createWrapper } from '../../testutils/TestingLibraryUtils' +import { http, HttpResponse } from 'msw' const onReceivedRequest = jest.fn() @@ -25,16 +26,17 @@ describe('usePreFetchResource tests', () => { it('Returns a local URL when passed a presigned URL', async () => { server.use( - rest.get( + http.get( PRESIGNED_URL, - async (req, res, ctx) => { + () => { onReceivedRequest() - return res( - ctx.status(200), - ctx.set('Content-Type', 'image/jpeg'), - ctx.body('abcdef'), - ) + return new HttpResponse('abcdef', { + status: 200, + headers: { + 'Content-Type': 'image/jpeg', + }, + }) }, ), ) diff --git a/packages/synapse-react-client/test/containers/EntityBadgeIcons.integration.test.tsx b/packages/synapse-react-client/test/containers/EntityBadgeIcons.integration.test.tsx index 5a536d99ca..96b569dd60 100644 --- a/packages/synapse-react-client/test/containers/EntityBadgeIcons.integration.test.tsx +++ b/packages/synapse-react-client/test/containers/EntityBadgeIcons.integration.test.tsx @@ -213,12 +213,12 @@ describe('EntityBadgeIcons tests', () => { getEndpoint(BackendDestinationEnum.REPO_ENDPOINT), bundle, ), - rest.delete( + http.delete( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_ID( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res(ctx.status(200)) }, ), @@ -251,12 +251,12 @@ describe('EntityBadgeIcons tests', () => { getEndpoint(BackendDestinationEnum.REPO_ENDPOINT), bundle, ), - rest.delete( + http.delete( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_ID( ':entityId', )}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res(ctx.status(403)) }, ), @@ -280,22 +280,24 @@ describe('EntityBadgeIcons tests', () => { describe('displays schema validity', () => { it('Displays that the annotations are valid w.r.t the schema', async () => { server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_SCHEMA_BINDING(':entityId')}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockSchemaBinding)) + async ({ request, params }) => { + return HttpResponse.json(mockSchemaBinding, { status: 200 }) }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_SCHEMA_VALIDATION(':entityId')}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockSchemaValidationResults)) + async ({ request, params }) => { + return HttpResponse.json(mockSchemaValidationResults, { + status: 200, + }) }, ), ) @@ -313,22 +315,22 @@ describe('EntityBadgeIcons tests', () => { it('Displays that the annotations are invalid w.r.t the schema', async () => { server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_SCHEMA_BINDING(':entityId')}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockSchemaBinding)) + async ({ request, params }) => { + return HttpResponse.json(mockSchemaBinding, { status: 200 }) }, ), - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_SCHEMA_VALIDATION(':entityId')}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.json({ @@ -360,13 +362,13 @@ describe('EntityBadgeIcons tests', () => { }, } server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_SCHEMA_BINDING(':entityId')}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(mockSchemaBinding)) + async ({ request, params }) => { + return HttpResponse.json(mockSchemaBinding, { status: 200 }) }, ), @@ -375,12 +377,12 @@ describe('EntityBadgeIcons tests', () => { bundle, ), // The entity's annotations are invalid - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_SCHEMA_VALIDATION(':entityId')}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(200), ctx.json({ @@ -407,12 +409,12 @@ describe('EntityBadgeIcons tests', () => { const onSchemaValidationFetched = jest.fn() server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_SCHEMA_BINDING(':entityId')}`, - async (req, res, ctx) => { + async ({ request, params }) => { return res( ctx.status(404), ctx.json({ reason: 'No JSON Schema found' }), @@ -422,12 +424,12 @@ describe('EntityBadgeIcons tests', () => { // This service should never be called. // To verify, see if we invoke a mock function that is called in the mocked service - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_SCHEMA_VALIDATION(':entityId')}`, - async (req, res, ctx) => { + async ({ request, params }) => { onSchemaValidationFetched() return res( ctx.status(200), diff --git a/packages/synapse-react-client/test/containers/entity_finder/details/DetailsView.integration.test.tsx b/packages/synapse-react-client/test/containers/entity_finder/details/DetailsView.integration.test.tsx index 328be0f5c5..fb61280b45 100644 --- a/packages/synapse-react-client/test/containers/entity_finder/details/DetailsView.integration.test.tsx +++ b/packages/synapse-react-client/test/containers/entity_finder/details/DetailsView.integration.test.tsx @@ -145,12 +145,12 @@ describe('DetailsView tests', () => { jest.clearAllMocks() server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}${ENTITY_ID_VERSIONS(entityHeaders[0].id)}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(versionResult)) + async ({ request, params }) => { + return HttpResponse.json(versionResult, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/test/containers/entity_finder/tree/EntityTree.integration.test.tsx b/packages/synapse-react-client/test/containers/entity_finder/tree/EntityTree.integration.test.tsx index 7aff53caf3..8f8b529694 100644 --- a/packages/synapse-react-client/test/containers/entity_finder/tree/EntityTree.integration.test.tsx +++ b/packages/synapse-react-client/test/containers/entity_finder/tree/EntityTree.integration.test.tsx @@ -201,25 +201,25 @@ describe('EntityTree tests', () => { beforeAll(() => { server.listen() server.use( - rest.get( + http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${FAVORITES}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(favorites)) + async ({ request, params }) => { + return HttpResponse.json(favorites, { status: 200 }) }, ), - rest.get( + http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_PATH( ':id', )}`, - async (req, res, ctx) => { - return res(ctx.status(200), ctx.json(entityPath)) + async ({ request, params }) => { + return HttpResponse.json(entityPath, { status: 200 }) }, ), - rest.post( + http.post( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${ENTITY_HEADERS}`, - async (req, res, ctx) => { - const { references } = await req.json() + async ({ request, params }) => { + const { references } = await request.json() if (references[0].targetId === projectIdWithNoReadAccess) { return res( ctx.status(200), @@ -238,19 +238,19 @@ describe('EntityTree tests', () => { ) }, ), - rest.get( + http.get( `${getEndpoint(BackendDestinationEnum.REPO_ENDPOINT)}${PROJECTS}`, - async (req, res, ctx) => { + async ({ request, params }) => { let response: ProjectHeaderList = { results: projectsPage1, nextPageToken: '50a0', } - if (req.params.nextPageToken === '50a0') { + if (params.nextPageToken === '50a0') { response.results = projectsPage2 response.nextPageToken = null } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), ) diff --git a/packages/synapse-react-client/test/containers/markdown/MarkdownSynapse.integration.test.tsx b/packages/synapse-react-client/test/containers/markdown/MarkdownSynapse.integration.test.tsx index 5b2526f4e9..de11f2ab06 100644 --- a/packages/synapse-react-client/test/containers/markdown/MarkdownSynapse.integration.test.tsx +++ b/packages/synapse-react-client/test/containers/markdown/MarkdownSynapse.integration.test.tsx @@ -59,15 +59,15 @@ const renderComponent = ( function mockGetEntityWiki(markdown: string) { server.use( - rest.get( + http.get( `${getEndpoint( BackendDestinationEnum.REPO_ENDPOINT, )}/repo/v1/entity/:id/wiki/:wikiId`, - async (req, res, ctx) => { + async ({ request, params }) => { const response: WikiPage = { markdown, } - return res(ctx.status(200), ctx.json(response)) + return HttpResponse.json(response, { status: 200 }) }, ), ) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 57dc279e3c..6a66cc5370 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -682,8 +682,8 @@ importers: specifier: ^3.5.3 version: 3.5.3 msw: - specifier: ^1.2.2 - version: 1.2.2(typescript@5.1.6) + specifier: ^2.2.2 + version: 2.2.2(typescript@5.1.6) object-assign: specifier: ^4.1.1 version: 4.1.1 @@ -1310,11 +1310,11 @@ importers: specifier: ^3.5.3 version: 3.5.3 msw: - specifier: ^1.2.2 - version: 1.2.2(typescript@5.1.6) + specifier: ^2.2.2 + version: 2.2.2(typescript@5.1.6) msw-storybook-addon: specifier: ^1.10.0 - version: 1.10.0(msw@1.2.2) + version: 1.10.0(msw@2.2.2) path-browserify: specifier: ^1.0.1 version: 1.0.1 @@ -1363,6 +1363,9 @@ importers: typescript: specifier: 5.1.6 version: 5.1.6 + undici: + specifier: ^6.6.2 + version: 6.6.2 util: specifier: ^0.12.5 version: 0.12.5 @@ -4018,6 +4021,18 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@bundled-es-modules/cookie@2.0.0: + resolution: {integrity: sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==} + dependencies: + cookie: 0.5.0 + dev: true + + /@bundled-es-modules/statuses@1.0.1: + resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} + dependencies: + statuses: 2.0.1 + dev: true + /@choojs/findup@0.2.1: resolution: {integrity: sha512-YstAqNb0MCN8PjdLCDfRsBcGVRN41f3vgLvaI0IrIcBp4AqILRSS0DeWNGkicC+f/zRIPJLc+9RURVSepwvfBw==} hasBin: true @@ -4588,6 +4603,11 @@ packages: resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} dev: true + /@fastify/busboy@2.1.1: + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + dev: true + /@figspec/components@1.0.3: resolution: {integrity: sha512-fBwHzJ4ouuOUJEi+yBZIrOy+0/fAjB3AeTcIHTT1PRxLz8P63xwC7R0EsIJXhScIcc+PljGmqbbVJCjLsnaGYA==} dependencies: @@ -4692,6 +4712,39 @@ packages: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true + /@inquirer/confirm@3.0.0: + resolution: {integrity: sha512-LHeuYP1D8NmQra1eR4UqvZMXwxEdDXyElJmmZfU44xdNLL6+GcQBS0uE16vyfZVjH8c22p9e+DStROfE/hyHrg==} + engines: {node: '>=18'} + dependencies: + '@inquirer/core': 7.0.0 + '@inquirer/type': 1.2.0 + dev: true + + /@inquirer/core@7.0.0: + resolution: {integrity: sha512-g13W5yEt9r1sEVVriffJqQ8GWy94OnfxLCreNSOTw0HPVcszmc/If1KIf7YBmlwtX4klmvwpZHnQpl3N7VX2xA==} + engines: {node: '>=18'} + dependencies: + '@inquirer/type': 1.2.0 + '@types/mute-stream': 0.0.4 + '@types/node': 20.11.23 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-spinners: 2.9.2 + cli-width: 4.1.0 + figures: 3.2.0 + mute-stream: 1.0.0 + run-async: 3.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + + /@inquirer/type@1.2.0: + resolution: {integrity: sha512-/vvkUkYhrjbm+RolU7V1aUFDydZVKNKqKHR5TsE+j5DXgXFwrsOPcoGUJ02K0O7q7O53CU2DOTMYCHeGZ25WHA==} + engines: {node: '>=18'} + dev: true + /@isaacs/cliui@8.0.2: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -5223,28 +5276,21 @@ packages: react: 18.2.0 dev: true - /@mswjs/cookies@0.2.2: - resolution: {integrity: sha512-mlN83YSrcFgk7Dm1Mys40DLssI1KdJji2CMKN8eOlBqsTADYzj2+jWzsANsUTFbxDMWPD5e9bfA1RGqBpS3O1g==} - engines: {node: '>=14'} - dependencies: - '@types/set-cookie-parser': 2.4.2 - set-cookie-parser: 2.6.0 + /@mswjs/cookies@1.1.0: + resolution: {integrity: sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw==} + engines: {node: '>=18'} dev: true - /@mswjs/interceptors@0.17.9: - resolution: {integrity: sha512-4LVGt03RobMH/7ZrbHqRxQrS9cc2uh+iNKSj8UWr8M26A2i793ju+csaB5zaqYltqJmA2jUq4VeYfKmVqvsXQg==} - engines: {node: '>=14'} + /@mswjs/interceptors@0.25.16: + resolution: {integrity: sha512-8QC8JyKztvoGAdPgyZy49c9vSHHAZjHagwl4RY9E8carULk8ym3iTaiawrT1YoLF/qb449h48f71XDPgkUSOUg==} + engines: {node: '>=18'} dependencies: - '@open-draft/until': 1.0.3 - '@types/debug': 4.1.8 - '@xmldom/xmldom': 0.8.8 - debug: 4.3.4 - headers-polyfill: 3.1.2 - outvariant: 1.4.0 - strict-event-emitter: 0.2.8 - web-encoding: 1.1.5 - transitivePeerDependencies: - - supports-color + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.2 + strict-event-emitter: 0.5.1 dev: true /@mui/base@5.0.0-beta.36(@types/react@18.0.27)(react-dom@18.2.0)(react@18.2.0): @@ -5646,8 +5692,19 @@ packages: resolution: {integrity: sha512-Rzd5JrXZX8zErHzgcGyngh4fmEbSHqTETdGj9rXtejlqMIgXFlyKBA7Jn1Xp0Ls0M0Y22+xHcWiEzbmdWl0BOA==} dev: true - /@open-draft/until@1.0.3: - resolution: {integrity: sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==} + /@open-draft/deferred-promise@2.2.0: + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + dev: true + + /@open-draft/logger@0.3.0: + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.2 + dev: true + + /@open-draft/until@2.1.0: + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} dev: true /@pkgjs/parseargs@0.11.0: @@ -8183,8 +8240,8 @@ packages: resolution: {integrity: sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==} dev: false - /@types/cookie@0.4.1: - resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} + /@types/cookie@0.6.0: + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} dev: true /@types/cross-spawn@6.0.2: @@ -8376,12 +8433,6 @@ packages: resolution: {integrity: sha512-rF3yXSwHIrDxEkN6edCE4TXknb5YSEpiXfLaspw1I08grC49ZFuAVGOQCmZGIuLUGoFgcqGlUFBL/XrpgYpQgw==} dev: true - /@types/debug@4.1.8: - resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==} - dependencies: - '@types/ms': 0.7.31 - dev: true - /@types/detect-port@1.3.3: resolution: {integrity: sha512-bV/jQlAJ/nPY3XqSatkGpu+nGzou+uSwrH1cROhn+jBFg47yaNH+blW4C7p9KhopC7QxCv/6M86s37k8dMk0Yg==} dev: true @@ -8536,10 +8587,6 @@ packages: '@types/sizzle': 2.3.3 dev: true - /@types/js-levenshtein@1.1.1: - resolution: {integrity: sha512-qC4bCqYGy1y/NP7dDVr7KJarn+PbX1nSpwA7JXdu0HxT3QYjO8MJ+cntENtHFVy2dRAyBV23OZ6MxsW1AM1L8g==} - dev: true - /@types/jsdom@20.0.1: resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} dependencies: @@ -8611,8 +8658,10 @@ packages: resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} dev: true - /@types/ms@0.7.31: - resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + /@types/mute-stream@0.0.4: + resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + dependencies: + '@types/node': 18.16.19 dev: true /@types/node-fetch@2.6.4: @@ -8625,6 +8674,12 @@ packages: /@types/node@18.16.19: resolution: {integrity: sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==} + /@types/node@20.11.23: + resolution: {integrity: sha512-ZUarKKfQuRILSNYt32FuPL20HS7XwNT7/uRwSV8tiHWfyyVwDLYZNF6DZKc2bove++pgfsXn9sUwII/OsQ82cQ==} + dependencies: + undici-types: 5.26.5 + dev: true + /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true @@ -8809,12 +8864,6 @@ packages: '@types/node': 18.16.19 dev: true - /@types/set-cookie-parser@2.4.2: - resolution: {integrity: sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==} - dependencies: - '@types/node': 18.16.19 - dev: true - /@types/shortid@0.0.29: resolution: {integrity: sha512-9BCYD9btg2CY4kPcpMQ+vCR8U6V8f/KvixYD5ZbxoWlkhddNF5IeZMVL3p+QFUkg+Hb+kPAG9Jgk4bnnF1v/Fw==} dev: true @@ -8831,6 +8880,10 @@ packages: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: true + /@types/statuses@2.0.4: + resolution: {integrity: sha512-eqNDvZsCNY49OAXB0Firg/Sc2BgoWsntsLUdybGFOhAfCD6QJ2n9HXUIHGqt5qjrxmMv4wS8WLAw43ZkKcJ8Pw==} + dev: true + /@types/tinycolor2@1.4.3: resolution: {integrity: sha512-Kf1w9NE5HEgGxCRyIcRXR/ZYtDv0V8FVPtYHwLxl0O+maGX0erE77pQlD0gpP+/KByMZ87mOA79SjifhSB3PjQ==} dev: true @@ -8859,6 +8912,10 @@ packages: resolution: {integrity: sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==} dev: false + /@types/wrap-ansi@3.0.0: + resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} + dev: true + /@types/xml2js@0.4.11: resolution: {integrity: sha512-JdigeAKmCyoJUiQljjr7tQG3if9NkqGUgwEUqBvV0N7LM4HyQk7UXCnusRa1lnvXAEYJ8mw8GtZWioagNztOwA==} dependencies: @@ -9240,11 +9297,6 @@ packages: react: 18.2.0 dev: true - /@xmldom/xmldom@0.8.8: - resolution: {integrity: sha512-0LNz4EY8B/8xXY86wMrQ4tz6zEHZv9ehFMJPm8u2gq5lQ71cfRKdaKyxfJAx5aUoyzx0qzgURblTisPGgz3d+Q==} - engines: {node: '>=10.0.0'} - dev: true - /@xtuc/ieee754@1.2.0: resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} dev: true @@ -9298,12 +9350,6 @@ packages: argparse: 2.0.1 dev: true - /@zxing/text-encoding@0.9.0: - resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==} - requiresBuild: true - dev: true - optional: true - /abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} deprecated: Use your platform's native atob() and btoa() methods instead @@ -10270,14 +10316,6 @@ packages: supports-color: 7.2.0 dev: true - /chalk@4.1.1: - resolution: {integrity: sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -10296,10 +10334,6 @@ packages: engines: {node: '>=10'} dev: true - /chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - dev: true - /check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} dependencies: @@ -10387,6 +10421,11 @@ packages: engines: {node: '>=6'} dev: true + /cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + dev: true + /cli-table3@0.6.3: resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} engines: {node: 10.* || >= 12.*} @@ -10412,9 +10451,9 @@ packages: string-width: 5.1.2 dev: true - /cli-width@3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} + /cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} dev: true /cliui@6.0.0: @@ -10675,6 +10714,7 @@ packages: /cookie@0.4.2: resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} engines: {node: '>= 0.6'} + dev: false /cookie@0.5.0: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} @@ -12222,15 +12262,6 @@ packages: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} dev: true - /external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - dev: true - /extract-zip@1.7.0: resolution: {integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==} hasBin: true @@ -12943,8 +12974,8 @@ packages: lodash: 4.17.21 dev: false - /graphql@16.7.1: - resolution: {integrity: sha512-DRYR9tf+UGU0KOsMcKAlXeFfX89UiiIZ0dRU3mR0yJfu6OjZqUcp68NnFLnqQU5RexygFoDy1EW+ccOYcPfmHg==} + /graphql@16.8.1: + resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} dev: true @@ -13063,8 +13094,8 @@ packages: minimalistic-assert: 1.0.1 dev: true - /headers-polyfill@3.1.2: - resolution: {integrity: sha512-tWCK4biJ6hcLqTviLXVR9DTRfYGQMXEIUj3gwJ2rZ5wO/at3XtkI4g8mCvFdUF9l1KMBNCfmNAdnahm1cgavQA==} + /headers-polyfill@4.0.2: + resolution: {integrity: sha512-EWGTfnTqAO2L/j5HZgoM/3z82L7necsJ0pO9Tp0X1wil3PDLrkypTBRgVO2ExehEEvUycejZD3FuRaXpZZc3kw==} dev: true /history@4.10.1: @@ -13242,27 +13273,6 @@ packages: /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - /inquirer@8.2.5: - resolution: {integrity: sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==} - engines: {node: '>=12.0.0'} - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - ora: 5.4.1 - run-async: 2.4.1 - rxjs: 7.8.1 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - wrap-ansi: 7.0.0 - dev: true - /internal-slot@1.0.5: resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} engines: {node: '>= 0.4'} @@ -14272,11 +14282,6 @@ packages: resolution: {integrity: sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==} dev: false - /js-levenshtein@1.1.6: - resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} - engines: {node: '>=0.10.0'} - dev: true - /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -15216,49 +15221,44 @@ packages: /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - /msw-storybook-addon@1.10.0(msw@1.2.2): + /msw-storybook-addon@1.10.0(msw@2.2.2): resolution: {integrity: sha512-soCTMTf7DnLeaMnFHPrtVgbyeFTJALVvnDHpzzXpJad+HOzJgQdwU4EAzVfDs1q+X5cVEgxOdAhSMC7ljvnSXg==} peerDependencies: msw: '>=0.35.0 <2.0.0' dependencies: is-node-process: 1.2.0 - msw: 1.2.2(typescript@5.1.6) + msw: 2.2.2(typescript@5.1.6) dev: true - /msw@1.2.2(typescript@5.1.6): - resolution: {integrity: sha512-GsW3PE/Es/a1tYThXcM8YHOZ1S1MtivcS3He/LQbbTCx3rbWJYCtWD5XXyJ53KlNPT7O1VI9sCW3xMtgFe8XpQ==} - engines: {node: '>=14'} + /msw@2.2.2(typescript@5.1.6): + resolution: {integrity: sha512-Vn3RGCmp14Oy1Lo9yGJMk4+qV/WdK8opNyHt0jdBnvzQ8OEhFvQ2AeM9EXOgQtGLvzUWzqrrwlfwmsCkFViUlg==} + engines: {node: '>=18'} hasBin: true requiresBuild: true peerDependencies: - typescript: '>= 4.4.x <= 5.1.x' + typescript: '>= 4.7.x <= 5.3.x' peerDependenciesMeta: typescript: optional: true dependencies: - '@mswjs/cookies': 0.2.2 - '@mswjs/interceptors': 0.17.9 - '@open-draft/until': 1.0.3 - '@types/cookie': 0.4.1 - '@types/js-levenshtein': 1.1.1 - chalk: 4.1.1 - chokidar: 3.5.3 - cookie: 0.4.2 - graphql: 16.7.1 - headers-polyfill: 3.1.2 - inquirer: 8.2.5 + '@bundled-es-modules/cookie': 2.0.0 + '@bundled-es-modules/statuses': 1.0.1 + '@inquirer/confirm': 3.0.0 + '@mswjs/cookies': 1.1.0 + '@mswjs/interceptors': 0.25.16 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.4 + chalk: 4.1.2 + graphql: 16.8.1 + headers-polyfill: 4.0.2 is-node-process: 1.2.0 - js-levenshtein: 1.1.6 - node-fetch: 2.6.12 - outvariant: 1.4.0 + outvariant: 1.4.2 path-to-regexp: 6.2.1 - strict-event-emitter: 0.4.6 - type-fest: 2.19.0 + strict-event-emitter: 0.5.1 + type-fest: 4.10.3 typescript: 5.1.6 yargs: 17.7.2 - transitivePeerDependencies: - - encoding - - supports-color dev: true /mui-one-time-password-input@1.1.0(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@5.15.10)(@types/react@18.0.27)(react-dom@18.2.0)(react@18.2.0): @@ -15293,8 +15293,9 @@ packages: resolution: {integrity: sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==} dev: false - /mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + /mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dev: true /mz@2.7.0: @@ -15701,13 +15702,8 @@ packages: resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} dev: true - /os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - dev: true - - /outvariant@1.4.0: - resolution: {integrity: sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw==} + /outvariant@1.4.2: + resolution: {integrity: sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==} dev: true /p-limit@2.3.0: @@ -17447,8 +17443,8 @@ packages: xml2js: 0.5.0 dev: false - /run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + /run-async@3.0.0: + resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} engines: {node: '>=0.12.0'} dev: true @@ -17592,10 +17588,6 @@ packages: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: false - /set-cookie-parser@2.6.0: - resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} - dev: true - /setimmediate-napi@1.0.6: resolution: {integrity: sha512-sdNXN15Av1jPXuSal4Mk4tEAKn0+8lfF9Z50/negaQMrAIO9c1qM0eiCh8fT6gctp0RiCObk+6/Xfn5RMGdZoA==} dependencies: @@ -17672,6 +17664,11 @@ packages: engines: {node: '>=14'} dev: true + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + /signum@1.0.0: resolution: {integrity: sha512-yodFGwcyt59XRh7w5W3jPcIQb3Bwi21suEfT7MAWnBX3iCdklJpgDgvGT9o04UonglZN5SNMfJFkHIR/jO8GHw==} dev: false @@ -17923,14 +17920,8 @@ packages: /stream-shift@1.0.1: resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} - /strict-event-emitter@0.2.8: - resolution: {integrity: sha512-KDf/ujU8Zud3YaLtMCcTI4xkZlZVIYxTLr+XIULexP+77EEVWixeXroLUXQXiVtH4XH2W7jr/3PT1v3zBuvc3A==} - dependencies: - events: 3.3.0 - dev: true - - /strict-event-emitter@0.4.6: - resolution: {integrity: sha512-12KWeb+wixJohmnwNFerbyiBrAlq5qJLwIt38etRtKtmmHyDSoGlIqFE9wx+4IwG0aDjI7GV8tc8ZccjWZZtTg==} + /strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} dev: true /string-argv@0.3.2: @@ -18383,13 +18374,6 @@ packages: resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==} engines: {node: '>=14.0.0'} - /tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - dependencies: - os-tmpdir: 1.0.2 - dev: true - /tmp@0.2.1: resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} engines: {node: '>=8.17.0'} @@ -18615,6 +18599,11 @@ packages: engines: {node: '>=14.16'} dev: true + /type-fest@4.10.3: + resolution: {integrity: sha512-JLXyjizi072smKGGcZiAJDCNweT8J+AuRxmPZ1aG7TERg4ijx9REl8CNhbr36RV4qXqL1gO1FF9HL8OkVmmrsA==} + engines: {node: '>=16'} + dev: true + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -18694,6 +18683,17 @@ packages: react-lifecycles-compat: 3.0.4 dev: false + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + + /undici@6.6.2: + resolution: {integrity: sha512-vSqvUE5skSxQJ5sztTZ/CdeJb1Wq0Hf44hlYMciqHghvz+K88U0l7D6u1VsndoFgskDcnU+nG3gYmMzJVzd9Qg==} + engines: {node: '>=18.0'} + dependencies: + '@fastify/busboy': 2.1.1 + dev: true + /unicode-canonical-property-names-ecmascript@2.0.0: resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} engines: {node: '>=4'} @@ -19194,14 +19194,6 @@ packages: setimmediate-napi: 1.0.6 dev: true - /web-encoding@1.1.5: - resolution: {integrity: sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==} - dependencies: - util: 0.12.5 - optionalDependencies: - '@zxing/text-encoding': 0.9.0 - dev: true - /webgl-context@2.2.0: resolution: {integrity: sha512-q/fGIivtqTT7PEoF07axFIlHNk/XCPaYpq64btnepopSWvKNFkoORlQYgqDigBIuGA1ExnFd/GnSUnBNEPQY7Q==} dependencies: