166 lines
4.2 KiB
TypeScript
166 lines
4.2 KiB
TypeScript
import { expect, test, describe, beforeEach, afterEach } from "vitest";
|
|
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import path from "node:path";
|
|
|
|
import { DEFAULT_SEED } from "../mocks/engine";
|
|
|
|
import { handleMnemonicCommand } from "../../../src/cli/commands/mnemonic";
|
|
import { CommandError } from "../../../src/cli/commands/types";
|
|
import {
|
|
createMockIO,
|
|
createMockPaths,
|
|
expectLogs,
|
|
type LogExpectation,
|
|
} from "../mocks/command";
|
|
import { BCHMnemonicURL } from "../../../src/utils/bch-mnemonic-url";
|
|
|
|
type TestCase = {
|
|
inputs: string[];
|
|
options?: Record<string, string>;
|
|
shouldThrow: boolean;
|
|
expectedEvent?: string;
|
|
expectedData?: Record<string, unknown>;
|
|
logs?: LogExpectation[];
|
|
};
|
|
|
|
const testCases: TestCase[] = [
|
|
// Successful creation of a mnemonic file
|
|
{
|
|
inputs: ["create"],
|
|
shouldThrow: false,
|
|
expectedData: {
|
|
savedAs: expect.stringMatching(/^mnemonic-\w+$/),
|
|
},
|
|
logs: [{ out: "Mnemonic file created" }],
|
|
},
|
|
// Successfully creating a mnemonic file with a custom filename
|
|
{
|
|
inputs: ["create"],
|
|
options: { output: "custom-filename" },
|
|
shouldThrow: false,
|
|
expectedData: {
|
|
savedAs: "custom-filename",
|
|
},
|
|
logs: [{ out: "custom-filename" }],
|
|
},
|
|
// Successfully listing mnemonic files
|
|
{
|
|
inputs: ["list"],
|
|
shouldThrow: false,
|
|
expectedData: {
|
|
count: expect.toSatisfy((count: number) => count >= 1),
|
|
},
|
|
logs: [{ out: "mnemonic-test" }],
|
|
},
|
|
// Successfully exposing a mnemonic file
|
|
{
|
|
inputs: ["expose", "mnemonic-test"],
|
|
shouldThrow: false,
|
|
expectedData: {
|
|
mnemonic: DEFAULT_SEED,
|
|
},
|
|
logs: [{ out: DEFAULT_SEED }],
|
|
},
|
|
// Successfully importing a mnemonic file
|
|
{
|
|
inputs: ["import", ...DEFAULT_SEED.split(" ")],
|
|
shouldThrow: false,
|
|
expectedData: {
|
|
savedAs: expect.stringMatching(/^mnemonic-\w+$/),
|
|
},
|
|
logs: [{ out: "Mnemonic file created" }],
|
|
},
|
|
// Failure to import a mnemonic file due to missing arguments
|
|
{
|
|
inputs: ["import"],
|
|
shouldThrow: true,
|
|
expectedEvent: "mnemonic.import.seed_missing",
|
|
},
|
|
// Failure to expose a mnemonic file due to missing arguments
|
|
{
|
|
inputs: ["expose"],
|
|
shouldThrow: true,
|
|
expectedEvent: "mnemonic.expose.file_missing",
|
|
},
|
|
// Failure to expose a mnemonic file due to unknown mnemonic file
|
|
{
|
|
inputs: ["expose", "unknown-mnemonic-file"],
|
|
shouldThrow: true,
|
|
expectedEvent: "mnemonic.expose.file_not_found",
|
|
},
|
|
// Missing sub-command
|
|
{
|
|
inputs: [],
|
|
shouldThrow: true,
|
|
expectedEvent: "mnemonic.subcommand.missing",
|
|
},
|
|
// Unknown sub-command
|
|
{
|
|
inputs: ["unknown"],
|
|
shouldThrow: true,
|
|
expectedEvent: "mnemonic.subcommand.unknown",
|
|
},
|
|
];
|
|
|
|
describe("mnemonic commands", () => {
|
|
let tempDir: string;
|
|
|
|
beforeEach(async () => {
|
|
tempDir = mkdtempSync(path.join(tmpdir(), "xo-cli-mnemonic-tests-"));
|
|
|
|
// Write a single test mnemonic file to the temp directory
|
|
writeFileSync(
|
|
path.join(tempDir, "mnemonic-test"),
|
|
BCHMnemonicURL.fromSeed(DEFAULT_SEED).toURL(),
|
|
"utf8",
|
|
);
|
|
});
|
|
|
|
afterEach(async () => {
|
|
rmSync(tempDir, { recursive: true, force: true });
|
|
});
|
|
|
|
test.each(testCases)(
|
|
"mnemonic command: $inputs",
|
|
async ({
|
|
inputs,
|
|
options,
|
|
shouldThrow,
|
|
expectedEvent,
|
|
expectedData,
|
|
logs,
|
|
}) => {
|
|
const { io, spies } = createMockIO();
|
|
const paths = createMockPaths(tempDir);
|
|
|
|
if (shouldThrow) {
|
|
try {
|
|
await handleMnemonicCommand({ io, paths }, 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 handleMnemonicCommand(
|
|
{ io, paths },
|
|
inputs,
|
|
options ?? {},
|
|
);
|
|
if (expectedData) {
|
|
Object.entries(expectedData).forEach(([key, value]) => {
|
|
expect(result[key as keyof typeof result]).toEqual(value);
|
|
});
|
|
}
|
|
}
|
|
|
|
if (logs) {
|
|
expectLogs(spies, logs);
|
|
}
|
|
},
|
|
);
|
|
});
|