* core: channel messages (WIP) * do not include member ID when quoting channel messages * query plans * reduce duplication * refactor * refactor plan * refactor 2 * all tests * remove plan * refactor 3 * refactor 4 * refactor 5 * refactor 6 * plans * plans to imrove test coverage and fix bugs * update plan * update plan * bug fixes (wip) * new plan * fixes wip * more tests * comment, fix lint * restore comment * restore comments * rename param * move type * simplify * comment * fix stale state * refactor * less diff * simplify * less diff * refactor --------- Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com> Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
11 KiB
Plan: Filling Group/Channel Test Coverage Gaps
Table of Contents
- Executive Summary
- Test File Organization
- Priority 0: Critical Channel Paths
- Priority 1: Error and Fallback Paths
- Priority 2: Scope-Related Features
- Priority 3: Feature Restrictions
Executive Summary
This plan addresses the coverage gaps identified in groups_test_coverage.md, focusing exclusively on DSL-based scenario tests using the existing test infrastructure. All tests follow patterns established in tests/ChatTests/Groups.hs.
Excluded from scope: JSON serialization tests (per user request).
Key gap categories:
- Non-channel-owner members sending in channel groups
- Moderation/delete paths in channels (
memberDelete) - Error fallback paths (
catchCINotFound) - Member support scope (
GCSIMemberSupport) - Full-delete feature, live updates, mentions
Test File Organization
All new tests go in tests/ChatTests/Groups.hs under existing or new describe blocks.
New describe blocks to add:
describe "channel moderation" $ do
-- Tests for memberDelete path, channel moderation errors
describe "channel error paths" $ do
-- Tests for catchCINotFound, invalid sender, etc.
describe "channel mentions" $ do
-- Tests for mentions in channel messages
describe "group full delete feature" $ do
-- Tests for SGFFullDelete enabled
Priority 0: Critical Channel Paths
Test 1: testChannelMemberModerate
File: tests/ChatTests/Groups.hs
Add to: describe "channel moderation"
Objective: Cover memberDelete path in groupMessageDelete (lines 2016-2076) - moderation of channel messages by admin/owner.
Scenario:
- Create channel with owner (alice) + relay (bob) + members (cath, dan)
- Owner sends channel message
- Admin/owner moderates (deletes) the channel message
- Verify message marked deleted for all members
- Verify moderation event is forwarded
Coverage targets:
memberDeletefunction executionmoderatehelper with role checksdeletewithdelMember_populated
Test 2: testChannelMemberDeleteError
File: tests/ChatTests/Groups.hs
Add to: describe "channel error paths"
Objective: Cover error path CIChannelRcv -> messageError "x.msg.del: unexpected channel message in member delete" (line 2036).
Scenario:
- Create channel with owner + relay + member
- Attempt to trigger memberDelete on CIChannelRcv item (malformed delete request)
- Verify error is logged/handled correctly
Coverage targets:
- Line 2036:
CIChannelRcverror case inmemberDelete
Test 3: testChannelUpdateNotFound
File: tests/ChatTests/Groups.hs
Add to: describe "channel error paths"
Objective: Cover catchCINotFound fallback in groupMessageUpdate (lines 1950-1969) - update arrives for locally deleted item.
Scenario:
- Create channel with owner + relay + member
- Owner sends message, member receives
- Member locally deletes the message
- Owner updates the message
- Verify member creates new item from update (fallback path)
Coverage targets:
- Line 1960:
Nothing -> pure (CDChannelRcv gInfo Nothing, M.empty, Nothing) - Lines 1951-1969: create-from-update fallback
Test 4: testChannelReactionNotFound
File: tests/ChatTests/Groups.hs
Add to: describe "channel error paths"
Objective: Cover catchCINotFound fallback in groupMsgReaction (lines 1823-1837) - reaction on locally deleted item.
Scenario:
- Create channel with owner + relay + member
- Owner sends message, member receives
- Member locally deletes the message
- Owner adds reaction
- Verify reaction is handled without crash
Coverage targets:
- Lines 1835-1837: channel reaction fallback
Test 5: testChannelForwardedMessages
File: tests/ChatTests/Groups.hs
Add to: describe "relay delivery" (existing)
Objective: Cover FwdChannel branch in delivery task (line 3311) and forwarded message parameters.
Scenario:
- Create channel with owner + 2 relays + members
- Send various message types (new, update, delete, reaction)
- Verify all are forwarded through relay chain
- Check forwarded parameters are correctly passed
Coverage targets:
- Line 3311:
FwdChannel -> (Nothing, Nothing) - Lines 3139-3145: forwarded message handlers
Priority 1: Error and Fallback Paths
Test 6: testGroupDeleteNotFound
File: tests/ChatTests/Groups.hs
Add to: describe "channel error paths" or existing moderation tests
Objective: Cover delete error when message not found (line 2039).
Scenario:
- Create group with alice, bob
- Bob sends message
- Alice locally deletes it
- Bob broadcasts delete for the same message
- Verify error path is handled
Coverage targets:
- Line 2039:
messageError ("x.msg.del: message not found, " <> tshow e)
Test 7: testGroupInvalidSenderUpdate
File: tests/ChatTests/Groups.hs
Add to: describe "channel error paths"
Objective: Cover validSender _ _ = False (line 1874) and update from wrong member error (line 1980).
Scenario:
- Create group with alice, bob, cath
- Bob sends message
- Cath (with spoofed member ID) attempts to update bob's message
- Verify error is thrown
Coverage targets:
- Line 1874:
validSender _ _ = False - Line 1980:
messageError "x.msg.update: group member attempted to update..."
Test 8: testGroupReactionDisabled
File: tests/ChatTests/Groups.hs
Add to: existing describe "group message reactions"
Objective: Cover reaction disabled path (line 1839).
Scenario:
- Create group with reactions feature disabled
- Member attempts to add reaction
- Verify reaction is rejected
Coverage targets:
- Line 1839:
otherwise = pure Nothingwhen reactions not allowed
Test 9: testChannelItemNotChanged
File: tests/ChatTests/Groups.hs
Add to: describe "channel message operations" (existing)
Objective: Cover CEvtChatItemNotChanged path (lines 2001-2002) - update with same content.
Scenario:
- Create channel with owner + relay + member
- Owner sends message
- Owner "updates" message with identical content
- Verify no change event is emitted
Coverage targets:
- Lines 2001-2002:
CEvtChatItemNotChangedpath
Priority 2: Scope-Related Features
Test 10: testScopedSupportMentions
File: tests/ChatTests/Groups.hs
Add to: describe "group scoped messages" (existing)
Objective: Cover mentions in scoped support messages (getRcvCIMentions with non-empty mentions).
Scenario:
- Create group with alice (owner), bob (member), dan (moderator)
- Bob sends support message mentioning @alice
- Alice receives with mention highlighted
- Verify
userMentionflag is set correctly
Coverage targets:
- Line 2316:
getRcvCIMentionswith actual mentions - Line 2319:
sameMemberId mId membershipin userReply check - Lines 279-281:
uniqueMsgMentionspath
Test 11: testMemberChatStats
File: tests/ChatTests/Groups.hs
Add to: describe "group scoped messages" (existing)
Objective: Cover memberChatStats function (lines 2323-2330) for both CDGroupRcv and CDChannelRcv with scope.
Scenario:
- Create group with support enabled
- Member sends support message
- Verify unread stats are updated
- Verify
memberAttentionChangeis computed
Coverage targets:
- Lines 2325-2329:
memberChatStatsbranches - Line 2621:
memberAttentionChange
Note: Tests testScopedSupportUnreadStatsOnRead and testScopedSupportUnreadStatsOnDelete exist but may not cover all branches.
Test 12: testMkGetMessageChatScope
File: tests/ChatTests/Groups.hs
Add to: describe "group scoped messages" (existing)
Objective: Cover mkGetMessageChatScope branches (lines 1599-1617).
Scenario:
- Create group with pending member (knocking)
- Pending member sends message with scope
- Verify correct scope resolution
- Test with
isReport mccontent type
Coverage targets:
- Line 1601:
Just _scopeInforeturn - Line 1604:
isReport mcbranch - Lines 1610-1617:
sameMemberIdandotherwisebranches
Priority 3: Feature Restrictions
Test 13: testGroupFullDelete
File: tests/ChatTests/Groups.hs
Add to: new describe "group full delete feature"
Objective: Cover groupFeatureAllowed SGFFullDelete = True path (line 2067) - deleteGroupCIs instead of markGroupCIsDeleted.
Scenario:
- Create group with full delete enabled:
/set delete #team on - Bob sends message
- Alice (or bob) deletes message
- Verify message is fully deleted (not just marked)
Coverage targets:
- Line 2067:
deleteGroupCIspath groupFeatureAllowed SGFFullDeletereturns True
Test 14: testGroupLiveMessage
File: tests/ChatTests/Groups.hs
Note: testGroupLiveMessage exists but may not cover update path.
Objective: Cover live message update path (line 830 in View.hs, itemLive == Just True).
Scenario:
- Create group
- Send live message
- Update live message content
- Verify live update is processed
Coverage targets:
- Line 830:
itemLive == Just True && not liveItems -> [] - Live update in
groupMessageUpdate
Test 15: testGroupVoiceDisabled
File: tests/ChatTests/Groups.hs
Add to: existing tests or new describe "group feature restrictions"
Objective: Cover voice message rejection (line 342 in Internal.hs).
Scenario:
- Create group with voice disabled:
/set voice #team off - Member attempts to send voice message
- Verify rejection
Coverage targets:
- Line 342:
isVoice mc && not (groupFeatureMemberAllowed SGFVoice m gInfo)
Test 16: testGroupReportsDisabled
File: tests/ChatTests/Groups.hs
Add to: describe "group member reports" (existing)
Objective: Cover reports disabled path (line 344 in Internal.hs).
Scenario:
- Create group with reports disabled
- Member attempts to send report
- Verify rejection
Coverage targets:
- Line 344:
isReport mc && ... not (groupFeatureAllowed SGFReports gInfo)
Implementation Order
- Phase 1 (P0): Tests 1-5 - Critical channel paths
- Phase 2 (P1): Tests 6-9 - Error and fallback paths
- Phase 3 (P2): Tests 10-12 - Scope-related features
- Phase 4 (P3): Tests 13-16 - Feature restrictions
Each test should:
- Use existing DSL operators (
##>,<#,#$>, etc.) - Follow naming convention
test<Feature><Scenario> - Include
HasCallStackconstraint - Use appropriate test helpers (
createGroup2,createChannel1Relay, etc.)
Dependencies
- Existing test infrastructure in
ChatTests.Utils - Helper functions:
createChannel1Relay,createGroup2,createGroup3, etc. - DSL operators for assertions
Estimated New Tests: 16
Files Modified: 1
tests/ChatTests/Groups.hs