test(marketplace): add product review unit tests
This commit is contained in:
parent
22c74e9beb
commit
a40c27bcc9
1 changed files with 222 additions and 0 deletions
222
veza-backend-api/internal/core/marketplace/review_test.go
Normal file
222
veza-backend-api/internal/core/marketplace/review_test.go
Normal 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)
|
||||
}
|
||||
Loading…
Reference in a new issue