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).
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/lagoon"
|
||||
"git.golem15.com/jakub/sm-bm-plugin/models"
|
||||
)
|
||||
|
||||
@@ -37,85 +38,41 @@ func TestParseDateTimeForms(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateTimeRoundTrip(t *testing.T) {
|
||||
d := models.DateTime("2026-10-03 08:00")
|
||||
v, err := d.Value()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
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)
|
||||
}
|
||||
stored, ok := v.(time.Time)
|
||||
if !ok || stored.Location() != time.UTC || stored.Hour() != 6 {
|
||||
t.Fatalf("Value = %#v, want 06:00 UTC", v)
|
||||
if _, err := models.ParseDate("03.10.2026"); err == nil {
|
||||
t.Error("a non-ISO date was accepted")
|
||||
}
|
||||
var read models.DateTime
|
||||
if err := read.Scan(stored); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if read != "2026-10-03T08:00:00+02:00" {
|
||||
t.Errorf("Scan = %q, want the Warsaw RFC 3339 form", read)
|
||||
}
|
||||
if err := read.Scan("2026-10-03 06:00:00+00"); err != nil || read != "2026-10-03T08:00:00+02:00" {
|
||||
t.Errorf("Scan(postgres text) = %q, %v", read, err)
|
||||
}
|
||||
if err := read.Scan(nil); err != nil || read != "" {
|
||||
t.Errorf("Scan(nil) = %q, %v", read, err)
|
||||
}
|
||||
if v, err := models.DateTime("").Value(); err != nil || v != nil {
|
||||
t.Errorf("empty Value = %v, %v; want NULL", v, err)
|
||||
}
|
||||
if _, err := models.DateTime("soon").Value(); err == nil {
|
||||
t.Error("an unparsable DateTime was stored")
|
||||
}
|
||||
if err := read.Scan(42); err == nil {
|
||||
t.Error("Scan(int) succeeded")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateRoundTrip(t *testing.T) {
|
||||
var d models.Date
|
||||
if err := d.Scan(time.Date(2026, 10, 3, 0, 0, 0, 0, time.UTC)); err != nil || d != "2026-10-03" {
|
||||
t.Errorf("Scan(time) = %q, %v", d, err)
|
||||
}
|
||||
if err := d.Scan([]byte("2026-10-04")); err != nil || d != "2026-10-04" {
|
||||
t.Errorf("Scan(bytes) = %q, %v", d, err)
|
||||
}
|
||||
if v, err := models.Date("2026-10-03").Value(); err != nil || v != "2026-10-03" {
|
||||
t.Errorf("Value = %v, %v", v, err)
|
||||
}
|
||||
if _, err := models.Date("03.10.2026").Value(); err == nil {
|
||||
t.Error("a non-ISO date was stored")
|
||||
}
|
||||
if models.NewDate(time.Date(2026, 10, 2, 23, 30, 0, 0, time.UTC)) != "2026-10-03" {
|
||||
t.Error("NewDate does not use the Warsaw calendar day")
|
||||
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) {
|
||||
s := &models.ClassSession{StartsAt: "2026-10-03 10:00", EndsAt: "2026-10-03 09:00"}
|
||||
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)
|
||||
}
|
||||
s = &models.ClassSession{StartsAt: "bad"}
|
||||
errs := s.TemporalErrors()
|
||||
if len(errs["starts_at"]) != 1 || len(errs["ends_at"]) != 1 {
|
||||
t.Errorf("bad and missing: %v", errs)
|
||||
if errs := (&models.ClassSession{StartsAt: at(8), EndsAt: at(10)}).TemporalErrors(); errs != nil {
|
||||
t.Errorf("valid session: %v", errs)
|
||||
}
|
||||
m := &models.Meeting{StartsOn: "2026-10-04", EndsOn: "2026-10-03"}
|
||||
// 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: "2026-10-03", EndsOn: "2026-10-04"}
|
||||
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)
|
||||
}
|
||||
draft := &models.Material{}
|
||||
if errs := draft.TemporalErrors(); errs != nil {
|
||||
t.Errorf("draft material: %v", errs)
|
||||
}
|
||||
bad := models.DateTime("yesterday")
|
||||
if errs := (&models.Material{PublishedAt: &bad}).TemporalErrors(); len(errs["published_at"]) != 1 {
|
||||
t.Errorf("bad published_at: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBeforeSaveBlanksOptionalText(t *testing.T) {
|
||||
@@ -127,10 +84,4 @@ func TestBeforeSaveBlanksOptionalText(t *testing.T) {
|
||||
if c.Code != nil || c.Lecturer != nil {
|
||||
t.Errorf("blank text kept: %v %v", c.Code, c.Lecturer)
|
||||
}
|
||||
pub := models.DateTime("")
|
||||
m := &models.Material{PublishedAt: &pub}
|
||||
_ = m.BeforeSave(nil)
|
||||
if m.PublishedAt != nil {
|
||||
t.Error("an empty published_at was not cleared to a draft")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user