fix(talk): address remaining PR #741 reviewer feedback

Closes the seven outstanding items from the @claude review on PR #741:

1. Add empty `tests/client/talk/__init__.py` for pytest discovery parity
   with `tests/client/{collectives,news}/`.
2. Standardise boolean query params to integers — `includeStatus` was the
   string `"true"` in `list_conversations`/`list_participants` while every
   other flag (`noStatusUpdate`, `lookIntoFuture`, `setReadMarker`,
   `includeLastKnown`) used `1`/`0`.
3. Replace the `app:install || app:enable` chain in the spreed install hook
   with `app:install --keep-disabled --force || true; app:enable spreed`,
   so unrelated install failures surface as a clear "app not found" from
   `app:enable` rather than being silently masked.
4. Add `_validate_token()` (alphanumeric whitelist) and call it from all
   six TalkClient methods that interpolate the token into a URL path —
   defence-in-depth against pathological tokens reaching httpx.
5. Rename `TalkConversation.type` to `room_type` with `Field(alias="type")`
   and `populate_by_name=True`, so the field no longer shadows Python's
   builtin while preserving spreed's wire format on input. MCP responses
   now serialize `room_type` (field name) instead of `type`.
6. `mark_as_read` now passes `json=body or None` so the bodyless
   "mark everything as read" call doesn't send a spurious `{}` body and
   `Content-Type: application/json` header.
7. `_validate_message_text` rejects whitespace-only messages, not just
   empty strings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-04-30 01:14:32 +02:00
co-authored by Claude Opus 4.7
parent 9614c0b361
commit f075540232
7 changed files with 119 additions and 26 deletions
+10 -5
View File
@@ -131,16 +131,21 @@ async def test_talk_list_participants(
assert len(actor_ids) >= 1
async def test_talk_send_message_validation_empty_text(
nc_mcp_client: ClientSession, temporary_conversation: dict
@pytest.mark.parametrize("blank_text", ["", " ", "\t\n", " \t \n "])
async def test_talk_send_message_validation_blank_text(
nc_mcp_client: ClientSession,
temporary_conversation: dict,
blank_text: str,
):
"""Empty message text is rejected client-side."""
"""Empty and whitespace-only message text are rejected client-side."""
token = temporary_conversation["token"]
result = await nc_mcp_client.call_tool(
"talk_send_message", {"token": token, "message": ""}
"talk_send_message", {"token": token, "message": blank_text}
)
assert result.isError is True, (
f"Expected validation error for blank message {blank_text!r}"
)
assert result.isError is True, "Expected validation error for empty message"
async def test_talk_send_message_validation_too_long(