From 724d8fc161562d88468e9ae9adf947e269a85230 Mon Sep 17 00:00:00 2001 From: Kyle Peacock Date: Mon, 24 Oct 2022 15:41:47 -0700 Subject: [PATCH 01/12] experimental changes --- packages/agent/src/agent/http/index.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts index 4a53c6d67..021ef7ff3 100644 --- a/packages/agent/src/agent/http/index.ts +++ b/packages/agent/src/agent/http/index.ts @@ -72,6 +72,10 @@ export interface HttpAgentOptions { // A surrogate to the global fetch function. Useful for testing. fetch?: typeof fetch; + // Additional options to pass along to fetch. Will not override fields that + // the agent already needs to set + fetchOptions?: Record; + // The host to use for the client. By default, uses the same host as // the current page. host?: string; @@ -162,6 +166,7 @@ export class HttpAgent implements Agent { private readonly _pipeline: HttpAgentRequestTransformFn[] = []; private _identity: Promise | null; private readonly _fetch: typeof fetch; + private readonly _fetchOptions?: Record; private _timeDiffMsecs = 0; private readonly _host: URL; private readonly _credentials: string | undefined; @@ -177,6 +182,7 @@ export class HttpAgent implements Agent { this._pipeline = [...options.source._pipeline]; this._identity = options.source._identity; this._fetch = options.source._fetch; + this._fetchOptions = options.source._fetchOptions; this._host = options.source._host; this._credentials = options.source._credentials; } else { @@ -386,6 +392,7 @@ export class HttpAgent implements Agent { const body = cbor.encode(transformedRequest.body); const response = await this._requestAndRetry(() => this._fetch('' + new URL(`/api/v2/canister/${canister.toText()}/query`, this._host), { + ...this._fetchOptions, ...transformedRequest.request, body, }), @@ -445,6 +452,7 @@ export class HttpAgent implements Agent { const response = await this._fetch( '' + new URL(`/api/v2/canister/${canister}/read_state`, this._host), { + ...this._fetchOptions, ...transformedRequest.request, body, }, @@ -497,7 +505,7 @@ export class HttpAgent implements Agent { : {}; const response = await this._requestAndRetry(() => - this._fetch('' + new URL(`/api/v2/status`, this._host), { headers }), + this._fetch('' + new URL(`/api/v2/status`, this._host), { headers, ...this._fetchOptions }), ); return cbor.decode(await response.arrayBuffer()); From a9e7d5d4aab71e2205ece25c5911067a49cc09ec Mon Sep 17 00:00:00 2001 From: Sue Ann Kim Date: Tue, 1 Nov 2022 16:37:56 -0700 Subject: [PATCH 02/12] added callOptions, and changed assignment logic of this._fetchOptions --- packages/agent/src/agent/http/index.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts index 021ef7ff3..3a885d3ae 100644 --- a/packages/agent/src/agent/http/index.ts +++ b/packages/agent/src/agent/http/index.ts @@ -76,6 +76,9 @@ export interface HttpAgentOptions { // the agent already needs to set fetchOptions?: Record; + // Additional options to pass along to fetch for the call API. + callOptions?: Record; + // The host to use for the client. By default, uses the same host as // the current page. host?: string; @@ -167,6 +170,7 @@ export class HttpAgent implements Agent { private _identity: Promise | null; private readonly _fetch: typeof fetch; private readonly _fetchOptions?: Record; + private readonly _callOptions?: Record; private _timeDiffMsecs = 0; private readonly _host: URL; private readonly _credentials: string | undefined; @@ -182,7 +186,8 @@ export class HttpAgent implements Agent { this._pipeline = [...options.source._pipeline]; this._identity = options.source._identity; this._fetch = options.source._fetch; - this._fetchOptions = options.source._fetchOptions; + this._fetchOptions = options.source._fetchOptions || options.fetchOptions; + this._callOptions = options.source._fetchOptions || options.callOptions; this._host = options.source._host; this._credentials = options.source._credentials; } else { @@ -307,6 +312,7 @@ export class HttpAgent implements Agent { const request = this._requestAndRetry(() => this._fetch('' + new URL(`/api/v2/canister/${ecid.toText()}/call`, this._host), { + ...this._callOptions, ...transformedRequest.request, body, }), From 2ad9a20f5160c75614671512819aff60471af2a4 Mon Sep 17 00:00:00 2001 From: Sue Ann Kim Date: Tue, 1 Nov 2022 16:46:10 -0700 Subject: [PATCH 03/12] Typo error. In case options.source is correctly implemented I've still included the logic: - `this._fetchOptions = options.source._fetchOptions || options.fetchOptions;` - `this._callOptions = options.source._callOptions || options.callOptions;` --- packages/agent/src/agent/http/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts index 3a885d3ae..056d64158 100644 --- a/packages/agent/src/agent/http/index.ts +++ b/packages/agent/src/agent/http/index.ts @@ -187,7 +187,7 @@ export class HttpAgent implements Agent { this._identity = options.source._identity; this._fetch = options.source._fetch; this._fetchOptions = options.source._fetchOptions || options.fetchOptions; - this._callOptions = options.source._fetchOptions || options.callOptions; + this._callOptions = options.source._callOptions || options.callOptions; this._host = options.source._host; this._credentials = options.source._credentials; } else { From 2f07956b01dfb201df425ccbfc5dd0f7fadd84e2 Mon Sep 17 00:00:00 2001 From: Sue Ann Kim Date: Tue, 8 Nov 2022 09:46:05 -0800 Subject: [PATCH 04/12] When source isn't provided in constructing the HttpAgent, this._fetchOptions and this._callOptions will automatically get fromm provided options. --- packages/agent/src/agent/http/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts index 056d64158..e52709762 100644 --- a/packages/agent/src/agent/http/index.ts +++ b/packages/agent/src/agent/http/index.ts @@ -186,12 +186,12 @@ export class HttpAgent implements Agent { this._pipeline = [...options.source._pipeline]; this._identity = options.source._identity; this._fetch = options.source._fetch; - this._fetchOptions = options.source._fetchOptions || options.fetchOptions; - this._callOptions = options.source._callOptions || options.callOptions; this._host = options.source._host; this._credentials = options.source._credentials; } else { this._fetch = options.fetch || getDefaultFetch() || fetch.bind(global); + this._fetchOptions = options.fetchOptions; + this._callOptions = options.callOptions; } if (options.host !== undefined) { if (!options.host.match(/^[a-z]+:/) && typeof window !== 'undefined') { From 3298d3c9f113ea797c3af1d1708a8bb6c704f508 Mon Sep 17 00:00:00 2001 From: Kyle Peacock Date: Mon, 24 Oct 2022 15:41:47 -0700 Subject: [PATCH 05/12] experimental changes --- packages/agent/src/agent/http/index.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts index 4a53c6d67..021ef7ff3 100644 --- a/packages/agent/src/agent/http/index.ts +++ b/packages/agent/src/agent/http/index.ts @@ -72,6 +72,10 @@ export interface HttpAgentOptions { // A surrogate to the global fetch function. Useful for testing. fetch?: typeof fetch; + // Additional options to pass along to fetch. Will not override fields that + // the agent already needs to set + fetchOptions?: Record; + // The host to use for the client. By default, uses the same host as // the current page. host?: string; @@ -162,6 +166,7 @@ export class HttpAgent implements Agent { private readonly _pipeline: HttpAgentRequestTransformFn[] = []; private _identity: Promise | null; private readonly _fetch: typeof fetch; + private readonly _fetchOptions?: Record; private _timeDiffMsecs = 0; private readonly _host: URL; private readonly _credentials: string | undefined; @@ -177,6 +182,7 @@ export class HttpAgent implements Agent { this._pipeline = [...options.source._pipeline]; this._identity = options.source._identity; this._fetch = options.source._fetch; + this._fetchOptions = options.source._fetchOptions; this._host = options.source._host; this._credentials = options.source._credentials; } else { @@ -386,6 +392,7 @@ export class HttpAgent implements Agent { const body = cbor.encode(transformedRequest.body); const response = await this._requestAndRetry(() => this._fetch('' + new URL(`/api/v2/canister/${canister.toText()}/query`, this._host), { + ...this._fetchOptions, ...transformedRequest.request, body, }), @@ -445,6 +452,7 @@ export class HttpAgent implements Agent { const response = await this._fetch( '' + new URL(`/api/v2/canister/${canister}/read_state`, this._host), { + ...this._fetchOptions, ...transformedRequest.request, body, }, @@ -497,7 +505,7 @@ export class HttpAgent implements Agent { : {}; const response = await this._requestAndRetry(() => - this._fetch('' + new URL(`/api/v2/status`, this._host), { headers }), + this._fetch('' + new URL(`/api/v2/status`, this._host), { headers, ...this._fetchOptions }), ); return cbor.decode(await response.arrayBuffer()); From 8b6b183cbf5670006d5c21e03eac99946e19d353 Mon Sep 17 00:00:00 2001 From: Sue Ann Kim Date: Tue, 1 Nov 2022 16:37:56 -0700 Subject: [PATCH 06/12] added callOptions, and changed assignment logic of this._fetchOptions --- packages/agent/src/agent/http/index.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts index 021ef7ff3..3a885d3ae 100644 --- a/packages/agent/src/agent/http/index.ts +++ b/packages/agent/src/agent/http/index.ts @@ -76,6 +76,9 @@ export interface HttpAgentOptions { // the agent already needs to set fetchOptions?: Record; + // Additional options to pass along to fetch for the call API. + callOptions?: Record; + // The host to use for the client. By default, uses the same host as // the current page. host?: string; @@ -167,6 +170,7 @@ export class HttpAgent implements Agent { private _identity: Promise | null; private readonly _fetch: typeof fetch; private readonly _fetchOptions?: Record; + private readonly _callOptions?: Record; private _timeDiffMsecs = 0; private readonly _host: URL; private readonly _credentials: string | undefined; @@ -182,7 +186,8 @@ export class HttpAgent implements Agent { this._pipeline = [...options.source._pipeline]; this._identity = options.source._identity; this._fetch = options.source._fetch; - this._fetchOptions = options.source._fetchOptions; + this._fetchOptions = options.source._fetchOptions || options.fetchOptions; + this._callOptions = options.source._fetchOptions || options.callOptions; this._host = options.source._host; this._credentials = options.source._credentials; } else { @@ -307,6 +312,7 @@ export class HttpAgent implements Agent { const request = this._requestAndRetry(() => this._fetch('' + new URL(`/api/v2/canister/${ecid.toText()}/call`, this._host), { + ...this._callOptions, ...transformedRequest.request, body, }), From 425f0b1c8e814494bdab1f4c2b7fa8c140f44040 Mon Sep 17 00:00:00 2001 From: Sue Ann Kim Date: Tue, 1 Nov 2022 16:46:10 -0700 Subject: [PATCH 07/12] Typo error. In case options.source is correctly implemented I've still included the logic: - `this._fetchOptions = options.source._fetchOptions || options.fetchOptions;` - `this._callOptions = options.source._callOptions || options.callOptions;` --- packages/agent/src/agent/http/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts index 3a885d3ae..056d64158 100644 --- a/packages/agent/src/agent/http/index.ts +++ b/packages/agent/src/agent/http/index.ts @@ -187,7 +187,7 @@ export class HttpAgent implements Agent { this._identity = options.source._identity; this._fetch = options.source._fetch; this._fetchOptions = options.source._fetchOptions || options.fetchOptions; - this._callOptions = options.source._fetchOptions || options.callOptions; + this._callOptions = options.source._callOptions || options.callOptions; this._host = options.source._host; this._credentials = options.source._credentials; } else { From 1be96e0ef13224c499cc8701052bc44abf15f675 Mon Sep 17 00:00:00 2001 From: Sue Ann Kim Date: Tue, 8 Nov 2022 09:46:05 -0800 Subject: [PATCH 08/12] When source isn't provided in constructing the HttpAgent, this._fetchOptions and this._callOptions will automatically get fromm provided options. --- packages/agent/src/agent/http/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts index 056d64158..e52709762 100644 --- a/packages/agent/src/agent/http/index.ts +++ b/packages/agent/src/agent/http/index.ts @@ -186,12 +186,12 @@ export class HttpAgent implements Agent { this._pipeline = [...options.source._pipeline]; this._identity = options.source._identity; this._fetch = options.source._fetch; - this._fetchOptions = options.source._fetchOptions || options.fetchOptions; - this._callOptions = options.source._callOptions || options.callOptions; this._host = options.source._host; this._credentials = options.source._credentials; } else { this._fetch = options.fetch || getDefaultFetch() || fetch.bind(global); + this._fetchOptions = options.fetchOptions; + this._callOptions = options.callOptions; } if (options.host !== undefined) { if (!options.host.match(/^[a-z]+:/) && typeof window !== 'undefined') { From be9bf079977b3b7a402c46534bf5b0d891865330 Mon Sep 17 00:00:00 2001 From: Sue Ann Kim Date: Thu, 10 Nov 2022 11:40:58 -0800 Subject: [PATCH 09/12] Migration Change from port 8000 to 4943 for new DFX 0.12.0 -made changes mainly inside tests and yml setup --- .github/workflows/e2e-tests.yml | 4 ++-- .github/workflows/mitm.yml | 4 ++-- e2e/browser/.proxyrc | 2 +- packages/agent/src/agent/http/http.test.ts | 20 +++++++++---------- .../agent/src/canisterStatus/index.test.ts | 2 +- packages/auth-client/src/index.test.ts | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index d0121c02e..6d15d72cc 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -45,12 +45,12 @@ jobs: - run: npm run e2e --workspaces --if-present env: CI: true - REPLICA_PORT: 8000 + REPLICA_PORT: 4943 aggregate: name: e2e:required if: ${{ always() }} - needs: [ test ] + needs: [test] runs-on: ubuntu-latest steps: - name: check e2e test result diff --git a/.github/workflows/mitm.yml b/.github/workflows/mitm.yml index c1c65d824..33150f1cf 100644 --- a/.github/workflows/mitm.yml +++ b/.github/workflows/mitm.yml @@ -51,7 +51,7 @@ jobs: id: mitmdump run: | set -ex - mitmdump -p 8888 --mode reverse:http://127.0.0.1:8000 \ + mitmdump -p 8888 --mode reverse:http://127.0.0.1:4943 \ --modify-headers '/~s/Transfer-Encoding/' \ --modify-body '/~s/Hello/Hullo' \ & @@ -67,7 +67,7 @@ jobs: aggregate: name: mitm:required if: ${{ always() }} - needs: [ test ] + needs: [test] runs-on: ubuntu-latest steps: - name: check e2e test result diff --git a/e2e/browser/.proxyrc b/e2e/browser/.proxyrc index 190c27806..e85d9991a 100644 --- a/e2e/browser/.proxyrc +++ b/e2e/browser/.proxyrc @@ -1,5 +1,5 @@ { "/api": { - "target": "http://localhost:8000/", + "target": "http://localhost:4943/", } } diff --git a/packages/agent/src/agent/http/http.test.ts b/packages/agent/src/agent/http/http.test.ts index 5c4613acf..9fa5baabc 100644 --- a/packages/agent/src/agent/http/http.test.ts +++ b/packages/agent/src/agent/http/http.test.ts @@ -313,26 +313,26 @@ test('use anonymous principal if unspecified', async () => { describe('getDefaultFetch', () => { it("should use fetch from window if it's available", async () => { - const generateAgent = () => new HttpAgent({ host: 'localhost:8000' }); + const generateAgent = () => new HttpAgent({ host: 'localhost:4943' }); expect(generateAgent).not.toThrowError(); }); it('should throw an error if fetch is not available on the window object', async () => { delete (window as any).fetch; - const generateAgent = () => new HttpAgent({ host: 'localhost:8000' }); + const generateAgent = () => new HttpAgent({ host: 'localhost:4943' }); expect(generateAgent).toThrowError('Fetch implementation was not available'); }); it('should throw error for defaultFetch with no window or global fetch', () => { delete (global as any).window; delete (global as any).fetch; - const generateAgent = () => new HttpAgent({ host: 'localhost:8000' }); + const generateAgent = () => new HttpAgent({ host: 'localhost:4943' }); expect(generateAgent).toThrowError('Fetch implementation was not available'); }); it('should fall back to global.fetch if window is not available', () => { delete (global as any).window; global.fetch = originalFetch; - const generateAgent = () => new HttpAgent({ host: 'localhost:8000' }); + const generateAgent = () => new HttpAgent({ host: 'localhost:4943' }); expect(generateAgent).not.toThrowError(); }); @@ -494,7 +494,7 @@ describe('retry failures', () => { statusText: 'Internal Server Error', }), ); - const agent = new HttpAgent({ host: 'http://localhost:8000', fetch: mockFetch, retryTimes: 0 }); + const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch, retryTimes: 0 }); expect( agent.call(Principal.managementCanister(), { methodName: 'test', @@ -510,7 +510,7 @@ describe('retry failures', () => { }); }); - const agent = new HttpAgent({ host: 'http://localhost:8000', fetch: mockFetch }); + const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch }); try { expect( agent.call(Principal.managementCanister(), { @@ -540,7 +540,7 @@ describe('retry failures', () => { } }); - const agent = new HttpAgent({ host: 'http://localhost:8000', fetch: mockFetch }); + const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch }); const result = await agent.call(Principal.managementCanister(), { methodName: 'test', arg: new Uint8Array().buffer, @@ -556,7 +556,7 @@ test('should change nothing if time is within 30 seconds of replica', async () = // jest.setSystemTime(systemTime); const mockFetch = jest.fn(); - const agent = new HttpAgent({ host: 'http://localhost:8000', fetch: mockFetch }); + const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch }); await agent.syncTime(); @@ -590,7 +590,7 @@ test('should adjust the Expiry if the clock is more than 30 seconds behind', asy await import('../../canisterStatus'); const { HttpAgent } = await import('../index'); - const agent = new HttpAgent({ host: 'http://localhost:8000', fetch: mockFetch }); + const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch }); await agent.syncTime(); @@ -633,7 +633,7 @@ test('should adjust the Expiry if the clock is more than 30 seconds ahead', asyn await import('../../canisterStatus'); const { HttpAgent } = await import('../index'); - const agent = new HttpAgent({ host: 'http://localhost:8000', fetch: mockFetch }); + const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch }); await agent.syncTime(); diff --git a/packages/agent/src/canisterStatus/index.test.ts b/packages/agent/src/canisterStatus/index.test.ts index 4d1f0d40f..51e55a7a0 100644 --- a/packages/agent/src/canisterStatus/index.test.ts +++ b/packages/agent/src/canisterStatus/index.test.ts @@ -46,7 +46,7 @@ const getRealStatus = async () => { ), )) as unknown as Identity; - const agent = new HttpAgent({ host: 'http://127.0.0.1:8000', fetch, identity }); + const agent = new HttpAgent({ host: 'http://127.0.0.1:4943', fetch, identity }); await agent.fetchRootKey(); const canisterBuffer = new DataView(testPrincipal.toUint8Array().buffer).buffer; canisterBuffer; diff --git a/packages/auth-client/src/index.test.ts b/packages/auth-client/src/index.test.ts index 7c1525929..9c59be3e3 100644 --- a/packages/auth-client/src/index.test.ts +++ b/packages/auth-client/src/index.test.ts @@ -85,7 +85,7 @@ describe('Auth Client', () => { (window as any).location = { reload: jest.fn(), fetch, - toString: jest.fn(() => 'http://localhost:8000'), + toString: jest.fn(() => 'http://localhost:4943'), }; const identity = Ed25519KeyIdentity.generate(); From 4f659bd4fd0e07e1821467e154983ae446357a40 Mon Sep 17 00:00:00 2001 From: Sue Ann Kim Date: Thu, 10 Nov 2022 14:31:23 -0800 Subject: [PATCH 10/12] Node 12 support deprecated, along with recent latest npm version 9.1.1 does not support node 12. --- .github/workflows/unit-tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 534988c77..a35d85a6b 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -19,7 +19,6 @@ jobs: spec: - '0.16.1' node: - - 12 - 14 - 16 From 56071af53335517adae319dbb40afad1e66eb959 Mon Sep 17 00:00:00 2001 From: Sue Ann Kim Date: Wed, 16 Nov 2022 15:47:32 -0800 Subject: [PATCH 11/12] Unit test added for agent/http.test.ts --- packages/agent/src/agent/http/http.test.ts | 49 +++++++++++++++++----- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/packages/agent/src/agent/http/http.test.ts b/packages/agent/src/agent/http/http.test.ts index 9fa5baabc..04bcf70d7 100644 --- a/packages/agent/src/agent/http/http.test.ts +++ b/packages/agent/src/agent/http/http.test.ts @@ -22,6 +22,8 @@ const { window } = new JSDOM(`

Hello world

`); window.fetch = global.fetch; (global as any).window = window; +const HTTP_AGENT_HOST = 'http://localhost:4943'; + const DEFAULT_INGRESS_EXPIRY_DELTA_IN_MSECS = 5 * 60 * 1000; const REPLICA_PERMITTED_DRIFT_MILLISECONDS = 60 * 1000; const NANOSECONDS_PER_MILLISECONDS = 1_000_000; @@ -313,26 +315,26 @@ test('use anonymous principal if unspecified', async () => { describe('getDefaultFetch', () => { it("should use fetch from window if it's available", async () => { - const generateAgent = () => new HttpAgent({ host: 'localhost:4943' }); + const generateAgent = () => new HttpAgent({ host: HTTP_AGENT_HOST }); expect(generateAgent).not.toThrowError(); }); it('should throw an error if fetch is not available on the window object', async () => { delete (window as any).fetch; - const generateAgent = () => new HttpAgent({ host: 'localhost:4943' }); + const generateAgent = () => new HttpAgent({ host: HTTP_AGENT_HOST }); expect(generateAgent).toThrowError('Fetch implementation was not available'); }); it('should throw error for defaultFetch with no window or global fetch', () => { delete (global as any).window; delete (global as any).fetch; - const generateAgent = () => new HttpAgent({ host: 'localhost:4943' }); + const generateAgent = () => new HttpAgent({ host: HTTP_AGENT_HOST }); expect(generateAgent).toThrowError('Fetch implementation was not available'); }); it('should fall back to global.fetch if window is not available', () => { delete (global as any).window; global.fetch = originalFetch; - const generateAgent = () => new HttpAgent({ host: 'localhost:4943' }); + const generateAgent = () => new HttpAgent({ host: HTTP_AGENT_HOST }); expect(generateAgent).not.toThrowError(); }); @@ -494,7 +496,7 @@ describe('retry failures', () => { statusText: 'Internal Server Error', }), ); - const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch, retryTimes: 0 }); + const agent = new HttpAgent({ host: HTTP_AGENT_HOST, fetch: mockFetch, retryTimes: 0 }); expect( agent.call(Principal.managementCanister(), { methodName: 'test', @@ -510,7 +512,7 @@ describe('retry failures', () => { }); }); - const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch }); + const agent = new HttpAgent({ host: HTTP_AGENT_HOST, fetch: mockFetch }); try { expect( agent.call(Principal.managementCanister(), { @@ -540,7 +542,7 @@ describe('retry failures', () => { } }); - const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch }); + const agent = new HttpAgent({ host: HTTP_AGENT_HOST, fetch: mockFetch }); const result = await agent.call(Principal.managementCanister(), { methodName: 'test', arg: new Uint8Array().buffer, @@ -556,7 +558,7 @@ test('should change nothing if time is within 30 seconds of replica', async () = // jest.setSystemTime(systemTime); const mockFetch = jest.fn(); - const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch }); + const agent = new HttpAgent({ host: HTTP_AGENT_HOST, fetch: mockFetch }); await agent.syncTime(); @@ -590,7 +592,7 @@ test('should adjust the Expiry if the clock is more than 30 seconds behind', asy await import('../../canisterStatus'); const { HttpAgent } = await import('../index'); - const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch }); + const agent = new HttpAgent({ host: HTTP_AGENT_HOST, fetch: mockFetch }); await agent.syncTime(); @@ -633,7 +635,7 @@ test('should adjust the Expiry if the clock is more than 30 seconds ahead', asyn await import('../../canisterStatus'); const { HttpAgent } = await import('../index'); - const agent = new HttpAgent({ host: 'http://localhost:4943', fetch: mockFetch }); + const agent = new HttpAgent({ host: HTTP_AGENT_HOST, fetch: mockFetch }); await agent.syncTime(); @@ -657,3 +659,30 @@ test('should adjust the Expiry if the clock is more than 30 seconds ahead', asyn expect(delay).toBe(-1 * DEFAULT_INGRESS_EXPIRY_DELTA_IN_MSECS); jest.resetModules(); }); +test('should fetch with given call options and fetch options', async () => { + const mockFetch: jest.Mock = jest.fn(); + + const agent = new HttpAgent({ + fetch: mockFetch, + callOptions: { + reactNative: { textStreaming: true }, + }, + fetchOptions: { + reactNative: { + __nativeResponseType: 'base64', + }, + }, + }); + + const canisterString = 'ryjl3-tyaaa-aaaaa-aaaba-cai'; + + agent.call(canisterString, { + methodName: 'greet', + arg: new Uint8Array([]), + }); + + expect(mockFetch.mock.calls[0][1].fetchOptions.reactNative.__nativeResponseType.toBe('base64')); + expect(mockFetch.mock.calls[0][1].callOptions.reactNative.toBe({ textStreaming: true })); + + jest.resetModules(); +}); From b7c8e505ee4fe38cb11029d0f3c16214b62a864a Mon Sep 17 00:00:00 2001 From: rvanasa Date: Wed, 16 Nov 2022 19:03:49 -0700 Subject: [PATCH 12/12] Test both call and query behavior --- packages/agent/src/agent/http/http.test.ts | 27 ++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/packages/agent/src/agent/http/http.test.ts b/packages/agent/src/agent/http/http.test.ts index 04bcf70d7..6c5b85b58 100644 --- a/packages/agent/src/agent/http/http.test.ts +++ b/packages/agent/src/agent/http/http.test.ts @@ -659,11 +659,21 @@ test('should adjust the Expiry if the clock is more than 30 seconds ahead', asyn expect(delay).toBe(-1 * DEFAULT_INGRESS_EXPIRY_DELTA_IN_MSECS); jest.resetModules(); }); + test('should fetch with given call options and fetch options', async () => { - const mockFetch: jest.Mock = jest.fn(); + const mockFetch: jest.Mock = jest.fn(() => { + const body = cbor.encode({}); + return Promise.resolve( + new Response(body, { + status: 200, + }), + ); + }); - const agent = new HttpAgent({ + const canisterId: Principal = Principal.fromText('2chl6-4hpzw-vqaaa-aaaaa-c'); + const httpAgent = new HttpAgent({ fetch: mockFetch, + host: 'http://localhost', callOptions: { reactNative: { textStreaming: true }, }, @@ -674,15 +684,18 @@ test('should fetch with given call options and fetch options', async () => { }, }); - const canisterString = 'ryjl3-tyaaa-aaaaa-aaaba-cai'; + await httpAgent.call(canisterId, { + methodName: 'greet', + arg: new Uint8Array([]), + }); - agent.call(canisterString, { + await httpAgent.query(canisterId, { methodName: 'greet', arg: new Uint8Array([]), }); - expect(mockFetch.mock.calls[0][1].fetchOptions.reactNative.__nativeResponseType.toBe('base64')); - expect(mockFetch.mock.calls[0][1].callOptions.reactNative.toBe({ textStreaming: true })); + const { calls } = mockFetch.mock; - jest.resetModules(); + expect(calls[0][1].reactNative).toStrictEqual({ textStreaming: true }); + expect(calls[1][1].reactNative.__nativeResponseType).toBe('base64'); });