]> git.giacomolli.uk - onechat/blobdiff - telegram_test.go
Stop a subagent with /stop NAME
[onechat] / telegram_test.go
index cf46106874d3d4d641e6a663158216f93e45dfb4..c1f123036a4d8806d5435d9583c0d4b46f5e85f7 100644 (file)
@@ -127,6 +127,13 @@ func TestStopFromTelegramInterruptsTheTurn(t *testing.T) {
        })
 
        telegramWaitForSent(t, telegram, "Error: interrupted", "No turn runs.")
+
+       telegram.Add(TelegramUpdate{
+               UpdateID: 4,
+               Message:  telegramOwnerMessage(stopCommand + " BlueFox"),
+       })
+
+       telegramWaitForSent(t, telegram, "No turn runs.", "No subagent BlueFox runs.")
 }
 
 func TestBotStartsAtTheStoredOffset(t *testing.T) {
@@ -398,12 +405,12 @@ func TestReplyTagsGoAsText(t *testing.T) {
        }{
                {
                        name: "rich message escapes the tag outside code",
-                       sent: []string{"a \\<details> tag and `<b>`"},
+                       sent: []string{"a &lt;details> &amp; tag and `<b>`"},
                },
                {
                        name:   "entity fallback shows the tag as written",
                        status: http.StatusBadRequest,
-                       sent:   []string{"a <details> tag and <b>"},
+                       sent:   []string{"a <details> & tag and <b>"},
                },
        }
 
@@ -421,7 +428,7 @@ func TestReplyTagsGoAsText(t *testing.T) {
                        bot, _ := telegramStartTestBot(t, telegram)
                        bot.post(t.Context(), Event{
                                Kind: "reply",
-                               Text: "a <details> tag and `<b>`",
+                               Text: "a <details> & tag and `<b>`",
                        })
 
                        require.Equal(t, tc.sent, telegram.Sent())
@@ -451,6 +458,50 @@ func TestLongReplySplitCountsTheEscapedTags(t *testing.T) {
        }
 }
 
+func TestRefusedRichPartGoesWithTheTextAsWritten(t *testing.T) {
+       paragraph := "A <b> & c.\n\n"
+       reply := strings.Repeat(paragraph, telegramRichBytes/len(paragraph))
+
+       telegram := newTelegramFake(t)
+       refused := false
+       telegram.fail = func(call TelegramFakeCall) (int, string) {
+               if call.method != "sendRichMessage" || refused {
+                       return 0, ""
+               }
+
+               refused = true
+
+               return http.StatusBadRequest, "Bad Request"
+       }
+
+       bot, _ := telegramStartTestBot(t, telegram)
+       bot.post(t.Context(), Event{
+               Kind: "reply",
+               Text: reply,
+       })
+
+       var fallback, rich []string
+       for _, call := range telegram.Calls() {
+               switch {
+               case !call.ok:
+               case call.method == "sendMessage":
+                       fallback = append(fallback, call.params["text"].(string))
+               case call.method == "sendRichMessage":
+                       rich = append(rich, call.params["rich_message"].(map[string]any)["markdown"].(string))
+               }
+       }
+
+       require.Greater(t, len(fallback), 1)
+       require.Len(t, rich, 1)
+       require.True(t, strings.HasPrefix(reply, strings.Join(fallback, "")), "fallback text is not the reply as written")
+
+       for _, text := range fallback {
+               require.LessOrEqual(t, telegramUTF16Units(text), telegramMessageUnits)
+       }
+
+       require.True(t, reply == strings.Join(fallback, "")+telegramUnescapeTags(rich[0]), "reply is not sent once and whole")
+}
+
 func TestRefusedEntitiesGoAgainAsPlainText(t *testing.T) {
        telegram := newTelegramFake(t)
        telegram.fail = func(call TelegramFakeCall) (int, string) {
@@ -629,6 +680,12 @@ func TestSplitRich(t *testing.T) {
                        limit:    3,
                        parts:    []string{"ab", "\u00e9c", "d"},
                },
+               {
+                       name:     "long line is not cut inside an entity",
+                       markdown: "abc&amp;def",
+                       limit:    6,
+                       parts:    []string{"abc", "&amp;d", "ef"},
+               },
        }
 
        for _, tc := range testCases {