Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ module.exports = [
globals: globals.jest,
},
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe('Topic Messages Integration Tests', () => {

await delay(5000);

const findMessageEqArgs: Record<string, any> = {
const findMessageEqArgs: Record<string, string | number> = {
topic: createTopicOutput.topicId,
sequenceEq: 3,
};
Expand All @@ -114,7 +114,7 @@ describe('Topic Messages Integration Tests', () => {
expect(findMessageEqOutput.topicId).toBe(createTopicOutput.topicId);
expect(findMessageEqOutput.messages?.at(0)?.message).toBe(`Test message 3`);

const findMessageGtArgs: Record<string, any> = {
const findMessageGtArgs: Record<string, string | number> = {
topic: createTopicOutput.topicId,
sequenceGt: 7,
};
Expand All @@ -132,7 +132,7 @@ describe('Topic Messages Integration Tests', () => {
expect(findMessageGtOutput.topicId).toBe(createTopicOutput.topicId);
expect(findMessageGtOutput.messages.length).toBe(3);

const findMessageGteArgs: Record<string, any> = {
const findMessageGteArgs: Record<string, string | number> = {
topic: createTopicOutput.topicId,
sequenceGte: 7,
};
Expand All @@ -150,7 +150,7 @@ describe('Topic Messages Integration Tests', () => {
expect(findMessageGteOutput.topicId).toBe(createTopicOutput.topicId);
expect(findMessageGteOutput.messages.length).toBe(4);

const findMessageLtArgs: Record<string, any> = {
const findMessageLtArgs: Record<string, string | number> = {
topic: createTopicOutput.topicId,
sequenceLt: 4,
};
Expand All @@ -168,7 +168,7 @@ describe('Topic Messages Integration Tests', () => {
expect(findMessageLtOutput.topicId).toBe(createTopicOutput.topicId);
expect(findMessageLtOutput.messages.length).toBe(3);

const findMessageLteArgs: Record<string, any> = {
const findMessageLteArgs: Record<string, string | number> = {
topic: createTopicOutput.topicId,
sequenceLte: 4,
};
Expand Down
168 changes: 132 additions & 36 deletions src/__tests__/mocks/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,36 @@ import type { NetworkService } from '@/core/services/network/network-service.int
import type { OutputService } from '@/core/services/output/output-service.interface';
import type { PluginManagementService } from '@/core/services/plugin-management/plugin-management-service.interface';
import type { StateService } from '@/core/services/state/state-service.interface';
import type { TxExecutionService } from '@/core/services/tx-execution/tx-execution-service.interface';
import type {
TransactionResult,
TxExecutionService,
} from '@/core/services/tx-execution/tx-execution-service.interface';

import { KeyAlgorithm } from '@/core/shared/constants';
import { SupportedNetwork } from '@/core/types/shared.types';

import { MOCK_PUBLIC_KEY } from './fixtures';

/**
* Alias account data structure
*/
interface AccountAlias {
entityId: string;
publicKey: string;
keyRefId: string;
}

/**
* Account info structure for mirror node mock
*/
interface AccountInfo {
accountId: string;
balance: { balance: number; timestamp: string };
evmAddress: string;
accountPublicKey: string;
keyAlgorithm: KeyAlgorithm;
}

/**
* Create a mocked Logger instance
*/
Expand Down Expand Up @@ -94,7 +120,7 @@ export const makeAliasMock = (): jest.Mocked<AliasService> => ({
resolve: jest.fn().mockImplementation((alias, type) => {
// Domyślnie zwracaj dane dla typowych aliasów używanych w testach
if (type === 'account') {
const accountAliases: Record<string, any> = {
const accountAliases: Record<string, AccountAlias> = {
'admin-key': {
entityId: '0.0.100000',
publicKey: '302a300506032b6570032100' + '0'.repeat(64),
Expand Down Expand Up @@ -181,6 +207,24 @@ export const makeSigningMock = (
}),
});

/**
* Create mock TransactionResult
*/
export const makeTransactionResultMock = (
overrides?: Partial<TransactionResult>,
): TransactionResult => ({
success: true,
transactionId: 'mock-tx-id',
consensusTimestamp: '2024-01-01T00:00:00.000Z',
receipt: {
status: {
status: 'success' as const,
transactionId: 'mock-tx-id',
},
},
...overrides,
});

export const createMirrorNodeMock =
(): jest.Mocked<HederaMirrornodeService> => ({
getAccount: jest.fn(),
Expand All @@ -204,18 +248,20 @@ export const makeStateMock = (
options: {
listData?: unknown[];
} = {},
): Partial<StateService> => ({
): jest.Mocked<StateService> => ({
list: jest.fn().mockReturnValue(options.listData || []),
get: jest.fn(),
set: jest.fn(),
delete: jest.fn(),
clear: jest.fn(),
has: jest.fn(),
getNamespaces: jest.fn(),
getKeys: jest.fn(),
getNamespaces: jest.fn().mockReturnValue([]),
getKeys: jest.fn().mockReturnValue([]),
subscribe: jest.fn(),
getActions: jest.fn(),
getState: jest.fn(),
getStorageDirectory: jest.fn().mockReturnValue(''),
isInitialized: jest.fn().mockReturnValue(true),
});

/**
Expand All @@ -226,7 +272,7 @@ export const makeMirrorMock = (
hbarBalance?: bigint;
tokenBalances?: { token_id: string; balance: number }[];
tokenError?: Error;
accountInfo?: any;
accountInfo?: AccountInfo;
getAccountImpl?: jest.Mock;
tokenInfo?: Record<
string,
Expand All @@ -246,7 +292,7 @@ export const makeMirrorMock = (
balance: { balance: 1000, timestamp: '1234567890' },
evmAddress: '0xabc',
accountPublicKey: 'pubKey',
keyAlgorithm: 'ecdsa',
keyAlgorithm: KeyAlgorithm.ECDSA,
},
),
getTokenInfo: jest.fn().mockImplementation((tokenId: string) => {
Expand Down Expand Up @@ -331,30 +377,78 @@ export const makeArgs = (
const alias = api.alias || makeAliasMock();
const kms = api.kms || makeKmsMock();

// Exclude state and config from api spread since they're already mocked above
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { state, config, ...restApi } = api;

const apiObject = {
account: {} as unknown,
token: {} as unknown,
txExecution: makeSigningMock(),
topic: {
createTopic: jest.fn(),
submitMessage: jest.fn(),
} as unknown,
state: {
list: jest.fn().mockReturnValue([]),
get: jest.fn(),
set: jest.fn(),
delete: jest.fn(),
clear: jest.fn(),
has: jest.fn(),
getNamespaces: jest.fn(),
getKeys: jest.fn(),
subscribe: jest.fn(),
getActions: jest.fn(),
getState: jest.fn(),
getStorageDirectory: jest.fn().mockReturnValue(''),
isInitialized: jest.fn().mockReturnValue(true),
} as unknown as StateService,
mirror: {
setBaseUrl: jest.fn(),
getAccount: jest.fn(),
getAccountHBarBalance: jest.fn(),
getAccountTokenBalances: jest.fn(),
getTopicMessage: jest.fn(),
getTopicMessages: jest.fn(),
getTokenInfo: jest.fn(),
getTopicInfo: jest.fn(),
getTransactionRecord: jest.fn(),
getContractInfo: jest.fn(),
getPendingAirdrops: jest.fn(),
getOutstandingAirdrops: jest.fn(),
getExchangeRate: jest.fn(),
} as HederaMirrornodeService,
network,
config: makeConfigMock(),
logger,
alias,
kms,
hbar: makeHbarMock(),
output: makeOutputMock(),
pluginManagement: makePluginManagementServiceMock(),
keyResolver: makeKeyResolverMock({ network, alias, kms }),
...restApi,
} as unknown as CoreApi;

return {
api: {
account: {} as any,
token: {} as any,
txExecution: makeSigningMock(),
topic: {
createTopic: jest.fn(),
submitMessage: jest.fn(),
} as any,
state: {} as any,
mirror: {} as any,
network,
config: makeConfigMock(),
logger,
alias,
kms,
hbar: makeHbarMock(),
output: makeOutputMock(),
pluginManagement: makePluginManagementServiceMock(),
keyResolver: makeKeyResolverMock({ network, alias, kms }),
...api,
},
api: apiObject,
logger,
state: {} as StateService,
state: {
list: jest.fn().mockReturnValue([]),
get: jest.fn(),
set: jest.fn(),
delete: jest.fn(),
clear: jest.fn(),
has: jest.fn(),
getNamespaces: jest.fn(),
getKeys: jest.fn(),
subscribe: jest.fn(),
getActions: jest.fn(),
getState: jest.fn(),
getStorageDirectory: jest.fn().mockReturnValue(''),
isInitialized: jest.fn().mockReturnValue(true),
} as unknown as StateService,
config: makeConfigMock(),
args,
};
Expand All @@ -374,10 +468,10 @@ export const setupExitSpy = (): jest.SpyInstance => {
*/
export const makeKeyResolverMock = (
options: {
network?: any;
alias?: any;
kms?: any;
mirror?: any;
network?: NetworkService;
alias?: AliasService;
kms?: KmsService;
mirror?: HederaMirrornodeService;
} = {},
): jest.Mocked<KeyResolverService> => ({
getOrInitKey: jest
Expand All @@ -389,7 +483,7 @@ export const makeKeyResolverMock = (
// Call kms.importPrivateKey if available
if (options.kms?.importPrivateKey) {
const importResult = options.kms.importPrivateKey(
'ecdsa',
KeyAlgorithm.ECDSA,
keyOrAlias.privateKey,
keyManager,
labels || [],
Expand All @@ -409,7 +503,8 @@ export const makeKeyResolverMock = (

// alias format
if (keyOrAlias?.type === 'alias' && options.alias) {
const network = options.network?.getCurrentNetwork() || 'testnet';
const network =
options.network?.getCurrentNetwork() || SupportedNetwork.TESTNET;
const resolved = options.alias.resolve(
keyOrAlias.alias,
'account',
Expand Down Expand Up @@ -437,7 +532,8 @@ export const makeKeyResolverMock = (
.mockImplementation(async (keyOrAlias, keyManager, labels) => {
// undefined -> fallback do operatora
if (!keyOrAlias && options.network) {
const operator = options.network.getOperator();
const network = options.network.getCurrentNetwork();
const operator = options.network.getOperator(network);
if (!operator) throw new Error('No operator set');
// Always use default valid public key for mocking
const publicKey = '302a300506032b6570032100' + '0'.repeat(64);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('AliasServiceImpl', () => {
beforeEach(() => {
jest.clearAllMocks();
logger = makeLogger();
stateMock = makeStateMock() as jest.Mocked<StateService>;
stateMock = makeStateMock();
aliasService = new AliasServiceImpl(stateMock, logger);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('ConfigServiceImpl', () => {

beforeEach(() => {
jest.clearAllMocks();
stateMock = makeStateMock() as jest.Mocked<StateService>;
stateMock = makeStateMock();
configService = new ConfigServiceImpl(stateMock);
});

Expand Down
4 changes: 4 additions & 0 deletions src/core/services/hbar/__tests__/unit/hbar-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ jest.mock('@hashgraph/sdk', () => ({
HbarUnit: {
Tinybar: 'tinybar',
},
TokenType: {
NonFungibleUnique: 'NON_FUNGIBLE_UNIQUE',
FungibleCommon: 'FUNGIBLE_COMMON',
},
}));

import { AccountId, Hbar, HbarUnit } from '@hashgraph/sdk';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@ describe('HederaMirrornodeServiceDefaultImpl', () => {

it('should throw error when account field is missing', async () => {
const { service } = setupService();
const mockResponse = createMockAccountAPIResponse({ account: '' as any });
const mockResponse = createMockAccountAPIResponse({
account: '' as never,
});
(global.fetch as jest.Mock).mockResolvedValue({
ok: true,
json: jest.fn().mockResolvedValue(mockResponse),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('NetworkServiceImpl', () => {

beforeEach(() => {
jest.clearAllMocks();
stateMock = makeStateMock() as jest.Mocked<StateService>;
stateMock = makeStateMock();
loggerMock = makeLogger();
networkService = new NetworkServiceImpl(stateMock, loggerMock);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ describe('OutputServiceImpl', () => {
beforeEach(() => {
jest.clearAllMocks();
service = new OutputServiceImpl();
getStrategyMock = OutputFormatterFactory.getStrategy as any as jest.Mock;
getStrategyMock =
OutputFormatterFactory.getStrategy as unknown as jest.Mock;
consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('PluginManagementServiceImpl', () => {

beforeEach(() => {
jest.clearAllMocks();
stateMock = makeStateMock() as jest.Mocked<StateService>;
stateMock = makeStateMock();
service = new PluginManagementServiceImpl(stateMock);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ jest.mock('path', () => ({
join: jest.fn((...args: string[]) => args.join('/')),
}));

jest.mock('@hashgraph/sdk', () => ({
TokenType: {
NonFungibleUnique: 'NON_FUNGIBLE_UNIQUE',
FungibleCommon: 'FUNGIBLE_COMMON',
},
}));

describe('ZustandGenericStateServiceImpl', () => {
let service: ZustandGenericStateServiceImpl;
let logger: jest.Mocked<Logger>;
Expand Down
Loading