From 0ab55d5ab1dc683d50e1af51d95b56d480451947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Sworze=C5=84?= Date: Fri, 19 Apr 2024 13:38:31 +0200 Subject: [PATCH 1/4] add tests --- govtool/frontend/src/utils/dRep.ts | 2 +- .../utils/tests/checkIsMaintenanceOn.test.ts | 40 +++++++++++ .../tests/checkIsWalletConnected.test.ts | 25 +++++++ govtool/frontend/src/utils/tests/dRep.test.ts | 38 ++++++++++ .../src/utils/tests/generateAnchor.test.ts | 30 ++++++++ .../src/utils/tests/getDRepID.test.ts | 64 +++++++++++++++++ .../src/utils/tests/localStorage.test.ts | 27 +++++++ .../src/utils/tests/numberValidation.test.ts | 36 ++++++++++ .../src/utils/tests/openInNewTab.test.ts | 33 +++++++++ .../utils/tests/validateMetadataHash.test.ts | 71 +++++++++++++++++++ govtool/frontend/src/utils/tests/wait.test.ts | 28 ++++++++ 11 files changed, 393 insertions(+), 1 deletion(-) create mode 100644 govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts create mode 100644 govtool/frontend/src/utils/tests/checkIsWalletConnected.test.ts create mode 100644 govtool/frontend/src/utils/tests/dRep.test.ts create mode 100644 govtool/frontend/src/utils/tests/generateAnchor.test.ts create mode 100644 govtool/frontend/src/utils/tests/getDRepID.test.ts create mode 100644 govtool/frontend/src/utils/tests/localStorage.test.ts create mode 100644 govtool/frontend/src/utils/tests/numberValidation.test.ts create mode 100644 govtool/frontend/src/utils/tests/openInNewTab.test.ts create mode 100644 govtool/frontend/src/utils/tests/validateMetadataHash.test.ts create mode 100644 govtool/frontend/src/utils/tests/wait.test.ts diff --git a/govtool/frontend/src/utils/dRep.ts b/govtool/frontend/src/utils/dRep.ts index 2135677a1..7743a017e 100644 --- a/govtool/frontend/src/utils/dRep.ts +++ b/govtool/frontend/src/utils/dRep.ts @@ -1,4 +1,4 @@ -import { DRepData } from '@/models'; +import { DRepData } from "@/models"; export const isSameDRep = ( { drepId, view }: DRepData, diff --git a/govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts b/govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts new file mode 100644 index 000000000..e58ffb697 --- /dev/null +++ b/govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts @@ -0,0 +1,40 @@ +import { vi } from "vitest"; +import { checkIsMaintenanceOn } from ".."; +import axios from "axios"; + +vi.mock("axios"); +vi.stubEnv("VITE_IS_DEV", ""); + +describe("checkIsMaintenanceOn function", () => { + it("does not reload the page when maintenance mode is off", async () => { + const location: Location = window.location; + delete window.location; + window.location = { + ...location, + reload: vi.fn(), + }; + axios.get.mockResolvedValueOnce({ data: false }); + + const somethingSpy = vi.spyOn(window.location, "reload").mockReturnValue(); + + await checkIsMaintenanceOn(); + + expect(somethingSpy).not.toHaveBeenCalled(); + }); + + it("does not reload the page when maintenance mode is on", async () => { + const location: Location = window.location; + delete window.location; + window.location = { + ...location, + reload: vi.fn(), + }; + axios.get.mockResolvedValueOnce({ data: true }); + + const somethingSpy = vi.spyOn(window.location, "reload").mockReturnValue(); + + await checkIsMaintenanceOn(); + + expect(somethingSpy).toHaveBeenCalledTimes(1); + }); +}); diff --git a/govtool/frontend/src/utils/tests/checkIsWalletConnected.test.ts b/govtool/frontend/src/utils/tests/checkIsWalletConnected.test.ts new file mode 100644 index 000000000..54bb44a4f --- /dev/null +++ b/govtool/frontend/src/utils/tests/checkIsWalletConnected.test.ts @@ -0,0 +1,25 @@ +import { checkIsWalletConnected } from ".."; +import { + WALLET_LS_KEY, + setItemToLocalStorage, + removeItemFromLocalStorage, +} from "@/utils/localStorage"; + +describe("checkIsWalletConnected function", () => { + it("returns false when wallet information is present in local storage", () => { + setItemToLocalStorage(`${WALLET_LS_KEY}_name`, "Nami"); + setItemToLocalStorage(`${WALLET_LS_KEY}_stake_key`, "teststakekey"); + const isConnected = checkIsWalletConnected(); + + expect(isConnected).toBe(false); + }); + + it("returns true when wallet information is missing in local storage", () => { + removeItemFromLocalStorage(`${WALLET_LS_KEY}_name`); + removeItemFromLocalStorage(`${WALLET_LS_KEY}_stake_key`); + + const isConnected = checkIsWalletConnected(); + + expect(isConnected).toBe(true); + }); +}); diff --git a/govtool/frontend/src/utils/tests/dRep.test.ts b/govtool/frontend/src/utils/tests/dRep.test.ts new file mode 100644 index 000000000..26558791d --- /dev/null +++ b/govtool/frontend/src/utils/tests/dRep.test.ts @@ -0,0 +1,38 @@ +import { isSameDRep } from ".."; + +import { DRepStatus } from "@/models"; + +type TDRepType = "DRep" | "SoleVoter"; + +const EXAMPLE_DREP = { + drepId: "drep123", + view: "view123", + url: "url", + metadataHash: "hash", + deposit: 10000, + votingPower: 10000, + status: DRepStatus.Active, + type: "DRep" as TDRepType, +}; + +describe("isSameDRep function", () => { + it("returns false if dRepIdOrView is undefined", () => { + const dRepIdOrView = undefined; + expect(isSameDRep(EXAMPLE_DREP, dRepIdOrView)).toBe(false); + }); + + it("returns true if drepId matches dRepIdOrView", () => { + const dRepIdOrView = "drep123"; + expect(isSameDRep(EXAMPLE_DREP, dRepIdOrView)).toBe(true); + }); + + it("returns true if view matches dRepIdOrView", () => { + const dRepIdOrView = "view123"; + expect(isSameDRep(EXAMPLE_DREP, dRepIdOrView)).toBe(true); + }); + + it("returns false if neither drepId nor view matches dRepIdOrView", () => { + const dRepIdOrView = "otherId"; + expect(isSameDRep(EXAMPLE_DREP, dRepIdOrView)).toBe(false); + }); +}); diff --git a/govtool/frontend/src/utils/tests/generateAnchor.test.ts b/govtool/frontend/src/utils/tests/generateAnchor.test.ts new file mode 100644 index 000000000..cff8ded67 --- /dev/null +++ b/govtool/frontend/src/utils/tests/generateAnchor.test.ts @@ -0,0 +1,30 @@ +import { vi } from "vitest"; +import { generateAnchor } from ".."; +import { + Anchor, + AnchorDataHash, + URL, +} from "@emurgo/cardano-serialization-lib-asmjs"; + +describe("generateAnchor function", () => { + it("generates an anchor with the provided URL and hash", () => { + const url = "https://example.com"; + const hash = "aabbccddeeff"; + + URL.new = vi.fn().mockReturnValueOnce({}); + AnchorDataHash.from_hex = vi.fn().mockReturnValueOnce({}); + Anchor.new = vi.fn().mockReturnValueOnce({}); + + const anchor = generateAnchor(url, hash); + + expect(URL.new).toHaveBeenCalledWith(url); + + expect(AnchorDataHash.from_hex).toHaveBeenCalledWith(hash); + + const spyFoAnchor = vi.spyOn(Anchor, "new").mockReturnValue(); + + expect(spyFoAnchor).toHaveBeenCalledWith([{}, {}]); + + expect(anchor).toBeInstanceOf(Anchor); + }); +}); diff --git a/govtool/frontend/src/utils/tests/getDRepID.test.ts b/govtool/frontend/src/utils/tests/getDRepID.test.ts new file mode 100644 index 000000000..033a84e59 --- /dev/null +++ b/govtool/frontend/src/utils/tests/getDRepID.test.ts @@ -0,0 +1,64 @@ +import { vi } from "vitest"; +import { formHexToBech32, getPubDRepID } from "../getDRepID"; + +const dRepIdHex = "99f2c9a961ff53099796643a514a0640379b706ad310bc751c2997c9"; +const dRepIdBech32 = "drep1n8evn2tplafsn9ukvsa9zjsxgqmekur26vgtcagu9xtujzv2yv8"; + +describe("formHexToBech32 function", () => { + it("returns correct dRep bech32 format", () => { + const bech32Format = formHexToBech32(dRepIdHex); + + expect(bech32Format).toBe(dRepIdBech32); + }); + + it("expected undefined when no argument", () => { + const bech32Format = formHexToBech32(); + + expect(bech32Format).toBe(undefined); + }); +}); + +const mockGetPubDRepKey = vi.fn(); + +const mockWalletApi = { + cip95: { + getPubDRepKey: mockGetPubDRepKey, + }, +}; + +describe("getPubDRepID function", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + it("returns the dRepKey, dRepID, and dRepIDBech32 when walletApi returns a valid response", async () => { + const dRepKey = "dRepKey123"; + mockGetPubDRepKey.mockResolvedValueOnce(dRepKey); + + const result = await getPubDRepID(mockWalletApi); + + expect(result).toEqual({ + dRepKey, + dRepID: expect.any(String), + dRepIDBech32: expect.any(String), + }); + + expect(mockGetPubDRepKey).toHaveBeenCalled(); + }); + + it("returns undefined values for dRepKey, dRepID, and dRepIDBech32 when walletApi throws an error", async () => { + mockGetPubDRepKey.mockRejectedValueOnce( + new Error("Failed to get PubDRepKey"), + ); + + const result = await getPubDRepID(mockWalletApi); + + expect(result).toEqual({ + dRepKey: undefined, + dRepID: undefined, + dRepIDBech32: undefined, + }); + + expect(mockGetPubDRepKey).toHaveBeenCalled(); + }); +}); diff --git a/govtool/frontend/src/utils/tests/localStorage.test.ts b/govtool/frontend/src/utils/tests/localStorage.test.ts new file mode 100644 index 000000000..8cf7bc8b3 --- /dev/null +++ b/govtool/frontend/src/utils/tests/localStorage.test.ts @@ -0,0 +1,27 @@ +import { + getItemFromLocalStorage, + setItemToLocalStorage, + removeItemFromLocalStorage, +} from ".."; + +const EXAMPLE_KEY = "example_key"; +const VALUE = "exampleValue"; + +describe("localStorage util", () => { + it("returns correctly value after set item to localstorage", () => { + setItemToLocalStorage(EXAMPLE_KEY, VALUE); + + const itemFromStorage = getItemFromLocalStorage(EXAMPLE_KEY); + + expect(itemFromStorage).toBe(VALUE); + }); + + it("returns null after remove item from localstorage", () => { + setItemToLocalStorage(EXAMPLE_KEY, VALUE); + removeItemFromLocalStorage(EXAMPLE_KEY); + + const itemFromStorage = getItemFromLocalStorage(EXAMPLE_KEY); + + expect(itemFromStorage).toBe(null); + }); +}); diff --git a/govtool/frontend/src/utils/tests/numberValidation.test.ts b/govtool/frontend/src/utils/tests/numberValidation.test.ts new file mode 100644 index 000000000..4a7e332ec --- /dev/null +++ b/govtool/frontend/src/utils/tests/numberValidation.test.ts @@ -0,0 +1,36 @@ +import i18n from "@/i18n"; +import { numberValidation } from ".."; + +const positiveResponse = i18n.t( + "createGovernanceAction.fields.validations.positive", +); + +const numberResponse = i18n.t( + "createGovernanceAction.fields.validations.number", +); + +describe("numberValidation function", () => { + it("returns an error message when the input is not a valid number", () => { + const invalidInputs = ["abc", "1.2.3", "10,000.50abc", "/"]; + + invalidInputs.forEach((input) => { + expect(numberValidation(input)).toEqual(numberResponse); + }); + }); + + it("returns an error message when the input is negative", () => { + const negativeInputs = ["-10", "-1.5", "-5000"]; + + negativeInputs.forEach((input) => { + expect(numberValidation(input)).toEqual(positiveResponse); + }); + }); + + it("returns true when the input is a valid positive number", () => { + const validInputs = ["10", "1.5", "5000", "10,5"]; + + validInputs.forEach((input) => { + expect(numberValidation(input)).toEqual(true); + }); + }); +}); diff --git a/govtool/frontend/src/utils/tests/openInNewTab.test.ts b/govtool/frontend/src/utils/tests/openInNewTab.test.ts new file mode 100644 index 000000000..ebecfa62c --- /dev/null +++ b/govtool/frontend/src/utils/tests/openInNewTab.test.ts @@ -0,0 +1,33 @@ +import { vi } from "vitest"; +import { openInNewTab } from ".."; + +describe("openInNewTab function", () => { + it("opens a new tab with the provided URL", () => { + const originalOpen = window.open; + const mockOpen = vi.fn(); + window.open = mockOpen; + + const url = "https://example.com"; + openInNewTab(url); + + expect(mockOpen).toHaveBeenCalledWith(url, "_blank", "noopener,noreferrer"); + + window.open = originalOpen; + }); + + it("sets opener to null if new window is opened", () => { + const originalOpen = window.open; + const mockNewWindow = { + opener: "someOpener", + }; + const mockOpen = vi.fn().mockReturnValue(mockNewWindow); + window.open = mockOpen; + + const url = "https://example.com"; + openInNewTab(url); + + expect(mockNewWindow.opener).toBeNull(); + + window.open = originalOpen; + }); +}); diff --git a/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts b/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts new file mode 100644 index 000000000..efa35a9aa --- /dev/null +++ b/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts @@ -0,0 +1,71 @@ +import { checkIsMissingGAMetadata } from ".."; +import { postValidate } from "@services"; +import { MetadataStandard, MetadataValidationStatus } from "@/models"; +import { vi } from "vitest"; + +const url = "https://example.com"; +const hash = "abcdefg"; + +vi.mock("@services"); + +describe("checkIsMissingGAMetadata", () => { + it("returns false when url and hash are correct", async () => { + // Mock postValidate to resolve with a status + postValidate.mockResolvedValueOnce({ + status: false, + }); + + const result = await checkIsMissingGAMetadata({ url, hash }); + + expect(result).toBe(false); + expect(postValidate).toHaveBeenCalledWith({ + url, + hash, + standard: MetadataStandard.CIP108, + }); + }); + + it("returns a MetadataValidationStatus when postValidate resolves when status is invalid hash", async () => { + postValidate.mockResolvedValueOnce({ + status: MetadataValidationStatus.INVALID_HASH, + }); + + const result = await checkIsMissingGAMetadata({ url, hash }); + + expect(result).toBe(MetadataValidationStatus.INVALID_HASH); + expect(postValidate).toHaveBeenCalledWith({ + url, + hash, + standard: MetadataStandard.CIP108, + }); + }); + + it("returns a MetadataValidationStatus when postValidate resolves when status is invalid json", async () => { + postValidate.mockResolvedValueOnce({ + status: MetadataValidationStatus.INVALID_JSONLD, + }); + + const result = await checkIsMissingGAMetadata({ url, hash }); + + expect(result).toBe(MetadataValidationStatus.INVALID_JSONLD); + expect(postValidate).toHaveBeenCalledWith({ + url, + hash, + standard: MetadataStandard.CIP108, + }); + }); + + it("returns MetadataValidationStatus.URL_NOT_FOUND when postValidate throws an error", async () => { + // Mock postValidate to throw an error + postValidate.mockRejectedValueOnce(new Error("404 Not Found")); + + const result = await checkIsMissingGAMetadata({ url, hash }); + + expect(result).toBe(MetadataValidationStatus.URL_NOT_FOUND); + expect(postValidate).toHaveBeenCalledWith({ + url, + hash, + standard: MetadataStandard.CIP108, + }); + }); +}); diff --git a/govtool/frontend/src/utils/tests/wait.test.ts b/govtool/frontend/src/utils/tests/wait.test.ts new file mode 100644 index 000000000..1949f11c1 --- /dev/null +++ b/govtool/frontend/src/utils/tests/wait.test.ts @@ -0,0 +1,28 @@ +import { wait } from ".."; + +describe("wait function", () => { + it("resolves after the specified time", async () => { + const startTime = Date.now(); + const waitTime = 2000; + + await wait(waitTime); + + const endTime = Date.now(); + const elapsedTime = endTime - startTime; + + expect(elapsedTime).toBeGreaterThanOrEqual(waitTime - 100); + expect(elapsedTime).toBeLessThanOrEqual(waitTime + 100); + }); + + it("resolves after the default time if no time is specified", async () => { + const startTime = Date.now(); + + await wait(); + + const endTime = Date.now(); + const elapsedTime = endTime - startTime; + + expect(elapsedTime).toBeGreaterThanOrEqual(4900); + expect(elapsedTime).toBeLessThanOrEqual(5100); + }); +}); From 0ab65e89f07971633383c117d6caf047516e6f4a Mon Sep 17 00:00:00 2001 From: Jan Jaroszczak Date: Sun, 21 Apr 2024 16:59:45 +0200 Subject: [PATCH 2/4] add test - part 2 --- .../src/utils/tests/checkIsMaintenanceOn.test.ts | 6 +++--- .../frontend/src/utils/tests/generateAnchor.test.ts | 12 +++++------- .../src/utils/tests/validateMetadataHash.test.ts | 4 ++-- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts b/govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts index e58ffb697..a2aaa1ca6 100644 --- a/govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts +++ b/govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts @@ -1,13 +1,13 @@ import { vi } from "vitest"; -import { checkIsMaintenanceOn } from ".."; import axios from "axios"; +import { checkIsMaintenanceOn } from ".."; vi.mock("axios"); vi.stubEnv("VITE_IS_DEV", ""); describe("checkIsMaintenanceOn function", () => { it("does not reload the page when maintenance mode is off", async () => { - const location: Location = window.location; + const { location } = window; delete window.location; window.location = { ...location, @@ -23,7 +23,7 @@ describe("checkIsMaintenanceOn function", () => { }); it("does not reload the page when maintenance mode is on", async () => { - const location: Location = window.location; + const { location } = window; delete window.location; window.location = { ...location, diff --git a/govtool/frontend/src/utils/tests/generateAnchor.test.ts b/govtool/frontend/src/utils/tests/generateAnchor.test.ts index cff8ded67..a0f563112 100644 --- a/govtool/frontend/src/utils/tests/generateAnchor.test.ts +++ b/govtool/frontend/src/utils/tests/generateAnchor.test.ts @@ -1,10 +1,10 @@ import { vi } from "vitest"; -import { generateAnchor } from ".."; import { Anchor, AnchorDataHash, URL, } from "@emurgo/cardano-serialization-lib-asmjs"; +import { generateAnchor } from ".."; describe("generateAnchor function", () => { it("generates an anchor with the provided URL and hash", () => { @@ -15,16 +15,14 @@ describe("generateAnchor function", () => { AnchorDataHash.from_hex = vi.fn().mockReturnValueOnce({}); Anchor.new = vi.fn().mockReturnValueOnce({}); + const spyForAnchor = vi.spyOn(Anchor, "new").mockReturnValue(new Anchor()); const anchor = generateAnchor(url, hash); expect(URL.new).toHaveBeenCalledWith(url); - expect(AnchorDataHash.from_hex).toHaveBeenCalledWith(hash); - - const spyFoAnchor = vi.spyOn(Anchor, "new").mockReturnValue(); - - expect(spyFoAnchor).toHaveBeenCalledWith([{}, {}]); - + expect(spyForAnchor).toHaveBeenCalledWith({}, {}); expect(anchor).toBeInstanceOf(Anchor); + + spyForAnchor.mockRestore(); }); }); diff --git a/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts b/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts index efa35a9aa..d7dd66754 100644 --- a/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts +++ b/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts @@ -1,7 +1,7 @@ -import { checkIsMissingGAMetadata } from ".."; +import { vi } from "vitest"; import { postValidate } from "@services"; +import { checkIsMissingGAMetadata } from ".."; import { MetadataStandard, MetadataValidationStatus } from "@/models"; -import { vi } from "vitest"; const url = "https://example.com"; const hash = "abcdefg"; From 56868e959929cf05056e5f4fa3eb0c4337f81463 Mon Sep 17 00:00:00 2001 From: Jan Jaroszczak Date: Mon, 22 Apr 2024 11:01:07 +0200 Subject: [PATCH 3/4] add tests - part 3 --- .../utils/tests/checkIsMaintenanceOn.test.ts | 58 ++++++++++--------- .../src/utils/tests/getDRepID.test.ts | 11 +--- .../utils/tests/validateMetadataHash.test.ts | 32 +++++----- 3 files changed, 52 insertions(+), 49 deletions(-) diff --git a/govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts b/govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts index a2aaa1ca6..93aff7b68 100644 --- a/govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts +++ b/govtool/frontend/src/utils/tests/checkIsMaintenanceOn.test.ts @@ -1,40 +1,46 @@ -import { vi } from "vitest"; +import { describe, it, expect, vi, afterEach } from "vitest"; import axios from "axios"; import { checkIsMaintenanceOn } from ".."; -vi.mock("axios"); -vi.stubEnv("VITE_IS_DEV", ""); +vi.stubGlobal("location", { + ...window.location, + reload: vi.fn(), +}); -describe("checkIsMaintenanceOn function", () => { - it("does not reload the page when maintenance mode is off", async () => { - const { location } = window; - delete window.location; - window.location = { - ...location, - reload: vi.fn(), - }; - axios.get.mockResolvedValueOnce({ data: false }); +const axiosGetSpy = vi.spyOn(axios, "get"); - const somethingSpy = vi.spyOn(window.location, "reload").mockReturnValue(); +describe("checkIsMaintenanceOn function", () => { + afterEach(() => { + axiosGetSpy.mockClear(); + vi.resetAllMocks(); + }); + it("does nothing in development mode", async () => { + vi.stubEnv("VITE_IS_DEV", "true"); await checkIsMaintenanceOn(); - - expect(somethingSpy).not.toHaveBeenCalled(); + expect(axiosGetSpy).not.toHaveBeenCalled(); + expect(window.location.reload).not.toHaveBeenCalled(); }); - it("does not reload the page when maintenance mode is on", async () => { - const { location } = window; - delete window.location; - window.location = { - ...location, - reload: vi.fn(), - }; - axios.get.mockResolvedValueOnce({ data: true }); - - const somethingSpy = vi.spyOn(window.location, "reload").mockReturnValue(); + it("reloads the page if maintenance mode is active", async () => { + vi.stubEnv("VITE_IS_DEV", ""); + axiosGetSpy.mockResolvedValue({ data: true }); + await checkIsMaintenanceOn(); + expect(window.location.reload).toHaveBeenCalled(); + }); + it("does not reload the page if maintenance mode is not active", async () => { + vi.stubEnv("VITE_IS_DEV", ""); + axiosGetSpy.mockResolvedValue({ data: false }); await checkIsMaintenanceOn(); + expect(window.location.reload).not.toHaveBeenCalled(); + }); - expect(somethingSpy).toHaveBeenCalledTimes(1); + it("throws an error if the request fails", async () => { + vi.stubEnv("VITE_IS_DEV", ""); + axiosGetSpy.mockRejectedValue(new Error("Network Error")); + await expect(checkIsMaintenanceOn()).rejects.toThrow( + "Action canceled due to maintenance mode.", + ); }); }); diff --git a/govtool/frontend/src/utils/tests/getDRepID.test.ts b/govtool/frontend/src/utils/tests/getDRepID.test.ts index 033a84e59..61bc5470c 100644 --- a/govtool/frontend/src/utils/tests/getDRepID.test.ts +++ b/govtool/frontend/src/utils/tests/getDRepID.test.ts @@ -1,5 +1,6 @@ import { vi } from "vitest"; import { formHexToBech32, getPubDRepID } from "../getDRepID"; +import { CardanoApiWallet } from "@/models"; const dRepIdHex = "99f2c9a961ff53099796643a514a0640379b706ad310bc751c2997c9"; const dRepIdBech32 = "drep1n8evn2tplafsn9ukvsa9zjsxgqmekur26vgtcagu9xtujzv2yv8"; @@ -7,13 +8,11 @@ const dRepIdBech32 = "drep1n8evn2tplafsn9ukvsa9zjsxgqmekur26vgtcagu9xtujzv2yv8"; describe("formHexToBech32 function", () => { it("returns correct dRep bech32 format", () => { const bech32Format = formHexToBech32(dRepIdHex); - expect(bech32Format).toBe(dRepIdBech32); }); it("expected undefined when no argument", () => { const bech32Format = formHexToBech32(); - expect(bech32Format).toBe(undefined); }); }); @@ -24,7 +23,7 @@ const mockWalletApi = { cip95: { getPubDRepKey: mockGetPubDRepKey, }, -}; +} as unknown as CardanoApiWallet; describe("getPubDRepID function", () => { beforeEach(() => { @@ -34,15 +33,12 @@ describe("getPubDRepID function", () => { it("returns the dRepKey, dRepID, and dRepIDBech32 when walletApi returns a valid response", async () => { const dRepKey = "dRepKey123"; mockGetPubDRepKey.mockResolvedValueOnce(dRepKey); - const result = await getPubDRepID(mockWalletApi); - expect(result).toEqual({ dRepKey, dRepID: expect.any(String), dRepIDBech32: expect.any(String), }); - expect(mockGetPubDRepKey).toHaveBeenCalled(); }); @@ -50,15 +46,12 @@ describe("getPubDRepID function", () => { mockGetPubDRepKey.mockRejectedValueOnce( new Error("Failed to get PubDRepKey"), ); - const result = await getPubDRepID(mockWalletApi); - expect(result).toEqual({ dRepKey: undefined, dRepID: undefined, dRepIDBech32: undefined, }); - expect(mockGetPubDRepKey).toHaveBeenCalled(); }); }); diff --git a/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts b/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts index d7dd66754..d04f8d2fc 100644 --- a/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts +++ b/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts @@ -8,47 +8,52 @@ const hash = "abcdefg"; vi.mock("@services"); +const mockPostValidate = postValidate as jest.MockedFunction< + typeof postValidate +>; + describe("checkIsMissingGAMetadata", () => { - it("returns false when url and hash are correct", async () => { - // Mock postValidate to resolve with a status - postValidate.mockResolvedValueOnce({ - status: false, + it("returns false when there are no issues with the metadata", async () => { + mockPostValidate.mockResolvedValueOnce({ + valid: true, }); const result = await checkIsMissingGAMetadata({ url, hash }); expect(result).toBe(false); - expect(postValidate).toHaveBeenCalledWith({ + expect(mockPostValidate).toHaveBeenCalledWith({ url, hash, standard: MetadataStandard.CIP108, }); }); - it("returns a MetadataValidationStatus when postValidate resolves when status is invalid hash", async () => { - postValidate.mockResolvedValueOnce({ + it("returns MetadataValidationStatus.INVALID_HASH when postValidate resolves with INVALID_HASH", async () => { + mockPostValidate.mockResolvedValueOnce({ + valid: false, status: MetadataValidationStatus.INVALID_HASH, }); const result = await checkIsMissingGAMetadata({ url, hash }); expect(result).toBe(MetadataValidationStatus.INVALID_HASH); - expect(postValidate).toHaveBeenCalledWith({ + expect(mockPostValidate).toHaveBeenCalledWith({ url, hash, standard: MetadataStandard.CIP108, }); }); - it("returns a MetadataValidationStatus when postValidate resolves when status is invalid json", async () => { - postValidate.mockResolvedValueOnce({ + it("returns MetadataValidationStatus.INVALID_JSONLD when postValidate resolves with INVALID_JSONLD", async () => { + mockPostValidate.mockResolvedValueOnce({ + valid: false, status: MetadataValidationStatus.INVALID_JSONLD, }); const result = await checkIsMissingGAMetadata({ url, hash }); expect(result).toBe(MetadataValidationStatus.INVALID_JSONLD); - expect(postValidate).toHaveBeenCalledWith({ + expect(mockPostValidate).toHaveBeenCalledWith({ url, hash, standard: MetadataStandard.CIP108, @@ -56,13 +61,12 @@ describe("checkIsMissingGAMetadata", () => { }); it("returns MetadataValidationStatus.URL_NOT_FOUND when postValidate throws an error", async () => { - // Mock postValidate to throw an error - postValidate.mockRejectedValueOnce(new Error("404 Not Found")); + mockPostValidate.mockRejectedValueOnce(new Error("404 Not Found")); const result = await checkIsMissingGAMetadata({ url, hash }); expect(result).toBe(MetadataValidationStatus.URL_NOT_FOUND); - expect(postValidate).toHaveBeenCalledWith({ + expect(mockPostValidate).toHaveBeenCalledWith({ url, hash, standard: MetadataStandard.CIP108, From d6cee86fc2df2570dd53148a9f73fae4f786cc1d Mon Sep 17 00:00:00 2001 From: Jan Jaroszczak Date: Mon, 22 Apr 2024 13:04:24 +0200 Subject: [PATCH 4/4] add tests - part 4 --- .../src/utils/tests/canonizeJSON.test.ts | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 govtool/frontend/src/utils/tests/canonizeJSON.test.ts diff --git a/govtool/frontend/src/utils/tests/canonizeJSON.test.ts b/govtool/frontend/src/utils/tests/canonizeJSON.test.ts new file mode 100644 index 000000000..7115cc430 --- /dev/null +++ b/govtool/frontend/src/utils/tests/canonizeJSON.test.ts @@ -0,0 +1,106 @@ +import { describe, it, expect } from "vitest"; +import { canonizeJSON } from ".."; + +const exampleJson = { + "@context": { + "@language": "en-us", + CIP100: + "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#", + CIP108: + "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0108/README.md#", + hashAlgorithm: "CIP100:hashAlgorithm", + body: { + "@id": "CIP108:body", + "@context": { + references: { + "@id": "CIP108:references", + "@container": "@set", + "@context": { + GovernanceMetadata: "CIP100:GovernanceMetadataReference", + Other: "CIP100:OtherReference", + label: "CIP100:reference-label", + uri: "CIP100:reference-uri", + referenceHash: { + "@id": "CIP108:referenceHash", + "@context": { + hashDigest: "CIP108:hashDigest", + hashAlgorithm: "CIP100:hashAlgorithm", + }, + }, + }, + }, + title: "CIP108:title", + abstract: "CIP108:abstract", + motivation: "CIP108:motivation", + rationale: "CIP108:rationale", + }, + }, + authors: { + "@id": "CIP100:authors", + "@container": "@set", + "@context": { + name: "http://xmlns.com/foaf/0.1/name", + witness: { + "@id": "CIP100:witness", + "@context": { + witnessAlgorithm: "CIP100:witnessAlgorithm", + publicKey: "CIP100:publicKey", + signature: "CIP100:signature", + }, + }, + }, + }, + }, + authors: [], + hashAlgorithm: { + "@value": "blake2b-256", + }, + body: { + abstract: { + "@value": "Test abstract", + }, + motivation: { + "@value": "Test motivation", + }, + rationale: { + "@value": "Test rationale", + }, + references: [ + { + "@type": "Other", + "CIP108:reference-label": { + "@value": "Label", + }, + "CIP108:reference-uri": { + "@value": "https://www.google.com/", + }, + }, + ], + title: { + "@value": "Test title", + }, + }, +}; + +const expectedOutput = ` +_:c14n0 "blake2b-256" . +_:c14n0 _:c14n2 . +_:c14n1 . +_:c14n1 "Label" . +_:c14n1 "https://www.google.com/" . +_:c14n2 "Test abstract" . +_:c14n2 "Test motivation" . +_:c14n2 "Test rationale" . +_:c14n2 _:c14n1 . +_:c14n2 "Test title" . +` + .trim() + .replace(/\s+\n/g, "\n"); + +describe("canonizeJSON", () => { + it("should correctly canonize a jsonld object to the expected output", async () => { + const result = await canonizeJSON(exampleJson); + const normalizedResult = result.trim().replace(/\s+\n/g, "\n"); + expect(normalizedResult).toBe(expectedOutput); + }); +});