mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 01:05:19 +00:00
Inject notification/favorites singletons through coordinator contexts
NotificationService.shared and FavoritesPersistenceService.shared accesses across nine coordinators/components consolidate into ChatViewModel witnesses behind intent-named context members (notifyPrivateMessage, notifyMention, favoriteRelationship(forNoiseKey:), allFavoriteRelationships, postLocalNotification, ...). Singleton reach from coordinators is now zero; nine new tests cover previously untestable notification/favorites flows. Also root-causes the long-flaky gift-wrap dedup test: parallel tests share LocationChannelManager.shared, so channel-switch tests trigger clearProcessedNostrEvents() on every live ChatViewModel, wiping the dedup record mid-test. The invariant (forged-signature copies never poison dedup) now lives as a deterministic NostrInboundPipeline mock-context test; two Schnorr concurrency probes added along the way stay as regression guards for the P256K shared-context assumptions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,11 @@ protocol NostrInboundPipelineContext: AnyObject {
|
||||
func isNostrBlocked(pubkeyHexLowercased: String) -> Bool
|
||||
func displayNameForNostrPubkey(_ pubkeyHex: String) -> String
|
||||
|
||||
// MARK: Favorites bridge
|
||||
/// All favorite relationships, used to bridge a Nostr pubkey back to a
|
||||
/// Noise key on the inbound DM path.
|
||||
func allFavoriteRelationships() -> [FavoritesPersistenceService.FavoriteRelationship]
|
||||
|
||||
// MARK: Presence & key mapping
|
||||
func setGeoNickname(_ nickname: String, forPubkey pubkeyHex: String)
|
||||
/// Records the Nostr pubkey behind a (possibly virtual) peer ID.
|
||||
@@ -53,6 +58,10 @@ extension ChatViewModel: NostrInboundPipelineContext {
|
||||
deduplicationService.hasProcessedNostrEvent(eventID)
|
||||
}
|
||||
|
||||
func allFavoriteRelationships() -> [FavoritesPersistenceService.FavoriteRelationship] {
|
||||
Array(FavoritesPersistenceService.shared.favorites.values)
|
||||
}
|
||||
|
||||
func recordProcessedNostrEvent(_ eventID: String) {
|
||||
deduplicationService.recordNostrEvent(eventID)
|
||||
}
|
||||
@@ -437,7 +446,8 @@ final class NostrInboundPipeline {
|
||||
/// the favorites glue in `ChatNostrCoordinator` delegates to it.
|
||||
@MainActor
|
||||
func findNoiseKey(for nostrPubkey: String) -> Data? {
|
||||
let favorites = FavoritesPersistenceService.shared.favorites.values
|
||||
guard let context else { return nil }
|
||||
let favorites = context.allFavoriteRelationships()
|
||||
var npubToMatch = nostrPubkey
|
||||
|
||||
if !nostrPubkey.hasPrefix("npub") {
|
||||
|
||||
Reference in New Issue
Block a user