diff --git a/backend/internal/usecase/financial_service_test.go b/backend/internal/usecase/financial_service_test.go new file mode 100644 index 0000000..3c975d5 --- /dev/null +++ b/backend/internal/usecase/financial_service_test.go @@ -0,0 +1,131 @@ +package usecase + +import ( + "context" + "testing" + "time" + + "github.com/gofrs/uuid/v5" + "github.com/saveinmed/backend-go/internal/domain" +) + +func TestGetFormattedLedgerPaginationDefaults(t *testing.T) { + svc, repo := newTestService() + ctx := context.Background() + companyID := uuid.Must(uuid.NewV7()) + + repo.ledgerEntries = []domain.LedgerEntry{ + {ID: uuid.Must(uuid.NewV7()), CompanyID: companyID, AmountCents: 100, Type: "SALE", Description: "Sale 1"}, + {ID: uuid.Must(uuid.NewV7()), CompanyID: companyID, AmountCents: 200, Type: "SALE", Description: "Sale 2"}, + {ID: uuid.Must(uuid.NewV7()), CompanyID: companyID, AmountCents: -50, Type: "FEE", Description: "Fee"}, + } + + resp, err := svc.GetFormattedLedger(ctx, companyID, 0, 0) + if err != nil { + t.Fatalf("failed to get ledger: %v", err) + } + + if resp.CurrentPage != 1 { + t.Errorf("expected CurrentPage 1, got %d", resp.CurrentPage) + } + if resp.TotalPages != 1 { + t.Errorf("expected TotalPages 1, got %d", resp.TotalPages) + } + if resp.TotalCount != 3 { + t.Errorf("expected TotalCount 3, got %d", resp.TotalCount) + } + if len(resp.Items) != 3 { + t.Errorf("expected 3 items, got %d", len(resp.Items)) + } +} + +func TestGetFormattedLedgerPaginationSlicesResults(t *testing.T) { + svc, repo := newTestService() + ctx := context.Background() + companyID := uuid.Must(uuid.NewV7()) + + for i := 0; i < 25; i++ { + repo.ledgerEntries = append(repo.ledgerEntries, domain.LedgerEntry{ + ID: uuid.Must(uuid.NewV7()), + CompanyID: companyID, + AmountCents: int64(100 + i), + Type: "SALE", + Description: "Sale", + CreatedAt: time.Now(), + }) + } + + resp, err := svc.GetFormattedLedger(ctx, companyID, 2, 10) + if err != nil { + t.Fatalf("failed to get ledger: %v", err) + } + + if resp.TotalPages != 3 { + t.Errorf("expected TotalPages 3, got %d", resp.TotalPages) + } + if len(resp.Items) != 10 { + t.Errorf("expected 10 items, got %d", len(resp.Items)) + } + if resp.Items[0].AmountCents != 110 { + t.Errorf("expected first item amount 110, got %d", resp.Items[0].AmountCents) + } +} + +func TestRequestWithdrawalValidatesAmount(t *testing.T) { + svc, repo := newTestService() + ctx := context.Background() + companyID := uuid.Must(uuid.NewV7()) + repo.balance = 100000 + + _, err := svc.RequestWithdrawal(ctx, companyID, 0, "Bank Info") + if err == nil { + t.Error("expected error for zero amount") + } +} + +func TestRequestWithdrawalStoresLedgerAndWithdrawal(t *testing.T) { + svc, repo := newTestService() + ctx := context.Background() + companyID := uuid.Must(uuid.NewV7()) + repo.balance = 90000 + + withdrawal, err := svc.RequestWithdrawal(ctx, companyID, 45000, "Bank Info") + if err != nil { + t.Fatalf("failed to request withdrawal: %v", err) + } + + if len(repo.ledgerEntries) != 1 { + t.Fatalf("expected 1 ledger entry, got %d", len(repo.ledgerEntries)) + } + if repo.ledgerEntries[0].AmountCents != -45000 { + t.Errorf("expected ledger amount -45000, got %d", repo.ledgerEntries[0].AmountCents) + } + if len(repo.withdrawals) != 1 { + t.Fatalf("expected 1 withdrawal, got %d", len(repo.withdrawals)) + } + if withdrawal.ID != repo.withdrawals[0].ID { + t.Errorf("expected withdrawal to be stored in repository") + } +} + +func TestUploadDocumentAndListDocuments(t *testing.T) { + svc, _ := newTestService() + ctx := context.Background() + companyID := uuid.Must(uuid.NewV7()) + + _, err := svc.UploadDocument(ctx, companyID, "CNPJ", "http://example.com/doc.pdf") + if err != nil { + t.Fatalf("failed to upload document: %v", err) + } + + docs, err := svc.GetCompanyDocuments(ctx, companyID) + if err != nil { + t.Fatalf("failed to list documents: %v", err) + } + if len(docs) != 1 { + t.Errorf("expected 1 document, got %d", len(docs)) + } + if docs[0].Type != "CNPJ" { + t.Errorf("expected document type 'CNPJ', got '%s'", docs[0].Type) + } +} diff --git a/backend/internal/usecase/usecase_test.go b/backend/internal/usecase/usecase_test.go index 4bf7678..5c0f139 100644 --- a/backend/internal/usecase/usecase_test.go +++ b/backend/internal/usecase/usecase_test.go @@ -21,6 +21,10 @@ type MockRepository struct { shippingSettings map[uuid.UUID]domain.ShippingSettings paymentConfigs map[string]domain.PaymentGatewayConfig sellerAccounts map[uuid.UUID]domain.SellerPaymentAccount + documents []domain.CompanyDocument + ledgerEntries []domain.LedgerEntry + withdrawals []domain.Withdrawal + balance int64 } func NewMockRepository() *MockRepository { @@ -35,6 +39,10 @@ func NewMockRepository() *MockRepository { shippingSettings: make(map[uuid.UUID]domain.ShippingSettings), paymentConfigs: make(map[string]domain.PaymentGatewayConfig), sellerAccounts: make(map[uuid.UUID]domain.SellerPaymentAccount), + documents: make([]domain.CompanyDocument, 0), + ledgerEntries: make([]domain.LedgerEntry, 0), + withdrawals: make([]domain.Withdrawal, 0), + balance: 100000, } } @@ -330,31 +338,66 @@ func (m *MockRepository) ListShipments(ctx context.Context, filter domain.Shipme // Financial methods func (m *MockRepository) CreateDocument(ctx context.Context, doc *domain.CompanyDocument) error { + if doc != nil { + m.documents = append(m.documents, *doc) + } return nil } func (m *MockRepository) ListDocuments(ctx context.Context, companyID uuid.UUID) ([]domain.CompanyDocument, error) { - return []domain.CompanyDocument{}, nil + docs := make([]domain.CompanyDocument, 0) + for _, doc := range m.documents { + if doc.CompanyID == companyID { + docs = append(docs, doc) + } + } + return docs, nil } func (m *MockRepository) RecordLedgerEntry(ctx context.Context, entry *domain.LedgerEntry) error { + if entry != nil { + m.ledgerEntries = append(m.ledgerEntries, *entry) + } return nil } func (m *MockRepository) GetLedger(ctx context.Context, companyID uuid.UUID, limit, offset int) ([]domain.LedgerEntry, int64, error) { - return []domain.LedgerEntry{}, 0, nil + filtered := make([]domain.LedgerEntry, 0) + for _, entry := range m.ledgerEntries { + if entry.CompanyID == companyID { + filtered = append(filtered, entry) + } + } + total := int64(len(filtered)) + if offset >= len(filtered) { + return []domain.LedgerEntry{}, total, nil + } + end := offset + limit + if end > len(filtered) { + end = len(filtered) + } + return filtered[offset:end], total, nil } func (m *MockRepository) GetBalance(ctx context.Context, companyID uuid.UUID) (int64, error) { - return 100000, nil // Dummy balance + return m.balance, nil } func (m *MockRepository) CreateWithdrawal(ctx context.Context, withdrawal *domain.Withdrawal) error { + if withdrawal != nil { + m.withdrawals = append(m.withdrawals, *withdrawal) + } return nil } func (m *MockRepository) ListWithdrawals(ctx context.Context, companyID uuid.UUID) ([]domain.Withdrawal, error) { - return []domain.Withdrawal{}, nil + filtered := make([]domain.Withdrawal, 0) + for _, withdrawal := range m.withdrawals { + if withdrawal.CompanyID == companyID { + filtered = append(filtered, withdrawal) + } + } + return filtered, nil } // Payment Config methods