-
Notifications
You must be signed in to change notification settings - Fork 260
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(api): api package test + few adjustments
- Loading branch information
1 parent
386263e
commit 6eae2a9
Showing
12 changed files
with
317 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
'@moralisweb3/api': major | ||
'@moralisweb3/evm-api': major | ||
'@moralisweb3/integration': major | ||
--- | ||
|
||
test on api utils and few optimisations |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,18 @@ | ||
module.exports = { | ||
// Map workspaces to their source code so that Jest can resolve them correctly. | ||
moduleNameMapper: { | ||
'^@moralisweb3/evm-connector-utils$': '<rootDir>/../evmConnectors/EvmConnectorUtils/src', | ||
'^@moralisweb3/evm-metamask-connector$': '<rootDir>/../evmConnectors/EvmMetamaskConnector/src', | ||
'^@moralisweb3/evm-walletconnect-connector$': '<rootDir>/../evmConnectors/EvmWalletconnectConnector/src', | ||
'^@moralisweb3/evm-api': '<rootDir>/../evmApi/src', | ||
'^@moralisweb3/api': '<rootDir>/../api/src', | ||
'^@moralisweb3/core': '<rootDir>/../core/src', | ||
'^@moralisweb3/(.*)$': '<rootDir>/../$1/src', | ||
}, | ||
modulePaths: ['<rootDir>'], | ||
preset: 'ts-jest/presets/default', | ||
collectCoverageFrom: ['**/src/**/*.{js,ts,jsx,tsx}'], | ||
coverageThreshold: null, | ||
globals: { | ||
'ts-jest': { | ||
tsConfig: '<rootDir>/../../tsconfig.package.json', | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const MOCK_API_KEY = 'test-api-key'; | ||
export const API_ROOT = 'https://deep-index.moralis.io/api/v2'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* eslint-disable no-console */ | ||
import { rest } from 'msw'; | ||
import { API_ROOT, MOCK_API_KEY } from '../config'; | ||
|
||
export const mockEndpointWeightss = 'getBlock'; | ||
|
||
export const mockEndpointWeights = rest.get(`${API_ROOT}/info/endpointWeights`, (req, res, ctx) => { | ||
const apiKey = req.headers.get('x-api-key'); | ||
|
||
if (apiKey !== MOCK_API_KEY) { | ||
return res(ctx.status(401)); | ||
} | ||
|
||
const value = mockEndpointWeightss; | ||
|
||
if (!value) { | ||
return res(ctx.status(404)); | ||
} | ||
|
||
return res( | ||
ctx.status(200), | ||
ctx.json({ | ||
endpoint: value, | ||
weight: '8', | ||
}), | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { rest } from 'msw'; | ||
import { API_ROOT, MOCK_API_KEY } from '../config'; | ||
|
||
export const mockGetContractEvents = rest.post(`${API_ROOT}/:address/events`, (req, res, ctx) => { | ||
const apiKey = req.headers.get('x-api-key'); | ||
|
||
if (apiKey !== MOCK_API_KEY) { | ||
return res(ctx.status(401)); | ||
} | ||
|
||
return res( | ||
ctx.status(200), | ||
ctx.json({ | ||
total: 10, | ||
page: 0, | ||
page_size: 2, | ||
cursor: 'cursor_string', | ||
result: [ | ||
{ | ||
transaction_hash: '0x2d30ca6f024dbc1307ac8a1a44ca27de6f797ec22ef20627a1307243b0ab7d09', | ||
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', | ||
block_timestamp: '2021-04-02T10:07:54.000Z', | ||
block_number: '12526958', | ||
block_hash: '0x0372c302e3c52e8f2e15d155e2c545e6d802e479236564af052759253b20fd86', | ||
data: { | ||
from: '0x54ff6974c715956a5049a123408bff91fbe29f01', | ||
to: '0x74de5d4fcbf63e00296fd95d33236b9794016631', | ||
value: '260103496340000000000', | ||
}, | ||
}, | ||
], | ||
}), | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { ApiFormatType } from '../ApiResultAdapter'; | ||
import { setupApi, cleanApi, MockApi } from './setup'; | ||
|
||
const endpointWeightsRawResult = { | ||
endpoint: 'getBlock', | ||
weight: '8', | ||
}; | ||
|
||
const endpointWeightsTransformedResult = { | ||
endpoint: 'getBlock', | ||
weight: 8, | ||
}; | ||
|
||
const eventRawResult = [ | ||
{ | ||
transaction_hash: '0x2d30ca6f024dbc1307ac8a1a44ca27de6f797ec22ef20627a1307243b0ab7d09', | ||
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', | ||
block_timestamp: '2021-04-02T10:07:54.000Z', | ||
block_number: '12526958', | ||
block_hash: '0x0372c302e3c52e8f2e15d155e2c545e6d802e479236564af052759253b20fd86', | ||
data: { | ||
from: '0x54ff6974c715956a5049a123408bff91fbe29f01', | ||
to: '0x74de5d4fcbf63e00296fd95d33236b9794016631', | ||
value: '260103496340000000000', | ||
}, | ||
}, | ||
]; | ||
|
||
const expectedAddress = '0xdAC17F958D2ee523a2206206994597C13D831ec7'; | ||
|
||
const ABI = { | ||
anonymous: false, | ||
inputs: [ | ||
{ indexed: true, name: 'from', type: 'address' }, | ||
{ indexed: true, name: 'to', type: 'address' }, | ||
{ indexed: false, name: 'value', type: 'uint256' }, | ||
], | ||
name: 'Transfer', | ||
type: 'event', | ||
}; | ||
|
||
describe('ApiResolver', () => { | ||
let api: MockApi; | ||
beforeAll(() => { | ||
api = setupApi(); | ||
}); | ||
|
||
afterAll(() => { | ||
cleanApi(); | ||
}); | ||
it('should test api resolver functions with get request', async () => { | ||
const resolver = await api.endpoints.endpointWeights(); | ||
expect(resolver.raw).toStrictEqual(endpointWeightsRawResult); | ||
expect(resolver.toJSON()).toStrictEqual(endpointWeightsRawResult); | ||
expect(resolver.result).toStrictEqual(endpointWeightsTransformedResult); | ||
expect(resolver.format(ApiFormatType.NORMAL)).toStrictEqual(endpointWeightsTransformedResult); | ||
expect(resolver.format(ApiFormatType.RAW)).toStrictEqual(endpointWeightsRawResult); | ||
expect(() => resolver.format('legacy' as any)).toThrowErrorMatchingInlineSnapshot( | ||
`"[A0001] provided formatType not supported"`, | ||
); | ||
}); | ||
|
||
it('should test api resolver functions with post request and pagination', async () => { | ||
const resolver = await api.endpoints.getContractEvents({ | ||
chain: 'eth', | ||
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', | ||
topic: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', | ||
limit: 2, | ||
abi: ABI, | ||
}); | ||
expect(resolver.raw.total).toStrictEqual(10); | ||
expect(resolver.raw.page_size).toStrictEqual(2); | ||
expect(resolver.raw.result).toStrictEqual(eventRawResult); | ||
expect(resolver.result[0].address.format()).toBe(expectedAddress.toLowerCase()); | ||
}); | ||
|
||
it('should test next call', async () => { | ||
const resolver = await api.endpoints.getContractEvents({ | ||
chain: 'eth', | ||
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', | ||
topic: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', | ||
limit: 3, | ||
abi: ABI, | ||
}); | ||
const callSpy = jest.fn(async () => await resolver.next()); | ||
const result = await callSpy(); | ||
expect(result.raw.total).toStrictEqual(10); | ||
expect(result.raw.result).toStrictEqual(eventRawResult); | ||
expect(callSpy).toBeCalledTimes(1); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { MoralisApi } from './../MoralisApi'; | ||
import { ApiModule, EvmAddress, EvmAddressish, EvmChainish, MoralisCore, MoralisCoreProvider } from '@moralisweb3/core'; | ||
import { setupServer } from 'msw/node'; | ||
import { ApiResolver, BodyType } from '../Resolver'; | ||
import { API_ROOT, MOCK_API_KEY } from './config'; | ||
import { mockEndpointWeights } from './mockRequests/endpointWeights'; | ||
import { mockGetContractEvents } from './mockRequests/getContractEvents'; | ||
import { BASE_URL } from '@moralisweb3/evm-api'; | ||
import { resolveDefaultChain } from '../utils'; | ||
import { ApiPaginatedOptions, ApiPaginatedResolver, ApiPaginatedResponse } from '../PaginatedResolver'; | ||
|
||
interface EndpointWeight { | ||
endpoint: string; | ||
weight: string; | ||
} | ||
|
||
interface Params extends ApiPaginatedOptions { | ||
chain?: EvmChainish; | ||
address: EvmAddressish; | ||
abi: unknown; | ||
} | ||
|
||
type ApiResult = { | ||
transaction_hash: string; | ||
address: string; | ||
block_timestamp: string; | ||
block_number: string; | ||
block_hash: string; | ||
data: { | ||
from?: string | undefined; | ||
to?: string | undefined; | ||
value?: string | undefined; | ||
}; | ||
}[]; | ||
|
||
export class MockApi extends ApiModule { | ||
public static readonly moduleName = 'mockApi'; | ||
|
||
public static create(core?: MoralisCore): MockApi { | ||
return new MockApi(core ?? MoralisCoreProvider.getDefault()); | ||
} | ||
|
||
public constructor(core: MoralisCore) { | ||
super(MockApi.moduleName, core, API_ROOT); | ||
} | ||
|
||
get endpoints() { | ||
return { | ||
endpointWeights: () => | ||
new ApiResolver({ | ||
name: 'endpointWeights', | ||
getUrl: () => `${API_ROOT}/info/endpointWeights`, | ||
apiToResult: (data: EndpointWeight) => ({ | ||
endpoint: data.endpoint, | ||
weight: parseInt(data.weight), | ||
}), | ||
resultToJson: (data) => ({ | ||
endpoint: data.endpoint, | ||
weight: data.weight.toString(), | ||
}), | ||
parseParams: (params) => params, | ||
}).fetch({}), | ||
|
||
getContractEvents: new ApiPaginatedResolver({ | ||
name: 'getContractEvents', | ||
getUrl: (params: Params) => `${BASE_URL}/${params.address}/events`, | ||
// TODO: remove PaginatedResponse when api squad make swagger update | ||
apiToResult: (data: ApiPaginatedResponse<ApiResult>) => | ||
data.result.map((event) => ({ | ||
...event, | ||
address: EvmAddress.create(event.address), | ||
})), | ||
resultToJson: (data) => data, | ||
parseParams: (params: Params) => ({ | ||
chain: resolveDefaultChain(params.chain).apiHex, | ||
from_block: params.fromBlock, | ||
to_block: params.toBlock, | ||
from_date: params.toDate, | ||
to_date: params.toDate, | ||
providerUrl: params.providerUrl, | ||
topic: params.topic, | ||
limit: params.limit, | ||
offset: params.offset, | ||
subdomain: params.subdomain, | ||
address: EvmAddress.create(params.address).lowercase, | ||
abi: params.abi, | ||
}), | ||
method: 'post', | ||
bodyParams: ['abi'], | ||
bodyType: BodyType.BODY, | ||
}).fetch, | ||
}; | ||
} | ||
|
||
public setup() { | ||
// | ||
} | ||
|
||
public start(): void | Promise<void> { | ||
// Nothing... | ||
} | ||
} | ||
|
||
const mockServer = setupServer(mockEndpointWeights, mockGetContractEvents); | ||
export function setupApi() { | ||
const core = MoralisCoreProvider.getDefault(); | ||
const api = MoralisApi.create(core); | ||
const mockApi = MockApi.create(core); | ||
core.registerModules([api, mockApi]); | ||
core.start({ | ||
apiKey: MOCK_API_KEY, | ||
}); | ||
mockServer.listen({ | ||
onUnhandledRequest: 'warn', | ||
}); | ||
|
||
return mockApi; | ||
} | ||
|
||
export function cleanApi() { | ||
mockServer.close(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters