diff --git a/.github/workflows/run-ci.yaml b/.github/workflows/run-ci.yaml
index 846bee5f..cae140be 100644
--- a/.github/workflows/run-ci.yaml
+++ b/.github/workflows/run-ci.yaml
@@ -32,10 +32,6 @@ jobs:
token: ${{ secrets.PAT_CI }}
fetch-depth: 0
path: sinch-sdk-mockserver
- - name: Build custom Docker image
- run: |
- cd sinch-sdk-mockserver
- docker build -t sinch-sdk-mockserver -f Dockerfile .
- name: Install Docker Compose
run: |
sudo apt-get update
@@ -44,11 +40,6 @@ jobs:
run: |
cd sinch-sdk-mockserver
docker-compose up -d
- - name: Wait for the mock servers to be healthy
- run: |
- cd sinch-sdk-mockserver
- chmod +x ./scripts/healthcheck.sh
- ./scripts/healthcheck.sh
- name: Create target directories for feature files
run: |
mkdir -p ./packages/fax/tests/e2e/features
@@ -57,6 +48,7 @@ jobs:
mkdir -p ./packages/elastic-sip-trunking/tests/e2e/features
mkdir -p ./packages/sms/tests/e2e/features
mkdir -p ./packages/verification/tests/e2e/features
+ mkdir -p ./packages/voice/tests/e2e/features
- name: Copy feature files
run: |
cp sinch-sdk-mockserver/features/fax/*.feature ./packages/fax/tests/e2e/features/
@@ -65,6 +57,7 @@ jobs:
cp sinch-sdk-mockserver/features/elastic-sip-trunking/*.feature ./packages/elastic-sip-trunking/tests/e2e/features/
cp sinch-sdk-mockserver/features/sms/*.feature ./packages/sms/tests/e2e/features/
cp sinch-sdk-mockserver/features/verification/*.feature ./packages/verification/tests/e2e/features/
+ cp sinch-sdk-mockserver/features/voice/*.feature ./packages/voice/tests/e2e/features/
- name: Run e2e tests
run: |
yarn install
diff --git a/packages/voice/cucumber.js b/packages/voice/cucumber.js
new file mode 100644
index 00000000..691a9809
--- /dev/null
+++ b/packages/voice/cucumber.js
@@ -0,0 +1,8 @@
+module.exports = {
+ default: [
+ 'tests/e2e/features/**/*.feature',
+ '--require-module ts-node/register',
+ '--require tests/rest/v1/**/*.steps.ts',
+ `--format-options '{"snippetInterface": "synchronous"}'`,
+ ].join(' '),
+};
diff --git a/packages/voice/package.json b/packages/voice/package.json
index 473628fc..3a5528f4 100644
--- a/packages/voice/package.json
+++ b/packages/voice/package.json
@@ -25,7 +25,8 @@
"scripts": {
"build": "yarn run clean && yarn run compile",
"clean": "rimraf dist tsconfig.tsbuildinfo tsconfig.build.tsbuildinfo",
- "compile": "tsc -p tsconfig.build.json && tsc -p tsconfig.tests.json && rimraf dist/tests tsconfig.build.tsbuildinfo"
+ "compile": "tsc -p tsconfig.build.json && tsc -p tsconfig.tests.json && rimraf dist/tests tsconfig.build.tsbuildinfo",
+ "test:e2e": "cucumber-js"
},
"dependencies": {
"@sinch/sdk-client": "^1.1.0"
diff --git a/packages/voice/src/models/v1/conference-callout-request/conference-callout-request.ts b/packages/voice/src/models/v1/conference-callout-request/conference-callout-request.ts
index 6d7583da..54a96829 100644
--- a/packages/voice/src/models/v1/conference-callout-request/conference-callout-request.ts
+++ b/packages/voice/src/models/v1/conference-callout-request/conference-callout-request.ts
@@ -1,5 +1,6 @@
import { Destination } from '../destination';
import { ConferenceDtmfOptions } from '../conference-dtmf-options';
+import { MusicOnHold } from '../enums';
/**
* The conference callout calls a phone number or a user. When the call is answered, it's connected to a conference room.
@@ -28,7 +29,7 @@ export interface ConferenceCalloutRequest {
/** The text that will be spoken as a greeting. */
greeting?: string;
/** Means "music-on-hold." It's an optional parameter that specifies what the first participant should listen to while they're alone in the conference, waiting for other participants to join. It can take one of these pre-defined values:
- `ring` (progress tone)
- `music1` (music file)
- `music2` (music file)
- `music3` (music file)
If no “music-on-hold” is specified, the user will only hear silence. */
- mohClass?: string;
+ mohClass?: MusicOnHold;
/** Used to input custom data. */
custom?: string;
/** can be either “pstn” for PSTN endpoint or “mxp” for data (app or web) clients. */
diff --git a/packages/voice/tests/rest/v1/callouts/callouts.steps.ts b/packages/voice/tests/rest/v1/callouts/callouts.steps.ts
new file mode 100644
index 00000000..4f2662dd
--- /dev/null
+++ b/packages/voice/tests/rest/v1/callouts/callouts.steps.ts
@@ -0,0 +1,121 @@
+import { CalloutsApi, VoiceService, Voice } from '../../../../src';
+import { Given, When, Then } from '@cucumber/cucumber';
+import * as assert from 'assert';
+
+let calloutsApi: CalloutsApi;
+let ttsCallResponse: Voice.CalloutResponse;
+
+Given('the Voice service "Callouts" is available', () => {
+ const voiceService = new VoiceService({
+ applicationKey: 'appKey',
+ applicationSecret: 'appSecret',
+ voiceHostname: 'http://localhost:3019',
+ });
+ calloutsApi = voiceService.callouts;
+});
+
+When('I send a request to make a TTS call', async () => {
+ ttsCallResponse = await calloutsApi.tts({
+ ttsCalloutRequestBody: {
+ method: 'ttsCallout',
+ ttsCallout: {
+ cli: '+12015555555',
+ destination: {
+ type: 'number',
+ endpoint: '+12017777777',
+ },
+ locale: 'en-US',
+ text: 'Hello, this is a call from Sinch.',
+ },
+ },
+ });
+});
+
+Then('the callout response contains the TTS call ID', () => {
+ assert.equal(ttsCallResponse.callId, '1ce0ffee-ca11-ca11-ca11-abcdef000001');
+});
+
+When('I send a request to make a Conference call with the "Callout" service', async () => {
+ ttsCallResponse = await calloutsApi.conference({
+ conferenceCalloutRequestBody: {
+ method: 'conferenceCallout',
+ conferenceCallout: {
+ cli: '+12015555555',
+ destination: {
+ type: 'number',
+ endpoint: '+12017777777',
+ },
+ conferenceId: 'myConferenceId-E2E',
+ locale: 'en-US',
+ greeting: 'Welcome to this conference call.',
+ mohClass: 'music1',
+ },
+ },
+ });
+});
+
+Then('the callout response contains the Conference call ID', () => {
+ assert.equal(ttsCallResponse.callId, '1ce0ffee-ca11-ca11-ca11-abcdef000002');
+});
+
+When('I send a request to make a Custom call', async () => {
+ ttsCallResponse = await calloutsApi.custom({
+ customCalloutRequestBody: {
+ method: 'customCallout',
+ customCallout: {
+ cli: '+12015555555',
+ destination: {
+ type: 'number',
+ endpoint: '+12017777777',
+ },
+ custom: 'Custom text',
+ ice: Voice.customCalloutHelper.formatIceResponse(
+ Voice.iceActionHelper.connectPstn({
+ number: '+12017777777',
+ cli: '+12015555555',
+ }),
+ Voice.iceInstructionHelper.say('Welcome to Sinch.', 'en-US/male'),
+ Voice.iceInstructionHelper.startRecording({
+ destinationUrl: 'To specify',
+ credentials: 'To specify',
+ }),
+ ),
+ ace: Voice.customCalloutHelper.formatAceResponse(
+ Voice.aceActionHelper.runMenu({
+ locale: 'Kimberly',
+ enableVoice: true,
+ barge: true,
+ menus: [
+ {
+ id: 'main',
+ mainPrompt: '#tts[Welcome to the main menu. Press 1 to confirm order or 2 to cancel]',
+ repeatPrompt: '#tts[We didn\'t get your input, please try again]',
+ timeoutMills: 5000,
+ options: [
+ {
+ dtmf: '1',
+ action: 'menu(confirm)',
+ },
+ {
+ dtmf: '2',
+ action: 'return(cancel)',
+ },
+ ],
+ },
+ {
+ id: 'confirm',
+ mainPrompt: '#tts[Thank you for confirming your order. Enter your 4-digit PIN.]',
+ maxDigits: 4,
+ },
+ ],
+ }),
+ ),
+ pie: 'https://callback-server.com/voice',
+ },
+ },
+ });
+});
+
+Then('the callout response contains the Custom call ID', () => {
+ assert.equal(ttsCallResponse.callId, '1ce0ffee-ca11-ca11-ca11-abcdef000003');
+});