From e0e90af9fdb383ee2ee740bbf310bbc5f15e20b9 Mon Sep 17 00:00:00 2001 From: jack Date: Mon, 6 Jul 2026 22:38:45 +0200 Subject: [PATCH] Integration test fixes: reconcile SyncTypeFlags phantom-bit assertions and sync-round counts - SyncTypeFlags phantom-bit tests used bits 8/9/10 as unmapped examples; board/prekey/group now map those, so use bits 11+ (still unmapped). - rawValueInitNormalizesPhantomBits: highest known bit is now 10, so the flags serialize to 2 bytes, not 1. - Board/fragment/announce sync tests silence the prekey round (added by the prekeys feature; default 60s schedule fires at the maintenance barrier). - DiagnosticsMockContext: conform to the CommandContextProvider members added by private-groups (group*) and cashu-chips (sendPublicMessage). Co-Authored-By: Claude Fable 5 --- bitchatTests/GossipSyncManagerTests.swift | 4 ++++ .../Services/MeshDiagnosticsTests.swift | 6 ++++++ bitchatTests/Sync/GossipSyncBoardTests.swift | 3 +++ bitchatTests/Sync/SyncTypeFlagsBoardTests.swift | 9 +++++---- bitchatTests/Sync/SyncTypeFlagsTests.swift | 17 ++++++++++------- 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/bitchatTests/GossipSyncManagerTests.swift b/bitchatTests/GossipSyncManagerTests.swift index ef9be2b9..76ffdb77 100644 --- a/bitchatTests/GossipSyncManagerTests.swift +++ b/bitchatTests/GossipSyncManagerTests.swift @@ -370,6 +370,8 @@ struct GossipSyncManagerTests { config.messageSyncIntervalSeconds = 0 config.fragmentSyncIntervalSeconds = 0 config.fileTransferSyncIntervalSeconds = 0 + // Silence the prekey round so the maintenance barrier below emits nothing. + config.prekeyBundleSyncIntervalSeconds = 0 let requestSyncManager = RequestSyncManager() let manager = GossipSyncManager(myPeerID: myPeerID, config: config, requestSyncManager: requestSyncManager) @@ -543,6 +545,8 @@ struct GossipSyncManagerTests { config.messageSyncIntervalSeconds = 0 config.fragmentSyncIntervalSeconds = 0 config.fileTransferSyncIntervalSeconds = 0 + // Silence the prekey round so the maintenance barrier isolates fragments. + config.prekeyBundleSyncIntervalSeconds = 0 let requestSyncManager = RequestSyncManager() let manager = GossipSyncManager(myPeerID: myPeerID, config: config, requestSyncManager: requestSyncManager) diff --git a/bitchatTests/Services/MeshDiagnosticsTests.swift b/bitchatTests/Services/MeshDiagnosticsTests.swift index af22d393..d716791f 100644 --- a/bitchatTests/Services/MeshDiagnosticsTests.swift +++ b/bitchatTests/Services/MeshDiagnosticsTests.swift @@ -276,9 +276,15 @@ private final class DiagnosticsMockContext: CommandContextProvider { func clearCurrentPublicTimeline() {} func clearPrivateChat(_ peerID: PeerID) {} func sendPublicRaw(_ content: String) {} + func sendPublicMessage(_ content: String) {} func addLocalPrivateSystemMessage(_ content: String, to peerID: PeerID) {} func addPublicSystemMessage(_ content: String) {} func toggleFavorite(peerID: PeerID) {} + func groupCreate(named name: String) -> CommandResult { .handled } + func groupInvite(nickname: String) -> CommandResult { .handled } + func groupRemove(nickname: String) -> CommandResult { .handled } + func groupLeave() -> CommandResult { .handled } + func groupList() -> CommandResult { .handled } func currentCommandDestination() -> CommandOutputDestination { if let peerID = selectedPrivateChatPeer { diff --git a/bitchatTests/Sync/GossipSyncBoardTests.swift b/bitchatTests/Sync/GossipSyncBoardTests.swift index acfbf127..8676531a 100644 --- a/bitchatTests/Sync/GossipSyncBoardTests.swift +++ b/bitchatTests/Sync/GossipSyncBoardTests.swift @@ -34,6 +34,9 @@ struct GossipSyncBoardTests { config.messageSyncIntervalSeconds = 0 config.fragmentSyncIntervalSeconds = 0 config.fileTransferSyncIntervalSeconds = 0 + // Silence the prekey round (added by the prekeys feature; groupMessage + // rides the message schedule, already off) so board is isolated. + config.prekeyBundleSyncIntervalSeconds = 0 return config } diff --git a/bitchatTests/Sync/SyncTypeFlagsBoardTests.swift b/bitchatTests/Sync/SyncTypeFlagsBoardTests.swift index 49fd553b..47623f8f 100644 --- a/bitchatTests/Sync/SyncTypeFlagsBoardTests.swift +++ b/bitchatTests/Sync/SyncTypeFlagsBoardTests.swift @@ -38,9 +38,10 @@ struct SyncTypeFlagsBoardTests { /// decode path accepts the bytes and simply maps unknown bits to no /// message type, so a board-only request reads as "nothing I can serve". @Test func unknownBitsDecodeToNoTypes() throws { - // Bits 9-15 are unassigned; a future (or unknown) two-byte bitfield + // Bits 11-15 are unassigned after the feature integration (bit 8 is + // board, 9 prekey, 10 group); a future (or unknown) two-byte bitfield // must decode without error and yield no known types. - let decoded = try #require(SyncTypeFlags.decode(Data([0x00, 0xFE]))) + let decoded = try #require(SyncTypeFlags.decode(Data([0x00, 0xF8]))) #expect(decoded.toMessageTypes().isEmpty) for type in [MessageType.announce, .message, .fragment, .fileTransfer, .boardPost] { #expect(!decoded.contains(type)) @@ -48,8 +49,8 @@ struct SyncTypeFlagsBoardTests { } @Test func mixedKnownAndUnknownBitsKeepKnownTypes() throws { - // Known low-byte flags survive alongside unknown high bits. - let decoded = try #require(SyncTypeFlags.decode(Data([0x03, 0xFE]))) + // Known low-byte flags survive alongside unknown high bits (11-15). + let decoded = try #require(SyncTypeFlags.decode(Data([0x03, 0xF8]))) #expect(decoded.contains(.announce)) #expect(decoded.contains(.message)) #expect(Set(decoded.toMessageTypes()) == Set([.announce, .message])) diff --git a/bitchatTests/Sync/SyncTypeFlagsTests.swift b/bitchatTests/Sync/SyncTypeFlagsTests.swift index a3ab3cc4..15e33f4b 100644 --- a/bitchatTests/Sync/SyncTypeFlagsTests.swift +++ b/bitchatTests/Sync/SyncTypeFlagsTests.swift @@ -13,17 +13,19 @@ struct SyncTypeFlagsTests { } @Test func decodeDropsPhantomBits() { - // Bits 8+ map to no message type. They must not survive decode as + // Bits 11+ map to no message type (bits 8/9/10 are board/prekey/group + // after the feature integration). They must not survive decode as // phantom membership. - let phantom = Data([0x00, 0xFF]) // bits 8..15 set, no known type + let phantom = Data([0x00, 0xF8]) // bits 11..15 set, no known type let decoded = SyncTypeFlags.decode(phantom) #expect(decoded?.rawValue == 0) #expect(decoded?.toMessageTypes().isEmpty == true) } @Test func phantomBitsAreStrippedButKnownBitsSurvive() { - // Low byte = announce(0) + message(1); high byte = phantom. - let mixed = Data([0b0000_0011, 0xFF]) + // Low byte = announce(0) + message(1); high byte = phantom (bits 11+, + // which map to no known type). + let mixed = Data([0b0000_0011, 0xF8]) let decoded = SyncTypeFlags.decode(mixed) #expect(decoded?.contains(.announce) == true) #expect(decoded?.contains(.message) == true) @@ -33,11 +35,12 @@ struct SyncTypeFlagsTests { @Test func rawValueInitNormalizesPhantomBits() { let flags = SyncTypeFlags(rawValue: 0xFFFF_FFFF_FFFF_FFFF) - // Every known type bit is set; nothing above them survives, so the - // field serializes to a single byte. + // Every known type bit is set; nothing above them survives. The + // highest known bit is 10 (groupMessage), so the field serializes to + // two bytes. #expect(flags.contains(.announce)) #expect(flags.contains(.fileTransfer)) let data = flags.toData() - #expect(data?.count == 1) + #expect(data?.count == 2) } }