package models import ( "slices" "strings" "testing" "git.golem15.com/golem15/sm-quizzes-plugin/graders" ) func TestQuizDefaults(t *testing.T) { zero, negative := 0, -1 for name, hook := range map[string]func(*Quiz) error{ "BeforeSave": func(q *Quiz) error { return q.BeforeSave(nil) }, "BeforeValidate": func(q *Quiz) error { return q.BeforeValidate(nil) }, } { for _, limit := range []*int{&zero, &negative} { q := &Quiz{Title: "Q", MaxAttempts: limit} if err := hook(q); err != nil { t.Fatalf("%s: %v", name, err) } if q.Mode != ModeLearning || q.Navigation != NavigationFree || q.MaxAttempts != nil { t.Errorf("%s with max_attempts %d = %q %q %v, want learning free nil", name, *limit, q.Mode, q.Navigation, q.MaxAttempts) } if q.Grader != graders.Manual { t.Errorf("%s left grader %q, want %q", name, q.Grader, graders.Manual) } } two := 2 q := &Quiz{Title: "Q", Mode: ModeTest, Navigation: NavigationOneWay, MaxAttempts: &two, Grader: "ai"} if err := hook(q); err != nil { t.Fatalf("%s: %v", name, err) } if q.Mode != ModeTest || q.Navigation != NavigationOneWay || q.MaxAttempts == nil || *q.MaxAttempts != 2 { t.Errorf("%s changed a test quiz: %q %q %v", name, q.Mode, q.Navigation, q.MaxAttempts) } if q.Grader != "ai" { t.Errorf("%s changed an explicit grader to %q", name, q.Grader) } } } func TestOpenQuestionModel(t *testing.T) { if !slices.Contains(QuestionTypes, TypeOpen) || len(QuestionTypes) != 4 { t.Errorf("QuestionTypes = %v, want the open type appended", QuestionTypes) } if QuestionTypes[0] != TypeSingle || QuestionTypes[1] != TypeMultiple || QuestionTypes[2] != TypeSelfCheck { t.Errorf("QuestionTypes reordered the existing types: %v", QuestionTypes) } rules := Question{}.Rules() if !strings.Contains(rules["type"], "open") || !strings.Contains(rules["type"], "self_check") { t.Errorf("type rule = %q, want every type including open", rules["type"]) } if rules["max_length"] != "nullable|integer|between:1,20000" { t.Errorf("max_length rule = %q", rules["max_length"]) } fill := Question{}.Fillable() if !slices.Contains(fill, "rubric") || !slices.Contains(fill, "max_length") { t.Errorf("Fillable = %v, want rubric and max_length", fill) } if DefaultMaxLength != 2000 || MaxMaxLength != 20000 { t.Errorf("max length limits = %d / %d", DefaultMaxLength, MaxMaxLength) } if len(GradingStatuses) != 4 || GradingStatuses[0] != GradingPending { t.Errorf("GradingStatuses = %v", GradingStatuses) } if !slices.Contains(Quiz{}.Fillable(), "grader") { t.Error("Quiz.Fillable lacks grader") } if len(AttemptAnswer{}.Fillable()) != 0 { t.Error("AttemptAnswer.Fillable must stay empty") } }