TM-SGNL-iOS/SignalServiceKit/tests/Contacts/PhoneNumberChangedMessageInserterTest.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

163 lines
6.6 KiB
Swift

//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
import LibSignalClient
import XCTest
@testable import SignalServiceKit
class PhoneNumberChangedMessageInserterTest: XCTestCase {
func testDidLearnAssociation() {
let ssaCache = SignalServiceAddressCache()
let myAci = Aci.constantForTesting("00000000-0000-4000-8000-000000000000")
let myPhoneNumber1 = E164("+16505550111")!
let myPhoneNumber2 = E164("+16505550122")!
let myAddress1 = ssaCache.makeAddress(serviceId: myAci, phoneNumber: myPhoneNumber1)
let aliceAci = Aci.constantForTesting("00000000-0000-4000-8000-00000000000A")
let alicePhoneNumber1 = E164("+16505550133")!
let alicePhoneNumber2 = E164("+16505550144")!
let aliceAddress1 = ssaCache.makeAddress(serviceId: aliceAci, phoneNumber: alicePhoneNumber1)
let bobAci = Aci.constantForTesting("00000000-0000-4000-8000-00000000000B")
let bobPhoneNumber1: E164? = nil
let bobPhoneNumber2 = E164("+16505550166")!
let bobPhoneNumber3 = E164("+16505550177")!
let bobAddress1 = ssaCache.makeAddress(serviceId: bobAci, phoneNumber: bobPhoneNumber1)
let groupWithEveryone = TSGroupThread.forUnitTest(groupId: 1, groupMembers: [myAddress1, aliceAddress1, bobAddress1])
let groupWithoutAlice = TSGroupThread.forUnitTest(groupId: 2, groupMembers: [myAddress1, bobAddress1])
let groupArchived = TSGroupThread.forUnitTest(groupId: 3, groupMembers: [myAddress1, aliceAddress1, bobAddress1])
let myThread = TSContactThread(contactAddress: myAddress1)
myThread.shouldThreadBeVisible = true
let aliceThread = TSContactThread(contactAddress: aliceAddress1)
aliceThread.shouldThreadBeVisible = true
let threadStore = MockThreadStore()
threadStore.insertThreads([groupWithEveryone, groupWithoutAlice, groupArchived, myThread, aliceThread])
let mockDB = InMemoryDB()
let groupMemberStore = MockGroupMemberStore()
mockDB.write { tx in
// Create group members for all of the full members.
for thread in [groupWithEveryone, groupWithoutAlice, groupArchived] {
for fullMemberAddress in thread.groupMembership.fullMembers {
groupMemberStore.insert(
fullGroupMember: TSGroupMember(
address: NormalizedDatabaseRecordAddress(address: fullMemberAddress)!,
groupThreadId: thread.uniqueId,
lastInteractionTimestamp: 0),
tx: tx
)
}
}
}
let threadAssociatedDataStore = MockThreadAssociatedDataStore()
threadAssociatedDataStore.values = Dictionary(uniqueKeysWithValues: threadStore.threads.map {
($0.uniqueId, ThreadAssociatedData(threadUniqueId: $0.uniqueId))
})
threadAssociatedDataStore.values[groupArchived.uniqueId] = ThreadAssociatedData(
threadUniqueId: groupArchived.uniqueId,
isArchived: true,
isMarkedUnread: false,
mutedUntilTimestamp: 0,
audioPlaybackRate: 1
)
let interactionStore = MockInteractionStore()
let mergeObserver = PhoneNumberChangedMessageInserter(
groupMemberStore: groupMemberStore,
interactionStore: interactionStore,
threadAssociatedDataStore: threadAssociatedDataStore,
threadStore: threadStore
)
// Alice changes her number.
interactionStore.insertedInteractions = []
mockDB.write { tx in
mergeObserver.didLearnAssociation(
mergedRecipient: makeRecipient(
aci: aliceAci,
oldPhoneNumber: alicePhoneNumber1,
newPhoneNumber: alicePhoneNumber2,
isLocalRecipient: false
),
tx: tx
)
let threadIds = interactionStore.insertedInteractions.map { $0.uniqueThreadId }
XCTAssertEqual(Set(threadIds), [groupWithEveryone.uniqueId, aliceThread.uniqueId])
}
// Bob acquires a number for the first time.
interactionStore.insertedInteractions = []
mockDB.write { tx in
mergeObserver.didLearnAssociation(
mergedRecipient: makeRecipient(
aci: bobAci,
oldPhoneNumber: bobPhoneNumber1,
newPhoneNumber: bobPhoneNumber2,
isLocalRecipient: false
),
tx: tx
)
let threadIds = interactionStore.insertedInteractions.map { $0.uniqueThreadId }
XCTAssertEqual(Set(threadIds), [])
}
// Bob changes his number.
interactionStore.insertedInteractions = []
mockDB.write { tx in
mergeObserver.didLearnAssociation(
mergedRecipient: makeRecipient(
aci: bobAci,
oldPhoneNumber: bobPhoneNumber2,
newPhoneNumber: bobPhoneNumber3,
isLocalRecipient: false
),
tx: tx
)
let threadIds = interactionStore.insertedInteractions.map { $0.uniqueThreadId }
XCTAssertEqual(Set(threadIds), [groupWithEveryone.uniqueId, groupWithoutAlice.uniqueId])
}
// The local user changes their number.
interactionStore.insertedInteractions = []
mockDB.write { tx in
mergeObserver.didLearnAssociation(
mergedRecipient: makeRecipient(
aci: myAci,
oldPhoneNumber: myPhoneNumber1,
newPhoneNumber: myPhoneNumber2,
isLocalRecipient: true
),
tx: tx
)
let threadIds = interactionStore.insertedInteractions.map { $0.uniqueThreadId }
XCTAssertEqual(Set(threadIds), [])
}
}
private func makeRecipient(
aci: Aci,
oldPhoneNumber: E164?,
newPhoneNumber: E164,
isLocalRecipient: Bool
) -> MergedRecipient {
let oldRecipient = SignalRecipient(aci: aci, pni: nil, phoneNumber: oldPhoneNumber)
let newRecipient = oldRecipient.copyRecipient()
newRecipient.phoneNumber = .init(stringValue: newPhoneNumber.stringValue, isDiscoverable: true)
return MergedRecipient(isLocalRecipient: isLocalRecipient, oldRecipient: oldRecipient, newRecipient: newRecipient)
}
}