package safew import ( "context" "errors" "testing" "time" "aiaa-notification-service/internal/adapter" ) func TestRefreshMergesAndAdvancesOffset(t *testing.T) { st := NewMemStore() poll := func(token string, offset int64, timeout int) ([]adapter.SafewChat, int64, error) { if timeout != 0 { t.Fatalf("timeout=%d", timeout) } if offset != 0 { t.Fatalf("offset=%d", offset) } return []adapter.SafewChat{{ID: "10000778141", Type: "group", Title: "测试AI"}}, 11, nil } w := NewWatcher(st, poll) ctx := context.Background() if err := w.Refresh(ctx, "tok"); err != nil { t.Fatal(err) } list, err := w.List(ctx, "tok", "测试") if err != nil { t.Fatal(err) } if len(list) != 1 || list[0].ID != "10000778141" { t.Fatalf("%#v", list) } off, _ := st.GetSafewOffset(ctx, "tok") if off != 11 { t.Fatalf("offset=%d", off) } } func TestRefreshAuthError(t *testing.T) { st := NewMemStore() w := NewWatcher(st, func(string, int64, int) ([]adapter.SafewChat, int64, error) { return nil, 0, &adapter.SafewAuthError{Description: "BOT_TOKEN_INVALID"} }) err := w.Refresh(context.Background(), "bad") if err == nil { t.Fatal("expected auth error") } if _, ok := err.(*adapter.SafewAuthError); !ok { t.Fatalf("%T", err) } } func TestEnsurePollsInBackground(t *testing.T) { st := NewMemStore() got := make(chan int, 1) w := NewWatcher(st, func(token string, offset int64, timeout int) ([]adapter.SafewChat, int64, error) { if timeout != 30 { return nil, offset, errors.New("not background") } select { case got <- timeout: default: } return []adapter.SafewChat{{ID: "1", Type: "group", Title: "g"}}, offset + 1, nil }) w.bgIdle = 10 * time.Millisecond w.Ensure("tok") select { case <-got: case <-time.After(2 * time.Second): t.Fatal("background poll not called") } w.Stop() }