diff --git a/apps/web/src/components/settings/ConnectionsSettings.logic.test.ts b/apps/web/src/components/settings/ConnectionsSettings.logic.test.ts index a97eb6abac676..07bc8cc9e8610 100644 --- a/apps/web/src/components/settings/ConnectionsSettings.logic.test.ts +++ b/apps/web/src/components/settings/ConnectionsSettings.logic.test.ts @@ -1,7 +1,9 @@ import type { DesktopWslState } from "@t3tools/contracts"; +import { createAdvertisedEndpoint } from "@t3tools/shared/advertisedEndpoint"; import { describe, expect, it, vi } from "vite-plus/test"; import { applyWslEnableSelection, + missingTailscaleEndpointDescription, selectQrEndpointOption, togglePairingScopeSelection, } from "./ConnectionsSettings.logic"; @@ -123,3 +125,35 @@ describe("selectQrEndpointOption", () => { ); }); }); + +describe("missingTailscaleEndpointDescription", () => { + const networkAccessible = { mode: "network-accessible", tailscaleServeEnabled: false } as const; + const tailscaleIp = createAdvertisedEndpoint({ + id: "tailscale-ip:http://100.84.12.7:4780", + label: "Tailscale IP", + provider: { id: "tailscale", label: "Tailscale", kind: "private-network", isAddon: true }, + httpBaseUrl: "http://100.84.12.7:4780", + reachability: "private-network", + source: "desktop-addon", + }); + + it("does not ask to start Tailscale when its adapter is up but MagicDNS could not be read", () => { + expect(missingTailscaleEndpointDescription(networkAccessible, [tailscaleIp])).toBe( + "Tailscale is running, but its MagicDNS name could not be read. Make sure the tailscale command is installed and MagicDNS is on.", + ); + }); + + it("keeps detection-off guidance when Network access is off, even with a cached IP", () => { + expect( + missingTailscaleEndpointDescription({ mode: "local-only", tailscaleServeEnabled: false }, [ + tailscaleIp, + ]), + ).toBe("Turn on Network access to detect Tailscale."); + }); + + it("asks to start Tailscale when no Tailscale address is present", () => { + expect(missingTailscaleEndpointDescription(networkAccessible, [])).toBe( + "Start Tailscale to set up HTTPS access through MagicDNS.", + ); + }); +}); diff --git a/apps/web/src/components/settings/ConnectionsSettings.logic.ts b/apps/web/src/components/settings/ConnectionsSettings.logic.ts index f3f803af42ce2..1733d93c0a57b 100644 --- a/apps/web/src/components/settings/ConnectionsSettings.logic.ts +++ b/apps/web/src/components/settings/ConnectionsSettings.logic.ts @@ -61,9 +61,13 @@ export function isQrShareableEndpoint(endpoint: AdvertisedEndpoint): boolean { * means unchecked. */ export function missingTailscaleEndpointDescription( state: Pick | null, + endpoints: ReadonlyArray, ): string { - return state && state.mode !== "network-accessible" && !state.tailscaleServeEnabled - ? "Turn on Network access to detect Tailscale." + if (state && state.mode !== "network-accessible" && !state.tailscaleServeEnabled) { + return "Turn on Network access to detect Tailscale."; + } + return endpoints.some((endpoint) => endpoint.id.startsWith("tailscale-ip:")) + ? "Tailscale is running, but its MagicDNS name could not be read. Make sure the tailscale command is installed and MagicDNS is on." : "Start Tailscale to set up HTTPS access through MagicDNS."; } diff --git a/apps/web/src/components/settings/ConnectionsSettings.tsx b/apps/web/src/components/settings/ConnectionsSettings.tsx index 3aa4a150a4d83..4f8ce56fb9eb2 100644 --- a/apps/web/src/components/settings/ConnectionsSettings.tsx +++ b/apps/web/src/components/settings/ConnectionsSettings.tsx @@ -911,7 +911,10 @@ export function ConnectionsSettings() { ? tailscaleHttpsEndpoint.status === "available" ? tailscaleHttpsEndpoint.httpBaseUrl : "Use Tailscale Serve to expose this backend through a MagicDNS HTTPS URL." - : missingTailscaleEndpointDescription(desktopServerExposureState) + : missingTailscaleEndpointDescription( + desktopServerExposureState, + desktopAdvertisedEndpoints, + ) } control={ tailscaleHttpsEndpoint ? (