diff --git a/code/Test_definitions/carrier-billing-cancelPayment.feature b/code/Test_definitions/carrier-billing-cancelPayment.feature new file mode 100644 index 0000000..adb0b8d --- /dev/null +++ b/code/Test_definitions/carrier-billing-cancelPayment.feature @@ -0,0 +1,186 @@ +Feature: CAMARA Carrier Billing API, v0.3 - Operation cancelPayment + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * Endpoint required for 2-step payment + # + # Testing assets: + # * A phone number eligible for payment (no restrictions for it to be used to perform a payment) + # + # References to OAS spec schemas refer to schemas specifies in carrier-billing.yaml, version 0.3.0 + + Background: Common cancelPayment setup + Given the resource "/carrier-billing/v0.3/payments/{paymentId}/cancel" | + And the header "Content-Type" is set to "application/json" + And the header "Authorization" is set to a valid access token + And the header "x-correlator" is set to a UUID value + And the path parameter "paymentId" is set to a valid value + And the request body is set by default to a request body compliant with the schema + + ############################## + # Happy path scenarios + ############################## + + + @cancel_payment_01_generic_success_scenario + Scenario: Common validations for any success scenario + # Valid default request body compliant with the schema + Given the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 202 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + + + @cancel_payment_02_phoneNumber_three_legged + # Case using a 3-legged Access Token + Scenario: Request cancel payment indicating phoneNumber + Given the request body property "$.phonenumber" is set to a valid value which is the same as associated to access token + When the HTTP "POST" request is sent + Then the response status code is 202 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + + + @cancel_payment_03_phoneNumber_two_legged + # Case using a 2-legged Access Token. Only applicable for Countries and Telco Operators whose regulation allows for it + Scenario: Request cancel payment indicating phoneNumber + Given the request body property "$.phonenumber" is set to a valid value which is the same as associated to access token + When the HTTP "POST" request is sent + Then the response status code is 202 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + + + ############################## + # Error scenarios + ############################## + + # Error 400 scenarios + + @cancel_payment_400.01_no_request_body + Scenario: Missing request body + Given the request body is not included + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + @cancel_payment_400.02_empty_request_body + Scenario: Empty object as request body + Given the request body is set to "{}" + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + # Error 401 scenarios + + @cancel_payment_401.01_no_authorization_header + Scenario: No Authorization header + Given the header "Authorization" is removed + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @cancel_payment_401.02_expired_access_token + Scenario: Expired access token + Given the header "Authorization" is set to an expired access token + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @cancel_payment_401.03_invalid_access_token + Scenario: Invalid access token + Given the header "Authorization" is set to an invalid access token + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + # Error 403 scenarios + + @cancel_payment_403.01_invalid_token_permissions + Scenario: Inconsistent access token permissions + # To test this, an access token has to be obtained without carrier-billing:payments:write scope + Given the request body is set to a valid request body + And the header "Authorization" is set to a valid access token emitted without carrier-billing:payments:write scope + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "PERMISSION_DENIED" + And the response property "$.message" contains a user friendly text + + + @cancel_payment_403.02_phoneNumber_token_mismatch + Scenario: Inconsistent access token context for the phoneNumber + # To test this, a 3-legged access token has to be obtained for a different phoneNumber + Given the request body property "$.amountTransaction.phoneNumber" is set to a valid testing phone number + And the header "Authorization" is set to a valid access token emitted for a different phone number + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "INVALID_TOKEN_CONTEXT" + And the response property "$.message" contains a user friendly text + + + # Error 409 scenarios + + @cancel_payment_409.01_payment_confirmed + Scenario: Payment already confirmed + Given the request body is set to a valid request body + And the path param "paymentId" is set to a valid value of an already confirmed payment + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 409 + And the response property "$.status" is 409 + And the response property "$.code" is "CARRIER_BILLING.PAYMENT_CONFIRMED" + And the response property "$.message" contains a user friendly text + + + @cancel_payment_409.02_payment_cancelled + Scenario: Payment already cancelled + Given the request body is set to a valid request body + And the path param "paymentId" is set to a valid value of an already cancelled payment + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 409 + And the response property "$.status" is 409 + And the response property "$.code" is "CARRIER_BILLING.PAYMENT_CANCELLED" + And the response property "$.message" contains a user friendly text + + + # Error 422 scenarios + + @cancel_payment_422.01_phoneNumber_required + Scenario: Payment requires the indication of phoneNumber. Only applicable to Countries and Telco Operators that allow and need it. + Given the request body is set to a valid request body + And the request body property "$.phoneNumber" is missing + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "CARRIER_BILLING.PHONE_NUMBER_REQUIRED" + And the response property "$.message" contains a user friendly text + + + ############################## + ##END + ############################## + diff --git a/code/Test_definitions/carrier-billing-confirmPayment.feature b/code/Test_definitions/carrier-billing-confirmPayment.feature new file mode 100644 index 0000000..c6e8f17 --- /dev/null +++ b/code/Test_definitions/carrier-billing-confirmPayment.feature @@ -0,0 +1,199 @@ +Feature: CAMARA Carrier Billing API, v0.3 - Operation confirmPayment + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * Endpoint required for 2-step payment + # + # Testing assets: + # * A phone number eligible for payment (no restrictions for it to be used to perform a payment) + # * A phone number not-eligible for payment (payment is denied for it due to business conditions) + # + # References to OAS spec schemas refer to schemas specifies in carrier-billing.yaml, version 0.3.0 + + Background: Common confirmPayment setup + Given the resource "/carrier-billing/v0.3/payments/{paymentId}/confirm" | + And the header "Content-Type" is set to "application/json" + And the header "Authorization" is set to a valid access token + And the header "x-correlator" is set to a UUID value + And the path parameter "paymentId" is set to a valid value + And the request body is set by default to a request body compliant with the schema + + ############################## + # Happy path scenarios + ############################## + + + @confirm_payment_01_generic_success_scenario + Scenario: Common validations for any success scenario + # Valid default request body compliant with the schema + Given the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 202 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + + + @confirm_payment_02_phoneNumber_three_legged + # Case using a 3-legged Access Token + Scenario: Request confirm payment indicating phoneNumber + Given the request body property "$.phonenumber" is set to a valid value which is the same as associated to access token + When the HTTP "POST" request is sent + Then the response status code is 202 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + + + @confirm_payment_03_phoneNumber_two_legged + # Case using a 2-legged Access Token. Only applicable for Countries and Telco Operators whose regulation allows for it + Scenario: Request confirm payment indicating phoneNumber + Given the request body property "$.phonenumber" is set to a valid value which is the same as associated to access token + When the HTTP "POST" request is sent + Then the response status code is 202 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + + + ############################## + # Error scenarios + ############################## + + # Error 400 scenarios + + @confirm_payment_400.01_no_request_body + Scenario: Missing request body + Given the request body is not included + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + @confirm_payment_400.02_empty_request_body + Scenario: Empty object as request body + Given the request body is set to "{}" + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + # Error 401 scenarios + + @confirm_payment_401.01_no_authorization_header + Scenario: No Authorization header + Given the header "Authorization" is removed + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @confirm_payment_401.02_expired_access_token + Scenario: Expired access token + Given the header "Authorization" is set to an expired access token + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @confirm_payment_401.03_invalid_access_token + Scenario: Invalid access token + Given the header "Authorization" is set to an invalid access token + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + # Error 403 scenarios + + @confirm_payment_403.01_invalid_token_permissions + Scenario: Inconsistent access token permissions + # To test this, an access token has to be obtained without carrier-billing:payments:write scope + Given the request body is set to a valid request body + And the header "Authorization" is set to a valid access token emitted without carrier-billing:payments:confirm scope + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "PERMISSION_DENIED" + And the response property "$.message" contains a user friendly text + + + @confirm_payment_403.02_phoneNumber_token_mismatch + Scenario: Inconsistent access token context for the phoneNumber + # To test this, a 3-legged access token has to be obtained for a different phoneNumber + Given the request body property "$.amountTransaction.phoneNumber" is set to a valid testing phone number + And the header "Authorization" is set to a valid access token emitted for a different phone number + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "INVALID_TOKEN_CONTEXT" + And the response property "$.message" contains a user friendly text + + + @confirm_payment_403.02_payment_denied + Scenario: Payment denied by business + # To test this, a business context exists in the Telco Operator to deny the payment + Given the request body is set to a valid request body + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "CARRIER_BILLING.PAYMENT_DENIED" + And the response property "$.message" contains a user friendly text + + + # Error 409 scenarios + + @confirm_payment_409.01_payment_confirmed + Scenario: Payment already confirmed + Given the request body is set to a valid request body + And the path param "paymentId" is set to a valid value of an already confirmed payment + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 409 + And the response property "$.status" is 409 + And the response property "$.code" is "CARRIER_BILLING.PAYMENT_CONFIRMED" + And the response property "$.message" contains a user friendly text + + + @confirm_payment_409.02_payment_cancelled + Scenario: Payment already cancelled + Given the request body is set to a valid request body + And the path param "paymentId" is set to a valid value of an already cancelled payment + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 409 + And the response property "$.status" is 409 + And the response property "$.code" is "CARRIER_BILLING.PAYMENT_CANCELLED" + And the response property "$.message" contains a user friendly text + + + # Error 422 scenarios + + @confirm_payment_422.01_phoneNumber_required + Scenario: Payment requires the indication of phoneNumber. Only applicable to Countries and Telco Operators that allow and need it. + Given the request body is set to a valid request body + And the request body property "$.phoneNumber" is missing + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "CARRIER_BILLING.PHONE_NUMBER_REQUIRED" + And the response property "$.message" contains a user friendly text + + + ############################## + ##END + ############################## + diff --git a/code/Test_definitions/carrier-billing-createPayment.feature b/code/Test_definitions/carrier-billing-createPayment.feature new file mode 100644 index 0000000..d547515 --- /dev/null +++ b/code/Test_definitions/carrier-billing-createPayment.feature @@ -0,0 +1,430 @@ +Feature: CAMARA Carrier Billing API, v0.3 - Operation createPayment + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * Telco Operator carrier billing behaviour mode: sync or async + # + # Testing assets: + # * A phone number eligible for payment (no restrictions for it to be used to perform a payment) + # * A phone number not-eligible for payment (payment is denied for it due to business conditions) + # + # References to OAS spec schemas refer to schemas specifies in carrier-billing.yaml, version 0.3.0 + + Background: Common createPayment setup + Given the resource "/carrier-billing/v0.3/payments" | + And the header "Content-Type" is set to "application/json" + And the header "Authorization" is set to a valid access token + And the header "x-correlator" is set to a UUID value + And the request body is set by default to a request body compliant with the schema + + ############################## + # Happy path scenarios + ############################## + + + @create_payment_01_generic_success_scenario + Scenario: Common validations for any success scenario + # Valid default request body compliant with the schema + # Property "$.amountTransaction" is set with required information only + Given the request body property "$.amountTransaction" is set with valid required information + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + + + @create_payment_02_generic_success_scenario_with_sink_information + Scenario: Common validations for any success scenario with sink information provided + # Property "$.amountTransaction" is set with required information only + # Property "$.sink" is set with a valid public accessible HTTPs endpoint + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.sink" is set with a valid URL + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + + + @create_payment_03_generic_success_scenario_with_sink_and_sinkCredential_information + Scenario: Common validations for any success scenario sink and sinkCredential information provided + # Property "$.amountTransaction" is set with required information only + # Property "$.sink" is set with a valid public accessible HTTPs endpoint + # Property "$.sinkCredential" is set with a valid credential of type "ACCESSTOKEN" + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.sink" is set with a valid HTTPS URL + And the request body property "$.sinkCredential" is set to a valid credential with property "$.sinkCredential.credentialType" set to "ACCESSTOKEN" + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + + + # Scenarios testing specific situations for amountTransaction + + @create_payment_04_amountTransaction_gross_amount + Scenario: Request 1-step payment with gross amount + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.paymentAmount.chargingInformation.isTaxIncluded" is set to true + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + And the response body property "$.amountTransaction.paymentAmount.chargingInformation.isTaxIncluded" is true + + + @create_payment_05_amountTransaction_net_amount + Scenario: Request 1-step payment with net amount + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.paymentAmount.chargingInformation.isTaxIncluded" is set to false OR not set + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + And the response body property "$.amountTransaction.paymentAmount.chargingInformation.isTaxIncluded" is false OR not returned + + + @create_payment_06_amountTransaction_taxAmount + Scenario: Request 1-step payment indicating taxAmount + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.paymentAmount.chargingInformation.taxAmount" is set to a valid value + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + And the response body property "$.amountTransaction.paymentAmount.chargingInformation.taxAmount" has the same value as provided in the request body + + + @create_payment_07_amountTransaction_merchantIdentifier + # May be relevant scenario for Payment Aggregator Case + Scenario: Request 1-step payment indicating merchantIdentifier + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.paymentAmount.chargingMetaData.merchantIdentifier" is set to a valid value + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + And the response body property "$.amountTransaction.paymentAmount.chargingMetaData.merchantIdentifier" has the same value as provided in the request body + + + @create_payment_08_amountTransaction_paymentDetails + Scenario: Request 1-step payment indicating merchantIdentifier + Given the request body property "$.amountTransaction" is set with valid required information + And the request body array property "$.amountTransaction.paymentAmount.paymentDetails" is set with valid information + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + And the response body array property "$.amountTransaction.paymentAmount.paymentDetails" has the same information as provided in the request body + + + @create_payment_09_amountTransaction_clientCorrelator + # Recommended scenario to manage request idempotency + Scenario: Request 1-step payment indicating clientCorrelator + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.clientCorrelator" is set to a valid value + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + And the response body property "$.amountTransaction.clientCorrelator" has the same value as provided in the request body + + + @create_payment_10_amountTransaction_phoneNumber_three_legged + # Case using a 3-legged Access Token emitted for a specific phone number + Scenario: Request 1-step payment indicating phoneNumber + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.phoneNumber" is set to a valid value which is the same as associated to access token + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + And the response body property "$.amountTransaction.phoneNumber" has the same value as provided in the request body + + + @create_payment_11_amountTransaction_phoneNumber_two_legged + # Case using a 2-legged Access Token. Only applicable for Countries and Telco Operators whose regulation allows for it + Scenario: Request 1-step payment indicating phoneNumber + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.phoneNumber" is set to a valid value + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + And the response body property "$.amountTransaction.phoneNumber" has the same value as provided in the request body + + + @create_payment_12_sync_behaviour + # Scenario for a Telco Operator that behaves synchronously + Scenario: Request 1-step payment with sync behaviour + Given the request body property "$.amountTransaction" is set with valid required information + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + And the response body property "$.paymentStatus" is "succeeded" + + + @create_payment_13_async_behaviour + # Scenario for a Telco Operator that behaves asynchronously + Scenario: Request 1-step payment with async behaviour + Given the request body property "$.amountTransaction" is set with valid required information + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/PaymentCreated" + And the response body property "$.paymentStatus" is "processing" + + + ############################## + # Error scenarios + ############################## + + # Error 400 scenarios + + @create_payment_400.01_no_request_body + Scenario: Missing request body + Given the request body is not included + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + @create_payment_400.02_empty_request_body + Scenario: Empty object as request body + Given the request body is set to "{}" + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + @create_payment_400.03_other_input_properties_schema_not_compliant + # Test other input properties in addition to amountTransaction + Scenario Outline: Input property values does not comply with the schema + Given the request body property "" does not comply with the OAS schema at + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + Examples: + | input_property | oas_spec_schema | + | $.sink | /components/schemas/CreatePayment | + | $.sinkCredential | /components/schemas/SinkCredential | | + + + @create_payment_400.04_required_input_properties_missing + Scenario Outline: Required input properties are missing + Given the request body property "" is not included + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + Examples: + | input_property | + | $.amountTransaction | + | $.amountTransaction.paymentAmount | + | $.amountTransaction.referenceCode | + | $.amountTransaction.paymentAmount.chargingInformation | + | $.amountTransaction.paymentAmount.chargingInformation.amount | + | $.amountTransaction.paymentAmount.chargingInformation.currency | + | $.amountTransaction.paymentAmount.chargingInformation.description | + + + @create_payment_400.05_clientCorrelator_in_use + Scenario: Using the same client correlator for two different payment requests + Given the request body property includes property "$.clientCorrelator" with a value already use in a non-completed payment + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + @create_payment_400.06_invalid_sink + Scenario: Using a invalid sink value + Given the request body property includes property "$.sink" which is not set to an url + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + @create_payment_400.07_invalid_sinkCredential + Scenario: Using a invalid sinkCredential type value + Given the request body property includes property "$.sinkCredential.credentialType" whose value is not "ACCESSTOKEN" + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_CREDENTIAL" + And the response property "$.message" contains a user friendly text + + + @create_payment_400.08_invalid_sinkCredential_Acccestoken + Scenario: Using a invalid sinkCredential accesstoken type value + Given the request body property includes property "$.sinkCredential.accessTokenType" whose value is not "bearer" + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_TOKEN" + And the response property "$.message" contains a user friendly text + + # Error 401 scenarios + + @create_payment_401.01_no_authorization_header + Scenario: No Authorization header + Given the header "Authorization" is removed + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @create_payment_401.02_expired_access_token + Scenario: Expired access token + Given the header "Authorization" is set to an expired access token + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @create_payment_401.03_invalid_access_token + Scenario: Invalid access token + Given the header "Authorization" is set to an invalid access token + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + # Error 403 scenarios + + @create_payment_403.01_invalid_token_permissions + Scenario: Inconsistent access token permissions + # To test this, an access token has to be obtained without carrier-billing:payments:create scope + Given the request body is set to a valid request body + And the header "Authorization" is set to a valid access token emitted without carrier-billing:payments:create scope + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "PERMISSION_DENIED" + And the response property "$.message" contains a user friendly text + + + @create_payment_403.02_phoneNumber_token_mismatch + Scenario: Inconsistent access token context for the phoneNumber + # To test this, a 3-legged access token has to be obtained for a different phoneNumber + Given the request body property "$.amountTransaction.phoneNumber" is set to a valid testing phone number + And the header "Authorization" is set to a valid access token emitted for a different phone number + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "INVALID_TOKEN_CONTEXT" + And the response property "$.message" contains a user friendly text + + + @create_payment_403.03_payment_denied + Scenario: Payment denied by business + # To test this, a business context exists in the Telco Operator to deny the payment + Given the request body is set to a valid request body + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "CARRIER_BILLING.PAYMENT_DENIED" + And the response property "$.message" contains a user friendly text + + + # Error 409 scenarios + + @create_payment_409.01_payment_duplicated + Scenario: Payment duplicated + Given the request body is set to a valid request body + And the request body property "$.amountTransaction.referenceCode" is set to a value already use in another payment request + And the request body property "$.clientCorrelator" is missing + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 409 + And the response property "$.status" is 409 + And the response property "$.code" is "ALREADY_EXISTS" + And the response property "$.message" contains a user friendly text + + + # Error 422 scenarios + + @create_payment_422.01_phoneNumber_required + Scenario: Payment requires the indication of phoneNumber. Only applicable to Countries and Telco Operators that allow and need it. + Given the request body is set to a valid request body + And the request body property "$.amountTransaction.phoneNumber" is missing + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "CARRIER_BILLING.PHONE_NUMBER_REQUIRED" + And the response property "$.message" contains a user friendly text + + + @create_payment_422.02_unauthorized_amount + Scenario: Payment amount exceeds the value allowed by the regulation + # This test applies/depends on the regulation applicable for a given Country + Given the request body is set to a valid request body + And the request body property "$.amountTransaction.paymentAmount.chargingInformationAmount" exceeds the value allowed by the regulation + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "CARRIER_BILLING.UNAUTHORIZED_AMOUNT" + And the response property "$.message" contains a user friendly text + + + @create_payment_422.02_accumulated_threshold_amount_overpassed + Scenario: Payment amount exceeds the accumulated threshold amount value allowed by the regulation + # This test applies/depends on the regulation applicable for a given Country + Given the request body is set to a valid request body + And the request body property "$.amountTransaction.paymentAmount.chargingInformationAmount" exceeds the accumulated threshold amount value allowed by the regulation + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "CARRIER_BILLING.AMOUNT_THRESHOLD_OVERPASSED" + And the response property "$.message" contains a user friendly text + + + ############################## + ##END + ############################## + diff --git a/code/Test_definitions/carrier-billing-preparePayment.feature b/code/Test_definitions/carrier-billing-preparePayment.feature new file mode 100644 index 0000000..e24b679 --- /dev/null +++ b/code/Test_definitions/carrier-billing-preparePayment.feature @@ -0,0 +1,444 @@ +Feature: CAMARA Carrier Billing API, v0.3 - Operation preparePayment + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * Telco Operator carrier billing behaviour mode: sync or async + # + # Testing assets: + # * A phone number eligible for payment (no restrictions for it to be used to perform a payment) + # * A phone number not-eligible for payment (payment is denied for it due to business conditions) + # + # References to OAS spec schemas refer to schemas specifies in carrier-billing.yaml, version 0.3.0 + + Background: Common preparePayment setup + Given the resource "/carrier-billing/v0.3/payments/prepare" | + And the header "Content-Type" is set to "application/json" + And the header "Authorization" is set to a valid access token + And the header "x-correlator" is set to a UUID value + And the request body is set by default to a request body compliant with the schema + + ############################## + # Happy path scenarios + ############################## + + + @prepare_payment_01_generic_success_scenario + Scenario: Common validations for any success scenario + # Valid default request body compliant with the schema + # Property "$.amountTransaction" is set with required information only + Given the request body property "$.amountTransaction" is set with valid required information + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + + + @prepare_payment_02_generic_success_scenario_with_sink_information + Scenario: Common validations for any success scenario with sink information provided + # Property "$.amountTransaction" is set with required information only + # Property "$.sink" is set with a valid public accessible HTTPs endpoint + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.sink" is set with a valid URL + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + + + @prepare_payment_03_generic_success_scenario_with_sink_and_sinkCredential_information + Scenario: Common validations for any success scenario sink and sinkCredential information provided + # Property "$.amountTransaction" is set with required information only + # Property "$.sink" is set with a valid public accessible HTTPs endpoint + # Property "$.sinkCredential" is set with a valid credential of type "ACCESSTOKEN" + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.sink" is set with a valid HTTPS URL + And the request body property "$.sinkCredential" is set to a valid credential with property "$.sinkCredential.credentialType" set to "ACCESSTOKEN" + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + + + # Scenarios testing specific situations for amountTransaction + + @prepare_payment_04_amountTransaction_gross_amount + Scenario: Request 2-step payment with gross amount + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.paymentAmount.chargingInformation.isTaxIncluded" is set to true + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + And the response body property "$.amountTransaction.paymentAmount.chargingInformation.isTaxIncluded" is true + + + @prepare_payment_05_amountTransaction_net_amount + Scenario: Request 2-step payment with net amount + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.paymentAmount.chargingInformation.isTaxIncluded" is set to false OR not set + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + And the response body property "$.amountTransaction.paymentAmount.chargingInformation.isTaxIncluded" is false OR not returned + + + @prepare_payment_06_amountTransaction_taxAmount + Scenario: Request 2-step payment indicating taxAmount + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.paymentAmount.chargingInformation.taxAmount" is set to a valid value + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + And the response body property "$.amountTransaction.paymentAmount.chargingInformation.taxAmount" has the same value as provided in the request body + + + @prepare_payment_07_amountTransaction_merchantIdentifier + # May be relevant scenario for Payment Aggregator Case + Scenario: Request 2-step payment indicating merchantIdentifier + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.paymentAmount.chargingMetaData.merchantIdentifier" is set to a valid value + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + And the response body property "$.amountTransaction.paymentAmount.chargingMetaData.merchantIdentifier" has the same value as provided in the request body + + + @prepare_payment_08_amountTransaction_paymentDetails + Scenario: Request 2-step payment indicating merchantIdentifier + Given the request body property "$.amountTransaction" is set with valid required information + And the request body array property "$.amountTransaction.paymentAmount.paymentDetails" is set with valid information + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + And the response body array property "$.amountTransaction.paymentAmount.paymentDetails" has the same information as provided in the request body + + + @prepare_payment_09_amountTransaction_clientCorrelator + # Recommended scenario to manage request idempotency + Scenario: Request 2-step payment indicating clientCorrelator + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.clientCorrelator" is set to a valid value + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + And the response body property "$.amountTransaction.clientCorrelator" has the same value as provided in the request body + + + @prepare_payment_10_amountTransaction_phoneNumber_three_legged + # Case using a 3-legged Access Token identifying a specific phone number + Scenario: Request 2-step payment indicating phoneNumber + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.phoneNumber" is set to a valid value which is the same as associated to access token + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + And the response body property "$.amountTransaction.phoneNumber" has the same value as provided in the request body + + + @prepare_payment_11_amountTransaction_phoneNumber_two_legged + # Case using a 2-legged Access Token. Only applicable for Countries and Operators whose regulation allows for it + Scenario: Request 2-step payment indicating phoneNumber + Given the request body property "$.amountTransaction" is set with valid required information + And the request body property "$.amountTransaction.phoneNumber" is set to a valid value + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + And the response body property "$.amountTransaction.phoneNumber" has the same value as provided in the request body + + + @prepare_payment_12_sync_behaviour_without_validation_info + # Scenario for a Telco Operator that behaves synchronously + Scenario: Request 2-step payment with sync behaviour + Given the request body property "$.amountTransaction" is set with valid required information + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + And the response property "$.validatioInfo" is not returned + And the response body property "$.paymentStatus" is "reserved" + + + @prepare_payment_13_sync_behaviour_with_validation_info + # Scenario for a Telco Operator that behaves synchronously + Scenario: Request 2-step payment with sync behaviour + Given the request body property "$.amountTransaction" is set with valid required information + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + And the response property "$.validatioInfo" is returned + And the response body property "$.paymentStatus" is "pending_validation" + + + @prepare_payment_14_async_behaviour + # Scenario for a Telco Operator that behaves asynchronously + Scenario: Request 2-step payment with async behaviour + Given the request body property "$.amountTransaction" is set with valid required information + When the HTTP "POST" request is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/BodyAmountReservationTransactionForReserve" + And the response body property "$.paymentStatus" is "processing" + + + ############################## + # Error scenarios + ############################## + + # Error 400 scenarios + + @prepare_payment_400.01_no_request_body + Scenario: Missing request body + Given the request body is not included + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + @prepare_payment_400.02_empty_request_body + Scenario: Empty object as request body + Given the request body is set to "{}" + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + @prepare_payment_400.03_other_input_properties_schema_not_compliant + # Test other input properties in addition to amountTransaction + Scenario Outline: Input property values does not comply with the schema + Given the request body property "" does not comply with the OAS schema at + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + Examples: + | input_property | oas_spec_schema | + | $.sink | /components/schemas/CreatePayment | + | $.sinkCredential | /components/schemas/SinkCredential | | + + + @prepare_payment_400.04_required_input_properties_missing + Scenario Outline: Required input properties are missing + Given the request body property "" is not included + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + Examples: + | input_property | + | $.amountTransaction | + | $.amountTransaction.paymentAmount | + | $.amountTransaction.referenceCode | + | $.amountTransaction.paymentAmount.chargingInformation | + | $.amountTransaction.paymentAmount.chargingInformation.amount | + | $.amountTransaction.paymentAmount.chargingInformation.currency | + | $.amountTransaction.paymentAmount.chargingInformation.description | + + + @prepare_payment_400.05_clientCorrelator_in_use + Scenario: Using the same client correlator for two different payment requests + Given the request body property includes property "$.clientCorrelator" with a value already use in a non-completed payment + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + @prepare_payment_400.06_invalid_sink + Scenario: Using a invalid sink value + Given the request body property includes property "$.sink" which is not set to an url + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + @prepare_payment_400.07_invalid_sinkCredential + Scenario: Using a invalid sinkCredential type value + Given the request body property includes property "$.sinkCredential.credentialType" whose value is not "ACCESSTOKEN" + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_CREDENTIAL" + And the response property "$.message" contains a user friendly text + + + @prepare_payment_400.08_invalid_sinkCredential_Acccestoken + Scenario: Using a invalid sinkCredential accesstoken type value + Given the request body property includes property "$.sinkCredential.accessTokenType" whose value is not "bearer" + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_TOKEN" + And the response property "$.message" contains a user friendly text + + # Error 401 scenarios + + @prepare_payment_401.01_no_authorization_header + Scenario: No Authorization header + Given the header "Authorization" is removed + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @prepare_payment_401.02_expired_access_token + Scenario: Expired access token + Given the header "Authorization" is set to an expired access token + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @prepare_payment_401.03_invalid_access_token + Scenario: Invalid access token + Given the header "Authorization" is set to an invalid access token + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + # Error 403 scenarios + + @prepare_payment_403.01_invalid_token_permissions + Scenario: Inconsistent access token permissions + # To test this, an access token has to be obtained without carrier-billing:payments:create scope + Given the request body is set to a valid request body + And the header "Authorization" is set to a valid access token emitted without carrier-billing:payments:create scope + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "PERMISSION_DENIED" + And the response property "$.message" contains a user friendly text + + + @prepare_payment_403.02_phoneNumber_token_mismatch + Scenario: Inconsistent access token context for the phoneNumber + # To test this, a 3-legged access token has to be obtained for a different phoneNumber + Given the request body property "$.amountTransaction.phoneNumber" is set to a valid testing phone number + And the header "Authorization" is set to a valid access token emitted for a different phone number + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "INVALID_TOKEN_CONTEXT" + And the response property "$.message" contains a user friendly text + + + @prepare_payment_403.03_payment_denied + Scenario: Payment denied by business + # To test this, a business context exists in the Telco Operator to deny the payment + Given the request body is set to a valid request body + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "CARRIER_BILLING.PAYMENT_DENIED" + And the response property "$.message" contains a user friendly text + + + # Error 409 scenarios + + @prepare_payment_409.01_payment_duplicated + Scenario: Payment duplicated + Given the request body is set to a valid request body + And the request body property "$.amountTransaction.referenceCode" is set to a value already use in another payment request + And the request body property "$.clientCorrelator" is missing + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 409 + And the response property "$.status" is 409 + And the response property "$.code" is "ALREADY_EXISTS" + And the response property "$.message" contains a user friendly text + + + # Error 422 scenarios + + @prepare_payment_422.01_phoneNumber_required + Scenario: Payment requires the indication of phoneNumber. Only applicable to Countries and Telco Operators that allow and need it. + Given the request body is set to a valid request body + And the request body property "$.amountTransaction.phoneNumber" is missing + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "CARRIER_BILLING.PHONE_NUMBER_REQUIRED" + And the response property "$.message" contains a user friendly text + + + @prepare_payment_422.02_unauthorized_amount + Scenario: Payment amount exceeds the value allowed by the regulation + # This test applies/depends on the regulation applicable for a given Country + Given the request body is set to a valid request body + And the request body property "$.amountTransaction.paymentAmount.chargingInformationAmount" exceeds the value allowed by the regulation + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "CARRIER_BILLING.UNAUTHORIZED_AMOUNT" + And the response property "$.message" contains a user friendly text + + + @prepare_payment_422.02_accumulated_threshold_amount_overpassed + Scenario: Payment amount exceeds the accumulated threshold amount value allowed by the regulation + # This test applies/depends on the regulation applicable for a given Country + Given the request body is set to a valid request body + And the request body property "$.amountTransaction.paymentAmount.chargingInformationAmount" exceeds the accumulated threshold amount value allowed by the regulation + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "CARRIER_BILLING.AMOUNT_THRESHOLD_OVERPASSED" + And the response property "$.message" contains a user friendly text + + + ############################## + ##END + ############################## + diff --git a/code/Test_definitions/carrier-billing-retrievePayment.feature b/code/Test_definitions/carrier-billing-retrievePayment.feature new file mode 100644 index 0000000..860e305 --- /dev/null +++ b/code/Test_definitions/carrier-billing-retrievePayment.feature @@ -0,0 +1,120 @@ +Feature: CAMARA Carrier Billing API, v0.3 - Operation retrievePayment + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * + # + # Testing assets: + # * A phone number eligible for payment (no restrictions for it to be used to perform a payment) + # * Several payments performed in different status in the environment (at least 10) + # + # References to OAS spec schemas refer to schemas specifies in carrier-billing.yaml, version 0.3.0 + + Background: Common retrievePayment setup + Given the resource "/carrier-billing/v0.3/payments/{paymentId}" | + And the header "Content-Type" is set to "application/json" + And the header "Authorization" is set to a valid access token + And the header "x-correlator" is set to a UUID value + And the path parameter "paymentId" is set to a valid value + + ############################## + # Happy path scenarios + ############################## + + + @retrieve_payment_01_generic_success_scenario + Scenario: Common validations for any success scenario + Given an existing payment created by operation createPayment OR preparePayment + And the path parameter "paymentId" is set to the value for that payment + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/Payment" + + + ############################## + # Error scenarios + ############################## + + # Error 401 scenarios + + @retrieve_payment_401.01_no_authorization_header + Scenario: No Authorization header + Given the header "Authorization" is removed + And the path parameter "paymentId" is set to a valid value + When the HTTP "GET" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @retrieve_payment_401.02_expired_access_token + Scenario: Expired access token + Given the header "Authorization" is set to an expired access token + And the path parameter "paymentId" is set to a valid value + When the HTTP "GET" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @retrieve_payment_401.03_invalid_access_token + Scenario: Invalid access token + Given the header "Authorization" is set to an invalid access token + And the path parameter "paymentId" is set to a valid value + When the HTTP "GET" request is sent + Then the response status code is 401 + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + # Error 403 scenarios + + @retrieve_payment_403.01_invalid_token_permissions + Scenario: Inconsistent access token permissions + # To test this, an access token has to be obtained without carrier-billing:payments:read scope + Given header "Authorization" is set to a valid access token emitted without carrier-billing:payments:read scope + And the path parameter "paymentId" is set to a valid value + When the HTTP "GET" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "PERMISSION_DENIED" + And the response property "$.message" contains a user friendly text + + + @retrieve_payment_403.02_phoneNumber_token_mismatch + Scenario: Inconsistent access token context for the phoneNumber + # To test this, a 3-legged access token has to be obtained for a different phoneNumber + Given the header "Authorization" is set to a valid access token emitted for a phone number + And the path parameter "paymentId" is set to a valid value associated to a phone number different than the access token is associated + When the HTTP "GET" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "INVALID_TOKEN_CONTEXT" + And the response property "$.message" contains a user friendly text + + + # Error 404 scenarios + + @retrieve_payment_404.01_payment_not_found + Scenario: Payment not found + # To test this, a 2-legged access token is needed, just beacuse if not it triggers test "@retrieve_payment_403.02_phoneNumber_token_mismatch" + Given the path parameter "paymentId" is set to non-existing value in the environment + And the header "Authorization" is set to a valid access token + When the HTTP "POST" request is sent + Then the response status code is 404 + And the response property "$.status" is 404 + And the response property "$.code" is "NOT_FOUND" + And the response property "$.message" contains a user friendly text + + + ############################## + ##END + ############################## + diff --git a/code/Test_definitions/carrier-billing-retrievePayments.feature b/code/Test_definitions/carrier-billing-retrievePayments.feature new file mode 100644 index 0000000..28345f7 --- /dev/null +++ b/code/Test_definitions/carrier-billing-retrievePayments.feature @@ -0,0 +1,322 @@ +Feature: CAMARA Carrier Billing API, v0.3 - Operation retrievePayments + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * + # + # Testing assets: + # * A phone number eligible for payment (no restrictions for it to be used to perform a payment) + # * Several payments performed in different status in the environment (at least 10) + # + # References to OAS spec schemas refer to schemas specifies in carrier-billing.yaml, version 0.3.0 + + Background: Common retrievePayment setup + Given the resource "/carrier-billing/v0.3/payments" | + And the header "Content-Type" is set to "application/json" + And the header "Authorization" is set to a valid access token + And the header "x-correlator" is set to a UUID value + + ############################## + # Happy path scenarios + ############################## + + + @retrieve_payments_01_generic_success_scenario + Scenario: Common validations for any success scenario + Given at least an existing payment created by operation createPayment OR preparePayment + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentArray" + + + @retrieve_payments_02_no_payments + Scenario: No existing payments + Given no payments have been created by operation createPayment OR preparePayment + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body is an empty array "[]" + + + @retrieve_payments_03_for_phoneNumber + Scenario: List of payments for a given phone number + Given at least an existing payment created by operation createPayment OR preparePayment + And the header "Authorization" is set to a valid access token associated for a phone number with payments requested + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentArray" + And only the payments associated to that phone number are returned + + + @retrieve_payments_04_for_application + Scenario: List of payments for a given application (API client) + #To test this scenario, a 2-legged token is needed + Given at least an existing payment created by operation createPayment OR preparePayment + And the header "Authorization" is set to a valid access token not emitted for a specific phone number + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentArray" + And only the payments associated to that application are returned + + + # Query Parameter scenarios + + @retrieve_payments_05_start_creationDate + Scenario Outline: List of payments since a given creationDate + Given several existing payments created by operation createPayment OR preparePayment + And the header "Authorization" is set to a valid access token + And the query parameter "paymentCreationDate.gte" is set to "" + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentArray" + And all the payments returned have their property "$.paymentCreationDate" >= "" + And only the payments with their property "$.paymentCreationDate" >= "" are returned + + Examples: + | creation_date | + | NOW - 1 day | + | NOW - 7 days | + | NOW - 30 days | + + + @retrieve_payments_06_end_creationDate + Scenario Outline: List of payments up to a given creationDate + Given several existing payments created by operation createPayment OR preparePayment + And the header "Authorization" is set to a valid access token + And the query parameter "paymentCreationDate.lte" is set to "" + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentArray" + And all the payments returned have their property "$.paymentCreationDate" <= "" + And only the payments with their property "$.paymentCreationDate" <= "" are returned + + Examples: + | creation_date | + | NOW - 1 day | + | NOW - 3 days | + | NOW - 7 days | + + + @retrieve_payments_07_date_range + Scenario Outline: List of payments within a creationDate range + Given several existing payments created by operation createPayment OR preparePayment + And the header "Authorization" is set to a valid access token + And the query parameter "paymentCreationDate.gte" is set to "" + And the query parameter "paymentCreationDate.lte" is set to "" + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentArray" + And all the payments returned have their property "$.paymentCreationDate" between "" and "" + And only the payments with their property "$.paymentCreationDate" between "" and "" + + Examples: + | start_creation_date | end_creation_date | + | NOW - 7 days | NOW | + | NOW - 30 days | NOW | + | NOW - 30 days | NOW - 7 days | + + + @retrieve_payments_08_ordering + Scenario Outline: List of payments ordered by creationPaymentDate + Given several existing payments created by operation createPayment OR preparePayment + And the header "Authorization" is set to a valid access token + And the query parameter "order" is set to "" + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentArray" + And all the payments returned are ordered by "" property "$.paymentCreationDate" + + Examples: + | order | + | desc | + | asc | + + + @retrieve_payments_09_payment_status + Scenario Outline: List of payments in a given status + Given several existing payments created by operation createPayment OR preparePayment in different payment status + And the header "Authorization" is set to a valid access token + And the query parameter "paymentStatus" is set to "" + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentArray" + And all the payments returned have their property "$.paymentStatus" == "" + And only the payments with their property "$.paymentStatus" == "" are returned + + Examples: + | payment_status | + | processing | + | pending_validation | + | denied | + | reserved | + | succeeded | + | cancelled | + + + @retrieve_payments_10_merchantIdentifier + Scenario: List of payments for a given merchantIdentifier + Given several existing payments created by operation createPayment OR preparePayment for a given merchant + And the header "Authorization" is set to a valid access token + And the query parameter "merchantIdentifier" is set to the value representing such a merchant + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentArray" + And all the payments returned have their property "$.amountTransaction.paymentAmount.chargingMetadata.merchantIdentifier" set to the same value as the query parameter "merchantIdentifier" + And only the payments with their property "$.amountTransaction.paymentAmount.chargingMetadata.merchantIdentifier" set to the same value as the query parameter "merchantIdentifier" are returned + + + @retrieve_payments_11_pagination + Scenario: Pagination in List of payments + Given several existing payments created by operation createPayment OR preparePayment, at least more than five + And the header "Authorization" is set to a valid access token + And the query parameter "page" is set to "1" + And the query parameter "perPage" is set to "5" + When the HTTP "GET" request is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + # The response has to comply with the generic response schema which is part of the spec + And the response body complies with the OAS schema at "/components/schemas/PaymentArray" + And only five payments returned + + + ############################## + # Error scenarios + ############################## + + # Error 400 scenarios + + @retrieve_payments_400.01_invalid_date_range + Scenario Outline: List of payments with an invalid date range + Given several existing payments created by operation createPayment OR preparePayment + And the header "Authorization" is set to a valid access token + And the query parameter "paymentCreationDate.gte" is set to "" + And the query parameter "paymentCreationDate.lte" is set to "" + When the HTTP "GET" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "CARRIER_BILLING.INVALID_DATE_RANGE" + And the response property "$.message" contains a user friendly text + + Examples: + | start_creation_date | end_creation_date | + | NOW | NOW - 7 days | + | NOW - 7 days | NOW - 30 days | + + + @retrieve_payments_400.02_out_of_range + Scenario: List of payments out of range + Given several existing payments created by operation createPayment OR preparePayment + And the header "Authorization" is set to a valid access token + And the query parameter "page" is set to "1000" + And the query parameter "perPage" is set to "1000" + When the HTTP "GET" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "CARRIER_BILLING.OUT_OF_RANGE" + And the response property "$.message" contains a user friendly text + + + @retrieve_payments_400.03_too_many_matching_records + Scenario: List of payments too many matching records + #Optional test to be performed. To test this scenario there would be needed many payments in the environment. + Given several existing payments created by operation createPayment OR preparePayment + And the header "Authorization" is set to a valid access token + And the query parameter "page" is set to "1" + And the query parameter "perPage" is set to "1000" + When the HTTP "GET" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "CARRIER_BILLING.TOO_MANY_MATCHING_RECORDS" + And the response property "$.message" contains a user friendly text + + + # Error 401 scenarios + + @retrieve_payments_401.01_no_authorization_header + Scenario: No Authorization header + Given the header "Authorization" is removed + When the HTTP "GET" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @retrieve_payments_401.02_expired_access_token + Scenario: Expired access token + Given the header "Authorization" is set to an expired access token + When the HTTP "GET" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @retrieve_payments_401.03_invalid_access_token + Scenario: Invalid access token + Given the header "Authorization" is set to an invalid access token + When the HTTP "GET" request is sent + Then the response status code is 401 + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + # Error 403 scenarios + + @retrieve_payment_403.01_invalid_token_permissions + Scenario: Inconsistent access token permissions + # To test this, an access token has to be obtained without carrier-billing:payments:read scope + Given header "Authorization" is set to a valid access token emitted without carrier-billing:payments:read scope + When the HTTP "GET" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "PERMISSION_DENIED" + And the response property "$.message" contains a user friendly text + + + @retrieve_payment_403.02_phoneNumber_token_mismatch + Scenario: Inconsistent access token context for the phoneNumber + # To test this, a 3-legged access token has to be obtained without associated to a phoneNumber + Given the header "Authorization" is set to a valid access token not emitted for a phone number + When the HTTP "GET" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "INVALID_TOKEN_CONTEXT" + And the response property "$.message" contains a user friendly text + + + ############################## + ##END + ############################## + diff --git a/code/Test_definitions/carrier-billing-validatePayment.feature b/code/Test_definitions/carrier-billing-validatePayment.feature new file mode 100644 index 0000000..311b904 --- /dev/null +++ b/code/Test_definitions/carrier-billing-validatePayment.feature @@ -0,0 +1,168 @@ +Feature: CAMARA Carrier Billing API, v0.3 - Operation validatePayment + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * Optional endpoint in a 2-step payment just only used in case a validation step is needed between reservation and commitment of the payment + # + # Testing assets: + # * N/A (so far) + # + # References to OAS spec schemas refer to schemas specifies in carrier-billing.yaml, version 0.3.0 + + Background: Common validatePayment setup + Given the resource "/carrier-billing/v0.3/payments/{paymentId}/validate" | + And the header "Content-Type" is set to "application/json" + And the header "Authorization" is set to a valid access token + And the header "x-correlator" is set to a UUID value + And the path parameter "paymentId" is set to a valid value + And the request body is set by default to a request body compliant with the schema + + ############################## + # Happy path scenarios + ############################## + + + @validate_payment_01_generic_success_scenario + Scenario: Common validations for any success scenario + # Valid default request body compliant with the schema + Given the request body property "$.authorizationId" is set to a valid value + And the request body property "$.code" is set to a valid value + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 204 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + + + ############################## + # Error scenarios + ############################## + + + # Error 400 scenarios + + @validate_payment_400.01_no_request_body + Scenario: Missing request body + Given the request body is not included + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + + @validate_payment_400.02_empty_request_body + Scenario: Empty object as request body + Given the request body is set to "{}" + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text | + + + @validate_payment_400.03_required_input_properties_missing + Scenario Outline: Required input properties are missing + Given the request body property "" is not included + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "INVALID_ARGUMENT" + And the response property "$.message" contains a user friendly text + + Examples: + | input_property | + | $.authorizationId | + | $.code | + + + @validate_payment_400.04_invalid_authorizationId + Scenario: Using a invalid authorizationId value + Given the request body property includes property "$.authorizationId" with a non-existing value in the environment + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "CARRIER_BILLING.INVALID_AUTHORIZATION_ID" + And the response property "$.message" contains a user friendly text + + + @validate_payment_400.05_invalid_code + Scenario: Using a invalid code value + Given the request body property includes property "$.code" with a non-existing value in the environment + When the HTTP "POST" request is sent + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "CARRIER_BILLING.INVALID_CODE" + And the response property "$.message" contains a user friendly text + + + @validate_payment_400.06_exceeding_validation attempts + # Variable "N" can vary up to Telco Operator policies + Scenario outline: Using a invalid code value after N requests + Given the request body property includes property "$.code" with a non-existing value in the environment + When the HTTP "POST" request is sent after "" times + Then the response status code is 400 + And the response property "$.status" is 400 + And the response property "$.code" is "CARRIER_BILLING.VALIDATION_FAILED" + And the response property "$.message" contains a user friendly text + + Examples: + | Number | + | 3 | + | 5 | + + + # Error 401 scenarios + + @validate_payment_01_generic_success_scenario_payment_401.01_no_authorization_header + Scenario: No Authorization header + Given the header "Authorization" is removed + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @validate_payment_401.02_expired_access_token + Scenario: Expired access token + Given the header "Authorization" is set to an expired access token + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + @validate_payment_401.03_invalid_access_token + Scenario: Invalid access token + Given the header "Authorization" is set to an invalid access token + And the request body is set to a valid request body + When the HTTP "POST" request is sent + Then the response status code is 401 + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 401 + And the response property "$.code" is "UNAUTHENTICATED" + And the response property "$.message" contains a user friendly text + + + # Error 403 scenarios + + @validate_payment_403.01_invalid_token_permissions + Scenario: Inconsistent access token permissions + # To test this, an access token has to be obtained without carrier-billing:payments:write scope + Given the request body is set to a valid request body + And the header "Authorization" is set to a valid access token emitted without carrier-billing:payments:write scope + When the HTTP "POST" request is sent + Then the response status code is 403 + And the response property "$.status" is 403 + And the response property "$.code" is "PERMISSION_DENIED" + And the response property "$.message" contains a user friendly text + + + ############################## + ##END + ############################## +