]> git.giacomolli.uk - onechat/blobdiff - botapi_test.go
Capitalize type names so variables can use them
[onechat] / botapi_test.go
index 9c4db5461c2d1434be43d0577ff0753b012f498b..fb57b45b468116c0687419123eedd7421c5fd738 100644 (file)
@@ -79,31 +79,69 @@ func TestSendMessageSendsTheEntities(t *testing.T) {
        }, server.Calls()[0].params["entities"])
 }
 
        }, server.Calls()[0].params["entities"])
 }
 
-func TestSendMessageTimesOutOnAStalledConnection(t *testing.T) {
+func TestSendRichMessageSendsTheMarkdownUnchanged(t *testing.T) {
        server := newFakeBot(t)
        server := newFakeBot(t)
-       server.stall = func(call fakeBotCall) bool {
-               return call.method == "sendMessage"
+       markdown := "| a | b |\n|---|---|\n| **1** | `2` |"
+       err := newBotAPI(server.URL, testBotToken).SendRichMessage(t.Context(), testOwner, markdown)
+       require.NoError(t, err)
+
+       call := server.Calls()[0]
+       require.Equal(t, "sendRichMessage", call.method)
+       require.Equal(t, map[string]any{
+               "chat_id": float64(testOwner),
+               "rich_message": map[string]any{
+                       "markdown": markdown,
+               },
+       }, call.params)
+}
+
+func TestSendCallsTimeOutOnAStalledConnection(t *testing.T) {
+       testCases := []struct {
+               method string
+               send   func(ctx context.Context, api *botAPI) error
+       }{
+               {
+                       method: "sendMessage",
+                       send: func(ctx context.Context, api *botAPI) error {
+                               return api.SendMessage(ctx, testOwner, "hi", nil)
+                       },
+               },
+               {
+                       method: "sendRichMessage",
+                       send: func(ctx context.Context, api *botAPI) error {
+                               return api.SendRichMessage(ctx, testOwner, "hi")
+                       },
+               },
        }
 
        }
 
-       api := newBotAPI(server.URL, testBotToken)
-       api.sendTimeout = 50 * time.Millisecond
-       start := time.Now()
-       err := api.SendMessage(t.Context(), testOwner, "hi", nil)
-       require.ErrorIs(t, err, errBotNetwork)
-       require.Less(t, time.Since(start), 5*time.Second)
-       require.NotContains(t, err.Error(), testBotToken)
-       require.NotContains(t, err.Error(), server.URL)
-
-       retry, _ := retryable(err)
-       require.True(t, retry)
-
-       api.sendTimeout = time.Hour
-       ctx, cancel := context.WithCancel(t.Context())
-       time.AfterFunc(50*time.Millisecond, cancel)
-       start = time.Now()
-       err = api.SendMessage(ctx, testOwner, "hi", nil)
-       require.Error(t, err)
-       require.Less(t, time.Since(start), 5*time.Second)
+       for _, tc := range testCases {
+               t.Run(tc.method, func(t *testing.T) {
+                       server := newFakeBot(t)
+                       server.stall = func(call fakeBotCall) bool {
+                               return call.method == tc.method
+                       }
+
+                       api := newBotAPI(server.URL, testBotToken)
+                       api.sendTimeout = 50 * time.Millisecond
+                       start := time.Now()
+                       err := tc.send(t.Context(), api)
+                       require.ErrorIs(t, err, errBotNetwork)
+                       require.Less(t, time.Since(start), 5*time.Second)
+                       require.NotContains(t, err.Error(), testBotToken)
+                       require.NotContains(t, err.Error(), server.URL)
+
+                       retry, _ := retryable(err)
+                       require.True(t, retry)
+
+                       api.sendTimeout = time.Hour
+                       ctx, cancel := context.WithCancel(t.Context())
+                       time.AfterFunc(50*time.Millisecond, cancel)
+                       start = time.Now()
+                       err = tc.send(ctx, api)
+                       require.Error(t, err)
+                       require.Less(t, time.Since(start), 5*time.Second)
+               })
+       }
 }
 
 func TestBotErrorsDoNotHoldTheToken(t *testing.T) {
 }
 
 func TestBotErrorsDoNotHoldTheToken(t *testing.T) {
@@ -112,6 +150,7 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) {
                reply     func(w http.ResponseWriter)
                retry     bool
                wait      time.Duration
                reply     func(w http.ResponseWriter)
                retry     bool
                wait      time.Duration
+               rejected  bool
                errorText string
        }{
                {
                errorText string
        }{
                {
@@ -153,6 +192,35 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) {
                        retry:     false,
                        errorText: "Unauthorized: botTOKEN",
                },
                        retry:     false,
                        errorText: "Unauthorized: botTOKEN",
                },
+               {
+                       name: "bad request is a refusal",
+                       reply: func(w http.ResponseWriter) {
+                               w.WriteHeader(http.StatusBadRequest)
+                               _, _ = io.WriteString(w, `{"ok":false,"error_code":400,"description":"Bad Request: can't parse"}`)
+                       },
+                       retry:     false,
+                       rejected:  true,
+                       errorText: "answered 400: Bad Request: can't parse",
+               },
+               {
+                       name: "unknown method is a refusal",
+                       reply: func(w http.ResponseWriter) {
+                               w.WriteHeader(http.StatusNotFound)
+                               _, _ = io.WriteString(w, `{"ok":false,"error_code":404,"description":"Not Found"}`)
+                       },
+                       retry:     false,
+                       rejected:  true,
+                       errorText: "answered 404: Not Found",
+               },
+               {
+                       name: "not found page of a proxy is not a refusal",
+                       reply: func(w http.ResponseWriter) {
+                               w.WriteHeader(http.StatusNotFound)
+                               _, _ = io.WriteString(w, "<html>not found</html>")
+                       },
+                       retry:     false,
+                       errorText: "answered 404: Not Found",
+               },
                {
                        name: "broken answer is retried",
                        reply: func(w http.ResponseWriter) {
                {
                        name: "broken answer is retried",
                        reply: func(w http.ResponseWriter) {
@@ -178,6 +246,7 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) {
                        retry, wait := retryable(err)
                        require.Equal(t, tc.retry, retry)
                        require.Equal(t, tc.wait, wait)
                        retry, wait := retryable(err)
                        require.Equal(t, tc.retry, retry)
                        require.Equal(t, tc.wait, wait)
+                       require.Equal(t, tc.rejected, rejected(err))
                })
        }
 
                })
        }
 
@@ -253,12 +322,17 @@ func (f *fakeBot) Calls() []fakeBotCall {
        return append([]fakeBotCall(nil), f.calls...)
 }
 
        return append([]fakeBotCall(nil), f.calls...)
 }
 
-// Sent returns the texts of the sendMessage calls that succeeded.
+// Sent returns the texts of the sendMessage calls and the Markdown of the
+// sendRichMessage calls that succeeded, in order.
 func (f *fakeBot) Sent() []string {
        var texts []string
        for _, call := range f.Calls() {
 func (f *fakeBot) Sent() []string {
        var texts []string
        for _, call := range f.Calls() {
-               if call.method == "sendMessage" && call.ok {
+               switch {
+               case !call.ok:
+               case call.method == "sendMessage":
                        texts = append(texts, call.params["text"].(string))
                        texts = append(texts, call.params["text"].(string))
+               case call.method == "sendRichMessage":
+                       texts = append(texts, call.params["rich_message"].(map[string]any)["markdown"].(string))
                }
        }
 
                }
        }