@itentialopensource/adapter-aruba_airwave 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/.eslintignore +6 -0
  2. package/.eslintrc.js +18 -0
  3. package/.gitlab/.gitkeep +0 -0
  4. package/.gitlab/issue_templates/.gitkeep +0 -0
  5. package/.gitlab/issue_templates/Default.md +17 -0
  6. package/.gitlab/issue_templates/bugReportTemplate.md +76 -0
  7. package/.gitlab/issue_templates/featureRequestTemplate.md +14 -0
  8. package/.jshintrc +0 -0
  9. package/CHANGELOG.md +9 -0
  10. package/CODE_OF_CONDUCT.md +48 -0
  11. package/CONTRIBUTING.md +158 -0
  12. package/LICENSE +201 -0
  13. package/README.md +544 -0
  14. package/adapter.js +2860 -0
  15. package/adapterBase.js +906 -0
  16. package/entities/.system/action.json +50 -0
  17. package/entities/.system/mockdatafiles/getToken-default.json +3 -0
  18. package/entities/.system/mockdatafiles/healthcheck-default.json +3 -0
  19. package/entities/.system/schema.json +19 -0
  20. package/entities/.system/schemaTokenReq.json +77 -0
  21. package/entities/.system/schemaTokenResp.json +65 -0
  22. package/entities/BatchExecuteAPCommandsAPIS/action.json +45 -0
  23. package/entities/BatchExecuteAPCommandsAPIS/schema.json +20 -0
  24. package/entities/ConfigurationAPIS/action.json +126 -0
  25. package/entities/ConfigurationAPIS/schema.json +90 -0
  26. package/entities/DeviceAPIS/action.json +46 -0
  27. package/entities/DeviceAPIS/schema.json +20 -0
  28. package/entities/LOGIN/action.json +24 -0
  29. package/entities/LOGIN/schema.json +41 -0
  30. package/entities/QueryAPIS/action.json +298 -0
  31. package/entities/QueryAPIS/schema.json +32 -0
  32. package/entities/ReportAPIS/action.json +25 -0
  33. package/entities/ReportAPIS/schema.json +30 -0
  34. package/entities/SearchAPIS/action.json +67 -0
  35. package/entities/SearchAPIS/schema.json +21 -0
  36. package/error.json +184 -0
  37. package/package.json +86 -0
  38. package/pronghorn.json +1589 -0
  39. package/propertiesSchema.json +801 -0
  40. package/refs?service=git-upload-pack +0 -0
  41. package/report/ArubaAirwavePostman.json-OpenApi3Json.json +1583 -0
  42. package/report/creationReport.json +381 -0
  43. package/sampleProperties.json +97 -0
  44. package/test/integration/adapterTestBasicGet.js +85 -0
  45. package/test/integration/adapterTestConnectivity.js +93 -0
  46. package/test/integration/adapterTestIntegration.js +1125 -0
  47. package/test/unit/adapterBaseTestUnit.js +929 -0
  48. package/test/unit/adapterTestUnit.js +1413 -0
  49. package/utils/artifactize.js +146 -0
  50. package/utils/basicGet.js +63 -0
  51. package/utils/packModificationScript.js +35 -0
  52. package/utils/pre-commit.sh +27 -0
  53. package/utils/setup.js +33 -0
  54. package/utils/tbScript.js +163 -0
  55. package/utils/tbUtils.js +372 -0
  56. package/utils/testRunner.js +298 -0
  57. package/utils/troubleshootingAdapter.js +219 -0
  58. package/workflows/README.md +3 -0
@@ -0,0 +1,372 @@
1
+ /* @copyright Itential, LLC 2020 */
2
+
3
+ /* eslint import/no-extraneous-dependencies: warn */
4
+ /* eslint global-require: warn */
5
+ /* eslint import/no-dynamic-require: warn */
6
+
7
+ const path = require('path');
8
+ const fs = require('fs-extra');
9
+ const cp = require('child_process');
10
+
11
+ module.exports = {
12
+ SERVICE_CONFIGS_COLLECTION: 'service_configs',
13
+ IAP_PROFILES_COLLECTION: 'iap_profiles',
14
+
15
+ /**
16
+ * @summary update newConnection properties in adapter config
17
+ *
18
+ * @function updateNewConnection
19
+ * @param {Object} config - adaper configuration object required by IAP
20
+ * @param {Object} newConnection - connection related property collection from user
21
+ */
22
+ updateNewConnection: (config, newConnection) => {
23
+ const updatedConfig = JSON.parse(JSON.stringify(config));
24
+ Object.keys(newConnection).forEach((key) => {
25
+ updatedConfig.properties.properties[key] = newConnection[key];
26
+ });
27
+ return updatedConfig;
28
+ },
29
+
30
+ /**
31
+ * @summary assemble heathcheck endpoint into an URL
32
+ *
33
+ * @function getHealthCheckEndpointURL
34
+ * @param {Object} endpoint - user updated healthcheck endpoint object
35
+ * @param {Object} config - adaper configuration object required by IAP
36
+ */
37
+ getHealthCheckEndpointURL: (endpoint, config) => {
38
+ const p = config.properties.properties;
39
+ const healthCheckEndpointURL = `${p.protocol}://${p.host}${p.base_path}${p.version}${endpoint.healthCheckEndpoint}`;
40
+ console.log({ healthCheckEndpointURL });
41
+ return healthCheckEndpointURL;
42
+ },
43
+
44
+ /**
45
+ * @summary persist healthcheck endpoint when user make update
46
+ *
47
+ * @function updateHealthCheckEndpoint
48
+ * @param {Object} newHealthCheckEndpoint - user confirmed healthcheck object
49
+ * @param {Object} healthCheckEndpoint - existing healthcheck object
50
+ * @param {Object} healthcheck - ./entities/.system/action.json object
51
+ */
52
+ updateHealthCheckEndpoint: (newHealthCheckEndpoint, healthCheckEndpoint, healthcheck) => {
53
+ if (newHealthCheckEndpoint.healthCheckEndpoint !== healthCheckEndpoint.healthCheckEndpoint) {
54
+ const p = healthcheck.actions[1].entitypath;
55
+ const newEntitypath = p.slice(0, 21) + newHealthCheckEndpoint.healthCheckEndpoint + p.slice(p.length - 8);
56
+ const updatedHealthcheck = JSON.parse(JSON.stringify(healthcheck));
57
+ updatedHealthcheck.actions[1].entitypath = newEntitypath;
58
+ console.log('updating healthcheck setting');
59
+ fs.writeFileSync('./entities/.system/action.json', JSON.stringify(updatedHealthcheck, null, 2));
60
+ }
61
+ },
62
+
63
+ /**
64
+ * @summary update authentication property given new input value from user
65
+ * compare values from auth and newAuth, if there's difference
66
+ * update adapter config
67
+ * @function updateAuth
68
+ * @param {Object} newAuth - user confirmed authentication object
69
+ * @param {Object} auth - existing authentication object
70
+ * @param {Object} config - adaper configuration object required by IAP
71
+ */
72
+ updateAuth: (newAuth, auth, config) => {
73
+ const updatedConfig = JSON.parse(JSON.stringify(config));
74
+ if (Object.keys(newAuth).every((key) => newAuth[key] === auth[key])) {
75
+ return config;
76
+ }
77
+ Object.keys(newAuth).forEach((key) => {
78
+ updatedConfig.properties.properties.authentication[key] = newAuth[key];
79
+ });
80
+ console.log(updatedConfig.properties.properties.authentication);
81
+ return updatedConfig;
82
+ },
83
+
84
+ /**
85
+ * @summary add mark current auth_method with `(current)`
86
+ *
87
+ * @function getDisplayAuthOptions
88
+ * @param {String} currentAuth - current auth method in adapter config
89
+ * @param {Array} authOptions - available auth method
90
+ */
91
+ getDisplayAuthOptions: (currentAuth, authOptions) => {
92
+ const displayAuthOptions = JSON.parse(JSON.stringify(authOptions));
93
+ displayAuthOptions[authOptions.indexOf(currentAuth)] += ' (current)';
94
+ return displayAuthOptions;
95
+ },
96
+
97
+ /**
98
+ * @summary decrypt IAP properties
99
+ * code from pronghorn-core/migration_scripts/installService.js
100
+ *
101
+ * @function decryptProperties
102
+ */
103
+ decryptProperties: (props, dirname, discovery) => {
104
+ const propertyEncryptionClassPath = path.join(dirname, '../../../@itential/pronghorn-core/core/PropertyEncryption.js');
105
+ const isEncrypted = props.pathProps.encrypted;
106
+ const PropertyEncryption = discovery.require(propertyEncryptionClassPath, isEncrypted);
107
+ const propertyEncryption = new PropertyEncryption({
108
+ algorithm: 'aes-256-ctr',
109
+ key: 'TG9uZ0Rpc3RhbmNlUnVubmVyUHJvbmdob3JuCg==',
110
+ encoding: 'utf-8'
111
+ });
112
+ return propertyEncryption.decryptProps(props);
113
+ },
114
+
115
+ /**
116
+ * @summary create connection object for verification
117
+ *
118
+ * @function getConnection
119
+ * @param {Object} props - adapter config.properties
120
+ */
121
+ getConnection: (props) => {
122
+ const connection = {
123
+ host: props.properties.host,
124
+ base_path: props.properties.base_path,
125
+ protocol: props.properties.protocol,
126
+ version: props.properties.version,
127
+ port: props.properties.port
128
+ };
129
+ return connection;
130
+ },
131
+
132
+ /**
133
+ * @summary update connection properties based on user answer
134
+ *
135
+ * @function getNewProps
136
+ * @param {Array} answers - values collected from CLI
137
+ * @param {Object} connection - connection property verified by user
138
+ */
139
+ getNewProps: (answers, connection) => {
140
+ if (answers.every((answer) => answer === '')) {
141
+ return connection;
142
+ }
143
+ const newConnection = {};
144
+ const properties = Object.keys(connection);
145
+ for (let i = 0; i < answers.length; i += 1) {
146
+ if (answers[i]) {
147
+ newConnection[properties[i]] = Number.isNaN(Number(answers[i])) ? answers[i] : Number(answers[i]);
148
+ } else {
149
+ newConnection[properties[i]] = connection[properties[i]];
150
+ }
151
+ }
152
+ return newConnection;
153
+ },
154
+
155
+ /**
156
+ * @summary extract endpoint string from healthcheck object
157
+ *
158
+ * @function getHealthCheckEndpoint
159
+ * @param {Object} healthcheck - {Object} healthcheck - ./entities/.system/action.json object
160
+ */
161
+ getHealthCheckEndpoint: (healthcheck) => {
162
+ const endpoint = healthcheck.actions[1].entitypath.slice(21,
163
+ healthcheck.actions[1].entitypath.length - 8);
164
+ return { healthCheckEndpoint: endpoint };
165
+ },
166
+
167
+ /**
168
+ * @summary Verify that the adapter is in the correct directory
169
+ * - Within IAP
170
+ * - In node_modules/@ namespace
171
+ * verify the adapter is installed under node_modules/
172
+ * and is consistent with the name property of package.json
173
+ * and the node_modules/ is in the correct path within IAP
174
+ * @param {String} dirname - current path
175
+ * @param {String} name - name property from package.json
176
+ */
177
+ verifyInstallationDir: (dirname, name) => {
178
+ const pathArray = dirname.split(path.sep);
179
+ const expectedPath = `node_modules/${name}`;
180
+ const currentPath = pathArray.slice(pathArray.length - 4, pathArray.length - 1).join('/');
181
+ if (expectedPath !== currentPath) {
182
+ throw new Error(`adapter should be installed under ${expectedPath}`);
183
+ }
184
+
185
+ const serverFile = path.join(dirname, '../../../..', 'server.js');
186
+ if (!fs.existsSync(serverFile)) {
187
+ throw new Error(`adapter should be installed under IAP/${expectedPath}`);
188
+ }
189
+ console.log(`adapter correctly installed at ${currentPath}`);
190
+ },
191
+
192
+ /**
193
+ * @summary execute command and preserve the output the same as run command in shell
194
+ *
195
+ * @function systemSync
196
+ * @param {String} cmd - Command to execute
197
+ * @param {boolean} process - Whether stdout should be processed and returned
198
+ */
199
+ systemSync: function systemSync(cmd, process) {
200
+ if (process) {
201
+ let stdout;
202
+ try {
203
+ stdout = cp.execSync(cmd).toString();
204
+ } catch (error) {
205
+ stdout = error.stdout.toString();
206
+ }
207
+ const output = this.getTestCount(stdout);
208
+ output.stdout = stdout;
209
+ return output;
210
+ }
211
+ try {
212
+ return cp.execSync(cmd, { stdio: 'inherit' });
213
+ } catch (error) {
214
+ return console.error(error.stdout);
215
+ }
216
+ },
217
+
218
+ /**
219
+ * @summary parses a string and returns the number parsed from startIndex backwards
220
+ *
221
+ * @function parseNum
222
+ * @param {String} inputStr - Any String
223
+ * @param {Number} startIndex - Index to begin parsing
224
+ */
225
+ parseNum: function parseNum(inputStr, startIndex) {
226
+ let count = '';
227
+ let currChar;
228
+ let start = startIndex;
229
+ while (currChar !== ' ') {
230
+ currChar = inputStr.charAt(start);
231
+ count = currChar + count;
232
+ start -= 1;
233
+ }
234
+ return parseInt(count, 10);
235
+ },
236
+
237
+ /**
238
+ * @summary Parses a mocha test result and returns the count of passing and failing tests
239
+ *
240
+ * @function getTestCount
241
+ * @param {String} testStr - Output from mocha test
242
+ */
243
+ getTestCount: function getTestCount(testStr) {
244
+ const passIndex = testStr.search('passing');
245
+ const failIndex = testStr.search('failing');
246
+ const passCount = passIndex >= 0 ? this.parseNum(testStr, passIndex - 2) : 0;
247
+ const failCount = failIndex >= 0 ? this.parseNum(testStr, failIndex - 2) : 0;
248
+ return { passCount, failCount };
249
+ },
250
+
251
+ /**
252
+ * @summary remove package-lock.json and node_modules directory if exists
253
+ * run npm install and print result to stdout
254
+ */
255
+ npmInstall: function npmInstall() {
256
+ fs.removeSync('../package-lock.json');
257
+ fs.removeSync('../node_modules/');
258
+ console.log('Run npm install ...');
259
+ this.systemSync('npm install');
260
+ },
261
+
262
+ /**
263
+ * @summary run lint, unit test and integration test
264
+ * print result to stdout
265
+ */
266
+ runTest: function runTest() {
267
+ this.systemSync('npm run lint:errors');
268
+ this.systemSync('npm run test:unit');
269
+ this.systemSync('npm run test:integration');
270
+ },
271
+
272
+ /**
273
+ * @summary run basicget with mocha
274
+ * @param {boolean} scriptFlag - whether the function is ran from a script
275
+ * print result to stdout
276
+ * returns mocha test results otherwise
277
+ */
278
+ runBasicGet: function runBasicGet(scriptFlag) {
279
+ const testPath = path.resolve(__dirname, '..', 'test/integration/adapterTestBasicGet.js');
280
+ return this.systemSync(`mocha ${testPath} --exit`, !scriptFlag);
281
+ },
282
+
283
+ /**
284
+ * @summary run connectivity with mocha
285
+ * @param {String} host - Host url to run healthcheck
286
+ * @param {boolean} scriptFlag - Whether the function is ran from a script
287
+ * print result to stdout if ran from script
288
+ * returns mocha test results otherwise
289
+ */
290
+ runConnectivity: function runConnectivity(host, scriptFlag) {
291
+ let testPath = 'test/integration/adapterTestConnectivity.js';
292
+ if (!scriptFlag) {
293
+ testPath = path.resolve(__dirname, '..', testPath);
294
+ }
295
+ return this.systemSync(`mocha ${testPath} --HOST=${host} --timeout 10000 --exit`, !scriptFlag);
296
+ },
297
+
298
+ /**
299
+ * @summary create Adapter property
300
+ *
301
+ * @function createAdapter
302
+ * @param {Object} pronghornProps - decrypted 'properties.json' from IAP root directory
303
+ * @param {Object} profileItem - pronghorn props saved in database
304
+ * @param {Object} adapterPronghorn - ./pronghorn.json in adapter dir
305
+ * @param {Object} sampleProperties - './sampleProperties.json' in adapter dir
306
+ */
307
+ createAdapter: (pronghornProps, profileItem, sampleProperties, adapterPronghorn) => {
308
+ const adapter = {
309
+ mongoProps: pronghornProps.mongoProps,
310
+ isEncrypted: pronghornProps.pathProps.encrypted,
311
+ model: adapterPronghorn.id,
312
+ name: sampleProperties.id,
313
+ type: adapterPronghorn.type,
314
+ properties: sampleProperties,
315
+ redisProps: profileItem.redisProps,
316
+ loggerProps: profileItem.loggerProps,
317
+ rabbitmq: profileItem.rabbitmq
318
+ };
319
+ adapter.loggerProps.log_filename = `adapter-${adapter.name}.log`;
320
+ adapter.mongoProps.pdb = true;
321
+ return adapter;
322
+ },
323
+
324
+ /**
325
+ * @summary return async healthcheck result as a Promise
326
+ *
327
+ * @function request
328
+ * @param {Adapter} a - Adapter instance
329
+ */
330
+ request: function request(a) {
331
+ return new Promise((resolve, reject) => {
332
+ a.healthCheck(null, (data) => {
333
+ if (!data) reject(new Error('healthCheckEndpoint failed'));
334
+ resolve(data);
335
+ });
336
+ });
337
+ },
338
+
339
+ /**
340
+ * @summary deal with healthcheck response returned from adapter instace
341
+ *
342
+ * @function healthCheck
343
+ * @param {Adapter} a - Adapter instance
344
+ */
345
+ healthCheck: async function healthCheck(a) {
346
+ const result = await this.request(a)
347
+ .then((res) => {
348
+ console.log('healthCheckEndpoint OK');
349
+ return res;
350
+ })
351
+ .catch((error) => {
352
+ console.error(error.message);
353
+ return false;
354
+ });
355
+ return result;
356
+ },
357
+
358
+ /**
359
+ * @summary Check whether adapter is located within IAP node_modules
360
+ * by loading properties.json. If not, return false.
361
+ * @function withinIAP
362
+ * @param {String} iapDir root directory of IAP
363
+ */
364
+ withinIAP: (iapDir) => {
365
+ try {
366
+ const rawProps = require(path.join(iapDir, 'properties.json'));
367
+ return rawProps;
368
+ } catch (error) {
369
+ return false;
370
+ }
371
+ }
372
+ };
@@ -0,0 +1,298 @@
1
+ #!/usr/bin/env node
2
+ /* @copyright Itential, LLC 2019 */
3
+
4
+ const fs = require('fs-extra');
5
+ const rl = require('readline-sync');
6
+ const execute = require('child_process').exec;
7
+
8
+ /**
9
+ * This script will determine the type of integration test to run
10
+ * based on input. If other information is needed, it will solicit
11
+ * that input and then edit the integration test accordingly.
12
+ */
13
+
14
+ let stub = true;
15
+ let isRapidFail = false;
16
+ let isSaveMockData = false;
17
+ let host = 'replace.hostorip.here';
18
+ let username = 'username';
19
+ let password = 'password';
20
+ let protocol = 'http';
21
+ let port = 80;
22
+ let sslenable = false;
23
+ let sslinvalid = false;
24
+ const dstub = true;
25
+ const disRapidFail = false;
26
+ const disSaveMockData = false;
27
+ const dhost = 'replace.hostorip.here';
28
+ const dusername = 'username';
29
+ const dpassword = 'password';
30
+ const dprotocol = 'http';
31
+ const dport = 80;
32
+ const dsslenable = false;
33
+ const dsslinvalid = false;
34
+
35
+ let stderror = false;
36
+ let running = false;
37
+
38
+ /**
39
+ * Updates the integration test file with the proper vars
40
+ */
41
+ function replaceTestVars(test) {
42
+ if (!fs.existsSync(test)) {
43
+ console.log(`Could not find ${test}`);
44
+ return 'error';
45
+ }
46
+
47
+ let intTest = fs.readFileSync(test, 'utf8');
48
+
49
+ // replace stub variable but check if it exists first
50
+ let sindex = intTest.indexOf('const stub');
51
+ let eindex = intTest.indexOf(';', sindex);
52
+ let replStr = intTest.substring(sindex, eindex + 1);
53
+ if (sindex > -1) {
54
+ intTest = intTest.replace(replStr, `const stub = ${stub};`);
55
+ }
56
+
57
+ // replace isRapidFail variable but check if it exists first
58
+ sindex = intTest.indexOf('const isRapidFail');
59
+ eindex = intTest.indexOf(';', sindex);
60
+ replStr = intTest.substring(sindex, eindex + 1);
61
+ if (sindex > -1) {
62
+ intTest = intTest.replace(replStr, `const isRapidFail = ${isRapidFail};`);
63
+ }
64
+
65
+ // replace isSaveMockData variable but check if it exists first
66
+ sindex = intTest.indexOf('const isSaveMockData');
67
+ eindex = intTest.indexOf(';', sindex);
68
+ replStr = intTest.substring(sindex, eindex + 1);
69
+ if (sindex > -1) {
70
+ intTest = intTest.replace(replStr, `const isSaveMockData = ${isSaveMockData};`);
71
+ }
72
+
73
+ // replace host variable
74
+ sindex = intTest.indexOf('const host');
75
+ eindex = intTest.indexOf(';', sindex);
76
+ replStr = intTest.substring(sindex, eindex + 1);
77
+ intTest = intTest.replace(replStr, `const host = '${host}';`);
78
+
79
+ // replace username variable
80
+ sindex = intTest.indexOf('const username');
81
+ eindex = intTest.indexOf(';', sindex);
82
+ replStr = intTest.substring(sindex, eindex + 1);
83
+ intTest = intTest.replace(replStr, `const username = '${username}';`);
84
+
85
+ // replace password variable
86
+ sindex = intTest.indexOf('const password');
87
+ eindex = intTest.indexOf(';', sindex);
88
+ replStr = intTest.substring(sindex, eindex + 1);
89
+ intTest = intTest.replace(replStr, `const password = '${password}';`);
90
+
91
+ // replace protocol variable
92
+ sindex = intTest.indexOf('const protocol');
93
+ eindex = intTest.indexOf(';', sindex);
94
+ replStr = intTest.substring(sindex, eindex + 1);
95
+ intTest = intTest.replace(replStr, `const protocol = '${protocol}';`);
96
+
97
+ // replace port variable
98
+ sindex = intTest.indexOf('const port');
99
+ eindex = intTest.indexOf(';', sindex);
100
+ replStr = intTest.substring(sindex, eindex + 1);
101
+ intTest = intTest.replace(replStr, `const port = ${port};`);
102
+
103
+ // replace sslenable variable
104
+ sindex = intTest.indexOf('const sslenable');
105
+ eindex = intTest.indexOf(';', sindex);
106
+ replStr = intTest.substring(sindex, eindex + 1);
107
+ intTest = intTest.replace(replStr, `const sslenable = ${sslenable};`);
108
+
109
+ // replace sslinvalid variable
110
+ sindex = intTest.indexOf('const sslinvalid');
111
+ eindex = intTest.indexOf(';', sindex);
112
+ replStr = intTest.substring(sindex, eindex + 1);
113
+ intTest = intTest.replace(replStr, `const sslinvalid = ${sslinvalid};`);
114
+
115
+ console.log(`Updates to ${test} complete`);
116
+ fs.writeFileSync(test, intTest);
117
+ return 'success';
118
+ }
119
+
120
+ /**
121
+ * Updates the integration test file and runs the script
122
+ */
123
+ function runTest(callback) {
124
+ replaceTestVars('test/integration/adapterTestIntegration.js');
125
+
126
+ let cmdPath = 'npm run test:integration';
127
+ console.log('\nRUNNING INTEGRATION TESTS - THIS WILL TAKE SOME TIME AND WILL NOT PRINT UNTIL TEST IS COMPLETE!\n');
128
+ if (stderror) {
129
+ console.log('\nNOTE: standard error from tests is included - unless test failed, these may be expected errors:\n');
130
+ cmdPath += ' 2>&1';
131
+ } else {
132
+ console.log('stderr not shown');
133
+ }
134
+
135
+ return execute(cmdPath, (cerror, stdout) => {
136
+ console.log('executed tests:\n');
137
+ console.log(`${stdout}\n`);
138
+ if (cerror) {
139
+ console.log('\x1b[31m%s\x1b[0m', '\nexec error:\n');
140
+ console.log('\x1b[31m%s\x1b[0m', `${cerror}\n`);
141
+ }
142
+ // reset the defaults
143
+ stub = dstub;
144
+ isRapidFail = disRapidFail;
145
+ isSaveMockData = disSaveMockData;
146
+ host = dhost;
147
+ username = dusername;
148
+ password = dpassword;
149
+ protocol = dprotocol;
150
+ port = dport;
151
+ sslenable = dsslenable;
152
+ sslinvalid = dsslinvalid;
153
+ replaceTestVars('test/integration/adapterTestIntegration.js');
154
+ return callback('done');
155
+ });
156
+ }
157
+
158
+ /**
159
+ * Updates the unit test file and runs the script
160
+ */
161
+ function runUnitTest(callback) {
162
+ let cmdPath = 'npm run test:unit';
163
+ console.log('\nRUNNING UNIT TESTS - THIS WILL TAKE SOME TIME AND WILL NOT PRINT UNTIL TEST IS COMPLETE!\n');
164
+
165
+ if (stderror) {
166
+ console.log('\nNOTE: standard error from tests is included- unless test failed, these may be expected errors:\n');
167
+ cmdPath += ' 2>&1';
168
+ } else {
169
+ console.log('stderr not shown');
170
+ }
171
+
172
+ return execute(cmdPath, (cerror, stdout) => {
173
+ console.log('executed tests:\n');
174
+ console.log(`${stdout}\n`);
175
+
176
+ if (cerror) {
177
+ console.log('\x1b[31m%s\x1b[0m', '\nexec error:\n');
178
+ console.log('\x1b[31m%s\x1b[0m', `${cerror}\n`);
179
+ }
180
+
181
+ return callback('done');
182
+ });
183
+ }
184
+
185
+ // print process.argv
186
+ const args = process.argv.slice(2);
187
+
188
+ // go through the arguments that where provided
189
+ for (let a = 0; a < args.length; a += 1) {
190
+ if (args[a].toUpperCase() === '-H' || args[a].toUpperCase() === '--HELP') {
191
+ let message = '\nThis tool is used to make it easier to run integration tests.\n';
192
+ message += '\n';
193
+ message += 'Options:\n';
194
+ message += '-h, --help: Prints this message\n';
195
+ message += '-f, --failfast: Fail the test when the first test fails\n';
196
+ message += '-m, --mockdata: Update mock data files with the results from testing (only if running integrated)\n';
197
+ message += '-r, --reset: Resets the variables back to stub settings and removes credentials\n';
198
+ message += '-s, --stderror: Displays the standard error from the run, this can have data even if all the tests pass\n';
199
+ message += '-u, --unit: Runs just the unit tests as well\n';
200
+ console.log(message);
201
+ running = true;
202
+ }
203
+
204
+ if (args[a].toUpperCase() === '-F' || args[a].toUpperCase() === '--FAILFAST') {
205
+ isRapidFail = true;
206
+ }
207
+ if (args[a].toUpperCase() === '-M' || args[a].toUpperCase() === '--MOCKDATA') {
208
+ isSaveMockData = true;
209
+ }
210
+ if (args[a].toUpperCase() === '-R' || args[a].toUpperCase() === '--RESET') {
211
+ running = true;
212
+ replaceTestVars('test/integration/adapterTestIntegration.js');
213
+ replaceTestVars('test/unit/adapterTestUnit.js');
214
+ console.log('test reset complete');
215
+ }
216
+ if (args[a].toUpperCase() === '-S' || args[a].toUpperCase() === '--STDERROR') {
217
+ stderror = true;
218
+ }
219
+ if (args[a].toUpperCase() === '-U' || args[a].toUpperCase() === '--UNIT') {
220
+ running = true;
221
+ runUnitTest((status) => {
222
+ console.log(status);
223
+ process.exit(1);
224
+ });
225
+ }
226
+ }
227
+
228
+ if (!running) {
229
+ // how are we running the test?
230
+ let answer = rl.question('\nDo you want to run the integration test integrated with the other system? (no): ');
231
+ if (answer && (answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y')) {
232
+ stub = false;
233
+ console.log('Need more information about the integration!');
234
+ } else {
235
+ running = true;
236
+ runTest((status) => {
237
+ console.log(status);
238
+ process.exit(1);
239
+ });
240
+ }
241
+
242
+ if (!running) {
243
+ // how are we running the test?
244
+ answer = rl.question('\nWhat is the dns or ip of the system you want to test with? (localhost): ');
245
+ if (answer) {
246
+ host = answer;
247
+ } else {
248
+ host = 'localhost';
249
+ }
250
+
251
+ // need the username to authenticate with
252
+ answer = rl.question('\nWhat is the username to authenticate, if no authentication just return? (username): ');
253
+ if (answer) {
254
+ username = answer;
255
+ }
256
+
257
+ // need the password to authenticate with
258
+ answer = rl.question('\nWhat is the password to authenticate, if no authentication just return? (password): ', { hideEchoBack: true });
259
+ if (answer) {
260
+ password = answer;
261
+ }
262
+
263
+ // need the protocol used with other system
264
+ answer = rl.question('\nWhat is the protocol used to communicate with the system? (http): ');
265
+ if (answer) {
266
+ protocol = answer;
267
+ }
268
+
269
+ if (protocol === 'https') {
270
+ // if protocol is https, set default port to 443
271
+ port = 443;
272
+ // need the port used with other system
273
+ answer = rl.question('\nWhat is the port used to communicate with the system? (443): ');
274
+ port = 443; // update default answer to 443 for https
275
+ if (answer) {
276
+ port = Number(answer);
277
+ }
278
+
279
+ // turn on ssl and accept invalid certs
280
+ sslenable = true;
281
+ sslinvalid = true;
282
+ runTest((status) => {
283
+ console.log(status);
284
+ process.exit(1);
285
+ });
286
+ } else {
287
+ // need the port used with other system
288
+ answer = rl.question('\nWhat is the port used to communicate with the system? (80): ');
289
+ if (answer) {
290
+ port = Number(answer);
291
+ }
292
+ runTest((status) => {
293
+ console.log(status);
294
+ process.exit(1);
295
+ });
296
+ }
297
+ }
298
+ }