diff --git a/code/Test_definitions/geofencing-subscriptions.feature b/code/Test_definitions/geofencing-subscriptions.feature index e929ca7e..c5f45892 100644 --- a/code/Test_definitions/geofencing-subscriptions.feature +++ b/code/Test_definitions/geofencing-subscriptions.feature @@ -16,132 +16,127 @@ Feature: Camara Geofencing Subscriptions API, vwip - Operations on subscriptions And the header "Authorization" is set to a valid access token And the header "x-correlator" complies with the schema at "#/components/schemas/XCorrelator" -############################ Happy Path Scenarios ######################## - @geofencing_subscriptions_01_Create_geofencing_subscription_for_a_device_sync - Scenario: Create geofencing subscription (sync creation) + # Success scenarios + + # Note: Depending on the API managed personal data specific scenario update may be require to specify use of 2-legs or 3-legs access token. + + @geofencing_subscriptions_01_create_subscription_sync + Scenario: Create geofencing subscription (sync creation) Given that subscriptions are created synchronously And a valid subscription request body When the request "createGeofencingSubscription" is sent Then the response 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/Subscription" + And the response header "x-correlator" has the same value as the request header "x-correlator" + And the response body complies with the OAS schema at "#/components/schemas/Subscription" - @geofencing_subscriptions_02_Create_geofencing_subscription_for_a_device_async - Scenario: Create geofencing subscription (async creation) + @geofencing_subscriptions_02_create_subscription_async + Scenario: Create geofencing subscription (async creation) Given that subscriptions are created asynchronously And a valid subscription request body When the request "createGeofencingSubscription" is sent - Then the response code is 202 + 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" And the response body complies with the OAS schema at "#/components/schemas/SubscriptionAsync" - @geofencing_subscriptions_03_Operation_to_retrieve_list_of_subscriptions_when_no_records - Scenario: Get a list of subscriptions when no subscriptions available - Given a client without subscriptions created + @geofencing_subscriptions_03_subscription_creation_event_validation + Scenario: Receive notification for subscription-started event on creation + Given a valid subscription request body + When the request "createGeofencingSubscription" is sent + Then the response code is 201 or 202 + And event notification "subscription-started" is received on callback-url + And notification body complies with the OAS schema at "#/components/schemas/EventSubscriptionStarted" + And type="org.camaraproject.geofencing-subscriptions.v0.subscription-started" + And the response property "$.initiationReason" is "SUBSCRIPTION_CREATED" + + @geofencing_subscriptions_04_Operation_to_retrieve_list_of_subscriptions_when_no_records + Scenario: Get a list of Geofencing subscriptions when no subscriptions available + Given a client without Geofencing subscriptions created When the request "retrieveGeofencingSubscriptionList" is sent Then the response 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 header "x-correlator" has the same value as the request header "x-correlator" And the response body is an empty array - @geofencing_subscriptions_04_Operation_to_retrieve_list_of_subscriptions + @geofencing_subscriptions_05_Operation_to_retrieve_list_of_subscriptions Scenario: Get a list of subscriptions - Given a client with subscriptions created + Given a client with Geofencing subscriptions created When the request "retrieveGeofencingSubscriptionList" is sent Then the response 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 has an array of items and each item complies with the OAS schema at "/components/schemas/Subscription" + And the response header "x-correlator" has the same value as the request header "x-correlator" + And the response body has an array of items and each item complies with the OAS schema at "#/components/schemas/Subscription" - @geofencing_subscriptions_05_Operation_to_retrieve_subscription_based_on_an_existing_subscription-id + @geofencing_subscriptions_06_Operation_to_retrieve_subscription_based_on_an_existing_subscription-id Scenario: Get a subscription based on existing subscription-id. - Given the path parameter "subscriptionId" is set to the identifier of an existing subscription + Given the path parameter "subscriptionId" is set to the identifier of an existing Geofencing subscription When the request "retrieveGeofencingSubscription" is sent Then the response 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 complies with the OAS schema at "/components/schemas/Subscription" + And the response header "x-correlator" has the same value as the request header "x-correlator" + And the response body complies with the OAS schema at "#/components/schemas/Subscription" - @geofencing_subscriptions_06_Operation_to_delete_subscription_based_on_an_existing_subscription-id + @geofencing_subscriptions_07_Operation_to_delete_subscription_based_on_an_existing_subscription-id Scenario: Delete a subscription based on existing subscription-id. - Given the path parameter "subscriptionId" is set to the identifier of an existing subscription + Given the path parameter "subscriptionId" is set to the identifier of an existing Geofencing subscription When the request "deleteGeofencingSubscription" is sent Then the response code is 202 or 204 - And the response header "x-correlator" has same value as the request header "x-correlator" - And if the response property $.status is 204 then response body is not available - And if the response property $.status is 202 then response body complies with the OAS schema at "/components/schemas/SubscriptionAsync" - - @geofencing_subscriptions_07_Receive_notification_when_device_enters_geofence - Scenario: Receive notification for area-entered event - Given a valid subscription request body - And the request body property "$.area" is set to circle which covers location "Place1" - And the request body property "$.type" is "area-entered" - When the request "createGeofencingSubscription" is sent - Then the response code is 201 - And the device entered location "Place1" - And event notification "area-entered" is received on callback-url - And sink credentials are received as expected - And notification body complies with the OAS schema at "##/components/schemas/EventAreaEntered" - And type="org.camaraproject.geofencing-subscriptions.v0.area-entered" - - @geofencing_subscriptions_08_receive_notification_when_device_leaves_geofence - Scenario: Receive notification for area-left event - Given a valid subscription request body - And the request body property "$.area" is set to circle which covers location "Place1" - And the request body property "$.type" is "area-left" - When the request "createGeofencingSubscription" is sent - Then the response code is 201 - And the device left from location "Place1" - And event notification "area-left" is received on callback-url - And sink credentials are received as expected - And notification body complies with the OAS schema at "##/components/schemas/EventAreaLeft" - And type="org.camaraproject.geofencing-subscriptions.v0.area-left" + And the response header "x-correlator" has the same value as the request header "x-correlator" + And if the response property "$.status" is 204 then the response body is not available + And if the response property "$.status" is 202 then the response body complies with the OAS schema at "#/components/schemas/SubscriptionAsync" - @geofencing_subscriptions_09_subscription_ends_on_expiry + @geofencing_subscriptions_08_subscription_ends_on_expiry Scenario: Receive notification for subscription-ended event on expiry - Given a valid subscription request body - And the request body property "$.area" is set to circle which covers location "Place1" - And the request body property "$.type" is "area-left" - And the request body property "$.subscriptionExpireTime" is set to a value in the near future - When the request "createGeofencingSubscription" is sent - Then the response code is 201 - And the subscription is expired - And event notification "subscription-ended" is received on callback-url - And notification body complies with the OAS schema at "##/components/schemas/EventSubscriptionEnded" + Given an existing Geofencing subscription with some value for the property "expiresAt" in the near future + When the subscription is expired + Then the event notification "subscription-ended" is received on callback-url + And notification body complies with the OAS schema at "#/components/schemas/EventSubscriptionEnded" And type="org.camaraproject.geofencing-subscriptions.v0.subscription-ended" And the response property "$.terminationReason" is "SUBSCRIPTION_EXPIRED" - @geofencing_subscriptions_10_subscription_ends_on_max_events + @geofencing_subscriptions_09_subscription_ends_on_max_events Scenario: Receive notification for subscription-ended event on max events reached - Given a valid subscription request body - And the request body property "$.area" is set to circle which covers location "Place1" - And the request body property "$.type" is "area-left" - And the request body property "$.subscriptionMaxEvents" is set to 1 - When the request "createGeofencingSubscription" is sent - Then the response code is 201 - And the device left from location "Place1" - And event notification "area-left" is received on callback-url + Given an existing Geofencing subscription with the property "config.subscriptionMaxEvents" set to 1 + When the event subscribed occurs + Then event notification "" is received on callback-url And event notification "subscription-ended" is received on callback-url - And notification body complies with the OAS schema at "##/components/schemas/EventSubscriptionEnded" - And type="org.camaraproject.geofencing-subscriptions.v0.subscription-ended"And the response property "$.terminationReason" is "MAX_EVENTS_REACHED" + And notification body complies with the OAS schema at "#/components/schemas/EventSubscriptionEnded" + And type="org.camaraproject.geofencing-subscriptions.v0.subscription-ended" + And the response property "$.terminationReason" is "MAX_EVENTS_REACHED" - @geofencing_subscriptions_11_subscription_delete_event_validation + @geofencing_subscriptions_10_subscription_delete_event_validation Scenario: Receive notification for subscription-ended event on deletion - Given a valid subscription is existing + Given the path parameter "subscriptionId" is set to the identifier of an existing Geofencing subscription When the request "deleteGeofencingSubscription" is sent - And path parameter "subscriptionId" is set to the identifier of an existing subscription created - And the request "deleteGeofencingSubscription" is sent Then the response code is 202 or 204 And event notification "subscription-ended" is received on callback-url - And notification body complies with the OAS schema at "##/components/schemas/EventSubscriptionEnded" + And notification body complies with the OAS schema at "#/components/schemas/EventSubscriptionEnded" And type="org.camaraproject.geofencing-subscriptions.v0.subscription-ended" And the response property "$.terminationReason" is "SUBSCRIPTION_DELETED" + @geofencing_subscriptions_11_receive_notification_when_device_enters_geofence + Scenario: Receive notification for area-entered event + Given a valid subscription of type "org.camaraproject.geofencing-subscriptions.v0.area-entered" for certain device and area + When the device enters the area in the subscription + Then an event notification "area-entered" is sent to the specified callback URL + And the sink credentials specified when the subscription was created are included + And notification body complies with the OAS schema at "#/components/schemas/EventAreaEntered" + And the notification property "$.type" is equal to "org.camaraproject.geofencing-subscriptions.v0.area-entered" + And the notification property "$.data.subscriptionId" is equal to the existing subscriptionId + + @geofencing_subscriptions_12_receive_notification_when_device_leaves_geofence + Scenario: Receive notification for area-left event + Given a valid subscription of type "org.camaraproject.geofencing-subscriptions.v0.area-left" for certain device and area + When the device leaves the area in the subscription + Then an event notification "area-left" is sent to the specified callback URL + And notification body complies with the OAS schema at "#/components/schemas/EventAreaLeft" + And the notification property "$.type" is equal to "org.camaraproject.geofencing-subscriptions.v0.area-left" + And the notification property "$.data.subscriptionId" is equal to the existing subscriptionId + ######################### Scenario in case initialEvent is managed ############################## - @geofencing_subscriptions_12_subscription_creation_initial_event + @geofencing_subscriptions_13_subscription_creation_initial_event Scenario: Receive initial event notification on creation Given the API supports initial events to be sent And a valid subscription request body with property "$.config.initialEvent" set to true @@ -150,79 +145,165 @@ Feature: Camara Geofencing Subscriptions API, vwip - Operations on subscriptions And an event notification of the subscribed type is received on callback-url And notification body complies with the OAS schema at "#/components/schemas/CloudEvent" -########################### Error response scenarios ############################################ - @geofencing_subscriptions_12_create_geofencing_subscription_for_a_device_with_invalid_parameter - Scenario: Create geofencing subscription with invalid parameter - Given the request body is not compliant with the schema "/components/schemas/SubscriptionRequest" - When the request "createGeofencingSubscription" is sent - Then the response code is 400 + # Error scenarios for management of input parameter device + + @geofencing_subscriptions_C01.01_device_empty + Scenario: The device value is an empty object + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "$.config.subscriptionDetail.device" is set to: {} + When the request "createGeofencingSubscription" 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 - @geofencing_subscriptions_13_creation_of_subscription_with_expiry_time_in_past + @geofencing_subscriptions_C01.02_device_identifiers_not_schema_compliant + Scenario Outline: Some device identifier value does not comply with the schema + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "" does not comply with the OAS schema at "" + When the request "createGeofencingSubscription" 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: + | device_identifier | oas_spec_schema | + | $.config.subscriptionDetail.device.phoneNumber | /components/schemas/PhoneNumber | + | $.config.subscriptionDetail.device.ipv4Address | /components/schemas/DeviceIpv4Addr | + | $.config.subscriptionDetail.device.ipv6Address | /components/schemas/DeviceIpv6Address | + | $.config.subscriptionDetail.device.networkIdentifier | /components/schemas/NetworkAccessIdentifier | + + # This scenario may happen e.g. with 2-legged access tokens, which do not identify a single device. + @geofencing_subscriptions_C01.03_device_not_found + Scenario: Some identifier cannot be matched to a device + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "$.config.subscriptionDetail.device" is compliant with the schema but does not identify a device whose connectivity is managed by the API provider + When the request "createGeofencingSubscription" is sent + Then the response status code is 404 + And the response property "$.status" is 404 + And the response property "$.code" is "IDENTIFIER_NOT_FOUND" + And the response property "$.message" contains a user friendly text + + @geofencing_subscriptions_C01.04_unnecessary_device + Scenario: Device not to be included when it can be deduced from the access token + Given the header "Authorization" is set to a valid access token identifying a device + And the request body property "$.config.subscriptionDetail.device" is also set to a valid device, which may or may not be the same device + When the request "createGeofencingSubscription" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "UNNECESSARY_IDENTIFIER" + And the response property "$.message" contains a user-friendly text + + @geofencing_subscriptions_C01.05_missing_device + Scenario: Device not included and cannot be deduced from the access token + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "$.config.subscriptionDetail.device" is not included + When the request "createGeofencingSubscription" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "MISSING_IDENTIFIER" + And the response property "$.message" contains a user-friendly text + + @geofencing_subscriptions_C01.06_unsupported_device + Scenario: None of the provided device identifiers is supported by the implementation + Given that some types of device identifiers are not supported by the implementation + And the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "$.config.subscriptionDetail.device" only includes device identifiers not supported by the implementation + When the request "createGeofencingSubscription" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "UNSUPPORTED_IDENTIFIER" + And the response property "$.message" contains a user-friendly text + + # When the service is only offered to certain types of devices or subscriptions, e.g. IoT, B2C, etc. + @geofencing_subscriptions_C01.07_device_not_supported + Scenario: Service not available for the device + Given that the service is not available for all devices commercialized by the operator + And a valid device, identified by the token or provided in the request body, for which the service is not applicable + When the request "createGeofencingSubscription" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "SERVICE_NOT_APPLICABLE" + And the response property "$.message" contains a user-friendly text + + # Several identifiers provided but they do not identify the same device + # This scenario may happen with 2-legged access tokens, which do not identify a device + @geofencing_subscriptions_C01.08_device_identifiers_mismatch + Scenario: Device identifiers mismatch + Given the header "Authorization" is set to a valid access token which does not identify a single device + And at least 2 types of device identifiers are supported by the implementation + And the request body property "$.config.subscriptionDetail.device" includes several identifiers, each of them identifying a valid but different device + When the request "createGeofencingSubscription" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "IDENTIFIER_MISMATCH" + And the response property "$.message" contains a user friendly text + + # Error code 400 + + @geofencing_subscriptions_400.1_create_subscriptions_with_invalid_parameter + Scenario: Create subscription with invalid parameter + Given the request body is not compliant with the schema "#/components/schemas/SubscriptionRequest" + When the request "createGeofencingSubscription" 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 + + @geofencing_subscriptions_400.2_creation_of_subscription_with_expiry_time_in_past Scenario: Expiry time in past - Given a valid subscription request body - And request body property "$.subscriptionexpiretime" in past + Given a valid geofencing subscription request body + And the request property "$.config.subscriptionExpireTime" in the past When the request "createGeofencingSubscription" is sent - Then the response code is 400 + 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 - @geofencing_subscription_14_creation_with_invalid_eventType + @geofencing_subscriptions_400.3_invalid_eventType Scenario: Subscription creation with invalid event type - Given a valid subscription request body - And the request body property "$.types" is set to invalid value + Given a valid geofencing subscription request body + And the request body property "$.types" is set to an invalid value When the request "createGeofencingSubscription" is sent - Then the response property "$.status" is 400 + 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 - @geofencing_subscription_15_invalid_protocol - Scenario: Subscription creation with invalid protocol - Given a valid subscription request body + @geofencing_subscriptions_400.4_invalid_protocol + Scenario: subscription creation with invalid protocol + Given a valid geofencing subscription request body + And the request property "$.protocol" is not equal to "HTTP" When the request "createGeofencingSubscription" is sent - And the request property "$.types" is set to "org.camaraproject.geofencing-subscriptions.v0.area-entered" - And the request property "$.protocol" is not set to "HTTP" - And the request property "$.config.subscriptionDetail.phoneNumber" is set with provided phoneNumber - And the request property "$.sink" is set to provided callbackUrl - Then the response property "$.status" is 400 + Then the response status code is 400 + And the response property "$.status" is 400 And the response property "$.code" is "INVALID_PROTOCOL" And the response property "$.message" contains a user friendly text - @geofencing_subscription_16_invalid_credential - Scenario: Subscription creation with invalid credential - Given a valid subscription request body + @geofencing_subscriptions_400.5_invalid_credential + Scenario: subscription creation with invalid credential type + Given a valid geofencing subscription request body + And the request property "$.sinkCredential.accessTokenType" is equal to "bearer" + And the request property "$.sinkCredential.credentialType" is not equal to "ACCESSTOKEN" When the request "createGeofencingSubscription" is sent - And the request property "$.types" is set to "org.camaraproject.geofencing-subscriptions.v0.area-entered" - And the request property "$.protocol" is set to "HTTP" - And the request property "$.config.subscriptionDetail.phoneNumber" is set with with provided phoneNumber - And the request property "$.sink" is set to provided callbackUrl - And the request property "$.sinkCredential.credentialType" is not set to "ACCESSTOKEN" - And the request property "$.sinkCredential.accessTokenType" is set to "bearer" - And the request property "$.sinkCredential.accessToken" is valued with a valid value - And the request property "$.sinkCredential.accessTokenExpiresUtc" is valued with a valid value - Then the response property "$.status" is 400 + 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 - @geofencing_subscription_17_invalid_token - Scenario: Subscription creation with invalid token - Given a valid subscription request body + @geofencing_subscriptions_400.6_create_subscriptions_with_invalid_access_token_type + Scenario: subscription creation with invalid token + Given a valid geofencing subscription request body + And the request property "$.sinkCredential.credentialType" is equal to "ACCESSTOKEN" + And the request property "$.sinkCredential.accessTokenType" is not equal to "bearer" When the request "createGeofencingSubscription" is sent - And the request property "$.types"="org.camaraproject.geofencing-subscriptions.v0.area-entered" - And the request property "$.protocol" is set to "HTTP" - And the request property "$.sink" is set to provided callbackUrl - And the request property "$.sinkCredential.credentialType" is set to "ACCESSTOKEN" - And the request property "$.sinkCredential.accessTokenType" is not set to "bearer" - And the request property "$.sinkCredential.accessToken" is valued with a valid value - And the request property "$.sinkCredential.accessTokenExpiresUtc" is valued with a valid value - Then the response property "$.status" is 400 - And the response property "$.code" is "INVALID_TOKEN" or "INVALID_ARGUMENT" + 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 - @geofencing_subscription_17_invalid_url + @geofencing_subscriptions_400.7_invalid_url Scenario: Subscription creation with sink Given a valid subscription request body When the request "createGeofencingSubscription" is sent @@ -231,27 +312,28 @@ Feature: Camara Geofencing Subscriptions API, vwip - Operations on subscriptions And the response property "$.code" is "INVALID_SINK" And the response property "$.message" contains a user friendly text - @geofencing_subscriptions_18_no_authorization_header_for_create_subscription + @geofencing_subscriptions_400.8_no_authorization_header_for_create_subscription Scenario: No Authorization header for create subscription - Given a valid subscription request body and header "Authorization" is not set to + Given a valid geofencing subscription request body + And the request does not include the "Authorization" header When the request "createGeofencingSubscription" 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 - @geofencing_subscriptions_19_expired_access_token_for_create_subscription + @geofencing_subscriptions_400.9_expired_access_token_for_create_subscription Scenario: Expired access token for create subscription - Given a valid subscription request body and header "Authorization" is expired + Given a valid geofencing subscription request body and header "Authorization" is expired When the request "createGeofencingSubscription" 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 - @geofencing_subscriptions_20_invalid_access_token_for_create_subscription + @geofencing_subscriptions_400.10_invalid_access_token_for_create_subscription Scenario: Invalid access token for create subscription - Given a valid subscription request body + Given a valid geofencing subscription request body And header "Authorization" set to an invalid access token When the request "createGeofencingSubscription" is sent Then the response status code is 401 @@ -260,36 +342,31 @@ Feature: Camara Geofencing Subscriptions API, vwip - Operations on subscriptions And the response property "$.code" is "UNAUTHENTICATED" And the response property "$.message" contains a user friendly text - @geofencing_subscriptions_21_no_authorization_header_for_get_subscription - Scenario: No Authorization header for get subscription - Given header "Authorization" is not set to valid token - And path parameter "subscriptionId" is set to the identifier of an existing subscription - When the request "retrieveGeofencingSubscription" 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 + # Error code 401 - @geofencing_subscriptions_22_expired_access_token_for_get_subscription - Scenario: Expired access token for get subscription - Given the header "Authorization" is set to expired token - When the request "retrieveGeofencingSubscription" is sent + @geofencing_subscriptions_creation_401.1_no_authorization_header + Scenario: No Authorization header + Given the header "Authorization" is removed + And the request body is compliant with the schema "#/components/schemas/SubscriptionRequest" + When the request "createGeofencingSubscription" 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 "$.code" is "UNAUTHENTICATED" or "AUTHENTICATION_REQUIRED" And the response property "$.message" contains a user friendly text - @geofencing_subscriptions_23_invalid_access_token_for_get_subscription - Scenario: Invalid access token for get subscription - Given the header "Authorization" set to an invalid access token - When the request "retrieveGeofencingSubscription" is sent + @geofencing_subscriptions_creation_401.2_expired_access_token + Scenario: Expired access token + Given the header "Authorization" is set to a previously valid but now expired access token + And the request body is compliant with the schema "#/components/schemas/SubscriptionRequest" + When the request "createGeofencingSubscription" 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 "$.code" is "UNAUTHENTICATED" or "AUTHENTICATION_REQUIRED" And the response property "$.message" contains a user friendly text - @geofencing_subscriptions_23_no_authorization_header_for_delete_subscription + @geofencing_subscriptions_401.3_no_authorization_header_for_delete_subscription Scenario: No Authorization header for delete subscription Given header "Authorization" is set without a token When the request "deleteGeofencingSubscription" is sent @@ -298,96 +375,74 @@ Feature: Camara Geofencing Subscriptions API, vwip - Operations on subscriptions And the response property "$.code" is "UNAUTHENTICATED" And the response property "$.message" contains a user friendly text - @geofencing_subscriptions_24_expired_access_token_for_delete_subscription - Scenario: Expired access token for delete subscription - Given header "Authorization" is set with an expired token - When the request "deleteGeofencingSubscription" is sent + @geofencing_subscriptions_401.4_no_authorization_header_for_get_subscription + Scenario: No Authorization header for get subscription + Given header "Authorization" is not set to valid token + And path parameter "subscriptionId" is set to the identifier of an existing subscription + When the request "retrieveGeofencingSubscription" 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 - @geofencing_subscriptions_25_invalid_access_token_for_delete_subscription - Scenario: Invalid access token for delete subscription - Given header "Authorization" set to an invalid access token - When the request "deleteGeofencingSubscription" is sent + @geofencing_subscriptions_creation_401.5_malformed_access_token + Scenario: Malformed access token + Given the header "Authorization" is set to a malformed token + And the request body is compliant with the schema "#/components/schemas/SubscriptionRequest" + When the request "createGeofencingSubscription" 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 "$.code" is "UNAUTHENTICATED" or "AUTHENTICATION_REQUIRED" And the response property "$.message" contains a user friendly text - @geofencing_subscriptions_26_get_unknown_geofencing_subscription_for_a_device - Scenario: Get method for geofencing subscription with subscription-id unknown to the system - Given the path parameter "subscriptionId" is set to the value unknown to system + # Error code 404 + + @geofencing_subscriptions_404.1_retrieve_unknown_subscriptions_id + Scenario: Get subscription when subscriptionId is unknown to the system + Given the path parameter "subscriptionId" is set to a value not corresponding to any existing subscription When the request "retrieveGeofencingSubscription" is sent - Then the response code is 404 + 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 - @geofencing_subscriptions_27_delete_invalid_geofencing_subscription_for_a_device - Scenario: Delete geofencing subscription with subscription-id unknown to the system - Given the path parameter "subscriptionId" is set to the value unknown to system + @geofencing_subscriptions_404.2_delete_unknown_subscriptions_id + Scenario: Delete subscription with subscriptionId unknown to the system + Given the path parameter "subscriptionId" is set to a value not corresponding to any existing subscription When the request "deleteGeofencingSubscription" is sent Then the response 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 - @geofencing_subscriptions_28_create_with_an_unsupported_area + # Error code 422 + + @geofencing_subscriptions_422.1_create_with_an_unsupported_area Scenario: Create subscription with an unsupported area - Given the request body property "$.area" is set to an unsupported - When the HTTP "POST" request is sent + Given the request body property "$.area" is set to an unsupported / uncovered area + When the request "createGeofencingSubscription" is sent Then the response status code is 422 And the response property "$.status" is 422 And the response property "$.code" is "GEOFENCING_SUBSCRIPTIONS.AREA_NOT_COVERED" And the response property "$.message" contains "Unable to cover the requested area" - # @geofencing_subscriptions_29_create_with_identifier_mismatch deprecated - - @geofencing_subscriptions_30_create_with_service_not_applicable - Scenario: Create subscription for a device not supported by the service - Given the request body includes a device identifier not applicable for this service - 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 "SERVICE_NOT_APPLICABLE" - And the response property "$.message" contains "Service is not available for the provided device identifier." - - @geofencing_subscriptions_31_create_with_unnecessary_identifier - Scenario: Create subscription with an unnecessary identifier - Given the request body explicitly includes a device identifier when it is not required - 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 "UNNECESSARY_IDENTIFIER" - And the response property "$.message" contains "Device is already identified by the access token." - - @geofencing_subscriptions_32_create_with_unsupported_identifier - Scenario: Create subscription with an unsupported identifier - Given the request body includes an identifier type not supported by the implementation - 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 "UNSUPPORTED_IDENTIFIER" - And the response property "$.message" contains "The identifier provided is not supported." - - @geofencing_subscriptions_33_create_with_an_invalid_area + @geofencing_subscriptions_422.2_create_with_an_invalid_area Scenario: Create subscription with an invalid area Given the request body property "$.area" is set with an too small area-size - When the HTTP "POST" request is sent + When the request "createGeofencingSubscription" is sent Then the response status code is 422 And the response property "$.status" is 422 And the response property "$.code" is "GEOFENCING_SUBSCRIPTIONS.INVALID_AREA" And the response property "$.message" contains "The requested area is too small" - @geofencing_subscriptions_33_missing_device - Scenario: Device not included and cannot be deduced from the access token - Given the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "$.device" is not included - When the HTTP "POST" request is sent - Then the response status code is 422 + @geofencing_subscriptions_422.3_create_with_unsupported_multiple_event_type + Scenario: Multi event subscription not supported + Given the API provider only allows one event to be subscribed per subscription request + And a valid subscription request body + And the request body property "$.types" is set to an array with 2 valid items + When the request "createGeofencingSubscription" is sent + Then the response code is 422 And the response property "$.status" is 422 - And the response property "$.code" is "MISSING_IDENTIFIER" - And the response property "$.message" contains a user-friendly text \ No newline at end of file + And the response property "$.code" is "MULTIEVENT_SUBSCRIPTION_NOT_SUPPORTED" + And the response property "$.message" contains a user friendly text diff --git a/code/Test_definitions/location-retrieval.feature b/code/Test_definitions/location-retrieval.feature index 51d21875..1a1878ae 100644 --- a/code/Test_definitions/location-retrieval.feature +++ b/code/Test_definitions/location-retrieval.feature @@ -1,269 +1,264 @@ -Feature: CAMARA Device location retrieval API, vwip - Operation retrieveLocation - # Input to be provided by the implementation to the tester - # - # Implementation indications: - # * List of device identifier types which are not supported, among: phoneNumber, networkAccessIdentifier, ipv4Address, ipv6Address - # - # Testing assets: - # * A device object which location is known by the network when connected. 2 distinct device are required for some scenario. - # * A device object identifying a device commercialized by the implementation for which the service is not applicable - # * A device object which location cannot be provided during test by the network. - # - # References to OAS spec schemas refer to schemas specifies in location-retrieval.yaml - - Background: Common retrieveLocation setup - Given the resource "/location-retrieval/vwip/retrieve" | - 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" complies with the schema at "#/components/schemas/XCorrelator" - And the request body is set by default to a request body compliant with the schema - - # Happy path scenarios - - # This first scenario serves as a minimum - @location_retrieval_01_generic_success_scenario - Scenario: Common validations for any success scenario - # Valid testing device and default request body compliant with the schema - # Not that in case the device is identifed by the token the body could be {} - Given a valid testing device supported by the service, identified by the token or provided in the request body - And the request body is set to a valid request body - When the HTTP "POST" 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/Location" - - # Scenarios testing specific situations for the device location - - @location_retrieval_02_location_retrieval_for_device_no_maxAge - Scenario: Retrieve location of a device without specifying maxAge - Given a valid testing device supported by the service, identified by the token or provided in the request body - And the request body property "$.maxAge" is not included - When the HTTP "POST" 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 complies with the OAS schema at "/components/schemas/Location" - - @location_retrieval_03_location_retrieval_for_device_with_maxAge - Scenario: Retrieve location of a device specifying maxAge - # maxAge could be tested with several values with scenario variable - Given a valid testing device supported by the service, identified by the token or provided in the request body - And the request body property "$.device" is set to a valid testing device supported by the service - And the request body property "$.maxAge" is included - When the HTTP "POST" 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 complies with the OAS schema at "/components/schemas/Location" - And the response property "$.lastLocationTime" value is not older than the value of "$.maxAge" the request time - - @location_retrieval_04_location_retrieval_unable_to_locate_device - # Input set to a device that could not be located - Scenario: Unable to provide device location - Given a valid testing device which cannot be located by the network, identified by the token or provided in the request body - And the request body property "$.maxAge" is not included - When the HTTP "POST" request is sent - Then the response status code is 422 - 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 property "$.status" is 422 - And the response property "$.code" is "LOCATION_RETRIEVAL.UNABLE_TO_LOCATE" - And the response property "$.message" contains a user friendly text - - @location_retrieval_05_location_retrieval_unable_to_locate_device_with_required_freshness - Scenario: Unable to provide device location with required maxAge - Given the testing device, identified by the token or provided in the request, is not connected to the network for some time - And request body property "$.device" is set to a valid testing device which is not connected to the network for some time - And the request body property "$.maxAge" is set to a value shorter than that time - When the HTTP "POST" request is sent - Then the response status code is 422 - 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 property "$.status" is 422 - And the response property "$.code" is "LOCATION_RETRIEVAL.UNABLE_TO_FULFILL_MAX_AGE" - And the response property "$.message" contains a user friendly text - - # Error scenarios for object device - - @location_retrieval_10_device_empty - Scenario: The device value is an empty object - Given the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "$.device" 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 - - @location_retrieval_11_device_identifiers_not_schema_compliant - Scenario Outline: Some device identifier value does not comply with the schema - Given the header "Authorization" is set to a valid access token which does not identify a single device - And 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: - | device_identifier | oas_spec_schema | - | $.device.phoneNumber | /components/schemas/PhoneNumber | - | $.device.ipv4Address | /components/schemas/DeviceIpv4Addr | - | $.device.ipv6Address | /components/schemas/DeviceIpv6Address | - | $.device.networkIdentifier | /components/schemas/NetworkAccessIdentifier | - - @location_retrieval_11.1_device_phoneNumber_schema_compliant - # Example of the scenario above with a higher level of specification - # TBD if test plan has to provide specific testing values to provoke an error - Scenario Outline: Device identifier phoneNumber value does not comply with the schema - Given the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "$.device.phoneNumber" 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 - - Examples: - | phone_number_value | - | string_value | - | 1234567890 | - | +12334foo22222 | - | +00012230304913849 | - | 123 | - | ++49565456787 | - - @location_retrieval_12_device_identifiers_unsupported - Scenario: None of the provided device identifiers is supported by the implementation - Given that some type of device identifiers are not supported by the implementation - And the header "Authorization" is set to a valid access token which does not identify a single device - And the request body property "$.device" only includes device identifiers not supported by the implementation - 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 "UNSUPPORTED_IDENTIFIERS" - And the response property "$.message" contains a user friendly text - - @location_retrieval_13_device_not_found - Scenario: Some identifier cannot be matched to a device - Given the request body property "$.device" is set to a value compliant to the OAS schema at "/components/schemas/Device" but does not identify a valid device - And the header "Authorization" is set to a valid access token which does not identify a single device - 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 "IDENTIFIER_NOT_FOUND" - And the response property "$.message" contains a user friendly text - - # @location_retrieval_14_device_identifiers_mismatch deprecated - - @location_retrieval_15_unnecessary_device - Scenario: Device not to be included when it can be deduced from the access token - Given the header "Authorization" is set to a valid access token identifying a device - And the request body property "$.device" is set to a valid device - 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 "UNNECESSARY_IDENTIFIER" - And the response property "$.message" contains a user friendly text - - @location_retrieval_16_device_not_supported - Scenario: Service not available for the device - Given that the service is not available for all devices commercialized by the operator - And a valid device, identified by the token or provided in the request body, for which the service is not applicable - 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 "SERVICE_NOT_APPLICABLE" - And the response property "$.message" contains a user friendly text - - @location_retrieval_17_device_identifier_missing - Scenario: Required device identifier is missing - Given the request body property "$.device" is not included - And the header "Authorization" is set to a valid access token which does not identify a single device - 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 "MISSING_IDENTIFIER" - And the response property "$.message" contains a user friendly text - - # Scenario specific to maxSurface - - @location_retireval_18_unable_to_fulfill_max_surface - Scenario: Unable to provide device location with required maxSurface - Given the testing device, identified by the token or provided in the request, is located within a surface of certain area - And the request body property "$.maxSurface" is set to a value smaller than that area - When the HTTP "POST" request is sent - Then the response status code is 422 - 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 property "$.status" is 422 - And the response property "$.code" is "LOCATION_RETRIEVAL.UNABLE_TO_FULFILL_MAX_SURFACE" - And the response property "$.message" contains a user friendly text - - # Generic 400 errors - - @location_retrieval_400.1_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 - - # Other specific 400 errors - - @location_retrieval_400.3_max_age_schema_compliant - Scenario: Input property values doe not comply with the schema - Given a valid testing device supported by the service, identified by the token or provided in the request body - And the "maxAge" is set to 6a0 - 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 - - # Generic 401 errors - - @location_retrieval_401.1_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 - - @location_retrieval_401.2_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 - - @location_retrieval_401.3_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 - - @location_retrieval_403_missing_scope - Scenario: Missing scope in the access token - Given the header "Authorization" is set to an access token without the required scope - And the request body is set to a valid request body - 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" +Feature: CAMARA Device location retrieval API, vwip - Operation retrieveLocation + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * List of device identifier types which are not supported, among: phoneNumber, networkAccessIdentifier, ipv4Address, ipv6Address + # + # Testing assets: + # * A device object which location is known by the network when connected. 2 distinct device are required for some scenario. + # * A device object identifying a device commercialized by the implementation for which the service is not applicable + # * A device object which location cannot be provided during test by the network. + # + # References to OAS spec schemas refer to schemas specifies in location-retrieval.yaml + + Background: Common retrieveLocation setup + Given the resource "/location-retrieval/vwip/retrieve" | + 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" complies with the schema at "#/components/schemas/XCorrelator" + And the request body is set by default to a request body compliant with the schema + + # Success scenarios + + # This first scenario serves as a minimum + @location_retrieval_200_generic_success_scenario + Scenario: Common validations for any success scenario + # Valid testing device and default request body compliant with the schema + # Not that in case the device is identified by the token the body could be {} + Given a valid testing device supported by the service, identified by the token or provided in the request body + And the request body is set to a valid request body + When the request "retrieveLocation" 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/Location" + + # Scenarios testing specific situations for the device location + + @location_retrieval_200.1_location_retrieval_for_device_no_maxAge + Scenario: Retrieve location of a device without specifying maxAge + Given a valid testing device supported by the service, identified by the token or provided in the request body + And the request body property "$.maxAge" is not included + When the request "retrieveLocation" 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 complies with the OAS schema at "#/components/schemas/Location" + + @location_retrieval_200.2_location_retrieval_for_device_with_maxAge + Scenario: Retrieve location of a device specifying maxAge + # maxAge could be tested with several values with scenario variable + Given a valid testing device supported by the service, identified by the token or provided in the request body + And the request body property "$.device" is set to a valid testing device supported by the service + And the request body property "$.maxAge" is included + When the request "retrieveLocation" 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 complies with the OAS schema at "#/components/schemas/Location" + And the response property "$.lastLocationTime" value is not older than the value of "$.maxAge" the request time + + # Error scenarios for management of input parameter device + + @location_retrieval_C01.01_device_empty + Scenario: The device value is an empty object + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "$.device" is set to: {} + When the request "retrieveLocation" 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 + + @location_retrieval_C01.02_device_identifiers_not_schema_compliant + Scenario Outline: Some device identifier value does not comply with the schema + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "" does not comply with the OAS schema at "" + When the request "retrieveLocation" 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: + | device_identifier | oas_spec_schema | + | $.device.phoneNumber | /components/schemas/PhoneNumber | + | $.device.ipv4Address | /components/schemas/DeviceIpv4Addr | + | $.device.ipv6Address | /components/schemas/DeviceIpv6Address | + | $.device.networkIdentifier | /components/schemas/NetworkAccessIdentifier | + + @location_retrieval_C01.03_device_not_found + Scenario: Some identifier cannot be matched to a device + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "$.device" is compliant with the schema, but does not identify a device whose connectivity is managed by the API provider + When the request "retrieveLocation" is sent + Then the response status code is 404 + And the response property "$.status" is 404 + And the response property "$.code" is "IDENTIFIER_NOT_FOUND" + And the response property "$.message" contains a user friendly text + + @location_retrieval_C01.04_unnecessary_device + Scenario: Device not to be included when it can be deduced from the access token + Given the header "Authorization" is set to a valid access token identifying a device + And the request body property "$.device" is set to a valid device, which may or may not be the same device that is identified by the access token + When the request "retrieveLocation" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "UNNECESSARY_IDENTIFIER" + And the response property "$.message" contains a user-friendly text + + @location_retrieval_C01.05_missing_device + Scenario: Device not included and cannot be deduced from the access token + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "$.device" is not included + When the request "retrieveLocation" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "MISSING_IDENTIFIER" + And the response property "$.message" contains a user-friendly text + + @location_retrieval_C01.06_unsupported_device + Scenario: None of the provided device identifiers is supported by the implementation + Given that some types of device identifiers are not supported by the implementation + And the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "$.device" only includes device identifiers not supported by the implementation + When the request "retrieveLocation" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "UNSUPPORTED_IDENTIFIER" + And the response property "$.message" contains a user-friendly text + + # When the service is only offered to certain types of devices or subscriptions, e.g. IoT, B2C, etc. + @location_retrieval_C01.07_device_not_supported + Scenario: Service not available for the device + Given that the service is not available for all devices commercialized by the API provider + And a valid device, identified by the token or provided in the request body, for which the service is not applicable + And a valid device, provided in the request body, for which the service is not applicable + When the request "retrieveLocation" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "SERVICE_NOT_APPLICABLE" + And the response property "$.message" contains a user-friendly text + + # Several identifiers provided but they do not identify the same device + # This scenario may happen with 2-legged access tokens, which do not identify a device + @location_retrieval_C01.08_device_identifiers_mismatch + Scenario: Device identifiers mismatch + Given the header "Authorization" is set to a valid access token which does not identify a single device + And at least 2 types of device identifiers are supported by the implementation + And the request body property "$.device" includes several identifiers, each of them identifying a valid but different device + When the request "retrieveLocation" is sent + Then the response status code is 422 + And the response property "$.status" is 422 + And the response property "$.code" is "IDENTIFIER_MISMATCH" + And the response property "$.message" contains a user friendly text + + # Error code 400 + + @location_retrieval_400.1_no_request_body + Scenario: Missing request body + Given the request body is not included + When the request "retrieveLocation" 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 + + @location_retrieval_400.2_max_age_schema_compliant + Scenario: Input property values doe not comply with the schema + Given a valid testing device supported by the service, identified by the token or provided in the request body + And the "maxAge" is set to 6a0 + When the request "retrieveLocation" 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 code 401 + + @location_retrieval_401.1_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 request "retrieveLocation" 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 + + @location_retrieval_401.2_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 request "retrieveLocation" 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 + + @location_retrieval_401.3_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 request "retrieveLocation" 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 code 403 + + @location_retrieval_403_missing_scope + Scenario: Missing scope in the access token + Given the header "Authorization" is set to an access token without the required scope + And the request body is set to a valid request body + When the request "retrieveLocation" 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 + + # Error code 404 + + @location_retrieval_404_unable_to_locate_device + # Input set to a device that could not be located + Scenario: Unable to provide device location + Given a valid testing device which cannot be located by the network operator, identified by the token or provided in the request body + + And the request body property "$.maxAge" is not included + When the request "retrieveLocation" is sent + Then the response status code is 404 + 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 property "$.status" is 404 + And the response property "$.code" is "LOCATION_RETRIEVAL.DEVICE_NOT_FOUND" + And the response property "$.message" contains a user friendly text + + # HTTP - 422 + + @location_retrieval_422.1_unable_to_fulfill_max_surface + Scenario: Unable to provide device location with required maxSurface + Given the testing device, identified by the token or provided in the request, is located by the network operator within a surface of certain area + + And the request body property "$.maxSurface" is set to a value smaller than that area + When the request "retrieveLocation" is sent + Then the response status code is 422 + 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 property "$.status" is 422 + And the response property "$.code" is "LOCATION_RETRIEVAL.UNABLE_TO_FULFILL_MAX_SURFACE" + And the response property "$.message" contains a user friendly text + + @location_retrieval_422.2_unable_to_locate_device_with_required_freshness + Scenario: Unable to provide device location with required maxAge + Given the testing device, identified by the token or provided in the request, is not connected to the network for some time + And the request body property "$.maxAge" is set to a value shorter than that time + When the request "retrieveLocation" is sent + Then the response status code is 422 + 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 property "$.status" is 422 + And the response property "$.code" is "LOCATION_RETRIEVAL.UNABLE_TO_FULFILL_MAX_AGE" And the response property "$.message" contains a user friendly text \ No newline at end of file diff --git a/code/Test_definitions/location-verification.feature b/code/Test_definitions/location-verification.feature index 72e98e0c..1ca6b3dd 100644 --- a/code/Test_definitions/location-verification.feature +++ b/code/Test_definitions/location-verification.feature @@ -18,6 +18,8 @@ Feature: CAMARA Device location verification API, vwip - Operation verifyLocatio And the header "x-correlator" complies with the schema at "#/components/schemas/XCorrelator" And the request body is set by default to a request body compliant with the schema + # Success scenarios + # This first scenario serves as a minimum, not testing any specific verificationResult @location_verification_01_generic_success_scenario Scenario: Common validations for any success scenario @@ -158,7 +160,7 @@ Feature: CAMARA Device location verification API, vwip - Operation verifyLocatio And the response property "$.code" is "SERVICE_NOT_APPLICABLE" And the response property "$.message" contains a user-friendly text - # Generic 400 errors + # Error code 400 @location_verification_400.1_no_request_body Scenario: Missing request body @@ -178,8 +180,6 @@ Feature: CAMARA Device location verification API, vwip - Operation verifyLocatio And the response property "$.code" is "INVALID_ARGUMENT" And the response property "$.message" contains a user friendly text - # Other specific 400 errors - @location_verification_400.3_other_input_properties_schema_not_compliant # Test other input properties in addition to device Scenario Outline: Input property values doe not comply with the schema @@ -216,7 +216,7 @@ Feature: CAMARA Device location verification API, vwip - Operation verifyLocatio | $.area.center.longitude | | $.area.radius | - # Generic 401 errors + # Error code 401 @location_verification_401.1_no_authorization_header Scenario: No Authorization header @@ -249,7 +249,7 @@ Feature: CAMARA Device location verification API, vwip - Operation verifyLocatio And the response property "$.code" is "UNAUTHENTICATED" And the response property "$.message" contains a user friendly text - # Generic 403 error + # Error code 403 @location_verification_403_missing_scope Scenario: Missing scope in the access token @@ -261,7 +261,7 @@ Feature: CAMARA Device location verification API, vwip - Operation verifyLocatio And the response property "$.code" is "PERMISSION_DENIED" And the response property "$.message" contains a user friendly text - # 422 error codes + # Error code 422 @location_verification_422.1_area_not_covered Scenario: Area not covered