Skip to content

Commit 9e499f4

Browse files
committed
fix: inline a 2.x channel reference whose target is not written
A 2.x channel reference is written with its target's address, since 2.x keys channels by address. When the target is not one of the document's channels, for example because it was removed after reading, that address points nowhere and did not match the reference, so it was left dangling. Such a reference now keeps its own pointer, which is found dangling and written inline.
1 parent fe66369 commit 9e499f4

2 files changed

Lines changed: 19 additions & 2 deletions

File tree

‎src/ByteBard.AsyncAPI/Models/References/AsyncApiChannelReference.cs‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ namespace ByteBard.AsyncAPI.Models
33
using System;
44
using System.Collections.Generic;
55
using System.Diagnostics;
6+
using System.Linq;
67
using ByteBard.AsyncAPI.Models.Interfaces;
78
using ByteBard.AsyncAPI.Writers;
89

@@ -56,9 +57,12 @@ public override void SerializeV2(IAsyncApiWriter writer)
5657
if (!writer.GetSettings().ShouldInlineReference(this.Reference))
5758
{
5859
this.Reference.Workspace = writer.Workspace;
59-
if (this.IsRootChannelReference() && this.Target?.Address != null)
60+
if (this.IsRootChannelReference()
61+
&& this.Target?.Address != null
62+
&& writer.Workspace.RootDocument?.Channels.Values.Any(channel => ReferenceEquals(channel, this.Target)) == true)
6063
{
61-
// 2.x keys root channels by address instead of by key.
64+
// 2.x keys root channels by address instead of by key. A target the document does not write
65+
// keeps its own reference, so it can be found dangling and written inline.
6266
writer.WriteStartObject();
6367
writer.WriteOptionalProperty(AsyncApiConstants.DollarRef, "#/channels/" + JsonPointer.EscapeToken(this.Target.Address));
6468
writer.WriteEndObject();

‎test/ByteBard.AsyncAPI.Tests/Models/ReferenceFallback_Should.cs‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,19 @@ public void WriteAsV2_ReadsBackTheSame(string name)
591591
this.AssertRoundTrip(name, AsyncApiVersion.AsyncApi2_0);
592592
}
593593

594+
[Test]
595+
public void WriteAsV2_ChannelReference_ToARemovedChannel_IsInlined()
596+
{
597+
var document = Read(Cases["v2 channel by address"].Yaml);
598+
599+
// The reference still resolves to the channel it was read with, but the document no longer has it.
600+
document.Channels.Remove("usersignedup");
601+
var written = document.SerializeAsYaml(AsyncApiVersion.AsyncApi2_0);
602+
603+
References(document.SerializeAsJson(AsyncApiVersion.AsyncApi2_0)).Should().NotContain(r => r.StartsWith("#/channels/"), written);
604+
Cases["v2 channel by address"].Inspect(Read(written)).Should().Be(Marker, written);
605+
}
606+
594607
[TestCaseSource(nameof(CaseNames))]
595608
public void WriteAsV3_ReadsBackTheSame(string name)
596609
{

0 commit comments

Comments
 (0)