diff --git a/src/handlers/settlements/{id}.js b/src/handlers/settlements/{id}.js index 7b536af9..a6c6d23d 100644 --- a/src/handlers/settlements/{id}.js +++ b/src/handlers/settlements/{id}.js @@ -35,7 +35,7 @@ const Boom = require('boom') -const settlement = require('../../domain/settlement/index') +const Settlements = require('../../domain/settlement') const Logger = require('@mojaloop/central-services-shared').Logger const Path = require('path') @@ -57,13 +57,14 @@ module.exports = { try { const Enums = await request.server.methods.enums('settlementStates') request.server.log('info', `get settlement by Id requested with id ${settlementId}`) - let settlementResult = await settlement.getById({ settlementId }, Enums) + let settlementResult = await Settlements.getById({ settlementId }, Enums) return h.response(settlementResult) } catch (e) { request.server.log('error', e) return Boom.notFound(e.message) } }, + /** * summary: Acknowledegement of settlement by updating with Settlements Id. * description: @@ -71,7 +72,6 @@ module.exports = { * produces: application/json * responses: 200, 400, 401, 404, 415, default */ - put: async function updateSettlementById (request) { const settlementId = request.params.id try { @@ -91,9 +91,9 @@ module.exports = { transferStates: await request.server.methods.enums('transferStates') } if (p.participants) { - return await settlement.putById(settlementId, request.payload, Enums) + return await Settlements.putById(settlementId, request.payload, Enums) } else if (p.state && p.state === Enums.settlementStates.ABORTED) { - return await settlement.abortById(settlementId, request.payload, Enums) + return await Settlements.abortById(settlementId, request.payload, Enums) } else { throw new Error('Invalid request payload input') } diff --git a/src/handlers/settlements/{settlementId}/participants/{participantId}.js b/src/handlers/settlements/{settlementId}/participants/{participantId}.js index 8ba49050..6d3fecd4 100644 --- a/src/handlers/settlements/{settlementId}/participants/{participantId}.js +++ b/src/handlers/settlements/{settlementId}/participants/{participantId}.js @@ -65,5 +65,41 @@ module.exports = { request.server.log('error', e) return Boom.badRequest(e) } + }, + + /** + * summary: Acknowledegement of settlement by updating with Settlements Id. + * description: + * parameters: id, participantId, settlementUpdatePayload + * produces: application/json + * responses: 200, 400, 401, 404, 415, default + */ + put: async function updateSettlementById (request) { + const settlementId = request.params.settlementId + const participantId = request.params.participantId + try { + const p = request.payload + const universalPayload = { + participants: [ + { + id: participantId, + accounts: p.accounts + } + ] + } + const Enums = { + ledgerAccountTypes: await request.server.methods.enums('ledgerAccountTypes'), + ledgerEntryTypes: await request.server.methods.enums('ledgerEntryTypes'), + participantLimitTypes: await request.server.methods.enums('participantLimitTypes'), + settlementStates: await request.server.methods.enums('settlementStates'), + settlementWindowStates: await request.server.methods.enums('settlementWindowStates'), + transferParticipantRoleTypes: await request.server.methods.enums('transferParticipantRoleTypes'), + transferStates: await request.server.methods.enums('transferStates') + } + return await Settlements.putById(settlementId, universalPayload, Enums) + } catch (e) { + request.server.log('error', e) + return Boom.badRequest(e) + } } } diff --git a/src/handlers/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}.js b/src/handlers/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}.js index befede6a..4e64e01e 100644 --- a/src/handlers/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}.js +++ b/src/handlers/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}.js @@ -54,5 +54,42 @@ module.exports = { request.server.log('error', e) return Boom.badRequest(e) } + }, + + /** + * summary: Acknowledegement of settlement by updating with Settlements Id. + * description: + * parameters: id, participantId, settlementUpdatePayload + * produces: application/json + * responses: 200, 400, 401, 404, 415, default + */ + put: async function updateSettlementById (request) { + const settlementId = request.params.settlementId + const participantId = request.params.participantId + const accountId = request.params.accountId + try { + const accounts = [Object.assign({}, request.payload, { id: accountId })] + const universalPayload = { + participants: [ + { + id: participantId, + accounts + } + ] + } + const Enums = { + ledgerAccountTypes: await request.server.methods.enums('ledgerAccountTypes'), + ledgerEntryTypes: await request.server.methods.enums('ledgerEntryTypes'), + participantLimitTypes: await request.server.methods.enums('participantLimitTypes'), + settlementStates: await request.server.methods.enums('settlementStates'), + settlementWindowStates: await request.server.methods.enums('settlementWindowStates'), + transferParticipantRoleTypes: await request.server.methods.enums('transferParticipantRoleTypes'), + transferStates: await request.server.methods.enums('transferStates') + } + return await Settlements.putById(settlementId, universalPayload, Enums) + } catch (e) { + request.server.log('error', e) + return Boom.badRequest(e) + } } } diff --git a/src/interface/swagger.json b/src/interface/swagger.json index acb876a6..37e3c6c5 100644 --- a/src/interface/swagger.json +++ b/src/interface/swagger.json @@ -418,43 +418,29 @@ } } }, - "/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}": { + "/settlements/{id}": { "get": { "produces": [ "application/json" ], "deprecated": false, - "summary": "Returns Settlement(s) as per filter criteria.", - "operationId": "getSettlementBySettlementParticipantAccount", + "summary": "Returns Settlement(s) as per parameters/filter criteria.", + "operationId": "getSettlementById", "parameters": [ { "in": "path", - "name": "settlementId", + "name": "id", "required": true, "type": "integer", "description": "A valid Settlement Id.\n" - }, - { - "in": "path", - "name": "participantId", - "required": true, - "type": "integer", - "description": "A valid Participant Id.\n" - }, - { - "in": "path", - "name": "accountId", - "required": true, - "type": "integer", - "description": "A valid Account Id. \n" } ], "tags": [ - "getSettlementBySettlementParticipantAccount" + "getSettlementById" ], "responses": { "200": { - "description": "Settlement, settlement windows and settlement accounts returned by the filtering parameters.", + "description": "Settlement successfully returned by the filtering/Query parameters.", "schema": { "$ref": "#/definitions/Settlement" } @@ -499,42 +485,28 @@ "application/json" ], "deprecated": false, - "summary": "Acknowledegement of settlement by updating the reason and state by Settlements Id, Participant Id and accounts Id.", - "operationId": "updateSettlementBySettlementParticipantAccount", + "summary": "Acknowledegement of settlement by updating with Settlement Id.", + "operationId": "updateSettlementById", "parameters": [ { "in": "path", - "name": "settlementId", + "name": "id", "description": "A valid Settlement Id.", "required": true, "type": "integer" }, - { - "in": "path", - "name": "participantId", - "description": "A valid Participant Id.", - "required": true, - "type": "integer" - }, - { - "in": "path", - "name": "accountId", - "description": "A valid Account Id.", - "required": true, - "type": "integer" - }, { "in": "body", "name": "payload", "description": "A JSON object containing settlement update info.", "schema": { - "$ref": "#/definitions/SettlementUpdateBySettlementParticipantAccount" + "$ref": "#/definitions/SettlementUpdatebySettlementIdPayload" }, "required": true } ], "tags": [ - "updateSettlementBySettlementParticipantAccount" + "updateSettlementById" ], "responses": { "200": { @@ -576,29 +548,36 @@ } } }, - "/settlements/{id}": { + "/settlements/{settlementId}/participants/{participantId}": { "get": { "produces": [ "application/json" ], "deprecated": false, - "summary": "Returns Settlement(s) as per parameters/filter criteria.", - "operationId": "getSettlementById", + "summary": "Returns Settlement(s) as per filter criteria.", + "operationId": "getSettlementBySettlementParticipant", "parameters": [ { "in": "path", - "name": "id", + "name": "settlementId", "required": true, "type": "integer", "description": "A valid Settlement Id.\n" + }, + { + "in": "path", + "name": "participantId", + "required": true, + "type": "integer", + "description": "A valid Participant Id.\n" } ], "tags": [ - "getSettlementById" + "getSettlementBySettlementParticipant" ], "responses": { "200": { - "description": "Settlement successfully returned by the filtering/Query parameters.", + "description": "Settlement, settlement windows and settlement accounts returned by the filtering parameters.", "schema": { "$ref": "#/definitions/Settlement" } @@ -643,28 +622,35 @@ "application/json" ], "deprecated": false, - "summary": "Acknowledegement of settlement by updating with Settlement Id.", - "operationId": "updateSettlementById", + "summary": "Acknowledegement of settlement by updating with Settlements Id and Participant Id.", + "operationId": "updateSettlementBySettlementParticipant", "parameters": [ { "in": "path", - "name": "id", + "name": "settlementId", "description": "A valid Settlement Id.", "required": true, "type": "integer" }, + { + "in": "path", + "name": "participantId", + "description": "A valid Participant Id.", + "required": true, + "type": "integer" + }, { "in": "body", "name": "payload", "description": "A JSON object containing settlement update info.", "schema": { - "$ref": "#/definitions/SettlementUpdatebySettlementIdPayload" + "$ref": "#/definitions/SettlementUpdateBySettlementPartricipantPayload" }, "required": true } ], "tags": [ - "updateSettlementById" + "updateSettlementBySettlementParticipant" ], "responses": { "200": { @@ -706,14 +692,14 @@ } } }, - "/settlements/{settlementId}/participants/{participantId}": { + "/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}": { "get": { "produces": [ "application/json" ], "deprecated": false, "summary": "Returns Settlement(s) as per filter criteria.", - "operationId": "getSettlementBySettlementParticipant", + "operationId": "getSettlementBySettlementParticipantAccount", "parameters": [ { "in": "path", @@ -728,10 +714,17 @@ "required": true, "type": "integer", "description": "A valid Participant Id.\n" + }, + { + "in": "path", + "name": "accountId", + "required": true, + "type": "integer", + "description": "A valid Account Id. \n" } ], "tags": [ - "getSettlementBySettlementParticipant" + "getSettlementBySettlementParticipantAccount" ], "responses": { "200": { @@ -780,8 +773,8 @@ "application/json" ], "deprecated": false, - "summary": "Acknowledegement of settlement by updating with Settlements Id and Participant Id.", - "operationId": "updateSettlementBySettlementParticipant", + "summary": "Acknowledegement of settlement by updating the reason and state by Settlements Id, Participant Id and accounts Id.", + "operationId": "updateSettlementBySettlementParticipantAccount", "parameters": [ { "in": "path", @@ -797,18 +790,25 @@ "required": true, "type": "integer" }, + { + "in": "path", + "name": "accountId", + "description": "A valid Account Id.", + "required": true, + "type": "integer" + }, { "in": "body", "name": "payload", "description": "A JSON object containing settlement update info.", "schema": { - "$ref": "#/definitions/SettlementUpdateBySettlementPartricipantPayload" + "$ref": "#/definitions/SettlementUpdateBySettlementParticipantAccount" }, "required": true } ], "tags": [ - "updateSettlementBySettlementParticipant" + "updateSettlementBySettlementParticipantAccount" ], "responses": { "200": { @@ -989,6 +989,10 @@ "reason": { "type": "string", "example": "string" + }, + "externalReference": { + "type": "string", + "example": "external-reference-abc123" } }, "required": [ diff --git a/test/unit/handlers/settlements/{id}.test.js b/test/unit/handlers/settlements/{id}.test.js index 03b22c91..e8f29ff7 100644 --- a/test/unit/handlers/settlements/{id}.test.js +++ b/test/unit/handlers/settlements/{id}.test.js @@ -105,7 +105,7 @@ Test('/settlements/{id}', async (settlementTest) => { } }) - await settlementTest.test('test settlements get by Id throws', async (t) => { + await settlementTest.test('test settlements get by id throws', async (t) => { sandbox.stub(Enums, 'settlementStates').returns({}) sandbox.stub(settlement, 'getById').throws() try { @@ -151,6 +151,7 @@ Test('/settlements/{id}', async (settlementTest) => { t.end() } }) + await settlementTest.test('test settlements put operation :: putById', async (t) => { sandbox.stub(Enums, 'ledgerAccountTypes').returns({}) sandbox.stub(Enums, 'ledgerEntryTypes').returns({}) @@ -379,7 +380,7 @@ Test('/settlements/{id}', async (settlementTest) => { } }) - await settlementTest.test('test settlements get by params throws', async (t) => { + await settlementTest.test('test settlements put by id throws', async (t) => { sandbox.stub(Enums, 'ledgerAccountTypes').returns({}) sandbox.stub(Enums, 'ledgerEntryTypes').returns({}) sandbox.stub(Enums, 'participantLimitTypes').returns({}) diff --git a/test/unit/handlers/settlements/{settlementId}/participants/{participantId}.test.js b/test/unit/handlers/settlements/{settlementId}/participants/{participantId}.test.js index faf26f2c..283aa95e 100644 --- a/test/unit/handlers/settlements/{settlementId}/participants/{participantId}.test.js +++ b/test/unit/handlers/settlements/{settlementId}/participants/{participantId}.test.js @@ -150,5 +150,116 @@ Test('/settlements/{settlementId}/participants/{participantId}', async (settleme } }) + await settlementTest.test('test settlements put operation :: putById', async (t) => { + sandbox.stub(Enums, 'ledgerAccountTypes').returns({}) + sandbox.stub(Enums, 'ledgerEntryTypes').returns({}) + sandbox.stub(Enums, 'participantLimitTypes').returns({}) + sandbox.stub(Enums, 'settlementStates').returns({}) + sandbox.stub(Enums, 'settlementWindowStates').returns({}) + sandbox.stub(Enums, 'transferParticipantRoleTypes').returns({}) + sandbox.stub(Enums, 'transferStates').returns({}) + sandbox.stub(settlement, 'putById').returns({}) + try { + const requests = new Promise((resolve, reject) => { + Mockgen().requests({ + path: '/settlements/{settlementId}/participants/{participantId}', + operation: 'put' + }, function (error, mock) { + return error ? reject(error) : resolve(mock) + }) + }) + + const mock = await requests + + t.ok(mock) + t.ok(mock.request) + // Get the resolved path from mock request + // Mock request Path templates({}) are resolved using path parameters + const options = { + method: 'put', + url: '/v1' + mock.request.path + } + if (mock.request.body) { + // Send the request body + options.payload = mock.request.body + } else if (mock.request.formData) { + // Send the request form data + options.payload = mock.request.formData + // Set the Content-Type as application/x-www-form-urlencoded + options.headers = options.headers || {} + options.headers['Content-Type'] = 'application/x-www-form-urlencoded' + } + // If headers are present, set the headers. + if (mock.request.headers && mock.request.headers.length > 0) { + options.headers = mock.request.headers + } + + delete options.payload.state + delete options.payload.reason + delete options.payload.externalReference + + const response = await server.inject(options) + t.equal(response.statusCode, 200, 'Ok response status') + t.end() + } catch (e) { + Logger.error(`testing error ${e}`) + t.fail() + t.end() + } + }) + + await settlementTest.test('test settlements put by params throws', async (t) => { + sandbox.stub(Enums, 'ledgerAccountTypes').returns({}) + sandbox.stub(Enums, 'ledgerEntryTypes').returns({}) + sandbox.stub(Enums, 'participantLimitTypes').returns({}) + sandbox.stub(Enums, 'settlementStates').returns({}) + sandbox.stub(Enums, 'settlementWindowStates').returns({}) + sandbox.stub(Enums, 'transferParticipantRoleTypes').returns({}) + sandbox.stub(Enums, 'transferStates').returns({}) + sandbox.stub(settlement, 'putById').throws() + try { + const requests = new Promise((resolve, reject) => { + Mockgen().requests({ + path: '/settlements/{settlementId}/participants/{participantId}', + operation: 'put' + }, function (error, mock) { + return error ? reject(error) : resolve(mock) + }) + }) + + const mock = await requests + + t.ok(mock) + t.ok(mock.request) + // Get the resolved path from mock request + // Mock request Path templates({}) are resolved using path parameters + const options = { + method: 'put', + url: '/v1' + mock.request.path + } + if (mock.request.body) { + // Send the request body + options.payload = mock.request.body + } else if (mock.request.formData) { + // Send the request form data + options.payload = mock.request.formData + // Set the Content-Type as application/x-www-form-urlencoded + options.headers = options.headers || {} + options.headers['Content-Type'] = 'application/x-www-form-urlencoded' + } + // If headers are present, set the headers. + if (mock.request.headers && mock.request.headers.length > 0) { + options.headers = mock.request.headers + } + const response = await server.inject(options) + t.equal(response.statusCode, 400, 'Ok response status') + t.end() + } catch (e) { + Logger.error(`testing error ${e}`) + t.fail() + t.end() + } + }) + await settlementTest.end() -}) \ No newline at end of file +}) diff --git a/test/unit/handlers/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}.test.js b/test/unit/handlers/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}.test.js index ab97f3e3..d61719f8 100644 --- a/test/unit/handlers/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}.test.js +++ b/test/unit/handlers/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}.test.js @@ -146,5 +146,112 @@ Test('/settlements/{settlementId}/participants/{participantId}/account/{accountI } }) + await settlementTest.test('test settlements put operation :: putById', async (t) => { + sandbox.stub(Enums, 'ledgerAccountTypes').returns({}) + sandbox.stub(Enums, 'ledgerEntryTypes').returns({}) + sandbox.stub(Enums, 'participantLimitTypes').returns({}) + sandbox.stub(Enums, 'settlementStates').returns({}) + sandbox.stub(Enums, 'settlementWindowStates').returns({}) + sandbox.stub(Enums, 'transferParticipantRoleTypes').returns({}) + sandbox.stub(Enums, 'transferStates').returns({}) + sandbox.stub(settlement, 'putById').returns({}) + try { + const requests = new Promise((resolve, reject) => { + Mockgen().requests({ + path: '/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}', + operation: 'put' + }, function (error, mock) { + return error ? reject(error) : resolve(mock) + }) + }) + + const mock = await requests + + t.ok(mock) + t.ok(mock.request) + // Get the resolved path from mock request + // Mock request Path templates({}) are resolved using path parameters + const options = { + method: 'put', + url: '/v1' + mock.request.path + } + if (mock.request.body) { + // Send the request body + options.payload = mock.request.body + } else if (mock.request.formData) { + // Send the request form data + options.payload = mock.request.formData + // Set the Content-Type as application/x-www-form-urlencoded + options.headers = options.headers || {} + options.headers['Content-Type'] = 'application/x-www-form-urlencoded' + } + // If headers are present, set the headers. + if (mock.request.headers && mock.request.headers.length > 0) { + options.headers = mock.request.headers + } + + const response = await server.inject(options) + t.equal(response.statusCode, 200, 'Ok response status') + t.end() + } catch (e) { + Logger.error(`testing error ${e}`) + t.fail() + t.end() + } + }) + + await settlementTest.test('test settlements put by params throws', async (t) => { + sandbox.stub(Enums, 'ledgerAccountTypes').returns({}) + sandbox.stub(Enums, 'ledgerEntryTypes').returns({}) + sandbox.stub(Enums, 'participantLimitTypes').returns({}) + sandbox.stub(Enums, 'settlementStates').returns({}) + sandbox.stub(Enums, 'settlementWindowStates').returns({}) + sandbox.stub(Enums, 'transferParticipantRoleTypes').returns({}) + sandbox.stub(Enums, 'transferStates').returns({}) + sandbox.stub(settlement, 'putById').throws() + try { + const requests = new Promise((resolve, reject) => { + Mockgen().requests({ + path: '/settlements/{settlementId}/participants/{participantId}/accounts/{accountId}', + operation: 'put' + }, function (error, mock) { + return error ? reject(error) : resolve(mock) + }) + }) + + const mock = await requests + + t.ok(mock) + t.ok(mock.request) + // Get the resolved path from mock request + // Mock request Path templates({}) are resolved using path parameters + const options = { + method: 'put', + url: '/v1' + mock.request.path + } + if (mock.request.body) { + // Send the request body + options.payload = mock.request.body + } else if (mock.request.formData) { + // Send the request form data + options.payload = mock.request.formData + // Set the Content-Type as application/x-www-form-urlencoded + options.headers = options.headers || {} + options.headers['Content-Type'] = 'application/x-www-form-urlencoded' + } + // If headers are present, set the headers. + if (mock.request.headers && mock.request.headers.length > 0) { + options.headers = mock.request.headers + } + const response = await server.inject(options) + t.equal(response.statusCode, 400, 'Ok response status') + t.end() + } catch (e) { + Logger.error(`testing error ${e}`) + t.fail() + t.end() + } + }) + await settlementTest.end() }) diff --git a/test/util/scripts/settlementTransfer/env.sh b/test/util/scripts/settlementTransfer/env.sh index 90893879..93dd8d0c 100755 --- a/test/util/scripts/settlementTransfer/env.sh +++ b/test/util/scripts/settlementTransfer/env.sh @@ -15,4 +15,4 @@ export CENTRAL_LEDGER_ADMIN_URI_PREFIX=http export CENTRAL_LEDGER_ADMIN_HOST=localhost export CENTRAL_LEDGER_ADMIN_PORT=3001 export CENTRAL_LEDGER_ADMIN_BASE=/ -export EXPIRATION_DATE=2019-01-01T17:00:00.000+00:00 +export EXPIRATION_DATE=2019-03-01T17:00:00.000+00:00