-
Notifications
You must be signed in to change notification settings - Fork 313
/
Copy pathdirect-function-args.test.ts
135 lines (112 loc) · 4.48 KB
/
direct-function-args.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// packages/cli/tests/direct-function-args.test.ts
import { testables } from '../src/cli';
import { CLINetworkAdapter, CLI_NETWORK_OPTS, getNetwork } from '../src/network';
import { CLI_CONFIG_TYPE } from '../src/argparse';
import { ClarityAbi } from '@stacks/transactions';
import { readFileSync } from 'fs';
import inquirer from 'inquirer';
import fetchMock from 'jest-fetch-mock';
import path from 'path';
import {
makeContractCall,
uintCV,
falseCV,
standardPrincipalCV,
PostConditionMode,
} from '@stacks/transactions';
import { STACKS_TESTNET } from '@stacks/network';
const { contractFunctionCall } = testables as any;
// Import the real ABI file that contains all the test functions
const TEST_ABI: ClarityAbi = JSON.parse(
readFileSync(path.join(__dirname, './abi/test-abi.json')).toString()
);
// jest.mock('inquirer');
fetchMock.enableMocks();
const testnetNetwork = new CLINetworkAdapter(
getNetwork({} as CLI_CONFIG_TYPE, true),
{} as CLI_NETWORK_OPTS
);
describe('Contract Function Call with Direct Arguments', () => {
beforeEach(() => {
fetchMock.resetMocks();
});
test('Should fall back to interactive prompts when no direct arguments provided', async () => {
const contractAddress = 'STB44HYPYAT2BB2QE513NSP81HTMYWBJP02HPGK6';
const contractName = 'test-contract-name';
const functionName = 'test-func-primitive-argument';
const fee = '230';
const nonce = '3';
const privateKey = 'cb3df38053d132895220b9ce471f6b676db5b9bf0b4adefb55f2118ece2478df01';
const args = [contractAddress, contractName, functionName, fee, nonce, privateKey];
const contractInputArg = {
amount: '1000',
address: 'STB44HYPYAT2BB2QE513NSP81HTMYWBJP02HPGK6',
exists: 'false',
};
// Mock the inquirer prompt to return our test values
// @ts-ignore
inquirer.prompt = jest.fn().mockResolvedValue(contractInputArg);
fetchMock.mockResponseOnce(JSON.stringify(TEST_ABI), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
fetchMock.mockResponseOnce(
JSON.stringify({
txid: '0x94b1cfab79555b8c6725f19e4fcd6268934d905578a3e8ef7a1e542b931d3676',
}),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
}
);
// Create the expected transaction that should match what contractFunctionCall builds
const functionArgs = [
uintCV(1000),
standardPrincipalCV('STB44HYPYAT2BB2QE513NSP81HTMYWBJP02HPGK6'),
falseCV(),
];
const expectedTx = await makeContractCall({
contractAddress,
contractName,
functionName,
functionArgs,
senderKey: privateKey,
fee: BigInt(fee),
nonce: BigInt(nonce),
network: STACKS_TESTNET,
postConditionMode: PostConditionMode.Allow,
});
const expectedTxHex = expectedTx.serialize();
await contractFunctionCall(testnetNetwork, args);
// Verify interactive prompts were used
expect(inquirer.prompt).toHaveBeenCalled();
// Verify fetch was called with the expected URLs
expect(fetchMock).toHaveBeenCalledTimes(2);
// First call should be to fetch the ABI
const abiCallUrl = fetchMock.mock.calls[0][0];
const abiCallUrlString = abiCallUrl instanceof Request ? abiCallUrl.url : String(abiCallUrl);
expect(abiCallUrlString).toContain('/v2/contracts/interface/');
expect(abiCallUrlString).toContain(contractAddress);
expect(abiCallUrlString).toContain(contractName);
// Second call should be to broadcast the transaction
const txCallUrl = fetchMock.mock.calls[1][0];
const txCallUrlString = txCallUrl instanceof Request ? txCallUrl.url : String(txCallUrl);
expect(txCallUrlString).toContain('/v2/transactions');
// Extract the transaction from the second fetch call
const broadcastRequest = fetchMock.mock.calls[1][1] as RequestInit;
// TypeScript safety: ensure body exists and convert to string if needed
const bodyString = broadcastRequest?.body
? typeof broadcastRequest.body === 'string'
? broadcastRequest.body
: String(broadcastRequest.body)
: '{}';
const requestBody = JSON.parse(bodyString);
const capturedTxHex = requestBody.tx;
// Validate the transaction
expect(capturedTxHex).toBeTruthy();
expect(typeof capturedTxHex).toBe('string');
expect(capturedTxHex.length).toBeGreaterThan(100); // Reasonable transaction length
// Compare the captured transaction hex with our expected transaction
expect(capturedTxHex).toEqual(expectedTxHex);
});
});