Skip to content

Commit

Permalink
fix: pr comments
Browse files Browse the repository at this point in the history
  • Loading branch information
0xkenj1 committed Nov 12, 2024
1 parent 00f4a92 commit 1d60049
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ export class ProjectNotFound extends Error {
super(`Project not found for chainId: ${chainId} and anchorAddress: ${anchorAddress}`);
}
}

export class ProjectByRoleNotFound extends Error {
constructor(chainId: ChainId, role: string) {
super(`Project not found for chainId: ${chainId} and role: ${role}`);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ type Dependencies = Pick<
>;
/**
* Handles the ProfileCreated event for the Registry contract from Allo protocol.
*
* This handler performs the following steps:
* - Fetches the metadata for the profile from the metadata provider
* - Parses the metadata to extract the project type
* - Returns the changeset to insert the project with the metadata
*
* If the metadata is not valid, it sets the metadata to null and the project type to canonical.
*/
export class ProfileCreatedHandler implements IEventHandler<"Registry", "ProfileCreated"> {
constructor(
Expand All @@ -35,14 +42,6 @@ export class ProfileCreatedHandler implements IEventHandler<"Registry", "Profile
projectType = this.getProjectTypeFromMetadata(parsedMetadata.data);
isProgram = parsedMetadata.data.type === "program";
metadataValue = parsedMetadata.data;
} else {
//TODO: Replace with logger
// this.logger.warn({
// msg: `ProfileCreated: Failed to parse metadata for profile ${profileId}`,
// event: this.event,
// metadataCid,
// metadata,
// });
}

const createdBy =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ type Dependencies = Pick<
ProcessorDependencies,
"projectRepository" | "evmProvider" | "metadataProvider" | "logger"
>;

/**
* Handles the ProfileMetadataUpdated event for the Registry contract from Allo protocol.
*
* This handler performs the following steps:
* - Fetches the metadata for the profile from the metadata provider
* - Parses the metadata to extract the project type
* - Returns the changeset to update the project with the metadata
*/
export class ProfileMetadataUpdatedHandler
implements IEventHandler<"Registry", "ProfileMetadataUpdated">
Expand All @@ -19,6 +25,7 @@ export class ProfileMetadataUpdatedHandler
readonly chainId: ChainId,
private dependencies: Dependencies,
) {}
/* @inheritdoc */
async handle(): Promise<Changeset[]> {
const { metadataProvider } = this.dependencies;

Expand All @@ -27,13 +34,20 @@ export class ProfileMetadataUpdatedHandler
const parsedMetadata = ProjectMetadataSchema.safeParse(metadata);

if (!parsedMetadata.success) {
// logger.warn({
// msg: `ProfileMetadataUpdated: Failed to parse metadata`,
// event,
// metadataCid,
// metadata,
// });
return [];
return [
{
type: "UpdateProject",
args: {
chainId: this.chainId,
projectId: this.event.params.profileId,
project: {
metadataCid: metadataCid,
metadata: null,
projectType: "canonical",
},
},
},
];
}

const projectType = this.getProjectTypeFromMetadata(parsedMetadata.data);
Expand All @@ -52,7 +66,6 @@ export class ProfileMetadataUpdatedHandler
},
},
];
return [];
}
private getProjectTypeFromMetadata(metadata: ProjectMetadata): ProjectType {
// if the metadata contains a canonical reference, it's a linked project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import { IEventHandler, ProcessorDependencies } from "../../../internal.js";
type Dependencies = Pick<ProcessorDependencies, "logger">;
/**
* Handles the ProfileNameUpdated event for the Registry contract from Allo protocol.
*
* This handler performs the following steps:
* - Returns the changeset to update the project with the new name
*/
export class ProfileNameUpdatedHandler implements IEventHandler<"Registry", "ProfileNameUpdated"> {
constructor(
readonly event: ProcessorEvent<"Registry", "ProfileNameUpdated">,
readonly chainId: ChainId,
private dependencies: Dependencies,
) {}
/* @inheritdoc */
async handle(): Promise<Changeset[]> {
return [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import { IEventHandler, ProcessorDependencies } from "../../../internal.js";
type Dependencies = Pick<ProcessorDependencies, "logger">;
/**
* Handles the ProfileOwnerUpdated event for the Registry contract from Allo protocol.
*
* This handler performs the following steps:
*
* - Returns the changeset to delete all project roles with the role "owner"
* for the profile and insert a new project role with the new owner address.
*/
export class ProfileOwnerUpdatedHandler
implements IEventHandler<"Registry", "ProfileOwnerUpdated">
Expand All @@ -17,6 +22,7 @@ export class ProfileOwnerUpdatedHandler
readonly chainId: ChainId,
private dependencies: Dependencies,
) {}
/* @inheritdoc */
async handle(): Promise<Changeset[]> {
return [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ import { getAddress } from "viem";
import { Changeset } from "@grants-stack-indexer/repository";
import { ChainId, ProcessorEvent } from "@grants-stack-indexer/shared";

import { IEventHandler, ProcessorDependencies } from "../../../internal.js";
import { IEventHandler, ProcessorDependencies, ProjectByRoleNotFound } from "../../../internal.js";

type Dependencies = Pick<ProcessorDependencies, "projectRepository" | "logger">;
/**
* Handles the RoleRevoked event for the Registry contract from Allo protocol.
*
* This handler performs the following steps:
*
* - Returns the changeset to delete all project roles with the role "member"
* for the profile and address.
*
* If the project with the role id doesn't exist, it throws an error.
*/
export class RoleRevokedHandler implements IEventHandler<"Registry", "RoleRevoked"> {
constructor(
Expand All @@ -25,7 +32,7 @@ export class RoleRevokedHandler implements IEventHandler<"Registry", "RoleRevoke
// which is the project id in this database.
// If we don't find a project with that id we can't remove the role.
if (!project) {
return [];
throw new ProjectByRoleNotFound(this.chainId, role);
}

return [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,20 @@ describe("ProfileMetadataUpdatedHandler", () => {
const handler = new ProfileMetadataUpdatedHandler(mockEvent, chainId, mockDependencies);
const result = await handler.handle();

expect(result).toEqual([]);
expect(result).toEqual([
{
type: "UpdateProject",
args: {
chainId,
projectId: mockEvent.params.profileId,
project: {
metadataCid: mockCid,
metadata: null,
projectType: "canonical",
},
},
},
]);
});

it("throws an error if getMetadata fails", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ 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 { ProjectByRoleNotFound } from "../../../src/internal.js";
import { RoleRevokedHandler } from "../../../src/processors/registry/handlers/roleRevoked.handler.js";

describe("RoleRevokedHandler", () => {
Expand Down Expand Up @@ -64,9 +65,8 @@ describe("RoleRevokedHandler", () => {
);

const handler = new RoleRevokedHandler(mockEvent, mockChainId, mockDependencies);
const result = await handler.handle();

expect(result).toEqual([]);
await expect(handler.handle()).rejects.toThrow(ProjectByRoleNotFound);
});

it("throw an error when getProjectById fails", async () => {
Expand Down
91 changes: 90 additions & 1 deletion packages/processors/test/registry/registry.processor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import type { ChainId, ProcessorEvent, RegistryEvent } from "@grants-stack-index

import { ProcessorDependencies, UnsupportedEventException } from "../../src/internal.js";
import { ProfileCreatedHandler } from "../../src/processors/registry/handlers/profileCreated.handler.js";
import { ProfileMetadataUpdatedHandler } from "../../src/processors/registry/handlers/profileMetadataUpdated.handler.js";
import { ProfileNameUpdatedHandler } from "../../src/processors/registry/handlers/profileNameUpdated.handler.js";
import { ProfileOwnerUpdatedHandler } from "../../src/processors/registry/handlers/profileOwnerUpdated.handler.js";
import { RoleGrantedHandler } from "../../src/processors/registry/handlers/roleGranted.handler.js";
import { RoleRevokedHandler } from "../../src/processors/registry/handlers/roleRevoked.handler.js";
import { RegistryProcessor } from "../../src/processors/registry/registry.processor.js";

// Mock the handlers and their handle methods
Expand All @@ -17,7 +21,6 @@ vi.mock("../../src/processors/registry/handlers/roleGranted.handler.js", () => {
};
});

// Mock the handlers and their handle methods
vi.mock("../../src/processors/registry/handlers/profileCreated.handler.js", () => {
const ProfileCreatedHandler = vi.fn();
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
Expand All @@ -27,6 +30,40 @@ vi.mock("../../src/processors/registry/handlers/profileCreated.handler.js", () =
};
});

vi.mock("../../src/processors/registry/handlers/profileOwnerUpdated.handler.js", () => {
const ProfileOwnerUpdatedHandler = vi.fn();
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
ProfileOwnerUpdatedHandler.prototype.handle = vi.fn();
return {
ProfileOwnerUpdatedHandler,
};
});

vi.mock("../../src/processors/registry/handlers/roleRevoked.handler.js", () => {
const RoleRevokedHandler = vi.fn();
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
RoleRevokedHandler.prototype.handle = vi.fn();
return {
RoleRevokedHandler,
};
});
vi.mock("../../src/processors/registry/handlers/profileMetadataUpdated.handler.js", () => {
const ProfileMetadataUpdatedHandler = vi.fn();
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
ProfileMetadataUpdatedHandler.prototype.handle = vi.fn();
return {
ProfileMetadataUpdatedHandler,
};
});
vi.mock("../../src/processors/registry/handlers/profileNameUpdated.handler.js", () => {
const ProfileNameUpdatedHandler = vi.fn();
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
ProfileNameUpdatedHandler.prototype.handle = vi.fn();
return {
ProfileNameUpdatedHandler,
};
});

describe("RegistryProcessor", () => {
const chainId: ChainId = 10 as ChainId; // Replace with appropriate chainId
const dependencies: ProcessorDependencies = {} as ProcessorDependencies; // Replace with actual dependencies
Expand Down Expand Up @@ -72,4 +109,56 @@ describe("RegistryProcessor", () => {
expect(RoleGrantedHandler.prototype.handle).toHaveBeenCalled();
expect(result).toEqual([]); // Check if handle returns []
});
it("calls ProfileOwnerUpdatedHandler", async () => {
const event: ProcessorEvent<"Registry", "ProfileOwnerUpdated"> = {
eventName: "ProfileOwnerUpdated",
} as ProcessorEvent<"Registry", "ProfileOwnerUpdated">;

vi.spyOn(ProfileOwnerUpdatedHandler.prototype, "handle").mockResolvedValue([]);

const processor = new RegistryProcessor(chainId, dependencies);
const result = await processor.process(event);

expect(ProfileOwnerUpdatedHandler.prototype.handle).toHaveBeenCalled();
expect(result).toEqual([]); // Check if handle returns []
});
it("calls RoleRevokedHandler", async () => {
const event: ProcessorEvent<"Registry", "RoleRevoked"> = {
eventName: "RoleRevoked",
} as ProcessorEvent<"Registry", "RoleRevoked">;

vi.spyOn(RoleRevokedHandler.prototype, "handle").mockResolvedValue([]);

const processor = new RegistryProcessor(chainId, dependencies);
const result = await processor.process(event);

expect(RoleRevokedHandler.prototype.handle).toHaveBeenCalled();
expect(result).toEqual([]); // Check if handle returns []
});
it("calls ProfileMetadataUpdatedHandler", async () => {
const event: ProcessorEvent<"Registry", "ProfileMetadataUpdated"> = {
eventName: "ProfileMetadataUpdated",
} as ProcessorEvent<"Registry", "ProfileMetadataUpdated">;

vi.spyOn(ProfileMetadataUpdatedHandler.prototype, "handle").mockResolvedValue([]);

const processor = new RegistryProcessor(chainId, dependencies);
const result = await processor.process(event);

expect(ProfileMetadataUpdatedHandler.prototype.handle).toHaveBeenCalled();
expect(result).toEqual([]); // Check if handle returns []
});
it("calls ProfileNameUpdatedHandler", async () => {
const event: ProcessorEvent<"Registry", "ProfileNameUpdated"> = {
eventName: "ProfileNameUpdated",
} as ProcessorEvent<"Registry", "ProfileNameUpdated">;

vi.spyOn(ProfileNameUpdatedHandler.prototype, "handle").mockResolvedValue([]);

const processor = new RegistryProcessor(chainId, dependencies);
const result = await processor.process(event);

expect(ProfileNameUpdatedHandler.prototype.handle).toHaveBeenCalled();
expect(result).toEqual([]); // Check if handle returns []
});
});
2 changes: 1 addition & 1 deletion packages/repository/src/types/project.types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Address, ChainId } from "@grants-stack-indexer/shared";

export type ProjectType = "canonical" | "linked";
export type ProjectType = "canonical" | "linked" | "unknown";

export type Project = {
id: string;
Expand Down

0 comments on commit 1d60049

Please sign in to comment.