saveinmed/backend-old/internal/repository/postgres/repository_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

283 lines
8 KiB
Go

package postgres
import (
"context"
"regexp"
"testing"
"time"
"github.com/DATA-DOG/go-sqlmock"
"github.com/gofrs/uuid/v5"
"github.com/jmoiron/sqlx"
"github.com/saveinmed/backend-go/internal/domain"
"github.com/stretchr/testify/assert"
)
func newMockRepo(t *testing.T) (*Repository, sqlmock.Sqlmock) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
sqlxDB := sqlx.NewDb(db, "sqlmock")
repo := New(sqlxDB)
return repo, mock
}
func TestCreateCompany(t *testing.T) {
repo, mock := newMockRepo(t)
defer repo.db.Close()
company := &domain.Company{
ID: uuid.Must(uuid.NewV7()),
CNPJ: "12345678901234",
CorporateName: "Test Pharmacy",
Category: "farmacia",
LicenseNumber: "123",
IsVerified: false,
Latitude: -10.0,
Longitude: -20.0,
City: "Test City",
State: "TS",
Phone: "(11) 99999-9999",
OperatingHours: "08:00-18:00",
Is24Hours: false,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
query := `INSERT INTO companies`
mock.ExpectExec(regexp.QuoteMeta(query)).
WithArgs(
company.ID,
company.CNPJ,
company.CorporateName,
company.Category,
company.LicenseNumber,
company.IsVerified,
company.Latitude,
company.Longitude,
company.City,
company.State,
company.Phone,
company.OperatingHours,
company.Is24Hours,
sqlmock.AnyArg(), // CreatedAt
sqlmock.AnyArg(), // UpdatedAt
).
WillReturnResult(sqlmock.NewResult(1, 1))
err := repo.CreateCompany(context.Background(), company)
assert.NoError(t, err)
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
}
}
func TestGetCompany(t *testing.T) {
repo, mock := newMockRepo(t)
defer repo.db.Close()
id := uuid.Must(uuid.NewV7())
rows := sqlmock.NewRows([]string{"id", "cnpj", "corporate_name", "category", "license_number", "is_verified", "latitude", "longitude", "city", "state", "created_at", "updated_at"}).
AddRow(id, "123", "Test", "farmacia", "123", false, 0.0, 0.0, "City", "ST", time.Now(), time.Now())
// query := `SELECT .* FROM companies WHERE id = \$1`
// Use explicit regex without QuoteMeta for the wildcard part
mock.ExpectQuery(`SELECT .* FROM companies WHERE id = \$1`).
WithArgs(id).
WillReturnRows(rows)
company, err := repo.GetCompany(context.Background(), id)
assert.NoError(t, err)
if company != nil {
assert.Equal(t, id, company.ID)
} else {
t.Error("expected company to not be nil")
}
}
func TestCreateProduct(t *testing.T) {
repo, mock := newMockRepo(t)
defer repo.db.Close()
product := &domain.Product{
ID: uuid.Must(uuid.NewV7()),
SellerID: uuid.Must(uuid.NewV7()),
EANCode: "7891234567890",
Name: "Test Product",
Description: "Desc",
Manufacturer: "Test Manufacturer",
Category: "medicamento",
Subcategory: "analgésico",
// Batch: "B1", // Removed
// ExpiresAt: time.Now().AddDate(1, 0, 0), // Removed
PriceCents: 1000,
// Stock: 10, // Removed
Observations: "Test observations",
}
query := `INSERT INTO products`
rows := sqlmock.NewRows([]string{"created_at", "updated_at"}).
AddRow(time.Now(), time.Now())
mock.ExpectQuery(regexp.QuoteMeta(query)).
WithArgs(
product.ID,
product.SellerID,
product.EANCode,
product.Name,
product.Description,
product.Manufacturer,
product.Category,
product.Subcategory,
// product.Batch,
// product.ExpiresAt,
product.PriceCents,
// product.Stock,
product.Observations,
).
WillReturnRows(rows)
err := repo.CreateProduct(context.Background(), product)
assert.NoError(t, err)
}
func TestListProducts(t *testing.T) {
repo, mock := newMockRepo(t)
defer repo.db.Close()
rows := sqlmock.NewRows([]string{"id", "name"}).AddRow(uuid.Must(uuid.NewV7()), "P1")
// We expect two queries: count and select list
mock.ExpectQuery(`SELECT count\(\*\) FROM products`).WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1))
mock.ExpectQuery(`SELECT .* FROM products`).WithArgs(10, 0).WillReturnRows(rows)
list, count, err := repo.ListProducts(context.Background(), domain.ProductFilter{Limit: 10})
assert.NoError(t, err)
assert.Equal(t, int64(1), count)
assert.Len(t, list, 1)
}
func TestCreateUser(t *testing.T) {
repo, mock := newMockRepo(t)
defer repo.db.Close()
user := &domain.User{
ID: uuid.Must(uuid.NewV7()),
CompanyID: uuid.Must(uuid.NewV7()),
Role: "Colaborador",
Name: "Test User",
Username: "testuser",
Email: "test@example.com",
PasswordHash: "hashed_password",
}
query := `INSERT INTO users`
mock.ExpectExec(regexp.QuoteMeta(query)).
WithArgs(
user.ID,
user.CompanyID,
user.Role,
user.Name,
user.Username,
user.Email,
user.EmailVerified, // email_verified
user.PasswordHash, // password_hash
sqlmock.AnyArg(), // CreatedAt
sqlmock.AnyArg(), // UpdatedAt
).
WillReturnResult(sqlmock.NewResult(1, 1))
err := repo.CreateUser(context.Background(), user)
assert.NoError(t, err)
}
func TestListUsers(t *testing.T) {
repo, mock := newMockRepo(t)
defer repo.db.Close()
companyID := uuid.Must(uuid.NewV7())
userID := uuid.Must(uuid.NewV7())
rows := sqlmock.NewRows([]string{
"id", "company_id", "role", "name", "username", "email",
"email_verified", "password_hash", "created_at", "updated_at",
}).AddRow(
userID, companyID, "Owner", "Test", "test", "test@test.com",
true, "hash", time.Now(), time.Now(),
)
mock.ExpectQuery(`SELECT count\(\*\) FROM users`).
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1))
mock.ExpectQuery(`SELECT .* FROM users`).
WithArgs(20, 0).
WillReturnRows(rows)
list, count, err := repo.ListUsers(context.Background(), domain.UserFilter{Limit: 20})
assert.NoError(t, err)
assert.Equal(t, int64(1), count)
assert.Len(t, list, 1)
}
func TestListOrders(t *testing.T) {
repo, mock := newMockRepo(t)
defer repo.db.Close()
orderID := uuid.Must(uuid.NewV7())
buyerID := uuid.Must(uuid.NewV7())
sellerID := uuid.Must(uuid.NewV7())
rows := sqlmock.NewRows([]string{
"id", "buyer_id", "seller_id", "status", "total_cents", "payment_method",
"shipping_recipient_name", "shipping_street", "shipping_number", "shipping_complement",
"shipping_district", "shipping_city", "shipping_state", "shipping_zip_code",
"shipping_country", "created_at", "updated_at",
}).AddRow(
orderID, buyerID, sellerID, "Pendente", 10000, "pix",
"Test User", "Test Street", "123", "", "Centro", "City", "ST", "12345-678", "Brasil",
time.Now(), time.Now(),
)
mock.ExpectQuery(`SELECT count\(\*\) FROM orders`).
WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1))
mock.ExpectQuery(`SELECT .* FROM orders`).
WithArgs(20, 0).
WillReturnRows(rows)
// Expect query for order items
mock.ExpectQuery(`SELECT .* FROM order_items WHERE order_id`).
WithArgs(orderID).
WillReturnRows(sqlmock.NewRows([]string{"id", "order_id", "product_id", "quantity", "unit_cents", "batch", "expires_at"}))
list, count, err := repo.ListOrders(context.Background(), domain.OrderFilter{Limit: 20})
assert.NoError(t, err)
assert.Equal(t, int64(1), count)
assert.Len(t, list, 1)
}
func TestGetShippingSettings(t *testing.T) {
repo, mock := newMockRepo(t)
defer repo.db.Close()
vendorID := uuid.Must(uuid.NewV7())
rows := sqlmock.NewRows([]string{
"vendor_id", "active", "max_radius_km", "price_per_km_cents", "min_fee_cents",
"free_shipping_threshold_cents", "pickup_active", "pickup_address", "pickup_hours",
"latitude", "longitude", "created_at", "updated_at",
}).AddRow(
vendorID, true, 50.0, 150, 1000, nil, true, "Rua Test, 123", "08:00-18:00",
-23.55, -46.63, time.Now(), time.Now(),
)
mock.ExpectQuery(`SELECT \* FROM shipping_settings WHERE vendor_id`).
WithArgs(vendorID).
WillReturnRows(rows)
settings, err := repo.GetShippingSettings(context.Background(), vendorID)
assert.NoError(t, err)
assert.NotNil(t, settings)
assert.Equal(t, vendorID, settings.VendorID)
assert.True(t, settings.Active)
}