diff --git a/jest.config.js b/jest.config.js index 1bc73fa000..b62b7ab130 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,24 @@ +/** + * Copyright 2020 Inrupt Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + module.exports = { preset: "ts-jest", testEnvironment: "jsdom", @@ -17,4 +38,5 @@ module.exports = { // By default we only run unit tests: "e2e.test.ts", ], + injectGlobals: false, }; diff --git a/src/acl/acl.test.ts b/src/acl/acl.test.ts index 7ab20f74db..785323623a 100644 --- a/src/acl/acl.test.ts +++ b/src/acl/acl.test.ts @@ -19,7 +19,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { describe, it, expect } from "@jest/globals"; +import { jest, describe, it, expect } from "@jest/globals"; jest.mock("../fetcher.ts", () => ({ fetch: jest.fn().mockImplementation(() => Promise.resolve( diff --git a/src/acp/policy.test.ts b/src/acp/policy.test.ts index 48d0930c83..e7d4c3f188 100644 --- a/src/acp/policy.test.ts +++ b/src/acp/policy.test.ts @@ -19,7 +19,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { describe, it, expect } from "@jest/globals"; +import { jest, describe, it, expect } from "@jest/globals"; jest.mock("../fetcher.ts", () => ({ fetch: jest.fn().mockImplementation(() => Promise.resolve( @@ -56,7 +56,11 @@ const policyUrl = "https://some.pod/policy-resource"; describe("savePolicyDatasetAt", () => { it("sets the type of acp:AccessPolicy if not set yet", async () => { - const mockFetch = jest.fn(window.fetch).mockResolvedValue(new Response()); + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + const mockFetch = jest + .fn(window.fetch) + .mockResolvedValue(new Response() as any); const newDataset = createSolidDataset(); const savedDataset = await savePolicyDatasetAt(policyUrl, newDataset, { @@ -69,7 +73,11 @@ describe("savePolicyDatasetAt", () => { }); it("overwrites an existing type that might be set", async () => { - const mockFetch = jest.fn(window.fetch).mockResolvedValue(new Response()); + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + const mockFetch = jest + .fn(window.fetch) + .mockResolvedValue(new Response() as any); let newDatasetThing = createThing({ url: policyUrl }); newDatasetThing = setUrl( newDatasetThing, @@ -103,7 +111,11 @@ describe("savePolicyDatasetAt", () => { }); it("uses the given fetcher if provided", async () => { - const mockFetch = jest.fn(window.fetch).mockResolvedValue(new Response()); + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + const mockFetch = jest + .fn(window.fetch) + .mockResolvedValue(new Response() as any); await savePolicyDatasetAt(policyUrl, createSolidDataset(), { fetch: mockFetch, diff --git a/src/fetcher.test.ts b/src/fetcher.test.ts index 0b3a108573..d850667725 100644 --- a/src/fetcher.test.ts +++ b/src/fetcher.test.ts @@ -19,7 +19,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { it, expect } from "@jest/globals"; +import { jest, it, expect } from "@jest/globals"; jest.mock("cross-fetch"); import { fetch } from "./fetcher"; diff --git a/src/resource/nonRdfData.test.ts b/src/resource/nonRdfData.test.ts index e6d76b4bdb..5e2b5e48a1 100644 --- a/src/resource/nonRdfData.test.ts +++ b/src/resource/nonRdfData.test.ts @@ -19,7 +19,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { describe, it, expect } from "@jest/globals"; +import { jest, describe, it, expect } from "@jest/globals"; jest.mock("../fetcher", () => ({ fetch: jest @@ -31,6 +31,7 @@ jest.mock("../fetcher", () => ({ ), })); +import type { Mock } from "jest-mock"; import { getFile, deleteFile, @@ -211,7 +212,7 @@ describe("getFileWithAcl", () => { : undefined; const init: ResponseInit & { url: string } = { headers: headers, - url: url, + url: url as string, }; return Promise.resolve(new Response(undefined, init)); }); @@ -472,7 +473,7 @@ describe("Write non-RDF data into a folder", () => { type: "binary", } as Blob; - type MockFetch = jest.Mock< + type MockFetch = Mock< ReturnType, [RequestInfo, RequestInit?] >; @@ -489,8 +490,10 @@ describe("Write non-RDF data into a folder", () => { } as ResponseInit) ): MockFetch { fetch - .mockResolvedValueOnce(saveResponse) - .mockResolvedValueOnce(headResponse); + // The type assertions to any are necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + .mockResolvedValueOnce(saveResponse as any) + .mockResolvedValueOnce(headResponse as any); return fetch; } @@ -579,10 +582,7 @@ describe("Write non-RDF data into a folder", () => { it("returns null if the current user does not have Read access to the new file", async () => { const fetcher = jest.requireMock("../fetcher") as { - fetch: jest.Mock< - ReturnType, - [RequestInfo, RequestInit?] - >; + fetch: MockFetch; }; fetcher.fetch = setMockOnFetch( diff --git a/src/resource/resource.test.ts b/src/resource/resource.test.ts index 9a72408288..d78280c6b6 100644 --- a/src/resource/resource.test.ts +++ b/src/resource/resource.test.ts @@ -19,7 +19,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { describe, it, expect } from "@jest/globals"; +import { jest, describe, it, expect } from "@jest/globals"; jest.mock("../fetcher.ts", () => ({ fetch: jest.fn().mockImplementation(() => Promise.resolve( @@ -54,13 +54,15 @@ function mockResponse( return new Response(body, init); } +type MockedFetch = jest.Mock< + ReturnType, + Parameters +>; + describe("fetchAcl", () => { it("calls the included fetcher by default", async () => { const mockedFetcher = jest.requireMock("../fetcher.ts") as { - fetch: jest.Mock< - ReturnType, - [RequestInfo, RequestInit?] - >; + fetch: MockedFetch; }; const mockResourceInfo: WithResourceInfo = { @@ -114,7 +116,7 @@ describe("fetchAcl", () => { return Promise.resolve( mockResponse(undefined, { headers: headers, - url: url, + url: url as string, }) ); }); @@ -161,7 +163,7 @@ describe("fetchAcl", () => { return Promise.resolve( mockResponse(undefined, { headers: headers, - url: url, + url: url as string, }) ); }); @@ -200,7 +202,7 @@ describe("getResourceInfoWithAcl", () => { return Promise.resolve( mockResponse(undefined, { headers: headers, - url: url, + url: url as string, }) ); }); @@ -230,10 +232,7 @@ describe("getResourceInfoWithAcl", () => { it("calls the included fetcher by default", async () => { const mockedFetcher = jest.requireMock("../fetcher.ts") as { - fetch: jest.Mock< - ReturnType, - [RequestInfo, RequestInit?] - >; + fetch: MockedFetch; }; await getResourceInfoWithAcl("https://some.pod/resource"); @@ -336,10 +335,7 @@ describe("getResourceInfoWithAcl", () => { describe("getResourceInfo", () => { it("calls the included fetcher by default", async () => { const mockedFetcher = jest.requireMock("../fetcher.ts") as { - fetch: jest.Mock< - ReturnType, - [RequestInfo, RequestInit?] - >; + fetch: MockedFetch; }; await getResourceInfo("https://some.pod/resource"); @@ -533,7 +529,9 @@ describe("getResourceInfo", () => { const mockFetch = jest.fn(window.fetch).mockResolvedValue( mockResponse(undefined, { url: "https://arbitrary.pod", - }) + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + }) as any ); const solidDatasetInfo = await getResourceInfo( @@ -545,16 +543,19 @@ describe("getResourceInfo", () => { }); it("does not provide an IRI to an ACL resource if not provided one by the server", async () => { - const mockFetch = jest.fn(window.fetch).mockResolvedValue( - new Response(undefined, { - headers: { - Link: '; rel="not-acl"', - }, - url: "https://arbitrary.pod", - // We need the type assertion because in non-mock situations, - // you cannot set the URL manually: - } as ResponseInit) - ); + const mockResponse = new Response(undefined, { + headers: { + Link: '; rel="not-acl"', + }, + url: "https://arbitrary.pod", + // We need the type assertion because in non-mock situations, + // you cannot set the URL manually: + } as ResponseInit); + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + const mockFetch = jest + .fn(window.fetch) + .mockResolvedValue(mockResponse as any); const solidDatasetInfo = await getResourceInfo( "https://some.pod/container/resource", diff --git a/src/resource/solidDataset.test.ts b/src/resource/solidDataset.test.ts index 27ceda3859..8da767b84e 100644 --- a/src/resource/solidDataset.test.ts +++ b/src/resource/solidDataset.test.ts @@ -19,7 +19,9 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { describe, it, expect } from "@jest/globals"; +import { jest, describe, it, expect } from "@jest/globals"; +import type { Mock } from "jest-mock"; + jest.mock("../fetcher.ts", () => ({ fetch: jest.fn().mockImplementation(() => Promise.resolve( @@ -167,16 +169,19 @@ describe("getSolidDataset", () => { }); it("does not provide an IRI to an ACL resource if not provided one by the server", async () => { - const mockFetch = jest.fn(window.fetch).mockResolvedValue( - new Response(undefined, { - headers: { - Link: '; rel="not-acl"', - }, - url: "https://arbitrary.pod", - // We need the type assertion because in non-mock situations, - // you cannot set the URL manually: - } as ResponseInit) - ); + const mockResponse = new Response(undefined, { + headers: { + Link: '; rel="not-acl"', + }, + url: "https://arbitrary.pod", + // We need the type assertion because in non-mock situations, + // you cannot set the URL manually: + } as ResponseInit); + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + const mockFetch = jest + .fn(window.fetch) + .mockResolvedValue(mockResponse as any); const solidDataset = await getSolidDataset( "https://some.pod/container/resource", @@ -349,7 +354,7 @@ describe("getSolidDatasetWithAcl", () => { return Promise.resolve( mockResponse(undefined, { headers: headers, - url: url, + url: url as string, }) ); }); @@ -1045,11 +1050,11 @@ describe("deleteSolidDataset", () => { }); it("should DELETE a remote SolidDataset using the provided fetcher", async () => { - const mockFetch = jest - .fn(window.fetch) - .mockResolvedValue( - new Response(undefined, { status: 200, statusText: "Deleted" }) - ); + const mockFetch = jest.fn(window.fetch).mockResolvedValue( + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + new Response(undefined, { status: 200, statusText: "Deleted" }) as any + ); const response = await deleteSolidDataset("https://some.url", { fetch: mockFetch, @@ -1067,11 +1072,11 @@ describe("deleteSolidDataset", () => { }); it("should accept a fetched SolidDataset as target", async () => { - const mockFetch = jest - .fn(window.fetch) - .mockResolvedValue( - new Response(undefined, { status: 200, statusText: "Deleted" }) - ); + const mockFetch = jest.fn(window.fetch).mockResolvedValue( + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + new Response(undefined, { status: 200, statusText: "Deleted" }) as any + ); const mockSolidDataset = mockSolidDatasetFrom("https://some.url"); @@ -1095,7 +1100,9 @@ describe("deleteSolidDataset", () => { new Response(undefined, { status: 400, statusText: "Bad request", - }) + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + }) as any ); const deletionPromise = deleteSolidDataset("https://some.url", { @@ -1232,16 +1239,19 @@ describe("createContainerAt", () => { }); it("does not provide an IRI to an ACL resource if not provided one by the server", async () => { - const mockFetch = jest.fn(window.fetch).mockResolvedValue( - new Response(undefined, { - headers: { - Link: '; rel="not-acl"', - }, - url: "https://arbitrary.pod", - // We need the type assertion because in non-mock situations, - // you cannot set the URL manually: - } as ResponseInit) - ); + const mockResponse = new Response(undefined, { + headers: { + Link: '; rel="not-acl"', + }, + url: "https://arbitrary.pod", + // We need the type assertion because in non-mock situations, + // you cannot set the URL manually: + } as ResponseInit); + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + const mockFetch = jest + .fn(window.fetch) + .mockResolvedValue(mockResponse as any); const solidDataset = await createContainerAt( "https://some.pod/container/", @@ -1565,9 +1575,9 @@ describe("createContainerAt", () => { }); describe("saveSolidDatasetInContainer", () => { - type MockFetch = jest.Mock< + type MockFetch = Mock< ReturnType, - [RequestInfo, RequestInit?] + Parameters >; function setMockOnFetch( fetch: MockFetch, @@ -1585,8 +1595,10 @@ describe("saveSolidDatasetInContainer", () => { } as ResponseInit) ): MockFetch { fetch - .mockResolvedValueOnce(saveResponse) - .mockResolvedValueOnce(headResponse); + // The type assertions to any are necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + .mockResolvedValueOnce(saveResponse as any) + .mockResolvedValueOnce(headResponse as any); return fetch; } @@ -1926,7 +1938,7 @@ describe("saveSolidDatasetInContainer", () => { }); describe("createContainerInContainer", () => { - type MockFetch = jest.Mock< + type MockFetch = Mock< ReturnType, [RequestInfo, RequestInit?] >; @@ -1946,17 +1958,16 @@ describe("createContainerInContainer", () => { } as ResponseInit) ): MockFetch { fetch - .mockResolvedValueOnce(saveResponse) - .mockResolvedValueOnce(headResponse); + // The type assertions to any are necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + .mockResolvedValueOnce(saveResponse as any) + .mockResolvedValueOnce(headResponse as any); return fetch; } it("calls the included fetcher by default", async () => { const mockedFetcher = jest.requireMock("../fetcher.ts") as { - fetch: jest.Mock< - ReturnType, - [RequestInfo, RequestInit?] - >; + fetch: MockFetch; }; mockedFetcher.fetch = setMockOnFetch(mockedFetcher.fetch); @@ -2235,11 +2246,11 @@ describe("deleteContainer", () => { }); it("should DELETE a remote Container using the provided fetcher", async () => { - const mockFetch = jest - .fn(window.fetch) - .mockResolvedValue( - new Response(undefined, { status: 200, statusText: "Deleted" }) - ); + const mockFetch = jest.fn(window.fetch).mockResolvedValue( + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + new Response(undefined, { status: 200, statusText: "Deleted" }) as any + ); const response = await deleteContainer("https://some.pod/container/", { fetch: mockFetch, @@ -2257,11 +2268,11 @@ describe("deleteContainer", () => { }); it("should accept a fetched Container as target", async () => { - const mockFetch = jest - .fn(window.fetch) - .mockResolvedValue( - new Response(undefined, { status: 200, statusText: "Deleted" }) - ); + const mockFetch = jest.fn(window.fetch).mockResolvedValue( + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + new Response(undefined, { status: 200, statusText: "Deleted" }) as any + ); const mockContainer = mockSolidDatasetFrom("https://some.pod/container/"); @@ -2294,7 +2305,9 @@ describe("deleteContainer", () => { new Response(undefined, { status: 400, statusText: "Bad request", - }) + // The type assertion to any is necessary due to invalid Jest type definitions: + // https://github.com/facebook/jest/pull/10600 + }) as any ); const deletionPromise = deleteContainer("https://some.pod/container/", {