112 lines
3.5 KiB
Go
112 lines
3.5 KiB
Go
package models
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func at(day string) time.Time {
|
|
parsed, err := time.Parse("2006-01-02", day)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return parsed
|
|
}
|
|
|
|
func TestOpenByDefault(t *testing.T) {
|
|
// Every branch trading today has isopen true and no date. None of them may
|
|
// go dark the moment this ships.
|
|
if !StoreIsOpen("Active", true, "", at("2026-10-09")) {
|
|
t.Error("a normal trading branch was reported closed")
|
|
}
|
|
}
|
|
|
|
func TestClosedWithNoDateStaysClosed(t *testing.T) {
|
|
// A power cut nobody can put an end to. It stays shut until a person says
|
|
// otherwise — the safe way round, because a shop wrongly shown open takes
|
|
// orders it cannot fill.
|
|
if StoreIsOpen("Active", false, "", at("2026-10-09")) {
|
|
t.Error("a branch closed with no reopen date was reported open")
|
|
}
|
|
}
|
|
|
|
func TestReopensOnTheDateItNamed(t *testing.T) {
|
|
// "Closed until the 12th" means open ON the 12th.
|
|
cases := []struct {
|
|
today string
|
|
want bool
|
|
}{
|
|
{"2026-10-10", false}, // still closed
|
|
{"2026-10-11", false}, // last closed day
|
|
{"2026-10-12", true}, // back
|
|
{"2026-10-13", true}, // and stays back
|
|
}
|
|
for _, tc := range cases {
|
|
got := StoreIsOpen("Active", false, "2026-10-12", at(tc.today))
|
|
if got != tc.want {
|
|
t.Errorf("on %s: open=%v, want %v", tc.today, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestReopeningNeedsNobodyToRemember(t *testing.T) {
|
|
// The whole reason this is computed and not scheduled: no job ran, nothing
|
|
// flipped the flag, and the shop is open anyway.
|
|
if !StoreIsOpen("Active", false, "2026-10-01", at("2026-12-25")) {
|
|
t.Error("a branch whose reopen date passed months ago is still shut")
|
|
}
|
|
}
|
|
|
|
func TestDecommissionedBeatsEverything(t *testing.T) {
|
|
// Status is Nearle's word for whether the branch exists. A date passing
|
|
// must not bring back a branch that was switched off.
|
|
if StoreIsOpen("Inactive", true, "", at("2026-10-09")) {
|
|
t.Error("an inactive branch was reported open")
|
|
}
|
|
if StoreIsOpen("Inactive", false, "2026-10-01", at("2026-12-25")) {
|
|
t.Error("an inactive branch came back because a date passed")
|
|
}
|
|
}
|
|
|
|
func TestUnreadableDateIsNotTreatedAsToday(t *testing.T) {
|
|
// A zero time would be before today and quietly reopen the shop.
|
|
if StoreIsOpen("Active", false, "not a date", at("2026-10-09")) {
|
|
t.Error("an unreadable reopen date reopened the branch")
|
|
}
|
|
}
|
|
|
|
func TestAcceptsATimestampAsWellAsADate(t *testing.T) {
|
|
// The column is a DATE, but GORM and the console have both been known to
|
|
// hand over a full timestamp.
|
|
if !StoreIsOpen("Active", false, "2026-10-12T00:00:00Z", at("2026-10-12")) {
|
|
t.Error("a timestamp form of the reopen date was not understood")
|
|
}
|
|
}
|
|
|
|
func TestReasonIsWrittenForAShopper(t *testing.T) {
|
|
if msg := StoreClosedReason("Active", true, "", at("2026-10-09")); msg != "" {
|
|
t.Errorf("an open store gave a reason: %q", msg)
|
|
}
|
|
|
|
msg := StoreClosedReason("Active", false, "2026-10-12", at("2026-10-09"))
|
|
if !strings.Contains(msg, "12 Oct") {
|
|
t.Errorf("the reason does not say when it reopens: %q", msg)
|
|
}
|
|
|
|
// No date: say it is closed, and do not invent a return.
|
|
plain := StoreClosedReason("Active", false, "", at("2026-10-09"))
|
|
if plain == "" || strings.Contains(plain, "reopens") {
|
|
t.Errorf("a close with no date promised a return: %q", plain)
|
|
}
|
|
}
|
|
|
|
func TestStatusIsNotCaseSensitive(t *testing.T) {
|
|
// The column holds "Active" today, but nothing enforces the capital.
|
|
for _, s := range []string{"Active", "active", "ACTIVE", " Active "} {
|
|
if !StoreIsOpen(s, true, "", at("2026-10-09")) {
|
|
t.Errorf("status %q read as not active", s)
|
|
}
|
|
}
|
|
}
|