From 38947f8302759faa7fc087357368f10b752d7431 Mon Sep 17 00:00:00 2001 From: 0xkenj1 Date: Tue, 12 Nov 2024 17:43:21 -0300 Subject: [PATCH] feat: add tests --- .../test/unit/eventsRegistry.spec.ts | 2 +- .../handlers/profileNameUpdated.handler.ts | 5 +- .../handlers/profileOwnerUpdated.handler.ts | 5 +- .../registry/handlers/roleRevoked.handler.ts | 5 +- .../processors/test/helpers/tokenMath.spec.ts | 4 +- .../profileMetadataUpdated.handler.spec.ts | 80 +++++++++++++++++++ .../profileNameUpdated.handler.spec.ts | 57 +++++++++++++ .../profileOwnerUpdated.handler.spec.ts | 72 +++++++++++++++++ .../handlers/roleRevoked.handler.spec.ts | 80 +++++++++++++++++++ .../test/registry/registry.processor.spec.ts | 4 +- .../helpers/decoder.spec.ts | 2 +- .../processors/test/strategy/mapping.spec.ts | 12 +-- 12 files changed, 304 insertions(+), 24 deletions(-) create mode 100644 packages/processors/test/registry/handlers/profileMetadataUpdated.handler.spec.ts create mode 100644 packages/processors/test/registry/handlers/profileNameUpdated.handler.spec.ts create mode 100644 packages/processors/test/registry/handlers/profileOwnerUpdated.handler.spec.ts create mode 100644 packages/processors/test/registry/handlers/roleRevoked.handler.spec.ts diff --git a/packages/data-flow/test/unit/eventsRegistry.spec.ts b/packages/data-flow/test/unit/eventsRegistry.spec.ts index 7a293f2..59920e4 100644 --- a/packages/data-flow/test/unit/eventsRegistry.spec.ts +++ b/packages/data-flow/test/unit/eventsRegistry.spec.ts @@ -48,7 +48,7 @@ describe("InMemoryEventsRegistry", () => { expect(retrievedEvent).toEqual(mockEvent); }); - it("should update the last processed event when saving multiple times", async () => { + it("updates the last processed event when saving multiple times", async () => { const registry = new InMemoryEventsRegistry(logger); const firstEvent: ProcessorEvent<"Allo", "PoolCreated"> = { diff --git a/packages/processors/src/processors/registry/handlers/profileNameUpdated.handler.ts b/packages/processors/src/processors/registry/handlers/profileNameUpdated.handler.ts index 14ac422..e7a9088 100644 --- a/packages/processors/src/processors/registry/handlers/profileNameUpdated.handler.ts +++ b/packages/processors/src/processors/registry/handlers/profileNameUpdated.handler.ts @@ -5,10 +5,7 @@ import { ChainId, ProcessorEvent } from "@grants-stack-indexer/shared"; import { IEventHandler, ProcessorDependencies } from "../../../internal.js"; -type Dependencies = Pick< - ProcessorDependencies, - "projectRepository" | "evmProvider" | "metadataProvider" | "logger" ->; +type Dependencies = Pick; /** * Handles the ProfileNameUpdated event for the Registry contract from Allo protocol. */ diff --git a/packages/processors/src/processors/registry/handlers/profileOwnerUpdated.handler.ts b/packages/processors/src/processors/registry/handlers/profileOwnerUpdated.handler.ts index e75579f..38aff7b 100644 --- a/packages/processors/src/processors/registry/handlers/profileOwnerUpdated.handler.ts +++ b/packages/processors/src/processors/registry/handlers/profileOwnerUpdated.handler.ts @@ -5,10 +5,7 @@ import { ChainId, ProcessorEvent } from "@grants-stack-indexer/shared"; import { IEventHandler, ProcessorDependencies } from "../../../internal.js"; -type Dependencies = Pick< - ProcessorDependencies, - "projectRepository" | "evmProvider" | "metadataProvider" | "logger" ->; +type Dependencies = Pick; /** * Handles the ProfileOwnerUpdated event for the Registry contract from Allo protocol. */ diff --git a/packages/processors/src/processors/registry/handlers/roleRevoked.handler.ts b/packages/processors/src/processors/registry/handlers/roleRevoked.handler.ts index ba6514a..c5fd532 100644 --- a/packages/processors/src/processors/registry/handlers/roleRevoked.handler.ts +++ b/packages/processors/src/processors/registry/handlers/roleRevoked.handler.ts @@ -5,10 +5,7 @@ import { ChainId, ProcessorEvent } from "@grants-stack-indexer/shared"; import { IEventHandler, ProcessorDependencies } from "../../../internal.js"; -type Dependencies = Pick< - ProcessorDependencies, - "projectRepository" | "evmProvider" | "metadataProvider" | "logger" ->; +type Dependencies = Pick; /** * Handles the RoleRevoked event for the Registry contract from Allo protocol. */ diff --git a/packages/processors/test/helpers/tokenMath.spec.ts b/packages/processors/test/helpers/tokenMath.spec.ts index 3aee76c..4c4d9c7 100644 --- a/packages/processors/test/helpers/tokenMath.spec.ts +++ b/packages/processors/test/helpers/tokenMath.spec.ts @@ -33,7 +33,7 @@ describe("calculateAmountInUsd", () => { }); // Test case for 8 decimal token with float price - it("should correctly calculate USD amount for 8 decimal token with float price", () => { + it("correctly calculates USD amount for 8 decimal token with float price", () => { const amount = 150000000n; // 1.5 tokens const tokenPriceInUsd = 12.75; // $12.75 per token const tokenDecimals = 8; @@ -89,7 +89,7 @@ describe("calculateAmountInUsd", () => { expect(result).toBe("0"); }); - it("should return zero for zero token price", () => { + it("returns zero for zero token price", () => { const amount = 1000000000000000000n; // 1 token const tokenPriceInUsd = 0; const tokenDecimals = 18; diff --git a/packages/processors/test/registry/handlers/profileMetadataUpdated.handler.spec.ts b/packages/processors/test/registry/handlers/profileMetadataUpdated.handler.spec.ts new file mode 100644 index 0000000..a2165d2 --- /dev/null +++ b/packages/processors/test/registry/handlers/profileMetadataUpdated.handler.spec.ts @@ -0,0 +1,80 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { ChainId, ProcessorEvent } from "@grants-stack-indexer/shared"; + +import { ProcessorDependencies } from "../../../src/internal.js"; +import { ProfileMetadataUpdatedHandler } from "../../../src/processors/registry/handlers/profileMetadataUpdated.handler.js"; + +describe("ProfileMetadataUpdatedHandler", () => { + const mockCid = "mockCid"; + const mockEvent: ProcessorEvent<"Registry", "ProfileMetadataUpdated"> = { + params: { + metadata: [0, mockCid], + profileId: "mockProfileId", + }, + // Add other necessary event properties here + } as ProcessorEvent<"Registry", "ProfileMetadataUpdated">; + + const mockDependencies = { + metadataProvider: { + getMetadata: vi.fn(), + }, + logger: { + warn: vi.fn(), + }, + } as unknown as ProcessorDependencies; + + const chainId = 1 as ChainId; + + afterEach(() => { + vi.resetAllMocks(); + }); + + it("handles valid metadata", async () => { + const mockMetadata = { + type: "program", + name: "Test Project", + }; + vi.spyOn(mockDependencies.metadataProvider, "getMetadata").mockResolvedValueOnce( + mockMetadata, + ); + + const handler = new ProfileMetadataUpdatedHandler(mockEvent, chainId, mockDependencies); + const result = await handler.handle(); + + expect(mockDependencies.metadataProvider.getMetadata).toHaveBeenCalledWith(mockCid); + expect(result).toEqual([ + { + type: "UpdateProject", + args: { + chainId, + projectId: mockEvent.params.profileId, + project: { + metadataCid: mockCid, + metadata: mockMetadata, + projectType: "canonical", + }, + }, + }, + ]); + }); + + it("returns an empty array for invalid metadata", async () => { + vi.spyOn(mockDependencies.metadataProvider, "getMetadata").mockResolvedValueOnce(null); + + const handler = new ProfileMetadataUpdatedHandler(mockEvent, chainId, mockDependencies); + const result = await handler.handle(); + + expect(result).toEqual([]); + }); + + it("throws an error if getMetadata fails", async () => { + vi.spyOn(mockDependencies.metadataProvider, "getMetadata").mockRejectedValueOnce( + new Error("Failed to fetch metadata"), + ); + + const handler = new ProfileMetadataUpdatedHandler(mockEvent, chainId, mockDependencies); + + await expect(handler.handle()).rejects.toThrow("Failed to fetch metadata"); + }); +}); diff --git a/packages/processors/test/registry/handlers/profileNameUpdated.handler.spec.ts b/packages/processors/test/registry/handlers/profileNameUpdated.handler.spec.ts new file mode 100644 index 0000000..68230b2 --- /dev/null +++ b/packages/processors/test/registry/handlers/profileNameUpdated.handler.spec.ts @@ -0,0 +1,57 @@ +import { getAddress } from "viem"; +import { describe, expect, it, vi } from "vitest"; + +import { Changeset } from "@grants-stack-indexer/repository"; +import { Bytes32String, ChainId, ProcessorEvent } from "@grants-stack-indexer/shared"; + +import { ProfileNameUpdatedHandler } from "../../../src/processors/registry/handlers/profileNameUpdated.handler.js"; + +describe("ProfileNameUpdatedHandler", () => { + const mockEvent: ProcessorEvent<"Registry", "ProfileNameUpdated"> = { + contractName: "Registry", + eventName: "ProfileNameUpdated", + params: { + profileId: "0xprofile1" as Bytes32String, + name: "New Profile Name", + anchor: "0x5aD1D85Bb68791Cb3cE598f56E00F5D5694FAd14", + }, + blockNumber: 1, + blockTimestamp: 1, + chainId: 1 as ChainId, + logIndex: 1, + srcAddress: "0x0", + transactionFields: { + hash: "0x0", + transactionIndex: 1, + }, + }; + + it("returns a changeset with updated project name and anchor address", async () => { + const handler = new ProfileNameUpdatedHandler(mockEvent, 1 as ChainId, { + logger: { + debug: vi.fn(), + error: vi.fn(), + info: vi.fn(), + warn: vi.fn(), + }, + }); + + const result = await handler.handle(); + + const expectedChangeset: Changeset[] = [ + { + type: "UpdateProject", + args: { + chainId: mockEvent.chainId as ChainId, + projectId: mockEvent.params.profileId, + project: { + name: mockEvent.params.name, + anchorAddress: getAddress(mockEvent.params.anchor), + }, + }, + }, + ]; + + expect(result).toEqual(expectedChangeset); + }); +}); diff --git a/packages/processors/test/registry/handlers/profileOwnerUpdated.handler.spec.ts b/packages/processors/test/registry/handlers/profileOwnerUpdated.handler.spec.ts new file mode 100644 index 0000000..396ad2e --- /dev/null +++ b/packages/processors/test/registry/handlers/profileOwnerUpdated.handler.spec.ts @@ -0,0 +1,72 @@ +import { describe, expect, it, vi } from "vitest"; + +import { Changeset } from "@grants-stack-indexer/repository"; +import { Bytes32String, ChainId, ProcessorEvent } from "@grants-stack-indexer/shared"; + +import { ProfileOwnerUpdatedHandler } from "../../../src/processors/registry/handlers/profileOwnerUpdated.handler.js"; + +describe("ProfileOwnerUpdatedHandler", () => { + it("handles ProfileOwnerUpdated event correctly", async () => { + const mockEvent: ProcessorEvent<"Registry", "ProfileOwnerUpdated"> = { + blockNumber: 123456, + blockTimestamp: 123456, + chainId: 1 as ChainId, + contractName: "Registry", + eventName: "ProfileOwnerUpdated", + logIndex: 0, + srcAddress: "0x1234567890123456789012345678901234567890", + params: { + profileId: "0xprofile123" as Bytes32String, + owner: "0x5aD1D85Bb68791Cb3cE598f56E00F5D5694FAd14", + }, + transactionFields: { + hash: "0xhash", + transactionIndex: 0, + }, + }; + + const mockDependencies = { + logger: { + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + debug: vi.fn(), + }, + }; + + const handler = new ProfileOwnerUpdatedHandler( + mockEvent, + mockEvent.chainId as ChainId, + mockDependencies, + ); + + const result = await handler.handle(); + + const expectedChangeset: Changeset[] = [ + { + type: "DeleteAllProjectRolesByRole", + args: { + projectRole: { + chainId: mockEvent.chainId as ChainId, + projectId: mockEvent.params.profileId, + role: "owner", + }, + }, + }, + { + type: "InsertProjectRole", + args: { + projectRole: { + chainId: mockEvent.chainId as ChainId, + projectId: mockEvent.params.profileId, + address: mockEvent.params.owner, + role: "owner", + createdAtBlock: BigInt(mockEvent.blockNumber), + }, + }, + }, + ]; + + expect(result).toEqual(expectedChangeset); + }); +}); diff --git a/packages/processors/test/registry/handlers/roleRevoked.handler.spec.ts b/packages/processors/test/registry/handlers/roleRevoked.handler.spec.ts new file mode 100644 index 0000000..6a0b80b --- /dev/null +++ b/packages/processors/test/registry/handlers/roleRevoked.handler.spec.ts @@ -0,0 +1,80 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import { IProjectRepository, Project } from "@grants-stack-indexer/repository"; +import { ChainId, ILogger, ProcessorEvent } from "@grants-stack-indexer/shared"; + +import { RoleRevokedHandler } from "../../../src/processors/registry/handlers/roleRevoked.handler.js"; + +describe("RoleRevokedHandler", () => { + let mockEvent: ProcessorEvent<"Registry", "RoleRevoked">; + let mockChainId: ChainId; + let mockDependencies: { projectRepository: IProjectRepository; logger: ILogger }; + let mockedRole: string; + let mockedAccount: string; + + beforeEach(() => { + mockedRole = "0x5aD1D85Bb68791Cb3cE598f56E00F5D5694FAd14ASD"; + mockedAccount = "0x5aD1D85Bb68791Cb3cE598f56E00F5D5694FAd14"; + mockEvent = { + params: { + account: mockedAccount, + role: mockedRole, + }, + } as ProcessorEvent<"Registry", "RoleRevoked">; + + mockChainId = 1 as ChainId; + + mockDependencies = { + projectRepository: { + getProjectById: vi.fn(), + } as unknown as IProjectRepository, + logger: { + info: vi.fn(), + } as unknown as ILogger, + }; + }); + + it("return a changeset when project is found", async () => { + const project = { id: "project-1" }; + vi.spyOn(mockDependencies.projectRepository, "getProjectById").mockResolvedValueOnce({ + ...project, + } as Project); + + const handler = new RoleRevokedHandler(mockEvent, mockChainId, mockDependencies); + const result = await handler.handle(); + + expect(result).toEqual([ + { + type: "DeleteAllProjectRolesByRoleAndAddress", + args: { + projectRole: { + chainId: mockChainId, + projectId: project.id, + address: mockedAccount, + role: "member", + }, + }, + }, + ]); + }); + + it("return an empty array when project is not found", async () => { + vi.spyOn(mockDependencies.projectRepository, "getProjectById").mockResolvedValueOnce( + undefined, + ); + + const handler = new RoleRevokedHandler(mockEvent, mockChainId, mockDependencies); + const result = await handler.handle(); + + expect(result).toEqual([]); + }); + + it("throw an error when getProjectById fails", async () => { + const error = new Error("Database error"); + vi.spyOn(mockDependencies.projectRepository, "getProjectById").mockRejectedValueOnce(error); + + const handler = new RoleRevokedHandler(mockEvent, mockChainId, mockDependencies); + + await expect(handler.handle()).rejects.toThrow(error); + }); +}); diff --git a/packages/processors/test/registry/registry.processor.spec.ts b/packages/processors/test/registry/registry.processor.spec.ts index 030b6b0..80c0b98 100644 --- a/packages/processors/test/registry/registry.processor.spec.ts +++ b/packages/processors/test/registry/registry.processor.spec.ts @@ -45,7 +45,7 @@ describe("RegistryProcessor", () => { await expect(processor.process(event)).rejects.toThrow(UnsupportedEventException); }); - it("should call ProfileCreatedHandler", async () => { + it("calls ProfileCreatedHandler", async () => { const event: ProcessorEvent<"Registry", "ProfileCreated"> = { eventName: "ProfileCreated", } as ProcessorEvent<"Registry", "ProfileCreated">; @@ -59,7 +59,7 @@ describe("RegistryProcessor", () => { expect(result).toEqual([]); // Check if handle returns [] }); - it("should call RoleGrantedHandler", async () => { + it("calls RoleGrantedHandler", async () => { const event: ProcessorEvent<"Registry", "RoleGranted"> = { eventName: "RoleGranted", } as ProcessorEvent<"Registry", "RoleGranted">; diff --git a/packages/processors/test/strategy/donationVotingMerkleDistributionDirectTransfer/helpers/decoder.spec.ts b/packages/processors/test/strategy/donationVotingMerkleDistributionDirectTransfer/helpers/decoder.spec.ts index 2c77c8b..7bfdfc7 100644 --- a/packages/processors/test/strategy/donationVotingMerkleDistributionDirectTransfer/helpers/decoder.spec.ts +++ b/packages/processors/test/strategy/donationVotingMerkleDistributionDirectTransfer/helpers/decoder.spec.ts @@ -4,7 +4,7 @@ import { decodeDVMDApplicationData } from "../../../../src/processors/strategy/d import { DVMDApplicationData } from "../../../../src/processors/strategy/donationVotingMerkleDistributionDirectTransfer/types/index.js"; describe("decodeDVMDApplicationData", () => { - it("should correctly decode the encoded data", () => { + it("correctly decodes the encoded data", () => { const encodedData = "0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001000000000000000000000000002c7296a5ec0539f0a018c7176c97c92a9c44e2b4000000000000000000000000e7eb5d2b5b188777df902e89c54570e7ef4f59ce000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003b6261666b72656967796334336366696e786c6e6168713561617773676869626574763675737273376b6b78663776786d7a626a79726f37366977790000000000"; diff --git a/packages/processors/test/strategy/mapping.spec.ts b/packages/processors/test/strategy/mapping.spec.ts index 811b4a8..913bd82 100644 --- a/packages/processors/test/strategy/mapping.spec.ts +++ b/packages/processors/test/strategy/mapping.spec.ts @@ -6,7 +6,7 @@ import { DVMDDirectTransferStrategyHandler } from "../../src/processors/strategy describe("Strategy Mapping", () => { describe("getHandler", () => { - it("should return the correct handler for a valid strategy ID", () => { + it("returns the correct handler for a valid strategy ID", () => { const validStrategyId = "0x6f9291df02b2664139cec5703c124e4ebce32879c74b6297faa1468aa5ff9ebf"; @@ -17,7 +17,7 @@ describe("Strategy Mapping", () => { expectTypeOf(handler).toEqualTypeOf(); }); - it("should return the correct handler for a valid strategy ID in uppercase", () => { + it("returns the correct handler for a valid strategy ID in uppercase", () => { const validStrategyId = "0x6F9291DF02B2664139CEC5703C124E4EBCE32879C74B6297FAA1468AA5FF9EBF"; @@ -28,7 +28,7 @@ describe("Strategy Mapping", () => { expectTypeOf(handler).toEqualTypeOf(); }); - it("should return undefined for an invalid strategy ID", () => { + it("returns undefined for an invalid strategy ID", () => { const invalidStrategyId = "0x1234567890123456789012345678901234567890123456789012345678901234"; @@ -39,7 +39,7 @@ describe("Strategy Mapping", () => { }); describe("existsHandler", () => { - it("should return true for a valid strategy ID", () => { + it("returns true for a valid strategy ID", () => { const validStrategyId = "0x2f46bf157821dc41daa51479e94783bb0c8699eac63bf75ec450508ab03867ce"; @@ -48,7 +48,7 @@ describe("Strategy Mapping", () => { expect(exists).toBe(true); }); - it("should return true for a valid strategy ID in uppercase", () => { + it("returns true for a valid strategy ID in uppercase", () => { const validStrategyId = "0x2F46BF157821DC41DAA51479E94783BB0C8699EAC63BF75EC450508AB03867CE"; @@ -57,7 +57,7 @@ describe("Strategy Mapping", () => { expect(exists).toBe(true); }); - it("should return false for an invalid strategy ID", () => { + it("returns false for an invalid strategy ID", () => { const invalidStrategyId = "0x1234567890123456789012345678901234567890123456789012345678901234";