feat: change order status by moving its Deck card between stacks
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V57jSQPqwkGG8BuAXg59X5
This commit is contained in:
parent
21e63685c9
commit
c10fd61c54
|
|
@ -556,6 +556,29 @@ async def list_orders(status: str = None) -> list:
|
|||
return orders
|
||||
|
||||
|
||||
async def update_order_status(order_id: int, status: str) -> dict:
|
||||
board = await _ensure_deck_board()
|
||||
if status not in board["stacks"]:
|
||||
raise ValueError(f"Unknown status: {status}")
|
||||
target_stack_id = board["stacks"][status]
|
||||
|
||||
stacks = await _deck_request("GET", f"/boards/{board['board_id']}/stacks")
|
||||
current_stack_id = None
|
||||
for stack in stacks:
|
||||
if any(c["id"] == order_id for c in stack.get("cards", [])):
|
||||
current_stack_id = stack["id"]
|
||||
break
|
||||
if current_stack_id is None:
|
||||
raise ValueError(f"Order {order_id} not found")
|
||||
|
||||
await _deck_request(
|
||||
"PUT",
|
||||
f"/boards/{board['board_id']}/stacks/{current_stack_id}/cards/{order_id}/reorder",
|
||||
{"stackId": target_stack_id, "order": 999},
|
||||
)
|
||||
return {"id": order_id, "status": status}
|
||||
|
||||
|
||||
def _decode_mime_words(value: str) -> str:
|
||||
parts = decode_header(value)
|
||||
decoded = []
|
||||
|
|
|
|||
|
|
@ -215,3 +215,51 @@ async def test_list_orders_filters_by_status():
|
|||
orders = await main.list_orders(status="Erledigt")
|
||||
|
||||
assert [o["id"] for o in orders] == [56]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_order_status_finds_current_stack_and_reorders():
|
||||
stacks_response = [
|
||||
{"id": 1, "title": "Offen", "cards": [{"id": 55, "title": "A"}]},
|
||||
{"id": 2, "title": "In Arbeit", "cards": []},
|
||||
{"id": 3, "title": "Erledigt", "cards": []},
|
||||
]
|
||||
|
||||
async def fake_deck_request(method, path, json_body=None):
|
||||
if (method, path) == ("GET", "/boards/10/stacks"):
|
||||
return stacks_response
|
||||
if method == "PUT":
|
||||
return {"id": 55}
|
||||
raise AssertionError(f"unexpected call {method} {path}")
|
||||
|
||||
with patch.object(main, "_ensure_deck_board", new=AsyncMock(return_value=_BOARD)), patch.object(
|
||||
main, "_deck_request", new=AsyncMock(side_effect=fake_deck_request)
|
||||
) as mock_req:
|
||||
result = await main.update_order_status(55, "In Arbeit")
|
||||
|
||||
assert result == {"id": 55, "status": "In Arbeit"}
|
||||
put_call = [c for c in mock_req.call_args_list if c.args[0] == "PUT"][0]
|
||||
_, path, body = put_call.args
|
||||
assert path == "/boards/10/stacks/1/cards/55/reorder"
|
||||
assert body == {"stackId": 2, "order": 999}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_order_status_raises_for_unknown_status():
|
||||
with patch.object(main, "_ensure_deck_board", new=AsyncMock(return_value=_BOARD)):
|
||||
with pytest.raises(ValueError):
|
||||
await main.update_order_status(55, "Storniert")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_order_status_raises_when_card_not_found():
|
||||
stacks_response = [
|
||||
{"id": 1, "title": "Offen", "cards": []},
|
||||
{"id": 2, "title": "In Arbeit", "cards": []},
|
||||
{"id": 3, "title": "Erledigt", "cards": []},
|
||||
]
|
||||
with patch.object(main, "_ensure_deck_board", new=AsyncMock(return_value=_BOARD)), patch.object(
|
||||
main, "_deck_request", new=AsyncMock(return_value=stacks_response)
|
||||
):
|
||||
with pytest.raises(ValueError):
|
||||
await main.update_order_status(999, "Erledigt")
|
||||
|
|
|
|||
Loading…
Reference in New Issue