diff --git a/.github/workflows/pr_validation_caller.yml b/.github/workflows/pr_validation_caller.yml new file mode 100644 index 0000000..d847f6e --- /dev/null +++ b/.github/workflows/pr_validation_caller.yml @@ -0,0 +1,49 @@ +# ========================================================================================= +# CAMARA Project - Pull Request Validation Workflow Caller +# +# This GitHub Actions workflow is responsible for invoking a reusable PR validation workflow +# from the camaraproject/tooling repository. It is intended to ensure consistent validation +# steps for all PRs targeting the main branch in this repository. +# +# CHANGELOG: +# - 2025-08-01: Initial version for v0 +# +# USAGE: +# - Automatically triggers on pull requests targeting main. +# - Can be triggered manually via workflow_dispatch. +# - Calls by default the reusable workflow at +# camaraproject/tooling/.github/workflows/pr_validation.yml@v0 +# +# DOCUMENTATION: +# see https://github.com/camaraproject/tooling/tree/main/linting/docs +# ========================================================================================= + +name: Caller for PR validation workflow + +on: + # Trigger on pull requests to the main branch only + pull_request: + branches: main + # Enable manual trigger via the GitHub UI + workflow_dispatch: + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +permissions: + # Grant necessary write permissions for PRs, contents, and issues + pull-requests: write + contents: write + issues: write + statuses: write + +jobs: + pr_validation: + # Invoke the reusable PR validation workflow from "v0" tag of camaraproject/tooling + uses: camaraproject/tooling/.github/workflows/pr_validation.yml@v0 + secrets: inherit +# Tools configuration from the tooling repository subfolder of /linting/config/ indicated by `configurations` variable +# If needed, you can specify a configuration from another subfolder of camaraproject/tooling/linting/config/ (uncomment below) +# with: +# configurations: api-name diff --git a/.github/workflows/spectral-oas-caller.yml b/.github/workflows/spectral-oas-caller.yml new file mode 100644 index 0000000..05cde3f --- /dev/null +++ b/.github/workflows/spectral-oas-caller.yml @@ -0,0 +1,42 @@ +# ========================================================================================= +# CAMARA Project - Linting OpenAPI Specification with CAMARA Ruleset Caller +# +# This GitHub Actions workflow is responsible for invoking a reusable "Spectral linting with +# CAMARA ruleset" workflow from the camaraproject/tooling repository. It is intended to +# provide more detailed output from Spectral tool (warnings, hints) +# +# CHANGELOG: +# - 2025-08-01: Initial version for v0 +# +# USAGE: +# - Can be triggered manually via workflow_dispatch. +# - Calls by default the reusable workflow at +# camaraproject/tooling/.github/workflows/spectral-oas.yml@v0 +# +# DOCUMENTATION: +# see https://github.com/camaraproject/tooling/tree/main/linting/docs +# ========================================================================================= + +name: Caller for Spectral linting with CAMARA ruleset + +on: + workflow_dispatch: + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +permissions: + # Grant necessary write permissions for PRs and issues + pull-requests: write + contents: read + issues: write + +jobs: + spectral: + # Invoke the reusable PR validation workflow from the main branch of camaraproject/tooling + uses: camaraproject/tooling/.github/workflows/spectral-oas.yml@v0 +# Spectral configuration from the tooling repository subfolder of /linting/config/ indicated by `configurations` variable +# If needed, you can specify a configuration from another subfolder of camaraproject/tooling/linting/config/ (uncomment below) +# with: +# configurations: api-name diff --git a/code/API_definitions/click-to-dial.yaml b/code/API_definitions/click-to-dial.yaml index 31fa375..bf41da0 100644 --- a/code/API_definitions/click-to-dial.yaml +++ b/code/API_definitions/click-to-dial.yaml @@ -615,7 +615,7 @@ components: status: 401 code: UNAUTHENTICATED message: Request not authenticated due to missing, invalid, or expired credentials. - + Generic403: description: Forbidden headers: @@ -637,7 +637,7 @@ components: value: status: 403 code: INVALID_TOKEN_CONTEXT - message: "{{field}} is not consistent with access token." + message: "{{field}} is not consistent with access token." Generic404: description: Not found diff --git a/code/Test_definitions/click-to-dial-createCall.feature b/code/Test_definitions/click-to-dial-createCall.feature index a1aeb4a..1cef225 100644 --- a/code/Test_definitions/click-to-dial-createCall.feature +++ b/code/Test_definitions/click-to-dial-createCall.feature @@ -43,17 +43,30 @@ Feature: CAMARA Click to Dial API, vwip - Operation createCall And the event header "Authorization" is set to "Bearer " + the value of the request property "$.sinkCredential.accessToken" And the event header "Content-Type" is "application/cloudevents+json" And the event body complies with the OAS schema at "#/components/schemas/EventCTDStatusChanged" - # Additional constraints beyond schema compliance - And the event body property "$.id" is unique - And the event body property "$.type" is set to "org.camaraproject.click-to-dial.v0.status-changed" - And the event body property "$.data.callId" has the same value as createCall response property "$.callId" - And the event body property "$.data.caller" has the same value as createCall request property "$.caller" - And the event body property "$.data.callee" has the same value as createCall request property "$.callee" - And the event body property "$.data.status.state" is "initiating" or "callingCaller" or "callingCallee" or "connected" or "disconnected" or "failed" - And the event body property "$.data.status.reason" exists only if "$.data.status.state" is "disconnected" and the value is "hangUp" or "callerBusy" or "callerNoAnswer" or "callerFailure" or "callerAbandon" or "calleeBusy" or "calleeNoAnswer" or "calleeFailure" or "other" - And the event body property "$.data.recordingResult" is "success" or "noRecord" or "fail" if present - And the event body property "$.data.callDuration" exists only if "$.data.status.state" is "disconnected" - And the event body property "$.data.timestamp" is set to the time of state change + + @createcall_event_notification + Scenario: Event body fields follow ClickToDial status rules + Given the request property "$.caller" is set to a valid caller number in E.164 format + And the request property "$.callee" is set to a valid callee number in E.164 format + And the request property "$.sink" is set to a URL where events can be monitored + And the request property "$.sinkCredential.credentialType" is set to "ACCESSTOKEN" + And the request property "$.sinkCredential.accessTokenType" is set to "bearer" + And the request property "$.sinkCredential.accessToken" is set to a valid access token accepted by the events receiver + And the request property "$.sinkCredential.accessTokenExpiresUtc" is set to a future RFC3339 timestamp + When the request "createCall" is sent + And an event is received at the address of the request property "$.sink" + Then the event body fields follow the ClickToDial status rules + | path | rule | + | $.id | unique per event | + | $.type | = "org.camaraproject.click-to-dial.v0.status-changed" | + | $.data.callId | = createCall response property "$.callId" | + | $.data.caller | = createCall request property "$.caller" | + | $.data.callee | = createCall request property "$.callee" | + | $.data.status.state | in [initiating, callingCaller, callingCallee, connected, disconnected, failed] | + | $.data.status.reason | present iff state="disconnected" and in [hangUp, callerBusy, callerNoAnswer, callerFailure, callerAbandon, calleeBusy, calleeNoAnswer, calleeFailure, other] | + | $.data.recordingResult | optional; if present, in [success, noRecord, fail] | + | $.data.callDuration | present iff state="disconnected" | + | $.data.timestamp | time of state change | @createcall_failure_missing_fields Scenario: Fail to initiate call due to missing required fields in createCall request