diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f46eb57df..781d66cb5 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,6 +6,10 @@ - ci: removing headless browser tests pending a rewrite +### Added + +- test: adding test for backwards compatibility with actor for v1 agents + ## [1.4.0] - 2024-06-17 ### Added diff --git a/e2e/node/canisters/counter.ts b/e2e/node/canisters/counter.ts index 73076cc1d..0818e5303 100644 --- a/e2e/node/canisters/counter.ts +++ b/e2e/node/canisters/counter.ts @@ -1,4 +1,4 @@ -import { Actor, ActorSubclass, HttpAgentOptions } from '@dfinity/agent'; +import { Actor, ActorSubclass, HttpAgentOptions, Agent } from '@dfinity/agent'; import { IDL } from '@dfinity/candid'; import { Principal } from '@dfinity/principal'; import { readFileSync } from 'fs'; @@ -47,20 +47,22 @@ export default async function (): Promise<{ return cache; } -export const createActor = async (options?: HttpAgentOptions) => { +export const createActor = async (options?: HttpAgentOptions, agent?: Agent) => { const module = readFileSync(path.join(__dirname, 'counter.wasm')); - const agent = await makeAgent({ - ...options, - }); + const effectiveAgent = agent + ? agent + : await makeAgent({ + ...options, + }); try { if (!options?.host?.includes('icp-api')) { - await agent.fetchRootKey(); + await effectiveAgent.fetchRootKey(); } } catch (_) { // } - const canisterId = await Actor.createCanister({ agent }); - await Actor.install({ module }, { canisterId, agent }); - return Actor.createActor(idl, { canisterId, agent }) as ActorSubclass<_SERVICE>; + const canisterId = await Actor.createCanister({ agent: effectiveAgent }); + await Actor.install({ module }, { canisterId, agent: effectiveAgent }); + return Actor.createActor(idl, { canisterId, agent: effectiveAgent }) as ActorSubclass<_SERVICE>; }; diff --git a/e2e/node/integration/actor.test.ts b/e2e/node/integration/actor.test.ts new file mode 100644 index 000000000..49b48cf4c --- /dev/null +++ b/e2e/node/integration/actor.test.ts @@ -0,0 +1,22 @@ +import { HttpAgent } from '@dfinity/agent'; +import { HttpAgent as HttpAgentv1 } from 'agent1'; +import { createActor } from '../canisters/counter'; +import { vi, test, expect } from 'vitest'; + +vi.useRealTimers(); +test("Legacy Agent interface should be accepted by Actor's createActor", async () => { + // Use the v1.4.0 agent to create an actor + const actor = await createActor( + {}, + new HttpAgentv1({ + host: `http://127.0.0.1:${process.env.REPLICA_PORT ?? 4943}`, + }) as unknown as HttpAgent, + ); + + // Verify that update calls work + await actor.write(8n); //? + // Verify that query calls work + const count = await actor.read(); //? + expect(count).toBe(8n); +}, 15_000); +// TODO: tests for rejected, unknown time out diff --git a/e2e/node/package.json b/e2e/node/package.json index 7fbee2052..755ed3076 100644 --- a/e2e/node/package.json +++ b/e2e/node/package.json @@ -32,6 +32,7 @@ "@types/text-encoding": "^0.0.36", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.5", + "agent1": "npm:@dfinity/agent@^1.4.0", "esbuild": "^0.15.16", "eslint": "^8.19.0", "eslint-plugin-jsdoc": "^39.3.3", diff --git a/package-lock.json b/package-lock.json index 4c6beb99b..c956aa8f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,6 +81,7 @@ "@types/text-encoding": "^0.0.36", "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.30.5", + "agent1": "npm:@dfinity/agent@^1.4.0", "esbuild": "^0.15.16", "eslint": "^8.19.0", "eslint-plugin-jsdoc": "^39.3.3", @@ -4563,6 +4564,26 @@ "node": ">= 6.0.0" } }, + "node_modules/agent1": { + "name": "@dfinity/agent", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@dfinity/agent/-/agent-1.4.0.tgz", + "integrity": "sha512-/zgGajZpxtbu+kLXtFx2e9V2+HbMUjrtGWx9ZEwtVwhVxKgVi/2kGQpFRPEDFJ461V7wdTwCig4OkMxVU4shTw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.3.1", + "base64-arraybuffer": "^0.2.0", + "borc": "^2.1.1", + "buffer": "^6.0.3", + "simple-cbor": "^0.4.1" + }, + "peerDependencies": { + "@dfinity/candid": "^1.4.0", + "@dfinity/principal": "^1.4.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", diff --git a/packages/agent/src/actor.test.ts b/packages/agent/src/actor.test.ts index aac774204..8f3ef481e 100644 --- a/packages/agent/src/actor.test.ts +++ b/packages/agent/src/actor.test.ts @@ -370,6 +370,5 @@ describe('makeActor', () => { ); }); }); -// TODO: tests for rejected, unknown time out jest.setTimeout(20000); diff --git a/packages/agent/src/actor.ts b/packages/agent/src/actor.ts index a5f145218..88fe7f9d1 100644 --- a/packages/agent/src/actor.ts +++ b/packages/agent/src/actor.ts @@ -531,6 +531,10 @@ function _createActorMethod( effectiveCanisterId: ecid, }); + requestId; + response; + requestDetails; + if (!response.ok || response.body /* IC-1462 */) { throw new UpdateCallRejectedError(cid, methodName, requestId, response); } @@ -544,6 +548,7 @@ function _createActorMethod( pollStrategy, blsVerify, ); + reply; const shouldIncludeHttpDetails = func.annotations.includes(ACTOR_METHOD_WITH_HTTP_DETAILS); const shouldIncludeCertificate = func.annotations.includes(ACTOR_METHOD_WITH_CERTIFICATE);