1import {
2 BearerConnectionTarget,
3 PrimaryConnectionTarget,
4 RelayConnectionTarget,
5 SshConnectionTarget,
6} from "@t3tools/client-runtime/connection";
7import { EnvironmentId } from "@t3tools/contracts";
8import { describe, expect, it } from "vite-plus/test";
9
10import {
11 isOnboardingRelayEnvironment,
12 resolveOnboardingSetup,
13 resolveOnboardingTargetEnvironment,
14} from "./targetEnvironment.logic";
15
16const primaryEnvironment = {
17 environmentId: EnvironmentId.make("primary"),
18 connection: { phase: "connected" },
19 entry: {
20 target: new PrimaryConnectionTarget({
21 environmentId: EnvironmentId.make("primary"),
22 label: "This computer",
23 httpBaseUrl: "http://127.0.0.1:3773",
24 wsBaseUrl: "ws://127.0.0.1:3773",
25 }),
26 },
27 label: "This computer",
28} as const;
29
30const olderRelay = {
31 environmentId: EnvironmentId.make("older-remote"),
32 connection: { phase: "connected" },
33 entry: {
34 target: new RelayConnectionTarget({
35 environmentId: EnvironmentId.make("older-remote"),
36 label: "Older computer",
37 }),
38 },
39 label: "Older computer",
40} as const;
41
42const newerRelay = {
43 environmentId: EnvironmentId.make("newer-relay"),
44 connection: { phase: "connected" },
45 entry: {
46 target: new RelayConnectionTarget({
47 environmentId: EnvironmentId.make("newer-relay"),
48 label: "New computer",
49 }),
50 },
51 label: "New computer",
52} as const;
53
54const pairedRemote = {
55 environmentId: EnvironmentId.make("paired-remote"),
56 connection: { phase: "connected" },
57 entry: {
58 target: new BearerConnectionTarget({
59 environmentId: EnvironmentId.make("paired-remote"),
60 label: "Direct computer",
61 connectionId: "paired-remote",
62 }),
63 },
64 label: "Direct computer",
65} as const;
66
67const sshEnvironment = {
68 environmentId: EnvironmentId.make("ssh-remote"),
69 connection: { phase: "connected" },
70 entry: {
71 target: new SshConnectionTarget({
72 environmentId: EnvironmentId.make("ssh-remote"),
73 label: "SSH computer",
74 connectionId: "ssh-remote",
75 }),
76 },
77 label: "SSH computer",
78} as const;
79
80const desktopLocalEnvironment = {
81 environmentId: EnvironmentId.make("desktop-local-wsl"),
82 connection: { phase: "connected" },
83 entry: {
84 target: new BearerConnectionTarget({
85 environmentId: EnvironmentId.make("desktop-local-wsl"),
86 label: "WSL",
87 connectionId: "local:wsl:Ubuntu",
88 }),
89 },
90 label: "WSL",
91} as const;
92
93describe("resolveOnboardingTargetEnvironment", () => {
94 it("waits for the exact paired machine instead of using an older connected machine", () => {
95 const pendingPairedRemote = { ...pairedRemote, connection: { phase: "connecting" } };
96
97 expect(
98 resolveOnboardingTargetEnvironment({
99 mode: "direct",
100 environments: [primaryEnvironment, olderRelay, pendingPairedRemote],
101 primaryEnvironment,
102 pairedEnvironmentId: pairedRemote.environmentId,
103 }),
104 ).toBeNull();
105 });
106
107 it("uses the exact paired machine once it connects", () => {
108 expect(
109 resolveOnboardingTargetEnvironment({
110 mode: "direct",
111 environments: [primaryEnvironment, olderRelay, pairedRemote],
112 primaryEnvironment,
113 pairedEnvironmentId: pairedRemote.environmentId,
114 }),
115 ).toBe(pairedRemote);
116 });
117
118 it("waits for a newly paired machine that has not appeared in the catalog", () => {
119 expect(
120 resolveOnboardingTargetEnvironment({
121 mode: "direct",
122 environments: [primaryEnvironment, olderRelay],
123 primaryEnvironment,
124 pairedEnvironmentId: pairedRemote.environmentId,
125 }),
126 ).toBeNull();
127 });
128
129 it("uses the primary machine for local onboarding", () => {
130 expect(
131 resolveOnboardingTargetEnvironment({
132 mode: "local",
133 environments: [primaryEnvironment, olderRelay],
134 primaryEnvironment,
135 pairedEnvironmentId: null,
136 }),
137 ).toBe(primaryEnvironment);
138 });
139
140 it("does not substitute a remote machine when the local primary is offline", () => {
141 const offlinePrimary = { ...primaryEnvironment, connection: { phase: "disconnected" } };
142
143 expect(
144 resolveOnboardingTargetEnvironment({
145 mode: "local",
146 environments: [offlinePrimary, olderRelay],
147 primaryEnvironment: offlinePrimary,
148 pairedEnvironmentId: null,
149 }),
150 ).toBeNull();
151 });
152
153 it("uses the newest connected remote when no exact machine was selected", () => {
154 expect(
155 resolveOnboardingTargetEnvironment({
156 mode: "connect",
157 environments: [primaryEnvironment, olderRelay, newerRelay],
158 primaryEnvironment,
159 pairedEnvironmentId: null,
160 }),
161 ).toBe(newerRelay);
162 });
163
164 it("ignores direct, SSH, and desktop-managed connections in Connect mode", () => {
165 expect(
166 resolveOnboardingTargetEnvironment({
167 mode: "connect",
168 environments: [
169 primaryEnvironment,
170 olderRelay,
171 pairedRemote,
172 sshEnvironment,
173 desktopLocalEnvironment,
174 ],
175 primaryEnvironment,
176 pairedEnvironmentId: null,
177 }),
178 ).toBe(olderRelay);
179 });
180
181 it("uses the primary computer when no relay connection exists", () => {
182 expect(
183 resolveOnboardingTargetEnvironment({
184 mode: "connect",
185 environments: [primaryEnvironment, pairedRemote, sshEnvironment, desktopLocalEnvironment],
186 primaryEnvironment,
187 pairedEnvironmentId: null,
188 }),
189 ).toBe(primaryEnvironment);
190 });
191
192 it("falls back to the connected primary when no remote is available", () => {
193 expect(
194 resolveOnboardingTargetEnvironment({
195 mode: "connect",
196 environments: [primaryEnvironment],
197 primaryEnvironment,
198 pairedEnvironmentId: null,
199 }),
200 ).toBe(primaryEnvironment);
201 });
202});
203
204describe("isOnboardingRelayEnvironment", () => {
205 it("includes only T3 Connect relay targets", () => {
206 expect(
207 [olderRelay, pairedRemote, sshEnvironment, desktopLocalEnvironment].filter(
208 isOnboardingRelayEnvironment,
209 ),
210 ).toEqual([olderRelay]);
211 });
212});
213
214describe("resolveOnboardingSetup", () => {
215 const computer = (id: string, phase: string) => ({
216 environmentId: EnvironmentId.make(id),
217 connection: { phase },
218 });
219 const local = computer("local", "connected");
220
221 it("skips selected computers that will not connect on their own", () => {
222 const environments = [
223 local,
224 computer("switched-off", "available"),
225 computer("offline", "offline"),
226 computer("failing", "reconnecting"),
227 computer("old-client", "unsupported"),
228 ];
229 expect(
230 resolveOnboardingSetup(
231 environments,
232 new Set(environments.map((environment) => environment.environmentId)),
233 ),
234 ).toEqual({
235 ready: true,
236 environmentIds: [local.environmentId],
237 skippedIds: environments.slice(1).map((environment) => environment.environmentId),
238 });
239 });
240
241 it("waits for a first connection attempt to settle", () => {
242 const connecting = computer("new", "connecting");
243 expect(
244 resolveOnboardingSetup(
245 [local, connecting],
246 new Set([local.environmentId, connecting.environmentId]),
247 ).ready,
248 ).toBe(false);
249 });
250
251 it("is not ready without a connected selection", () => {
252 expect(resolveOnboardingSetup([local], new Set()).ready).toBe(false);
253 expect(
254 resolveOnboardingSetup([computer("off", "available")], new Set([EnvironmentId.make("off")]))
255 .ready,
256 ).toBe(false);
257 });
258});