diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Service/MatrixSDK/UserSessionsDataProvider.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Service/MatrixSDK/UserSessionsDataProvider.swift index 5f1273329..60f0b2054 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Service/MatrixSDK/UserSessionsDataProvider.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionsOverview/Service/MatrixSDK/UserSessionsDataProvider.swift @@ -76,18 +76,25 @@ class UserSessionsDataProvider: UserSessionsDataProviderProtocol { } } -private extension UserSessionsDataProvider { - func deleteAccountDataIfNeeded(deviceList: [MXDevice]) { +extension UserSessionsDataProvider { + // internal just to facilitate tests + func obsoletedDeviceAccountData(deviceList: [MXDevice], accountDataEvents: [String: Any]) -> Set { let deviceAccountDataKeys = Set( - session - .accountData - .allAccountDataEvents() + accountDataEvents .map(\.key) .filter { $0.hasPrefix(kMXAccountDataTypeClientInformation) } ) - let expectedDeviceAccountDataKeys = Set(deviceList.map { "\(kMXAccountDataTypeClientInformation).\($0.deviceId)" }) - let obsoletedDeviceAccountDataKeys = deviceAccountDataKeys.subtracting(expectedDeviceAccountDataKeys) + let expectedDeviceAccountDataKeys = Set(deviceList.map { + "\(kMXAccountDataTypeClientInformation).\($0.deviceId)" + }) + + return deviceAccountDataKeys.subtracting(expectedDeviceAccountDataKeys) + } + + private func deleteAccountDataIfNeeded(deviceList: [MXDevice]) { + let obsoletedDeviceAccountDataKeys = obsoletedDeviceAccountData(deviceList: deviceList, + accountDataEvents: session.accountData.allAccountDataEvents()) for accountDataKey in obsoletedDeviceAccountDataKeys { session.deleteAccountData(withType: accountDataKey, success: {}, failure: { _ in }) diff --git a/RiotTests/UserSessionsDataProviderTests.swift b/RiotTests/UserSessionsDataProviderTests.swift index 4695d9fc3..1877f22c4 100644 --- a/RiotTests/UserSessionsDataProviderTests.swift +++ b/RiotTests/UserSessionsDataProviderTests.swift @@ -100,10 +100,67 @@ class UserSessionCardViewDataTests: XCTestCase { 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": "" + ] + + 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": "" + ] + + let expectedObsoletedEvents: Set = [] + 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: [:]) { 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" }