From 0a5ecc0d4422b6643517a834002433f18a368d84 Mon Sep 17 00:00:00 2001 From: Joao Pedro da Silva Date: Mon, 16 May 2022 23:30:49 -0300 Subject: [PATCH] [IPCT1-755] - order by out of funds (#278) * order by out of funds * remove duplicated code --- .../core/src/services/ubi/community/list.ts | 119 +++++++++------- .../core/src/subgraph/queries/community.ts | 1 + .../tests/integration/v2/community.test.ts | 131 ++++++++++++++++++ 3 files changed, 201 insertions(+), 50 deletions(-) diff --git a/packages/core/src/services/ubi/community/list.ts b/packages/core/src/services/ubi/community/list.ts index cea1ebae0..a603463e4 100644 --- a/packages/core/src/services/ubi/community/list.ts +++ b/packages/core/src/services/ubi/community/list.ts @@ -54,6 +54,15 @@ export class CommunityListService { ] | undefined = undefined; + let funds: + | [ + { + id: string; + estimatedFunds: string; + } + ] + | undefined = undefined; + let communitiesId: (number | undefined)[]; let contractAddress: string[] = []; @@ -176,25 +185,30 @@ export class CommunityListService { } case 'out_of_funds': { // this requires extended - // query.extended = 'true'; - // // check if there was another order previously - // if ( - // orderOption.length === 0 && - // !orderBeneficiary.active - // ) { - // const result = await this._getOutOfFunds( - // { - // limit: query.limit, - // offset: query.offset, - // }, - // orderType - // ); - // // communitiesId = result.map((el) => el.id); - // } else { - // // list communities out of funds after - // orderOutOfFunds.active = true; - // orderOutOfFunds.orderType = orderType; - // } + query.extended = 'true'; + // check if there was another order previously + if ( + orderOption.length === 0 && + !orderBeneficiary.active + ) { + funds = await this._communityEntities( + 'estimatedFunds', + { + status: query.status, + limit: query.limit, + offset: query.offset, + }, + extendedWhere, + orderType + ); + contractAddress = funds!.map((el) => + ethers.utils.getAddress(el.id) + ); + } else { + // list communities out of funds after + orderOutOfFunds.active = true; + orderOutOfFunds.orderType = orderType; + } break; } case 'newest': @@ -210,7 +224,8 @@ export class CommunityListService { !orderOutOfFunds.active ) { beneficiariesState = - await this._getBeneficiaryState( + await this._communityEntities( + 'beneficiaries', { status: query.status, limit: query.limit, @@ -234,7 +249,8 @@ export class CommunityListService { } else { // if searching by pending or did not pass the "state" on fields, do not search on the graph if (query.status !== 'pending' && (!query.fields || query.fields.indexOf('state') !== -1)) { - beneficiariesState = await this._getBeneficiaryState( + beneficiariesState = await this._communityEntities( + 'beneficiaries', { status: query.status, limit: query.limit, @@ -335,7 +351,8 @@ export class CommunityListService { } if (orderBeneficiary.active) { - beneficiariesState = await this._getBeneficiaryState( + beneficiariesState = await this._communityEntities( + 'beneficiaries', { status: query.status, limit: query.limit, @@ -358,18 +375,30 @@ export class CommunityListService { }); } - // if (orderOutOfFunds.active) { - // const result = await this._getOutOfFunds( - // { - // limit: query.limit, - // offset: query.offset, - // }, - // orderOutOfFunds.orderType, - // communitiesId - // ); - // // re-order by out of funds - // communitiesId = result.map((el) => el.id); - // } + if (orderOutOfFunds.active) { + funds = await this._communityEntities( + 'estimatedFunds', + { + status: query.status, + limit: query.limit, + offset: query.offset, + }, + {}, + undefined, + contractAddress + ); + contractAddress = funds!.map((el) => + ethers.utils.getAddress(el.id) + ); + + // re-order IDs + communitiesId = contractAddress.map((el) => { + const community = communitiesResult.find( + (community) => community.contractAddress === el + ); + return community?.id; + }); + } // remove empty elements communitiesId = communitiesId.filter(Number); @@ -443,7 +472,8 @@ export class CommunityListService { return requestByAddress; } - private async _getBeneficiaryState( + private async _communityEntities( + orderBy: string, query: { status?: string; limit?: string; @@ -477,7 +507,7 @@ export class CommunityListService { if (contractAddress.length > 0) { result = await communityEntities( - `orderBy: beneficiaries, + `orderBy: ${orderBy}, orderDirection: ${ orderType ? orderType.toLocaleLowerCase() : 'desc' }, @@ -494,11 +524,11 @@ export class CommunityListService { where: { id_in: [${contractAddress.map( (el) => `"${el.toLocaleLowerCase()}"` )}]}`, - `id, beneficiaries` + `id, ${orderBy}` ); } else { result = await communityEntities( - `orderBy: beneficiaries, + `orderBy: ${orderBy}, orderDirection: ${ orderType ? orderType.toLocaleLowerCase() : 'desc' }, @@ -512,24 +542,13 @@ export class CommunityListService { ? parseInt(query.offset, 10) : config.defaultOffset },`, - `id, beneficiaries` + `id, ${orderBy}` ); } return result; } - // private async _getOutOfFunds( - // query: { - // limit?: string; - // offset?: string; - // }, - // orderType?: string, - // communitiesId?: number[] - // ): Promise { - - // } - private _generateInclude(fields: any): Includeable[] { const extendedInclude: Includeable[] = []; diff --git a/packages/core/src/subgraph/queries/community.ts b/packages/core/src/subgraph/queries/community.ts index 2baea6fa0..88d868a66 100644 --- a/packages/core/src/subgraph/queries/community.ts +++ b/packages/core/src/subgraph/queries/community.ts @@ -138,6 +138,7 @@ export const getCommunityState = async ( contributors managers baseInterval + estimatedFunds } } `; diff --git a/packages/core/tests/integration/v2/community.test.ts b/packages/core/tests/integration/v2/community.test.ts index 2839d468a..24c4bb0d3 100644 --- a/packages/core/tests/integration/v2/community.test.ts +++ b/packages/core/tests/integration/v2/community.test.ts @@ -1133,6 +1133,137 @@ describe('community service v2', () => { requestByAddress: users[2].address, }); }); + + it('out of funds', async () => { + const communities = await CommunityFactory([ + { + requestByAddress: users[0].address, + started: new Date(), + status: 'valid', + visibility: 'public', + contract: { + baseInterval: 60 * 60 * 24, + claimAmount: '1000000000000000000', + communityId: 0, + incrementInterval: 5 * 60, + maxClaim: '450000000000000000000', + }, + hasAddress: true, + gps: { + latitude: -23.4378873, + longitude: -46.4841214, + }, + }, + { + requestByAddress: users[1].address, + started: new Date(), + status: 'valid', + visibility: 'public', + contract: { + baseInterval: 60 * 60 * 24, + claimAmount: '1000000000000000000', + communityId: 0, + incrementInterval: 5 * 60, + maxClaim: '450000000000000000000', + }, + hasAddress: true, + gps: { + latitude: -23.4378873, + longitude: -46.4841214, + }, + }, + { + requestByAddress: users[2].address, + started: new Date(), + status: 'valid', + visibility: 'public', + contract: { + baseInterval: 60 * 60 * 24, + claimAmount: '1000000000000000000', + communityId: 0, + incrementInterval: 5 * 60, + maxClaim: '450000000000000000000', + }, + hasAddress: true, + gps: { + latitude: -15.8697203, + longitude: -47.9207824, + }, + }, + ]); + + const claimed: SubgraphClaimed = []; + for (const community of communities) { + claimed.push({ + id: community.contractAddress!, + claimed: 0, + }); + await BeneficiaryFactory( + await UserFactory({ + n: + community.requestByAddress === users[1].address + ? 5 + : 4, + }), + community.id + ); + } + + returnCommunityEntities.returns([ + { + id: communities[1].contractAddress, + estimatedFunds: '0.01', + }, + { + id: communities[2].contractAddress, + estimatedFunds: '1.50', + }, + { + id: communities[0].contractAddress, + estimatedFunds: '100.00', + }, + ]); + + communities.forEach((el) => { + returnCommunityStateSubgraph + .withArgs(el.contractAddress) + .returns({ + claims: 0, + claimed: '0', + beneficiaries: + el.requestByAddress === users[1].address + ? 5 + : 4, + removedBeneficiaries: 0, + contributed: '0', + contributors: 0, + managers: 0, + }); + }); + + const result = await communityListService.list({ + orderBy: 'out_of_funds', + }); + + expect(result.rows[0]).to.include({ + id: communities[1].id, + name: communities[1].name, + country: communities[1].country, + requestByAddress: users[1].address, + }); + expect(result.rows[1]).to.include({ + id: communities[2].id, + name: communities[2].name, + country: communities[2].country, + requestByAddress: users[2].address, + }); + expect(result.rows[2]).to.include({ + id: communities[0].id, + name: communities[0].name, + country: communities[0].country, + requestByAddress: users[0].address, + }); + }); }); describe('query string filter', () => {