143 lines
3.7 KiB
TypeScript
143 lines
3.7 KiB
TypeScript
import { expect, test, describe, beforeEach, afterEach } from "vitest";
|
|
import { mkdtempSync, rmSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import path from "node:path";
|
|
|
|
import {
|
|
createMockAppService,
|
|
createMockEngine,
|
|
DEFAULT_SEED,
|
|
} from "../mocks/engine";
|
|
import { type Engine } from "@xo-cash/engine";
|
|
import { p2pkhTemplate } from "../mocks/template-p2pkh";
|
|
import { AppService } from "../../../src/services/app";
|
|
|
|
import { handleReceiveCommand } from "../../../src/cli/commands/receive";
|
|
import { CommandError } from "../../../src/cli/commands/types";
|
|
import {
|
|
createCommandDeps,
|
|
createMockIO,
|
|
expectLogs,
|
|
type LogExpectation,
|
|
} from "../mocks/command";
|
|
|
|
type TestCase = {
|
|
name: string;
|
|
inputs: string[];
|
|
options?: Record<string, string>;
|
|
shouldThrow: boolean;
|
|
expectedEvent?: string;
|
|
expectedData?: Record<string, unknown>;
|
|
logs?: LogExpectation[];
|
|
};
|
|
|
|
const testCases: TestCase[] = [
|
|
// Successful address generation with template name and output identifier
|
|
{
|
|
name: "generates address with template name and output",
|
|
inputs: ["Wallet (P2PKH)", "receiveOutput"],
|
|
shouldThrow: false,
|
|
expectedData: {
|
|
address: expect.stringMatching(/^bitcoincash:q[a-z0-9]+$/),
|
|
},
|
|
logs: [{ out: "bitcoincash:q" }],
|
|
},
|
|
// Successful address generation with role specified
|
|
{
|
|
name: "generates address with template name, output, and role",
|
|
inputs: ["Wallet (P2PKH)", "receiveOutput", "receiver"],
|
|
shouldThrow: false,
|
|
expectedData: {
|
|
address: expect.stringMatching(/^bitcoincash:q[a-z0-9]+$/),
|
|
},
|
|
logs: [{ out: "bitcoincash:q" }],
|
|
},
|
|
// Missing all required arguments
|
|
{
|
|
name: "throws when no arguments provided",
|
|
inputs: [],
|
|
shouldThrow: true,
|
|
expectedEvent: "receive.arguments.missing",
|
|
},
|
|
// Missing output identifier
|
|
{
|
|
name: "throws when output identifier missing",
|
|
inputs: ["Wallet (P2PKH)"],
|
|
shouldThrow: true,
|
|
expectedEvent: "receive.arguments.missing",
|
|
},
|
|
// Unknown template
|
|
{
|
|
name: "throws when template not found",
|
|
inputs: ["unknown-template", "receiveOutput"],
|
|
shouldThrow: true,
|
|
expectedEvent: "template.resolve.not_found",
|
|
},
|
|
];
|
|
|
|
describe("receive command", () => {
|
|
let engine: Engine;
|
|
let app: AppService;
|
|
let tempDir: string;
|
|
|
|
beforeEach(async () => {
|
|
const mockEngine = await createMockEngine(DEFAULT_SEED);
|
|
engine = mockEngine.engine;
|
|
await engine.importTemplate(p2pkhTemplate);
|
|
|
|
app = await createMockAppService(engine);
|
|
|
|
tempDir = mkdtempSync(path.join(tmpdir(), "xo-cli-receive-tests-"));
|
|
});
|
|
|
|
afterEach(async () => {
|
|
await engine.stop();
|
|
rmSync(tempDir, { recursive: true, force: true });
|
|
});
|
|
|
|
test.each(testCases)(
|
|
"$name",
|
|
async ({
|
|
inputs,
|
|
options,
|
|
shouldThrow,
|
|
expectedEvent,
|
|
expectedData,
|
|
logs,
|
|
}) => {
|
|
const { io, spies } = createMockIO();
|
|
|
|
if (shouldThrow) {
|
|
try {
|
|
await handleReceiveCommand(
|
|
createCommandDeps(app, io),
|
|
inputs,
|
|
options ?? {},
|
|
);
|
|
expect.fail("Expected command to throw");
|
|
} catch (error) {
|
|
if (expectedEvent) {
|
|
expect(error).toBeInstanceOf(CommandError);
|
|
expect((error as CommandError).event).toBe(expectedEvent);
|
|
}
|
|
}
|
|
} else {
|
|
const result = await handleReceiveCommand(
|
|
createCommandDeps(app, io),
|
|
inputs,
|
|
options ?? {},
|
|
);
|
|
if (expectedData) {
|
|
Object.entries(expectedData).forEach(([key, value]) => {
|
|
expect(result[key as keyof typeof result]).toEqual(value);
|
|
});
|
|
}
|
|
}
|
|
|
|
if (logs) {
|
|
expectLogs(spies, logs);
|
|
}
|
|
},
|
|
);
|
|
});
|