138 lines
2.8 KiB
Go
138 lines
2.8 KiB
Go
package domain
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestValidateTaskInputRequiresTitleSKUImageAndPositiveQuantity(t *testing.T) {
|
||
|
|
err := ValidateTaskInput(
|
||
|
|
" ",
|
||
|
|
nil,
|
||
|
|
"",
|
||
|
|
"",
|
||
|
|
"",
|
||
|
|
"",
|
||
|
|
0,
|
||
|
|
)
|
||
|
|
var validation *TaskValidationError
|
||
|
|
if !asTaskValidationError(err, &validation) {
|
||
|
|
t.Fatalf("ValidateTaskInput() error = %v", err)
|
||
|
|
}
|
||
|
|
for _, field := range []string{
|
||
|
|
"creator_subject",
|
||
|
|
"title",
|
||
|
|
"sku",
|
||
|
|
"image_asset_id",
|
||
|
|
"quantity",
|
||
|
|
} {
|
||
|
|
if validation.Fields[field] == "" {
|
||
|
|
t.Fatalf("missing validation for %s", field)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestValidateTaskInputEnforcesUTF8AndCharacterLimits(t *testing.T) {
|
||
|
|
sourceRef := strings.Repeat("a", MaxSourceRefBytes+1)
|
||
|
|
err := ValidateTaskInput(
|
||
|
|
"local-admin",
|
||
|
|
&sourceRef,
|
||
|
|
strings.Repeat("商", MaxTitleRunes+1),
|
||
|
|
strings.Repeat("a", MaxDescriptionBytes+1),
|
||
|
|
strings.Repeat("货", MaxSKUBytes/3+1),
|
||
|
|
"00000000-0000-4000-8000-000000000001",
|
||
|
|
1,
|
||
|
|
)
|
||
|
|
var validation *TaskValidationError
|
||
|
|
if !asTaskValidationError(err, &validation) {
|
||
|
|
t.Fatalf("ValidateTaskInput() error = %v", err)
|
||
|
|
}
|
||
|
|
for _, field := range []string{
|
||
|
|
"source_ref",
|
||
|
|
"title",
|
||
|
|
"description",
|
||
|
|
"sku",
|
||
|
|
} {
|
||
|
|
if validation.Fields[field] == "" {
|
||
|
|
t.Fatalf("missing limit validation for %s", field)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestParseOptionalCNYUsesExactCents(t *testing.T) {
|
||
|
|
tests := []struct {
|
||
|
|
input string
|
||
|
|
want int64
|
||
|
|
}{
|
||
|
|
{input: "0.01", want: 1},
|
||
|
|
{input: "1", want: 100},
|
||
|
|
{input: "19.9", want: 1990},
|
||
|
|
{input: "200.00", want: 20000},
|
||
|
|
}
|
||
|
|
for _, test := range tests {
|
||
|
|
t.Run(test.input, func(t *testing.T) {
|
||
|
|
got, err := ParseOptionalCNY(&test.input)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("ParseOptionalCNY() error = %v", err)
|
||
|
|
}
|
||
|
|
if got == nil || *got != test.want {
|
||
|
|
t.Fatalf("ParseOptionalCNY() = %v, want %d", got, test.want)
|
||
|
|
}
|
||
|
|
formatted := FormatOptionalCNY(got)
|
||
|
|
if formatted == nil {
|
||
|
|
t.Fatal("FormatOptionalCNY() = nil")
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestParseOptionalCNYRejectsInvalidAndOverflow(t *testing.T) {
|
||
|
|
for _, value := range []string{
|
||
|
|
"",
|
||
|
|
"0",
|
||
|
|
"0.00",
|
||
|
|
"-1",
|
||
|
|
"+1",
|
||
|
|
".5",
|
||
|
|
"1.",
|
||
|
|
"1.001",
|
||
|
|
"1e2",
|
||
|
|
"99999999999999999.99",
|
||
|
|
} {
|
||
|
|
t.Run(value, func(t *testing.T) {
|
||
|
|
if _, err := ParseOptionalCNY(&value); err == nil {
|
||
|
|
t.Fatalf("ParseOptionalCNY(%q) error = nil", value)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestCanCancelOnlyPending(t *testing.T) {
|
||
|
|
for _, status := range []TaskStatus{
|
||
|
|
TaskStatusClaimed,
|
||
|
|
TaskStatusRunning,
|
||
|
|
TaskStatusWaitingConfirmation,
|
||
|
|
TaskStatusSucceeded,
|
||
|
|
TaskStatusFailed,
|
||
|
|
TaskStatusCanceled,
|
||
|
|
} {
|
||
|
|
if CanCancel(status) {
|
||
|
|
t.Fatalf("CanCancel(%s) = true", status)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if !CanCancel(TaskStatusPending) {
|
||
|
|
t.Fatal("CanCancel(PENDING) = false")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func asTaskValidationError(
|
||
|
|
err error,
|
||
|
|
target **TaskValidationError,
|
||
|
|
) bool {
|
||
|
|
value, ok := err.(*TaskValidationError)
|
||
|
|
if ok {
|
||
|
|
*target = value
|
||
|
|
}
|
||
|
|
return ok
|
||
|
|
}
|