From 28f566884145de6bf08ac6ef9ea38f8861bdd530 Mon Sep 17 00:00:00 2001 From: Antoine SEIN <142824551+asein-sinch@users.noreply.github.com> Date: Tue, 30 Apr 2024 15:39:49 +0200 Subject: [PATCH] DEVEXP-406: Add support for SIP Trunks (#76) --- examples/simple-examples/README.md | 15 + examples/simple-examples/package.json | 8 + examples/simple-examples/src/config.ts | 15 +- .../elastic-sip-trunking/sip-trunks/addACL.ts | 38 +++ .../elastic-sip-trunking/sip-trunks/create.ts | 27 ++ .../elastic-sip-trunking/sip-trunks/delete.ts | 20 ++ .../sip-trunks/deleteACL.ts | 26 ++ .../elastic-sip-trunking/sip-trunks/get.ts | 31 ++ .../elastic-sip-trunking/sip-trunks/list.ts | 64 ++++ .../sip-trunks/listACLs.ts | 44 +++ .../elastic-sip-trunking/sip-trunks/update.ts | 35 +++ packages/elastic-sip-trunking/src/index.ts | 1 + .../elastic-sip-trunking/src/models/index.ts | 1 + .../add-access-control-list-to-trunk.ts | 6 + .../add-access-control-list-to-trunk/index.ts | 1 + .../src/models/v1/index.ts | 4 + .../src/models/v1/requests/index.ts | 1 + .../sip-trunks/sip-trunks-request-data.ts | 45 +++ .../src/models/v1/sip-trunk/index.ts | 1 + .../src/models/v1/sip-trunk/sip-trunk.ts | 27 ++ .../rest/v1/elastic-sip-trunking-service.ts | 15 +- .../elastic-sip-trunking/src/rest/v1/index.ts | 1 + .../src/rest/v1/sip-trunks/index.ts | 2 + .../sip-trunks/sip-trunks-api.jest.fixture.ts | 57 ++++ .../src/rest/v1/sip-trunks/sip-trunks-api.ts | 295 ++++++++++++++++++ .../rest/v1/sip-trunks/sip-trunks-api.test.ts | 252 +++++++++++++++ 26 files changed, 1024 insertions(+), 8 deletions(-) create mode 100644 examples/simple-examples/src/elastic-sip-trunking/sip-trunks/addACL.ts create mode 100644 examples/simple-examples/src/elastic-sip-trunking/sip-trunks/create.ts create mode 100644 examples/simple-examples/src/elastic-sip-trunking/sip-trunks/delete.ts create mode 100644 examples/simple-examples/src/elastic-sip-trunking/sip-trunks/deleteACL.ts create mode 100644 examples/simple-examples/src/elastic-sip-trunking/sip-trunks/get.ts create mode 100644 examples/simple-examples/src/elastic-sip-trunking/sip-trunks/list.ts create mode 100644 examples/simple-examples/src/elastic-sip-trunking/sip-trunks/listACLs.ts create mode 100644 examples/simple-examples/src/elastic-sip-trunking/sip-trunks/update.ts create mode 100644 packages/elastic-sip-trunking/src/models/index.ts create mode 100644 packages/elastic-sip-trunking/src/models/v1/add-access-control-list-to-trunk/add-access-control-list-to-trunk.ts create mode 100644 packages/elastic-sip-trunking/src/models/v1/add-access-control-list-to-trunk/index.ts create mode 100644 packages/elastic-sip-trunking/src/models/v1/index.ts create mode 100644 packages/elastic-sip-trunking/src/models/v1/requests/index.ts create mode 100644 packages/elastic-sip-trunking/src/models/v1/requests/sip-trunks/sip-trunks-request-data.ts create mode 100644 packages/elastic-sip-trunking/src/models/v1/sip-trunk/index.ts create mode 100644 packages/elastic-sip-trunking/src/models/v1/sip-trunk/sip-trunk.ts create mode 100644 packages/elastic-sip-trunking/src/rest/v1/sip-trunks/index.ts create mode 100644 packages/elastic-sip-trunking/src/rest/v1/sip-trunks/sip-trunks-api.jest.fixture.ts create mode 100644 packages/elastic-sip-trunking/src/rest/v1/sip-trunks/sip-trunks-api.ts create mode 100644 packages/elastic-sip-trunking/tests/rest/v1/sip-trunks/sip-trunks-api.test.ts diff --git a/examples/simple-examples/README.md b/examples/simple-examples/README.md index 6888a735..108475f0 100644 --- a/examples/simple-examples/README.md +++ b/examples/simple-examples/README.md @@ -75,6 +75,9 @@ FAX_SERVICE_ID=serviceId to fill with one the fax services created with the Fax FAX_ID=id from a sendFax response FAX_CALLBACK_URL=callback url to override the one defined in the default service or specified service FAX_EMAIL=email to associate with a phone number to use the fax-to-email functionality +## Elastic SIP Trunking API +SIP_TRUNK_ID=sipTrunkId to fill with one of the SIP trunk created with the Elastic SIP Trunking API +ACL_ID=accessControlList Id to fill with one of the access control list created with the Elastic SIP Trunking API ``` **Note**: If you prefer using environment variables, the sample app is also supporting them: they take precedence over the value from the `.env` file. @@ -270,3 +273,15 @@ yarn run numbers:regions:list | | [./src/fax/emails/update.ts](./src/fax/emails/update.ts) | `FAX_EMAIL` + `PHONE_NUMBER` | | | [./src/fax/emails/delete.ts](./src/fax/emails/delete.ts) | `FAX_EMAIL` | +### Elastic SIP Trunk + +| Service | Sample application name and location | Required parameters | +|------------|----------------------------------------------------------------------------------------------------------|----------------------| +| SIP Trunks | [./src/elastic-sip-trunking/sip-trunks/create.ts](./src/elastic-sip-trunking/sip-trunks/create.ts) | | +| | [./src/elastic-sip-trunking/sip-trunks/get.ts](./src/elastic-sip-trunking/sip-trunks/get.ts) | SIP_TRUNK_ID | +| | [./src/elastic-sip-trunking/sip-trunks/list.ts](./src/elastic-sip-trunking/sip-trunks/list.ts) | | +| | [./src/elastic-sip-trunking/sip-trunks/update.ts](./src/elastic-sip-trunking/sip-trunks/update.ts) | SIP_TRUNK_ID | +| | [./src/elastic-sip-trunking/sip-trunks/delete.ts](./src/elastic-sip-trunking/sip-trunks/delete.ts) | SIP_TRUNK_ID | +| | [./src/elastic-sip-trunking/sip-trunks/addACL.ts](./src/elastic-sip-trunking/sip-trunks/addACL.ts) | SIP_TRUNK_ID, ACL_ID | +| | [./src/elastic-sip-trunking/sip-trunks/listACLs.ts](./src/elastic-sip-trunking/sip-trunks/listACLs.ts) | SIP_TRUNK_ID | +| | [./src/elastic-sip-trunking/sip-trunks/deleteACL.ts](./src/elastic-sip-trunking/sip-trunks/deleteACL.ts) | SIP_TRUNK_ID, ACL_ID | diff --git a/examples/simple-examples/package.json b/examples/simple-examples/package.json index 3145c819..dc7ee5c4 100644 --- a/examples/simple-examples/package.json +++ b/examples/simple-examples/package.json @@ -71,6 +71,14 @@ "conversation:templatev2:listTranslations": "ts-node src/conversation/templates-v2/list-translations.ts", "conversation:templatev2:update": "ts-node src/conversation/templates-v2/update.ts", "conversation:templatev2:delete": "ts-node src/conversation/templates-v2/delete.ts", + "elasticSipTrunks:sipTrunk:create": "ts-node src/elastic-sip-trunking/sip-trunks/create.ts", + "elasticSipTrunks:sipTrunk:get": "ts-node src/elastic-sip-trunking/sip-trunks/get.ts", + "elasticSipTrunks:sipTrunk:list": "ts-node src/elastic-sip-trunking/sip-trunks/list.ts", + "elasticSipTrunks:sipTrunk:update": "ts-node src/elastic-sip-trunking/sip-trunks/update.ts", + "elasticSipTrunks:sipTrunk:delete": "ts-node src/elastic-sip-trunking/sip-trunks/delete.ts", + "elasticSipTrunks:sipTrunk:addACL": "ts-node src/elastic-sip-trunking/sip-trunks/addACL.ts", + "elasticSipTrunks:sipTrunk:listACLs": "ts-node src/elastic-sip-trunking/sip-trunks/listACLs.ts", + "elasticSipTrunks:sipTrunk:deleteACL": "ts-node src/elastic-sip-trunking/sip-trunks/deleteACL.ts", "fax:services:create": "ts-node src/fax/services/create.ts", "fax:services:get": "ts-node src/fax/services/get.ts", "fax:services:list": "ts-node src/fax/services/list.ts", diff --git a/examples/simple-examples/src/config.ts b/examples/simple-examples/src/config.ts index 8445fd6e..e131a71f 100644 --- a/examples/simple-examples/src/config.ts +++ b/examples/simple-examples/src/config.ts @@ -7,10 +7,11 @@ import { SmsService, VerificationService, VoiceService, + ElasticSipTrunkingService, } from '@sinch/sdk-core'; require('dotenv').config(); -const initClient = (): Pick => { +const initClient = (): Pick => { const keyId = process.env.SINCH_KEY_ID || ''; const keySecret = process.env.SINCH_KEY_SECRET || ''; const projectId = process.env.SINCH_PROJECT_ID || ''; @@ -21,6 +22,10 @@ export const initConversationService = (): ConversationService => { return initClient().conversation; }; +export const initElasticSipTrunkingService = (): ElasticSipTrunkingService => { + return initClient().elasticSipTrunking; +}; + export const initFaxService = (): FaxService => { return initClient().fax; }; @@ -198,6 +203,14 @@ export const getFaxEmailFromConfig = () => { return readVariable('FAX_EMAIL'); }; +export const getSipTrunkIdFromConfig = () => { + return readVariable('SIP_TRUNK_ID'); +}; + +export const getAccessControlListIdFromConfig = () => { + return readVariable('ACL_ID'); +}; + const readVariable = ( name: string): string => { const value = process.env[name]; if (!value) { diff --git a/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/addACL.ts b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/addACL.ts new file mode 100644 index 00000000..117ddb1b --- /dev/null +++ b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/addACL.ts @@ -0,0 +1,38 @@ +import { ElasticSipTrunking } from '@sinch/sdk-core'; +import { + getAccessControlListIdFromConfig, + getPrintFormat, + getSipTrunkIdFromConfig, + initElasticSipTrunkingService, + printFullResponse, +} from '../../config'; + +(async () => { + console.log('*******************************'); + console.log('* addAccessControlListToTrunk *'); + console.log('*******************************'); + + const sipTrunkId = getSipTrunkIdFromConfig(); + const aclId = getAccessControlListIdFromConfig(); + + const requestData: ElasticSipTrunking.AddAccessControlListToTrunkRequestData = { + trunkId: sipTrunkId, + addAccessControlListToTrunkRequestBody: { + accessControlListIds: [ + aclId, + ], + }, + }; + + const elasticSipTrunkingService = initElasticSipTrunkingService(); + const response = await elasticSipTrunkingService.sipTrunks.addAccessControlList(requestData); + + const printFormat = getPrintFormat(process.argv); + + if (printFormat === 'pretty') { + console.log(`The SIP trunk with the id '${requestData.trunkId}' contains the following ACL IDs:\n - ${response.accessControlListIds?.join('\n - ')}`); + } else { + printFullResponse(response); + } + +})(); diff --git a/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/create.ts b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/create.ts new file mode 100644 index 00000000..175c1831 --- /dev/null +++ b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/create.ts @@ -0,0 +1,27 @@ +import { ElasticSipTrunking } from '@sinch/sdk-core'; +import { getPrintFormat, initElasticSipTrunkingService, printFullResponse } from '../../config'; + +(async () => { + console.log('******************'); + console.log('* createSipTrunk *'); + console.log('******************'); + + const requestData: ElasticSipTrunking.CreateSipTrunkRequestData = { + createSipTrunkRequestBody: { + name: 'Node.js SDK Sinch Trunk', + hostName: 'node-js-sdk-sinch', + }, + }; + + const elasticSipTrunkingService = initElasticSipTrunkingService(); + const response = await elasticSipTrunkingService.sipTrunks.create(requestData); + + const printFormat = getPrintFormat(process.argv); + + if (printFormat === 'pretty') { + console.log(`New SIP trunk created with the id '${response.id}'`); + } else { + printFullResponse(response); + } + +})(); diff --git a/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/delete.ts b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/delete.ts new file mode 100644 index 00000000..c0f63d7b --- /dev/null +++ b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/delete.ts @@ -0,0 +1,20 @@ +import { ElasticSipTrunking } from '@sinch/sdk-core'; +import { getSipTrunkIdFromConfig, initElasticSipTrunkingService } from '../../config'; + +(async () => { + console.log('******************'); + console.log('* deleteSipTrunk *'); + console.log('******************'); + + const sipTrunkId = getSipTrunkIdFromConfig(); + + const requestData: ElasticSipTrunking.DeleteSipTrunkRequestData = { + sipTrunkId, + }; + + const elasticSipTrunkingService = initElasticSipTrunkingService(); + await elasticSipTrunkingService.sipTrunks.delete(requestData); + + console.log(`The SIP trunk with the id '${requestData.sipTrunkId}' has been deleted.`); + +})(); diff --git a/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/deleteACL.ts b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/deleteACL.ts new file mode 100644 index 00000000..bef50a6b --- /dev/null +++ b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/deleteACL.ts @@ -0,0 +1,26 @@ +import { ElasticSipTrunking } from '@sinch/sdk-core'; +import { + getAccessControlListIdFromConfig, + getSipTrunkIdFromConfig, + initElasticSipTrunkingService, +} from '../../config'; + +(async () => { + console.log('************************************'); + console.log('* deleteAccessControlListFromTrunk *'); + console.log('************************************'); + + const sipTrunkId = getSipTrunkIdFromConfig(); + const aclId = getAccessControlListIdFromConfig(); + + const requestData: ElasticSipTrunking.DeleteAccessControlListFromTrunkRequestData = { + trunkId: sipTrunkId, + accessControlListId: aclId, + }; + + const elasticSipTrunkingService = initElasticSipTrunkingService(); + await elasticSipTrunkingService.sipTrunks.deleteAccessControlList(requestData); + + console.log(`The ACL '${requestData.accessControlListId}' has been removed fromm the SIP trunk '${requestData.trunkId}'`); + +})(); diff --git a/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/get.ts b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/get.ts new file mode 100644 index 00000000..cd5e65ec --- /dev/null +++ b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/get.ts @@ -0,0 +1,31 @@ +import { ElasticSipTrunking } from '@sinch/sdk-core'; +import { + getPrintFormat, + getSipTrunkIdFromConfig, + initElasticSipTrunkingService, + printFullResponse, +} from '../../config'; + +(async () => { + console.log('*******************'); + console.log('* getSipTrunkById *'); + console.log('*******************'); + + const sipTrunkId = getSipTrunkIdFromConfig(); + + const requestData: ElasticSipTrunking.GetSipTrunkRequestData = { + sipTrunkId, + }; + + const elasticSipTrunkingService = initElasticSipTrunkingService(); + const response = await elasticSipTrunkingService.sipTrunks.get(requestData); + + const printFormat = getPrintFormat(process.argv); + + if (printFormat === 'pretty') { + console.log(`The SIP trunk with the id '${response.id}' is named '${response.name}' and has been created at '${response.createTime?.toISOString()}'`); + } else { + printFullResponse(response); + } + +})(); diff --git a/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/list.ts b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/list.ts new file mode 100644 index 00000000..b40426e3 --- /dev/null +++ b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/list.ts @@ -0,0 +1,64 @@ +import { ElasticSipTrunking, PageResult } from '@sinch/sdk-core'; +import { getPrintFormat, initElasticSipTrunkingService, printFullResponse } from '../../config'; + +const populateSipTrunksList = ( + sipTrunkPage: PageResult, + sipTrunksList: ElasticSipTrunking.SipTrunk[], + sipTrunksDetailsList: string[], +) => { + sipTrunkPage.data.map((sipTrunk: ElasticSipTrunking.SipTrunk) => { + sipTrunksList.push(sipTrunk); + sipTrunksDetailsList.push(`${sipTrunk.id} - ${sipTrunk.name}`); + }); +}; + +(async () => { + console.log('****************'); + console.log('* getSipTrunks *'); + console.log('****************'); + + const requestData: ElasticSipTrunking.ListSipTrunksRequestData = {}; + + const elasticSipTrunkingService = initElasticSipTrunkingService(); + + // ---------------------------------------------- + // Method 1: Fetch the data page by page manually + // ---------------------------------------------- + let response = await elasticSipTrunkingService.sipTrunks.list(requestData); + + const sipTrunksList: ElasticSipTrunking.SipTrunk[] = []; + const sipTrunksDetailsList: string[] = []; + + // Loop on all the pages to get all the active numbers + let reachedEndOfPages = false; + while (!reachedEndOfPages) { + populateSipTrunksList(response, sipTrunksList, sipTrunksDetailsList); + if (response.hasNextPage) { + response = await response.nextPage(); + } else { + reachedEndOfPages = true; + } + } + + const printFormat = getPrintFormat(process.argv); + + if (printFormat === 'pretty') { + console.log(sipTrunksDetailsList.length > 0 + ? 'List of SIP trunks:\n' + sipTrunksDetailsList.join('\n') + : 'Sorry, no SIP trunks were found.'); + } else { + printFullResponse(sipTrunksList); + } + + // --------------------------------------------------------------------- + // Method 2: Use the iterator and fetch data on more pages automatically + // --------------------------------------------------------------------- + for await (const sipTrunk of elasticSipTrunkingService.sipTrunks.list(requestData)) { + if (printFormat === 'pretty') { + console.log(`${sipTrunk.id} - ${sipTrunk.name}`); + } else { + console.log(sipTrunk); + } + } + +})(); diff --git a/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/listACLs.ts b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/listACLs.ts new file mode 100644 index 00000000..bf3ab3bd --- /dev/null +++ b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/listACLs.ts @@ -0,0 +1,44 @@ +import { ElasticSipTrunking } from '@sinch/sdk-core'; +import { getSipTrunkIdFromConfig, initElasticSipTrunkingService, printFullResponse } from '../../config'; + +(async () => { + console.log('*********************************'); + console.log('* getAccessControlListsForTrunk *'); + console.log('*********************************'); + + const sipTrunkId = getSipTrunkIdFromConfig(); + + const requestData: ElasticSipTrunking.ListAccessControlListsForTrunkRequestData = { + trunkId: sipTrunkId, + }; + + const elasticSipTrunkingService = initElasticSipTrunkingService(); + + // ---------------------------------------------- + // Method 1: Fetch the data page by page manually + // ---------------------------------------------- + let response = await elasticSipTrunkingService.sipTrunks.listAccessControlLists(requestData); + + const aclList: string[] = []; + + // Loop on all the pages to get all the active numbers + let reachedEndOfPages = false; + while (!reachedEndOfPages) { + aclList.push(...response.data); + if (response.hasNextPage) { + response = await response.nextPage(); + } else { + reachedEndOfPages = true; + } + } + + printFullResponse(aclList); + + // --------------------------------------------------------------------- + // Method 2: Use the iterator and fetch data on more pages automatically + // --------------------------------------------------------------------- + for await (const acl of elasticSipTrunkingService.sipTrunks.listAccessControlLists(requestData)) { + console.log(acl); + } + +})(); diff --git a/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/update.ts b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/update.ts new file mode 100644 index 00000000..956eb5eb --- /dev/null +++ b/examples/simple-examples/src/elastic-sip-trunking/sip-trunks/update.ts @@ -0,0 +1,35 @@ +import { ElasticSipTrunking } from '@sinch/sdk-core'; +import { + getPrintFormat, + getSipTrunkIdFromConfig, + initElasticSipTrunkingService, + printFullResponse, +} from '../../config'; + +(async () => { + console.log('******************'); + console.log('* updateSipTrunk *'); + console.log('******************'); + + const sipTrunkId = getSipTrunkIdFromConfig(); + + const requestData: ElasticSipTrunking.UpdateSipTrunkRequestData = { + sipTrunkId, + updateSipTrunkRequestBody: { + name: 'Node.js SDK Sinch Trunk Reloaded', + hostName: 'node-js-sdk-sinch-reloaded', + }, + }; + + const elasticSipTrunkingService = initElasticSipTrunkingService(); + const response = await elasticSipTrunkingService.sipTrunks.update(requestData); + + const printFormat = getPrintFormat(process.argv); + + if (printFormat === 'pretty') { + console.log(`The SIP trunk with the id '${response.id}' has been updated at '${response.updateTime?.toISOString()}'. Its new name is '${response.name}'`); + } else { + printFullResponse(response); + } + +})(); diff --git a/packages/elastic-sip-trunking/src/index.ts b/packages/elastic-sip-trunking/src/index.ts index bb7724b7..f5cfc836 100644 --- a/packages/elastic-sip-trunking/src/index.ts +++ b/packages/elastic-sip-trunking/src/index.ts @@ -1,2 +1,3 @@ +export * as ElasticSipTrunking from './models'; export * from './rest'; export * from '@sinch/sdk-client'; diff --git a/packages/elastic-sip-trunking/src/models/index.ts b/packages/elastic-sip-trunking/src/models/index.ts new file mode 100644 index 00000000..5b98253d --- /dev/null +++ b/packages/elastic-sip-trunking/src/models/index.ts @@ -0,0 +1 @@ +export * from './v1'; diff --git a/packages/elastic-sip-trunking/src/models/v1/add-access-control-list-to-trunk/add-access-control-list-to-trunk.ts b/packages/elastic-sip-trunking/src/models/v1/add-access-control-list-to-trunk/add-access-control-list-to-trunk.ts new file mode 100644 index 00000000..9bb30577 --- /dev/null +++ b/packages/elastic-sip-trunking/src/models/v1/add-access-control-list-to-trunk/add-access-control-list-to-trunk.ts @@ -0,0 +1,6 @@ + +export interface AddAccessControlListToTrunk { + + /** Array of AccessControlList ids */ + accessControlListIds?: string[]; +} diff --git a/packages/elastic-sip-trunking/src/models/v1/add-access-control-list-to-trunk/index.ts b/packages/elastic-sip-trunking/src/models/v1/add-access-control-list-to-trunk/index.ts new file mode 100644 index 00000000..493dca3f --- /dev/null +++ b/packages/elastic-sip-trunking/src/models/v1/add-access-control-list-to-trunk/index.ts @@ -0,0 +1 @@ +export type { AddAccessControlListToTrunk } from './add-access-control-list-to-trunk'; diff --git a/packages/elastic-sip-trunking/src/models/v1/index.ts b/packages/elastic-sip-trunking/src/models/v1/index.ts new file mode 100644 index 00000000..48f1fd82 --- /dev/null +++ b/packages/elastic-sip-trunking/src/models/v1/index.ts @@ -0,0 +1,4 @@ +export * from './add-access-control-list-to-trunk'; +export * from './sip-trunk'; + +export * from './requests'; diff --git a/packages/elastic-sip-trunking/src/models/v1/requests/index.ts b/packages/elastic-sip-trunking/src/models/v1/requests/index.ts new file mode 100644 index 00000000..56ee01d7 --- /dev/null +++ b/packages/elastic-sip-trunking/src/models/v1/requests/index.ts @@ -0,0 +1 @@ +export * from './sip-trunks/sip-trunks-request-data'; diff --git a/packages/elastic-sip-trunking/src/models/v1/requests/sip-trunks/sip-trunks-request-data.ts b/packages/elastic-sip-trunking/src/models/v1/requests/sip-trunks/sip-trunks-request-data.ts new file mode 100644 index 00000000..24197c43 --- /dev/null +++ b/packages/elastic-sip-trunking/src/models/v1/requests/sip-trunks/sip-trunks-request-data.ts @@ -0,0 +1,45 @@ +import { AddAccessControlListToTrunk } from '../../add-access-control-list-to-trunk'; +import { SipTrunk } from '../../sip-trunk'; + +export interface AddAccessControlListToTrunkRequestData { + /** The ID of the trunk that you want to work with */ + 'trunkId': string; + /** The body containing the list of ACLs to add to the SIP trunk */ + 'addAccessControlListToTrunkRequestBody': AddAccessControlListToTrunk; +} +export interface CreateSipTrunkRequestData { + /** The SIP trunk details to be used to create a SIP trunk */ + 'createSipTrunkRequestBody': SipTrunk; +} +export interface DeleteAccessControlListFromTrunkRequestData { + /** The ID of the trunk that you want to work with */ + 'trunkId': string; + /** The ID of the access control list entry. that you want to remove from trunk */ + 'accessControlListId': string; +} +export interface DeleteSipTrunkRequestData { + /** The ID of the SIP trunk. */ + 'sipTrunkId': string; +} +export interface ListAccessControlListsForTrunkRequestData { + /** The ID of the trunk that you want to work with */ + 'trunkId': string; +} +export interface GetSipTrunkRequestData { + /** The ID of the SIP trunk. */ + 'sipTrunkId': string; +} +export interface ListSipTrunksRequestData { + /** The page you want to fetch, can set to 1 for first page, or omitted for first page */ + 'page'?: number; + /** The size of each page to fetch */ + 'pageSize'?: number; + /** Filter by domain */ + 'domain'?: string; +} +export interface UpdateSipTrunkRequestData { + /** The ID of the SIP trunk. */ + 'sipTrunkId': string; + /** The SIP trunk details to be used to update the SIP trunk */ + 'updateSipTrunkRequestBody': SipTrunk; +} diff --git a/packages/elastic-sip-trunking/src/models/v1/sip-trunk/index.ts b/packages/elastic-sip-trunking/src/models/v1/sip-trunk/index.ts new file mode 100644 index 00000000..2413627d --- /dev/null +++ b/packages/elastic-sip-trunking/src/models/v1/sip-trunk/index.ts @@ -0,0 +1 @@ +export type { SipTrunk } from './sip-trunk'; diff --git a/packages/elastic-sip-trunking/src/models/v1/sip-trunk/sip-trunk.ts b/packages/elastic-sip-trunking/src/models/v1/sip-trunk/sip-trunk.ts new file mode 100644 index 00000000..8bd1cc9b --- /dev/null +++ b/packages/elastic-sip-trunking/src/models/v1/sip-trunk/sip-trunk.ts @@ -0,0 +1,27 @@ + +/** + * A created SIP trunk. + */ +export interface SipTrunk { + + /** The SIP trunk id. */ + id?: string; + /** The host of the domain you would like to have for you trunk. */ + hostName: string; + /** The top level domain to which the SIP trunk belongs. */ + topLevelDomain?: string; + /** The fully qualified name of the domain, which is a combination of your \'hostName\' and the \'topLevelDomain\'. */ + domain?: string; + /** The friendly name of your SIP trunk. */ + name: string; + /** Number of calls started per second, to increase this please contact your account manager. */ + callsPerSecond?: number; + /** Enable caller name lookup for incoming calls. US and canada only. */ + enableCallerName?: boolean; + /** The date and time that the SIP trunk was created. */ + createTime?: Date; + /** The date and time that the SIP trunk was last modified. */ + updateTime?: Date; + /** The ID of the account. */ + projectId?: string; +} diff --git a/packages/elastic-sip-trunking/src/rest/v1/elastic-sip-trunking-service.ts b/packages/elastic-sip-trunking/src/rest/v1/elastic-sip-trunking-service.ts index cb2578fb..71f0f375 100644 --- a/packages/elastic-sip-trunking/src/rest/v1/elastic-sip-trunking-service.ts +++ b/packages/elastic-sip-trunking/src/rest/v1/elastic-sip-trunking-service.ts @@ -1,19 +1,20 @@ import { SinchClientParameters } from '@sinch/sdk-client'; +import { SipTrunksApi } from './sip-trunks'; export class ElasticSipTrunkingService { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - constructor(_params: SinchClientParameters) { + public readonly sipTrunks: SipTrunksApi; + constructor(params: SinchClientParameters) { + this.sipTrunks = new SipTrunksApi(params); } /** - * Update the default basePath for each API + * Update the default hostname for each API * - * @param {string} _basePath - The new base path to use for all the APIs. + * @param {string} hostname - The new hostname to use for all the APIs. */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public setBasePath(_basePath: string) { - + public setHostname(hostname: string) { + this.sipTrunks.setHostname(hostname); } } diff --git a/packages/elastic-sip-trunking/src/rest/v1/index.ts b/packages/elastic-sip-trunking/src/rest/v1/index.ts index e45986c4..767f01d1 100644 --- a/packages/elastic-sip-trunking/src/rest/v1/index.ts +++ b/packages/elastic-sip-trunking/src/rest/v1/index.ts @@ -1 +1,2 @@ +export * from './sip-trunks'; export * from './elastic-sip-trunking-service'; diff --git a/packages/elastic-sip-trunking/src/rest/v1/sip-trunks/index.ts b/packages/elastic-sip-trunking/src/rest/v1/sip-trunks/index.ts new file mode 100644 index 00000000..a15b43b9 --- /dev/null +++ b/packages/elastic-sip-trunking/src/rest/v1/sip-trunks/index.ts @@ -0,0 +1,2 @@ +export * from './sip-trunks-api'; +export * from './sip-trunks-api.jest.fixture'; diff --git a/packages/elastic-sip-trunking/src/rest/v1/sip-trunks/sip-trunks-api.jest.fixture.ts b/packages/elastic-sip-trunking/src/rest/v1/sip-trunks/sip-trunks-api.jest.fixture.ts new file mode 100644 index 00000000..922eff5e --- /dev/null +++ b/packages/elastic-sip-trunking/src/rest/v1/sip-trunks/sip-trunks-api.jest.fixture.ts @@ -0,0 +1,57 @@ +import { SipTrunksApi } from './sip-trunks-api'; +import { + AddAccessControlListToTrunk, + SipTrunk, + AddAccessControlListToTrunkRequestData, + CreateSipTrunkRequestData, + DeleteAccessControlListFromTrunkRequestData, + DeleteSipTrunkRequestData, + ListAccessControlListsForTrunkRequestData, + GetSipTrunkRequestData, + ListSipTrunksRequestData, + UpdateSipTrunkRequestData, +} from '../../../models'; +import { ApiListPromise } from '@sinch/sdk-client'; + +export class SipTrunksApiFixture implements Partial> { + + /** + * Fixture associated to function addAccessControlList + */ + public addAccessControlList: jest.Mock< + Promise, + [AddAccessControlListToTrunkRequestData] + > = jest.fn(); + /** + * Fixture associated to function create + */ + public create: jest.Mock, [CreateSipTrunkRequestData]> = jest.fn(); + /** + * Fixture associated to function deleteAccessControlListFromTrunk + */ + public deleteAccessControlList: jest.Mock, [DeleteAccessControlListFromTrunkRequestData]> = jest.fn(); + /** + * Fixture associated to function deleteSipTrunk + */ + public delete: jest.Mock, [DeleteSipTrunkRequestData]> = jest.fn(); + /** + * Fixture associated to function getAccessControlListsForTrunk + */ + public listAccessControlLists: jest.Mock< + ApiListPromise, + [ListAccessControlListsForTrunkRequestData] + > = jest.fn(); + /** + * Fixture associated to function getSipTrunkById + */ + public get: jest.Mock, [GetSipTrunkRequestData]> = jest.fn(); + /** + * Fixture associated to function getSipTrunks + */ + public list: jest.Mock, [ListSipTrunksRequestData]> = jest.fn(); + /** + * Fixture associated to function updateSipTrunk + */ + public update: jest.Mock, [UpdateSipTrunkRequestData]> = jest.fn(); +} + diff --git a/packages/elastic-sip-trunking/src/rest/v1/sip-trunks/sip-trunks-api.ts b/packages/elastic-sip-trunking/src/rest/v1/sip-trunks/sip-trunks-api.ts new file mode 100644 index 00000000..7b59645b --- /dev/null +++ b/packages/elastic-sip-trunking/src/rest/v1/sip-trunks/sip-trunks-api.ts @@ -0,0 +1,295 @@ +import { + AddAccessControlListToTrunk, + AddAccessControlListToTrunkRequestData, + CreateSipTrunkRequestData, + DeleteAccessControlListFromTrunkRequestData, + DeleteSipTrunkRequestData, + ListAccessControlListsForTrunkRequestData, + GetSipTrunkRequestData, + ListSipTrunksRequestData, + UpdateSipTrunkRequestData, + SipTrunk, +} from '../../../models'; +import { + RequestBody, + SinchClientParameters, + ApiListPromise, + PaginatedApiProperties, + PaginationEnum, + buildPageResultPromise, + createIteratorMethodsForPagination, +} from '@sinch/sdk-client'; +import { ElasticSipTrunkingDomainApi } from '../elastic-sip-trunking-domain-api'; + +export class SipTrunksApi extends ElasticSipTrunkingDomainApi { + + /** + * Initialize your interface + * + * @param {SinchClientParameters} sinchClientParameters - The parameters used to initialize the API Client. + */ + constructor(sinchClientParameters: SinchClientParameters) { + super(sinchClientParameters, 'SipTrunksApi'); + } + + /** + * Add ACL to a trunk + * Add an access control list entry to a trunk. + * @param { AddAccessControlListToTrunkRequestData } data - The data to provide to the API call. + */ + public async addAccessControlList( + data: AddAccessControlListToTrunkRequestData, + ): Promise { + this.client = this.getSinchClient(); + const getParams = this.client.extractQueryParams(data, [] as never[]); + const headers: { [key: string]: string | undefined } = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }; + + const body: RequestBody = data['addAccessControlListToTrunkRequestBody'] + ? JSON.stringify(data['addAccessControlListToTrunkRequestBody']) + : '{}'; + const basePathUrl = `${this.client.apiClientOptions.hostname}/v1/projects/${this.client.apiClientOptions.projectId}/trunks/${data['trunkId']}/accessControlLists`; + + const requestOptions = await this.client.prepareOptions(basePathUrl, 'POST', getParams, headers, body || undefined); + const url = this.client.prepareUrl(requestOptions.hostname, requestOptions.queryParams); + + return this.client.processCall({ + url, + requestOptions, + apiName: this.apiName, + operationId: 'AddAccessControlListToTrunk', + }); + } + + /** + * Create SIP trunk + * Creates a new SIP trunk. + * @param { CreateSipTrunkRequestData } data - The data to provide to the API call. + */ + public async create(data: CreateSipTrunkRequestData): Promise { + this.client = this.getSinchClient(); + const getParams = this.client.extractQueryParams(data, [] as never[]); + const headers: { [key: string]: string | undefined } = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }; + + const body: RequestBody = data['createSipTrunkRequestBody'] + ? JSON.stringify(data['createSipTrunkRequestBody']) + : '{}'; + const basePathUrl = `${this.client.apiClientOptions.hostname}/v1/projects/${this.client.apiClientOptions.projectId}/trunks`; + + const requestOptions = await this.client.prepareOptions(basePathUrl, 'POST', getParams, headers, body || undefined); + const url = this.client.prepareUrl(requestOptions.hostname, requestOptions.queryParams); + + return this.client.processCall({ + url, + requestOptions, + apiName: this.apiName, + operationId: 'CreateSipTrunk', + }); + } + + /** + * Delete ACL from trunk + * Remove an access control list entry from a trunk. + * @param { DeleteAccessControlListFromTrunkRequestData } data - The data to provide to the API call. + */ + public async deleteAccessControlList(data: DeleteAccessControlListFromTrunkRequestData): Promise { + this.client = this.getSinchClient(); + const getParams = this.client.extractQueryParams(data, [] as never[]); + const headers: { [key: string]: string | undefined } = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }; + + const body: RequestBody = ''; + const basePathUrl = `${this.client.apiClientOptions.hostname}/v1/projects/${this.client.apiClientOptions.projectId}/trunks/${data['trunkId']}/accessControlLists/${data['accessControlListId']}`; + + const requestOptions + = await this.client.prepareOptions(basePathUrl, 'DELETE', getParams, headers, body || undefined); + const url = this.client.prepareUrl(requestOptions.hostname, requestOptions.queryParams); + + return this.client.processCall({ + url, + requestOptions, + apiName: this.apiName, + operationId: 'DeleteAccessControlListFromTrunk', + }); + } + + /** + * Delete SIP trunk + * Delete a SIP trunk by its ID. + * @param { DeleteSipTrunkRequestData } data - The data to provide to the API call. + */ + public async delete(data: DeleteSipTrunkRequestData): Promise { + this.client = this.getSinchClient(); + const getParams = this.client.extractQueryParams(data, [] as never[]); + const headers: { [key: string]: string | undefined } = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }; + + const body: RequestBody = ''; + const basePathUrl = `${this.client.apiClientOptions.hostname}/v1/projects/${this.client.apiClientOptions.projectId}/trunks/${data['sipTrunkId']}`; + + const requestOptions + = await this.client.prepareOptions(basePathUrl, 'DELETE', getParams, headers, body || undefined); + const url = this.client.prepareUrl(requestOptions.hostname, requestOptions.queryParams); + + return this.client.processCall({ + url, + requestOptions, + apiName: this.apiName, + operationId: 'DeleteSipTrunk', + }); + } + + /** + * List all ACLs for a trunk + * Get all access control list entries for a trunk. + * @param { ListAccessControlListsForTrunkRequestData } data - The data to provide to the API call. + * @return { ApiListPromise } + */ + public listAccessControlLists(data: ListAccessControlListsForTrunkRequestData): ApiListPromise { + this.client = this.getSinchClient(); + const getParams = this.client.extractQueryParams(data, [] as never[]); + const headers: { [key: string]: string | undefined } = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }; + + const body: RequestBody = ''; + const basePathUrl = `${this.client.apiClientOptions.hostname}/v1/projects/${this.client.apiClientOptions.projectId}/trunks/${data['trunkId']}/accessControlLists`; + + const requestOptionsPromise = this.client.prepareOptions(basePathUrl, 'GET', getParams, headers, body || undefined); + + const operationProperties: PaginatedApiProperties = { + pagination: PaginationEnum.PAGE2, + apiName: this.apiName, + operationId: 'GetAccessControlListsForTrunk', + dataKey: 'accessControlListIds', + }; + + // Create the promise containing the response wrapped as a PageResult + const listPromise = buildPageResultPromise( + this.client, + requestOptionsPromise, + operationProperties, + ); + + // Add properties to the Promise to offer the possibility to use it as an iterator + Object.assign( + listPromise, + createIteratorMethodsForPagination( + this.client, requestOptionsPromise, listPromise, operationProperties), + ); + + return listPromise as ApiListPromise; + } + + /** + * Get SIP Trunk + * Search for a SIP trunk by ID. + * @param { GetSipTrunkRequestData } data - The data to provide to the API call. + */ + public async get(data: GetSipTrunkRequestData): Promise { + this.client = this.getSinchClient(); + const getParams = this.client.extractQueryParams(data, [] as never[]); + const headers: { [key: string]: string | undefined } = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }; + + const body: RequestBody = ''; + const basePathUrl = `${this.client.apiClientOptions.hostname}/v1/projects/${this.client.apiClientOptions.projectId}/trunks/${data['sipTrunkId']}`; + + const requestOptions = await this.client.prepareOptions(basePathUrl, 'GET', getParams, headers, body || undefined); + const url = this.client.prepareUrl(requestOptions.hostname, requestOptions.queryParams); + + return this.client.processCall({ + url, + requestOptions, + apiName: this.apiName, + operationId: 'GetSipTrunkById', + }); + } + + /** + * List SIP trunks + * Returns a list of all SIP trunks. If you specify pagination settings, the list of SIP trunks can be returned separated and sorted into pages. + * @param { ListSipTrunksRequestData } data - The data to provide to the API call. + * @return { ApiListPromise } + */ + public list(data: ListSipTrunksRequestData): ApiListPromise { + this.client = this.getSinchClient(); + data['page'] = data['page'] !== undefined ? data['page'] : 1; + data['pageSize'] = data['pageSize'] !== undefined ? data['pageSize'] : 1000; + const getParams = this.client.extractQueryParams(data, ['page', 'pageSize', 'domain']); + const headers: { [key: string]: string | undefined } = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }; + + const body: RequestBody = ''; + const basePathUrl = `${this.client.apiClientOptions.hostname}/v1/projects/${this.client.apiClientOptions.projectId}/trunks`; + + const requestOptionsPromise = this.client.prepareOptions(basePathUrl, 'GET', getParams, headers, body || undefined); + + const operationProperties: PaginatedApiProperties = { + pagination: PaginationEnum.PAGE2, + apiName: this.apiName, + operationId: 'GetSipTrunks', + dataKey: 'sipTrunks', + }; + + // Create the promise containing the response wrapped as a PageResult + const listPromise = buildPageResultPromise( + this.client, + requestOptionsPromise, + operationProperties, + ); + + // Add properties to the Promise to offer the possibility to use it as an iterator + Object.assign( + listPromise, + createIteratorMethodsForPagination( + this.client, requestOptionsPromise, listPromise, operationProperties), + ); + + return listPromise as ApiListPromise; + } + + /** + * Update SIP trunk + * Update an existing SIP Trunk by ID. The whole object must be sent. Any missing fields will be set to null. + * @param { UpdateSipTrunkRequestData } data - The data to provide to the API call. + */ + public async update(data: UpdateSipTrunkRequestData): Promise { + this.client = this.getSinchClient(); + const getParams = this.client.extractQueryParams(data, [] as never[]); + const headers: { [key: string]: string | undefined } = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }; + + const body: RequestBody = data['updateSipTrunkRequestBody'] + ? JSON.stringify(data['updateSipTrunkRequestBody']) + : '{}'; + const basePathUrl = `${this.client.apiClientOptions.hostname}/v1/projects/${this.client.apiClientOptions.projectId}/trunks/${data['sipTrunkId']}`; + + const requestOptions = await this.client.prepareOptions(basePathUrl, 'PUT', getParams, headers, body || undefined); + const url = this.client.prepareUrl(requestOptions.hostname, requestOptions.queryParams); + + return this.client.processCall({ + url, + requestOptions, + apiName: this.apiName, + operationId: 'UpdateSipTrunk', + }); + } + +} diff --git a/packages/elastic-sip-trunking/tests/rest/v1/sip-trunks/sip-trunks-api.test.ts b/packages/elastic-sip-trunking/tests/rest/v1/sip-trunks/sip-trunks-api.test.ts new file mode 100644 index 00000000..7d4e53ad --- /dev/null +++ b/packages/elastic-sip-trunking/tests/rest/v1/sip-trunks/sip-trunks-api.test.ts @@ -0,0 +1,252 @@ +import { SinchClientParameters } from '@sinch/sdk-client'; +import { + SipTrunksApi, + SipTrunksApiFixture, + ElasticSipTrunking, +} from '../../../../src'; + +describe('SIPTrunksApi', () => { + let sipTrunksApi: SipTrunksApi; + let fixture: SipTrunksApiFixture; + let credentials: SinchClientParameters; + + beforeEach(() => { + fixture = new SipTrunksApiFixture(); + credentials = { + projectId: 'PROJECT_ID', + keyId: 'KEY_ID', + keySecret: 'KEY_SECRET', + }; + sipTrunksApi = new SipTrunksApi(credentials); + }); + + + describe ('addAccessControlListToTrunk', () => { + it('should make a POST request to add an access control list entry to a trunk', async () => { + // Given + const requestData: ElasticSipTrunking.AddAccessControlListToTrunkRequestData = { + trunkId: 'trunkId', + addAccessControlListToTrunkRequestBody: { + accessControlListIds: [ + '01HA2E80QCBX185VVP21PJG9CT', + '01H8Y95DBJT31F104PWFVV9H8B', + ], + }, + }; + const expectedResponse: ElasticSipTrunking.AddAccessControlListToTrunk = { + accessControlListIds: [ + '01HA2E80QCBX185VVP21PJG9CT', + '01H8Y95DBJT31F104PWFVV9H8B', + ], + }; + + // When + fixture.addAccessControlList.mockResolvedValue(expectedResponse); + sipTrunksApi.addAccessControlList = fixture.addAccessControlList; + const response = await sipTrunksApi.addAccessControlList(requestData); + + // Then + expect(response).toEqual(expectedResponse); + expect(fixture.addAccessControlList).toHaveBeenCalledWith(requestData); + }); + }); + + describe ('createSipTrunk', () => { + it('should make a POST request to create a new SIP trunk', async () => { + // Given + const requestData: ElasticSipTrunking.CreateSipTrunkRequestData = { + createSipTrunkRequestBody: { + name: 'Acme Trunk', + hostName: 'acme-domain-1', + }, + }; + const expectedResponse: ElasticSipTrunking.SipTrunk = { + id: 'trunkId', + hostName: 'acme-domain-1', + topLevelDomain: '.elastic-sip.sinch.com', + domain: 'acme-domain-1.elastic-sip.sinch.com', + name: 'Acme Trunk', + callsPerSecond: 100, + enableCallerName: true, + createTime: new Date('2022-01-01T00:00:00Z'), + updateTime: new Date('2022-01-01T00:00:00Z'), + projectId: '1bf62742-7b84-4666-9cbe-8e5734fd57d0', + }; + + // When + fixture.create.mockResolvedValue(expectedResponse); + sipTrunksApi.create = fixture.create; + const response = await sipTrunksApi.create(requestData); + + // Then + expect(response).toEqual(expectedResponse); + expect(fixture.create).toHaveBeenCalledWith(requestData); + }); + }); + + describe ('deleteAccessControlList', () => { + it('should make a DELETE request to remove an access control list entry from a trunk', async () => { + // Given + const requestData: ElasticSipTrunking.DeleteAccessControlListFromTrunkRequestData = { + trunkId: 'trunkId', + accessControlListId: '01HA2E80QCBX185VVP21PJG9CT', + }; + + // When + fixture.deleteAccessControlList.mockResolvedValue(); + sipTrunksApi.deleteAccessControlList = fixture.deleteAccessControlList; + const response = await sipTrunksApi.deleteAccessControlList(requestData); + + // Then + expect(response).toBeUndefined(); + expect(fixture.deleteAccessControlList).toHaveBeenCalledWith(requestData); + }); + }); + + describe ('deleteSipTrunk', () => { + it('should make a DELETE request to delete a SIP trunk by its ID', async () => { + // Given + const requestData: ElasticSipTrunking.DeleteSipTrunkRequestData = { + sipTrunkId: 'trunkId', + }; + + // When + fixture.delete.mockResolvedValue(); + sipTrunksApi.delete = fixture.delete; + const response = await sipTrunksApi.delete(requestData); + + // Then + expect(response).toBeUndefined(); + expect(fixture.delete).toHaveBeenCalledWith(requestData); + }); + }); + + describe ('listAccessControlLists', () => { + it('should make a GET request to list all access control list entries for a trunk', async () => { + // Given + const requestData: ElasticSipTrunking.ListAccessControlListsForTrunkRequestData = { + trunkId: 'trunkId', + }; + const mockData: string[] = [ + '01HA2E80QCBX185VVP21PJG9CT', + ]; + const expectedResponse = { + data: mockData, + hasNextPage: false, + nextPageValue: '', + nextPage: jest.fn(), + }; + + // When + fixture.listAccessControlLists.mockResolvedValue(expectedResponse); + sipTrunksApi.listAccessControlLists = fixture.listAccessControlLists; + const response = await sipTrunksApi.listAccessControlLists(requestData); + + // Then + expect(response).toEqual(expectedResponse); + expect(fixture.listAccessControlLists).toHaveBeenCalledWith(requestData); + }); + }); + + describe ('getSipTrunkById', () => { + it('should make a GET request to search for a SIP trunk by ID', async () => { + // Given + const requestData: ElasticSipTrunking.GetSipTrunkRequestData = { + sipTrunkId: 'trunkId', + }; + const expectedResponse: ElasticSipTrunking.SipTrunk = { + id: 'trunkId', + hostName: 'acme-domain-1', + topLevelDomain: '.elastic-sip.sinch.com', + domain: 'acme-domain-1.elastic-sip.sinch.com', + name: 'Acme Trunk', + callsPerSecond: 100, + enableCallerName: true, + createTime: new Date('2022-01-01T00:00:00Z'), + updateTime: new Date('2022-01-01T00:00:00Z'), + projectId: '1bf62742-7b84-4666-9cbe-8e5734fd57d0', + }; + + // When + fixture.get.mockResolvedValue(expectedResponse); + sipTrunksApi.get = fixture.get; + const response = await sipTrunksApi.get(requestData); + + // Then + expect(response).toEqual(expectedResponse); + expect(fixture.get).toHaveBeenCalledWith(requestData); + }); + }); + + describe ('getSipTrunks', () => { + it('should make a GET request to list all SIP trunks', async () => { + // Given + const requestData: ElasticSipTrunking.ListSipTrunksRequestData = { + domain: 'acme-domain-1.elastic-sip.sinch.com', + }; + const mockData: ElasticSipTrunking.SipTrunk[] =[ + { + id: 'trunkId', + hostName: 'acme-domain-1', + topLevelDomain: '.elastic-sip.sinch.com', + domain: 'acme-domain-1.elastic-sip.sinch.com', + name: 'Acme Trunk', + callsPerSecond: 100, + enableCallerName: true, + createTime: new Date('2022-01-01T00:00:00Z'), + updateTime: new Date('2022-01-01T00:00:00Z'), + projectId: '1bf62742-7b84-4666-9cbe-8e5734fd57d0', + }, + ]; + const expectedResponse = { + data: mockData, + hasNextPage: false, + nextPageValue: '', + nextPage: jest.fn(), + }; + + // When + fixture.list.mockResolvedValue(expectedResponse); + sipTrunksApi.list = fixture.list; + const response = await sipTrunksApi.list(requestData); + + // Then + expect(response).toEqual(expectedResponse); + expect(fixture.list).toHaveBeenCalledWith(requestData); + }); + }); + + describe ('updateSipTrunk', () => { + it('should make a PUT request to update an existing SIP Trunk by ID', async () => { + // Given + const requestData: ElasticSipTrunking.UpdateSipTrunkRequestData = { + sipTrunkId: 'trunkId', + updateSipTrunkRequestBody: { + name: 'Acme Trunk Updated', + hostName: 'acme-domain-updated-1', + }, + }; + const expectedResponse: ElasticSipTrunking.SipTrunk = { + id: 'trunkId', + hostName: 'acme-domain-updated-1', + topLevelDomain: '.elastic-sip.sinch.com', + domain: 'acme-domain-updated-1.elastic-sip.sinch.com', + name: 'Acme Trunk Updated', + callsPerSecond: 100, + enableCallerName: true, + createTime: new Date('2022-01-01T00:00:00Z'), + updateTime: new Date('2022-01-01T00:00:00Z'), + projectId: '1bf62742-7b84-4666-9cbe-8e5734fd57d0', + }; + + // When + fixture.update.mockResolvedValue(expectedResponse); + sipTrunksApi.update = fixture.update; + const response = await sipTrunksApi.update(requestData); + + // Then + expect(response).toEqual(expectedResponse); + expect(fixture.update).toHaveBeenCalledWith(requestData); + }); + }); +});