/
Alex_Ural
/
opencode
Обзор
Документация
Войти
/
Alex_Ural
/
opencode
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
packages/app/src/context/server.test.ts
245 строк
8 KB
usrnk1
feat(desktop): add recently closed projects to home (#34926)
03 июл 2026, 10:52
Не верифицирован
03 июл 2026, 10:52
bf58fae
Код
Авторство
О чём код?
import { describe, expect, test } from "bun:test" import { createRoot, createSignal } from "solid-js" import { createStore } from "solid-js/store" import { createServerProjects, migrateCanonicalLocalServerState, nextServerAfterRemoval, resolveServerList, ServerConnection, } from "./server" import { ServerScope } from "@/utils/server-scope" describe("resolveServerList", () => { test("lets startup auth_token credentials override a persisted same-url server", () => { const list = resolveServerList({ stored: [{ url: "https://server.example.test" }], props: [ { type: "http", authToken: true, http: { url: "https://server.example.test", username: "opencode", password: "secret", }, }, ], }) expect(list).toHaveLength(1) expect(list[0]?.type).toBe("http") expect(list[0]?.http).toEqual({ url: "https://server.example.test", username: "opencode", password: "secret", }) expect(list[0]?.type === "http" ? list[0].authToken : false).toBe(true) expect(ServerConnection.key(list[0]!) as string).toBe("https://server.example.test") }) test("keeps persisted credentials when startup has no auth_token", () => { const list = resolveServerList({ stored: [ { url: "https://server.example.test", username: "opencode", password: "saved", }, ], props: [{ type: "http", http: { url: "https://server.example.test" } }], }) expect(list).toHaveLength(1) expect(list[0]?.type).toBe("http") expect(list[0]?.http).toEqual({ url: "https://server.example.test", username: "opencode", password: "saved", }) expect(list[0]?.type === "http" ? list[0].authToken : true).toBeUndefined() }) }) test("treats WSL sidecars as remote server connections", () => { expect( ServerConnection.local({ type: "sidecar", variant: "wsl", distro: "Debian", http: { url: "http://127.0.0.1:4097" }, }), ).toBe(false) expect(ServerConnection.local({ type: "sidecar", variant: "base", http: { url: "http://127.0.0.1:4096" } })).toBe( true, ) expect(ServerConnection.local({ type: "http", http: { url: "http://localhost:4096" } })).toBe(true) expect(ServerConnection.local({ type: "http", http: { url: "https://server.example.test" } })).toBe(false) }) test("active server removal falls back across built-in and persisted servers", () => { const local = { type: "sidecar", variant: "base", http: { url: "http://127.0.0.1:4096" } } as const const debian = { type: "sidecar", variant: "wsl", distro: "Debian", http: { url: "http://127.0.0.1:4097" }, } as const expect( nextServerAfterRemoval( [local, debian], ServerConnection.Key.make("wsl:Debian"), ServerConnection.Key.make("sidecar"), ), ).toBe(ServerConnection.Key.make("sidecar")) }) describe("createServerProjects", () => { test("keeps active and explicit server buckets in one reactive store", () => { createRoot((dispose) => { const [scope] = createSignal(ServerScope.local) const [store, setStore] = createStore({ projects: {}, lastProject: {}, recentlyClosed: {} }) const active = createServerProjects({ scope, store, setStore }) const remote = createServerProjects({ scope: () => "https://debian.example" as ServerScope, store, setStore }) remote.open("/repo") expect(remote.list()).toEqual([{ worktree: "/repo", expanded: true }]) expect(active.list()).toEqual([]) const adopted = createServerProjects({ scope: () => "https://debian.example" as ServerScope, store, setStore }) expect(adopted.list()).toEqual([{ worktree: "/repo", expanded: true }]) adopted.close("/repo") expect(remote.list()).toEqual([]) dispose() }) }) test("tracks recently closed projects and drops them when reopened", () => { createRoot((dispose) => { const [scope] = createSignal(ServerScope.local) const [store, setStore] = createStore({ projects: {}, lastProject: {}, recentlyClosed: {} }) const projects = createServerProjects({ scope, store, setStore }) projects.open("/a") projects.open("/b") projects.close("/a") expect(projects.recentlyClosed()).toEqual(["/a"]) projects.close("/b") expect(projects.recentlyClosed()).toEqual(["/b", "/a"]) projects.open("/a") expect(projects.recentlyClosed()).toEqual(["/b"]) expect(projects.list()).toEqual([{ worktree: "/a", expanded: true }]) dispose() }) }) test("remove drops a project without recording it as recently closed", () => { createRoot((dispose) => { const [scope] = createSignal(ServerScope.local) const [store, setStore] = createStore({ projects: {}, lastProject: {}, recentlyClosed: {} }) const projects = createServerProjects({ scope, store, setStore }) projects.open("/repo/subdir") projects.remove("/repo/subdir") expect(projects.list()).toEqual([]) expect(projects.recentlyClosed()).toEqual([]) dispose() }) }) test("retains recently closed history beyond the visible display limit", () => { createRoot((dispose) => { const [scope] = createSignal(ServerScope.local) const [store, setStore] = createStore({ projects: {}, lastProject: {}, recentlyClosed: {} }) const projects = createServerProjects({ scope, store, setStore }) // Closing 6 projects keeps all 6 in the store even though only 5 are displayed; // this prevents display-filtered entries from evicting still-visible ones. for (const dir of ["/1", "/2", "/3", "/4", "/5", "/6"]) { projects.open(dir) projects.close(dir) } expect(projects.recentlyClosed()).toEqual(["/6", "/5", "/4", "/3", "/2", "/1"]) dispose() }) }) test("caps recently closed history at the store limit", () => { createRoot((dispose) => { const [scope] = createSignal(ServerScope.local) const [store, setStore] = createStore({ projects: {}, lastProject: {}, recentlyClosed: {} }) const projects = createServerProjects({ scope, store, setStore }) for (let i = 1; i <= 20; i++) { projects.open(`/p${i}`) projects.close(`/p${i}`) } expect(projects.recentlyClosed()).toHaveLength(16) expect(projects.recentlyClosed()[0]).toBe("/p20") expect(projects.recentlyClosed().at(-1)).toBe("/p5") dispose() }) }) test("dedupes recently closed entries by normalized path", () => { createRoot((dispose) => { const [scope] = createSignal(ServerScope.local) const [store, setStore] = createStore({ projects: {}, lastProject: {}, recentlyClosed: {} }) const projects = createServerProjects({ scope, store, setStore }) projects.close("/repo") projects.close("/repo/") expect(projects.recentlyClosed()).toEqual(["/repo/"]) dispose() }) }) }) describe("migrateCanonicalLocalServerState", () => { test("moves an existing canonical web bucket into local scope", () => { expect( migrateCanonicalLocalServerState( { list: [], projects: { "https://opencode.example.com": [{ worktree: "/remote", expanded: true }] }, lastProject: { "https://opencode.example.com": "/remote" }, }, ServerConnection.Key.make("https://opencode.example.com"), ), ).toEqual({ list: [], projects: { local: [{ worktree: "/remote", expanded: true }] }, lastProject: { local: "/remote" }, }) }) test("preserves existing local state while merging a canonical web bucket", () => { expect( migrateCanonicalLocalServerState( { projects: { local: [{ worktree: "/local", expanded: false }], "https://opencode.example.com": [ { worktree: "/local", expanded: true }, { worktree: "/remote", expanded: true }, ], }, lastProject: { local: "/local", "https://opencode.example.com": "/remote" }, }, ServerConnection.Key.make("https://opencode.example.com"), ), ).toEqual({ projects: { local: [ { worktree: "/local", expanded: false }, { worktree: "/remote", expanded: true }, ], }, lastProject: { local: "/local" }, }) }) })