50 lines · 2.2 KB · TypeScript
RawDownload
import * as NodeServices from "@effect/platform-node/NodeServices";import { assert, describe, expect, it } from "@effect/vitest";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Schema from "effect/Schema";import { HttpClient, HttpClientResponse } from "effect/unstable/http";import * as Generator from "./generate.ts"; const isDownloadError = Schema.is(Generator.AcpGeneratorDownloadError); const httpClient = (response: Response) =>  HttpClient.make((request) => Effect.succeed(HttpClientResponse.fromWeb(request, response))); describe("ACP schema generator errors", () => {  it.effect("retains safe URL diagnostics, output path, and HTTP cause when a download fails", () =>    Effect.gen(function* () {      const fs = yield* FileSystem.FileSystem;      const directory = yield* fs.makeTempDirectoryScoped({ prefix: "acp-generator-test-" });      const url =        "https://generator-user:generator-password@example.test/private/schema.json?token=generator-secret#fragment";      const outputPath = `${directory}/schema.json`;      const error = yield* Generator.downloadFile(url, outputPath).pipe(        Effect.provideService(          HttpClient.HttpClient,          httpClient(new Response("unavailable", { status: 503 })),        ),        Effect.flip,      );       assert(isDownloadError(error));      expect(error).toMatchObject({        urlInputLength: url.length,        urlProtocol: "https:",        urlHostname: "example.test",      });      expect(error).not.toHaveProperty("url");      expect(error.outputPath).toBe(outputPath);      expect(error.stage).toBe("request");      expect(error.cause).toBeDefined();      expect(error.message).toContain(outputPath);      const { cause: _, ...directDiagnostics } = error;      expect(directDiagnostics).not.toHaveProperty("url");      expect(directDiagnostics.urlProtocol).toBe("https:");      expect(directDiagnostics.urlHostname).toBe("example.test");      expect(error.message).not.toMatch(        /generator-user|generator-password|private|token|generator-secret|fragment/,      );    }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),  );});