Signal-iOS/SignalServiceKit/tests/Contacts/UUIDBackfillTaskTest.swift
Max Radermacher 50e0405276
Add ContactDiscoveryManager
RATE LIMITS & IS CRITICAL PRIORITY

Before this change, there was a notion of “critical” discovery tasks
that had their own rate limit, and that rate limit was used for
UUIDBackfillTask. In this change, that logic has been generalized to
consider a separate rate limit for additional request types.

QUEUE PRIORITIES

All of the discovery operations were updated to use `.userInitiated` as
their priority. Before this change, the `UUIDBackfillTask` and message
sending flow used lower priorities. However, both of those should use
higher priorities -- the former blocks receiving messages and the latter
blocks outgoing messages. This change allows the code to be simplified.

TESTS

This removes most of the existing `UUIDBackfillTaskTest` test cases
(they were commented out) and all of the `ContactDiscoveryTaskTest` test
cases (which were for the rate limiter, which has been moved elsewhere).

It introduces a few new tests. These aren’t meant to be exhausive;
instead, they’re meant to hit most of the code in the new classes and a
few specific edge cases that aren’t likely to be hit in normal use.
2022-11-15 13:37:28 -08:00

66 lines
2.4 KiB
Swift

//
// Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import XCTest
@testable import SignalServiceKit
final class UUIDBackfillTaskTest: SSKBaseTestSwift {
private class MockContactDiscoveryManager: ContactDiscoveryManager {
private(set) var requests = [Set<String>]()
func lookUp(phoneNumbers: Set<String>, mode: ContactDiscoveryMode) -> Promise<Set<SignalRecipient>> {
requests.append(phoneNumbers)
switch requests.count {
case 1:
return Promise(error: ContactDiscoveryError(
kind: .genericServerError, debugDescription: "", retryable: true, retryAfterDate: nil
))
case 2:
return Promise(error: ContactDiscoveryError.rateLimit(expiryDate: Date(timeIntervalSinceNow: -60)))
case 3:
return Promise(error: ContactDiscoveryError.rateLimit(expiryDate: Date(timeIntervalSinceNow: 0.001)))
default:
return .value([])
}
}
}
override func setUp() {
super.setUp()
let localAddress = CommonGenerator.address()
tsAccountManager.registerForTests(withLocalNumber: localAddress.phoneNumber!, uuid: localAddress.uuid!)
}
func testRetryOnError() throws {
// Add a few phone number-only recipients.
let addressesMissingUUIDs = [
CommonGenerator.address(hasUUID: false),
CommonGenerator.address(hasUUID: false)
]
databaseStorage.write { transaction in
for address in addressesMissingUUIDs + [CommonGenerator.address()] {
SignalRecipient.mark(asRegisteredAndGet: address, trustLevel: .high, transaction: transaction)
}
}
let manager = MockContactDiscoveryManager()
let task = UUIDBackfillTask(contactDiscoveryManager: manager, databaseStorage: databaseStorage)
let completed = expectation(description: "Waiting for task.")
task.perform().done {
completed.fulfill()
}
waitForExpectations(timeout: 10)
// We expect four requests.
XCTAssertEqual(manager.requests.count, 4)
// Which should match the addresses missing UUIDs.
let phoneNumbersMissingUUIDs = addressesMissingUUIDs.map { $0.phoneNumber! }
XCTAssertEqual(Set(manager.requests), [Set(phoneNumbersMissingUUIDs)])
}
}