1import { describe, expect, it } from "vite-plus/test";
2import * as OpenApi from "effect/http-api/OpenApi";
3import * as Schema from "effect/Schema";
4
5import { RelayApi, RelayDeviceRegistrationRequest } from "./relay.ts";
6
7const decodeDevice = Schema.decodeUnknownExit(RelayDeviceRegistrationRequest);
8const device = {
9 deviceId: "device",
10 label: "Phone",
11 pushToken: "token",
12 preferences: {
13 notificationsEnabled: true,
14 liveActivitiesEnabled: true,
15 notifyOnApproval: true,
16 notifyOnInput: true,
17 notifyOnCompletion: true,
18 notifyOnFailure: true,
19 },
20};
21
22describe("mobile device platforms", () => {
23 it.each([
24 [23, "Failure"],
25 [24, "Success"],
26 [37, "Success"],
27 ])("enforces the Android minimum without an upper bound (API %i)", (androidApiLevel, result) => {
28 expect(decodeDevice({ ...device, platform: "android", androidApiLevel })._tag).toBe(result);
29 });
30
31 it("accepts Android tokens without Apple routing and preserves older iOS registrations", () => {
32 expect(decodeDevice({ ...device, platform: "android", androidApiLevel: 36 })._tag).toBe(
33 "Success",
34 );
35 expect(decodeDevice({ ...device, platform: "ios", iosMajorVersion: 18 })._tag).toBe("Success");
36 });
37 it("rejects missing platform versions and Apple activity tokens on Android", () => {
38 expect(decodeDevice({ ...device, platform: "ios" })._tag).toBe("Failure");
39 expect(decodeDevice({ ...device, platform: "android" })._tag).toBe("Failure");
40 expect(
41 decodeDevice({
42 ...device,
43 platform: "android",
44 androidApiLevel: 36,
45 pushToStartToken: "apple-token",
46 })._tag,
47 ).toBe("Failure");
48 });
49});
50
51describe("RelayApi security", () => {
52 it("describes DPoP access tokens using the HTTP DPoP authorization scheme", () => {
53 const document = OpenApi.fromApi(RelayApi);
54
55 expect(document.components.securitySchemes?.relayDpop).toEqual({
56 type: "http",
57 scheme: "DPoP",
58 description: "DPoP-bound access token. Requests must also include the DPoP proof JWT header.",
59 });
60 });
61});