mirror of
https://github.com/anomalyco/opencode.git
synced 2026-10-31 17:20:50 +00:00
81 lines
3.5 KiB
TypeScript
81 lines
3.5 KiB
TypeScript
import { describe, expect } from "bun:test"
|
|
import { Bus } from "@opencode/core/bus"
|
|
import { Database } from "@opencode/core/database/database"
|
|
import { AppNodeBuilder } from "@opencode/core/effect/app-node-builder"
|
|
import { EventTable } from "@opencode/core/event/sql"
|
|
import { Location } from "@opencode/core/location"
|
|
import { Project } from "@opencode/core/project"
|
|
import { AbsolutePath } from "@opencode/core/schema"
|
|
import { Session } from "@opencode/core/session"
|
|
import { SessionEvent } from "@opencode/core/session/event"
|
|
import { SessionExecution } from "@opencode/core/session/execution"
|
|
import { SessionProjector } from "@opencode/core/session/projector"
|
|
import { SessionStore } from "@opencode/core/session/store"
|
|
import { LayerNode } from "@opencode/util/effect/layer-node"
|
|
import { Effect } from "effect"
|
|
import { eq } from "drizzle-orm"
|
|
import { testEffect } from "./lib/effect"
|
|
import { globalProjectNode } from "./lib/project"
|
|
|
|
const it = testEffect(
|
|
AppNodeBuilder.build(
|
|
LayerNode.group([Database.node, Bus.node, SessionProjector.node, SessionStore.node, Session.node]),
|
|
[
|
|
Bus.node.replace(Bus.configured({ persist: true })),
|
|
Project.node.replace(globalProjectNode),
|
|
SessionExecution.node.replace(SessionExecution.noopLayer),
|
|
],
|
|
),
|
|
)
|
|
const location = Location.Ref.make({ directory: AbsolutePath.make("/project") })
|
|
|
|
describe("Session.archive", () => {
|
|
it.effect("archives and unarchives through one durable event each", () =>
|
|
Effect.gen(function* () {
|
|
const session = yield* Session.Service
|
|
const { db } = yield* Database.Service
|
|
const created = yield* session.create({ location })
|
|
expect(created.time.archived).toBeUndefined()
|
|
|
|
yield* session.archive(created.id)
|
|
yield* session.archive(created.id)
|
|
expect((yield* session.get(created.id)).time.archived).toBeDefined()
|
|
|
|
yield* session.unarchive(created.id)
|
|
yield* session.unarchive(created.id)
|
|
expect((yield* session.get(created.id)).time.archived).toBeUndefined()
|
|
|
|
const types = (yield* db
|
|
.select({ type: EventTable.type })
|
|
.from(EventTable)
|
|
.where(eq(EventTable.aggregate_id, created.id))
|
|
.all()).map((event) => event.type)
|
|
expect(types.filter((type) => type === Bus.versionedType(SessionEvent.Archived.type, 1))).toHaveLength(1)
|
|
expect(types.filter((type) => type === Bus.versionedType(SessionEvent.Unarchived.type, 1))).toHaveLength(1)
|
|
}),
|
|
)
|
|
|
|
it.effect("filters listed sessions by archive state", () =>
|
|
Effect.gen(function* () {
|
|
const session = yield* Session.Service
|
|
const active = yield* session.create({ location })
|
|
const archived = yield* session.create({ location })
|
|
yield* session.archive(archived.id)
|
|
|
|
const ids = (input?: Session.ListInput) =>
|
|
session.list(input).pipe(Effect.map((page) => page.data.map((item) => item.id).toSorted()))
|
|
expect(yield* ids()).toEqual([active.id, archived.id].toSorted())
|
|
expect(yield* ids({ archived: false })).toEqual([active.id])
|
|
expect(yield* ids({ archived: true })).toEqual([archived.id])
|
|
}),
|
|
)
|
|
|
|
it.effect("rejects an unknown session", () =>
|
|
Effect.gen(function* () {
|
|
const session = yield* Session.Service
|
|
const sessionID = Session.ID.make("ses_missing_archive")
|
|
expect(yield* Effect.flip(session.archive(sessionID))).toEqual(new Session.NotFoundError({ sessionID }))
|
|
expect(yield* Effect.flip(session.unarchive(sessionID))).toEqual(new Session.NotFoundError({ sessionID }))
|
|
}),
|
|
)
|
|
})
|