test(12.2-05): cover every Go behaviour of phase 12.2

- lagoon: Date and TimeOfDay through JSON, text and real DATE/TIME
  columns; Fill text fallback without changing earlier conversions;
  required on zero dates; deferred_bindings shape, store isolation and
  envelope; PurgeDeferred cut-off, after-commit blobs, SKIP LOCKED,
  skipped types and the deferred:purge command
- attach: Store limits, extensions, MIME patterns, default lists, key
  shape and blob cleanup; IsAllowedImage formats, polyglots, ceiling
- conga and pact: framework purge schedule entry and forged jobs; the
  six relation child hook interfaces
- cabana: fileupload and datepicker compile, upload, remove, caption,
  reorder and bounds; deferred commit order, rollback, applied-only and
  concurrent saves; relation contracts, forms, CRUD, deferral, schema
This commit is contained in:
Jakub Zych
2026-10-02 20:34:23 +02:00
parent 9c87a59532
commit c8d41a68c6
16 changed files with 3509 additions and 10 deletions

View File

@@ -3,6 +3,7 @@ package lagoon
import (
"strings"
"testing"
"time"
)
func TestValidateBetweenYear(t *testing.T) {
@@ -269,3 +270,48 @@ func TestValidateNumericRangeMessageTranslated(t *testing.T) {
t.Fatalf("pl between = %v", got)
}
}
// TestValidateRequiredZeroDates: required rejects a zero time.Time, Date or
// TimeOfDay and a non-nil pointer to one, accepts set values (midnight
// included), and keeps the old emptiness of every other type: an int 0, a
// false bool and a non-date struct are present.
func TestValidateRequiredZeroDates(t *testing.T) {
zeroTime, zeroDate, zeroClock := time.Time{}, Date{}, TimeOfDay{}
setTime, setDate, midnight := time.Date(2026, 10, 2, 0, 0, 0, 0, time.UTC), NewDate(2026, 10, 2), NewTimeOfDay(0, 0, 0)
type other struct{ A int }
cases := []struct {
name string
value any
empty bool
}{
{"zero time", zeroTime, true},
{"pointer to zero time", &zeroTime, true},
{"nil time pointer", (*time.Time)(nil), true},
{"zero date", zeroDate, true},
{"pointer to zero date", &zeroDate, true},
{"nil date pointer", (*Date)(nil), true},
{"zero clock", zeroClock, true},
{"pointer to zero clock", &zeroClock, true},
{"nil clock pointer", (*TimeOfDay)(nil), true},
{"set time", setTime, false},
{"pointer to set time", &setTime, false},
{"set date", setDate, false},
{"pointer to set date", &setDate, false},
{"midnight", midnight, false},
{"pointer to midnight", &midnight, false},
{"int zero", 0, false},
{"false", false, false},
{"zero struct", other{}, false},
{"empty string", "", true},
{"nil", nil, true},
}
for _, tc := range cases {
errs, err := Validate(t.Context(), nil, &fillDates{}, map[string]string{"v": "required"}, map[string]any{"v": tc.value}, nil)
if err != nil {
t.Fatalf("%s: %v", tc.name, err)
}
if got := len(errs["v"]) > 0; got != tc.empty {
t.Fatalf("%s: required failed=%v, want %v (%v)", tc.name, got, tc.empty, errs)
}
}
}