| 1 | using System.Text.Json; |
| 2 | using CascadeIDE.Features.Intercom.Transport; |
| 3 | using CascadeIDE.Models.AgentChat; |
| 4 | using CascadeIDE.Models.Intercom; |
| 5 | using CascadeIDE.Services.Intercom; |
| 6 | using Xunit; |
| 7 | |
| 8 | namespace CascadeIDE.Tests; |
| 9 | |
| 10 | public sealed class IntercomRelatesToWireTests |
| 11 | { |
| 12 | [Fact] |
| 13 | public void EnrichForWire_MessageRangeRelated_AddsRelatesTo() |
| 14 | { |
| 15 | var anchor = new AttachmentAnchor { File = "src/Foo.cs", LineStart = 10, LineEnd = 12 }; |
| 16 | var range = new ChatHistoryMessageRangeRelatedPayload( |
| 17 | Guid.NewGuid().ToString("N"), |
| 18 | 3, |
| 19 | 5, |
| 20 | anchor, |
| 21 | "slash"); |
| 22 | var json = JsonSerializer.Serialize(range, IntercomTransportJson.Web); |
| 23 | var element = JsonSerializer.Deserialize<JsonElement>(json, IntercomTransportJson.Web); |
| 24 | |
| 25 | var wire = IntercomTransportPayloadEnricher.EnrichForWire(ChatHistoryEventKind.MessageRangeRelated, element); |
| 26 | |
| 27 | Assert.True(wire.TryGetProperty("relates_to", out var relates)); |
| 28 | Assert.Equal(JsonValueKind.Array, relates.ValueKind); |
| 29 | Assert.Equal(1, relates.GetArrayLength()); |
| 30 | var link = relates[0]; |
| 31 | Assert.Equal("code", link.GetProperty("target_kind").GetString()); |
| 32 | Assert.Equal("documents", link.GetProperty("relation").GetString()); |
| 33 | Assert.Equal("explicit", link.GetProperty("confidence").GetString()); |
| 34 | Assert.Equal(3, link.GetProperty("ordinal_range").GetProperty("start_ordinal").GetInt32()); |
| 35 | Assert.Equal(5, link.GetProperty("ordinal_range").GetProperty("end_ordinal").GetInt32()); |
| 36 | Assert.Equal("src/Foo.cs", link.GetProperty("code_ref").GetProperty("file").GetString()); |
| 37 | } |
| 38 | |
| 39 | [Fact] |
| 40 | public void EnrichForWire_Disjoint_AddsMultipleRelatesToAndOrdinalSegments() |
| 41 | { |
| 42 | var anchor = new AttachmentAnchor { File = "src/Foo.cs", LineStart = 1, LineEnd = 2 }; |
| 43 | var range = IntercomMessageRangeRelatedSupport.CreatePayload( |
| 44 | Guid.NewGuid().ToString("N"), |
| 45 | [ |
| 46 | new ChatHistoryMessageOrdinalSegment(3, 5), |
| 47 | new ChatHistoryMessageOrdinalSegment(8, 15), |
| 48 | ], |
| 49 | anchor, |
| 50 | "slash"); |
| 51 | var json = JsonSerializer.Serialize(range, IntercomTransportJson.Web); |
| 52 | var element = JsonSerializer.Deserialize<JsonElement>(json, IntercomTransportJson.Web); |
| 53 | |
| 54 | var wire = IntercomTransportPayloadEnricher.EnrichForWire(ChatHistoryEventKind.MessageRangeRelated, element); |
| 55 | |
| 56 | Assert.True(wire.TryGetProperty("relates_to", out var relates)); |
| 57 | Assert.Equal(2, relates.GetArrayLength()); |
| 58 | Assert.Equal(3, relates[0].GetProperty("ordinal_range").GetProperty("start_ordinal").GetInt32()); |
| 59 | Assert.Equal(5, relates[0].GetProperty("ordinal_range").GetProperty("end_ordinal").GetInt32()); |
| 60 | Assert.Equal(8, relates[1].GetProperty("ordinal_range").GetProperty("start_ordinal").GetInt32()); |
| 61 | Assert.Equal(15, relates[1].GetProperty("ordinal_range").GetProperty("end_ordinal").GetInt32()); |
| 62 | |
| 63 | Assert.True(wire.TryGetProperty("ordinal_segments", out var segments)); |
| 64 | Assert.Equal(2, segments.GetArrayLength()); |
| 65 | } |
| 66 | |
| 67 | [Fact] |
| 68 | public void NormalizeInbound_DisjointFromRelatesTo_FillsOrdinalSegments() |
| 69 | { |
| 70 | var anchor = new AttachmentAnchor { File = "src/Foo.cs" }; |
| 71 | var wireJson = JsonSerializer.Serialize(new |
| 72 | { |
| 73 | thread_id = Guid.NewGuid().ToString("N"), |
| 74 | start_ordinal = 3, |
| 75 | end_ordinal = 15, |
| 76 | code_ref = anchor, |
| 77 | source = "slash", |
| 78 | relates_to = new object[] |
| 79 | { |
| 80 | new |
| 81 | { |
| 82 | target_kind = "code", |
| 83 | relation = "documents", |
| 84 | code_ref = anchor, |
| 85 | ordinal_range = new { start_ordinal = 3, end_ordinal = 5 }, |
| 86 | confidence = "explicit", |
| 87 | }, |
| 88 | new |
| 89 | { |
| 90 | target_kind = "code", |
| 91 | relation = "documents", |
| 92 | code_ref = anchor, |
| 93 | ordinal_range = new { start_ordinal = 8, end_ordinal = 15 }, |
| 94 | confidence = "explicit", |
| 95 | }, |
| 96 | }, |
| 97 | }, IntercomTransportJson.Web); |
| 98 | |
| 99 | var normalized = IntercomTransportPayloadNormalizer.NormalizeInbound( |
| 100 | "message_range_related", |
| 101 | wireJson); |
| 102 | |
| 103 | using var doc = JsonDocument.Parse(normalized); |
| 104 | var root = doc.RootElement; |
| 105 | Assert.True(root.TryGetProperty("ordinal_segments", out var segments)); |
| 106 | Assert.Equal(2, segments.GetArrayLength()); |
| 107 | Assert.Equal(3, segments[0].GetProperty("start_ordinal").GetInt32()); |
| 108 | Assert.Equal(5, segments[0].GetProperty("end_ordinal").GetInt32()); |
| 109 | Assert.Equal(8, segments[1].GetProperty("start_ordinal").GetInt32()); |
| 110 | Assert.Equal(15, segments[1].GetProperty("end_ordinal").GetInt32()); |
| 111 | } |
| 112 | |
| 113 | [Fact] |
| 114 | public void EnrichForWire_MessageAdded_Unchanged() |
| 115 | { |
| 116 | var msg = new ChatHistoryMessagePayload( |
| 117 | Guid.NewGuid().ToString("N"), |
| 118 | "user", |
| 119 | "hi", |
| 120 | Guid.NewGuid().ToString("N")); |
| 121 | var json = JsonSerializer.Serialize(msg, IntercomTransportJson.Web); |
| 122 | var element = JsonSerializer.Deserialize<JsonElement>(json, IntercomTransportJson.Web); |
| 123 | |
| 124 | var wire = IntercomTransportPayloadEnricher.EnrichForWire(ChatHistoryEventKind.MessageAdded, element); |
| 125 | |
| 126 | Assert.False(wire.TryGetProperty("relates_to", out _)); |
| 127 | } |
| 128 | } |
| 129 | |