1// @effect-diagnostics nodeBuiltinImport:off
2import * as NodeFS from "node:fs";
3import * as NodePath from "node:path";
4import * as NodeServices from "@effect/platform-node/NodeServices";
5import { describe, expect, it } from "@effect/vitest";
6import * as Effect from "effect/Effect";
7import * as Layer from "effect/Layer";
8import * as ServerConfig from "../config.ts";
9import { appendUserInputAttachmentPaths } from "./userInputAttachments.ts";
10
11const layer = ServerConfig.layerTest(process.cwd(), { prefix: "t3-answer-paths-" }).pipe(
12 Layer.provideMerge(NodeServices.layer),
13);
14const attachment = {
15 type: "file" as const,
16 id: "thread-1-00000000-0000-4000-8000-0000000000aa-txt",
17 name: 'spec "final".txt',
18 mimeType: "text/plain",
19 sizeBytes: 4,
20};
21describe("question answer paths", () => {
22 it.effect("keeps selected values intact and appends an actual readable server path", () =>
23 Effect.gen(function* () {
24 const config = yield* ServerConfig.ServerConfig;
25 const path = NodePath.join(config.attachmentsDir, `${attachment.id}.txt`);
26 NodeFS.writeFileSync(path, "spec");
27 const original = { q: ["First", "Second"], other: "No file" };
28 const answers = yield* appendUserInputAttachmentPaths({
29 answers: original,
30 attachmentsDir: config.attachmentsDir,
31 attachmentsByQuestionId: { q: [attachment] },
32 });
33 expect(answers.q).toEqual([
34 "First",
35 "Second",
36 `Attached file "spec \\"final\\".txt": "${path}"`,
37 ]);
38 expect(answers.other).toBe("No file");
39 expect(original.q).toEqual(["First", "Second"]);
40 expect(NodeFS.readFileSync(path, "utf8")).toBe("spec");
41 const specialKey = yield* appendUserInputAttachmentPaths({
42 answers: {},
43 attachmentsDir: config.attachmentsDir,
44 attachmentsByQuestionId: { ["__proto__"]: [attachment] },
45 });
46 expect(Object.keys(specialKey)).toEqual(["__proto__"]);
47 expect(specialKey["__proto__"]).toContain(path);
48 }).pipe(Effect.provide(layer)),
49 );
50 it.effect("does not send an unavailable attachment path", () =>
51 Effect.gen(function* () {
52 const config = yield* ServerConfig.ServerConfig;
53 const result = yield* appendUserInputAttachmentPaths({
54 answers: { q: "" },
55 attachmentsDir: config.attachmentsDir,
56 attachmentsByQuestionId: { q: [attachment] },
57 }).pipe(Effect.result);
58 expect(result._tag).toBe("Failure");
59 }).pipe(Effect.provide(layer)),
60 );
61});