From 5e7d62ddb119483f9b2dac17e17781e5975f04db Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Mon, 23 Apr 2018 12:18:51 +0200 Subject: [PATCH 01/12] :seedling: Add additional filter to api/transactions --- api/controllers/transactions.js | 1 + modules/transactions.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/api/controllers/transactions.js b/api/controllers/transactions.js index 48c4d3b2ea4..e86f133f702 100644 --- a/api/controllers/transactions.js +++ b/api/controllers/transactions.js @@ -54,6 +54,7 @@ TransactionsController.getTransactions = function(context, next) { var params = context.request.swagger.params; var filters = { + address: params.address.value, id: params.id.value, blockId: params.blockId.value, recipientId: params.recipientId.value, diff --git a/modules/transactions.js b/modules/transactions.js index e8e6f5d730d..0fc655021e7 100644 --- a/modules/transactions.js +++ b/modules/transactions.js @@ -102,6 +102,8 @@ __private.list = function(filter, cb) { const params = {}; const where = []; const allowedFieldsMap = { + address: + 't_senderId" IN (${senderId:csv}) OR t_recipientId" IN (${recipientId:csv})', id: '"t_id" = ${id}', blockId: '"t_blockId" = ${blockId}', fromHeight: '"b_height" >= ${fromHeight}', From f41418e050b98a30ad1564f92714d1b334f02a41 Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Mon, 23 Apr 2018 14:46:04 +0200 Subject: [PATCH 02/12] Change param name to senderIdOrRecipientId --- api/controllers/transactions.js | 2 +- modules/transactions.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/controllers/transactions.js b/api/controllers/transactions.js index e86f133f702..e9c90d1fa24 100644 --- a/api/controllers/transactions.js +++ b/api/controllers/transactions.js @@ -54,7 +54,7 @@ TransactionsController.getTransactions = function(context, next) { var params = context.request.swagger.params; var filters = { - address: params.address.value, + senderIdOrRecipientId: params.senderIdOrRecipientId.value, id: params.id.value, blockId: params.blockId.value, recipientId: params.recipientId.value, diff --git a/modules/transactions.js b/modules/transactions.js index 0fc655021e7..1fc9d01eca2 100644 --- a/modules/transactions.js +++ b/modules/transactions.js @@ -102,7 +102,7 @@ __private.list = function(filter, cb) { const params = {}; const where = []; const allowedFieldsMap = { - address: + senderIdOrRecipientId: 't_senderId" IN (${senderId:csv}) OR t_recipientId" IN (${recipientId:csv})', id: '"t_id" = ${id}', blockId: '"t_blockId" = ${blockId}', From 5931c44f42651028c2daeeed7598b48602ec05d9 Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Mon, 23 Apr 2018 14:46:32 +0200 Subject: [PATCH 03/12] Add senderIdOrRecipientId to swagger --- schema/swagger.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/schema/swagger.yml b/schema/swagger.yml index 6a404e45979..e44c54ed5dd 100755 --- a/schema/swagger.yml +++ b/schema/swagger.yml @@ -859,6 +859,7 @@ paths: - $ref: '#/parameters/recipientPublicKey' - $ref: '#/parameters/senderId' - $ref: '#/parameters/senderPublicKey' + - $ref: '#/parameters/senderIdOrRecipientId' - $ref: '#/parameters/transactionType' - $ref: '#/parameters/height' - $ref: '#/parameters/minAmount' @@ -1086,6 +1087,14 @@ parameters: type: string format: publicKey minLength: 1 + senderIdOrRecipientId: + name: senderIdOrRecipientId + in: query + description: Sender or Recipient address to query + type: string + format: address + minLength: 1 + maxLength: 22 transactionType: name: type in: query @@ -1563,6 +1572,7 @@ definitions: - fee - senderPublicKey - recipientId + - senderIdOrRecipientId - timestamp - asset - signature @@ -1615,6 +1625,10 @@ definitions: type: string format: publicKey example: 2ca9a7143fc721fdc540fef893b27e8d648d2288efa61e56264edf01a2c23079 + senderIdOrRecipientId: + type: string + format: address + example: 12668885769632475474L signature: type: string format: signature From e22c2fd4f7b2ab4eb1dd6a79c838a4d405874190 Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Mon, 23 Apr 2018 15:16:26 +0200 Subject: [PATCH 04/12] Add senderIdOrRecipientId property --- schema/swagger.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/schema/swagger.yml b/schema/swagger.yml index e44c54ed5dd..5355c65d5f7 100755 --- a/schema/swagger.yml +++ b/schema/swagger.yml @@ -1176,6 +1176,10 @@ definitions: type: string format: address example: 12668885769632475474L + senderIdOrRecipientId: + type: string + format: address + example: 12668885769632475474L signature: type: string format: signature @@ -1572,7 +1576,6 @@ definitions: - fee - senderPublicKey - recipientId - - senderIdOrRecipientId - timestamp - asset - signature From 04eccfc281d087115495a0ea00184843456a2ac8 Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Mon, 23 Apr 2018 16:54:10 +0200 Subject: [PATCH 05/12] Add missing quotes, remove wrong properties --- modules/transactions.js | 2 +- schema/swagger.yml | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/modules/transactions.js b/modules/transactions.js index 1fc9d01eca2..2ce9229845b 100644 --- a/modules/transactions.js +++ b/modules/transactions.js @@ -103,7 +103,7 @@ __private.list = function(filter, cb) { const where = []; const allowedFieldsMap = { senderIdOrRecipientId: - 't_senderId" IN (${senderId:csv}) OR t_recipientId" IN (${recipientId:csv})', + '"t_senderId" IN (${senderId:csv}) OR "t_recipientId" IN (${recipientId:csv})', id: '"t_id" = ${id}', blockId: '"t_blockId" = ${blockId}', fromHeight: '"b_height" >= ${fromHeight}', diff --git a/schema/swagger.yml b/schema/swagger.yml index 5355c65d5f7..9ef29befefe 100755 --- a/schema/swagger.yml +++ b/schema/swagger.yml @@ -1176,10 +1176,6 @@ definitions: type: string format: address example: 12668885769632475474L - senderIdOrRecipientId: - type: string - format: address - example: 12668885769632475474L signature: type: string format: signature @@ -1628,10 +1624,6 @@ definitions: type: string format: publicKey example: 2ca9a7143fc721fdc540fef893b27e8d648d2288efa61e56264edf01a2c23079 - senderIdOrRecipientId: - type: string - format: address - example: 12668885769632475474L signature: type: string format: signature From 4e141574ac136aa3a22b3e2b38dbae3ed7489f03 Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Mon, 23 Apr 2018 17:14:11 +0200 Subject: [PATCH 06/12] Fix indents --- schema/swagger.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/schema/swagger.yml b/schema/swagger.yml index 9ef29befefe..1e4d9f7c126 100755 --- a/schema/swagger.yml +++ b/schema/swagger.yml @@ -1088,13 +1088,13 @@ parameters: format: publicKey minLength: 1 senderIdOrRecipientId: - name: senderIdOrRecipientId - in: query - description: Sender or Recipient address to query - type: string - format: address - minLength: 1 - maxLength: 22 + name: senderIdOrRecipientId + in: query + description: Public key to query + type: string + format: address + minLength: 1 + maxLength: 22 transactionType: name: type in: query From 9c287d50c14afd40924dcb7fad036b757f8c5a8c Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Tue, 24 Apr 2018 10:38:53 +0200 Subject: [PATCH 07/12] Fix params in query --- modules/transactions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/transactions.js b/modules/transactions.js index 2ce9229845b..4e522f12057 100644 --- a/modules/transactions.js +++ b/modules/transactions.js @@ -103,7 +103,7 @@ __private.list = function(filter, cb) { const where = []; const allowedFieldsMap = { senderIdOrRecipientId: - '"t_senderId" IN (${senderId:csv}) OR "t_recipientId" IN (${recipientId:csv})', + '"t_senderId" IN (${senderIdOrRecipientId:csv}) OR "t_recipientId" IN (${senderIdOrRecipientId:csv})', id: '"t_id" = ${id}', blockId: '"t_blockId" = ${blockId}', fromHeight: '"b_height" >= ${fromHeight}', From 94eeb83cc95c36bccd1eb77e2ae9bf8a8458220e Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Tue, 24 Apr 2018 10:41:01 +0200 Subject: [PATCH 08/12] Add description for new new param --- schema/swagger.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/swagger.yml b/schema/swagger.yml index 1e4d9f7c126..6e7932f25d1 100755 --- a/schema/swagger.yml +++ b/schema/swagger.yml @@ -1090,7 +1090,7 @@ parameters: senderIdOrRecipientId: name: senderIdOrRecipientId in: query - description: Public key to query + description: Sender Id or Recipient Id to query type: string format: address minLength: 1 From cb8f94bd2970402ceeac68fc7e21116afc87e7fc Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Tue, 24 Apr 2018 15:16:14 +0200 Subject: [PATCH 09/12] :white_check_mark: Add functional tests for senderIdOrRecipientId --- test/functional/http/get/transactions.js | 70 +++++++++++++++++++++++- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/test/functional/http/get/transactions.js b/test/functional/http/get/transactions.js index 47dc2d34a8c..7c01de257c8 100644 --- a/test/functional/http/get/transactions.js +++ b/test/functional/http/get/transactions.js @@ -47,16 +47,31 @@ describe('GET /api/transactions', () => { passphrase: accountFixtures.genesis.password, recipientId: account2.address, }); + var transaction3 = lisk.transaction.transfer({ + amount: 10 * constants.normalizer, // 10 LSK + passphrase: account.password, + recipientId: account2.address, + }); // Crediting accounts before(() => { var promises = []; promises.push(apiHelpers.sendTransactionPromise(transaction1)); promises.push(apiHelpers.sendTransactionPromise(transaction2)); + return Promise.all(promises).then(() => { transactionList.push(transaction1); transactionList.push(transaction2); - return waitFor.confirmations(_.map(transactionList, 'id')); + + return waitFor + .confirmations(_.map(transactionList, 'id')) + .then(() => { + return apiHelpers.sendTransactionPromise(transaction3); + }) + .then(() => { + transactionList.push(transaction3); + return waitFor.confirmations([transaction3.id]); + }); }); }); @@ -383,6 +398,52 @@ describe('GET /api/transactions', () => { }); }); + describe('senderIdOrRecipientId', () => { + it('using invalid senderIdOrRecipientId should fail', () => { + return transactionsEndpoint + .makeRequest({ senderIdOrRecipientId: '' }, 400) + .then(res => { + expectSwaggerParamError(res, 'senderIdOrRecipientId'); + }); + }); + + it('using one senderIdOrRecipientId should return incoming and outgoing transaction of an account', () => { + var sender = []; + var recipient = []; + var accountId = account.address; + return transactionsEndpoint + .makeRequest({ senderIdOrRecipientId: accountId }, 200) + .then(res => { + expect(res.body.data).to.not.empty; + res.body.data.map(transaction => { + if (accountId === transaction.recipientId) { + recipient.push(transaction); + } else if (accountId === transaction.senderId) { + sender.push(transaction); + } + }); + expect(sender).to.have.length(1); + expect(recipient).to.have.length(1); + }); + }); + + it('using multiple senderIdOrRecipientId should fail', () => { + return transactionsEndpoint + .makeRequest( + { + senderIdOrRecipientId: [ + accountFixtures.genesis.address, + accountFixtures.existingDelegate.address, + ], + }, + 400 + ) + .then(res => { + expectSwaggerParamError(res, 'senderIdOrRecipientId'); + }); + }); + }); + describe('recipientPublicKey', () => { it('using invalid recipientPublicKey should fail', () => { return transactionsEndpoint @@ -575,11 +636,14 @@ describe('GET /api/transactions', () => { var firstTransaction = null; return transactionsEndpoint - .makeRequest({ offset: 0 }, 200) + .makeRequest({ offset: 0, limit: 1 }, 200) .then(res => { firstTransaction = res.body.data[0]; - return transactionsEndpoint.makeRequest({ offset: 1 }, 200); + return transactionsEndpoint.makeRequest( + { offset: 1, limit: 1 }, + 200 + ); }) .then(res => { res.body.data.forEach(transaction => { From 98e63246bdca5f6b84d3b1305a005212ca42ab50 Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Wed, 25 Apr 2018 14:12:33 +0200 Subject: [PATCH 10/12] Remove csv formatting for senderIdOrRecipientId --- modules/transactions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/transactions.js b/modules/transactions.js index 4e522f12057..b027936e12b 100644 --- a/modules/transactions.js +++ b/modules/transactions.js @@ -103,7 +103,7 @@ __private.list = function(filter, cb) { const where = []; const allowedFieldsMap = { senderIdOrRecipientId: - '"t_senderId" IN (${senderIdOrRecipientId:csv}) OR "t_recipientId" IN (${senderIdOrRecipientId:csv})', + '"t_senderId" IN ${senderIdOrRecipientId} OR "t_recipientId" IN ${senderIdOrRecipientId}', id: '"t_id" = ${id}', blockId: '"t_blockId" = ${blockId}', fromHeight: '"b_height" >= ${fromHeight}', From b5cd640cbe905e7bca29cfdae9e1b4e526b1b618 Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Wed, 25 Apr 2018 14:14:58 +0200 Subject: [PATCH 11/12] Add test for invalid senderIdOrRecipientId, remove unnecessary test --- modules/transactions.js | 2 +- test/functional/http/get/transactions.js | 42 ++++++++---------------- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/modules/transactions.js b/modules/transactions.js index b027936e12b..511680b4cf4 100644 --- a/modules/transactions.js +++ b/modules/transactions.js @@ -103,7 +103,7 @@ __private.list = function(filter, cb) { const where = []; const allowedFieldsMap = { senderIdOrRecipientId: - '"t_senderId" IN ${senderIdOrRecipientId} OR "t_recipientId" IN ${senderIdOrRecipientId}', + '"t_senderId" IN (${senderIdOrRecipientId}) OR "t_recipientId" IN (${senderIdOrRecipientId})', id: '"t_id" = ${id}', blockId: '"t_blockId" = ${blockId}', fromHeight: '"b_height" >= ${fromHeight}', diff --git a/test/functional/http/get/transactions.js b/test/functional/http/get/transactions.js index 7c01de257c8..ffa5dba81d4 100644 --- a/test/functional/http/get/transactions.js +++ b/test/functional/http/get/transactions.js @@ -399,49 +399,33 @@ describe('GET /api/transactions', () => { }); describe('senderIdOrRecipientId', () => { - it('using invalid senderIdOrRecipientId should fail', () => { + it('using empty senderIdOrRecipientId should fail', () => { return transactionsEndpoint .makeRequest({ senderIdOrRecipientId: '' }, 400) .then(res => { expectSwaggerParamError(res, 'senderIdOrRecipientId'); }); }); - - it('using one senderIdOrRecipientId should return incoming and outgoing transaction of an account', () => { - var sender = []; - var recipient = []; - var accountId = account.address; - return transactionsEndpoint - .makeRequest({ senderIdOrRecipientId: accountId }, 200) - .then(res => { - expect(res.body.data).to.not.empty; - res.body.data.map(transaction => { - if (accountId === transaction.recipientId) { - recipient.push(transaction); - } else if (accountId === transaction.senderId) { - sender.push(transaction); - } - }); - expect(sender).to.have.length(1); - expect(recipient).to.have.length(1); - }); - }); - - it('using multiple senderIdOrRecipientId should fail', () => { + it('using invalid senderIdOrRecipientId should fail', () => { return transactionsEndpoint .makeRequest( - { - senderIdOrRecipientId: [ - accountFixtures.genesis.address, - accountFixtures.existingDelegate.address, - ], - }, + { senderIdOrRecipientId: '1234567890123456789012L' }, 400 ) .then(res => { expectSwaggerParamError(res, 'senderIdOrRecipientId'); }); }); + it('using senderIdOrRecipientId should return incoming and outgoing transactions of an account', () => { + var accountId = account.address; + return transactionsEndpoint + .makeRequest({ senderIdOrRecipientId: accountId }, 200) + .then(res => { + expect(res.body.data).to.not.empty; + expect(res.body.data[0].senderId).to.be.eql(accountId); + expect(res.body.data[1].recipientId).to.be.eql(accountId); + }); + }); }); describe('recipientPublicKey', () => { From 3baca6c95933f47c9319300ecc5857a4bf346776 Mon Sep 17 00:00:00 2001 From: Mona Baerenfaenger Date: Wed, 25 Apr 2018 14:50:22 +0200 Subject: [PATCH 12/12] Make filter expect only single address each query --- modules/transactions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/transactions.js b/modules/transactions.js index 511680b4cf4..24920c2b1b2 100644 --- a/modules/transactions.js +++ b/modules/transactions.js @@ -103,7 +103,7 @@ __private.list = function(filter, cb) { const where = []; const allowedFieldsMap = { senderIdOrRecipientId: - '"t_senderId" IN (${senderIdOrRecipientId}) OR "t_recipientId" IN (${senderIdOrRecipientId})', + '"t_senderId" = ${senderIdOrRecipientId} OR "t_recipientId" = ${senderIdOrRecipientId}', id: '"t_id" = ${id}', blockId: '"t_blockId" = ${blockId}', fromHeight: '"b_height" >= ${fromHeight}',