Files
sm-bm-plugin/classes/seed_test.go

118 lines
4.2 KiB
Go

package classes_test
import (
"os"
"strings"
"testing"
"git.golem15.com/jakub/sm-bm-plugin/classes"
)
func parse(t *testing.T, doc string) *classes.SeedFile {
t.Helper()
f, err := classes.ParseSeed(strings.NewReader(doc))
if err != nil {
t.Fatalf("ParseSeed: %v", err)
}
return f
}
func TestExampleFixtureIsValid(t *testing.T) {
fh, err := os.Open("../testdata/seed.example.json")
if err != nil {
t.Fatal(err)
}
defer fh.Close()
f, err := classes.ParseSeed(fh)
if err != nil {
t.Fatal(err)
}
if err := f.Validate(); err != nil {
t.Fatalf("Validate: %v", err)
}
if len(f.Meetings) != 2 || len(f.Courses) != 3 || len(f.ClassSessions) != 3 || len(f.Deadlines) != 2 || len(f.Readings) != 2 {
t.Errorf("fixture counts = %d %d %d %d %d", len(f.Meetings), len(f.Courses), len(f.ClassSessions), len(f.Deadlines), len(f.Readings))
}
if f.Courses[2].ElectiveGroup == nil || *f.Courses[2].ElectiveGroup != "przyklad-do-wyboru" {
t.Errorf("elective_group = %v", f.Courses[2].ElectiveGroup)
}
}
func TestEmptyDocumentIsValid(t *testing.T) {
if err := parse(t, `{}`).Validate(); err != nil {
t.Errorf("{}: %v", err)
}
}
func TestParseRejectsUnknownFieldsAndTrailingData(t *testing.T) {
for _, doc := range []string{
`{"courses": [{"key": "a", "nmae": "typo"}]}`,
`{"lectures": []}`,
`{} {}`,
`[]`,
`{"meetings": [{"number": "one"}]}`,
} {
if _, err := classes.ParseSeed(strings.NewReader(doc)); err == nil {
t.Errorf("ParseSeed(%s) accepted", doc)
}
}
}
func TestValidateNamesTheRecord(t *testing.T) {
cases := []struct {
doc string
want []string
}{
{`{"class_sessions": [{"course": "ghost", "starts_at": "2030-10-05T08:00:00+02:00", "ends_at": "2030-10-05T09:00:00+02:00"}]}`,
[]string{`class_sessions[0]`, `unknown course key "ghost"`}},
{`{"courses": [{"key": "a", "name": "A", "form": "wyklad", "semester": 1}],
"class_sessions": [{"course": "a", "meeting": 9, "starts_at": "2030-10-05T08:00:00+02:00", "ends_at": "2030-10-05T09:00:00+02:00"}]}`,
[]string{`unknown meeting number 9`}},
{`{"deadlines": [{"title": "X", "due_at": "2030-10-05T08:00:00+02:00", "course": "nope", "kind": "inne"}]}`,
[]string{`deadlines[0] ("X")`, `unknown course key "nope"`}},
{`{"readings": [{"course": "nope", "title": "Book"}]}`,
[]string{`readings[0]`, `unknown course key "nope"`}},
{`{"courses": [{"key": "a", "name": "A", "form": "lecture", "semester": 7}]}`,
[]string{`form "lecture"`, `semester must be between 1 and 4`}},
{`{"courses": [{"key": "a", "name": "A", "form": "wyklad", "semester": 1}, {"key": "a", "name": "A", "form": "wyklad", "semester": 1}]}`,
[]string{`duplicate course key`, `same name, form and semester`}},
{`{"meetings": [{"number": 1, "starts_on": "2030-10-06", "ends_on": "2030-10-05"}, {"number": 1, "starts_on": "05.10.2030", "ends_on": "2030-10-05"}]}`,
[]string{`ends_on is before starts_on`, `duplicate meeting number`, `starts_on`}},
{`{"courses": [{"key": "a", "name": "A", "form": "wyklad", "semester": 1}],
"class_sessions": [{"course": "a", "starts_at": "2030-10-05 10:00", "ends_at": "2030-10-05 09:00"}]}`,
[]string{`ends_at is not after starts_at`}},
{`{"deadlines": [{"title": "", "due_at": "soon", "kind": "deadline"}]}`,
[]string{`title is required`, `due_at`, `kind "deadline"`}},
}
for _, tc := range cases {
err := parse(t, tc.doc).Validate()
if err == nil {
t.Errorf("Validate(%s) passed", tc.doc)
continue
}
for _, want := range tc.want {
if !strings.Contains(err.Error(), want) {
t.Errorf("Validate(%s) = %q, want it to mention %q", tc.doc, err, want)
}
}
}
}
func TestSeedValidatesBeforeTouchingTheDatabase(t *testing.T) {
f := parse(t, `{"readings": [{"course": "ghost", "title": "Book"}]}`)
// A nil database would panic if Seed reached it.
if _, err := classes.Seed(t.Context(), nil, f); err == nil || !strings.Contains(err.Error(), "ghost") {
t.Errorf("Seed = %v, want the unknown course error", err)
}
}
func TestSummaryRows(t *testing.T) {
var s classes.SeedSummary
s.Courses.Created = 2
s.Readings.Unchanged = 1
rows := s.Rows()
if len(rows) != 5 || rows[1][0] != "courses" || rows[1][1] != "2" || rows[4][3] != "1" || len(rows[0]) != 5 {
t.Errorf("Rows = %v", rows)
}
}