; Phase 4 — visibility (ACL) + federation, and the end-to-end timeline. ; (feed-test name got expected) ; ---------- ACL visibility ---------- ; pub: public. sec: bob, allows carol. dm: frank, allows dave. (define C (feed/stream (list (feed/normalize {:actor "alice" :object "pub" :at 10}) (feed/normalize {:actor "bob" :object "sec" :visible-to (list "carol") :at 20}) (feed/normalize {:actor "frank" :object "dm" :visible-to (list "dave") :at 30})))) (feed-test "public visible to anyone" (feed/count (feed/visible C "zoe" feed/permit-acl?)) 1) (feed-test "carol sees allowlisted + public" (feed/count (feed/visible C "carol" feed/permit-acl?)) 2) (feed-test "dave sees dm + public" (feed/count (feed/visible C "dave" feed/permit-acl?)) 2) (feed-test "author always sees own private" (feed/count (feed/visible C "frank" feed/permit-acl?)) 2) (feed-test "permit-public? lets all through" (feed/count (feed/visible C "zoe" feed/permit-public?)) 3) (feed-test "visible objects for dave" (map (fn (a) (get a :object)) (feed/items (feed/visible C "dave" feed/permit-acl?))) (list "pub" "dm")) ; per-viewer: same stream, different timelines (feed-test "zoe timeline differs from carol" (not (= (feed/count (feed/visible C "zoe" feed/permit-acl?)) (feed/count (feed/visible C "carol" feed/permit-acl?)))) true) ; ---------- federation: merge / ingest ---------- (define L (feed/stream (list (feed/activity "alice" "post" "p1" 10 (list)) (feed/activity "alice" "post" "p2" 20 (list))))) (define P (feed/stream (list (feed/activity "alice" "post" "p2" 20 (list)) (feed/activity "peer" "post" "p9" 25 (list))))) (feed-test "merge concatenates" (feed/count (feed/merge L P)) 4) (feed-test "ingest dedupes overlap" (feed/count (feed/ingest L P)) 3) (feed-test "inbound normalizes + ingests" (feed/count (feed/inbound L (list {:actor "peer" :object "p9" :at 25} {:actor "alice" :object "p1" :at 10}))) 3) ; backfill via injected fetch-fn (define peer-history (fn (peer-id) (list {:actor peer-id :object "h1" :at 1} {:actor peer-id :object "h2" :at 2}))) (feed-test "backfill merges peer history" (feed/count (feed/backfill L peer-history "remote")) 4) (feed-test "backfill objects present" (map (fn (a) (get a :object)) (feed/items (feed/by-actor (feed/backfill L peer-history "remote") "remote"))) (list "h1" "h2")) ; ---------- federation: outbound partition ---------- ; bob (local), alice@remote + carol@remote (remote) follow star (define Gf (feed/follow-graph (list (list "bob" "star") (list "alice@remote" "star") (list "carol@remote" "star")))) (define Sf (feed/stream (list (feed/activity "star" "post" "s1" 1 (list))))) (define remote? (fn (id) (feed/-elem? id (list "alice@remote" "carol@remote")))) (define parts (feed/federate Sf Gf remote?)) (feed-test "local deliveries" (feed/count (get parts :local)) 1) (feed-test "remote deliveries" (feed/count (get parts :remote)) 2) (feed-test "local recipient is bob" (feed/recipients (get parts :local)) (list "bob")) ; deliver: send-fn receives each remote event, local inbox returned (define sent (list)) (define send-fn (fn (to act) (set! sent (append sent (list to))))) (define local-inbox (feed/deliver Sf Gf remote? send-fn)) (feed-test "deliver returns local inbox" (feed/count local-inbox) 1) (feed-test "deliver sent to both remotes" (len sent) 2) (feed-test "deliver remote targets" sent (list "alice@remote" "carol@remote")) ; ---------- end-to-end: federated, ACL-filtered, ranked timeline ---------- (define base (feed/stream (list (feed/normalize {:actor "alice" :object "a1" :at 100}) (feed/normalize {:actor "bob" :object "b1" :visible-to (list "carol") :at 90}) (feed/normalize {:actor "eve" :object "e1" :visible-to (list "dave") :at 80})))) (define federated (feed/inbound base (list {:actor "peer" :object "x1" :at 110}))) (define rec (feed/recency 120 10)) (define carol-tl (feed/timeline federated "carol" feed/permit-acl? rec 3)) ; eve's :visible-to excludes carol -> filtered out; peer/alice public, bob allows carol (feed-test "carol federated timeline count" (feed/count carol-tl) 3) (feed-test "carol timeline order (recency)" (map (fn (a) (get a :object)) (feed/items carol-tl)) (list "x1" "a1" "b1")) (feed-test "eve dm excluded from carol" (feed/-elem? "e1" (map (fn (a) (get a :object)) (feed/items carol-tl))) false) (feed-test "dave sees eve dm not bob" (map (fn (a) (get a :object)) (feed/items (feed/timeline federated "dave" feed/permit-acl? rec 5))) (list "x1" "a1" "e1"))