X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/087d725b5ab41ad34ffd24938482d45a8b99a080..8707a09fee94c97e29d668d24fb9713373913e0b:/telegram_api_test.go diff --git a/telegram_api_test.go b/telegram_api_test.go index 43e952e..4395d6b 100644 --- a/telegram_api_test.go +++ b/telegram_api_test.go @@ -6,6 +6,7 @@ import ( "net/http" "net/http/httptest" "testing" + "testing/synctest" "time" "github.com/stretchr/testify/require" @@ -28,7 +29,7 @@ func TestGetUpdatesAsksForMessagesFromTheOffset(t *testing.T) { require.Equal(t, "getUpdates", call.method) require.Equal(t, map[string]any{ "offset": float64(7), - "timeout": float64(telegramPollSeconds), + "timeout": float64(telegramUpdateWaitTimeout / time.Second), "allowed_updates": []any{"message"}, }, call.params) } @@ -103,30 +104,34 @@ func TestSendCallsTimeOutOnAStalledConnection(t *testing.T) { for _, tc := range testCases { t.Run(tc.method, func(t *testing.T) { - server := newTelegramFake(t) - server.stall = func(call TelegramFakeCall) bool { - return call.method == tc.method - } - - api := newTelegramAPI(server.URL, telegramTestToken) - api.sendTimeout = 50 * time.Millisecond - start := time.Now() - err := tc.send(t.Context(), api) - require.EqualError(t, err, "no answer in 50ms") - require.Less(t, time.Since(start), 5*time.Second) - require.NotContains(t, err.Error(), telegramTestToken) - require.NotContains(t, err.Error(), server.URL) + synctest.Test(t, func(t *testing.T) { + server := newTelegramLocalFake(t) + server.stall = func(call TelegramFakeCall) bool { + return call.method == tc.method + } + + api := newTelegramAPI(server.URL, telegramTestToken) + api.http.Transport = server + start := time.Now() + err := tc.send(t.Context(), api) + require.EqualError(t, err, "no answer in 30s") + require.Equal(t, telegramSendTimeout, time.Since(start)) + require.NotContains(t, err.Error(), telegramTestToken) + require.NotContains(t, err.Error(), server.URL) + + retry, _ := telegramRetryable(err) + require.True(t, retry) + + ctx, cancel := context.WithCancel(t.Context()) + defer cancel() - retry, _ := telegramRetryable(err) - require.True(t, retry) + time.AfterFunc(time.Second, cancel) - 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) + start = time.Now() + err = tc.send(ctx, api) + require.Error(t, err) + require.Equal(t, time.Second, time.Since(start)) + }) }) } } @@ -144,9 +149,13 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { name: "refused connection is retried", reply: func(w http.ResponseWriter) { conn, _, err := http.NewResponseController(w).Hijack() - if err == nil { - _ = conn.Close() + if err != nil { + panic(err) } + + // This forced disconnect has no response or + // retry after close. + conn.Close() // nolint: errcheck }, retry: true, errorText: "no answer", @@ -155,7 +164,11 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { name: "rate limit waits as asked", reply: func(w http.ResponseWriter) { w.WriteHeader(http.StatusTooManyRequests) - _, _ = io.WriteString(w, `{"ok":false,"error_code":429,"description":"Too Many Requests: retry after 3","parameters":{"retry_after":3}}`) + + _, err := io.WriteString(w, `{"ok":false,"error_code":429,"description":"Too Many Requests: retry after 3","parameters":{"retry_after":3}}`) + if err != nil { + panic(err) + } }, retry: true, wait: 3 * time.Second, @@ -165,7 +178,11 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { name: "server error page is retried", reply: func(w http.ResponseWriter) { w.WriteHeader(http.StatusBadGateway) - _, _ = io.WriteString(w, "bad gateway") + + _, err := io.WriteString(w, "bad gateway") + if err != nil { + panic(err) + } }, retry: true, errorText: "502 Bad Gateway", @@ -174,7 +191,11 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { name: "token echoed in a description is hidden", reply: func(w http.ResponseWriter) { w.WriteHeader(http.StatusUnauthorized) - _, _ = io.WriteString(w, `{"ok":false,"error_code":401,"description":"Unauthorized: bot`+telegramTestToken+`"}`) + + _, err := io.WriteString(w, `{"ok":false,"error_code":401,"description":"Unauthorized: bot`+telegramTestToken+`"}`) + if err != nil { + panic(err) + } }, retry: false, errorText: "Unauthorized: botTOKEN", @@ -183,7 +204,11 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { 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"}`) + + _, err := io.WriteString(w, `{"ok":false,"error_code":400,"description":"Bad Request: can't parse"}`) + if err != nil { + panic(err) + } }, retry: false, rejected: true, @@ -193,7 +218,11 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { 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"}`) + + _, err := io.WriteString(w, `{"ok":false,"error_code":404,"description":"Not Found"}`) + if err != nil { + panic(err) + } }, retry: false, rejected: true, @@ -203,7 +232,11 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { name: "not found page of a proxy is not a refusal", reply: func(w http.ResponseWriter) { w.WriteHeader(http.StatusNotFound) - _, _ = io.WriteString(w, "not found") + + _, err := io.WriteString(w, "not found") + if err != nil { + panic(err) + } }, retry: false, errorText: "404 Not Found", @@ -211,7 +244,10 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { { name: "broken answer is retried", reply: func(w http.ResponseWriter) { - _, _ = io.WriteString(w, `{"ok":`) + _, err := io.WriteString(w, `{"ok":`) + if err != nil { + panic(err) + } }, retry: true, errorText: "invalid JSON", @@ -223,6 +259,7 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { tc.reply(w) })) + t.Cleanup(server.Close) err := newTelegramAPI(server.URL, telegramTestToken).SendMessage(t.Context(), telegramTestOwner, "hi", nil)