Tests. Autocomplete. Few Fixes. Mocks for Electrum Service. Template-to-Json parser. Fix global paths. Use IO Dependency injection for logging from cli. Additional commands in CLI.
This commit is contained in:
146
tests/cli/commands/mnemonic.test.ts
Normal file
146
tests/cli/commands/mnemonic.test.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
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);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user