attestation-canister.test.mjs
90 lines 3.2 KB
Raw
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf mirror: GitHub Phase A durable MCP OAuth (#270) Human minor ⚠ breaking 10 days ago
1 /**
2 * Integration tests for the ICP attestation canister.
3 *
4 * Requires a local dfx replica with the attestation canister deployed:
5 * cd hub/icp && dfx start --background && dfx deploy attestation
6 *
7 * Run:
8 * ATTESTATION_CANISTER_URL=http://localhost:4943/?canisterId=<id> \
9 * node --test test/attestation-canister.test.mjs
10 *
11 * These tests verify the canister's HTTP query interface (read-only).
12 * The Candid storeAttestation method requires an authorized caller identity,
13 * so write tests use @icp-sdk/core agent calls.
14 *
15 * When ATTESTATION_CANISTER_URL is not set, all tests are skipped gracefully.
16 */
17
18 import { test, describe } from 'node:test';
19 import assert from 'node:assert/strict';
20
21 const CANISTER_URL = process.env.ATTESTATION_CANISTER_URL;
22 const skipReason = CANISTER_URL
23 ? null
24 : 'ATTESTATION_CANISTER_URL not set (requires local dfx replica)';
25
26 describe('attestation canister HTTP interface', { skip: skipReason }, () => {
27 test('GET /health returns ok', async () => {
28 const res = await fetch(`${CANISTER_URL}/health`);
29 assert.equal(res.status, 200);
30 const body = await res.json();
31 assert.equal(body.ok, true);
32 assert.equal(body.canister, 'attestation');
33 });
34
35 test('GET /stats returns total and next_seq', async () => {
36 const res = await fetch(`${CANISTER_URL}/stats`);
37 assert.equal(res.status, 200);
38 const body = await res.json();
39 assert.ok(typeof body.total === 'number', 'total should be a number');
40 assert.ok(typeof body.next_seq === 'number', 'next_seq should be a number');
41 assert.ok(body.total >= 0);
42 });
43
44 test('GET /attest/nonexistent-id returns 404', async () => {
45 const res = await fetch(`${CANISTER_URL}/attest/air-00000000-0000-0000-0000-000000000000`);
46 assert.equal(res.status, 404);
47 const body = await res.json();
48 assert.equal(body.code, 'NOT_FOUND');
49 });
50
51 test('GET /unknown returns 404', async () => {
52 const res = await fetch(`${CANISTER_URL}/unknown-path`);
53 assert.equal(res.status, 404);
54 });
55
56 test('OPTIONS returns 204 with CORS headers', async () => {
57 const res = await fetch(`${CANISTER_URL}/health`, { method: 'OPTIONS' });
58 assert.equal(res.status, 204);
59 const allow = res.headers.get('access-control-allow-origin');
60 assert.equal(allow, '*');
61 });
62 });
63
64 describe('attestation canister Candid interface', { skip: skipReason }, () => {
65 let canisterId;
66
67 test('can query getStats via Candid', async () => {
68 if (!process.env.ATTESTATION_CANISTER_ID_LOCAL) {
69 return;
70 }
71 canisterId = process.env.ATTESTATION_CANISTER_ID_LOCAL;
72
73 const { HttpAgent, Actor } = await import('@icp-sdk/core/agent');
74 const { IDL } = await import('@icp-sdk/core/candid');
75
76 const idlFactory = ({ IDL: _IDL }) => {
77 return IDL.Service({
78 getStats: IDL.Func([], [IDL.Record({ total: IDL.Nat, nextSeq: IDL.Nat })], ['query']),
79 });
80 };
81
82 const agent = await HttpAgent.create({ host: 'http://localhost:4943' });
83 await agent.fetchRootKey();
84
85 const actor = Actor.createActor(idlFactory, { agent, canisterId });
86 const stats = await actor.getStats();
87 assert.ok(typeof stats.total === 'bigint' || typeof stats.total === 'number');
88 assert.ok(stats.total >= 0n || stats.total >= 0);
89 });
90 });
File History 4 commits
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf mirror: GitHub Phase A durable MCP OAuth (#270) Human minor 10 days ago
sha256:d8c648b20a4d53b2673c5c082ee7edfa7b2fc9b11080832da1f38807b6bf940b fix(7C-L1b): route hosted delegation proposals through cani… Human minor 30 days ago
sha256:2827ba9e7632a4b141c50caf1e8f7d77abbc3515be20e7465f2bccb0ac4edf91 fix: repair endpoint now sets has_active_subscription when … Human minor 50 days ago