Files
sm-bm-plugin/models/material_revision_test.go
Jakub Zych 237069c827 feat: revision-check material writes
- add jz_bm_materials.revision (default 1), read-only for GORM
- bump it only on content changes (models.ReviseMaterial)
- PUT /materials/{id} locks the row and answers 409 to a stale revision
- management answers carry revision and updated_at, the student detail
  carries revision
2026-11-08 23:33:34 +01:00

64 lines
2.6 KiB
Go

package models_test
import (
"testing"
"time"
"git.golem15.com/jakub/sm-bm-plugin/models"
)
func TestMaterialFingerprint(t *testing.T) {
str := func(s string) *string { return &s }
id := func(n uint) *uint { return &n }
base := func() models.Material {
return models.Material{
ID: 7, CourseID: id(1), MeetingID: id(2), Title: "Definicje", Type: "notatka",
Body: str("# Robertson\n"), Source: str("wykład"), URL: str("https://example.test/a"),
}
}
tags := []string{"globalizacja", "teoria-2"}
want := models.MaterialFingerprint(base(), tags)
if got := models.MaterialFingerprint(base(), []string{"teoria-2", "globalizacja"}); got != want {
t.Errorf("tag order changed the fingerprint: %s != %s", got, want)
}
changes := map[string]func(m *models.Material, tags *[]string){
"title": func(m *models.Material, _ *[]string) { m.Title = "Inne" },
"type": func(m *models.Material, _ *[]string) { m.Type = "link" },
"body": func(m *models.Material, _ *[]string) { m.Body = str("# Robertson\n\nwięcej\n") },
"source": func(m *models.Material, _ *[]string) { m.Source = str("seminarium") },
"url": func(m *models.Material, _ *[]string) { m.URL = str("https://example.test/b") },
"course": func(m *models.Material, _ *[]string) { m.CourseID = id(3) },
"no course": func(m *models.Material, _ *[]string) { m.CourseID = nil },
"meeting": func(m *models.Material, _ *[]string) { m.MeetingID = id(4) },
"tag": func(_ *models.Material, tags *[]string) { *tags = append(*tags, "nowy") },
"untag": func(_ *models.Material, tags *[]string) { *tags = (*tags)[:1] },
}
for name, change := range changes {
m, ts := base(), append([]string(nil), tags...)
change(&m, &ts)
if got := models.MaterialFingerprint(m, ts); got == want {
t.Errorf("a %s change kept the fingerprint", name)
}
}
empty, null := base(), base()
empty.Body, empty.Source, empty.URL = str(""), str(" "), str("")
null.Body, null.Source, null.URL = nil, nil, nil
if models.MaterialFingerprint(empty, tags) != models.MaterialFingerprint(null, tags) {
t.Error("blank and nil optional text give different fingerprints")
}
if models.MaterialFingerprint(base(), nil) != models.MaterialFingerprint(base(), []string{}) {
t.Error("nil and empty tag lists give different fingerprints")
}
now := time.Now()
other := base()
other.ID, other.PublishedAt, other.IsPrivate, other.AuthorUserID = 8, &now, true, id(9)
other.UpdatedAt, other.Revision = now, 5
if got := models.MaterialFingerprint(other, tags); got != want {
t.Errorf("published_at, is_private, author, id or revision changed the fingerprint: %s != %s", got, want)
}
}