Folo/apps/cli/src/cli.e2e.test.ts

102 lines
2.7 KiB
TypeScript

import type { ExecFileException } from "node:child_process"
import { execFile } from "node:child_process"
import { mkdtempSync } from "node:fs"
import { tmpdir } from "node:os"
import { promisify } from "node:util"
import { resolve } from "pathe"
import { describe, expect, it } from "vitest"
const execFileAsync = promisify(execFile)
const cliPath = resolve(process.cwd(), "dist/index.js")
const testToken = process.env.FOLO_TEST_TOKEN
const isolatedHome = mkdtempSync(resolve(tmpdir(), "folocli-test-"))
type CLIExecution = {
code: number
stdout: string
stderr: string
}
const runCLI = async (args: string[]): Promise<CLIExecution> => {
try {
const { stdout, stderr } = await execFileAsync("node", [cliPath, ...args], {
env: {
...process.env,
HOME: isolatedHome,
USERPROFILE: isolatedHome,
FOLO_TOKEN: "",
},
})
return {
code: 0,
stdout,
stderr,
}
} catch (error) {
const execError = error as ExecFileException & {
stdout?: string
stderr?: string
}
return {
code: typeof execError.code === "number" ? execError.code : 1,
stdout: execError.stdout ?? "",
stderr: execError.stderr ?? "",
}
}
}
describe("cli e2e", () => {
it("returns structured unauthorized error without token", async () => {
const result = await runCLI(["timeline", "--limit", "1"])
expect(result.code).not.toBe(0)
const payload = JSON.parse(result.stderr) as {
ok: boolean
data: null
error: { code: string; message: string }
}
expect(payload.ok).toBe(false)
expect(payload.data).toBeNull()
expect(payload.error.code).toBe("UNAUTHORIZED")
})
it.runIf(Boolean(testToken))("can fetch session with test token", async () => {
const result = await runCLI(["--token", testToken!, "whoami"])
expect(result.code).toBe(0)
const payload = JSON.parse(result.stdout) as {
ok: boolean
data: {
user: { id: string }
session: { id: string }
}
error: null
}
expect(payload.ok).toBe(true)
expect(payload.error).toBeNull()
expect(typeof payload.data.user.id).toBe("string")
expect(typeof payload.data.session.id).toBe("string")
})
it.runIf(Boolean(testToken))("can fetch timeline with test token", async () => {
const result = await runCLI(["--token", testToken!, "timeline", "--limit", "1"])
expect(result.code).toBe(0)
const payload = JSON.parse(result.stdout) as {
ok: boolean
data: {
entries: unknown[]
nextCursor: string | null
hasNext: boolean
}
error: null
}
expect(payload.ok).toBe(true)
expect(Array.isArray(payload.data.entries)).toBe(true)
expect(typeof payload.data.hasNext).toBe("boolean")
})
})