package moduleconfmod import ( "encoding/json" "testing" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) func TestModuleConfValidateSchedule(t *testing.T) { start := time.Date(2026, 7, 27, 8, 0, 0, 0, time.UTC) after := start.Add(time.Hour) before := start.Add(-time.Second) tests := []struct { name string module ModuleConf wantErr bool }{ {name: "no limits", module: ModuleConf{}}, {name: "only online", module: ModuleConf{OnlineAt: &start}}, {name: "only offline", module: ModuleConf{OfflineAt: &after}}, {name: "valid window", module: ModuleConf{OnlineAt: &start, OfflineAt: &after}}, {name: "equal boundary", module: ModuleConf{OnlineAt: &start, OfflineAt: &start}, wantErr: true}, {name: "reversed window", module: ModuleConf{OnlineAt: &start, OfflineAt: &before}, wantErr: true}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { err := test.module.ValidateSchedule() if (err != nil) != test.wantErr { t.Fatalf("ValidateSchedule() error = %v, wantErr %v", err, test.wantErr) } }) } } func TestModuleConfIsActiveAt(t *testing.T) { now := time.Date(2026, 7, 27, 8, 0, 0, 0, time.UTC) past := now.Add(-time.Hour) future := now.Add(time.Hour) tests := []struct { name string module ModuleConf want bool }{ {name: "enabled without window", module: ModuleConf{Status: 1}, want: true}, {name: "disabled", module: ModuleConf{Status: 0}, want: false}, {name: "not online yet", module: ModuleConf{Status: 1, OnlineAt: &future}, want: false}, {name: "online boundary is inclusive", module: ModuleConf{Status: 1, OnlineAt: &now}, want: true}, {name: "inside window", module: ModuleConf{Status: 1, OnlineAt: &past, OfflineAt: &future}, want: true}, {name: "offline boundary is exclusive", module: ModuleConf{Status: 1, OfflineAt: &now}, want: false}, {name: "already offline", module: ModuleConf{Status: 1, OfflineAt: &past}, want: false}, {name: "deleted", module: ModuleConf{Status: 1, DeletedAt: &past}, want: false}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { if got := test.module.IsActiveAt(now); got != test.want { t.Fatalf("IsActiveAt() = %v, want %v", got, test.want) } }) } } func TestModuleConfJSONIncludesExcludeSearch(t *testing.T) { data, err := json.Marshal(ModuleConf{}) if err != nil { t.Fatal(err) } var decoded map[string]interface{} if err = json.Unmarshal(data, &decoded); err != nil { t.Fatal(err) } value, exists := decoded["excludeSearch"] if !exists || value != false { t.Fatalf("excludeSearch = %#v, exists = %v; want false and present", value, exists) } } func TestEditSelectorBSONIncludesFalseExcludeSearch(t *testing.T) { value := false data, err := bson.Marshal(EditSelector{ ID: primitive.NewObjectID(), ExcludeSearch: &value, }) if err != nil { t.Fatal(err) } var decoded bson.M if err = bson.Unmarshal(data, &decoded); err != nil { t.Fatal(err) } got, exists := decoded["excludeSearch"] if !exists || got != false { t.Fatalf("excludeSearch = %#v, exists = %v; want false and present", got, exists) } }