Files
rose-ash/lib/identity/tests/facade.sx
giles d2f5b49d3f
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 19s
identity: unify api.sx facade over audit + membership (+9 tests)
The identity coordinator now owns an audit ledger and a membership registry
alongside its token table (started with the ledger) and session registry.
login/logout are audited; new ops history/enroll/member_status/member_project
surface the audit and membership axes through the one `identity` door.
Identity proves who and reports membership; acl still decides permission.
Existing api behaviour unchanged. New tests/facade.sx. 177/177.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 02:51:48 +00:00

98 lines
4.0 KiB
Plaintext

;; identity/tests/facade.sx — the unified facade: one coordinator wiring
;; sessions+tokens, the audit ledger, and membership. Exercises the
;; cross-module integration (login/logout auditing, audit history, member
;; enrollment + projection) through the single `identity` door.
(define id-facade-test-count 0)
(define id-facade-test-pass 0)
(define id-facade-test-fails (list))
(define
id-facade-test
(fn
(name actual expected)
(set! id-facade-test-count (+ id-facade-test-count 1))
(if
(= actual expected)
(set! id-facade-test-pass (+ id-facade-test-pass 1))
(append! id-facade-test-fails {:name name :expected expected :actual actual}))))
(define idfc-ev erlang-eval-ast)
(define idfcnm (fn (v) (get v :name)))
(identity-load-all!)
;; ── login + logout are audited through the ledger ────────────────
(id-facade-test
"login then logout records login, issue, logout in order"
(idfcnm
(idfc-ev
"Svc = identity:start(),\n {ok, Sid, _Tok} = identity:login(Svc, alice, web, read),\n identity:logout(Svc, Sid),\n case identity:history(Svc, alice) of\n [login, issue, logout] -> ordered;\n Other -> Other\n end"))
"ordered")
(id-facade-test
"revoking a token is audited"
(idfcnm
(idfc-ev
"Svc = identity:start(),\n {ok, _Sid, Tok} = identity:login(Svc, alice, web, read),\n identity:revoke(Svc, Tok),\n case identity:history(Svc, alice) of\n [login, issue, revoke] -> ordered;\n Other -> Other\n end"))
"ordered")
(id-facade-test
"history is per-subject"
(idfc-ev
"Svc = identity:start(),\n identity:login(Svc, alice, web, read),\n identity:login(Svc, bob, cli, read),\n identity:login(Svc, alice, mobile, read),\n length(identity:history(Svc, alice))")
4)
;; ── membership through the facade ────────────────────────────────
(id-facade-test
"enroll makes the subject an active member"
(idfcnm
(idfc-ev
"Svc = identity:start(),\n identity:enroll(Svc, alice, supporter),\n case identity:member_status(Svc, alice) of\n {ok, St, _} -> St;\n {none} -> none\n end"))
"active")
(id-facade-test
"enroll keeps the tier"
(idfcnm
(idfc-ev
"Svc = identity:start(),\n identity:enroll(Svc, alice, supporter),\n case identity:member_status(Svc, alice) of\n {ok, _, Tier} -> Tier\n end"))
"supporter")
(id-facade-test
"an enrolled member projects per-app"
(idfcnm
(idfc-ev
"Svc = identity:start(),\n identity:enroll(Svc, alice, basic),\n case identity:member_project(Svc, alice, market) of\n {member, _, App} -> App;\n {Tag, _} -> Tag\n end"))
"market")
(id-facade-test
"a non-member projects as non_member"
(idfcnm
(idfc-ev
"Svc = identity:start(),\n case identity:member_project(Svc, stranger, blog) of\n {member, _, _} -> member;\n {Tag, _} -> Tag\n end"))
"non_member")
;; ── the facade still proves identity ─────────────────────────────
(id-facade-test
"verify still returns the subject after login"
(idfcnm
(idfc-ev
"Svc = identity:start(),\n {ok, _Sid, Tok} = identity:login(Svc, alice, web, read),\n case identity:verify(Svc, Tok) of\n {active, Subject, _, _} -> Subject;\n {inactive} -> inactive\n end"))
"alice")
;; ── identity and membership are distinct axes ────────────────────
(id-facade-test
"logging in does not enroll membership"
(idfcnm
(idfc-ev
"Svc = identity:start(),\n identity:login(Svc, alice, web, read),\n case identity:member_status(Svc, alice) of\n {ok, St, _} -> St;\n {none} -> none\n end"))
"none")
(define
id-facade-test-summary
(str "facade " id-facade-test-pass "/" id-facade-test-count))