//go:build test package square import ( "context" "encoding/json" "net/http" "net/http/httptest" "testing" ) func TestPaymentFromSquare_ElseBranch_SurfacesBrandWithoutCardID(t *testing.T) { p := &sqPayment{ ID: "pay_1", Status: "COMPLETED", TotalMoney: sqMoney{Amount: 5000, Currency: "GBP"}, CardDetails: &sqCardDetails{ Card: sqCard{ ID: "", CardBrand: "VISA", Last4: "4242", }, }, } result := paymentFromSquare(p) if result.CardBrand != "VISA" { t.Errorf("expected CardBrand VISA, got %s", result.CardBrand) } if result.CardLast4 != "4242" { t.Errorf("expected CardLast4 4242, got %s", result.CardLast4) } } func TestPaymentFromSquare_NilCardDetails(t *testing.T) { p := &sqPayment{ ID: "pay_2", Status: "COMPLETED", TotalMoney: sqMoney{Amount: 2500, Currency: "GBP"}, CardDetails: nil, } result := paymentFromSquare(p) if result.CardBrand != "" { t.Errorf("expected empty CardBrand when no card details, got %s", result.CardBrand) } if result.Amount != 2500 { t.Errorf("expected amount 2500, got %d", result.Amount) } } // TestCreateCheckoutHTTP_DeviceOptionsWireShape verifies the terminal checkout // request puts device_id inside checkout.device_options (Square's required // shape), not at the top level. A top-level device_id is rejected with 400 by // Square's real API. func TestCreateCheckoutHTTP_DeviceOptionsWireShape(t *testing.T) { var captured map[string]any srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { t.Errorf("expected POST, got %s", r.Method) } if r.URL.Path != "/v2/terminals/checkouts" { t.Errorf("expected /v2/terminals/checkouts, got %s", r.URL.Path) } if err := json.NewDecoder(r.Body).Decode(&captured); err != nil { t.Errorf("failed to decode request body: %v", err) } w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(`{"checkout":{"id":"chk_test","status":"PENDING","amount_money":{"amount":5000,"currency":"GBP"},"created_at":"2026-07-31T00:00:00Z","updated_at":"2026-07-31T00:00:00Z"}}`)) })) defer srv.Close() hc := &httpClient{baseURL: srv.URL, token: "test-token", http: srv.Client()} _, err := createCheckoutHTTPWithClient(context.Background(), CreateCheckoutReq{ Amount: 5000, Currency: "GBP", IdempotencyKey: "ik-1", DeviceID: "dvc_test", }, hc) if err != nil { t.Fatalf("createCheckoutHTTP failed: %v", err) } checkout, ok := captured["checkout"].(map[string]any) if !ok { t.Fatalf("expected checkout object in body, got %v", captured) } // device_id must NOT be at the top level if _, hasTopLevel := captured["device_id"]; hasTopLevel { t.Errorf("device_id must not be top-level in terminal checkout request: %v", captured) } // device_id must live under checkout.device_options devOpts, ok := checkout["device_options"].(map[string]any) if !ok { t.Fatalf("expected checkout.device_options in body, got %v", checkout) } if devOpts["device_id"] != "dvc_test" { t.Errorf("expected checkout.device_options.device_id = dvc_test, got %v", devOpts) } }