feat: private materials with per-user shares
A material may be private: only its author and the users it is shared
with see it. Every student read (list, detail, course detail and
counters, the checklist linked material, the token twins) goes through
one visibility fragment. Existing materials stay public with no author.
GET/PUT /_bm/api/v1/materials/{id}/access let the author, a material
manager, toggle the flag and pick the users; the first change of an
author-less material makes the caller its author.
This commit is contained in:
@@ -49,3 +49,44 @@ func TestMaterialJSONCarriesMeetingID(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestMaterialJSONCarriesPrivacy checks that is_private is always present in
|
||||
// a material and that the detail carries can_manage, false by default.
|
||||
func TestMaterialJSONCarriesPrivacy(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
private bool
|
||||
want string
|
||||
}{
|
||||
{true, `"is_private":true`},
|
||||
{false, `"is_private":false`},
|
||||
} {
|
||||
b, err := json.Marshal(newMaterialListJSON(models.Material{ID: 1, Title: "Materiał", Type: "pdf", IsPrivate: tc.private}, 0))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(b), tc.want) {
|
||||
t.Errorf("material JSON %s does not contain %s", b, tc.want)
|
||||
}
|
||||
}
|
||||
b, err := json.Marshal(materialDetailJSON{materialListJSON: newMaterialListJSON(models.Material{ID: 1, Title: "Materiał", Type: "pdf"}, 0)})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(b), `"can_manage":false`) {
|
||||
t.Errorf("material detail JSON %s does not contain can_manage false", b)
|
||||
}
|
||||
}
|
||||
|
||||
// TestVisibleMaterialSQL checks the visibility fragment: public, the author,
|
||||
// or a share of the caller, with the caller id bound twice.
|
||||
func TestVisibleMaterialSQL(t *testing.T) {
|
||||
got := visibleMaterialSQL("m")
|
||||
for _, want := range []string{"m.is_private = FALSE", "m.author_user_id = ?", "jz_bm_material_shares", ".material_id = m.id"} {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Errorf("visibleMaterialSQL(m) = %q, missing %q", got, want)
|
||||
}
|
||||
}
|
||||
if n := strings.Count(got, "?"); n != 2 {
|
||||
t.Errorf("visibleMaterialSQL(m) has %d placeholders, want 2", n)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user