- graders registry collected at boot from every HasGraders plugin, manual first; a duplicate or reserved code fails boot - grading job on queue quizzes_grading with three attempts; a stale or reviewed answer is never touched; the last failure marks it failed - learning answers enqueue at once, tests at close; a grade recalculates a finished attempt and fires AnswerGradedEvent after commit
66 lines
2.3 KiB
Go
66 lines
2.3 KiB
Go
package quizzes_test
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"slices"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/sm-quizzes-plugin/graders"
|
|
"git.golem15.com/golem15/summercms/modules/backpack"
|
|
"git.golem15.com/golem15/summercms/modules/party"
|
|
)
|
|
|
|
// fixtureGrader is the grader both fixture plugins publish, under the same
|
|
// code.
|
|
type fixtureGrader struct{}
|
|
|
|
func (fixtureGrader) Code() string { return "fixture" }
|
|
func (fixtureGrader) Label() string { return "Fixture" }
|
|
func (fixtureGrader) Grade(context.Context, graders.Input) (graders.Result, error) {
|
|
return graders.Result{}, nil
|
|
}
|
|
|
|
// graderPlugin is a test-only plugin that provides fixtureGrader. It is
|
|
// registered here and activated only by the tests that name it.
|
|
type graderPlugin struct{ id string }
|
|
|
|
func (p *graderPlugin) ID() string { return p.id }
|
|
func (p *graderPlugin) Requires() []string { return []string{"golem15.quizzes"} }
|
|
func (p *graderPlugin) Register(*backpack.App) error { return nil }
|
|
func (p *graderPlugin) Boot(*backpack.App) error { return nil }
|
|
func (p *graderPlugin) QuizGraders() []graders.Grader { return []graders.Grader{fixtureGrader{}} }
|
|
|
|
func init() {
|
|
party.Register(&graderPlugin{id: "acme.gradersone"})
|
|
party.Register(&graderPlugin{id: "acme.graderstwo"})
|
|
}
|
|
|
|
func TestGradersCollectedAtBoot(t *testing.T) {
|
|
app := backpack.New(testConfig(t))
|
|
if _, err := party.Activate(app, []string{"golem15.user", "golem15.quizzes", "acme.gradersone"}); err != nil {
|
|
t.Fatalf("Activate: %v", err)
|
|
}
|
|
reg, ok := app.Lookup[*graders.Registry]()
|
|
if !ok || reg == nil {
|
|
t.Fatal("no *graders.Registry published")
|
|
}
|
|
if got := reg.Codes(); !slices.Equal(got, []string{graders.Manual, "fixture"}) {
|
|
t.Errorf("Codes = %v, want [manual fixture]", got)
|
|
}
|
|
if id, _ := reg.PluginID("fixture"); id != "acme.gradersone" {
|
|
t.Errorf("PluginID(fixture) = %q", id)
|
|
}
|
|
|
|
plain, _ := activate(t, nil, nil)
|
|
if reg, ok := plain.Lookup[*graders.Registry](); !ok || !slices.Equal(reg.Codes(), []string{graders.Manual}) {
|
|
t.Errorf("without grading plugins the registry should hold manual only")
|
|
}
|
|
|
|
dup := backpack.New(testConfig(t))
|
|
_, err := party.Activate(dup, []string{"golem15.user", "golem15.quizzes", "acme.gradersone", "acme.graderstwo"})
|
|
if !errors.Is(err, graders.ErrDuplicateCode) {
|
|
t.Errorf("Activate with two fixture plugins = %v, want ErrDuplicateCode", err)
|
|
}
|
|
}
|