test(marketplace): add product review unit tests

This commit is contained in:
senke 2026-02-24 00:18:45 +01:00
parent 22c74e9beb
commit a40c27bcc9

View file

@ -0,0 +1,222 @@
package marketplace
import (
"context"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"veza-backend-api/internal/models"
)
func setupReviewTestDB(t *testing.T) *gorm.DB {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
require.NoError(t, err)
require.NoError(t, db.AutoMigrate(
&models.User{},
&Product{},
&Order{},
&OrderItem{},
&License{},
&ProductReview{},
&models.Track{},
))
return db
}
func TestCreateReview_Success(t *testing.T) {
db := setupReviewTestDB(t)
logger := zap.NewNop()
svc := NewService(db, logger, nil)
buyerID := uuid.New()
sellerID := uuid.New()
trackID := uuid.New()
productID := uuid.New()
orderID := uuid.New()
require.NoError(t, db.Create(&models.User{ID: buyerID}).Error)
require.NoError(t, db.Create(&models.User{ID: sellerID}).Error)
require.NoError(t, db.Create(&models.Track{ID: trackID, UserID: sellerID, FilePath: "/test.mp3"}).Error)
require.NoError(t, db.Create(&Product{
ID: productID,
SellerID: sellerID,
Title: "Test Product",
Price: 9.99,
ProductType: "track",
TrackID: &trackID,
Status: ProductStatusActive,
}).Error)
require.NoError(t, db.Create(&Order{
ID: orderID,
BuyerID: buyerID,
Status: "completed",
TotalAmount: 9.99,
Currency: "EUR",
}).Error)
require.NoError(t, db.Create(&OrderItem{
ID: uuid.New(),
OrderID: orderID,
ProductID: productID,
Price: 9.99,
}).Error)
require.NoError(t, db.Create(&License{
BuyerID: buyerID,
TrackID: trackID,
ProductID: productID,
OrderID: orderID,
Type: LicenseBasic,
}).Error)
review, err := svc.CreateReview(context.Background(), productID, buyerID, 5, "Great product!")
require.NoError(t, err)
require.NotNil(t, review)
assert.Equal(t, productID, review.ProductID)
assert.Equal(t, buyerID, review.BuyerID)
assert.Equal(t, 5, review.Rating)
assert.Equal(t, "Great product!", review.Comment)
assert.NotEqual(t, uuid.Nil, review.ID)
}
func TestCreateReview_InvalidRating(t *testing.T) {
db := setupReviewTestDB(t)
logger := zap.NewNop()
svc := NewService(db, logger, nil)
productID := uuid.New()
sellerID := uuid.New()
require.NoError(t, db.Create(&models.User{ID: uuid.New()}).Error)
require.NoError(t, db.Create(&models.User{ID: sellerID}).Error)
require.NoError(t, db.Create(&models.Track{ID: uuid.New(), UserID: sellerID, FilePath: "/t.mp3"}).Error)
require.NoError(t, db.Create(&Product{
ID: productID,
SellerID: sellerID,
Title: "P",
Price: 1,
ProductType: "track",
Status: ProductStatusActive,
}).Error)
_, err := svc.CreateReview(context.Background(), productID, uuid.New(), 0, "bad")
require.Error(t, err)
assert.Contains(t, err.Error(), "rating must be between 1 and 5")
_, err = svc.CreateReview(context.Background(), productID, uuid.New(), 6, "bad")
require.Error(t, err)
assert.Contains(t, err.Error(), "rating must be between 1 and 5")
}
func TestCreateReview_NotPurchased(t *testing.T) {
db := setupReviewTestDB(t)
logger := zap.NewNop()
svc := NewService(db, logger, nil)
buyerID := uuid.New()
sellerID := uuid.New()
trackID := uuid.New()
productID := uuid.New()
require.NoError(t, db.Create(&models.User{ID: buyerID}).Error)
require.NoError(t, db.Create(&models.User{ID: sellerID}).Error)
require.NoError(t, db.Create(&models.Track{ID: trackID, UserID: sellerID, FilePath: "/t.mp3"}).Error)
require.NoError(t, db.Create(&Product{
ID: productID,
SellerID: sellerID,
Title: "P",
Price: 1,
ProductType: "track",
TrackID: &trackID,
Status: ProductStatusActive,
}).Error)
// No order, no license for this buyer
_, err := svc.CreateReview(context.Background(), productID, buyerID, 5, "Great!")
require.Error(t, err)
assert.ErrorIs(t, err, ErrReviewNotPurchased)
}
func TestCreateReview_DuplicateReview(t *testing.T) {
db := setupReviewTestDB(t)
logger := zap.NewNop()
svc := NewService(db, logger, nil)
buyerID := uuid.New()
sellerID := uuid.New()
trackID := uuid.New()
productID := uuid.New()
orderID := uuid.New()
require.NoError(t, db.Create(&models.User{ID: buyerID}).Error)
require.NoError(t, db.Create(&models.User{ID: sellerID}).Error)
require.NoError(t, db.Create(&models.Track{ID: trackID, UserID: sellerID, FilePath: "/t.mp3"}).Error)
require.NoError(t, db.Create(&Product{
ID: productID,
SellerID: sellerID,
Title: "P",
Price: 1,
ProductType: "track",
TrackID: &trackID,
Status: ProductStatusActive,
}).Error)
require.NoError(t, db.Create(&Order{ID: orderID, BuyerID: buyerID, Status: "completed", TotalAmount: 1, Currency: "EUR"}).Error)
require.NoError(t, db.Create(&OrderItem{ID: uuid.New(), OrderID: orderID, ProductID: productID, Price: 1}).Error)
require.NoError(t, db.Create(&License{BuyerID: buyerID, TrackID: trackID, ProductID: productID, OrderID: orderID, Type: LicenseBasic}).Error)
_, err := svc.CreateReview(context.Background(), productID, buyerID, 5, "First")
require.NoError(t, err)
_, err = svc.CreateReview(context.Background(), productID, buyerID, 4, "Second")
require.Error(t, err)
assert.ErrorIs(t, err, ErrReviewAlreadyExists)
}
func TestListReviews_Paginated(t *testing.T) {
db := setupReviewTestDB(t)
logger := zap.NewNop()
svc := NewService(db, logger, nil)
productID := uuid.New()
buyer1 := uuid.New()
buyer2 := uuid.New()
buyer3 := uuid.New()
order1 := uuid.New()
order2 := uuid.New()
order3 := uuid.New()
require.NoError(t, db.Create(&models.User{ID: buyer1}).Error)
require.NoError(t, db.Create(&models.User{ID: buyer2}).Error)
require.NoError(t, db.Create(&models.User{ID: buyer3}).Error)
require.NoError(t, db.Create(&Product{ID: productID, SellerID: uuid.New(), Title: "P", Price: 1, ProductType: "track", Status: ProductStatusActive}).Error)
require.NoError(t, db.Create(&Order{ID: order1, BuyerID: buyer1, Status: "completed", TotalAmount: 1, Currency: "EUR"}).Error)
require.NoError(t, db.Create(&Order{ID: order2, BuyerID: buyer2, Status: "completed", TotalAmount: 1, Currency: "EUR"}).Error)
require.NoError(t, db.Create(&Order{ID: order3, BuyerID: buyer3, Status: "completed", TotalAmount: 1, Currency: "EUR"}).Error)
require.NoError(t, db.Create(&ProductReview{ProductID: productID, BuyerID: buyer1, OrderID: order1, Rating: 5, Comment: "A"}).Error)
require.NoError(t, db.Create(&ProductReview{ProductID: productID, BuyerID: buyer2, OrderID: order2, Rating: 4, Comment: "B"}).Error)
require.NoError(t, db.Create(&ProductReview{ProductID: productID, BuyerID: buyer3, OrderID: order3, Rating: 3, Comment: "C"}).Error)
reviews, err := svc.ListReviews(context.Background(), productID, 2, 0)
require.NoError(t, err)
require.Len(t, reviews, 2)
// Order is created_at DESC; C created last so first in result
assert.Equal(t, 3, reviews[0].Rating)
assert.Equal(t, 4, reviews[1].Rating)
}
func TestListReviews_EmptyProduct(t *testing.T) {
db := setupReviewTestDB(t)
logger := zap.NewNop()
svc := NewService(db, logger, nil)
productID := uuid.New()
require.NoError(t, db.Create(&Product{ID: productID, SellerID: uuid.New(), Title: "P", Price: 1, ProductType: "track", Status: ProductStatusActive}).Error)
reviews, err := svc.ListReviews(context.Background(), productID, 20, 0)
require.NoError(t, err)
require.Empty(t, reviews)
}