Skip to content

Commit

Permalink
fix: pr comments
Browse files Browse the repository at this point in the history
  • Loading branch information
0xkenj1 committed Dec 9, 2024
1 parent da7bbe7 commit 3c07513
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 46 deletions.
6 changes: 5 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ module.exports = {
"@typescript-eslint/no-unsafe-return": "error",
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "_+", ignoreRestSiblings: true },
{
argsIgnorePattern: "_+",
ignoreRestSiblings: true,
destructuredArrayIgnorePattern: "^_",
},
],
"@typescript-eslint/prefer-as-const": "warn",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,14 @@ export class PoolFundedHandler implements IEventHandler<"Allo", "PoolFunded"> {
private readonly chainId: ChainId,
private readonly dependencies: Dependencies,
) {}

/* @inheritdoc */
async handle(): Promise<Changeset[]> {
const poolId = this.event.params.poolId.toString();
const fundedAmount = BigInt(this.event.params.amount);
const { roundRepository, pricingProvider } = this.dependencies;

const round = await roundRepository.getRoundById(this.chainId, poolId);
const round = await roundRepository.getRoundByIdOrThrow(this.chainId, poolId);

if (!round) {
return [];
}
const token = getToken(this.chainId, round.matchTokenAddress);

//TODO: Review this on Advace Recovery Milestone
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import type { ChainId, ProcessorEvent } from "@grants-stack-indexer/shared";
import { getToken } from "@grants-stack-indexer/shared";

import type { IEventHandler, ProcessorDependencies } from "../../../internal.js";
import { getTokenAmountInUsd } from "../../../helpers/pricing.js";
import { getTokenAmountInUsd } from "../../../helpers/index.js";
import { RoundMetadataSchema } from "../../../schemas/index.js";

type Dependencies = Pick<
ProcessorDependencies,
"metadataProvider" | "roundRepository" | "logger" | "pricingProvider"
"metadataProvider" | "roundRepository" | "pricingProvider"
>;

/**
Expand All @@ -26,27 +26,21 @@ export class PoolMetadataUpdatedHandler implements IEventHandler<"Allo", "PoolMe
private readonly chainId: ChainId,
private readonly dependencies: Dependencies,
) {}

/* @inheritdoc */
async handle(): Promise<Changeset[]> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_protocol, metadataPointer] = this.event.params.metadata;
const { metadataProvider, pricingProvider, roundRepository, logger } = this.dependencies;
const { metadataProvider, pricingProvider, roundRepository } = this.dependencies;

const metadata = await metadataProvider.getMetadata<{
round?: unknown;
application?: unknown;
}>(metadataPointer);

const round = await roundRepository.getRoundById(
const round = await roundRepository.getRoundByIdOrThrow(
this.chainId,
this.event.params.poolId.toString(),
);

if (!round) {
logger.error(`Round not found for roundId: ${this.event.params.poolId.toString()}`);
return [];
}

let matchAmount = round.matchAmount;
let matchAmountInUsd = round.matchAmountInUsd;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class RoleGrantedHandler implements IEventHandler<"Allo", "RoleGranted">
private readonly chainId: ChainId,
private readonly dependencies: Dependencies,
) {}

/* @inheritdoc */
async handle(): Promise<Changeset[]> {
const role = this.event.params.role.toLowerCase();
const account = getAddress(this.event.params.account);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class RoleRevokedHandler implements IEventHandler<"Allo", "RoleRevoked">
private readonly chainId: ChainId,
private readonly dependencies: Dependencies,
) {}

/* @inheritdoc */
async handle(): Promise<Changeset[]> {
const role = this.event.params.role.toLowerCase();
const account = getAddress(this.event.params.account);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export class BaseDistributionUpdatedHandler
/* @inheritdoc */
async handle(): Promise<Changeset[]> {
const { logger, metadataProvider } = this.dependencies;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, pointer] = this.event.params.metadata;

const strategyAddress = getAddress(this.event.srcAddress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ describe("PoolFundedHandler", () => {
beforeEach(() => {
mockRoundRepository = {
getRoundById: vi.fn(),
getRoundByIdOrThrow: vi.fn(),
} as unknown as IRoundReadRepository;
mockPricingProvider = {
getTokenPrice: vi.fn(),
Expand Down Expand Up @@ -82,7 +83,7 @@ describe("PoolFundedHandler", () => {
id: "1",
matchTokenAddress: mockToken?.address,
};
vi.spyOn(mockRoundRepository, "getRoundById").mockResolvedValue(round as Round);
vi.spyOn(mockRoundRepository, "getRoundByIdOrThrow").mockResolvedValue(round as Round);
vi.spyOn(mockPricingProvider, "getTokenPrice").mockResolvedValue(mockPrice);

handler = new PoolFundedHandler(
Expand All @@ -93,7 +94,7 @@ describe("PoolFundedHandler", () => {

const result = await handler.handle();

expect(mockRoundRepository.getRoundById).toHaveBeenCalledWith(10, "1");
expect(mockRoundRepository.getRoundByIdOrThrow).toHaveBeenCalledWith(10, "1");
expect(mockPricingProvider.getTokenPrice).toHaveBeenCalled();
expect(result).toEqual([
{
Expand All @@ -112,20 +113,18 @@ describe("PoolFundedHandler", () => {
]);
});

it("returns an empty changeset if the round does not exist", async () => {
it("throw if the round does not exist", async () => {
const mockEvent = createMockEvent();
vi.spyOn(mockRoundRepository, "getRoundById").mockResolvedValue(undefined);
const roundError = new Error("Round not found");
vi.spyOn(mockRoundRepository, "getRoundByIdOrThrow").mockRejectedValue(roundError);

handler = new PoolFundedHandler(
mockEvent,
mockEvent.chainId as ChainId,
mockDependencies(),
);

const result = await handler.handle();

expect(mockRoundRepository.getRoundById).toHaveBeenCalledWith(mockEvent.chainId, "1");
expect(result).toEqual([]);
await expect(handler.handle()).rejects.toThrowError(roundError);
});

it("throws an error for an unknown token", async () => {
Expand All @@ -134,7 +133,7 @@ describe("PoolFundedHandler", () => {
id: "1",
matchTokenAddress: "0xUnknownToken",
};
vi.spyOn(mockRoundRepository, "getRoundById").mockResolvedValue(mockRound as Round);
vi.spyOn(mockRoundRepository, "getRoundByIdOrThrow").mockResolvedValue(mockRound as Round);

handler = new PoolFundedHandler(
mockEvent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ describe("PoolMetadataUpdatedHandler", () => {
};
mockRoundRepository = {
getRoundById: vi.fn(),
getRoundByIdOrThrow: vi.fn(),
} as unknown as IRoundReadRepository;
mockLogger = {
error: vi.fn(),
Expand Down Expand Up @@ -102,7 +103,7 @@ describe("PoolMetadataUpdatedHandler", () => {
timestampMs: 1708369911,
};
vi.spyOn(mockMetadataProvider, "getMetadata").mockResolvedValue(metadata);
vi.spyOn(mockRoundRepository, "getRoundById").mockResolvedValue(round as Round);
vi.spyOn(mockRoundRepository, "getRoundByIdOrThrow").mockResolvedValue(round as Round);
vi.spyOn(mockPricingProvider, "getTokenPrice").mockResolvedValue(mockTokenPrice);

handler = new PoolMetadataUpdatedHandler(
Expand All @@ -119,7 +120,7 @@ describe("PoolMetadataUpdatedHandler", () => {
expect(mockMetadataProvider.getMetadata).toHaveBeenCalledWith(
"bafkreihrjyu5tney6wia2hmkertc74nzfpsgxw2epvnxm72bxj6ifnd4ku",
);
expect(mockRoundRepository.getRoundById).toHaveBeenCalledWith(10, "1");
expect(mockRoundRepository.getRoundByIdOrThrow).toHaveBeenCalledWith(10, "1");
expect(result).toEqual([
{
type: "UpdateRound",
Expand All @@ -145,19 +146,6 @@ describe("PoolMetadataUpdatedHandler", () => {
]);
});

it("returns an empty changeset if the round does not exist", async () => {
const mockEvent = createMockEvent();
vi.spyOn(mockRoundRepository, "getRoundById").mockResolvedValue(undefined);

handler = new PoolMetadataUpdatedHandler(mockEvent, 10 as ChainId, mockDependencies());

const result = await handler.handle();

expect(mockRoundRepository.getRoundById).toHaveBeenCalledWith(10, "1");
expect(result).toEqual([]);
expect(mockLogger.error).toHaveBeenCalledWith("Round not found for roundId: 1");
});

it("throws if tokenPrice is not found", async () => {
const mockEvent = createMockEvent();
const mockToken = Object.values(
Expand All @@ -182,7 +170,7 @@ describe("PoolMetadataUpdatedHandler", () => {
};

vi.spyOn(mockMetadataProvider, "getMetadata").mockResolvedValue(metadata);
vi.spyOn(mockRoundRepository, "getRoundById").mockResolvedValue(round as Round);
vi.spyOn(mockRoundRepository, "getRoundByIdOrThrow").mockResolvedValue(round as Round);
vi.spyOn(mockPricingProvider, "getTokenPrice").mockResolvedValue(undefined);

handler = new PoolMetadataUpdatedHandler(mockEvent, 10 as ChainId, mockDependencies());
Expand All @@ -191,6 +179,27 @@ describe("PoolMetadataUpdatedHandler", () => {
expect(mockPricingProvider.getTokenPrice).toHaveBeenCalled();
});

it("throws if round is not found", async () => {
const mockEvent = createMockEvent();
const metadata = {
round: {
name: "asd",
roundType: "public",
quadraticFundingConfig: {
matchingFundsAvailable: 100,
},
},
};
const roundError = new Error("Round not found");
vi.spyOn(mockMetadataProvider, "getMetadata").mockResolvedValue(metadata);
vi.spyOn(mockRoundRepository, "getRoundByIdOrThrow").mockRejectedValue(roundError);
vi.spyOn(mockPricingProvider, "getTokenPrice").mockResolvedValue(undefined);

handler = new PoolMetadataUpdatedHandler(mockEvent, 10 as ChainId, mockDependencies());

await expect(handler.handle()).rejects.toThrowError(roundError);
});

it("returns a changeset with empty metadata if metadata parsing fails", async () => {
const mockEvent = createMockEvent();
const metadata = { round: null };
Expand All @@ -202,7 +211,7 @@ describe("PoolMetadataUpdatedHandler", () => {
};

vi.spyOn(mockMetadataProvider, "getMetadata").mockResolvedValue(metadata);
vi.spyOn(mockRoundRepository, "getRoundById").mockResolvedValue(round as Round);
vi.spyOn(mockRoundRepository, "getRoundByIdOrThrow").mockResolvedValue(round as Round);

handler = new PoolMetadataUpdatedHandler(mockEvent, 10 as ChainId, mockDependencies());

Expand Down
6 changes: 6 additions & 0 deletions packages/repository/src/exceptions/roundNotFound.exception.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ export class RoundNotFound extends Error {
super(`Round not found for chainId: ${chainId} and strategyAddress: ${strategyAddress}`);
}
}

export class RoundNotFoundForId extends Error {
constructor(chainId: ChainId, roundId: string) {
super(`Round not found for chainId: ${chainId} and roundId: ${roundId}`);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ export interface IRoundReadRepository {
*/
getRoundById(chainId: ChainId, roundId: string): Promise<Round | undefined>;

/**
* Retrieves a specific round by its ID and chain ID.
* @param chainId The chain ID of the round.
* @param roundId The ID of the round to fetch.
* @returns A promise that resolves to a Round object
* @throws {RoundNotFoundForId} if the round does not exist
*/
getRoundByIdOrThrow(chainId: ChainId, roundId: string): Promise<Round>;
/**
* Retrieves a round by its strategy address and chain ID.
* @param chainId The chain ID of the round.
Expand Down
11 changes: 11 additions & 0 deletions packages/repository/src/repositories/kysely/round.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
PendingRoundRole,
Round,
RoundNotFound,
RoundNotFoundForId,
RoundRole,
RoundRoleNames,
} from "../../internal.js";
Expand Down Expand Up @@ -45,6 +46,16 @@ export class KyselyRoundRepository implements IRoundRepository {
.executeTakeFirst();
}

/* @inheritdoc */
async getRoundByIdOrThrow(chainId: ChainId, roundId: string): Promise<Round> {
const round = await this.getRoundById(chainId, roundId);

if (!round) {
throw new RoundNotFoundForId(chainId, roundId);
}
return round;
}

/* @inheritdoc */
async getRoundByStrategyAddress(
chainId: ChainId,
Expand Down

0 comments on commit 3c07513

Please sign in to comment.