package igw_test import ( "context" "encoding/json" "net/http" "net/http/httptest" "testing" "time" "git.zetit.ru/zuevav/Bridge-and-Join-s/internal/nsdadapter/igw" ) func TestSendPackageHappyPath(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/api/package/TEST3/file" { t.Errorf("неожиданный путь %q", r.URL.Path) } w.WriteHeader(http.StatusOK) _ = json.NewEncoder(w).Encode(map[string]string{"package_id": "pkg-123"}) })) defer srv.Close() c := igw.NewClient(srv.URL, igw.WithRetry(0, time.Millisecond)) id, err := c.SendPackage(context.Background(), "TEST3", "#M2MTR", []byte("")) if err != nil { t.Fatal(err) } if id != "pkg-123" { t.Errorf("package_id = %q, ожидалось %q", id, "pkg-123") } } func TestSendPackageRetryOn500(t *testing.T) { calls := 0 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { calls++ if calls < 2 { w.WriteHeader(http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) _ = json.NewEncoder(w).Encode(map[string]string{"package_id": "pkg-retry"}) })) defer srv.Close() c := igw.NewClient(srv.URL, igw.WithRetry(3, time.Millisecond)) id, err := c.SendPackage(context.Background(), "TEST3", "#M2MTR", []byte("x")) if err != nil { t.Fatal(err) } if id != "pkg-retry" { t.Errorf("ожидалось pkg-retry, получено %q", id) } if calls < 2 { t.Errorf("ожидалось хотя бы 2 попытки, получено %d", calls) } } func TestSendPackage4xxNoRetry(t *testing.T) { calls := 0 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { calls++ w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(`{"error":"bad"}`)) })) defer srv.Close() c := igw.NewClient(srv.URL, igw.WithRetry(3, time.Millisecond)) _, err := c.SendPackage(context.Background(), "TEST3", "#M2MTR", []byte("x")) if err == nil { t.Fatal("ожидалась ошибка на 400") } if calls != 1 { t.Errorf("4xx не должен ретраиться, попыток = %d", calls) } } func TestGetStatus(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/api/package/status/pkg-1" { t.Errorf("неожиданный путь %q", r.URL.Path) } w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"package_id":"pkg-1","state":"delivered","updated_at":"2026-03-02T14:30:00Z"}`)) })) defer srv.Close() c := igw.NewClient(srv.URL, igw.WithRetry(0, time.Millisecond)) st, err := c.GetStatus(context.Background(), "pkg-1") if err != nil { t.Fatal(err) } if st.State != "delivered" { t.Errorf("state = %q, ожидалось delivered", st.State) } } func TestListIncoming(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if !contains(r.URL.RawQuery, "channel=TEST3") { t.Errorf("в query нет channel: %s", r.URL.RawQuery) } w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"items":[{"package_id":"p1","package_type":"#M2MTD","channel":"TEST3","received_at":"2026-03-02T14:00:00Z","body":""}]}`)) })) defer srv.Close() c := igw.NewClient(srv.URL, igw.WithRetry(0, time.Millisecond)) pkgs, err := c.ListIncoming(context.Background(), "TEST3", time.Now().Add(-time.Hour), "#M2MTD") if err != nil { t.Fatal(err) } if len(pkgs) != 1 || pkgs[0].PackageType != "#M2MTD" { t.Errorf("неожиданный результат: %+v", pkgs) } body, err := pkgs[0].DecodeBody() if err != nil { t.Errorf("DecodeBody: %v", err) } if body != nil { t.Errorf("ожидалось пустое тело") } } func contains(s, substr string) bool { return len(s) >= len(substr) && (indexOf(s, substr) >= 0) } func indexOf(s, substr string) int { for i := 0; i+len(substr) <= len(s); i++ { if s[i:i+len(substr)] == substr { return i } } return -1 }