diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index a1e9869..e543c58 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [9.x, 10.x, 12.x, 14.x] + node-version: [22.x, 24.x] steps: - uses: actions/checkout@v2 @@ -31,4 +31,4 @@ jobs: file: ./ccoverage.lcov flags: unittests name: codecov-umbrella - fail_ci_if_err: true \ No newline at end of file + fail_ci_if_error: true diff --git a/README.md b/README.md index 632bf6d..01f9a0d 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,28 @@ # SMSGlobal node SDK - ![Build](https://github.com/smsglobal/smsglobal-node/workflows/Build/badge.svg?branch=master) [![codecov](https://codecov.io/gh/smsglobal/smsglobal-node/branch/master/graph/badge.svg)](https://codecov.io/gh/smsglobal/smsglobal-node) [![Node](https://img.shields.io/node/v/smsglobal)](https://www.npmjs.com/package/smsglobal) [![npm](https://img.shields.io/npm/v/smsglobal)](https://www.npmjs.com/package/smsglobal) [![Downloads](https://img.shields.io/npm/dm/smsglobal.svg)](https://www.npmjs.com/package/smsglobal) - The SMSGlobal Node library provides convenient access to the SMSGlobal REST API from node applications. Sign up for a [free SMSGlobal account](https://www.smsglobal.com/mxt-sign-up/?utm_source=dev&utm_medium=github&utm_campaign=node_sdk) today and get your API Key from our advanced SMS platform, MXT. Plus, enjoy unlimited free developer sandbox testing to try out your API in full! - ## Example - Check out the [code examples](examples) +Check out the [code examples](examples) - -## SMSGlobal rest API credentials +## SMSGlobal REST API credentials Rest API credentials can be provided in the SMSGlobal client or node environment variables. The credential variables are `SMSGLOBAL_API_KEY` and `SMSGLOBAL_API_SECRET` - ## Installation ``` npm install --save smsglobal ``` - ## Usage * Require `smsglobal` in your file @@ -39,9 +33,9 @@ const apiSecret = 'YOUR_API_SECRET'; var smsglobal = require('smsglobal')(apiKey, secret); ``` -> All method return promise if no callback is given +> All methods return a promise if no callback is given. -### To send a sms +### To send an SMS ```js var payload = { origin: 'from number', @@ -53,7 +47,7 @@ smsglobal.sms.send(payload, function (error, response) { console.log(response); }); ``` -### To fetch a list outgoing sms +### To fetch a list of outgoing SMS ```js var promise = smsglobal.sms.getAll(); @@ -67,7 +61,7 @@ promise }); ``` -### To fetch an outgoing sms by id +### To fetch an outgoing SMS by id ```js var id = 'outgoing-sms-id'; @@ -82,7 +76,7 @@ promise }); ``` -### To fetch a list incoming sms +### To fetch a list of incoming SMS ```js var promise = smsglobal.sms.incoming.getAll(); @@ -96,7 +90,7 @@ promise }); ``` -### To fetch an incoming sms by id +### To fetch an incoming SMS by id ```js var id = 'incoming-sms-id'; @@ -111,8 +105,8 @@ promise }); ``` - ### To send an OTP + ```js var payload = { origin: 'from number', @@ -131,47 +125,46 @@ smsglobal.otp.send(payload, function(error, response) { console.log(error); } }); - ``` *Success response object* -```js +```json { - statusCode: 200, - status: 'OK', - data: { - requestId: '404372541683676561917558', - destination: '61400000000', - validUnitlTimestamp: '2020-11-18 17:08:14', - createdTimestamp: '2020-11-18 16:58:14', - lastEventTimestamp: '2020-11-18 16:58:14', - status: 'Sent' + "statusCode": 200, + "status": "OK", + "data": { + "requestId": "404372541683676561917558", + "destination": "61400000000", + "validUnitlTimestamp": "2025-11-18 17:08:14", + "createdTimestamp": "2025-11-18 16:58:14", + "lastEventTimestamp": "2025-11-18 16:58:14", + "status": "Sent" } } ``` *Error response object in the case of validation error* -```js +```json { - statusCode: 400, - status: 'Bad Request', - data: { - errors: { - message: { - errors: [ - 'Message template should contain a placeholder for code i.e. {*code*}.' + "statusCode": 400, + "status": "Bad Request", + "data": { + "errors": { + "message": { + "errors": [ + "Message template should contain a placeholder for code i.e. {*code*}." ] } } } } - ``` ### To cancel an OTP request -The OTP request can be cancelled if it's not expired and verified yet. It can be done by either using `requestId` or `destination number`. The followings are examples of each method: + +The OTP request can be cancelled if it's not expired and verified yet. It can be done by either using `requestId` or `destination number`. The following are examples of each method: ```js var id = 'otp-request-id'; // requestId received upon sending an OTP @@ -183,6 +176,7 @@ promise.then((response) => { console.log(error) }); ``` + ```js var destination = 'destination-number'; var promise = smsglobal.otp.cancelByDestination(id) @@ -196,24 +190,24 @@ promise.then((response) => { *Success response object* -```js +```json { - statusCode: 200, - status: 'OK', - data: { - requestId: '404372541683676561917558', - destination: '61400000000', - validUnitlTimestamp: '2020-11-18 17:08:14', - createdTimestamp: '2020-11-18 16:58:14', - lastEventTimestamp: '2020-11-18 16:58:14', - status: 'Cancelled' + "statusCode": 200, + "status": "OK", + "data": { + "requestId": "404372541683676561917558", + "destination": "61400000000", + "validUnitlTimestamp": "2025-11-18 17:08:14", + "createdTimestamp": "2025-11-18 16:58:14", + "lastEventTimestamp": "2025-11-18 16:58:14", + "status": "Cancelled" } } ``` ### To verify an OTP code entered by your user -The OTP code entered by your user can be verified by either using `requestId` or `destination number`. The followings are examples of each method: +The OTP code entered by your user can be verified by either using `requestId` or `destination number`. The following are examples of each method: ```js var id = 'otp-request-id'; // requestId received upon sending an OTP @@ -247,22 +241,21 @@ smsglobal.otp.verifyByDestination(id, code, function(error, response) { *Success response object* -```js +```json { - statusCode: 200, - status: 'OK', - data: { - requestId: '404372541683676561917558', - destination: '61400000000', - validUnitlTimestamp: '2020-11-18 17:08:14', - createdTimestamp: '2020-11-18 16:58:14', - lastEventTimestamp: '2020-11-18 16:58:14', - status: 'Verified' + "statusCode": 200, + "status": "OK", + "data": { + "requestId": "404372541683676561917558", + "destination": "61400000000", + "validUnitlTimestamp": "2025-11-18 17:08:14", + "createdTimestamp": "2025-11-18 16:58:14", + "lastEventTimestamp": "2025-11-18 16:58:14", + "status": "Verified" } } ``` - ## Running tests Run the tests: @@ -271,7 +264,7 @@ Run the tests: npm test ``` -To run test with code coverage report +To run tests with a code coverage report: ``` npm run mocha-only @@ -280,9 +273,10 @@ npm run mocha-only ## Available REST API Resources * Sms * Sms Incoming -* OTP (beta) +* OTP # Reference + [REST API Documentation](https://www.smsglobal.com/rest-api/?utm_source=dev&utm_medium=github&utm_campaign=node_sdk) For any query [contact us](https://www.smsglobal.com/contact/?utm_source=dev&utm_medium=github&utm_campaign=node_sdk) diff --git a/examples/index.js b/examples/index.js index c9b4efb..8458d35 100644 --- a/examples/index.js +++ b/examples/index.js @@ -5,27 +5,23 @@ const smsglobal = require('smsglobal')(SMSGLOBAL_API_KEY, SMSGLOBAL_API_SECRET); const util = require('util'); // Send sms -var payload = { +const payload = { origin: 'SMSGlobal', destination: '61400000000', message: 'Test sms from node sdk', }; smsglobal.sms.send(payload, function(error, response) { - if (response) { console.log('Response:', response.data ? response.data : response); } - if (error) { console.log('Error:', util.inspect(error, {showHidden: false, depth: null, colors: true})); } - }); - // fetch a list of outgoing sms -var options = { +const options = { offset: 1, limit: 50, }; @@ -40,11 +36,9 @@ smsglobal.sms.getAll(options) // fetch a list of incoming sms smsglobal.sms.incoming.getAll(function(error, response) { - if (response) { console.log('Response:', response.data ? response.data : response); } - if (error) { console.log('Error:', util.inspect(error, {showHidden: false, depth: null, colors: true})); } diff --git a/examples/otp.js b/examples/otp.js index 1478a19..e323290 100644 --- a/examples/otp.js +++ b/examples/otp.js @@ -2,7 +2,7 @@ const smsglobal = require('smsglobal')(); const util = require('util'); // To send an OTP request -var payload = { +const payload = { origin: 'SMSGlobal', message: '{*code*} is your SMSGlobal verification code.', destination: '61400000000', diff --git a/lib/Smsglobal.js b/lib/Smsglobal.js index 48df576..e3267a5 100644 --- a/lib/Smsglobal.js +++ b/lib/Smsglobal.js @@ -1,4 +1,5 @@ const errors = require('./errors'); + /** * @constructor Smsglobal * @@ -19,7 +20,7 @@ const Smsglobal = function (key, secret) { process.env['SMSGLOBAL_API_SECRET'] = secret; } - // check if credetials not supplier in constructor + // check if credentials not supplied in the constructor if (this.key === undefined || this.secret === undefined) { throw new Error(errors.smsglobal); } diff --git a/lib/api/Otp.js b/lib/api/Otp.js index d518d51..5ef7f60 100644 --- a/lib/api/Otp.js +++ b/lib/api/Otp.js @@ -1,8 +1,57 @@ const axios = require('../client'); -const ajv = require('../validator'); const uri = '/otp'; - const errors = require('../errors'); +const AjvLib = require('ajv'); +const Ajv = AjvLib.default || AjvLib; +const addErrors = require('ajv-errors'); +const { DateTime } = require('luxon'); +const schemas = require('../schema'); + +const ajv = new Ajv({ + allErrors: true, + allowUnionTypes: true, +}); + +function formatAjvErrors(errs) { + if (!Array.isArray(errs) || errs.length === 0) { + return ''; + } + + return errs + .map((e) => { + // instancePath like "/id" -> ".id"; keep "data" prefix + const dotPath = + 'data' + (e.instancePath ? e.instancePath.replace(/\//g, '.').replace(/^\.*/, '.') : ''); + // e.message already contains our ajv-errors custom text like "should be string" + return `${dotPath} ${e.message}`; + }) + .join(', '); +} + +addErrors(ajv); + +ajv.addSchema(schemas); + +ajv.addKeyword({ + keyword: 'dateTimeFormat', + type: ['string', 'object'], + errors: true, + compile(expectedFormat) { + return function (data) { + if (data == null) { + return true; + } + if (typeof data !== 'string') { + return true; + } + const parsed = DateTime.fromFormat(data, expectedFormat); + + return parsed.isValid; + }; + }, +}); + +module.exports = ajv; /** * Send an OTP request @@ -10,7 +59,6 @@ const errors = require('../errors'); * * @param {object} data * @param {function} callback - * @version beta */ const send = function name(data, callback) { // prevent mutation of given data @@ -26,7 +74,7 @@ const send = function name(data, callback) { }); } - if (Object.keys(_data).length == 0) { + if (Object.keys(_data).length === 0) { callback(Error(errors.otp.missingData)); return promise; } @@ -56,7 +104,7 @@ const send = function name(data, callback) { }; // Bad request errors - if (error.response.status == 400) { + if (error.response.status === 400) { Object.assign(errorResponse, { data: error.response.data }); } @@ -65,7 +113,6 @@ const send = function name(data, callback) { // return the promise if no callback specified return promise; - }; /** @@ -73,8 +120,8 @@ const send = function name(data, callback) { * * @function verify * @param {string} id requestId received upon sending an OTP + * @param code * @param {function} callback - * @version beta */ const verifyByRequestId = function (id, code, callback) { // Setup Promise if no callback specified. @@ -89,7 +136,7 @@ const verifyByRequestId = function (id, code, callback) { } if (ajv.validate('#otp/verify-with-id', {id: id, code: code}) === false) { - callback(ajv.errorsText(ajv.errors)); + callback(formatAjvErrors(ajv.errors)); // return the promise if no callback specified return promise; @@ -114,14 +161,13 @@ const verifyByRequestId = function (id, code, callback) { }; // Bad request errors - if (error.response.status == 400) { + if (error.response.status === 400) { Object.assign(errorResponse, { data: error.response.data }); } callback(errorResponse); }); - // return the promise if no callback specified return promise; }; @@ -131,8 +177,8 @@ const verifyByRequestId = function (id, code, callback) { * * @function verify * @param {string} destination destination number + * @param code * @param {function} callback - * @version beta */ const verifyByDestination = function (destination, code, callback) { // Setup Promise if no callback specified. @@ -147,7 +193,7 @@ const verifyByDestination = function (destination, code, callback) { } if (ajv.validate('#otp/verify-with-destination', {destination: destination, code: code}) === false) { - callback(ajv.errorsText(ajv.errors)); + callback(formatAjvErrors(ajv.errors)); // return the promise if no callback specified return promise; @@ -172,7 +218,7 @@ const verifyByDestination = function (destination, code, callback) { }; // Bad request errors - if (error.response.status == 400) { + if (error.response.status === 400) { Object.assign(errorResponse, { data: error.response.data }); } @@ -189,10 +235,8 @@ const verifyByDestination = function (destination, code, callback) { * @function cancel * @param {string} id requestId received upon sending an OTP * @param {function} callback - * @version beta */ const cancelByRequestId = function (id, callback) { - // Setup Promise if no callback specified. let promise; @@ -235,17 +279,14 @@ const cancelByRequestId = function (id, callback) { return promise; }; - /** * Cancel an OTP request by using destination number * * @function cancel * @param {string} destination destination number * @param {function} callback - * @version beta */ const cancelByDestination = function (destination, callback) { - // Setup Promise if no callback specified. let promise; @@ -281,14 +322,10 @@ const cancelByDestination = function (destination, callback) { callback(errorResponse); }); - // return the promise if no callback specified return promise; }; -/** - * @version This api resource is curently a beta release - */ module.exports = { send, verifyByRequestId, diff --git a/lib/api/Sms.js b/lib/api/Sms.js index eb37692..43824cf 100644 --- a/lib/api/Sms.js +++ b/lib/api/Sms.js @@ -4,7 +4,7 @@ const uri = '/sms'; const ajv = require('../validator'); /** - * Send a sms request + * Send an SMS request * * @function send * @param {object} data @@ -24,7 +24,7 @@ const send = function (data, callback) { }); } - if (Object.keys(_data).length == 0) { + if (Object.keys(_data).length === 0) { callback(Error(errors.sms.missingData)); return promise; } @@ -54,7 +54,7 @@ const send = function (data, callback) { }; // Bad request errors - if (error.response.status == 400) { + if (error.response.status === 400) { Object.assign(errorResponse, { data: error.response.data }); } @@ -136,13 +136,12 @@ const getAll = function (options, callback) { } // validate optional parameters - if (_options && ajv.validate('#sms/getAll', _options) == false) { + if (_options && ajv.validate('#sms/getAll', _options) === false) { callback(ajv.errorsText(ajv.errors)); return promise; } - // TODO: Move to validor module - // validaton: maximum offset + limit <= 10,000 + // validation: maximum offset + limit <= 10,000 if (_options.offset) { // use default limit value if not set if (_options.offset + (_options.limit || 20) > 10000) { @@ -151,7 +150,6 @@ const getAll = function (options, callback) { } } - axios .get(uri, { params: _options, @@ -172,9 +170,11 @@ const getAll = function (options, callback) { status: error.response.statusText, }); }); + // return the promise if no callback specified return promise; }; + /* /** * @function deleteSms diff --git a/lib/api/SmsIncoming.js b/lib/api/SmsIncoming.js index 441e5a3..160f028 100644 --- a/lib/api/SmsIncoming.js +++ b/lib/api/SmsIncoming.js @@ -5,6 +5,7 @@ const uri = '/sms-incoming'; /** * @function dedicatedNumber + * @param id * @param {function} callback */ const deleteIncomingSms = function (id, callback) { @@ -51,7 +52,6 @@ const deleteIncomingSms = function (id, callback) { * @param {function} callback */ const getAll = function (options, callback) { - // keep it like api and dont force user to send an empty object with callback if (arguments.length === 1 && typeof options === 'function') { callback = options; @@ -72,12 +72,12 @@ const getAll = function (options, callback) { } // validate optional parameters - if (_options && ajv.validate('#sms-incoming/getAll', _options) == false) { + if (_options && ajv.validate('#sms-incoming/getAll', _options) === false) { callback(ajv.errorsText(ajv.errors)); return promise; } - // validaton: maximum offset + limit <= 10,000 + // validation: maximum offset + limit <= 10,000 if (_options.offset) { // use default limit value if not set if (_options.offset + (_options.limit || 20) > 10000) { @@ -113,7 +113,6 @@ const getAll = function (options, callback) { return promise; }; -/** /** * @function get * @param {integer} id sms id or outgoing id diff --git a/lib/client.js b/lib/client.js index 66b8c16..d03e2c7 100644 --- a/lib/client.js +++ b/lib/client.js @@ -4,7 +4,7 @@ const querystring = require('querystring'); const url = require('url'); const sdkConfig = require('./config'); -var axiosInstance = axios.create({ +const axiosInstance = axios.create({ baseURL: sdkConfig.host, /* other custom settings */ }); @@ -22,7 +22,7 @@ axiosInstance.interceptors.request.use((config) => { const timestamp = Math.floor(Date.now() / 1000); const nonce = Math.floor(Math.random() * 10000000); - const port = urlFragments.protocol == 'https:' ? 443 : 80; + const port = urlFragments.protocol === 'https:' ? 443 : 80; const auth = `${timestamp}\n${nonce}\n${config.method.toUpperCase()}\n${urlFragments.path}\n${urlFragments.host}\n${port}\n\n`; const hash = crypto .createHmac('sha256', process.env.SMSGLOBAL_API_SECRET) diff --git a/lib/config.js b/lib/config.js index 4116e69..b20c38c 100644 --- a/lib/config.js +++ b/lib/config.js @@ -2,6 +2,6 @@ module.exports = { host: 'https://api.smsglobal.com/v2', headers: { 'Content-Type': 'application/json', - 'User-Agent': `SMSGlobal-SDK/v2 Version/1.0.0 Node/${process.version} (${process.platform} ${process.arch}; OpenSSL/${process.versions.openssl})`, + 'User-Agent': `SMSGlobal-SDK/v2 Version/1.3.0 Node/${process.version} (${process.platform} ${process.arch}; OpenSSL/${process.versions.openssl})`, }, }; diff --git a/lib/errors.js b/lib/errors.js index 4e48c78..c363fbe 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -1,4 +1,4 @@ -// client side validation errors other than json scheema validator +// client side validation errors other than json schema validator module.exports = { smsglobal: 'api key and secret are both required parameters.', @@ -7,7 +7,7 @@ module.exports = { missingData: 'OTP data is required', destination: 'destination number should be string', }, - searchOffsetLimit: 'offset and limit (defualt 20) total can not exceed 10000.', + searchOffsetLimit: 'offset and limit (default 20) total can not exceed 10000.', sms: { missingData: 'sms data not provided.', }, diff --git a/lib/schema.js b/lib/schema.js index b863591..4115f3f 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -65,7 +65,6 @@ module.exports = [ $id: '#sms/getAll', type: 'object', additionalProperties: false, - useDefaults: true, properties: { offset: { type: 'integer', minimum: 1 }, limit: { type: 'integer', minimum: 1, maximum: 1000 }, @@ -89,7 +88,6 @@ module.exports = [ $id: '#sms-incoming/getAll', type: 'object', additionalProperties: false, - useDefaults: true, properties: { offset: { type: 'integer', minimum: 1 }, limit: { type: 'integer', minimum: 1, maximum: 1000 }, @@ -116,13 +114,12 @@ module.exports = [ required: ['id', 'code'], properties: { id: { type: 'string'}, - code: { - type: 'string', minLength: 4, maxKength: 10 }, + code: { type: 'string', minLength: 4, maxLength: 10 }, }, errorMessage: { properties: { - id: 'id should be a string', - code: 'code should be an integer', + id: 'should be string', + code: 'should be string', }, }, }, @@ -133,13 +130,12 @@ module.exports = [ required: ['destination', 'code'], properties: { destination: { type: 'string', minLength: 3, maxLength: 15}, - code: { - type: 'string', minLength: 4, maxKength: 10 }, + code: { type: 'string', minLength: 4, maxLength: 10 }, }, errorMessage: { properties: { - id: 'destination should be a string', - code: 'code should be an integer', + id: 'should be a string', + code: 'should be string', }, }, }, @@ -161,7 +157,6 @@ module.exports = [ }, message: { type: 'string' }, messageExpiryDateTime: { - type: ['string', 'object'], dateTimeFormat: dateTimeFormat, }, diff --git a/lib/validator.js b/lib/validator.js index b24c1fb..1485086 100644 --- a/lib/validator.js +++ b/lib/validator.js @@ -12,12 +12,9 @@ ajv.addKeyword('dateTimeFormat', { modifying: true, errors: true, validate: function validator(schema, data) { - - validator.errors = [{keyword: 'dateTimeFormat', message: `shoud be a valid date time string (${schema})`, params: {keyword: 'dateTimeFormat'}}]; - + validator.errors = [{keyword: 'dateTimeFormat', message: `should be a valid date time string (${schema})`, params: {keyword: 'dateTimeFormat'}}]; // validate data and convert into given as format return typeof data === 'string' && luxon.DateTime.fromFormat(data, schema).isValid; - }, }); diff --git a/package.json b/package.json index 4715fd2..b07e756 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "smsglobal", - "version": "1.2.5", + "version": "2.0.0", "description": "SDK for SMSGlobal rest api", "homepage": "https://github.com/smsglobal/smsglobal-node#readme", "bugs": { @@ -26,28 +26,29 @@ }, "license": "MIT", "dependencies": { - "ajv": "^6.12.2", - "axios": "^1.7.9", - "luxon": "^1.25.0" + "ajv": "^8.17.1", + "ajv-errors": "^3.0.0", + "axios": "^1.13.2", + "luxon": "^3.7.2" }, "devDependencies": { "asset": "^0.4.13", - "chai": "^4.2.0", - "dotenv": "^8.2.0", - "eslint": "^7.2.0", - "eslint-config-prettier": "^6.11.0", - "eslint-plugin-chai-friendly": "^0.6.0", - "eslint-plugin-import": "^2.21.2", - "eslint-plugin-prettier": "^3.1.4", + "chai": "^6.2.0", + "dotenv": "^17.2.3", + "eslint": "^9.39.1", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-chai-friendly": "^1.1.0", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-prettier": "^5.5.4", "install": "^0.13.0", - "mocha": "^7.1.2", - "nock": "^13.0.3", - "npm": "^6.14.5", - "nyc": "^15.0.1", - "prettier": "^2.0.5" + "mocha": "^11.7.5", + "nock": "^14.0.10", + "npm": "^11.6.2", + "nyc": "^17.1.0", + "prettier": "^3.6.2" }, "engines": { - "node": ">=9" + "node": ">=22" }, "directories": { "example": "examples", diff --git a/test/Otp.spec.js b/test/Otp.spec.js index 49907ab..f1c86a9 100644 --- a/test/Otp.spec.js +++ b/test/Otp.spec.js @@ -77,9 +77,9 @@ describe('OTP', () => { let response = { requestId: '404372541681858603038893', destination: '61400000000', - validUnitlTimestamp: '2020-10-29 15:24:33', - createdTimestamp: '2020-10-29 15:22:33', - lastEventTimestamp: '2020-10-29 15:22:33', + validUnitlTimestamp: '2025-10-29 15:24:33', + createdTimestamp: '2025-10-29 15:22:33', + lastEventTimestamp: '2025-10-29 15:22:33', status: 'Sent', }; nock(config.host) @@ -97,13 +97,12 @@ describe('OTP', () => { }); describe('cancel', () => { - let response = { requestId: '404372541681858603038893', destination: '61400000000', - validUnitlTimestamp: '2020-10-29 15:24:33', - createdTimestamp: '2020-10-29 15:22:33', - lastEventTimestamp: '2020-10-29 15:22:33', + validUnitlTimestamp: '2025-10-29 15:24:33', + createdTimestamp: '2025-10-29 15:22:33', + lastEventTimestamp: '2025-10-29 15:22:33', status: 'Cancelled', }; @@ -195,13 +194,12 @@ describe('OTP', () => { }); describe('verify', () => { - let response = { requestId: '404372541681858603038893', destination: '61400000000', - validUnitlTimestamp: '2020-10-29 15:24:33', - createdTimestamp: '2020-10-29 15:22:33', - lastEventTimestamp: '2020-10-29 15:22:33', + validUnitlTimestamp: '2025-10-29 15:24:33', + createdTimestamp: '2025-10-29 15:22:33', + lastEventTimestamp: '2025-10-29 15:22:33', status: 'Verified', }; @@ -269,7 +267,6 @@ describe('OTP', () => { ); }); - it('should should verify an OTP request with destination number', () => { nock(config.host).post(`${uri}/${response.destination}/validate`).reply(200, response); Smsglobal.otp.verifyByDestination(response.destination, '32423', (err, res) => { @@ -289,6 +286,5 @@ describe('OTP', () => { () => Promise.reject(new Error('Expected method to resolve.')), ); }); - }); }); diff --git a/test/Sms.spec.js b/test/Sms.spec.js index 218fdc1..63131b9 100755 --- a/test/Sms.spec.js +++ b/test/Sms.spec.js @@ -17,7 +17,7 @@ describe('Outgoing', () => { afterEach(nock.cleanAll); - const apiOutgingResponses = { + const apiOutgoingResponses = { singleDestination: { id: 6359736682344313, outgoing_id: 5211897953, @@ -25,7 +25,7 @@ describe('Outgoing', () => { destination: '61400000000', message: 'Test sms from node sdk', status: 'sent', - dateTime: '2020-07-30 13:23:38 +0000', + dateTime: '2025-07-30 13:23:38 +0000', }, multipleDestinations: { messages: [ @@ -34,7 +34,7 @@ describe('Outgoing', () => { origin: 'NodeSdk', destination: '61400000000', message: 'Test sms from node sdk', - dateTime: '2020-07-30 14:29:50 +0000', + dateTime: '2025-07-30 14:29:50 +0000', status: 'Processing', }, { @@ -42,12 +42,12 @@ describe('Outgoing', () => { origin: 'NodeSdk', destination: '61400000000', message: 'Test sms from node sdk', - dateTime: '2020-07-30 14:29:50 +0000', + dateTime: '2025-07-30 14:29:50 +0000', status: 'Processing', }, ], }, - incompleteMesssage: { + incompleteMessage: { status: 'OK', data: { messages: [] }, }, @@ -58,7 +58,7 @@ describe('Outgoing', () => { destination: '61400000000', message: 'Test sms from node sdk', status: 'delivered', - dateTime: '2020-08-18 10:36:29 +1000', + dateTime: '2025-08-18 10:36:29 +1000', }, fetchAllSms: { total: 4165, @@ -72,7 +72,7 @@ describe('Outgoing', () => { destination: '61400000000', message: 'Test sms from node sdk', status: 'delivered', - dateTime: '2020-08-18 10:36:29 +1000', + dateTime: '2025-08-18 10:36:29 +1000', }, { id: 6298870819574735, @@ -81,7 +81,7 @@ describe('Outgoing', () => { destination: '61400000000', message: 'Test sms from node sdk', status: 'delivered', - dateTime: '2020-08-18 10:36:29 +1000', + dateTime: '2025-08-18 10:36:29 +1000', }, ], }, @@ -158,7 +158,7 @@ describe('Outgoing', () => { Smsglobal.sms.send({ messages: [{}]}).then( (res) => { assert.equal(res.statusCode, 200); - assert.deepEqual(res.data, apiOutgingResponses.incompleteMesssage); + assert.deepEqual(res.data, apiOutgoingResponses.incompleteMessage); }, () => Promise.reject(new Error('Expected method to resolve.')), ); @@ -167,18 +167,18 @@ describe('Outgoing', () => { it('should send a sms to single destination with promises', () => { nock(config.host) .post(uri) - .reply(200, apiOutgingResponses.singleDestination); + .reply(200, apiOutgoingResponses.singleDestination); Smsglobal.sms .send({ origin: 'NodeSdk', message: 'Test sms from node sdk 2', destination: '61400000000', - scheduledDateTime: '2020-08-28 03:38:20', + scheduledDateTime: '2025-08-28 03:38:20', }) .then((res) => { assert.equal(res.statusCode, 200); - assert.deepEqual(res.data, apiOutgingResponses.singleDestination); + assert.deepEqual(res.data, apiOutgoingResponses.singleDestination); }, () => Promise.reject(new Error('Expected method to resolve.')), ); @@ -187,7 +187,7 @@ describe('Outgoing', () => { it('should send a sms to multiple destinations', () => { nock(config.host) .post(uri) - .reply(200, apiOutgingResponses.multipleDestinations); + .reply(200, apiOutgoingResponses.multipleDestinations); Smsglobal.sms.send( { @@ -198,7 +198,7 @@ describe('Outgoing', () => { function (err, res) { assert.equal(err, ''); assert.equal(res.statusCode, 200); - assert.deepEqual(res.data, apiOutgingResponses.multipleDestinations); + assert.deepEqual(res.data, apiOutgoingResponses.multipleDestinations); }, ); }); @@ -206,7 +206,7 @@ describe('Outgoing', () => { it('should send mulitple sms as an array', () => { nock(config.host) .post(uri) - .reply(200, apiOutgingResponses.multipleDestinations); + .reply(200, apiOutgoingResponses.multipleDestinations); Smsglobal.sms.send( { @@ -226,7 +226,7 @@ describe('Outgoing', () => { function (err, res) { assert.equal(err, ''); assert.equal(res.statusCode, 200); - assert.deepEqual(res.data, apiOutgingResponses.multipleDestinations); + assert.deepEqual(res.data, apiOutgoingResponses.multipleDestinations); }, ); }); @@ -255,12 +255,11 @@ describe('Outgoing', () => { ); }); - it('should fail when id not given with promise', () => { - let id = apiOutgingResponses.fetchSingleSms.id; + let id = apiOutgoingResponses.fetchSingleSms.id; nock(config.host) .get(`${uri}/${id}`) - .reply(200, apiOutgingResponses.fetchSingleSms); + .reply(200, apiOutgoingResponses.fetchSingleSms); Smsglobal.sms.get().then( () => Promise.reject(new Error('Expected method to reject.')), @@ -272,35 +271,33 @@ describe('Outgoing', () => { }); it('should fetch single sms as an object', () => { - let id = apiOutgingResponses.fetchSingleSms.id; + let id = apiOutgoingResponses.fetchSingleSms.id; nock(config.host) .get(`${uri}/${id}`) - .reply(200, apiOutgingResponses.fetchSingleSms); + .reply(200, apiOutgoingResponses.fetchSingleSms); Smsglobal.sms.get(id).then( (res) => { assert.equal(res.statusCode, 200); - assert.deepEqual(res.data, apiOutgingResponses.fetchSingleSms); + assert.deepEqual(res.data, apiOutgoingResponses.fetchSingleSms); }, () => Promise.reject(new Error('Expected method to resolve.')), ); }); }); - describe('getAll', () => { - it('should load outgoing sms list with as array when callback is only given argument', () => { nock(config.host) .get('/sms') - .reply(200, apiOutgingResponses.fetchAllSms); + .reply(200, apiOutgoingResponses.fetchAllSms); Smsglobal.sms.getAll((err, res) => { assert.equal(err, ''); assert.equal(res.statusCode, 200); assert.deepEqual( res.data, - apiOutgingResponses.fetchAllSms, + apiOutgoingResponses.fetchAllSms, ); }); }); @@ -310,7 +307,7 @@ describe('Outgoing', () => { nock(config.host) .get('/sms') .query(query) - .reply(200, apiOutgingResponses.fetchAllSms); + .reply(200, apiOutgoingResponses.fetchAllSms); Smsglobal.sms.getAll(query).then( () => Promise.reject(new Error('Expected method to reject.')), @@ -326,7 +323,7 @@ describe('Outgoing', () => { nock(config.host) .get('/sms') .query(query) - .reply(200, apiOutgingResponses.fetchAllSms); + .reply(200, apiOutgoingResponses.fetchAllSms); Smsglobal.sms.getAll(query).then( () => Promise.reject(new Error('Expected method to reject.')), @@ -342,7 +339,7 @@ describe('Outgoing', () => { nock(config.host) .get('/sms') .query(query) - .reply(200, apiOutgingResponses.fetchAllSms); + .reply(200, apiOutgoingResponses.fetchAllSms); Smsglobal.sms.getAll(query).then( () => Promise.reject(new Error('Expected method to reject.')), @@ -365,27 +362,24 @@ describe('Outgoing', () => { ); }); - it('should load outgoing sms list with as array of object with promise', () => { let query = { limit: 2 }; nock(config.host) .get('/sms') .query(query) - .reply(200, apiOutgingResponses.fetchAllSms); + .reply(200, apiOutgoingResponses.fetchAllSms); Smsglobal.sms.getAll(query).then( (res) => { assert.equal(res.statusCode, 200); assert.deepEqual( res.data, - apiOutgingResponses.fetchAllSms, + apiOutgoingResponses.fetchAllSms, ); }, () => Promise.reject(new Error('Expected method to resolve.')), ); }); - - }); describe('delete', () => { @@ -420,4 +414,3 @@ describe('Outgoing', () => { }); }); }); - diff --git a/test/SmsIncoming.spec.js b/test/SmsIncoming.spec.js index 8b2dbe2..47ba98d 100644 --- a/test/SmsIncoming.spec.js +++ b/test/SmsIncoming.spec.js @@ -18,13 +18,12 @@ describe('Incoming', () => { afterEach(nock.cleanAll); describe('get', () => { - let incomingSmsResponse = { id: 465605611, origin: '61400000001', destination: '61400000000', message: 'Test sms from SMSGlobal', - dateTime: '2020-08-04 11:24:27 +1000', + dateTime: '2025-08-04 11:24:27 +1000', isMultipart: false, }; @@ -85,7 +84,6 @@ describe('Incoming', () => { }); describe('getAll', () => { - let getAllSmsResponse = { total: 173, offset: 1, @@ -94,18 +92,17 @@ describe('Incoming', () => { { origin: '61400000000', destination: '61400000001', - dateTime: '2020-08-05 11:04:04 +1000', + dateTime: '2025-08-05 11:04:04 +1000', isMultipart: false, }, { origin: '61400000000', destination: '61400000002', - dateTime: '2020-08-04 15:56:05 +1000', + dateTime: '2025-08-04 15:56:05 +1000', isMultipart: false, }], }; - it('should fail when invalid search data is given with promise', () => { let query = { limit: 1200, destination: '33' }; nock(config.host) @@ -150,8 +147,7 @@ describe('Incoming', () => { ); }); - - it('should load outgoing sms list with as array when callback is only given argument', () => { + it('should load outgoing sms list as array when callback is only given argument', () => { nock(config.host) .get(uri) .reply(200, getAllSmsResponse); @@ -165,8 +161,7 @@ describe('Incoming', () => { }); }); - - it('should load sms list with as array of object with promise', () => { + it('should load sms list as array of object with promise', () => { let query = { limit: 2 }; nock(config.host) .get(uri) @@ -227,6 +222,5 @@ describe('Incoming', () => { () => Promise.reject(new Error('Expected method to resolve.')), ); }); - }); }); diff --git a/test/Smsglobal.spec.js b/test/Smsglobal.spec.js index dd23eb1..99d8744 100644 --- a/test/Smsglobal.spec.js +++ b/test/Smsglobal.spec.js @@ -2,20 +2,18 @@ const { expect } = require('chai'); const errors = require('../lib/errors'); describe('Smsglobal', () => { - after(() => { delete process.env.SMSGLOBAL_API_KEY; delete process.env.SMSGLOBAL_API_SECRET; }); it('should fail if no api key or api secret are specified', () => { - var Smsglobal = require('../lib'); + const Smsglobal = require('../lib'); expect(() => { new Smsglobal();}).to.throw(errors.smsglobal); }); - it('should return smsglobal instahce with given key & secret', () => { + it('should return smsglobal instance with given key & secret', () => { const Smsglobal = require('../lib'); expect((new Smsglobal('key', 'secret'))).to.be.an.instanceof(Smsglobal); }); }); -