Skip to content

test: integration coverage for basic group-DM lifecycle#59

Merged
jackparnell merged 2 commits into
mainfrom
feat/integration-tests-group-dm
May 27, 2026
Merged

test: integration coverage for basic group-DM lifecycle#59
jackparnell merged 2 commits into
mainfrom
feat/integration-tests-group-dm

Conversation

@ColonistOne
Copy link
Copy Markdown
Collaborator

Summary

Adds tests/integration/test_group_messages.py exercising the basic group-DM round trip against the real Colony API. Uses the pre-existing two test accounts (COLONY_TEST_API_KEY + COLONY_TEST_API_KEY_2) and the existing rate-limit / auth / karma-gate skip plumbing in conftest.py.

Coverage:

  • create_group_conversation (primary invites secondary)
  • get_group_conversation visibility from creator + invitee
  • respond_to_group_invite — both accept=True and accept=False paths
  • send_group_message round trip in both directions after acceptance
  • list_group_members consistency between creator and invitee views
  • mark_group_all_read

Fixtures:

  • accepted_groupmodule-scoped, created once and reused by all "happy path" tests so the suite doesn't burn create-group rate-limit budget per test.
  • pending_groupfunction-scoped, so accept / decline / pending-status tests each get a clean room.

Both fixtures best-effort-clean-up by calling remove_group_member on the invitee in teardown. There's no delete_group_conversation endpoint, so the rows persist on the creator's side — same shape as how test_posts.py artifacts work, and tester accounts are flagged is_tester so the rooms stay off public listings.

Karma gate is handled the same way as test_messages.py: each test skips cleanly if the sending account is below the 5-karma threshold the server enforces on DM eligibility (which group invites also pass through). Jack — flagging that the test accounts may need a karma bump before these will actually run; we'll see when you fire them locally.

Test plan

  • pytest tests/integration/test_group_messages.py --collect-only -q — 8 tests collected
  • pytest tests/integration/test_group_messages.py (no env var) — all 8 auto-skip cleanly via the conftest's pytest_collection_modifyitems hook
  • pytest -m "not integration" — full unit-test suite still passes (661 tests)
  • ruff check tests/integration/test_group_messages.py — clean
  • ruff format --check tests/integration/test_group_messages.py — clean
  • Run end-to-end against the real API with both test keys (deferred — Jack to confirm karma budget and run locally before merge)

Per the TheColonyCC/* convention, holding the merge button for a human reviewer.

🤖 Generated with Claude Code

Adds tests/integration/test_group_messages.py covering the round
trip across two real test accounts:

- create_group_conversation (primary invites secondary)
- get_group_conversation visibility from creator + invitee
- respond_to_group_invite (accept + decline branches)
- send_group_message round trip (both directions after accept)
- list_group_members consistency across both sides
- mark_group_all_read

Module-scoped accepted_group fixture keeps create-group calls down
for the rate-limit budget; per-test pending_group fixture is
function-scoped so accept/decline tests get clean rooms.

Karma gate is handled the same way as test_messages.py: tests skip
cleanly if the sending account is below the 5-karma threshold.

Also extends tests/integration/README.md so the new file shows up
in the test-scope table.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented May 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Live API run against the integration-tester / integration-tester-2
account pair surfaced three places where the docstring shape didn't
match server reality:

1. get_group_conversation returns a slim envelope: {id, title,
   description, creator_id, member_count, messages, pinned}. No
   is_group, no my_invite_status, no members[]. Membership lives on
   the dedicated list_group_members endpoint.
2. Invites between these two accounts auto-accept on creation —
   respond_to_group_invite returns 400 "Invite is not pending".
   Likely a trust-level / follow gate bypass for accounts with
   prior DM history.
3. mark_group_all_read returns {marked: int}, not {marked_read: int}.

Rewrites the test file to:

- Drop assertions on get_group_conversation fields that don't exist
  (is_group, my_invite_status); assert on what's actually returned
  (id, title, member_count).
- Replace the pending → accept → decline lifecycle tests with a
  single TestGroupInviteAcceptPath::test_accept_invite_when_pending
  that probes for a pending invite and skips with a clear reason
  when the server auto-accepted. A future run against accounts with
  no trust relationship will cover the accept path automatically.
- Use the module-scoped `group` fixture with a defensive
  contextlib.suppress(ColonyAPIError) around the accept call, so it
  works whether the invite was pending or auto-accepted.
- Accept either `marked` or `marked_read` in test_mark_group_all_read.
- Document the observed-vs-docstring divergence in the module
  docstring so the SDK author can decide whether to update the
  client docstrings.

Live run: 7 passed, 1 skipped (accept path).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@ColonistOne
Copy link
Copy Markdown
Collaborator Author

Live-API run results (updated commit ce62ef0):

Ran against the integration tester accounts (integration-tester-account + integration-tester-2-8c9156, both at karma 15+ / trust level "Member"):

7 passed, 1 skipped in 6.31s

The skip is TestGroupInviteAcceptPath::test_accept_invite_when_pending, which probes whether the secondary's invite is actually pending and skips with a clear reason if not — see below.

Three docstring vs server shape divergences surfaced by the live run

These are in src/colony_sdk/client.py, not in the new tests — the tests now match server reality, but the SDK docstrings should be updated separately if you want to fix the source of truth:

  1. get_group_conversation returns a slim envelope{id, title, description, creator_id, member_count, messages, pinned}. The docstring claims {id, title, description, is_group, creator_id, members, messages, my_role, my_invite_status, total_others} — but is_group, my_invite_status, my_role, total_others, and members[] are all absent from the response. Membership lives on the dedicated list_group_members endpoint.

  2. Invites auto-accept between trusted accounts — the docstring describes a pending → accepted lifecycle via respond_to_group_invite, but for these two tester accounts (which have prior DM history / mutual trust), the secondary is added as a full member at creation time and respond_to_group_invite returns 400 "Invite is not pending". The lifecycle is presumably real for fresh / non-trusting account pairs, just bypassed here. The new TestGroupInviteAcceptPath detects this and skips with a clear reason; a future run against accounts with no trust relationship will exercise the accept path automatically.

  3. mark_group_all_read returns {marked: int}, not {marked_read: int} — the test accepts either key in case the field name is corrected server-side later.

The new test file documents all three observations in its module docstring so future contributors can see why certain assertions look the way they do. Happy to open a separate follow-up PR against client.py to align the docstrings if useful.

@jackparnell jackparnell merged commit 2378eb8 into main May 27, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants