Skip to content

Commit

Permalink
test: method test code
Browse files Browse the repository at this point in the history
  • Loading branch information
tfrg committed Jan 2, 2025
1 parent 368d704 commit a4c5959
Show file tree
Hide file tree
Showing 7 changed files with 454 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { GnoWalletProvider } from '../../../providers';
import { WalletResponseFailureType, WalletResponseSuccessType } from '../../types';
import { AddNetworkOptions } from '../../types/methods';
import { makeResponseMessage } from '../../utils';

describe('GnoWalletProvider.addNetwork', () => {
let provider: GnoWalletProvider;

beforeEach(() => {
provider = new GnoWalletProvider();
});

// Normal network addition case
it('should return ADD_NETWORK_SUCCESS response when adding network', async () => {
const options: AddNetworkOptions = {
chainId: 'test-chain',
chainName: 'Test Chain',
rpcUrl: 'https://test.network.com',
};

const addResponse = await provider.addNetwork(options);
expect(addResponse).toEqual(makeResponseMessage(WalletResponseSuccessType.ADD_NETWORK_SUCCESS));
});

// Validate if a required field is missing
it('should return INVALID_FORMAT when required fields are missing', async () => {
const testCases = [
{ chainName: 'Test Chain', rpcUrl: 'https://test.com' },
{ chainId: 'test-chain', rpcUrl: 'https://test.com' },
{ chainId: 'test-chain', chainName: 'Test Chain' },
];

for (const testCase of testCases) {
const response = await provider.addNetwork(testCase as unknown as AddNetworkOptions);
expect(response).toEqual(makeResponseMessage(WalletResponseFailureType.INVALID_FORMAT));
}
});

// Validating whitespace characters in RPC URL
it('should return INVALID_FORMAT when rpcUrl contains whitespace', async () => {
const options = {
chainId: 'test-chain',
chainName: 'Test Chain',
rpcUrl: 'https://test network.com', // Blank space in the rpcUrl
};
const response = await provider.addNetwork(options);

expect(response).toEqual(makeResponseMessage(WalletResponseFailureType.INVALID_FORMAT));
});

// Attempting to add a duplicate network case
it('should return duplicate error when adding network with same network', async () => {
const testNetworkOptions: AddNetworkOptions[] = [
{
chainId: 'test-chain',
chainName: 'Test Chain',
rpcUrl: 'https://test.network.com/', // With trailing slash
},
{
chainId: 'test-chain2',
chainName: 'Test Chain 2',
rpcUrl: 'https://test.network.com', // Without trailing slash
},
];

const response = await provider.addNetwork(testNetworkOptions[0]);
expect(response).toEqual(makeResponseMessage(WalletResponseSuccessType.ADD_NETWORK_SUCCESS));

const duplicateResponse = await provider.addNetwork(testNetworkOptions[1]);
expect(duplicateResponse).toEqual(makeResponseMessage(WalletResponseFailureType.NETWORK_ALREADY_EXISTS));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { GnoWalletProvider } from '../../../providers';
import { NetworkInfo } from '../../types';
import { JSONRPCProvider, Wallet as TM2Wallet } from '@gnolang/tm2-js-client';
import { GNO_ADDRESS_PREFIX } from '../../constants/chains.constant';

// Mock JSONRPCProvider to test without a real network connection
jest.mock('@gnolang/tm2-js-client', () => ({
...jest.requireActual('@gnolang/tm2-js-client'),
JSONRPCProvider: jest.fn(),
}));

describe('GnoWalletProvider.connectProvider', () => {
let provider: GnoWalletProvider;
let mockWallet: TM2Wallet;

const TEST_RPC_URL = 'https://testnet.gno.land';

const mockNetwork: NetworkInfo = {
chainId: 'test-chain-1',
networkName: 'Test Network 1',
rpcUrl: TEST_RPC_URL,
addressPrefix: GNO_ADDRESS_PREFIX,
indexerUrl: null,
};

beforeEach(() => {
jest.clearAllMocks();

mockWallet = {
connect: jest.fn(),
} as unknown as TM2Wallet;

provider = new GnoWalletProvider(mockWallet, [mockNetwork]);
provider['currentNetwork'] = mockNetwork;
});

// Test the normal Provider connection case
it('should connect provider with correct rpcUrl', async () => {
const result = provider['connectProvider']();

expect(JSONRPCProvider).toHaveBeenCalledWith(TEST_RPC_URL);
expect(mockWallet.connect).toHaveBeenCalled();
expect(result).toBe(true);
});

// Test the exception case where the wallet is not set up
it('should return false when wallet is not set', () => {
provider['wallet'] = null;
const result = provider['connectProvider']();
expect(result).toBe(false);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { GnoWalletProvider } from '../../../providers';
import { GNO_ADDRESS_PREFIX } from '../../constants/chains.constant';
import { NetworkInfo } from '../../types';
import { GnoWallet } from '@gnolang/gno-js-client';

describe('GnoWalletProvider.disconnectProvider', () => {
let provider: GnoWalletProvider;

const mockNetwork: NetworkInfo = {
chainId: 'test-chain-1',
networkName: 'Test Network 1',
rpcUrl: 'http://test1.com',
addressPrefix: GNO_ADDRESS_PREFIX,
indexerUrl: null,
};

beforeEach(() => {
provider = new GnoWalletProvider(undefined, [mockNetwork]);
provider['networkCallback'] = jest.fn();
provider['wallet'] = new GnoWallet();
});

// Verify that all properties of the provider are initialized correctly
it('should reset all provider properties', () => {
provider['disconnectProvider']();

expect(provider['networkCallback']).toBeNull();
expect(provider['networks']).toEqual([]);
expect(provider['currentNetwork']).toBeNull();
expect(provider['wallet']).toBeNull();
});

it('should return true after disconnection', () => {
const result = provider['disconnectProvider']();
expect(result).toBe(true);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { GnoWalletProvider } from '../../../providers';
import { GNO_ADDRESS_PREFIX } from '../../constants/chains.constant';
import { NetworkInfo, WalletResponseFailureType, WalletResponseSuccessType } from '../../types';
import { makeResponseMessage } from '../../utils';

describe('GnoWalletProvider.getNetwork', () => {
let provider: GnoWalletProvider;
const mockNetworks: NetworkInfo[] = [
{
chainId: 'test-chain-1',
networkName: 'Test Network 1',
rpcUrl: 'http://test1.com',
addressPrefix: GNO_ADDRESS_PREFIX,
indexerUrl: null,
},
{
chainId: 'test-chain-2',
networkName: 'Test Network 2',
rpcUrl: 'http://test2.com',
addressPrefix: GNO_ADDRESS_PREFIX,
indexerUrl: null,
},
];

beforeEach(() => {
provider = new GnoWalletProvider(undefined, mockNetworks);
});

afterEach(() => {
jest.clearAllMocks();
});

// Test for no wallet connection
it('should return NOT_CONNECTED when wallet is not connected', async () => {
const response = await provider.getNetwork();

expect(response).toEqual(makeResponseMessage(WalletResponseFailureType.NOT_CONNECTED));
});

// Test with wallet connected but network not initialized
it('should return NOT_INITIALIZED_NETWORK when network is not initialized', async () => {
(provider as unknown as { wallet: object }).wallet = {};

const response = await provider.getNetwork();

expect(response).toEqual(makeResponseMessage(WalletResponseFailureType.NOT_INITIALIZED_NETWORK));
});

// Steady state test with both wallet connection and network initialization complete
it('should return current network information when wallet is connected and network is initialized', async () => {
(provider as unknown as { wallet: object }).wallet = {};
(provider as unknown as { currentNetwork: NetworkInfo }).currentNetwork = mockNetworks[0];

const response = await provider.getNetwork();

expect(response).toEqual(makeResponseMessage(WalletResponseSuccessType.GET_NETWORK_SUCCESS, mockNetworks[0]));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { GnoWalletProvider } from '../../../providers';
import { GNO_ADDRESS_PREFIX } from '../../constants/chains.constant';
import { NetworkInfo } from '../../types';
import { OnChangeNetworkOptions } from '../../types/methods';

describe('GnoWalletProvider.onChange', () => {
let provider: GnoWalletProvider;
const mockNetworks: NetworkInfo[] = [
{
chainId: 'test-chain-1',
networkName: 'Test Network 1',
rpcUrl: 'http://test1.com',
addressPrefix: GNO_ADDRESS_PREFIX,
indexerUrl: null,
},
{
chainId: 'test-chain-2',
networkName: 'Test Network 2',
rpcUrl: 'http://test2.com',
addressPrefix: GNO_ADDRESS_PREFIX,
indexerUrl: null,
},
];

beforeEach(() => {
provider = new GnoWalletProvider(undefined, mockNetworks);
jest.spyOn(provider as unknown as { connectProvider(): boolean }, 'connectProvider').mockReturnValue(true);
jest.spyOn(provider as unknown as { setNetwork(network: NetworkInfo): void }, 'setNetwork');
});

afterEach(() => {
jest.clearAllMocks();
});

// Verify that the callbacks registered with onChangeNetwork are stored correctly inside the provider
it('should register network callback successfully', () => {
const mockCallback = jest.fn();
const options: OnChangeNetworkOptions = {
callback: mockCallback,
};

provider.onChangeNetwork(options);

const providerWithCallback = provider as unknown as { networkCallback: ((chainId: string) => void) | null };
expect(providerWithCallback.networkCallback).toBe(mockCallback);
});

// Ensure that only registered callbacks are executed and no other callbacks are executed
it('should fail when checking registered callback', () => {
const mockCallback = jest.fn();
const differentCallback = jest.fn();

provider.onChangeNetwork({ callback: mockCallback });

const providerWithCallback = provider as unknown as { networkCallback: ((chainId: string) => void) | null };
providerWithCallback.networkCallback?.('test-chain');

expect(mockCallback).toHaveBeenCalledTimes(1);
expect(differentCallback).not.toHaveBeenCalled();
});

// Ensure callbacks are fired with the correct chainId on network changes
it('should execute registered callback when network changes', () => {
const mockCallback = jest.fn();
const testChainId = 'test-chain-1';

provider.onChangeNetwork({ callback: mockCallback });

const providerWithCallback = provider as unknown as { networkCallback: ((chainId: string) => void) | null };
const registeredCallback = providerWithCallback.networkCallback;

registeredCallback?.(testChainId);

expect(mockCallback).toHaveBeenCalledWith(testChainId);
expect(mockCallback).toHaveBeenCalledTimes(1);
});

// To ensure that the callback system works in real-world network change situations.
it('should notify when network actually changes', () => {
const mockCallback = jest.fn();
provider.onChangeNetwork({ callback: mockCallback });

const newNetwork = mockNetworks[1];
(provider as unknown as { setNetwork(network: NetworkInfo): void }).setNetwork(newNetwork);

expect(mockCallback).toHaveBeenCalledWith(newNetwork.chainId);
expect(mockCallback).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { GnoWalletProvider } from '../../../providers';
import { GNO_ADDRESS_PREFIX } from '../../constants/chains.constant';
import { NetworkInfo } from '../../types';

describe('GnoWalletProvider.setNetwork', () => {
let provider: GnoWalletProvider;
const mockNetwork: NetworkInfo = {
chainId: 'test-chain-1',
networkName: 'Test Network 1',
rpcUrl: 'http://test1.com',
addressPrefix: GNO_ADDRESS_PREFIX,
indexerUrl: null,
};

beforeEach(() => {
provider = new GnoWalletProvider(undefined, [mockNetwork]);
provider['triggerNetworkCallback'] = jest.fn();
});

afterEach(() => {
jest.clearAllMocks();
});

// Validate the currentNetwork setting
it('should set currentNetwork', () => {
provider['setNetwork'](mockNetwork);
expect(provider['currentNetwork']).toBe(mockNetwork);
});

// Validate network callback calls
it('should trigger network callback with chainId', () => {
provider['setNetwork'](mockNetwork);
expect(provider['triggerNetworkCallback']).toHaveBeenCalledWith(mockNetwork.chainId);
});
});
Loading

0 comments on commit a4c5959

Please sign in to comment.