242 lines
9.2 KiB
Swift
242 lines
9.2 KiB
Swift
//
|
|
// Copyright 2022 New Vector Ltd
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
import XCTest
|
|
|
|
@testable import Element
|
|
|
|
class UserSessionCardViewDataTests: XCTestCase {
|
|
func testOtherSessionsWithCrossSigning() {
|
|
// Given a data provider for a session that can cross sign.
|
|
let mxSession = MockSession(canCrossSign: true)
|
|
let dataProvider = UserSessionsDataProvider(session: mxSession)
|
|
|
|
// When the verification state of other sessions is requested.
|
|
let deviceA = MockDeviceInfo(deviceID: .otherDeviceA, verified: true)
|
|
let deviceB = MockDeviceInfo(deviceID: .otherDeviceB, verified: false)
|
|
let verificationStateA = dataProvider.verificationState(for: deviceA)
|
|
let verificationStateB = dataProvider.verificationState(for: deviceB)
|
|
|
|
// Then they should match the verification state from the device info.
|
|
XCTAssertEqual(verificationStateA, .verified)
|
|
XCTAssertEqual(verificationStateB, .unverified)
|
|
}
|
|
|
|
func testOtherSessionsWithoutCrossSigning() {
|
|
// Given a data provider for a session that can't cross sign.
|
|
let mxSession = MockSession(canCrossSign: false)
|
|
let dataProvider = UserSessionsDataProvider(session: mxSession)
|
|
|
|
// When the verification state of other sessions is requested.
|
|
let deviceA = MockDeviceInfo(deviceID: .otherDeviceA, verified: true)
|
|
let deviceB = MockDeviceInfo(deviceID: .otherDeviceB, verified: false)
|
|
let verificationStateA = dataProvider.verificationState(for: deviceA)
|
|
let verificationStateB = dataProvider.verificationState(for: deviceB)
|
|
|
|
// Then they should return an unknown verification state.
|
|
XCTAssertEqual(verificationStateA, .unknown)
|
|
XCTAssertEqual(verificationStateB, .unknown)
|
|
}
|
|
|
|
func testCurrentDeviceWithCrossSigning() {
|
|
// Given a data provider for a session that can cross sign.
|
|
let mxSession = MockSession(canCrossSign: true)
|
|
let dataProvider = UserSessionsDataProvider(session: mxSession)
|
|
|
|
// When the verification state of the same session is requested.
|
|
let currentDeviceVerified = MockDeviceInfo(deviceID: .currentDevice, verified: true)
|
|
let currentDeviceUnverified = MockDeviceInfo(deviceID: .currentDevice, verified: false)
|
|
let verificationStateVerified = dataProvider.verificationState(for: currentDeviceVerified)
|
|
let verificationStateUnverified = dataProvider.verificationState(for: currentDeviceUnverified)
|
|
|
|
// Then the verification state should be unknown.
|
|
XCTAssertEqual(verificationStateVerified, .verified)
|
|
XCTAssertEqual(verificationStateUnverified, .unverified)
|
|
}
|
|
|
|
func testCurrentDeviceWithoutCrossSigning() {
|
|
// Given a data provider for a session that can't cross sign.
|
|
let mxSession = MockSession(canCrossSign: false)
|
|
let dataProvider = UserSessionsDataProvider(session: mxSession)
|
|
|
|
// When the verification state of the same session is requested.
|
|
let currentDeviceVerified = MockDeviceInfo(deviceID: .currentDevice, verified: true)
|
|
let currentDeviceUnverified = MockDeviceInfo(deviceID: .currentDevice, verified: false)
|
|
let verificationStateVerified = dataProvider.verificationState(for: currentDeviceVerified)
|
|
let verificationStateUnverified = dataProvider.verificationState(for: currentDeviceUnverified)
|
|
|
|
// Then the verification state should be unknown.
|
|
XCTAssertEqual(verificationStateVerified, .unverified)
|
|
XCTAssertEqual(verificationStateUnverified, .unverified)
|
|
}
|
|
|
|
func testDeviceNotHavingCryptoSupportOnVerifiedDevice() {
|
|
let mxSession = MockSession(canCrossSign: true)
|
|
let dataProvider = UserSessionsDataProvider(session: mxSession)
|
|
|
|
let verificationState = dataProvider.verificationState(for: nil)
|
|
|
|
XCTAssertEqual(verificationState, .permanentlyUnverified)
|
|
}
|
|
|
|
func testDeviceNotHavingCryptoSupportOnUnverifiedDevice() {
|
|
let mxSession = MockSession(canCrossSign: false)
|
|
let dataProvider = UserSessionsDataProvider(session: mxSession)
|
|
|
|
let verificationState = dataProvider.verificationState(for: nil)
|
|
|
|
XCTAssertEqual(verificationState, .permanentlyUnverified)
|
|
}
|
|
|
|
func testObsoletedDeviceInformation_someMatch() {
|
|
let mxSession = MockSession(canCrossSign: true)
|
|
let dataProvider = UserSessionsDataProvider(session: mxSession)
|
|
|
|
let accountDataEvents: [String: Any] = [
|
|
"io.element.matrix_client_information.D": "",
|
|
"foo": ""
|
|
]
|
|
|
|
let expectedObsoletedEvents: Set = [
|
|
"io.element.matrix_client_information.D"
|
|
]
|
|
|
|
let obsoletedEvents = dataProvider.obsoletedDeviceAccountData(deviceList: .mockDevices, accountDataEvents: accountDataEvents)
|
|
|
|
XCTAssertEqual(obsoletedEvents, expectedObsoletedEvents)
|
|
}
|
|
|
|
func testObsoletedDeviceInformation_noMatch() {
|
|
let mxSession = MockSession(canCrossSign: true)
|
|
let dataProvider = UserSessionsDataProvider(session: mxSession)
|
|
|
|
let accountDataEvents: [String: Any] = [
|
|
"io.element.matrix_client_information.C": "",
|
|
"foo": ""
|
|
]
|
|
|
|
let expectedObsoletedEvents: Set<String> = []
|
|
let obsoletedEvents = dataProvider.obsoletedDeviceAccountData(deviceList: .mockDevices, accountDataEvents: accountDataEvents)
|
|
|
|
XCTAssertEqual(obsoletedEvents, expectedObsoletedEvents)
|
|
}
|
|
|
|
func testObsoletedDeviceInformation_allMatch() {
|
|
let mxSession = MockSession(canCrossSign: true)
|
|
let dataProvider = UserSessionsDataProvider(session: mxSession)
|
|
|
|
let expectedObsoletedEvents = Set(["D", "E", "F"].map { "io.element.matrix_client_information.\($0)"})
|
|
|
|
let accountDataEvents: [String: Any] = expectedObsoletedEvents.reduce(into: ["foo": ""]) { partialResult, value in
|
|
partialResult[value] = ""
|
|
}
|
|
|
|
let obsoletedEvents = dataProvider.obsoletedDeviceAccountData(deviceList: .mockDevices, accountDataEvents: accountDataEvents)
|
|
|
|
XCTAssertEqual(obsoletedEvents, expectedObsoletedEvents)
|
|
}
|
|
}
|
|
|
|
// MARK: Mocks
|
|
|
|
private extension Array where Element == MXDevice {
|
|
static let mockDevices: [MXDevice] = {
|
|
["A", "B", "C"]
|
|
.map {
|
|
let device = MXDevice()
|
|
device.deviceId = $0
|
|
return device
|
|
}
|
|
}()
|
|
}
|
|
|
|
// Device ID constants.
|
|
private extension String {
|
|
static var otherDeviceA: String { "abcdef" }
|
|
static var otherDeviceB: String { "ghijkl" }
|
|
static var currentDevice: String { "uvwxyz" }
|
|
}
|
|
|
|
/// A mock `MXSession` that can override the `canCrossSign` state.
|
|
private class MockSession: MXSession {
|
|
let canCrossSign: Bool
|
|
override var myDeviceId: String! { .currentDevice }
|
|
|
|
override var crypto: MXCrypto! {
|
|
get { MockCrypto(canCrossSign: canCrossSign) }
|
|
set { }
|
|
}
|
|
|
|
init(canCrossSign: Bool) {
|
|
self.canCrossSign = canCrossSign
|
|
super.init()
|
|
}
|
|
|
|
}
|
|
|
|
/// A mock `MXCrypto` that can override the `canCrossSign` state.
|
|
private class MockCrypto: MXLegacyCrypto {
|
|
let canCrossSign: Bool
|
|
override var crossSigning: MXCrossSigning { MockCrossSigning(canCrossSign: canCrossSign) }
|
|
|
|
init(canCrossSign: Bool) {
|
|
self.canCrossSign = canCrossSign
|
|
super.init()
|
|
}
|
|
|
|
}
|
|
|
|
/// A mock `MXCrossSigning` with an overridden `canCrossSign` property.
|
|
private class MockCrossSigning: MXLegacyCrossSigning {
|
|
let canCrossSignMock: Bool
|
|
override var canCrossSign: Bool { canCrossSignMock }
|
|
|
|
init(canCrossSign: Bool) {
|
|
self.canCrossSignMock = canCrossSign
|
|
super.init()
|
|
}
|
|
|
|
override var state: MXCrossSigningState {
|
|
.crossSigningExists
|
|
}
|
|
}
|
|
|
|
/// A mock `MXDeviceInfo` that can override the `isVerified` state.
|
|
private class MockDeviceInfo: MXDeviceInfo {
|
|
private let verified: Bool
|
|
override var trustLevel: MXDeviceTrustLevel! { MockDeviceTrustLevel(verified: verified) }
|
|
|
|
init(deviceID: String, verified: Bool) {
|
|
self.verified = verified
|
|
super.init(deviceId: deviceID)
|
|
}
|
|
|
|
required init?(coder: NSCoder) { fatalError() }
|
|
}
|
|
|
|
/// A mock `MXDeviceTrustLevel` with an overridden `isVerified` property.
|
|
private class MockDeviceTrustLevel: MXDeviceTrustLevel {
|
|
private let verified: Bool
|
|
override var isVerified: Bool { verified }
|
|
|
|
init(verified: Bool) {
|
|
self.verified = verified
|
|
super.init()
|
|
}
|
|
|
|
required init?(coder: NSCoder) { fatalError() }
|
|
}
|