Monorepo for Tangled
tangled.org
1package knotacl
2
3import (
4 "context"
5 "slices"
6 "testing"
7
8 "tangled.org/core/appview/db"
9 "tangled.org/core/orm"
10)
11
12func registerOwner(t *testing.T, d *db.DB, host, ownerDid string) {
13 t.Helper()
14 if err := db.AddKnot(d, host, ownerDid); err != nil {
15 t.Fatalf("AddKnot: %v", err)
16 }
17 if err := db.MarkRegistered(d, orm.FilterEq("domain", host), orm.FilterEq("did", ownerDid)); err != nil {
18 t.Fatalf("MarkRegistered: %v", err)
19 }
20}
21
22func TestService_IsKnotMemberNative(t *testing.T) {
23 ctx := context.Background()
24 svc, d, host := newServiceEnv(t, &fakeKnot{version: "v1.15.0", capabilities: capsKnotACL, members: []string{testCollab}}, nil)
25
26 if !svc.IsKnotMember(ctx, host, testCollab) {
27 t.Error("a did in the native listMembers must read as a member")
28 }
29 if svc.IsKnotMember(ctx, host, testStrange) {
30 t.Error("a stranger must not read as a member")
31 }
32
33 registerOwner(t, d, host, testOwner)
34 if !svc.IsKnotMember(ctx, host, testOwner) {
35 t.Error("a registered owner must read as a member of its own native knot")
36 }
37}
38
39func TestService_IsKnotMemberLegacy(t *testing.T) {
40 ctx := context.Background()
41 svc, _, host := newServiceEnv(t, &fakeKnot{version: "v1.14.0"}, nil)
42
43 if !svc.IsKnotMember(ctx, host, testOwner) {
44 t.Error("the casbin-seeded owner must read as a member on an old knot")
45 }
46 if svc.IsKnotMember(ctx, host, testStrange) {
47 t.Error("a stranger must not read as a member on an old knot")
48 }
49}
50
51func TestService_KnotsForUserNativeMemberAndOwner(t *testing.T) {
52 ctx := context.Background()
53 svc, d, host := newServiceEnv(t, &fakeKnot{version: "v1.15.0", capabilities: capsKnotACL, members: []string{testCollab}}, nil)
54 registerOwner(t, d, host, testOwner)
55
56 if got := svc.KnotsForUser(ctx, testCollab); !slices.Contains(got, host) {
57 t.Errorf("KnotsForUser(member) = %v; a native member must surface via the listMembers fan-out, not casbin", got)
58 }
59 if got := svc.KnotsForUser(ctx, testOwner); !slices.Contains(got, host) {
60 t.Errorf("KnotsForUser(owner) = %v, want the registered knot", got)
61 }
62 if got := svc.KnotsForUser(ctx, testStrange); slices.Contains(got, host) {
63 t.Errorf("KnotsForUser(stranger) = %v, want the knot omitted", got)
64 }
65}
66
67func TestService_KnotsForUserNativeListDownDegrades(t *testing.T) {
68 ctx := context.Background()
69 svc, d, host := newServiceEnv(t, &fakeKnot{version: "v1.15.0", capabilities: capsKnotACL, listStatus: 500, members: []string{testCollab}}, nil)
70 registerOwner(t, d, host, testOwner)
71
72 if got := svc.KnotsForUser(ctx, testOwner); !slices.Contains(got, host) {
73 t.Errorf("KnotsForUser(owner) = %v; an owner must surface from registrations even when the knot list is down", got)
74 }
75 if got := svc.KnotsForUser(ctx, testCollab); slices.Contains(got, host) {
76 t.Errorf("KnotsForUser(member) = %v; a member must not surface when the bounded fan-out cannot reach the knot", got)
77 }
78}