From ae6a9ac568bbc9fde13794093958a55a7ee67e03 Mon Sep 17 00:00:00 2001 From: Ben Hepworth Date: Tue, 1 Jul 2025 16:05:28 -0600 Subject: [PATCH 01/10] Add test definitions --- code/Test_definitions/README.md | 275 +++++++++++++- .../session-insights-createSession.feature | 269 ++++++++++++++ .../session-insights-deleteSession.feature | 216 +++++++++++ .../session-insights-getSession.feature | 211 +++++++++++ .../session-insights-retrieveSessions.feature | 271 ++++++++++++++ .../session-insights-sendMetrics.feature | 342 ++++++++++++++++++ 6 files changed, 1583 insertions(+), 1 deletion(-) create mode 100644 code/Test_definitions/session-insights-createSession.feature create mode 100644 code/Test_definitions/session-insights-deleteSession.feature create mode 100644 code/Test_definitions/session-insights-getSession.feature create mode 100644 code/Test_definitions/session-insights-retrieveSessions.feature create mode 100644 code/Test_definitions/session-insights-sendMetrics.feature diff --git a/code/Test_definitions/README.md b/code/Test_definitions/README.md index 27a1f06..1155d14 100644 --- a/code/Test_definitions/README.md +++ b/code/Test_definitions/README.md @@ -1 +1,274 @@ -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 + +### 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 + +#### 🌧️ 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 + +### Key Testing Areas + +1. **API Compliance** + - Request/response schema validation + - HTTP status code verification + - Header validation (x-correlator, content-type) + - Error response format compliance + +2. **Security & Authentication** + - CAMARA-compliant token handling + - Device identifier validation + - Scope and permission enforcement + - 2-legged vs 3-legged token behavior + +3. **Session Lifecycle Management** + - Session creation with various configurations + - Session state transitions + - Proper resource cleanup + - Expiration handling + +4. **Multi-Protocol Support** + - HTTP webhook configurations + - MQTT broker settings (MQTT3/MQTT5) + - Protocol-specific features and limitations + +5. **Metrics and Quality Assessment** + - KPI validation (latency, jitter, packet loss, bitrate, resolution) + - Data type and range validation + - Streaming frequency limits + +## 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: + +```bash +# API Configuration +API_BASE_URL=https://api.example.com/session-insights/v0 +API_TIMEOUT=30000 + +# Authentication +TWO_LEGGED_ACCESS_TOKEN=your_2legged_token_here +THREE_LEGGED_ACCESS_TOKEN=your_3legged_token_here +INVALID_ACCESS_TOKEN=invalid_token_for_testing + +# Test Data +VALID_PHONE_NUMBER=+1234567890 +VALID_IPV4_ADDRESS=192.168.1.100 +VALID_IPV4_PORT=8080 +VALID_IPV6_ADDRESS=2001:db8::1 +VALID_NETWORK_ACCESS_ID=user@domain.com +VALID_APPLICATION_PROFILE_ID=550e8400-e29b-41d4-a716-446655440000 + +# Application Server +APP_SERVER_DOMAIN=app.example.com +APP_SERVER_IPV4=203.0.113.1 +APP_SERVER_PORT=443 + +# Protocol Settings +HTTP_WEBHOOK_URL=https://webhook.example.com/notifications +MQTT_BROKER_URI=mqtt://broker.example.com:1883 +MQTT_USERNAME=testuser +MQTT_PASSWORD=testpass + +# Test Configuration +X_CORRELATOR_VALID=test-correlator-123 +X_CORRELATOR_INVALID=invalid@correlator! +``` + +## 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 +- Response schemas match API specification +- Error scenarios return appropriate error codes and messages +- x-correlator headers are properly handled + +**❌ Common Failure Scenarios:** + +- Schema validation failures (check API implementation) +- Authentication errors (verify tokens and scopes) +- Network connectivity issues (check endpoints and firewall rules) +- Missing environment variables (verify configuration) + +### 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: + +1. **Follow Gherkin Conventions**: Use clear Given/When/Then structure +2. **Maintain CAMARA Compliance**: Ensure tests align with CAMARA testing guidelines +3. **Cover Edge Cases**: Include boundary testing and error conditions +4. **Update Documentation**: Keep this README current with any changes +5. **Test Locally**: Validate new scenarios before submitting + +### Test Naming Conventions + +- Use descriptive scenario names that clearly indicate the test purpose +- Follow the pattern: `[Action] [Entity] [Condition/Context]` +- Examples: + - `Create HTTP session with valid parameters` + - `Retrieve session with invalid sessionId format` + - `Send metrics to expired session` + +## API Versioning + +These tests are designed for **Session Insights API v0.wip**. When the API version changes: + +1. Update the version references in feature file headers +2. Review and update test scenarios for any breaking changes +3. Validate all existing tests against the new API version +4. Add new test cases for any new functionality + +## 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 Guide](https://github.com/camaraproject/Commonalities/blob/main/documentation/CAMARA-API-Design-Guide.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 or open issue on GitHub +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..5a3881e --- /dev/null +++ b/code/Test_definitions/session-insights-createSession.feature @@ -0,0 +1,269 @@ +Feature: CAMARA Session Insights API, v0.wip - Operation createSession + As a developer integrating with CAMARA Session Insights API + I want to create a sessions for real-time quality assessment + So that I can monitor and optimize my application's network performance + + Background: + Given the Session Insights API is available + And I have a valid access token with appropriate scopes + And I have a valid Application Profile ID + + # Sunny day scenarios - HTTP protocol + Scenario: Create HTTP session with valid parameters + Given I have a valid device with phoneNumber + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + When I send POST request to "/sessions" with valid HTTP session data + Then I receive a 201 response + And the response contains "id" property with UUID format + And the response contains "protocol" property with value "HTTP" + And the response contains "sink" property with webhook URL + And the response contains "sinkCredential" property for HTTP callbacks + And the response contains "startTime" property with valid date-time + And the response contains "expiresAt" property with valid date-time + And the response headers contain "x-correlator" + + Scenario: Create MQTT3 session with valid parameters + Given I have a valid device with phoneNumber + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify MQTT3 protocol + When I send POST request to "/sessions" with valid MQTT3 session data + Then I receive a 201 response + And the response contains "id" property with UUID format + And the response contains "protocol" property with value "MQTT3" + And the response contains "protocolSettings" with MQTT broker configuration + And the response contains "sinkCredential" property for MQTT access + And the response headers contain "x-correlator" + + Scenario: Create MQTT5 session with valid parameters + Given I have a valid device with phoneNumber + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify MQTT5 protocol + When I send POST request to "/sessions" with valid MQTT5 session data + Then I receive a 201 response + And the response contains "id" property with UUID format + And the response contains "protocol" property with value "MQTT5" + And the response contains "protocolSettings" with MQTT broker configuration + And the response headers contain "x-correlator" + + Scenario: Create session with optional applicationSessionId + Given I have a valid device with phoneNumber + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + And I provide an applicationSessionId "meet-12345" + When I send POST request to "/sessions" with session data including applicationSessionId + Then I receive a 201 response + And the response contains "applicationSessionId" property with value "meet-12345" + + Scenario: Create session with IPv4 device identifier + Given I have a valid device with IPv4 address and port + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + When I send POST request to "/sessions" with valid session data + Then I receive a 201 response + And the response contains device information with IPv4 address + + Scenario: Create session with IPv6 device identifier + Given I have a valid device with IPv6 address + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + When I send POST request to "/sessions" with valid session data + Then I receive a 201 response + And the response contains device information with IPv6 address + + Scenario: Create session with network access identifier + Given I have a valid device with networkAccessIdentifier + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + When I send POST request to "/sessions" with valid session data + Then I receive a 201 response + And the response contains device information with networkAccessIdentifier + + # Rainy day scenarios - Input validation + + Scenario: Create session without required applicationProfileId + Given I have a valid device with phoneNumber + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + But I do not provide applicationProfileId + When I send POST request to "/sessions" with incomplete session data + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + And the response headers contain "x-correlator" + + Scenario: Create session without required device + Given I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + But I do not provide device information + When I send POST request to "/sessions" with incomplete session data + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Create session without required applicationServer + Given I have a valid device with phoneNumber + And I have a valid Application Profile ID + And I specify HTTP protocol with webhook URL + But I do not provide applicationServer information + When I send POST request to "/sessions" with incomplete session data + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Create session without required protocol + Given I have a valid device with phoneNumber + And I have a valid Application Profile ID + And I have a valid application server configuration + But I do not specify protocol + When I send POST request to "/sessions" with incomplete session data + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Create session with invalid protocol value + Given I have a valid device with phoneNumber + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify an invalid protocol "INVALID_PROTOCOL" + When I send POST request to "/sessions" with invalid session data + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Create HTTP session without required sink + Given I have a valid device with phoneNumber + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol + But I do not provide sink webhook URL + When I send POST request to "/sessions" with incomplete HTTP session data + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Create session with invalid applicationProfileId format + Given I have a valid device with phoneNumber + And I have an invalid Application Profile ID "not-a-uuid" + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + When I send POST request to "/sessions" with invalid session data + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Create session with invalid device phoneNumber format + Given I have a device with invalid phoneNumber "invalid-phone" + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + When I send POST request to "/sessions" with invalid session data + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Create session with device having no identifiers + Given I have a device object with no identifiers + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + When I send POST request to "/sessions" with invalid session data + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Error scenarios - Authorization and permissions + + Scenario: Create session without authentication + Given I do not have an access token + And I have valid session data + When I send POST request to "/sessions" without authentication + Then I receive a 401 response + And the response contains error code "UNAUTHENTICATED" + + Scenario: Create session with invalid access token + Given I have an invalid access token + And I have valid session data + When I send POST request to "/sessions" with invalid authentication + Then I receive a 401 response + And the response contains error code "UNAUTHENTICATED" + + Scenario: Create session without sufficient permissions + Given I have an access token without required scopes + And I have valid session data + When I send POST request to "/sessions" with insufficient permissions + Then I receive a 403 response + And the response contains error code indicating insufficient permissions + + # Error scenarios - Business logic + + Scenario: Create session with non-existent applicationProfileId + Given I have a valid device with phoneNumber + And I have a non-existent Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + When I send POST request to "/sessions" with non-existent profile + Then I receive a 404 response + And the response contains error code indicating resource not found + + Scenario: Create session that conflicts with existing session + Given I have a valid device with phoneNumber + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + And a session already exists for this device and application profile + When I send POST request to "/sessions" with conflicting session data + Then I receive a 409 response + And the response contains error code "CONFLICT" + + # Device identifier validation scenarios + + Scenario: Create session with device using 3-legged token and device parameter + Given I have a 3-legged access token + And I provide device information in the request + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + When I send POST request to "/sessions" with device parameter + Then I receive a 422 response + And the response contains error code "UNNECESSARY_IDENTIFIER" + + Scenario: Create session with 2-legged token but no device parameter + Given I have a 2-legged access token + And I do not provide device information in the request + And I have a valid Application Profile ID + And I have a valid application server configuration + And I specify HTTP protocol with webhook URL + When I send POST request to "/sessions" without device parameter + Then I receive a 422 response + And the response contains error code "MISSING_IDENTIFIER" + + # Content-Type and format validation + + Scenario: Create session with invalid Content-Type + Given I have valid session data + And I set Content-Type to "text/plain" + When I send POST request to "/sessions" with invalid content type + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Create session with malformed JSON + Given I have malformed JSON in the request body + When I send POST request to "/sessions" with malformed JSON + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # x-correlator header validation + + Scenario: Create session with valid x-correlator header + Given I have valid session data + And I provide a valid x-correlator header + When I send POST request to "/sessions" with correlator + Then I receive a 201 response + And the response headers contain the same x-correlator value + + Scenario: Create session with invalid x-correlator header format + Given I have valid session data + And I provide an invalid x-correlator header with special characters + When I send POST request to "/sessions" with invalid correlator + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" diff --git a/code/Test_definitions/session-insights-deleteSession.feature b/code/Test_definitions/session-insights-deleteSession.feature new file mode 100644 index 0000000..8a9fbfd --- /dev/null +++ b/code/Test_definitions/session-insights-deleteSession.feature @@ -0,0 +1,216 @@ +Feature: CAMARA Session Insights API, v0.wip - Operation deleteSession + As a developer integrating with CAMARA Session Insights API + I want to delete a Session Insights sessions + So that I can clean up resources when monitoring is no longer needed + + Background: + Given the Session Insights API is available + And I have a valid access token with appropriate scopes + + # Sunny day scenarios + + Scenario: Delete existing HTTP session + Given I have created an HTTP session with sessionId + When I send DELETE request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 204 response + And the response body is empty + And the response headers contain "x-correlator" + + Scenario: Delete existing MQTT3 session + Given I have created an MQTT3 session with sessionId + When I send DELETE request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 204 response + And the response body is empty + And the response headers contain "x-correlator" + + Scenario: Delete existing MQTT5 session + Given I have created an MQTT5 session with sessionId + When I send DELETE request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 204 response + And the response body is empty + And the response headers contain "x-correlator" + + Scenario: Delete session with applicationSessionId + Given I have created a session with applicationSessionId "meet-12345" + When I send DELETE request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 204 response + And the response body is empty + + Scenario: Verify session is no longer accessible after deletion + Given I have created a session with sessionId + And I have successfully deleted the session + When I send GET request to "/sessions/{sessionId}" to verify deletion + Then I receive a 410 response + And the response contains error code "GONE" + + Scenario: Verify notifications stop after session deletion + Given I have created a session with notifications enabled + And I have been receiving notifications for the session + When I send DELETE request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 204 response + And no further notifications are sent for this session + + Scenario: Delete session created with different device identifiers + Given I have created a session with device phoneNumber + When I send DELETE request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 204 response + And the session is successfully deleted + + # Rainy day scenarios - Path parameter validation + + Scenario: Delete session with invalid sessionId format + Given I have an invalid sessionId "not-a-uuid" + When I send DELETE request to "/sessions/{sessionId}" with invalid sessionId + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + And the response headers contain "x-correlator" + + Scenario: Delete session with empty sessionId + Given I have an empty sessionId + When I send DELETE request to "/sessions/{sessionId}" with empty sessionId + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Delete session with malformed UUID sessionId + Given I have a malformed UUID sessionId "123e4567-e89b-12d3-a456-42661417400" + When I send DELETE request to "/sessions/{sessionId}" with malformed sessionId + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Error scenarios - Resource not found + + Scenario: Delete non-existent session + Given I have a valid but non-existent sessionId + When I send DELETE request to "/sessions/{sessionId}" with non-existent sessionId + Then I receive a 404 response + And the response contains error code indicating resource not found + And the response headers contain "x-correlator" + + # Error scenarios - Authorization and permissions + + Scenario: Delete session without authentication + Given I do not have an access token + And I have a valid sessionId + When I send DELETE request to "/sessions/{sessionId}" without authentication + Then I receive a 401 response + And the response contains error code "UNAUTHENTICATED" + + Scenario: Delete session with invalid access token + Given I have an invalid access token + And I have a valid sessionId + When I send DELETE request to "/sessions/{sessionId}" with invalid authentication + Then I receive a 401 response + And the response contains error code "UNAUTHENTICATED" + + Scenario: Delete session without sufficient permissions + Given I have an access token without required scopes + And I have a valid sessionId + When I send DELETE request to "/sessions/{sessionId}" with insufficient permissions + Then I receive a 403 response + And the response contains error code indicating insufficient permissions + + Scenario: Delete session belonging to different user/device + Given I have a valid access token for user A + And I have a sessionId created by user B + When I send DELETE request to "/sessions/{sessionId}" to delete other user's session + Then I receive a 403 response + And the response contains error code indicating insufficient permissions + + # Error scenarios - Session lifecycle + + Scenario: Delete already expired session + Given I have a sessionId for an expired session + When I send DELETE request to "/sessions/{sessionId}" with expired sessionId + Then I receive a 410 response + And the response contains error code "GONE" + And the response headers contain "x-correlator" + + Scenario: Delete already deleted session (idempotency test) + Given I have a sessionId for a session that was already deleted + When I send DELETE request to "/sessions/{sessionId}" with previously deleted sessionId + Then I receive a 410 response + And the response contains error code "GONE" + + # HTTP method validation + + Scenario: Use unsupported HTTP method on sessions endpoint + Given I have a valid sessionId + When I send PATCH request to "/sessions/{sessionId}" + Then I receive a 405 response + And the response contains error indicating method not allowed + + # x-correlator header validation + + Scenario: Delete session with valid x-correlator header + Given I have a valid sessionId + And I provide a valid x-correlator header + When I send DELETE request to "/sessions/{sessionId}" with correlator + Then I receive a 204 response + And the response headers contain the same x-correlator value + + Scenario: Delete session with invalid x-correlator header format + Given I have a valid sessionId + And I provide an invalid x-correlator header with special characters + When I send DELETE request to "/sessions/{sessionId}" with invalid correlator + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Edge cases and integration + + Scenario: Delete session with pending metrics + Given I have created a session with sessionId + And I have sent metrics to the session that are still being processed + When I send DELETE request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 204 response + And all pending metrics processing is stopped + + Scenario: Delete session with active webhook notifications + Given I have created an HTTP session with webhook notifications + And the session is actively sending notifications + When I send DELETE request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 204 response + And no further webhook notifications are sent + + Scenario: Delete session with active MQTT subscriptions + Given I have created an MQTT session with active subscriptions + And the session is actively publishing to MQTT topics + When I send DELETE request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 204 response + And all MQTT subscriptions are terminated + + # Concurrency scenarios + + Scenario: Delete session while sending metrics + Given I have created a session with sessionId + And I am actively sending metrics to the session + When I send DELETE request to "/sessions/{sessionId}" concurrently + Then I receive a 204 response + And subsequent metric submissions to this session fail + + Scenario: Multiple delete requests for same session + Given I have created a session with sessionId + When I send multiple DELETE requests to "/sessions/{sessionId}" simultaneously + Then the first request receives a 204 response + And subsequent requests receive a 410 response + + # Content validation + + Scenario: Delete session with request body (should be ignored) + Given I have created a session with sessionId + And I include a request body in the DELETE request + When I send DELETE request to "/sessions/{sessionId}" with body + Then I receive a 204 response + And the request body is ignored + + # Resource cleanup verification + + Scenario: Verify all session resources are cleaned up after deletion + Given I have created a session with full configuration + And the session has active metrics streaming + And the session has active notifications + When I send DELETE request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 204 response + And all webhook endpoints stop receiving notifications + And all MQTT topics stop receiving messages + And session metrics are no longer accepted + And session cannot be retrieved via GET request diff --git a/code/Test_definitions/session-insights-getSession.feature b/code/Test_definitions/session-insights-getSession.feature new file mode 100644 index 0000000..e9486b6 --- /dev/null +++ b/code/Test_definitions/session-insights-getSession.feature @@ -0,0 +1,211 @@ +Feature: CAMARA Session Insights API, v0.wip - Operation getSession + As a developer integrating with CAMARA Session Insights API + I want to retrieve details of an existing session + So that I can check session status and configuration + + Background: + Given the Session Insights API is available + And I have a valid access token with appropriate scopes + + # Sunny day scenarios + + Scenario: Retrieve existing HTTP session by sessionId + Given I have created an HTTP session with sessionId + When I send GET request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 200 response + And the response contains "id" property with the requested sessionId + And the response contains "protocol" property with value "HTTP" + And the response contains "device" property with device information + And the response contains "applicationServer" property + And the response contains "sink" property with webhook URL + And the response contains "subscribedEventTypes" array + And the response contains "startTime" property with valid date-time + And the response contains "expiresAt" property with valid date-time + And the response headers contain "x-correlator" + + Scenario: Retrieve existing MQTT3 session by sessionId + Given I have created an MQTT3 session with sessionId + When I send GET request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 200 response + And the response contains "id" property with the requested sessionId + And the response contains "protocol" property with value "MQTT3" + And the response contains "protocolSettings" with MQTT configuration + And the response contains "device" property with device information + And the response contains "applicationServer" property + And the response contains "subscribedEventTypes" array + And the response headers contain "x-correlator" + + Scenario: Retrieve existing MQTT5 session by sessionId + Given I have created an MQTT5 session with sessionId + When I send GET request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 200 response + And the response contains "id" property with the requested sessionId + And the response contains "protocol" property with value "MQTT5" + And the response contains "protocolSettings" with MQTT configuration + And the response headers contain "x-correlator" + + Scenario: Retrieve session with applicationSessionId + Given I have created a session with applicationSessionId "meet-12345" + When I send GET request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 200 response + And the response contains "applicationSessionId" property with value "meet-12345" + + Scenario: Retrieve session created with device phoneNumber + Given I have created a session with device phoneNumber + When I send GET request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 200 response + And the response contains "device" property with phoneNumber + And the device object contains exactly one identifier + + Scenario: Retrieve session created with device IPv4 address + Given I have created a session with device IPv4 address + When I send GET request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 200 response + And the response contains "device" property with IPv4 address + And the device object contains exactly one identifier + + Scenario: Retrieve session created with device IPv6 address + Given I have created a session with device IPv6 address + When I send GET request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 200 response + And the response contains "device" property with IPv6 address + And the device object contains exactly one identifier + + Scenario: Retrieve session created with network access identifier + Given I have created a session with device networkAccessIdentifier + When I send GET request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 200 response + And the response contains "device" property with networkAccessIdentifier + And the device object contains exactly one identifier + + # Rainy day scenarios - Path parameter validation + + Scenario: Retrieve session with invalid sessionId format + Given I have an invalid sessionId "not-a-uuid" + When I send GET request to "/sessions/{sessionId}" with invalid sessionId + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + And the response headers contain "x-correlator" + + Scenario: Retrieve session with empty sessionId + Given I have an empty sessionId + When I send GET request to "/sessions/{sessionId}" with empty sessionId + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Retrieve session with malformed UUID sessionId + Given I have a malformed UUID sessionId "123e4567-e89b-12d3-a456-42661417400" + When I send GET request to "/sessions/{sessionId}" with malformed sessionId + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Error scenarios - Resource not found + + Scenario: Retrieve non-existent session + Given I have a valid but non-existent sessionId + When I send GET request to "/sessions/{sessionId}" with non-existent sessionId + Then I receive a 404 response + And the response contains error code indicating resource not found + And the response headers contain "x-correlator" + + # Error scenarios - Authorization and permissions + + Scenario: Retrieve session without authentication + Given I do not have an access token + And I have a valid sessionId + When I send GET request to "/sessions/{sessionId}" without authentication + Then I receive a 401 response + And the response contains error code "UNAUTHENTICATED" + + Scenario: Retrieve session with invalid access token + Given I have an invalid access token + And I have a valid sessionId + When I send GET request to "/sessions/{sessionId}" with invalid authentication + Then I receive a 401 response + And the response contains error code "UNAUTHENTICATED" + + Scenario: Retrieve session without sufficient permissions + Given I have an access token without required scopes + And I have a valid sessionId + When I send GET request to "/sessions/{sessionId}" with insufficient permissions + Then I receive a 403 response + And the response contains error code indicating insufficient permissions + + Scenario: Retrieve session belonging to different user/device + Given I have a valid access token for user A + And I have a sessionId created by user B + When I send GET request to "/sessions/{sessionId}" to access other user's session + Then I receive a 403 response + And the response contains error code indicating insufficient permissions + + # Error scenarios - Session lifecycle + + Scenario: Retrieve expired session + Given I have a sessionId for an expired session + When I send GET request to "/sessions/{sessionId}" with expired sessionId + Then I receive a 410 response + And the response contains error code "GONE" + And the response headers contain "x-correlator" + + Scenario: Retrieve deleted session + Given I have a sessionId for a deleted session + When I send GET request to "/sessions/{sessionId}" with deleted sessionId + Then I receive a 410 response + And the response contains error code "GONE" + + # x-correlator header validation + + Scenario: Retrieve session with valid x-correlator header + Given I have a valid sessionId + And I provide a valid x-correlator header + When I send GET request to "/sessions/{sessionId}" with correlator + Then I receive a 200 response + And the response headers contain the same x-correlator value + + Scenario: Retrieve session with invalid x-correlator header format + Given I have a valid sessionId + And I provide an invalid x-correlator header with special characters + When I send GET request to "/sessions/{sessionId}" with invalid correlator + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Content negotiation + + Scenario: Retrieve session with unsupported Accept header + Given I have a valid sessionId + And I set Accept header to "text/xml" + When I send GET request to "/sessions/{sessionId}" with unsupported Accept + Then I receive a 406 response + And the response contains error indicating unsupported media type + + # Response schema validation + + Scenario: Verify response schema compliance for HTTP session + Given I have created an HTTP session + When I send GET request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 200 response + And the response body complies with Session schema + And all required properties are present + And all property types match the specification + + Scenario: Verify response schema compliance for MQTT session + Given I have created an MQTT session + When I send GET request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 200 response + And the response body complies with Session schema + And the protocolSettings contain required MQTT properties + And all property types match the specification + + # Edge cases + + Scenario: Retrieve session multiple times + Given I have created a session with sessionId + When I send GET request to "/sessions/{sessionId}" multiple times + Then I receive a 200 response each time + And the response data is consistent across requests + + Scenario: Retrieve session near expiration time + Given I have created a session that is near expiration + When I send GET request to "/sessions/{sessionId}" with valid sessionId + Then I receive a 200 response + And the response contains "expiresAt" property showing near expiration diff --git a/code/Test_definitions/session-insights-retrieveSessions.feature b/code/Test_definitions/session-insights-retrieveSessions.feature new file mode 100644 index 0000000..c1d7c2a --- /dev/null +++ b/code/Test_definitions/session-insights-retrieveSessions.feature @@ -0,0 +1,271 @@ +Feature: CAMARA Session Insights API, v0.wip - Operation retrieveSessionsByDevice + As a developer integrating with CAMARA Session Insights API + I want to retrieve all sessions associated with a specific device + So that I can manage and monitor device-specific sessions + + Background: + Given the Session Insights API is available + And I have a valid access token with appropriate scopes + + # Sunny day scenarios + + Scenario: Retrieve sessions for device with phoneNumber using 2-legged token + Given I have a 2-legged access token + And I have created multiple sessions for device with phoneNumber + When I send POST request to "/retrieve-sessions" with device phoneNumber + Then I receive a 200 response + And the response contains an array of sessions + And all sessions in the array belong to the specified device + And each session contains required properties (id, device, applicationServer, protocol, sink, subscribedEventTypes, startTime) + And the response headers contain "x-correlator" + + Scenario: Retrieve sessions for device with IPv4 address using 2-legged token + Given I have a 2-legged access token + And I have created sessions for device with IPv4 address + When I send POST request to "/retrieve-sessions" with device IPv4 address + Then I receive a 200 response + And the response contains an array of sessions + And all sessions belong to the device with specified IPv4 address + + Scenario: Retrieve sessions for device with IPv6 address using 2-legged token + Given I have a 2-legged access token + And I have created sessions for device with IPv6 address + When I send POST request to "/retrieve-sessions" with device IPv6 address + Then I receive a 200 response + And the response contains an array of sessions + And all sessions belong to the device with specified IPv6 address + + Scenario: Retrieve sessions for device with networkAccessIdentifier using 2-legged token + Given I have a 2-legged access token + And I have created sessions for device with networkAccessIdentifier + When I send POST request to "/retrieve-sessions" with device networkAccessIdentifier + Then I receive a 200 response + And the response contains an array of sessions + And all sessions belong to the device with specified networkAccessIdentifier + + Scenario: Retrieve sessions using 3-legged token without device parameter + Given I have a 3-legged access token for a specific device + And I have created sessions for the authenticated device + When I send POST request to "/retrieve-sessions" without device parameter + Then I receive a 200 response + And the response contains an array of sessions + And all sessions belong to the authenticated device + + Scenario: Retrieve empty array when device has no sessions + Given I have a 2-legged access token + And I have a device with phoneNumber that has no sessions + When I send POST request to "/retrieve-sessions" with device phoneNumber + Then I receive a 200 response + And the response contains an empty array + And the response headers contain "x-correlator" + + Scenario: Retrieve sessions including different protocol types + Given I have a 2-legged access token + And I have created HTTP sessions for a device + And I have created MQTT3 sessions for the same device + And I have created MQTT5 sessions for the same device + When I send POST request to "/retrieve-sessions" with device identifier + Then I receive a 200 response + And the response contains sessions with different protocol types + And each session contains appropriate protocol-specific properties + + Scenario: Retrieve sessions including sessions with different states + Given I have a 2-legged access token + And I have active sessions for a device + And I have expired sessions for the same device + When I send POST request to "/retrieve-sessions" with device identifier + Then I receive a 200 response + And the response includes all sessions regardless of state + And each session shows its current state information + + # Rainy day scenarios - Request validation + + Scenario: Retrieve sessions with 2-legged token but no device parameter + Given I have a 2-legged access token + And I do not provide device information in the request + When I send POST request to "/retrieve-sessions" without device parameter + Then I receive a 422 response + And the response contains error code "MISSING_IDENTIFIER" + And the response headers contain "x-correlator" + + Scenario: Retrieve sessions with 3-legged token and device parameter + Given I have a 3-legged access token + And I provide device information in the request + When I send POST request to "/retrieve-sessions" with device parameter + Then I receive a 422 response + And the response contains error code "UNNECESSARY_IDENTIFIER" + And the response headers contain "x-correlator" + + Scenario: Retrieve sessions with invalid device phoneNumber format + Given I have a 2-legged access token + And I provide device with invalid phoneNumber "invalid-phone" + When I send POST request to "/retrieve-sessions" with invalid phoneNumber + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Retrieve sessions with invalid device IPv4 address format + Given I have a 2-legged access token + And I provide device with invalid IPv4 address "999.999.999.999" + When I send POST request to "/retrieve-sessions" with invalid IPv4 address + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Retrieve sessions with invalid device IPv6 address format + Given I have a 2-legged access token + And I provide device with invalid IPv6 address "invalid-ipv6" + When I send POST request to "/retrieve-sessions" with invalid IPv6 address + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Retrieve sessions with device having no identifiers + Given I have a 2-legged access token + And I provide device object with no identifiers + When I send POST request to "/retrieve-sessions" with empty device + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Retrieve sessions with device having multiple identifiers + Given I have a 2-legged access token + And I provide device object with both phoneNumber and IPv4 address + When I send POST request to "/retrieve-sessions" with multiple identifiers + Then I receive a 200 response + And the response contains sessions for the device + And the response device object contains only one identifier + + # Error scenarios - HTTP method and content type + + Scenario: Use GET method instead of POST + Given I have a valid access token + When I send GET request to "/retrieve-sessions" + Then I receive a 405 response + And the response contains error indicating method not allowed + + Scenario: Retrieve sessions with invalid Content-Type + Given I have a 2-legged access token + And I have valid device information + And I set Content-Type to "text/plain" + When I send POST request to "/retrieve-sessions" with invalid content type + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Retrieve sessions with malformed JSON + Given I have a 2-legged access token + And I have malformed JSON in the request body + When I send POST request to "/retrieve-sessions" with malformed JSON + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Error scenarios - Authorization and permissions + + Scenario: Retrieve sessions without authentication + Given I do not have an access token + And I have valid device information + When I send POST request to "/retrieve-sessions" without authentication + Then I receive a 401 response + And the response contains error code "UNAUTHENTICATED" + + Scenario: Retrieve sessions with invalid access token + Given I have an invalid access token + And I have valid device information + When I send POST request to "/retrieve-sessions" with invalid authentication + Then I receive a 401 response + And the response contains error code "UNAUTHENTICATED" + + Scenario: Retrieve sessions without sufficient permissions + Given I have an access token without required scopes + And I have valid device information + When I send POST request to "/retrieve-sessions" with insufficient permissions + Then I receive a 403 response + And the response contains error code indicating insufficient permissions + + Scenario: Retrieve sessions for device not belonging to authenticated user + Given I have a 3-legged access token for user A + And I have device information for user B + When I send POST request to "/retrieve-sessions" for other user's device + Then I receive a 403 response + And the response contains error code indicating insufficient permissions + + # Error scenarios - Device not found + + Scenario: Retrieve sessions for non-existent device + Given I have a 2-legged access token + And I have a valid but non-existent device phoneNumber + When I send POST request to "/retrieve-sessions" with non-existent device + Then I receive a 404 response + And the response contains error code indicating device not found + And the response headers contain "x-correlator" + + # Rate limiting scenarios + + Scenario: Retrieve sessions with rate limiting exceeded + Given I have a valid access token + And I have exceeded the rate limit for this endpoint + When I send POST request to "/retrieve-sessions" exceeding rate limit + Then I receive a 429 response + And the response contains error code "TOO_MANY_REQUESTS" or "QUOTA_EXCEEDED" + And the response headers contain "x-correlator" + + # x-correlator header validation + + Scenario: Retrieve sessions with valid x-correlator header + Given I have a 2-legged access token + And I have valid device information + And I provide a valid x-correlator header + When I send POST request to "/retrieve-sessions" with correlator + Then I receive a 200 response + And the response headers contain the same x-correlator value + + Scenario: Retrieve sessions with invalid x-correlator header format + Given I have a 2-legged access token + And I have valid device information + And I provide an invalid x-correlator header with special characters + When I send POST request to "/retrieve-sessions" with invalid correlator + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Response schema validation + + Scenario: Verify response schema compliance for session array + Given I have a 2-legged access token + And I have created sessions for a device + When I send POST request to "/retrieve-sessions" with device identifier + Then I receive a 200 response + And the response body complies with RetrieveSessionsOutput schema + And the response is an array of Session objects + And each session object contains all required properties + And all property types match the specification + + # Edge cases and filtering + + Scenario: Retrieve large number of sessions for device + Given I have a 2-legged access token + And I have created many sessions (50+) for a device + When I send POST request to "/retrieve-sessions" with device identifier + Then I receive a 200 response + And the response contains all sessions for the device + And the response time is reasonable + + Scenario: Retrieve sessions with various applicationSessionIds + Given I have a 2-legged access token + And I have created sessions with different applicationSessionIds for a device + When I send POST request to "/retrieve-sessions" with device identifier + Then I receive a 200 response + And each session shows its respective applicationSessionId + + Scenario: Retrieve sessions created at different times + Given I have a 2-legged access token + And I have created sessions at different times for a device + When I send POST request to "/retrieve-sessions" with device identifier + Then I receive a 200 response + And sessions are returned with their respective creation timestamps + And sessions may be ordered by creation time + + # Content negotiation + + Scenario: Retrieve sessions with unsupported Accept header + Given I have a 2-legged access token + And I have valid device information + And I set Accept header to "text/xml" + When I send POST request to "/retrieve-sessions" with unsupported Accept + Then I receive a 406 response + And the response contains error indicating unsupported media type diff --git a/code/Test_definitions/session-insights-sendMetrics.feature b/code/Test_definitions/session-insights-sendMetrics.feature new file mode 100644 index 0000000..96da351 --- /dev/null +++ b/code/Test_definitions/session-insights-sendMetrics.feature @@ -0,0 +1,342 @@ +Feature: CAMARA Session Insights API, v0.wip - Operation sendSessionMetrics + As a developer integrating with CAMARA Session Insights API + I want to send application-level KPIs to monitoring sessions + So that the network operator can evaluate session quality and provide insights + + Background: + Given the Session Insights API is available + And I have a valid access token with appropriate scopes + And I have created a session with valid sessionId + + # Sunny day scenarios + + Scenario: Send valid metrics to HTTP session + Given I have an active HTTP session with sessionId + And I have valid metrics payload with all required fields + When I send POST request to "/sessions/{sessionId}/metrics" with valid metrics + Then I receive a 204 response + And the response body is empty + And the response headers contain "x-correlator" + + Scenario: Send valid metrics to MQTT3 session + Given I have an active MQTT3 session with sessionId + And I have valid metrics payload with all required fields + When I send POST request to "/sessions/{sessionId}/metrics" with valid metrics + Then I receive a 204 response + And the response body is empty + And the response headers contain "x-correlator" + + Scenario: Send valid metrics to MQTT5 session + Given I have an active MQTT5 session with sessionId + And I have valid metrics payload with all required fields + When I send POST request to "/sessions/{sessionId}/metrics" with valid metrics + Then I receive a 204 response + And the response body is empty + + Scenario: Send metrics with minimum required fields + Given I have an active session with sessionId + And I have metrics payload with latency, jitter, packetLoss, bitrate, and resolution + When I send POST request to "/sessions/{sessionId}/metrics" with minimum metrics + Then I receive a 204 response + + Scenario: Send metrics with all valid field types + Given I have an active session with sessionId + And I have metrics with latency as float (15.5) + And I have metrics with jitter as float (2.1) + And I have metrics with packetLoss as number (0.01) + And I have metrics with bitrate as number (1000000) + And I have metrics with resolution as string ("1920x1080") + When I send POST request to "/sessions/{sessionId}/metrics" with typed metrics + Then I receive a 204 response + + Scenario: Send metrics multiple times to same session + Given I have an active session with sessionId + And I have valid metrics payload + When I send POST request to "/sessions/{sessionId}/metrics" multiple times + Then I receive a 204 response each time + And each metrics submission is processed independently + + Scenario: Send different metric values over time + Given I have an active session with sessionId + When I send metrics with latency 10.5 at time T1 + And I send metrics with latency 15.2 at time T2 + And I send metrics with latency 8.7 at time T3 + Then I receive a 204 response for each submission + And all metric values are processed + + # Rainy day scenarios - Path parameter validation + + Scenario: Send metrics with invalid sessionId format + Given I have an invalid sessionId "not-a-uuid" + And I have valid metrics payload + When I send POST request to "/sessions/{sessionId}/metrics" with invalid sessionId + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + And the response headers contain "x-correlator" + + Scenario: Send metrics with empty sessionId + Given I have an empty sessionId + And I have valid metrics payload + When I send POST request to "/sessions/{sessionId}/metrics" with empty sessionId + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with malformed UUID sessionId + Given I have a malformed UUID sessionId "123e4567-e89b-12d3-a456-42661417400" + And I have valid metrics payload + When I send POST request to "/sessions/{sessionId}/metrics" with malformed sessionId + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Error scenarios - Missing required fields + + Scenario: Send metrics without required latency field + Given I have an active session with sessionId + And I have metrics payload without latency field + When I send POST request to "/sessions/{sessionId}/metrics" with incomplete metrics + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics without required jitter field + Given I have an active session with sessionId + And I have metrics payload without jitter field + When I send POST request to "/sessions/{sessionId}/metrics" with incomplete metrics + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics without required packetLoss field + Given I have an active session with sessionId + And I have metrics payload without packetLoss field + When I send POST request to "/sessions/{sessionId}/metrics" with incomplete metrics + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics without required bitrate field + Given I have an active session with sessionId + And I have metrics payload without bitrate field + When I send POST request to "/sessions/{sessionId}/metrics" with incomplete metrics + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics without required resolution field + Given I have an active session with sessionId + And I have metrics payload without resolution field + When I send POST request to "/sessions/{sessionId}/metrics" with incomplete metrics + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Error scenarios - Invalid field types and values + + Scenario: Send metrics with invalid latency type + Given I have an active session with sessionId + And I have metrics with latency as string "invalid" + When I send POST request to "/sessions/{sessionId}/metrics" with invalid latency + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with negative latency value + Given I have an active session with sessionId + And I have metrics with latency as negative number (-5.0) + When I send POST request to "/sessions/{sessionId}/metrics" with negative latency + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with invalid jitter type + Given I have an active session with sessionId + And I have metrics with jitter as boolean true + When I send POST request to "/sessions/{sessionId}/metrics" with invalid jitter + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with negative jitter value + Given I have an active session with sessionId + And I have metrics with jitter as negative number (-2.5) + When I send POST request to "/sessions/{sessionId}/metrics" with negative jitter + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with invalid packetLoss type + Given I have an active session with sessionId + And I have metrics with packetLoss as string "low" + When I send POST request to "/sessions/{sessionId}/metrics" with invalid packetLoss + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with packetLoss greater than 1 + Given I have an active session with sessionId + And I have metrics with packetLoss as 1.5 (greater than 100%) + When I send POST request to "/sessions/{sessionId}/metrics" with invalid packetLoss + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with invalid bitrate type + Given I have an active session with sessionId + And I have metrics with bitrate as string "high" + When I send POST request to "/sessions/{sessionId}/metrics" with invalid bitrate + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with negative bitrate value + Given I have an active session with sessionId + And I have metrics with bitrate as negative number (-1000) + When I send POST request to "/sessions/{sessionId}/metrics" with negative bitrate + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with invalid resolution type + Given I have an active session with sessionId + And I have metrics with resolution as number 1080 + When I send POST request to "/sessions/{sessionId}/metrics" with invalid resolution + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Error scenarios - Session state + + Scenario: Send metrics to non-existent session + Given I have a valid but non-existent sessionId + And I have valid metrics payload + When I send POST request to "/sessions/{sessionId}/metrics" with non-existent sessionId + Then I receive a 404 response + And the response contains error code indicating resource not found + And the response headers contain "x-correlator" + + Scenario: Send metrics to expired session + Given I have a sessionId for an expired session + And I have valid metrics payload + When I send POST request to "/sessions/{sessionId}/metrics" with expired sessionId + Then I receive a 410 response + And the response contains error code "GONE" + And the response headers contain "x-correlator" + + Scenario: Send metrics to deleted session + Given I have a sessionId for a deleted session + And I have valid metrics payload + When I send POST request to "/sessions/{sessionId}/metrics" with deleted sessionId + Then I receive a 410 response + And the response contains error code "GONE" + + # Error scenarios - Authorization and permissions + + Scenario: Send metrics without authentication + Given I do not have an access token + And I have a valid sessionId + And I have valid metrics payload + When I send POST request to "/sessions/{sessionId}/metrics" without authentication + Then I receive a 401 response + And the response contains error code "UNAUTHENTICATED" + + Scenario: Send metrics with invalid access token + Given I have an invalid access token + And I have a valid sessionId + And I have valid metrics payload + When I send POST request to "/sessions/{sessionId}/metrics" with invalid authentication + Then I receive a 401 response + And the response contains error code "UNAUTHENTICATED" + + Scenario: Send metrics without sufficient permissions + Given I have an access token without required scopes + And I have a valid sessionId + And I have valid metrics payload + When I send POST request to "/sessions/{sessionId}/metrics" with insufficient permissions + Then I receive a 403 response + And the response contains error code indicating insufficient permissions + + Scenario: Send metrics to session belonging to different user/device + Given I have a valid access token for user A + And I have a sessionId created by user B + And I have valid metrics payload + When I send POST request to "/sessions/{sessionId}/metrics" to other user's session + Then I receive a 403 response + And the response contains error code indicating insufficient permissions + + # Error scenarios - Request validation + + Scenario: Send metrics with invalid Content-Type + Given I have an active session with sessionId + And I have valid metrics payload + And I set Content-Type to "text/plain" + When I send POST request to "/sessions/{sessionId}/metrics" with invalid content type + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with malformed JSON + Given I have an active session with sessionId + And I have malformed JSON in the request body + When I send POST request to "/sessions/{sessionId}/metrics" with malformed JSON + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with empty request body + Given I have an active session with sessionId + When I send POST request to "/sessions/{sessionId}/metrics" with empty body + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + Scenario: Send metrics with extra unknown fields + Given I have an active session with sessionId + And I have metrics payload with additional unknown field "extraField" + When I send POST request to "/sessions/{sessionId}/metrics" with extra fields + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Validation scenarios - Business logic + + Scenario: Send metrics payload that exceeds size limits + Given I have an active session with sessionId + And I have metrics payload that exceeds maximum allowed size + When I send POST request to "/sessions/{sessionId}/metrics" with oversized payload + Then I receive a 422 response + And the response contains error code indicating payload too large + + Scenario: Send metrics at too high frequency + Given I have an active session with sessionId + And I have valid metrics payload + When I send POST requests to "/sessions/{sessionId}/metrics" at very high frequency + Then some requests may receive a 429 response + And the response contains error code "TOO_MANY_REQUESTS" + + # x-correlator header validation + + Scenario: Send metrics with valid x-correlator header + Given I have an active session with sessionId + And I have valid metrics payload + And I provide a valid x-correlator header + When I send POST request to "/sessions/{sessionId}/metrics" with correlator + Then I receive a 204 response + And the response headers contain the same x-correlator value + + Scenario: Send metrics with invalid x-correlator header format + Given I have an active session with sessionId + And I have valid metrics payload + And I provide an invalid x-correlator header with special characters + When I send POST request to "/sessions/{sessionId}/metrics" with invalid correlator + Then I receive a 400 response + And the response contains error code "INVALID_ARGUMENT" + + # Edge cases and boundary testing + + Scenario: Send metrics with zero values + Given I have an active session with sessionId + And I have metrics with latency 0.0, jitter 0.0, packetLoss 0.0, bitrate 0 + When I send POST request to "/sessions/{sessionId}/metrics" with zero values + Then I receive a 204 response + + Scenario: Send metrics with very large values + Given I have an active session with sessionId + And I have metrics with very large but valid values + When I send POST request to "/sessions/{sessionId}/metrics" with large values + Then I receive a 204 response + + Scenario: Send metrics with very small positive values + Given I have an active session with sessionId + And I have metrics with very small positive values (0.001) + When I send POST request to "/sessions/{sessionId}/metrics" with small values + Then I receive a 204 response + + # HTTP method validation + + Scenario: Use unsupported HTTP method on metrics endpoint + Given I have an active session with sessionId + When I send GET request to "/sessions/{sessionId}/metrics" + Then I receive a 405 response + And the response contains error indicating method not allowed From de19f5fad8eeddbd96c189f305538fc45bfebc27 Mon Sep 17 00:00:00 2001 From: Ben Hepworth Date: Tue, 8 Jul 2025 15:50:47 -0600 Subject: [PATCH 02/10] Update to follow Commonalities Guidelines --- code/Test_definitions/README.md | 164 ++-- .../session-insights-createSession.feature | 649 +++++++++------ .../session-insights-deleteSession.feature | 394 +++++---- .../session-insights-getSession.feature | 2 +- .../session-insights-retrieveSessions.feature | 550 +++++++------ .../session-insights-sendMetrics.feature | 777 ++++++++++-------- 6 files changed, 1419 insertions(+), 1117 deletions(-) diff --git a/code/Test_definitions/README.md b/code/Test_definitions/README.md index 1155d14..07747bd 100644 --- a/code/Test_definitions/README.md +++ b/code/Test_definitions/README.md @@ -20,62 +20,80 @@ The following Gherkin feature files are provided: ## 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 +- **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 - +#### 🌧️ 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. **API Compliance** - - Request/response schema validation - - HTTP status code verification - - Header validation (x-correlator, content-type) - - Error response format compliance +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 - - Device identifier validation - - Scope and permission enforcement - - 2-legged vs 3-legged token behavior + - 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 configurations - - Session state transitions - - Proper resource cleanup - - Expiration handling + - 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 - - MQTT broker settings (MQTT3/MQTT5) - - Protocol-specific features and limitations + - 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 - - Streaming frequency limits + - 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.) @@ -83,47 +101,63 @@ Before running the tests, ensure you have: - 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: +The following environment variables should be configured for test execution following CAMARA testing patterns: ```bash # API Configuration -API_BASE_URL=https://api.example.com/session-insights/v0 +API_ROOT=https://api.example.com # Used as apiRoot in Background sections API_TIMEOUT=30000 -# Authentication +# 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 +# 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 -VALID_APPLICATION_PROFILE_ID=550e8400-e29b-41d4-a716-446655440000 -# Application Server +# 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 -# Test Configuration +# 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 @@ -176,21 +210,17 @@ 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 @@ -200,18 +230,19 @@ Ensure you have access to devices with the following characteristics: ### Expected Results **✅ Successful Test Indicators:** - -- All sunny day scenarios pass with expected HTTP status codes -- Response schemas match API specification -- Error scenarios return appropriate error codes and messages -- x-correlator headers are properly handled +- 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) -- Authentication errors (verify tokens and scopes) -- Network connectivity issues (check endpoints and firewall rules) -- Missing environment variables (verify configuration) +- 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 @@ -223,37 +254,44 @@ Ensure you have access to devices with the following characteristics: ## Contributing to Tests -When modifying or adding test scenarios: +When modifying or adding test scenarios, follow CAMARA testing guidelines: -1. **Follow Gherkin Conventions**: Use clear Given/When/Then structure -2. **Maintain CAMARA Compliance**: Ensure tests align with CAMARA testing guidelines -3. **Cover Edge Cases**: Include boundary testing and error conditions +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 before submitting +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 -- Use descriptive scenario names that clearly indicate the test purpose -- Follow the pattern: `[Action] [Entity] [Condition/Context]` -- Examples: - - `Create HTTP session with valid parameters` - - `Retrieve session with invalid sessionId format` - - `Send metrics to expired session` +- **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 v0.wip**. When the API version changes: +These tests are designed for **Session Insights API vwip** following CAMARA versioning standards. When the API version changes: -1. Update the version references in feature file headers -2. Review and update test scenarios for any breaking changes -3. Validate all existing tests against the new API version -4. Add new test cases for any new functionality +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 Guide](https://github.com/camaraproject/Commonalities/blob/main/documentation/CAMARA-API-Design-Guide.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/) @@ -261,7 +299,7 @@ These tests are designed for **Session Insights API v0.wip**. When the API versi For questions or issues related to these test definitions: -1. **API Issues**: Report to the Session Insights API working group or open issue on GitHub +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 diff --git a/code/Test_definitions/session-insights-createSession.feature b/code/Test_definitions/session-insights-createSession.feature index 5a3881e..da5dd31 100644 --- a/code/Test_definitions/session-insights-createSession.feature +++ b/code/Test_definitions/session-insights-createSession.feature @@ -1,269 +1,394 @@ -Feature: CAMARA Session Insights API, v0.wip - Operation createSession - As a developer integrating with CAMARA Session Insights API - I want to create a sessions for real-time quality assessment - So that I can monitor and optimize my application's network performance - - Background: - Given the Session Insights API is available - And I have a valid access token with appropriate scopes - And I have a valid Application Profile ID - - # Sunny day scenarios - HTTP protocol +Feature: CAMARA Session Insights API, vwip - 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" is set to a UUID value + + # Success scenarios + + @session_insights_createSession_01_http_session_creation Scenario: Create HTTP session with valid parameters - Given I have a valid device with phoneNumber - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - When I send POST request to "/sessions" with valid HTTP session data - Then I receive a 201 response - And the response contains "id" property with UUID format - And the response contains "protocol" property with value "HTTP" - And the response contains "sink" property with webhook URL - And the response contains "sinkCredential" property for HTTP callbacks - And the response contains "startTime" property with valid date-time - And the response contains "expiresAt" property with valid date-time - And the response headers contain "x-correlator" - + 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 I have a valid device with phoneNumber - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify MQTT3 protocol - When I send POST request to "/sessions" with valid MQTT3 session data - Then I receive a 201 response - And the response contains "id" property with UUID format - And the response contains "protocol" property with value "MQTT3" - And the response contains "protocolSettings" with MQTT broker configuration - And the response contains "sinkCredential" property for MQTT access - And the response headers contain "x-correlator" - + 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 I have a valid device with phoneNumber - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify MQTT5 protocol - When I send POST request to "/sessions" with valid MQTT5 session data - Then I receive a 201 response - And the response contains "id" property with UUID format - And the response contains "protocol" property with value "MQTT5" - And the response contains "protocolSettings" with MQTT broker configuration - And the response headers contain "x-correlator" - + 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 I have a valid device with phoneNumber - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - And I provide an applicationSessionId "meet-12345" - When I send POST request to "/sessions" with session data including applicationSessionId - Then I receive a 201 response - And the response contains "applicationSessionId" property with value "meet-12345" - + 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 I have a valid device with IPv4 address and port - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - When I send POST request to "/sessions" with valid session data - Then I receive a 201 response - And the response contains device information with IPv4 address - + 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 I have a valid device with IPv6 address - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - When I send POST request to "/sessions" with valid session data - Then I receive a 201 response - And the response contains device information with IPv6 address - + 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 I have a valid device with networkAccessIdentifier - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - When I send POST request to "/sessions" with valid session data - Then I receive a 201 response - And the response contains device information with networkAccessIdentifier - - # Rainy day scenarios - Input validation - - Scenario: Create session without required applicationProfileId - Given I have a valid device with phoneNumber - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - But I do not provide applicationProfileId - When I send POST request to "/sessions" with incomplete session data - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - And the response headers contain "x-correlator" - - Scenario: Create session without required device - Given I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - But I do not provide device information - When I send POST request to "/sessions" with incomplete session data - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Create session without required applicationServer - Given I have a valid device with phoneNumber - And I have a valid Application Profile ID - And I specify HTTP protocol with webhook URL - But I do not provide applicationServer information - When I send POST request to "/sessions" with incomplete session data - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Create session without required protocol - Given I have a valid device with phoneNumber - And I have a valid Application Profile ID - And I have a valid application server configuration - But I do not specify protocol - When I send POST request to "/sessions" with incomplete session data - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Create session with invalid protocol value - Given I have a valid device with phoneNumber - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify an invalid protocol "INVALID_PROTOCOL" - When I send POST request to "/sessions" with invalid session data - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Create HTTP session without required sink - Given I have a valid device with phoneNumber - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol - But I do not provide sink webhook URL - When I send POST request to "/sessions" with incomplete HTTP session data - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Create session with invalid applicationProfileId format - Given I have a valid device with phoneNumber - And I have an invalid Application Profile ID "not-a-uuid" - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - When I send POST request to "/sessions" with invalid session data - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Create session with invalid device phoneNumber format - Given I have a device with invalid phoneNumber "invalid-phone" - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - When I send POST request to "/sessions" with invalid session data - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Create session with device having no identifiers - Given I have a device object with no identifiers - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - When I send POST request to "/sessions" with invalid session data - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Error scenarios - Authorization and permissions - - Scenario: Create session without authentication - Given I do not have an access token - And I have valid session data - When I send POST request to "/sessions" without authentication - Then I receive a 401 response - And the response contains error code "UNAUTHENTICATED" - - Scenario: Create session with invalid access token - Given I have an invalid access token - And I have valid session data - When I send POST request to "/sessions" with invalid authentication - Then I receive a 401 response - And the response contains error code "UNAUTHENTICATED" - - Scenario: Create session without sufficient permissions - Given I have an access token without required scopes - And I have valid session data - When I send POST request to "/sessions" with insufficient permissions - Then I receive a 403 response - And the response contains error code indicating insufficient permissions - - # Error scenarios - Business logic - - Scenario: Create session with non-existent applicationProfileId - Given I have a valid device with phoneNumber - And I have a non-existent Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - When I send POST request to "/sessions" with non-existent profile - Then I receive a 404 response - And the response contains error code indicating resource not found - - Scenario: Create session that conflicts with existing session - Given I have a valid device with phoneNumber - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - And a session already exists for this device and application profile - When I send POST request to "/sessions" with conflicting session data - Then I receive a 409 response - And the response contains error code "CONFLICT" - - # Device identifier validation scenarios - - Scenario: Create session with device using 3-legged token and device parameter - Given I have a 3-legged access token - And I provide device information in the request - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - When I send POST request to "/sessions" with device parameter - Then I receive a 422 response - And the response contains error code "UNNECESSARY_IDENTIFIER" - - Scenario: Create session with 2-legged token but no device parameter - Given I have a 2-legged access token - And I do not provide device information in the request - And I have a valid Application Profile ID - And I have a valid application server configuration - And I specify HTTP protocol with webhook URL - When I send POST request to "/sessions" without device parameter - Then I receive a 422 response - And the response contains error code "MISSING_IDENTIFIER" - - # Content-Type and format validation - - Scenario: Create session with invalid Content-Type - Given I have valid session data - And I set Content-Type to "text/plain" - When I send POST request to "/sessions" with invalid content type - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Create session with malformed JSON - Given I have malformed JSON in the request body - When I send POST request to "/sessions" with malformed JSON - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # x-correlator header validation - - Scenario: Create session with valid x-correlator header - Given I have valid session data - And I provide a valid x-correlator header - When I send POST request to "/sessions" with correlator - Then I receive a 201 response - And the response headers contain the same x-correlator value - - Scenario: Create session with invalid x-correlator header format - Given I have valid session data - And I provide an invalid x-correlator header with special characters - When I send POST request to "/sessions" with invalid correlator - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" + 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 index 8a9fbfd..32c0066 100644 --- a/code/Test_definitions/session-insights-deleteSession.feature +++ b/code/Test_definitions/session-insights-deleteSession.feature @@ -1,216 +1,204 @@ -Feature: CAMARA Session Insights API, v0.wip - Operation deleteSession - As a developer integrating with CAMARA Session Insights API - I want to delete a Session Insights sessions - So that I can clean up resources when monitoring is no longer needed - - Background: - Given the Session Insights API is available - And I have a valid access token with appropriate scopes - - # Sunny day scenarios - - Scenario: Delete existing HTTP session - Given I have created an HTTP session with sessionId - When I send DELETE request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 204 response +Feature: CAMARA Session Insights API, vwip - 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" is set to a UUID value + 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 headers contain "x-correlator" - - Scenario: Delete existing MQTT3 session - Given I have created an MQTT3 session with sessionId - When I send DELETE request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 204 response + 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 headers contain "x-correlator" - - Scenario: Delete existing MQTT5 session - Given I have created an MQTT5 session with sessionId - When I send DELETE request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 204 response + 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 headers contain "x-correlator" + 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 I have created a session with applicationSessionId "meet-12345" - When I send DELETE request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 204 response + 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 I have created a session with sessionId - And I have successfully deleted the session - When I send GET request to "/sessions/{sessionId}" to verify deletion - Then I receive a 410 response - And the response contains error code "GONE" - + 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 I have created a session with notifications enabled - And I have been receiving notifications for the session - When I send DELETE request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 204 response + 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 - Scenario: Delete session created with different device identifiers - Given I have created a session with device phoneNumber - When I send DELETE request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 204 response - And the session is successfully deleted - - # Rainy day scenarios - Path parameter validation - - Scenario: Delete session with invalid sessionId format - Given I have an invalid sessionId "not-a-uuid" - When I send DELETE request to "/sessions/{sessionId}" with invalid sessionId - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - And the response headers contain "x-correlator" - - Scenario: Delete session with empty sessionId - Given I have an empty sessionId - When I send DELETE request to "/sessions/{sessionId}" with empty sessionId - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Delete session with malformed UUID sessionId - Given I have a malformed UUID sessionId "123e4567-e89b-12d3-a456-42661417400" - When I send DELETE request to "/sessions/{sessionId}" with malformed sessionId - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Error scenarios - Resource not found - - Scenario: Delete non-existent session - Given I have a valid but non-existent sessionId - When I send DELETE request to "/sessions/{sessionId}" with non-existent sessionId - Then I receive a 404 response - And the response contains error code indicating resource not found - And the response headers contain "x-correlator" - - # Error scenarios - Authorization and permissions - - Scenario: Delete session without authentication - Given I do not have an access token - And I have a valid sessionId - When I send DELETE request to "/sessions/{sessionId}" without authentication - Then I receive a 401 response - And the response contains error code "UNAUTHENTICATED" - - Scenario: Delete session with invalid access token - Given I have an invalid access token - And I have a valid sessionId - When I send DELETE request to "/sessions/{sessionId}" with invalid authentication - Then I receive a 401 response - And the response contains error code "UNAUTHENTICATED" - - Scenario: Delete session without sufficient permissions - Given I have an access token without required scopes - And I have a valid sessionId - When I send DELETE request to "/sessions/{sessionId}" with insufficient permissions - Then I receive a 403 response - And the response contains error code indicating insufficient permissions - - Scenario: Delete session belonging to different user/device - Given I have a valid access token for user A - And I have a sessionId created by user B - When I send DELETE request to "/sessions/{sessionId}" to delete other user's session - Then I receive a 403 response - And the response contains error code indicating insufficient permissions - - # Error scenarios - Session lifecycle - + @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 I have a sessionId for an expired session - When I send DELETE request to "/sessions/{sessionId}" with expired sessionId - Then I receive a 410 response - And the response contains error code "GONE" - And the response headers contain "x-correlator" - + 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 I have a sessionId for a session that was already deleted - When I send DELETE request to "/sessions/{sessionId}" with previously deleted sessionId - Then I receive a 410 response - And the response contains error code "GONE" - - # HTTP method validation - - Scenario: Use unsupported HTTP method on sessions endpoint - Given I have a valid sessionId - When I send PATCH request to "/sessions/{sessionId}" - Then I receive a 405 response - And the response contains error indicating method not allowed - - # x-correlator header validation - - Scenario: Delete session with valid x-correlator header - Given I have a valid sessionId - And I provide a valid x-correlator header - When I send DELETE request to "/sessions/{sessionId}" with correlator - Then I receive a 204 response - And the response headers contain the same x-correlator value - - Scenario: Delete session with invalid x-correlator header format - Given I have a valid sessionId - And I provide an invalid x-correlator header with special characters - When I send DELETE request to "/sessions/{sessionId}" with invalid correlator - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Edge cases and integration - - Scenario: Delete session with pending metrics - Given I have created a session with sessionId - And I have sent metrics to the session that are still being processed - When I send DELETE request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 204 response - And all pending metrics processing is stopped - - Scenario: Delete session with active webhook notifications - Given I have created an HTTP session with webhook notifications - And the session is actively sending notifications - When I send DELETE request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 204 response - And no further webhook notifications are sent - - Scenario: Delete session with active MQTT subscriptions - Given I have created an MQTT session with active subscriptions - And the session is actively publishing to MQTT topics - When I send DELETE request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 204 response - And all MQTT subscriptions are terminated - - # Concurrency scenarios - - Scenario: Delete session while sending metrics - Given I have created a session with sessionId - And I am actively sending metrics to the session - When I send DELETE request to "/sessions/{sessionId}" concurrently - Then I receive a 204 response - And subsequent metric submissions to this session fail - - Scenario: Multiple delete requests for same session - Given I have created a session with sessionId - When I send multiple DELETE requests to "/sessions/{sessionId}" simultaneously - Then the first request receives a 204 response - And subsequent requests receive a 410 response - - # Content validation - - Scenario: Delete session with request body (should be ignored) - Given I have created a session with sessionId - And I include a request body in the DELETE request - When I send DELETE request to "/sessions/{sessionId}" with body - Then I receive a 204 response - And the request body is ignored - - # Resource cleanup verification - - Scenario: Verify all session resources are cleaned up after deletion - Given I have created a session with full configuration - And the session has active metrics streaming - And the session has active notifications - When I send DELETE request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 204 response - And all webhook endpoints stop receiving notifications - And all MQTT topics stop receiving messages - And session metrics are no longer accepted - And session cannot be retrieved via GET request + 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 index e9486b6..b967193 100644 --- a/code/Test_definitions/session-insights-getSession.feature +++ b/code/Test_definitions/session-insights-getSession.feature @@ -1,4 +1,4 @@ -Feature: CAMARA Session Insights API, v0.wip - Operation getSession +Feature: CAMARA Session Insights API, v0.1.0 - Operation getSession As a developer integrating with CAMARA Session Insights API I want to retrieve details of an existing session So that I can check session status and configuration diff --git a/code/Test_definitions/session-insights-retrieveSessions.feature b/code/Test_definitions/session-insights-retrieveSessions.feature index c1d7c2a..7c28fbb 100644 --- a/code/Test_definitions/session-insights-retrieveSessions.feature +++ b/code/Test_definitions/session-insights-retrieveSessions.feature @@ -1,271 +1,301 @@ -Feature: CAMARA Session Insights API, v0.wip - Operation retrieveSessionsByDevice - As a developer integrating with CAMARA Session Insights API - I want to retrieve all sessions associated with a specific device - So that I can manage and monitor device-specific sessions - - Background: - Given the Session Insights API is available - And I have a valid access token with appropriate scopes - - # Sunny day scenarios - +Feature: CAMARA Session Insights API, vwip - 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" is set to a UUID value + + # Success scenarios + + @session_insights_retrieveSessions_01_phone_number_2legged_token Scenario: Retrieve sessions for device with phoneNumber using 2-legged token - Given I have a 2-legged access token - And I have created multiple sessions for device with phoneNumber - When I send POST request to "/retrieve-sessions" with device phoneNumber - Then I receive a 200 response - And the response contains an array of sessions - And all sessions in the array belong to the specified device - And each session contains required properties (id, device, applicationServer, protocol, sink, subscribedEventTypes, startTime) - And the response headers contain "x-correlator" - + 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 I have a 2-legged access token - And I have created sessions for device with IPv4 address - When I send POST request to "/retrieve-sessions" with device IPv4 address - Then I receive a 200 response - And the response contains an array of sessions - And all sessions belong to the device with specified IPv4 address - + 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 I have a 2-legged access token - And I have created sessions for device with IPv6 address - When I send POST request to "/retrieve-sessions" with device IPv6 address - Then I receive a 200 response - And the response contains an array of sessions - And all sessions belong to the device with specified IPv6 address - + 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 I have a 2-legged access token - And I have created sessions for device with networkAccessIdentifier - When I send POST request to "/retrieve-sessions" with device networkAccessIdentifier - Then I receive a 200 response - And the response contains an array of sessions - And all sessions belong to the device with specified networkAccessIdentifier - + 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 I have a 3-legged access token for a specific device - And I have created sessions for the authenticated device - When I send POST request to "/retrieve-sessions" without device parameter - Then I receive a 200 response - And the response contains an array of sessions - And all sessions belong to the authenticated device - + 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 I have a 2-legged access token - And I have a device with phoneNumber that has no sessions - When I send POST request to "/retrieve-sessions" with device phoneNumber - Then I receive a 200 response - And the response contains an empty array - And the response headers contain "x-correlator" - + 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 I have a 2-legged access token - And I have created HTTP sessions for a device - And I have created MQTT3 sessions for the same device - And I have created MQTT5 sessions for the same device - When I send POST request to "/retrieve-sessions" with device identifier - Then I receive a 200 response + 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 - Scenario: Retrieve sessions including sessions with different states - Given I have a 2-legged access token - And I have active sessions for a device - And I have expired sessions for the same device - When I send POST request to "/retrieve-sessions" with device identifier - Then I receive a 200 response - And the response includes all sessions regardless of state - And each session shows its current state information - - # Rainy day scenarios - Request validation - - Scenario: Retrieve sessions with 2-legged token but no device parameter - Given I have a 2-legged access token - And I do not provide device information in the request - When I send POST request to "/retrieve-sessions" without device parameter - Then I receive a 422 response - And the response contains error code "MISSING_IDENTIFIER" - And the response headers contain "x-correlator" - - Scenario: Retrieve sessions with 3-legged token and device parameter - Given I have a 3-legged access token - And I provide device information in the request - When I send POST request to "/retrieve-sessions" with device parameter - Then I receive a 422 response - And the response contains error code "UNNECESSARY_IDENTIFIER" - And the response headers contain "x-correlator" - - Scenario: Retrieve sessions with invalid device phoneNumber format - Given I have a 2-legged access token - And I provide device with invalid phoneNumber "invalid-phone" - When I send POST request to "/retrieve-sessions" with invalid phoneNumber - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Retrieve sessions with invalid device IPv4 address format - Given I have a 2-legged access token - And I provide device with invalid IPv4 address "999.999.999.999" - When I send POST request to "/retrieve-sessions" with invalid IPv4 address - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Retrieve sessions with invalid device IPv6 address format - Given I have a 2-legged access token - And I provide device with invalid IPv6 address "invalid-ipv6" - When I send POST request to "/retrieve-sessions" with invalid IPv6 address - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Retrieve sessions with device having no identifiers - Given I have a 2-legged access token - And I provide device object with no identifiers - When I send POST request to "/retrieve-sessions" with empty device - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - + @session_insights_retrieveSessions_08_multiple_device_identifiers Scenario: Retrieve sessions with device having multiple identifiers - Given I have a 2-legged access token - And I provide device object with both phoneNumber and IPv4 address - When I send POST request to "/retrieve-sessions" with multiple identifiers - Then I receive a 200 response - And the response contains sessions for the device - And the response device object contains only one identifier - - # Error scenarios - HTTP method and content type - - Scenario: Use GET method instead of POST - Given I have a valid access token - When I send GET request to "/retrieve-sessions" - Then I receive a 405 response - And the response contains error indicating method not allowed - - Scenario: Retrieve sessions with invalid Content-Type - Given I have a 2-legged access token - And I have valid device information - And I set Content-Type to "text/plain" - When I send POST request to "/retrieve-sessions" with invalid content type - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Retrieve sessions with malformed JSON - Given I have a 2-legged access token - And I have malformed JSON in the request body - When I send POST request to "/retrieve-sessions" with malformed JSON - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Error scenarios - Authorization and permissions - - Scenario: Retrieve sessions without authentication - Given I do not have an access token - And I have valid device information - When I send POST request to "/retrieve-sessions" without authentication - Then I receive a 401 response - And the response contains error code "UNAUTHENTICATED" - - Scenario: Retrieve sessions with invalid access token - Given I have an invalid access token - And I have valid device information - When I send POST request to "/retrieve-sessions" with invalid authentication - Then I receive a 401 response - And the response contains error code "UNAUTHENTICATED" - - Scenario: Retrieve sessions without sufficient permissions - Given I have an access token without required scopes - And I have valid device information - When I send POST request to "/retrieve-sessions" with insufficient permissions - Then I receive a 403 response - And the response contains error code indicating insufficient permissions - - Scenario: Retrieve sessions for device not belonging to authenticated user - Given I have a 3-legged access token for user A - And I have device information for user B - When I send POST request to "/retrieve-sessions" for other user's device - Then I receive a 403 response - And the response contains error code indicating insufficient permissions - - # Error scenarios - Device not found - - Scenario: Retrieve sessions for non-existent device - Given I have a 2-legged access token - And I have a valid but non-existent device phoneNumber - When I send POST request to "/retrieve-sessions" with non-existent device - Then I receive a 404 response - And the response contains error code indicating device not found - And the response headers contain "x-correlator" - - # Rate limiting scenarios - - Scenario: Retrieve sessions with rate limiting exceeded - Given I have a valid access token - And I have exceeded the rate limit for this endpoint - When I send POST request to "/retrieve-sessions" exceeding rate limit - Then I receive a 429 response - And the response contains error code "TOO_MANY_REQUESTS" or "QUOTA_EXCEEDED" - And the response headers contain "x-correlator" - - # x-correlator header validation - - Scenario: Retrieve sessions with valid x-correlator header - Given I have a 2-legged access token - And I have valid device information - And I provide a valid x-correlator header - When I send POST request to "/retrieve-sessions" with correlator - Then I receive a 200 response - And the response headers contain the same x-correlator value - - Scenario: Retrieve sessions with invalid x-correlator header format - Given I have a 2-legged access token - And I have valid device information - And I provide an invalid x-correlator header with special characters - When I send POST request to "/retrieve-sessions" with invalid correlator - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Response schema validation - - Scenario: Verify response schema compliance for session array - Given I have a 2-legged access token - And I have created sessions for a device - When I send POST request to "/retrieve-sessions" with device identifier - Then I receive a 200 response - And the response body complies with RetrieveSessionsOutput schema - And the response is an array of Session objects - And each session object contains all required properties - And all property types match the specification - - # Edge cases and filtering - - Scenario: Retrieve large number of sessions for device - Given I have a 2-legged access token - And I have created many sessions (50+) for a device - When I send POST request to "/retrieve-sessions" with device identifier - Then I receive a 200 response - And the response contains all sessions for the device - And the response time is reasonable - - Scenario: Retrieve sessions with various applicationSessionIds - Given I have a 2-legged access token - And I have created sessions with different applicationSessionIds for a device - When I send POST request to "/retrieve-sessions" with device identifier - Then I receive a 200 response - And each session shows its respective applicationSessionId - - Scenario: Retrieve sessions created at different times - Given I have a 2-legged access token - And I have created sessions at different times for a device - When I send POST request to "/retrieve-sessions" with device identifier - Then I receive a 200 response - And sessions are returned with their respective creation timestamps - And sessions may be ordered by creation time - - # Content negotiation - - Scenario: Retrieve sessions with unsupported Accept header - Given I have a 2-legged access token - And I have valid device information - And I set Accept header to "text/xml" - When I send POST request to "/retrieve-sessions" with unsupported Accept - Then I receive a 406 response - And the response contains error indicating unsupported media type + 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 index 96da351..307746b 100644 --- a/code/Test_definitions/session-insights-sendMetrics.feature +++ b/code/Test_definitions/session-insights-sendMetrics.feature @@ -1,342 +1,463 @@ -Feature: CAMARA Session Insights API, v0.wip - Operation sendSessionMetrics - As a developer integrating with CAMARA Session Insights API - I want to send application-level KPIs to monitoring sessions - So that the network operator can evaluate session quality and provide insights - - Background: - Given the Session Insights API is available - And I have a valid access token with appropriate scopes - And I have created a session with valid sessionId - - # Sunny day scenarios - +Feature: CAMARA Session Insights API, vwip - 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" is set to a UUID value + 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 I have an active HTTP session with sessionId - And I have valid metrics payload with all required fields - When I send POST request to "/sessions/{sessionId}/metrics" with valid metrics - Then I receive a 204 response + 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 headers contain "x-correlator" + 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 I have an active MQTT3 session with sessionId - And I have valid metrics payload with all required fields - When I send POST request to "/sessions/{sessionId}/metrics" with valid metrics - Then I receive a 204 response + 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 headers contain "x-correlator" + 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 I have an active MQTT5 session with sessionId - And I have valid metrics payload with all required fields - When I send POST request to "/sessions/{sessionId}/metrics" with valid metrics - Then I receive a 204 response + 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 I have an active session with sessionId - And I have metrics payload with latency, jitter, packetLoss, bitrate, and resolution - When I send POST request to "/sessions/{sessionId}/metrics" with minimum metrics - Then I receive a 204 response - - Scenario: Send metrics with all valid field types - Given I have an active session with sessionId - And I have metrics with latency as float (15.5) - And I have metrics with jitter as float (2.1) - And I have metrics with packetLoss as number (0.01) - And I have metrics with bitrate as number (1000000) - And I have metrics with resolution as string ("1920x1080") - When I send POST request to "/sessions/{sessionId}/metrics" with typed metrics - Then I receive a 204 response - + 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 I have an active session with sessionId - And I have valid metrics payload - When I send POST request to "/sessions/{sessionId}/metrics" multiple times - Then I receive a 204 response each time - And each metrics submission is processed independently - - Scenario: Send different metric values over time - Given I have an active session with sessionId - When I send metrics with latency 10.5 at time T1 - And I send metrics with latency 15.2 at time T2 - And I send metrics with latency 8.7 at time T3 - Then I receive a 204 response for each submission - And all metric values are processed - - # Rainy day scenarios - Path parameter validation - - Scenario: Send metrics with invalid sessionId format - Given I have an invalid sessionId "not-a-uuid" - And I have valid metrics payload - When I send POST request to "/sessions/{sessionId}/metrics" with invalid sessionId - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - And the response headers contain "x-correlator" - - Scenario: Send metrics with empty sessionId - Given I have an empty sessionId - And I have valid metrics payload - When I send POST request to "/sessions/{sessionId}/metrics" with empty sessionId - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with malformed UUID sessionId - Given I have a malformed UUID sessionId "123e4567-e89b-12d3-a456-42661417400" - And I have valid metrics payload - When I send POST request to "/sessions/{sessionId}/metrics" with malformed sessionId - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Error scenarios - Missing required fields - - Scenario: Send metrics without required latency field - Given I have an active session with sessionId - And I have metrics payload without latency field - When I send POST request to "/sessions/{sessionId}/metrics" with incomplete metrics - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics without required jitter field - Given I have an active session with sessionId - And I have metrics payload without jitter field - When I send POST request to "/sessions/{sessionId}/metrics" with incomplete metrics - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics without required packetLoss field - Given I have an active session with sessionId - And I have metrics payload without packetLoss field - When I send POST request to "/sessions/{sessionId}/metrics" with incomplete metrics - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics without required bitrate field - Given I have an active session with sessionId - And I have metrics payload without bitrate field - When I send POST request to "/sessions/{sessionId}/metrics" with incomplete metrics - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics without required resolution field - Given I have an active session with sessionId - And I have metrics payload without resolution field - When I send POST request to "/sessions/{sessionId}/metrics" with incomplete metrics - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Error scenarios - Invalid field types and values - - Scenario: Send metrics with invalid latency type - Given I have an active session with sessionId - And I have metrics with latency as string "invalid" - When I send POST request to "/sessions/{sessionId}/metrics" with invalid latency - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with negative latency value - Given I have an active session with sessionId - And I have metrics with latency as negative number (-5.0) - When I send POST request to "/sessions/{sessionId}/metrics" with negative latency - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with invalid jitter type - Given I have an active session with sessionId - And I have metrics with jitter as boolean true - When I send POST request to "/sessions/{sessionId}/metrics" with invalid jitter - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with negative jitter value - Given I have an active session with sessionId - And I have metrics with jitter as negative number (-2.5) - When I send POST request to "/sessions/{sessionId}/metrics" with negative jitter - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with invalid packetLoss type - Given I have an active session with sessionId - And I have metrics with packetLoss as string "low" - When I send POST request to "/sessions/{sessionId}/metrics" with invalid packetLoss - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with packetLoss greater than 1 - Given I have an active session with sessionId - And I have metrics with packetLoss as 1.5 (greater than 100%) - When I send POST request to "/sessions/{sessionId}/metrics" with invalid packetLoss - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with invalid bitrate type - Given I have an active session with sessionId - And I have metrics with bitrate as string "high" - When I send POST request to "/sessions/{sessionId}/metrics" with invalid bitrate - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with negative bitrate value - Given I have an active session with sessionId - And I have metrics with bitrate as negative number (-1000) - When I send POST request to "/sessions/{sessionId}/metrics" with negative bitrate - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with invalid resolution type - Given I have an active session with sessionId - And I have metrics with resolution as number 1080 - When I send POST request to "/sessions/{sessionId}/metrics" with invalid resolution - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Error scenarios - Session state - - Scenario: Send metrics to non-existent session - Given I have a valid but non-existent sessionId - And I have valid metrics payload - When I send POST request to "/sessions/{sessionId}/metrics" with non-existent sessionId - Then I receive a 404 response - And the response contains error code indicating resource not found - And the response headers contain "x-correlator" - + 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 I have a sessionId for an expired session - And I have valid metrics payload - When I send POST request to "/sessions/{sessionId}/metrics" with expired sessionId - Then I receive a 410 response - And the response contains error code "GONE" - And the response headers contain "x-correlator" - + 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 I have a sessionId for a deleted session - And I have valid metrics payload - When I send POST request to "/sessions/{sessionId}/metrics" with deleted sessionId - Then I receive a 410 response - And the response contains error code "GONE" - - # Error scenarios - Authorization and permissions - - Scenario: Send metrics without authentication - Given I do not have an access token - And I have a valid sessionId - And I have valid metrics payload - When I send POST request to "/sessions/{sessionId}/metrics" without authentication - Then I receive a 401 response - And the response contains error code "UNAUTHENTICATED" - - Scenario: Send metrics with invalid access token - Given I have an invalid access token - And I have a valid sessionId - And I have valid metrics payload - When I send POST request to "/sessions/{sessionId}/metrics" with invalid authentication - Then I receive a 401 response - And the response contains error code "UNAUTHENTICATED" - - Scenario: Send metrics without sufficient permissions - Given I have an access token without required scopes - And I have a valid sessionId - And I have valid metrics payload - When I send POST request to "/sessions/{sessionId}/metrics" with insufficient permissions - Then I receive a 403 response - And the response contains error code indicating insufficient permissions - - Scenario: Send metrics to session belonging to different user/device - Given I have a valid access token for user A - And I have a sessionId created by user B - And I have valid metrics payload - When I send POST request to "/sessions/{sessionId}/metrics" to other user's session - Then I receive a 403 response - And the response contains error code indicating insufficient permissions - - # Error scenarios - Request validation - - Scenario: Send metrics with invalid Content-Type - Given I have an active session with sessionId - And I have valid metrics payload - And I set Content-Type to "text/plain" - When I send POST request to "/sessions/{sessionId}/metrics" with invalid content type - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with malformed JSON - Given I have an active session with sessionId - And I have malformed JSON in the request body - When I send POST request to "/sessions/{sessionId}/metrics" with malformed JSON - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with empty request body - Given I have an active session with sessionId - When I send POST request to "/sessions/{sessionId}/metrics" with empty body - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Send metrics with extra unknown fields - Given I have an active session with sessionId - And I have metrics payload with additional unknown field "extraField" - When I send POST request to "/sessions/{sessionId}/metrics" with extra fields - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Validation scenarios - Business logic - - Scenario: Send metrics payload that exceeds size limits - Given I have an active session with sessionId - And I have metrics payload that exceeds maximum allowed size - When I send POST request to "/sessions/{sessionId}/metrics" with oversized payload - Then I receive a 422 response - And the response contains error code indicating payload too large - + 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 I have an active session with sessionId - And I have valid metrics payload - When I send POST requests to "/sessions/{sessionId}/metrics" at very high frequency - Then some requests may receive a 429 response - And the response contains error code "TOO_MANY_REQUESTS" - - # x-correlator header validation - - Scenario: Send metrics with valid x-correlator header - Given I have an active session with sessionId - And I have valid metrics payload - And I provide a valid x-correlator header - When I send POST request to "/sessions/{sessionId}/metrics" with correlator - Then I receive a 204 response - And the response headers contain the same x-correlator value - - Scenario: Send metrics with invalid x-correlator header format - Given I have an active session with sessionId - And I have valid metrics payload - And I provide an invalid x-correlator header with special characters - When I send POST request to "/sessions/{sessionId}/metrics" with invalid correlator - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Edge cases and boundary testing - - Scenario: Send metrics with zero values - Given I have an active session with sessionId - And I have metrics with latency 0.0, jitter 0.0, packetLoss 0.0, bitrate 0 - When I send POST request to "/sessions/{sessionId}/metrics" with zero values - Then I receive a 204 response - - Scenario: Send metrics with very large values - Given I have an active session with sessionId - And I have metrics with very large but valid values - When I send POST request to "/sessions/{sessionId}/metrics" with large values - Then I receive a 204 response - - Scenario: Send metrics with very small positive values - Given I have an active session with sessionId - And I have metrics with very small positive values (0.001) - When I send POST request to "/sessions/{sessionId}/metrics" with small values - Then I receive a 204 response - - # HTTP method validation - - Scenario: Use unsupported HTTP method on metrics endpoint - Given I have an active session with sessionId - When I send GET request to "/sessions/{sessionId}/metrics" - Then I receive a 405 response - And the response contains error indicating method not allowed + 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 From 64d3a9c5040e6d5b9a068ce69f751a7da89a7a59 Mon Sep 17 00:00:00 2001 From: Ben Hepworth Date: Wed, 16 Jul 2025 19:29:35 -0600 Subject: [PATCH 03/10] Change uuid to x-correlator to align with 0.6 Commonalities --- code/Test_definitions/session-insights-createSession.feature | 2 +- code/Test_definitions/session-insights-deleteSession.feature | 2 +- code/Test_definitions/session-insights-getSession.feature | 3 ++- .../Test_definitions/session-insights-retrieveSessions.feature | 2 +- code/Test_definitions/session-insights-sendMetrics.feature | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/code/Test_definitions/session-insights-createSession.feature b/code/Test_definitions/session-insights-createSession.feature index da5dd31..1b32d56 100644 --- a/code/Test_definitions/session-insights-createSession.feature +++ b/code/Test_definitions/session-insights-createSession.feature @@ -19,7 +19,7 @@ Feature: CAMARA Session Insights API, vwip - Operation createSession 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" is set to a UUID value + And the header "x-correlator" complies with the schema at "#/components/schemas/XCorrelator" # Success scenarios diff --git a/code/Test_definitions/session-insights-deleteSession.feature b/code/Test_definitions/session-insights-deleteSession.feature index 32c0066..015e453 100644 --- a/code/Test_definitions/session-insights-deleteSession.feature +++ b/code/Test_definitions/session-insights-deleteSession.feature @@ -18,7 +18,7 @@ Feature: CAMARA Session Insights API, vwip - Operation deleteSession 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" is set to a UUID value + 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 diff --git a/code/Test_definitions/session-insights-getSession.feature b/code/Test_definitions/session-insights-getSession.feature index b967193..ae17992 100644 --- a/code/Test_definitions/session-insights-getSession.feature +++ b/code/Test_definitions/session-insights-getSession.feature @@ -1,4 +1,4 @@ -Feature: CAMARA Session Insights API, v0.1.0 - Operation getSession +Feature: CAMARA Session Insights API, vwip - Operation getSession As a developer integrating with CAMARA Session Insights API I want to retrieve details of an existing session So that I can check session status and configuration @@ -6,6 +6,7 @@ Feature: CAMARA Session Insights API, v0.1.0 - Operation getSession Background: Given the Session Insights API is available And I have a valid access token with appropriate scopes + And the header "x-correlator" is set to a UUID value # Sunny day scenarios diff --git a/code/Test_definitions/session-insights-retrieveSessions.feature b/code/Test_definitions/session-insights-retrieveSessions.feature index 7c28fbb..9679789 100644 --- a/code/Test_definitions/session-insights-retrieveSessions.feature +++ b/code/Test_definitions/session-insights-retrieveSessions.feature @@ -17,7 +17,7 @@ Feature: CAMARA Session Insights API, vwip - Operation retrieveSessionsByDevice 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" is set to a UUID value + And the header "x-correlator" complies with the schema at "#/components/schemas/XCorrelator" # Success scenarios diff --git a/code/Test_definitions/session-insights-sendMetrics.feature b/code/Test_definitions/session-insights-sendMetrics.feature index 307746b..e810ce2 100644 --- a/code/Test_definitions/session-insights-sendMetrics.feature +++ b/code/Test_definitions/session-insights-sendMetrics.feature @@ -20,7 +20,7 @@ Feature: CAMARA Session Insights API, vwip - Operation sendSessionMetrics 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" is set to a UUID value + 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 From b5e44a8fb20beb2a0d9e369d6a436bfc56e3f676 Mon Sep 17 00:00:00 2001 From: Ben Hepworth <125334035+benhepworth@users.noreply.github.com> Date: Thu, 17 Jul 2025 04:43:21 -0600 Subject: [PATCH 04/10] Update code/Test_definitions/session-insights-deleteSession.feature update version Co-authored-by: Kevin Smith --- code/Test_definitions/session-insights-deleteSession.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Test_definitions/session-insights-deleteSession.feature b/code/Test_definitions/session-insights-deleteSession.feature index 015e453..346576c 100644 --- a/code/Test_definitions/session-insights-deleteSession.feature +++ b/code/Test_definitions/session-insights-deleteSession.feature @@ -1,4 +1,4 @@ -Feature: CAMARA Session Insights API, vwip - Operation deleteSession +Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation deleteSession # Input to be provided by the implementation to the tester # # Implementation indications: From 5187824cbaefb3f5008f2ce61b8ae65fc9192328 Mon Sep 17 00:00:00 2001 From: Ben Hepworth <125334035+benhepworth@users.noreply.github.com> Date: Thu, 17 Jul 2025 04:43:38 -0600 Subject: [PATCH 05/10] Update code/Test_definitions/session-insights-getSession.feature update version Co-authored-by: Kevin Smith --- code/Test_definitions/session-insights-getSession.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Test_definitions/session-insights-getSession.feature b/code/Test_definitions/session-insights-getSession.feature index ae17992..f9cb322 100644 --- a/code/Test_definitions/session-insights-getSession.feature +++ b/code/Test_definitions/session-insights-getSession.feature @@ -1,4 +1,4 @@ -Feature: CAMARA Session Insights API, vwip - Operation getSession +Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation getSession As a developer integrating with CAMARA Session Insights API I want to retrieve details of an existing session So that I can check session status and configuration From 9da1d5ef5e0e10a91b2b046dc13a9478081f60c2 Mon Sep 17 00:00:00 2001 From: Ben Hepworth <125334035+benhepworth@users.noreply.github.com> Date: Thu, 17 Jul 2025 04:43:51 -0600 Subject: [PATCH 06/10] Update code/Test_definitions/session-insights-retrieveSessions.feature update version Co-authored-by: Kevin Smith --- code/Test_definitions/session-insights-retrieveSessions.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Test_definitions/session-insights-retrieveSessions.feature b/code/Test_definitions/session-insights-retrieveSessions.feature index 9679789..0d5208e 100644 --- a/code/Test_definitions/session-insights-retrieveSessions.feature +++ b/code/Test_definitions/session-insights-retrieveSessions.feature @@ -1,4 +1,4 @@ -Feature: CAMARA Session Insights API, vwip - Operation retrieveSessionsByDevice +Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation retrieveSessionsByDevice # Input to be provided by the implementation to the tester # # Implementation indications: From 88fdac5b34c8900b6d062b8af84905745113fbad Mon Sep 17 00:00:00 2001 From: Ben Hepworth <125334035+benhepworth@users.noreply.github.com> Date: Thu, 17 Jul 2025 04:44:03 -0600 Subject: [PATCH 07/10] Update code/Test_definitions/session-insights-sendMetrics.feature update version Co-authored-by: Kevin Smith --- code/Test_definitions/session-insights-sendMetrics.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Test_definitions/session-insights-sendMetrics.feature b/code/Test_definitions/session-insights-sendMetrics.feature index e810ce2..1b23c9c 100644 --- a/code/Test_definitions/session-insights-sendMetrics.feature +++ b/code/Test_definitions/session-insights-sendMetrics.feature @@ -1,4 +1,4 @@ -Feature: CAMARA Session Insights API, vwip - Operation sendSessionMetrics +Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation sendSessionMetrics # Input to be provided by the implementation to the tester # # Implementation indications: From e619614381a78cff82deb70d959eec98e950cb14 Mon Sep 17 00:00:00 2001 From: Ben Hepworth Date: Thu, 17 Jul 2025 04:57:15 -0600 Subject: [PATCH 08/10] Update version --- code/Test_definitions/session-insights-createSession.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Test_definitions/session-insights-createSession.feature b/code/Test_definitions/session-insights-createSession.feature index 1b32d56..0d1b59c 100644 --- a/code/Test_definitions/session-insights-createSession.feature +++ b/code/Test_definitions/session-insights-createSession.feature @@ -1,4 +1,4 @@ -Feature: CAMARA Session Insights API, vwip - Operation createSession +Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation createSession # Input to be provided by the implementation to the tester # # Implementation indications: From 7dfd54763e3d256f8ce3ff8a0bb8a523c2e5d119 Mon Sep 17 00:00:00 2001 From: Ben Hepworth Date: Thu, 17 Jul 2025 05:00:36 -0600 Subject: [PATCH 09/10] Update based on Kevin's feedback to align with Commonalities --- .../session-insights-getSession.feature | 418 +++++++++--------- 1 file changed, 219 insertions(+), 199 deletions(-) diff --git a/code/Test_definitions/session-insights-getSession.feature b/code/Test_definitions/session-insights-getSession.feature index f9cb322..a4866fe 100644 --- a/code/Test_definitions/session-insights-getSession.feature +++ b/code/Test_definitions/session-insights-getSession.feature @@ -1,212 +1,232 @@ Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation getSession - As a developer integrating with CAMARA Session Insights API - I want to retrieve details of an existing session - So that I can check session status and configuration - - Background: - Given the Session Insights API is available - And I have a valid access token with appropriate scopes + # 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" is set to a UUID value + And the path parameter "sessionId" is set by default to an existing session sessionId - # Sunny day scenarios + # Success scenarios + @session_insights_getSession_01_retrieve_http_session Scenario: Retrieve existing HTTP session by sessionId - Given I have created an HTTP session with sessionId - When I send GET request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 200 response - And the response contains "id" property with the requested sessionId - And the response contains "protocol" property with value "HTTP" - And the response contains "device" property with device information - And the response contains "applicationServer" property - And the response contains "sink" property with webhook URL - And the response contains "subscribedEventTypes" array - And the response contains "startTime" property with valid date-time - And the response contains "expiresAt" property with valid date-time - And the response headers contain "x-correlator" - + 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 I have created an MQTT3 session with sessionId - When I send GET request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 200 response - And the response contains "id" property with the requested sessionId - And the response contains "protocol" property with value "MQTT3" - And the response contains "protocolSettings" with MQTT configuration - And the response contains "device" property with device information - And the response contains "applicationServer" property - And the response contains "subscribedEventTypes" array - And the response headers contain "x-correlator" - + 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 I have created an MQTT5 session with sessionId - When I send GET request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 200 response - And the response contains "id" property with the requested sessionId - And the response contains "protocol" property with value "MQTT5" - And the response contains "protocolSettings" with MQTT configuration - And the response headers contain "x-correlator" - + 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 I have created a session with applicationSessionId "meet-12345" - When I send GET request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 200 response - And the response contains "applicationSessionId" property with value "meet-12345" + 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 I have created a session with device phoneNumber - When I send GET request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 200 response - And the response contains "device" property with phoneNumber - And the device object contains exactly one identifier - + 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 I have created a session with device IPv4 address - When I send GET request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 200 response - And the response contains "device" property with IPv4 address - And the device object contains exactly one identifier - + 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 I have created a session with device IPv6 address - When I send GET request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 200 response - And the response contains "device" property with IPv6 address - And the device object contains exactly one identifier - + 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 I have created a session with device networkAccessIdentifier - When I send GET request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 200 response - And the response contains "device" property with networkAccessIdentifier - And the device object contains exactly one identifier - - # Rainy day scenarios - Path parameter validation - - Scenario: Retrieve session with invalid sessionId format - Given I have an invalid sessionId "not-a-uuid" - When I send GET request to "/sessions/{sessionId}" with invalid sessionId - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - And the response headers contain "x-correlator" - - Scenario: Retrieve session with empty sessionId - Given I have an empty sessionId - When I send GET request to "/sessions/{sessionId}" with empty sessionId - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - Scenario: Retrieve session with malformed UUID sessionId - Given I have a malformed UUID sessionId "123e4567-e89b-12d3-a456-42661417400" - When I send GET request to "/sessions/{sessionId}" with malformed sessionId - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Error scenarios - Resource not found - - Scenario: Retrieve non-existent session - Given I have a valid but non-existent sessionId - When I send GET request to "/sessions/{sessionId}" with non-existent sessionId - Then I receive a 404 response - And the response contains error code indicating resource not found - And the response headers contain "x-correlator" - - # Error scenarios - Authorization and permissions - - Scenario: Retrieve session without authentication - Given I do not have an access token - And I have a valid sessionId - When I send GET request to "/sessions/{sessionId}" without authentication - Then I receive a 401 response - And the response contains error code "UNAUTHENTICATED" - - Scenario: Retrieve session with invalid access token - Given I have an invalid access token - And I have a valid sessionId - When I send GET request to "/sessions/{sessionId}" with invalid authentication - Then I receive a 401 response - And the response contains error code "UNAUTHENTICATED" - - Scenario: Retrieve session without sufficient permissions - Given I have an access token without required scopes - And I have a valid sessionId - When I send GET request to "/sessions/{sessionId}" with insufficient permissions - Then I receive a 403 response - And the response contains error code indicating insufficient permissions - - Scenario: Retrieve session belonging to different user/device - Given I have a valid access token for user A - And I have a sessionId created by user B - When I send GET request to "/sessions/{sessionId}" to access other user's session - Then I receive a 403 response - And the response contains error code indicating insufficient permissions - - # Error scenarios - Session lifecycle - - Scenario: Retrieve expired session - Given I have a sessionId for an expired session - When I send GET request to "/sessions/{sessionId}" with expired sessionId - Then I receive a 410 response - And the response contains error code "GONE" - And the response headers contain "x-correlator" - - Scenario: Retrieve deleted session - Given I have a sessionId for a deleted session - When I send GET request to "/sessions/{sessionId}" with deleted sessionId - Then I receive a 410 response - And the response contains error code "GONE" - - # x-correlator header validation - - Scenario: Retrieve session with valid x-correlator header - Given I have a valid sessionId - And I provide a valid x-correlator header - When I send GET request to "/sessions/{sessionId}" with correlator - Then I receive a 200 response - And the response headers contain the same x-correlator value - - Scenario: Retrieve session with invalid x-correlator header format - Given I have a valid sessionId - And I provide an invalid x-correlator header with special characters - When I send GET request to "/sessions/{sessionId}" with invalid correlator - Then I receive a 400 response - And the response contains error code "INVALID_ARGUMENT" - - # Content negotiation - - Scenario: Retrieve session with unsupported Accept header - Given I have a valid sessionId - And I set Accept header to "text/xml" - When I send GET request to "/sessions/{sessionId}" with unsupported Accept - Then I receive a 406 response - And the response contains error indicating unsupported media type - - # Response schema validation - - Scenario: Verify response schema compliance for HTTP session - Given I have created an HTTP session - When I send GET request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 200 response - And the response body complies with Session schema - And all required properties are present - And all property types match the specification - - Scenario: Verify response schema compliance for MQTT session - Given I have created an MQTT session - When I send GET request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 200 response - And the response body complies with Session schema - And the protocolSettings contain required MQTT properties - And all property types match the specification - - # Edge cases - - Scenario: Retrieve session multiple times - Given I have created a session with sessionId - When I send GET request to "/sessions/{sessionId}" multiple times - Then I receive a 200 response each time - And the response data is consistent across requests - - Scenario: Retrieve session near expiration time - Given I have created a session that is near expiration - When I send GET request to "/sessions/{sessionId}" with valid sessionId - Then I receive a 200 response - And the response contains "expiresAt" property showing near expiration + 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 From 146e7ec81933b048fa50913fab07c1a1a94cb79f Mon Sep 17 00:00:00 2001 From: Ben Hepworth <125334035+benhepworth@users.noreply.github.com> Date: Thu, 17 Jul 2025 09:31:13 -0600 Subject: [PATCH 10/10] Update code/Test_definitions/session-insights-getSession.feature match commonalities 0.6 XCorellator Co-authored-by: Kevin Smith --- code/Test_definitions/session-insights-getSession.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Test_definitions/session-insights-getSession.feature b/code/Test_definitions/session-insights-getSession.feature index a4866fe..4ac5033 100644 --- a/code/Test_definitions/session-insights-getSession.feature +++ b/code/Test_definitions/session-insights-getSession.feature @@ -18,7 +18,7 @@ Feature: CAMARA Session Insights API, v0.1.0-rc.1 - Operation getSession 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" is set to a UUID value + 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