1import { afterEach, describe, expect, it, vi } from "vite-plus/test";
2import { EnvironmentId } from "@t3tools/contracts";
3
4import { isRelayManagedConnection, toStableSavedRemoteConnection } from "./connection";
5import { authClientMetadata } from "./authClientMetadata";
6
7const mobilePlatform = vi.hoisted(() => ({ OS: "ios" as "ios" | "android" }));
8const mobileDevice = vi.hoisted(() => ({
9 deviceType: 1,
10 DeviceType: {
11 UNKNOWN: 0,
12 PHONE: 1,
13 TABLET: 2,
14 DESKTOP: 3,
15 TV: 4,
16 },
17}));
18
19vi.mock("./runtime", () => ({
20 runtime: {
21 runPromise: vi.fn(),
22 },
23}));
24
25vi.mock("react-native", () => ({
26 Platform: mobilePlatform,
27}));
28
29vi.mock("expo-device", () => mobileDevice);
30
31describe("mobile remote connection records", () => {
32 afterEach(() => {
33 mobilePlatform.OS = "ios";
34 mobileDevice.deviceType = mobileDevice.DeviceType.PHONE;
35 });
36
37 it("identifies mobile token exchanges for authorized-client presentation", () => {
38 expect(authClientMetadata()).toEqual({
39 label: "The Knife Mobile",
40 deviceType: "mobile",
41 os: "iOS",
42 surface: "mobile",
43 });
44 });
45
46 it("identifies Android clients for authorized-client presentation", () => {
47 mobilePlatform.OS = "android";
48
49 expect(authClientMetadata()).toMatchObject({
50 os: "Android",
51 });
52 });
53
54 it("identifies native tablets separately from phones", () => {
55 mobileDevice.deviceType = mobileDevice.DeviceType.TABLET;
56
57 expect(authClientMetadata()).toMatchObject({
58 deviceType: "tablet",
59 os: "iOS",
60 });
61 });
62
63 it("includes the mobile app version when the client provides it", () => {
64 expect(authClientMetadata("1.2.3")).toMatchObject({
65 surface: "mobile",
66 appVersion: "1.2.3",
67 });
68 });
69
70 it("recognizes explicitly managed relay connections", () => {
71 expect(isRelayManagedConnection({ relayManaged: true })).toBe(true);
72 });
73
74 it("keeps existing DPoP tunnel records read-only after upgrading", () => {
75 expect(isRelayManagedConnection({ authenticationMethod: "dpop" })).toBe(true);
76 expect(isRelayManagedConnection({ authenticationMethod: "bearer" })).toBe(false);
77 });
78
79 it("drops short-lived managed environment credentials from stable records", () => {
80 const connection = {
81 environmentId: EnvironmentId.make("environment-1"),
82 environmentLabel: "Desktop",
83 pairingUrl: "https://desktop.example/",
84 displayUrl: "https://desktop.example/",
85 httpBaseUrl: "https://desktop.example/",
86 wsBaseUrl: "wss://desktop.example/",
87 bearerToken: null,
88 authenticationMethod: "dpop",
89 dpopAccessToken: "short-lived-token",
90 relayManaged: true,
91 } as const;
92
93 expect(toStableSavedRemoteConnection(connection)).not.toHaveProperty("dpopAccessToken");
94 });
95});