"""Regression tests for argument aggregation (#233). Both tests cover the same 2026-08-05 incident from different angles: the appellant side of 1069-04-26 sent 310 propositions in one Claude call, the call came back as something other than a JSON array, and the code logged a warning and returned ``[]``. The caller could not tell that apart from "this side has no arguments", so ``aggregate_claims_to_arguments`` reported ``completed`` with the central litigant of the appeal missing entirely. """ from __future__ import annotations import pytest from legal_mcp.services.argument_aggregator import ( MAX_PROPS_PER_CALL, AggregationFailed, _aggregate_party, _chunk, ) def test_chunk_preserves_every_proposition_and_their_order(): """Chunking must not drop or reorder — losing claims here is invisible.""" props = [{"i": i} for i in range(310)] chunks = _chunk(props, MAX_PROPS_PER_CALL) assert sum(len(c) for c in chunks) == 310, "propositions were lost" assert [p for c in chunks for p in c] == props, "order changed" assert all(len(c) <= MAX_PROPS_PER_CALL for c in chunks) @pytest.mark.asyncio async def test_non_list_reply_raises_instead_of_dropping_the_side(monkeypatch): """A malformed reply must surface, never look like an empty side. This is the exact 1069-04-26 failure. If this test ever goes back to asserting ``== []``, the silent-drop bug has been reintroduced. """ async def _query_json(prompt, tools=""): # noqa: ARG001 return {"error": "not a list"} monkeypatch.setattr( "legal_mcp.services.argument_aggregator.claude_session.query_json", _query_json, ) with pytest.raises(AggregationFailed) as excinfo: await _aggregate_party("appellant", [{"id": "x", "claim_text": "t"}]) # The message has to name the side, or an operator reading # completed_with_errors cannot tell which litigant went missing. assert "appellant" in str(excinfo.value)