- 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
34 lines
1.0 KiB
Go
34 lines
1.0 KiB
Go
package classes
|
|
|
|
import (
|
|
"strings"
|
|
"unicode/utf8"
|
|
|
|
"git.golem15.com/golem15/sm-quizzes-plugin/models"
|
|
)
|
|
|
|
// MaxLength is the longest answer an open question accepts, in characters:
|
|
// its MaxLength when set and positive, else models.DefaultMaxLength.
|
|
func MaxLength(q models.Question) int {
|
|
if q.MaxLength != nil && *q.MaxLength > 0 {
|
|
return *q.MaxLength
|
|
}
|
|
return models.DefaultMaxLength
|
|
}
|
|
|
|
// CheckOpenText cleans a student's answer to an open question (D-04): it
|
|
// removes every NUL character (Postgres text refuses them) and the
|
|
// surrounding whitespace. A blank text is a FieldError text_required and a
|
|
// text longer than MaxLength(q) characters (runes, not bytes) is a
|
|
// FieldError text_too_long.
|
|
func CheckOpenText(text string, q models.Question) (string, error) {
|
|
text = strings.TrimSpace(strings.ReplaceAll(text, "\x00", ""))
|
|
if text == "" {
|
|
return "", &FieldError{Field: "text", Key: "text_required"}
|
|
}
|
|
if utf8.RuneCountInString(text) > MaxLength(q) {
|
|
return "", &FieldError{Field: "text", Key: "text_too_long"}
|
|
}
|
|
return text, nil
|
|
}
|