Skip to content

Commit a7e90e8

Browse files
committed
fix: tests
1 parent e3b0251 commit a7e90e8

7 files changed

Lines changed: 321 additions & 382 deletions

File tree

packages/wallet-sdk/package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"build": "tsc -p tsconfig.build.json",
88
"test": "vitest run",
99
"test:watch": "vitest",
10-
"check-types": "tsc --noEmit"
10+
"check-types": "tsc --noEmit",
11+
"postinstall": "npm run build"
1112
},
1213
"keywords": [],
1314
"author": "",
@@ -20,12 +21,14 @@
2021
"types": "./dist/index.d.ts"
2122
}
2223
},
23-
"files": ["dist"],
24+
"files": [
25+
"dist"
26+
],
2427
"dependencies": {
2528
"jose": "^5.2.0"
2629
},
2730
"devDependencies": {
2831
"typescript": "~5.6.2",
2932
"vitest": "^3.0.9"
3033
}
31-
}
34+
}
Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,33 @@
1-
import type { CryptoAdapter } from "../crypto-adapter";
1+
import type { CryptoAdapter } from "../crypto-adapter.js";
22

33
const TEST_PUBLIC_KEY = "test-public-key-base64-or-multibase";
44
const KEY_ID = "test-key-1";
55

6+
function toBase64(s: string): string {
7+
return btoa(String.fromCharCode(...new TextEncoder().encode(s)));
8+
}
9+
610
/**
711
* In-memory test double for CryptoAdapter. Deterministic key and fake signatures.
812
* For use in SDK unit/integration tests only; no real crypto.
913
*/
1014
export class TestCryptoAdapter implements CryptoAdapter {
11-
private keys = new Map<string, string>();
15+
private keys = new Map<string, string>();
1216

13-
async generateKeyPair(): Promise<{ keyId: string; publicKey: string }> {
14-
this.keys.set(KEY_ID, TEST_PUBLIC_KEY);
15-
return { keyId: KEY_ID, publicKey: TEST_PUBLIC_KEY };
16-
}
17+
async getPublicKey(keyId: string, _context: string): Promise<string | undefined> {
18+
const pk = this.keys.get(keyId) ?? TEST_PUBLIC_KEY;
19+
return pk;
20+
}
1721

18-
async getPublicKey(keyId: string): Promise<string> {
19-
const pk = this.keys.get(keyId) ?? TEST_PUBLIC_KEY;
20-
return pk;
21-
}
22+
async signPayload(keyId: string, _context: string, payload: string): Promise<string> {
23+
return `sig:${keyId}:${toBase64(payload)}`;
24+
}
2225

23-
async sign(keyId: string, payload: string): Promise<string> {
24-
return `sig:${keyId}:${Buffer.from(payload, "utf-8").toString("base64")}`;
25-
}
26+
async ensureKey(keyId: string, _context: string): Promise<{ created: boolean }> {
27+
if (!this.keys.has(keyId)) {
28+
this.keys.set(keyId, TEST_PUBLIC_KEY);
29+
return { created: true };
30+
}
31+
return { created: false };
32+
}
2633
}
Lines changed: 35 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,37 @@
11
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2-
import { authenticateToPlatform, parseAuthUri } from "../auth";
3-
import { TestCryptoAdapter } from "./TestCryptoAdapter";
4-
5-
describe("parseAuthUri", () => {
6-
it("parses w3ds://auth URI", () => {
7-
const uri =
8-
"w3ds://auth?redirect=https%3A%2F%2Fplatform.test%2Fapi%2Fauth&session=sess-123&platform=myapp";
9-
const parsed = parseAuthUri(uri);
10-
expect(parsed.redirectUrl).toBe("https://platform.test/api/auth");
11-
expect(parsed.sessionId).toBe("sess-123");
12-
expect(parsed.platform).toBe("myapp");
13-
});
14-
15-
it("throws on invalid URL", () => {
16-
expect(() => parseAuthUri("not-a-url")).toThrow("Invalid auth URI");
17-
});
18-
19-
it("throws on wrong scheme", () => {
20-
expect(() => parseAuthUri("https://auth?redirect=x&session=y")).toThrow(
21-
"expected scheme w3ds://auth"
22-
);
23-
});
24-
25-
it("throws when redirect missing", () => {
26-
expect(() =>
27-
parseAuthUri("w3ds://auth?session=s1&platform=p")
28-
).toThrow("missing redirect");
29-
});
30-
31-
it("throws when session missing", () => {
32-
expect(() =>
33-
parseAuthUri("w3ds://auth?redirect=https%3A%2F%2Fa.b%2Fc&platform=p")
34-
).toThrow("missing session");
35-
});
36-
});
37-
38-
describe("authenticateToPlatform", () => {
39-
const adapter = new TestCryptoAdapter();
40-
41-
beforeEach(async () => {
42-
await adapter.generateKeyPair();
43-
});
44-
45-
afterEach(() => {
46-
vi.unstubAllGlobals();
47-
});
48-
49-
it("POSTs ename, session, signature to redirect URL", async () => {
50-
const authUri =
51-
"w3ds://auth?redirect=https%3A%2F%2Fplatform.test%2Fapi%2Fauth&session=sess-456&platform=test";
52-
let capturedBody: Record<string, string> = {};
53-
vi.stubGlobal(
54-
"fetch",
55-
vi.fn((input: string | URL, init?: RequestInit) => {
56-
const url = typeof input === "string" ? input : input.toString();
57-
if (url === "https://platform.test/api/auth") {
58-
capturedBody = init?.body ? JSON.parse(init.body as string) : {};
59-
return Promise.resolve(
60-
new Response(JSON.stringify({ token: "jwt-123" }), { status: 200 })
61-
);
62-
}
63-
return Promise.reject(new Error(`Unexpected: ${url}`));
64-
})
65-
);
66-
67-
const result = await authenticateToPlatform({
68-
cryptoAdapter: adapter,
69-
keyId: "test-key-1",
70-
w3id: "w3id-xyz",
71-
authUri,
72-
});
73-
74-
expect(result.success).toBe(true);
75-
expect(result.token).toBe("jwt-123");
76-
expect(capturedBody.ename).toBe("w3id-xyz");
77-
expect(capturedBody.session).toBe("sess-456");
78-
expect(capturedBody.signature).toMatch(/^sig:test-key-1:/);
79-
});
80-
81-
it("includes appVersion when provided", async () => {
82-
const authUri =
83-
"w3ds://auth?redirect=https%3A%2F%2Fp.test%2Fauth&session=s1&platform=p";
84-
let capturedBody: Record<string, string> = {};
85-
vi.stubGlobal(
86-
"fetch",
87-
vi.fn((_input: string | URL, init?: RequestInit) => {
88-
capturedBody = init?.body ? JSON.parse(init.body as string) : {};
89-
return Promise.resolve(
90-
new Response(JSON.stringify({}), { status: 200 })
91-
);
92-
})
93-
);
94-
95-
await authenticateToPlatform({
96-
cryptoAdapter: adapter,
97-
keyId: "test-key-1",
98-
w3id: "w3id",
99-
authUri,
100-
appVersion: "1.0.0",
101-
});
102-
103-
expect(capturedBody.appVersion).toBe("1.0.0");
104-
});
105-
106-
it("throws when platform returns error", async () => {
107-
const authUri =
108-
"w3ds://auth?redirect=https%3A%2F%2Fp.test%2Fauth&session=s1&platform=p";
109-
vi.stubGlobal(
110-
"fetch",
111-
vi.fn(() =>
112-
Promise.resolve(
113-
new Response(
114-
JSON.stringify({ error: "Invalid session" }),
115-
{ status: 400 }
116-
)
117-
)
118-
)
119-
);
120-
121-
await expect(
122-
authenticateToPlatform({
123-
cryptoAdapter: adapter,
124-
keyId: "test-key-1",
125-
w3id: "w3id",
126-
authUri,
127-
})
128-
).rejects.toThrow(/Platform auth failed/);
129-
});
2+
import { authenticate } from "../auth.js";
3+
import { TestCryptoAdapter } from "./TestCryptoAdapter.js";
4+
5+
describe("authenticate", () => {
6+
const adapter = new TestCryptoAdapter();
7+
const CONTEXT = "onboarding";
8+
9+
beforeEach(async () => {
10+
await adapter.ensureKey("default", CONTEXT);
11+
});
12+
13+
afterEach(() => {
14+
vi.unstubAllGlobals();
15+
});
16+
17+
it("returns signature from adapter", async () => {
18+
const result = await authenticate(adapter, {
19+
sessionId: "sess-123",
20+
keyId: "default",
21+
context: CONTEXT,
22+
});
23+
expect(result.signature).toMatch(/^sig:default:/);
24+
const b64 = result.signature.replace(/^sig:default:/, "");
25+
expect(atob(b64)).toBe("sess-123");
26+
});
27+
28+
it("uses custom keyId when provided", async () => {
29+
await adapter.ensureKey("test-key-1", CONTEXT);
30+
const result = await authenticate(adapter, {
31+
sessionId: "hello",
32+
keyId: "test-key-1",
33+
context: CONTEXT,
34+
});
35+
expect(result.signature).toMatch(/^sig:test-key-1:/);
36+
});
13037
});

0 commit comments

Comments
 (0)