197 lines
7.9 KiB
Go
197 lines
7.9 KiB
Go
package handler
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gofrs/uuid/v5"
|
|
"github.com/golang-jwt/jwt/v5"
|
|
"github.com/saveinmed/backend-go/internal/domain"
|
|
"github.com/saveinmed/backend-go/internal/http/middleware"
|
|
)
|
|
|
|
func newAuthedRequest(t *testing.T, method, path string, body *bytes.Buffer, secret []byte, role string, companyID *uuid.UUID) *http.Request {
|
|
t.Helper()
|
|
userID := uuid.Must(uuid.NewV7())
|
|
claims := jwt.MapClaims{
|
|
"sub": userID.String(),
|
|
"role": role,
|
|
"exp": time.Now().Add(time.Hour).Unix(),
|
|
}
|
|
if companyID != nil {
|
|
claims["company_id"] = companyID.String()
|
|
}
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
tokenStr, err := token.SignedString(secret)
|
|
if err != nil {
|
|
t.Fatalf("failed to sign token: %v", err)
|
|
}
|
|
|
|
req := httptest.NewRequest(method, path, body)
|
|
req.Header.Set("Authorization", "Bearer "+tokenStr)
|
|
req.Header.Set("Content-Type", "application/json")
|
|
return req
|
|
}
|
|
|
|
func serveWithAuth(secret []byte, h http.Handler, req *http.Request) *httptest.ResponseRecorder {
|
|
rec := httptest.NewRecorder()
|
|
middleware.RequireAuth(secret)(h).ServeHTTP(rec, req)
|
|
return rec
|
|
}
|
|
|
|
func TestAdminPaymentGatewayConfigHandlers(t *testing.T) {
|
|
handler, repo := newTestHandlerWithRepo()
|
|
repo.gatewayConfigs["stripe"] = domain.PaymentGatewayConfig{
|
|
Provider: "stripe",
|
|
Active: true,
|
|
Credentials: "token",
|
|
Environment: "sandbox",
|
|
Commission: 0.05,
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/payment-gateways/stripe", nil)
|
|
req.SetPathValue("provider", "stripe")
|
|
rec := httptest.NewRecorder()
|
|
handler.GetPaymentGatewayConfig(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", rec.Code)
|
|
}
|
|
if !strings.Contains(rec.Body.String(), `"provider":"stripe"`) {
|
|
t.Fatalf("expected response to contain provider stripe, got %s", rec.Body.String())
|
|
}
|
|
|
|
updatePayload := bytes.NewBufferString(`{"active":true,"credentials":"updated","environment":"prod","commission":0.1}`)
|
|
updateReq := httptest.NewRequest(http.MethodPut, "/api/v1/admin/payment-gateways/stripe", updatePayload)
|
|
updateReq.SetPathValue("provider", "stripe")
|
|
updateRec := httptest.NewRecorder()
|
|
handler.UpdatePaymentGatewayConfig(updateRec, updateReq)
|
|
|
|
if updateRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", updateRec.Code)
|
|
}
|
|
if repo.gatewayConfigs["stripe"].Credentials != "updated" {
|
|
t.Fatalf("expected credentials updated, got %s", repo.gatewayConfigs["stripe"].Credentials)
|
|
}
|
|
|
|
testReq := httptest.NewRequest(http.MethodPost, "/api/v1/admin/payment-gateways/stripe/test", nil)
|
|
testRec := httptest.NewRecorder()
|
|
handler.TestPaymentGateway(testRec, testReq)
|
|
if testRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", testRec.Code)
|
|
}
|
|
}
|
|
|
|
func TestFinancialHandlers_WithAuth(t *testing.T) {
|
|
handler, _ := newTestHandlerWithRepo()
|
|
secret := []byte("test-secret")
|
|
companyID := uuid.Must(uuid.NewV7())
|
|
|
|
docPayload := bytes.NewBufferString(`{"type":"CNPJ","url":"http://example.com/doc.pdf"}`)
|
|
docReq := newAuthedRequest(t, http.MethodPost, "/api/v1/companies/documents", docPayload, secret, "Admin", &companyID)
|
|
docRec := serveWithAuth(secret, http.HandlerFunc(handler.UploadDocument), docReq)
|
|
if docRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", docRec.Code)
|
|
}
|
|
|
|
listReq := newAuthedRequest(t, http.MethodGet, "/api/v1/companies/documents", &bytes.Buffer{}, secret, "Admin", &companyID)
|
|
listRec := serveWithAuth(secret, http.HandlerFunc(handler.GetDocuments), listReq)
|
|
if listRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", listRec.Code)
|
|
}
|
|
|
|
ledgerReq := newAuthedRequest(t, http.MethodGet, "/api/v1/finance/ledger?page=1&page_size=10", &bytes.Buffer{}, secret, "Admin", &companyID)
|
|
ledgerRec := serveWithAuth(secret, http.HandlerFunc(handler.GetLedger), ledgerReq)
|
|
if ledgerRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", ledgerRec.Code)
|
|
}
|
|
|
|
balanceReq := newAuthedRequest(t, http.MethodGet, "/api/v1/finance/balance", &bytes.Buffer{}, secret, "Admin", &companyID)
|
|
balanceRec := serveWithAuth(secret, http.HandlerFunc(handler.GetBalance), balanceReq)
|
|
if balanceRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", balanceRec.Code)
|
|
}
|
|
var balancePayload map[string]int64
|
|
if err := json.Unmarshal(balanceRec.Body.Bytes(), &balancePayload); err != nil {
|
|
t.Fatalf("failed to decode balance: %v", err)
|
|
}
|
|
if balancePayload["balance_cents"] != 100000 {
|
|
t.Fatalf("expected balance 100000, got %d", balancePayload["balance_cents"])
|
|
}
|
|
|
|
withdrawPayload := bytes.NewBufferString(`{"amount_cents":5000,"bank_info":"bank"}`)
|
|
withdrawReq := newAuthedRequest(t, http.MethodPost, "/api/v1/finance/withdrawals", withdrawPayload, secret, "Admin", &companyID)
|
|
withdrawRec := serveWithAuth(secret, http.HandlerFunc(handler.RequestWithdrawal), withdrawReq)
|
|
if withdrawRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", withdrawRec.Code)
|
|
}
|
|
|
|
listWithdrawReq := newAuthedRequest(t, http.MethodGet, "/api/v1/finance/withdrawals", &bytes.Buffer{}, secret, "Admin", &companyID)
|
|
listWithdrawRec := serveWithAuth(secret, http.HandlerFunc(handler.ListWithdrawals), listWithdrawReq)
|
|
if listWithdrawRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", listWithdrawRec.Code)
|
|
}
|
|
}
|
|
|
|
func TestSellerPaymentHandlers(t *testing.T) {
|
|
handler, repo := newTestHandlerWithRepo()
|
|
secret := []byte("test-secret")
|
|
sellerID := uuid.Must(uuid.NewV7())
|
|
repo.sellerAccounts[sellerID] = domain.SellerPaymentAccount{
|
|
SellerID: sellerID,
|
|
Gateway: "stripe",
|
|
Status: "active",
|
|
AccountType: "standard",
|
|
}
|
|
|
|
getReq := newAuthedRequest(t, http.MethodGet, "/api/v1/sellers/"+sellerID.String()+"/payment-config", &bytes.Buffer{}, secret, "Admin", nil)
|
|
getReq.SetPathValue("id", sellerID.String())
|
|
getRec := serveWithAuth(secret, http.HandlerFunc(handler.GetSellerPaymentConfig), getReq)
|
|
if getRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", getRec.Code)
|
|
}
|
|
if !strings.Contains(getRec.Body.String(), `"gateway":"stripe"`) {
|
|
t.Fatalf("expected gateway stripe, got %s", getRec.Body.String())
|
|
}
|
|
|
|
onboardPayload := bytes.NewBufferString(`{"gateway":"stripe"}`)
|
|
onboardReq := newAuthedRequest(t, http.MethodPost, "/api/v1/sellers/"+sellerID.String()+"/onboarding", onboardPayload, secret, "Admin", nil)
|
|
onboardReq.SetPathValue("id", sellerID.String())
|
|
onboardRec := serveWithAuth(secret, http.HandlerFunc(handler.OnboardSeller), onboardReq)
|
|
if onboardRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", onboardRec.Code)
|
|
}
|
|
if !strings.Contains(onboardRec.Body.String(), "onboarding_url") {
|
|
t.Fatalf("expected onboarding_url, got %s", onboardRec.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestPushNotificationHandlers(t *testing.T) {
|
|
handler := newTestHandler()
|
|
secret := []byte("test-secret")
|
|
|
|
registerPayload := bytes.NewBufferString(`{"token":"abc","platform":"web"}`)
|
|
registerReq := newAuthedRequest(t, http.MethodPost, "/api/v1/push/register", registerPayload, secret, "Admin", nil)
|
|
registerRec := serveWithAuth(secret, http.HandlerFunc(handler.RegisterPushToken), registerReq)
|
|
if registerRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", registerRec.Code)
|
|
}
|
|
|
|
unregisterPayload := bytes.NewBufferString(`{"token":"abc"}`)
|
|
unregisterReq := newAuthedRequest(t, http.MethodDelete, "/api/v1/push/unregister", unregisterPayload, secret, "Admin", nil)
|
|
unregisterRec := serveWithAuth(secret, http.HandlerFunc(handler.UnregisterPushToken), unregisterReq)
|
|
if unregisterRec.Code != http.StatusNoContent {
|
|
t.Fatalf("expected status 204, got %d", unregisterRec.Code)
|
|
}
|
|
|
|
testReq := newAuthedRequest(t, http.MethodPost, "/api/v1/push/test", &bytes.Buffer{}, secret, "Admin", nil)
|
|
testRec := serveWithAuth(secret, http.HandlerFunc(handler.TestPushNotification), testReq)
|
|
if testRec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", testRec.Code)
|
|
}
|
|
}
|