genlayer 0.38.8 → 0.38.10
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/.eslintignore +2 -0
- package/.github/workflows/cli-docs.yml +124 -0
- package/.github/workflows/publish.yml +55 -0
- package/.github/workflows/smoke.yml +27 -0
- package/.github/workflows/validate-code.yml +51 -0
- package/.prettierignore +19 -0
- package/.prettierrc +12 -0
- package/.release-it.json +66 -0
- package/CHANGELOG.md +545 -0
- package/CLAUDE.md +55 -0
- package/CONTRIBUTING.md +117 -0
- package/dist/index.js +221 -62
- package/docs/api-references/_meta.json +9 -0
- package/docs/api-references/accounts/_meta.json +3 -0
- package/docs/api-references/accounts/account/create.mdx +19 -0
- package/docs/api-references/accounts/account/export.mdx +19 -0
- package/docs/api-references/accounts/account/import.mdx +22 -0
- package/docs/api-references/accounts/account/list.mdx +15 -0
- package/docs/api-references/accounts/account/lock.mdx +16 -0
- package/docs/api-references/accounts/account/remove.mdx +20 -0
- package/docs/api-references/accounts/account/send.mdx +24 -0
- package/docs/api-references/accounts/account/show.mdx +17 -0
- package/docs/api-references/accounts/account/unlock.mdx +17 -0
- package/docs/api-references/accounts/account/use.mdx +19 -0
- package/docs/api-references/accounts/account.mdx +32 -0
- package/docs/api-references/configuration/_meta.json +4 -0
- package/docs/api-references/configuration/config/get.mdx +21 -0
- package/docs/api-references/configuration/config/reset.mdx +21 -0
- package/docs/api-references/configuration/config/set.mdx +21 -0
- package/docs/api-references/configuration/config.mdx +25 -0
- package/docs/api-references/configuration/network/info.mdx +15 -0
- package/docs/api-references/configuration/network/list.mdx +15 -0
- package/docs/api-references/configuration/network/set.mdx +21 -0
- package/docs/api-references/configuration/network.mdx +25 -0
- package/docs/api-references/contracts/_meta.json +7 -0
- package/docs/api-references/contracts/call.mdx +21 -0
- package/docs/api-references/contracts/code.mdx +20 -0
- package/docs/api-references/contracts/deploy.mdx +17 -0
- package/docs/api-references/contracts/schema.mdx +20 -0
- package/docs/api-references/contracts/write.mdx +21 -0
- package/docs/api-references/environment/_meta.json +7 -0
- package/docs/api-references/environment/init.mdx +20 -0
- package/docs/api-references/environment/new.mdx +21 -0
- package/docs/api-references/environment/stop.mdx +15 -0
- package/docs/api-references/environment/up.mdx +20 -0
- package/docs/api-references/environment/update/ollama.mdx +16 -0
- package/docs/api-references/environment/update.mdx +23 -0
- package/docs/api-references/index.mdx +35 -0
- package/docs/api-references/localnet/_meta.json +3 -0
- package/docs/api-references/localnet/localnet/validators/count.mdx +15 -0
- package/docs/api-references/localnet/localnet/validators/create-random.mdx +16 -0
- package/docs/api-references/localnet/localnet/validators/create.mdx +19 -0
- package/docs/api-references/localnet/localnet/validators/delete.mdx +16 -0
- package/docs/api-references/localnet/localnet/validators/get.mdx +16 -0
- package/docs/api-references/localnet/localnet/validators/update.mdx +23 -0
- package/docs/api-references/localnet/localnet/validators.mdx +28 -0
- package/docs/api-references/localnet/localnet.mdx +23 -0
- package/docs/api-references/staking/_meta.json +3 -0
- package/docs/api-references/staking/staking/active-validators.mdx +18 -0
- package/docs/api-references/staking/staking/banned-validators.mdx +18 -0
- package/docs/api-references/staking/staking/delegation-info.mdx +25 -0
- package/docs/api-references/staking/staking/delegator-claim.mdx +26 -0
- package/docs/api-references/staking/staking/delegator-exit.mdx +26 -0
- package/docs/api-references/staking/staking/delegator-join.mdx +26 -0
- package/docs/api-references/staking/staking/epoch-info.mdx +19 -0
- package/docs/api-references/staking/staking/prime-all.mdx +20 -0
- package/docs/api-references/staking/staking/quarantined-validators.mdx +18 -0
- package/docs/api-references/staking/staking/set-identity.mdx +33 -0
- package/docs/api-references/staking/staking/set-operator.mdx +26 -0
- package/docs/api-references/staking/staking/validator-claim.mdx +24 -0
- package/docs/api-references/staking/staking/validator-deposit.mdx +25 -0
- package/docs/api-references/staking/staking/validator-exit.mdx +25 -0
- package/docs/api-references/staking/staking/validator-history.mdx +29 -0
- package/docs/api-references/staking/staking/validator-info.mdx +25 -0
- package/docs/api-references/staking/staking/validator-join.mdx +22 -0
- package/docs/api-references/staking/staking/validator-prime.mdx +25 -0
- package/docs/api-references/staking/staking/validators.mdx +19 -0
- package/docs/api-references/staking/staking/wizard.mdx +20 -0
- package/docs/api-references/staking/staking.mdx +42 -0
- package/docs/api-references/transactions/_meta.json +6 -0
- package/docs/api-references/transactions/appeal-bond.mdx +20 -0
- package/docs/api-references/transactions/appeal.mdx +21 -0
- package/docs/api-references/transactions/receipt.mdx +25 -0
- package/docs/api-references/transactions/trace.mdx +21 -0
- package/docs/delegator-guide.md +203 -0
- package/docs/validator-guide.md +329 -0
- package/esbuild.config.dev.js +17 -0
- package/esbuild.config.js +22 -0
- package/esbuild.config.prod.js +17 -0
- package/eslint.config.js +60 -0
- package/package.json +2 -11
- package/renovate.json +22 -0
- package/scripts/generate-cli-docs.mjs +68 -5
- package/src/commands/account/create.ts +30 -0
- package/src/commands/account/export.ts +106 -0
- package/src/commands/account/import.ts +135 -0
- package/src/commands/account/index.ts +129 -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 +162 -0
- package/src/commands/account/show.ts +74 -0
- package/src/commands/account/unlock.ts +56 -0
- package/src/commands/account/use.ts +21 -0
- package/src/commands/config/getSetReset.ts +51 -0
- package/src/commands/config/index.ts +30 -0
- package/src/commands/contracts/call.ts +39 -0
- package/src/commands/contracts/code.ts +33 -0
- package/src/commands/contracts/deploy.ts +161 -0
- package/src/commands/contracts/index.ts +150 -0
- package/src/commands/contracts/schema.ts +31 -0
- package/src/commands/contracts/write.ts +49 -0
- package/src/commands/general/index.ts +45 -0
- package/src/commands/general/init.ts +180 -0
- package/src/commands/general/start.ts +128 -0
- package/src/commands/general/stop.ts +26 -0
- package/src/commands/localnet/index.ts +100 -0
- package/src/commands/localnet/validators.ts +269 -0
- package/src/commands/network/index.ts +29 -0
- package/src/commands/network/setNetwork.ts +77 -0
- package/src/commands/scaffold/index.ts +16 -0
- package/src/commands/scaffold/new.ts +34 -0
- package/src/commands/staking/StakingAction.ts +279 -0
- package/src/commands/staking/delegatorClaim.ts +41 -0
- package/src/commands/staking/delegatorExit.ts +56 -0
- package/src/commands/staking/delegatorJoin.ts +44 -0
- package/src/commands/staking/index.ts +357 -0
- package/src/commands/staking/setIdentity.ts +78 -0
- package/src/commands/staking/setOperator.ts +46 -0
- package/src/commands/staking/stakingInfo.ts +584 -0
- package/src/commands/staking/validatorClaim.ts +43 -0
- package/src/commands/staking/validatorDeposit.ts +48 -0
- package/src/commands/staking/validatorExit.ts +63 -0
- package/src/commands/staking/validatorHistory.ts +300 -0
- package/src/commands/staking/validatorJoin.ts +47 -0
- package/src/commands/staking/validatorPrime.ts +73 -0
- package/src/commands/staking/wizard.ts +809 -0
- package/src/commands/transactions/appeal.ts +83 -0
- package/src/commands/transactions/index.ts +60 -0
- package/src/commands/transactions/receipt.ts +90 -0
- package/src/commands/transactions/trace.ts +42 -0
- package/src/commands/update/index.ts +25 -0
- package/src/commands/update/ollama.ts +103 -0
- package/src/lib/actions/BaseAction.ts +301 -0
- package/src/lib/clients/jsonRpcClient.ts +41 -0
- package/src/lib/clients/system.ts +73 -0
- package/src/lib/config/ConfigFileManager.ts +194 -0
- package/src/lib/config/KeychainManager.ts +89 -0
- package/src/lib/config/simulator.ts +68 -0
- package/src/lib/config/text.ts +2 -0
- package/src/lib/errors/missingRequirement.ts +9 -0
- package/src/lib/errors/versionRequired.ts +9 -0
- package/src/lib/interfaces/ISimulatorService.ts +39 -0
- package/src/lib/services/simulator.ts +386 -0
- package/src/types/node-fetch.d.ts +1 -0
- package/tests/actions/appeal.test.ts +141 -0
- package/tests/actions/call.test.ts +94 -0
- package/tests/actions/code.test.ts +87 -0
- package/tests/actions/create.test.ts +65 -0
- package/tests/actions/deploy.test.ts +420 -0
- package/tests/actions/getSetReset.test.ts +88 -0
- package/tests/actions/init.test.ts +483 -0
- package/tests/actions/lock.test.ts +86 -0
- package/tests/actions/new.test.ts +80 -0
- package/tests/actions/ollama.test.ts +193 -0
- package/tests/actions/receipt.test.ts +261 -0
- package/tests/actions/schema.test.ts +94 -0
- package/tests/actions/setNetwork.test.ts +161 -0
- package/tests/actions/staking.test.ts +280 -0
- package/tests/actions/start.test.ts +257 -0
- package/tests/actions/stop.test.ts +77 -0
- package/tests/actions/unlock.test.ts +139 -0
- package/tests/actions/validators.test.ts +750 -0
- package/tests/actions/write.test.ts +102 -0
- package/tests/commands/account.test.ts +146 -0
- package/tests/commands/appeal.test.ts +97 -0
- package/tests/commands/call.test.ts +78 -0
- package/tests/commands/code.test.ts +69 -0
- package/tests/commands/config.test.ts +54 -0
- package/tests/commands/deploy.test.ts +83 -0
- package/tests/commands/init.test.ts +101 -0
- package/tests/commands/localnet.test.ts +131 -0
- package/tests/commands/network.test.ts +60 -0
- package/tests/commands/new.test.ts +68 -0
- package/tests/commands/parseArg.test.ts +156 -0
- package/tests/commands/receipt.test.ts +142 -0
- package/tests/commands/schema.test.ts +67 -0
- package/tests/commands/staking.test.ts +329 -0
- package/tests/commands/stop.test.ts +27 -0
- package/tests/commands/up.test.ts +105 -0
- package/tests/commands/update.test.ts +45 -0
- package/tests/commands/write.test.ts +76 -0
- package/tests/index.test.ts +56 -0
- package/tests/libs/baseAction.test.ts +535 -0
- package/tests/libs/configFileManager.test.ts +118 -0
- package/tests/libs/jsonRpcClient.test.ts +59 -0
- package/tests/libs/keychainManager.test.ts +156 -0
- package/tests/libs/platformCommands.test.ts +78 -0
- package/tests/libs/system.test.ts +148 -0
- package/tests/services/simulator.test.ts +789 -0
- package/tests/smoke.test.ts +134 -0
- package/tests/utils.ts +13 -0
- package/tsconfig.json +120 -0
- package/vitest.config.ts +13 -0
- package/vitest.smoke.config.ts +17 -0
|
@@ -0,0 +1,750 @@
|
|
|
1
|
+
import { describe, test, vi, beforeEach, afterEach, expect } from "vitest";
|
|
2
|
+
import { ValidatorsAction } from "../../src/commands/localnet/validators";
|
|
3
|
+
import { rpcClient } from "../../src/lib/clients/jsonRpcClient";
|
|
4
|
+
import inquirer from "inquirer";
|
|
5
|
+
|
|
6
|
+
vi.mock("../../src/lib/clients/jsonRpcClient", () => ({
|
|
7
|
+
rpcClient: {
|
|
8
|
+
request: vi.fn(),
|
|
9
|
+
},
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
vi.mock("inquirer");
|
|
13
|
+
|
|
14
|
+
describe("ValidatorsAction", () => {
|
|
15
|
+
let validatorsAction: ValidatorsAction;
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
vi.clearAllMocks();
|
|
19
|
+
validatorsAction = new ValidatorsAction();
|
|
20
|
+
|
|
21
|
+
vi.spyOn(validatorsAction as any, "logSuccess").mockImplementation(() => {});
|
|
22
|
+
vi.spyOn(validatorsAction as any, "logError").mockImplementation(() => {});
|
|
23
|
+
vi.spyOn(validatorsAction as any, "startSpinner").mockImplementation(() => {});
|
|
24
|
+
vi.spyOn(validatorsAction as any, "succeedSpinner").mockImplementation(() => {});
|
|
25
|
+
vi.spyOn(validatorsAction as any, "failSpinner").mockImplementation(() => {});
|
|
26
|
+
vi.spyOn(validatorsAction as any, "log").mockImplementation(() => {});
|
|
27
|
+
vi.spyOn(validatorsAction as any, "stopSpinner").mockImplementation(() => {});
|
|
28
|
+
vi.spyOn(validatorsAction as any, "setSpinnerText").mockImplementation(() => {});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
vi.restoreAllMocks();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("getValidator", () => {
|
|
36
|
+
test("should fetch a specific validator by address", async () => {
|
|
37
|
+
const mockAddress = "mocked_address";
|
|
38
|
+
const mockResponse = { result: { id: 1, name: "Validator1" } };
|
|
39
|
+
vi.mocked(rpcClient.request).mockResolvedValue(mockResponse);
|
|
40
|
+
|
|
41
|
+
await validatorsAction.getValidator({ address: mockAddress });
|
|
42
|
+
|
|
43
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith(
|
|
44
|
+
`Fetching validator with address: ${mockAddress}`
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
48
|
+
method: "sim_getValidator",
|
|
49
|
+
params: [mockAddress],
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith(
|
|
53
|
+
`Successfully fetched validator with address: ${mockAddress}`,
|
|
54
|
+
mockResponse.result
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("should fetch all validators when no address is provided", async () => {
|
|
61
|
+
const mockResponse = { result: [{ id: 1 }, { id: 2 }] };
|
|
62
|
+
vi.mocked(rpcClient.request).mockResolvedValue(mockResponse);
|
|
63
|
+
|
|
64
|
+
await validatorsAction.getValidator({});
|
|
65
|
+
|
|
66
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Fetching all validators...");
|
|
67
|
+
|
|
68
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
69
|
+
method: "sim_getAllValidators",
|
|
70
|
+
params: [],
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith(
|
|
74
|
+
"Successfully fetched all validators.",
|
|
75
|
+
mockResponse.result
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("should log an error if an exception occurs while fetching a specific validator", async () => {
|
|
82
|
+
const mockAddress = "mocked_address";
|
|
83
|
+
const mockError = new Error("Unexpected error");
|
|
84
|
+
|
|
85
|
+
vi.mocked(rpcClient.request).mockRejectedValue(mockError);
|
|
86
|
+
|
|
87
|
+
await validatorsAction.getValidator({ address: mockAddress });
|
|
88
|
+
|
|
89
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith(
|
|
90
|
+
`Fetching validator with address: ${mockAddress}`
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
94
|
+
method: "sim_getValidator",
|
|
95
|
+
params: [mockAddress],
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
expect(validatorsAction["failSpinner"]).toHaveBeenCalledWith("Error fetching validators", mockError);
|
|
99
|
+
expect(validatorsAction["succeedSpinner"]).not.toHaveBeenCalled();
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("should log an error if an exception occurs while fetching all validators", async () => {
|
|
103
|
+
const mockError = new Error("Unexpected error");
|
|
104
|
+
|
|
105
|
+
vi.mocked(rpcClient.request).mockRejectedValue(mockError);
|
|
106
|
+
|
|
107
|
+
await validatorsAction.getValidator({});
|
|
108
|
+
|
|
109
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Fetching all validators...");
|
|
110
|
+
|
|
111
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
112
|
+
method: "sim_getAllValidators",
|
|
113
|
+
params: [],
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
expect(validatorsAction["failSpinner"]).toHaveBeenCalledWith("Error fetching validators", mockError);
|
|
117
|
+
expect(validatorsAction["succeedSpinner"]).not.toHaveBeenCalled();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe("deleteValidator", () => {
|
|
122
|
+
test("should delete a specific validator", async () => {
|
|
123
|
+
const mockAddress = "0x725a9D2D572E8833059a3e9a844791aF185C5Ff4";
|
|
124
|
+
vi.mocked(inquirer.prompt).mockResolvedValue({ confirmAction: true });
|
|
125
|
+
vi.mocked(rpcClient.request).mockResolvedValue({ result: mockAddress });
|
|
126
|
+
|
|
127
|
+
await validatorsAction.deleteValidator({ address: mockAddress });
|
|
128
|
+
|
|
129
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith(
|
|
130
|
+
`Deleting validator with address: ${mockAddress}`
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
134
|
+
method: "sim_deleteValidator",
|
|
135
|
+
params: [mockAddress],
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith(
|
|
139
|
+
`Deleted Address: ${mockAddress}`
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test("should delete all validators when no address is provided", async () => {
|
|
146
|
+
vi.mocked(inquirer.prompt).mockResolvedValue({ confirmAction: true });
|
|
147
|
+
vi.mocked(rpcClient.request).mockResolvedValue({});
|
|
148
|
+
|
|
149
|
+
await validatorsAction.deleteValidator({});
|
|
150
|
+
|
|
151
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith(
|
|
152
|
+
"Deleting all validators..."
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
156
|
+
method: "sim_deleteAllValidators",
|
|
157
|
+
params: [],
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith(
|
|
161
|
+
"Successfully deleted all validators"
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("should abort deletion if user declines confirmation", async () => {
|
|
168
|
+
vi.mocked(inquirer.prompt).mockResolvedValue({ confirmAction: false });
|
|
169
|
+
|
|
170
|
+
await validatorsAction.deleteValidator({ address: "mocked_address" });
|
|
171
|
+
|
|
172
|
+
expect(inquirer.prompt).toHaveBeenCalled();
|
|
173
|
+
expect(validatorsAction["logError"]).toHaveBeenCalledWith("Operation aborted!");
|
|
174
|
+
expect(rpcClient.request).not.toHaveBeenCalled();
|
|
175
|
+
expect(validatorsAction["startSpinner"]).not.toHaveBeenCalled();
|
|
176
|
+
expect(validatorsAction["succeedSpinner"]).not.toHaveBeenCalled();
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe("countValidators", () => {
|
|
182
|
+
test("should count all validators", async () => {
|
|
183
|
+
const mockResponse = { result: 42 };
|
|
184
|
+
vi.mocked(rpcClient.request).mockResolvedValue(mockResponse);
|
|
185
|
+
|
|
186
|
+
await validatorsAction.countValidators();
|
|
187
|
+
|
|
188
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Counting all validators...");
|
|
189
|
+
|
|
190
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
191
|
+
method: "sim_countValidators",
|
|
192
|
+
params: [],
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith("Total Validators: 42");
|
|
196
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("should log an error if an exception occurs while counting validators", async () => {
|
|
200
|
+
const mockError = new Error("Unexpected error");
|
|
201
|
+
|
|
202
|
+
vi.mocked(rpcClient.request).mockRejectedValue(mockError);
|
|
203
|
+
|
|
204
|
+
await validatorsAction.countValidators();
|
|
205
|
+
|
|
206
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Counting all validators...");
|
|
207
|
+
|
|
208
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
209
|
+
method: "sim_countValidators",
|
|
210
|
+
params: [],
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
expect(validatorsAction["failSpinner"]).toHaveBeenCalledWith("Error counting validators", mockError);
|
|
214
|
+
expect(validatorsAction["succeedSpinner"]).not.toHaveBeenCalled();
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
describe("createValidator", () => {
|
|
220
|
+
test("should create a validator with selected provider and model", async () => {
|
|
221
|
+
const mockProvidersAndModels = [
|
|
222
|
+
{
|
|
223
|
+
provider: "Provider1",
|
|
224
|
+
is_available: true,
|
|
225
|
+
is_model_available: true,
|
|
226
|
+
model: "Model1",
|
|
227
|
+
config: { max_tokens: 500 },
|
|
228
|
+
plugin: "Plugin1",
|
|
229
|
+
plugin_config: { api_key_env_var: "KEY1" },
|
|
230
|
+
},
|
|
231
|
+
];
|
|
232
|
+
const mockResponse = { result: { id: 123 } };
|
|
233
|
+
|
|
234
|
+
vi.mocked(rpcClient.request)
|
|
235
|
+
.mockResolvedValueOnce({ result: mockProvidersAndModels })
|
|
236
|
+
.mockResolvedValueOnce(mockResponse);
|
|
237
|
+
|
|
238
|
+
vi.mocked(inquirer.prompt)
|
|
239
|
+
.mockResolvedValueOnce({ selectedProvider: "Provider1" })
|
|
240
|
+
.mockResolvedValueOnce({ selectedModel: "Model1" });
|
|
241
|
+
|
|
242
|
+
await validatorsAction.createValidator({ stake: "10" });
|
|
243
|
+
|
|
244
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Fetching available providers and models...");
|
|
245
|
+
|
|
246
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
247
|
+
method: "sim_getProvidersAndModels",
|
|
248
|
+
params: [],
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
expect(validatorsAction["stopSpinner"]).toHaveBeenCalled();
|
|
252
|
+
|
|
253
|
+
expect(inquirer.prompt).toHaveBeenCalledWith([
|
|
254
|
+
{
|
|
255
|
+
type: "list",
|
|
256
|
+
name: "selectedProvider",
|
|
257
|
+
message: "Select a provider:",
|
|
258
|
+
choices: ["Provider1"],
|
|
259
|
+
},
|
|
260
|
+
]);
|
|
261
|
+
|
|
262
|
+
expect(inquirer.prompt).toHaveBeenCalledWith([
|
|
263
|
+
{
|
|
264
|
+
type: "list",
|
|
265
|
+
name: "selectedModel",
|
|
266
|
+
message: "Select a model:",
|
|
267
|
+
choices: ["Model1"],
|
|
268
|
+
},
|
|
269
|
+
]);
|
|
270
|
+
|
|
271
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Creating validator...");
|
|
272
|
+
|
|
273
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
274
|
+
method: "sim_createValidator",
|
|
275
|
+
params: [
|
|
276
|
+
10,
|
|
277
|
+
"Provider1",
|
|
278
|
+
"Model1",
|
|
279
|
+
{ max_tokens: 500 },
|
|
280
|
+
"Plugin1",
|
|
281
|
+
{ api_key_env_var: "KEY1" },
|
|
282
|
+
],
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith(
|
|
286
|
+
"Validator successfully created:",
|
|
287
|
+
mockResponse.result
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
test("should log an error for invalid stake", async () => {
|
|
294
|
+
|
|
295
|
+
await validatorsAction.createValidator({ stake: "invalid" });
|
|
296
|
+
|
|
297
|
+
expect(validatorsAction["logError"]).toHaveBeenCalledWith(
|
|
298
|
+
"Invalid stake. Please provide a positive integer."
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
expect(rpcClient.request).not.toHaveBeenCalled();
|
|
302
|
+
expect(validatorsAction["startSpinner"]).not.toHaveBeenCalled();
|
|
303
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
test("should log an error if no providers or models are available", async () => {
|
|
307
|
+
vi.mocked(rpcClient.request).mockResolvedValueOnce({ result: [] });
|
|
308
|
+
|
|
309
|
+
await validatorsAction.createValidator({ stake: "10" });
|
|
310
|
+
|
|
311
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Fetching available providers and models...");
|
|
312
|
+
|
|
313
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
314
|
+
method: "sim_getProvidersAndModels",
|
|
315
|
+
params: [],
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
expect(validatorsAction["stopSpinner"]).toHaveBeenCalled();
|
|
319
|
+
|
|
320
|
+
expect(validatorsAction["logError"]).toHaveBeenCalledWith("No providers or models available.");
|
|
321
|
+
|
|
322
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
323
|
+
expect(validatorsAction["succeedSpinner"]).not.toHaveBeenCalled();
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
test("should log an error if no models are available for the selected provider", async () => {
|
|
327
|
+
const mockProvidersAndModels = [
|
|
328
|
+
{ provider: "Provider1", is_available: true, is_model_available: false },
|
|
329
|
+
];
|
|
330
|
+
|
|
331
|
+
vi.mocked(rpcClient.request).mockResolvedValueOnce({ result: mockProvidersAndModels });
|
|
332
|
+
vi.mocked(inquirer.prompt).mockResolvedValueOnce({ selectedProvider: "Provider1" });
|
|
333
|
+
|
|
334
|
+
await validatorsAction.createValidator({ stake: "10" });
|
|
335
|
+
|
|
336
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Fetching available providers and models...");
|
|
337
|
+
|
|
338
|
+
expect(validatorsAction["stopSpinner"]).toHaveBeenCalled();
|
|
339
|
+
|
|
340
|
+
expect(inquirer.prompt).toHaveBeenCalledWith([
|
|
341
|
+
{
|
|
342
|
+
type: "list",
|
|
343
|
+
name: "selectedProvider",
|
|
344
|
+
message: "Select a provider:",
|
|
345
|
+
choices: ["Provider1"],
|
|
346
|
+
},
|
|
347
|
+
]);
|
|
348
|
+
|
|
349
|
+
expect(validatorsAction["logError"]).toHaveBeenCalledWith("No models available for the selected provider.");
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
test("should log an error if selected model details are not found", async () => {
|
|
353
|
+
const mockProvidersAndModels = [
|
|
354
|
+
{
|
|
355
|
+
provider: "Provider1",
|
|
356
|
+
is_available: true,
|
|
357
|
+
is_model_available: true,
|
|
358
|
+
model: "Model1",
|
|
359
|
+
},
|
|
360
|
+
];
|
|
361
|
+
|
|
362
|
+
vi.mocked(rpcClient.request).mockResolvedValueOnce({ result: mockProvidersAndModels });
|
|
363
|
+
vi.mocked(inquirer.prompt)
|
|
364
|
+
.mockResolvedValueOnce({ selectedProvider: "Provider1" })
|
|
365
|
+
.mockResolvedValueOnce({ selectedModel: "NonExistentModel" });
|
|
366
|
+
|
|
367
|
+
await validatorsAction.createValidator({ stake: "10" });
|
|
368
|
+
|
|
369
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Fetching available providers and models...");
|
|
370
|
+
|
|
371
|
+
expect(validatorsAction["stopSpinner"]).toHaveBeenCalled();
|
|
372
|
+
|
|
373
|
+
expect(inquirer.prompt).toHaveBeenCalledWith([
|
|
374
|
+
{
|
|
375
|
+
type: "list",
|
|
376
|
+
name: "selectedProvider",
|
|
377
|
+
message: "Select a provider:",
|
|
378
|
+
choices: ["Provider1"],
|
|
379
|
+
},
|
|
380
|
+
]);
|
|
381
|
+
|
|
382
|
+
expect(inquirer.prompt).toHaveBeenCalledWith([
|
|
383
|
+
{
|
|
384
|
+
type: "list",
|
|
385
|
+
name: "selectedModel",
|
|
386
|
+
message: "Select a model:",
|
|
387
|
+
choices: ["Model1"],
|
|
388
|
+
},
|
|
389
|
+
]);
|
|
390
|
+
|
|
391
|
+
expect(validatorsAction["logError"]).toHaveBeenCalledWith("Selected model details not found.");
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
test("should log an error if an exception occurs during the process", async () => {
|
|
395
|
+
const mockError = new Error("Unexpected error");
|
|
396
|
+
vi.mocked(rpcClient.request).mockRejectedValue(mockError);
|
|
397
|
+
|
|
398
|
+
await validatorsAction.createValidator({ stake: "10" });
|
|
399
|
+
|
|
400
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Fetching available providers and models...");
|
|
401
|
+
|
|
402
|
+
expect(validatorsAction["failSpinner"]).toHaveBeenCalledWith("Error creating validator", mockError);
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
test("should use user-provided config if specified", async () => {
|
|
406
|
+
const mockProvidersAndModels = [
|
|
407
|
+
{
|
|
408
|
+
provider: "Provider1",
|
|
409
|
+
is_available: true,
|
|
410
|
+
is_model_available: true,
|
|
411
|
+
model: "Model1",
|
|
412
|
+
config: { max_tokens: 500 },
|
|
413
|
+
plugin: "Plugin1",
|
|
414
|
+
plugin_config: { api_key_env_var: "KEY1" },
|
|
415
|
+
},
|
|
416
|
+
];
|
|
417
|
+
const mockResponse = { result: { id: 123 } };
|
|
418
|
+
|
|
419
|
+
vi.mocked(rpcClient.request)
|
|
420
|
+
.mockResolvedValueOnce({ result: mockProvidersAndModels })
|
|
421
|
+
.mockResolvedValueOnce(mockResponse);
|
|
422
|
+
|
|
423
|
+
vi.mocked(inquirer.prompt)
|
|
424
|
+
.mockResolvedValueOnce({ selectedProvider: "Provider1" })
|
|
425
|
+
.mockResolvedValueOnce({ selectedModel: "Model1" });
|
|
426
|
+
|
|
427
|
+
const customConfig = '{"custom_key":"custom_value"}';
|
|
428
|
+
await validatorsAction.createValidator({ stake: "10", config: customConfig });
|
|
429
|
+
|
|
430
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Fetching available providers and models...");
|
|
431
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
432
|
+
method: "sim_getProvidersAndModels",
|
|
433
|
+
params: [],
|
|
434
|
+
});
|
|
435
|
+
expect(validatorsAction["stopSpinner"]).toHaveBeenCalled();
|
|
436
|
+
expect(inquirer.prompt).toHaveBeenCalledWith([
|
|
437
|
+
{ type: "list", name: "selectedProvider", message: "Select a provider:", choices: ["Provider1"] },
|
|
438
|
+
]);
|
|
439
|
+
expect(inquirer.prompt).toHaveBeenCalledWith([
|
|
440
|
+
{ type: "list", name: "selectedModel", message: "Select a model:", choices: ["Model1"] },
|
|
441
|
+
]);
|
|
442
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Creating validator...");
|
|
443
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
444
|
+
method: "sim_createValidator",
|
|
445
|
+
params: [
|
|
446
|
+
10,
|
|
447
|
+
"Provider1",
|
|
448
|
+
"Model1",
|
|
449
|
+
{ custom_key: "custom_value" },
|
|
450
|
+
"Plugin1",
|
|
451
|
+
{ api_key_env_var: "KEY1" },
|
|
452
|
+
],
|
|
453
|
+
});
|
|
454
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith("Validator successfully created:", mockResponse.result);
|
|
455
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
test("should log an error if model is provided without provider", async () => {
|
|
459
|
+
vi.spyOn(validatorsAction as any, "logError").mockImplementation(() => {});
|
|
460
|
+
|
|
461
|
+
await validatorsAction.createValidator({ stake: "10", model: "Model1" });
|
|
462
|
+
|
|
463
|
+
expect(validatorsAction["logError"]).toHaveBeenCalledWith("You must specify a provider if using a model.");
|
|
464
|
+
expect(rpcClient.request).not.toHaveBeenCalled();
|
|
465
|
+
});
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
describe("createRandomValidators", () => {
|
|
469
|
+
test("should create random validators with valid count and providers", async () => {
|
|
470
|
+
const mockResponse = { result: { success: true } };
|
|
471
|
+
vi.mocked(rpcClient.request).mockResolvedValue(mockResponse);
|
|
472
|
+
|
|
473
|
+
await validatorsAction.createRandomValidators({ count: "5", providers: ["Provider1", "Provider2"], models: [] });
|
|
474
|
+
|
|
475
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Creating 5 random validator(s)...");
|
|
476
|
+
expect(validatorsAction["log"]).toHaveBeenCalledWith("Providers: Provider1, Provider2");
|
|
477
|
+
expect(validatorsAction["log"]).toHaveBeenCalledWith("Models: All");
|
|
478
|
+
|
|
479
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
480
|
+
method: "sim_createRandomValidators",
|
|
481
|
+
params: [5, 1, 10, ["Provider1", "Provider2"], []],
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith("Random validators successfully created", mockResponse.result);
|
|
485
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
test("should create random validators with valid count, providers and models", async () => {
|
|
489
|
+
const mockResponse = { result: { success: true } };
|
|
490
|
+
vi.mocked(rpcClient.request).mockResolvedValue(mockResponse);
|
|
491
|
+
|
|
492
|
+
await validatorsAction.createRandomValidators({ count: "10", providers: ["Provider3"], models: ["Model1", "Model2"] });
|
|
493
|
+
|
|
494
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Creating 10 random validator(s)...");
|
|
495
|
+
expect(validatorsAction["log"]).toHaveBeenCalledWith("Providers: Provider3");
|
|
496
|
+
expect(validatorsAction["log"]).toHaveBeenCalledWith("Models: Model1, Model2");
|
|
497
|
+
|
|
498
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
499
|
+
method: "sim_createRandomValidators",
|
|
500
|
+
params: [10, 1, 10, ["Provider3"], ["Model1", "Model2"]],
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith("Random validators successfully created", mockResponse.result);
|
|
504
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
test("should create random validators with default provider message when providers list is empty", async () => {
|
|
508
|
+
const mockResponse = { result: { success: true } };
|
|
509
|
+
vi.mocked(rpcClient.request).mockResolvedValue(mockResponse);
|
|
510
|
+
|
|
511
|
+
await validatorsAction.createRandomValidators({ count: "3", providers: [], models: [] });
|
|
512
|
+
|
|
513
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Creating 3 random validator(s)...");
|
|
514
|
+
expect(validatorsAction["log"]).toHaveBeenCalledWith("Providers: All");
|
|
515
|
+
expect(validatorsAction["log"]).toHaveBeenCalledWith("Models: All");
|
|
516
|
+
|
|
517
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
518
|
+
method: "sim_createRandomValidators",
|
|
519
|
+
params: [3, 1, 10, [], []],
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith("Random validators successfully created", mockResponse.result);
|
|
523
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
test("should throw an error for invalid count", async () => {
|
|
527
|
+
await validatorsAction.createRandomValidators({ count: "invalid", providers: ["Provider1"], models: [] });
|
|
528
|
+
|
|
529
|
+
expect(validatorsAction["logError"]).toHaveBeenCalledWith("Invalid count. Please provide a positive integer.");
|
|
530
|
+
expect(rpcClient.request).not.toHaveBeenCalled();
|
|
531
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
test("should log an error if rpc request fails", async () => {
|
|
535
|
+
const mockError = new Error("RPC failure");
|
|
536
|
+
vi.mocked(rpcClient.request).mockRejectedValue(mockError);
|
|
537
|
+
|
|
538
|
+
await validatorsAction.createRandomValidators({ count: "5", providers: ["Provider1"], models: [] });
|
|
539
|
+
|
|
540
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith("Creating 5 random validator(s)...");
|
|
541
|
+
|
|
542
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
543
|
+
method: "sim_createRandomValidators",
|
|
544
|
+
params: [5, 1, 10, ["Provider1"], []],
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
expect(validatorsAction["failSpinner"]).toHaveBeenCalledWith("Error creating random validators", mockError);
|
|
548
|
+
});
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
describe("updateValidator", () => {
|
|
552
|
+
test("should fetch and update a validator with new stake", async () => {
|
|
553
|
+
const mockAddress = "mocked_address";
|
|
554
|
+
const mockCurrentValidator = {
|
|
555
|
+
result: {
|
|
556
|
+
address: "mocked_address",
|
|
557
|
+
stake: 100,
|
|
558
|
+
provider: "Provider1",
|
|
559
|
+
model: "Model1",
|
|
560
|
+
config: { max_tokens: 500 },
|
|
561
|
+
},
|
|
562
|
+
};
|
|
563
|
+
const mockResponse = { result: { success: true } };
|
|
564
|
+
|
|
565
|
+
vi.mocked(rpcClient.request)
|
|
566
|
+
.mockResolvedValueOnce(mockCurrentValidator)
|
|
567
|
+
.mockResolvedValueOnce(mockResponse);
|
|
568
|
+
|
|
569
|
+
await validatorsAction.updateValidator({ address: mockAddress, stake: "200" });
|
|
570
|
+
|
|
571
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith(`Fetching validator with address: ${mockAddress}...`);
|
|
572
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
573
|
+
method: "sim_getValidator",
|
|
574
|
+
params: [mockAddress],
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
expect(validatorsAction["log"]).toHaveBeenCalledWith("Current Validator Details:", mockCurrentValidator.result);
|
|
578
|
+
expect(validatorsAction["setSpinnerText"]).toHaveBeenCalledWith("Updating Validator...");
|
|
579
|
+
|
|
580
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
581
|
+
method: "sim_updateValidator",
|
|
582
|
+
params: [
|
|
583
|
+
"mocked_address",
|
|
584
|
+
"200",
|
|
585
|
+
"Provider1",
|
|
586
|
+
"Model1",
|
|
587
|
+
{ max_tokens: 500 },
|
|
588
|
+
],
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith("Validator successfully updated", mockResponse.result);
|
|
592
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
test("should fetch and update a validator with new provider and model", async () => {
|
|
596
|
+
const mockAddress = "mocked_address";
|
|
597
|
+
const mockCurrentValidator = {
|
|
598
|
+
result: {
|
|
599
|
+
address: "mocked_address",
|
|
600
|
+
stake: "100",
|
|
601
|
+
provider: "Provider1",
|
|
602
|
+
model: "Model1",
|
|
603
|
+
config: { max_tokens: 500 },
|
|
604
|
+
},
|
|
605
|
+
};
|
|
606
|
+
const mockResponse = { result: { success: true } };
|
|
607
|
+
|
|
608
|
+
vi.mocked(rpcClient.request)
|
|
609
|
+
.mockResolvedValueOnce(mockCurrentValidator)
|
|
610
|
+
.mockResolvedValueOnce(mockResponse);
|
|
611
|
+
|
|
612
|
+
await validatorsAction.updateValidator({ address: mockAddress, provider: "Provider2", model: "Model2" });
|
|
613
|
+
|
|
614
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith(`Fetching validator with address: ${mockAddress}...`);
|
|
615
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
616
|
+
method: "sim_getValidator",
|
|
617
|
+
params: [mockAddress],
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
expect(validatorsAction["log"]).toHaveBeenCalledWith("Current Validator Details:", mockCurrentValidator.result);
|
|
621
|
+
expect(validatorsAction["setSpinnerText"]).toHaveBeenCalledWith("Updating Validator...");
|
|
622
|
+
|
|
623
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
624
|
+
method: "sim_updateValidator",
|
|
625
|
+
params: [
|
|
626
|
+
"mocked_address",
|
|
627
|
+
"100",
|
|
628
|
+
"Provider2",
|
|
629
|
+
"Model2",
|
|
630
|
+
{ max_tokens: 500 },
|
|
631
|
+
],
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith("Validator successfully updated", mockResponse.result);
|
|
635
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
test("should fetch and update a validator with new config", async () => {
|
|
639
|
+
const mockAddress = "mocked_address";
|
|
640
|
+
const mockCurrentValidator = {
|
|
641
|
+
result: {
|
|
642
|
+
address: "mocked_address",
|
|
643
|
+
stake: "100",
|
|
644
|
+
provider: "Provider1",
|
|
645
|
+
model: "Model1",
|
|
646
|
+
config: { max_tokens: 500 },
|
|
647
|
+
},
|
|
648
|
+
};
|
|
649
|
+
const mockResponse = { result: { success: true } };
|
|
650
|
+
|
|
651
|
+
vi.mocked(rpcClient.request)
|
|
652
|
+
.mockResolvedValueOnce(mockCurrentValidator)
|
|
653
|
+
.mockResolvedValueOnce(mockResponse);
|
|
654
|
+
|
|
655
|
+
const newConfig = '{"max_tokens":1000}';
|
|
656
|
+
await validatorsAction.updateValidator({ address: mockAddress, config: newConfig });
|
|
657
|
+
|
|
658
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith(`Fetching validator with address: ${mockAddress}...`);
|
|
659
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
660
|
+
method: "sim_getValidator",
|
|
661
|
+
params: [mockAddress],
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
expect(validatorsAction["log"]).toHaveBeenCalledWith("Current Validator Details:", mockCurrentValidator.result);
|
|
665
|
+
expect(validatorsAction["setSpinnerText"]).toHaveBeenCalledWith("Updating Validator...");
|
|
666
|
+
|
|
667
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
668
|
+
method: "sim_updateValidator",
|
|
669
|
+
params: [
|
|
670
|
+
"mocked_address",
|
|
671
|
+
"100",
|
|
672
|
+
"Provider1",
|
|
673
|
+
"Model1",
|
|
674
|
+
{ max_tokens: 1000 },
|
|
675
|
+
],
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
expect(validatorsAction["succeedSpinner"]).toHaveBeenCalledWith("Validator successfully updated", mockResponse.result);
|
|
679
|
+
expect(validatorsAction["failSpinner"]).not.toHaveBeenCalled();
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
test("should log an error if updateValidator RPC call fails", async () => {
|
|
683
|
+
const mockAddress = "mocked_address";
|
|
684
|
+
const mockCurrentValidator = {
|
|
685
|
+
result: {
|
|
686
|
+
address: "mocked_address",
|
|
687
|
+
stake: "100",
|
|
688
|
+
provider: "Provider1",
|
|
689
|
+
model: "Model1",
|
|
690
|
+
config: { max_tokens: 500 },
|
|
691
|
+
},
|
|
692
|
+
};
|
|
693
|
+
const mockError = new Error("RPC failure");
|
|
694
|
+
|
|
695
|
+
vi.mocked(rpcClient.request)
|
|
696
|
+
.mockResolvedValueOnce(mockCurrentValidator)
|
|
697
|
+
.mockRejectedValueOnce(mockError);
|
|
698
|
+
|
|
699
|
+
vi.spyOn(validatorsAction as any, "failSpinner").mockImplementation(() => {});
|
|
700
|
+
|
|
701
|
+
await validatorsAction.updateValidator({ address: mockAddress, stake: "200" });
|
|
702
|
+
|
|
703
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
704
|
+
method: "sim_getValidator",
|
|
705
|
+
params: [mockAddress],
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
709
|
+
method: "sim_updateValidator",
|
|
710
|
+
params: [
|
|
711
|
+
"mocked_address",
|
|
712
|
+
"200",
|
|
713
|
+
"Provider1",
|
|
714
|
+
"Model1",
|
|
715
|
+
{ max_tokens: 500 },
|
|
716
|
+
],
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
expect(validatorsAction["failSpinner"]).toHaveBeenCalledWith("Error updating validator", mockError);
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
test("should log an error for invalid stake value", async () => {
|
|
723
|
+
const mockAddress = "mocked_address";
|
|
724
|
+
const mockCurrentValidator = {
|
|
725
|
+
result: {
|
|
726
|
+
address: "mocked_address",
|
|
727
|
+
stake: 100,
|
|
728
|
+
provider: "Provider1",
|
|
729
|
+
model: "Model1",
|
|
730
|
+
config: { max_tokens: 500 },
|
|
731
|
+
},
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
vi.mocked(rpcClient.request).mockResolvedValue(mockCurrentValidator);
|
|
735
|
+
|
|
736
|
+
vi.spyOn(validatorsAction as any, "failSpinner").mockImplementation(() => {});
|
|
737
|
+
|
|
738
|
+
await validatorsAction.updateValidator({ address: mockAddress, stake: "-10" });
|
|
739
|
+
|
|
740
|
+
expect(validatorsAction["startSpinner"]).toHaveBeenCalledWith(`Fetching validator with address: ${mockAddress}...`);
|
|
741
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
742
|
+
method: "sim_getValidator",
|
|
743
|
+
params: [mockAddress],
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
expect(validatorsAction["failSpinner"]).toHaveBeenCalledWith("Invalid stake value. Stake must be a positive integer.");
|
|
747
|
+
expect(rpcClient.request).toHaveBeenCalledTimes(1);
|
|
748
|
+
});
|
|
749
|
+
});
|
|
750
|
+
});
|