feat: add --prune and a rolled-back --dry-run to bm:seed
This commit is contained in:
@@ -659,3 +659,64 @@ func TestAPIAgainstDatabase(t *testing.T) {
|
||||
}
|
||||
|
||||
func ptr(s string) *string { return &s }
|
||||
|
||||
// TestSeedPrune moves a session, drops a course, renames a course's form and
|
||||
// drops a reading: --dry-run reports it without writing, --prune applies it.
|
||||
func TestSeedPrune(t *testing.T) {
|
||||
_, plugins, gdb := migrated(t)
|
||||
seedFixture(t, plugins, "testdata/seed.example.json")
|
||||
next := filepath.Join(t.TempDir(), "next.json")
|
||||
writeJSON(t, next, `{"meetings": [{"number": 1, "starts_on": "2030-10-05", "ends_on": "2030-10-06", "notes": "przykład"}],
|
||||
"courses": [{"key": "a-w", "name": "Przedmiot przykładowy A", "form": "wyklad", "semester": 1, "sort_order": 1},
|
||||
{"key": "b", "name": "Przedmiot przykładowy B", "form": "inne", "semester": 1, "sort_order": 3}],
|
||||
"class_sessions": [{"course": "a-w", "meeting": 1, "starts_at": "2030-10-05T08:15:00+02:00", "ends_at": "2030-10-05T09:45:00+02:00"},
|
||||
{"course": "b", "meeting": 1, "starts_at": "2030-10-06T08:00:00+02:00", "ends_at": "2030-10-06T09:30:00+02:00"}],
|
||||
"readings": [{"course": "a-w", "title": "Lektura przykładowa 1", "is_required": true, "sort_order": 1}]}`)
|
||||
before := map[string]int64{}
|
||||
for _, table := range []string{"jz_bm_courses", "jz_bm_class_sessions", "jz_bm_readings", "jz_bm_meetings", "jz_bm_deadlines"} {
|
||||
before[table] = count(t, gdb, table)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := bonfire.Call(t.Context(), bmPlugin(t, plugins).Commands(), "bm:seed", []string{next, "--prune", "--dry-run"}, &buf); err != nil {
|
||||
t.Fatalf("dry run: %v\n%s", err, buf.String())
|
||||
}
|
||||
out := buf.String()
|
||||
for _, want := range []string{"courses\t1\t1\t0\t2", "class_sessions\t2\t0\t0\t3", "readings\t0\t1\t0\t1", "nothing was written", `deleted: course "Przedmiot przykładowy A" (cwiczenia, semester 1) with 1 sessions and 0 readings`} {
|
||||
if !strings.Contains(out, want) {
|
||||
t.Errorf("dry run output lacks %q:\n%s", want, out)
|
||||
}
|
||||
}
|
||||
for table, n := range before {
|
||||
if got := count(t, gdb, table); got != n {
|
||||
t.Errorf("dry run changed %s: %d -> %d", table, n, got)
|
||||
}
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
if err := bonfire.Call(t.Context(), bmPlugin(t, plugins).Commands(), "bm:seed", []string{next, "--prune"}, &buf); err != nil {
|
||||
t.Fatalf("prune: %v\n%s", err, buf.String())
|
||||
}
|
||||
want := map[string]int64{"jz_bm_courses": 2, "jz_bm_class_sessions": 2, "jz_bm_readings": 1, "jz_bm_meetings": 2, "jz_bm_deadlines": 2}
|
||||
for table, n := range want {
|
||||
if got := count(t, gdb, table); got != n {
|
||||
t.Errorf("after prune %s = %d rows, want %d", table, got, n)
|
||||
}
|
||||
}
|
||||
var orphan int64
|
||||
gdb.Model(&models.Deadline{}).Where("title = ? AND course_id IS NULL", "Esej przykładowy").Count(&orphan)
|
||||
if orphan != 1 {
|
||||
t.Error("the deadline of the pruned course was not unlinked")
|
||||
}
|
||||
|
||||
// Without --prune the same file deletes nothing.
|
||||
seedFixture(t, plugins, "testdata/seed.example.json")
|
||||
buf.Reset()
|
||||
if err := bonfire.Call(t.Context(), bmPlugin(t, plugins).Commands(), "bm:seed", []string{next}, &buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// The fixture brought back course a-c (its session) and b-k next to b.
|
||||
if got := count(t, gdb, "jz_bm_courses"); got != 4 || strings.Contains(buf.String(), "deleted:") {
|
||||
t.Errorf("seed without --prune deleted rows: %d courses\n%s", got, buf.String())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user