saveinmed/backend-old/internal/usecase/product_service_test.go
NANDO9322 e8c29877de feat(produto): implementação do fluxo de cadastro e gestão de estoque
Backend:
- Adição das migrações SQL 0012 e 0013 para estrutura de produtos e itens de estoque.
- Implementação do método [CreateInventoryItem](cci:1://file:///c:/Projetos/saveinmed/backend-old/internal/http/handler/handler_test.go:168:0-170:1) no repositório Postgres e mocks de teste.
- Atualização do [product_handler.go](cci:7://file:///c:/Projetos/saveinmed/backend-old/internal/http/handler/product_handler.go:0:0-0:0) para suportar `original_price_cents` e corrigir filtragem de estoque.
- Mapeamento da rota GET `/api/v1/produtos-venda` no [server.go](cci:7://file:///c:/Projetos/saveinmed/backend-old/internal/server/server.go:0:0-0:0).
- Ajuste no endpoint `/auth/me` para retornar `empresasDados` (ID da empresa) necessário ao frontend.
- Refatoração da query [ListInventory](cci:1://file:///c:/Projetos/saveinmed/backend-old/internal/repository/postgres/postgres.go:771:0-805:1) para buscar da tabela correta e incluir nome do produto.

Frontend:
- Correção no mapeamento de dados (snake_case para camelCase) na página de Gestão de Produtos.
- Ajustes de integração no Wizard de Cadastro de Produtos (`CadastroProdutoWizard.tsx`).
- Atualização da tipagem para exibir corretamente preços e estoque a partir da API.
2026-01-22 18:59:21 -03:00

132 lines
4.1 KiB
Go

package usecase
import (
"context"
"errors"
"strings"
"testing"
"time"
"github.com/gofrs/uuid/v5"
"github.com/saveinmed/backend-go/internal/domain"
)
type failingBatchRepo struct {
*MockRepository
}
func (f *failingBatchRepo) BatchCreateProducts(ctx context.Context, products []domain.Product) error {
return errors.New("boom")
}
func (f *failingBatchRepo) CreateInventoryItem(ctx context.Context, item *domain.InventoryItem) error {
return errors.New("boom")
}
func TestImportProductsSuccess(t *testing.T) {
repo := NewMockRepository()
svc := NewService(repo, &MockPaymentGateway{}, &MockNotificationService{}, 2.5, "secret", time.Hour, "pepper")
csvData := strings.NewReader("name,price,stock,description,ean\nAspirin,12.5,5,Anti-inflammatory,123\nIbuprofen,10,0,,\n")
sellerID := uuid.Must(uuid.NewV7())
report, err := svc.ImportProducts(context.Background(), sellerID, csvData)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if report.TotalProcessed != 2 {
t.Fatalf("expected total processed 2, got %d", report.TotalProcessed)
}
if report.SuccessCount != 2 {
t.Fatalf("expected success count 2, got %d", report.SuccessCount)
}
if report.FailedCount != 0 {
t.Fatalf("expected failed count 0, got %d", report.FailedCount)
}
if len(repo.products) != 2 {
t.Fatalf("expected 2 products, got %d", len(repo.products))
}
if repo.products[0].SellerID != sellerID {
t.Errorf("expected seller ID %s, got %s", sellerID, repo.products[0].SellerID)
}
if repo.products[0].PriceCents != 1250 {
t.Errorf("expected price cents 1250, got %d", repo.products[0].PriceCents)
}
// Stock check removed (Dictionary Mode)
}
func TestImportProductsMissingHeaders(t *testing.T) {
repo := NewMockRepository()
svc := NewService(repo, &MockPaymentGateway{}, &MockNotificationService{}, 2.5, "secret", time.Hour, "pepper")
csvData := strings.NewReader("ean,stock\n123,5\n")
_, err := svc.ImportProducts(context.Background(), uuid.Must(uuid.NewV7()), csvData)
if err == nil {
t.Fatal("expected error for missing headers")
}
if !strings.Contains(err.Error(), "missing required header") {
t.Fatalf("expected missing header error, got %v", err)
}
}
func TestImportProductsEmptyCSV(t *testing.T) {
repo := NewMockRepository()
svc := NewService(repo, &MockPaymentGateway{}, &MockNotificationService{}, 2.5, "secret", time.Hour, "pepper")
csvData := strings.NewReader("name,price\n")
_, err := svc.ImportProducts(context.Background(), uuid.Must(uuid.NewV7()), csvData)
if err == nil {
t.Fatal("expected error for empty CSV")
}
if !strings.Contains(err.Error(), "csv file is empty") {
t.Fatalf("expected empty csv error, got %v", err)
}
}
func TestImportProductsInvalidRows(t *testing.T) {
repo := NewMockRepository()
svc := NewService(repo, &MockPaymentGateway{}, &MockNotificationService{}, 2.5, "secret", time.Hour, "pepper")
csvData := strings.NewReader("name,price,stock\n,12.5,5\nValid,abc,2\nGood,5,1\n")
sellerID := uuid.Must(uuid.NewV7())
report, err := svc.ImportProducts(context.Background(), sellerID, csvData)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if report.TotalProcessed != 3 {
t.Fatalf("expected total processed 3, got %d", report.TotalProcessed)
}
if report.FailedCount != 2 {
t.Fatalf("expected failed count 2, got %d", report.FailedCount)
}
if report.SuccessCount != 1 {
t.Fatalf("expected success count 1, got %d", report.SuccessCount)
}
if len(report.Errors) != 2 {
t.Fatalf("expected 2 errors, got %d", len(report.Errors))
}
if len(repo.products) != 1 {
t.Fatalf("expected 1 product, got %d", len(repo.products))
}
}
func TestImportProductsBatchInsertFailure(t *testing.T) {
baseRepo := NewMockRepository()
repo := &failingBatchRepo{MockRepository: baseRepo}
svc := NewService(repo, &MockPaymentGateway{}, &MockNotificationService{}, 2.5, "secret", time.Hour, "pepper")
csvData := strings.NewReader("name,price\nItem,12.5\n")
_, err := svc.ImportProducts(context.Background(), uuid.Must(uuid.NewV7()), csvData)
if err == nil {
t.Fatal("expected batch insert error")
}
if !strings.Contains(err.Error(), "batch insert failed") {
t.Fatalf("expected batch insert error, got %v", err)
}
}