Skip to content

Commit 2f6e70a

Browse files
committed
chore: fix tests
1 parent 100bfb3 commit 2f6e70a

File tree

4 files changed

+141
-41
lines changed

4 files changed

+141
-41
lines changed

src/calculator/index.ts

Lines changed: 76 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -280,41 +280,106 @@ export default class Calculator {
280280
/**
281281
* Estimates matching for a given project and potential additional votes
282282
* @param potentialVotes
283+
* @param roundId
283284
*/
284285
async estimateMatching(
285-
potentialVotes: Vote[],
286-
roundId: string,
287-
roundToken: string
286+
potentialVotes: PotentialVote[],
287+
roundId: string
288288
): Promise<MatchingEstimateResult[]> {
289289
const votes = await this.parseJSONFile<Vote>(
290290
"votes",
291291
`${this.chainId}/rounds/${this.roundId}/votes.json`
292292
);
293293

294+
const rounds = await this.parseJSONFile<Round>(
295+
"rounds",
296+
`${this.chainId}/rounds.json`
297+
);
298+
299+
const round = rounds.find((r: Round) => r.id === this.roundId);
300+
301+
if (round === undefined) {
302+
throw new ResourceNotFoundError("round");
303+
}
304+
305+
if (round.matchAmount === undefined) {
306+
throw new ResourceNotFoundError("round match amount");
307+
}
308+
309+
if (round.token === undefined) {
310+
throw new ResourceNotFoundError("round token");
311+
}
312+
313+
const applications = await this.parseJSONFile<Application>(
314+
"applications",
315+
`${this.chainId}/rounds/${this.roundId}/applications.json`
316+
);
317+
294318
const currentResults = await this._calculate(votes);
319+
const potentialVotesAugmented: Vote[] = await Promise.all(
320+
potentialVotes.map(async (vote) => {
321+
const { amount: amountUSD } = await this.priceProvider.convertToUSD(
322+
this.chainId,
323+
vote.token,
324+
vote.amount
325+
);
326+
327+
const { amount: amountRoundToken } =
328+
await this.priceProvider.convertFromUSD(
329+
this.chainId,
330+
round.token,
331+
amountUSD
332+
);
333+
334+
/* Find the latest approved application */
335+
const application = applications
336+
.filter(
337+
(application) =>
338+
application.metadata?.application.recipient === vote.recipient
339+
)
340+
.filter((application) => application.status === "APPROVED")
341+
.sort((a, b) => a.statusUpdatedAtBlock - b.statusUpdatedAtBlock)[0];
342+
if (!application) {
343+
throw "Couldn't find application for project";
344+
}
345+
return {
346+
amount: vote.amount.toString(),
347+
amountRoundToken: amountRoundToken.toString(),
348+
amountUSD,
349+
token: vote.token,
350+
roundId: this.roundId,
351+
voter: vote.contributor,
352+
grantAddress: vote.recipient,
353+
projectId: application.projectId,
354+
id: "",
355+
applicationId: application.id,
356+
};
357+
})
358+
);
295359
const potentialResults = await this._calculate([
296360
...votes,
297-
...potentialVotes,
361+
...potentialVotesAugmented,
298362
]);
299363

300364
const finalResults: MatchingEstimateResult[] = [];
301365

302-
for (const key in potentialResults) {
303-
const potentialResult = potentialResults[key];
304-
const currentResult = currentResults[key];
366+
for (const potentialResult of potentialResults) {
367+
const currentResult = currentResults.find(
368+
(res) => res.applicationId === potentialResult.applicationId
369+
);
305370

306371
/* Subtracting undefined from a bigint would fail,
307372
* so we explicitly subtract 0 if it's undefined */
308373
const difference =
309-
potentialResult.matched - (currentResult.matched ?? 0n);
374+
potentialResult.matched - (currentResult?.matched ?? 0n);
310375
const differenceInUSD = await this.priceProvider.convertToUSD(
311376
this.chainId,
312-
roundToken,
377+
round.token,
313378
difference
314379
);
315380

316-
const recipient = potentialVotes.find(
317-
(vote) => vote.applicationId == key
381+
const recipient = potentialVotesAugmented.find(
382+
(vote) => vote.applicationId === potentialResult.applicationId
318383
)?.grantAddress;
319384

320385
/** Can be undefined, but spreading an undefined is a no-op, so it's okay here */

src/http/api/v1/matches.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ export const createHandler = (config: HttpApiConfig): express.Router => {
113113
res.send(responseBody);
114114
}
115115

116-
router.post("/chains/:chainId/rounds/:roundId/estimate", (req, res) => {
117-
return estimateMatchesHandler(req, res, 200);
116+
router.post("/chains/:chainId/rounds/:roundId/estimate", async (req, res) => {
117+
await estimateMatchesHandler(req, res, 200);
118118
});
119119

120120
async function estimateMatchesHandler(
@@ -149,7 +149,7 @@ export const createHandler = (config: HttpApiConfig): express.Router => {
149149
};
150150

151151
const calculator = new Calculator(calculatorOptions);
152-
const matches = await calculator.estimateMatching(potentialVotes);
152+
const matches = await calculator.estimateMatching(potentialVotes, roundId);
153153
const responseBody = JSON.stringify(matches, (_key, value) =>
154154
typeof value === "bigint" ? value.toString() : (value as unknown)
155155
);

src/http/app.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { createHandler as createApiHandler } from "./api/v1/index.js";
1111
import { PriceProvider } from "../prices/provider.js";
1212
import { PassportProvider } from "../passport/index.js";
1313
import { DataProvider } from "../calculator/index.js";
14-
import bodyParser from "body-parser";
1514
import { Chain } from "../config.js";
1615

1716
export interface HttpApiConfig {
@@ -32,10 +31,11 @@ interface HttpApi {
3231

3332
export const createHttpApi = (config: HttpApiConfig): HttpApi => {
3433
const app = express();
35-
const api = createApiHandler(config);
3634

3735
app.use(cors());
38-
app.use(bodyParser.json());
36+
app.use(express.json());
37+
38+
const api = createApiHandler(config);
3939

4040
app.use((_req, res, next) => {
4141
if (config.buildTag !== null) {

src/test/http/app.test.ts

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { Logger } from "pino";
1616
import { PotentialVotes } from "../../http/api/v1/matches.js";
1717
import { PassportScore } from "../../passport/index.js";
1818
import { Chain } from "../../config.js";
19+
import { constants } from "ethers";
1920

2021
vi.spyOn(os, "hostname").mockReturnValue("dummy-hostname");
2122

@@ -325,59 +326,93 @@ describe("server", () => {
325326
expect(resp.body).toEqual(expectedResults);
326327
});
327328

328-
test("should estimate matching with new votes for projects", async () => {
329-
const expectedResults = {
330-
"application-id-1": {
329+
test.only("should estimate matching with new votes for projects", async () => {
330+
const expectedResults = [
331+
{
332+
applicationId: "application-id-1",
331333
capOverflow: "0",
334+
chainId: 1,
332335
contributionsCount: "4",
333-
difference: "-171",
334-
matched: "1189",
335-
matchedWithoutCap: "1189",
336+
difference: "0",
337+
differenceInUSD: 0,
338+
matched: "1360",
339+
matchedUSD: 0,
340+
matchedWithoutCap: "1360",
341+
payoutAddress: "grant-address-1",
342+
projectId: "project-id-1",
343+
recipient: "grant-address-1",
344+
roundId: "0x1234",
336345
sumOfSqrt: "70",
337-
totalReceived: "1510",
346+
totalReceived: "1500",
338347
},
339-
"application-id-2": {
348+
{
349+
applicationId: "application-id-2",
340350
capOverflow: "0",
351+
chainId: 1,
341352
contributionsCount: "8",
342-
difference: "964",
343-
matched: "3124",
344-
matchedWithoutCap: "3124",
345-
sumOfSqrt: "102",
346-
totalReceived: "1500",
353+
difference: "0",
354+
differenceInUSD: 0,
355+
matched: "2160",
356+
matchedUSD: 0,
357+
matchedWithoutCap: "2160",
358+
payoutAddress: "grant-address-2",
359+
projectId: "project-id-2",
360+
recipient: "grant-address-2",
361+
roundId: "0x1234",
362+
sumOfSqrt: "80",
363+
totalReceived: "1000",
347364
},
348-
"application-id-3": {
365+
{
366+
applicationId: "application-id-3",
349367
capOverflow: "0",
368+
chainId: 1,
350369
contributionsCount: "7",
351-
difference: "-795",
352-
matched: "5685",
353-
matchedWithoutCap: "5685",
370+
difference: "0",
371+
differenceInUSD: 0,
372+
matched: "6480",
373+
matchedUSD: 0,
374+
matchedWithoutCap: "6480",
375+
payoutAddress: "grant-address-3",
376+
projectId: "project-id-3",
377+
recipient: "0x0000000000000000000000000000000000000000",
378+
roundId: "0x1234",
354379
sumOfSqrt: "140",
355380
totalReceived: "3400",
356381
},
357-
};
382+
];
358383

359384
const potentialVotes: PotentialVotes = [
360385
{
361386
amount: 10n,
362387
contributor: "voter-1",
363388
recipient: "grant-address-1",
364-
token: "0",
389+
token: constants.AddressZero,
365390
},
366391
{
367392
amount: 500n,
368393
contributor: "voter-2",
369394
recipient: "grant-address-2",
370-
token: "0",
395+
token: constants.AddressZero,
371396
},
372397
];
373398

399+
const replacer = (
400+
_key: string,
401+
value: bigint | string | number | object
402+
) => (typeof value === "bigint" ? value.toString() : value);
403+
374404
const resp = await request(app)
375405
.post("/api/v1/chains/1/rounds/0x1234/estimate")
376-
.send({
377-
potentialVotes,
378-
})
379406
.set("Content-Type", "application/json")
380-
.set("Accept", "application/json");
407+
.set("Accept", "application/json")
408+
.send(
409+
JSON.stringify(
410+
{
411+
potentialVotes,
412+
},
413+
replacer
414+
)
415+
);
381416
expect(resp.statusCode).toBe(200);
382417
expect(resp.body).toEqual(expectedResults);
383418
});

0 commit comments

Comments
 (0)