Forge
csharpdeeb25a2
1using CascadeIDE.Features.Chat;
2using CascadeIDE.Services;
3using Xunit;
4
5namespace CascadeIDE.Tests;
6
7public sealed class ChatSlashSessionReportsTests
8{
9 private static readonly Guid MainId = Guid.Parse("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
10 private static readonly Guid BranchId = Guid.Parse("bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb");
11
12 [Fact]
13 public void TopicList_IncludesFlagsAndCounts()
14 {
15 var snapshot = SampleSnapshot();
16 var text = ChatSlashSessionReports.FormatTopicList(snapshot);
17 Assert.Contains("Темы сессии (2)", text);
18 Assert.Contains("[main, active]", text);
19 Assert.Contains("1 сообщ.", text);
20 }
21
22 [Fact]
23 public void TopicTree_ShowsBranchUnderMain()
24 {
25 var snapshot = SampleSnapshot();
26 var text = ChatSlashSessionReports.FormatTopicTree(snapshot);
27 Assert.Contains("Дерево тем", text);
28 Assert.Contains("Основная тема", text);
29 Assert.Contains("Ветка", text);
30 }
31
32 [Fact]
33 public void SpineList_Empty_ReturnsHint()
34 {
35 var text = ChatSlashSessionReports.FormatSpineList(ChatProductSpine.Empty);
36 Assert.Contains("Spine пуст", text);
37 }
38
39 [Fact]
40 public void SpineTree_WithMilestones_DrawsBranches()
41 {
42 var spine = new ChatProductSpine("Линия A", "Фокус B", ["M1", "M2"], true);
43 var text = ChatSlashSessionReports.FormatSpineTree(spine);
44 Assert.Contains("Линия A", text);
45 Assert.Contains("M1", text);
46 Assert.Contains("M2", text);
47 }
48
49 [Fact]
50 public void Catalog_ResolvesTopicList_AsLocalIntercom()
51 {
52 Assert.True(ChatSlashCommandCatalog.TryResolveInput("/intercom topic list", out var d, out _));
53 Assert.Equal(ChatSlashCommandExecutionKind.LocalIntercom, d.ExecutionKind);
54 Assert.Equal("/intercom topic list", d.SlashPath);
55 }
56
57 [Fact]
58 public void Catalog_ResolvesTopicListText_AsLocalReport()
59 {
60 Assert.True(ChatSlashCommandCatalog.TryResolveInput("/intercom topic list text", out var d, out _));
61 Assert.Equal(ChatSlashCommandExecutionKind.LocalReport, d.ExecutionKind);
62 Assert.Equal("/intercom topic list text", d.SlashPath);
63 }
64
65 [Fact]
66 public void TryFormat_TopicListText_Route()
67 {
68 var snapshot = SampleSnapshot();
69 var text = ChatSlashSessionReports.TryFormat("/intercom topic list text", snapshot);
70 Assert.NotNull(text);
71 Assert.Contains("Темы сессии", text);
72 }
73
74 [Fact]
75 public void Catalog_ReportRoutes_HaveReportHandler()
76 {
77 foreach (var route in IntentSlashCatalog.SlashRoutes.Values)
78 {
79 if (route.ExecutionKind != ChatSlashCommandExecutionKind.LocalReport)
80 continue;
81
82 Assert.False(string.IsNullOrWhiteSpace(route.ReportHandlerId), route.SlashPath);
83 Assert.True(ChatSlashReportHandlers.IsKnown(route.ReportHandlerId!), route.SlashPath);
84 }
85 }
86
87 [Fact]
88 public void Catalog_IntercomRoutes_HaveIntercomHandler()
89 {
90 foreach (var route in IntentSlashCatalog.SlashRoutes.Values)
91 {
92 if (route.ExecutionKind != ChatSlashCommandExecutionKind.LocalIntercom)
93 continue;
94
95 Assert.False(string.IsNullOrWhiteSpace(route.IntercomHandlerId), route.SlashPath);
96 Assert.True(ChatSlashIntercomHandlers.IsKnown(route.IntercomHandlerId!), route.SlashPath);
97 }
98 }
99
100 [Fact]
101 public void Catalog_ResolvesIntercomTopicCreate_AsLocalIntercom()
102 {
103 Assert.True(ChatSlashCommandCatalog.TryResolveInput("/intercom topic create My title", out var d, out _));
104 Assert.Equal(ChatSlashCommandExecutionKind.LocalIntercom, d.ExecutionKind);
105 Assert.Equal("/intercom topic create", d.SlashPath);
106 Assert.True(IntentSlashCatalog.TryGetRoute("/intercom topic create", out var route));
107 Assert.Equal(ChatSlashIntercomHandlers.Ids.TopicCreate, route.IntercomHandlerId);
108 }
109
110 private static ChatSurfaceSnapshot SampleSnapshot()
111 {
112 var main = new ChatThreadNode(MainId, "t-main", "Основная тема", true, true, null, null, 0, 0);
113 var branch = new ChatThreadNode(BranchId, "t-branch", "Ветка", false, false, MainId, null, 1, 1);
114 var msgMain = new ChatMessageNode(
115 Guid.NewGuid(), "m1", MainId, null, 0, "user", "hi", false, false, null, null, null);
116 var msgBranch = new ChatMessageNode(
117 Guid.NewGuid(), "m2", BranchId, msgMain.MessageId, 1, "user", "branch", false, true, null, null, null);
118 var state = new ChatSurfaceState(
119 [main, branch],
120 [msgMain, msgBranch],
121 [],
122 [],
123 MainId,
124 "Chat");
125 var layout = new ChatSurfaceLayout(
126 [
127 new ChatThreadOverviewItem(MainId, "Основная тема", "hi", true, true, 0, 1),
128 new ChatThreadOverviewItem(BranchId, "Ветка", "branch", false, false, 1, 1),
129 ],
130 [
131 new ChatSurfaceLane(main, []),
132 new ChatSurfaceLane(branch, []),
133 ]);
134 return new ChatSurfaceSnapshot(state, layout, ChatProductSpine.Empty);
135 }
136}
137
View only · write via MCP/CIDE