authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-09-05 00:27:13-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-05 00:27:13-07:00
log1449deca0afb98a422ea54b0d0fbed56da9f9f8f
tree4f4a10de4af2b94b0233c88364bf750b3eb6ab53
parent4e5e17fd9e2454a7b828a19f0b46e48cde0c7a90
signature Signed by PGP key B5690EEEBB952194

refactor(mobile): test final connection status presentation (#10007)


2 files changed, 22 insertions(+), 48 deletions(-)

apps/mobile/src/features/home/workspace-connection-status.test.ts+20-46
...@@ -1,11 +1,7 @@...@@ -1,11 +1,7 @@
1import { describe, expect, it } from "vite-plus/test";1import { describe, expect, it } from "vite-plus/test";
22
3import type { WorkspaceState } from "../../state/workspaceModel";3import type { WorkspaceState } from "../../state/workspaceModel";
4import {4import { workspaceConnectionStatusPresentation } from "./workspace-connection-status";
5 shouldShowWorkspaceConnectionStatus,
6 workspaceConnectionStatusLabel,
7 workspaceConnectionStatusPresentation,
8} from "./workspace-connection-status";
95
10function workspaceState(overrides: Partial<WorkspaceState> = {}): WorkspaceState {6function workspaceState(overrides: Partial<WorkspaceState> = {}): WorkspaceState {
11 return {7 return {
...@@ -27,14 +23,16 @@ function workspaceState(overrides: Partial<WorkspaceState> = {}): WorkspaceState...@@ -27,14 +23,16 @@ function workspaceState(overrides: Partial<WorkspaceState> = {}): WorkspaceState
2723
28describe("workspace connection status", () => {24describe("workspace connection status", () => {
29 it("stays hidden while a ready environment is connected", () => {25 it("stays hidden while a ready environment is connected", () => {
30 expect(shouldShowWorkspaceConnectionStatus(workspaceState())).toBe(false);26 expect(workspaceConnectionStatusPresentation(workspaceState())).toBeNull();
31 });27 });
3228
33 it("surfaces offline snapshots", () => {29 it("surfaces offline snapshots", () => {
34 const state = workspaceState({ networkStatus: "offline", hasReadyEnvironment: false });30 const state = workspaceState({ networkStatus: "offline", hasReadyEnvironment: false });
3531
36 expect(shouldShowWorkspaceConnectionStatus(state)).toBe(true);32 expect(workspaceConnectionStatusPresentation(state)).toEqual({
37 expect(workspaceConnectionStatusLabel(state)).toBe("You are offline");33 label: "You are offline",
34 showsProgress: false,
35 });
38 });36 });
3937
40 it("names the environment while reconnecting", () => {38 it("names the environment while reconnecting", () => {
...@@ -54,8 +52,10 @@ describe("workspace connection status", () => {...@@ -54,8 +52,10 @@ describe("workspace connection status", () => {
54 ],52 ],
55 });53 });
5654
57 expect(shouldShowWorkspaceConnectionStatus(state)).toBe(true);55 expect(workspaceConnectionStatusPresentation(state)).toEqual({
58 expect(workspaceConnectionStatusLabel(state)).toBe("Reconnecting to Julius’s Mac mini");56 label: "Reconnecting to Julius’s Mac mini",
57 showsProgress: true,
58 });
59 });59 });
6060
61 it("surfaces connection errors before the generic disconnected fallback", () => {61 it("surfaces connection errors before the generic disconnected fallback", () => {
...@@ -65,15 +65,19 @@ describe("workspace connection status", () => {...@@ -65,15 +65,19 @@ describe("workspace connection status", () => {
65 hasReadyEnvironment: false,65 hasReadyEnvironment: false,
66 });66 });
6767
68 expect(shouldShowWorkspaceConnectionStatus(state)).toBe(true);68 expect(workspaceConnectionStatusPresentation(state)).toEqual({
69 expect(workspaceConnectionStatusLabel(state)).toBe("Could not reach Julius’s Mac mini");69 label: "Could not reach Julius’s Mac mini",
70 showsProgress: false,
71 });
70 });72 });
7173
72 it("shows shell catch-up while cached threads remain visible", () => {74 it("shows shell catch-up while cached threads remain visible", () => {
73 const state = workspaceState({ hasPendingShellSnapshot: true });75 const state = workspaceState({ hasPendingShellSnapshot: true });
7476
75 expect(shouldShowWorkspaceConnectionStatus(state)).toBe(true);77 expect(workspaceConnectionStatusPresentation(state)).toEqual({
76 expect(workspaceConnectionStatusLabel(state)).toBe("Syncing threads...");78 label: "Syncing threads...",
79 showsProgress: true,
80 });
77 });81 });
7882
79 it("distinguishes initial shell loading from cached catch-up", () => {83 it("distinguishes initial shell loading from cached catch-up", () => {
...@@ -82,39 +86,9 @@ describe("workspace connection status", () => {...@@ -82,39 +86,9 @@ describe("workspace connection status", () => {
82 hasPendingShellSnapshot: true,86 hasPendingShellSnapshot: true,
83 });87 });
8488
85 expect(shouldShowWorkspaceConnectionStatus(state)).toBe(true);89 expect(workspaceConnectionStatusPresentation(state)).toEqual({
86 expect(workspaceConnectionStatusLabel(state)).toBe("Loading threads...");90 label: "Loading threads...",
87 });
88
89 it("presents nothing while connected", () => {
90 expect(workspaceConnectionStatusPresentation(workspaceState())).toBeNull();
91 });
92
93 it("presents progress while reconnecting but not while offline", () => {
94 const reconnecting = workspaceState({
95 hasConnectingEnvironment: true,
96 hasReadyEnvironment: false,
97 connectingEnvironments: [
98 {
99 environmentId: "environment-1" as never,
100 environmentLabel: "Julius’s Mac mini",
101 displayUrl: "",
102 isRelayManaged: false,
103 connectionState: "reconnecting",
104 connectionError: null,
105 connectionErrorTraceId: null,
106 },
107 ],
108 });
109 expect(workspaceConnectionStatusPresentation(reconnecting)).toEqual({
110 label: "Reconnecting to Julius’s Mac mini",
111 showsProgress: true,91 showsProgress: true,
112 });92 });
113
114 const offline = workspaceState({ networkStatus: "offline", hasReadyEnvironment: false });
115 expect(workspaceConnectionStatusPresentation(offline)).toEqual({
116 label: "You are offline",
117 showsProgress: false,
118 });
119 });93 });
120});94});
apps/mobile/src/features/home/workspace-connection-status.ts+2-2
...@@ -6,7 +6,7 @@ export interface WorkspaceConnectionStatusPresentation {...@@ -6,7 +6,7 @@ export interface WorkspaceConnectionStatusPresentation {
6 readonly showsProgress: boolean;6 readonly showsProgress: boolean;
7}7}
88
9export function shouldShowWorkspaceConnectionStatus(state: WorkspaceState): boolean {9function shouldShowWorkspaceConnectionStatus(state: WorkspaceState): boolean {
10 return (10 return (
11 state.networkStatus === "offline" ||11 state.networkStatus === "offline" ||
12 state.connectionError !== null ||12 state.connectionError !== null ||
...@@ -16,7 +16,7 @@ export function shouldShowWorkspaceConnectionStatus(state: WorkspaceState): bool...@@ -16,7 +16,7 @@ export function shouldShowWorkspaceConnectionStatus(state: WorkspaceState): bool
16 );16 );
17}17}
1818
19export function workspaceConnectionStatusLabel(state: WorkspaceState): string {19function workspaceConnectionStatusLabel(state: WorkspaceState): string {
20 if (state.networkStatus === "offline") return "You are offline";20 if (state.networkStatus === "offline") return "You are offline";
21 if (state.connectingEnvironments.length === 1) {21 if (state.connectingEnvironments.length === 1) {
22 return `Reconnecting to ${state.connectingEnvironments[0]!.environmentLabel}`;22 return `Reconnecting to ${state.connectingEnvironments[0]!.environmentLabel}`;