@itentialopensource/adapter-meraki 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- package/AUTH.md +40 -0
- package/CALLS.md +100 -0
- package/CHANGELOG.md +8 -0
- package/ENHANCE.md +69 -0
- package/PROPERTIES.md +247 -0
- package/README.md +112 -542
- package/SUMMARY.md +9 -0
- package/SYSTEMINFO.md +11 -0
- package/TROUBLESHOOT.md +46 -0
- package/adapter.js +583 -204
- package/adapterBase.js +291 -290
- package/error.json +6 -0
- package/package.json +1 -1
- package/pronghorn.json +106 -113
- package/propertiesSchema.json +223 -0
- package/refs?service=git-upload-pack +0 -0
- package/test/integration/adapterTestIntegration.js +1 -0
- package/test/unit/adapterBaseTestUnit.js +22 -24
- package/test/unit/adapterTestUnit.js +57 -51
@@ -317,8 +317,8 @@ describe('[unit] Adapter Base Test', () => {
|
|
317
317
|
});
|
318
318
|
it('should return a list of functions', (done) => {
|
319
319
|
const returnedFunctions = ['addEntityCache', 'capabilityResults', 'checkActionFiles', 'checkProperties', 'connect', 'encryptProperty',
|
320
|
-
'entityInList', '
|
321
|
-
'
|
320
|
+
'entityInList', 'getAllCapabilities', 'getAllFunctions', 'healthCheck', 'iapFindAdapterPath', 'iapGetAdapterQueue', 'iapGetAdapterWorkflowFunctions', 'iapMoveAdapterEntitiesToDB',
|
321
|
+
'iapRunAdapterBasicGet', 'iapRunAdapterConnectivity', 'iapRunAdapterHealthcheck', 'iapSuspendAdapter', 'iapTroubleshootAdapter', 'iapUnsuspendAdapter', 'iapUpdateAdapterConfiguration', 'refreshProperties', 'addListener',
|
322
322
|
'emit', 'eventNames', 'getMaxListeners', 'listenerCount', 'listeners', 'off', 'on', 'once', 'prependListener',
|
323
323
|
'prependOnceListener', 'rawListeners', 'removeAllListeners', 'removeListener', 'setMaxListeners'];
|
324
324
|
try {
|
@@ -337,10 +337,10 @@ describe('[unit] Adapter Base Test', () => {
|
|
337
337
|
}).timeout(attemptTimeout);
|
338
338
|
});
|
339
339
|
|
340
|
-
describe('#
|
341
|
-
it('should have a
|
340
|
+
describe('#iapGetAdapterWorkflowFunctions', () => {
|
341
|
+
it('should have a iapGetAdapterWorkflowFunctions function', (done) => {
|
342
342
|
try {
|
343
|
-
assert.equal(true, typeof a.
|
343
|
+
assert.equal(true, typeof a.iapGetAdapterWorkflowFunctions === 'function');
|
344
344
|
done();
|
345
345
|
} catch (error) {
|
346
346
|
log.error(`Test Failure: ${error}`);
|
@@ -349,7 +349,7 @@ describe('[unit] Adapter Base Test', () => {
|
|
349
349
|
});
|
350
350
|
it('should retrieve workflow functions', (done) => {
|
351
351
|
try {
|
352
|
-
const expectedFunctions = a.
|
352
|
+
const expectedFunctions = a.iapGetAdapterWorkflowFunctions([]);
|
353
353
|
try {
|
354
354
|
assert.equal(0, expectedFunctions.length);
|
355
355
|
done();
|
@@ -426,10 +426,10 @@ describe('[unit] Adapter Base Test', () => {
|
|
426
426
|
}).timeout(attemptTimeout);
|
427
427
|
});
|
428
428
|
|
429
|
-
describe('#
|
430
|
-
it('should have a
|
429
|
+
describe('#iapGetAdapterQueue', () => {
|
430
|
+
it('should have a iapGetAdapterQueue function', (done) => {
|
431
431
|
try {
|
432
|
-
assert.equal(true, typeof a.
|
432
|
+
assert.equal(true, typeof a.iapGetAdapterQueue === 'function');
|
433
433
|
done();
|
434
434
|
} catch (error) {
|
435
435
|
log.error(`Test Failure: ${error}`);
|
@@ -438,7 +438,7 @@ describe('[unit] Adapter Base Test', () => {
|
|
438
438
|
});
|
439
439
|
it('should get information for all of the requests currently in the queue', (done) => {
|
440
440
|
try {
|
441
|
-
const expectedFunctions = a.
|
441
|
+
const expectedFunctions = a.iapGetAdapterQueue();
|
442
442
|
try {
|
443
443
|
assert.equal(0, expectedFunctions.length);
|
444
444
|
done();
|
@@ -843,12 +843,10 @@ describe('[unit] Adapter Base Test', () => {
|
|
843
843
|
}).timeout(attemptTimeout);
|
844
844
|
});
|
845
845
|
|
846
|
-
|
847
|
-
|
848
|
-
describe('#updateAdapterConfiguration', () => {
|
849
|
-
it('should have a updateAdapterConfiguration function', (done) => {
|
846
|
+
describe('#iapUpdateAdapterConfiguration', () => {
|
847
|
+
it('should have a iapUpdateAdapterConfiguration function', (done) => {
|
850
848
|
try {
|
851
|
-
assert.equal(true, typeof a.
|
849
|
+
assert.equal(true, typeof a.iapUpdateAdapterConfiguration === 'function');
|
852
850
|
done();
|
853
851
|
} catch (error) {
|
854
852
|
log.error(`Test Failure: ${error}`);
|
@@ -857,7 +855,7 @@ describe('[unit] Adapter Base Test', () => {
|
|
857
855
|
});
|
858
856
|
it('should return no updated if no changes are provided', (done) => {
|
859
857
|
try {
|
860
|
-
a.
|
858
|
+
a.iapUpdateAdapterConfiguration(null, null, null, null, null, (data, error) => {
|
861
859
|
try {
|
862
860
|
assert.equal('No configuration updates to make', data.response);
|
863
861
|
done();
|
@@ -873,10 +871,10 @@ describe('[unit] Adapter Base Test', () => {
|
|
873
871
|
}).timeout(attemptTimeout);
|
874
872
|
it('should throw an error if missing configuration file', (done) => {
|
875
873
|
try {
|
876
|
-
a.
|
874
|
+
a.iapUpdateAdapterConfiguration(null, { name: 'fakeChange' }, null, null, null, (data, error) => {
|
877
875
|
try {
|
878
876
|
const displayE = 'configFile is required';
|
879
|
-
runErrorAsserts(data, error, 'AD.300', 'Test-Base-adapterBase-
|
877
|
+
runErrorAsserts(data, error, 'AD.300', 'Test-Base-adapterBase-iapUpdateAdapterConfiguration', displayE);
|
880
878
|
done();
|
881
879
|
} catch (err) {
|
882
880
|
log.error(`Test Failure: ${err}`);
|
@@ -890,10 +888,10 @@ describe('[unit] Adapter Base Test', () => {
|
|
890
888
|
}).timeout(attemptTimeout);
|
891
889
|
it('if not package.json, entity is required', (done) => {
|
892
890
|
try {
|
893
|
-
a.
|
891
|
+
a.iapUpdateAdapterConfiguration('notPackage', { name: 'fakeChange' }, null, null, null, (data, error) => {
|
894
892
|
try {
|
895
893
|
const displayE = 'Unsupported Configuration Change or Missing Entity';
|
896
|
-
runErrorAsserts(data, error, 'AD.999', 'Test-Base-adapterBase-
|
894
|
+
runErrorAsserts(data, error, 'AD.999', 'Test-Base-adapterBase-iapUpdateAdapterConfiguration', displayE);
|
897
895
|
done();
|
898
896
|
} catch (err) {
|
899
897
|
log.error(`Test Failure: ${err}`);
|
@@ -907,10 +905,10 @@ describe('[unit] Adapter Base Test', () => {
|
|
907
905
|
}).timeout(attemptTimeout);
|
908
906
|
it('if not package.json, type is required', (done) => {
|
909
907
|
try {
|
910
|
-
a.
|
908
|
+
a.iapUpdateAdapterConfiguration('notPackage', { name: 'fakeChange' }, 'entity', null, null, (data, error) => {
|
911
909
|
try {
|
912
910
|
const displayE = 'type is required';
|
913
|
-
runErrorAsserts(data, error, 'AD.300', 'Test-Base-adapterBase-
|
911
|
+
runErrorAsserts(data, error, 'AD.300', 'Test-Base-adapterBase-iapUpdateAdapterConfiguration', displayE);
|
914
912
|
done();
|
915
913
|
} catch (err) {
|
916
914
|
log.error(`Test Failure: ${err}`);
|
@@ -924,10 +922,10 @@ describe('[unit] Adapter Base Test', () => {
|
|
924
922
|
}).timeout(attemptTimeout);
|
925
923
|
it('if not package.json, entity must be valid', (done) => {
|
926
924
|
try {
|
927
|
-
a.
|
925
|
+
a.iapUpdateAdapterConfiguration('notPackage', { name: 'fakeChange' }, 'fakeEntity', 'fakeType', null, (data, error) => {
|
928
926
|
try {
|
929
927
|
const displayE = 'Incomplete Configuration Change: Invalid Entity - fakeEntity';
|
930
|
-
runErrorAsserts(data, error, 'AD.999', 'Test-Base-adapterBase-
|
928
|
+
runErrorAsserts(data, error, 'AD.999', 'Test-Base-adapterBase-iapUpdateAdapterConfiguration', displayE);
|
931
929
|
done();
|
932
930
|
} catch (err) {
|
933
931
|
log.error(`Test Failure: ${err}`);
|
@@ -271,10 +271,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
271
271
|
});
|
272
272
|
|
273
273
|
let wffunctions = [];
|
274
|
-
describe('#
|
274
|
+
describe('#iapGetAdapterWorkflowFunctions', () => {
|
275
275
|
it('should retrieve workflow functions', (done) => {
|
276
276
|
try {
|
277
|
-
wffunctions = a.
|
277
|
+
wffunctions = a.iapGetAdapterWorkflowFunctions([]);
|
278
278
|
|
279
279
|
try {
|
280
280
|
assert.notEqual(0, wffunctions.length);
|
@@ -465,15 +465,15 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
465
465
|
assert.notEqual('', pronghornDotJson.methods);
|
466
466
|
assert.equal(true, Array.isArray(pronghornDotJson.methods));
|
467
467
|
assert.notEqual(0, pronghornDotJson.methods.length);
|
468
|
-
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === '
|
469
|
-
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === '
|
470
|
-
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === '
|
471
|
-
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === '
|
472
|
-
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === '
|
473
|
-
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === '
|
474
|
-
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === '
|
475
|
-
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === '
|
476
|
-
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === '
|
468
|
+
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === 'iapUpdateAdapterConfiguration'));
|
469
|
+
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === 'iapFindAdapterPath'));
|
470
|
+
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === 'iapTroubleshootAdapter'));
|
471
|
+
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === 'iapRunAdapterHealthcheck'));
|
472
|
+
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === 'iapRunAdapterConnectivity'));
|
473
|
+
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === 'iapRunAdapterBasicGet'));
|
474
|
+
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === 'iapSuspendAdapter'));
|
475
|
+
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === 'iapUnsuspendAdapter'));
|
476
|
+
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === 'iapGetAdapterQueue'));
|
477
477
|
assert.notEqual(undefined, pronghornDotJson.methods.find((e) => e.name === 'genericAdapterRequest'));
|
478
478
|
done();
|
479
479
|
} catch (error) {
|
@@ -724,6 +724,12 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
724
724
|
assert.equal('string', propertiesDotJson.definitions.mongo.properties.db_ssl.properties.ca_file.type);
|
725
725
|
assert.equal('string', propertiesDotJson.definitions.mongo.properties.db_ssl.properties.key_file.type);
|
726
726
|
assert.equal('string', propertiesDotJson.definitions.mongo.properties.db_ssl.properties.cert_file.type);
|
727
|
+
assert.notEqual('', propertiesDotJson.definitions.devicebroker);
|
728
|
+
assert.equal('object', propertiesDotJson.definitions.devicebroker.properties.getDevice.type);
|
729
|
+
assert.equal('object', propertiesDotJson.definitions.devicebroker.properties.getDevicesFiltered.type);
|
730
|
+
assert.equal('object', propertiesDotJson.definitions.devicebroker.properties.isAlive.type);
|
731
|
+
assert.equal('object', propertiesDotJson.definitions.devicebroker.properties.getConfig.type);
|
732
|
+
assert.equal('object', propertiesDotJson.definitions.devicebroker.properties.getCount.type);
|
727
733
|
done();
|
728
734
|
} catch (error) {
|
729
735
|
log.error(`Test Failure: ${error}`);
|
@@ -1002,10 +1008,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1002
1008
|
});
|
1003
1009
|
});
|
1004
1010
|
|
1005
|
-
describe('#
|
1006
|
-
it('should have a
|
1011
|
+
describe('#iapUpdateAdapterConfiguration', () => {
|
1012
|
+
it('should have a iapUpdateAdapterConfiguration function', (done) => {
|
1007
1013
|
try {
|
1008
|
-
assert.equal(true, typeof a.
|
1014
|
+
assert.equal(true, typeof a.iapUpdateAdapterConfiguration === 'function');
|
1009
1015
|
done();
|
1010
1016
|
} catch (error) {
|
1011
1017
|
log.error(`Test Failure: ${error}`);
|
@@ -1014,19 +1020,19 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1014
1020
|
});
|
1015
1021
|
});
|
1016
1022
|
|
1017
|
-
describe('#
|
1018
|
-
it('should have a
|
1023
|
+
describe('#iapFindAdapterPath', () => {
|
1024
|
+
it('should have a iapFindAdapterPath function', (done) => {
|
1019
1025
|
try {
|
1020
|
-
assert.equal(true, typeof a.
|
1026
|
+
assert.equal(true, typeof a.iapFindAdapterPath === 'function');
|
1021
1027
|
done();
|
1022
1028
|
} catch (error) {
|
1023
1029
|
log.error(`Test Failure: ${error}`);
|
1024
1030
|
done(error);
|
1025
1031
|
}
|
1026
1032
|
});
|
1027
|
-
it('
|
1033
|
+
it('iapFindAdapterPath should find atleast one path that matches', (done) => {
|
1028
1034
|
try {
|
1029
|
-
a.
|
1035
|
+
a.iapFindAdapterPath('{base_path}/{version}', (data, error) => {
|
1030
1036
|
try {
|
1031
1037
|
assert.equal(undefined, error);
|
1032
1038
|
assert.notEqual(undefined, data);
|
@@ -1048,10 +1054,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1048
1054
|
}).timeout(attemptTimeout);
|
1049
1055
|
});
|
1050
1056
|
|
1051
|
-
describe('#
|
1052
|
-
it('should have a
|
1057
|
+
describe('#iapSuspendAdapter', () => {
|
1058
|
+
it('should have a iapSuspendAdapter function', (done) => {
|
1053
1059
|
try {
|
1054
|
-
assert.equal(true, typeof a.
|
1060
|
+
assert.equal(true, typeof a.iapSuspendAdapter === 'function');
|
1055
1061
|
done();
|
1056
1062
|
} catch (error) {
|
1057
1063
|
log.error(`Test Failure: ${error}`);
|
@@ -1060,10 +1066,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1060
1066
|
});
|
1061
1067
|
});
|
1062
1068
|
|
1063
|
-
describe('#
|
1064
|
-
it('should have a
|
1069
|
+
describe('#iapUnsuspendAdapter', () => {
|
1070
|
+
it('should have a iapUnsuspendAdapter function', (done) => {
|
1065
1071
|
try {
|
1066
|
-
assert.equal(true, typeof a.
|
1072
|
+
assert.equal(true, typeof a.iapUnsuspendAdapter === 'function');
|
1067
1073
|
done();
|
1068
1074
|
} catch (error) {
|
1069
1075
|
log.error(`Test Failure: ${error}`);
|
@@ -1072,10 +1078,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1072
1078
|
});
|
1073
1079
|
});
|
1074
1080
|
|
1075
|
-
describe('#
|
1076
|
-
it('should have a
|
1081
|
+
describe('#iapGetAdapterQueue', () => {
|
1082
|
+
it('should have a iapGetAdapterQueue function', (done) => {
|
1077
1083
|
try {
|
1078
|
-
assert.equal(true, typeof a.
|
1084
|
+
assert.equal(true, typeof a.iapGetAdapterQueue === 'function');
|
1079
1085
|
done();
|
1080
1086
|
} catch (error) {
|
1081
1087
|
log.error(`Test Failure: ${error}`);
|
@@ -1084,10 +1090,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1084
1090
|
});
|
1085
1091
|
});
|
1086
1092
|
|
1087
|
-
describe('#
|
1088
|
-
it('should have a
|
1093
|
+
describe('#iapTroubleshootAdapter', () => {
|
1094
|
+
it('should have a iapTroubleshootAdapter function', (done) => {
|
1089
1095
|
try {
|
1090
|
-
assert.equal(true, typeof a.
|
1096
|
+
assert.equal(true, typeof a.iapTroubleshootAdapter === 'function');
|
1091
1097
|
done();
|
1092
1098
|
} catch (error) {
|
1093
1099
|
log.error(`Test Failure: ${error}`);
|
@@ -1096,10 +1102,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1096
1102
|
});
|
1097
1103
|
});
|
1098
1104
|
|
1099
|
-
describe('#
|
1100
|
-
it('should have a
|
1105
|
+
describe('#iapRunAdapterHealthcheck', () => {
|
1106
|
+
it('should have a iapRunAdapterHealthcheck function', (done) => {
|
1101
1107
|
try {
|
1102
|
-
assert.equal(true, typeof a.
|
1108
|
+
assert.equal(true, typeof a.iapRunAdapterHealthcheck === 'function');
|
1103
1109
|
done();
|
1104
1110
|
} catch (error) {
|
1105
1111
|
log.error(`Test Failure: ${error}`);
|
@@ -1108,10 +1114,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1108
1114
|
});
|
1109
1115
|
});
|
1110
1116
|
|
1111
|
-
describe('#
|
1112
|
-
it('should have a
|
1117
|
+
describe('#iapRunAdapterConnectivity', () => {
|
1118
|
+
it('should have a iapRunAdapterConnectivity function', (done) => {
|
1113
1119
|
try {
|
1114
|
-
assert.equal(true, typeof a.
|
1120
|
+
assert.equal(true, typeof a.iapRunAdapterConnectivity === 'function');
|
1115
1121
|
done();
|
1116
1122
|
} catch (error) {
|
1117
1123
|
log.error(`Test Failure: ${error}`);
|
@@ -1120,10 +1126,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1120
1126
|
});
|
1121
1127
|
});
|
1122
1128
|
|
1123
|
-
describe('#
|
1124
|
-
it('should have a
|
1129
|
+
describe('#iapRunAdapterBasicGet', () => {
|
1130
|
+
it('should have a iapRunAdapterBasicGet function', (done) => {
|
1125
1131
|
try {
|
1126
|
-
assert.equal(true, typeof a.
|
1132
|
+
assert.equal(true, typeof a.iapRunAdapterBasicGet === 'function');
|
1127
1133
|
done();
|
1128
1134
|
} catch (error) {
|
1129
1135
|
log.error(`Test Failure: ${error}`);
|
@@ -1132,10 +1138,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1132
1138
|
});
|
1133
1139
|
});
|
1134
1140
|
|
1135
|
-
describe('#
|
1136
|
-
it('should have a
|
1141
|
+
describe('#iapMoveAdapterEntitiesToDB', () => {
|
1142
|
+
it('should have a iapMoveAdapterEntitiesToDB function', (done) => {
|
1137
1143
|
try {
|
1138
|
-
assert.equal(true, typeof a.
|
1144
|
+
assert.equal(true, typeof a.iapMoveAdapterEntitiesToDB === 'function');
|
1139
1145
|
done();
|
1140
1146
|
} catch (error) {
|
1141
1147
|
log.error(`Test Failure: ${error}`);
|
@@ -1229,10 +1235,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1229
1235
|
}).timeout(attemptTimeout);
|
1230
1236
|
});
|
1231
1237
|
|
1232
|
-
// describe('#
|
1233
|
-
// it('should have a
|
1238
|
+
// describe('#iapHasAdapterEntity', () => {
|
1239
|
+
// it('should have a iapHasAdapterEntity function', (done) => {
|
1234
1240
|
// try {
|
1235
|
-
// assert.equal(true, typeof a.
|
1241
|
+
// assert.equal(true, typeof a.iapHasAdapterEntity === 'function');
|
1236
1242
|
// done();
|
1237
1243
|
// } catch (error) {
|
1238
1244
|
// log.error(`Test Failure: ${error}`);
|
@@ -1241,7 +1247,7 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1241
1247
|
// });
|
1242
1248
|
// it('should find entity', (done) => {
|
1243
1249
|
// try {
|
1244
|
-
// a.
|
1250
|
+
// a.iapHasAdapterEntity('template_entity', // 'a9e9c33dc61122760072455df62663d2', (data) => {
|
1245
1251
|
// try {
|
1246
1252
|
// assert.equal(true, data[0]);
|
1247
1253
|
// done();
|
@@ -1257,7 +1263,7 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1257
1263
|
// }).timeout(attemptTimeout);
|
1258
1264
|
// it('should not find entity', (done) => {
|
1259
1265
|
// try {
|
1260
|
-
// a.
|
1266
|
+
// a.iapHasAdapterEntity('template_entity', 'blah', (data) => {
|
1261
1267
|
// try {
|
1262
1268
|
// assert.equal(false, data[0]);
|
1263
1269
|
// done();
|
@@ -1345,10 +1351,10 @@ describe('[unit] Meraki Adapter Test', () => {
|
|
1345
1351
|
});
|
1346
1352
|
});
|
1347
1353
|
|
1348
|
-
describe('#
|
1349
|
-
it('should have a
|
1354
|
+
describe('#iapGetDeviceCount', () => {
|
1355
|
+
it('should have a iapGetDeviceCount function', (done) => {
|
1350
1356
|
try {
|
1351
|
-
assert.equal(true, typeof a.
|
1357
|
+
assert.equal(true, typeof a.iapGetDeviceCount === 'function');
|
1352
1358
|
done();
|
1353
1359
|
} catch (error) {
|
1354
1360
|
log.error(`Test Failure: ${error}`);
|