test(workspace): use Effect for local session warp cases (#27393)

This commit is contained in:
Kit Langton
2026-05-13 22:22:51 +00:00
committed by GitHub
parent 73e1de4513
commit 5182a3698d
@@ -749,30 +749,39 @@ describe("workspace CRUD", () => {
}) })
}) })
test("remove deletes the workspace, associated sessions, adapter resources, and status", async () => { it.instance(
await withInstance(async (dir) => { "remove deletes the workspace, associated sessions, adapter resources, and status",
const type = unique("remove-local") () => {
const recorded = localAdapter(path.join(dir, "remove-local")) return Effect.gen(function* () {
registerAdapter(Instance.project.id, type, recorded.adapter) const { directory: dir } = yield* TestInstance
const info = await createWorkspace({ type, branch: null, projectID: Instance.project.id, extra: null }) const instance = yield* InstanceRef
const one = await AppRuntime.runPromise(SessionNs.Service.use((svc) => svc.create({}))) if (!instance) return yield* Effect.die(new Error("missing test instance"))
const two = await AppRuntime.runPromise(SessionNs.Service.use((svc) => svc.create({}))) const workspace = yield* Workspace.Service
attachSessionToWorkspace(one.id, info.id) const sessionSvc = yield* SessionNs.Service
attachSessionToWorkspace(two.id, info.id) const type = unique("remove-local")
const recorded = localAdapter(path.join(dir, "remove-local"))
registerAdapter(instance.project.id, type, recorded.adapter)
const info = yield* workspace.create({ type, branch: null, projectID: instance.project.id, extra: null })
const one = yield* sessionSvc.create({})
const two = yield* sessionSvc.create({})
attachSessionToWorkspace(one.id, info.id)
attachSessionToWorkspace(two.id, info.id)
const removed = await removeWorkspace(info.id) const removed = yield* workspace.remove(info.id)
expect(removed).toEqual(info) expect(removed).toEqual(info)
expect(await getWorkspace(info.id)).toBeUndefined() expect(yield* workspace.get(info.id)).toBeUndefined()
expect(recorded.calls.remove).toEqual([info]) expect(recorded.calls.remove).toEqual([info])
expect((await workspaceStatus()).find((item) => item.workspaceID === info.id)?.status).toBeUndefined() expect((yield* workspace.status()).find((item) => item.workspaceID === info.id)?.status).toBeUndefined()
expect( expect(
Database.use((db) => Database.use((db) =>
db.select({ id: SessionTable.id }).from(SessionTable).where(eq(SessionTable.workspace_id, info.id)).all(), db.select({ id: SessionTable.id }).from(SessionTable).where(eq(SessionTable.workspace_id, info.id)).all(),
), ),
).toEqual([]) ).toEqual([])
}) })
}) },
{ git: true },
)
test("remove still deletes the row when the adapter cannot remove resources", async () => { test("remove still deletes the row when the adapter cannot remove resources", async () => {
await withInstance(async () => { await withInstance(async () => {
@@ -797,84 +806,111 @@ describe("workspace CRUD", () => {
}) })
}) })
test("sessionWarp moves a session into a local workspace and claims ownership", async () => { it.instance(
await withInstance(async (dir) => { "sessionWarp moves a session into a local workspace and claims ownership",
const previousType = unique("warp-prev-local") () => {
const targetType = unique("warp-target-local") return Effect.gen(function* () {
const previous = workspaceInfo(Instance.project.id, previousType) const { directory: dir } = yield* TestInstance
const target = workspaceInfo(Instance.project.id, targetType) const instance = yield* InstanceRef
insertWorkspace(previous) if (!instance) return yield* Effect.die(new Error("missing test instance"))
insertWorkspace(target) const workspace = yield* Workspace.Service
registerAdapter(Instance.project.id, previousType, localAdapter(path.join(dir, "warp-prev-local")).adapter) const sessionSvc = yield* SessionNs.Service
registerAdapter(Instance.project.id, targetType, localAdapter(path.join(dir, "warp-target-local")).adapter) const previousType = unique("warp-prev-local")
const session = await AppRuntime.runPromise(SessionNs.Service.use((svc) => svc.create({}))) const targetType = unique("warp-target-local")
attachSessionToWorkspace(session.id, previous.id) const previous = workspaceInfo(instance.project.id, previousType)
const target = workspaceInfo(instance.project.id, targetType)
insertWorkspace(previous)
insertWorkspace(target)
registerAdapter(instance.project.id, previousType, localAdapter(path.join(dir, "warp-prev-local")).adapter)
registerAdapter(instance.project.id, targetType, localAdapter(path.join(dir, "warp-target-local")).adapter)
const session = yield* sessionSvc.create({})
attachSessionToWorkspace(session.id, previous.id)
await warpWorkspaceSession({ workspaceID: target.id, sessionID: session.id }) yield* workspace.sessionWarp({ workspaceID: target.id, sessionID: session.id })
expect( expect(
Database.use((db) => Database.use((db) =>
db db
.select({ workspaceID: SessionTable.workspace_id }) .select({ workspaceID: SessionTable.workspace_id })
.from(SessionTable) .from(SessionTable)
.where(eq(SessionTable.id, session.id)) .where(eq(SessionTable.id, session.id))
.get(), .get(),
)?.workspaceID, )?.workspaceID,
).toBe(target.id) ).toBe(target.id)
expect(sessionSequenceOwner(session.id)).toBe(target.id) expect(sessionSequenceOwner(session.id)).toBe(target.id)
}) })
}) },
{ git: true },
)
test("sessionWarp applies source workspace patch to local target workspace", async () => { it.instance(
await withInstance(async (dir) => { "sessionWarp applies source workspace patch to local target workspace",
const previousType = unique("warp-patch-prev-local") () => {
const targetType = unique("warp-patch-target-local") return Effect.gen(function* () {
const previousDir = path.join(dir, "warp-patch-prev-local") const { directory: dir } = yield* TestInstance
const targetDir = path.join(dir, "warp-patch-target-local") const instance = yield* InstanceRef
await initGitRepo(previousDir) if (!instance) return yield* Effect.die(new Error("missing test instance"))
await initGitRepo(targetDir) const workspace = yield* Workspace.Service
await fs.writeFile(path.join(previousDir, "tracked.txt"), "changed\n") const sessionSvc = yield* SessionNs.Service
await fs.writeFile(path.join(previousDir, "new.txt"), "new\n") const previousType = unique("warp-patch-prev-local")
const targetType = unique("warp-patch-target-local")
const previousDir = path.join(dir, "warp-patch-prev-local")
const targetDir = path.join(dir, "warp-patch-target-local")
yield* Effect.promise(() => initGitRepo(previousDir))
yield* Effect.promise(() => initGitRepo(targetDir))
yield* Effect.promise(() => fs.writeFile(path.join(previousDir, "tracked.txt"), "changed\n"))
yield* Effect.promise(() => fs.writeFile(path.join(previousDir, "new.txt"), "new\n"))
const previous = workspaceInfo(Instance.project.id, previousType) const previous = workspaceInfo(instance.project.id, previousType)
const target = workspaceInfo(Instance.project.id, targetType) const target = workspaceInfo(instance.project.id, targetType)
insertWorkspace(previous) insertWorkspace(previous)
insertWorkspace(target) insertWorkspace(target)
registerAdapter(Instance.project.id, previousType, localAdapter(previousDir, { createDir: false }).adapter) registerAdapter(instance.project.id, previousType, localAdapter(previousDir, { createDir: false }).adapter)
registerAdapter(Instance.project.id, targetType, localAdapter(targetDir, { createDir: false }).adapter) registerAdapter(instance.project.id, targetType, localAdapter(targetDir, { createDir: false }).adapter)
const session = await AppRuntime.runPromise(SessionNs.Service.use((svc) => svc.create({}))) const session = yield* sessionSvc.create({})
attachSessionToWorkspace(session.id, previous.id) attachSessionToWorkspace(session.id, previous.id)
await warpWorkspaceSession({ workspaceID: target.id, sessionID: session.id, copyChanges: true }) yield* workspace.sessionWarp({ workspaceID: target.id, sessionID: session.id, copyChanges: true })
expect(await fs.readFile(path.join(targetDir, "tracked.txt"), "utf8")).toBe("changed\n") expect(yield* Effect.promise(() => fs.readFile(path.join(targetDir, "tracked.txt"), "utf8"))).toBe("changed\n")
expect(await fs.readFile(path.join(targetDir, "new.txt"), "utf8")).toBe("new\n") expect(yield* Effect.promise(() => fs.readFile(path.join(targetDir, "new.txt"), "utf8"))).toBe("new\n")
}) })
}) },
{ git: true },
)
test("sessionWarp detaches a session to the local project and claims project ownership", async () => { it.instance(
await withInstance(async (dir) => { "sessionWarp detaches a session to the local project and claims project ownership",
const previousType = unique("warp-detach-local") () => {
const previous = workspaceInfo(Instance.project.id, previousType) return Effect.gen(function* () {
insertWorkspace(previous) const { directory: dir } = yield* TestInstance
registerAdapter(Instance.project.id, previousType, localAdapter(path.join(dir, "warp-detach-local")).adapter) const instance = yield* InstanceRef
const session = await AppRuntime.runPromise(SessionNs.Service.use((svc) => svc.create({}))) if (!instance) return yield* Effect.die(new Error("missing test instance"))
attachSessionToWorkspace(session.id, previous.id) const workspace = yield* Workspace.Service
const sessionSvc = yield* SessionNs.Service
const previousType = unique("warp-detach-local")
const previous = workspaceInfo(instance.project.id, previousType)
insertWorkspace(previous)
registerAdapter(instance.project.id, previousType, localAdapter(path.join(dir, "warp-detach-local")).adapter)
const session = yield* sessionSvc.create({})
attachSessionToWorkspace(session.id, previous.id)
await warpWorkspaceSession({ workspaceID: null, sessionID: session.id }) yield* workspace.sessionWarp({ workspaceID: null, sessionID: session.id })
expect( expect(
Database.use((db) => Database.use((db) =>
db db
.select({ workspaceID: SessionTable.workspace_id }) .select({ workspaceID: SessionTable.workspace_id })
.from(SessionTable) .from(SessionTable)
.where(eq(SessionTable.id, session.id)) .where(eq(SessionTable.id, session.id))
.get(), .get(),
)?.workspaceID, )?.workspaceID,
).toBeNull() ).toBeNull()
expect(sessionSequenceOwner(session.id)).toBe(Instance.project.id) expect(sessionSequenceOwner(session.id)).toBe(instance.project.id)
}) })
}) },
{ git: true },
)
test("sessionWarp detaches to the source project when invoked from a workspace instance", async () => { test("sessionWarp detaches to the source project when invoked from a workspace instance", async () => {
await withInstance(async () => { await withInstance(async () => {