| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- import { describe, expect } from "bun:test"
- import { asc } from "drizzle-orm"
- import { Effect } from "effect"
- import { Database } from "@opencode-ai/core/database/database"
- import { LayerNode } from "@opencode-ai/core/effect/layer-node"
- import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
- import { EventV2 } from "@opencode-ai/core/event"
- import { Project } from "@opencode-ai/core/project"
- import { ProjectTable } from "@opencode-ai/core/project/sql"
- import { AbsolutePath } from "@opencode-ai/core/schema"
- import { SessionV2 } from "@opencode-ai/core/session"
- import { SessionTable, TodoTable } from "@opencode-ai/core/session/sql"
- import { SessionTodo } from "@opencode-ai/core/session/todo"
- import { testEffect } from "./lib/effect"
- const it = testEffect(AppNodeBuilder.build(LayerNode.group([Database.node, EventV2.node, SessionTodo.node])))
- const sessionID = SessionV2.ID.make("ses_todo_test")
- const setup = Effect.gen(function* () {
- const { db } = yield* Database.Service
- yield* db
- .insert(ProjectTable)
- .values({ id: Project.ID.global, worktree: AbsolutePath.make("/project"), sandboxes: [] })
- .run()
- .pipe(Effect.orDie)
- yield* db
- .insert(SessionTable)
- .values({
- id: sessionID,
- project_id: Project.ID.global,
- slug: "todo",
- directory: "/project",
- title: "todo",
- version: "test",
- })
- .run()
- .pipe(Effect.orDie)
- })
- describe("SessionTodo", () => {
- it.effect("replaces persisted todos in order and publishes updates", () =>
- Effect.gen(function* () {
- yield* setup
- const { db } = yield* Database.Service
- const events = yield* EventV2.Service
- const todos = yield* SessionTodo.Service
- const published = new Array<EventV2.Payload>()
- const unsubscribe = yield* events.listen((event) =>
- Effect.sync(() => {
- if (event.type === SessionTodo.Event.Updated.type) published.push(event)
- }),
- )
- yield* Effect.addFinalizer(() => unsubscribe)
- yield* todos.update({
- sessionID,
- todos: [
- { content: "second", status: "pending", priority: "low" },
- { content: "first", status: "in_progress", priority: "high" },
- ],
- })
- expect(yield* todos.get(sessionID)).toEqual([
- { content: "second", status: "pending", priority: "low" },
- { content: "first", status: "in_progress", priority: "high" },
- ])
- expect(
- (yield* db.select().from(TodoTable).orderBy(asc(TodoTable.position)).all().pipe(Effect.orDie)).map((row) => ({
- content: row.content,
- position: row.position,
- })),
- ).toEqual([
- { content: "second", position: 0 },
- { content: "first", position: 1 },
- ])
- yield* todos.update({ sessionID, todos: [{ content: "replacement", status: "completed", priority: "medium" }] })
- expect(yield* todos.get(sessionID)).toEqual([{ content: "replacement", status: "completed", priority: "medium" }])
- yield* todos.update({ sessionID, todos: [] })
- expect(yield* todos.get(sessionID)).toEqual([])
- expect(published.map((event) => event.data)).toEqual([
- {
- sessionID,
- todos: [
- { content: "second", status: "pending", priority: "low" },
- { content: "first", status: "in_progress", priority: "high" },
- ],
- },
- { sessionID, todos: [{ content: "replacement", status: "completed", priority: "medium" }] },
- { sessionID, todos: [] },
- ])
- }),
- )
- })
|