Skip to content
Source
Sign inSign up

device.test.ts

110 lines3.7 KB

1import { describe, expect, it } from "@effect/vitest";
2import { Schema } from "effect";
3import {
4 DeviceBootError,
5 DeviceServiceState,
6 EasDeviceHostConfig,
7 SimlockDeviceHostConfig,
8 EasDeviceHostConfigs,
9 SshDeviceHostConfigs,
10} from "./device.ts";
11import { secretSettingsFields } from "./settings.ts";
12​
13const decodeSshHosts = Schema.decodeUnknownSync(SshDeviceHostConfigs);
14const decodeEas = Schema.decodeUnknownSync(EasDeviceHostConfigs);
15const encodeState = Schema.encodeSync(DeviceServiceState);
16const decodeState = Schema.decodeUnknownSync(DeviceServiceState);
17// The host summary as clients decoded it before EAS hosts existed.
18const decodeOlderState = Schema.decodeUnknownSync(
19 Schema.Struct({
20 hosts: Schema.Array(
21 Schema.Struct({ id: Schema.String, kind: Schema.Literals(["local", "ssh"]) }),
22 ),
23 }),
24);
25​
26describe("configured device hosts", () => {
27 it("reads SSH hosts saved before hosts had a kind, and bounds EAS sessions", () => {
28 expect(decodeSshHosts([{ id: "mac", label: "Mac mini", target: "julius@mac" }])).toEqual([
29 { kind: "ssh", id: "mac", label: "Mac mini", target: "julius@mac" },
30 ]);
31 expect(decodeEas([{ kind: "eas", id: "eas", label: "EAS Simulator" }])).toEqual([
32 {
33 kind: "eas",
34 id: "eas",
35 label: "EAS Simulator",
36 accessToken: "",
37 maxSessionMinutes: 30,
38 idleMinutes: 10,
39 maxConcurrentSessions: 2,
40 },
41 ]);
42 expect(() =>
43 decodeEas([{ kind: "eas", id: "eas", label: "EAS", maxSessionMinutes: 600 }]),
44 ).toThrow();
45 // The default idle limit of 10 is not smaller than a session limit of 10.
46 expect(() =>
47 decodeEas([{ kind: "eas", id: "eas", label: "EAS", maxSessionMinutes: 10 }]),
48 ).toThrow();
49 });
50​
51 it("marks the EAS access token as a secret setting", () => {
52 expect(secretSettingsFields(EasDeviceHostConfig)).toEqual(["accessToken"]);
53 expect(secretSettingsFields(SimlockDeviceHostConfig)).toEqual(["agentToken"]);
54 });
55});
56​
57describe("device state for clients from before EAS hosts", () => {
58 const summary = {
59 label: "Host",
60 platforms: [],
61 hubInstalled: true,
62 agentDeviceInstalled: true,
63 };
64 const state = {
65 hosts: [
66 { ...summary, id: "local", kind: "local" as const },
67 { ...summary, id: "eas", kind: "eas" as const },
68 { ...summary, id: "pool", kind: "simlock" as const },
69 ],
70 hostStatus: "ready" as const,
71 hostStatuses: {},
72 devices: [],
73 sessions: [],
74 onboardingCompleted: true,
75 agentAccessEnabled: true,
76 hubBasePath: "/api/device-hub",
77 revision: 1,
78 };
79​
80 it("sends EAS and Simlock hosts where an older client does not look, and reads them back", () => {
81 const wire = encodeState(state);
82 expect(decodeOlderState(wire).hosts.map((host) => host.id)).toEqual(["local"]);
83 expect(decodeState(wire).hosts).toEqual(state.hosts);
84 });
85});
86​
87describe("device boot errors", () => {
88 it("gives a next step instead of blaming the environment server when the host sent no details", () => {
89 const message = new DeviceBootError({
90 hostId: "mac",
91 deviceId: "Pixel_10",
92 reason: "launch_failed",
93 cause: null,
94 }).message;
95 expect(message).not.toContain("environment server");
96 expect(message).toContain("Try again or open another device");
97 });
98​
99 it("keeps the host's diagnostics when it sent them", () => {
100 const message = new DeviceBootError({
101 hostId: "mac",
102 deviceId: "Pixel_10",
103 reason: "launch_failed",
104 diagnostics: "emulator: PANIC: Missing emulator engine program for 'x86_64' CPU.",
105 cause: null,
106 }).message;
107 expect(message).toContain("PANIC: Missing emulator engine program");
108 expect(message).not.toContain("Try again");
109 });
110});