You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-ios/SignalServiceKit/src/Loki/Protocol/Friend Requests/FriendRequestProtocolTests....

644 lines
31 KiB
Swift

import CryptoSwift
5 years ago
import PromiseKit
@testable import SignalServiceKit
import XCTest
5 years ago
import Curve25519Kit
5 years ago
class FriendRequestProtocolTests : XCTestCase {
private var storage: OWSPrimaryStorage { OWSPrimaryStorage.shared() }
private var messageSender: OWSFakeMessageSender { return MockSSKEnvironment.shared.messageSender as! OWSFakeMessageSender }
5 years ago
override func setUp() {
super.setUp()
// Activate the mock environment
ClearCurrentAppContextForTests()
SetCurrentAppContext(TestAppContext())
MockSSKEnvironment.activate()
// Register a mock user
let identityManager = OWSIdentityManager.shared()
let seed = Randomness.generateRandomBytes(16)!
let keyPair = Curve25519.generateKeyPair(fromSeed: seed + seed)
let databaseConnection = identityManager.value(forKey: "dbConnection") as! YapDatabaseConnection
databaseConnection.setObject(keyPair, forKey: OWSPrimaryStorageIdentityKeyStoreIdentityKey, inCollection: OWSPrimaryStorageIdentityKeyStoreCollection)
TSAccountManager.sharedInstance().phoneNumberAwaitingVerification = keyPair.hexEncodedPublicKey
TSAccountManager.sharedInstance().didRegister()
}
5 years ago
// MARK: - Helpers
func isFriendRequestStatus(_ values: [LKFriendRequestStatus], for hexEncodedPublicKey: String, transaction: YapDatabaseReadWriteTransaction) -> Bool {
5 years ago
let status = storage.getFriendRequestStatus(for: hexEncodedPublicKey, transaction: transaction)
return values.contains(status)
}
func isFriendRequestStatus(_ value: LKFriendRequestStatus, for hexEncodedPublicKey: String, transaction: YapDatabaseReadWriteTransaction) -> Bool {
return isFriendRequestStatus([value], for: hexEncodedPublicKey, transaction: transaction)
}
func generateHexEncodedPublicKey() -> String {
return Curve25519.generateKeyPair().hexEncodedPublicKey
}
func getDevice(for hexEncodedPublicKey: String) -> DeviceLink.Device? {
5 years ago
guard let signature = Data.getSecureRandomData(ofSize: 64) else { return nil }
return DeviceLink.Device(hexEncodedPublicKey: hexEncodedPublicKey, signature: signature)
}
func createContactThread(for hexEncodedPublicKey: String) -> TSContactThread {
var result: TSContactThread!
storage.dbReadWriteConnection.readWrite { transaction in
result = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction)
}
return result
}
func createGroupThread(groupType: GroupType) -> TSGroupThread? {
let stringId = Randomness.generateRandomBytes(kGroupIdLength)!.toHexString()
let groupId: Data!
switch groupType {
case .closedGroup:
groupId = LKGroupUtilities.getEncodedClosedGroupIDAsData(stringId)
break
case .openGroup:
groupId = LKGroupUtilities.getEncodedOpenGroupIDAsData(stringId)
break
case .rssFeed:
groupId = LKGroupUtilities.getEncodedRSSFeedIDAsData(stringId)
default:
return nil
}
return TSGroupThread.getOrCreateThread(withGroupId: groupId, groupType: groupType)
}
// MARK: - shouldInputBarBeEnabled
func test_shouldInputBarBeEnabledReturnsTrueOnGroupThread() {
let allGroupTypes: [GroupType] = [.closedGroup, .openGroup, .rssFeed]
for groupType in allGroupTypes {
guard let groupThread = createGroupThread(groupType: groupType) else { return XCTFail() }
XCTAssertTrue(FriendRequestProtocol.shouldInputBarBeEnabled(for: groupThread))
}
}
func test_shouldInputBarBeEnabledReturnsTrueOnNoteToSelf() {
guard let master = OWSIdentityManager.shared().identityKeyPair()?.hexEncodedPublicKey else { return XCTFail() }
let slave = generateHexEncodedPublicKey()
5 years ago
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
5 years ago
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
5 years ago
self.storage.setFriendRequestStatus(.requestSent, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.requestSent, for: slave, transaction: transaction)
5 years ago
}
let masterThread = createContactThread(for: master)
let slaveThread = createContactThread(for: slave)
5 years ago
XCTAssertTrue(FriendRequestProtocol.shouldInputBarBeEnabled(for: masterThread))
XCTAssertTrue(FriendRequestProtocol.shouldInputBarBeEnabled(for: slaveThread))
}
func test_shouldInputBarBeEnabledReturnsTrueWhenStatusIsNotPending() {
let validStatuses: [LKFriendRequestStatus] = [.none, .requestExpired, .friends]
let device = generateHexEncodedPublicKey()
5 years ago
let thread = createContactThread(for: device)
for status in validStatuses {
storage.dbReadWriteConnection.readWrite { transaction in
5 years ago
self.storage.setFriendRequestStatus(status, for: device, transaction: transaction)
5 years ago
}
XCTAssertTrue(FriendRequestProtocol.shouldInputBarBeEnabled(for: thread))
}
}
func test_shouldInputBarBeEnabledReturnsFalseWhenStatusIsPending() {
let pendingStatuses: [LKFriendRequestStatus] = [.requestSending, .requestSent, .requestReceived]
let device = generateHexEncodedPublicKey()
let thread = createContactThread(for: device)
for status in pendingStatuses {
storage.dbReadWriteConnection.readWrite { transaction in
5 years ago
self.storage.setFriendRequestStatus(status, for: device, transaction: transaction)
}
XCTAssertFalse(FriendRequestProtocol.shouldInputBarBeEnabled(for: thread))
}
5 years ago
}
func test_shouldInputBarBeEnabledReturnsTrueWhenFriendsWithOneLinkedDevice() {
let master = generateHexEncodedPublicKey()
let slave = generateHexEncodedPublicKey()
5 years ago
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
5 years ago
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
5 years ago
self.storage.setFriendRequestStatus(.friends, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.requestSent, for: slave, transaction: transaction)
5 years ago
}
let masterThread = createContactThread(for: master)
let slaveThread = createContactThread(for: slave)
5 years ago
XCTAssertTrue(FriendRequestProtocol.shouldInputBarBeEnabled(for: masterThread))
XCTAssertTrue(FriendRequestProtocol.shouldInputBarBeEnabled(for: slaveThread))
}
func test_shouldInputBarBeEnabledReturnsFalseWhenOneLinkedDeviceIsPending() {
let master = generateHexEncodedPublicKey()
let slave = generateHexEncodedPublicKey()
5 years ago
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
5 years ago
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
5 years ago
self.storage.setFriendRequestStatus(.none, for: master, transaction: transaction)
5 years ago
}
let masterThread = createContactThread(for: master)
let slaveThread = createContactThread(for: slave)
5 years ago
let pendingStatuses: [LKFriendRequestStatus] = [.requestSending, .requestSent, .requestReceived]
for status in pendingStatuses {
storage.dbReadWriteConnection.readWrite { transaction in
5 years ago
self.storage.setFriendRequestStatus(status, for: slave, transaction: transaction)
5 years ago
}
XCTAssertFalse(FriendRequestProtocol.shouldInputBarBeEnabled(for: masterThread))
XCTAssertFalse(FriendRequestProtocol.shouldInputBarBeEnabled(for: slaveThread))
}
}
func test_shouldInputBarBeEnabledReturnsTrueWhenAllLinkedDevicesAreNotPendingAndNotFriends() {
let master = generateHexEncodedPublicKey()
let slave = generateHexEncodedPublicKey()
5 years ago
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
5 years ago
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
5 years ago
self.storage.setFriendRequestStatus(.none, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.none, for: slave, transaction: transaction)
5 years ago
}
let masterThread = createContactThread(for: master)
let slaveThread = createContactThread(for: slave)
5 years ago
let safeStatuses: [LKFriendRequestStatus] = [.requestExpired, .none]
for status in safeStatuses {
storage.dbReadWriteConnection.readWrite { transaction in
5 years ago
self.storage.setFriendRequestStatus(status, for: slave, transaction: transaction)
5 years ago
}
XCTAssertTrue(FriendRequestProtocol.shouldInputBarBeEnabled(for: masterThread))
XCTAssertTrue(FriendRequestProtocol.shouldInputBarBeEnabled(for: slaveThread))
}
}
func test_shouldInputBarEnabledShouldStillWorkIfLinkedDeviceThreadDoesNotExist() {
let master = generateHexEncodedPublicKey()
let slave = generateHexEncodedPublicKey()
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
self.storage.setFriendRequestStatus(.requestSent, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.friends, for: slave, transaction: transaction)
}
let masterThread = createContactThread(for: master)
XCTAssertTrue(FriendRequestProtocol.shouldInputBarBeEnabled(for: masterThread))
}
5 years ago
// MARK: - shouldAttachmentButtonBeEnabled
func test_shouldAttachmentButtonBeEnabledReturnsTrueOnGroupThread() {
let allGroupTypes: [GroupType] = [.closedGroup, .openGroup, .rssFeed]
for groupType in allGroupTypes {
guard let groupThread = createGroupThread(groupType: groupType) else { return XCTFail() }
XCTAssertTrue(FriendRequestProtocol.shouldAttachmentButtonBeEnabled(for: groupThread))
}
}
func test_shouldAttachmentButtonBeEnabledReturnsTrueOnNoteToSelf() {
guard let master = OWSIdentityManager.shared().identityKeyPair()?.hexEncodedPublicKey else { return XCTFail() }
let slave = generateHexEncodedPublicKey()
5 years ago
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
5 years ago
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
5 years ago
self.storage.setFriendRequestStatus(.requestSent, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.requestSent, for: slave, transaction: transaction)
}
5 years ago
let masterThread = createContactThread(for: master)
let slaveThread = createContactThread(for: slave)
5 years ago
XCTAssertTrue(FriendRequestProtocol.shouldAttachmentButtonBeEnabled(for: masterThread))
XCTAssertTrue(FriendRequestProtocol.shouldAttachmentButtonBeEnabled(for: slaveThread))
5 years ago
}
func test_shouldAttachmentButtonBeEnabledReturnsTrueWhenFriends() {
let device = generateHexEncodedPublicKey()
5 years ago
let thread = createContactThread(for: device)
storage.dbReadWriteConnection.readWrite { transaction in
5 years ago
self.storage.setFriendRequestStatus(.friends, for: device, transaction: transaction)
5 years ago
}
XCTAssertTrue(FriendRequestProtocol.shouldAttachmentButtonBeEnabled(for: thread))
}
func test_shouldAttachmentButtonBeEnabledReturnsFalseWhenNotFriends() {
let nonFriendStatuses: [LKFriendRequestStatus] = [.requestSending, .requestSent, .requestReceived, .none, .requestExpired]
let device = generateHexEncodedPublicKey()
5 years ago
let thread = createContactThread(for: device)
for status in nonFriendStatuses {
storage.dbReadWriteConnection.readWrite { transaction in
5 years ago
self.storage.setFriendRequestStatus(status, for: device, transaction: transaction)
5 years ago
}
XCTAssertFalse(FriendRequestProtocol.shouldAttachmentButtonBeEnabled(for: thread))
}
}
func test_shouldAttachmentButtonBeEnabledReturnsTrueWhenFriendsWithOneLinkedDevice() {
let master = generateHexEncodedPublicKey()
let slave = generateHexEncodedPublicKey()
5 years ago
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
5 years ago
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
5 years ago
self.storage.setFriendRequestStatus(.friends, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.requestSent, for: slave, transaction: transaction)
5 years ago
}
let masterThread = createContactThread(for: master)
let slaveThread = createContactThread(for: slave)
5 years ago
XCTAssertTrue(FriendRequestProtocol.shouldAttachmentButtonBeEnabled(for: masterThread))
XCTAssertTrue(FriendRequestProtocol.shouldAttachmentButtonBeEnabled(for: slaveThread))
}
func test_shouldAttachmentButtonBeEnabledShouldStillWorkIfLinkedDeviceThreadDoesNotExist() {
let master = generateHexEncodedPublicKey()
let slave = generateHexEncodedPublicKey()
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
self.storage.setFriendRequestStatus(.none, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.friends, for: slave, transaction: transaction)
}
let masterThread = createContactThread(for: master)
XCTAssertTrue(FriendRequestProtocol.shouldAttachmentButtonBeEnabled(for: masterThread))
}
// MARK: - getFriendRequestUIState
func test_getFriendRequestUIStateShouldReturnNoneForGroupThreads() {
let allGroupTypes: [GroupType] = [.closedGroup, .openGroup, .rssFeed]
for groupType in allGroupTypes {
guard let groupThread = createGroupThread(groupType: groupType) else { return XCTFail() }
XCTAssertTrue(FriendRequestProtocol.getFriendRequestUIStatus(for: groupThread) == .none)
}
}
func test_getFriendRequestUIStateShouldReturnNoneOnNoteToSelf() {
guard let master = OWSIdentityManager.shared().identityKeyPair()?.hexEncodedPublicKey else { return XCTFail() }
let slave = generateHexEncodedPublicKey()
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
self.storage.setFriendRequestStatus(.friends, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.friends, for: slave, transaction: transaction)
}
let masterThread = createContactThread(for: master)
let slaveThread = createContactThread(for: slave)
XCTAssertTrue(FriendRequestProtocol.getFriendRequestUIStatus(for: masterThread) == .none)
XCTAssertTrue(FriendRequestProtocol.getFriendRequestUIStatus(for: slaveThread) == .none )
}
func test_getFriendRequestUIStateShouldReturnTheCorrectStates() {
let bob = generateHexEncodedPublicKey()
let bobThread = createContactThread(for: bob)
5 years ago
let expectedStates: [LKFriendRequestStatus : FriendRequestProtocol.FriendRequestUIStatus] = [
.none: .none,
.requestExpired: .none,
.requestSending: .none,
.requestSent: .sent,
.requestReceived: .received,
.friends: .friends,
]
for (friendRequestStatus, uiState) in expectedStates {
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.setFriendRequestStatus(friendRequestStatus, for: bob, transaction: transaction)
}
XCTAssertEqual(FriendRequestProtocol.getFriendRequestUIStatus(for: bobThread), uiState, "Expected FriendRequestUIState to be \(uiState)")
}
}
func test_getFriendRequestUIStateShouldWorkWithMultiDevice() {
let master = generateHexEncodedPublicKey()
let slave = generateHexEncodedPublicKey()
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
self.storage.setFriendRequestStatus(.none, for: master, transaction: transaction)
}
let masterThread = createContactThread(for: master)
let slaveThread = createContactThread(for: slave)
5 years ago
let expectedStates: [LKFriendRequestStatus : FriendRequestProtocol.FriendRequestUIStatus] = [
.none: .none,
.requestExpired: .none,
.requestSending: .none,
.requestSent: .sent,
.requestReceived: .received,
.friends: .friends,
]
for (friendRequestStatus, uiState) in expectedStates {
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.setFriendRequestStatus(friendRequestStatus, for: slave, transaction: transaction)
}
XCTAssertEqual(FriendRequestProtocol.getFriendRequestUIStatus(for: masterThread), uiState, "Expected FriendRequestUIState to be \(uiState.rawValue)")
XCTAssertEqual(FriendRequestProtocol.getFriendRequestUIStatus(for: slaveThread), uiState, "Expected FriendRequestUIState to be \(uiState.rawValue)")
}
}
func test_getFriendRequestUIStateShouldPreferFriendsOverRequestReceived() {
// Case: We don't want to confuse the user by showing a friend request box when they're already friends
let master = generateHexEncodedPublicKey()
let slave = generateHexEncodedPublicKey()
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
let masterThread = createContactThread(for: master)
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
self.storage.setFriendRequestStatus(.requestReceived, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.friends, for: slave, transaction: transaction)
}
XCTAssertTrue(FriendRequestProtocol.getFriendRequestUIStatus(for: masterThread) == .friends)
}
func test_getFriendRequestUIStateShouldPreferReceivedOverSent() {
// Case: We sent Bob a friend request and he sent one back to us through another device.
// If something went wrong then we should be able to fallback to manually accepting the friend request even if we sent one.
let master = generateHexEncodedPublicKey()
let slave = generateHexEncodedPublicKey()
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
let masterThread = createContactThread(for: master)
let deviceLink = DeviceLink(between: masterDevice, and: slaveDevice)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(deviceLink, in: transaction)
self.storage.setFriendRequestStatus(.requestSent, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.requestReceived, for: slave, transaction: transaction)
}
XCTAssertTrue(FriendRequestProtocol.getFriendRequestUIStatus(for: masterThread) == .received)
}
// MARK: - acceptFriendRequest
func test_acceptFriendRequestShouldSetStatusToFriendsIfWeReceivedAFriendRequest() {
// Case: Bob sent us a friend request, we should become friends with him on accepting
let bob = generateHexEncodedPublicKey()
storage.dbReadWriteConnection.readWrite { transaction in
5 years ago
self.storage.setFriendRequestStatus(.requestReceived, for: bob, transaction: transaction)
}
storage.dbReadWriteConnection.readWrite { transaction in
FriendRequestProtocol.acceptFriendRequest(from: bob, using: transaction)
5 years ago
XCTAssertTrue(self.storage.getFriendRequestStatus(for: bob, transaction: transaction) == .friends)
}
}
// TODO: Add test to see if an accept message is sent out
func test_acceptFriendRequestShouldSendAFriendRequestMessageIfStatusIsNoneOrExpired() {
// Case: Somehow our friend request status doesn't match the UI
// Since user accepted then we should send a friend request message
let statuses: [LKFriendRequestStatus] = [.none, .requestExpired]
for status in statuses {
let bob = generateHexEncodedPublicKey()
storage.dbReadWriteConnection.readWrite { transaction in
5 years ago
self.storage.setFriendRequestStatus(status, for: bob, transaction: transaction)
}
let expectation = self.expectation(description: "sent message")
messageSender.sendMessageWasCalledBlock = { [weak messageSender] sentMessage in
guard sentMessage is FriendRequestMessage else {
XCTFail("unexpected sentMessage: \(sentMessage)")
return
}
expectation.fulfill()
guard let strongMessageSender = messageSender else {
return
}
strongMessageSender.sendMessageWasCalledBlock = nil
}
storage.dbReadWriteConnection.readWrite { transaction in
FriendRequestProtocol.acceptFriendRequest(from: bob, using: transaction)
}
self.wait(for: [expectation], timeout: 1.0)
}
}
5 years ago
func test_acceptFriendRequestShouldNotDoAnythingIfRequestHasBeenSent() {
// Case: We sent Bob a friend request.
// We can't accept because we don't have keys to communicate with Bob.
let bob = generateHexEncodedPublicKey()
storage.dbReadWriteConnection.readWrite { transaction in
5 years ago
self.storage.setFriendRequestStatus(.requestSent, for: bob, transaction: transaction)
5 years ago
}
5 years ago
storage.dbReadWriteConnection.readWrite { transaction in
FriendRequestProtocol.acceptFriendRequest(from: bob, using: transaction)
XCTAssertTrue(self.isFriendRequestStatus(.requestSent, for: bob, transaction: transaction))
}
}
func test_acceptFriendRequestShouldWorkWithMultiDevice() {
// Case: Bob sent a friend request from his slave device.
// Accepting the friend request should set it to friends.
// We should also send out a friend request to Bob's other devices if possible.
let master = generateHexEncodedPublicKey()
let slave = generateHexEncodedPublicKey()
let otherSlave = generateHexEncodedPublicKey()
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
guard let otherSlaveDevice = getDevice(for: otherSlave) else { return XCTFail() }
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(DeviceLink(between: masterDevice, and: slaveDevice), in: transaction)
self.storage.addDeviceLink(DeviceLink(between: masterDevice, and: otherSlaveDevice), in: transaction)
5 years ago
self.storage.setFriendRequestStatus(.none, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.requestReceived, for: slave, transaction: transaction)
self.storage.setFriendRequestStatus(.requestSent, for: otherSlave, transaction: transaction)
}
storage.dbReadWriteConnection.readWrite { transaction in
FriendRequestProtocol.acceptFriendRequest(from: master, using: transaction)
}
eventually {
self.storage.dbReadWriteConnection.readWrite { transaction in
// TODO: Re-enable this case when we split friend request logic from OWSMessageSender
// XCTAssertTrue(self.isFriendRequestStatus([.requestSending, .requestSent], for: master, transaction: transaction))
XCTAssertTrue(self.isFriendRequestStatus(.friends, for: slave, transaction: transaction))
XCTAssertTrue(self.isFriendRequestStatus(.requestSent, for: otherSlave, transaction: transaction))
}
}
}
func test_acceptFriendRequestShouldNotChangeStatusIfDevicesAreNotLinked() {
let alice = generateHexEncodedPublicKey()
let bob = generateHexEncodedPublicKey()
storage.dbReadWriteConnection.readWrite { transaction in
5 years ago
self.storage.setFriendRequestStatus(.requestReceived, for: alice, transaction: transaction)
self.storage.setFriendRequestStatus(.requestReceived, for: bob, transaction: transaction)
}
storage.dbReadWriteConnection.readWrite { transaction in
FriendRequestProtocol.acceptFriendRequest(from: alice, using: transaction)
XCTAssertTrue(self.isFriendRequestStatus(.friends, for: alice, transaction: transaction))
XCTAssertTrue(self.isFriendRequestStatus(.requestReceived, for: bob, transaction: transaction))
}
}
// MARK: - declineFriendRequest
func test_declineFriendRequestShouldChangeStatusFromReceivedToNone() {
let bob = generateHexEncodedPublicKey()
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.setFriendRequestStatus(.requestReceived, for: bob, transaction: transaction)
}
storage.dbReadWriteConnection.readWrite { transaction in
FriendRequestProtocol.declineFriendRequest(from: bob, using: transaction)
XCTAssertTrue(self.isFriendRequestStatus(.none, for: bob, transaction: transaction))
}
}
func test_declineFriendRequestShouldNotChangeStatusToNoneFromOtherStatuses() {
let otherStatuses: [LKFriendRequestStatus] = [.none, .requestSending, .requestSent, .requestExpired, .friends]
let bob = generateHexEncodedPublicKey()
for status in otherStatuses {
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.setFriendRequestStatus(status, for: bob, transaction: transaction)
}
storage.dbReadWriteConnection.readWrite { transaction in
FriendRequestProtocol.declineFriendRequest(from: bob, using: transaction)
XCTAssertTrue(self.isFriendRequestStatus(status, for: bob, transaction: transaction))
}
}
}
func test_declineFriendRequestShouldDeletePreKeyBundleIfNeeded() {
let shouldExpectDeletedPreKeyBundle = { (status: LKFriendRequestStatus) -> Bool in
return status == .requestReceived
}
let statuses: [LKFriendRequestStatus] = [.none, .requestSending, .requestSent, .requestReceived, .requestExpired, .friends]
for status in statuses {
let bob = generateHexEncodedPublicKey()
let bundle = storage.generatePreKeyBundle(forContact: bob)
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.setPreKeyBundle(bundle, forContact: bob, transaction: transaction)
self.storage.setFriendRequestStatus(status, for: bob, transaction: transaction)
}
storage.dbReadWriteConnection.readWrite { transaction in
FriendRequestProtocol.declineFriendRequest(from: bob, using: transaction)
}
let storedBundle = storage.getPreKeyBundle(forContact: bob)
if (shouldExpectDeletedPreKeyBundle(status)) {
XCTAssertNil(storedBundle, "Was expecting PreKeyBundle to be deleted for friend request status \(status.rawValue)")
} else {
XCTAssertNotNil(storedBundle, "Was expecting PreKeyBundle to not be deleted for friend request status \(status.rawValue)")
}
}
}
func test_declineFriendRequestShouldWorkWithMultipleLinkedDevices() {
// Case: Bob sends 2 friend requests to Alice.
// When Alice declines, it should change the statuses from requestReceived to none so friend request logic can be re-triggered.
let master = generateHexEncodedPublicKey()
let slave = generateHexEncodedPublicKey()
let otherSlave = generateHexEncodedPublicKey()
guard let masterDevice = getDevice(for: master) else { return XCTFail() }
guard let slaveDevice = getDevice(for: slave) else { return XCTFail() }
guard let otherSlaveDevice = getDevice(for: otherSlave) else { return XCTFail() }
storage.dbReadWriteConnection.readWrite { transaction in
self.storage.addDeviceLink(DeviceLink(between: masterDevice, and: slaveDevice), in: transaction)
self.storage.addDeviceLink(DeviceLink(between: masterDevice, and: otherSlaveDevice), in: transaction)
self.storage.setFriendRequestStatus(.requestSent, for: master, transaction: transaction)
self.storage.setFriendRequestStatus(.requestReceived, for: slave, transaction: transaction)
self.storage.setFriendRequestStatus(.requestReceived, for: otherSlave, transaction: transaction)
}
storage.dbReadWriteConnection.readWrite { transaction in
FriendRequestProtocol.declineFriendRequest(from: master, using: transaction)
XCTAssertTrue(self.isFriendRequestStatus(.requestSent, for: master, transaction: transaction))
XCTAssertTrue(self.isFriendRequestStatus(.none, for: slave, transaction: transaction))
XCTAssertTrue(self.isFriendRequestStatus(.none, for: otherSlave, transaction: transaction))
}
}
5 years ago
}