1import { PrismaApiError } from "@/Prisma/Client";
2import {
3 getBuildLogsRequest,
4 getDeploymentLogsRequest,
5} from "@/Prisma/Internal/LogsClient";
6import { Credentials } from "@/Prisma/Credentials";
7import { describe, expect, it } from "alchemy-test";
8import * as Effect from "effect/Effect";
9import * as Redacted from "effect/Redacted";
10
11const provideEnv = Effect.provideService(
12 Credentials,
13 Effect.succeed({
14 apiToken: Redacted.make("test-token"),
15 apiBaseUrl: "https://api.prisma.test",
16 }),
17);
18
19describe(
20 "Prisma log request builders",
21 { tags: ["unit", "provider:prisma", "local"] },
22 () => {
23 it.effect("builds authenticated deployment log stream requests", () =>
24 Effect.gen(function* () {
25 const request = yield* getDeploymentLogsRequest("deployment-1", {
26 tail: 100,
27 fromStart: true,
28 cursor: "byte-42",
29 });
30 expect(request.url).toBe(
31 "wss://api.prisma.test/v1/deployments/deployment-1/logs?tail=100&cursor=byte-42&from_start=true",
32 );
33 expect(Redacted.value(request.headers.Authorization)).toBe(
34 "Bearer test-token",
35 );
36 }).pipe(provideEnv),
37 );
38
39 it.effect("builds authenticated build log stream requests", () =>
40 Effect.gen(function* () {
41 const request = yield* getBuildLogsRequest("build-1", {
42 follow: true,
43 cursor: "cursor-1",
44 });
45 expect(request.url).toBe(
46 "https://api.prisma.test/v1/builds/build-1/logs?follow=true&cursor=cursor-1",
47 );
48 expect(Redacted.value(request.headers.Authorization)).toBe(
49 "Bearer test-token",
50 );
51 expect(request.headers.Accept).toBe("application/x-ndjson");
52 }).pipe(provideEnv),
53 );
54
55 it.effect("rejects path-confusing resource IDs before building a URL", () =>
56 Effect.gen(function* () {
57 const deploymentLog = yield* getDeploymentLogsRequest(
58 "deployment-1/../../projects",
59 ).pipe(Effect.flip);
60 const buildLog = yield* getBuildLogsRequest("build-1?token=leak").pipe(
61 Effect.flip,
62 );
63
64 for (const error of [deploymentLog, buildLog]) {
65 expect(error).toBeInstanceOf(PrismaApiError);
66 expect(error.message).toContain("invalid Prisma Management API");
67 }
68 }).pipe(provideEnv),
69 );
70 },
71);