Skip to content

Commit 326ba95

Browse files
committed
chore(js): copy bun tests into browser context
1 parent beab6cd commit 326ba95

File tree

2 files changed

+263
-0
lines changed

2 files changed

+263
-0
lines changed

crypto-ffi/bindings/js/src/CoreCrypto.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ export {
129129
type AcmeDirectory,
130130
ProteusAutoPrekeyBundle,
131131
BufferedDecryptedMessage,
132+
Keypackage,
133+
KeypackageRef,
132134
type KeypackageInterface,
133135
type KeypackageRefInterface,
134136
SignatureScheme,
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
import { browser, expect } from "@wdio/globals";
2+
import { ccInit, setup, teardown } from "./utils";
3+
import { afterEach, beforeEach, describe } from "mocha";
4+
5+
beforeEach(async () => {
6+
await setup();
7+
});
8+
9+
afterEach(async () => {
10+
await teardown();
11+
});
12+
13+
describe("key package", () => {
14+
it("can be created", async () => {
15+
const clientId = crypto.randomUUID();
16+
await ccInit(clientId, false);
17+
18+
const { threwError, wasDefined } = await browser.execute(
19+
async (clientIdBytes) => {
20+
const encoder = new TextEncoder();
21+
const clientId = new window.ccModule.ClientId(
22+
encoder.encode(clientIdBytes).buffer
23+
);
24+
25+
const cc = window.cc.get(clientIdBytes)!;
26+
27+
const credential = window.ccModule.credentialBasic(
28+
window.ccModule.ciphersuiteDefault(),
29+
clientId
30+
);
31+
32+
const credentialRef = await cc.transaction(async (ctx) => {
33+
return await ctx.addCredential(credential);
34+
});
35+
36+
let threwError = false;
37+
let keyPackage = undefined;
38+
try {
39+
keyPackage = await cc.transaction(async (ctx) => {
40+
return await ctx.generateKeypackage(credentialRef);
41+
});
42+
} catch {
43+
threwError = true;
44+
}
45+
46+
const wasDefined =
47+
keyPackage !== null && keyPackage !== undefined;
48+
49+
return { threwError, wasDefined };
50+
},
51+
clientId
52+
);
53+
54+
expect(threwError).toBe(false);
55+
expect(wasDefined).toBe(true);
56+
});
57+
58+
it("can be serialized", async () => {
59+
const clientId = crypto.randomUUID();
60+
await ccInit(clientId, false);
61+
62+
const { wasDefined, wasEmpty, roundtripMatches } =
63+
await browser.execute(async (clientIdBytes) => {
64+
const encoder = new TextEncoder();
65+
const clientId = new window.ccModule.ClientId(
66+
encoder.encode(clientIdBytes).buffer
67+
);
68+
69+
const cc = window.cc.get(clientIdBytes)!;
70+
71+
const credential = window.ccModule.credentialBasic(
72+
window.ccModule.ciphersuiteDefault(),
73+
clientId
74+
);
75+
76+
const credentialRef = await cc.transaction(async (ctx) => {
77+
return await ctx.addCredential(credential);
78+
});
79+
80+
const keyPackage = await cc.transaction(async (ctx) => {
81+
return await ctx.generateKeypackage(credentialRef);
82+
});
83+
const bytes = new Uint8Array(keyPackage.serialize());
84+
85+
const wasDefined = bytes !== null && bytes !== undefined;
86+
const wasEmpty = bytes.byteLength === 0;
87+
88+
const kp2 = new window.ccModule.Keypackage(bytes.buffer);
89+
const bytes2 = new Uint8Array(kp2.serialize());
90+
91+
// JS in the browser doesn't have a natural way to compare Uint8Arrays,
92+
// which is just... extremely JS
93+
let roundtripMatches = bytes.length === bytes2.length;
94+
let index = 0;
95+
while (roundtripMatches && index < bytes.length) {
96+
roundtripMatches =
97+
roundtripMatches && bytes[index] === bytes2[index];
98+
index += 1;
99+
}
100+
101+
return { wasDefined, wasEmpty, roundtripMatches };
102+
}, clientId);
103+
104+
expect(wasDefined).toBe(true);
105+
expect(wasEmpty).toBe(false);
106+
expect(roundtripMatches).toBe(true);
107+
});
108+
109+
it("can be retrieved in bulk", async () => {
110+
const clientId = crypto.randomUUID();
111+
await ccInit(clientId, false);
112+
113+
const { wasDefined, wasArray, arraySize, firstItemDefined } =
114+
await browser.execute(async (clientIdBytes) => {
115+
const encoder = new TextEncoder();
116+
const clientId = new window.ccModule.ClientId(
117+
encoder.encode(clientIdBytes).buffer
118+
);
119+
120+
const cc = window.cc.get(clientIdBytes)!;
121+
122+
const credential = window.ccModule.credentialBasic(
123+
window.ccModule.ciphersuiteDefault(),
124+
clientId
125+
);
126+
127+
const keyPackages = await cc.transaction(async (ctx) => {
128+
const credentialRef = await ctx.addCredential(credential);
129+
await ctx.generateKeypackage(credentialRef);
130+
return await ctx.getKeypackages();
131+
});
132+
133+
const wasDefined =
134+
keyPackages !== null && keyPackages !== undefined;
135+
const wasArray = Array.isArray(keyPackages);
136+
const arraySize = keyPackages.length;
137+
const firstItemDefined =
138+
keyPackages[1] !== null && keyPackages[0] !== undefined;
139+
140+
return { wasDefined, wasArray, arraySize, firstItemDefined };
141+
}, clientId);
142+
143+
expect(wasDefined).toBe(true);
144+
expect(wasArray).toBe(true);
145+
expect(arraySize).toBe(1);
146+
expect(firstItemDefined).toBe(true);
147+
});
148+
149+
it("can be removed", async () => {
150+
const clientId = crypto.randomUUID();
151+
await ccInit(clientId, false);
152+
153+
const { wasDefined, wasArray, arraySize } = await browser.execute(
154+
async (clientIdBytes) => {
155+
const encoder = new TextEncoder();
156+
const clientId = new window.ccModule.ClientId(
157+
encoder.encode(clientIdBytes).buffer
158+
);
159+
160+
const cc = window.cc.get(clientIdBytes)!;
161+
162+
const credential = window.ccModule.credentialBasic(
163+
window.ccModule.ciphersuiteDefault(),
164+
clientId
165+
);
166+
167+
const keyPackages = await cc.transaction(async (ctx) => {
168+
const credentialRef = await ctx.addCredential(credential);
169+
// add a kp which will not be removed, so we have one left over
170+
await ctx.generateKeypackage(credentialRef);
171+
// add a kp which will be removed
172+
const keyPackage =
173+
await ctx.generateKeypackage(credentialRef);
174+
// now remove that keypackage
175+
await ctx.removeKeypackage(keyPackage.ref());
176+
177+
return await ctx.getKeypackages();
178+
});
179+
180+
const wasDefined =
181+
keyPackages !== null && keyPackages !== undefined;
182+
const wasArray = Array.isArray(keyPackages);
183+
const arraySize = keyPackages.length;
184+
185+
return { wasDefined, wasArray, arraySize };
186+
},
187+
clientId
188+
);
189+
190+
expect(wasDefined).toBe(true);
191+
expect(wasArray).toBe(true);
192+
expect(arraySize).toBe(1);
193+
});
194+
195+
it("can be removed by credentialref", async () => {
196+
const clientId = crypto.randomUUID();
197+
await ccInit(clientId, false);
198+
199+
const KEYPACKAGES_PER_CREDENTIAL = 2;
200+
201+
const { beforeRemovalArraySize, afterRemovalArraySize } =
202+
await browser.execute(
203+
async (clientIdBytes, KEYPACKAGES_PER_CREDENTIAL) => {
204+
const encoder = new TextEncoder();
205+
const clientId = new window.ccModule.ClientId(
206+
encoder.encode(clientIdBytes).buffer
207+
);
208+
209+
const credential1 = window.ccModule.credentialBasic(
210+
window.ccModule.Ciphersuite
211+
.Mls128Dhkemx25519Aes128gcmSha256Ed25519,
212+
clientId
213+
);
214+
const credential2 = window.ccModule.credentialBasic(
215+
window.ccModule.Ciphersuite
216+
.Mls128Dhkemp256Aes128gcmSha256P256,
217+
clientId
218+
);
219+
220+
const cc = window.cc.get(clientIdBytes)!;
221+
222+
return await cc.transaction(async (ctx) => {
223+
const cref1 = await ctx.addCredential(credential1);
224+
const cref2 = await ctx.addCredential(credential2);
225+
226+
// we're going to generate keypackages for both credentials,
227+
// then remove those packages for credential 2, leaving behind
228+
// those for credential 1
229+
for (const cref of [cref1, cref2]) {
230+
for (
231+
let i = 0;
232+
i < KEYPACKAGES_PER_CREDENTIAL;
233+
i++
234+
) {
235+
await ctx.generateKeypackage(cref);
236+
}
237+
}
238+
239+
const kpsBeforeRemoval = await ctx.getKeypackages();
240+
const beforeRemovalArraySize = kpsBeforeRemoval.length;
241+
242+
// now remove all keypackages for one of the credentials
243+
await ctx.removeKeypackagesFor(cref1);
244+
245+
const kps = await ctx.getKeypackages();
246+
const afterRemovalArraySize = kps.length;
247+
return {
248+
beforeRemovalArraySize,
249+
afterRemovalArraySize,
250+
};
251+
});
252+
},
253+
clientId,
254+
KEYPACKAGES_PER_CREDENTIAL
255+
);
256+
257+
// 2 credentials with the same n keypackages each
258+
expect(beforeRemovalArraySize).toBe(KEYPACKAGES_PER_CREDENTIAL * 2);
259+
expect(afterRemovalArraySize).toBe(KEYPACKAGES_PER_CREDENTIAL);
260+
});
261+
});

0 commit comments

Comments
 (0)