| 1 | using System.Text.Json; |
| 2 | using CascadeIDE.Models.AgentChat; |
| 3 | using Xunit; |
| 4 | |
| 5 | namespace CascadeIDE.Tests; |
| 6 | |
| 7 | public sealed class AgentChatClarificationBatchTests |
| 8 | { |
| 9 | [Fact] |
| 10 | public void TryValidate_ValidBatch_NoResponse_Ok() |
| 11 | { |
| 12 | var id = Guid.NewGuid(); |
| 13 | var batch = new ClarificationBatch( |
| 14 | id, |
| 15 | [ |
| 16 | new ClarificationItem("a", "Первый?"), |
| 17 | new ClarificationItem("b", "Второй?", ClarificationAnswerStyle.FreeText), |
| 18 | ], |
| 19 | "Тест"); |
| 20 | |
| 21 | Assert.True(ClarificationBatchValidation.TryValidate(batch, null, out var err)); |
| 22 | Assert.Null(err); |
| 23 | } |
| 24 | |
| 25 | [Fact] |
| 26 | public void TryValidate_DuplicateItemId_Fails() |
| 27 | { |
| 28 | var batch = new ClarificationBatch( |
| 29 | Guid.NewGuid(), |
| 30 | [ |
| 31 | new ClarificationItem("x", "Один"), |
| 32 | new ClarificationItem("x", "Другой"), |
| 33 | ]); |
| 34 | |
| 35 | Assert.False(ClarificationBatchValidation.TryValidate(batch, null, out var err)); |
| 36 | Assert.Contains("Дублируется", err, StringComparison.Ordinal); |
| 37 | } |
| 38 | |
| 39 | [Fact] |
| 40 | public void TryValidate_CompleteResponse_Ok() |
| 41 | { |
| 42 | var id = Guid.NewGuid(); |
| 43 | var batch = new ClarificationBatch( |
| 44 | id, |
| 45 | [ |
| 46 | new ClarificationItem("q1", "Имя файла?"), |
| 47 | new ClarificationItem("q2", "Ок?", ClarificationAnswerStyle.YesNo), |
| 48 | ]); |
| 49 | |
| 50 | var response = new ClarificationResponse( |
| 51 | id, |
| 52 | new Dictionary<string, string> { ["q1"] = "foo.cs", ["q2"] = "да" }); |
| 53 | |
| 54 | Assert.True(ClarificationBatchValidation.TryValidate(batch, response, out var err)); |
| 55 | Assert.Null(err); |
| 56 | } |
| 57 | |
| 58 | [Fact] |
| 59 | public void TryValidate_SingleChoice_InvalidAnswer_Fails() |
| 60 | { |
| 61 | var id = Guid.NewGuid(); |
| 62 | var batch = new ClarificationBatch( |
| 63 | id, |
| 64 | [ |
| 65 | new ClarificationItem( |
| 66 | "mode", |
| 67 | "Режим?", |
| 68 | ClarificationAnswerStyle.SingleChoice, |
| 69 | ["A", "B"]), |
| 70 | ]); |
| 71 | |
| 72 | var response = new ClarificationResponse(id, new Dictionary<string, string> { ["mode"] = "C" }); |
| 73 | |
| 74 | Assert.False(ClarificationBatchValidation.TryValidate(batch, response, out var err)); |
| 75 | Assert.Contains("не входит", err, StringComparison.Ordinal); |
| 76 | } |
| 77 | |
| 78 | [Fact] |
| 79 | public void TryValidate_ResponseKeysTrimmed_MatchesBatchIds() |
| 80 | { |
| 81 | var id = Guid.NewGuid(); |
| 82 | var batch = new ClarificationBatch( |
| 83 | id, |
| 84 | [new ClarificationItem("q1", "Текст?")]); |
| 85 | |
| 86 | var response = new ClarificationResponse( |
| 87 | id, |
| 88 | new Dictionary<string, string> { [" q1 "] = "ответ" }); |
| 89 | |
| 90 | Assert.True(ClarificationBatchValidation.TryValidate(batch, response, out var err)); |
| 91 | Assert.Null(err); |
| 92 | } |
| 93 | |
| 94 | [Fact] |
| 95 | public void Json_RoundTrip_Batch() |
| 96 | { |
| 97 | var id = Guid.NewGuid(); |
| 98 | var batch = new ClarificationBatch( |
| 99 | id, |
| 100 | [new ClarificationItem("only", "Вопрос?")], |
| 101 | "Заголовок"); |
| 102 | |
| 103 | var json = JsonSerializer.Serialize(batch); |
| 104 | var back = JsonSerializer.Deserialize<ClarificationBatch>(json); |
| 105 | Assert.NotNull(back); |
| 106 | Assert.Equal(batch.Id, back.Id); |
| 107 | Assert.Equal(batch.Title, back.Title); |
| 108 | Assert.Single(back.Items); |
| 109 | Assert.Equal("only", back.Items[0].Id); |
| 110 | } |
| 111 | } |
| 112 | |