133 lines
4.8 KiB
Swift
133 lines
4.8 KiB
Swift
//
|
|
// Copyright 2024 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
@testable import SignalServiceKit
|
|
|
|
import XCTest
|
|
|
|
final class DeleteForMeOutgoingSyncMessageManagerTest: XCTestCase {
|
|
private var mockAddressableMessageFinder: MockDeleteForMeAddressableMessageFinder!
|
|
private var mockSyncMessageSender: MockSyncMessageSender!
|
|
private var mockRecipientDatabaseTable: MockRecipientDatabaseTable!
|
|
private var mockThreadStore: MockThreadStore!
|
|
private var mockTSAccountManager: MockTSAccountManager!
|
|
|
|
private var outgoingSyncMessageManager: DeleteForMeOutgoingSyncMessageManagerImpl!
|
|
|
|
override func setUp() {
|
|
mockAddressableMessageFinder = MockDeleteForMeAddressableMessageFinder()
|
|
mockSyncMessageSender = MockSyncMessageSender()
|
|
mockRecipientDatabaseTable = MockRecipientDatabaseTable()
|
|
mockThreadStore = MockThreadStore()
|
|
mockTSAccountManager = MockTSAccountManager()
|
|
|
|
outgoingSyncMessageManager = DeleteForMeOutgoingSyncMessageManagerImpl(
|
|
addressableMessageFinder: mockAddressableMessageFinder,
|
|
deleteForMeSyncMessageSettingsStore: MockDeleteForMeSyncMessageSettingsStore(),
|
|
recipientDatabaseTable: mockRecipientDatabaseTable,
|
|
syncMessageSender: mockSyncMessageSender,
|
|
threadStore: mockThreadStore,
|
|
tsAccountManager: mockTSAccountManager
|
|
)
|
|
}
|
|
|
|
func testBatchedInteractionDeletes() {
|
|
let thread = TSContactThread(contactAddress: .isolatedRandomForTesting())
|
|
let messagesToDelete = (0..<1501).map { _ -> TSOutgoingMessage in
|
|
return TSOutgoingMessage(uniqueId: .uniqueId(), thread: thread)
|
|
}
|
|
|
|
/// These should be ignored by the sync message sender, since they are
|
|
/// not addressable.
|
|
let interactionsToDelete = (0..<10).map { _ -> TSInteraction in
|
|
return TSInteraction(uniqueId: .uniqueId(), thread: thread)
|
|
}
|
|
|
|
var expectedInteractionBatches: [Int] = [500, 500, 500, 1]
|
|
mockSyncMessageSender.sendSyncMessageMock = { contents in
|
|
guard let expectedBatchSize = expectedInteractionBatches.popFirst() else {
|
|
XCTFail("Unexpected batch!")
|
|
return
|
|
}
|
|
|
|
XCTAssertEqual(contents.messageDeletes.count, 1)
|
|
XCTAssertEqual(contents.messageDeletes.first!.addressableMessages.count, expectedBatchSize)
|
|
}
|
|
|
|
MockDB().write { tx in
|
|
outgoingSyncMessageManager.send(
|
|
deletedInteractions: messagesToDelete + interactionsToDelete,
|
|
thread: thread,
|
|
tx: tx
|
|
)
|
|
}
|
|
|
|
XCTAssertTrue(expectedInteractionBatches.isEmpty)
|
|
}
|
|
|
|
func testBatchedThreadDeletes() {
|
|
let threadsToDelete = (0..<301).map { _ -> TSContactThread in
|
|
return TSContactThread(contactAddress: .isolatedRandomForTesting())
|
|
}
|
|
|
|
var expectedThreadBatches: [Int] = [100, 100, 100, 1]
|
|
mockSyncMessageSender.sendSyncMessageMock = { contents in
|
|
guard let expectedBatchSize = expectedThreadBatches.popFirst() else {
|
|
XCTFail("Unexpected batch!")
|
|
return
|
|
}
|
|
|
|
XCTAssertEqual(contents.localOnlyConversationDelete.count, expectedBatchSize)
|
|
}
|
|
|
|
MockDB().write { tx in
|
|
/// These should all be local-only deletes, since the threads have
|
|
/// no messages (the `MockDeleteForMeAddressableMessageFinder` will
|
|
/// return `[]` for all threads, at the time of writing).
|
|
let deletionContexts: [DeleteForMeSyncMessage.Outgoing.ThreadDeletionContext] = threadsToDelete.map { thread in
|
|
outgoingSyncMessageManager.buildThreadDeletionContext(
|
|
thread: thread,
|
|
isFullDelete: true,
|
|
tx: tx
|
|
)!
|
|
}
|
|
|
|
outgoingSyncMessageManager.send(
|
|
threadDeletionContexts: deletionContexts,
|
|
tx: tx
|
|
)
|
|
}
|
|
|
|
XCTAssertTrue(expectedThreadBatches.isEmpty)
|
|
}
|
|
}
|
|
|
|
private extension String {
|
|
static func uniqueId() -> String {
|
|
return UUID().uuidString
|
|
}
|
|
}
|
|
|
|
// MARK: - Mocks
|
|
|
|
private final class MockDeleteForMeSyncMessageSettingsStore: DeleteForMeSyncMessageSettingsStore {
|
|
func isSendingEnabled(tx: any DBReadTransaction) -> Bool {
|
|
return true
|
|
}
|
|
|
|
func enableSending(tx: any DBWriteTransaction) {
|
|
owsFail("Not implemented!")
|
|
}
|
|
}
|
|
|
|
private final class MockSyncMessageSender: DeleteForMeOutgoingSyncMessageManagerImpl.Shims.SyncMessageSender {
|
|
var sendSyncMessageMock: ((
|
|
_ contents: DeleteForMeOutgoingSyncMessage.Contents
|
|
) -> Void)!
|
|
func sendSyncMessage(contents: DeleteForMeOutgoingSyncMessage.Contents, localThread: TSContactThread, tx: any DBWriteTransaction) {
|
|
sendSyncMessageMock(contents)
|
|
}
|
|
}
|