From 7a32b69ff8a84b0b32b5c9f9587ab3902f8422f0 Mon Sep 17 00:00:00 2001 From: maheshc01 Date: Mon, 14 Sep 2026 12:58:48 -0500 Subject: [PATCH] Address r1.1 review findings in the API definition and test definitions - Reuse the Rate / RateUnitEnum schemas from QualityOnDemand for the response and rename the property to maxDownstreamMediaRate (#39) - Clarify that the returned value is the maximum rate the network allows for the device, as enforced for media traffic, not a measurement or forecast of achievable throughput (#41) - Point externalDocs.url to this repository (#42) - Declare error responses explicitly with only the codes this API can return; 500 removed, 429 kept (#40) - Consolidate test definitions into a single media-streaming-rate.feature covering happy path, request validation, C01 device errors, 401 and 403 - Update README scope to describe the API purpose --- README.md | 8 +- .../API_definitions/media-streaming-rate.yaml | 326 ++++++++++++++---- .../media-streaming-rate.feature | 244 +++++++++++++ 3 files changed, 506 insertions(+), 72 deletions(-) create mode 100644 code/Test_definitions/media-streaming-rate.feature diff --git a/README.md b/README.md index c53caa6..b43b254 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,10 @@ Sandbox API Repository to describe, develop, document, and test the DeviceMediaS ## Scope * Service API “DeviceMediaStreamingRate” (see [APIBacklog.md](https://github.com/camaraproject/APIBacklog/blob/main/documentation/APIbacklog.md)) -* The API provides the customer with the ability to: - * Get insights about the network status of a defined mobile device. - * For this the API will return an indicator which is bundeling information about the device network status such as availibilty, open datavolume, congjestion, historical congjestion or the connecitvity status (2G, 3G, 4G, 5G). - * This API would be useful for applications that optimize user experience based on the connecitvity status of a defined device. +* The API provides the API consumer with the ability to: + * Retrieve the maximum downstream media streaming rate that the network allows for a given device. + * The returned value is the rate the network enforces for media traffic to the device, not a measurement or forecast of the throughput the device will actually experience. + * This API is useful for media streaming applications using adaptive bitrate protocols (e.g. DASH, HLS), which can select a media representation that fits within the permitted rate before the media session starts, avoiding buffering and network policing. * Describe, develop, document, and test the APIs * Started: August 2024 diff --git a/code/API_definitions/media-streaming-rate.yaml b/code/API_definitions/media-streaming-rate.yaml index d2085cd..2b41272 100644 --- a/code/API_definitions/media-streaming-rate.yaml +++ b/code/API_definitions/media-streaming-rate.yaml @@ -4,57 +4,52 @@ info: version: wip x-camara-commonalities: wip description: | - This is a media streaming rate service API that allows application developers to retrieve - the maximum media streaming bit rate supported for a given device. + The Media Streaming Rate API allows an application developer to retrieve the maximum + downstream media streaming rate that the network allows for a given device. # Introduction - The Media Streaming Rate API allows an application developer to query the network - for the maximum supported media streaming bit rate for a specific end user device. - This API measures device connection quality by determining the maximum downstream - data rate available for media streaming, which is influenced by factors such as - network conditions, device capabilities, and current network congestion. - This information helps developers ensure their media streaming applications can provide - optimal quality while using the current network connection, enabling adaptive bitrate - streaming and preventing buffering issues. + Media streaming applications using adaptive bitrate protocols such as DASH or HLS select a media + representation (resolution and bit rate) from a manifest. Without knowing the limit that the + network applies to media traffic for a device, the application may select a representation that + the network will not deliver, resulting in buffering, packet loss and degraded quality, or the + network may need to police the media traffic down to the permitted rate. - # API functionality - - Prerequisite: authorisation and authentication - - Usage: - 1. Request: POST `retrieve-maximum-downstream-media-rate`, passing device identification - information such as IP address, phone number, or network access identifier. - 2. Response: The network will return the maximum downstream media streaming bit rate supported - for the device along with the unit of measurement. - - # Usage in Media Streaming Applications + This API exposes that limit to the application before the media session starts, so the + application can select a representation that fits within it. - This API can be integrated into media streaming applications to determine optimal - video resolution for streaming. A typical workflow: + ## Definition of the maximum downstream media streaming rate - 1. Application client requests manifest file (DASH/HLS) from CDN server - 2. Application client calls Media Streaming Rate API to get maximum supported bit rate - 3. Based on the response, application selects appropriate media resolution from the manifest - 4. Application begins media streaming from CDN using the optimal resolution + The value returned by this API is the **maximum downstream media streaming rate that the network + allows for the device**, as enforced by the network for media traffic (for example through + policing). It is not a measurement or a forecast of the throughput the device will actually + experience, which may be lower. Applications should use it as the upper bound when selecting a + media representation. - This approach ensures the best possible viewing experience while preventing buffering or quality issues. + # API functionality - The diagram below illustrates how the Media Streaming Rate API is used in a typical media streaming application: + Prerequisite: authorisation and authentication - ![Media Streaming Rate API Sequence Diagram](https://raw.githubusercontent.com/camaraproject/DeviceMediaStreamingRate/main/documentation/SupportingDocuments/media-rate-sequence-flow.png)` + Usage: + 1. Request: POST `retrieve-maximum-downstream-media-rate`, identifying the device either + through the access token or by providing the `device` object in the request body. + 2. Response: The maximum downstream media streaming rate permitted for the device, as a rate + value and unit. - # Token usage: two-legged vs three-legged + # Usage in media streaming applications - This API supports two types of access tokens: + A typical workflow: - - **Two-legged token**: Used for server-to-server calls. The device to be queried MUST be identified by providing the `device` object in the request body. - - **Three-legged token**: Used for user-authenticated calls. The device is identified from the access token itself, and the `device` object MUST NOT be provided in the request. + 1. The application client requests the manifest file (DASH/HLS) from the CDN server. + 2. The application client calls this API to obtain the maximum downstream media streaming rate + permitted for the device. + 3. Based on the response, the application selects a media representation from the manifest + whose bit rate does not exceed the returned value. + 4. The application starts media streaming from the CDN using the selected representation. - If a two-legged token is used and the device object is missing, the API will return a `422 MISSING_IDENTIFIER` error. - If a three-legged token is used and the device object is provided, the API will return a `422 UNNECESSARY_IDENTIFIER` error. + The diagram below illustrates this workflow: - This approach ensures clarity and security in device identification, and aligns with CAMARA API standards. + ![Media Streaming Rate API Sequence Diagram](https://raw.githubusercontent.com/camaraproject/DeviceMediaStreamingRate/main/documentation/SupportingDocuments/media-rate-sequence-flow.png) @@ -106,8 +101,8 @@ info: url: https://www.apache.org/licenses/LICENSE-2.0.html externalDocs: - description: Product documentation - url: https://github.com/camaraproject/DeviceQualityIndicator + description: Product documentation at CAMARA + url: https://github.com/camaraproject/DeviceMediaStreamingRate servers: - url: "{apiRoot}/media-streaming-rate/vwip" @@ -119,7 +114,7 @@ servers: tags: - name: Media Streaming Rate description: | - Retrieve the maximum media streaming bit rate supported for a given device. + Retrieve the maximum downstream media streaming rate permitted for a given device. paths: /retrieve-maximum-downstream-media-rate: @@ -131,17 +126,18 @@ paths: - Media Streaming Rate summary: Get maximum downstream media streaming rate description: | - Retrieve the maximum downstream media streaming rate for a device. This helps application - developers determine the optimal media quality settings for their applications. + Retrieve the maximum downstream media streaming rate that the network permits for a device. + This helps application developers select a media representation that fits within the + network limit for the device. - When using a two-legged token, the device object MUST be provided. - When using a three-legged token, the device object MUST NOT be provided as - the device information will be extracted from the token. + When using a two-legged access token, the `device` object MUST be provided. + When using a three-legged access token, the `device` object MUST NOT be provided, as the + device is identified from the access token. operationId: retrieveMaximumDownstreamMediaRate parameters: - $ref: "../common/CAMARA_common.yaml#/components/parameters/x-correlator" requestBody: - description: Device information needed to determine media rate capabilities. + description: Device information needed to determine the permitted media streaming rate. content: application/json: schema: @@ -158,56 +154,250 @@ paths: schema: $ref: "#/components/schemas/MediaStreamingRateResponse" "400": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic400" + $ref: "#/components/responses/Generic400" "401": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic401" + $ref: "#/components/responses/Generic401" "403": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic403" + $ref: "#/components/responses/Generic403" "404": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic404" + $ref: "#/components/responses/Generic404" "422": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic422" + $ref: "#/components/responses/Generic422" "429": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic429" - "503": - $ref: "../common/CAMARA_common.yaml#/components/responses/Generic500" + $ref: "#/components/responses/Generic429" components: securitySchemes: openId: $ref: "../common/CAMARA_common.yaml#/components/securitySchemes/openId" + responses: + Generic400: + description: Bad Request + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "../common/CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 400 + code: + enum: + - INVALID_ARGUMENT + examples: + GENERIC_400_INVALID_ARGUMENT: + description: Invalid Argument. Generic Syntax Exception + value: + status: 400 + code: INVALID_ARGUMENT + message: Client specified an invalid argument, request body or query param. + + Generic401: + description: Unauthorized + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "../common/CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 401 + code: + enum: + - UNAUTHENTICATED + examples: + GENERIC_401_UNAUTHENTICATED: + description: Request cannot be authenticated and a new authentication is required + value: + status: 401 + code: UNAUTHENTICATED + message: Request not authenticated due to missing, invalid, or expired credentials. A new authentication is required. + + Generic403: + description: Forbidden + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "../common/CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 403 + code: + enum: + - PERMISSION_DENIED + examples: + GENERIC_403_PERMISSION_DENIED: + description: Permission denied. OAuth2 token access does not have the required scope or when the user fails operational security + value: + status: 403 + code: PERMISSION_DENIED + message: Client does not have sufficient permissions to perform this action. + + Generic404: + description: Not found + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "../common/CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 404 + code: + enum: + - IDENTIFIER_NOT_FOUND + examples: + GENERIC_404_IDENTIFIER_NOT_FOUND: + description: Some identifier cannot be matched to a device + value: + status: 404 + code: IDENTIFIER_NOT_FOUND + message: Device identifier not found. + + Generic422: + description: Unprocessable Content + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "../common/CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 422 + code: + enum: + - SERVICE_NOT_APPLICABLE + - MISSING_IDENTIFIER + - UNSUPPORTED_IDENTIFIER + - UNNECESSARY_IDENTIFIER + examples: + GENERIC_422_SERVICE_NOT_APPLICABLE: + description: Service not applicable for the provided identifier + value: + status: 422 + code: SERVICE_NOT_APPLICABLE + message: The service is not available for the provided identifier. + GENERIC_422_MISSING_IDENTIFIER: + description: An identifier is not included in the request and the device identification cannot be derived from the 3-legged access token + value: + status: 422 + code: MISSING_IDENTIFIER + message: The device cannot be identified. + GENERIC_422_UNSUPPORTED_IDENTIFIER: + description: None of the provided identifiers is supported by the implementation + value: + status: 422 + code: UNSUPPORTED_IDENTIFIER + message: The identifier provided is not supported. + GENERIC_422_UNNECESSARY_IDENTIFIER: + description: An explicit identifier is provided when a device has already been identified from the access token + value: + status: 422 + code: UNNECESSARY_IDENTIFIER + message: The device is already identified by the access token. + + Generic429: + description: Too Many Requests + headers: + x-correlator: + $ref: "../common/CAMARA_common.yaml#/components/headers/x-correlator" + content: + application/json: + schema: + allOf: + - $ref: "../common/CAMARA_common.yaml#/components/schemas/ErrorInfo" + - type: object + properties: + status: + enum: + - 429 + code: + enum: + - QUOTA_EXCEEDED + - TOO_MANY_REQUESTS + examples: + GENERIC_429_QUOTA_EXCEEDED: + description: Request is rejected due to exceeding a business quota limit + value: + status: 429 + code: QUOTA_EXCEEDED + message: Out of resource quota. + GENERIC_429_TOO_MANY_REQUESTS: + description: Access to the API has been temporarily blocked due to rate or spike arrest limits being reached + value: + status: 429 + code: TOO_MANY_REQUESTS + message: Rate limit reached. + schemas: MediaStreamingRateRequest: type: object - description: Defines the request body parameters + description: Request body identifying the device for which the permitted media streaming rate is retrieved. properties: device: $ref: "../common/CAMARA_common.yaml#/components/schemas/Device" MediaStreamingRateResponse: type: object - description: The maximum downstream media streaming bit rate supported for the device. + description: The maximum downstream media streaming rate permitted for the device. properties: device: $ref: "../common/CAMARA_common.yaml#/components/schemas/DeviceResponse" - maxDownstreamMediaBitRateSupported: + maxDownstreamMediaRate: + $ref: "#/components/schemas/Rate" + required: + - maxDownstreamMediaRate + + Rate: + description: Specification of rate + type: object + properties: + value: + description: Quantity of rate type: integer - description: The maximum downstream bit rate supported for the device example: 10 format: int32 minimum: 0 maximum: 1024 unit: - type: string - description: The unit of the bit rate (e.g., Mbps, Kbps) - example: "Mbps" - enum: - - bps - - kbps - - Mbps - - Gbps - - Tbps + $ref: "#/components/schemas/RateUnitEnum" required: - - maxDownstreamMediaBitRateSupported + - value - unit + + RateUnitEnum: + description: Units of rate + type: string + enum: + - bps + - kbps + - Mbps + - Gbps + - Tbps diff --git a/code/Test_definitions/media-streaming-rate.feature b/code/Test_definitions/media-streaming-rate.feature new file mode 100644 index 0000000..e74fbbb --- /dev/null +++ b/code/Test_definitions/media-streaming-rate.feature @@ -0,0 +1,244 @@ +Feature: CAMARA Media Streaming Rate API, vwip - Operation retrieveMaximumDownstreamMediaRate + + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * apiRoot: API root of the server URL + # * List of device identifier types which are not supported, among: phoneNumber, ipv4Address, ipv6Address, networkAccessIdentifier + # * Whether the service is offered only to certain types of devices or subscriptions + # + # Testing assets: + # * A device object identifying a device for which the network can determine the maximum permitted downstream media streaming rate + # * A device object including more than one identifier type, all identifying the same device + # * A device object which is schema compliant but does not identify any device known to the network + # * A device object for which the service is not applicable, if the service is not offered to all devices + # * Access tokens: a two-legged access token which does not identify any device, and a three-legged access token which identifies the testing device + # + # Note: Unless a scenario states otherwise, request bodies are assumed to be otherwise + # valid, with only the property under test deviating. + # + # References to OAS spec schemas refer to schemas specified in media-streaming-rate.yaml + # or, for referenced common schemas, in CAMARA_common.yaml + + Background: Common Media Streaming Rate setup + Given an environment at "apiRoot" + And the resource "/media-streaming-rate/vwip/retrieve-maximum-downstream-media-rate" + 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 at "#/components/schemas/MediaStreamingRateRequest" + + ########################## + # Happy path scenarios + ########################## + + @media_streaming_rate_01_two_legged_device_in_body + Scenario: Retrieve the maximum downstream media streaming rate with a two-legged 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 set to a valid device supported by the implementation + When the request "retrieveMaximumDownstreamMediaRate" 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/MediaStreamingRateResponse" + And the response property "$.maxDownstreamMediaRate.value" is an integer greater than or equal to 0 + And the response property "$.maxDownstreamMediaRate.unit" is one of "bps", "kbps", "Mbps", "Gbps" or "Tbps" + And the response property "$.device", if present, contains a single device identifier that was included in the request + + @media_streaming_rate_02_three_legged_device_from_token + Scenario: Retrieve the maximum downstream media streaming rate with a three-legged access token + Given the header "Authorization" is set to a valid access token identifying a device + And the request body property "$.device" is not included + When the request "retrieveMaximumDownstreamMediaRate" 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/MediaStreamingRateResponse" + And the response property "$.maxDownstreamMediaRate.value" is an integer greater than or equal to 0 + And the response property "$.maxDownstreamMediaRate.unit" is one of "bps", "kbps", "Mbps", "Gbps" or "Tbps" + And the response property "$.device" is not present + + @media_streaming_rate_03_multiple_device_identifiers + Scenario: Retrieve the maximum downstream media streaming rate providing more than one device identifier + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body property "$.device" includes more than one identifier type, all identifying the same valid device + When the request "retrieveMaximumDownstreamMediaRate" 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/MediaStreamingRateResponse" + And the response property "$.device" is present + And the response property "$.device" contains a single device identifier that was included in the request + + ########################## + # 400 - Request body validation + ########################## + + @media_streaming_rate_400.1_no_request_body + Scenario: Missing request body + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body is not included + When the request "retrieveMaximumDownstreamMediaRate" 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 + + @media_streaming_rate_400.2_empty_request_body + Scenario: Empty object as request body + Given the header "Authorization" is set to a valid access token which does not identify a single device + And the request body is set to "{}" + When the request "retrieveMaximumDownstreamMediaRate" 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 + + # Request body strictness: undeclared properties are rejected at any nesting level + @media_streaming_rate_400.3_unknown_property + Scenario Outline: A request body with an undeclared property is rejected + 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 a valid device supported by the implementation + And the request body property "" is set to "x" + When the request "retrieveMaximumDownstreamMediaRate" 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: + | property | + | $.unknownProperty | + | $.device.unknownProperty | + + ########################## + # Device identifier errors (Commonalities C01) + ########################## + + @media_streaming_rate_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 "retrieveMaximumDownstreamMediaRate" 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 + + @media_streaming_rate_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 "retrieveMaximumDownstreamMediaRate" 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/DeviceIpv4Address | + | $.device.ipv6Address | #/components/schemas/DeviceIpv6Address | + | $.device.networkAccessIdentifier | #/components/schemas/NetworkAccessIdentifier | + + # This scenario may happen e.g. with 2-legged access tokens, which do not identify a single device. + @media_streaming_rate_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 valid device + When the request "retrieveMaximumDownstreamMediaRate" 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 + + @media_streaming_rate_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 + When the request "retrieveMaximumDownstreamMediaRate" 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 + + @media_streaming_rate_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 "retrieveMaximumDownstreamMediaRate" 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 + + @media_streaming_rate_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 "retrieveMaximumDownstreamMediaRate" 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. + @media_streaming_rate_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 "retrieveMaximumDownstreamMediaRate" 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 + + ########################## + # 401 - Authentication errors + ########################## + + @media_streaming_rate_401.1_no_authorization_header + Scenario: No Authorization header + Given the header "Authorization" is removed + And the request body property "$.device" is set to a valid device supported by the implementation + When the request "retrieveMaximumDownstreamMediaRate" 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 + + @media_streaming_rate_401.2_expired_access_token + Scenario: Expired access token + Given the header "Authorization" is set to an expired access token + And the request body property "$.device" is set to a valid device supported by the implementation + When the request "retrieveMaximumDownstreamMediaRate" 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 + + @media_streaming_rate_401.3_invalid_access_token + Scenario: Invalid access token + Given the header "Authorization" is set to an invalid access token + And the request body property "$.device" is set to a valid device supported by the implementation + When the request "retrieveMaximumDownstreamMediaRate" 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 + + ########################## + # 403 - Authorization errors + ########################## + + @media_streaming_rate_403.1_missing_access_token_scope + Scenario: Access token does not include the required scope + Given the header "Authorization" is set to a valid access token which does not include the scope "media-streaming-rate:retrieve-maximum-downstream-media-rate" + And the request body property "$.device" is set to a valid device supported by the implementation + When the request "retrieveMaximumDownstreamMediaRate" 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