From b72e391359ea8fc54bf0f67827acc53dfc0714c0 Mon Sep 17 00:00:00 2001 From: "[._.]/ Adam Eivy" Date: Wed, 2 Sep 2026 07:52:55 -0700 Subject: [PATCH] drop the two apps API wrappers the socket-driven update flow orphaned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moving RepositorySourcePanel onto the socket-backed useAppOperation hook (2e996e4d2) left `pullAndUpdateApp` and `getPreferredSelfRestartOrigin` with no production caller, so client/src/services/api.deadExports.test.js fails on any full-mode run — main's CI stays green only because the run planner scopes tests to changed files. Neither symbol is referenced inside apiApps.js (handleSelfRestart does not call either), so both are deleted rather than un-exported, along with the now-unused apiSystem.js import and its test mock. The server's POST /api/apps/:id/update route is untouched; the live update path is the app:update socket event. Fixes #5848 --- .../apps/tabs/RepositorySourcePanel.test.jsx | 5 +--- client/src/services/apiApps.js | 17 ------------ client/src/services/apiApps.test.js | 27 +------------------ 3 files changed, 2 insertions(+), 47 deletions(-) diff --git a/client/src/components/apps/tabs/RepositorySourcePanel.test.jsx b/client/src/components/apps/tabs/RepositorySourcePanel.test.jsx index f8c3bef21d..97ebc8b670 100644 --- a/client/src/components/apps/tabs/RepositorySourcePanel.test.jsx +++ b/client/src/components/apps/tabs/RepositorySourcePanel.test.jsx @@ -5,8 +5,6 @@ vi.mock('../../../services/api', () => ({ PORTOS_APP_ID: 'portos-default', getAppRepositorySources: vi.fn(), syncAppRepositoryFork: vi.fn(), - pullAndUpdateApp: vi.fn(), - getPreferredSelfRestartOrigin: vi.fn(), handleSelfRestart: vi.fn(), })); vi.mock('../../../hooks/useAppOperation', () => ({ @@ -90,7 +88,6 @@ beforeEach(() => { }); api.getAppRepositorySources.mockResolvedValue(canonicalStatus()); api.syncAppRepositoryFork.mockResolvedValue({ synced: true, alreadyUpToDate: false }); - api.pullAndUpdateApp.mockResolvedValue({ success: true }); }); afterEach(() => cleanup()); @@ -147,7 +144,7 @@ describe('managed app repository sources', () => { fireEvent.click(screen.getByRole('button', { name: 'Sync fork' })); await waitFor(() => expect(api.syncAppRepositoryFork).toHaveBeenCalledWith('app-example', { silent: true })); - expect(api.pullAndUpdateApp).not.toHaveBeenCalled(); + expect(useAppOperation.mock.results[0].value.startUpdate).not.toHaveBeenCalled(); }); it('confirms that one managed update syncs the fork and updates every checkout', async () => { diff --git a/client/src/services/apiApps.js b/client/src/services/apiApps.js index 709f971f61..3d24513172 100644 --- a/client/src/services/apiApps.js +++ b/client/src/services/apiApps.js @@ -1,6 +1,5 @@ import toast from '../components/ui/Toast'; import { request, API_BASE } from './apiCore.js'; -import { getNetworkExposure } from './apiSystem.js'; // Apps export const getApps = (options) => request('/apps', options); @@ -163,22 +162,6 @@ export const openAppFolder = (id) => request(`/apps/${id}/open-folder`, { method // comes back as a real error instead of a silent `xcode://` no-op. export const openAppInXcode = (id) => request(`/apps/${id}/open-xcode`, { method: 'POST' }); export const refreshAppConfig = (id) => request(`/apps/${id}/refresh-config`, { method: 'POST' }); -// Capture the server's currently trusted origin before a PortOS restart. A -// Vite dev UI on :5554 must not be reused after the server comes back when a -// Tailscale HTTPS origin is available. The read is best-effort so an instance -// without trusted HTTPS keeps the existing same-origin recovery behavior. -export const getPreferredSelfRestartOrigin = async () => { - const exposure = await getNetworkExposure({ silent: true }).catch(() => null); - const trustedUrl = exposure?.setup?.trustedUrl; - return typeof trustedUrl === 'string' && trustedUrl.startsWith('https://') - ? trustedUrl - : null; -}; -export const pullAndUpdateApp = (id, body = {}, options = {}) => request(`/apps/${id}/update`, { - method: 'POST', - body: JSON.stringify(body), - ...options, -}); // `options` lets a caller suppress request()'s auto-toast with `{ silent: true }` // when it already renders its own error UI. export const buildApp = (id, options = {}) => request(`/apps/${id}/build`, { method: 'POST', ...options }); diff --git a/client/src/services/apiApps.test.js b/client/src/services/apiApps.test.js index a3f970782b..defd77b68f 100644 --- a/client/src/services/apiApps.test.js +++ b/client/src/services/apiApps.test.js @@ -4,16 +4,12 @@ vi.mock('../components/ui/Toast', () => ({ default: { loading: vi.fn(), success: vi.fn(), error: vi.fn() }, })); -const mockNetwork = vi.hoisted(() => ({ getNetworkExposure: vi.fn() })); -vi.mock('./apiSystem.js', () => mockNetwork); - import toast from '../components/ui/Toast'; -import { getPreferredSelfRestartOrigin, handleSelfRestart } from './apiApps'; +import { handleSelfRestart } from './apiApps'; beforeEach(() => { vi.useFakeTimers(); vi.clearAllMocks(); - mockNetwork.getNetworkExposure.mockResolvedValue({ setup: { trustedUrl: null } }); }); afterEach(() => { @@ -58,24 +54,3 @@ describe('handleSelfRestart', () => { ); }); }); - -describe('getPreferredSelfRestartOrigin', () => { - it('returns the active trusted origin supplied by network exposure', async () => { - mockNetwork.getNetworkExposure.mockResolvedValueOnce({ - setup: { trustedUrl: 'https://host-alpha.example-tailnet.ts.net:5555' }, - }); - - await expect(getPreferredSelfRestartOrigin()).resolves.toBe( - 'https://host-alpha.example-tailnet.ts.net:5555', - ); - expect(mockNetwork.getNetworkExposure).toHaveBeenCalledWith({ silent: true }); - }); - - it('does not turn an unavailable or non-HTTPS setup value into a restart target', async () => { - mockNetwork.getNetworkExposure.mockResolvedValueOnce({ - setup: { pendingTrustedUrl: 'https://host-alpha.example-tailnet.ts.net:5555', trustedUrl: null }, - }); - - await expect(getPreferredSelfRestartOrigin()).resolves.toBeNull(); - }); -});