Uncommit feature in character creation
Players can now unlock and revise any reasonably revisable choice while character creation is ongoing: basic Rat Records (also in recruit creation), submitted techniques (until the swap phase begins), J/Q/K face-card assignments (until everyone is ready), and Like/Hate answers written for crewmates. New endpoints unsubmit-techniques and unassign-face-techniques clear the locked-in state server-side so the phase machine waits for the revision. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1124,6 +1124,84 @@ def test_submit_techniques_rejects_collisions(session):
|
||||
session.refresh(game)
|
||||
assert game.phase == "swap_techniques"
|
||||
|
||||
def test_unsubmit_techniques(session):
|
||||
game = crud.create_game(session)
|
||||
p1 = crud.add_player(session, game.id, "P1", is_creator=True)
|
||||
p2 = crud.add_player(session, game.id, "P2")
|
||||
game.phase = "character_creation"
|
||||
session.add(game)
|
||||
session.commit()
|
||||
|
||||
# Nothing to unlock before submitting
|
||||
ok, _ = crud.unsubmit_techniques(session, p1.id)
|
||||
assert not ok
|
||||
|
||||
err = crud.submit_techniques(session, p1.id, "Tail Whip", "Pocket Sand", "Cheese Decoy")
|
||||
assert err is None
|
||||
|
||||
# Unlock clears the submission so it can be revised
|
||||
ok, msg = crud.unsubmit_techniques(session, p1.id)
|
||||
assert ok, msg
|
||||
session.refresh(p1)
|
||||
assert json.loads(p1.created_techniques) == []
|
||||
|
||||
# Resubmitting (with everyone else done) still triggers the swap
|
||||
err = crud.submit_techniques(session, p2.id, "Plank Pirouette", "Bilge Bomb", "Rat King Roar")
|
||||
assert err is None
|
||||
err = crud.submit_techniques(session, p1.id, "Tail Whip", "Pocket Sand", "Cheese Decoy")
|
||||
assert err is None
|
||||
session.refresh(game)
|
||||
assert game.phase == "swap_techniques"
|
||||
|
||||
# Once swapping has begun, revision is locked out
|
||||
ok, _ = crud.unsubmit_techniques(session, p1.id)
|
||||
assert not ok
|
||||
|
||||
def test_unassign_face_techniques(session):
|
||||
game, p1, p2, p3 = make_swap_game(session)
|
||||
crud.auto_assign_techniques(session, game)
|
||||
session.refresh(game)
|
||||
assert game.phase == "scene_setup"
|
||||
# Wrong phase is rejected
|
||||
ok, _ = crud.unassign_face_techniques(session, p1.id)
|
||||
assert not ok
|
||||
|
||||
# Fresh game stopped in assign_techniques: two assign, one revises
|
||||
game, p1, p2, p3 = make_swap_game(session)
|
||||
game.phase = "assign_techniques"
|
||||
for p in (p1, p2, p3):
|
||||
p.swapped_techniques = p.created_techniques
|
||||
session.add(p)
|
||||
session.add(game)
|
||||
session.commit()
|
||||
|
||||
# Not assigned yet -> nothing to unlock
|
||||
ok, _ = crud.unassign_face_techniques(session, p1.id)
|
||||
assert not ok
|
||||
|
||||
t1 = json.loads(p1.swapped_techniques)
|
||||
ok, msg = crud.assign_face_card_techniques(session, p1.id, t1[0], t1[1], t1[2])
|
||||
assert ok, msg
|
||||
ok, msg = crud.unassign_face_techniques(session, p1.id)
|
||||
assert ok, msg
|
||||
session.refresh(p1)
|
||||
assert not p1.tech_jack and not p1.tech_queen and not p1.tech_king
|
||||
assert not p1.is_ready
|
||||
|
||||
# Others finishing while p1 is revising must not advance the game
|
||||
for p in (p2, p3):
|
||||
t = json.loads(p.swapped_techniques)
|
||||
ok, msg = crud.assign_face_card_techniques(session, p.id, t[0], t[1], t[2])
|
||||
assert ok, msg
|
||||
session.refresh(game)
|
||||
assert game.phase == "assign_techniques"
|
||||
|
||||
# p1 reassigns (swapped order) and the game moves on
|
||||
ok, msg = crud.assign_face_card_techniques(session, p1.id, t1[2], t1[0], t1[1])
|
||||
assert ok, msg
|
||||
session.refresh(game)
|
||||
assert game.phase == "scene_setup"
|
||||
|
||||
def make_swap_game(session):
|
||||
"""Helper: 3 players in the swap_techniques phase, each holding their own techniques."""
|
||||
game = crud.create_game(session)
|
||||
|
||||
Reference in New Issue
Block a user