diff --git a/package.json b/package.json index 4bd2a0a1..4ebd63e6 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "test-repository": "NODE_ENV=test DOTENV_CONFIG_PATH=.env.test mocha -r dotenv/config --exit ./server/repositories/**/*.spec.js", "server-test": "npm run test-seed and npm run server", "server": "NODE_ENV=development nodemon server/server.js", + "server-debug": "NODE_ENV=development nodemon --inspect=9229 server/server.js", "test-seed": "NODE_ENV=test DOTENV_CONFIG_PATH=.env.test mocha -r dotenv/config --timeout 10000 './__tests__/seed.spec.js'", "test-seed-ci": "NODE_ENV=test DOTENV_CONFIG_PATH=.env.ci mocha -r dotenv/config --timeout 10000 './__tests__/seed.spec.js'", "test-integration": "NODE_ENV=test DOTENV_CONFIG_PATH=.env.test mocha -r dotenv/config --exit --timeout 20000 './__tests__/*.spec.js' './__tests__/integration/*.spec.js'", diff --git a/server/handlers/trustHandler.spec.js b/server/handlers/trustHandler.spec.js index 7c1a88bb..34d1a43e 100644 --- a/server/handlers/trustHandler.spec.js +++ b/server/handlers/trustHandler.spec.js @@ -193,11 +193,17 @@ describe('trustRouter', () => { }); it('successfully', async () => { + const limit = 10; + const offset = 0; + const count = 1; const getAllTrustRelationshipsStub = sinon .stub(TrustService.prototype, 'getAllTrustRelationships') - .resolves([{ id: trustId }]); + .resolves({ + result: [{ id: trustId }], + count + }); const res = await request(app).get( - `/trust_relationships?type=${TrustRelationshipEnums.ENTITY_TRUST_TYPE.send}&request_type=${TrustRelationshipEnums.ENTITY_TRUST_REQUEST_TYPE.send}&state=${TrustRelationshipEnums.ENTITY_TRUST_STATE_TYPE.trusted}`, + `/trust_relationships?type=${TrustRelationshipEnums.ENTITY_TRUST_TYPE.send}&request_type=${TrustRelationshipEnums.ENTITY_TRUST_REQUEST_TYPE.send}&state=${TrustRelationshipEnums.ENTITY_TRUST_STATE_TYPE.trusted}&limit=${limit}&offset=${offset}`, ); expect(res).property('statusCode').eq(200); expect(res.body.trust_relationships).lengthOf(1); @@ -206,6 +212,8 @@ describe('trustRouter', () => { state: TrustRelationshipEnums.ENTITY_TRUST_STATE_TYPE.trusted, type: TrustRelationshipEnums.ENTITY_TRUST_TYPE.send, request_type: TrustRelationshipEnums.ENTITY_TRUST_REQUEST_TYPE.send, + limit, + offset, walletId: authenticatedWalletId, }); }); diff --git a/server/handlers/trustHandler/index.js b/server/handlers/trustHandler/index.js index 123a7be4..96f953d8 100644 --- a/server/handlers/trustHandler/index.js +++ b/server/handlers/trustHandler/index.js @@ -14,22 +14,27 @@ const trustGet = async (req, res) => { state, type, request_type, - // limit, offset + limit, offset } = validatedQuery; const { wallet_id } = req; const trustService = new TrustService(); - const trustRelationships = await trustService.getAllTrustRelationships({ + const { + result: trust_relationships, + count: total, + } = await trustService.getAllTrustRelationships({ walletId: wallet_id, state, type, request_type, - // offset, - // limit, + offset, + limit, }); res.status(200).json({ - trust_relationships: trustRelationships, + trust_relationships, + query: { limit, offset }, + total, }); }; diff --git a/server/models/Trust.js b/server/models/Trust.js index fe551c61..42ff7cfd 100644 --- a/server/models/Trust.js +++ b/server/models/Trust.js @@ -49,6 +49,28 @@ class Trust { return this._trustRepository.getByFilter(filter, { offset, limit }); } + /* + * Get all trust relationships by filters, setting filter to undefined to allow all data + */ + async getAllTrustRelationships({ walletId, state, type, request_type, offset, limit }) { + + const filter = { + and: [ + {'originator_wallet.id': walletId}, + ], + }; + if (state) { + filter.and.push({ state }); + } + if (type) { + filter.and.push({ type }); + } + if (request_type) { + filter.and.push({ request_type }); + } + return this._trustRepository.getAllByFilter(filter, { offset, limit }); + } + /* * Get all relationships which has been accepted */ diff --git a/server/repositories/TrustRepository.js b/server/repositories/TrustRepository.js index ba8cb5ef..4fc7cf8b 100644 --- a/server/repositories/TrustRepository.js +++ b/server/repositories/TrustRepository.js @@ -78,6 +78,62 @@ class TrustRepository extends BaseRepository { return promise; } + + async getAllByFilter(filter, limitOptions) { + let promise = this._session + .getDB() + .select( + 'wallet_trust.id', + 'wallet_trust.actor_wallet_id', + 'wallet_trust.target_wallet_id', + 'wallet_trust.type', + 'wallet_trust.originator_wallet_id', + 'wallet_trust.request_type', + 'wallet_trust.state', + 'wallet_trust.created_at', + 'wallet_trust.updated_at', + 'wallet_trust.active', + 'originator_wallet.name as originating_wallet', + 'actor_wallet.name as actor_wallet', + 'target_wallet.name as target_wallet', + ) + .from('wallet_trust') + .leftJoin( + 'wallet as originator_wallet', + 'wallet_trust.originator_wallet_id', + '=', + 'originator_wallet.id', + ) + .leftJoin( + 'wallet as actor_wallet', + 'wallet_trust.actor_wallet_id', + '=', + 'actor_wallet.id', + ) + .leftJoin( + 'wallet as target_wallet', + 'wallet_trust.target_wallet_id', + '=', + 'target_wallet.id', + ) + .where((builder) => this.whereBuilder(filter, builder)) + .distinctOn('wallet_trust.id'); // distinct on id to avoid duplicates + + // get the total count (before applying limit and offset options) + const count = await this._session.getDB().from(promise.as('p')).count('*'); + + if (limitOptions && limitOptions.limit) { + promise = promise.limit(limitOptions.limit); + } + + if (limitOptions && limitOptions.offset) { + promise = promise.offset(limitOptions.offset); + } + + const result = await promise; + + return { result, count: +count[0].count }; + } } module.exports = TrustRepository; diff --git a/server/services/TrustService.js b/server/services/TrustService.js index 50cce6ce..17c9b3d5 100644 --- a/server/services/TrustService.js +++ b/server/services/TrustService.js @@ -1,6 +1,5 @@ const Trust = require('../models/Trust'); const Session = require('../infra/database/Session'); -const Wallet = require('../models/Wallet'); const WalletService = require('./WalletService'); const EventService = require('./EventService'); const EventEnums = require('../utils/event-enum'); @@ -35,44 +34,15 @@ class TrustService { }); } - // limit and offset not feasible using the current implementation - // except if done manually or coming up with a single query - async getAllTrustRelationships({ walletId, state, type, request_type }) { - const walletModel = new Wallet(this._session); - const { wallets } = await walletModel.getAllWallets( + async getAllTrustRelationships({ walletId, state, type, request_type, offset, limit }) { + return this._trust.getAllTrustRelationships({ walletId, - undefined, - undefined, - 'created_at', - 'desc', - ); - - const alltrustRelationships = []; - - await Promise.all( - wallets.map(async (w) => { - const trustRelationships = await this.getTrustRelationships({ - walletId: w.id, - state, - type, - request_type, - }); - alltrustRelationships.push(...trustRelationships); - }), - ); - - // remove possible duplicates - const ids = {}; - const finalTrustRelationships = []; - - alltrustRelationships.forEach((tr) => { - if (!ids[tr.id]) { - finalTrustRelationships.push(tr); - ids[tr.id] = 1; - } + state, + type, + request_type, + offset, + limit, }); - - return finalTrustRelationships; } async createTrustRelationship({ diff --git a/server/services/TrustService.spec.js b/server/services/TrustService.spec.js index d5571684..d086fd9c 100644 --- a/server/services/TrustService.spec.js +++ b/server/services/TrustService.spec.js @@ -2,7 +2,6 @@ const sinon = require('sinon'); const chai = require('chai'); const TrustService = require('./TrustService'); const WalletService = require('./WalletService'); -const Wallet = require('../models/Wallet'); const Trust = require('../models/Trust'); const EventService = require('./EventService'); @@ -181,67 +180,41 @@ describe('TrustService', () => { }); it('getAllTrustRelationships', async () => { - const getAllWalletsStub = sinon - .stub(Wallet.prototype, 'getAllWallets') - .resolves({ wallets: [{ id: 'id1' }, { id: 'id2' }] }); - const getTrustRelationshipsStub = sinon.stub( - TrustService.prototype, - 'getTrustRelationships', - ); - getTrustRelationshipsStub - .onFirstCall() - .resolves([ + + const data = { + result: [ { id: 'trustId1' }, { id: 'trustId2' }, { id: 'trustId3' }, { id: 'trustId4' }, - ]); - getTrustRelationshipsStub - .onSecondCall() - .resolves([ - { id: 'trustId1' }, - { id: 'trustId2' }, - { id: 'trustId5' }, - { id: 'trustId6' }, - ]); + ], + count: 4, + } + + const getAllTrustRelationshipsStub = sinon.stub( + TrustService.prototype, + 'getAllTrustRelationships', + ); + getAllTrustRelationshipsStub + .resolves(data); const trustRelationships = await trustService.getAllTrustRelationships({ - walletId: 'walletId', - state: 'state', - type: 'type', - request_type: 'request_type', + state: 'requested', + type: 'send', + request_type: 'send', + limit: 10, + offset: 0, }); - expect(trustRelationships).eql([ - { id: 'trustId1' }, - { id: 'trustId2' }, - { id: 'trustId3' }, - { id: 'trustId4' }, - { id: 'trustId5' }, - { id: 'trustId6' }, - ]); - expect( - getAllWalletsStub.calledOnceWithExactly( - 'walletId', - undefined, - undefined, - 'created_at', - 'desc', - ), - ).eql(true); - expect( - getTrustRelationshipsStub.getCall(0).calledWithExactly({ - walletId: 'id1', - state: 'state', - type: 'type', - request_type: 'request_type', - }), - ).eql(true); + + expect(trustRelationships).eql(data); + expect( - getTrustRelationshipsStub.getCall(1).calledWithExactly({ - walletId: 'id2', - state: 'state', - type: 'type', - request_type: 'request_type', + getAllTrustRelationshipsStub.calledWithExactly({ + state: 'requested', + type: 'send', + request_type: 'send', + limit: 10, + offset: 0, }), ).eql(true); });