132 lines · 4.4 KB · TypeScript
RawDownload
import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient";import * as NodeServices from "@effect/platform-node/NodeServices";import { assert, describe, it } from "@effect/vitest";import * as NetService from "@t3tools/shared/Net";import { SshPasswordPromptError } from "@t3tools/ssh/errors";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Layer from "effect/Layer";import * as Path from "effect/Path"; import * as DesktopSshEnvironment from "./DesktopSshEnvironment.ts";import * as DesktopSshPasswordPrompts from "./DesktopSshPasswordPrompts.ts"; function makeTempHomeDir() {  return Effect.gen(function* () {    const fs = yield* FileSystem.FileSystem;    return yield* fs.makeTempDirectoryScoped({ prefix: "t3-ssh-env-test-" });  });} describe("sshEnvironment", () => {  it("keeps prompt presentation diagnostics distinct from the legacy wrapper message", () => {    const cause = new DesktopSshPasswordPrompts.DesktopSshPromptPresentationError({      requestId: "prompt-1",      destination: "devbox",      operation: "send-prompt-request",      cause: new Error("renderer send failed"),    });     assert.equal(cause.message, "Failed to present SSH password prompt for devbox.");    assert.equal(      DesktopSshEnvironment.toSshPasswordPromptError(cause).message,      "T3 Code window is not available for SSH authentication.",    );  });   it("treats password prompt timeouts as cancellable authentication prompts", () => {    assert.equal(      DesktopSshEnvironment.isDesktopSshPasswordPromptCancellation(        new SshPasswordPromptError({          message: "SSH authentication timed out for devbox.",          cause: new DesktopSshPasswordPrompts.DesktopSshPromptTimedOutError({            requestId: "prompt-1",            destination: "devbox",          }),        }),      ),      true,    );  });   it.effect("wires desktop host discovery through the ssh package runtime", () =>    Effect.gen(function* () {      const fs = yield* FileSystem.FileSystem;      const path = yield* Path.Path;      const homeDir = yield* makeTempHomeDir();      const sshDir = path.join(homeDir, ".ssh");      yield* fs.makeDirectory(path.join(sshDir, "config.d"), { recursive: true });      yield* fs.writeFileString(        path.join(sshDir, "config"),        ["Host devbox", "  HostName devbox.example.com", "Include config.d/*.conf", ""].join("\n"),      );      yield* fs.writeFileString(        path.join(sshDir, "config.d", "team.conf"),        [          "Host staging",          "  HostName staging.example.com",          "Host *",          "  ServerAliveInterval 30",          "",        ].join("\n"),      );      yield* fs.writeFileString(        path.join(sshDir, "known_hosts"),        [          "known.example.com ssh-ed25519 AAAA",          "|1|hashed|entry ssh-ed25519 AAAA",          "[bastion.example.com]:2222 ssh-ed25519 AAAA",          "",        ].join("\n"),      );       const sshEnvironment = yield* DesktopSshEnvironment.DesktopSshEnvironment;      const hosts = yield* sshEnvironment.discoverHosts({ homeDir });      assert.deepEqual(hosts, [        {          alias: "bastion.example.com",          hostname: "bastion.example.com",          username: null,          port: null,          source: "known-hosts",        },        {          alias: "devbox",          hostname: "devbox",          username: null,          port: null,          source: "ssh-config",        },        {          alias: "known.example.com",          hostname: "known.example.com",          username: null,          port: null,          source: "known-hosts",        },        {          alias: "staging",          hostname: "staging",          username: null,          port: null,          source: "ssh-config",        },      ]);    }).pipe(      Effect.provide(        DesktopSshEnvironment.layer().pipe(          Layer.provideMerge(            Layer.succeed(DesktopSshPasswordPrompts.DesktopSshPasswordPrompts, {              request: () => Effect.die("unexpected password prompt request"),              resolve: () => Effect.die("unexpected password prompt resolution"),            }),          ),          Layer.provideMerge(NodeServices.layer),          Layer.provideMerge(NodeHttpClient.layerUndici),          Layer.provideMerge(NetService.layer),        ),      ),      Effect.scoped,    ),  );});