diff --git a/Claude outputs/main.py b/Claude outputs/main.py index 5e9669d..e293df6 100644 --- a/Claude outputs/main.py +++ b/Claude outputs/main.py @@ -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 = [] diff --git a/Claude outputs/tests/test_orders.py b/Claude outputs/tests/test_orders.py index 73fef13..0bd9bef 100644 --- a/Claude outputs/tests/test_orders.py +++ b/Claude outputs/tests/test_orders.py @@ -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")