session-actions.test.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import { afterEach, describe, expect, mock } from "bun:test"
  2. import { LayerNode } from "@kirincode-ai/core/effect/layer-node"
  3. import { Effect, Layer } from "effect"
  4. import { Session as SessionNs } from "@/session/session"
  5. import { disposeAllInstances, TestInstance } from "../fixture/fixture"
  6. import { testEffect } from "../lib/effect"
  7. import { httpApiLayer, requestInDirectory } from "./httpapi-layer"
  8. const it = testEffect(Layer.mergeAll(LayerNode.compile(SessionNs.node), httpApiLayer))
  9. afterEach(async () => {
  10. mock.restore()
  11. await disposeAllInstances()
  12. })
  13. describe("session action routes", () => {
  14. it.instance(
  15. "session routes expose metadata on create, update, get, and fork",
  16. () =>
  17. Effect.gen(function* () {
  18. const test = yield* TestInstance
  19. const headers = { "Content-Type": "application/json" }
  20. const created = yield* requestInDirectory("/session", test.directory, {
  21. method: "POST",
  22. headers,
  23. body: JSON.stringify({
  24. title: "meta-session",
  25. metadata: { source: "sdk", trace: { id: "abc" } },
  26. }),
  27. })
  28. expect(created.status).toBe(200)
  29. const session = (yield* created.json) as SessionNs.Info
  30. expect(session.metadata).toEqual({ source: "sdk", trace: { id: "abc" } })
  31. const updated = yield* requestInDirectory(`/session/${session.id}`, test.directory, {
  32. method: "PATCH",
  33. headers,
  34. body: JSON.stringify({ metadata: { source: "sdk", trace: { id: "def" }, tags: ["one"] } }),
  35. })
  36. expect(updated.status).toBe(200)
  37. const next = (yield* updated.json) as SessionNs.Info
  38. expect(next.metadata).toEqual({ source: "sdk", trace: { id: "def" }, tags: ["one"] })
  39. const fetched = yield* requestInDirectory(`/session/${session.id}`, test.directory)
  40. expect(fetched.status).toBe(200)
  41. expect(((yield* fetched.json) as SessionNs.Info).metadata).toEqual(next.metadata)
  42. const forked = yield* requestInDirectory(`/session/${session.id}/fork`, test.directory, {
  43. method: "POST",
  44. headers,
  45. body: JSON.stringify({}),
  46. })
  47. expect(forked.status).toBe(200)
  48. const fork = (yield* forked.json) as SessionNs.Info
  49. expect(fork.metadata).toEqual(next.metadata)
  50. const reset = yield* requestInDirectory(`/session/${session.id}`, test.directory, {
  51. method: "PATCH",
  52. headers,
  53. body: JSON.stringify({ metadata: {} }),
  54. })
  55. expect(reset.status).toBe(200)
  56. expect(((yield* reset.json) as SessionNs.Info).metadata).toEqual({})
  57. yield* SessionNs.Service.use((svc) => svc.remove(fork.id).pipe(Effect.ignore))
  58. yield* SessionNs.Service.use((svc) => svc.remove(session.id).pipe(Effect.ignore))
  59. }),
  60. { git: true },
  61. )
  62. it.instance(
  63. "abort route returns success",
  64. () =>
  65. Effect.gen(function* () {
  66. const test = yield* TestInstance
  67. const session = yield* Effect.acquireRelease(SessionNs.use.create({}), (created) =>
  68. SessionNs.use.remove(created.id).pipe(Effect.ignore),
  69. )
  70. const res = yield* requestInDirectory(`/session/${session.id}/abort`, test.directory, { method: "POST" })
  71. expect(res.status).toBe(200)
  72. expect(yield* res.json).toBe(true)
  73. }),
  74. { git: true },
  75. )
  76. it.instance(
  77. "experimental background route is a no-op without synchronous subagents",
  78. () =>
  79. Effect.gen(function* () {
  80. const test = yield* TestInstance
  81. const session = yield* Effect.acquireRelease(SessionNs.use.create({}), (created) =>
  82. SessionNs.use.remove(created.id).pipe(Effect.ignore),
  83. )
  84. const res = yield* requestInDirectory(`/experimental/session/${session.id}/background`, test.directory, {
  85. method: "POST",
  86. })
  87. expect(res.status).toBe(200)
  88. expect(yield* res.json).toBe(false)
  89. }),
  90. { git: true },
  91. )
  92. })