From 3fa96c87c7e737ebdabb6fa7fa6fb8d5f15dc21b Mon Sep 17 00:00:00 2001 From: Alain Nicolas Date: Fri, 20 Oct 2023 16:17:06 +0200 Subject: [PATCH] chore: Add unit test to the subgraph --- .gitignore | 1 + pnpm-lock.yaml | 45 ++++++------ subgraph/package.json | 8 +-- subgraph/src/portal-registry.ts | 6 +- subgraph/src/schema-registry.ts | 2 +- subgraph/tests/module-registry.test.ts | 39 ++++++++--- subgraph/tests/portal-registry.test.ts | 95 ++++++++++++++++++++++++++ subgraph/tests/schema-registry.test.ts | 37 +++++++++- 8 files changed, 192 insertions(+), 41 deletions(-) create mode 100644 subgraph/tests/portal-registry.test.ts diff --git a/.gitignore b/.gitignore index e235ddc9..89c5cbdd 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ generated subgraph.yaml .bin .latest.json +.docker # Misc .DS_Store diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e8026a9..43d5701a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,9 +1,5 @@ lockfileVersion: '6.0' -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - overrides: flat@<5.0.1: '>=5.0.1' ejs@<3.1.7: '>=3.1.7' @@ -140,17 +136,17 @@ importers: subgraph: devDependencies: '@graphprotocol/graph-cli': - specifier: 0.59.0 - version: 0.59.0(@types/node@20.8.0)(node-fetch@3.3.2)(typescript@5.2.2) + specifier: 0.60.0 + version: 0.60.0(@types/node@20.8.0)(node-fetch@3.3.2)(typescript@5.2.2) '@graphprotocol/graph-ts': - specifier: 0.30.0 - version: 0.30.0 + specifier: 0.31.0 + version: 0.31.0 assemblyscript: specifier: 0.19.10 version: 0.19.10 matchstick-as: - specifier: 0.5.2 - version: 0.5.2 + specifier: 0.6.0 + version: 0.6.0 packages: @@ -2262,8 +2258,8 @@ packages: tslib: 2.6.2 dev: false - /@graphprotocol/graph-cli@0.59.0(@types/node@20.8.0)(node-fetch@3.3.2)(typescript@5.2.2): - resolution: {integrity: sha512-uddsyUootdhQgMqQXkrD0INn/nNkQB+3t5luRzjY0pxA4O9hidXjYZNScjvSgf3eiaN0rcEs/s56qa/dsy4LwA==} + /@graphprotocol/graph-cli@0.60.0(@types/node@20.8.0)(node-fetch@3.3.2)(typescript@5.2.2): + resolution: {integrity: sha512-8tGaQJ0EzAPtkDXCAijFGoVdJXM+pKFlGxjiU31TdG5bS4cIUoSB6yWojVsFFod0yETAwf+giel/0/8sudYsDw==} engines: {node: '>=14'} hasBin: true dependencies: @@ -2307,8 +2303,8 @@ packages: - utf-8-validate dev: true - /@graphprotocol/graph-ts@0.30.0: - resolution: {integrity: sha512-h5tJqlsZXglGYM0PcBsBOqof4PT0Fr4Z3QBTYN/IjMF3VvRX2A8/bdpqaAnva+2N0uAfXXwRcwcOcW5O35yzXw==} + /@graphprotocol/graph-ts@0.31.0: + resolution: {integrity: sha512-xreRVM6ho2BtolyOh2flDkNoGZximybnzUnF53zJVp0+Ed0KnAlO1/KOCUYw06euVI9tk0c9nA2Z/D5SIQV2Rg==} dependencies: assemblyscript: 0.19.10 dev: true @@ -8289,7 +8285,7 @@ packages: /fs-jetpack@4.3.1: resolution: {integrity: sha512-dbeOK84F6BiQzk2yqqCVwCPWTxAvVGJ3fMQc6E2wuEohS28mR6yHngbrKuVCK1KHRx/ccByDylqu4H5PCP2urQ==} dependencies: - minimatch: 9.0.3 + minimatch: 3.1.2 rimraf: 2.7.1 dev: true @@ -8432,7 +8428,7 @@ packages: dependencies: inflight: 1.0.6 inherits: 2.0.4 - minimatch: 9.0.3 + minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 dev: true @@ -8443,7 +8439,7 @@ packages: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 9.0.3 + minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 dev: true @@ -9620,7 +9616,7 @@ packages: resolution: {integrity: sha512-Ch2Dzhw4URfB9L/0ZHyY+uqOnKvBNeS/SMcRiPmJfpHiM0TsUZn+GkpcZxAoF3dJVdPm/PuIk3A4wlV7SUo23Q==} dependencies: '@types/minimatch': 3.0.5 - minimatch: 9.0.3 + minimatch: 3.1.2 dev: true /it-last@1.0.6: @@ -10628,8 +10624,8 @@ packages: resolution: {integrity: sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==} dev: true - /matchstick-as@0.5.2: - resolution: {integrity: sha512-fb1OVphDKEvJY06Ue02Eh1CNncuW95vp6b8tNAP7UIqplICSLoU/zgN6U7ge7R0upsoO78C7CRi4EyK/7Jxz7g==} + /matchstick-as@0.6.0: + resolution: {integrity: sha512-E36fWsC1AbCkBFt05VsDDRoFvGSdcZg6oZJrtIe/YDBbuFh8SKbR5FcoqDhNWqSN+F7bN/iS2u8Md0SM+4pUpw==} dependencies: wabt: 1.0.24 dev: true @@ -11074,6 +11070,7 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dependencies: brace-expansion: 2.0.1 + dev: false /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -11277,7 +11274,7 @@ packages: resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} engines: {node: '>= 0.10.5'} dependencies: - minimatch: 9.0.3 + minimatch: 3.1.2 dev: false /node-domexception@1.0.0: @@ -13151,7 +13148,7 @@ packages: dependencies: '@istanbuljs/schema': 0.1.3 glob: 7.2.3 - minimatch: 9.0.3 + minimatch: 3.1.2 dev: true /text-table@0.2.0: @@ -14166,3 +14163,7 @@ packages: /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false diff --git a/subgraph/package.json b/subgraph/package.json index 502e6710..8e3d02ec 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -25,12 +25,12 @@ "deploy:goerli": "source .env && cp subgraph.goerli.yaml subgraph.yaml && pnpm run build:goerli && graph deploy --network linea-goerli --node $DEPLOY_ENDPOINT_GOERLI --headers \"{\\\"Authorization\\\": \\\"Basic $IPFS_IDENTIFIERS\\\"}\" --ipfs $IPFS_ENDPOINT --version-label v0.0.5 Consensys/linea-attestation-registry", "remove": "source .env && graph remove --node $DEPLOY_ENDPOINT_MAINNET Consensys/linea-attestation-registry", "remove:goerli": "source .env && graph remove --node $DEPLOY_ENDPOINT_GOERLI Consensys/linea-attestation-registry", - "test": "graph test -v 0.5.2" + "test": "graph test" }, "devDependencies": { - "@graphprotocol/graph-cli": "0.59.0", - "@graphprotocol/graph-ts": "0.30.0", - "matchstick-as": "0.5.2", + "@graphprotocol/graph-cli": "0.60.0", + "@graphprotocol/graph-ts": "0.31.0", + "matchstick-as": "0.6.0", "assemblyscript": "0.19.10" } } diff --git a/subgraph/src/portal-registry.ts b/subgraph/src/portal-registry.ts index f8b3ae22..811700c3 100644 --- a/subgraph/src/portal-registry.ts +++ b/subgraph/src/portal-registry.ts @@ -5,15 +5,15 @@ import { Counter, Portal } from "../generated/schema"; export function handlePortalRegistered(event: PortalRegisteredEvent): void { const contract = PortalRegistry.bind(event.address); const portalData = contract.getPortalByAddress(event.params.portalAddress); - const portal = new Portal(event.params.portalAddress.toHex()); + const portal = new Portal(event.params.portalAddress.toHexString()); incrementPortalsCount(); + portal.name = event.params.name; + portal.description = event.params.description; portal.ownerAddress = portalData.ownerAddress; portal.modules = changetype(portalData.modules); portal.isRevocable = portalData.isRevocable; - portal.name = portalData.name; - portal.description = portalData.description; portal.ownerName = portalData.ownerName; portal.save(); diff --git a/subgraph/src/schema-registry.ts b/subgraph/src/schema-registry.ts index 373fcaf5..cc2069bd 100644 --- a/subgraph/src/schema-registry.ts +++ b/subgraph/src/schema-registry.ts @@ -2,7 +2,7 @@ import { SchemaCreated as SchemaCreatedEvent } from "../generated/SchemaRegistry import { Counter, Schema } from "../generated/schema"; export function handleSchemaCreated(event: SchemaCreatedEvent): void { - const schema = new Schema(event.params.id.toString()); + const schema = new Schema(event.params.id.toHexString()); incrementSchemasCount(); diff --git a/subgraph/tests/module-registry.test.ts b/subgraph/tests/module-registry.test.ts index e788bec8..3ca7796a 100644 --- a/subgraph/tests/module-registry.test.ts +++ b/subgraph/tests/module-registry.test.ts @@ -1,4 +1,4 @@ -import { afterEach, assert, clearStore, describe, log, test } from "matchstick-as"; +import { afterEach, assert, clearStore, describe, test } from "matchstick-as"; import { ModuleRegistered as ModuleRegisteredEvent, ModuleRegistered, @@ -8,7 +8,7 @@ import { newTypedMockEvent } from "matchstick-as/assembly/defaults"; import { handleModuleRegistered } from "../src/module-registry"; describe("handleModuleRegistered()", () => { - const moduleAddress = "0xF75BE6f9418710fd516fA82Afb3AAD07e11a0f1b"; + const moduleAddress = "f75be6f9418710fd516fa82afb3aad07e11a0f1b"; const moduleName = "module name"; const moduleDescription = "module description"; @@ -25,10 +25,31 @@ describe("handleModuleRegistered()", () => { assert.entityCount("Module", 1); - assert.fieldEquals("Module", moduleAddress, "id", moduleAddress); - assert.fieldEquals("Module", moduleAddress, "name", moduleName); - assert.fieldEquals("Module", moduleAddress, "description", moduleDescription); - assert.fieldEquals("Module", moduleAddress, "moduleAddress", moduleAddress); + assert.fieldEquals("Module", "0x" + moduleAddress, "id", "0x" + moduleAddress); + assert.fieldEquals("Module", "0x" + moduleAddress, "name", moduleName); + assert.fieldEquals("Module", "0x" + moduleAddress, "description", moduleDescription); + assert.fieldEquals("Module", "0x" + moduleAddress, "moduleAddress", "0x" + moduleAddress); + }); + + test("Should increment the modules Counter", () => { + assert.entityCount("Module", 0); + + const moduleAddress1 = "f75be6f9418710fd516fa82afb3aad07e11a0f1b"; + const moduleAddress2 = "e75be6f9418710fd516fa82afb3aad07e11a0f1b"; + + const moduleRegisteredEvent1 = createModuleRegisteredEvent(moduleAddress1, moduleName, moduleDescription); + + handleModuleRegistered(moduleRegisteredEvent1); + + assert.entityCount("Module", 1); + assert.fieldEquals("Counter", "counter", "modules", "1"); + + const moduleRegisteredEvent2 = createModuleRegisteredEvent(moduleAddress2, moduleName, moduleDescription); + + handleModuleRegistered(moduleRegisteredEvent2); + + assert.entityCount("Module", 2); + assert.fieldEquals("Counter", "counter", "modules", "2"); }); }); @@ -39,12 +60,12 @@ function createModuleRegisteredEvent( ): ModuleRegistered { const moduleRegisteredEvent = newTypedMockEvent(); + moduleRegisteredEvent.parameters.push(new ethereum.EventParam("name", ethereum.Value.fromString(moduleName))); moduleRegisteredEvent.parameters.push( - new ethereum.EventParam("moduleAddress", ethereum.Value.fromAddress(Address.fromString(moduleAddress))), + new ethereum.EventParam("description", ethereum.Value.fromString(moduleDescription)), ); - moduleRegisteredEvent.parameters.push(new ethereum.EventParam("moduleName", ethereum.Value.fromString(moduleName))); moduleRegisteredEvent.parameters.push( - new ethereum.EventParam("moduleDescription", ethereum.Value.fromString(moduleDescription)), + new ethereum.EventParam("moduleAddress", ethereum.Value.fromAddress(Address.fromString(moduleAddress))), ); return moduleRegisteredEvent; diff --git a/subgraph/tests/portal-registry.test.ts b/subgraph/tests/portal-registry.test.ts new file mode 100644 index 00000000..3375e65f --- /dev/null +++ b/subgraph/tests/portal-registry.test.ts @@ -0,0 +1,95 @@ +import { afterEach, assert, beforeAll, clearStore, createMockedFunction, describe, test } from "matchstick-as"; +import { Address, ethereum } from "@graphprotocol/graph-ts"; +import { newTypedMockEvent } from "matchstick-as/assembly/defaults"; +import { handlePortalRegistered } from "../src/portal-registry"; +import { PortalRegistered as PortalRegisteredEvent } from "../generated/PortalRegistry/PortalRegistry"; + +const portalRegistryAddress = Address.fromString("506f88a5Ca8D5F001f2909b029738A40042e42a6"); + +describe("handlePortalRegistered()", () => { + const portalAddress = "f75be6f9418710fd516fa82afb3aad07e11a0f1b"; + const ownerAddress = "e75be6f9418710fd516fa82afb3aad07e11a0f1b"; + const ownerName = "Verax"; + const portalName = "portal name"; + const portalDescription = "portal description"; + + beforeAll(() => { + const tupleArray: Array = [ + ethereum.Value.fromAddress(Address.fromString(portalAddress)), + ethereum.Value.fromAddress(Address.fromString(ownerAddress)), + ethereum.Value.fromAddressArray([Address.zero()]), + ethereum.Value.fromBoolean(true), + ethereum.Value.fromString(portalName), + ethereum.Value.fromString(portalDescription), + ethereum.Value.fromString(ownerName), + ]; + const tuple = changetype(tupleArray); + const tupleValue = ethereum.Value.fromTuple(tuple); + + createMockedFunction( + portalRegistryAddress, + "getPortalByAddress", + "getPortalByAddress(address):((address,address,address[],bool,string,string,string))", + ) + .withArgs([ethereum.Value.fromAddress(Address.fromString(portalAddress))]) + .returns([tupleValue]); + }); + + afterEach(() => { + clearStore(); + }); + + test("Should create a new Portal entity", () => { + assert.entityCount("Portal", 0); + + const portalRegisteredEvent = createPortalRegisteredEvent(portalAddress, portalName, portalDescription); + + handlePortalRegistered(portalRegisteredEvent); + + assert.entityCount("Portal", 1); + + assert.fieldEquals("Portal", "0x" + portalAddress, "id", "0x" + portalAddress); + assert.fieldEquals("Portal", "0x" + portalAddress, "name", portalName); + assert.fieldEquals("Portal", "0x" + portalAddress, "description", portalDescription); + }); + + test("Should increment the portals Counter", () => { + assert.entityCount("Portal", 0); + + const portalAddress1 = "f75be6f9418710fd516fa82afb3aad07e11a0f1b"; + const portalAddress2 = "e75be6f9418710fd516fa82afb3aad07e11a0f1b"; + + const portalRegisteredEvent1 = createPortalRegisteredEvent(portalAddress1, portalName, portalDescription); + + handlePortalRegistered(portalRegisteredEvent1); + + assert.entityCount("Portal", 1); + assert.fieldEquals("Counter", "counter", "portals", "1"); + + const portalRegisteredEvent2 = createPortalRegisteredEvent(portalAddress2, portalName, portalDescription); + + handlePortalRegistered(portalRegisteredEvent2); + + assert.entityCount("Portal", 2); + assert.fieldEquals("Counter", "counter", "portals", "2"); + }); +}); + +function createPortalRegisteredEvent( + portalAddress: string, + portalName: string, + portalDescription: string, +): PortalRegisteredEvent { + const portalRegisteredEvent = newTypedMockEvent(); + portalRegisteredEvent.address = portalRegistryAddress; + + portalRegisteredEvent.parameters.push(new ethereum.EventParam("name", ethereum.Value.fromString(portalName))); + portalRegisteredEvent.parameters.push( + new ethereum.EventParam("description", ethereum.Value.fromString(portalDescription)), + ); + portalRegisteredEvent.parameters.push( + new ethereum.EventParam("portalAddress", ethereum.Value.fromAddress(Address.fromString(portalAddress))), + ); + + return portalRegisteredEvent; +} diff --git a/subgraph/tests/schema-registry.test.ts b/subgraph/tests/schema-registry.test.ts index e7b28ee4..7362c056 100644 --- a/subgraph/tests/schema-registry.test.ts +++ b/subgraph/tests/schema-registry.test.ts @@ -1,5 +1,5 @@ import { afterEach, assert, clearStore, describe, test } from "matchstick-as"; -import { BigInt, ethereum } from "@graphprotocol/graph-ts"; +import { Bytes, ethereum } from "@graphprotocol/graph-ts"; import { newTypedMockEvent } from "matchstick-as/assembly/defaults"; import { handleSchemaCreated } from "../src/schema-registry"; import { SchemaCreated, SchemaCreated as SchemaCreatedEvent } from "../generated/SchemaRegistry/SchemaRegistry"; @@ -36,6 +36,39 @@ describe("handleSchemaCreated()", () => { assert.fieldEquals("Schema", schemaId, "context", schemaContext); assert.fieldEquals("Schema", schemaId, "schema", schemaString); }); + + test("Should increment the schemas Counter", () => { + assert.entityCount("Schema", 0); + + const schemaId1 = "0x7930a5ebfabdd4ef76bbb8cdcbc2225b6256d9511d9cf5ff0d6514c1bdb4d7dc"; + const schemaId2 = "0x8930a5ebfabdd4ef76bbb8cdcbc2225b6256d9511d9cf5ff0d6514c1bdb4d7dc"; + + const schemaCreatedEvent1 = createSchemaCreatedEvent( + schemaId1, + schemaName, + schemaDescription, + schemaContext, + schemaString, + ); + + handleSchemaCreated(schemaCreatedEvent1); + + assert.entityCount("Schema", 1); + assert.fieldEquals("Counter", "counter", "schemas", "1"); + + const schemaCreatedEvent2 = createSchemaCreatedEvent( + schemaId2, + schemaName, + schemaDescription, + schemaContext, + schemaString, + ); + + handleSchemaCreated(schemaCreatedEvent2); + + assert.entityCount("Schema", 2); + assert.fieldEquals("Counter", "counter", "schemas", "2"); + }); }); function createSchemaCreatedEvent( @@ -48,7 +81,7 @@ function createSchemaCreatedEvent( const schemaCreatedEvent = newTypedMockEvent(); schemaCreatedEvent.parameters.push( - new ethereum.EventParam("id", ethereum.Value.fromI32(BigInt.fromString(schemaId).toI32())), + new ethereum.EventParam("id", ethereum.Value.fromBytes(Bytes.fromHexString(schemaId))), ); schemaCreatedEvent.parameters.push(new ethereum.EventParam("name", ethereum.Value.fromString(schemaName))); schemaCreatedEvent.parameters.push(