181 lines
5.7 KiB
Go
181 lines
5.7 KiB
Go
package processor
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"apskel-pos-be/internal/models"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
)
|
|
|
|
// Mock repositories for testing
|
|
type MockProductRepository struct {
|
|
mock.Mock
|
|
}
|
|
|
|
type MockCategoryRepository struct {
|
|
mock.Mock
|
|
}
|
|
|
|
type MockProductVariantRepository struct {
|
|
mock.Mock
|
|
}
|
|
|
|
type MockInventoryRepository struct {
|
|
mock.Mock
|
|
}
|
|
|
|
type MockOutletRepository struct {
|
|
mock.Mock
|
|
}
|
|
|
|
// Test helper functions
|
|
func TestCreateProductWithInventory(t *testing.T) {
|
|
// This is a basic test structure - in a real implementation,
|
|
// you would use a proper testing framework with database mocks
|
|
|
|
t.Run("should create product with inventory when create_inventory is true", func(t *testing.T) {
|
|
// Arrange
|
|
productRepo := &MockProductRepository{}
|
|
categoryRepo := &MockCategoryRepository{}
|
|
productVariantRepo := &MockProductVariantRepository{}
|
|
inventoryRepo := &MockInventoryRepository{}
|
|
outletRepo := &MockOutletRepository{}
|
|
|
|
processor := NewProductProcessorImpl(
|
|
productRepo,
|
|
categoryRepo,
|
|
productVariantRepo,
|
|
inventoryRepo,
|
|
outletRepo,
|
|
)
|
|
|
|
req := &models.CreateProductRequest{
|
|
OrganizationID: uuid.New(),
|
|
CategoryID: uuid.New(),
|
|
Name: "Test Product",
|
|
Price: 10.0,
|
|
Cost: 5.0,
|
|
InitialStock: &[]int{100}[0],
|
|
ReorderLevel: &[]int{20}[0],
|
|
CreateInventory: true,
|
|
}
|
|
|
|
// Mock expectations
|
|
categoryRepo.On("GetByID", mock.Anything, req.CategoryID).Return(&models.Category{}, nil)
|
|
productRepo.On("ExistsBySKU", mock.Anything, req.OrganizationID, mock.Anything, mock.Anything).Return(false, nil)
|
|
productRepo.On("ExistsByName", mock.Anything, req.OrganizationID, req.Name, mock.Anything).Return(false, nil)
|
|
productRepo.On("Create", mock.Anything, mock.Anything).Return(nil)
|
|
productRepo.On("GetWithCategory", mock.Anything, mock.Anything).Return(&models.Product{}, nil)
|
|
|
|
// Mock outlets
|
|
outlets := []*models.Outlet{
|
|
{ID: uuid.New()},
|
|
{ID: uuid.New()},
|
|
}
|
|
outletRepo.On("GetByOrganizationID", mock.Anything, req.OrganizationID).Return(outlets, nil)
|
|
|
|
// Mock inventory creation
|
|
inventoryRepo.On("BulkCreate", mock.Anything, mock.Anything).Return(nil)
|
|
|
|
// Act
|
|
result, err := processor.CreateProduct(context.Background(), req)
|
|
|
|
// Assert
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, result)
|
|
|
|
// Verify that inventory was created
|
|
inventoryRepo.AssertCalled(t, "BulkCreate", mock.Anything, mock.Anything)
|
|
outletRepo.AssertCalled(t, "GetByOrganizationID", mock.Anything, req.OrganizationID)
|
|
})
|
|
|
|
t.Run("should not create inventory when create_inventory is false", func(t *testing.T) {
|
|
// Arrange
|
|
productRepo := &MockProductRepository{}
|
|
categoryRepo := &MockCategoryRepository{}
|
|
productVariantRepo := &MockProductVariantRepository{}
|
|
inventoryRepo := &MockInventoryRepository{}
|
|
outletRepo := &MockOutletRepository{}
|
|
|
|
processor := NewProductProcessorImpl(
|
|
productRepo,
|
|
categoryRepo,
|
|
productVariantRepo,
|
|
inventoryRepo,
|
|
outletRepo,
|
|
)
|
|
|
|
req := &models.CreateProductRequest{
|
|
OrganizationID: uuid.New(),
|
|
CategoryID: uuid.New(),
|
|
Name: "Test Product",
|
|
Price: 10.0,
|
|
Cost: 5.0,
|
|
CreateInventory: false,
|
|
}
|
|
|
|
// Mock expectations
|
|
categoryRepo.On("GetByID", mock.Anything, req.CategoryID).Return(&models.Category{}, nil)
|
|
productRepo.On("ExistsBySKU", mock.Anything, req.OrganizationID, mock.Anything, mock.Anything).Return(false, nil)
|
|
productRepo.On("ExistsByName", mock.Anything, req.OrganizationID, req.Name, mock.Anything).Return(false, nil)
|
|
productRepo.On("Create", mock.Anything, mock.Anything).Return(nil)
|
|
productRepo.On("GetWithCategory", mock.Anything, mock.Anything).Return(&models.Product{}, nil)
|
|
|
|
// Act
|
|
result, err := processor.CreateProduct(context.Background(), req)
|
|
|
|
// Assert
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, result)
|
|
|
|
// Verify that inventory was NOT created
|
|
inventoryRepo.AssertNotCalled(t, "BulkCreate", mock.Anything, mock.Anything)
|
|
outletRepo.AssertNotCalled(t, "GetByOrganizationID", mock.Anything, mock.Anything)
|
|
})
|
|
}
|
|
|
|
// Mock implementations (simplified for testing)
|
|
func (m *MockProductRepository) Create(ctx context.Context, product *models.Product) error {
|
|
args := m.Called(ctx, product)
|
|
return args.Error(0)
|
|
}
|
|
|
|
func (m *MockProductRepository) GetByID(ctx context.Context, id uuid.UUID) (*models.Product, error) {
|
|
args := m.Called(ctx, id)
|
|
return args.Get(0).(*models.Product), args.Error(1)
|
|
}
|
|
|
|
func (m *MockProductRepository) GetWithCategory(ctx context.Context, id uuid.UUID) (*models.Product, error) {
|
|
args := m.Called(ctx, id)
|
|
return args.Get(0).(*models.Product), args.Error(1)
|
|
}
|
|
|
|
func (m *MockProductRepository) ExistsBySKU(ctx context.Context, organizationID uuid.UUID, sku string, excludeID *uuid.UUID) (bool, error) {
|
|
args := m.Called(ctx, organizationID, sku, excludeID)
|
|
return args.Bool(0), args.Error(1)
|
|
}
|
|
|
|
func (m *MockProductRepository) ExistsByName(ctx context.Context, organizationID uuid.UUID, name string, excludeID *uuid.UUID) (bool, error) {
|
|
args := m.Called(ctx, organizationID, name, excludeID)
|
|
return args.Bool(0), args.Error(1)
|
|
}
|
|
|
|
func (m *MockCategoryRepository) GetByID(ctx context.Context, id uuid.UUID) (*models.Category, error) {
|
|
args := m.Called(ctx, id)
|
|
return args.Get(0).(*models.Category), args.Error(1)
|
|
}
|
|
|
|
func (m *MockInventoryRepository) BulkCreate(ctx context.Context, inventoryItems []*models.Inventory) error {
|
|
args := m.Called(ctx, inventoryItems)
|
|
return args.Error(0)
|
|
}
|
|
|
|
func (m *MockOutletRepository) GetByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]*models.Outlet, error) {
|
|
args := m.Called(ctx, organizationID)
|
|
return args.Get(0).([]*models.Outlet), args.Error(1)
|
|
}
|