Skip to content

Commit 28de27e

Browse files
committed
test: add tests for messageId and duplicate validation
1 parent 9e10c92 commit 28de27e

File tree

5 files changed

+295
-7
lines changed

5 files changed

+295
-7
lines changed

dist/bundle.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/customValidators_test.js

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const {
33
validateOperationId,
44
validateServerSecurity,
55
validateChannels,
6+
validateMessageId,
67
} = require('../lib/customValidators.js');
78
const { checkErrorWrapper } = require('./testsUtils');
89

@@ -1076,6 +1077,273 @@ describe('validateOperationId()', function () {
10761077
});
10771078
});
10781079

1080+
describe('validateMessageId()', function () {
1081+
const operations = ['subscribe', 'publish'];
1082+
1083+
it('should successfully validate messageId', async function () {
1084+
const inputString = `{
1085+
"asyncapi": "2.0.0",
1086+
"info": {
1087+
"version": "1.0.0"
1088+
},
1089+
"channels": {
1090+
"test/1": {
1091+
"publish": {
1092+
"message": {
1093+
"messageId": "test1"
1094+
}
1095+
}
1096+
},
1097+
"test/2": {
1098+
"subscribe": {
1099+
"message": {
1100+
"messageId": "test2"
1101+
}
1102+
}
1103+
}
1104+
}
1105+
}`;
1106+
const parsedInput = JSON.parse(inputString);
1107+
1108+
expect(
1109+
validateMessageId(parsedInput, inputString, input, operations)
1110+
).to.equal(true);
1111+
});
1112+
1113+
it('should throw error that messageIds are duplicated and that they duplicate', async function () {
1114+
const inputString = `{
1115+
"asyncapi": "2.0.0",
1116+
"info": {
1117+
"version": "1.0.0"
1118+
},
1119+
"channels": {
1120+
"test/1": {
1121+
"publish": {
1122+
"message": {
1123+
"messageId": "test"
1124+
}
1125+
}
1126+
},
1127+
"test/2": {
1128+
"subscribe": {
1129+
"message": {
1130+
"messageId": "test"
1131+
}
1132+
}
1133+
},
1134+
"test/3": {
1135+
"subscribe": {
1136+
"message": {
1137+
"messageId": "test"
1138+
}
1139+
}
1140+
},
1141+
"test/4": {
1142+
"subscribe": {
1143+
"operationId": "test4"
1144+
}
1145+
}
1146+
}
1147+
}`;
1148+
const parsedInput = JSON.parse(inputString);
1149+
1150+
const expectedErrorObject = {
1151+
type: 'https://github.com/asyncapi/parser-js/validation-errors',
1152+
title: 'messageId must be unique across all the messages.',
1153+
parsedJSON: parsedInput,
1154+
validationErrors: [
1155+
{
1156+
title:
1157+
'test/2/subscribe/message/messageId is a duplicate of: test/1/publish/message/messageId',
1158+
location: {
1159+
jsonPointer: '/channels/test~12/subscribe/message/messageId',
1160+
startLine: 17,
1161+
startColumn: 29,
1162+
startOffset: 337,
1163+
endLine: 17,
1164+
endColumn: 35,
1165+
endOffset: 343,
1166+
},
1167+
},
1168+
{
1169+
title:
1170+
'test/3/subscribe/message/messageId is a duplicate of: test/1/publish/message/messageId',
1171+
location: {
1172+
jsonPointer: '/channels/test~13/subscribe/message/messageId',
1173+
startLine: 24,
1174+
startColumn: 29,
1175+
startOffset: 478,
1176+
endLine: 24,
1177+
endColumn: 35,
1178+
endOffset: 484,
1179+
},
1180+
},
1181+
],
1182+
};
1183+
1184+
await checkErrorWrapper(async () => {
1185+
await validateMessageId(parsedInput, inputString, input, operations);
1186+
}, expectedErrorObject);
1187+
});
1188+
1189+
it('should throw error that messageIds are duplicated and that they duplicate with oneOf', async function () {
1190+
const inputString = `{
1191+
"asyncapi": "2.0.0",
1192+
"info": {
1193+
"version": "1.0.0"
1194+
},
1195+
"channels": {
1196+
"test/1": {
1197+
"publish": {
1198+
"message": {
1199+
"oneOf": [{
1200+
"messageId": "test1"
1201+
}]
1202+
}
1203+
}
1204+
},
1205+
"test/2": {
1206+
"subscribe": {
1207+
"message": {
1208+
"messageId": "test1"
1209+
}
1210+
}
1211+
},
1212+
"test/3": {
1213+
"subscribe": {
1214+
"message": {
1215+
"oneOf": [
1216+
{
1217+
"messageId": "test2"
1218+
},
1219+
{
1220+
"messageId": "test2"
1221+
}
1222+
]
1223+
}
1224+
}
1225+
},
1226+
"test/4": {
1227+
"subscribe": {
1228+
"operationId": "test4"
1229+
}
1230+
}
1231+
}
1232+
}`;
1233+
const parsedInput = JSON.parse(inputString);
1234+
1235+
const expectedErrorObject = {
1236+
type: 'https://github.com/asyncapi/parser-js/validation-errors',
1237+
title: 'messageId must be unique across all the messages.',
1238+
parsedJSON: parsedInput,
1239+
validationErrors: [
1240+
{
1241+
title:
1242+
'test/2/subscribe/message/messageId is a duplicate of: test/1/publish/message/oneOf/messageId',
1243+
location: {
1244+
jsonPointer: '/channels/test~12/subscribe/message/messageId',
1245+
startLine: 19,
1246+
startColumn: 29,
1247+
startOffset: 383,
1248+
endLine: 19,
1249+
endColumn: 36,
1250+
endOffset: 390,
1251+
},
1252+
},
1253+
{
1254+
title:
1255+
'test/3/subscribe/message/oneOf/messageId is a duplicate of: test/3/subscribe/message/oneOf/messageId',
1256+
location: {
1257+
jsonPointer: '/channels/test~13/subscribe/message/oneOf/messageId',
1258+
startLine: 28,
1259+
startColumn: 33,
1260+
startOffset: 572,
1261+
endLine: 28,
1262+
endColumn: 40,
1263+
endOffset: 579,
1264+
},
1265+
},
1266+
],
1267+
};
1268+
1269+
await checkErrorWrapper(async () => {
1270+
await validateMessageId(parsedInput, inputString, input, operations);
1271+
}, expectedErrorObject);
1272+
});
1273+
1274+
it('should only throw error for message that have defined duplicate messageIds', async function () {
1275+
const inputString = `{
1276+
"asyncapi": "2.0.0",
1277+
"info": {
1278+
"version": "1.0.0"
1279+
},
1280+
"channels": {
1281+
"test/1": {
1282+
"publish": {
1283+
"message": {
1284+
"oneOf": [{
1285+
"messageId": "test1"
1286+
}]
1287+
}
1288+
}
1289+
},
1290+
"test/2": {
1291+
"subscribe": {
1292+
"message": {
1293+
"name": "test1"
1294+
}
1295+
}
1296+
},
1297+
"test/3": {
1298+
"subscribe": {
1299+
"message": {
1300+
"oneOf": [
1301+
{
1302+
"messageId": "test2"
1303+
},
1304+
{
1305+
"messageId": "test2"
1306+
}
1307+
]
1308+
}
1309+
}
1310+
},
1311+
"test/4": {
1312+
"subscribe": {
1313+
"operationId": "test4"
1314+
}
1315+
}
1316+
}
1317+
}`;
1318+
const parsedInput = JSON.parse(inputString);
1319+
1320+
const expectedErrorObject = {
1321+
type: 'https://github.com/asyncapi/parser-js/validation-errors',
1322+
title: 'messageId must be unique across all the messages.',
1323+
parsedJSON: parsedInput,
1324+
validationErrors: [
1325+
{
1326+
title:
1327+
'test/3/subscribe/message/oneOf/messageId is a duplicate of: test/3/subscribe/message/oneOf/messageId',
1328+
location: {
1329+
jsonPointer: '/channels/test~13/subscribe/message/oneOf/messageId',
1330+
startLine: 28,
1331+
startColumn: 33,
1332+
startOffset: 567,
1333+
endLine: 28,
1334+
endColumn: 40,
1335+
endOffset: 574,
1336+
},
1337+
},
1338+
],
1339+
};
1340+
1341+
await checkErrorWrapper(async () => {
1342+
await validateMessageId(parsedInput, inputString, input, operations);
1343+
}, expectedErrorObject);
1344+
});
1345+
});
1346+
10791347
describe('validateServerSecurity()', function () {
10801348
const specialSecTypes = ['oauth2', 'openIdConnect'];
10811349

test/models/message-trait_test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ describe('MessageTrait', function() {
4040
});
4141
});
4242

43+
describe('#id()', function() {
44+
it('should return a string', function() {
45+
const d = new MessageTrait(js);
46+
expect(d.id()).to.be.equal(js.id);
47+
});
48+
});
49+
4350
describe('#correlationId()', function() {
4451
it('should return a CorrelationId object', function() {
4552
const d = new MessageTrait(js);

test/models/message-traitable_test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ describe('MessageTraitable', function() {
4040
});
4141
});
4242

43+
describe('#id()', function() {
44+
it('should return a string', function() {
45+
const d = new MessageTraitable(js);
46+
expect(d.id()).to.be.equal(js.id);
47+
});
48+
});
49+
4350
describe('#correlationId()', function() {
4451
it('should return a CorrelationId object', function() {
4552
const d = new MessageTraitable(js);

test/models/message_test.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const { expect } = require('chai');
2-
const js = { schemaFormat: 'mySchema', traits: [{headers: {type: 'object',properties: {'my-app-header': {type: 'integer',minimum: 0,maximum: 100}}}}], headers: { properties: { test1: { type: 'string' }, test2: { type: 'number' } } }, payload: { test: true }, 'x-parser-original-payload': { testing: true }, correlationId: { test: true }, 'x-parser-original-schema-format': 'application/vnd.apache.avro;version=1.9.0', contentType: 'application/json', name: 'test', title: 'Test', summary: 'test', description: 'testing', externalDocs: { test: true }, tags: [{ name: 'tag1' }], bindings: { amqp: { test: true } }, examples: [{name: 'test', summary: 'test summary', payload: {test: true}}], 'x-test': 'testing' };
2+
const js = { schemaFormat: 'mySchema', traits: [{headers: {type: 'object',properties: {'my-app-header': {type: 'integer',minimum: 0,maximum: 100}}}}], headers: { properties: { test1: { type: 'string' }, test2: { type: 'number' } } }, payload: { test: true }, 'x-parser-original-payload': { testing: true }, correlationId: { test: true }, 'x-parser-original-schema-format': 'application/vnd.apache.avro;version=1.9.0', contentType: 'application/json', messageId: 'test', title: 'Test', summary: 'test', description: 'testing', externalDocs: { test: true }, tags: [{ name: 'tag1' }], bindings: { amqp: { test: true } }, examples: [{name: 'test', summary: 'test summary', payload: {test: true}}], 'x-test': 'testing' };
33

44
const Message = require('../../lib/models/message');
55

@@ -11,19 +11,25 @@ const { assertMixinSpecificationExtensionsInheritance } = require('../mixins/spe
1111

1212
describe('Message', function() {
1313
describe('#uid()', function() {
14-
it('should return a string with the name', function() {
14+
it('should return a string with the messageId', function() {
1515
const d = new Message(js);
1616
expect(d.uid()).to.be.equal('test');
1717
});
18+
19+
it('should return a string with the name when messageId is not available', function() {
20+
const msg = { ...js, ...{ name: 'test', messageId: undefined } };
21+
const d = new Message(msg);
22+
expect(d.uid()).to.be.equal('test');
23+
});
1824

19-
it('should return a string with the x-parser-message-name extension when name is not available', function() {
20-
const msg = { ...js, ...{ 'x-parser-message-name': 'test' } };
25+
it('should return a string with the x-parser-message-name extension when name and messageId are not available', function() {
26+
const msg = { ...js, ...{ 'x-parser-message-name': 'test', messageId: undefined } };
2127
const d = new Message(msg);
2228
expect(d.uid()).to.be.equal('test');
2329
});
2430

25-
it('should return a string with the base64 representation of the object when x-parser-message-name extension and name are not available', function() {
26-
const msg = { ...js, ...{ name: undefined } };
31+
it('should return a string with the base64 representation of the object when x-parser-message-name extension, name and messageId are not available', function() {
32+
const msg = { ...js, ...{ messageId: undefined } };
2733
const d = new Message(msg);
2834
expect(d.uid()).to.be.equal('eyJzY2hlbWFGb3JtYXQiOiJteVNjaGVtYSIsInRyYWl0cyI6W3siaGVhZGVycyI6eyJ0eXBlIjoib2JqZWN0IiwicHJvcGVydGllcyI6eyJteS1hcHAtaGVhZGVyIjp7InR5cGUiOiJpbnRlZ2VyIiwibWluaW11bSI6MCwibWF4aW11bSI6MTAwfX19fV0sImhlYWRlcnMiOnsicHJvcGVydGllcyI6eyJ0ZXN0MSI6eyJ0eXBlIjoic3RyaW5nIn0sInRlc3QyIjp7InR5cGUiOiJudW1iZXIifX19LCJwYXlsb2FkIjp7InRlc3QiOnRydWV9LCJ4LXBhcnNlci1vcmlnaW5hbC1wYXlsb2FkIjp7InRlc3RpbmciOnRydWV9LCJjb3JyZWxhdGlvbklkIjp7InRlc3QiOnRydWV9LCJ4LXBhcnNlci1vcmlnaW5hbC1zY2hlbWEtZm9ybWF0IjoiYXBwbGljYXRpb24vdm5kLmFwYWNoZS5hdnJvO3ZlcnNpb249MS45LjAiLCJjb250ZW50VHlwZSI6ImFwcGxpY2F0aW9uL2pzb24iLCJ0aXRsZSI6IlRlc3QiLCJzdW1tYXJ5IjoidGVzdCIsImRlc2NyaXB0aW9uIjoidGVzdGluZyIsImV4dGVybmFsRG9jcyI6eyJ0ZXN0Ijp0cnVlfSwidGFncyI6W3sibmFtZSI6InRhZzEifV0sImJpbmRpbmdzIjp7ImFtcXAiOnsidGVzdCI6dHJ1ZX19LCJleGFtcGxlcyI6W3sibmFtZSI6InRlc3QiLCJzdW1tYXJ5IjoidGVzdCBzdW1tYXJ5IiwicGF5bG9hZCI6eyJ0ZXN0Ijp0cnVlfX1dLCJ4LXRlc3QiOiJ0ZXN0aW5nIn0=');
2935
});

0 commit comments

Comments
 (0)