|
@@ -537,6 +537,62 @@ def run(ctx):
|
|
|
check(wait_task_done(auth, identity_task, timeout=60) is not None,
|
|
check(wait_task_done(auth, identity_task, timeout=60) is not None,
|
|
|
"identity task completes")
|
|
"identity task completes")
|
|
|
|
|
|
|
|
|
|
+ print("== goal 8 task 5: per-saddle prompt note ==")
|
|
|
|
|
+ # The admin edits the note on the /saddles card; it persists on the
|
|
|
|
|
+ # row and rides EVERY later assignment as `prompt_note`.
|
|
|
|
|
+ fake_card = saddle_card(auth, "fake-saddle")
|
|
|
|
|
+ check(fake_card.get("prompt_note", "") == "",
|
|
|
|
|
+ "no prompt note before the admin sets one")
|
|
|
|
|
+ check(all(p.get("prompt_note") == "" for p in fake.start_payloads),
|
|
|
|
|
+ "unset note carries an empty string (never a null)")
|
|
|
|
|
+ act(auth, fake_card["update_prompt_note"],
|
|
|
|
|
+ {"prompt_note": "You have root and may install development tooling via DNF."})
|
|
|
|
|
+ fake_card = saddle_card(auth, "fake-saddle")
|
|
|
|
|
+ check(fake_card.get("prompt_note") == "You have root and may install development tooling via DNF.",
|
|
|
|
|
+ "inline edit saves the prompt note")
|
|
|
|
|
+ note_task = create_queued(auth, {
|
|
|
|
|
+ "project_id": "1",
|
|
|
|
|
+ "title": "Prompt note task",
|
|
|
|
|
+ "priority": "2",
|
|
|
|
|
+ })
|
|
|
|
|
+ check(wait_for(lambda: any(int(p.get("task", {}).get("id") or 0) == note_task
|
|
|
|
|
+ for p in fake.start_payloads) or False,
|
|
|
|
|
+ timeout=60, what="prompt-note task dispatched") is not None,
|
|
|
|
|
+ "prompt-note task dispatches")
|
|
|
|
|
+ note_payload = [p for p in fake.start_payloads
|
|
|
|
|
+ if int(p.get("task", {}).get("id") or 0) == note_task][-1]
|
|
|
|
|
+ check(note_payload.get("prompt_note") == "You have root and may install development tooling via DNF.",
|
|
|
|
|
+ "the assignment carries the saddle's prompt_note verbatim")
|
|
|
|
|
+ check(wait_task_done(auth, note_task, timeout=60) is not None,
|
|
|
|
|
+ "prompt-note task completes")
|
|
|
|
|
+ # Clearing the note empties the member on later assignments.
|
|
|
|
|
+ fake_card = saddle_card(auth, "fake-saddle")
|
|
|
|
|
+ act(auth, fake_card["update_prompt_note"], {"prompt_note": ""})
|
|
|
|
|
+ check(saddle_card(auth, "fake-saddle").get("prompt_note", "") == "",
|
|
|
|
|
+ "clearing the prompt note empties the row")
|
|
|
|
|
+ # A fat note is clamped: the row keeps the full text but the wire
|
|
|
|
|
+ # serves at most PROMPT_NOTE_MAX_CHARS.
|
|
|
|
|
+ fat = "N" * 5000
|
|
|
|
|
+ fake_card = saddle_card(auth, "fake-saddle")
|
|
|
|
|
+ act(auth, fake_card["update_prompt_note"], {"prompt_note": fat})
|
|
|
|
|
+ clamp_task = create_queued(auth, {
|
|
|
|
|
+ "project_id": "1",
|
|
|
|
|
+ "title": "Clamp note task",
|
|
|
|
|
+ "priority": "2",
|
|
|
|
|
+ })
|
|
|
|
|
+ check(wait_for(lambda: any(int(p.get("task", {}).get("id") or 0) == clamp_task
|
|
|
|
|
+ for p in fake.start_payloads) or False,
|
|
|
|
|
+ timeout=60, what="clamp-note task dispatched") is not None,
|
|
|
|
|
+ "clamp-note task dispatches")
|
|
|
|
|
+ clamp_payload = [p for p in fake.start_payloads
|
|
|
|
|
+ if int(p.get("task", {}).get("id") or 0) == clamp_task][-1]
|
|
|
|
|
+ check(len(clamp_payload.get("prompt_note") or "") == 2000,
|
|
|
|
|
+ "a fat prompt_note is clamped to 2000 chars on the wire")
|
|
|
|
|
+ check(wait_task_done(auth, clamp_task, timeout=60) is not None,
|
|
|
|
|
+ "clamp-note task completes")
|
|
|
|
|
+ fake_card = saddle_card(auth, "fake-saddle")
|
|
|
|
|
+ act(auth, fake_card["update_prompt_note"], {"prompt_note": ""})
|
|
|
|
|
+
|
|
|
print("== phase 2: blocked push -> block row + pulse ==")
|
|
print("== phase 2: blocked push -> block row + pulse ==")
|
|
|
# The browser flow on each pulse: statum.act(task.refresh) — the
|
|
# The browser flow on each pulse: statum.act(task.refresh) — the
|
|
|
# sealed GET action must rehydrate the task slot with the new
|
|
# sealed GET action must rehydrate the task slot with the new
|