diff --git a/WireDomain/Sources/WireDomain/Synchronization/ConversationUpdatesGenerator.swift b/WireDomain/Sources/WireDomain/Synchronization/ConversationUpdatesGenerator.swift index c9a85ea3f5e..9caf367859e 100644 --- a/WireDomain/Sources/WireDomain/Synchronization/ConversationUpdatesGenerator.swift +++ b/WireDomain/Sources/WireDomain/Synchronization/ConversationUpdatesGenerator.swift @@ -75,7 +75,11 @@ public final class ConversationUpdatesGenerator: NSObject, ConversationUpdatesGe private func createFetchRequestController() -> NSFetchedResultsController { let request = NSFetchRequest(entityName: ZMConversation.entityName()) - request.predicate = ZMConversation.predicateForNeedingToBeUpdatedFromBackend() + request.predicate = NSPredicate.all(of: [ + ZMConversation.predicateForNeedingToBeUpdatedFromBackend(), + NSPredicate(format: "%K == NO", #keyPath(ZMConversation.isDeletedRemotely)) + ]) + request.sortDescriptors = [NSSortDescriptor(key: ZMConversationLastServerTimeStampKey, ascending: true)] return NSFetchedResultsController( fetchRequest: request, diff --git a/WireDomain/Tests/WireDomainTests/Synchronization/ConversationUpdatesGeneratorTests.swift b/WireDomain/Tests/WireDomainTests/Synchronization/ConversationUpdatesGeneratorTests.swift index 9f3f584c8e6..2ac7f2bc5fa 100644 --- a/WireDomain/Tests/WireDomainTests/Synchronization/ConversationUpdatesGeneratorTests.swift +++ b/WireDomain/Tests/WireDomainTests/Synchronization/ConversationUpdatesGeneratorTests.swift @@ -145,4 +145,28 @@ class ConversationUpdatesGeneratorTests { #expect(updateConversationItems.isEmpty) } + + @Test("It does not generate an item when a conversation is deleted") + func deletedConversation() async throws { + // GIVEN + let conversationID = QualifiedID.random() + await coreDataStack.syncContext.perform { [modelHelper, context = coreDataStack.syncContext] in + let conversation = modelHelper.createGroupConversation( + id: conversationID.uuid, + domain: conversationID.domain, + in: context + ) + conversation.needsToBeUpdatedFromBackend = true + conversation.isDeletedRemotely = true + } + var updateConversationItems = [UpdateConversationItem]() + updateConversationItemClosure = { item in + updateConversationItems.append(item) + } + // WHEN + await sut.start() + + // THEN + #expect(updateConversationItems.isEmpty) + } } diff --git a/wire-ios-data-model/Source/Model/ZMManagedObject+Internal.h b/wire-ios-data-model/Source/Model/ZMManagedObject+Internal.h index 722026a0015..3f92a1cb92f 100644 --- a/wire-ios-data-model/Source/Model/ZMManagedObject+Internal.h +++ b/wire-ios-data-model/Source/Model/ZMManagedObject+Internal.h @@ -88,7 +88,7 @@ extern NSString * _Nonnull const ZMManagedObjectLocallyModifiedKeysKey; @property (nonatomic, readonly, nullable) NSSet *ignoredKeys; /// Returns a predicate that will match objects which need additional data from the backend. -+ (nullable NSPredicate *)predicateForNeedingToBeUpdatedFromBackend; ++ (NSPredicate * _Nonnull)predicateForNeedingToBeUpdatedFromBackend; /// Returns a predicate that will match objects that have local modifications that need to be pushed to the backend + (nullable NSPredicate *)predicateForObjectsThatNeedToBeUpdatedUpstream; diff --git a/wire-ios-data-model/Source/Model/ZMManagedObject.m b/wire-ios-data-model/Source/Model/ZMManagedObject.m index 09451070212..6a27e5bb81e 100644 --- a/wire-ios-data-model/Source/Model/ZMManagedObject.m +++ b/wire-ios-data-model/Source/Model/ZMManagedObject.m @@ -441,7 +441,7 @@ + (NSSet *)fetchObjectsWithRemoteIdentifiers:(NSSet *)uuids inManaged @implementation ZMManagedObject (PersistentChangeTracking) -+ (NSPredicate *)predicateForNeedingToBeUpdatedFromBackend; ++ (NSPredicate * _Nonnull)predicateForNeedingToBeUpdatedFromBackend; { return [NSPredicate predicateWithFormat:@"%K != 0", NeedsToBeUpdatedFromBackendKey]; } diff --git a/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategy.swift b/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategy.swift index 56edc96595a..86883445d47 100644 --- a/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategy.swift +++ b/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategy.swift @@ -167,7 +167,7 @@ extension FetchingClientRequestStrategy: ZMContextChangeTracker, ZMContextChange } public func fetchRequestForTrackedObjects() -> NSFetchRequest? { - UserClient.sortedFetchRequest(with: UserClient.predicateForNeedingToBeUpdatedFromBackend()!) + UserClient.sortedFetchRequest(with: UserClient.predicateForNeedingToBeUpdatedFromBackend()) } public func addTrackedObjects(_ objects: Set) { diff --git a/wire-ios-request-strategy/Sources/Request Strategies/User/UserProfileRequestStrategy.swift b/wire-ios-request-strategy/Sources/Request Strategies/User/UserProfileRequestStrategy.swift index 70e78f4b7b9..2c5863e6976 100644 --- a/wire-ios-request-strategy/Sources/Request Strategies/User/UserProfileRequestStrategy.swift +++ b/wire-ios-request-strategy/Sources/Request Strategies/User/UserProfileRequestStrategy.swift @@ -174,7 +174,7 @@ extension UserProfileRequestStrategy: ZMContextChangeTracker { } public func fetchRequestForTrackedObjects() -> NSFetchRequest? { - ZMUser.sortedFetchRequest(with: ZMUser.predicateForNeedingToBeUpdatedFromBackend()!) + ZMUser.sortedFetchRequest(with: ZMUser.predicateForNeedingToBeUpdatedFromBackend()) } public func addTrackedObjects(_ objects: Set) {