From 34801ac2ce2ac83f9cba541295964c7495069784 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 4 May 2018 11:21:51 +0100 Subject: [PATCH] init --- airbnb.txt | 53 + codes.md | 21 + log.md | 225 +++ meh.md | 113 ++ noted.md | 30 + process.md | 1 + .../BRIDGE-588_update_paytostored_e2e_test.md | 160 ++ tasks/bridge-1001/atps.json | 0 tasks/bridge-1001/comment.md | 0 tasks/bridge-1001/commit-message.md | 17 + tasks/bridge-1001/failed.json | 0 tasks/bridge-1001/rtps.json | 0 tasks/bridge-1001/temp.md | 0 tasks/bridge-1001/what.md | 0 tasks/bridge-646/acceptance.md | 90 ++ tasks/bridge-646/checkin_summary.md | 53 + tasks/bridge-646/dev.md | 109 ++ tasks/bridge-646/payload.json | 35 + tasks/bridge-647/something.md | 0 tasks/bridge-647/tests-dev.md | 467 ++++++ tasks/bridge-760/notes.js | 110 ++ tasks/bridge-764/checkin_summary.md | 22 + tasks/bridge-764/error.txt | 0 tasks/bridge-764/get-rtp-list.e2e.spec.js | 73 + tasks/bridge-779/story.md | 103 ++ tasks/bridge-779/swagger.json | 1248 ++++++++++++++ tasks/bridge-796/checkin-summary.md | 59 + tasks/bridge-796/stuff.md | 40 + tasks/bridge-798/checkin-summary.md | 70 + tasks/bridge-798/errors.md | 64 + tasks/bridge-798/rerun.md | 35 + tasks/bridge-800/checkin-summary.md | 33 + tasks/bridge-800/newstuff.md | 72 + tasks/bridge-800/swagger.json | 1439 +++++++++++++++++ tasks/bridge-801/checkin-summary.md | 43 + tasks/bridge-822/what.md | 42 + tasks/bridge-826/step01.md | 141 ++ tasks/bridge-826/tests.md | 74 + tasks/bridge-826/what.md | 42 + tasks/bridge-837/checkin-summary.md | 68 + tasks/bridge-837/swagger | 35 + tasks/bridge-838/checkin-summary.md | 34 + tasks/bridge-839/what.md | 61 + tasks/bridge-844/swagger | 0 tasks/bridge-844/what | 17 + tasks/bridge-858/Untitled-15 | 130 ++ tasks/bridge-858/check | 86 + tasks/bridge-858/checkin-summary.md | 33 + tasks/bridge-858/structure | 80 + tasks/bridge-860/checkin-summary.md | 43 + tasks/bridge-860/get-all-atps-for-rtp.spec.js | 46 + tasks/bridge-860/what.md | 61 + tasks/bridge-868/checkin-summary.md | 54 + tasks/bridge-877/checkin-summary.md | 12 + tasks/bridge-885/checkin-summary.md | 64 + tasks/bridge-885/stuff | 112 ++ tasks/bridge-895/test.md | 63 + tasks/bridge-895/what.md | 0 tasks/bridge-895/writeup.md | 0 tasks/bridge-901/checkin-summary.md | 61 + tasks/bridge-922/checkin-summary.md | 67 + tasks/bridge-922/structure.md | 0 tasks/bridge-922/what.md | 0 tasks/bridge_592/tests.md | 120 ++ tasks/bridge_619/tests.dev.md | 421 +++++ tasks/bridge_619/tests.md | 416 +++++ useful/good-e2e-tests.spec.js | 144 ++ useful/test.xsl | 47 + 68 files changed, 7359 insertions(+) create mode 100644 airbnb.txt create mode 100644 codes.md create mode 100644 log.md create mode 100644 meh.md create mode 100644 noted.md create mode 100644 process.md create mode 100644 tasks/BRIDGE-588_update_paytostored_e2e_test.md create mode 100644 tasks/bridge-1001/atps.json create mode 100644 tasks/bridge-1001/comment.md create mode 100644 tasks/bridge-1001/commit-message.md create mode 100644 tasks/bridge-1001/failed.json create mode 100644 tasks/bridge-1001/rtps.json create mode 100644 tasks/bridge-1001/temp.md create mode 100644 tasks/bridge-1001/what.md create mode 100644 tasks/bridge-646/acceptance.md create mode 100644 tasks/bridge-646/checkin_summary.md create mode 100644 tasks/bridge-646/dev.md create mode 100644 tasks/bridge-646/payload.json create mode 100644 tasks/bridge-647/something.md create mode 100644 tasks/bridge-647/tests-dev.md create mode 100644 tasks/bridge-760/notes.js create mode 100644 tasks/bridge-764/checkin_summary.md create mode 100644 tasks/bridge-764/error.txt create mode 100644 tasks/bridge-764/get-rtp-list.e2e.spec.js create mode 100644 tasks/bridge-779/story.md create mode 100644 tasks/bridge-779/swagger.json create mode 100644 tasks/bridge-796/checkin-summary.md create mode 100644 tasks/bridge-796/stuff.md create mode 100644 tasks/bridge-798/checkin-summary.md create mode 100644 tasks/bridge-798/errors.md create mode 100644 tasks/bridge-798/rerun.md create mode 100644 tasks/bridge-800/checkin-summary.md create mode 100644 tasks/bridge-800/newstuff.md create mode 100644 tasks/bridge-800/swagger.json create mode 100644 tasks/bridge-801/checkin-summary.md create mode 100644 tasks/bridge-822/what.md create mode 100644 tasks/bridge-826/step01.md create mode 100644 tasks/bridge-826/tests.md create mode 100644 tasks/bridge-826/what.md create mode 100644 tasks/bridge-837/checkin-summary.md create mode 100644 tasks/bridge-837/swagger create mode 100644 tasks/bridge-838/checkin-summary.md create mode 100644 tasks/bridge-839/what.md create mode 100644 tasks/bridge-844/swagger create mode 100644 tasks/bridge-844/what create mode 100644 tasks/bridge-858/Untitled-15 create mode 100644 tasks/bridge-858/check create mode 100644 tasks/bridge-858/checkin-summary.md create mode 100644 tasks/bridge-858/structure create mode 100644 tasks/bridge-860/checkin-summary.md create mode 100644 tasks/bridge-860/get-all-atps-for-rtp.spec.js create mode 100644 tasks/bridge-860/what.md create mode 100644 tasks/bridge-868/checkin-summary.md create mode 100644 tasks/bridge-877/checkin-summary.md create mode 100644 tasks/bridge-885/checkin-summary.md create mode 100644 tasks/bridge-885/stuff create mode 100644 tasks/bridge-895/test.md create mode 100644 tasks/bridge-895/what.md create mode 100644 tasks/bridge-895/writeup.md create mode 100644 tasks/bridge-901/checkin-summary.md create mode 100644 tasks/bridge-922/checkin-summary.md create mode 100644 tasks/bridge-922/structure.md create mode 100644 tasks/bridge-922/what.md create mode 100644 tasks/bridge_592/tests.md create mode 100644 tasks/bridge_619/tests.dev.md create mode 100644 tasks/bridge_619/tests.md create mode 100644 useful/good-e2e-tests.spec.js create mode 100644 useful/test.xsl diff --git a/airbnb.txt b/airbnb.txt new file mode 100644 index 0000000..c7dfa3a --- /dev/null +++ b/airbnb.txt @@ -0,0 +1,53 @@ +Hi. I spoke to Caroline yesterday about the over night temperature in the room. It has been very cold, and it has been going down to at 13c / 14c these past two nights. It was much colder the previous week, so cold that I could not stay there for several nights ( including the nights there was no actual heating or hot water ). She does not want me using a small heating fan to help raise the temperature a bit but I find her solution of extra duvets to not be great. + +As someone who suffers from asthma, waking up in a 13c, damp room is giving me concerns for my health. + + + + + + + + + + + + + + + +Hi, + +Our next bathroom sale ends Friday 27th April - Please see link at the bottom of this email. + +For goods in question from this auction, delivery will be £20 + VAT (£24 in total) + +Delivery is to UK mainland only. Scottish Isles & Ireland will be more, please email for a quote. + +If you would like to go ahead please send payment to: + +Clearance Stock Supplies Limited + +Santander Bank + +Sort Code: 09-01-29 + +Account Number: 069 818 39 + + + +Please leave your buyer/order number as a reference, we will not be able to track your payment without this. + + + +Once payment has been sent, please forward a telephone number and your delivery address by replying to this email. + + + +Delivery Times (approx.) + +For Pallets please allow 3-5 Working Days. + +For Parcels please allow 1-3 Working Days. + + \ No newline at end of file diff --git a/codes.md b/codes.md new file mode 100644 index 0000000..7109264 --- /dev/null +++ b/codes.md @@ -0,0 +1,21 @@ +### Bitbucket ### + +27453392 +20039015 +36545995 +87248887 +02408931 +38002416 + +### Google ### + +6407 2843 +1087 1854 +6646 1575 +4262 5428 +0598 3084 +8242 4502 +4017 1063 +8204 1638 +2674 6962 +6923 6580 \ No newline at end of file diff --git a/log.md b/log.md new file mode 100644 index 0000000..40d3267 --- /dev/null +++ b/log.md @@ -0,0 +1,225 @@ +## Log ## + + +##### 2018-03-19 // Monday ##### + +**[BRIDGE_592](https://comcarde.atlassian.net/browse/BRIDGE-592)** Use validated `req.swagger.params.body.value` not unvalidated `req.body` in controllers + +##### 2018-03-20 // Tuesday ##### + +Continuing and finishing BRIDGE_592 + +##### 2018-03-21 // Wednesday ##### + +Started working on BRIDGE_588: Updating e2e tests using the new testing helpers. + +##### 2018-03-22 // Thursday ##### + +Continuing and finishing BRIDGE_588 + +updated pay-to-stored-worldpay-account.e2e.spec.js to use the new testing helper. + +Tests finally past + +##### 2018-03-23 // Friday ##### + +Started looking at BRIDGE-619, the main story for generating aa receive code. + +Creating swagger end point for receivecode + +Creating tests for receivecode + +--- + + +##### 2018-03-26 // Monday ##### +Fixed a few issues with receivecodes stub. +Returning the 502 code required {info, code} +Recommitted, and merged + +##### 2018-03-27 // Tuesday ##### +BRIDGE-641 Make sure everything works as expected + +Worked through the acceptance criteria and documented all results. + +##### 2018-03-28 // Wednesday ##### + +BRIDGE-641 - Redo acceptance critereia tests on dev? + +BRIDGE-646 - Start Implement for Bridge-643 'As a User I want to be able to redeem a receivecode with a new credit/debit card' + +Started writing redeem.spec.js + +##### 2018-03-29 // Thursday ##### + +BRIDGE-646 - Continuing with this item, finishing the tests. + +*DONE* BRIDGE-641 - Redo acceptance criteria tests on dev. I have login and db details now. + +##### 2018-03-30 // Friday ##### + +BRIDGE-646 - Starting E2E tests for using a receivecode with a new credit/debit card, expanding other tests + +--- + + +##### 2018-04-02 // Monday ##### + +BRIDGE-646 - Plugged my code into the work by John from BRIDGE-644 + +Updated tests to work with this merged code + +Updated code to work with the new renaming Expiry work from Richard + +##### 2018-04-03 // Tuesday ##### + +*DONE* Finally merged the code for BRIDGE-646. Task moved to done + +*DONE* Picked up BRIDGE-647 Make sure everything works as expected + +*DONE* Picked up BRIDGE-749 No compliance log entry for this story, updated confluence [https://comcarde.atlassian.net/wiki/spaces/TA/pages/96108550/Make+a+Worldpay+payment+using+a+receivecode+and+Payment+Instrument+Payment+Details+POST+payments+receivecode] + +##### 2018-04-04 // Wednesday ##### + +Sprint planning + +##### 2018-04-05 // Thursday ##### + +Writing user story and tasks for Cancelling RTPs - BRIDGE-779 + +Started BRIDGE-760 - Swagger definition + +##### 2018-04-06 // Friday ##### + +*DONE* BRIDGE-760 - Swagger definition +Started BRIDGE-764 - E2E Test of swagger spec + +--- + +##### 2018-04-09 // Monday ##### + +BRIDGE-764 - E2E Test of swagger spec +Started BRIDGE-796 - Create a robust getByQuery + +##### 2018-04-10 // Tuesday ##### + +*DONE* Continuing with BRIDGE-796 + +*DONE* Started BRIDGE-798 - Swagger response example values do not match actual + +Continued BRIDGE-764 now that BRIDGE0796, BRIDGE-798 are complete + +##### 2018-04-11 // Wednesday ##### + +*DONE* BRIDGE-764 - E2E tests for RPT list + +Created story and tasks for BRIDGE-813 - As a system, I want my receivables objects to be identified as such + +Created story and tasks for BRIDGE-867 - As an operator, I want to list all ATPs related to my receivable RTP + +Created story and tasks for BRIDGE-857 - As a user I want to list all ATPs related to my payable RTP + +##### 2018-04-12 // Thursday ##### + +*DONE* Started BRIDGE-800 - Swagger def + +Started BRIDGE-801 - E2E Tests of Swagger Def + +##### 2018-04-13 // Friday ##### + +*DONE* BRIDGE-801 - E2E Tests of Swagger Def + +Started BRIDGE-858 - Update swagger def + + +--- + +##### 2018-04-16 // Monday ##### + +*DONE* BRIDGE-858 - Update swagger def + + +##### 2018-04-17 // Tuesday ##### + +Started BRIDGE-860 - E2E tests for swagger + +*DONE* Started BRIDGE-885 - Swagger UI for list returns a single ATP. + + +##### 2018-04-18 // Wednesday ##### + +Sprint planning + +BRIDGE-885 - Swagger UI for list returns a single ATP. + +*DONE* Started BRIDGE-837 - Update swagger def + +Fixed small issue with BRIDGE-868 + +##### 2018-04-19 // Thursday ##### + +Started BRIDGE-838 - E2E tests for swagger + +Started BRIDGE-844 - Update swagger def + +##### 2018-04-20 // Friday ##### + +*DONE* BRIDGE-838 - E2E tests for swagger + +Started BRIDGE-838 - Implementation + +Started BRIDGE-822 - As a user I want to pay an RTP in full (using stored or new instrument) + +--- + +##### 2018-04-23 // Monday ##### + +Ill + +##### 2018-04-24 // Tuesday ##### + +*DONE* BRIDGE-860 - e2e test swagger + +*DONE* Started BRIDGE-877 - Spelling mistake in "Merhcant" error message + +*DONE* Started BRIDGE-901 - Unit test decrypt-card.spec.js sometimes fails due to MS difference + +##### 2018-04-25 // Wednesday ##### + +Started BRODGE-895 - INVESTIGATION: check if TTL query deletions can be ignored based on another property + +##### 2018-04-26 // Thursday ##### + +Ill + +##### 2018-04-27 // Friday ##### + +Ill + +--- + +##### 2018-04-30 // Monday ##### + +Started BRIDGE-922 - Swagger E2E tests + +##### 2018-05-01 // Tuesday ##### + +*DONE* BRIDGE-922 - Swagger E2E tests + +##### 2018-05-02 // Wednesday ##### + +Sprint Planning + +Started BRIDGE-1001 - processorResponse inconsistent location + +##### 2018-04-03 // Thursday ##### + +BRIDGE-1001 - processorResponse inconsistent location + +##### 2018-04-04 // Friday ##### + +*DONE* BRIDGE-1001 - processorResponse inconsistent location + +Started BRIDGE-923 - Implementation + + diff --git a/meh.md b/meh.md new file mode 100644 index 0000000..257f13b --- /dev/null +++ b/meh.md @@ -0,0 +1,113 @@ +As an operator, I want to list all ATPs related to my receivable RTP + +## Summary ## + +Operator see a list of all ATPs related to this RTP where I am the payee + +## Acceptance Criteria ## + + +1. I will see basic details on ALL related ATPs + +**Given** that I am an authorised Bridge user + +AND I am the RTP PAYEE + +GET /receivables/rtps/{rtpID}/atps + +THEN request returns basic details on ALL related ATPs + + +2. I will see full payeeInstrument info (as RTP payee is always ATP payee) + +**Given** that I am an authorised Bridge user + +AND I am the RTP PAYEE + +AND I am also the ATP payee + +GET /receivables/rtps/{rtpID}/atps + +THEN request returns full payeeInstrument info for ALL related ATPs + + + +3. I will see full payerInstrument info + +**Given** that I am an authorised Bridge user + +AND I am the RTP PAYEE + +AND I am the ATP PAYER + +GET /receivables/rtps/{rtpID}/atps + +THEN request returns full payeeInstrument info for ALL related ATPs + + +4. I will see reduced/no payerInstrument info + +**Given** that I am an authorised Bridge user + +AND I am the RTP PAYEE + +AND I am NOT the ATP PAYER + +GET /receivables/rtps/{rtpID}/atps + +THEN request returns reduced/no payerInstrument info for ALL related ATPs + + + +5. The wiki is updated + + + + + +--- + + +Update swagger def + +Implementation + +E2E tests of swagger def + +Update E2E tests + +Update integration tests + +Manual tests + +Automated tests + +Update wiki + +Make sure everything works + + + + + +As an operator, I want to list all ATPs related to my receivable RTP + + +GET /receivables/rtps/{rtpID}/atps + +: list all ATPs related to this RTP where I am the payee + +RTP PAYEE only can call + +Will see basic details on ALL related ATPs + +Will see full payeeInstrument info (as RTP payee is always ATP payee) + +Will see full payerInstrument info IF they ARE also the ATP payer + +Will see reduced/no payerInstrument info IF they ARE NOT also the ATP payer + + + + +As a user I want to list all ATPs where I am the payer \ No newline at end of file diff --git a/noted.md b/noted.md new file mode 100644 index 0000000..24dcfa6 --- /dev/null +++ b/noted.md @@ -0,0 +1,30 @@ +## WorldPay Keys ## + +#### API Keys #### + +``` +2b8b6d93-131a-45c7-900e-661bb91fe629 +``` + +#### Service Key #### + +``` +T_S_7c8551db-2aa0-489d-b80e-d1a8d42e4bfb +``` + +#### Client Key #### + +``` +T_C_97abb455-15d4-4d1d-9f6c-13aec73c5590 +``` + +#### dev db access #### + +martin fjJsL9qXP50GsUlQxkwL + + + + +Bearer YTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU1 +Bearer YTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU2 +Bearer YTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU3 \ No newline at end of file diff --git a/process.md b/process.md new file mode 100644 index 0000000..7d0f86b --- /dev/null +++ b/process.md @@ -0,0 +1 @@ +Oh and, don't forget to rebase your branch onto master, then force push, before merging (as there have been updates to master). Then update the task in Jira. \ No newline at end of file diff --git a/tasks/BRIDGE-588_update_paytostored_e2e_test.md b/tasks/BRIDGE-588_update_paytostored_e2e_test.md new file mode 100644 index 0000000..e7ac2ae --- /dev/null +++ b/tasks/BRIDGE-588_update_paytostored_e2e_test.md @@ -0,0 +1,160 @@ +BRIDGE-588_update_paytostored_e2e_test + +# Summary + +Update the pay-to-stored-worldpay-account.e2e.spec.js file with the new method of testing which uses e2e-helper.js + +# Test Plan + +* Unit tests run and pass + +```bash + E2E: dev api Worldpay payment for saved merchant request + tests with missing required parameters +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument parameters (60ms) +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no receiveInstrument parameters +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no amount parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no transactionDetails parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.payer parameters +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.payer.email parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.payer.firstName parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.payer.lastName parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.card parameters +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.card.nameOnCard parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.card.PAN parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.card.expiryDate parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.card.address parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.card.address.address1 parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:25 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.card.address.town parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no paymentInstrument.card.address.postcode parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no transactionDetails.worldpay parameters +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with no receiving account encryption key + bad data format tests +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with an invalid paymentInstrument email parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with an invalid payer first name parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with an invalid payer last name parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a bad card PAN parameter containing a letter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a bad card PAN parameter with a trailing space +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a bad character in the payment card expiry date parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a bad month number in the payment card expiry date parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted payment card start date parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a bad month number in the payment card start date parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted payment card issue number parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted payment card CV2 parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a card address line 1 too long +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a card address line 1 too short +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted card address line 2 parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted card address line 3 parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted card address town name parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted card address county name parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted card address postcode parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted card address phone number parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted order description parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted receiving account encryption key parameter +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a badly formatted amount value parameter + - with a badly formatted instrument ID + invalid card ID +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/aaaaaa/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ with a short card ID +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/zzzzzzzzzzzzzzzzzzzzzzzz/payments HTTP/1.1" 400 - "-" "node-superagent/3.8.2" + + ✓ card ID with an invalid pattern + Good parameter data tests +[2018-03-23T10:42:26.532Z undefined (VIP undefined)] CRITICAL (mainDB.findOneObject) from System at 127.0.0.1: Database offline; cannot find object. TRIED TO FIND: {"_id":"deadbeefdeadbeefdeadbeef","UserID":"79a26d981246978135edadf1","AccountType":"Worldpay Online Payments Account"} +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 502 33 "-" "node-superagent/3.8.2" + + ✓ with the minimum set of correct parameters +[2018-03-23T10:42:26.548Z undefined (VIP undefined)] CRITICAL (mainDB.findOneObject) from System at 127.0.0.1: Database offline; cannot find object. TRIED TO FIND: {"_id":"deadbeefdeadbeefdeadbeef","UserID":"79a26d981246978135edadf1","AccountType":"Worldpay Online Payments Account"} +::ffff:127.0.0.1 - 79a26d981246978135edadf1 [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 502 33 "-" "node-superagent/3.8.2" + + ✓ with a full set of correct parameters + authorization +::ffff:127.0.0.1 - - [23/Mar/2018:10:42:26 +0000] "POST /dev/v0/payment-instruments/worldpay-merchants/deadbeefdeadbeefdeadbeef/payments HTTP/1.1" 401 - "-" "node-superagent/3.8.2" + + ✓ is required to access the path + + + 45 passing (1s) + 1 pending + ``` \ No newline at end of file diff --git a/tasks/bridge-1001/atps.json b/tasks/bridge-1001/atps.json new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-1001/comment.md b/tasks/bridge-1001/comment.md new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-1001/commit-message.md b/tasks/bridge-1001/commit-message.md new file mode 100644 index 0000000..410302f --- /dev/null +++ b/tasks/bridge-1001/commit-message.md @@ -0,0 +1,17 @@ +BRIDGE-1001 processorResponse inconsistent location + +# Summary + +If there was a WorldPay error when an ATP was being created, the ResultDetails were being included inside ErrorDetails. + +* Swagger definition for ErrorDetails was updated to prevent anything other than the specified details being included. +* get-all-atps-for-rtp.spec.js was updated to test that swagger prevents ResultDetails from appearing in ErrorDetails +* controllers/atps/payables/create.js updated to move ProcessorResponse out of ErrorDetails and is now a child of ResultDetails +* tests refreshed using the new test framework + +# Test Plan + +* Run All tests +* Run E2E: get All ATPs + +Test Results diff --git a/tasks/bridge-1001/failed.json b/tasks/bridge-1001/failed.json new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-1001/rtps.json b/tasks/bridge-1001/rtps.json new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-1001/temp.md b/tasks/bridge-1001/temp.md new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-1001/what.md b/tasks/bridge-1001/what.md new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-646/acceptance.md b/tasks/bridge-646/acceptance.md new file mode 100644 index 0000000..f174434 --- /dev/null +++ b/tasks/bridge-646/acceptance.md @@ -0,0 +1,90 @@ +## Summary ## + +As a user, I want to be able to redeem a receivecode, so that I can pay given credit or debit card (in the body of the request) + +### Acceptance Criteria ### + +1. User redeems receivecode with given credit or debit card (in the body of the request) + + Given that I am an authorised Bridge user + + When I make a request to POST /payments/receivecode + + And I have specified other details as per DONE (apart from payee details) in the request body + + And I specify a receivecode string in the request body + + And the receivecode exists + + And the receivecode has not been redeemed + + And the receivecode has not expired + + And I specify a valid amount + + And I specify a valid order description + + Then the payment is processed as per BRIDGE‌-325 + +2. Receivecode does not exist + + Given that I am an authorised Bridge user + + When I make a request to POST /payments/receivecode + + And I have specified other details as per (apart from payee details) in the request body + + And I specify a receivecode string in the request body + + And the receivecode does not exist + + Then the request fails with status 400 + + And the response body contains information about the failure + +3. Receivecode has expired + + Given that I am an authorised Bridge user + + When I make a request to POST /payments/receivecode + + And I have specified other details as per DONE (apart from payee details) in the request body + + And I specify a receivecode string in the request body + + And the receivecode exists + + And the receivecode has not been redeemed + + And the receivecode has expired + + Then the request fails with status 400 + + And the response body contains information about the failure + +4. Receivecode has already been redeemed + + Given that I am an authorised Bridge user + + When I make a request to POST /payments/receivecode + + And I have specified other details as per DONE (apart from payee details) in the request body + + And I specify a receivecode string in the request body + + And the receivecode exists + + And the receivecode has been redeemed + + Then the request fails with status 400 + +5. Request should be logged + + Given that I have made a request as per the other scenarios on this story + + When the request is processed + + Then compliance information about the request and response is logged to the database + +6. Wiki should be updated + diff --git a/tasks/bridge-646/checkin_summary.md b/tasks/bridge-646/checkin_summary.md new file mode 100644 index 0000000..b8395ee --- /dev/null +++ b/tasks/bridge-646/checkin_summary.md @@ -0,0 +1,53 @@ +# Summary + +When redeeming a receiveCode, if PaymentDetails are passed through instead of a PaymentInstrument, then it should be processed as a new Credit / Credit card. + +This revision connects the `receivecode_controller` to `pay-with-saved-details/redeem-receivecode/redeem.js` + +# Details + +`pay-with-saved-details/redeem-receivecode/redeem.js` was created to process using a receiveCode with new Payment Details instead of an exising Payment Instrument. + +Unit tests were create to test this new functionality. + + +# Test Plan: + +* All unit tests run and pass +* Test results for blah are: + +``` + aquirers.worldpay.pay-directly.redeem-receivecode.redeem + User redeems receivecode with given credit or debit card + ✓ it finds the receivecode and updates it from Pending to Payment Started + ✓ it decrypts the worldpay data + ✓ calls makePayment correctly + ✓ it deletes the receivecode + ✓ returns a success + can't find the receivecode to update the Status to Paid + ✓ it finds the receivecode and updates it from Pending to Payment Started + ✓ it updates receivecode Status from Payment Started to Paid + ✓ it decrypts worldpay the data + ✓ it fails to make the payment + ✓ returns a success + Worldpay rejects the payment + ✓ it finds the receivecode and updates it from Pending to Payment Started + ✓ it updates receivecode Status from Payment Started to Pending + ✓ it decrypts worldpay the data + ✓ it fails to make the payment + ✓ throws an error + fails to update the receivecode Status to Paid + ✓ it finds the receivecode and updates it from Pending to Payment Started + ✓ it updates receivecode Status from Payment Started to Paid + ✓ it decrypts worldpay the data + ✓ it fails to make the payment + ✓ returns a success + Failures + can't find the receivecode instrument on DB + ✓ returns error + + + 21 passing (85ms) + + +``` \ No newline at end of file diff --git a/tasks/bridge-646/dev.md b/tasks/bridge-646/dev.md new file mode 100644 index 0000000..6bc0e32 --- /dev/null +++ b/tasks/bridge-646/dev.md @@ -0,0 +1,109 @@ +Re-authorise with : + +``` +Bearer YTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU1 + +``` + +Red Taurus Details + + +```json +{ + "key": "080a89f1-1fde-4a24-ab9d-3de04a0bf9dc", + "ID": "5ac231e56b7bdbf37d165370" +} +``` + +Codes + +```json +{ + "receivecode": "RWXSG" +} +``` + + + +{ + "receivecode": "RWXSG", + "payerInstrument": { + "ID": "000000000000000000000000", + "key": "00000000-0000-0000-0000-000000000000" + }, + "paymentDetails": { + payer: { + email: 'a@b.com', + firstName: 'John', + lastName: 'Doe' + }, + card: { + CV2: undefined, + nameOnCard: 'John E Doe', + PAN: '4444 3333 2222 1111', + expiryDate: '01-20', + startDate: '01-00', + issueNumber: 1, + address: { + address1: 'Flat 20', + address2: 'Victoria House', + address3: '15 The Street', + town: 'Christchurch', + county: 'Dorset', + postcode: 'BH23 6AA', + phoneNumber: '+44 123 1110000' + } + } +}, + "amount": { + "value": 1 + }, + "transactionDetails": { + "worldpay": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + } + } +} + + + + +{ + "receivecode": "RWXSG", + "paymentDetails": { + "payer": { + email: 'a@b.com', + firstName: 'John', + lastName: 'Doe' + }, + card: { + CV2: undefined, + nameOnCard: 'John E Doe', + PAN: '4444 3333 2222 1111', + expiryDate: '01-20', + startDate: '01-00', + issueNumber: 1, + address: { + address1: 'Flat 20', + address2: 'Victoria House', + address3: '15 The Street', + town: 'Christchurch', + county: 'Dorset', + postcode: 'BH23 6AA', + phoneNumber: '+44 123 1110000' + } + } +}, + "amount": { + "value": 1 + }, + "transactionDetails": { + "worldpay": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + } + } +} + + + +/Users/martin/.nvm/versions/node/v8.10.0/bin/node /Users/martin/dev/bridge-node-server/node_server/node_modules/mocha/bin/_mocha --file /Users/martin/dev/bridge-node-server/node_server/test/init_mocha.js --file /Users/martin/dev/bridge-node-server/node_server/tools/test/testGlobals.js --exit --reporter spec --ui bdd /Users/martin/dev/bridge-node-server/node_server/dev_api/controllers/acquirers/worldpay/pay-directly/redeem-receivecode/redeem.spec.js --grep "aquirers\.worldpay\.pay\-directly\.redeem\-receivecode\.redeem " diff --git a/tasks/bridge-646/payload.json b/tasks/bridge-646/payload.json new file mode 100644 index 0000000..bd6e309 --- /dev/null +++ b/tasks/bridge-646/payload.json @@ -0,0 +1,35 @@ +{ + "receivecode": "RWXSG", + "paymentDetails": { + "payer": { + "email": "a@b.com", + "firstName": "John", + "lastName": "Doe" + }, + "card": { + "CV2": undefined, + "nameOnCard": "John E Doe", + "PAN": "4444 3333 2222 1111", + "expiryDate": "01-20", + "startDate": "01-00", + "issueNumber": 1, + "address": { + "address1": "Flat 20", + "address2": "Victoria House", + "address3": "15 The Street", + "town": "Christchurch", + "county": "Dorset", + "postcode": "BH23 6AA", + "phoneNumber": "+44 123 1110000" + } + } +}, + "amount": { + "value": 1 + }, + "transactionDetails": { + "worldpay": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + } + } +} \ No newline at end of file diff --git a/tasks/bridge-647/something.md b/tasks/bridge-647/something.md new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-647/tests-dev.md b/tasks/bridge-647/tests-dev.md new file mode 100644 index 0000000..cdaad8f --- /dev/null +++ b/tasks/bridge-647/tests-dev.md @@ -0,0 +1,467 @@ +# Acceptance Criteria # + +The following acceptance criteria tests were performed on DEV. + +### 1. User redeems receivecode with given credit or debit card ### + +Authorise with : + +``` +Bearer YTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU1 + +``` + +Create Worldpay Merchant + +```json +{ + "key": "1ae580b2-0b9e-4864-a0f8-a4db14e4495a", + "ID": "5ac3587872999f1ef044d2d5" +} +``` + +Create Receive Code + +Using : `/receivecodes` + +```json +{ + "key": "1ae580b2-0b9e-4864-a0f8-a4db14e4495a", + "ID": "5ac3587872999f1ef044d2d5" +} +``` + +Response + +```json +{ + "receivecode": "SAE7K" +} +``` + +Redeem Receive Code using Credit card details + +```json +{ + "receivecode": "SAE7K", + "paymentDetails": { + "payer": { + "email": "a@b.com", + "firstName": "John", + "lastName": "Doe" + }, + "card": { + "nameOnCard": "John E Doe", + "PAN": "4444 3333 2222 1111", + "expiryDate": "01-20", + "startDate": "01-00", + "issueNumber": 1, + "address": { + "address1": "Flat 20", + "address2": "Victoria House", + "address3": "15 The Street", + "town": "Christchurch", + "county": "Dorset", + "postcode": "BH23 6AA", + "phoneNumber": "+44 123 1110000" + } + } +}, + "amount": { + "value": 1 + }, + "transactionDetails": { + "worldpay": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + } + } +} + +``` + +Server Response +```json +{ + "transaction": { + "id": "714d09e0-bd85-4588-9ed9-444316030f1b" + } +} +``` + + +### 2. Receivecode does not exist ### + +Use non-existent receivecode: `F2EE5` + +Redeem Receive Code using Credit card details + +```json +{ + "receivecode": "F2EE5", + "paymentDetails": { + "payer": { + "email": "a@b.com", + "firstName": "John", + "lastName": "Doe" + }, + "card": { + "nameOnCard": "John E Doe", + "PAN": "4444 3333 2222 1111", + "expiryDate": "01-20", + "startDate": "01-00", + "issueNumber": 1, + "address": { + "address1": "Flat 20", + "address2": "Victoria House", + "address3": "15 The Street", + "town": "Christchurch", + "county": "Dorset", + "postcode": "BH23 6AA", + "phoneNumber": "+44 123 1110000" + } + } +}, + "amount": { + "value": 1 + }, + "transactionDetails": { + "worldpay": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + } + } +} + +``` + +Server Response +```json +{ + "code": 608, + "info": "The receivecode could not be found or has expired." +} + +``` + +### 3. Receivecode has expired ### + +Create Receive Code + +Using : `/receivecodes` + +```json +{ + "key": "1ae580b2-0b9e-4864-a0f8-a4db14e4495a", + "ID": "5ac3587872999f1ef044d2d5" +} +``` + +Response + +```json +{ + "receivecode": "VPCHT" +} +``` + +Wait for 4 minutes + +Redeem Receive Code using Credit card details + +```json +{ + "receivecode": "VPCHT", + "paymentDetails": { + "payer": { + "email": "a@b.com", + "firstName": "John", + "lastName": "Doe" + }, + "card": { + "nameOnCard": "John E Doe", + "PAN": "4444 3333 2222 1111", + "expiryDate": "01-20", + "startDate": "01-00", + "issueNumber": 1, + "address": { + "address1": "Flat 20", + "address2": "Victoria House", + "address3": "15 The Street", + "town": "Christchurch", + "county": "Dorset", + "postcode": "BH23 6AA", + "phoneNumber": "+44 123 1110000" + } + } +}, + "amount": { + "value": 1 + }, + "transactionDetails": { + "worldpay": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + } + } +} +``` + +Server Response +```json +{ + "code": 608, + "info": "The receivecode could not be found or has expired." +} +``` + +### 4. Receivecode has already been redeemed ### + +Create Receive Code + +Using : `/receivecodes` + +```json +{ + "key": "1ae580b2-0b9e-4864-a0f8-a4db14e4495a", + "ID": "5ac3587872999f1ef044d2d5" +} +``` + +Response + +```json +{ + "receivecode": "HJ571" +} +``` + +Redeem Receive Code using Credit card details + +```json +{ + "receivecode": "HJ571", + "paymentDetails": { + "payer": { + "email": "a@b.com", + "firstName": "John", + "lastName": "Doe" + }, + "card": { + "nameOnCard": "John E Doe", + "PAN": "4444 3333 2222 1111", + "expiryDate": "01-20", + "startDate": "01-00", + "issueNumber": 1, + "address": { + "address1": "Flat 20", + "address2": "Victoria House", + "address3": "15 The Street", + "town": "Christchurch", + "county": "Dorset", + "postcode": "BH23 6AA", + "phoneNumber": "+44 123 1110000" + } + } +}, + "amount": { + "value": 1 + }, + "transactionDetails": { + "worldpay": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + } + } +} +``` + +Server Response +```json +{ + "transaction": { + "id": "1a553300-7bd4-4fc6-8f8b-23eccea76963" + } +} +``` + +Redeem Receive Code a second time using Credit card details + +```json +{ + "receivecode": "HJ571", + "paymentDetails": { + "payer": { + "email": "a@b.com", + "firstName": "John", + "lastName": "Doe" + }, + "card": { + "nameOnCard": "John E Doe", + "PAN": "4444 3333 2222 1111", + "expiryDate": "01-20", + "startDate": "01-00", + "issueNumber": 1, + "address": { + "address1": "Flat 20", + "address2": "Victoria House", + "address3": "15 The Street", + "town": "Christchurch", + "county": "Dorset", + "postcode": "BH23 6AA", + "phoneNumber": "+44 123 1110000" + } + } +}, + "amount": { + "value": 1 + }, + "transactionDetails": { + "worldpay": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + } + } +} +``` + +Server Response +```json +{ + "code": 608, + "info": "The receivecode could not be found or has expired." +} +``` + +### 5. Request should be logged ### + +##### 1. User redeems receivecode with given credit or debit card ##### + +```json +{ + "_id" : ObjectId("5ac35c6772999f1ef044d342"), + "timestamp" : ISODate("2018-04-03T10:50:15.806Z"), + "level" : "info", + "message" : "Successful redeemed a receivecode", + "meta" : { + "logId" : "payments:receivecodes", + "ip" : "62.232.80.210", + "reqId" : "921e72ab-c093-4a8c-8bd7-14dff2dd83a2", + "userId" : "79a26d981246978135edadf1", + "file" : "/home/flexops/node_server/dev_api/controllers/receivecode_controller.js", + "_payerDetailsPAN" : "4*** **** **** 22 1", + "_receivecode" : "SAE7K", + "_totalAmount" : 1, + "_currency" : "GBP", + "_worldpayOrderCode" : "714d09e0-bd85-4588-9ed9-444316030f1b", + "_cardSchemeName" : "VISA CREDIT", + "_riskScore" : "1" + }, + "hostname" : "node01-cl01-cc" +} +``` + +##### 2. Receivecode does not exist ##### + +```json +{ + "_id" : ObjectId("5ac35d1372999f1ef044d345"), + "timestamp" : ISODate("2018-04-03T10:53:07.954Z"), + "level" : "error", + "message" : "Unsuccessful redeemed a receivecode", + "meta" : { + "logId" : "payments:receivecodes", + "ip" : "62.232.80.210", + "reqId" : "117d2f1b-0650-4f1b-811a-64ed4baef740", + "userId" : "79a26d981246978135edadf1", + "file" : "/home/flexops/node_server/dev_api/controllers/receivecode_controller.js", + "_payerDetailsPAN" : "4*** **** **** 22 1", + "_receivecode" : "F2EE5", + "_totalAmount" : 1, + "_currency" : "GBP", + "_extraInfo" : {}, + "_internalError" : "Error: BRIDGE: INVALID RECEIVECODE", + "_httpCode" : 400, + "_info" : "The receivecode could not be found or has expired.", + "_code" : 608 + }, + "hostname" : "node01-cl01-cc" +} +``` + +##### 3. Receivecode has expired ##### + +```json +{ + "_id" : ObjectId("5ac35e9b72999f1ef044d355"), + "timestamp" : ISODate("2018-04-03T10:59:39.994Z"), + "level" : "error", + "message" : "Unsuccessful redeemed a receivecode", + "meta" : { + "logId" : "payments:receivecodes", + "ip" : "62.232.80.210", + "reqId" : "c7d8c892-6946-4039-ab05-032deb3eea2f", + "userId" : "79a26d981246978135edadf1", + "file" : "/home/flexops/node_server/dev_api/controllers/receivecode_controller.js", + "_payerDetailsPAN" : "4*** **** **** 22 1", + "_receivecode" : "VPCHT", + "_totalAmount" : 1, + "_currency" : "GBP", + "_extraInfo" : {}, + "_internalError" : "Error: BRIDGE: INVALID RECEIVECODE", + "_httpCode" : 400, + "_info" : "The receivecode could not be found or has expired.", + "_code" : 608 + }, + "hostname" : "node01-cl01-cc" +} +``` + +##### 4. Receivecode has already been redeemed ##### + +First use: +```json +{ + "_id" : ObjectId("5ac35dda72999f1ef044d34e"), + "timestamp" : ISODate("2018-04-03T10:56:26.800Z"), + "level" : "info", + "message" : "Successful redeemed a receivecode", + "meta" : { + "logId" : "payments:receivecodes", + "ip" : "62.232.80.210", + "reqId" : "2eeded01-fa80-4070-b422-b7fcf889d4c7", + "userId" : "79a26d981246978135edadf1", + "file" : "/home/flexops/node_server/dev_api/controllers/receivecode_controller.js", + "_payerDetailsPAN" : "4*** **** **** 22 1", + "_receivecode" : "HJ571", + "_totalAmount" : 1, + "_currency" : "GBP", + "_worldpayOrderCode" : "1a553300-7bd4-4fc6-8f8b-23eccea76963", + "_cardSchemeName" : "VISA CREDIT", + "_riskScore" : "1" + }, + "hostname" : "node01-cl01-cc" +} +``` + +Second use: +```json +{ + "_id" : ObjectId("5ac35e0472999f1ef044d351"), + "timestamp" : ISODate("2018-04-03T10:57:08.340Z"), + "level" : "error", + "message" : "Unsuccessful redeemed a receivecode", + "meta" : { + "logId" : "payments:receivecodes", + "ip" : "62.232.80.210", + "reqId" : "0ee62f01-2e15-442c-a271-d11dbc2669fe", + "userId" : "79a26d981246978135edadf1", + "file" : "/home/flexops/node_server/dev_api/controllers/receivecode_controller.js", + "_payerDetailsPAN" : "4*** **** **** 22 1", + "_receivecode" : "HJ571", + "_totalAmount" : 1, + "_currency" : "GBP", + "_extraInfo" : {}, + "_internalError" : "Error: BRIDGE: INVALID RECEIVECODE", + "_httpCode" : 400, + "_info" : "The receivecode could not be found or has expired.", + "_code" : 608 + }, + "hostname" : "node01-cl01-cc" +} +``` \ No newline at end of file diff --git a/tasks/bridge-760/notes.js b/tasks/bridge-760/notes.js new file mode 100644 index 0000000..a07a5e9 --- /dev/null +++ b/tasks/bridge-760/notes.js @@ -0,0 +1,110 @@ +"CreateRTPSucceededInfo": { + "description": "RTP created successfully.", + "type": "object", + "properties": { + "requestToPayID": {"$ref": "#/definitions/uuid"} + }, + "required": ["requestToPayID"] + }, + + + + + + "CreateRTPSucceededInfo": { + "description": "RTP created successfully.", + "type": "object", + "properties": { + "requestToPayID": {"$ref": "#/definitions/uuid"} + }, + "required": ["requestToPayID"] + } + + + + + +"paymentInstrumentList": { + "type": "object", + "description": "Successful listing", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/payment-instrument-list-item" + } + } + }, + "required": ["data"] + } + + + + + + +"rtpList": { + + "type": "object", + "description": "Successful list", + "properties": { + "data" : { + "type": "array", + "items" : { + "requestToPayID" : {"$ref": "#/definitions/uuid" } + } + } + }, + "required": ["requestToPayID"] +} + + + + + +{ + "payeeInstrument": {"$ref": "#/definitions/instrument-id-and-key"}, + "amount": {"$ref": "#/definitions/amount-value-currency-params"}, + "counterparty":{ + "type": "object", + "properties": { + "userID": {"$ref": "#/definitions/object-id"} + }, + "required": ["userID"] + }, + "transactionDetails": {"$ref": "#/definitions/transaction-details-params"} + }, + "required": ["payeeInstrument", "amount", "counterparty", "transactionDetails" ] + + + + + + +"TransactionSucceededInfo": { + "description": "A payment has been successfully made", + "type": "object", + "properties": { + "transaction": { + "description": "Contains the transaction ID", + "type": "object", + "properties": { + "id": { + "allOf": [ + {"$ref": "#/definitions/uuid"}, + { "description": "Transaction Unique Identifier"} + ] + } + }, + "required": [ + "id" + ] + } + }, + "required": ["transaction"] + }, + + + + + \ No newline at end of file diff --git a/tasks/bridge-764/checkin_summary.md b/tasks/bridge-764/checkin_summary.md new file mode 100644 index 0000000..a389592 --- /dev/null +++ b/tasks/bridge-764/checkin_summary.md @@ -0,0 +1,22 @@ +BRIDGE-764 RTP E2E Get List test + +# Summary + +Tests the get RTP list + +# Test Plan: + +* All unit tests run and pass + +* E2E tests run + +``` + E2E: get RTP list + + + ✓ with a valid request (43ms) + + + 1 passing (556ms) + +``` \ No newline at end of file diff --git a/tasks/bridge-764/error.txt b/tasks/bridge-764/error.txt new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-764/get-rtp-list.e2e.spec.js b/tasks/bridge-764/get-rtp-list.e2e.spec.js new file mode 100644 index 0000000..4280d9c --- /dev/null +++ b/tasks/bridge-764/get-rtp-list.e2e.spec.js @@ -0,0 +1,73 @@ +/** + * @fileOverview End-to-end testing of the get RTP list swagger API + */ +'use strict'; + +const _ = require('lodash'); + +const helper = require('../../utils/test/e2e-helper'); + +let app; + +/** + * + * Test Values + * + */ + +// INCorrect auth method (Bearer), correct token +const TOKEN_INVALID = 'ZTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU1'; +const HEADER_INVALID = 'Bearer ' + TOKEN_INVALID; + +// Valid test data +const correctParameters = { + +}; + +let badParameters; + +describe('E2E: get a list of RTP items', () => { + /** + * Load the dev API router to handle `/dev/*` routes + */ + before(() => { + app = new helper.DevValidatorApp(); + app.setRequestPath('/dev/v0/rtps'); + }); + + // getAndValidate(expectedStatusCode, expectedErrors) + // + + describe('test with an incorrect parameter', () => { + /* + * Tests where required top level attributes are missing. + * ====================================================== + */ + + it('added id parameter', () => { + /* + * No receiving account service key + */ + badParameters = _.cloneDeep(correctParameters); + + // badParameters.id = 0; + return app.getAndValidate(badParameters, 400, [ + helper.errors.missingRequired('receivingAccountServiceKey') + ]); + }); + }); + + describe('authorization', () => { + // eslint-disable-next-line mocha/no-hooks-for-single-case + after(() => { + // Reset the authorization header after these tests, whether they + // pass or fail + app.resetAuthorizationHeader(); + }); + + it('is required to access the path', () => { + app.setRequestAuthorization(HEADER_INVALID); + return app.postAndValidate(correctParameters, 401); + }); + }); +}); diff --git a/tasks/bridge-779/story.md b/tasks/bridge-779/story.md new file mode 100644 index 0000000..44fcb0f --- /dev/null +++ b/tasks/bridge-779/story.md @@ -0,0 +1,103 @@ +Summary + +As an Operator and creator of a request to pay, I want to cancel one my existing pending RTP's, so that I can prevent an RTP from continuing. I **CANNOT** cancel a RTP which is in a *PAID* or *UNKNOWN* state + +Acceptance Criteria + +1. Successfully cancel a pending RTP + + **Given** there is an existing RTP where the PayeeID is my user id + + *And* I have authorization to use Bridge + + **When** I make a request to `DELETE /rtps/{id}` + + *And* the RTP is in a pending state + + **Then** RTP is marked in the database as cancelled + + *And* the request succeeds with a 200 status code + + *And* Subsequent calls to `GET /rtps/{id}` returns status code 400 + + *And* relevent missing error message + +2. Invalid attempt to cancel RTP in non pending state + + **Given** there is an existing RTP where the PayeeID is my user id + + *And* I have authorization to use Bridge + + **When** I make a request to `DELETE /rtps/{id}` + + *And* the RTP is **NOT** in a pending state + + **Then** The request fails with a 400 status code + + *And* relevent error message + +3. Invalid attempt to cancel with no ID + + **Given** I have authorization to use Bridge + + **When** I make a request to `DELETE /rtps` + + **Then** The request fails with a 400 status code + + *And* relevent error message + +4. Invalid attempt to cancel RTP where I am **NOT** the Payee + + **Given** there is an existing RTP where the PayeeID is **NOT** my user id + + *And* I have authorization to use Bridge + + **When** I make a request to `DELETE /rtps/{id}` + + **Then** The request fails with a 400 status code + + *And* relevent missing error message + +5. Invalid attempt to cancel RTP that is already cancelled + + **Given** there is an existing RTP where the PayeeID is my user id + + *And* I have authorization to use Bridge + + **When** I make a request to `DELETE /rtps/{id}` + + *And* the RTP **IS** in a cancelled state + + **Then** The request fails with a 400 status code + + *And* relevent error message + +6. Compliance Logging + + **Given** that I have authorization to use Bridge + + **When** I make a request to `DELETE /rtps/{id}` + + **Then** Details of the request will be added to the compliance log. + + *And* This should include (where possible): + + * All standard fields in compliance log entries + + * RTP id + + * Success or failure of the update + +7. The wiki is updated + + + + +Swagger spec + +E2E testing of swagger definition +Implement controller +Update wiki ( Logging Details ) +Create automated tests +Run automated tests +Manual testing \ No newline at end of file diff --git a/tasks/bridge-779/swagger.json b/tasks/bridge-779/swagger.json new file mode 100644 index 0000000..488262b --- /dev/null +++ b/tasks/bridge-779/swagger.json @@ -0,0 +1,1248 @@ +{ + "swagger": "2.0", + "info": { + "version": "0.1", + "title": "Comcarde Bridge Payment Development API Definition", + "description": "The REST Payment Development API that provides access to specified payment commands. Please contact Comcard for more details and access to the system." + }, + "basePath": "/dev/v0", + "schemes": [ + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "security": [ + { + "bearer": [] + } + ], + "tags": [ + { + "name": "general", + "description": "Functions in the API" + }, + { + "name": "payments", + "description": "Functions related to taking payment in various manners" + }, + { + "name": "instruments" + }, + { + "name": "paycodes" + }, + { + "name": "receivecodes" + }, + { + "name": "request to pay (RTPs)" + } + ], + "securityDefinitions": { + "bearer": { + "type": "apiKey", + "name": "Authorization", + "in": "header", + "description": "Bearer token for the specific integration partner. The bearer token **MUST** be kept secure as it provides access to the controlled functionality. The token should be sent in the `\"Authorization\"` header as `\"Bearer \"` following [Section 2.1 of RFC 6750](https://tools.ietf.org/html/rfc6750#section-2.1). Contact Comcarde to request a token for use with this API." + } + }, + "parameters": { + "instrumentID": { + "name": "instrumentID", + "in": "path", + "required": true, + "description": "Unique identifier for payments instrument", + "type": "string", + "pattern": "[0-9a-f]{24}", + "maxLength": 24, + "minLength": 24 + }, + "bridgecode": { + "name": "bridgecode", + "in": "path", + "required": true, + "description": "Bridgecode string. 0-9A-Z except for I, O and Q", + "type": "string", + "minLength": 5, + "maxLength": 10, + "pattern": "^([0-9ABCDEFGHJKLMNPRSTUVWXYZ]*)$", + "x-invalid-pattern": "[^0-9ABCDEFGHJKLMNPRSTUVWXYZ]" + } + }, + "responses": { + "AddedPaymentCard": { + "description": "Success. The card has been stored.", + "schema": { + "$ref": "#/definitions/AddedCardInfo" + } + }, + "badParameterError": { + "description": "Parameter validation failed", + "schema": { + "$ref": "#/definitions/badParametersInfo" + } + }, + "GeneralError": { + "description": "General error response format", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + } + }, + "paths": { + "/test": { + "x-swagger-router-controller": "test_controller", + "get": { + "summary": "Test function", + "description": "Tests that communication with the API works, and the supplied bearer token is valid", + "tags": [ + "general" + ], + "operationId": "test", + "responses": { + "default": { + "$ref": "#/responses/GeneralError" + }, + "200": { + "description": "Successful request: bearer token is valid", + "schema": {} + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + } + } + } + }, + "/payments/worldpay": { + "x-swagger-router-controller": "worldpay_transaction_controller", + "post": { + "summary": "Make a worldpay payment.", + "description": "Create a WorldPay transaction by making a card payment for an amount in pennies.", + "tags": [ "payments" ], + "operationId": "worldpayPayment", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Create WorldPay transaction body", + "required": true, + "schema": { "$ref": "#/definitions/worldpay-params" } + } + ], + "responses": { + "200": { + "description": "Success. The payment has been made.", + "schema": { + "$ref": "#/definitions/TransactionSucceededInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payment-instruments/worldpay-merchants": { + "x-swagger-router-controller": "payment_instruments_controller", + "post": { + "summary": "Save a worldpay receiving account.", + "description": "Save the encrypted details of a worldpay receiving account.", + "tags": [ "instruments" ], + "operationId": "saveWorldpayReceivingAccount", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Save receiving account details.", + "required": true, + "schema": { "$ref": "#/definitions/worldpay-receiving-account-params" } + } + ], + "responses": { + "201": { + "description": "Success. The account has been stored.", + "schema": { + "$ref": "#/definitions/AddedReceiveAccountInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payment-instruments/cards": { + "x-swagger-router-controller": "payment_instruments_controller", + "post": { + "summary": "Save card details.", + "description": "Save the details of a banking card for future use in payments.", + "tags": [ "instruments" ], + "operationId": "saveCardDetails", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Save card details.", + "required": true, + "schema": { "$ref": "#/definitions/payment-instrument-no-cv2-params" } + } + ], + "responses": { + "201": { + "description": "Success. The card has been stored.", + "schema": { + "$ref": "#/definitions/AddedCardInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + }, + "get": { + "summary": "List card payment instruments", + "description": "Return a list of the card payment instrument IDs of the user.", + "tags": [ "instruments" ], + "operationId": "listCards", + "responses": { + "200": { + "description": "Successful request: users card IDs returned", + "schema": { + "$ref": "#/definitions/paymentInstrumentList" + } + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payment-instruments/cards/{instrumentID}/payments": { + "x-swagger-router-controller": "payment_instruments_controller", + "post": { + "summary": "Pay using stored card.", + "description": "Make payment with stored card using Worldpay.", + "tags": [ "payments" ], + "operationId": "makeWorldpayPaymentWithSavedCard", + "parameters": [ + { "$ref": "#/parameters/instrumentID" }, + { + "name": "body", + "in":"body", + "description": "Make payment with stored card using Worldpay.", + "required": true, + "schema": { "$ref": "#/definitions/transaction-details-stored-card" } + } + ], + "responses": { + "200": { + "description": "Successfully made payment with stored card using Worldpay.", + "schema": { + "$ref": "#/definitions/TransactionSucceededInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payment-instruments/worldpay-merchants/{instrumentID}/payments": { + "x-swagger-router-controller": "payment_instruments_controller", + "post": { + "summary": "Pay to a stored merchant.", + "description": "Make payment to a stored Worldpay merchant using a specified card.", + "tags": [ "payments" ], + "operationId": "makeWorldpayPaymentToSavedMerchant", + "parameters": [ + { "$ref": "#/parameters/instrumentID" }, + { + "name": "body", + "in":"body", + "description": "Make payment to stored Worldpay merchant from a card.", + "required": true, + "schema": { "$ref": "#/definitions/transaction-details-stored-merchant" } + } + ], + "responses": { + "200": { + "description": "Successfully made payment to stored Worldpay merchant.", + "schema": { + "$ref": "#/definitions/TransactionSucceededInfo" + } + + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payments/paycode": { + "x-swagger-router-controller": "paycode_controller", + "post": { + "summary": "Redeem a paycode.", + "description": "Pay a stored merchant with the account defined by a paycode.", + "tags": [ "payments" ], + "operationId": "redeemPaycode", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Pay a stored merchant with the account defined by a paycode.", + "required": true, + "schema": { "$ref": "#/definitions/redeem-paycode-params" } + } + ], + "responses": { + "201": { + "description": "Successfully received payment from paycode payment instrument.", + "schema": { + "$ref": "#/definitions/TransactionSucceededInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/paycodes": { + "x-swagger-router-controller": "paycode_controller", + "post": { + "summary": "Create a paycode.", + "description": "Create a paycode that can be used later to make a payment.", + "tags": [ "paycodes" ], + "operationId": "createPaycode", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Create a paycode.", + "required": true, + "schema": { "$ref": "#/definitions/instrument-id-and-key" } + } + ], + "responses": { + "201": { + "description": "Successfully created a paycode.", + "schema": { + "$ref": "#/definitions/CreatePaycodeSucceededInfo" + } + + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/rtps": { + "x-swagger-router-controller": "rtp_controller", + "post": { + "summary": "Create a Request to Pay (RTP).", + "description": "Create an RTP that can be used later to receive a payment by creating an Attempt to pay (ATP).", + "tags": [ "request to pay (RTPs)" ], + "operationId": "createRTP", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Create an RTP.", + "required": true, + "schema": { "$ref": "#/definitions/create-rtp-params" } + } + ], + "responses": { + "201": { + "description": "Successfully created an RTP.", + "schema": { + "$ref": "#/definitions/CreateRTPSucceededInfo" + } + + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + }, + "get": { + "summary": "List Requests to Pay (RTP).", + "description": "Return a list of the RTPs of the user.", + "tags": [ + "request to pay (RTPs)" + ], + "operationId": "listRTP", + "responses": { + "200": { + "description": "Successful request: Request To Pay (RTP) IDs returned", + "schema": { + "$ref": "#/definitions/rtpList" + } + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/receivecodes": { + "x-swagger-router-controller": "receivecode_controller", + "post": { + "summary": "Create a receivecode.", + "description": "Create a receivecode that can be used later to receive a payment.", + "tags": [ "receivecodes" ], + "operationId": "createReceivecode", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Create a receivecode.", + "required": true, + "schema": { "$ref": "#/definitions/instrument-id-and-key" } + } + ], + "responses": { + "201": { + "description": "Successfully created a receivecode.", + "schema": { + "$ref": "#/definitions/CreateReceivecodeSucceededInfo" + } + + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/receivecodes/{bridgecode}": { + "x-swagger-router-controller": "receivecode_controller", + "delete": { + "summary": "Delete a receivecode.", + "description": "Delete a receivecode", + "tags": [ "receivecodes" ], + "operationId": "deleteReceivecode", + "parameters": [ + { "$ref": "#/parameters/bridgecode" } + ], + "responses": { + "200": { + "description": "Successfully deleted the receivecode." + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payments/receivecode": { + "x-swagger-router-controller": "receivecode_controller", + "post": { + "summary": "Redeem a receivecode.", + "description": "Pay a stored merchant to the account defined by a receivecode. If payerInstrument is provided, the payment is made from the saved payment instrument specified. Alternatively, if paymentDetails is specified, the payment is made from the card details specified.", + "tags": [ "payments" ], + "operationId": "redeemReceivecode", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Pay a stored merchant to the account defined by a receivecode. If payerInstrument is provided, the payment is made from the saved payment instrument specified. Alternatively, if paymentDetails is specified, the payment is made from the card details specified.", + "required": true, + "schema": { "$ref": "#/definitions/redeem-receivecode-params" } + } + ], + "responses": { + "201": { + "description": "Successfully received payment from receivecode payment instrument.", + "schema": { + "$ref": "#/definitions/TransactionSucceededInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + } + }, + "definitions": { + "worldpay-params": { + "type": "object", + "properties": { + "paymentInstrument": { "$ref": "#/definitions/payment-instrument-params" }, + "payee": { "$ref": "#/definitions/payee-params" }, + "amount": { "$ref": "#/definitions/amount-params" }, + "transactionDetails": { "$ref": "#/definitions/worldpay-transaction-details-params" } + }, + "required": [ "paymentInstrument", "payee", "amount", "transactionDetails" ] + }, + "payment-instrument-params": { + "type": "object", + "properties": { + "payer": { "$ref": "#/definitions/payer" }, + "card": { "$ref": "#/definitions/card-details-params" } + }, + "required": [ "payer", "card" ] + }, + "payee-params": { + "type": "object", + "properties": { + "worldpay": { + "type": "object", + "properties": { + "receivingAccountServiceKey": { + "$ref": "#/definitions/worldpay-service-key" + } + }, + "required": [ "receivingAccountServiceKey" ] + } + }, + "required": [ "worldpay" ] + }, + "amount-params": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/total-amount" + } + }, + "required": [ "value" ] + }, + "amount-value-currency-params": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/total-amount" + }, + "currency": { + "$ref": "#/definitions/currency" + } + }, + "required": [ "value" , "currency"] + }, + "worldpay-transaction-details-params": { + "type": "object", + "properties": { + "worldpay": { + "type": "object", + "properties": { + "orderDescription": {"$ref": "#/definitions/order-description"} + }, + "required": [ "orderDescription" ] + } + }, + "required": [ "worldpay" ] + }, + "transaction-details-params": { + "type": "object", + "properties": { + "orderDescription": {"$ref": "#/definitions/order-description"} + }, + "required": [ "orderDescription" ] + }, + "transaction-details-stored-card": { + "type": "object", + "properties": { + "paymentInstrument": {"$ref": "#/definitions/payment-instrument-data"}, + "payee": {"$ref": "#/definitions/payee-params"}, + "amount": {"$ref": "#/definitions/amount-params"}, + "transactionDetails": {"$ref": "#/definitions/worldpay-transaction-details-params"} + }, + "required": [ "paymentInstrument", "payee", "amount", "transactionDetails" ] + }, + "transaction-details-stored-merchant": { + "type": "object", + "properties": { + "paymentInstrument": {"$ref": "#/definitions/payment-instrument-params"}, + "receiveInstrument": {"$ref": "#/definitions/instrument-ref-data"}, + "amount": {"$ref": "#/definitions/amount-params"}, + "transactionDetails": {"$ref": "#/definitions/worldpay-transaction-details-params"} + }, + "required": [ "paymentInstrument", "receiveInstrument", "amount", "transactionDetails" ] + }, + "redeem-paycode-params": { + "type": "object", + "properties": { + "paycode": {"$ref": "#/definitions/bridgecodeString"}, + "payee": {"$ref": "#/definitions/instrument-id-and-key"}, + "amount": {"$ref": "#/definitions/amount-params"}, + "transactionDetails": {"$ref": "#/definitions/worldpay-transaction-details-params"} + }, + "required": [ "paycode", "payee", "amount", "transactionDetails" ] + }, + "redeem-receivecode-params": { + "type": "object", + "properties": { + "receivecode": {"$ref": "#/definitions/bridgecodeString"}, + "payerInstrument": {"$ref": "#/definitions/instrument-id-and-key"}, + "paymentDetails": {"$ref": "#/definitions/payment-instrument-params" }, + "amount": {"$ref": "#/definitions/amount-params"}, + "transactionDetails": {"$ref": "#/definitions/worldpay-transaction-details-params"} + }, + "required": [ "receivecode", "amount", "transactionDetails" ] + }, + "create-rtp-params": { + "type": "object", + "properties": { + "payeeInstrument": {"$ref": "#/definitions/instrument-id-and-key"}, + "amount": {"$ref": "#/definitions/amount-value-currency-params"}, + "counterparty":{ + "type": "object", + "properties": { + "userID": {"$ref": "#/definitions/object-id"} + }, + "required": ["userID"] + }, + "transactionDetails": {"$ref": "#/definitions/transaction-details-params"} + }, + "required": ["payeeInstrument", "amount", "counterparty", "transactionDetails" ] + }, + "instrument-id-and-key": { + "type": "object", + "properties": { + "ID": {"$ref": "#/definitions/object-id"}, + "key": {"$ref": "#/definitions/instrument-decrypt-key"} + }, + "required": ["ID", "key"] + }, + "address": { + "description": "Postal address of payment party.", + "type": "object", + "properties": { + "address1": { "$ref": "#/definitions/address-line1" }, + "address2": { "$ref": "#/definitions/address-line2" }, + "address3": { "$ref": "#/definitions/address-line3" }, + "town": { "$ref": "#/definitions/town" }, + "county": { "$ref": "#/definitions/county" }, + "postcode": { "$ref": "#/definitions/postcode" }, + "phoneNumber": { "$ref": "#/definitions/phone-number" } + }, + "required": [ + "address1", "town", "postcode" + ] + }, + "payment-instrument-data": { + "description": "Data require to use the specified payment instrument", + "type": "object", + "properties": { + "encryptionKey": {"$ref": "#/definitions/instrument-decrypt-key"}, + "CV2": {"$ref": "#/definitions/card-CV2"} + }, + "required": [ "encryptionKey" ] + }, + "instrument-ref-data": { + "description": "Data required to use the specified payment instrument", + "type": "object", + "properties": { + "encryptionKey": { "$ref": "#/definitions/instrument-decrypt-key" } + }, + "required": [ "encryptionKey" ] + }, + "payer": { + "description": "Details of the paying party.", + "type": "object", + "properties": { + "email": { + "allOf": [ + {"$ref": "#/definitions/email"}, + { "description": "Email of party making payment"} + ] + }, + "firstName": { + "allOf": [ + {"$ref": "#/definitions/name-field"}, + {"example": "John"} + ] + }, + "lastName": { + "allOf": [ + {"$ref": "#/definitions/name-field"}, + {"example": "Doe"} + ] + } + }, + "required": [ + "email", "firstName", "lastName" + ] + }, + "payment-instrument-no-cv2-params": { + "type": "object", + "properties": { + "payer": { "$ref": "#/definitions/payer" }, + "description": { "$ref": "#/definitions/instrument-description" }, + "card": { "$ref": "#/definitions/card-details-params-no-cv2" } + }, + "required": [ "payer", "card" ] + }, + "worldpay-receiving-account-params": { + "type": "object", + "properties": { + "description": { "$ref": "#/definitions/instrument-description" }, + "receivingAccountServiceKey": { "$ref": "#/definitions/worldpay-service-key" } + }, + "required": [ "receivingAccountServiceKey" ] + }, + "card-details-params-no-cv2": { + "description": "Details of the paying card.", + "type": "object", + "properties": { + "nameOnCard": { + "$ref": "#/definitions/full-name-field" + }, + "PAN": { + "$ref": "#/definitions/card-PAN" + }, + "expiryDate": { + "allOf": [ + {"$ref": "#/definitions/card-date"}, + {"description": "Expiry date (MM-YY) of card making payment"} + ] + }, + "startDate": { + "allOf": [ + {"$ref": "#/definitions/card-date"}, + {"description": "Start date (MM-YY) of card making payment"} + ] + }, + "issueNumber": { + "$ref": "#/definitions/issue-number" + }, + "address": { + "$ref": "#/definitions/address" + } + }, + "required": [ + "nameOnCard", "PAN", "expiryDate", "address" + ] + }, + "card-details-params": { + "description": "Details of the paying card.", + "type": "object", + "properties": { + "nameOnCard": { + "$ref": "#/definitions/full-name-field" + }, + "PAN": { + "$ref": "#/definitions/card-PAN" + }, + "expiryDate": { + "allOf": [ + {"$ref": "#/definitions/card-date"}, + {"description": "Expiry date (MM-YY) of card making payment"} + ] + }, + "startDate": { + "allOf": [ + {"$ref": "#/definitions/card-date"}, + {"description": "Start date (MM-YY) of card making payment"} + ] + }, + "issueNumber": { + "$ref": "#/definitions/issue-number" + }, + "CV2": { + "$ref": "#/definitions/card-CV2" + }, + "address": { + "$ref": "#/definitions/address" + } + }, + "required": [ + "nameOnCard", "PAN", "expiryDate", "address" + ] + }, + "order-description": { + "allOf": [ + {"$ref": "#/definitions/general-text"}, + { + "description": "Order description", + "minLength": 1, + "example": "2 Calling Birds, 1 Partridge in a Pear tree" + } + ] + }, + "address-line1": { + "allOf": [ + {"$ref": "#/definitions/address-line"}, + {"description": "First line of address."}, + {"example": "Flat 20"}, + {"minLength": 1} + ] + }, + "address-line2": { + "allOf": [ + {"$ref": "#/definitions/address-line"}, + {"description": "Second line of address."}, + {"example": "Victoria House"} + ] + }, + "address-line3": { + "allOf": [ + {"$ref": "#/definitions/address-line"}, + {"description": "Third line of address"}, + {"example": "15 The Street"} + ] + }, + "town": { + "allOf": [ + {"$ref": "#/definitions/area-description"}, + {"description": "Town name address."}, + {"example": "Christchurch"}, + {"minLength": 1} + ] + }, + "county": { + "allOf": [ + {"$ref": "#/definitions/area-description"}, + {"description": "County name of address."}, + {"example": "Dorset"}, + {"minLength": 1} + ] + }, + "email": { + "example": "a@b.com", + "type": "string", + "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", + "x-invalid-pattern": "[^a-zA-Z0-9.%+-.@]", + "minLength": 7, + "maxLength": 255 + }, + "name-field": { + "description": "Single part of a personal name (no spaces).", + "type": "string", + "pattern": "^([A-Za-z]*)$", + "x-invalid-pattern": "[^A-Za-z]", + "minLength": 2, + "maxLength": 255, + "example": "John" + }, + "full-name-field": { + "description": "All parts of a personal name separated by spaces.", + "type": "string", + "pattern": "^([A-Za-z ]*)$", + "x-invalid-pattern": "[^A-Za-z]", + "minLength": 2, + "maxLength": 255, + "example": "John E Doe" + }, + "object-id": { + "description": "Unique Identifier", + "type": "string", + "example": "000000000000000000000000", + "pattern": "[0-9a-f]{24}", + "maxLength": 24, + "minLength": 24 + }, + "instrument-decrypt-key": { + "allOf": [ + {"$ref": "#/definitions/uuid"}, + {"description": "Decryption key required to use instrument."} + ] + }, + "transaction-id": { + "allOf": [ + {"$ref": "#/definitions/uuid"}, + {"description": "ID of transaction."} + ] + }, + "card-PAN": { + "description": "PAN (long number) of card.", + "type": "string", + "pattern": "^[0-9][0-9 ]*[0-9]+$", + "minLength": 8, + "maxLength": 255, + "example": "4444 3333 2222 1111" + }, + "obfuscated-card-pan": { + "description": "Obfuscated PAN (long number) of card.", + "type": "string", + "pattern": "^[0-9][0-9* ]*[0-9]+$", + "minLength": 8, + "maxLength": 255, + "example": "4*** **** **** *111" + }, + "total-amount": { + "description": "Total amount in pence (100 = £1.00)", + "type": "integer" + }, + "currency": { + "description": "Currency code (e.g. GBP)", + "type": "string", + "enum": ["GBP"], + "example": "GBP" + }, + "card-date": { + "example": "01-00", + "description": "Date (MM-YY)", + "type": "string", + "pattern": "^(?:0[1-9]|1[0-2])-[0-9][0-9]$", + "x-invalid-pattern": "[^0-9\\-]" + }, + "postcode": { + "description": "Postal code for address.", + "type": "string", + "pattern": "^([A-Za-z0-9\\- ]*)$", + "x-invalid-pattern": "[^a-zA-Z0-9\\- ]", + "example": "BH23 6AA", + "minLength": 4, + "maxLength": 15 + }, + "issue-number": { + "description": "Issue number on the bank card. Only applies to some cards", + "type": "integer", + "minimum": 0, + "maximum": 9999999, + "example": 1 + }, + "card-CV2": { + "example":"000", + "description": "CVV of bank card", + "type": "string", + "pattern": "^[0-9]*$", + "minLength": 3, + "maxLength": 255 + }, + "worldpay-service-key": { + "description": "The Worldpay Service Key format.", + "type": "string", + "pattern": "^(?:T_S_|T_C_|L_S_|L_C_)[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "example": "T_S_4db79f58-b8e8-4485-9346-1aafe16ffc57", + "x-invalid-pattern": "[^0-9a-f\\-_TLSC]" + }, + "phone-number": { + "description": "Phone number.", + "type": "string", + "pattern": "^[+]?[0-9 ]+[0-9]$", + "minLength": 5, + "maxLength": 255, + "example": "+44 123 1110000" + }, + "area-description": { + "allOf": [ + {"$ref": "#/definitions/general-text"}, + {"description": "General area format: town, county and so on."}, + {"example": "Dorset"}, + {"maxLength": 255} + ] + }, + "address-line": { + "allOf": [ + {"$ref": "#/definitions/general-text"}, + {"description": "General address line."}, + {"example": "Dorset"}, + {"maxLength": 255}, + {"example": "1 Second Street"} + ] + }, + "instrument-description": { + "allOf": [ + {"$ref": "#/definitions/general-text"}, + {"description": "Description of the payment instrument."}, + {"example": "BloggsCo Inc. account."}, + {"minLength": 1}, + {"maxLength": 255} + ] + }, + "payment-instrument-list-item": { + "type": "object", + "properties": { + "cardID": { "$ref": "#/definitions/object-id" }, + "description": {"$ref": "#/definitions/instrument-description"}, + "obfuscatedCardPAN": {"$ref": "#/definitions/obfuscated-card-pan"} + }, + "required": ["cardID"] + }, + "bridgecodeString": { + "description": "Bridgecode string. 0-9A-Z except for I, O and Q", + "type": "string", + "minLength": 5, + "maxLength": 10, + "pattern": "^([0-9ABCDEFGHJKLMNPRSTUVWXYZ]*)$", + "x-invalid-pattern": "[^0-9ABCDEFGHJKLMNPRSTUVWXYZ]", + "example": "ABC12" + }, + "general-text": { + "description": "General text with spaces + special chars", + "type": "string", + "pattern": "^([A-Za-z 0-9'[\\]()@?!\\-/.,_&*:;+=]*)$", + "x-invalid-pattern": "[^a-zA-Z0-9'[\\]()@?!\\-/.,_&*:;+=]", + "maxLength": 255, + "example": "Some Text With Spaces And With'&','*',etc." + }, + "uuid": { + "description": "Unique identifier", + "type": "string", + "example": "00000000-0000-0000-0000-000000000000", + "pattern": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", + "maxLength": 36, + "minLength": 36 + }, + "sha256": { + "description": "A SHA-256 value.", + "allOf": [ + { + "$ref": "#/definitions/lowerCaseHex" + }, + { + "example": "f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1", + "minLength": 64, + "maxLength": 64 + } + ] + }, + "lowerCaseHex": { + "description": "Lower case, hexadecimal string (for hashes etc.)", + "type": "string", + "pattern": "^([a-f0-9]*)$", + "x-invalid-pattern": "[^a-f0-9]" + }, + "paymentInstrumentList": { + "type": "object", + "description": "Successful listing", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/payment-instrument-list-item" + } + } + }, + "required": ["data"] + }, + "AddedCardInfo": { + "description": "Reference information to use stored card", + "type": "object", + "properties": { + "cardID": {"$ref": "#/definitions/object-id"}, + "cardUsageKey": {"$ref": "#/definitions/instrument-decrypt-key"} + }, + "required": ["cardID", "cardUsageKey"] + }, + "AddedReceiveAccountInfo": { + "allOf": [ + {"$ref": "#/definitions/instrument-id-and-key"}, + { "description": "Reference information to use stored instrument"} + ] + }, + "TransactionSucceededInfo": { + "description": "A payment has been successfully made", + "type": "object", + "properties": { + "transaction": { + "description": "Contains the transaction ID", + "type": "object", + "properties": { + "id": { + "allOf": [ + {"$ref": "#/definitions/uuid"}, + { "description": "Transaction Unique Identifier"} + ] + } + }, + "required": [ + "id" + ] + } + }, + "required": ["transaction"] + }, + "CreatePaycodeSucceededInfo": { + "description": "Paycode created successfully.", + "type": "object", + "properties": { + "paycode": {"$ref": "#/definitions/bridgecodeString"} + }, + "required": ["paycode"] + }, + "CreateReceivecodeSucceededInfo": { + "description": "Receivecode created successfully.", + "type": "object", + "properties": { + "receivecode": {"$ref": "#/definitions/bridgecodeString"} + }, + "required": ["receivecode"] + }, + "CreateRTPSucceededInfo": { + "description": "RTP created successfully.", + "type": "object", + "properties": { + "requestToPayID": {"$ref": "#/definitions/uuid"} + }, + "required": ["requestToPayID"] + }, + "rtpList": { + "type": "object", + "description": "Successful list", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/uuid" + } + } + }, + "required": [ + "data" + ] + }, + "badParametersInfo": { + "description": "Validation failed", + "type": "object", + "properties": { + "code": { + "description": "Error code", + "type": "integer", + "example": -1 + }, + "info": { + "description": "Text description of the issue", + "type": "string", + "example": "Unknown Error" + }, + "response": { + "description": "Optional additional information", + "type": "object" + } + }, + "required": ["code", "info"], + "example": { + "code": 1, + "info": "Some error" + } + }, + "ErrorInfo": { + "description": "More information on the error reason", + "type": "object", + "properties": { + "code": { + "description": "Error code", + "type": "integer", + "example": -1 + }, + "info": { + "description": "Text description of the issue", + "type": "string", + "example": "Unknown Error" + } + }, + "required": ["code", "info"], + "example": { + "code": 1, + "info": "Some error" + } + } + } +} diff --git a/tasks/bridge-796/checkin-summary.md b/tasks/bridge-796/checkin-summary.md new file mode 100644 index 0000000..b0cdc4a --- /dev/null +++ b/tasks/bridge-796/checkin-summary.md @@ -0,0 +1,59 @@ +# Summary + +When querying the database using `getByQuery`, it was interacting directly with the MongoCollection instead of going through mainDB. This meant there was no checking for the database existing or other error checking. + +# Details + +`findManyObjects` was added to mainDB.js as a way of querying the database for 1 or many results. +The promise was added to `mainDB-promises.js` +`getByQuery` was then modified to use the new `findManyObjects` function. +The `getByQuery` test was updated to work correctly with the new method. + +Unit tests were updated to test this new functionality. + +The test for `getByUUID` which used `getByQuery` passed without any requirement for modification. + + +# Test Plan: + +* All unit tests run and pass +* Test results for daoFactory are: + +``` + daoFactory + ✓ requires a collection name + ✓ creates a factory + functions + createOne + ✓ pass args correctly + ✓ maps data correctly + getByQuery + calls getByQuery + ✓ pass args correctly + getOneByQuery + success + ✓ pass args correctly with ObjectId translation + ✓ maps data correctly + fail + ✓ returns null if not found + getOneByQueryAndDelete + success + ✓ pass args correctly with ObjectId translation + ✓ maps data correctly + fail + ✓ returns null if not found + getOneByUUID + calls getOneByQuery + ✓ pass args and adds _id to empty projection + ✓ pass args and adds _id to projection + ✓ maps data correctly + getByUUID + calls getByQuery + ✓ pass args correctly + ✓ maps data correctly + + + 16 passing (21ms) + + +``` \ No newline at end of file diff --git a/tasks/bridge-796/stuff.md b/tasks/bridge-796/stuff.md new file mode 100644 index 0000000..9046620 --- /dev/null +++ b/tasks/bridge-796/stuff.md @@ -0,0 +1,40 @@ + +{ + "description": "Glasgow Argon Ltd. account.", + "receivingAccountServiceKey": "T_S_7c8551db-2aa0-489d-b80e-d1a8d42e4bfb" +} + + +{ + "key": "1d4d0833-3875-44bc-baf8-d2b1ca757572", + "ID": "5acc8ac5ebf5a808d4fff24d" +} + + +** create rtp + +{ + "amount": { + "value": 0, + "currency": "GBP" + }, + "counterparty": { + "userID": "000000000000000000000000" + }, + "transactionDetails": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + }, + "payeeInstrument": { + "key": "1d4d0833-3875-44bc-baf8-d2b1ca757572", + "ID": "5acc8ac5ebf5a808d4fff24d" +} +} + + + +created + +{ + "requestToPayID": "5acc8b1aebf5a808d4fff250" +} + diff --git a/tasks/bridge-798/checkin-summary.md b/tasks/bridge-798/checkin-summary.md new file mode 100644 index 0000000..031dd43 --- /dev/null +++ b/tasks/bridge-798/checkin-summary.md @@ -0,0 +1,70 @@ +BRIDGE-798 Update swagger definition + +# Summary + +Results being returned via a get to `/rtps` were not matching the swagger definition. + +# Details + +When an RTP was added, then the list of RTP's was requested using a GET to `/rtps`, the resulting data included `status` and `requestToPayID`. These were missing in the swagger definition. + +#### Swagger Example Value + +```json +{ + "data": [ + { + "amount": { + "value": 0, + "currency": "GBP" + }, + "counterparty": { + "userID": "000000000000000000000000" + }, + "transactionDetails": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + }, + "lastUpdate": "2017-07-16T19:20:30.450Z", + "lastVersion": 0, + "payeeInstrument": { + "ID": "000000000000000000000000", + "description": "Description of the payee Instrument" + }, + "status": "Pending", + "requestToPayID": "000000000000000000000000" + } + ] +} +``` + +#### Updated Swagger output + +```json +{ + "data": [ + { + "requestToPayID": "5accb994c538630e5be1c5a4", + "amount": { + "value": 1, + "currency": "GBP" + }, + "status": "Pending", + "payeeInstrument": { + "ID": "5acc8ac5ebf5a808d4fff24d", + "description": "Glasgow Argon Ltd. account." + }, + "transactionDetails": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + }, + "counterparty": { + "userID": "000000000000000000000000" + }, + "lastUpdate": "2018-04-10T13:18:12.034Z", + "lastVersion": 1 + } + ] +} +``` +# Test Plan: + +* All unit tests run and pass diff --git a/tasks/bridge-798/errors.md b/tasks/bridge-798/errors.md new file mode 100644 index 0000000..4921fa1 --- /dev/null +++ b/tasks/bridge-798/errors.md @@ -0,0 +1,64 @@ +{ + "data": [ + { + "amount": { + "value": 0, + "currency": "GBP" + }, + "counterparty": { + "userID": "000000000000000000000000" + }, + "transactionDetails": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + }, + "lastUpdate": "2017-07-16T19:20:30.450Z", + "lastVersion": 0, + "payeeInstrument": { + "ID": "000000000000000000000000", + "description": "Description of the payee Instrument" + } + } + ] +} + + +{ + "data": [ + { + "requestToPayID": "5acc820887eb1c5237524843", + "status": "Pending", + } +] +} + + + + + + +{ + "data": [ + { + "requestToPayID": "5acc820887eb1c5237524843", + "amount": { + "value": 100, + "currency": "GBP" + }, + "status": "Pending", + "payeeInstrument": { + "ID": "5acc820787eb1c5237524840", + "description": "usertoday2" + }, + "transactionDetails": { + "orderDescription": "create RTP for the user 79a26d981246978135edadf3 " + }, + "counterparty": { + "userID": "79a26d981246978135edadf3" + }, + "lastUpdate": "2018-04-10T09:21:12.537Z", + "lastVersion": 1 + } +] +} + +Comments diff --git a/tasks/bridge-798/rerun.md b/tasks/bridge-798/rerun.md new file mode 100644 index 0000000..2946a42 --- /dev/null +++ b/tasks/bridge-798/rerun.md @@ -0,0 +1,35 @@ +{ + "data": [ + { + "amount": { + "value": 0, + "currency": "GBP" + }, + "counterparty": { + "userID": "000000000000000000000000" + }, + "transactionDetails": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + }, + "lastUpdate": "2017-07-16T19:20:30.450Z", + "lastVersion": 0, + "payeeInstrument": { + "ID": "000000000000000000000000", + "description": "Description of the payee Instrument" + }, + "status": "Pending", + "requestToPayID": "000000000000000000000000" + } + ] +} + + + + + +{ + "data": [ + { + } + ] +} \ No newline at end of file diff --git a/tasks/bridge-800/checkin-summary.md b/tasks/bridge-800/checkin-summary.md new file mode 100644 index 0000000..877afe9 --- /dev/null +++ b/tasks/bridge-800/checkin-summary.md @@ -0,0 +1,33 @@ + +BRIDGE-800 Update swagger definition + +# Summary + +This updates the swagger so the user can list their payableRTP's by adding a new endpoint `/payables/rtps' + +# Test Plan + +* Check the server starts ok +* Check the /docs page shows the new paths +* Check we can still carry out the operations from that page +* Check the unit tests all run and pass + + + +BRIDGE-800 Update swagger definition + +# Summary + +This updates the swagger and end-to-end tests for the existing `/rtps` +paths to move them under `/receivables/rtps` to leave room for future +development of `/payables/rtps` for the counterparty/payer side. + +# Test Plan + +* Check the server starts ok +* Check the /docs page shows the new paths +* Check we can still carry out the operations from that page +* Check the unit tests all run and pass + + + diff --git a/tasks/bridge-800/newstuff.md b/tasks/bridge-800/newstuff.md new file mode 100644 index 0000000..8cc9e0a --- /dev/null +++ b/tasks/bridge-800/newstuff.md @@ -0,0 +1,72 @@ +acceptedPaymentTypes mayke it an array / enum + + + +"amount": {"$ref": "#/definitions/amount-value-currency-params"}, + "counterparty": { + "type": "object", + "properties": { + "userID": {"$ref": "#/definitions/object-id"} + }, + "required": ["userID"] + }, + "transactionDetails": {"$ref": "#/definitions/transaction-details-params"} + + + + + + +{ + "data": [ + { + "amount": { + "value": 0, + "currency": "GBP" + }, + "counterparty": { + "userID": "000000000000000000000000" + }, + "transactionDetails": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + }, + "lastUpdate": "2017-07-16T19:20:30.450Z", + "lastVersion": 0, + "status": "Pending", + "requestToPayID": "000000000000000000000000", + "payeeID": "000000000000000000000000" + } + ] +} + + +{ + "data": [ + { + "amount": { + "value": 0, + "currency": "GBP" + }, + "lastUpdate": "2017-07-16T19:20:30.450Z", + "lastVersion": 0, + "status": "Pending", + "requestToPayID": "000000000000000000000000", + "payeeID": "000000000000000000000000", + "transactionDetails": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + } + } + ] +} + + + +"paymentInstrumentType": { + "data": [ + "Unspecified" + ] + } + + + +"paymentInstrumentType": "Unspecified" \ No newline at end of file diff --git a/tasks/bridge-800/swagger.json b/tasks/bridge-800/swagger.json new file mode 100644 index 0000000..960016a --- /dev/null +++ b/tasks/bridge-800/swagger.json @@ -0,0 +1,1439 @@ +{ + "swagger": "2.0", + "info": { + "version": "0.1", + "title": "Comcarde Bridge Payment Development API Definition", + "description": "The REST Payment Development API that provides access to specified payment commands. Please contact Comcard for more details and access to the system." + }, + "basePath": "/dev/v0", + "schemes": [ + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "security": [ + { + "bearer": [] + } + ], + "tags": [ + { + "name": "general", + "description": "Functions in the API" + }, + { + "name": "payments", + "description": "Functions related to taking payment in various manners" + }, + { + "name": "instruments" + }, + { + "name": "paycodes" + }, + { + "name": "receivecodes" + }, + { + "name": "request to pay (RTPs)" + } + ], + "securityDefinitions": { + "bearer": { + "type": "apiKey", + "name": "Authorization", + "in": "header", + "description": "Bearer token for the specific integration partner. The bearer token **MUST** be kept secure as it provides access to the controlled functionality. The token should be sent in the `\"Authorization\"` header as `\"Bearer \"` following [Section 2.1 of RFC 6750](https://tools.ietf.org/html/rfc6750#section-2.1). Contact Comcarde to request a token for use with this API." + } + }, + "parameters": { + "objectID": { + "name": "objectID", + "in": "path", + "required": true, + "description": "Unique identifier for an object in the system", + "type": "string", + "pattern": "[0-9a-f]{24}", + "maxLength": 24, + "minLength": 24 + }, + "bridgecode": { + "name": "bridgecode", + "in": "path", + "required": true, + "description": "Bridgecode string. 0-9A-Z except for I, O and Q", + "type": "string", + "minLength": 5, + "maxLength": 10, + "pattern": "^([0-9ABCDEFGHJKLMNPRSTUVWXYZ]*)$", + "x-invalid-pattern": "[^0-9ABCDEFGHJKLMNPRSTUVWXYZ]" + } + }, + "responses": { + "AddedPaymentCard": { + "description": "Success. The card has been stored.", + "schema": { + "$ref": "#/definitions/AddedCardInfo" + } + }, + "badParameterError": { + "description": "Parameter validation failed", + "schema": { + "$ref": "#/definitions/badParametersInfo" + } + }, + "GeneralError": { + "description": "General error response format", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + } + }, + "paths": { + "/test": { + "x-swagger-router-controller": "test_controller", + "get": { + "summary": "Test function", + "description": "Tests that communication with the API works, and the supplied bearer token is valid", + "tags": [ + "general" + ], + "operationId": "test", + "responses": { + "default": { + "$ref": "#/responses/GeneralError" + }, + "200": { + "description": "Successful request: bearer token is valid", + "schema": {} + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + } + } + } + }, + "/payments/worldpay": { + "x-swagger-router-controller": "worldpay_transaction_controller", + "post": { + "summary": "Make a worldpay payment.", + "description": "Create a WorldPay transaction by making a card payment for an amount in pennies.", + "tags": [ "payments" ], + "operationId": "worldpayPayment", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Create WorldPay transaction body", + "required": true, + "schema": { "$ref": "#/definitions/worldpay-params" } + } + ], + "responses": { + "200": { + "description": "Success. The payment has been made.", + "schema": { + "$ref": "#/definitions/TransactionSucceededInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payment-instruments/worldpay-merchants": { + "x-swagger-router-controller": "payment_instruments_controller", + "post": { + "summary": "Save a worldpay receiving account.", + "description": "Save the encrypted details of a worldpay receiving account.", + "tags": [ "instruments" ], + "operationId": "saveWorldpayReceivingAccount", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Save receiving account details.", + "required": true, + "schema": { "$ref": "#/definitions/worldpay-receiving-account-params" } + } + ], + "responses": { + "201": { + "description": "Success. The account has been stored.", + "schema": { + "$ref": "#/definitions/AddedReceiveAccountInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payment-instruments/cards": { + "x-swagger-router-controller": "payment_instruments_controller", + "post": { + "summary": "Save card details.", + "description": "Save the details of a banking card for future use in payments.", + "tags": [ "instruments" ], + "operationId": "saveCardDetails", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Save card details.", + "required": true, + "schema": { "$ref": "#/definitions/payment-instrument-no-cv2-params" } + } + ], + "responses": { + "201": { + "description": "Success. The card has been stored.", + "schema": { + "$ref": "#/definitions/AddedCardInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + }, + "get": { + "summary": "List card payment instruments", + "description": "Return a list of the card payment instrument IDs of the user.", + "tags": [ "instruments" ], + "operationId": "listCards", + "responses": { + "200": { + "description": "Successful request: users card IDs returned", + "schema": { + "$ref": "#/definitions/paymentInstrumentList" + } + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payment-instruments/cards/{objectID}/payments": { + "x-swagger-router-controller": "payment_instruments_controller", + "post": { + "summary": "Pay using stored card.", + "description": "Make payment with stored card using Worldpay.", + "tags": [ "payments" ], + "operationId": "makeWorldpayPaymentWithSavedCard", + "parameters": [ + { "$ref": "#/parameters/objectID" }, + { + "name": "body", + "in":"body", + "description": "Make payment with stored card using Worldpay.", + "required": true, + "schema": { "$ref": "#/definitions/transaction-details-stored-card" } + } + ], + "responses": { + "200": { + "description": "Successfully made payment with stored card using Worldpay.", + "schema": { + "$ref": "#/definitions/TransactionSucceededInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payment-instruments/worldpay-merchants/{objectID}/payments": { + "x-swagger-router-controller": "payment_instruments_controller", + "post": { + "summary": "Pay to a stored merchant.", + "description": "Make payment to a stored Worldpay merchant using a specified card.", + "tags": [ "payments" ], + "operationId": "makeWorldpayPaymentToSavedMerchant", + "parameters": [ + { "$ref": "#/parameters/objectID" }, + { + "name": "body", + "in":"body", + "description": "Make payment to stored Worldpay merchant from a card.", + "required": true, + "schema": { "$ref": "#/definitions/transaction-details-stored-merchant" } + } + ], + "responses": { + "200": { + "description": "Successfully made payment to stored Worldpay merchant.", + "schema": { + "$ref": "#/definitions/TransactionSucceededInfo" + } + + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payments/paycode": { + "x-swagger-router-controller": "paycode_controller", + "post": { + "summary": "Redeem a paycode.", + "description": "Pay a stored merchant with the account defined by a paycode.", + "tags": [ "payments" ], + "operationId": "redeemPaycode", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Pay a stored merchant with the account defined by a paycode.", + "required": true, + "schema": { "$ref": "#/definitions/redeem-paycode-params" } + } + ], + "responses": { + "201": { + "description": "Successfully received payment from paycode payment instrument.", + "schema": { + "$ref": "#/definitions/TransactionSucceededInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/paycodes": { + "x-swagger-router-controller": "paycode_controller", + "post": { + "summary": "Create a paycode.", + "description": "Create a paycode that can be used later to make a payment.", + "tags": [ "paycodes" ], + "operationId": "createPaycode", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Create a paycode.", + "required": true, + "schema": { "$ref": "#/definitions/instrument-id-and-key" } + } + ], + "responses": { + "201": { + "description": "Successfully created a paycode.", + "schema": { + "$ref": "#/definitions/CreatePaycodeSucceededInfo" + } + + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/receivables/rtps": { + "x-swagger-router-controller": "rtp_controller", + "post": { + "summary": "Create a Request to Pay (RTP).", + "description": "Create an RTP that can be used later to receive a payment by creating an Attempt to pay (ATP).", + "tags": [ "request to pay (RTPs)" ], + "operationId": "createRTP", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Create an RTP.", + "required": true, + "schema": { "$ref": "#/definitions/create-rtp-params" } + } + ], + "responses": { + "201": { + "description": "Successfully created an RTP.", + "schema": { + "$ref": "#/definitions/CreateRTPSucceededInfo" + } + + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + }, + "get": { + "summary": "List receivable Requests to Pay (RTP).", + "description": "Return a list of the receivable RTPs, where the current user is the payee.", + "tags": [ + "request to pay (RTPs)" + ], + "operationId": "listRTPs", + "responses": { + "200": { + "description": "Successful request: Request To Pay (RTP) record(s) returned", + "schema": { + "$ref": "#/definitions/rtpList" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/receivables/rtps/{objectID}": { + "x-swagger-router-controller": "rtp_controller", + "get": { + "summary": "Get a receivable Request to Pay (RTP).", + "description": "Returns the details of the specified receivable RTP.", + "tags": [ + "request to pay (RTPs)" + ], + "operationId": "getRTP", + "parameters": [ + { "$ref": "#/parameters/objectID" } + ], + "responses": { + "200": { + "description": "Successful request: Request To Pay (RTP) record(s) returned", + "schema": { + "$ref": "#/definitions/rtp-get-item" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + }, + "delete": { + "summary": "Cancel an RTP.", + "description": "Cancel a receivable RTP.", + "tags": [ "request to pay (RTPs)" ], + "operationId": "cancelRTP", + "parameters": [ + { "$ref": "#/parameters/objectID" } + ], + "responses": { + "200": { + "description": "Successfully canceled the RTP." + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + }, + "patch": { + "summary": "Update an RTP", + "description": "Update a receivable RTP", + "tags": [ "request to pay (RTPs)" ], + "operationId": "updateRTP", + "parameters": [ + { "$ref": "#/parameters/objectID" }, + { + "name": "body", + "in":"body", + "description": "Create an RTP.", + "required": true, + "schema": { "$ref": "#/definitions/rtp-update-item" } + } + ], + "responses": { + "200": { + "description": "Successfully updated the RTP." + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payables/rtps": { + "x-swagger-router-controller": "rtp_controller", + "get": { + "summary": "List payable Requests to Pay (RTP).", + "description": "Return a list of the payable RTPs, where the current user is the payeer.", + "tags": [ + "request to pay (RTPs)" + ], + "operationId": "listPayablesRTPs", + "responses": { + "200": { + "description": "Successful request: Payable Request To Pay (RTP) record(s) returned", + "schema": { + "$ref": "#/definitions/rtpPayablesList" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/receivecodes": { + "x-swagger-router-controller": "receivecode_controller", + "post": { + "summary": "Create a receivecode.", + "description": "Create a receivecode that can be used later to receive a payment.", + "tags": [ "receivecodes" ], + "operationId": "createReceivecode", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Create a receivecode.", + "required": true, + "schema": { "$ref": "#/definitions/instrument-id-and-key" } + } + ], + "responses": { + "201": { + "description": "Successfully created a receivecode.", + "schema": { + "$ref": "#/definitions/CreateReceivecodeSucceededInfo" + } + + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/receivecodes/{bridgecode}": { + "x-swagger-router-controller": "receivecode_controller", + "delete": { + "summary": "Delete a receivecode.", + "description": "Delete a receivecode", + "tags": [ "receivecodes" ], + "operationId": "deleteReceivecode", + "parameters": [ + { "$ref": "#/parameters/bridgecode" } + ], + "responses": { + "200": { + "description": "Successfully deleted the receivecode." + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + }, + "/payments/receivecode": { + "x-swagger-router-controller": "receivecode_controller", + "post": { + "summary": "Redeem a receivecode.", + "description": "Pay a stored merchant to the account defined by a receivecode. If payerInstrument is provided, the payment is made from the saved payment instrument specified. Alternatively, if paymentDetails is specified, the payment is made from the card details specified.", + "tags": [ "payments" ], + "operationId": "redeemReceivecode", + "parameters": [ + { + "name": "body", + "in":"body", + "description": "Pay a stored merchant to the account defined by a receivecode. If payerInstrument is provided, the payment is made from the saved payment instrument specified. Alternatively, if paymentDetails is specified, the payment is made from the card details specified.", + "required": true, + "schema": { "$ref": "#/definitions/redeem-receivecode-params" } + } + ], + "responses": { + "201": { + "description": "Successfully received payment from receivecode payment instrument.", + "schema": { + "$ref": "#/definitions/TransactionSucceededInfo" + } + }, + "400": { + "$ref": "#/responses/badParameterError" + }, + "401": { + "description": "Invalid key", + "schema": { + "$ref": "#/definitions/ErrorInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + } + }, + "definitions": { + "worldpay-params": { + "type": "object", + "properties": { + "paymentInstrument": { "$ref": "#/definitions/payment-instrument-params" }, + "payee": { "$ref": "#/definitions/payee-params" }, + "amount": { "$ref": "#/definitions/amount-params" }, + "transactionDetails": { "$ref": "#/definitions/worldpay-transaction-details-params" } + }, + "required": [ "paymentInstrument", "payee", "amount", "transactionDetails" ] + }, + "payment-instrument-params": { + "type": "object", + "properties": { + "payer": { "$ref": "#/definitions/payer" }, + "card": { "$ref": "#/definitions/card-details-params" } + }, + "required": [ "payer", "card" ] + }, + "payeeID": { + + }, + "payee-params": { + "type": "object", + "properties": { + "worldpay": { + "type": "object", + "properties": { + "receivingAccountServiceKey": { + "$ref": "#/definitions/worldpay-service-key" + } + }, + "required": [ "receivingAccountServiceKey" ] + } + }, + "required": [ "worldpay" ] + }, + "amount-params": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/total-amount" + } + }, + "required": [ "value" ] + }, + "amount-value-currency-params": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/total-amount" + }, + "currency": { + "$ref": "#/definitions/currency" + } + }, + "required": [ "value" , "currency"] + }, + "worldpay-transaction-details-params": { + "type": "object", + "properties": { + "worldpay": { + "type": "object", + "properties": { + "orderDescription": {"$ref": "#/definitions/order-description"} + }, + "required": [ "orderDescription" ] + } + }, + "required": [ "worldpay" ] + }, + "transaction-details-params": { + "type": "object", + "properties": { + "orderDescription": {"$ref": "#/definitions/order-description"} + }, + "required": [ "orderDescription" ] + }, + "transaction-details-stored-card": { + "type": "object", + "properties": { + "paymentInstrument": {"$ref": "#/definitions/payment-instrument-data"}, + "payee": {"$ref": "#/definitions/payee-params"}, + "amount": {"$ref": "#/definitions/amount-params"}, + "transactionDetails": {"$ref": "#/definitions/worldpay-transaction-details-params"} + }, + "required": [ "paymentInstrument", "payee", "amount", "transactionDetails" ] + }, + "transaction-details-stored-merchant": { + "type": "object", + "properties": { + "paymentInstrument": {"$ref": "#/definitions/payment-instrument-params"}, + "receiveInstrument": {"$ref": "#/definitions/instrument-ref-data"}, + "amount": {"$ref": "#/definitions/amount-params"}, + "transactionDetails": {"$ref": "#/definitions/worldpay-transaction-details-params"} + }, + "required": [ "paymentInstrument", "receiveInstrument", "amount", "transactionDetails" ] + }, + "redeem-paycode-params": { + "type": "object", + "properties": { + "paycode": {"$ref": "#/definitions/bridgecodeString"}, + "payee": {"$ref": "#/definitions/instrument-id-and-key"}, + "amount": {"$ref": "#/definitions/amount-params"}, + "transactionDetails": {"$ref": "#/definitions/worldpay-transaction-details-params"} + }, + "required": [ "paycode", "payee", "amount", "transactionDetails" ] + }, + "redeem-receivecode-params": { + "type": "object", + "properties": { + "receivecode": {"$ref": "#/definitions/bridgecodeString"}, + "payerInstrument": {"$ref": "#/definitions/instrument-id-and-key"}, + "paymentDetails": {"$ref": "#/definitions/payment-instrument-params" }, + "amount": {"$ref": "#/definitions/amount-params"}, + "transactionDetails": {"$ref": "#/definitions/worldpay-transaction-details-params"} + }, + "required": [ "receivecode", "amount", "transactionDetails" ] + }, + "create-rtp-params": { + "type" : "object", + "allOf": [ + {"$ref": "#/definitions/baseRTP"}, + { + "type": "object", + "properties": { + "payeeInstrument": {"$ref": "#/definitions/instrument-id-and-key"} + } + } + ], + "required": ["payeeInstrument", "amount", "counterparty", "transactionDetails" ] + }, + "instrument-id-and-key": { + "type": "object", + "properties": { + "ID": {"$ref": "#/definitions/object-id"}, + "key": {"$ref": "#/definitions/instrument-decrypt-key"} + }, + "required": ["ID", "key"] + }, + "instrument-id-and-description": { + "type": "object", + "properties": { + "ID": {"$ref": "#/definitions/object-id"}, + "description": {"$ref": "#/definitions/payee-instrument-description"} + }, + "required": ["ID"] + }, + "payee-instrument-description": { + "allOf": [ + {"$ref": "#/definitions/general-text"}, + { + "description": "Payee Instrument description", + "minLength": 1, + "example": "Description of the payee Instrument" + } + ] + }, + "address": { + "description": "Postal address of payment party.", + "type": "object", + "properties": { + "address1": { "$ref": "#/definitions/address-line1" }, + "address2": { "$ref": "#/definitions/address-line2" }, + "address3": { "$ref": "#/definitions/address-line3" }, + "town": { "$ref": "#/definitions/town" }, + "county": { "$ref": "#/definitions/county" }, + "postcode": { "$ref": "#/definitions/postcode" }, + "phoneNumber": { "$ref": "#/definitions/phone-number" } + }, + "required": [ + "address1", "town", "postcode" + ] + }, + "payment-instrument-data": { + "description": "Data require to use the specified payment instrument", + "type": "object", + "properties": { + "encryptionKey": {"$ref": "#/definitions/instrument-decrypt-key"}, + "CV2": {"$ref": "#/definitions/card-CV2"} + }, + "required": [ "encryptionKey" ] + }, + "instrument-ref-data": { + "description": "Data required to use the specified payment instrument", + "type": "object", + "properties": { + "encryptionKey": { "$ref": "#/definitions/instrument-decrypt-key" } + }, + "required": [ "encryptionKey" ] + }, + "payer": { + "description": "Details of the paying party.", + "type": "object", + "properties": { + "email": { + "allOf": [ + {"$ref": "#/definitions/email"}, + { "description": "Email of party making payment"} + ] + }, + "firstName": { + "allOf": [ + {"$ref": "#/definitions/name-field"}, + {"example": "John"} + ] + }, + "lastName": { + "allOf": [ + {"$ref": "#/definitions/name-field"}, + {"example": "Doe"} + ] + } + }, + "required": [ + "email", "firstName", "lastName" + ] + }, + "payment-instrument-no-cv2-params": { + "type": "object", + "properties": { + "payer": { "$ref": "#/definitions/payer" }, + "description": { "$ref": "#/definitions/instrument-description" }, + "card": { "$ref": "#/definitions/card-details-params-no-cv2" } + }, + "required": [ "payer", "card" ] + }, + "worldpay-receiving-account-params": { + "type": "object", + "properties": { + "description": { "$ref": "#/definitions/instrument-description" }, + "receivingAccountServiceKey": { "$ref": "#/definitions/worldpay-service-key" } + }, + "required": [ "receivingAccountServiceKey" ] + }, + "card-details-params-no-cv2": { + "description": "Details of the paying card.", + "type": "object", + "properties": { + "nameOnCard": { + "$ref": "#/definitions/full-name-field" + }, + "PAN": { + "$ref": "#/definitions/card-PAN" + }, + "expiryDate": { + "allOf": [ + {"$ref": "#/definitions/card-date"}, + {"description": "Expiry date (MM-YY) of card making payment"} + ] + }, + "startDate": { + "allOf": [ + {"$ref": "#/definitions/card-date"}, + {"description": "Start date (MM-YY) of card making payment"} + ] + }, + "issueNumber": { + "$ref": "#/definitions/issue-number" + }, + "address": { + "$ref": "#/definitions/address" + } + }, + "required": [ + "nameOnCard", "PAN", "expiryDate", "address" + ] + }, + "card-details-params": { + "description": "Details of the paying card.", + "type": "object", + "properties": { + "nameOnCard": { + "$ref": "#/definitions/full-name-field" + }, + "PAN": { + "$ref": "#/definitions/card-PAN" + }, + "expiryDate": { + "allOf": [ + {"$ref": "#/definitions/card-date"}, + {"description": "Expiry date (MM-YY) of card making payment"} + ] + }, + "startDate": { + "allOf": [ + {"$ref": "#/definitions/card-date"}, + {"description": "Start date (MM-YY) of card making payment"} + ] + }, + "issueNumber": { + "$ref": "#/definitions/issue-number" + }, + "CV2": { + "$ref": "#/definitions/card-CV2" + }, + "address": { + "$ref": "#/definitions/address" + } + }, + "required": [ + "nameOnCard", "PAN", "expiryDate", "address" + ] + }, + "order-description": { + "allOf": [ + {"$ref": "#/definitions/general-text"}, + { + "description": "Order description", + "minLength": 1, + "example": "2 Calling Birds, 1 Partridge in a Pear tree" + } + ] + }, + "address-line1": { + "allOf": [ + {"$ref": "#/definitions/address-line"}, + {"description": "First line of address."}, + {"example": "Flat 20"}, + {"minLength": 1} + ] + }, + "address-line2": { + "allOf": [ + {"$ref": "#/definitions/address-line"}, + {"description": "Second line of address."}, + {"example": "Victoria House"} + ] + }, + "address-line3": { + "allOf": [ + {"$ref": "#/definitions/address-line"}, + {"description": "Third line of address"}, + {"example": "15 The Street"} + ] + }, + "town": { + "allOf": [ + {"$ref": "#/definitions/area-description"}, + {"description": "Town name address."}, + {"example": "Christchurch"}, + {"minLength": 1} + ] + }, + "county": { + "allOf": [ + {"$ref": "#/definitions/area-description"}, + {"description": "County name of address."}, + {"example": "Dorset"}, + {"minLength": 1} + ] + }, + "email": { + "example": "a@b.com", + "type": "string", + "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", + "x-invalid-pattern": "[^a-zA-Z0-9.%+-.@]", + "minLength": 7, + "maxLength": 255 + }, + "name-field": { + "description": "Single part of a personal name (no spaces).", + "type": "string", + "pattern": "^([A-Za-z]*)$", + "x-invalid-pattern": "[^A-Za-z]", + "minLength": 2, + "maxLength": 255, + "example": "John" + }, + "full-name-field": { + "description": "All parts of a personal name separated by spaces.", + "type": "string", + "pattern": "^([A-Za-z ]*)$", + "x-invalid-pattern": "[^A-Za-z]", + "minLength": 2, + "maxLength": 255, + "example": "John E Doe" + }, + "object-id": { + "description": "Unique Identifier", + "type": "string", + "example": "000000000000000000000000", + "pattern": "[0-9a-f]{24}", + "maxLength": 24, + "minLength": 24 + }, + "instrument-decrypt-key": { + "allOf": [ + {"$ref": "#/definitions/uuid"}, + {"description": "Decryption key required to use instrument."} + ] + }, + "transaction-id": { + "allOf": [ + {"$ref": "#/definitions/uuid"}, + {"description": "ID of transaction."} + ] + }, + "card-PAN": { + "description": "PAN (long number) of card.", + "type": "string", + "pattern": "^[0-9][0-9 ]*[0-9]+$", + "minLength": 8, + "maxLength": 255, + "example": "4444 3333 2222 1111" + }, + "obfuscated-card-pan": { + "description": "Obfuscated PAN (long number) of card.", + "type": "string", + "pattern": "^[0-9][0-9* ]*[0-9]+$", + "minLength": 8, + "maxLength": 255, + "example": "4*** **** **** *111" + }, + "total-amount": { + "description": "Total amount in pence (100 = £1.00).", + "type": "integer", + "minimum": 1 + }, + "currency": { + "description": "Currency code (e.g. GBP)", + "type": "string", + "enum": ["GBP"], + "example": "GBP" + }, + "card-date": { + "example": "01-00", + "description": "Date (MM-YY)", + "type": "string", + "pattern": "^(?:0[1-9]|1[0-2])-[0-9][0-9]$", + "x-invalid-pattern": "[^0-9\\-]" + }, + "postcode": { + "description": "Postal code for address.", + "type": "string", + "pattern": "^([A-Za-z0-9\\- ]*)$", + "x-invalid-pattern": "[^a-zA-Z0-9\\- ]", + "example": "BH23 6AA", + "minLength": 4, + "maxLength": 15 + }, + "issue-number": { + "description": "Issue number on the bank card. Only applies to some cards", + "type": "integer", + "minimum": 0, + "maximum": 9999999, + "example": 1 + }, + "card-CV2": { + "example":"000", + "description": "CVV of bank card", + "type": "string", + "pattern": "^[0-9]*$", + "minLength": 3, + "maxLength": 255 + }, + "worldpay-service-key": { + "description": "The Worldpay Service Key format.", + "type": "string", + "pattern": "^(?:T_S_|T_C_|L_S_|L_C_)[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "example": "T_S_4db79f58-b8e8-4485-9346-1aafe16ffc57", + "x-invalid-pattern": "[^0-9a-f\\-_TLSC]" + }, + "phone-number": { + "description": "Phone number.", + "type": "string", + "pattern": "^[+]?[0-9 ]+[0-9]$", + "minLength": 5, + "maxLength": 255, + "example": "+44 123 1110000" + }, + "iso-date": { + "example": "2017-07-16T19:20:30.450Z", + "description": "Date (YYYY-MM-DDTHH:mm:ss.sssZ)", + "type": "string", + "format": "date-time" + }, + "area-description": { + "allOf": [ + {"$ref": "#/definitions/general-text"}, + {"description": "General area format: town, county and so on."}, + {"example": "Dorset"}, + {"maxLength": 255} + ] + }, + "address-line": { + "allOf": [ + {"$ref": "#/definitions/general-text"}, + {"description": "General address line."}, + {"example": "Dorset"}, + {"maxLength": 255}, + {"example": "1 Second Street"} + ] + }, + "instrument-description": { + "allOf": [ + {"$ref": "#/definitions/general-text"}, + {"description": "Description of the payment instrument."}, + {"example": "BloggsCo Inc. account."}, + {"minLength": 1}, + {"maxLength": 255} + ] + }, + "payment-instrument-list-item": { + "type": "object", + "properties": { + "cardID": { "$ref": "#/definitions/object-id" }, + "description": {"$ref": "#/definitions/instrument-description"}, + "obfuscatedCardPAN": {"$ref": "#/definitions/obfuscated-card-pan"} + }, + "required": ["cardID"] + }, + "bridgecodeString": { + "description": "Bridgecode string. 0-9A-Z except for I, O and Q", + "type": "string", + "minLength": 5, + "maxLength": 10, + "pattern": "^([0-9ABCDEFGHJKLMNPRSTUVWXYZ]*)$", + "x-invalid-pattern": "[^0-9ABCDEFGHJKLMNPRSTUVWXYZ]", + "example": "ABC12" + }, + "general-text": { + "description": "General text with spaces + special chars", + "type": "string", + "pattern": "^([A-Za-z 0-9'[\\]()@?!\\-/.,_&*:;+=]*)$", + "x-invalid-pattern": "[^a-zA-Z0-9'[\\]()@?!\\-/.,_&*:;+=]", + "maxLength": 255, + "example": "Some Text With Spaces And With'&','*',etc." + }, + "uuid": { + "description": "Unique identifier", + "type": "string", + "example": "00000000-0000-0000-0000-000000000000", + "pattern": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", + "maxLength": 36, + "minLength": 36 + }, + "sha256": { + "description": "A SHA-256 value.", + "allOf": [ + { + "$ref": "#/definitions/lowerCaseHex" + }, + { + "example": "f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1f0a1", + "minLength": 64, + "maxLength": 64 + } + ] + }, + "lowerCaseHex": { + "description": "Lower case, hexadecimal string (for hashes etc.)", + "type": "string", + "pattern": "^([a-f0-9]*)$", + "x-invalid-pattern": "[^a-f0-9]" + }, + "paymentInstrumentList": { + "type": "object", + "description": "Successful listing", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/payment-instrument-list-item" + } + } + }, + "required": ["data"] + }, + "AddedCardInfo": { + "description": "Reference information to use stored card", + "type": "object", + "properties": { + "cardID": {"$ref": "#/definitions/object-id"}, + "cardUsageKey": {"$ref": "#/definitions/instrument-decrypt-key"} + }, + "required": ["cardID", "cardUsageKey"] + }, + "AddedReceiveAccountInfo": { + "allOf": [ + {"$ref": "#/definitions/instrument-id-and-key"}, + { "description": "Reference information to use stored instrument"} + ] + }, + "TransactionSucceededInfo": { + "description": "A payment has been successfully made", + "type": "object", + "properties": { + "transaction": { + "description": "Contains the transaction ID", + "type": "object", + "properties": { + "id": { + "allOf": [ + {"$ref": "#/definitions/uuid"}, + { "description": "Transaction Unique Identifier"} + ] + } + }, + "required": [ + "id" + ] + } + }, + "required": ["transaction"] + }, + "CreatePaycodeSucceededInfo": { + "description": "Paycode created successfully.", + "type": "object", + "properties": { + "paycode": {"$ref": "#/definitions/bridgecodeString"} + }, + "required": ["paycode"] + }, + "CreateReceivecodeSucceededInfo": { + "description": "Receivecode created successfully.", + "type": "object", + "properties": { + "receivecode": {"$ref": "#/definitions/bridgecodeString"} + }, + "required": ["receivecode"] + }, + "CreateRTPSucceededInfo": { + "description": "RTP created successfully.", + "type": "object", + "properties": { + "requestToPayID": {"$ref": "#/definitions/object-id"} + }, + "required": ["requestToPayID"] + }, + "baseRTP": { + "type": "object", + "properties": { + "amount": {"$ref": "#/definitions/amount-value-currency-params"}, + "counterparty": { + "type": "object", + "properties": { + "userID": {"$ref": "#/definitions/object-id"} + }, + "required": ["userID"] + }, + "transactionDetails": {"$ref": "#/definitions/transaction-details-params"} + } + }, + "rtp-last-version": { + "description": "Last version", + "type": "integer" + }, + "rtpStatus": { + "description": "Status of the RTP", + "type": "string", + "enum": ["Paid", "Payment Started", "Unknown", "Cancelled", "Pending"], + "example": "Pending" + }, + "rtp-get-item": { + "type" : "object", + "allOf": [ + {"$ref": "#/definitions/baseRTP"}, + { + "type": "object", + "properties": { + "lastUpdate": {"$ref": "#/definitions/iso-date"}, + "lastVersion": {"$ref": "#/definitions/rtp-last-version"}, + "payeeInstrument": {"$ref": "#/definitions/instrument-id-and-description"}, + "status" : {"$ref": "#/definitions/rtpStatus"}, + "requestToPayID": {"$ref": "#/definitions/object-id"} + }, + "required": ["lastUpdate", "lastVersion", "payeeInstrument", "status", "requestToPayID"] + } + ], + "required": ["amount", "counterparty", "transactionDetails"] + }, + "rtp-payables-get-item": { + "type" : "object", + "allOf": [ + {"$ref": "#/definitions/baseRTP"}, + { + "type": "object", + "properties": { + "lastUpdate": {"$ref": "#/definitions/iso-date"}, + "lastVersion": {"$ref": "#/definitions/rtp-last-version"}, + "status" : {"$ref": "#/definitions/rtpStatus"}, + "requestToPayID": {"$ref": "#/definitions/object-id"}, + "payeeID": { "$ref": "#/definitions/object-id" } + }, + "required": ["lastUpdate", "lastVersion", "status", "requestToPayID"] + } + ], + "required": ["amount", "counterparty", "transactionDetails"] + }, + "rtp-update-item": { + "type" : "object", + "properties": { + "payeeInstrument": {"$ref": "#/definitions/instrument-id-and-key"}, + "amount": {"$ref": "#/definitions/amount-value-currency-params"}, + "transactionDetails": {"$ref": "#/definitions/transaction-details-params"} + }, + "additionalProperties": false + }, + "rtpList": { + "type": "object", + "description": "Successful list", + "properties" : { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/rtp-get-item" + } + } + } + }, + "rtpPayablesList": { + "type": "object", + "description": "Successful list", + "properties" : { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/rtp-payables-get-item" + } + } + } + }, + "badParametersInfo": { + "description": "Validation failed", + "type": "object", + "properties": { + "code": { + "description": "Error code", + "type": "integer", + "example": -1 + }, + "info": { + "description": "Text description of the issue", + "type": "string", + "example": "Unknown Error" + }, + "response": { + "description": "Optional additional information", + "type": "object" + } + }, + "required": ["code", "info"], + "example": { + "code": 1, + "info": "Some error" + } + }, + "ErrorInfo": { + "description": "More information on the error reason", + "type": "object", + "properties": { + "code": { + "description": "Error code", + "type": "integer", + "example": -1 + }, + "info": { + "description": "Text description of the issue", + "type": "string", + "example": "Unknown Error" + } + }, + "required": ["code", "info"], + "example": { + "code": 1, + "info": "Some error" + } + } + } +} diff --git a/tasks/bridge-801/checkin-summary.md b/tasks/bridge-801/checkin-summary.md new file mode 100644 index 0000000..e588a18 --- /dev/null +++ b/tasks/bridge-801/checkin-summary.md @@ -0,0 +1,43 @@ + +BRIDGE-801 E2E Tests of Swagger Def + +# Summary + +This adds an E2E for testing the new swagger new endpoint `/payables/rtps' + +# Test Plan + +* Run All tests +* Run E2E: get Payables RTP list + +Test Results + +``` + +E2E: get Payables RTP list + + ✓ with a valid request (39ms) + + + 1 passing (532ms) + + +``` + +BRIDGE-800 Update swagger definition + +# Summary + +This updates the swagger and end-to-end tests for the existing `/rtps` +paths to move them under `/receivables/rtps` to leave room for future +development of `/payables/rtps` for the counterparty/payer side. + +# Test Plan + +* Check the server starts ok +* Check the /docs page shows the new paths +* Check we can still carry out the operations from that page +* Check the unit tests all run and pass + + + diff --git a/tasks/bridge-822/what.md b/tasks/bridge-822/what.md new file mode 100644 index 0000000..2aae7ee --- /dev/null +++ b/tasks/bridge-822/what.md @@ -0,0 +1,42 @@ +As a user I want to pay an RTP in full (using stored or new instrument) + + +Summary + +As a user, I want to pay an RTP in full. This is an attempt to pay (ATP) + +AC's + +1. User successfully pays the RTP (ATP is successfull) + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument belongs to meAnd I have specified the corresponding encryption key in the request bodyOr I have specified other details as per BRIDGE-284 (apart from payee details) in the request bodyAnd the RTP existsAnd the RTP is in the correct state (Status: Pending)And I specify the correct amount (the amount specified on the RTP)Then the payment is processed as per BRIDGE‌-325 + +2. I have supplied a saved payment instrument and the instrument ID is invalid + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is invalidThen the payment fails with status 400 + +3. I have supplied a saved payment instrument and the instrument does not belong to me + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument does not belong to meThen the payment fails with status 400 + +4. I have supplied a saved payment instrument and the encryption key is not correct + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument belongs to meAnd I have specified the wrong encryption key in the request bodyThen the payment fails with status 401 + +5. the RTP does not exist + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument belongs to meAnd I have specified the corresponding encryption key in the request bodyOr I have specified other details as per (apart from payee details) in the request bodyAnd the RTP doe not existThen the payment fails with status 400 + +6. The RTP is not in the Pending state + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument belongs to meAnd I have specified the corresponding encryption key in the request bodyOr I have specified other details as per (apart from payee details) in the request bodyAnd the RTP existsAnd the RTP is not in the correct state (Status: Pending)Then the payment fails with status 400 + +7. The amount does not match the RTP's amount + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument belongs to meAnd I have specified the corresponding encryption key in the request bodyOr I have specified other details as per (apart from payee details) in the request bodyAnd the RTP existsAnd the RTP is in the correct state (Status: Pending)And I specify the incorrect amount (the amount specified on the RTP)Then the payment fails with status 400 + +9. Request should be logged + +Given that I have made a request as per the other scenarios on this storyWhen the request is processedThen compliance information about the request and response is logged to the database + +10. Wiki should be updated \ No newline at end of file diff --git a/tasks/bridge-826/step01.md b/tasks/bridge-826/step01.md new file mode 100644 index 0000000..9a1eb3a --- /dev/null +++ b/tasks/bridge-826/step01.md @@ -0,0 +1,141 @@ +Re-authorise with : + +``` +Bearer YTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU1 + +``` + +## step 1 ## + +Payee Account? +``` + +{ + "description": "Silver Carpenter Inc. account.", + "receivingAccountServiceKey": "T_S_7c8551db-2aa0-489d-b80e-d1a8d42e4bfb" +} + +``` + + +/payment-instruments/worldpay-merchants +Save a worldpay receiving account. +created instrument + +``` + +{ + "key": "66ef4cd0-aa02-444f-b4bd-81cce3f6674e", + "ID": "5ad9fde20a791abf542f8598" +} + +``` + +## step 2 ## + +/receivables/rtps +Create a Request to Pay (RTP). +``` + +{ + "amount": { + "value": 100, + "currency": "GBP" + }, + "counterparty": { + "userID": "5ad9fe6c0a791abf542f859c" + }, + "transactionDetails": { + "orderDescription": "A can of juice" + }, + "payeeInstrument": { + "key": "66ef4cd0-aa02-444f-b4bd-81cce3f6674e", + "ID": "5ad9fde20a791abf542f8598" + } +} + + +``` + +That generates: + +``` +{ + "requestToPayID": "5ad9fec20a791abf542f859f" +} +``` + +## step 3 ## + +create a card +/payment-instruments/cards +Save card details. + +``` +{ + "payer": { + "email": "a@b.com", + "firstName": "Bob", + "lastName": "Minion" + }, + "card": { + "nameOnCard": "John E Doe", + "PAN": "4444333322221111", + "expiryDate": "01-20", + "startDate": "01-00", + "issueNumber": 1, + "CV2": "134", + "address": { + "address1": "Flat 20", + "address2": "Victoria House", + "address3": "15 The Street", + "town": "Christchurch", + "county": "Dorset", + "postcode": "BH23 6AA", + "phoneNumber": "+44 123 1110000" + } + } + } + + +created + +{ + "cardUsageKey": "c1de7a81-2181-472d-b552-9a2e8aab9307", + "cardID": "5ada05fa0a791abf542f85a9" +} + +``` + +## step 4 ## + + +`post /payables/rtps/5ad9fec20a791abf542f859f/atps` + +``` +{ + "payerInstrument": { + "ID": "5ada05fa0a791abf542f85a9", + "key": "c1de7a81-2181-472d-b552-9a2e8aab9307" + }, + "amount": { + "value": 100, + "currency": "GBP" + } +} +``` + +result + +``` +{ + "transaction": { + "id": "1c63f278-edc7-47d9-ac3b-4574e9828a6f" + }, + "additionalInfo": { + "cardSchemeName": "VISA CREDIT", + "riskScore": "1" + }, + "atpID": "5ada06fc0a791abf542f85b9" +} +``` \ No newline at end of file diff --git a/tasks/bridge-826/tests.md b/tasks/bridge-826/tests.md new file mode 100644 index 0000000..f0e27c6 --- /dev/null +++ b/tasks/bridge-826/tests.md @@ -0,0 +1,74 @@ +# Acceptance Criteria # + +Summary + +As a user, I want to pay an RTP in full. This is an attempt to pay (ATP) + +The following acceptance criteria tests were performed on DEV. + +### 1. User successfully pays the RTP (ATP is successfull) ### + +Given that I am an authorised Bridge user + +When I make a request to POST /payables/rtps/{objectID}/atps + +If the request body contains my saved card payment instrument ID + +And the instrument ID is a valid ID for a saved card payment instrument + +And the instrument belongs to me + +And I have specified the corresponding encryption key in the request body + +Or I have specified other details as per BRIDGE-284 (apart from payee details) in the request body + +And the RTP existsAnd the RTP is in the correct state (Status: Pending) + +And I specify the correct amount (the amount specified on the RTP) + +Then the payment is processed as per BRIDGE‌-325 + + + + +Create a new worldpay merchant account using `/payment-instruments/worldpay-merchants` + +Testing data: + +```json +{ + "key": "66bbbe00-bd6c-4b34-8269-d19a041045a8", + "ID": "5abcecc0de91bd75beb21a0e" +} +``` + + + +### 2. I have supplied a saved payment instrument and the instrument ID is invalid ### + + + +### 3. I have supplied a saved payment instrument and the instrument does not belong to me ### + + + +### 4. I have supplied a saved payment instrument and the encryption key is not correct ### + + + +### 5. the RTP does not exist ### + + + +### 6. The RTP is not in the Pending state ### + + + +### 7. The amount does not match the RTP's amount ### + + + +### 8. Request should be logged ### + + + diff --git a/tasks/bridge-826/what.md b/tasks/bridge-826/what.md new file mode 100644 index 0000000..2aae7ee --- /dev/null +++ b/tasks/bridge-826/what.md @@ -0,0 +1,42 @@ +As a user I want to pay an RTP in full (using stored or new instrument) + + +Summary + +As a user, I want to pay an RTP in full. This is an attempt to pay (ATP) + +AC's + +1. User successfully pays the RTP (ATP is successfull) + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument belongs to meAnd I have specified the corresponding encryption key in the request bodyOr I have specified other details as per BRIDGE-284 (apart from payee details) in the request bodyAnd the RTP existsAnd the RTP is in the correct state (Status: Pending)And I specify the correct amount (the amount specified on the RTP)Then the payment is processed as per BRIDGE‌-325 + +2. I have supplied a saved payment instrument and the instrument ID is invalid + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is invalidThen the payment fails with status 400 + +3. I have supplied a saved payment instrument and the instrument does not belong to me + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument does not belong to meThen the payment fails with status 400 + +4. I have supplied a saved payment instrument and the encryption key is not correct + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument belongs to meAnd I have specified the wrong encryption key in the request bodyThen the payment fails with status 401 + +5. the RTP does not exist + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument belongs to meAnd I have specified the corresponding encryption key in the request bodyOr I have specified other details as per (apart from payee details) in the request bodyAnd the RTP doe not existThen the payment fails with status 400 + +6. The RTP is not in the Pending state + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument belongs to meAnd I have specified the corresponding encryption key in the request bodyOr I have specified other details as per (apart from payee details) in the request bodyAnd the RTP existsAnd the RTP is not in the correct state (Status: Pending)Then the payment fails with status 400 + +7. The amount does not match the RTP's amount + +Given that I am an authorised Bridge userWhen I make a request to POST /payables/rtps/{objectID}/atpsIf the request body contains my saved card payment instrument IDAnd the instrument ID is a valid ID for a saved card payment instrumentAnd the instrument belongs to meAnd I have specified the corresponding encryption key in the request bodyOr I have specified other details as per (apart from payee details) in the request bodyAnd the RTP existsAnd the RTP is in the correct state (Status: Pending)And I specify the incorrect amount (the amount specified on the RTP)Then the payment fails with status 400 + +9. Request should be logged + +Given that I have made a request as per the other scenarios on this storyWhen the request is processedThen compliance information about the request and response is logged to the database + +10. Wiki should be updated \ No newline at end of file diff --git a/tasks/bridge-837/checkin-summary.md b/tasks/bridge-837/checkin-summary.md new file mode 100644 index 0000000..6c0a9e6 --- /dev/null +++ b/tasks/bridge-837/checkin-summary.md @@ -0,0 +1,68 @@ +BRIDGE-837 Swagger UI for list all ATPs where I am the payee + +# Summary + +As an operator I want to list all ATPs where I am the payee + +This updates the swagger so the user can list their attempts to pay (ATP) where they are the payee. + +Using `GET /receivables/atps` + +### New Output + +```json +{ + "data": [ + { + "atpID": "000000000000000000000000", + "rtpID": "000000000000000000000000", + "payeeID": "000000000000000000000000", + "payerID": "000000000000000000000000", + "status": "Paid", + "lastUpdate": "2017-07-16T19:20:30.450Z", + "lastVersion": 0, + "payeeInstrument": { + "ID": "000000000000000000000000", + "description": "BloggsCo Inc. account.", + "accountType": "Credit/Debit Payment Card" + }, + "payerDetails": { + "payer": { + "email": "a@b.com", + "firstName": "John", + "lastName": "Doe" + }, + "payerInstrument": { + "ID": "000000000000000000000000", + "description": "BloggsCo Inc. account.", + "accountType": "Credit/Debit Payment Card" + } + }, + "amount": { + "value": 0, + "currency": "GBP" + }, + "transactionDetails": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + }, + "resultDetails": { + "errorDetails": { + "statusCode": 200, + "code": 1, + "info": "Some error" + }, + "processorResponse": { + "transactionID": "00000000-0000-0000-0000-000000000000" + } + } + } + ] +} +``` + +# Test Plan + +* Check the server starts ok +* Check the /docs page shows the new paths +* Check we can still carry out the operations from that page +* Check the unit tests all run and pass \ No newline at end of file diff --git a/tasks/bridge-837/swagger b/tasks/bridge-837/swagger new file mode 100644 index 0000000..ce737cc --- /dev/null +++ b/tasks/bridge-837/swagger @@ -0,0 +1,35 @@ +When I call GET /receivables/atps + + + +"/receivables/atps": { + "x-swagger-router-controller": "receivable_atp_controller", + "get": { + "summary": "Gets a list ATP's which I am the payee", + "description": "Return a list of Attempts to Pay (ATPs) for which I am the payee", + "tags": [ "payments" ], + "operationId": "listPayeeATPs", + "responses": { + "200": { + "description": "Successfully list ATPs.", + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/atpList" + } + } + } + }, + "400": { + "description": "Validation failed", + "schema": { + "$ref": "#/definitions/badParametersInfo" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } +}, \ No newline at end of file diff --git a/tasks/bridge-838/checkin-summary.md b/tasks/bridge-838/checkin-summary.md new file mode 100644 index 0000000..d15aa79 --- /dev/null +++ b/tasks/bridge-838/checkin-summary.md @@ -0,0 +1,34 @@ +BRIDGE-838 E2E Tests of Swagger Def + +# Summary + +* Updated test, simplified the authorisation test. Replaced the older method by using the e2e-helper. + +# Test Plan + +* Run All tests +* Run E2E: get All ATPs + +Test Results + +``` + + E2E: List all ATPs receivable for payee + Valid path + + ✓ with a valid path + + authorization + + ✓ is required to access the path + + + 2 passing (605ms) + + + + +``` + + + diff --git a/tasks/bridge-839/what.md b/tasks/bridge-839/what.md new file mode 100644 index 0000000..0f533da --- /dev/null +++ b/tasks/bridge-839/what.md @@ -0,0 +1,61 @@ +As an operator I want to list all ATPs where I am the payee + +Summary + +As a User, I would like to be able to retrieve a list of my ATP's where I am the payee. + +ACs + + + +## 1. I see a list of ATP's where I am the payee + + +Given that I am an authorised Bridge user + +When I call GET /receivables/atps + +Then the request succeeds + +And the request returns an array of the ATP's which I am the payee + + + +## I do not see ATP's where I not am the payee + +Given that I am an authorised Bridge user + +When I call GET /receivables/atps + +Then the request succeeds + +And the request returns an array of the ATP's which I am the payee + +And the array does not contain any ATP's which I am not the payee + + + +``` + +"/receivables/atps": { + "x-swagger-router-controller": "receivable_atp_controller", + "get": { + "summary": "Gets a list ATP's which I am the payee", + "description": "Return a list of Attempts to Pay (ATPs) for which I am the payee", + "tags": [ "payments" ], + "operationId": "listPayeeATPs", + "responses": { + "200": { + "description": "Successfully list ATPs.", + "schema": { + "$ref": "#/definitions/atpList" + } + }, + "default": { + "$ref": "#/responses/GeneralError" + } + } + } + } + +``` \ No newline at end of file diff --git a/tasks/bridge-844/swagger b/tasks/bridge-844/swagger new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-844/what b/tasks/bridge-844/what new file mode 100644 index 0000000..060f754 --- /dev/null +++ b/tasks/bridge-844/what @@ -0,0 +1,17 @@ +Summary + +As a User, I would like to be able to retrieve the detail of one ATP where I am the payee. + +AC's + +1. I see the detail of the ATP + +Given that I am an authorised Bridge userWhen I call GET receivables/atps/{objectID}And the ATP existsAnd my UserID is the same as the payee IDThen the request succeedsAnd the request returns an object containing the ATP which i requested. + +2. The ATP does not exist + +Given that I am an authorised Bridge userWhen I call GET receivables/atps/{objectID}And the ATP does not existThen the request failsWith Http code 400 + +3. My UserID does not match the payee ID + +Given that I am an authorised Bridge userWhen I call GET receivables/atps/{objectID}And the ATP existsAnd my UserID is not the same as the payee IDThen the request failsWith Http code 400 \ No newline at end of file diff --git a/tasks/bridge-858/Untitled-15 b/tasks/bridge-858/Untitled-15 new file mode 100644 index 0000000..830391f --- /dev/null +++ b/tasks/bridge-858/Untitled-15 @@ -0,0 +1,130 @@ +GET /payables/rtps/{rtpID}/atps + + +"/payables/rtps/{objectID}/atps" + + + + +"get": { + "summary": "Gets all Attempts to Pay (ATP) for a Request to Pay (RTP).", + "description": "Return a list of Attempts to Pay (ATPs) for a specific Request to Pay (RTP)", + "tags": [ "payments" ], + "operationId": "listPayablesATP", + "parameters": [ + { "$ref": "#/parameters/objectID" } + ], + "responses": {{ + "201": { + "description": "Successfully list associated ATP.", + "schema":{ + "allOf": [ + {"$ref": "#/definitions/TransactionSucceededInfo"}, + { + "type": "object", + "properties": { + "rtpID": {"$ref": "#/definitions/object-id"} + }, + "required": [ "rtpID" ] + } + ] + } + }, + "400": { + "description": "Validation failed", + "schema":{ + "allOf": [ + {"$ref": "#/definitions/badParametersInfo"}, + { + "type": "object", + "properties": { + "rtpID": {"$ref": "#/definitions/object-id"} + } + } + ] + } + }, + "401": { + "description": "Invalid key", + "schema":{ + "allOf": [ + {"$ref": "#/definitions/ErrorInfo"}, + { + "type": "object", + "properties": { + "atpID": {"$ref": "#/definitions/object-id"} + }, + "required": [ "rtpID" ] + } + ] + } + }, + "default": { + "description": "General error response format", + "schema":{ + "allOf": [ + {"$ref": "#/responses/GeneralError"}, + { + "type": "object", + "properties": { + "atpID": {"$ref": "#/definitions/object-id"} + } + } + ] + } + } + } + } + + + succesfull payment attempts + + + + + + + +{ + "_id": ObjectId("0123456789abcdef01234567"), + "RtpID": "0123456789abcdef01234567", + "PayeeID": "0123456789abcdef01234567", + "PayerID": "0123456789abcdef01234567", + "PayeeInstrument": { + "_id": ObjectId("0123456789abcdef01234567"), + "AccountType": "Worldpay Online Payments Account", + "Description": "BloggsCo Inc. account." + }, + "PayerInstrument": { + "Payer": { + "Email": "a@example.com", + "FirstName": "Joe", + "LastName": "Bloggs" + }, + "PayerInstrument": { + "_id": ObjectId("0123456789abcdef01234567"), + "AccountType": "Credit/Debit Payment Card", + "Description": "My payment card" + } + }, + "Amount": { + "Value": 220, + "Currency": "GBP" + }, + "TransactionDetails": { + "OrderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + }, + "Status": "Paid", + "ResultDetails": { + "ProcessorResponse": { + "StatusCode": 200, + "TransactionID": "76ebfbaa-7cd9-4f01-bd18-a32681f33133", + "RiskScore": 1 + } + }, + "LastUpdate": ISODate("2018-04-06T10:20:38.014Z"), + "LastVersion": 1 +} + + + diff --git a/tasks/bridge-858/check b/tasks/bridge-858/check new file mode 100644 index 0000000..12391af --- /dev/null +++ b/tasks/bridge-858/check @@ -0,0 +1,86 @@ +{ + "_id": ObjectId("0123456789abcdef01234567"), + "RtpID": "0123456789abcdef01234567", + "PayeeID": "0123456789abcdef01234567", + "PayerID": "0123456789abcdef01234567", + "PayeeInstrument": { + "_id": ObjectId("0123456789abcdef01234567"), + "AccountType": "Worldpay Online Payments Account", + "Description": "BloggsCo Inc. account." + }, + "PayerInstrument": { + "Payer": { + "Email": "a@example.com", + "FirstName": "Joe", + "LastName": "Bloggs" + }, + "PayerInstrument": { + "_id": ObjectId("0123456789abcdef01234567"), + "AccountType": "Credit/Debit Payment Card", + "Description": "My payment card" + } + }, + "Amount": { + "Value": 220, + "Currency": "GBP" + }, + "TransactionDetails": { + "OrderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + }, + "Status": "Paid", + "ResultDetails": { + "ProcessorResponse": { + "StatusCode": 200, + "TransactionID": "76ebfbaa-7cd9-4f01-bd18-a32681f33133", + "RiskScore": 1 + } + }, + "LastUpdate": ISODate("2018-04-06T10:20:38.014Z"), + "LastVersion": 1 +} + +------------ + +{ + "atpID": "000000000000000000000000", + "rtpID": "000000000000000000000000", + "payeeID": "000000000000000000000000", + "payerID": "000000000000000000000000", + "status": "Pending", + "lastUpdate": "2017-07-16T19:20:30.450Z", + "lastVersion": 0, + "payeeInstrument": { + "ID": "000000000000000000000000", + "description": "Description of the payee Instrument", + "accountType": "Credit/Debit Payment Card" + }, + "payerDetails": { + "payer": { + "email": "a@b.com", + "firstName": "John", + "lastName": "Doe" + }, + "payerInstrument": { + "ID": "000000000000000000000000", + "description": "Description of the payee Instrument", + "accountType": "Credit/Debit Payment Card" + } + }, + "amount": { + "value": 0, + "currency": "GBP" + }, + "transactionDetails": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + }, + "resultDetails": { + "errorDetails": { + "statusCode": 200, + "code": 1, + "info": "Some error" + }, + "processorResponse": { + "transactionID": "00000000-0000-0000-0000-000000000000" + } + } +} \ No newline at end of file diff --git a/tasks/bridge-858/checkin-summary.md b/tasks/bridge-858/checkin-summary.md new file mode 100644 index 0000000..6cb850f --- /dev/null +++ b/tasks/bridge-858/checkin-summary.md @@ -0,0 +1,33 @@ + +BRIDGE-858 Update swagger definition + +# Summary + +This updates the swagger so the user can list their attempts to pay (ATP) for a specific RTP GET /payables/rtps/{rtpID}/atps + +# Test Plan + +* Check the server starts ok +* Check the /docs page shows the new paths +* Check we can still carry out the operations from that page +* Check the unit tests all run and pass + + + +BRIDGE-800 Update swagger definition + +# Summary + +This updates the swagger and end-to-end tests for the existing `/rtps` +paths to move them under `/receivables/rtps` to leave room for future +development of `/payables/rtps` for the counterparty/payer side. + +# Test Plan + +* Check the server starts ok +* Check the /docs page shows the new paths +* Check we can still carry out the operations from that page +* Check the unit tests all run and pass + + + diff --git a/tasks/bridge-858/structure b/tasks/bridge-858/structure new file mode 100644 index 0000000..9f5e898 --- /dev/null +++ b/tasks/bridge-858/structure @@ -0,0 +1,80 @@ +{ + "AtpID": { "$ref": "#/definitions/object-id" }, + "RtpID": { "$ref": "#/definitions/object-id" }, + "PayeeID": { "$ref": "#/definitions/object-id" }, + "PayerID": { "$ref": "#/definitions/object-id" }, + "PayeeInstrument": { + "$ref": "#/definitions/payee-instrument-extended" + }, + + + "PayerInstrument": { + "type": "object", + "properties": { + "Payer": "#/definitions/payer", + "PayerInstrument": { + "$ref": "#/definitions/payee-instrument-extended" + } + } + }, + + + "amount": { "$ref": "#/definitions/amount-params" }, + + "transactionDetails": { "$ref": "#/definitions/worldpay-transaction-details-params" }, + "status" : {"$ref": "#/definitions/rtpStatus"}, + + + "ResultDetails": { + "ProcessorResponse": { + "StatusCode": 200, + "TransactionID": "76ebfbaa-7cd9-4f01-bd18-a32681f33133", + "RiskScore": 1 + } + }, + + + "LastUpdate": ISODate("2018-04-06T10:20:38.014Z"), + "LastVersion": 1 +} + + +{"$ref": "#/definitions/object-id"} + + + +"PayeeInstrument": { + "_id": { "$ref": "#/definitions/object-id" }, + "AccountType": "Worldpay Online Payments Account", + "Description": "BloggsCo Inc. account." + } + + + + + + + , + { + "type": "object", + "properties": { + "lastUpdate": {"$ref": "#/definitions/iso-date"}, + "lastVersion": {"$ref": "#/definitions/rtp-last-version"}, + "payeeInstrument": {"$ref": "#/definitions/instrument-id-and-description"}, + "status" : {"$ref": "#/definitions/rtpStatus"}, + "requestToPayID": {"$ref": "#/definitions/object-id"} + }, + "required": ["lastUpdate", "lastVersion", "payeeInstrument", "status", "requestToPayID"] + } + + + + + , + "processor-response": { + "type": "object", + "properties": { + "statusCode": "#/definitions/something", + "transactionID": "#/definitions/uuid" + } + }, \ No newline at end of file diff --git a/tasks/bridge-860/checkin-summary.md b/tasks/bridge-860/checkin-summary.md new file mode 100644 index 0000000..5eed158 --- /dev/null +++ b/tasks/bridge-860/checkin-summary.md @@ -0,0 +1,43 @@ + +BRIDGE-860 E2E Tests of Swagger Def + +# Summary + +This adds E2E tests for testing the new swagger new endpoint `/dev/v0/payables/rtps/{rtp}/atps' + +# Test Plan + +* Run All tests +* Run E2E: get All ATPs + +Test Results + +``` + + E2E: get All ATPs + objectID tests + + 1) with a valid objectID + + ✓ objectID with an invalid pattern + + ✓ objectID is too short + + ✓ objectID is too long + + ✓ responds with 404 + + ✓ responds with error body + + ✓ responds with error body (58ms) + + + 6 passing (701ms) + 1 failing + + 1) E2E: get All ATPs + objectID tests + with a valid objectID: + Error: expected 502 "Bad Gateway", got 500 "Internal Server Error" + +``` \ No newline at end of file diff --git a/tasks/bridge-860/get-all-atps-for-rtp.spec.js b/tasks/bridge-860/get-all-atps-for-rtp.spec.js new file mode 100644 index 0000000..a94b0eb --- /dev/null +++ b/tasks/bridge-860/get-all-atps-for-rtp.spec.js @@ -0,0 +1,46 @@ +/** + * @fileOverview End-to-end testing of the get all ATPs related to a payable RTP + */ +'use strict'; + +const helper = require('../../utils/test/e2e-helper'); + +let app; + +// Standard errored values + +const TOO_LONG = '0000000000000000000000001'; +const TOO_SHORT = '0123'; +const BAD_UUID = '00000000000000000000000Z'; +const VALID_UUID = '000000000000000000000000'; + +// Valid test data + +describe('E2E: get All ATPs', () => { + /** + * Load the dev API router to handle `/dev/*` routes + */ + before(() => { + app = new helper.DevValidatorApp(); + }); + it('with a valid objectID', () => { + app.setRequestPath('/dev/v0/payables/rtps/' + VALID_UUID + '/atps'); + + return app.getAndValidate(502); + }); + it('objectID with an invalid pattern', () => { + app.setRequestPath('/dev/v0/payables/rtps/' + BAD_UUID + '/atps'); + + return app.getAndValidate(400, undefined, helper.errors.failedPattern('objectID')); + }); + it('objectID is too short', () => { + app.setRequestPath('/dev/v0/payables/rtps/' + TOO_SHORT + '/atps'); + + return app.getAndValidate(400, undefined, helper.errors.minLength('objectID')); + }); + it('objectID is too long', () => { + app.setRequestPath('/dev/v0/payables/rtps/' + TOO_LONG + '/atps'); + + return app.getAndValidate(400, undefined, helper.errors.maxLength('objectID')); + }); +}); diff --git a/tasks/bridge-860/what.md b/tasks/bridge-860/what.md new file mode 100644 index 0000000..228e98f --- /dev/null +++ b/tasks/bridge-860/what.md @@ -0,0 +1,61 @@ +As a user I want to list all ATPs related to my payable RTP + + + +Summary + +User sees all ATPs related to their RTP where they are the counterparty + +Acceptance Criteria + +1. If neither payee not payer of ATP + +*Given* that I am an authorised Bridge user + +AND I am neither payee not payer of ATP + +When I GET /payables/rtps/{rtpID}/atps + +THEN request returns basic details on ALL related ATPs + +2. IF they ARE also the ATP payee + +*Given* that I am an authorised Bridge user + +AND I am the ATP payee + +When I GET /payables/rtps/{rtpID}/atps + +THEN request returns full payeeInstrument info + +3. IF they ARE NOT also the ATP payee + +*Given* that I am an authorised Bridge user + +AND I am AM NOT also the ATP payee + +When I GET /payables/rtps/{rtpID}/atps + +THEN request returns reduced/no payeeInstrument info + +4. IF they ARE also the ATP payer + +*Given* that I am an authorised Bridge user + +AND I am also the ATP payer + +When I GET /payables/rtps/{rtpID}/atps + +THEN request returns full payerInstrument + +5. IF they ARE NOT also the ATP payer + +*Given* that I am an authorised Bridge user + +AND I am NOT also the ATP payer + +When I GET /payables/rtps/{rtpID}/atps + +THEN request returns reduced/no payerInstrument info + +6. The wiki is updated \ No newline at end of file diff --git a/tasks/bridge-868/checkin-summary.md b/tasks/bridge-868/checkin-summary.md new file mode 100644 index 0000000..6c6a05e --- /dev/null +++ b/tasks/bridge-868/checkin-summary.md @@ -0,0 +1,54 @@ +# Summary + +This adds the swagger for getting a list of the ATPs associated with +a receivable RTP. + +This also updates the response to the listing of ATPs related to _payable_ +RTP to match the implementation of receivables.  The changes are: + +* Change the 201 Created response to a basic 200 as this is list not create +* Remove the 401 "Invalid Key" error as there are no keys involved +* Removed the atpID from all error responses as it isn't relevant + +It also makes some small updates to other definitions used by the shared +`atpList` and related definitions: + +* Adds and uses an `atpStatus` definition rather than the `rtpStatus` +  which has a different list of states +* Updated `instrument-id-description` and `instrument-id-description-type` +  to use the generic `instrument-description` instead of the payee specific +  version. This stops the _payer_ instrument having a description saying +  that it is the _payee_ instrument + +* Updated the 200 return object: + +The return object had a small issue where it was returning a data object, with a data array: +``` +{ + "data": { + "data": [ + { + ... + } +} + +``` + +The object schema was updated to just use the atpList object definition as that returns the data array: + +The output now looks like: + +``` +{ + "data": [ + { + ... + } +} + +``` + +# Test Plan + +* Check the server starts ok +* Check the docs page looks correct for list ATPs for both payables and receivables. \ No newline at end of file diff --git a/tasks/bridge-877/checkin-summary.md b/tasks/bridge-877/checkin-summary.md new file mode 100644 index 0000000..ec9e9b9 --- /dev/null +++ b/tasks/bridge-877/checkin-summary.md @@ -0,0 +1,12 @@ +BRIDGE-877 Spelling mistake in "Merhcant" error message + +# Summary + +This fixes the spelling of the word 'Merhcant' + +* The word 'Merhcant' was changed to 'Merchant' + + +# Test Plan + +* Run All tests diff --git a/tasks/bridge-885/checkin-summary.md b/tasks/bridge-885/checkin-summary.md new file mode 100644 index 0000000..70252c3 --- /dev/null +++ b/tasks/bridge-885/checkin-summary.md @@ -0,0 +1,64 @@ +BRIDGE-885 Swagger UI for list returns a single ATP + +# Summary + +This updates the swagger so the user can list their attempts to pay (ATP) for a specific RTP GET /payables/rtps/{rtpID}/atps as an actuall array. + +### New Output + +```json +{ + "data": [ + { + "atpID": "000000000000000000000000", + "rtpID": "000000000000000000000000", + "payeeID": "000000000000000000000000", + "payerID": "000000000000000000000000", + "status": "Pending", + "lastUpdate": "2017-07-16T19:20:30.450Z", + "lastVersion": 0, + "payeeInstrument": { + "ID": "000000000000000000000000", + "description": "Description of the payee Instrument", + "accountType": "Credit/Debit Payment Card" + }, + "payerDetails": { + "payer": { + "email": "a@b.com", + "firstName": "John", + "lastName": "Doe" + }, + "payerInstrument": { + "ID": "000000000000000000000000", + "description": "Description of the payee Instrument", + "accountType": "Credit/Debit Payment Card" + } + }, + "amount": { + "value": 0, + "currency": "GBP" + }, + "transactionDetails": { + "orderDescription": "2 Calling Birds, 1 Partridge in a Pear tree" + }, + "resultDetails": { + "errorDetails": { + "statusCode": 200, + "code": 1, + "info": "Some error" + }, + "processorResponse": { + "transactionID": "00000000-0000-0000-0000-000000000000" + } + } + } + ] +} +``` + +# Test Plan + +* Check the server starts ok +* Check the /docs page shows the new paths +* Check we can still carry out the operations from that page +* Check the unit tests all run and pass \ No newline at end of file diff --git a/tasks/bridge-885/stuff b/tasks/bridge-885/stuff new file mode 100644 index 0000000..e9b42eb --- /dev/null +++ b/tasks/bridge-885/stuff @@ -0,0 +1,112 @@ +"allOf": [ + {"$ref": "#/definitions/atp-list-base-item"}, + { + "type": "object", + "properties": { + "payeeInstrument": { + "$ref": "#/definitions/payee-instrument-extended" + }, + "payerDetails": { + "type": "object", + "properties": { + "payer": {"$ref": "#/definitions/payer"}, + "payerInstrument": { + "$ref": "#/definitions/payer-instrument-extended" + } + } + }, + "amount": { "$ref": "#/definitions/amount-value-currency-params" }, + "transactionDetails": { "$ref": "#/definitions/transaction-details-params" }, + "resultDetails": { + "type": "object", + "properties": { + "errorDetails" : { + "$ref": "#/definitions/ErrorDetails" + }, + "processorResponse": { + "$ref" : "#/definitions/processor-response" + } + } + } + }, + "required": ["PayeeInstrument"] + } + ] + } + + + + +"rtp-get-item": { + "type" : "object", + "allOf": [ + {"$ref": "#/definitions/baseRTP"}, + { + "type": "object", + "properties": { + "lastUpdate": {"$ref": "#/definitions/iso-date"}, + "lastVersion": {"$ref": "#/definitions/rtp-last-version"}, + "payeeInstrument": {"$ref": "#/definitions/instrument-id-and-description"}, + "status" : {"$ref": "#/definitions/rtpStatus"}, + "requestToPayID": {"$ref": "#/definitions/object-id"} + }, + "required": ["lastUpdate", "lastVersion", "payeeInstrument", "status", "requestToPayID"] + } + ], + "required": ["amount", "counterparty", "transactionDetails"] + }, + + + + "atpList": { + "type": "object", + "description": "Successful list", + "properties" : { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/atp-get-item" + } + } + } + } + +, +"atp-get-item": { + "type" : "object", + "allOf": [ + {"$ref": "#/definitions/atp-list-base-item"}, + { + "type": "object", + "properties": { + "payeeInstrument": { + "$ref": "#/definitions/payee-instrument-extended" + }, + "payerDetails": { + "type": "object", + "properties": { + "payer": {"$ref": "#/definitions/payer"}, + "payerInstrument": { + "$ref": "#/definitions/payer-instrument-extended" + } + } + }, + "amount": { "$ref": "#/definitions/amount-value-currency-params" }, + "transactionDetails": { "$ref": "#/definitions/transaction-details-params" }, + "resultDetails": { + "type": "object", + "properties": { + "errorDetails" : { + "$ref": "#/definitions/ErrorDetails" + }, + "processorResponse": { + "$ref" : "#/definitions/processor-response" + } + } + } + }, + "required": ["PayeeInstrument"] + } + ] + } +} \ No newline at end of file diff --git a/tasks/bridge-895/test.md b/tasks/bridge-895/test.md new file mode 100644 index 0000000..8efd96a --- /dev/null +++ b/tasks/bridge-895/test.md @@ -0,0 +1,63 @@ +db.getCollection('mdtest').insertMany( +[{item:"Record a", "createdAt": new Date()}, {item:"Record b", "createdAt": new Date()}, {item:"Record c", "deleteable": 1, "createdAt": new Date()}, {item:"Record D", "createdAt": new Date()}, {item:"Record e", "createdAt": new Date()}, {item:"Record f", "createdAt": new Date() }] +) + + + + + +```json +/* 1 */ +{ + "_id" : ObjectId("5ae05eda5a560b44ecfed75e"), + "item" : "Record a", + "createdAt" : ISODate("2018-04-25T10:56:26.833Z") +} + +/* 2 */ +{ + "_id" : ObjectId("5ae05eda5a560b44ecfed75f"), + "item" : "Record b", + "createdAt" : ISODate("2018-04-25T10:56:26.833Z") +} + +/* 3 */ +{ + "_id" : ObjectId("5ae05eda5a560b44ecfed760"), + "item" : "Record c", + "deleteable" : 1.0, + "createdAt" : ISODate("2018-04-25T10:56:26.833Z") +} + +/* 4 */ +{ + "_id" : ObjectId("5ae05eda5a560b44ecfed761"), + "item" : "Record D", + "createdAt" : ISODate("2018-04-25T10:56:26.833Z") +} + +/* 5 */ +{ + "_id" : ObjectId("5ae05eda5a560b44ecfed762"), + "item" : "Record e", + "createdAt" : ISODate("2018-04-25T10:56:26.833Z") +} + +/* 6 */ +{ + "_id" : ObjectId("5ae05eda5a560b44ecfed763"), + "item" : "Record f", + "createdAt" : ISODate("2018-04-25T10:56:26.833Z") +} + +``` + +db.getCollection('mdtest').createIndex( { "createdAt": 1 }, { expireAfterSeconds: 180, background:true } ) + +TTL set for 3 minutes + + + +quickDelete: 2m +longDelete: 10m + diff --git a/tasks/bridge-895/what.md b/tasks/bridge-895/what.md new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-895/writeup.md b/tasks/bridge-895/writeup.md new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-901/checkin-summary.md b/tasks/bridge-901/checkin-summary.md new file mode 100644 index 0000000..b9c8da9 --- /dev/null +++ b/tasks/bridge-901/checkin-summary.md @@ -0,0 +1,61 @@ +BRIDGE-901 Unit test decrypt-card.spec.js sometimes fails due to MS difference + +# Summary + +The two objects TEST_ACCOUNT_DECRYPTED and TEST_ACCOUNT_ENCRYPTED were both created using `new Date()` to create the lastUpdated value. + +``` +TEST_ACCOUNT_ENCRYPTED = { + ... + LastUpdate: new Date(), + ... +} + +TEST_ACCOUNT_DECRYPTED = { + ... + LastUpdate: new Date(), + ... +} + + +``` +The new version has a lastUpdate created before the two objects are created, and the objects using that to ensure the dates match. + +``` +const lastUpdate = new Date(); + +TEST_ACCOUNT_ENCRYPTED = { + ... + LastUpdate: lastUpdate, + ... +} + +TEST_ACCOUNT_DECRYPTED = { + ... + LastUpdate: lastUpdate, + ... +} + + +``` + +# Test Plan + +* Run All tests +* Run common.instrument.decrypt-card + +Test Results + +``` + + common.instrument.decrypt-card + ✓ it returns decrypted keys if instrument is valid + ✓ it throws a "DECRYPTION_FAIL" HttpError if key is wrong + ✓ it throws a "DECRYPTION_FAIL" HttpError if UserID is wrong + + + 3 passing (14ms) + + + +``` \ No newline at end of file diff --git a/tasks/bridge-922/checkin-summary.md b/tasks/bridge-922/checkin-summary.md new file mode 100644 index 0000000..e69a701 --- /dev/null +++ b/tasks/bridge-922/checkin-summary.md @@ -0,0 +1,67 @@ +BRIDGE-922 E2E Tests of Swagger Def + +# Summary + +This adds E2E tests for testing the new swagger new endpoint `/dev/v0/payables/rules' + +* tests refreshed using the new test framework +* createRule stub added to `dev_api/controllers/rules_controller.js` + + +# Test Plan + +* Run All tests +* Run E2E: Create a rule + +Test Results + +``` + + E2E: Create a rule + tests the body + tests with missing required parameters + + Missing paymentInstrument contents + + ✓ with no payer instrument encryptionKey parameter (63ms) + + Missing Trigger + + ✓ with no Trigger parameter + + Missing Payment rules + + ✓ with no Payment rules parameter + + Bad data tests + + ✓ with a badly formatted rule payer instrument CV2 parameter + + ✓ with a badly formatted rule payer key parameter + + ✓ with a badly formatted rule payeeID parameter + + ✓ with a short rule payeeID parameter + + ✓ with a long rule payeeID parameter + + ✓ with a badly formatted rule percentageShare parameter + + ✓ with a out of range rule percentageShare parameter + + ✓ with a badly formatted Trigger Stage parameter + + ✓ with a badly formatted Trigger Type parameter + + ✓ with a badly formatted Payment Rule parameter + + Good parameter data tests + + ✓ with a full set of correct parameters + + + 14 passing (820ms) + + + +``` \ No newline at end of file diff --git a/tasks/bridge-922/structure.md b/tasks/bridge-922/structure.md new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge-922/what.md b/tasks/bridge-922/what.md new file mode 100644 index 0000000..e69de29 diff --git a/tasks/bridge_592/tests.md b/tasks/bridge_592/tests.md new file mode 100644 index 0000000..1496685 --- /dev/null +++ b/tasks/bridge_592/tests.md @@ -0,0 +1,120 @@ +#### worldpayPayment #### + +Make a payment (not to be confused with making a worldpay payment with a saved instrument!). + +function worldpayPayment(req, res) { + +```javascript +return payDirectly.payment(req.body) +``` + +changed to + +```javascript +return payDirectly.payment(req.swagger.params.body.value) +``` + +/payments/worldpay +Make a worldpay payment. + +Code 200 + +Response body + +```json +{ + "transaction": { + "id": "58b243a2-0d37-4205-a24d-f606a914124e" + } +} +``` + + +#### saveCardDetails #### + +Save the card + +```javascript +return createCard.create(req.body, req.session.data.user) +``` + +changed to + +```javascript +return createCard.create(req.swagger.params.body.value, req.session.data.user) +``` + +/payment-instruments/cards +Save card details. + +Code 201 + +Response body + +```json +{ + "cardUsageKey": "b8a1b1fc-31f2-42f3-be87-8a17b5145ea1", + "cardID": "5aafc2f6f1e5b108cb6be947" +} +``` + +#### saveWorldpayReceivingAccount #### + +Save a worldpay receiving account + +```javascript +return createWorldPayMerchant.create(req.body, req.session.data.user) +``` + +changed to + +```javascript +return createWorldPayMerchant.create(req.swagger.params.body.value, req.session.data.user) +``` + +/payment-instruments/worldpay-merchants +Save a worldpay receiving account. + +Code 201 + +Response body + +```json +{ + "key": "926db588-d800-496f-85ce-0c2c4a203665", + "ID": "5aafc1e7f1e5b108cb6be943" +} +``` + + +#### makeWorldpayPaymentWithSavedCard #### + +Logs the correct information + +```javascript +return payWithSavedCard.payment(req.body, req.swagger.params.instrumentID.value, req.session.data.user) +``` + +changed to + +```javascript +return payWithSavedCard.payment(req.swagger.params.body.value, req.swagger.params.instrumentID.value, req.session.data.user) +``` + +/payment-instruments/cards/{instrumentID}/payments +Pay using stored card. + +Code 200 + +Response body + +```json +{ + "transaction": { + "id": "09f16a90-4328-4625-85b9-995a69ae24b4" + } +} +``` + + + diff --git a/tasks/bridge_619/tests.dev.md b/tasks/bridge_619/tests.dev.md new file mode 100644 index 0000000..5ae80e1 --- /dev/null +++ b/tasks/bridge_619/tests.dev.md @@ -0,0 +1,421 @@ +# Acceptance Criteria # + +The following acceptance criteria tests were performed on DEV. + +### 1. User generates receivecode ### + +Create a new worldpay merchant account using `/payment-instruments/worldpay-merchants` + +Testing data: + +```json +{ + "key": "66bbbe00-bd6c-4b34-8269-d19a041045a8", + "ID": "5abcecc0de91bd75beb21a0e" +} +``` + + +Using : `/receivecodes` + +```json +{ + "key": "66bbbe00-bd6c-4b34-8269-d19a041045a8", + "ID": "5abcecc0de91bd75beb21a0e" +}} +``` + +Response: + +```json +{ + "receivecode": "SCYDG" +} + +``` + +Database Contains: + +```json +{ + "_id" : ObjectId("5abcecf5de91bd75beb21a11"), + "ReceiveCode" : "SCYDG", + "Creation" : ISODate("2018-03-29T13:41:09.080Z"), + "Expiry" : ISODate("2018-03-29T13:44:09.080Z"), + "PaymentInstrument" : { + "_id" : ObjectId("5abcecc0de91bd75beb21a0e"), + "AccountType" : "Worldpay Online Payments Account", + "ReceivingAccount" : 1, + "PaymentsAccount" : 0, + "WorldpayOnlinePaymentsInfo" : { + "ServiceKeyEncrypted" : "3::0a6915f1f98ee7d3b6aa06608c1d6d960e06002be6de2bf067f5337db301ceb52b534a23b233d2d464c8977026f2d9f034a807540076fb42d44f66425eaf390649f9786ca604dda45c93cb65cd6b839f8cbb6c41f43a6a6b566815ebe1d5d410", + "ServiceKey" : "T_S_********-****-****-****-********4bfb" + }, + "UserID" : "79a26d981246978135edadf1", + "VendorID" : "Worldpay", + "VendorAccountName" : "Worldpay Online Payments", + "Description" : "Utah Iron Inc. account.", + "IconLocation" : "worldpay-account.png", + "APIVersion" : "7.6.4-44af11fdc504cff51f7e5fdaff97a7cf1a6b09a4", + "Integrity" : null, + "LastUpdate" : ISODate("2018-03-29T13:40:16.505Z"), + "LastVersion" : 1 + }, + "Status" : "Pending" +} + +``` + +_Receivecode object contains the receivecode string_ + +```json +"ReceiveCode" : "SCYDG" +``` + +_Receivecode object contains re-encrypted payment instrument details_ + +```json +"WorldpayOnlinePaymentsInfo" : { + "ServiceKeyEncrypted" : "3::0a6915f1f98ee7d3b6aa06608c1d6d960e06002be6de2bf067f5337db301ceb52b534a23b233d2d464c8977026f2d9f034a807540076fb42d44f66425eaf390649f9786ca604dda45c93cb65cd6b839f8cbb6c41f43a6a6b566815ebe1d5d410", + "ServiceKey" : "T_S_********-****-****-****-********4bfb" + } +``` + +_Receivecode object contains an expiry timestamp_ + +```json +"Expiry" : ISODate("2018-03-29T13:44:09.080Z") +``` + +### 2. User specifies nonexistent instrument ID ### + +Using : `/receivecodes` + +```json +{ + "key": "12345678-9012-3456-7890-123456789012", + "ID": "000000000000000000000000" +} +``` + +Response: `400 Error Bad Request` + +```json +{ + "code": 600, + "info": "The instrument could not be found, has no access or has expired." +} +``` + + + +### 3. User specifies instrument ID belonging to another user ### + +Create a new instrument for user `YTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU2` + +Create a new worldpay merchant account using `/payment-instruments/worldpay-merchants` + +Testing data: + +```json +{ + "key": "2626d3f2-87a9-441a-9e4d-4c6e84ab50d6", + "ID": "5abceedbde91bd75beb21a1b" +} +``` + +Re-authorise with `YTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU1` + +Using : `/receivecodes` + +```json +{ + "key": "2626d3f2-87a9-441a-9e4d-4c6e84ab50d6", + "ID": "5abceedbde91bd75beb21a1b" +} +``` + +Response: + +`400 Error: Bad Request` + +```json +{ + "code": 600, + "info": "The instrument could not be found, has no access or has expired." +} + +``` + + + +### 4. User provides incorrect encryption key ### + +Using : `/receivecodes` + +```json +{ + "key": "badbadba-dbad-badb-adba-dbadbadbadba", + "ID": "5abcecc0de91bd75beb21a0e" +} +``` + +Response: + +`401 Error: Unauthroized` + +```json +{ + "code": 602, + "info": "The instrument could not be decrypted." +} +``` + +### 5. Payment instrument cannot create receivecodes ### + +Create a new worldpay merchant account using `/payment-instruments/worldpay-merchants` + +Testing data: + +```json +{ + "key": "d995b840-6f0a-4362-b401-da3466e409b3", + "ID": "5abcf18bde91bd75beb21a5f" +} +``` + +Modify record to remove the ability to create receive codes. + +```json +{ + "_id" : ObjectId("5abcf18bde91bd75beb21a5f"), + "AccountType" : "Worldpay Online Payments Account", + "ReceivingAccount" : 0, + "PaymentsAccount" : 0, + "WorldpayOnlinePaymentsInfo" : { + "ServiceKeyEncrypted" : "3::a8c615cda59f2c75653bd4f26953ca0aae5bd2b095f5e211899b146c7824bb18990f4c6309694a33360b92bf79f03d374350dba679b36e8c1a65ace8c817bd097e7d2d5ccbf0cb9f5d17347e7e1e49ef062074a375de6dc74b6237bb827dce45", + "ServiceKey" : "T_S_********-****-****-****-********4bfb" + }, + "UserID" : "79a26d981246978135edadf1", + "VendorID" : "Worldpay", + "VendorAccountName" : "Worldpay Online Payments", + "Description" : "Islington Copper Inc. account.", + "IconLocation" : "worldpay-account.png", + "APIVersion" : "7.6.4-44af11fdc504cff51f7e5fdaff97a7cf1a6b09a4", + "Integrity" : null, + "LastUpdate" : ISODate("2018-03-29T14:00:43.099Z"), + "LastVersion" : 1 +} + +``` + +Response: + +`400 Error: Bad Request` + +```json +{ + "key": "de851ec5-6b36-453a-870c-14bb63e16ede", + "ID": "5aba46ecb28f2c8e1700c9c8" +} +``` + + +### 6. Receivecode should be deleted when it expires ### + +Using the code created in AC 1: + +Using : `/receivecodes` + +```json +{ + "key": "66bbbe00-bd6c-4b34-8269-d19a041045a8", + "ID": "5abcecc0de91bd75beb21a0e" +}} +``` + +Response: + +```json +{ + "receivecode": "SCYDG" +} + +``` + +Database Contains: + +```json +{ + "_id" : ObjectId("5abcecf5de91bd75beb21a11"), + "ReceiveCode" : "SCYDG", + "Creation" : ISODate("2018-03-29T13:41:09.080Z"), + "Expiry" : ISODate("2018-03-29T13:44:09.080Z"), + "PaymentInstrument" : { + "_id" : ObjectId("5abcecc0de91bd75beb21a0e"), + "AccountType" : "Worldpay Online Payments Account", + "ReceivingAccount" : 1, + "PaymentsAccount" : 0, + "WorldpayOnlinePaymentsInfo" : { + "ServiceKeyEncrypted" : "3::0a6915f1f98ee7d3b6aa06608c1d6d960e06002be6de2bf067f5337db301ceb52b534a23b233d2d464c8977026f2d9f034a807540076fb42d44f66425eaf390649f9786ca604dda45c93cb65cd6b839f8cbb6c41f43a6a6b566815ebe1d5d410", + "ServiceKey" : "T_S_********-****-****-****-********4bfb" + }, + "UserID" : "79a26d981246978135edadf1", + "VendorID" : "Worldpay", + "VendorAccountName" : "Worldpay Online Payments", + "Description" : "Utah Iron Inc. account.", + "IconLocation" : "worldpay-account.png", + "APIVersion" : "7.6.4-44af11fdc504cff51f7e5fdaff97a7cf1a6b09a4", + "Integrity" : null, + "LastUpdate" : ISODate("2018-03-29T13:40:16.505Z"), + "LastVersion" : 1 + }, + "Status" : "Pending" +} + +``` + +Database was checked again at 2018-03-29T13:45. + +`db.getCollection('ReceiveCode').find({"_id" : ObjectId("5abcecf5de91bd75beb21a11")})` + +`Fetched 0 record(s) in 21ms` + +### 7. Request should be logged ### + +Log for AC 1: + +```json +{ + "_id" : ObjectId("5abcecf5de91bd75beb21a12"), + "timestamp" : ISODate("2018-03-29T13:41:09.084Z"), + "level" : "info", + "message" : "Successfully created a receivecode", + "meta" : { + "logId" : "payments:receivecodes", + "ip" : "62.232.80.210", + "reqId" : "f0c1e13c-3a09-40c1-8e8a-007f52ebf846", + "userId" : "79a26d981246978135edadf1", + "file" : "/home/flexops/node_server/dev_api/controllers/receivecode_controller.js", + "_receivecode" : "SCYDG", + "_instrumentID" : "5abcecc0de91bd75beb21a0e" + }, + "hostname" : "node01-cl01-cc" +} +``` + +Log for AC 2: + +```json +{ + "_id" : ObjectId("5abcee6ade91bd75beb21a19"), + "timestamp" : ISODate("2018-03-29T13:47:22.098Z"), + "level" : "error", + "message" : "Failed to create a receivecode", + "meta" : { + "logId" : "payments:receivecodes", + "ip" : "62.232.80.210", + "reqId" : "10e1dcee-2330-456b-93e7-41b00f0c2a39", + "userId" : "79a26d981246978135edadf1", + "file" : "/home/flexops/node_server/dev_api/controllers/receivecode_controller.js", + "_instrumentID" : "000000000000000000000000", + "_internalError" : "Error: BRIDGE: INVALID INSTRUMENT", + "_httpCode" : 400, + "_info" : "The instrument could not be found, has no access or has expired.", + "_code" : 600 + }, + "hostname" : "node01-cl01-cc" +} +``` + +Log for AC 3: + +```json +{ + "_id" : ObjectId("5abcefd4de91bd75beb21a1e"), + "timestamp" : ISODate("2018-03-29T13:53:24.686Z"), + "level" : "error", + "message" : "Failed to create a receivecode", + "meta" : { + "logId" : "payments:receivecodes", + "ip" : "62.232.80.210", + "reqId" : "9bf49711-2f43-44db-a990-d695a31f0733", + "userId" : "79a26d981246978135edadf1", + "file" : "/home/flexops/node_server/dev_api/controllers/receivecode_controller.js", + "_instrumentID" : "5abceedbde91bd75beb21a1b", + "_internalError" : "Error: BRIDGE: INVALID INSTRUMENT", + "_httpCode" : 400, + "_info" : "The instrument could not be found, has no access or has expired.", + "_code" : 600 + }, + "hostname" : "node01-cl01-cc" +} +``` + +Log for AC 4: + +```json +{ + "_id" : ObjectId("5abcf00ede91bd75beb21a25"), + "timestamp" : ISODate("2018-03-29T13:54:22.750Z"), + "level" : "error", + "message" : "Failed to create a receivecode", + "meta" : { + "logId" : "payments:receivecodes", + "ip" : "62.232.80.210", + "reqId" : "f4f87109-1a40-440f-88ce-22d33121bd52", + "userId" : "79a26d981246978135edadf1", + "file" : "/home/flexops/node_server/dev_api/controllers/receivecode_controller.js", + "_instrumentID" : "5abcecc0de91bd75beb21a0e", + "_internalError" : "Error: BRIDGE: INSTRUMENT DECRYPTION FAILURE", + "_httpCode" : 401, + "_info" : "The instrument could not be decrypted.", + "_code" : 602 + }, + "hostname" : "node01-cl01-cc" +} +``` + +Log for AC 5: + +```json +{ + "_id" : ObjectId("5abcf4524e484a771f906de3"), + "timestamp" : ISODate("2018-03-29T14:12:34.702Z"), + "level" : "error", + "message" : "Failed to create a receivecode", + "meta" : { + "logId" : "payments:receivecodes", + "ip" : "62.232.80.210", + "reqId" : "e72cca16-e9ee-4ab1-9b74-97a18d9991c2", + "userId" : "79a26d981246978135edadf1", + "file" : "/home/flexops/node_server/dev_api/controllers/receivecode_controller.js", + "_instrumentID" : "5abcf18bde91bd75beb21a5f", + "_internalError" : "Error: BRIDGE: INVALID INSTRUMENT", + "_httpCode" : 400, + "_info" : "The instrument could not be found, has no access or has expired.", + "_code" : 600 + }, + "hostname" : "node01-cl01-cc" +} +``` + +Log for AC 6: +```json +{ + "_id" : ObjectId("5abcecf5de91bd75beb21a12"), + "timestamp" : ISODate("2018-03-29T13:41:09.084Z"), + "level" : "info", + "message" : "Successfully created a receivecode", + "meta" : { + "logId" : "payments:receivecodes", + "ip" : "62.232.80.210", + "reqId" : "f0c1e13c-3a09-40c1-8e8a-007f52ebf846", + "userId" : "79a26d981246978135edadf1", + "file" : "/home/flexops/node_server/dev_api/controllers/receivecode_controller.js", + "_receivecode" : "SCYDG", + "_instrumentID" : "5abcecc0de91bd75beb21a0e" + }, + "hostname" : "node01-cl01-cc" +} +``` \ No newline at end of file diff --git a/tasks/bridge_619/tests.md b/tasks/bridge_619/tests.md new file mode 100644 index 0000000..1b41524 --- /dev/null +++ b/tasks/bridge_619/tests.md @@ -0,0 +1,416 @@ +# Acceptance Criteria # + + +### 1. User generates receivecode ### + +Create a new worldpay merchant account using `/payment-instruments/worldpay-merchants` + +Testing data: + +```json +{ + "key": "4f84d8e7-b800-444d-b2ad-2633d5561bc0", + "ID": "5aba3afdb28f2c8e1700c9b6" +} +``` + + +Using : `/receivecodes` + +```json +{ + "key": "4f84d8e7-b800-444d-b2ad-2633d5561bc0", + "ID": "5aba3afdb28f2c8e1700c9b6" +} +``` + +Response: + +```json +{ + "receivecode": "WGB5U" +} + +``` + +Database Contains: + +```json +{ + "_id" : ObjectId("5aba3b2db28f2c8e1700c9b9"), + "ReceiveCode" : "WGB5U", + "Creation" : ISODate("2018-03-27T12:38:05.776Z"), + "Expiry" : ISODate("2018-03-27T12:41:05.776Z"), + "PaymentInstrument" : { + "_id" : ObjectId("5aba3afdb28f2c8e1700c9b6"), + "AccountType" : "Worldpay Online Payments Account", + "ReceivingAccount" : 1, + "PaymentsAccount" : 0, + "WorldpayOnlinePaymentsInfo" : { + "ServiceKeyEncrypted" : "3::3820fe3fa496b06d66f8c3c1e11fa7f590be6b3caf8ce31e9460b0eafade924d3da17699552fdfea26e48c8b904e52da146f4478a622b5aed3241182e27aa73eb91c94412e0c619506f57358f989b79369a4dd51c7ab8dea3a5ae961e758c22e", + "ServiceKey" : "T_S_********-****-****-****-********4bfb" + }, + "UserID" : "79a26d981246978135edadf1", + "VendorID" : "Worldpay", + "VendorAccountName" : "Worldpay Online Payments", + "Description" : "Erskine Argon Inc. account.", + "IconLocation" : "worldpay-account.png", + "APIVersion" : "7.6.4-dev", + "Integrity" : null, + "LastUpdate" : ISODate("2018-03-27T12:37:17.423Z"), + "LastVersion" : 1 + }, + "Status" : "Pending" +} + +``` + +_Receivecode object contains the receivecode string_ + +```json +"ReceiveCode" : "WGB5U" +``` + +_Receivecode object contains re-encrypted payment instrument details_ + +```json +"WorldpayOnlinePaymentsInfo" : { + "ServiceKeyEncrypted" : "3::3820fe3fa496b06d66f8c3c1e11fa7f590be6b3caf8ce31e9460b0eafade924d3da17699552fdfea26e48c8b904e52da146f4478a622b5aed3241182e27aa73eb91c94412e0c619506f57358f989b79369a4dd51c7ab8dea3a5ae961e758c22e", + "ServiceKey" : "T_S_********-****-****-****-********4bfb" + } +``` + +_Receivecode object contains an expiry timestamp_ + +```json +"Expiry" : ISODate("2018-03-27T12:41:05.776Z") +``` + +### 2. User specifies nonexistent instrument ID ### + +Using : `/receivecodes` + +```json +{ + "key": "12345678-9012-3456-7890-123456789012", + "ID": "000000000000000000000000" +} +``` + +Response: + +```json +{ + "code": 600, + "info": "The instrument could not be found, has no access or has expired." +} +``` + + + +### 3. User specifies instrument ID belonging to another user ### + +Create a new instrument for user `YTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU2` + +Create a new worldpay merchant account using `/payment-instruments/worldpay-merchants` + +Testing data: + +```json +{ + "key": "f3c94230-2e2d-4b7a-8f27-7c05ca51ab1a", + "ID": "5aba42b5b28f2c8e1700c9c0" +} +``` + +Re-authorise with `YTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU1` + +Using : `/receivecodes` + +```json +{ + "key": "f3c94230-2e2d-4b7a-8f27-7c05ca51ab1a", + "ID": "5aba42b5b28f2c8e1700c9c0" +} +``` + +Response: + +`400 Error: Bad Request` + +```json +{ + "code": 600, + "info": "The instrument could not be found, has no access or has expired." +} + +``` + + + +### 4. User provides incorrect encryption key ### + +Using : `/receivecodes` + +```json +{ + "key": "badbadba-dbad-badb-adba-badbadbadbad", + "ID": "5aba3afdb28f2c8e1700c9b6" +} +``` + +Response: + +`401 Error: Unauthroized` + +```json +{ + "code": 602, + "info": "The instrument could not be decrypted." +} +``` + +### 5. Payment instrument cannot create receivecodes ### + +Create a new worldpay merchant account using `/payment-instruments/worldpay-merchants` + +Testing data: + +```json +{ + "key": "de851ec5-6b36-453a-870c-14bb63e16ede", + "ID": "5aba46ecb28f2c8e1700c9c8" +} +``` + +Modify record to remove the ability to create receive codes. + +```json +{ + "_id" : ObjectId("5aba46ecb28f2c8e1700c9c8"), + "AccountType" : "Worldpay Online Payments Account", + "ReceivingAccount" : 0, + "PaymentsAccount" : 0, + "WorldpayOnlinePaymentsInfo" : { + "ServiceKeyEncrypted" : "3::e6c0dea6b0dff24f0c3502830aaafbf04d3530e36b18180186bde15b2e0984b2c4ef841a6f05e4f3d8ba4fd73d50b2296e881ed1a60eadddff1d955a4d07ac61798ad8d04b307b9b4b8df8a23ba6aacdc4ed8068f5fcaaeb985d1642b16e8339", + "ServiceKey" : "T_S_********-****-****-****-********4bfb" + }, + "UserID" : "79a26d981246978135edadf1", + "VendorID" : "Worldpay", + "VendorAccountName" : "Worldpay Online Payments", + "Description" : "Falkirk Tin Inc. account.", + "IconLocation" : "worldpay-account.png", + "APIVersion" : "7.6.4-dev", + "Integrity" : null, + "LastUpdate" : ISODate("2018-03-27T13:28:12.544Z"), + "LastVersion" : 1 +} + +``` + +Response: + +`400 Error: Bad Request` + +```json +{ + "key": "de851ec5-6b36-453a-870c-14bb63e16ede", + "ID": "5aba46ecb28f2c8e1700c9c8" +} +``` + + +### 6. Receivecode should be deleted when it expires ### + +Using : `/receivecodes` + +```json +{ + "key": "4f84d8e7-b800-444d-b2ad-2633d5561bc0", + "ID": "5aba3afdb28f2c8e1700c9b6" +} +``` + +Response: `201` + +```json +{ + "receivecode": "9S4CJ" +} +``` + +Database record: + +```json +{ + "_id" : ObjectId("5aba5a31febf9e953ffadcab"), + "ReceiveCode" : "9S4CJ", + "Creation" : ISODate("2018-03-27T14:50:25.997Z"), + "Expiry" : ISODate("2018-03-27T14:53:25.997Z"), + "PaymentInstrument" : { + "_id" : ObjectId("5aba3afdb28f2c8e1700c9b6"), + "AccountType" : "Worldpay Online Payments Account", + "ReceivingAccount" : 1, + "PaymentsAccount" : 0, + "WorldpayOnlinePaymentsInfo" : { + "ServiceKeyEncrypted" : "3::75bcbcb07040bc95c2409800f67384e1e186e87fceb90c4a6291189635d2a11bb52ce93d0e83a9bd82d3e130c9f25f60f64529f9b4ae9e6feac6c9d4ca2e131d5efc4793fdaf97d8b89909b05a8bd39c940899b71e816a0242149e360ad551a0", + "ServiceKey" : "T_S_********-****-****-****-********4bfb" + }, + "UserID" : "79a26d981246978135edadf1", + "VendorID" : "Worldpay", + "VendorAccountName" : "Worldpay Online Payments", + "Description" : "Erskine Argon Inc. account.", + "IconLocation" : "worldpay-account.png", + "APIVersion" : "7.6.4-dev", + "Integrity" : null, + "LastUpdate" : ISODate("2018-03-27T12:37:17.423Z"), + "LastVersion" : 1 + }, + "Status" : "Pending" +} +``` + +Database was checked again at 2018-03-27 14:54. + +`db.getCollection('ReceiveCode').find({"_id" : ObjectId("5aba5a31febf9e953ffadcab")})` + +`Fetched 0 record(s) in 1ms` + +### 7. Request should be logged ### + +Log for AC 1: + +```json +{ + "_id" : ObjectId("5aba3b2db28f2c8e1700c9ba"), + "timestamp" : ISODate("2018-03-27T12:38:05.791Z"), + "level" : "info", + "message" : "Successfully created a receivecode", + "meta" : { + "logId" : "payments:paycodes", + "ip" : "127.0.0.1", + "reqId" : "56c96602-9d3d-49ad-8495-3a7527e85be5", + "userId" : "79a26d981246978135edadf1", + "file" : "/Users/martin/dev/bridge-node-server/node_server/dev_api/controllers/receivecode_controller.js", + "_receivecode" : "WGB5U", + "_instrumentID" : "5aba3afdb28f2c8e1700c9b6" + }, + "hostname" : "Admins-MacBook-Pro.local" +} +``` + +Log for AC 2: + +```json +{ + "_id" : ObjectId("5aba3f05b28f2c8e1700c9bd"), + "timestamp" : ISODate("2018-03-27T12:54:29.830Z"), + "level" : "error", + "message" : "Failed to create a receivecode", + "meta" : { + "logId" : "payments:paycodes", + "ip" : "127.0.0.1", + "reqId" : "6eaea836-c247-41e1-940a-a84dc192d5ce", + "userId" : "79a26d981246978135edadf1", + "file" : "/Users/martin/dev/bridge-node-server/node_server/dev_api/controllers/receivecode_controller.js", + "_instrumentID" : "000000000000000000000000", + "_internalError" : "Error: BRIDGE: INVALID INSTRUMENT", + "_httpCode" : 400, + "_info" : "The instrument could not be found, has no access or has expired.", + "_code" : 600 + }, + "hostname" : "Admins-MacBook-Pro.local" +} +``` + +Log for AC 3: + +```json +{ + "_id" : ObjectId("5aba42fab28f2c8e1700c9c3"), + "timestamp" : ISODate("2018-03-27T13:11:22.983Z"), + "level" : "error", + "message" : "Failed to create a receivecode", + "meta" : { + "logId" : "payments:paycodes", + "ip" : "127.0.0.1", + "reqId" : "ad27c4a1-6324-459d-b457-380ed0d3140d", + "userId" : "79a26d981246978135edadf1", + "file" : "/Users/martin/dev/bridge-node-server/node_server/dev_api/controllers/receivecode_controller.js", + "_instrumentID" : "5aba42b5b28f2c8e1700c9c0", + "_internalError" : "Error: BRIDGE: INVALID INSTRUMENT", + "_httpCode" : 400, + "_info" : "The instrument could not be found, has no access or has expired.", + "_code" : 600 + }, + "hostname" : "Admins-MacBook-Pro.local" +} +``` + +Log for AC 4: + +```json +{ + "_id" : ObjectId("5aba4634b28f2c8e1700c9c6"), + "timestamp" : ISODate("2018-03-27T13:25:08.701Z"), + "level" : "error", + "message" : "Failed to create a receivecode", + "meta" : { + "logId" : "payments:paycodes", + "ip" : "127.0.0.1", + "reqId" : "14dcc4b2-80dc-41da-a680-f648099205e6", + "userId" : "79a26d981246978135edadf1", + "file" : "/Users/martin/dev/bridge-node-server/node_server/dev_api/controllers/receivecode_controller.js", + "_instrumentID" : "5aba3afdb28f2c8e1700c9b6", + "_internalError" : "Error: BRIDGE: INSTRUMENT DECRYPTION FAILURE", + "_httpCode" : 401, + "_info" : "The instrument could not be decrypted.", + "_code" : 602 + }, + "hostname" : "Admins-MacBook-Pro.local" +} +``` + +Log for AC 5: + +```json +{ + "_id" : ObjectId("5aba55a4febf9e953ffadca8"), + "timestamp" : ISODate("2018-03-27T14:31:00.918Z"), + "level" : "error", + "message" : "Failed to create a receivecode", + "meta" : { + "logId" : "payments:paycodes", + "ip" : "127.0.0.1", + "reqId" : "d01bf003-10d4-4cfa-8f31-c4bdb447445d", + "userId" : "79a26d981246978135edadf1", + "file" : "/Users/martin/dev/bridge-node-server/node_server/dev_api/controllers/receivecode_controller.js", + "_instrumentID" : "5aba46ecb28f2c8e1700c9c8", + "_internalError" : "Error: BRIDGE: INVALID INSTRUMENT", + "_httpCode" : 400, + "_info" : "The instrument could not be found, has no access or has expired.", + "_code" : 600 + }, + "hostname" : "Admins-MacBook-Pro.local" +} +``` + +Log for AC 6: +```json +{ + "_id" : ObjectId("5aba5a32febf9e953ffadcac"), + "timestamp" : ISODate("2018-03-27T14:50:26.008Z"), + "level" : "info", + "message" : "Successfully created a receivecode", + "meta" : { + "logId" : "payments:paycodes", + "ip" : "127.0.0.1", + "reqId" : "ea671287-89cf-4be0-9229-0144e743dd96", + "userId" : "79a26d981246978135edadf1", + "file" : "/Users/martin/dev/bridge-node-server/node_server/dev_api/controllers/receivecode_controller.js", + "_receivecode" : "9S4CJ", + "_instrumentID" : "5aba3afdb28f2c8e1700c9b6" + }, + "hostname" : "Admins-MacBook-Pro.local" +} +``` \ No newline at end of file diff --git a/useful/good-e2e-tests.spec.js b/useful/good-e2e-tests.spec.js new file mode 100644 index 0000000..1f0e25e --- /dev/null +++ b/useful/good-e2e-tests.spec.js @@ -0,0 +1,144 @@ +/** + * @fileOverview End-to-end testing of the get all ATPs related to a payable RTP + */ +'use strict'; + +const helper = require('../../utils/test/e2e-helper'); + +const request = require('supertest'); +const express = require('express'); +const chai = require('chai'); +const initDevApi = require('../dev_server.js'); + +const expect = chai.expect; + +/** + * Correct auth method (Bearer), correct token + */ +const TOKEN_VALID = 'YTM2ZGQ1NzUtOWFmNS01MjMyLTg5MjYtM2NkZjA5ZDU2ZGU1'; +const HEADER_VALID = 'Bearer ' + TOKEN_VALID; + +/** + * Correct auth method (Bearer), correct token + */ +const TOKEN_INVALID = 'MTM2ZGQ1NzUtOWN1nKYN0nKMP1nKYP0nKDU2ZGU1'; +const HEADER_INVALID = 'Bearer ' + TOKEN_INVALID; + +let app; + +// Standard errored values + +const TOO_LONG = '0000000000000000000000001'; +const TOO_SHORT = '0123'; +const BAD_UUID = '00000000000000000000000Z'; +const VALID_UUID = '000000000000000000000000'; +const MISSING_UUID = ''; + +// Valid test data + +/** + * Make a useable path + * + * @param segment + * @returns {string} + */ +function makePath(segment) { + return '/dev/v0/payables/rtps/' + segment + '/atps'; +} + +/** + * Attempt to make an authenticated request + * + * @param expApp + * @param auth + * @param requestPath + * @returns {*} + */ +function makeAuthenticatedRequest(expApp, auth, requestPath) { + return request(expApp) + .get(requestPath) + .set('Accept', 'application/json') + .set('Authorization', auth); +} + +describe('E2E: get All ATPs', () => { + /** + * Load the dev API router to handle `/dev/*` routes + */ + describe('objectID tests', () => { + before(() => { + app = new helper.DevValidatorApp(); + }); + it('with a valid objectID', () => { + app.setRequestPath(makePath(VALID_UUID)); + + return app.getAndValidate(502); + }); + it('objectID with an invalid pattern', () => { + app.setRequestPath(makePath(BAD_UUID)); + + return app.getAndValidate(400, undefined, helper.errors.failedPattern('objectID')); + }); + it('objectID is too short', () => { + app.setRequestPath(makePath(TOO_SHORT)); + + return app.getAndValidate(400, undefined, helper.errors.minLength('objectID')); + }); + it('objectID is too long', () => { + app.setRequestPath(makePath(TOO_LONG)); + + return app.getAndValidate(400, undefined, helper.errors.maxLength('objectID')); + }); + }); + + describe('invalid path', () => { + let expressApp; + + /** + * Initialise the app before running any tests + */ + + // Test missing RTP ObjectID + + before(() => { + expressApp = express(); + const devApiRouter = initDevApi.init(); + expressApp.use('/dev', devApiRouter); + }); + + it('responds with 404', () => { + return makeAuthenticatedRequest(expressApp, HEADER_VALID, makePath(MISSING_UUID)) + .expect(404); + }); + + it('responds with error body', () => { + return makeAuthenticatedRequest(expressApp, HEADER_VALID, makePath(MISSING_UUID)) + .expect(404) + .then((response) => { + return expect(response.body).to.deep.equal({ + code: 30000, + description: 'API path not found' + }); + }); + }); + }); + + describe('authorization', () => { + // eslint-disable-next-line mocha/no-hooks-for-single-case + after(() => { + // Reset the authorization header after these tests, whether they + // pass or fail + app.resetAuthorizationHeader(); + }); + + it('is required to access the path', () => { + app.setRequestAuthorization(HEADER_INVALID); + return app.getAndValidate(401).then((response) => { + return expect(response.body).to.deep.include({ + code: -1, + info: 'Not authorised' + }); + }); + }); + }); +}); diff --git a/useful/test.xsl b/useful/test.xsl new file mode 100644 index 0000000..8c4cb0d --- /dev/null +++ b/useful/test.xsl @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + +
TestRunTotalPassed
+ + + + + +
+ + + + + + + + + + + + + +
+ +
+ + + ms + +
+
+ + +
+
\ No newline at end of file