Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEVEXP-515: E2E SMS/Batches #123

Merged
merged 2 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ export class ExceptionResponse<
);
} else if (!res) {
res = {} as V;
if (context.response.status !== 204 && context.response.status !== 200) {
if (context.response.status !== 204
&& context.response.status !== 200
&& context.response.status !== 202
) {
res = {} as V;
error = new EmptyResponseError<V>(
context.response.statusText,
Expand Down
8 changes: 8 additions & 0 deletions packages/sms/cucumber.js
Original file line number Diff line number Diff line change
@@ -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(' '),
};
3 changes: 2 additions & 1 deletion packages/sms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export interface DryRunResponsePerRecipientInner {

recipient?: string;
message_part?: string;
number_of_parts?: number;
body?: string;
encoding?: string;
}
Expand Down
2 changes: 0 additions & 2 deletions packages/sms/src/rest/v1/batches/batches-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ export class BatchesApi extends SmsDomainApi {
*/
public async dryRun(data: DryRunRequestData): Promise<DryRunResponse> {
this.client = this.getSinchClient();
data['number_of_recipients'] = data['number_of_recipients'] !== undefined ? data['number_of_recipients'] : 100;
const getParams = this.client.extractQueryParams<DryRunRequestData>(data, [
'per_recipient',
'number_of_recipients']);
Expand Down Expand Up @@ -164,7 +163,6 @@ export class BatchesApi extends SmsDomainApi {
*/
public list(data: ListBatchesRequestData): ApiListPromise<SendSMSResponse> {
this.client = this.getSinchClient();
data['page_size'] = data['page_size'] !== undefined ? data['page_size'] : 30;
const getParams = this.client.extractQueryParams<ListBatchesRequestData>(
data,
['page', 'page_size', 'from', 'start_date', 'end_date', 'client_reference'],
Expand Down
257 changes: 257 additions & 0 deletions packages/sms/tests/rest/v1/batches/batches.steps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
import { BatchesApi, SmsService, Sms } from '../../../../src';
import { Given, When, Then } from '@cucumber/cucumber';
import * as assert from 'assert';
import { PageResult } from '@sinch/sdk-client';

let batchesApi: BatchesApi;
let sendSmsResponse: Sms.TextResponse;
let dryRunResponse: Sms.DryRunResponse;
let listResponse: PageResult<Sms.SendSMSResponse>;
let batchesList: Sms.SendSMSResponse[];
let pagesIteration: number;
let batch: Sms.SendSMSResponse;
let deliveryFeedbackResponse: void;

Given('the SMS service "Batches" is available', () => {
const smsService = new SmsService({
projectId: 'tinyfrog-jump-high-over-lilypadbasin',
keyId: 'keyId',
keySecret: 'keySecret',
authHostname: 'http://localhost:3011',
smsHostname: 'http://localhost:3017',
});
batchesApi = smsService.batches;
});

When('I send a request to send a text message', async () => {
const sendSmsRequest: Sms.SendTextSMSRequestData = {
sendSMSRequestBody: {
body: 'SMS body message',
to: ['+12017777777'],
from: '+12015555555',
send_at: new Date('2024-06-06T09:25:00Z'),
delivery_report: 'full',
feedback_enabled: true,
},
};
sendSmsResponse = await batchesApi.sendTextMessage(sendSmsRequest);
});

Then('the response contains the text SMS details', () => {
assert.equal(sendSmsResponse.id, '01W4FFL35P4NC4K35SMSBATCH1');
assert.deepEqual(sendSmsResponse.to, ['12017777777']);
assert.equal(sendSmsResponse.from, '12015555555');
assert.equal(sendSmsResponse.canceled, false);
assert.equal(sendSmsResponse.body, 'SMS body message');
assert.equal(sendSmsResponse.type, 'mt_text');
assert.deepEqual(sendSmsResponse.created_at, new Date('2024-06-06T09:22:14.304Z'));
assert.deepEqual(sendSmsResponse.modified_at, new Date('2024-06-06T09:22:14.304Z'));
const fullDeliveryReport: Sms.DeliveryReportEnum = 'full';
assert.equal(sendSmsResponse.delivery_report, fullDeliveryReport);
assert.deepEqual(sendSmsResponse.send_at, new Date('2024-06-06T09:25:00Z'));
assert.deepEqual(sendSmsResponse.expire_at, new Date('2024-06-09T09:25:00Z'));
assert.equal(sendSmsResponse.feedback_enabled, true);
assert.equal(sendSmsResponse.flash_message, false);
});

When('I send a request to perform a dry run of a batch', async () => {
const sendSmsRequest: Sms.DryRunRequestData = {
dryRunRequestBody: {
from: '+12015555555',
to: [
'+12017777777',
'+12018888888',
'+12019999999',
],
parameters: {
name: {
'+12017777777': 'John',
default: 'there',
},
},
body: 'Hello ${name}!',
delivery_report: 'none',
type: 'mt_text',
},
};
dryRunResponse = await batchesApi.dryRun(sendSmsRequest);
});

Then('the response contains the calculated bodies and number of parts for all messages in the batch', () => {
assert.equal(dryRunResponse.number_of_messages, 3);
assert.equal(dryRunResponse.number_of_recipients, 3);
assert.ok(dryRunResponse.per_recipient);
assert.equal(dryRunResponse.per_recipient.length, 3);
const johnMessage = dryRunResponse.per_recipient.filter(
(perRecipient) => perRecipient.recipient === '12017777777',
).pop();
assert.ok(johnMessage);
assert.equal(johnMessage.body, 'Hello John!');
assert.equal(johnMessage.number_of_parts, 1);
assert.equal(johnMessage.encoding, 'text');
const defaultMessage = dryRunResponse.per_recipient.filter(
(perRecipient) => perRecipient.recipient === '12018888888',
).pop();
assert.ok(defaultMessage);
assert.equal(defaultMessage.body, 'Hello there!');
assert.equal(defaultMessage.number_of_parts, 1);
assert.equal(defaultMessage.encoding, 'text');
});

When('I send a request to list the SMS batches', async () => {
const listBatchRequest: Sms.ListBatchesRequestData = {
page_size: 2,
};
listResponse = await batchesApi.list(listBatchRequest);
});

Then('the response contains {string} SMS batches', (expectedAnswer: string) => {
const expectedBatchesCount = parseInt(expectedAnswer, 10);
assert.equal(listResponse.data.length, expectedBatchesCount);
});

When('I send a request to list all the SMS batches', async () => {
batchesList = [];
for await (const batch of batchesApi.list({ page_size: 2 })) {
batchesList.push(batch);
}
});

When('I iterate manually over the SMS batches pages', async () => {
batchesList = [];
listResponse = await batchesApi.list({
page_size: 2,
});
batchesList.push(...listResponse.data);
pagesIteration = 1;
let reachedEndOfPages = false;
while (!reachedEndOfPages) {
if (listResponse.hasNextPage) {
listResponse = await listResponse.nextPage();
batchesList.push(...listResponse.data);
pagesIteration++;
} else {
reachedEndOfPages = true;
}
}
});

Then('the SMS batches list contains {string} SMS batches', (expectedAnswer: string) => {
const expectedBatchesCount = parseInt(expectedAnswer, 10);
assert.equal(batchesList.length, expectedBatchesCount);
});

Then('the SMS batches iteration result contains the data from {string} pages', (expectedAnswer: string) => {
const expectedPagesCount = parseInt(expectedAnswer, 10);
assert.equal(pagesIteration, expectedPagesCount);
});

When('I send a request to retrieve an SMS batch', async () => {
batch = await batchesApi.get({
batch_id: '01W4FFL35P4NC4K35SMSBATCH1',
});
});

Then('the response contains the SMS batch details', () => {
assert.equal(batch.id, '01W4FFL35P4NC4K35SMSBATCH1');
assert.deepEqual(sendSmsResponse.to, ['12017777777']);
assert.equal(sendSmsResponse.from, '12015555555');
assert.equal(sendSmsResponse.canceled, false);
assert.equal(sendSmsResponse.body, 'SMS body message');
assert.equal(sendSmsResponse.type, 'mt_text');
assert.deepEqual(sendSmsResponse.created_at, new Date('2024-06-06T09:22:14.304Z'));
assert.deepEqual(sendSmsResponse.modified_at, new Date('2024-06-06T09:22:14.304Z'));
const fullDeliveryReport: Sms.DeliveryReportEnum = 'full';
assert.equal(sendSmsResponse.delivery_report, fullDeliveryReport);
assert.deepEqual(sendSmsResponse.send_at, new Date('2024-06-06T09:25:00Z'));
assert.deepEqual(sendSmsResponse.expire_at, new Date('2024-06-09T09:25:00Z'));
assert.equal(sendSmsResponse.feedback_enabled, true);
assert.equal(sendSmsResponse.flash_message, false);
});

When('I send a request to update an SMS batch', async () => {
batch = await batchesApi.update({
batch_id: '01W4FFL35P4NC4K35SMSBATCH1',
updateBatchMessageRequestBody: {
from: '+12016666666',
to_add: [
'01W4FFL35P4NC4K35SMSGROUP1',
],
delivery_report: 'summary',
},
});
});

Then('the response contains the SMS batch details with updated data', () => {
assert.equal(batch.id, '01W4FFL35P4NC4K35SMSBATCH1');
assert.deepEqual(batch.to, ['12017777777', '01W4FFL35P4NC4K35SMSGROUP1']);
assert.equal(batch.from, '12016666666');
assert.equal(batch.canceled, false);
assert.equal(batch.body, 'SMS body message');
assert.equal(batch.type, 'mt_text');
assert.deepEqual(batch.created_at, new Date('2024-06-06T09:22:14.304Z'));
assert.deepEqual(batch.modified_at, new Date('2024-06-06T09:22:48.054Z'));
const summaryDeliveryReport: Sms.DeliveryReportEnum = 'summary';
assert.equal(batch.delivery_report, summaryDeliveryReport);
assert.deepEqual(batch.send_at, new Date('2024-06-06T09:25:00Z'));
assert.deepEqual(batch.expire_at, new Date('2024-06-09T09:25:00Z'));
assert.equal(batch.feedback_enabled, true);
assert.equal((batch as Sms.TextResponse).flash_message, false);
});

When('I send a request to replace an SMS batch', async () => {
batch = await batchesApi.replace({
batch_id: '01W4FFL35P4NC4K35SMSBATCH1',
replaceBatchMessageRequestBody: {
from: '+12016666666',
to: [
'+12018888888',
],
body: 'This is the replacement batch',
send_at: new Date('2024-06-06T09:35:00Z'),
},
});
});

Then('the response contains the new SMS batch details with the provided data for replacement', () => {
assert.equal(batch.id, '01W4FFL35P4NC4K35SMSBATCH1');
assert.deepEqual(batch.to, ['12018888888']);
assert.equal(batch.from, '12016666666');
assert.equal(batch.canceled, false);
assert.equal(batch.body, 'This is the replacement batch');
assert.equal(batch.type, 'mt_text');
assert.deepEqual(batch.created_at, new Date('2024-06-06T09:22:14.304Z'));
assert.deepEqual(batch.modified_at, new Date('2024-06-06T09:23:32.504Z'));
const noDeliveryReport: Sms.DeliveryReportEnum = 'none';
assert.equal(batch.delivery_report, noDeliveryReport);
assert.deepEqual(batch.send_at, new Date('2024-06-06T09:35:00Z'));
assert.deepEqual(batch.expire_at, new Date('2024-06-09T09:35:00Z'));
assert.equal(batch.feedback_enabled, undefined);
assert.equal((batch as Sms.TextResponse).flash_message, false);
});

When('I send a request to cancel an SMS batch', async () => {
batch = await batchesApi.cancel({
batch_id: '01W4FFL35P4NC4K35SMSBATCH1',
});
});

Then('the response contains the SMS batch details with a cancelled status', () => {
assert.equal(batch.id, '01W4FFL35P4NC4K35SMSBATCH1');
assert.equal(batch.canceled, true);
});

When('I send a request to send delivery feedbacks', async () => {
deliveryFeedbackResponse = await batchesApi.sendDeliveryFeedback({
batch_id: '01W4FFL35P4NC4K35SMSBATCH1',
deliveryFeedbackRequestBody: {
recipients: [
'+12017777777',
],
},
});
});

Then('the delivery feedback response contains no data', () => {
assert.deepEqual(deliveryFeedbackResponse, {});
});
Loading