Skip to content

Commit 6c75bc5

Browse files
authored
chore(api-client): replace jsdom by happy-dom env (#2172)
* chore: upgrade ofetch to 1.5.1 * chore: move from jsdom to happy-dom env * chore: revert ofetch * fix: make snapshot agnostic * fix: use latest version of happy-dom * fix: update happy-dom specific env info * fix: unset default happy-dom env * fix: tests * fix: changes after CR
1 parent 926aa11 commit 6c75bc5

File tree

3 files changed

+398
-758
lines changed

3 files changed

+398
-758
lines changed

packages/api-client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"@codspeed/vitest-plugin": "5.0.1",
5252
"@types/prettier": "3.0.0",
5353
"@vitest/coverage-v8": "3.2.4",
54-
"jsdom": "27.1.0",
54+
"happy-dom": "20.0.11",
5555
"prettier": "3.7.4",
5656
"tsconfig": "workspace:*",
5757
"unbuild": "2.0.0",

packages/api-client/src/createApiClient.test.ts

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ describe("createAPIClient", () => {
315315
});
316316

317317
it("should remove multipart/form-data headers in case of browser", async () => {
318-
// @vitest-environment jsdom
318+
// @vitest-environment happy-dom
319319

320320
const contentTypeSpy = vi.fn().mockImplementation(() => {});
321321
const app = createApp().use(
@@ -342,24 +342,21 @@ describe("createAPIClient", () => {
342342
},
343343
});
344344

345-
expect(contentTypeSpy.mock.calls).toMatchInlineSnapshot(`
346-
[
347-
[
348-
{
349-
"accept": "application/json",
350-
"accept-encoding": "gzip, deflate",
351-
"accept-language": "*",
352-
"connection": "keep-alive",
353-
"content-length": "0",
354-
"host": "localhost:3610",
355-
"sec-fetch-mode": "cors",
356-
"sw-access-key": "123",
357-
"sw-context-token": "456",
358-
"user-agent": "node",
359-
},
360-
],
361-
]
362-
`);
345+
expect(contentTypeSpy).toHaveBeenCalledTimes(1);
346+
const headers = contentTypeSpy.mock.calls[0]?.[0];
347+
expect(headers).toBeDefined();
348+
expect(headers).toMatchObject({
349+
accept: "application/json",
350+
"sw-access-key": "123",
351+
"sw-context-token": "456",
352+
});
353+
// Content-Type header should be removed when multipart/form-data in browser
354+
expect(headers?.["content-type"]).toBeUndefined();
355+
// Verify multipart/form-data is not present in any header value
356+
const headerValues = Object.values(headers || {}).join(" ");
357+
expect(headerValues).not.toContain("multipart/form-data");
358+
// User-agent should exist (platform-specific, so just check presence)
359+
expect(headers?.["user-agent"]).toBeTruthy();
363360
});
364361

365362
it("should trigger success callback", async () => {
@@ -446,7 +443,7 @@ describe("createAPIClient", () => {
446443
controller.abort();
447444

448445
await expect(request).rejects.toThrowErrorMatchingInlineSnapshot(
449-
`[FetchError: [GET] "${baseURL}context": <no response> The operation was aborted.]`,
446+
`[FetchError: [GET] "${baseURL}context": <no response> signal is aborted without reason]`,
450447
);
451448
});
452449

0 commit comments

Comments
 (0)