Files
apskel-pos-backend/internal/validator/purchase_order_validator_test.go
T
2026-08-11 22:41:10 +07:00

254 lines
7.5 KiB
Go

package validator
import (
"testing"
"apskel-pos-be/internal/constants"
"apskel-pos-be/internal/contract"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
)
func validCreatePurchaseOrderRequest() *contract.CreatePurchaseOrderRequest {
vendorID := uuid.New()
ingredientID := uuid.New()
quantity := 1.0
unitID := uuid.New()
return &contract.CreatePurchaseOrderRequest{
VendorID: &vendorID,
PONumber: "PO-001",
TransactionDate: "2026-05-29",
Items: []contract.CreatePurchaseOrderItemRequest{
{
IngredientID: &ingredientID,
PurchaseCategoryID: uuid.New(),
Quantity: &quantity,
UnitID: &unitID,
Amount: 1000,
},
},
}
}
func TestPurchaseOrderValidatorCreateAllowsMissingVendor(t *testing.T) {
validator := NewPurchaseOrderValidator()
req := validCreatePurchaseOrderRequest()
req.VendorID = nil
err, code := validator.ValidateCreatePurchaseOrderRequest(req)
require.NoError(t, err)
require.Empty(t, code)
}
func TestPurchaseOrderValidatorCreateRejectsEmptyVendor(t *testing.T) {
validator := NewPurchaseOrderValidator()
req := validCreatePurchaseOrderRequest()
vendorID := uuid.Nil
req.VendorID = &vendorID
err, code := validator.ValidateCreatePurchaseOrderRequest(req)
require.Error(t, err)
require.Equal(t, constants.MalformedFieldErrorCode, code)
require.Contains(t, err.Error(), "vendor_id cannot be empty")
}
func TestPurchaseOrderValidatorCreateAllowsMissingDueDate(t *testing.T) {
validator := NewPurchaseOrderValidator()
err, code := validator.ValidateCreatePurchaseOrderRequest(validCreatePurchaseOrderRequest())
require.NoError(t, err)
require.Empty(t, code)
}
func TestPurchaseOrderValidatorCreateRejectsInvalidDueDate(t *testing.T) {
validator := NewPurchaseOrderValidator()
req := validCreatePurchaseOrderRequest()
dueDate := "29-05-2026"
req.DueDate = &dueDate
err, code := validator.ValidateCreatePurchaseOrderRequest(req)
require.Error(t, err)
require.Equal(t, constants.MalformedFieldErrorCode, code)
require.Contains(t, err.Error(), "due_date must be in YYYY-MM-DD format")
}
func TestPurchaseOrderValidatorCreateRejectsDueDateBeforeTransactionDate(t *testing.T) {
validator := NewPurchaseOrderValidator()
req := validCreatePurchaseOrderRequest()
dueDate := "2026-05-28"
req.DueDate = &dueDate
err, code := validator.ValidateCreatePurchaseOrderRequest(req)
require.Error(t, err)
require.Equal(t, constants.MalformedFieldErrorCode, code)
require.Contains(t, err.Error(), "due_date must be after transaction_date")
}
func TestPurchaseOrderValidatorCreateAllowsCentralTeam(t *testing.T) {
validator := NewPurchaseOrderValidator()
req := validCreatePurchaseOrderRequest()
scope := constants.PurchaseTeamScopeCentral
req.TeamScope = &scope
err, code := validator.ValidateCreatePurchaseOrderRequest(req)
require.NoError(t, err)
require.Empty(t, code)
}
func TestPurchaseOrderValidatorCreateRejectsCentralTeamWithCategory(t *testing.T) {
validator := NewPurchaseOrderValidator()
req := validCreatePurchaseOrderRequest()
scope := constants.PurchaseTeamScopeCentral
categoryID := uuid.New()
req.TeamScope = &scope
req.TeamCategoryID = &categoryID
err, code := validator.ValidateCreatePurchaseOrderRequest(req)
require.Error(t, err)
require.Equal(t, constants.MalformedFieldErrorCode, code)
require.Contains(t, err.Error(), "team_category_id must be empty")
}
func TestPurchaseOrderValidatorCreateRejectsCategoryTeamWithoutCategory(t *testing.T) {
validator := NewPurchaseOrderValidator()
req := validCreatePurchaseOrderRequest()
scope := constants.PurchaseTeamScopeCategory
req.TeamScope = &scope
err, code := validator.ValidateCreatePurchaseOrderRequest(req)
require.Error(t, err)
require.Equal(t, constants.MissingFieldErrorCode, code)
require.Contains(t, err.Error(), "team_category_id is required")
}
func TestPurchaseOrderValidatorCreateRejectsCategoryWithoutScope(t *testing.T) {
validator := NewPurchaseOrderValidator()
req := validCreatePurchaseOrderRequest()
categoryID := uuid.New()
req.TeamCategoryID = &categoryID
err, code := validator.ValidateCreatePurchaseOrderRequest(req)
require.Error(t, err)
require.Equal(t, constants.MissingFieldErrorCode, code)
require.Contains(t, err.Error(), "team_scope is required")
}
func TestPurchaseOrderValidatorCreateRejectsUnknownTeamScope(t *testing.T) {
validator := NewPurchaseOrderValidator()
req := validCreatePurchaseOrderRequest()
scope := "outlet"
req.TeamScope = &scope
err, code := validator.ValidateCreatePurchaseOrderRequest(req)
require.Error(t, err)
require.Equal(t, constants.MalformedFieldErrorCode, code)
require.Contains(t, err.Error(), "team_scope must be one of")
}
// An update may clear the team with an empty scope; a create may not, because
// leaving the field out already means "no team".
func TestPurchaseOrderValidatorUpdateAllowsClearingTeam(t *testing.T) {
validator := NewPurchaseOrderValidator()
scope := ""
err, code := validator.ValidateUpdatePurchaseOrderRequest(&contract.UpdatePurchaseOrderRequest{TeamScope: &scope})
require.NoError(t, err)
require.Empty(t, code)
}
func TestPurchaseOrderValidatorCreateRejectsEmptyTeamScope(t *testing.T) {
validator := NewPurchaseOrderValidator()
req := validCreatePurchaseOrderRequest()
scope := ""
req.TeamScope = &scope
err, code := validator.ValidateCreatePurchaseOrderRequest(req)
require.Error(t, err)
require.Equal(t, constants.MalformedFieldErrorCode, code)
}
func TestPurchaseOrderValidatorUpdateRejectsClearingTeamWithCategory(t *testing.T) {
validator := NewPurchaseOrderValidator()
scope := ""
categoryID := uuid.New()
err, code := validator.ValidateUpdatePurchaseOrderRequest(&contract.UpdatePurchaseOrderRequest{
TeamScope: &scope,
TeamCategoryID: &categoryID,
})
require.Error(t, err)
require.Equal(t, constants.MalformedFieldErrorCode, code)
}
func TestPurchaseOrderValidatorListAcceptsTeamFilter(t *testing.T) {
validator := NewPurchaseOrderValidator()
for _, team := range []string{constants.PurchaseTeamScopeCentral, constants.PurchaseTeamNone, uuid.New().String()} {
err, code := validator.ValidateListPurchaseOrdersRequest(&contract.ListPurchaseOrdersRequest{
Page: 1,
Limit: 10,
Team: team,
})
require.NoError(t, err, team)
require.Empty(t, code, team)
}
}
func TestPurchaseOrderValidatorListRejectsUnknownTeamFilter(t *testing.T) {
validator := NewPurchaseOrderValidator()
err, code := validator.ValidateListPurchaseOrdersRequest(&contract.ListPurchaseOrdersRequest{
Page: 1,
Limit: 10,
Team: "marketing",
})
require.Error(t, err)
require.Equal(t, constants.MalformedFieldErrorCode, code)
}
func TestPurchaseOrderValidatorListRejectsTeamWithScope(t *testing.T) {
validator := NewPurchaseOrderValidator()
err, code := validator.ValidateListPurchaseOrdersRequest(&contract.ListPurchaseOrdersRequest{
Page: 1,
Limit: 10,
Team: constants.PurchaseTeamNone,
TeamScope: constants.PurchaseTeamScopeCentral,
})
require.Error(t, err)
require.Equal(t, constants.MalformedFieldErrorCode, code)
}
func TestPurchaseOrderValidatorListRejectsCentralScopeWithCategory(t *testing.T) {
validator := NewPurchaseOrderValidator()
categoryID := uuid.New()
err, code := validator.ValidateListPurchaseOrdersRequest(&contract.ListPurchaseOrdersRequest{
Page: 1,
Limit: 10,
TeamScope: constants.PurchaseTeamScopeCentral,
TeamCategoryID: &categoryID,
})
require.Error(t, err)
require.Equal(t, constants.MalformedFieldErrorCode, code)
}