Skip to content

Commit

Permalink
test: pool tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jackmellis committed Jan 8, 2024
1 parent 4d69dff commit 455bbb4
Show file tree
Hide file tree
Showing 36 changed files with 2,608 additions and 852 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ beforeEach(() => {
image: 'example.com/image',
imageSmall: 'example.com/imageSmall',
isFlagged: false,
media: 'example.com/media',
media: 'example.com/media.mp4',
name: 'CryptoPunks',
imageLarge: 'example.com/imageLarge',
rarityRank: 0,
Expand Down Expand Up @@ -104,7 +104,7 @@ beforeEach(() => {
image: 'example.com/image',
imageSmall: 'example.com/imageSmall',
isFlagged: false,
media: 'example.com/media',
media: 'example.com/media.mp4',
name: 'CryptoPunks',
imageLarge: 'example.com/imageLarge',
rarityRank: 0,
Expand All @@ -126,7 +126,7 @@ it('returns a list of assets', async () => {

const expected = [
{
animationUrl: 'example.com/media',
animationUrl: 'example.com/media.mp4',
assetAddress: '0x0000000',
id: '0x0000000/0',
imagePreviewUrl: 'example.com/imageSmall',
Expand All @@ -142,7 +142,6 @@ it('returns a list of assets', async () => {
vaultIds: ['0'],
},
{
animationUrl: 'example.com/media',
assetAddress: '0x0000000',
id: '0x0000000/1',
imagePreviewUrl: 'example.com/imageSmall',
Expand All @@ -158,7 +157,7 @@ it('returns a list of assets', async () => {
vaultIds: ['0'],
},
{
animationUrl: 'example.com/media',
animationUrl: 'example.com/media.mp4',
assetAddress: '0x0000000',
id: '0x0000000/2',
imagePreviewUrl: 'example.com/imageSmall',
Expand Down
81 changes: 81 additions & 0 deletions packages/core/src/balances/__tests__/fetchVTokenBalances.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { makeFetchVTokenBalances } from '../fetchVTokenBalances';

let erc20BalancesResponse: any;
let querySubgraph: jest.Mock;
let fetchVTokenBalances: ReturnType<typeof makeFetchVTokenBalances>;
let args: Parameters<typeof fetchVTokenBalances>[0];
let run: () => ReturnType<typeof fetchVTokenBalances>;

beforeEach(() => {
erc20BalancesResponse = {
erc20Balances: [
{
id: '0x0000000',
valueExact: '1000000000000000000',
contract: {
id: '0x0000000',
asVaultAsset: {
vaultId: '0',
},
},
},
],
};
querySubgraph = jest.fn().mockResolvedValue(erc20BalancesResponse);
fetchVTokenBalances = makeFetchVTokenBalances({ querySubgraph });
args = {
userAddresses: ['0x0000000'],
};
run = () => fetchVTokenBalances(args);
});

it('returns a list of all vToken balances for a given address', async () => {
const result = await run();
expect(result).toEqual([
{
type: 'vToken',
id: '0x0000000',
vaultId: '0',
balance: BigInt('1000000000000000000'),
},
]);
});

it('returns a list of vToken balances for a vault address', async () => {
args.vaultAddresses = ['0x0000000'];
const result = await run();

expect(result).toEqual([
{
type: 'vToken',
id: '0x0000000',
vaultId: '0',
balance: BigInt('1000000000000000000'),
},
]);
});

it('returns a list of vToken balances for a vaultId', async () => {
args.vaultIds = ['1'];
const result = await run();

expect(result).toEqual([]);
});

describe('when there are more than 1000 balances', () => {
beforeEach(() => {
const response = {
erc20Balances: new Array(1000).fill(
erc20BalancesResponse.erc20Balances[0]
),
};
querySubgraph.mockResolvedValueOnce(response);
});

it('recusively fetches all balances', async () => {
const result = await run();

expect(result.length).toEqual(1001);
expect(querySubgraph).toHaveBeenCalledTimes(2);
});
});
128 changes: 67 additions & 61 deletions packages/core/src/balances/fetchVTokenBalances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,73 +13,79 @@ type VTokenBalance = {
balance: bigint;
};

const fetchVTokenBalances = async ({
network = config.network,
userAddresses,
vaultAddresses,
vaultIds,
}: {
network?: number;
userAddresses?: Address[];
vaultIds?: string[];
vaultAddresses?: Address[];
}): Promise<VTokenBalance[]> => {
const balances: VTokenBalance[] = [];
let lastId: string | undefined;
type QuerySubgraph = typeof querySubgraph;

do {
const q = createQuery<NftxV3.Query>();
const query = q.erc20Balances
.first(1000)
.orderBy('id')
.where((w) => [
userAddresses?.length === 1
? w.account.is(userAddresses[0])
: w.account.in(userAddresses),
vaultAddresses?.length === 1
? w.contract.is(vaultAddresses[0])
: w.contract.in(vaultAddresses),
])
.select((balance) => [
balance.id,
balance.contract((contract) => [
contract.id,
contract.asVaultAsset((vault) => [vault.vaultId]),
]),
balance.valueExact,
]);
export const makeFetchVTokenBalances =
({ querySubgraph }: { querySubgraph: QuerySubgraph }) =>
async ({
network = config.network,
userAddresses,
vaultAddresses,
vaultIds,
}: {
network?: number;
userAddresses?: Address[];
vaultIds?: string[];
vaultAddresses?: Address[];
}): Promise<VTokenBalance[]> => {
const balances: VTokenBalance[] = [];
let lastId: string | undefined;

const result = await querySubgraph({
url: getChainConstant(config.subgraph.NFTX_SUBGRAPH, network),
query,
});
do {
const q = createQuery<NftxV3.Query>();
const query = q.erc20Balances
.first(1000)
.orderBy('id')
.where((w) => [
userAddresses?.length === 1
? w.account.is(userAddresses[0])
: w.account.in(userAddresses),
vaultAddresses?.length === 1
? w.contract.is(vaultAddresses[0])
: w.contract.in(vaultAddresses),
])
.select((balance) => [
balance.id,
balance.contract((contract) => [
contract.id,
contract.asVaultAsset((vault) => [vault.vaultId]),
]),
balance.valueExact,
]);

result.erc20Balances.forEach((balance) => {
if (
vaultIds &&
!vaultIds.includes(balance.contract.asVaultAsset.vaultId ?? '')
) {
return;
}
const result = await querySubgraph({
url: getChainConstant(config.subgraph.NFTX_SUBGRAPH, network),
query,
});

const vTokenBalance: VTokenBalance = {
type: 'vToken',
id: balance.contract.id as Address,
vaultId: balance.contract.asVaultAsset.vaultId ?? '',
balance: BigInt(balance.valueExact),
};
result.erc20Balances.forEach((balance) => {
if (
vaultIds &&
!vaultIds.includes(balance.contract.asVaultAsset.vaultId ?? '')
) {
return;
}

balances.push(vTokenBalance);
});
const vTokenBalance: VTokenBalance = {
type: 'vToken',
id: balance.contract.id as Address,
vaultId: balance.contract.asVaultAsset.vaultId ?? '',
balance: BigInt(balance.valueExact),
};

if (result.erc20Balances.length === 1000) {
lastId = result.erc20Balances[result.erc20Balances.length - 1].id;
} else {
lastId = undefined;
}
} while (lastId);
balances.push(vTokenBalance);
});

return balances;
};
if (result.erc20Balances.length === 1000) {
lastId = result.erc20Balances[result.erc20Balances.length - 1].id;
} else {
lastId = undefined;
}
} while (lastId);

return balances;
};

const fetchVTokenBalances = makeFetchVTokenBalances({ querySubgraph });

export default fetchVTokenBalances;
62 changes: 62 additions & 0 deletions packages/core/src/pools/__tests__/fetchPremiumPaids.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { makeFetchPremiumPaids } from '../fetchPremiumPaids';

let queryResponse: any;
let querySubgraph: jest.Mock;
let fetchPremiumPaids: ReturnType<typeof makeFetchPremiumPaids>;
let args: Parameters<typeof fetchPremiumPaids>[0];
let run: () => ReturnType<typeof fetchPremiumPaids>;

beforeEach(() => {
queryResponse = {
premiumPaids: [
{
amount: '100000000000000000000',
date: '1629830400',
id: '0x000000',
to: {
id: '0x0',
},
vault: {
id: '0x0',
vaultId: '0',
},
},
],
};
querySubgraph = jest.fn().mockResolvedValue(queryResponse);
fetchPremiumPaids = makeFetchPremiumPaids({ querySubgraph });

args = {
network: 1,
};

run = () => fetchPremiumPaids(args);
});

it('fetches premium paids', async () => {
const result = await run();

expect(result).toEqual([
{
amount: BigInt('100000000000000000000'),
date: 1629830400,
to: '0x0',
vaultAddress: '0x0',
vaultId: '0',
},
]);
});

describe('when there are more than 1000 premium paids', () => {
beforeEach(() => {
querySubgraph.mockResolvedValueOnce({
premiumPaids: new Array(1000).fill(queryResponse.premiumPaids[0]),
});
});

it('recusrively fetches all premium paids', async () => {
const result = await run();

expect(result).toHaveLength(1001);
});
});
Loading

0 comments on commit 455bbb4

Please sign in to comment.