Ctrl K
ComunidadGuías…

internal/rest/consumer_scope_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package rest_test

import (
	"context"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"github.com/go-chi/chi/v5"

	"github.com/sarathsp06/sparrow/internal/middleware"
	"github.com/sarathsp06/sparrow/internal/rest"
	"github.com/sarathsp06/sparrow/internal/webhooks"
	"github.com/sarathsp06/sparrow/internal/webhooks/store"
)

// scopeRecorder records the consumer scope each batch-job and attempts call
// receives; every other method panics via the nil embedded interface.
type scopeRecorder struct {
	webhooks.WebhookServiceInterface
	scopes    []webhooks.BatchScope
	consumers []string
}

func (s *scopeRecorder) job(scope webhooks.BatchScope) (*store.BatchJob, error) {
	s.scopes = append(s.scopes, scope)
	return &store.BatchJob{JobType: store.BatchTypeDeliveryRetry, Status: store.BatchStatusPending}, nil
}

func (s *scopeRecorder) GetRetryStatus(_ context.Context, scope webhooks.BatchScope, _ string) (*store.BatchJob, error) {
	return s.job(scope)
}

func (s *scopeRecorder) GetRepushStatus(_ context.Context, scope webhooks.BatchScope, _ string) (*store.BatchJob, error) {
	return s.job(scope)
}

func (s *scopeRecorder) CancelRetry(_ context.Context, scope webhooks.BatchScope, _ string) error {
	_, err := s.job(scope)
	return err
}

func (s *scopeRecorder) RetryDeliveries(_ context.Context, scope webhooks.BatchScope, _ string) error {
	_, err := s.job(scope)
	return err
}

func (s *scopeRecorder) GetDeliveryAttempts(_ context.Context, _ string, consumer string) ([]*store.WebhookHealthEvent, error) {
	s.consumers = append(s.consumers, consumer)
	return nil, nil
}

// Portal requests reach batch jobs and attempts pinned to the token's consumer
// and limited to it; tenant-wide /v1 requests keep the path consumer and may
// also reach all-consumers jobs.
func TestBatchJobsAndAttemptsCarryTheConsumerScope(t *testing.T) {
	svc := &scopeRecorder{}
	r := chi.NewRouter()
	rest.Mount(r, svc, rest.AccessDeps{}, rest.AIDeps{}, nil)
	portal := middleware.PortalGateway(func(context.Context, string) (string, error) { return "acme", nil }, middleware.PortalOptions{Retry: true}, r)
	const id = "11111111-1111-1111-1111-111111111111"

	send := func(h http.Handler, method, path, body, token string) {
		t.Helper()
		req := httptest.NewRequest(method, path, strings.NewReader(body))
		req.Header.Set("Content-Type", "application/json")
		if token != "" {
			req.Header.Set("Authorization", "Bearer "+token)
		}
		rec := httptest.NewRecorder()
		h.ServeHTTP(rec, req)
		if rec.Code >= 300 {
			t.Fatalf("%s %s = %d %s", method, path, rec.Code, rec.Body)
		}
	}

	send(portal, http.MethodGet, "/portal/api/retry-jobs/"+id, "", "t")
	send(portal, http.MethodPost, "/portal/api/retry-jobs/"+id+":cancel", "", "t")
	send(portal, http.MethodPost, "/portal/api/deliveries:retryBatch", `{"retry_id":"`+id+`"}`, "t")
	for i, got := range svc.scopes {
		if want := (webhooks.BatchScope{Consumer: "acme", ConsumerOnly: true}); got != want {
			t.Fatalf("portal call %d scope = %+v, want %+v", i, got, want)
		}
	}

	svc.scopes = nil
	send(r, http.MethodGet, "/v1/consumers/globex/retry-jobs/"+id, "", "")
	if want := (webhooks.BatchScope{Consumer: "globex"}); len(svc.scopes) != 1 || svc.scopes[0] != want {
		t.Fatalf("tenant-wide scope = %+v, want %+v", svc.scopes, want)
	}

	send(portal, http.MethodGet, "/portal/api/deliveries/"+id+"/attempts", "", "t")
	send(r, http.MethodGet, "/v1/consumers/globex/deliveries/"+id+"/attempts", "", "")
	send(r, http.MethodGet, "/v1/deliveries/"+id+"/attempts", "", "")
	if want := []string{"acme", "globex", ""}; strings.Join(svc.consumers, ",") != strings.Join(want, ",") {
		t.Fatalf("attempts consumers = %q, want %q", svc.consumers, want)
	}
}