diff --git a/code/Test_definitions/README.md b/code/Test_definitions/README.md index 27a1f06..07747bd 100644 --- a/code/Test_definitions/README.md +++ b/code/Test_definitions/README.md @@ -1 +1,312 @@ -This directory contains at least one `.feature` file containing test definitions for the repository API(s). +# Test Definitions for CAMARA Session Insights API + +This directory contains the test definitions for the CAMARA Session Insights API, written using the Gherkin language for Behavior-Driven Development (BDD) testing. + +## Overview + +The Session Insights API test definitions ensure compliance with the API specification and validate the correct implementation of all endpoints and operations. These tests are designed to be executed using Cucumber or other BDD testing frameworks that support Gherkin syntax. + +## Test Files + +The following Gherkin feature files are provided: + +| File | Description | Endpoints Covered | +|------|-------------|-------------------| +| `session-insights-createSession.feature` | Session creation and validation | `POST /sessions` | +| `session-insights-getSession.feature` | Session retrieval by ID | `GET /sessions/{sessionId}` | +| `session-insights-deleteSession.feature` | Session deletion and cleanup | `DELETE /sessions/{sessionId}` | +| `session-insights-retrieveSessions.feature` | Device-based session retrieval | `POST /retrieve-sessions` | +| `session-insights-sendMetrics.feature` | Session metrics streaming | `POST /sessions/{sessionId}/metrics` | + +## Test Coverage + +### CAMARA Compliance Structure + +All test files follow the [CAMARA API Testing Guidelines](https://github.com/camaraproject/Commonalities/blob/main/documentation/API-Testing-Guidelines.md) structure: + +- **Feature Headers**: Include implementation indications and testing assets documentation +- **Background Sections**: Standard CAMARA environment setup with `apiRoot`, proper resource paths, and required headers +- **Scenario Tags**: Follow `@session_insights_operationName_XX_description` format for unique identification +- **Error Organization**: Scenarios grouped by HTTP status codes (400, 401, 403, 404, 409, 410, 422, 429) +- **Response Validation**: Explicit validation of status, code, message properties and OAS schema compliance + +### Functional Areas Covered + +Each test file covers both **sunny day scenarios** (successful operations) and **rainy day scenarios** (error conditions) as required by CAMARA testing guidelines: + +#### 🌞 Sunny Day Scenarios +- **Session Management**: Create, retrieve, and delete sessions with valid parameters +- **Protocol Support**: HTTP, MQTT3, and MQTT5 protocol configurations +- **Device Identifiers**: phoneNumber, IPv4/IPv6 addresses, networkAccessIdentifier +- **Metrics Streaming**: Valid KPI submission and processing +- **Authentication**: 2-legged and 3-legged token flows +- **Schema Compliance**: Response validation against OpenAPI specifications + +#### 🌧️ Rainy Day Scenarios +- **Input Validation**: Invalid formats, missing required fields, malformed data +- **Authentication & Authorization**: Missing credentials, invalid tokens, insufficient permissions +- **Resource Management**: Non-existent resources, expired sessions, conflicts +- **Protocol Errors**: Unsupported methods, invalid content types +- **Business Logic**: Rate limiting, payload size limits, session lifecycle violations +- **CAMARA Error Codes**: Standard error responses (UNAUTHENTICATED, PERMISSION_DENIED, etc.) + +### Key Testing Areas + +1. **CAMARA API Compliance** + - Request/response schema validation against OpenAPI specification + - HTTP status code verification per CAMARA standards + - Header validation (x-correlator, content-type) with proper roundtrip testing + - Error response format compliance with CAMARA error schemas + - Background section setup following CAMARA environment patterns + +2. **Security & Authentication** + - CAMARA-compliant token handling (2-legged vs 3-legged) + - Device identifier validation with MISSING_IDENTIFIER and UNNECESSARY_IDENTIFIER scenarios + - Scope and permission enforcement per CAMARA security guidelines + - Standard authentication error responses (UNAUTHENTICATED, PERMISSION_DENIED) + +3. **Session Lifecycle Management** + - Session creation with various protocol configurations (HTTP, MQTT3, MQTT5) + - Session state transitions and proper resource cleanup + - Expiration handling with GONE (410) responses + - Conflict detection for duplicate session scenarios + +4. **Multi-Protocol Support** + - HTTP webhook configurations with sink credentials + - MQTT broker settings for MQTT3/MQTT5 protocols + - Protocol-specific features and validation + - protocolSettings schema compliance testing + +5. **Metrics and Quality Assessment** + - KPI validation (latency, jitter, packet loss, bitrate, resolution) + - Data type and range validation per MetricsPayload schema + - Streaming frequency limits and rate limiting scenarios + - Negative value and boundary condition testing + +6. **CAMARA Error Handling** + - Standard error codes: INVALID_ARGUMENT, NOT_FOUND, CONFLICT, GONE + - Device identifier errors: MISSING_IDENTIFIER, UNNECESSARY_IDENTIFIER + - Rate limiting: TOO_MANY_REQUESTS, QUOTA_EXCEEDED + - Proper error message and status code validation + +## Prerequisites + +Before running the tests, ensure you have: + +### Environment Setup +- A running Session Insights API implementation +- Valid access tokens (2-legged and 3-legged) with appropriate scopes +- Test devices with known identifiers (phoneNumber, IP addresses, etc.) +- Valid Application Profile IDs +- MQTT broker access (for MQTT protocol tests) + +### Test Framework +- Cucumber-compatible test runner (Java, JavaScript, Python, etc.) +- HTTP client for API requests +- JSON schema validation libraries + +## Environment Variables + +The following environment variables should be configured for test execution following CAMARA testing patterns: + +```bash +# API Configuration +API_ROOT=https://api.example.com # Used as apiRoot in Background sections +API_TIMEOUT=30000 + +# Authentication (CAMARA-compliant tokens) +TWO_LEGGED_ACCESS_TOKEN=your_2legged_token_here +THREE_LEGGED_ACCESS_TOKEN=your_3legged_token_here +EXPIRED_ACCESS_TOKEN=expired_token_for_testing +INVALID_ACCESS_TOKEN=invalid_token_for_testing + +# Test Data (must exist in test environment) +VALID_APPLICATION_PROFILE_ID=550e8400-e29b-41d4-a716-446655440000 +NON_EXISTENT_APPLICATION_PROFILE_ID=550e8400-e29b-41d4-a716-446655440001 + +# Device Identifiers (test assets) +VALID_PHONE_NUMBER=+1234567890 +INVALID_PHONE_NUMBER=invalid-phone +VALID_IPV4_ADDRESS=192.168.1.100 +VALID_IPV4_PORT=8080 +INVALID_IPV4_ADDRESS=999.999.999.999 +VALID_IPV6_ADDRESS=2001:db8::1 +INVALID_IPV6_ADDRESS=invalid-ipv6 +VALID_NETWORK_ACCESS_ID=user@domain.com + +# Application Server Configuration +APP_SERVER_DOMAIN=app.example.com +APP_SERVER_IPV4=203.0.113.1 +APP_SERVER_IPV6=2001:db8::2 +APP_SERVER_PORT=443 + +# Protocol Settings +HTTP_WEBHOOK_URL=https://webhook.example.com/notifications +HTTP_SINK_CREDENTIAL=webhook_bearer_token +MQTT_BROKER_URI=mqtt://broker.example.com:1883 +MQTT_USERNAME=testuser +MQTT_PASSWORD=testpass + +# Session Test Data +EXISTING_SESSION_ID=existing-session-uuid +EXPIRED_SESSION_ID=expired-session-uuid +DELETED_SESSION_ID=deleted-session-uuid +NON_EXISTENT_SESSION_ID=550e8400-e29b-41d4-a716-446655440999 + +# Test Configuration (CAMARA standard) +X_CORRELATOR_VALID=test-correlator-123 +X_CORRELATOR_INVALID=invalid@correlator! +MALFORMED_UUID=123e4567-e89b-12d3-a456-42661417400 +RANDOM_UUID=random-generated-uuid-here +``` + +## Running the Tests + +### Using Cucumber with Java/Maven + +```bash +# Run all tests +mvn test + +# Run specific feature file +mvn test -Dcucumber.options="src/test/resources/session-insights-createSession.feature" + +# Run tests with specific tags +mvn test -Dcucumber.options="--tags @sunny-day" +``` + +### Using Cucumber with Node.js + +```bash +# Install dependencies +npm install + +# Run all tests +npm test + +# Run specific feature +npx cucumber-js features/session-insights-createSession.feature + +# Run with tags +npx cucumber-js --tags "@sunny-day" +``` + +### Using Behave (Python) + +```bash +# Install dependencies +pip install behave requests + +# Run all tests +behave + +# Run specific feature +behave features/session-insights-createSession.feature + +# Run with tags +behave --tags=sunny-day +``` + +## Test Data Management + +### Device Test Data +Ensure you have access to devices with the following characteristics: +- **Valid devices**: Devices that exist and are accessible via the network +- **Invalid devices**: Device identifiers that are properly formatted but non-existent +- **Multiple identifiers**: Devices that can be identified by different methods + +### Session Test Data +- **Application Profile IDs**: Both valid and invalid UUIDs +- **Application Sessions**: Various session identifiers for correlation +- **Webhook URLs**: Valid and invalid webhook endpoints for HTTP protocol testing + +### Metrics Test Data +- **Valid KPI ranges**: Realistic values for latency, jitter, packet loss, bitrate +- **Edge cases**: Zero values, very large values, boundary conditions +- **Invalid data**: Wrong data types, negative values, missing fields + +## Test Result Interpretation + +### Expected Results + +**✅ Successful Test Indicators:** +- All sunny day scenarios pass with expected HTTP status codes per CAMARA standards +- Response schemas validate against OpenAPI specification schemas +- Error scenarios return appropriate CAMARA error codes and messages +- x-correlator headers are properly handled in request/response roundtrip +- Background environment setup executes successfully +- OAS schema compliance validation passes for all response bodies + +**❌ Common Failure Scenarios:** +- Schema validation failures (check API implementation against session-insights.yaml) +- Authentication errors (verify tokens have required scopes per CAMARA security) +- Network connectivity issues (check apiRoot endpoint accessibility) +- Missing environment variables (verify CAMARA test assets configuration) +- Incorrect error response format (ensure CAMARA error schema compliance) + +### Debugging Failed Tests + +1. **Check API Logs**: Review server-side logs for detailed error information +2. **Validate Environment**: Ensure all required environment variables are set +3. **Network Connectivity**: Verify API endpoint accessibility +4. **Token Validity**: Confirm access tokens are valid and have required scopes +5. **Test Data**: Ensure test devices and profiles exist in the test environment + +## Contributing to Tests + +When modifying or adding test scenarios, follow CAMARA testing guidelines: + +1. **Follow CAMARA Structure**: Use proper Background sections, scenario tags, and Given/When/Then patterns +2. **Maintain Scenario Tags**: Use format `@session_insights_operationName_XX_description` +3. **Cover Edge Cases**: Include boundary testing and error conditions per CAMARA standards +4. **Update Documentation**: Keep this README current with any changes +5. **Test Locally**: Validate new scenarios against CAMARA-compliant implementations +6. **Schema References**: Use correct OAS schema paths like `/components/schemas/SchemaName` +7. **Error Scenarios**: Organize by HTTP status code and include CAMARA error codes + +### Test Naming Conventions + +- **Scenario Tags**: `@session_insights_operationName_XX_description` + - Examples: `@session_insights_createSession_01_http_session_creation` + - Examples: `@session_insights_getSession_400.1_invalid_session_id_format` +- **Given/When/Then**: Use specific, testable conditions + - Given: Setup conditions and test data + - When: Single action (`When the request "operationName" is sent`) + - Then: Expected outcomes with specific validations +- **Error Scenarios**: Include HTTP status and CAMARA error code + - Examples: `400.1_invalid_argument`, `401.1_no_authorization_header`, `422.1_missing_identifier` + +## API Versioning + +These tests are designed for **Session Insights API vwip** following CAMARA versioning standards. When the API version changes: + +1. Update version references in feature file headers (`vwip` → `v1.0.0`) +2. Update resource paths in Background sections (`/session-insights/vwip/` → `/session-insights/v1.0.0/`) +3. Review and update test scenarios for any breaking changes +4. Validate all existing tests against the new API version per CAMARA guidelines +5. Add new test cases for any new functionality following CAMARA structure +6. Ensure OAS schema references remain accurate + +## Related Documentation + +- [CAMARA Session Insights API Specification](../API_definitions/session-insights.yaml) +- [CAMARA API Testing Guidelines](https://github.com/camaraproject/Commonalities/blob/main/documentation/API-Testing-Guidelines.md) +- [CAMARA API Design Guidelines](https://github.com/camaraproject/Commonalities/blob/main/documentation/API-design-guidelines.md) +- [Gherkin Reference](https://cucumber.io/docs/gherkin/reference/) +- [Behavior-Driven Development (BDD)](https://cucumber.io/docs/bdd/) + +## Support + +For questions or issues related to these test definitions: + +1. **API Issues**: Report to the Session Insights API working group +2. **Test Framework Issues**: Check Cucumber/Gherkin documentation +3. **CAMARA Guidelines**: Refer to Commonalities working group documentation + +## License + +This test suite is part of the CAMARA project and follows the same licensing terms as the Session Insights API specification. + +--- + +**Note**: These tests are designed to validate API implementation compliance and should be run in appropriate test environments. Do not run tests against production systems without proper authorization and safeguards. diff --git a/code/Test_definitions/session-insights-createSession.feature b/code/Test_definitions/session-insights-createSession.feature new file mode 100644 index 0000000..0d1b59c --- /dev/null +++ b/code/Test_definitions/session-insights-createSession.feature @@ -0,0 +1,394 @@ +Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation createSession + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * apiRoot: API root of the server URL + # + # Testing assets: + # * A valid Application Profile ID that exists in the system + # * Valid device identifiers (phoneNumber, IPv4/IPv6 addresses, networkAccessIdentifier) + # * Valid application server configuration (domain name or IP addresses with ports) + # * Valid webhook URLs for HTTP protocol testing + # * Valid MQTT broker configuration for MQTT protocol testing + # * Access tokens with appropriate scopes for 2-legged and 3-legged authentication + # + # References to OAS spec schemas refer to schemas specified in session-insights.yaml + + Background: Common createSession setup + Given an environment at "apiRoot" + And the resource "/session-insights/vwip/sessions" + 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" + + # Success scenarios + + @session_insights_createSession_01_http_session_creation + Scenario: Create HTTP session with valid parameters + Given a valid device with phoneNumber + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + When the request "createSession" is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/CreateSessionResponse" + And the response property "$.id" is present and complies with the OAS schema at "/components/schemas/SessionId" + And the response property "$.protocol" is "HTTP" + And the response property "$.sink" is present + And the response property "$.startTime" is present and complies with date-time format + And the response property "$.expiresAt" is present and complies with date-time format + + @session_insights_createSession_02_mqtt3_session_creation + Scenario: Create MQTT3 session with valid parameters + Given a valid device with phoneNumber + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "MQTT3" + When the request "createSession" is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response body complies with the OAS schema at "/components/schemas/CreateSessionResponse" + And the response property "$.id" is present and complies with the OAS schema at "/components/schemas/SessionId" + And the response property "$.protocol" is "MQTT3" + And the response property "$.protocolSettings" is present + + @session_insights_createSession_03_mqtt5_session_creation + Scenario: Create MQTT5 session with valid parameters + Given a valid device with phoneNumber + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "MQTT5" + When the request "createSession" is sent + Then the response status code is 201 + And the response header "Content-Type" is "application/json" + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response property "$.protocol" is "MQTT5" + And the response property "$.protocolSettings" is present + + @session_insights_createSession_04_with_application_session_id + Scenario: Create session with optional applicationSessionId + Given a valid device with phoneNumber + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + And the request body property "$.applicationSessionId" is set to "meet-12345" + When the request "createSession" is sent + Then the response status code is 201 + And the response property "$.applicationSessionId" is "meet-12345" + + @session_insights_createSession_05_ipv4_device_identifier + Scenario: Create session with IPv4 device identifier + Given a valid device with IPv4 address and port + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + When the request "createSession" is sent + Then the response status code is 201 + And the response property "$.device" contains IPv4 address information + + @session_insights_createSession_06_ipv6_device_identifier + Scenario: Create session with IPv6 device identifier + Given a valid device with IPv6 address + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + When the request "createSession" is sent + Then the response status code is 201 + And the response property "$.device" contains IPv6 address information + + @session_insights_createSession_07_network_access_identifier + Scenario: Create session with network access identifier + Given a valid device with networkAccessIdentifier + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + When the request "createSession" is sent + Then the response status code is 201 + And the response property "$.device" contains networkAccessIdentifier information + + # Errors 400 + + @session_insights_createSession_400.1_missing_application_profile_id + Scenario: Missing required applicationProfileId + Given a valid device with phoneNumber + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + But the request body property "$.applicationProfileId" is not included + When the request "createSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_400.2_missing_device + Scenario: Missing required device information + Given a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + But the request body property "$.device" is not included + When the request "createSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_400.3_missing_application_server + Scenario: Missing required applicationServer + Given a valid device with phoneNumber + And a valid Application Profile ID + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + But the request body property "$.applicationServer" is not included + When the request "createSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_400.4_missing_protocol + Scenario: Missing required protocol + Given a valid device with phoneNumber + And a valid Application Profile ID + And a valid application server configuration + But the request body property "$.protocol" is not included + When the request "createSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_400.5_invalid_protocol_value + Scenario: Invalid protocol value + Given a valid device with phoneNumber + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "INVALID_PROTOCOL" + When the request "createSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_400.6_http_missing_sink + Scenario: HTTP session missing required sink + Given a valid device with phoneNumber + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + But the request body property "$.sink" is not included + When the request "createSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_400.7_invalid_application_profile_id_format + Scenario: Invalid applicationProfileId format + Given a valid device with phoneNumber + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + And the request body property "$.applicationProfileId" is set to "not-a-uuid" + When the request "createSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_400.8_invalid_phone_number_format + Scenario: Invalid phoneNumber format + Given a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + And the request body property "$.device.phoneNumber" is set to "invalid-phone" + When the request "createSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_400.9_device_no_identifiers + Scenario: Device object with no identifiers + Given a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + And the request body property "$.device" is set to an empty object + When the request "createSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_400.10_invalid_content_type + Scenario: Invalid Content-Type header + Given a valid session request body + And the header "Content-Type" is set to "text/plain" + When the request "createSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_400.11_malformed_json + Scenario: Malformed JSON in request body + Given the request body is set to malformed JSON + When the request "createSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_401.1_no_authorization_header + Scenario: Error response for no header "Authorization" + Given the header "Authorization" is not sent + And a valid session request body + When the request "createSession" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + @session_insights_createSession_401.2_expired_access_token + Scenario: Error response for expired access token + Given the header "Authorization" is set to an expired access token + And a valid session request body + When the request "createSession" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + @session_insights_createSession_401.3_invalid_access_token + Scenario: Error response for invalid access token + Given the header "Authorization" is set to an invalid access token + And a valid session request body + When the request "createSession" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + # Generic 403 errors + + @session_insights_createSession_403.1_missing_access_token_scope + Scenario: Missing access token scope + Given the header "Authorization" is set to an access token that does not include the required scope + And a valid session request body + When the request "createSession" is sent + Then the response status code is 403 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + # Errors 404 + + @session_insights_createSession_404.1_application_profile_not_found + Scenario: applicationProfileId not found + Given a valid device with phoneNumber + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + And the request body property "$.applicationProfileId" is set to a valid UUID that does not exist + When the request "createSession" is sent + Then the response status code is 404 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + # Errors 409 + + @session_insights_createSession_409.1_session_conflict + Scenario: Session already exists for this device and application profile + Given a valid device with phoneNumber + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + And a session already exists for this device and application profile combination + When the request "createSession" is sent + Then the response status code is 409 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 409 + And the response property "$.code" is "CONFLICT" + And the response property "$.message" contains a user friendly text + + # Errors 422 + + @session_insights_createSession_422.1_three_legged_token_with_device_parameter + Scenario: 3-legged token used with device parameter + Given the header "Authorization" is set to a valid 3-legged access token + And a valid device with phoneNumber is provided in the request body + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + When the request "createSession" is sent + Then the response status code is 422 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_createSession_422.2_two_legged_token_without_device_parameter + Scenario: 2-legged token used without device parameter + Given the header "Authorization" is set to a valid 2-legged access token + And a valid Application Profile ID + And a valid application server configuration + And the request body property "$.protocol" is set to "HTTP" + And the request body property "$.sink" is set to a valid webhook URL + But the request body property "$.device" is not included + When the request "createSession" is sent + Then the response status code is 422 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 diff --git a/code/Test_definitions/session-insights-deleteSession.feature b/code/Test_definitions/session-insights-deleteSession.feature new file mode 100644 index 0000000..346576c --- /dev/null +++ b/code/Test_definitions/session-insights-deleteSession.feature @@ -0,0 +1,204 @@ +Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation deleteSession + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * apiRoot: API root of the server URL + # + # Testing assets: + # * The sessionId of an existing HTTP session + # * The sessionId of an existing MQTT3 session + # * The sessionId of an existing MQTT5 session + # * The sessionId of an existing session with active notifications + # * The sessionId of an existing session with active metrics streaming + # * Access tokens with appropriate scopes for session deletion + # + # References to OAS spec schemas refer to schemas specified in session-insights.yaml + + Background: Common deleteSession setup + Given an environment at "apiRoot" + And the resource "/session-insights/vwip/sessions/{sessionId}" + 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 path parameter "sessionId" is set by default to an existing session sessionId + + # Success scenarios + + @session_insights_deleteSession_01_delete_http_session + Scenario: Delete an existing HTTP session + Given an existing HTTP session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + When the request "deleteSession" is sent + Then the response status code is 204 + And the response body is empty + And the response header "x-correlator" has same value as the request header "x-correlator" + + @session_insights_deleteSession_02_delete_mqtt3_session + Scenario: Delete an existing MQTT3 session + Given an existing MQTT3 session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + When the request "deleteSession" is sent + Then the response status code is 204 + And the response body is empty + And the response header "x-correlator" has same value as the request header "x-correlator" + + @session_insights_deleteSession_03_delete_mqtt5_session + Scenario: Delete an existing MQTT5 session + Given an existing MQTT5 session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + When the request "deleteSession" is sent + Then the response status code is 204 + And the response body is empty + And the response header "x-correlator" has same value as the request header "x-correlator" + + @session_insights_deleteSession_04_delete_session_with_application_session_id + Scenario: Delete session with applicationSessionId + Given an existing session created with applicationSessionId "meet-12345" + And the path parameter "sessionId" is set to the value for that session + When the request "deleteSession" is sent + Then the response status code is 204 + And the response body is empty + + @session_insights_deleteSession_05_verify_session_deleted + Scenario: Verify session is no longer accessible after deletion + Given an existing session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the session has been successfully deleted + When the request "getSession" is sent to verify deletion + Then the response status code is 410 + And the response property "$.code" is "GONE" + + @session_insights_deleteSession_06_stop_notifications_after_deletion + Scenario: Verify notifications stop after session deletion + Given an existing HTTP session with active webhook notifications + And the path parameter "sessionId" is set to the value for that session + When the request "deleteSession" is sent + Then the response status code is 204 + And no further notifications are sent for this session + + @session_insights_deleteSession_07_stop_mqtt_subscriptions_after_deletion + Scenario: Verify MQTT subscriptions terminate after session deletion + Given an existing MQTT session with active subscriptions + And the path parameter "sessionId" is set to the value for that session + When the request "deleteSession" is sent + Then the response status code is 204 + And all MQTT subscriptions are terminated for this session + + # Errors 400 + + @session_insights_deleteSession_400.1_invalid_session_id_format + Scenario: Invalid sessionId format + Given the path parameter "sessionId" is set to "not-a-uuid" + When the request "deleteSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_deleteSession_400.2_malformed_uuid_session_id + Scenario: Malformed UUID sessionId + Given the path parameter "sessionId" is set to "123e4567-e89b-12d3-a456-42661417400" + When the request "deleteSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_deleteSession_401.1_no_authorization_header + Scenario: Error response for no header "Authorization" + Given the header "Authorization" is not sent + When the request "deleteSession" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + @session_insights_deleteSession_401.2_expired_access_token + Scenario: Error response for expired access token + Given the header "Authorization" is set to an expired access token + When the request "deleteSession" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + @session_insights_deleteSession_401.3_invalid_access_token + Scenario: Error response for invalid access token + Given the header "Authorization" is set to an invalid access token + When the request "deleteSession" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + # Generic 403 errors + + @session_insights_deleteSession_403.1_missing_access_token_scope + Scenario: Missing access token scope + Given the header "Authorization" is set to an access token that does not include the required scope + When the request "deleteSession" is sent + Then the response status code is 403 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_deleteSession_403.2_session_token_mismatch + Scenario: Session not created by the API client given in the access token + Given the header "Authorization" is set to a valid access token emitted to a client which did not create the session + When the request "deleteSession" is sent + Then the response status code is 403 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + # Errors 404 + + @session_insights_deleteSession_404.1_session_not_found + Scenario: sessionId of a non-existing session + Given the path parameter "sessionId" is set to a random UUID + When the request "deleteSession" is sent + Then the response status code is 404 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + # Errors 410 + + @session_insights_deleteSession_410.1_expired_session + Scenario: Delete already expired session + Given the path parameter "sessionId" is set to the value of an expired session + When the request "deleteSession" is sent + Then the response status code is 410 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 410 + And the response property "$.code" is "GONE" + And the response property "$.message" contains a user friendly text + + @session_insights_deleteSession_410.2_already_deleted_session + Scenario: Delete already deleted session (idempotency test) + Given the path parameter "sessionId" is set to the value of a previously deleted session + When the request "deleteSession" is sent + Then the response status code is 410 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 410 + And the response property "$.code" is "GONE" + And the response property "$.message" contains a user friendly text diff --git a/code/Test_definitions/session-insights-getSession.feature b/code/Test_definitions/session-insights-getSession.feature new file mode 100644 index 0000000..4ac5033 --- /dev/null +++ b/code/Test_definitions/session-insights-getSession.feature @@ -0,0 +1,232 @@ +Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation getSession + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * apiRoot: API root of the server URL + # + # Testing assets: + # * The sessionId of an existing HTTP session + # * The sessionId of an existing MQTT3 session + # * The sessionId of an existing MQTT5 session + # * The sessionId of an existing session with applicationSessionId + # * The sessionId of sessions created with different device identifier types + # * Access tokens with appropriate scopes for session retrieval + # + # References to OAS spec schemas refer to schemas specified in session-insights.yaml + + Background: Common getSession setup + Given an environment at "apiRoot" + And the resource "/session-insights/vwip/sessions/{sessionId}" + 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 path parameter "sessionId" is set by default to an existing session sessionId + + # Success scenarios + + @session_insights_getSession_01_retrieve_http_session + Scenario: Retrieve existing HTTP session by sessionId + Given an existing HTTP session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + When the request "getSession" 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/Session" + And the response property "$.id" has the same value as the path parameter "sessionId" + And the response property "$.protocol" is "HTTP" + And the response property "$.device" is present + And the response property "$.applicationServer" is present + And the response property "$.sink" is present + And the response property "$.subscribedEventTypes" is present + And the response property "$.startTime" is present and complies with date-time format + And the response property "$.expiresAt" is present and complies with date-time format + + @session_insights_getSession_02_retrieve_mqtt3_session + Scenario: Retrieve existing MQTT3 session by sessionId + Given an existing MQTT3 session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + When the request "getSession" 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/Session" + And the response property "$.id" has the same value as the path parameter "sessionId" + And the response property "$.protocol" is "MQTT3" + And the response property "$.protocolSettings" is present + And the response property "$.device" is present + And the response property "$.subscribedEventTypes" is present + + @session_insights_getSession_03_retrieve_mqtt5_session + Scenario: Retrieve existing MQTT5 session by sessionId + Given an existing MQTT5 session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + When the request "getSession" 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 property "$.protocol" is "MQTT5" + And the response property "$.protocolSettings" is present + + @session_insights_getSession_04_session_with_application_session_id + Scenario: Retrieve session with applicationSessionId + Given an existing session created with applicationSessionId "meet-12345" + And the path parameter "sessionId" is set to the value for that session + When the request "getSession" is sent + Then the response status code is 200 + And the response property "$.applicationSessionId" is "meet-12345" + + @session_insights_getSession_05_session_with_phone_number + Scenario: Retrieve session created with device phoneNumber + Given an existing session created with device phoneNumber + And the path parameter "sessionId" is set to the value for that session + When the request "getSession" is sent + Then the response status code is 200 + And the response property "$.device.phoneNumber" is present + And the response property "$.device" contains exactly one identifier property + + @session_insights_getSession_06_session_with_ipv4_address + Scenario: Retrieve session created with device IPv4 address + Given an existing session created with device IPv4 address + And the path parameter "sessionId" is set to the value for that session + When the request "getSession" is sent + Then the response status code is 200 + And the response property "$.device.ipv4Address" is present + And the response property "$.device" contains exactly one identifier property + + @session_insights_getSession_07_session_with_ipv6_address + Scenario: Retrieve session created with device IPv6 address + Given an existing session created with device IPv6 address + And the path parameter "sessionId" is set to the value for that session + When the request "getSession" is sent + Then the response status code is 200 + And the response property "$.device.ipv6Address" is present + And the response property "$.device" contains exactly one identifier property + + @session_insights_getSession_08_session_with_network_access_identifier + Scenario: Retrieve session created with network access identifier + Given an existing session created with device networkAccessIdentifier + And the path parameter "sessionId" is set to the value for that session + When the request "getSession" is sent + Then the response status code is 200 + And the response property "$.device.networkAccessIdentifier" is present + And the response property "$.device" contains exactly one identifier property + + # Errors 400 + + @session_insights_getSession_400.1_invalid_session_id_format + Scenario: Invalid sessionId format + Given the path parameter "sessionId" is set to "not-a-uuid" + When the request "getSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_getSession_400.2_malformed_uuid_session_id + Scenario: Malformed UUID sessionId + Given the path parameter "sessionId" is set to "123e4567-e89b-12d3-a456-42661417400" + When the request "getSession" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_getSession_401.1_no_authorization_header + Scenario: Error response for no header "Authorization" + Given the header "Authorization" is not sent + When the request "getSession" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + @session_insights_getSession_401.2_expired_access_token + Scenario: Error response for expired access token + Given the header "Authorization" is set to an expired access token + When the request "getSession" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + @session_insights_getSession_401.3_invalid_access_token + Scenario: Error response for invalid access token + Given the header "Authorization" is set to an invalid access token + When the request "getSession" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + # Generic 403 errors + + @session_insights_getSession_403.1_missing_access_token_scope + Scenario: Missing access token scope + Given the header "Authorization" is set to an access token that does not include the required scope + When the request "getSession" is sent + Then the response status code is 403 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_getSession_403.2_session_token_mismatch + Scenario: Session not accessible by the API client given in the access token + Given the header "Authorization" is set to a valid access token emitted to a client which did not create the session + When the request "getSession" is sent + Then the response status code is 403 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + # Errors 404 + + @session_insights_getSession_404.1_session_not_found + Scenario: sessionId of a non-existing session + Given the path parameter "sessionId" is set to a random UUID + When the request "getSession" is sent + Then the response status code is 404 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + # Errors 410 + + @session_insights_getSession_410.1_expired_session + Scenario: sessionId of an expired session + Given the path parameter "sessionId" is set to the value of an expired session + When the request "getSession" is sent + Then the response status code is 410 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 410 + And the response property "$.code" is "GONE" + And the response property "$.message" contains a user friendly text + + @session_insights_getSession_410.2_deleted_session + Scenario: sessionId of a deleted session + Given the path parameter "sessionId" is set to the value of a previously deleted session + When the request "getSession" is sent + Then the response status code is 410 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 410 + And the response property "$.code" is "GONE" + And the response property "$.message" contains a user friendly text diff --git a/code/Test_definitions/session-insights-retrieveSessions.feature b/code/Test_definitions/session-insights-retrieveSessions.feature new file mode 100644 index 0000000..0d5208e --- /dev/null +++ b/code/Test_definitions/session-insights-retrieveSessions.feature @@ -0,0 +1,301 @@ +Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation retrieveSessionsByDevice + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * apiRoot: API root of the server URL + # + # Testing assets: + # * Valid device identifiers (phoneNumber, IPv4/IPv6 addresses, networkAccessIdentifier) with existing sessions + # * Valid device identifiers with no existing sessions + # * Access tokens with appropriate scopes for 2-legged and 3-legged authentication + # * Device identifiers that exist but belong to different users/clients + # + # References to OAS spec schemas refer to schemas specified in session-insights.yaml + + Background: Common retrieveSessionsByDevice setup + Given an environment at "apiRoot" + And the resource "/session-insights/vwip/retrieve-sessions" + 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" + + # Success scenarios + + @session_insights_retrieveSessions_01_phone_number_2legged_token + Scenario: Retrieve sessions for device with phoneNumber using 2-legged token + Given the header "Authorization" is set to a valid 2-legged access token + And multiple existing sessions for a device with phoneNumber + And the request body property "$.device.phoneNumber" is set to that device phoneNumber + When the request "retrieveSessionsByDevice" 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/RetrieveSessionsOutput" + And the response property "$" is an array + And each item in the response array complies with the OAS schema at "/components/schemas/Session" + And all sessions in the response belong to the specified device + + @session_insights_retrieveSessions_02_ipv4_address_2legged_token + Scenario: Retrieve sessions for device with IPv4 address using 2-legged token + Given the header "Authorization" is set to a valid 2-legged access token + And existing sessions for a device with IPv4 address + And the request body property "$.device.ipv4Address" is set to that device IPv4 address + When the request "retrieveSessionsByDevice" 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 all sessions in the response belong to the device with specified IPv4 address + + @session_insights_retrieveSessions_03_ipv6_address_2legged_token + Scenario: Retrieve sessions for device with IPv6 address using 2-legged token + Given the header "Authorization" is set to a valid 2-legged access token + And existing sessions for a device with IPv6 address + And the request body property "$.device.ipv6Address" is set to that device IPv6 address + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And all sessions in the response belong to the device with specified IPv6 address + + @session_insights_retrieveSessions_04_network_access_identifier_2legged_token + Scenario: Retrieve sessions for device with networkAccessIdentifier using 2-legged token + Given the header "Authorization" is set to a valid 2-legged access token + And existing sessions for a device with networkAccessIdentifier + And the request body property "$.device.networkAccessIdentifier" is set to that device networkAccessIdentifier + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And all sessions in the response belong to the device with specified networkAccessIdentifier + + @session_insights_retrieveSessions_05_3legged_token_without_device + Scenario: Retrieve sessions using 3-legged token without device parameter + Given the header "Authorization" is set to a valid 3-legged access token for a specific device + And existing sessions for the authenticated device + And the request body does not include "$.device" property + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 200 + And the response header "Content-Type" is "application/json" + And all sessions in the response belong to the authenticated device + + @session_insights_retrieveSessions_06_empty_array_no_sessions + Scenario: Retrieve empty array when device has no sessions + Given the header "Authorization" is set to a valid 2-legged access token + And a device with phoneNumber that has no existing sessions + And the request body property "$.device.phoneNumber" is set to that device phoneNumber + When the request "retrieveSessionsByDevice" 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 property "$" is an empty array + + @session_insights_retrieveSessions_07_different_protocol_types + Scenario: Retrieve sessions including different protocol types + Given the header "Authorization" is set to a valid 2-legged access token + And existing HTTP, MQTT3, and MQTT5 sessions for a device + And the request body property "$.device.phoneNumber" is set to that device phoneNumber + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 200 + And the response contains sessions with different protocol types + And each session contains appropriate protocol-specific properties + + @session_insights_retrieveSessions_08_multiple_device_identifiers + Scenario: Retrieve sessions with device having multiple identifiers + Given the header "Authorization" is set to a valid 2-legged access token + And the request body property "$.device.phoneNumber" is set to a valid phoneNumber + And the request body property "$.device.ipv4Address" is set to a valid IPv4 address + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 200 + And the response device objects contain only one identifier property + + # Errors 400 + + @session_insights_retrieveSessions_400.1_invalid_phone_number_format + Scenario: Invalid phoneNumber format + Given the header "Authorization" is set to a valid 2-legged access token + And the request body property "$.device.phoneNumber" is set to "invalid-phone" + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_retrieveSessions_400.2_invalid_ipv4_address_format + Scenario: Invalid IPv4 address format + Given the header "Authorization" is set to a valid 2-legged access token + And the request body property "$.device.ipv4Address.publicAddress" is set to "999.999.999.999" + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_retrieveSessions_400.3_invalid_ipv6_address_format + Scenario: Invalid IPv6 address format + Given the header "Authorization" is set to a valid 2-legged access token + And the request body property "$.device.ipv6Address" is set to "invalid-ipv6" + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_retrieveSessions_400.4_device_no_identifiers + Scenario: Device object with no identifiers + Given the header "Authorization" is set to a valid 2-legged access token + And the request body property "$.device" is set to an empty object + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_retrieveSessions_400.5_invalid_content_type + Scenario: Invalid Content-Type header + Given the header "Authorization" is set to a valid 2-legged access token + And the header "Content-Type" is set to "text/plain" + And a valid device identifier in the request body + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_retrieveSessions_400.6_malformed_json + Scenario: Malformed JSON in request body + Given the header "Authorization" is set to a valid 2-legged access token + And the request body is set to malformed JSON + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_retrieveSessions_401.1_no_authorization_header + Scenario: Error response for no header "Authorization" + Given the header "Authorization" is not sent + And a valid device identifier in the request body + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + @session_insights_retrieveSessions_401.2_expired_access_token + Scenario: Error response for expired access token + Given the header "Authorization" is set to an expired access token + And a valid device identifier in the request body + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + @session_insights_retrieveSessions_401.3_invalid_access_token + Scenario: Error response for invalid access token + Given the header "Authorization" is set to an invalid access token + And a valid device identifier in the request body + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + # Generic 403 errors + + @session_insights_retrieveSessions_403.1_missing_access_token_scope + Scenario: Missing access token scope + Given the header "Authorization" is set to an access token that does not include the required scope + And a valid device identifier in the request body + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 403 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_retrieveSessions_403.2_device_access_denied + Scenario: Device not accessible by the API client given in the access token + Given the header "Authorization" is set to a valid 3-legged access token for user A + And the request body property "$.device.phoneNumber" is set to a device belonging to user B + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 403 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + # Errors 404 + + @session_insights_retrieveSessions_404.1_device_not_found + Scenario: Device not found + Given the header "Authorization" is set to a valid 2-legged access token + And the request body property "$.device.phoneNumber" is set to a valid but non-existent phoneNumber + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 404 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + # Errors 422 + + @session_insights_retrieveSessions_422.1_2legged_token_missing_device + Scenario: 2-legged token used without device parameter + Given the header "Authorization" is set to a valid 2-legged access token + And the request body does not include "$.device" property + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 422 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_retrieveSessions_422.2_3legged_token_with_device + Scenario: 3-legged token used with device parameter + Given the header "Authorization" is set to a valid 3-legged access token + And the request body property "$.device.phoneNumber" is set to a valid phoneNumber + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 422 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + # Errors 429 + + @session_insights_retrieveSessions_429.1_rate_limit_exceeded + Scenario: Rate limit exceeded + Given the header "Authorization" is set to a valid access token + And the rate limit for this endpoint has been exceeded + And a valid device identifier in the request body + When the request "retrieveSessionsByDevice" is sent + Then the response status code is 429 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 429 + And the response property "$.code" is "TOO_MANY_REQUESTS" + And the response property "$.message" contains a user friendly text diff --git a/code/Test_definitions/session-insights-sendMetrics.feature b/code/Test_definitions/session-insights-sendMetrics.feature new file mode 100644 index 0000000..1b23c9c --- /dev/null +++ b/code/Test_definitions/session-insights-sendMetrics.feature @@ -0,0 +1,463 @@ +Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation sendSessionMetrics + # Input to be provided by the implementation to the tester + # + # Implementation indications: + # * apiRoot: API root of the server URL + # + # Testing assets: + # * The sessionId of an existing active HTTP session + # * The sessionId of an existing active MQTT3 session + # * The sessionId of an existing active MQTT5 session + # * The sessionId of an expired session + # * The sessionId of a deleted session + # * Valid metrics payload with all required fields (latency, jitter, packetLoss, bitrate, resolution) + # * Access tokens with appropriate scopes for sending metrics + # + # References to OAS spec schemas refer to schemas specified in session-insights.yaml + + Background: Common sendSessionMetrics setup + Given an environment at "apiRoot" + And the resource "/session-insights/vwip/sessions/{sessionId}/metrics" + 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 path parameter "sessionId" is set by default to an existing active session sessionId + + # Success scenarios + + @session_insights_sendMetrics_01_valid_metrics_http_session + Scenario: Send valid metrics to HTTP session + Given an existing active HTTP session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to 15.5 + And the request body property "$.jitter" is set to 2.1 + And the request body property "$.packetLoss" is set to 0.01 + And the request body property "$.bitrate" is set to 1000000 + And the request body property "$.resolution" is set to "1920x1080" + When the request "sendSessionMetrics" is sent + Then the response status code is 204 + And the response body is empty + And the response header "x-correlator" has same value as the request header "x-correlator" + + @session_insights_sendMetrics_02_valid_metrics_mqtt3_session + Scenario: Send valid metrics to MQTT3 session + Given an existing active MQTT3 session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 204 + And the response body is empty + And the response header "x-correlator" has same value as the request header "x-correlator" + + @session_insights_sendMetrics_03_valid_metrics_mqtt5_session + Scenario: Send valid metrics to MQTT5 session + Given an existing active MQTT5 session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 204 + And the response body is empty + + @session_insights_sendMetrics_04_minimum_required_fields + Scenario: Send metrics with minimum required fields + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to 10.0 + And the request body property "$.jitter" is set to 1.5 + And the request body property "$.packetLoss" is set to 0.001 + And the request body property "$.bitrate" is set to 500000 + And the request body property "$.resolution" is set to "1280x720" + When the request "sendSessionMetrics" is sent + Then the response status code is 204 + + @session_insights_sendMetrics_05_zero_values + Scenario: Send metrics with zero values + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to 0.0 + And the request body property "$.jitter" is set to 0.0 + And the request body property "$.packetLoss" is set to 0.0 + And the request body property "$.bitrate" is set to 0 + And the request body property "$.resolution" is set to "640x480" + When the request "sendSessionMetrics" is sent + Then the response status code is 204 + + @session_insights_sendMetrics_06_large_values + Scenario: Send metrics with large valid values + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to 999.9 + And the request body property "$.jitter" is set to 100.0 + And the request body property "$.packetLoss" is set to 0.1 + And the request body property "$.bitrate" is set to 1000000000 + And the request body property "$.resolution" is set to "4096x2160" + When the request "sendSessionMetrics" is sent + Then the response status code is 204 + + @session_insights_sendMetrics_07_multiple_submissions + Scenario: Send metrics multiple times to same session + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 204 + When the request "sendSessionMetrics" is sent again with different metric values + Then the response status code is 204 + + # Errors 400 + + @session_insights_sendMetrics_400.1_invalid_session_id_format + Scenario: Invalid sessionId format + Given the path parameter "sessionId" is set to "not-a-uuid" + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.2_malformed_uuid_session_id + Scenario: Malformed UUID sessionId + Given the path parameter "sessionId" is set to "123e4567-e89b-12d3-a456-42661417400" + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.3_missing_latency_field + Scenario: Missing required latency field + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.jitter" is set to 2.1 + And the request body property "$.packetLoss" is set to 0.01 + And the request body property "$.bitrate" is set to 1000000 + And the request body property "$.resolution" is set to "1920x1080" + But the request body property "$.latency" is not included + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.4_missing_jitter_field + Scenario: Missing required jitter field + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to 15.5 + And the request body property "$.packetLoss" is set to 0.01 + And the request body property "$.bitrate" is set to 1000000 + And the request body property "$.resolution" is set to "1920x1080" + But the request body property "$.jitter" is not included + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.5_missing_packet_loss_field + Scenario: Missing required packetLoss field + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to 15.5 + And the request body property "$.jitter" is set to 2.1 + And the request body property "$.bitrate" is set to 1000000 + And the request body property "$.resolution" is set to "1920x1080" + But the request body property "$.packetLoss" is not included + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.6_missing_bitrate_field + Scenario: Missing required bitrate field + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to 15.5 + And the request body property "$.jitter" is set to 2.1 + And the request body property "$.packetLoss" is set to 0.01 + And the request body property "$.resolution" is set to "1920x1080" + But the request body property "$.bitrate" is not included + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.7_missing_resolution_field + Scenario: Missing required resolution field + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to 15.5 + And the request body property "$.jitter" is set to 2.1 + And the request body property "$.packetLoss" is set to 0.01 + And the request body property "$.bitrate" is set to 1000000 + But the request body property "$.resolution" is not included + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.8_invalid_latency_type + Scenario: Invalid latency data type + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to "invalid" + And the request body property "$.jitter" is set to 2.1 + And the request body property "$.packetLoss" is set to 0.01 + And the request body property "$.bitrate" is set to 1000000 + And the request body property "$.resolution" is set to "1920x1080" + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.9_negative_latency_value + Scenario: Negative latency value + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to -5.0 + And the request body property "$.jitter" is set to 2.1 + And the request body property "$.packetLoss" is set to 0.01 + And the request body property "$.bitrate" is set to 1000000 + And the request body property "$.resolution" is set to "1920x1080" + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.10_packet_loss_greater_than_one + Scenario: packetLoss value greater than 1 + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to 15.5 + And the request body property "$.jitter" is set to 2.1 + And the request body property "$.packetLoss" is set to 1.5 + And the request body property "$.bitrate" is set to 1000000 + And the request body property "$.resolution" is set to "1920x1080" + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.11_invalid_resolution_type + Scenario: Invalid resolution data type + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body property "$.latency" is set to 15.5 + And the request body property "$.jitter" is set to 2.1 + And the request body property "$.packetLoss" is set to 0.01 + And the request body property "$.bitrate" is set to 1000000 + And the request body property "$.resolution" is set to 1080 + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.12_invalid_content_type + Scenario: Invalid Content-Type header + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the header "Content-Type" is set to "text/plain" + And a valid metrics payload + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.13_malformed_json + Scenario: Malformed JSON in request body + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body is set to malformed JSON + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_400.14_empty_request_body + Scenario: Empty request body + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body is empty + When the request "sendSessionMetrics" is sent + Then the response status code is 400 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_401.1_no_authorization_header + Scenario: Error response for no header "Authorization" + Given the header "Authorization" is not sent + And an existing active session sessionId + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + @session_insights_sendMetrics_401.2_expired_access_token + Scenario: Error response for expired access token + Given the header "Authorization" is set to an expired access token + And an existing active session sessionId + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + @session_insights_sendMetrics_401.3_invalid_access_token + Scenario: Error response for invalid access token + Given the header "Authorization" is set to an invalid access token + And an existing active session sessionId + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 401 + And the response header "x-correlator" has same value as the request header "x-correlator" + 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 + + # Generic 403 errors + + @session_insights_sendMetrics_403.1_missing_access_token_scope + Scenario: Missing access token scope + Given the header "Authorization" is set to an access token that does not include the required scope + And an existing active session sessionId + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 403 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + @session_insights_sendMetrics_403.2_session_token_mismatch + Scenario: Session not accessible by the API client given in the access token + Given the header "Authorization" is set to a valid access token emitted to a client which did not create the session + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 403 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + # Errors 404 + + @session_insights_sendMetrics_404.1_session_not_found + Scenario: sessionId of a non-existing session + Given the path parameter "sessionId" is set to a random UUID + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 404 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + 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 + + # Errors 410 + + @session_insights_sendMetrics_410.1_expired_session + Scenario: Send metrics to expired session + Given the path parameter "sessionId" is set to the value of an expired session + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 410 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 410 + And the response property "$.code" is "GONE" + And the response property "$.message" contains a user friendly text + + @session_insights_sendMetrics_410.2_deleted_session + Scenario: Send metrics to deleted session + Given the path parameter "sessionId" is set to the value of a previously deleted session + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 410 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 410 + And the response property "$.code" is "GONE" + And the response property "$.message" contains a user friendly text + + # Errors 422 + + @session_insights_sendMetrics_422.1_payload_too_large + Scenario: Metrics payload exceeds size limits + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the request body contains a metrics payload that exceeds maximum allowed size + When the request "sendSessionMetrics" is sent + Then the response status code is 422 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 422 + And the response property "$.code" is "UNPROCESSABLE_ENTITY" + And the response property "$.message" contains a user friendly text + + # Errors 429 + + @session_insights_sendMetrics_429.1_too_many_requests + Scenario: Send metrics at too high frequency + Given an existing active session created by operation createSession + And the path parameter "sessionId" is set to the value for that session + And the rate limit for sending metrics has been exceeded + And the request body complies with the OAS schema at "/components/schemas/MetricsPayload" + When the request "sendSessionMetrics" is sent + Then the response status code is 429 + And the response header "x-correlator" has same value as the request header "x-correlator" + And the response header "Content-Type" is "application/json" + And the response property "$.status" is 429 + And the response property "$.code" is "TOO_MANY_REQUESTS" + And the response property "$.message" contains a user friendly text