;; identity/tests/introspect.sx — RFC 7662 §2.2 full introspection metadata ;; (sub, client_id, scope, exp, iat, token_type) alongside the live-lookup ;; active/inactive semantics. (define id-intr-test-count 0) (define id-intr-test-pass 0) (define id-intr-test-fails (list)) (define id-intr-test (fn (name actual expected) (set! id-intr-test-count (+ id-intr-test-count 1)) (if (= actual expected) (set! id-intr-test-pass (+ id-intr-test-pass 1)) (append! id-intr-test-fails {:name name :expected expected :actual actual})))) (define idi-ev erlang-eval-ast) (define idinm (fn (v) (get v :name))) (identity-load-token!) ;; ── metadata fields ────────────────────────────────────────────── (id-intr-test "introspect_full reports token_type bearer" (idinm (idi-ev "R = identity_tokens:start(),\n {ok, T} = identity_tokens:issue(R, alice, web, read, 100),\n case identity_tokens:introspect_full(R, T) of\n {active, _, _, _, _, _, Tt} -> Tt;\n {inactive} -> inactive\n end")) "bearer") (id-intr-test "introspect_full reports the subject" (idinm (idi-ev "R = identity_tokens:start(),\n {ok, T} = identity_tokens:issue(R, alice, web, read, 100),\n case identity_tokens:introspect_full(R, T) of\n {active, Sub, _, _, _, _, _} -> Sub\n end")) "alice") (id-intr-test "introspect_full reports the client_id" (idinm (idi-ev "R = identity_tokens:start(),\n {ok, T} = identity_tokens:issue(R, alice, mobile, read, 100),\n case identity_tokens:introspect_full(R, T) of\n {active, _, Cl, _, _, _, _} -> Cl\n end")) "mobile") (id-intr-test "introspect_full reports the scope" (idinm (idi-ev "R = identity_tokens:start(),\n {ok, T} = identity_tokens:issue(R, alice, web, write, 100),\n case identity_tokens:introspect_full(R, T) of\n {active, _, _, Sc, _, _, _} -> Sc\n end")) "write") ;; ── exp / iat reflect the logical clock ────────────────────────── (id-intr-test "iat is the clock value at issue" (idi-ev "R = identity_tokens:start(),\n identity_tokens:advance(R, 7),\n {ok, T} = identity_tokens:issue(R, alice, web, read, 100),\n case identity_tokens:introspect_full(R, T) of\n {active, _, _, _, _, Iat, _} -> Iat\n end") 7) (id-intr-test "exp is iat plus the ttl" (idi-ev "R = identity_tokens:start(),\n identity_tokens:advance(R, 7),\n {ok, T} = identity_tokens:issue(R, alice, web, read, 100),\n case identity_tokens:introspect_full(R, T) of\n {active, _, _, _, Exp, Iat, _} -> Exp - Iat\n end") 100) ;; ── inactive / expired / revoked ───────────────────────────────── (id-intr-test "an expired token introspects inactive in full mode too" (idinm (idi-ev "R = identity_tokens:start(),\n {ok, T} = identity_tokens:issue(R, alice, web, read, 100),\n identity_tokens:advance(R, 100),\n case identity_tokens:introspect_full(R, T) of\n {active, _, _, _, _, _, _} -> active;\n {inactive} -> inactive\n end")) "inactive") (id-intr-test "a revoked token introspects inactive in full mode" (idinm (idi-ev "R = identity_tokens:start(),\n {ok, T} = identity_tokens:issue(R, alice, web, read),\n identity_tokens:revoke(R, T),\n case identity_tokens:introspect_full(R, T) of\n {active, _, _, _, _, _, _} -> active;\n {inactive} -> inactive\n end")) "inactive") (id-intr-test "an unknown token introspects inactive in full mode" (idinm (idi-ev "R = identity_tokens:start(),\n Bogus = make_ref(),\n case identity_tokens:introspect_full(R, Bogus) of\n {active, _, _, _, _, _, _} -> active;\n {inactive} -> inactive\n end")) "inactive") (define id-intr-test-summary (str "introspect " id-intr-test-pass "/" id-intr-test-count))