test: reach complete unit coverage
This commit is contained in:
1 parent
8633246eff
commit
fafb6f47b9
123 files changed
+11689
-822
No files matched your search
@@ -0,0 +1,160 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/open-dingtalk/dingtalk-stream-sdk-go/chatbot"
|
||||
)
|
||||
|
||||
func TestAICardAccessTokenRemainingEdges(t *testing.T) {
|
||||
originalBase := dingtalkCardAPIBase
|
||||
defer func() { dingtalkCardAPIBase = originalBase }()
|
||||
|
||||
client := newAICardClient("client", "secret", "template")
|
||||
client.httpClient = &http.Client{Transport: mailRoundTripFunc(func(*http.Request) (*http.Response, error) {
|
||||
return nil, errors.New("transport")
|
||||
})}
|
||||
dingtalkCardAPIBase = "https://api.invalid"
|
||||
if _, err := client.accessToken(context.Background()); err == nil {
|
||||
t.Fatal("token transport error returned nil")
|
||||
}
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
status int
|
||||
body string
|
||||
ok bool
|
||||
}{
|
||||
{"http", http.StatusInternalServerError, "failure", false},
|
||||
{"invalid-json", http.StatusOK, "{", false},
|
||||
{"empty-token", http.StatusOK, `{}`, false},
|
||||
{"default-expiry", http.StatusOK, `{"accessToken":"token","expireIn":0}`, true},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(tc.status)
|
||||
_, _ = w.Write([]byte(tc.body))
|
||||
}))
|
||||
defer server.Close()
|
||||
dingtalkCardAPIBase = server.URL
|
||||
client := newAICardClient("client", "secret", "template")
|
||||
got, err := client.accessToken(context.Background())
|
||||
if tc.ok && (err != nil || got != "token") {
|
||||
t.Fatalf("token=%q err=%v", got, err)
|
||||
}
|
||||
if !tc.ok && err == nil {
|
||||
t.Fatal("error case returned nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAICardCallRawAndCheckedRemainingEdges(t *testing.T) {
|
||||
originalBase := dingtalkCardAPIBase
|
||||
defer func() { dingtalkCardAPIBase = originalBase }()
|
||||
cached := func() *aiCardClient {
|
||||
c := newAICardClient("client", "secret", "template")
|
||||
c.token = "token"
|
||||
c.tokenExp = time.Now().Add(time.Hour)
|
||||
return c
|
||||
}
|
||||
|
||||
c := cached()
|
||||
if _, err := c.callRaw(context.Background(), http.MethodPost, "/path", map[string]any{"bad": make(chan int)}); err == nil {
|
||||
t.Fatal("payload marshal error returned nil")
|
||||
}
|
||||
dingtalkCardAPIBase = "%"
|
||||
if _, err := newAICardClient("client", "secret", "template").callRaw(context.Background(), http.MethodGet, "/path", nil); err == nil {
|
||||
t.Fatal("access token error returned nil")
|
||||
}
|
||||
if _, err := cached().callRaw(context.Background(), http.MethodGet, "/path", nil); err == nil {
|
||||
t.Fatal("request construction error returned nil")
|
||||
}
|
||||
if err := cached().callChecked(context.Background(), http.MethodGet, "/path", nil); err == nil {
|
||||
t.Fatal("checked transport error returned nil")
|
||||
}
|
||||
|
||||
dingtalkCardAPIBase = "https://api.invalid"
|
||||
c = cached()
|
||||
c.httpClient = &http.Client{Transport: mailRoundTripFunc(func(*http.Request) (*http.Response, error) {
|
||||
return nil, errors.New("transport")
|
||||
})}
|
||||
if _, err := c.callRaw(context.Background(), http.MethodGet, "/path", nil); err == nil {
|
||||
t.Fatal("call transport error returned nil")
|
||||
}
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
_, _ = w.Write([]byte(`{"success":false,"errorMsg":"bad"}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
dingtalkCardAPIBase = server.URL
|
||||
if err := cached().callChecked(context.Background(), http.MethodPost, "/deliver", nil); err == nil {
|
||||
t.Fatal("business failure returned nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAICardDeliveryStreamingAndSleepEdges(t *testing.T) {
|
||||
recorder, server := newCardAPIServer(t)
|
||||
withCardAPIBase(t, server.URL)
|
||||
c := newAICardClient("client", "secret", defaultAICardTemplateID)
|
||||
recorder.fail["POST /v1.0/card/instances/deliver"] = 500
|
||||
if _, err := c.createAndDeliver(context.Background(), groupCallback()); err == nil {
|
||||
t.Fatal("deliver error returned nil")
|
||||
}
|
||||
recorder.fail = map[string]int{}
|
||||
if _, err := c.createAndDeliver(context.Background(), &chatbot.BotCallbackDataModel{}); err == nil {
|
||||
t.Fatal("one-to-one missing sender returned nil")
|
||||
}
|
||||
|
||||
long := strings.Repeat("界", aiCardMaxContent+1)
|
||||
if err := c.streamingUpdate(context.Background(), &aiCardInstance{outTrackID: "track"}, long, false, false); err != nil {
|
||||
t.Fatalf("long streaming update: %v", err)
|
||||
}
|
||||
if err := sleepCtx(context.Background(), time.Nanosecond); err != nil {
|
||||
t.Fatalf("timer sleep: %v", err)
|
||||
}
|
||||
|
||||
originalGap := aiCardFrameGap
|
||||
aiCardFrameGap = time.Hour
|
||||
defer func() { aiCardFrameGap = originalGap }()
|
||||
cancelled, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
if err := c.finalize(cancelled, &aiCardInstance{outTrackID: "track"}, "content"); !errors.Is(err, context.Canceled) {
|
||||
t.Fatalf("finalize cancel=%v", err)
|
||||
}
|
||||
|
||||
finishCtx := context.Background()
|
||||
finishServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
_, _ = w.Write([]byte(`{}`))
|
||||
}))
|
||||
defer finishServer.Close()
|
||||
dingtalkCardAPIBase = finishServer.URL
|
||||
finishClient := newAICardClient("client", "secret", "template")
|
||||
finishClient.token, finishClient.tokenExp = "token", time.Now().Add(time.Hour)
|
||||
originalSleep := aiCardSleepCtx
|
||||
aiCardSleepCtx = func(context.Context, time.Duration) error { return context.Canceled }
|
||||
defer func() { aiCardSleepCtx = originalSleep }()
|
||||
if err := finishClient.finish(finishCtx, &aiCardInstance{outTrackID: "track", inputing: true}, "content"); !errors.Is(err, context.Canceled) {
|
||||
t.Fatalf("finish cancel=%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCardMarkdownRemainingEdges(t *testing.T) {
|
||||
table := "intro\n| A | B |\n|---|---|\nend"
|
||||
if got := ensureCardTableBlankLines(table); !strings.Contains(got, "intro\n\n| A") {
|
||||
t.Fatalf("table normalization=%q", got)
|
||||
}
|
||||
input := "plain\nnext\n> quote one\n> quote two\nafter\n```go\ncode\n```\n\n- item"
|
||||
got := fixCardNewlines(input)
|
||||
for _, want := range []string{"plain<br>next", "> quote one<br>quote two", "```go\ncode\n```", "\n- item"} {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Fatalf("normalized output missing %q: %q", want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user