genlayer 0.31.0 → 0.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/CLAUDE.md +55 -0
- package/README.md +121 -8
- package/dist/index.js +7161 -3706
- package/docs/delegator-guide.md +203 -0
- package/docs/validator-guide.md +291 -0
- package/package.json +2 -2
- package/src/commands/account/create.ts +29 -0
- package/src/commands/account/export.ts +106 -0
- package/src/commands/account/import.ts +135 -0
- package/src/commands/account/index.ts +126 -0
- package/src/commands/account/list.ts +34 -0
- package/src/commands/account/lock.ts +39 -0
- package/src/commands/account/remove.ts +30 -0
- package/src/commands/account/send.ts +156 -0
- package/src/commands/account/show.ts +74 -0
- package/src/commands/account/unlock.ts +51 -0
- package/src/commands/account/use.ts +21 -0
- package/src/commands/network/index.ts +18 -3
- package/src/commands/network/setNetwork.ts +43 -26
- package/src/commands/staking/StakingAction.ts +157 -0
- package/src/commands/staking/delegatorClaim.ts +41 -0
- package/src/commands/staking/delegatorExit.ts +50 -0
- package/src/commands/staking/delegatorJoin.ts +44 -0
- package/src/commands/staking/index.ts +251 -0
- package/src/commands/staking/setIdentity.ts +66 -0
- package/src/commands/staking/setOperator.ts +40 -0
- package/src/commands/staking/stakingInfo.ts +300 -0
- package/src/commands/staking/validatorClaim.ts +38 -0
- package/src/commands/staking/validatorDeposit.ts +35 -0
- package/src/commands/staking/validatorExit.ts +44 -0
- package/src/commands/staking/validatorJoin.ts +47 -0
- package/src/commands/staking/validatorPrime.ts +35 -0
- package/src/commands/staking/wizard.ts +802 -0
- package/src/index.ts +4 -2
- package/src/lib/actions/BaseAction.ts +114 -55
- package/src/lib/config/ConfigFileManager.ts +143 -0
- package/src/lib/config/KeychainManager.ts +23 -7
- package/tests/actions/create.test.ts +41 -21
- package/tests/actions/deploy.test.ts +7 -0
- package/tests/actions/lock.test.ts +33 -13
- package/tests/actions/setNetwork.test.ts +18 -57
- package/tests/actions/staking.test.ts +323 -0
- package/tests/actions/unlock.test.ts +51 -33
- package/tests/commands/account.test.ts +146 -0
- package/tests/commands/network.test.ts +10 -10
- package/tests/commands/staking.test.ts +333 -0
- package/tests/index.test.ts +6 -2
- package/tests/libs/baseAction.test.ts +71 -42
- package/tests/libs/configFileManager.test.ts +8 -1
- package/tests/libs/keychainManager.test.ts +56 -16
- package/src/commands/keygen/create.ts +0 -23
- package/src/commands/keygen/index.ts +0 -39
- package/src/commands/keygen/lock.ts +0 -31
- package/src/commands/keygen/unlock.ts +0 -41
- package/src/lib/interfaces/KeystoreData.ts +0 -5
- package/tests/commands/keygen.test.ts +0 -123
|
@@ -41,17 +41,17 @@ describe("KeychainManager", () => {
|
|
|
41
41
|
const privateKey = "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890";
|
|
42
42
|
vi.mocked(keytar.setPassword).mockResolvedValue();
|
|
43
43
|
|
|
44
|
-
await keychainManager.storePrivateKey(privateKey);
|
|
44
|
+
await keychainManager.storePrivateKey("main", privateKey);
|
|
45
45
|
|
|
46
|
-
expect(keytar.setPassword).toHaveBeenCalledWith("genlayer-cli", "
|
|
46
|
+
expect(keytar.setPassword).toHaveBeenCalledWith("genlayer-cli", "account:main", privateKey);
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
test("handles storage error", async () => {
|
|
50
50
|
const privateKey = "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890";
|
|
51
51
|
vi.mocked(keytar.setPassword).mockRejectedValue(new Error("Storage failed"));
|
|
52
52
|
|
|
53
|
-
await expect(keychainManager.storePrivateKey(privateKey)).rejects.toThrow("Storage failed");
|
|
54
|
-
expect(keytar.setPassword).toHaveBeenCalledWith("genlayer-cli", "
|
|
53
|
+
await expect(keychainManager.storePrivateKey("main", privateKey)).rejects.toThrow("Storage failed");
|
|
54
|
+
expect(keytar.setPassword).toHaveBeenCalledWith("genlayer-cli", "account:main", privateKey);
|
|
55
55
|
});
|
|
56
56
|
});
|
|
57
57
|
|
|
@@ -60,26 +60,26 @@ describe("KeychainManager", () => {
|
|
|
60
60
|
const expectedKey = "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890";
|
|
61
61
|
vi.mocked(keytar.getPassword).mockResolvedValue(expectedKey);
|
|
62
62
|
|
|
63
|
-
const result = await keychainManager.getPrivateKey();
|
|
63
|
+
const result = await keychainManager.getPrivateKey("main");
|
|
64
64
|
|
|
65
65
|
expect(result).toBe(expectedKey);
|
|
66
|
-
expect(keytar.getPassword).toHaveBeenCalledWith("genlayer-cli", "
|
|
66
|
+
expect(keytar.getPassword).toHaveBeenCalledWith("genlayer-cli", "account:main");
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
test("returns null when private key does not exist", async () => {
|
|
70
70
|
vi.mocked(keytar.getPassword).mockResolvedValue(null);
|
|
71
71
|
|
|
72
|
-
const result = await keychainManager.getPrivateKey();
|
|
72
|
+
const result = await keychainManager.getPrivateKey("main");
|
|
73
73
|
|
|
74
74
|
expect(result).toBeNull();
|
|
75
|
-
expect(keytar.getPassword).toHaveBeenCalledWith("genlayer-cli", "
|
|
75
|
+
expect(keytar.getPassword).toHaveBeenCalledWith("genlayer-cli", "account:main");
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
test("handles retrieval error", async () => {
|
|
79
79
|
vi.mocked(keytar.getPassword).mockRejectedValue(new Error("Retrieval failed"));
|
|
80
80
|
|
|
81
|
-
await expect(keychainManager.getPrivateKey()).rejects.toThrow("Retrieval failed");
|
|
82
|
-
expect(keytar.getPassword).toHaveBeenCalledWith("genlayer-cli", "
|
|
81
|
+
await expect(keychainManager.getPrivateKey("main")).rejects.toThrow("Retrieval failed");
|
|
82
|
+
expect(keytar.getPassword).toHaveBeenCalledWith("genlayer-cli", "account:main");
|
|
83
83
|
});
|
|
84
84
|
});
|
|
85
85
|
|
|
@@ -87,26 +87,66 @@ describe("KeychainManager", () => {
|
|
|
87
87
|
test("successfully removes private key", async () => {
|
|
88
88
|
vi.mocked(keytar.deletePassword).mockResolvedValue(true);
|
|
89
89
|
|
|
90
|
-
const result = await keychainManager.removePrivateKey();
|
|
90
|
+
const result = await keychainManager.removePrivateKey("main");
|
|
91
91
|
|
|
92
92
|
expect(result).toBe(true);
|
|
93
|
-
expect(keytar.deletePassword).toHaveBeenCalledWith("genlayer-cli", "
|
|
93
|
+
expect(keytar.deletePassword).toHaveBeenCalledWith("genlayer-cli", "account:main");
|
|
94
94
|
});
|
|
95
95
|
|
|
96
96
|
test("returns false when key does not exist", async () => {
|
|
97
97
|
vi.mocked(keytar.deletePassword).mockResolvedValue(false);
|
|
98
98
|
|
|
99
|
-
const result = await keychainManager.removePrivateKey();
|
|
99
|
+
const result = await keychainManager.removePrivateKey("main");
|
|
100
100
|
|
|
101
101
|
expect(result).toBe(false);
|
|
102
|
-
expect(keytar.deletePassword).toHaveBeenCalledWith("genlayer-cli", "
|
|
102
|
+
expect(keytar.deletePassword).toHaveBeenCalledWith("genlayer-cli", "account:main");
|
|
103
103
|
});
|
|
104
104
|
|
|
105
105
|
test("handles removal error", async () => {
|
|
106
106
|
vi.mocked(keytar.deletePassword).mockRejectedValue(new Error("Removal failed"));
|
|
107
107
|
|
|
108
|
-
await expect(keychainManager.removePrivateKey()).rejects.toThrow("Removal failed");
|
|
109
|
-
expect(keytar.deletePassword).toHaveBeenCalledWith("genlayer-cli", "
|
|
108
|
+
await expect(keychainManager.removePrivateKey("main")).rejects.toThrow("Removal failed");
|
|
109
|
+
expect(keytar.deletePassword).toHaveBeenCalledWith("genlayer-cli", "account:main");
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe("listUnlockedAccounts", () => {
|
|
114
|
+
test("returns list of unlocked account names", async () => {
|
|
115
|
+
vi.mocked(keytar.findCredentials).mockResolvedValue([
|
|
116
|
+
{account: "account:main", password: "key1"},
|
|
117
|
+
{account: "account:validator", password: "key2"},
|
|
118
|
+
{account: "other:something", password: "key3"},
|
|
119
|
+
]);
|
|
120
|
+
|
|
121
|
+
const result = await keychainManager.listUnlockedAccounts();
|
|
122
|
+
|
|
123
|
+
expect(result).toEqual(["main", "validator"]);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("returns empty array when no accounts", async () => {
|
|
127
|
+
vi.mocked(keytar.findCredentials).mockResolvedValue([]);
|
|
128
|
+
|
|
129
|
+
const result = await keychainManager.listUnlockedAccounts();
|
|
130
|
+
|
|
131
|
+
expect(result).toEqual([]);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe("isAccountUnlocked", () => {
|
|
136
|
+
test("returns true when account is unlocked", async () => {
|
|
137
|
+
vi.mocked(keytar.getPassword).mockResolvedValue("some-key");
|
|
138
|
+
|
|
139
|
+
const result = await keychainManager.isAccountUnlocked("main");
|
|
140
|
+
|
|
141
|
+
expect(result).toBe(true);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("returns false when account is locked", async () => {
|
|
145
|
+
vi.mocked(keytar.getPassword).mockResolvedValue(null);
|
|
146
|
+
|
|
147
|
+
const result = await keychainManager.isAccountUnlocked("main");
|
|
148
|
+
|
|
149
|
+
expect(result).toBe(false);
|
|
110
150
|
});
|
|
111
151
|
});
|
|
112
152
|
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import {BaseAction} from "../../lib/actions/BaseAction";
|
|
2
|
-
|
|
3
|
-
export interface CreateKeypairOptions {
|
|
4
|
-
output: string;
|
|
5
|
-
overwrite: boolean;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export class KeypairCreator extends BaseAction {
|
|
9
|
-
constructor() {
|
|
10
|
-
super();
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async createKeypairAction(options: CreateKeypairOptions) {
|
|
14
|
-
try {
|
|
15
|
-
this.startSpinner(`Creating encrypted keystore...`);
|
|
16
|
-
await this.createKeypair(options.output, options.overwrite);
|
|
17
|
-
|
|
18
|
-
this.succeedSpinner(`Encrypted keystore successfully created and saved to: ${options.output}`);
|
|
19
|
-
} catch (error) {
|
|
20
|
-
this.failSpinner("Failed to generate keystore", error);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { CreateKeypairOptions, KeypairCreator } from "./create";
|
|
3
|
-
import { UnlockAction } from "./unlock";
|
|
4
|
-
import { LockAction } from "./lock";
|
|
5
|
-
|
|
6
|
-
export function initializeKeygenCommands(program: Command) {
|
|
7
|
-
|
|
8
|
-
const keygenCommand = program
|
|
9
|
-
.command("keygen")
|
|
10
|
-
.description("Manage keypair generation");
|
|
11
|
-
|
|
12
|
-
keygenCommand
|
|
13
|
-
.command("create")
|
|
14
|
-
.description("Generates a new encrypted keystore and saves it to a file")
|
|
15
|
-
.option("--output <path>", "Path to save the keystore", "./keypair.json")
|
|
16
|
-
.option("--overwrite", "Overwrite the existing file if it already exists", false)
|
|
17
|
-
.action(async (options: CreateKeypairOptions) => {
|
|
18
|
-
const keypairCreator = new KeypairCreator();
|
|
19
|
-
await keypairCreator.createKeypairAction(options);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
keygenCommand
|
|
23
|
-
.command("unlock")
|
|
24
|
-
.description("Unlock your wallet by storing the decrypted private key in OS keychain")
|
|
25
|
-
.action(async () => {
|
|
26
|
-
const unlockAction = new UnlockAction();
|
|
27
|
-
await unlockAction.execute();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
keygenCommand
|
|
31
|
-
.command("lock")
|
|
32
|
-
.description("Lock your wallet by removing the decrypted private key from OS keychain")
|
|
33
|
-
.action(async () => {
|
|
34
|
-
const lockAction = new LockAction();
|
|
35
|
-
await lockAction.execute();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
return program;
|
|
39
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { BaseAction } from "../../lib/actions/BaseAction";
|
|
2
|
-
|
|
3
|
-
export class LockAction extends BaseAction {
|
|
4
|
-
async execute(): Promise<void> {
|
|
5
|
-
this.startSpinner("Checking keychain availability...");
|
|
6
|
-
|
|
7
|
-
const keychainAvailable = await this.keychainManager.isKeychainAvailable();
|
|
8
|
-
if (!keychainAvailable) {
|
|
9
|
-
this.failSpinner("OS keychain is not available. This command requires a supported keychain (e.g. macOS Keychain, Windows Credential Manager, or GNOME Keyring).");
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
this.setSpinnerText("Checking for cached private key...");
|
|
14
|
-
|
|
15
|
-
const hasCachedKey = await this.keychainManager.getPrivateKey();
|
|
16
|
-
if (!hasCachedKey) {
|
|
17
|
-
this.succeedSpinner("Wallet is already locked (no cached key found in OS keychain).");
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
this.setSpinnerText("Removing private key from OS keychain...");
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
await this.keychainManager.removePrivateKey();
|
|
25
|
-
|
|
26
|
-
this.succeedSpinner("Wallet locked successfully! Your private key has been removed from the OS keychain.");
|
|
27
|
-
} catch (error) {
|
|
28
|
-
this.failSpinner("Failed to lock wallet.", error);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { BaseAction } from "../../lib/actions/BaseAction";
|
|
2
|
-
import { readFileSync, existsSync } from "fs";
|
|
3
|
-
import { ethers } from "ethers";
|
|
4
|
-
|
|
5
|
-
export class UnlockAction extends BaseAction {
|
|
6
|
-
async execute(): Promise<void> {
|
|
7
|
-
this.startSpinner("Checking keychain availability...");
|
|
8
|
-
|
|
9
|
-
const keychainAvailable = await this.keychainManager.isKeychainAvailable();
|
|
10
|
-
if (!keychainAvailable) {
|
|
11
|
-
this.failSpinner("OS keychain is not available. This command requires a supported keychain (e.g. macOS Keychain, Windows Credential Manager, or GNOME Keyring).");
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
this.setSpinnerText("Checking for existing keystore...");
|
|
16
|
-
|
|
17
|
-
const keypairPath = this.getConfigByKey("keyPairPath");
|
|
18
|
-
if (!keypairPath || !existsSync(keypairPath)) {
|
|
19
|
-
this.failSpinner("No keystore file found. Please create a keypair first using 'genlayer keygen create'.");
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const keystoreData = JSON.parse(readFileSync(keypairPath, "utf-8"));
|
|
24
|
-
if (!this.isValidKeystoreFormat(keystoreData)) {
|
|
25
|
-
this.failSpinner("Invalid keystore format. Expected encrypted keystore file.");
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
this.stopSpinner();
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
const password = await this.promptPassword("Enter password to decrypt keystore:");
|
|
33
|
-
const wallet = await ethers.Wallet.fromEncryptedJson(keystoreData.encrypted, password);
|
|
34
|
-
|
|
35
|
-
await this.keychainManager.storePrivateKey(wallet.privateKey);
|
|
36
|
-
this.succeedSpinner("Wallet unlocked successfully! Your private key is now stored securely in the OS keychain.");
|
|
37
|
-
} catch (error) {
|
|
38
|
-
this.failSpinner("Failed to unlock wallet.", error);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { vi, describe, beforeEach, afterEach, test, expect } from "vitest";
|
|
3
|
-
import { initializeKeygenCommands } from "../../src/commands/keygen";
|
|
4
|
-
import { KeypairCreator } from "../../src/commands/keygen/create";
|
|
5
|
-
import { UnlockAction } from "../../src/commands/keygen/unlock";
|
|
6
|
-
import { LockAction } from "../../src/commands/keygen/lock";
|
|
7
|
-
|
|
8
|
-
vi.mock("../../src/commands/keygen/create");
|
|
9
|
-
vi.mock("../../src/commands/keygen/unlock");
|
|
10
|
-
vi.mock("../../src/commands/keygen/lock");
|
|
11
|
-
|
|
12
|
-
describe("keygen create command", () => {
|
|
13
|
-
let program: Command;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
program = new Command();
|
|
17
|
-
initializeKeygenCommands(program);
|
|
18
|
-
vi.clearAllMocks();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
afterEach(() => {
|
|
22
|
-
vi.restoreAllMocks();
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test("keypairCreator.createKeypairAction is called with default options", async () => {
|
|
26
|
-
program.parse(["node", "test", "keygen", "create"]);
|
|
27
|
-
expect(KeypairCreator).toHaveBeenCalledTimes(1);
|
|
28
|
-
expect(KeypairCreator.prototype.createKeypairAction).toHaveBeenCalledWith({
|
|
29
|
-
output: "./keypair.json",
|
|
30
|
-
overwrite: false,
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
test("keypairCreator.createKeypairAction is called with custom output option", async () => {
|
|
35
|
-
program.parse(["node", "test", "keygen", "create", "--output", "./custom.json"]);
|
|
36
|
-
expect(KeypairCreator).toHaveBeenCalledTimes(1);
|
|
37
|
-
expect(KeypairCreator.prototype.createKeypairAction).toHaveBeenCalledWith({
|
|
38
|
-
output: "./custom.json",
|
|
39
|
-
overwrite: false,
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test("keypairCreator.createKeypairAction is called with overwrite enabled", async () => {
|
|
44
|
-
program.parse(["node", "test", "keygen", "create", "--overwrite"]);
|
|
45
|
-
expect(KeypairCreator).toHaveBeenCalledTimes(1);
|
|
46
|
-
expect(KeypairCreator.prototype.createKeypairAction).toHaveBeenCalledWith({
|
|
47
|
-
output: "./keypair.json",
|
|
48
|
-
overwrite: true,
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test("keypairCreator.createKeypairAction is called with custom output and overwrite enabled", async () => {
|
|
53
|
-
program.parse(["node", "test", "keygen", "create", "--output", "./custom.json", "--overwrite"]);
|
|
54
|
-
expect(KeypairCreator).toHaveBeenCalledTimes(1);
|
|
55
|
-
expect(KeypairCreator.prototype.createKeypairAction).toHaveBeenCalledWith({
|
|
56
|
-
output: "./custom.json",
|
|
57
|
-
overwrite: true,
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test("KeypairCreator is instantiated when the command is executed", async () => {
|
|
62
|
-
program.parse(["node", "test", "keygen", "create"]);
|
|
63
|
-
expect(KeypairCreator).toHaveBeenCalledTimes(1);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
test("keypairCreator.createKeypairAction is called without throwing errors for default options", async () => {
|
|
69
|
-
program.parse(["node", "test", "keygen", "create"]);
|
|
70
|
-
vi.mocked(KeypairCreator.prototype.createKeypairAction).mockReturnValue();
|
|
71
|
-
expect(() => program.parse(["node", "test", "keygen", "create"])).not.toThrow();
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
describe("keygen unlock command", () => {
|
|
76
|
-
let program: Command;
|
|
77
|
-
|
|
78
|
-
beforeEach(() => {
|
|
79
|
-
program = new Command();
|
|
80
|
-
initializeKeygenCommands(program);
|
|
81
|
-
vi.clearAllMocks();
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
afterEach(() => {
|
|
85
|
-
vi.restoreAllMocks();
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
test("UnlockAction is instantiated and execute is called", async () => {
|
|
89
|
-
program.parse(["node", "test", "keygen", "unlock"]);
|
|
90
|
-
expect(UnlockAction).toHaveBeenCalledTimes(1);
|
|
91
|
-
expect(UnlockAction.prototype.execute).toHaveBeenCalled();
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test("UnlockAction.execute is called without throwing errors", async () => {
|
|
95
|
-
vi.mocked(UnlockAction.prototype.execute).mockResolvedValue();
|
|
96
|
-
expect(() => program.parse(["node", "test", "keygen", "unlock"])).not.toThrow();
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe("keygen lock command", () => {
|
|
101
|
-
let program: Command;
|
|
102
|
-
|
|
103
|
-
beforeEach(() => {
|
|
104
|
-
program = new Command();
|
|
105
|
-
initializeKeygenCommands(program);
|
|
106
|
-
vi.clearAllMocks();
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
afterEach(() => {
|
|
110
|
-
vi.restoreAllMocks();
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
test("LockAction is instantiated and execute is called", async () => {
|
|
114
|
-
program.parse(["node", "test", "keygen", "lock"]);
|
|
115
|
-
expect(LockAction).toHaveBeenCalledTimes(1);
|
|
116
|
-
expect(LockAction.prototype.execute).toHaveBeenCalled();
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
test("LockAction.execute is called without throwing errors", async () => {
|
|
120
|
-
vi.mocked(LockAction.prototype.execute).mockResolvedValue();
|
|
121
|
-
expect(() => program.parse(["node", "test", "keygen", "lock"])).not.toThrow();
|
|
122
|
-
});
|
|
123
|
-
});
|