package paymentapiimp import ( "bytes" "context" "net/http" "net/http/httptest" "testing" "time" "github.com/go-chi/chi/v5" "github.com/tech/sendico/pkg/model" "github.com/tech/sendico/server/interface/api/sresponse" "go.mongodb.org/mongo-driver/v2/bson" ) func TestInitiateByQuote_ForwardsClientPaymentRef(t *testing.T) { orgRef := bson.NewObjectID() exec := &fakeExecutionClientForBatch{} api := newBatchAPI(exec) body := `{"idempotencyKey":"idem-by-quote","quoteRef":"quote-1","clientPaymentRef":"client-ref-1"}` rr := invokeInitiateByQuote(t, api, orgRef, body) if got, want := rr.Code, http.StatusOK; got != want { t.Fatalf("status mismatch: got=%d want=%d body=%s", got, want, rr.Body.String()) } if got, want := len(exec.executeReqs), 1; got != want { t.Fatalf("execute calls mismatch: got=%d want=%d", got, want) } if got, want := exec.executeReqs[0].GetClientPaymentRef(), "client-ref-1"; got != want { t.Fatalf("client_payment_ref mismatch: got=%q want=%q", got, want) } } func TestInitiateByQuote_DoesNotForwardLegacyClientPaymentRefFromMetadata(t *testing.T) { orgRef := bson.NewObjectID() exec := &fakeExecutionClientForBatch{} api := newBatchAPI(exec) body := `{"idempotencyKey":"idem-by-quote","quoteRef":"quote-1","metadata":{"client_payment_ref":"legacy-client-ref"}}` rr := invokeInitiateByQuote(t, api, orgRef, body) if got, want := rr.Code, http.StatusOK; got != want { t.Fatalf("status mismatch: got=%d want=%d body=%s", got, want, rr.Body.String()) } if got, want := len(exec.executeReqs), 1; got != want { t.Fatalf("execute calls mismatch: got=%d want=%d", got, want) } if got := exec.executeReqs[0].GetClientPaymentRef(); got != "" { t.Fatalf("expected empty client_payment_ref, got=%q", got) } } func TestInitiateByQuote_RejectsMetadataIntentRef(t *testing.T) { orgRef := bson.NewObjectID() exec := &fakeExecutionClientForBatch{} api := newBatchAPI(exec) body := `{"idempotencyKey":"idem-by-quote","quoteRef":"quote-1","metadata":{"intent_ref":"legacy-intent"}}` rr := invokeInitiateByQuote(t, api, orgRef, body) if got, want := rr.Code, http.StatusBadRequest; got != want { t.Fatalf("status mismatch: got=%d want=%d body=%s", got, want, rr.Body.String()) } if got := len(exec.executeReqs); got != 0 { t.Fatalf("expected no execute calls, got=%d", got) } } func invokeInitiateByQuote(t *testing.T, api *PaymentAPI, orgRef bson.ObjectID, body string) *httptest.ResponseRecorder { t.Helper() req := httptest.NewRequest(http.MethodPost, "/by-quote", bytes.NewBufferString(body)) routeCtx := chi.NewRouteContext() routeCtx.URLParams.Add("organizations_ref", orgRef.Hex()) req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, routeCtx)) rr := httptest.NewRecorder() handler := api.initiateByQuote(req, &model.Account{}, &sresponse.TokenData{ Token: "token", Expiration: time.Now().UTC().Add(time.Hour), }) handler.ServeHTTP(rr, req) return rr }