element-ios/RiotTests/UserSessionsDataProviderTes...

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() }
}