package models_test import ( "testing" "time" "git.golem15.com/golem15/summercms/modules/lagoon" "git.golem15.com/jakub/sm-bm-plugin/models" ) func TestParseDateTimeForms(t *testing.T) { want := time.Date(2026, 10, 3, 6, 0, 0, 0, time.UTC) for _, in := range []string{ "2026-10-03T08:00:00+02:00", "2026-10-03T06:00:00Z", "2026-10-03 08:00", "2026-10-03T08:00", " 2026-10-03 08:00:00 ", } { got, err := models.ParseDateTime(in) if err != nil { t.Errorf("ParseDateTime(%q): %v", in, err) continue } if !got.Equal(want) { t.Errorf("ParseDateTime(%q) = %v, want %v", in, got, want) } } // Winter time: a wall-clock time in December is UTC+1. got, err := models.ParseDateTime("2026-12-01 08:00") if err != nil || !got.Equal(time.Date(2026, 12, 1, 7, 0, 0, 0, time.UTC)) { t.Errorf("winter wall clock = %v, %v", got, err) } for _, bad := range []string{"", "tomorrow", "2026-13-01 08:00", "2026-10-03"} { if _, err := models.ParseDateTime(bad); err == nil { t.Errorf("ParseDateTime(%q) accepted", bad) } } } func TestParseDateAndFormat(t *testing.T) { d, err := models.ParseDate(" 2026-10-03 ") if err != nil || d.String() != "2026-10-03" { t.Errorf("ParseDate = %v, %v", d, err) } if _, err := models.ParseDate("03.10.2026"); err == nil { t.Error("a non-ISO date was accepted") } got := models.FormatDateTime(time.Date(2026, 10, 3, 6, 0, 0, 0, time.UTC)) if got != "2026-10-03T08:00:00+02:00" { t.Errorf("FormatDateTime = %q, want the Warsaw RFC 3339 form", got) } } func TestTemporalErrors(t *testing.T) { at := func(h int) time.Time { return time.Date(2026, 10, 3, h, 0, 0, 0, models.Location) } s := &models.ClassSession{StartsAt: at(10), EndsAt: at(9)} if errs := s.TemporalErrors(); len(errs["ends_at"]) != 1 { t.Errorf("end before start: %v", errs) } if errs := (&models.ClassSession{StartsAt: at(8), EndsAt: at(10)}).TemporalErrors(); errs != nil { t.Errorf("valid session: %v", errs) } // Missing times are the required rules' job, not an order error. if errs := (&models.ClassSession{}).TemporalErrors(); errs != nil { t.Errorf("empty session: %v", errs) } m := &models.Meeting{StartsOn: lagoon.NewDate(2026, 10, 4), EndsOn: lagoon.NewDate(2026, 10, 3)} if errs := m.TemporalErrors(); len(errs["ends_on"]) != 1 { t.Errorf("meeting order: %v", errs) } ok := &models.Meeting{StartsOn: lagoon.NewDate(2026, 10, 3), EndsOn: lagoon.NewDate(2026, 10, 4)} if errs := ok.TemporalErrors(); errs != nil { t.Errorf("valid meeting: %v", errs) } } func TestBeforeSaveBlanksOptionalText(t *testing.T) { empty, space := "", " " c := &models.Course{Code: &empty, Lecturer: &space} if err := c.BeforeSave(nil); err != nil { t.Fatal(err) } if c.Code != nil || c.Lecturer != nil { t.Errorf("blank text kept: %v %v", c.Code, c.Lecturer) } }