feat: add account change notifications
This commit is contained in:
@ -22,12 +22,17 @@ export const mockRpc: Array<[string, RpcRequest, RpcResponse]> = [];
|
||||
// identified by `url` instead of using the mock
|
||||
export const mockRpcEnabled = !process.env.DOITLIVE;
|
||||
|
||||
let mockNotice = true;
|
||||
|
||||
// Suppress lint: 'JestMockFn' is not defined
|
||||
// eslint-disable-next-line no-undef
|
||||
const mock: JestMockFn<any, any> = jest.fn(
|
||||
(fetchUrl, fetchOptions) => {
|
||||
if (!mockRpcEnabled) {
|
||||
console.log(`Note: node-fetch mock is disabled, testing live against ${fetchUrl}`);
|
||||
if (mockNotice) {
|
||||
console.log(`Note: node-fetch mock is disabled, testing live against ${fetchUrl}`);
|
||||
mockNotice = false;
|
||||
}
|
||||
return fetch(fetchUrl, fetchOptions);
|
||||
}
|
||||
|
||||
|
48
web3.js/test/__mocks__/rpc-websockets.js
Normal file
48
web3.js/test/__mocks__/rpc-websockets.js
Normal file
@ -0,0 +1,48 @@
|
||||
import {Client as RpcWebSocketClient} from 'rpc-websockets';
|
||||
|
||||
// Define DOITLIVE in the environment to test against the real full node
|
||||
// identified by `url` instead of using the mock
|
||||
export const mockRpcEnabled = !process.env.DOITLIVE;
|
||||
|
||||
let mockNotice = true;
|
||||
|
||||
export class Client {
|
||||
client: RpcWebSocketClient;
|
||||
|
||||
constructor(url, options) {
|
||||
//console.log('MockClient', url, options);
|
||||
if (!mockRpcEnabled) {
|
||||
if (mockNotice) {
|
||||
console.log('Note: rpc-websockets mock is disabled, testing live against', url);
|
||||
mockNotice = false;
|
||||
}
|
||||
this.client = new RpcWebSocketClient(url, options);
|
||||
}
|
||||
}
|
||||
|
||||
connect() {
|
||||
if (!mockRpcEnabled) {
|
||||
return this.client.connect();
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
if (!mockRpcEnabled) {
|
||||
return this.client.close();
|
||||
}
|
||||
}
|
||||
|
||||
on(event: string, callback: Function) {
|
||||
if (!mockRpcEnabled) {
|
||||
return this.client.on(event, callback);
|
||||
}
|
||||
//console.log('on', event);
|
||||
}
|
||||
|
||||
async call(method: string, params: Object): Promise<Object> {
|
||||
if (!mockRpcEnabled) {
|
||||
return await this.client.call(method, params);
|
||||
}
|
||||
throw new Error('call unsupported');
|
||||
}
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
// @flow
|
||||
|
||||
import {
|
||||
Account,
|
||||
Connection,
|
||||
BpfLoader,
|
||||
Loader,
|
||||
SystemProgram,
|
||||
sendAndConfirmTransaction,
|
||||
} from '../src';
|
||||
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
|
||||
import {mockGetLastId} from './mockrpc/getlastid';
|
||||
@ -410,3 +412,46 @@ test('multi-instruction transaction', async () => {
|
||||
expect(await connection.getBalance(accountTo.publicKey)).toBe(21);
|
||||
});
|
||||
|
||||
|
||||
test('account change notification', async () => {
|
||||
if (mockRpcEnabled) {
|
||||
console.log('non-live test skipped');
|
||||
return;
|
||||
}
|
||||
|
||||
const connection = new Connection(url);
|
||||
const owner = new Account();
|
||||
const programAccount = new Account();
|
||||
|
||||
const mockCallback = jest.fn();
|
||||
|
||||
const subscriptionId = connection.onAccountChange(programAccount.publicKey, mockCallback);
|
||||
|
||||
await connection.requestAirdrop(owner.publicKey, 42);
|
||||
const transaction = SystemProgram.createAccount(
|
||||
owner.publicKey,
|
||||
programAccount.publicKey,
|
||||
42,
|
||||
3,
|
||||
BpfLoader.programId,
|
||||
);
|
||||
await sendAndConfirmTransaction(connection, owner, transaction);
|
||||
|
||||
const loader = new Loader(connection, BpfLoader.programId);
|
||||
await loader.load(programAccount, [1, 2, 3]);
|
||||
|
||||
await connection.removeAccountChangeListener(subscriptionId);
|
||||
|
||||
// mockCallback should be called twice
|
||||
expect(mockCallback.mock.calls).toHaveLength(2);
|
||||
|
||||
// First mockCallback call is due to SystemProgram.createAccount()
|
||||
expect(mockCallback.mock.calls[0][0].tokens).toBe(42);
|
||||
expect(mockCallback.mock.calls[0][0].executable).toBe(false);
|
||||
expect(mockCallback.mock.calls[0][0].userdata).toEqual(Buffer.from([0, 0, 0]));
|
||||
expect(mockCallback.mock.calls[0][0].programId).toEqual(BpfLoader.programId);
|
||||
|
||||
// Second mockCallback call is due to loader.load()
|
||||
expect(mockCallback.mock.calls[1][0].userdata).toEqual(Buffer.from([1, 2, 3]));
|
||||
});
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
/**
|
||||
* The connection url to use when running unit tests against a live network
|
||||
*/
|
||||
export const url = 'http://localhost:8899';
|
||||
//export const url = 'http://testnet.solana.com:8899';
|
||||
//export const url = 'http://master.testnet.solana.com:8899';
|
||||
export const url = 'http://localhost:8899/';
|
||||
//export const url = 'http://testnet.solana.com:8899/';
|
||||
|
||||
|
Reference in New Issue
Block a user