From 21540dc92e5e8a4d3e0e31b4695027cba0675e10 Mon Sep 17 00:00:00 2001 From: Atmosfearful <88635679+Atmosfearful@users.noreply.github.com> Date: Fri, 29 Sep 2023 16:38:49 -0700 Subject: [PATCH] Fix #1607 (#1608) * test: add tests for /projects/:id (failing) * fix #1607 and pass tests --- .../src/routes/projects/[id]/get.ts | 1 + .../utils/helpers/fetchPoolPricesAndStats.ts | 2 +- .../test/fixtures/carbonProjects.ts | 10 +- carbonmark-api/test/fixtures/digitalCarbon.ts | 90 ++++++++++++++ .../test/routes/projects/[id]/get.test.ts | 116 ++++++++++++++++++ 5 files changed, 214 insertions(+), 5 deletions(-) create mode 100644 carbonmark-api/test/fixtures/digitalCarbon.ts create mode 100644 carbonmark-api/test/routes/projects/[id]/get.test.ts diff --git a/carbonmark-api/src/routes/projects/[id]/get.ts b/carbonmark-api/src/routes/projects/[id]/get.ts index 5a7c9da8a3..5cb1188210 100644 --- a/carbonmark-api/src/routes/projects/[id]/get.ts +++ b/carbonmark-api/src/routes/projects/[id]/get.ts @@ -37,6 +37,7 @@ const handler = (fastify: FastifyInstance) => fetchPoolPricesAndStats(sdk, { key, vintage, + network: request.query.network || "polygon", }), fetchMarketplaceListings(sdk, { key, diff --git a/carbonmark-api/src/utils/helpers/fetchPoolPricesAndStats.ts b/carbonmark-api/src/utils/helpers/fetchPoolPricesAndStats.ts index 40eacfbf5b..0ba81cb84d 100644 --- a/carbonmark-api/src/utils/helpers/fetchPoolPricesAndStats.ts +++ b/carbonmark-api/src/utils/helpers/fetchPoolPricesAndStats.ts @@ -8,7 +8,7 @@ import { fetchProjectPoolInfo, Stats } from "./fetchProjectPoolInfo"; type Params = { key: string; // Project key `"VCS-981"` vintage: string; // Vintage string `"2017"` - network?: NetworkParam; + network: NetworkParam; }; /** diff --git a/carbonmark-api/test/fixtures/carbonProjects.ts b/carbonmark-api/test/fixtures/carbonProjects.ts index 0a0d70675e..6881dcba7d 100644 --- a/carbonmark-api/test/fixtures/carbonProjects.ts +++ b/carbonmark-api/test/fixtures/carbonProjects.ts @@ -3,7 +3,7 @@ import { aProjectContent, } from "../../src/.generated/mocks/carbonProjects.mocks"; -const content = aProjectContent({ +const projectContent = aProjectContent({ project: { registry: "VCS", registryProjectId: "191", @@ -12,7 +12,7 @@ const content = aProjectContent({ longDescription: "Long description for vcs-101", }); -const cmsProject = aProject({ +const project = aProject({ country: "China", registry: "VCS", registryProjectId: "191", @@ -20,7 +20,7 @@ const cmsProject = aProject({ // Generated types are wrong, id is string - https://github.com/KlimaDAO/klimadao/issues/1500 const carbonProject = { - ...cmsProject, + ...project, // override these because the type from aProject() is wrong id: "VCS-191", methodologies: [ @@ -30,11 +30,13 @@ const carbonProject = { name: "Grid-connected electricity generation from renewable sources", }, ], - content, + content: projectContent, }; /** Fixtures for queries to the carbon-projects cms */ const fixtures = { + projectContent, + project, /** Project entry in `fetchAllProjects` query */ carbonProject, }; diff --git a/carbonmark-api/test/fixtures/digitalCarbon.ts b/carbonmark-api/test/fixtures/digitalCarbon.ts new file mode 100644 index 0000000000..c763ee7d2d --- /dev/null +++ b/carbonmark-api/test/fixtures/digitalCarbon.ts @@ -0,0 +1,90 @@ +import { + aCarbonCredit, + aCarbonPool, + aCarbonPoolCreditBalance, + aCarbonProject, +} from "../../src/.generated/mocks/digitalCarbon.mocks"; +import { POOL_INFO } from "../../src/routes/projects/get.constants"; + +const TCO2_VCS_981_2017 = "0xeaa9938076748d7edd4df0721b3e3fe4077349d3"; +const C3T_VCS_981_2017 = "0x7dbeebf8c2356ff8c53e41928c9575054a6f331b"; + +const uboPool = aCarbonPool({ + id: POOL_INFO.nbo.poolAddress, + decimals: 18, + name: "Universal Basic Offset", + supply: "21202280666164910248664", +}); +const nboPool = aCarbonPool({ + id: POOL_INFO.nbo.poolAddress, + decimals: 18, + name: "Nature Based Offset", + supply: "31202280666164910248664", +}); +const nctPool = aCarbonPool({ + id: POOL_INFO.nct.poolAddress, + name: "Toucan Protocol: Nature Carbon Tonne", + supply: "1604659955808874505539565", + decimals: 18, +}); +const bctPool = aCarbonPool({ + id: POOL_INFO.bct.poolAddress, + name: "Toucan Protocol: Base Carbon Tonne", + supply: "18545844499823544157213608", + decimals: 18, +}); +const poolBalance_NBO = aCarbonPoolCreditBalance({ + balance: "26202320013669175484739", + pool: nboPool, + deposited: "28903000000000000000000", + redeemed: "2700679986330824515261", +}); +const poolBalance_NCT = aCarbonPoolCreditBalance({ + balance: "137168659539439210", + pool: nctPool, + deposited: "19048774113647802186879", + redeemed: "17724636944988262747669", +}); +const poolBalance_BCT = aCarbonPoolCreditBalance({ + balance: "0", // all redeemed and moved to TCO2 + pool: bctPool, + deposited: "142330703112744844598983", + redeemed: "142330703112744844598983", +}); +const carbonCredit_C3T = aCarbonCredit({ + vintage: 2017, + bridged: "28903000000000000000000", + retired: "2645744986330824515261", + currentSupply: "26257255013669175484739", + poolBalances: [poolBalance_NBO], + id: C3T_VCS_981_2017, +}); +const carbonCredit_TCO2 = aCarbonCredit({ + vintage: 2017, + bridged: "73794000000000000000000", + retired: "6709707416786222240581", + currentSupply: "62876512583213777759419", + poolBalances: [poolBalance_BCT, poolBalance_NCT], + id: TCO2_VCS_981_2017, +}); +/** A project with two pool prices (1 empty pool) */ +const carbonProject = aCarbonProject({ + projectID: "VCS-981", + name: "Pacajai REDD+ Project", + methodologies: "VM0015", + id: "VCS-981", + country: "Brazil", + category: "Forestry", + carbonCredits: [carbonCredit_TCO2, carbonCredit_C3T], +}); + +/** Fixtures for the polygon-bridged-carbon subgraph */ +const fixtures = { + carbonProject, + bctPool, + nctPool, + uboPool, + nboPool, +}; + +export default fixtures; diff --git a/carbonmark-api/test/routes/projects/[id]/get.test.ts b/carbonmark-api/test/routes/projects/[id]/get.test.ts new file mode 100644 index 0000000000..ff7472b857 --- /dev/null +++ b/carbonmark-api/test/routes/projects/[id]/get.test.ts @@ -0,0 +1,116 @@ +import { FastifyInstance } from "fastify"; +import nock from "nock"; +import { GRAPH_URLS, SANITY_URLS } from "../../../../src/app.constants"; +import carbonProjects from "../../../fixtures/carbonProjects"; +import digitalCarbon from "../../../fixtures/digitalCarbon"; +import { build } from "../../../helper"; +import { DEV_URL } from "../../../test.constants"; + +describe("GET /projects/:id", () => { + let fastify: FastifyInstance; + + // Setup the server + beforeEach(async () => { + try { + fastify = await build(); + } catch (e) { + console.error("/projects/:id get.test.ts setup failed", e); + } + }); + + test("Returns project from CMS without prices or listings", async () => { + nock(SANITY_URLS.carbonProjects) + .post("") + .twice() // once for each query + .reply(200, { + data: { + allProject: [carbonProjects.project], + allProjectContent: [carbonProjects.projectContent], + }, + }); + nock(GRAPH_URLS["polygon"].tokens).post("").reply(200, { + data: {}, + }); + nock(GRAPH_URLS["polygon"].digitalCarbon).post("").twice().reply(200, { + data: {}, + }); + nock(GRAPH_URLS["polygon"].offsets).post("").reply(200, { data: {} }); + nock(GRAPH_URLS["polygon"].marketplace).post("").reply(200, { + data: {}, + }); + const response = await fastify.inject({ + method: "GET", + url: `${DEV_URL}/projects/VCS-191-2008`, + }); + const project = await response.json(); + expect(response.statusCode).toEqual(200); + expect(project.key).toEqual("VCS-191"); + expect(project.country).toEqual("China"); + }); + + test("Supports ?network=polygon", async () => { + nock(SANITY_URLS.carbonProjects) + .post("") + .twice() // once for each query + .reply(200, { + data: { + allProject: [carbonProjects.project], + allProjectContent: [carbonProjects.projectContent], + }, + }); + nock(GRAPH_URLS["polygon"].tokens).post("").reply(200, { + data: {}, + }); + nock(GRAPH_URLS["polygon"].digitalCarbon) + .post("") + .reply(200, { + data: { + carbonProjects: [digitalCarbon.carbonProject], + }, + }); + nock(GRAPH_URLS["polygon"].offsets).post("").reply(200, { data: {} }); + nock(GRAPH_URLS["polygon"].marketplace).post("").reply(200, { + data: {}, + }); + const response = await fastify.inject({ + method: "GET", + url: `${DEV_URL}/projects/VCS-191-2008?network=polygon`, + }); + const project = await response.json(); + expect(response.statusCode).toEqual(200); + expect(project.prices).toHaveLength(2); + }); + + test("Empty network param default is polygon", async () => { + nock(SANITY_URLS.carbonProjects) + .post("") + .twice() // once for each query + .reply(200, { + data: { + allProject: [carbonProjects.project], + allProjectContent: [carbonProjects.projectContent], + }, + }); + nock(GRAPH_URLS["polygon"].tokens).post("").reply(200, { + data: {}, + }); + nock(GRAPH_URLS["polygon"].digitalCarbon) + .post("") + .reply(200, { + data: { + carbonProjects: [digitalCarbon.carbonProject], + }, + }); + nock(GRAPH_URLS["polygon"].offsets).post("").reply(200, { data: {} }); + nock(GRAPH_URLS["polygon"].marketplace).post("").reply(200, { + data: {}, + }); + const response = await fastify.inject({ + method: "GET", + url: `${DEV_URL}/projects/VCS-981-2017`, + }); + const project = await response.json(); + expect(response.statusCode).toEqual(200); + expect(project.prices).toHaveLength(2); + }); +});