|
|
@@ -10,6 +10,18 @@ from harness import * # noqa: F401,F403
|
|
|
def run(ctx):
|
|
|
admin = ctx.auth
|
|
|
|
|
|
+ def login_frames(username, password):
|
|
|
+ """The login action's FULL directive chain (the harness login()
|
|
|
+ only keeps the auth slot; the ui seed rides the same chain)."""
|
|
|
+ frames = directives("/login")
|
|
|
+ content = json.loads(frames[0]["snapshot_frame"]["content"])
|
|
|
+ action = content["public"]["login"]
|
|
|
+ status, body = http(action.get("method", "POST"), action["uri"],
|
|
|
+ {"username": username, "password": password})
|
|
|
+ if status != 200:
|
|
|
+ raise SystemExit("login -> HTTP %d: %s" % (status, body[:300]))
|
|
|
+ return json.loads(body)
|
|
|
+
|
|
|
print("== profile page: the appearance card ==")
|
|
|
profile = slot_public(admin, "/profile", "profile")
|
|
|
check(profile.get("set_theme") is not None,
|
|
|
@@ -99,21 +111,14 @@ def run(ctx):
|
|
|
"profile reads the core default back")
|
|
|
|
|
|
print("== login seeds the ui slot from stored prefs ==")
|
|
|
- fresh = login("admin", "adminpass123")
|
|
|
- seeded = [d for d in directives("/", fresh)
|
|
|
+ # The seed rides the LOGIN response's directive chain (the same
|
|
|
+ # builder Spry's login action returns, extended by our subclass) -
|
|
|
+ # so assert it there, not on a later entrypoint.
|
|
|
+ frames = login_frames("admin", "adminpass123")
|
|
|
+ seeded = [d for d in frames
|
|
|
if d["type"] == "set"
|
|
|
and json.loads(d["snapshot_frame"]["content"])["slot"]["type"] == "ui"]
|
|
|
- # The DEVICE slot is client-held; a fresh login (a browser with no
|
|
|
- # cached frame) gets it seeded on the same directive chain as the
|
|
|
- # auth slot.
|
|
|
- if seeded:
|
|
|
- seeded_public = json.loads(seeded[0]["snapshot_frame"]["content"])["public"]
|
|
|
- check(seeded_public.get("theme") == "" and seeded_public.get("mode") == "light",
|
|
|
- "login seeds the ui slot from the stored preferences")
|
|
|
- else:
|
|
|
- # The entrypoint chain does not re-emit a held DEVICE slot when
|
|
|
- # the request already carries one; assert the seed indirectly
|
|
|
- # through the profile's mirror of the stored values instead.
|
|
|
- profile = slot_public(fresh, "/profile", "profile")
|
|
|
- check(profile.get("theme") == "" and profile.get("mode") == "light",
|
|
|
- "stored preferences survive a re-login (profile mirror)")
|
|
|
+ check(len(seeded) == 1, "the login response answers a ui slot")
|
|
|
+ seeded_public = json.loads(seeded[0]["snapshot_frame"]["content"])["public"]
|
|
|
+ check(seeded_public.get("theme") == "" and seeded_public.get("mode") == "light",
|
|
|
+ "login seeds the ui slot from the stored preferences")
|