TM-SGNL-iOS/Signal/test/CallsTab/CallRecordLoaderTest.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

234 lines
10 KiB
Swift

//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import SignalServiceKit
import XCTest
@testable import Signal
final class CallRecordLoaderTest: XCTestCase {
private var mockCallRecordQuerier: MockCallRecordQuerier!
private var callRecordLoader: CallRecordLoaderImpl!
override func setUp() {
mockCallRecordQuerier = MockCallRecordQuerier()
}
private func setupCallRecordLoader(
onlyLoadMissedCalls: Bool = false,
onlyMatchThreadRowIds: [Int64]? = nil
) {
callRecordLoader = CallRecordLoaderImpl(
callRecordQuerier: mockCallRecordQuerier,
configuration: CallRecordLoaderImpl.Configuration(
onlyLoadMissedCalls: onlyLoadMissedCalls,
onlyMatchThreadRowIds: onlyMatchThreadRowIds
)
)
}
private func loadRecords(loadDirection: CallRecordLoader.LoadDirection) -> [UInt64] {
return InMemoryDB().read { tx in
try! callRecordLoader
.loadCallRecords(loadDirection: loadDirection, tx: tx)
.drain(maxResults: 3)
.map { $0.callId }
}
}
func testNothingMatching() {
mockCallRecordQuerier.mockCallRecords = [
.fixture(callId: 1), .fixture(callId: 2)
]
setupCallRecordLoader(onlyMatchThreadRowIds: [1])
XCTAssertEqual([], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: nil)))
setupCallRecordLoader(onlyLoadMissedCalls: true)
XCTAssertEqual([], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: nil)))
setupCallRecordLoader()
XCTAssertEqual([2, 1], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: nil)))
}
// MARK: Older
func testGetOlderPage() {
setupCallRecordLoader()
mockCallRecordQuerier.mockCallRecords = [
.fixture(callId: 1), .fixture(callId: 2), .fixture(callId: 3),
.fixture(callId: 4), .fixture(callId: 5), .fixture(callId: 6),
.fixture(callId: 7)
]
XCTAssertEqual([7, 6, 5], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: nil)))
XCTAssertEqual([4, 3, 2], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: 5)))
XCTAssertEqual([1], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: 2)))
XCTAssertEqual([], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: 1)))
}
func testGetOlderPageSearching() {
setupCallRecordLoader(onlyMatchThreadRowIds: [1, 2])
mockCallRecordQuerier.mockCallRecords = [
.fixture(callId: 1),
.fixture(callId: 2, threadRowId: 1), .fixture(callId: 3, threadRowId: 2),
.fixture(callId: 4),
.fixture(callId: 5, threadRowId: 2), .fixture(callId: 6, threadRowId: 1),
.fixture(callId: 7),
]
XCTAssertEqual([6, 5, 3], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: nil)))
XCTAssertEqual([2], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: 3)))
XCTAssertEqual([], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: 2)))
}
func testGetOlderPageForMissed() {
setupCallRecordLoader(onlyLoadMissedCalls: true)
mockCallRecordQuerier.mockCallRecords = [
.fixture(callId: 1),
.fixture(callId: 2, threadRowId: 1, callStatus: .group(.ringingMissed)),
.fixture(callId: 3, threadRowId: 1),
.fixture(callId: 4, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 5, threadRowId: 2, callStatus: .individual(.accepted)),
.fixture(callId: 6, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 7, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 8, threadRowId: 1, callStatus: .group(.ringingMissedNotificationProfile)),
.fixture(callId: 9),
]
XCTAssertEqual([8, 7, 6], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: nil)))
XCTAssertEqual([4, 2], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: 6)))
XCTAssertEqual([], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: 2)))
}
func testGetOlderPageForMissedSearching() {
setupCallRecordLoader(onlyLoadMissedCalls: true, onlyMatchThreadRowIds: [1, 2])
mockCallRecordQuerier.mockCallRecords = [
.fixture(callId: 1),
.fixture(callId: 2, threadRowId: 1, callStatus: .group(.ringingMissed)),
.fixture(callId: 3, threadRowId: 1),
.fixture(callId: 4, threadRowId: 1, callStatus: .group(.ringingMissedNotificationProfile)),
.fixture(callId: 5, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 6, threadRowId: 1, callStatus: .group(.ringingMissed)),
.fixture(callId: 7, threadRowId: 1, callStatus: .group(.joined)),
.fixture(callId: 8, threadRowId: 2, callStatus: .individual(.accepted)),
.fixture(callId: 9, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 10, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 11, threadRowId: 1, callStatus: .group(.ringingMissedNotificationProfile)),
.fixture(callId: 12),
.fixture(callId: 13, callStatus: .group(.ringingMissed)),
]
XCTAssertEqual([11, 10, 9], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: nil)))
XCTAssertEqual([6, 5, 4], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: 9)))
XCTAssertEqual([2], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: 4)))
XCTAssertEqual([], loadRecords(loadDirection: .olderThan(oldestCallTimestamp: 2)))
}
// MARK: Newer
func testGetNewerPage() {
setupCallRecordLoader()
mockCallRecordQuerier.mockCallRecords = [
.fixture(callId: 1), .fixture(callId: 2), .fixture(callId: 3),
.fixture(callId: 4), .fixture(callId: 5), .fixture(callId: 6),
.fixture(callId: 7)
]
XCTAssertEqual([1, 2, 3], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 0)))
XCTAssertEqual([4, 5, 6], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 3)))
XCTAssertEqual([7], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 6)))
XCTAssertEqual([], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 7)))
}
func testGetNewerPageSearching() {
setupCallRecordLoader(onlyMatchThreadRowIds: [1, 2])
mockCallRecordQuerier.mockCallRecords = [
.fixture(callId: 1),
.fixture(callId: 2, threadRowId: 1), .fixture(callId: 3, threadRowId: 2),
.fixture(callId: 4),
.fixture(callId: 5, threadRowId: 2), .fixture(callId: 6, threadRowId: 1),
.fixture(callId: 7),
]
XCTAssertEqual([2, 3, 5], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 0)))
XCTAssertEqual([6], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 5)))
XCTAssertEqual([], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 6)))
}
func testGetNewerPageForMissed() {
setupCallRecordLoader(onlyLoadMissedCalls: true)
mockCallRecordQuerier.mockCallRecords = [
.fixture(callId: 1),
.fixture(callId: 2, threadRowId: 1, callStatus: .group(.ringingMissed)),
.fixture(callId: 3, threadRowId: 1),
.fixture(callId: 4, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 5, threadRowId: 2, callStatus: .individual(.accepted)),
.fixture(callId: 6, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 7, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 8, threadRowId: 1, callStatus: .group(.ringingMissedNotificationProfile)),
.fixture(callId: 9),
]
XCTAssertEqual([2, 4, 6], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 0)))
XCTAssertEqual([7, 8], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 6)))
XCTAssertEqual([], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 8)))
}
func testGetNewerPageForMissedSearching() {
setupCallRecordLoader(onlyLoadMissedCalls: true, onlyMatchThreadRowIds: [1, 2])
mockCallRecordQuerier.mockCallRecords = [
.fixture(callId: 1),
.fixture(callId: 2, threadRowId: 1, callStatus: .group(.ringingMissed)),
.fixture(callId: 3, threadRowId: 1),
.fixture(callId: 4, threadRowId: 1, callStatus: .group(.ringingMissedNotificationProfile)),
.fixture(callId: 5, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 6, threadRowId: 1, callStatus: .group(.ringingMissed)),
.fixture(callId: 7, threadRowId: 1, callStatus: .group(.joined)),
.fixture(callId: 8, threadRowId: 2, callStatus: .individual(.accepted)),
.fixture(callId: 9, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 10, threadRowId: 2, callStatus: .individual(.incomingMissed)),
.fixture(callId: 11, threadRowId: 1, callStatus: .group(.ringingMissedNotificationProfile)),
.fixture(callId: 12),
.fixture(callId: 13, callStatus: .group(.ringingMissed)),
]
XCTAssertEqual([2, 4, 5], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 0)))
XCTAssertEqual([6, 9, 10], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 5)))
XCTAssertEqual([11], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 10)))
XCTAssertEqual([], loadRecords(loadDirection: .newerThan(newestCallTimestamp: 11)))
}
}
// MARK: - Mocks
private extension CallRecord {
/// Creates a ``CallRecord`` with the given parameters. The record's
/// timestamp will be equivalent to its call ID.
static func fixture(
callId: UInt64,
threadRowId: Int64 = 0,
callStatus: CallRecord.CallStatus = .group(.joined)
) -> CallRecord {
return CallRecord(
callId: callId,
interactionRowId: 0,
threadRowId: threadRowId,
callType: .groupCall,
callDirection: .incoming,
callStatus: callStatus,
callBeganTimestamp: callId
)
}
}