From e0382474f194d1ea9396286ea088ef0a511d0e79 Mon Sep 17 00:00:00 2001 From: Austin Date: Mon, 30 Oct 2023 15:21:39 -0500 Subject: [PATCH] test: oracle price services, and general code cleaning --- src/client/index.ts | 9 ++- src/contracts/services/oracle.test.ts | 94 +++++++++++++++++++-------- src/contracts/services/oracle.ts | 6 +- src/test/mocks/oracle/pricesParsed.ts | 28 ++++++++ 4 files changed, 104 insertions(+), 33 deletions(-) create mode 100644 src/test/mocks/oracle/pricesParsed.ts diff --git a/src/client/index.ts b/src/client/index.ts index 99f43bc..1cd8c60 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -18,16 +18,19 @@ import { ClientData } from '~/types/client'; /** * Create and returns Secret Network client - * @param walletAccount not required for making public queries + * @param lcdEndpoint LCD endpoint to make queries to + * @param chainId chainID string from the config of the chain + * @param walletAccount wallet account data - not required for making public queries */ const getSecretNetworkClient$ = ({ - walletAccount, lcdEndpoint, chainId, + walletAccount, }:{ - walletAccount?: WalletAccount + lcdEndpoint: string, chainId: string, + walletAccount?: WalletAccount }): Observable => createFetchClient(defer( () => { if (walletAccount) { diff --git a/src/contracts/services/oracle.test.ts b/src/contracts/services/oracle.test.ts index 4954535..75c95cc 100644 --- a/src/contracts/services/oracle.test.ts +++ b/src/contracts/services/oracle.test.ts @@ -8,11 +8,18 @@ import { import { parsePriceFromContract, parsePricesFromContract, + queryPrice$, + queryPrices$, } from '~/contracts/services/oracle'; import priceResponse from '~/test/mocks/oracle/priceResponse.json'; import pricesResponse from '~/test/mocks/oracle/pricesResponse.json'; -import BigNumber from 'bignumber.js'; import { of } from 'rxjs'; +import { + priceParsed, + pricesParsed, +} from '~/test/mocks/oracle/pricesParsed'; + +const sendSecretClientContractQuery$ = vi.hoisted(() => vi.fn()); beforeAll(() => { vi.mock('~/contracts/definitions/oracle', () => ({ @@ -21,15 +28,11 @@ beforeAll(() => { })); vi.mock('~/client/index', () => ({ - getActiveQueryClient$: vi.fn(() => of('CLIENT')), + getActiveQueryClient$: vi.fn(() => of({ client: 'CLIENT' })), })); vi.mock('~/client/services/clientServices', () => ({ - sendSecretClientContractQuery$: vi.fn(() => of()), - })); - - vi.mock('~/client/services/clientServices', () => ({ - sendSecretClientContractQuery$: vi.fn(() => of()), + sendSecretClientContractQuery$, })); }); @@ -40,30 +43,65 @@ afterAll(() => { test('it can parse the price response', () => { expect(parsePriceFromContract( priceResponse, - )).toStrictEqual({ - oracleKey: 'BTC', - rate: BigNumber('27917.2071556'), - lastUpdatedBase: 1696644063, - lastUpdatedQuote: 18446744073709552000, - }); + )).toStrictEqual(priceParsed); }); test('it can parse the prices response', () => { - const parsedOutput = { - BTC: { - oracleKey: 'BTC', - rate: BigNumber('27917.2071556'), - lastUpdatedBase: 1696644063, - lastUpdatedQuote: 18446744073709552000, - }, - ETH: { - oracleKey: 'ETH', - rate: BigNumber('1644.0836829'), - lastUpdatedBase: 1696644063, - lastUpdatedQuote: 18446744073709552000, - }, - }; expect(parsePricesFromContract( pricesResponse, - )).toStrictEqual(parsedOutput); + )).toStrictEqual(pricesParsed); +}); + +test('it can send the query single price service', () => { + sendSecretClientContractQuery$.mockReturnValue(of(priceResponse)); + + const input = { + contractAddress: 'CONTRACT_ADDRESS', + codeHash: 'CODE_HASH', + oracleKey: 'ORACLE_KEY', + lcdEndpoint: 'LCD_ENDPOINT', + chainId: 'CHAIN_ID', + }; + let output; + queryPrice$(input).subscribe({ + next: (response) => { + output = response; + }, + }); + + expect(sendSecretClientContractQuery$).toHaveBeenCalledWith({ + queryMsg: 'MSG_QUERY_ORACLE_PRICE', + client: 'CLIENT', + contractAddress: input.contractAddress, + codeHash: input.codeHash, + }); + + expect(output).toStrictEqual(priceParsed); +}); + +test('it can send the query multiple prices service', () => { + sendSecretClientContractQuery$.mockReturnValue(of(pricesResponse)); + + const input = { + contractAddress: 'CONTRACT_ADDRESS', + codeHash: 'CODE_HASH', + oracleKeys: ['ORACLE_KEY'], + lcdEndpoint: 'LCD_ENDPOINT', + chainId: 'CHAIN_ID', + }; + let output; + queryPrices$(input).subscribe({ + next: (response) => { + output = response; + }, + }); + + expect(sendSecretClientContractQuery$).toHaveBeenCalledWith({ + queryMsg: 'MSG_QUERY_ORACLE_PRICES', + client: 'CLIENT', + contractAddress: input.contractAddress, + codeHash: input.codeHash, + }); + + expect(output).toStrictEqual(pricesParsed); }); diff --git a/src/contracts/services/oracle.ts b/src/contracts/services/oracle.ts index 44583e5..22d583d 100644 --- a/src/contracts/services/oracle.ts +++ b/src/contracts/services/oracle.ts @@ -14,12 +14,14 @@ import { getActiveQueryClient$ } from '~/client'; import { convertCoinFromUDenom } from '~/lib/utils'; import { msgQueryOraclePrice, msgQueryOraclePrices } from '~/contracts/definitions/oracle'; +const ORACLE_NORMALIZATION_FACTOR = 18; + /** * Parses the contract price query into the app data model */ const parsePriceFromContract = (response: OraclePriceResponse): ParsedOraclePriceResponse => ({ oracleKey: response.key, - rate: convertCoinFromUDenom(response.data.rate, 18), + rate: convertCoinFromUDenom(response.data.rate, ORACLE_NORMALIZATION_FACTOR), lastUpdatedBase: response.data.last_updated_base, lastUpdatedQuote: response.data.last_updated_quote, }); @@ -32,7 +34,7 @@ function parsePricesFromContract(pricesResponse: OraclePricesResponse) { ...prev, [curr.key]: { oracleKey: curr.key, - rate: convertCoinFromUDenom(curr.data.rate, 18), + rate: convertCoinFromUDenom(curr.data.rate, ORACLE_NORMALIZATION_FACTOR), lastUpdatedBase: curr.data.last_updated_base, lastUpdatedQuote: curr.data.last_updated_quote, } as ParsedOraclePriceResponse, diff --git a/src/test/mocks/oracle/pricesParsed.ts b/src/test/mocks/oracle/pricesParsed.ts new file mode 100644 index 0000000..7d5e333 --- /dev/null +++ b/src/test/mocks/oracle/pricesParsed.ts @@ -0,0 +1,28 @@ +import BigNumber from 'bignumber.js'; + +const priceParsed = { + oracleKey: 'BTC', + rate: BigNumber('27917.2071556'), + lastUpdatedBase: 1696644063, + lastUpdatedQuote: 18446744073709552000, +}; + +const pricesParsed = { + BTC: { + oracleKey: 'BTC', + rate: BigNumber('27917.2071556'), + lastUpdatedBase: 1696644063, + lastUpdatedQuote: 18446744073709552000, + }, + ETH: { + oracleKey: 'ETH', + rate: BigNumber('1644.0836829'), + lastUpdatedBase: 1696644063, + lastUpdatedQuote: 18446744073709552000, + }, +}; + +export { + priceParsed, + pricesParsed, +};