Files
sm-bm-plugin/models/temporal_test.go
Jakub Zych 71b848a376 Adopt SummerCMS v0.1.1 admin features
Datepickers on native time.Time / lagoon.Date fields, file uploads on
materials, readings and class sessions managed from the course form
(course_id made nullable).
2026-10-03 06:03:34 +02:00

88 lines
2.8 KiB
Go

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)
}
}