- migration: open question type, rubric, max_length, quiz grader and the grading and review columns of attempt answers - open answers are checked, stored as pending and never scored on answer; a changed text resets the grading state - student JSON gains text, grading_status, grader_feedback, review_comment, max_length, needs_review and open_answers; the rubric is never serialized
60 lines
2.1 KiB
Go
60 lines
2.1 KiB
Go
package classes_test
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/sm-quizzes-plugin/classes"
|
|
"git.golem15.com/golem15/sm-quizzes-plugin/models"
|
|
)
|
|
|
|
func TestCheckOpenText(t *testing.T) {
|
|
q := models.Question{Type: models.TypeOpen}
|
|
long := 3000
|
|
wide := models.Question{Type: models.TypeOpen, MaxLength: &long}
|
|
|
|
fieldKey := func(err error) string {
|
|
var fe *classes.FieldError
|
|
if errors.As(err, &fe) && fe.Field == "text" {
|
|
return fe.Key
|
|
}
|
|
return ""
|
|
}
|
|
|
|
if _, err := classes.CheckOpenText(" \n\t ", q); fieldKey(err) != "text_required" {
|
|
t.Errorf("blank text: err = %v, want text_required", err)
|
|
}
|
|
if _, err := classes.CheckOpenText("\x00 \x00", q); fieldKey(err) != "text_required" {
|
|
t.Errorf("NUL-only text: err = %v, want text_required", err)
|
|
}
|
|
over := strings.Repeat("a", 2001)
|
|
if _, err := classes.CheckOpenText(over, q); fieldKey(err) != "text_too_long" {
|
|
t.Errorf("2001 runes with default max: err = %v, want text_too_long", err)
|
|
}
|
|
if got, err := classes.CheckOpenText(over, wide); err != nil || got != over {
|
|
t.Errorf("2001 runes with max 3000: %q, %v", got[:10], err)
|
|
}
|
|
if got, err := classes.CheckOpenText("a\x00b", q); err != nil || got != "ab" {
|
|
t.Errorf("NUL stripped: %q, %v; want ab", got, err)
|
|
}
|
|
if got, err := classes.CheckOpenText(" moja odpowiedź \n", q); err != nil || got != "moja odpowiedź" {
|
|
t.Errorf("trimmed: %q, %v", got, err)
|
|
}
|
|
polish := strings.Repeat("ż", 2000)
|
|
if got, err := classes.CheckOpenText(polish, q); err != nil || got != polish {
|
|
t.Errorf("2000 runes of ż (4000 bytes) refused: %v", err)
|
|
}
|
|
five := 5
|
|
if _, err := classes.CheckOpenText("abcdef", models.Question{MaxLength: &five}); fieldKey(err) != "text_too_long" {
|
|
t.Errorf("6 runes with max 5: err = %v, want text_too_long", err)
|
|
}
|
|
if classes.MaxLength(q) != models.DefaultMaxLength || classes.MaxLength(wide) != 3000 {
|
|
t.Errorf("MaxLength = %d / %d", classes.MaxLength(q), classes.MaxLength(wide))
|
|
}
|
|
zero := 0
|
|
if classes.MaxLength(models.Question{MaxLength: &zero}) != models.DefaultMaxLength {
|
|
t.Error("MaxLength of a non-positive value should fall back to the default")
|
|
}
|
|
}
|