Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions js-user-library/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion js-user-library/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"jest": "^24.9.0",
"jest-expect-message": "^1.0.2",
"tslint": "^5.20.0",
"typescript": "^3.6.3"
"typescript": "^3.6.3",
"whatwg-fetch": "^3.0.0"
}
}
12 changes: 12 additions & 0 deletions js-user-library/src/callRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { BinaryBlob } from "./blob";
import { CanisterId } from "./canisterId";
import { Request } from "./request";
import { SubmitRequestType } from "./submitRequestType";

// The fields in a "call" submit request.
export interface CallRequest extends Request {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when we extend Request is there a standard way of ordering the fields in the encoding?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean the CBOR encoding? I haven't given that much thought and have been relying on the borc package for that. It seems to be deterministic though.

request_type: SubmitRequestType.Call;
canister_id: CanisterId;
method_name: string;
arg: BinaryBlob;
}
139 changes: 139 additions & 0 deletions js-user-library/src/httpAgent.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { BinaryBlob } from "./blob";
import * as canisterId from "./canisterId";
import * as cbor from "./cbor";
import { Hex } from "./hex";
import { makeHttpAgent } from "./index";
import { Nonce } from "./nonce";
import { Request } from "./request";
import { requestIdOf } from "./requestId";
import { RequestType } from "./requestType";
import { SenderPubKey } from "./senderPubKey";
import { SenderSig } from "./senderSig";

test("call", async () => {
const mockFetch: jest.Mock = jest.fn((resource, init) => {
return Promise.resolve(new Response(null, {
status: 200,
}));
});

const canisterIdent = "0000000000000001" as Hex;
const nonce = Uint8Array.from([0, 1, 2, 3, 4, 5, 6, 7]) as Nonce;
const senderPubKey = new Uint8Array(32) as SenderPubKey;
const senderSig = new Uint8Array(64) as SenderSig;

const httpAgent = makeHttpAgent({
canisterId: canisterIdent,
fetchFn: mockFetch,
nonceFn: () => nonce,
senderPubKey,
senderSigFn: () => senderSig,
});

const methodName = "greet";
const arg = Uint8Array.from([]) as BinaryBlob;

const { requestId, response } = await httpAgent.call({
methodName,
arg,
});

const expectedRequest: Request = {
request_type: "call" as RequestType,
nonce,
canister_id: canisterId.fromHex(canisterIdent),
method_name: methodName,
arg,
sender_pubkey: senderPubKey,
sender_sig: senderSig,
};

const expectedRequestId = await requestIdOf(expectedRequest);

const { calls, results } = mockFetch.mock;
expect(calls.length).toBe(1);
expect(requestId).toEqual(expectedRequestId);

expect(calls[0][0]).toBe("http://localhost:8000/api/v1/submit");
expect(calls[0][1]).toEqual({
method: "POST",
headers: {
"Content-Type": "application/cbor",
},
body: cbor.encode(expectedRequest),
});
});

test.todo("query");

test("requestStatus", async () => {
const mockResponse = {
status: "replied",
reply: { arg: Uint8Array.from([]) as BinaryBlob },
};

const mockFetch: jest.Mock = jest.fn((resource, init) => {
const body = cbor.encode(mockResponse);
return Promise.resolve(new Response(body, {
status: 200,
}));
});

const canisterIdent = "0000000000000001" as Hex;
const nonce = Uint8Array.from([0, 1, 2, 3, 4, 5, 6, 7]) as Nonce;
const senderPubKey = new Uint8Array(32) as SenderPubKey;
const senderSig = new Uint8Array(64) as SenderSig;

const httpAgent = makeHttpAgent({
canisterId: canisterIdent,
fetchFn: mockFetch,
nonceFn: () => nonce,
senderPubKey,
senderSigFn: () => senderSig,
});

const requestId = await requestIdOf({
request_type: "call" as RequestType,
nonce,
canister_id: canisterId.fromHex(canisterIdent),
method_name: "greet",
arg: Uint8Array.from([]),
});

const response = await httpAgent.requestStatus({
requestId,
});

const expectedRequest: Request = {
request_type: "request-status" as RequestType,
nonce,
request_id: requestId,
sender_pubkey: senderPubKey,
sender_sig: senderSig,
};

const { calls, results } = mockFetch.mock;
expect(calls.length).toBe(1);

const {
reply: { arg: responseArg },
...responseRest
} = response;

const {
reply: { arg: mockResponseArg },
...mockResponseRest
} = mockResponse;

expect(responseRest).toEqual(mockResponseRest);
expect(responseArg.equals(mockResponseArg)).toBe(true);

expect(calls[0][0]).toBe("http://localhost:8000/api/v1/read");
expect(calls[0][1]).toEqual({
method: "POST",
headers: {
"Content-Type": "application/cbor",
},
body: cbor.encode(expectedRequest),
});
});
Loading