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.NewV4()), CNPJ: "12345678901234", CorporateName: "Test Pharmacy", Category: "farmacia", LicenseNumber: "123", IsVerified: false, Latitude: -10.0, Longitude: -20.0, City: "Test City", State: "TS", 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.CreatedAt, company.UpdatedAt, ). WillReturnResult(sqlmock.NewResult(1, 1)) err := repo.CreateCompany(context.Background(), company) assert.NoError(t, err) if err := mock.ExpectationsMet(); 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.NewV4()) 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` mock.ExpectQuery(regexp.QuoteMeta(query)). WithArgs(id). WillReturnRows(rows) company, err := repo.GetCompany(context.Background(), id) assert.NoError(t, err) assert.NotNil(t, company) assert.Equal(t, id, company.ID) } func TestCreateProduct(t *testing.T) { repo, mock := newMockRepo(t) defer repo.db.Close() product := &domain.Product{ ID: uuid.Must(uuid.NewV4()), SellerID: uuid.Must(uuid.NewV4()), Name: "Test Product", Description: "Desc", Batch: "B1", PriceCents: 1000, Stock: 10, } 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.Name, product.Description, product.Batch, product.ExpiresAt, product.PriceCents, product.Stock, ). 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() query := `SELECT .* FROM products` rows := sqlmock.NewRows([]string{"id", "name"}).AddRow(uuid.Must(uuid.NewV4()), "P1") // We expect two queries: count and select list mock.ExpectQuery(`SELECT count\(\*\) FROM products`).WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1)) mock.ExpectQuery(regexp.QuoteMeta(query)).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) }