Skip to content

Commit

Permalink
feat: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
0xkenj1 committed Nov 12, 2024
1 parent b038c42 commit 38947f8
Show file tree
Hide file tree
Showing 12 changed files with 304 additions and 24 deletions.
2 changes: 1 addition & 1 deletion packages/data-flow/test/unit/eventsRegistry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"> = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ProcessorDependencies, "logger">;
/**
* Handles the ProfileNameUpdated event for the Registry contract from Allo protocol.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ProcessorDependencies, "logger">;
/**
* Handles the ProfileOwnerUpdated event for the Registry contract from Allo protocol.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ProcessorDependencies, "projectRepository" | "logger">;
/**
* Handles the RoleRevoked event for the Registry contract from Allo protocol.
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/processors/test/helpers/tokenMath.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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");
});
});
Original file line number Diff line number Diff line change
@@ -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);
});
});
Original file line number Diff line number Diff line change
@@ -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);
});
});
Original file line number Diff line number Diff line change
@@ -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);
});
});
4 changes: 2 additions & 2 deletions packages/processors/test/registry/registry.processor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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">;
Expand All @@ -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">;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down
Loading

0 comments on commit 38947f8

Please sign in to comment.