| 1 | import { EnvironmentId, ORCHESTRATION_PROTOCOL_VERSION } from "@t3tools/contracts"; |
| 2 | import type { RelayEnvironmentStatusResponse } from "@t3tools/contracts/relay"; |
| 3 | import { describe, expect, it } from "vite-plus/test"; |
| 4 | |
| 5 | import { RELAY_TUNNEL_RELEASED_MESSAGE } from "@t3tools/client-runtime/relay"; |
| 6 | |
| 7 | import { availableCloudEnvironmentPresentation } from "./cloudEnvironmentPresentation"; |
| 8 | |
| 9 | function relayStatus( |
| 10 | status: RelayEnvironmentStatusResponse["status"], |
| 11 | error?: string, |
| 12 | traceId?: string, |
| 13 | ): RelayEnvironmentStatusResponse { |
| 14 | return { |
| 15 | environmentId: EnvironmentId.make("environment-cloud"), |
| 16 | endpoint: { |
| 17 | httpBaseUrl: "https://cloud.example.test/", |
| 18 | wsBaseUrl: "wss://cloud.example.test/ws", |
| 19 | providerKind: "cloudflare_tunnel", |
| 20 | }, |
| 21 | status, |
| 22 | checkedAt: "2026-06-05T16:49:11.000Z", |
| 23 | ...(error ? { error } : {}), |
| 24 | ...(traceId ? { traceId } : {}), |
| 25 | }; |
| 26 | } |
| 27 | |
| 28 | describe("available cloud environment presentation", () => { |
| 29 | it("shows an incompatible discovered server before any connection attempt", () => { |
| 30 | const onlineStatus = relayStatus("online"); |
| 31 | const status = { |
| 32 | ...onlineStatus, |
| 33 | descriptor: { |
| 34 | environmentId: onlineStatus.environmentId, |
| 35 | label: "Preview server", |
| 36 | platform: { os: "darwin", arch: "arm64" }, |
| 37 | serverVersion: "2.0.0", |
| 38 | orchestrationProtocolVersion: ORCHESTRATION_PROTOCOL_VERSION + 1, |
| 39 | capabilities: { repositoryIdentity: true }, |
| 40 | }, |
| 41 | } satisfies RelayEnvironmentStatusResponse; |
| 42 | expect( |
| 43 | availableCloudEnvironmentPresentation({ |
| 44 | isStatusPending: false, |
| 45 | status, |
| 46 | statusError: null, |
| 47 | statusErrorTraceId: null, |
| 48 | }), |
| 49 | ).toMatchObject({ |
| 50 | connectionState: "unsupported", |
| 51 | statusText: expect.stringContaining("Update your app"), |
| 52 | }); |
| 53 | }); |
| 54 | |
| 55 | it("presents an online unsaved environment as available, not connected", () => { |
| 56 | expect( |
| 57 | availableCloudEnvironmentPresentation({ |
| 58 | isStatusPending: false, |
| 59 | status: relayStatus("online"), |
| 60 | statusError: null, |
| 61 | statusErrorTraceId: null, |
| 62 | }), |
| 63 | ).toEqual({ |
| 64 | connectionError: null, |
| 65 | connectionErrorTraceId: null, |
| 66 | connectionState: "available", |
| 67 | statusText: "Available · Relay online", |
| 68 | }); |
| 69 | }); |
| 70 | |
| 71 | it("keeps relay status checks distinct from connection attempts", () => { |
| 72 | expect( |
| 73 | availableCloudEnvironmentPresentation({ |
| 74 | isStatusPending: true, |
| 75 | status: null, |
| 76 | statusError: null, |
| 77 | statusErrorTraceId: null, |
| 78 | }), |
| 79 | ).toEqual({ |
| 80 | connectionError: null, |
| 81 | connectionErrorTraceId: null, |
| 82 | connectionState: "available", |
| 83 | statusText: "Available · Checking relay status...", |
| 84 | }); |
| 85 | }); |
| 86 | |
| 87 | it("surfaces an offline relay as an error", () => { |
| 88 | expect( |
| 89 | availableCloudEnvironmentPresentation({ |
| 90 | isStatusPending: false, |
| 91 | status: relayStatus("offline", "Tunnel is unavailable.", "trace-offline"), |
| 92 | statusError: null, |
| 93 | statusErrorTraceId: null, |
| 94 | }), |
| 95 | ).toEqual({ |
| 96 | connectionError: "Tunnel is unavailable.", |
| 97 | connectionErrorTraceId: "trace-offline", |
| 98 | connectionState: "error", |
| 99 | statusText: "Tunnel is unavailable.", |
| 100 | }); |
| 101 | }); |
| 102 | |
| 103 | it("preserves trace metadata for relay request failures", () => { |
| 104 | expect( |
| 105 | availableCloudEnvironmentPresentation({ |
| 106 | isStatusPending: false, |
| 107 | status: null, |
| 108 | statusError: "Could not get relay environment status.", |
| 109 | statusErrorTraceId: "trace-status", |
| 110 | }), |
| 111 | ).toMatchObject({ |
| 112 | connectionError: "Could not get relay environment status.", |
| 113 | connectionErrorTraceId: "trace-status", |
| 114 | }); |
| 115 | }); |
| 116 | |
| 117 | it("tells the user to update a host whose idle tunnel was removed", () => { |
| 118 | const status = { |
| 119 | ...relayStatus("offline", "Managed endpoint health request failed.", "trace-released"), |
| 120 | offlineReason: "tunnel_released", |
| 121 | } satisfies RelayEnvironmentStatusResponse; |
| 122 | expect( |
| 123 | availableCloudEnvironmentPresentation({ |
| 124 | isStatusPending: false, |
| 125 | status, |
| 126 | statusError: null, |
| 127 | statusErrorTraceId: null, |
| 128 | }), |
| 129 | ).toMatchObject({ |
| 130 | connectionState: "error", |
| 131 | statusText: RELAY_TUNNEL_RELEASED_MESSAGE, |
| 132 | connectionErrorTraceId: "trace-released", |
| 133 | }); |
| 134 | }); |
| 135 | }); |