diff --git a/examples/react/package.json b/examples/react/package.json index d9a95ed17..3870d59da 100644 --- a/examples/react/package.json +++ b/examples/react/package.json @@ -25,6 +25,7 @@ "@types/react-dom": "^19.0.4", "@vitejs/plugin-react": "^4.6.0", "@vitest/browser": "^3.2.4", + "msw": "^2.10.4", "playwright": "1.57.0", "typescript": "^5.7.3", "vite": "^7.1.11", diff --git a/examples/react/test/index.test.tsx b/examples/react/test/index.test.tsx index 067645e47..1c69dc57e 100644 --- a/examples/react/test/index.test.tsx +++ b/examples/react/test/index.test.tsx @@ -1,8 +1,18 @@ import { userEvent } from '@vitest/browser/context' -import { describe, expect, test } from 'vitest' +import { setupWorker } from 'msw/browser' +import { afterAll, beforeAll, describe, expect, test } from 'vitest' import { render } from 'vitest-browser-react' +import { tusHandlers } from '../../shared/tusHandlers.js' import App from '../src/App' +const worker = setupWorker(...tusHandlers) +beforeAll(async () => { + await worker.start({ onUnhandledRequest: 'bypass' }) +}) +afterAll(() => { + worker.stop() +}) + const createMockFile = (name: string, type: string, size: number = 1024) => { return new File(['test content'], name, { type }) } diff --git a/examples/shared/tusHandlers.ts b/examples/shared/tusHandlers.ts new file mode 100644 index 000000000..b26696eae --- /dev/null +++ b/examples/shared/tusHandlers.ts @@ -0,0 +1,39 @@ +import { HttpResponse, http } from 'msw' + +/** + * MSW handlers that mock the tus resumable upload protocol. + * + * Handles the tus v1 flow used by the example tests: + * 1. POST /files/ — create upload, return Location header + * 2. PATCH /files/:id — receive chunk, return new Upload-Offset + * + * See https://tus.io/protocols/resumable-upload#protocol + */ +export const TUS_ENDPOINT = 'https://tusd.tusdemo.net/files/' + +export const tusHandlers = [ + http.post(TUS_ENDPOINT, async ({ request }) => { + const uploadLength = request.headers.get('Upload-Length') || '0' + return new HttpResponse(null, { + status: 201, + headers: { + Location: `${TUS_ENDPOINT}mock-upload-id`, + 'Tus-Resumable': '1.0.0', + 'Upload-Offset': '0', + 'Upload-Length': uploadLength, + }, + }) + }), + http.patch(`${TUS_ENDPOINT}:id`, async ({ request }) => { + const uploadOffset = request.headers.get('Upload-Offset') || '0' + const body = await request.arrayBuffer() + const newOffset = Number.parseInt(uploadOffset, 10) + body.byteLength + return new HttpResponse(null, { + status: 204, + headers: { + 'Tus-Resumable': '1.0.0', + 'Upload-Offset': String(newOffset), + }, + }) + }), +] diff --git a/examples/sveltekit/package.json b/examples/sveltekit/package.json index 0cba9c803..07f02607d 100644 --- a/examples/sveltekit/package.json +++ b/examples/sveltekit/package.json @@ -27,6 +27,7 @@ "@sveltejs/vite-plugin-svelte": "^5.0.0", "@tailwindcss/vite": "^4.0.0", "@vitest/browser": "^3.2.4", + "msw": "^2.10.4", "playwright": "1.57.0", "svelte": "^5.0.0", "svelte-check": "^4.0.0", diff --git a/examples/sveltekit/test/index.test.ts b/examples/sveltekit/test/index.test.ts index 3c33fd04b..2c11f4fb7 100644 --- a/examples/sveltekit/test/index.test.ts +++ b/examples/sveltekit/test/index.test.ts @@ -1,9 +1,19 @@ import { userEvent } from '@vitest/browser/context' -import { describe, expect, test } from 'vitest' +import { setupWorker } from 'msw/browser' +import { afterAll, beforeAll, describe, expect, test } from 'vitest' import { render } from 'vitest-browser-svelte' +import { tusHandlers } from '../../shared/tusHandlers.js' import PropsReactivity from '../src/components/test/props-reactivity.svelte' import App from '../src/routes/+page.svelte' +const worker = setupWorker(...tusHandlers) +beforeAll(async () => { + await worker.start({ onUnhandledRequest: 'error' }) +}) +afterAll(() => { + worker.stop() +}) + const createMockFile = (name: string, type: string, size: number = 1024) => { return new File(['test content'], name, { type }) } diff --git a/examples/vue/package.json b/examples/vue/package.json index a0f42e3db..03ab1288a 100644 --- a/examples/vue/package.json +++ b/examples/vue/package.json @@ -23,6 +23,7 @@ "@tailwindcss/vite": "^4.1.11", "@vitejs/plugin-vue": "^6.0.1", "@vitest/browser": "^3.2.4", + "msw": "^2.10.4", "playwright": "1.57.0", "tailwindcss": "^4.0.0", "vite": "^7.1.11", diff --git a/examples/vue/test/index.test.ts b/examples/vue/test/index.test.ts index b9147ea94..8fd0be53b 100644 --- a/examples/vue/test/index.test.ts +++ b/examples/vue/test/index.test.ts @@ -1,8 +1,18 @@ import { userEvent } from '@vitest/browser/context' -import { describe, expect, test } from 'vitest' +import { setupWorker } from 'msw/browser' +import { afterAll, beforeAll, describe, expect, test } from 'vitest' import { render } from 'vitest-browser-vue' +import { tusHandlers } from '../../shared/tusHandlers.js' import App from '../src/App.vue' +const worker = setupWorker(...tusHandlers) +beforeAll(async () => { + await worker.start({ onUnhandledRequest: 'error' }) +}) +afterAll(() => { + worker.stop() +}) + const createMockFile = (name: string, type: string, size: number = 1024) => { return new File(['test content'], name, { type }) } diff --git a/yarn.lock b/yarn.lock index 83fe5acda..f2246134c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14228,6 +14228,7 @@ __metadata: "@uppy/webcam": "workspace:*" "@vitejs/plugin-react": "npm:^4.6.0" "@vitest/browser": "npm:^3.2.4" + msw: "npm:^2.10.4" playwright: "npm:1.57.0" react: "npm:^19.0.0" react-dom: "npm:^19.0.0" @@ -14284,6 +14285,7 @@ __metadata: "@uppy/tus": "workspace:*" "@uppy/webcam": "workspace:*" "@vitest/browser": "npm:^3.2.4" + msw: "npm:^2.10.4" playwright: "npm:1.57.0" svelte: "npm:^5.0.0" svelte-check: "npm:^4.0.0" @@ -14328,6 +14330,7 @@ __metadata: "@uppy/webcam": "workspace:*" "@vitejs/plugin-vue": "npm:^6.0.1" "@vitest/browser": "npm:^3.2.4" + msw: "npm:^2.10.4" playwright: "npm:1.57.0" tailwindcss: "npm:^4.0.0" vite: "npm:^7.1.11"