Skip to content

Commit 13ac13f

Browse files
committed
message inference for V2
1 parent ed30a2d commit 13ac13f

2 files changed

Lines changed: 182 additions & 3 deletions

File tree

src/ByteBard.AsyncAPI/Models/AsyncApiOperation.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,18 @@ public virtual void SerializeV2(IAsyncApiWriter writer)
9191

9292
writer.WriteOptionalObject(AsyncApiConstants.Bindings, this.Bindings, (w, t) => t.SerializeV2(w));
9393
writer.WriteOptionalCollection(AsyncApiConstants.Traits, this.Traits, (w, t) => t.SerializeV2(w));
94-
if (this.Messages.Count > 1)
94+
IEnumerable<AsyncApiMessage> messages = this.Messages.Any() ? this.Messages : this.Channel.Messages.Values;
95+
96+
if (messages.Count() > 1)
9597
{
9698
writer.WritePropertyName(AsyncApiConstants.Message);
9799
writer.WriteStartObject();
98-
writer.WriteOptionalCollection(AsyncApiConstants.OneOf, this.Messages, (w, t) => t.SerializeV2(w));
100+
writer.WriteOptionalCollection(AsyncApiConstants.OneOf, messages, (w, t) => t.SerializeV2(w));
99101
writer.WriteEndObject();
100102
}
101103
else
102104
{
103-
writer.WriteOptionalObject(AsyncApiConstants.Message, this.Messages.FirstOrDefault(), (w, m) => m.SerializeV2(w));
105+
writer.WriteOptionalObject(AsyncApiConstants.Message, messages.FirstOrDefault(), (w, m) => m.SerializeV2(w));
104106
}
105107

106108
writer.WriteExtensions(this.Extensions);

test/ByteBard.AsyncAPI.Tests/AsyncApiDocumentV3Tests.cs

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
namespace ByteBard.AsyncAPI.Tests
22
{
3+
using System;
4+
using System.Collections.Concurrent;
5+
using System.Collections.Generic;
36
using FluentAssertions;
47
using ByteBard.AsyncAPI.Bindings;
58
using ByteBard.AsyncAPI.Models;
@@ -230,5 +233,179 @@ public void V3_WithComplexInput_CanReSerialize()
230233
diagnostics.Warnings.Should().BeEmpty();
231234
reserialized.Should().BePlatformAgnosticEquivalentTo(expected);
232235
}
236+
237+
[Test]
238+
public void V3_SerializeV2_WithNoMessageReference_SerializesChannelMessagesOneOf()
239+
{
240+
var expected =
241+
"""
242+
asyncapi: 2.6.0
243+
info:
244+
title: my first asyncapi
245+
version: 1.0.0
246+
channels:
247+
user/signedUp:
248+
publish:
249+
message:
250+
oneOf:
251+
- payload:
252+
type: object
253+
properties:
254+
displayName:
255+
type: string
256+
description: Name of the user
257+
- payload:
258+
type: object
259+
properties:
260+
displayName:
261+
type: string
262+
description: Name of the user
263+
""";
264+
var myFirstAsyncApi = new AsyncApiDocument
265+
{
266+
Info = new AsyncApiInfo
267+
{
268+
Title = "my first asyncapi",
269+
Version = "1.0.0",
270+
},
271+
Channels = new Dictionary<string, AsyncApiChannel>
272+
{
273+
{
274+
"UserSignup", new AsyncApiChannel
275+
{
276+
Address = "user/signedUp",
277+
Messages = new Dictionary<string, AsyncApiMessage>()
278+
{
279+
{
280+
"UserMessage", new AsyncApiMessage
281+
{
282+
Payload = new AsyncApiJsonSchema()
283+
{
284+
Type = SchemaType.Object,
285+
Properties = new Dictionary<string, AsyncApiJsonSchema>()
286+
{
287+
{
288+
"displayName", new AsyncApiJsonSchema()
289+
{
290+
Type = SchemaType.String,
291+
Description = "Name of the user",
292+
}
293+
},
294+
},
295+
},
296+
}
297+
},
298+
{
299+
"OtherUserMessage", new AsyncApiMessage
300+
{
301+
Payload = new AsyncApiJsonSchema()
302+
{
303+
Type = SchemaType.Object,
304+
Properties = new Dictionary<string, AsyncApiJsonSchema>()
305+
{
306+
{
307+
"displayName", new AsyncApiJsonSchema()
308+
{
309+
Type = SchemaType.String,
310+
Description = "Name of the user",
311+
}
312+
},
313+
},
314+
},
315+
}
316+
},
317+
},
318+
}
319+
},
320+
},
321+
Operations = new Dictionary<string, AsyncApiOperation>()
322+
{
323+
{
324+
"ConsumerUserSignups", new AsyncApiOperation
325+
{
326+
Action = AsyncApiAction.Receive,
327+
Channel = new AsyncApiChannelReference("#/channels/UserSignup"),
328+
}
329+
},
330+
},
331+
};
332+
333+
var yamlV2 = myFirstAsyncApi.SerializeAsYaml(AsyncApiVersion.AsyncApi2_0);
334+
yamlV2.Should().BeEquivalentTo(expected);
335+
}
336+
337+
[Test]
338+
public void V3_SerializeV2_WithNoMessageReference_SerializesChannelMessage()
339+
{
340+
var expected =
341+
"""
342+
asyncapi: 2.6.0
343+
info:
344+
title: my first asyncapi
345+
version: 1.0.0
346+
channels:
347+
user/signedUp:
348+
publish:
349+
message:
350+
payload:
351+
type: object
352+
properties:
353+
displayName:
354+
type: string
355+
description: Name of the user
356+
""";
357+
var myFirstAsyncApi = new AsyncApiDocument
358+
{
359+
Info = new AsyncApiInfo
360+
{
361+
Title = "my first asyncapi",
362+
Version = "1.0.0",
363+
},
364+
Channels = new Dictionary<string, AsyncApiChannel>
365+
{
366+
{
367+
"UserSignup", new AsyncApiChannel
368+
{
369+
Address = "user/signedUp",
370+
Messages = new Dictionary<string, AsyncApiMessage>()
371+
{
372+
{
373+
"UserMessage", new AsyncApiMessage
374+
{
375+
Payload = new AsyncApiJsonSchema()
376+
{
377+
Type = SchemaType.Object,
378+
Properties = new Dictionary<string, AsyncApiJsonSchema>()
379+
{
380+
{
381+
"displayName", new AsyncApiJsonSchema()
382+
{
383+
Type = SchemaType.String,
384+
Description = "Name of the user",
385+
}
386+
},
387+
},
388+
},
389+
}
390+
},
391+
},
392+
}
393+
},
394+
},
395+
Operations = new Dictionary<string, AsyncApiOperation>()
396+
{
397+
{
398+
"ConsumerUserSignups", new AsyncApiOperation
399+
{
400+
Action = AsyncApiAction.Receive,
401+
Channel = new AsyncApiChannelReference("#/channels/UserSignup"),
402+
}
403+
},
404+
},
405+
};
406+
407+
var yamlV2 = myFirstAsyncApi.SerializeAsYaml(AsyncApiVersion.AsyncApi2_0);
408+
yamlV2.Should().BeEquivalentTo(expected);
409+
}
233410
}
234411
}

0 commit comments

Comments
 (0)