From eba16c5c868b3d6152480f4005ace6c8e77af489 Mon Sep 17 00:00:00 2001 From: Gil Eluard Date: Tue, 4 Oct 2022 16:07:35 +0200 Subject: [PATCH] Add support for m.local_notification_settings. in account_data --- MatrixSDK.xcodeproj/project.pbxproj | 6 + MatrixSDK/Data/MXAccountData.h | 3 + MatrixSDK/Data/MXAccountData.m | 20 ++ MatrixSDK/MXRestClient.h | 2 + MatrixSDK/MXRestClient.m | 2 + MatrixSDKTests/MXAccountDataTests.m | 42 ++++ .../MXMatrixVersionsUnitTests.swift | 190 ++++++++++++++++++ changelog.d/6797.change | 1 + 8 files changed, 266 insertions(+) create mode 100644 MatrixSDKTests/MXMatrixVersionsUnitTests.swift create mode 100644 changelog.d/6797.change diff --git a/MatrixSDK.xcodeproj/project.pbxproj b/MatrixSDK.xcodeproj/project.pbxproj index 5af8bcdf8c..d02f4cee60 100644 --- a/MatrixSDK.xcodeproj/project.pbxproj +++ b/MatrixSDK.xcodeproj/project.pbxproj @@ -687,6 +687,8 @@ 3A858DE327529183006322C1 /* MXRoomCapabilityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A858DE027517C0E006322C1 /* MXRoomCapabilityType.swift */; }; 3A858DE8275511A4006322C1 /* MXRoomAliasAvailabilityCheckerResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A858DE7275511A4006322C1 /* MXRoomAliasAvailabilityCheckerResultTests.swift */; }; 3A858DE9275511A4006322C1 /* MXRoomAliasAvailabilityCheckerResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A858DE7275511A4006322C1 /* MXRoomAliasAvailabilityCheckerResultTests.swift */; }; + 3A9E2B4328EB3960000DB2A7 /* MXMatrixVersionsUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A9E2B4228EB3960000DB2A7 /* MXMatrixVersionsUnitTests.swift */; }; + 3A9E2B4428EB3960000DB2A7 /* MXMatrixVersionsUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A9E2B4228EB3960000DB2A7 /* MXMatrixVersionsUnitTests.swift */; }; 3AB5EBB4270B332B0058703A /* MXSpaceStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AB5EBB3270B332B0058703A /* MXSpaceStore.swift */; }; 3AB5EBB5270B332B0058703A /* MXSpaceStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AB5EBB3270B332B0058703A /* MXSpaceStore.swift */; }; 3AB5EBB7270ED1C00058703A /* MXSpaceFileStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AB5EBB6270ED1C00058703A /* MXSpaceFileStore.swift */; }; @@ -2562,6 +2564,7 @@ 3A858DDB275120D1006322C1 /* MXHomeserverCapabilitiesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXHomeserverCapabilitiesTests.swift; sourceTree = ""; }; 3A858DE027517C0E006322C1 /* MXRoomCapabilityType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXRoomCapabilityType.swift; sourceTree = ""; }; 3A858DE7275511A4006322C1 /* MXRoomAliasAvailabilityCheckerResultTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXRoomAliasAvailabilityCheckerResultTests.swift; sourceTree = ""; }; + 3A9E2B4228EB3960000DB2A7 /* MXMatrixVersionsUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXMatrixVersionsUnitTests.swift; sourceTree = ""; }; 3AB5EBB3270B332B0058703A /* MXSpaceStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXSpaceStore.swift; sourceTree = ""; }; 3AB5EBB6270ED1C00058703A /* MXSpaceFileStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXSpaceFileStore.swift; sourceTree = ""; }; 3AC135D72640335100EE1E74 /* MXDehydrationService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXDehydrationService.h; sourceTree = ""; }; @@ -4290,6 +4293,7 @@ B135067327EB201E00BD3276 /* MXLocationServiceTests.swift */, B1EE98D328048ACF00AB63F0 /* MXGeoURIComponentsUnitTests.swift */, B1F04B152811EFF700103EBE /* MXBeaconAggregationsTests.swift */, + 3A9E2B4228EB3960000DB2A7 /* MXMatrixVersionsUnitTests.swift */, ); path = MatrixSDKTests; sourceTree = ""; @@ -7113,6 +7117,7 @@ EDB4209527DF822B0036AF39 /* MXEventsByTypesEnumeratorOnArrayTests.swift in Sources */, EC40385D28A16EDA0067D5B8 /* MXAes256KeyBackupTests.m in Sources */, ED6DAC0728C77E1100ECDCB6 /* MXForwardedRoomKeyEventContentUnitTests.swift in Sources */, + 3A9E2B4328EB3960000DB2A7 /* MXMatrixVersionsUnitTests.swift in Sources */, 3265CB3B1A151C3800E24B2F /* MXRoomStateTests.m in Sources */, ED8F1D302885AB0300F897E7 /* MXTrustLevelSourceUnitTests.swift in Sources */, B135066927EA100000BD3276 /* MXBeaconInfoUnitTests.swift in Sources */, @@ -7735,6 +7740,7 @@ EDB4209627DF822B0036AF39 /* MXEventsByTypesEnumeratorOnArrayTests.swift in Sources */, EC40385E28A16EDA0067D5B8 /* MXAes256KeyBackupTests.m in Sources */, ED6DAC0828C77E1100ECDCB6 /* MXForwardedRoomKeyEventContentUnitTests.swift in Sources */, + 3A9E2B4428EB3960000DB2A7 /* MXMatrixVersionsUnitTests.swift in Sources */, 32B477AA2638186000EA5800 /* MXHTTPAdditionalHeadersUnitTests.m in Sources */, B135066A27EA100100BD3276 /* MXBeaconInfoUnitTests.swift in Sources */, EC0B944727206D0B00B4D440 /* MXCoreDataRoomListDataManagerUnitTests.swift in Sources */, diff --git a/MatrixSDK/Data/MXAccountData.h b/MatrixSDK/Data/MXAccountData.h index 38c7658bb2..7055b91b0c 100644 --- a/MatrixSDK/Data/MXAccountData.h +++ b/MatrixSDK/Data/MXAccountData.h @@ -73,4 +73,7 @@ */ @property (nonatomic, readonly) NSDictionary *accountData; ++ (nonnull NSString *)localNotificationSettingsKeyForDeviceWithId:(nonnull NSString*)deviceId; +- (nullable NSDictionary *)localNotificationSettingsForDeviceWithId:(nonnull NSString*)deviceId; + @end diff --git a/MatrixSDK/Data/MXAccountData.m b/MatrixSDK/Data/MXAccountData.m index 051831ff80..ad349a2072 100644 --- a/MatrixSDK/Data/MXAccountData.m +++ b/MatrixSDK/Data/MXAccountData.m @@ -18,6 +18,7 @@ #import "MXAccountData.h" #import "MXJSONModel.h" +#import "MXRestClient.h" @interface MXAccountData () { @@ -90,4 +91,23 @@ - (NSDictionary *)accountDataForEventType:(NSString*)eventType return @{@"events": events}; } ++ (NSString *)localNotificationSettingsKeyForDeviceWithId:(NSString*)deviceId +{ + return [kMXAccountDataLocalNotificationKeyPrefix stringByAppendingString:deviceId]; +} + +- (NSDictionary *)localNotificationSettingsForDeviceWithId:(NSString*)deviceId +{ + if (!deviceId) + { + return nil; + } + + + NSString *deviceNotificationKey = [MXAccountData localNotificationSettingsKeyForDeviceWithId:deviceId]; + NSDictionary *deviceNotificationSettings; + MXJSONModelSetDictionary(deviceNotificationSettings, accountDataDict[deviceNotificationKey]); + return deviceNotificationSettings; +} + @end diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index bf7dab4471..52fb8950ab 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -85,6 +85,8 @@ FOUNDATION_EXPORT NSString *const kMXAccountDataTypeClientInformation; FOUNDATION_EXPORT NSString *const kMXAccountDataKeyIgnoredUser; FOUNDATION_EXPORT NSString *const kMXAccountDataKeyIdentityServer; FOUNDATION_EXPORT NSString *const kMXAccountDataTypeRecentRoomsKey; +FOUNDATION_EXPORT NSString *const kMXAccountDataLocalNotificationKeyPrefix; +FOUNDATION_EXPORT NSString *const kMXAccountDataIsSilencedKey; /** diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index dbf1b03654..54707eef23 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -61,6 +61,8 @@ NSString *const kMXAccountDataKeyIdentityServer = @"base_url"; NSString *const kMXAccountDataTypeAcceptedTermsKey = @"accepted"; NSString *const kMXAccountDataTypeRecentRoomsKey = @"recent_rooms"; +NSString *const kMXAccountDataLocalNotificationKeyPrefix = @"org.matrix.msc3890.local_notification_settings."; +NSString *const kMXAccountDataIsSilencedKey = @"is_silenced"; /** Types of third party media. diff --git a/MatrixSDKTests/MXAccountDataTests.m b/MatrixSDKTests/MXAccountDataTests.m index 0866d80fc3..efbff3f30e 100644 --- a/MatrixSDKTests/MXAccountDataTests.m +++ b/MatrixSDKTests/MXAccountDataTests.m @@ -205,6 +205,48 @@ - (void)testIgnoreUserUpdateHasNoCollateralDamageOnPushRules } +// Test the capability to read or write `m.local_notification_settings.` +// events in account data. +- (void)testReadWriteLocalNotificationSettings +{ + [matrixSDKTestsData doMXSessionTestWithBob:self readyToTest:^(MXSession *mxSession, XCTestExpectation *expectation) { + XCTAssertNotNil(mxSession.accountData, @"account data shouldn't be nil."); + XCTAssertNil([mxSession.accountData localNotificationSettingsForDeviceWithId:mxSession.myDeviceId], @"account local notification settings should be nil."); + + NSDictionary *localNotificationSettings = @{ + kMXAccountDataIsSilencedKey: @(YES) + }; + + [mxSession setAccountData:localNotificationSettings forType:[MXAccountData localNotificationSettingsKeyForDeviceWithId:mxSession.myDeviceId] success:^{ + NSDictionary *localNotificationSettings = [mxSession.accountData localNotificationSettingsForDeviceWithId:mxSession.myDeviceId]; + XCTAssertNotNil(localNotificationSettings, @"account local notification settings shouldn't be nil."); + NSNumber *isSilenced = localNotificationSettings[kMXAccountDataIsSilencedKey]; + XCTAssertNotNil(isSilenced, @"account local notification is_silenced settings shouldn't be nil."); + XCTAssertTrue(isSilenced.boolValue, @"is_silenced settings should be set to true."); + + localNotificationSettings = @{ + kMXAccountDataIsSilencedKey: @(NO) + }; + + [mxSession setAccountData:localNotificationSettings forType:[MXAccountData localNotificationSettingsKeyForDeviceWithId:mxSession.myDeviceId] success:^{ + NSDictionary *localNotificationSettings = [mxSession.accountData localNotificationSettingsForDeviceWithId:mxSession.myDeviceId]; + XCTAssertNotNil(localNotificationSettings, @"account local notification settings shouldn't be nil."); + NSNumber *isSilenced = localNotificationSettings[kMXAccountDataIsSilencedKey]; + XCTAssertNotNil(isSilenced, @"account local notification is_silenced settings shouldn't be nil."); + XCTAssertFalse(isSilenced.boolValue, @"is_silenced settings should be set to false."); + [expectation fulfill]; + } failure:^(NSError *error) { + XCTFail(@"MXSession setAccountData failed due to error %@", error); + [expectation fulfill]; + }]; + } failure:^(NSError *error) { + XCTFail(@"MXSession setAccountData failed due to error %@", error); + [expectation fulfill]; + }]; + }]; +} + + @end #pragma clang diagnostic pop diff --git a/MatrixSDKTests/MXMatrixVersionsUnitTests.swift b/MatrixSDKTests/MXMatrixVersionsUnitTests.swift new file mode 100644 index 0000000000..8307d2c473 --- /dev/null +++ b/MatrixSDKTests/MXMatrixVersionsUnitTests.swift @@ -0,0 +1,190 @@ +// +// Copyright 2022 The Matrix.org Foundation C.I.C +// +// 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 + +class MXMatrixVersionsUnitTests: XCTestCase { + + private static let emptyVersions: [String: Any] = + [ + "unstable_features": [:], + "versions": [] + ] + + private static let fullSupportVersions: [String: Any] = + [ + "unstable_features": [ + "org.matrix.msc2716": true, + "io.element.e2ee_forced.private": true, + "io.element.e2ee_forced.public": true, + "org.matrix.msc3030": true, + "org.matrix.e2e_cross_signing": true, + "org.matrix.msc2432": true, + "io.element.e2ee_forced.trusted_private": true, + "org.matrix.msc3440.stable": true, + "org.matrix.msc3827.stable": true, + "fi.mau.msc2815": true, + "uk.half-shot.msc2666.mutual_rooms": true, + "org.matrix.label_based_filtering": true, + "org.matrix.msc3026.busy_presence": true, + "org.matrix.msc2285.stable": true, + "org.matrix.msc3881.stable": true + ], + "versions": [ + "r0.0.1", + "r0.1.0", + "r0.2.0", + "r0.3.0", + "r0.4.0", + "r0.5.0", + "r0.6.0", + "r0.6.1", + "v1.1", + "v1.2" + ] + ] + + private static let noSupportVersions: [String: Any] = + [ + "unstable_features": [ + "org.matrix.msc2716": false, + "io.element.e2ee_forced.private": false, + "io.element.e2ee_forced.public": false, + "org.matrix.msc3030": false, + "org.matrix.e2e_cross_signing": false, + "org.matrix.msc2432": false, + "io.element.e2ee_forced.trusted_private": false, + "org.matrix.msc3440.stable": false, + "org.matrix.msc3827.stable": false, + "fi.mau.msc2815": false, + "uk.half-shot.msc2666.mutual_rooms": false, + "org.matrix.label_based_filtering": false, + "org.matrix.msc3026.busy_presence": false, + "org.matrix.msc2285.stable": false, + "org.matrix.msc3881.stable": false + ], + "versions": [ + "r0.0.1", + "r0.1.0", + "r0.2.0", + "r0.3.0", + "r0.4.0", + "r0.6.1", + "v1.1", + "v1.2" + ] + ] + + // MARK: - Properties + + private var testData: MatrixSDKTestsData! + + // MARK: - Setup + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + try super.setUpWithError() + testData = MatrixSDKTestsData() + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + testData = nil + try super.tearDownWithError() + } + + // MARK: - Tests + + /// - Create Bob + /// - Setup Bob session + /// + /// -> Supported Matrix versions should be initialised and not empty + func testSupportedMatrixVersionsInitialised() throws { + testData.doMXSessionTest(withBob: self) { session, expectation in + guard let session = session else { + XCTFail("session shouldn't be nil") + expectation?.fulfill() + return + } + + session.supportedMatrixVersions { response in + switch response { + case .success(let versions): + XCTAssertFalse(versions.versions.isEmpty, "versions shouldn't be empty") + XCTAssertNotNil(versions.unstableFeatures, "versions should contain unstable features") + case .failure(let error): + XCTFail("supportedMatrixVersions failed due to error \(error)") + } + + expectation?.fulfill() + } + } + } + + func testEmptyVersions() throws { + guard let versions = MXMatrixVersions(fromJSON: Self.emptyVersions) else { + XCTFail("Unable to instantiate MXMatrixVersions") + return + } + + XCTAssertTrue(versions.versions.isEmpty, "versions should be empty") + guard let unstableFeatures = versions.unstableFeatures else { + XCTFail("MXMatrixVersions instance should have unstableFeatures") + return + } + XCTAssertTrue(unstableFeatures.isEmpty, "unstableFeatures should be empty") + XCTAssertFalse(versions.supportLazyLoadMembers, "versions shouldn't support Lazy Load Members") + XCTAssertFalse(versions.supportsThreads, "versions shouldn't support threads") + XCTAssertFalse(versions.doesServerSupportSeparateAddAndBind, "versions shouldn't support separate Add And Bind") + XCTAssertFalse(versions.supportsRemotelyTogglingPushNotifications, "versions shouldn't support remotely toggling push notifications") + } + + func testFullSupportVersions() throws { + guard let versions = MXMatrixVersions(fromJSON: Self.fullSupportVersions) else { + XCTFail("Unable to instantiate MXMatrixVersions") + return + } + + XCTAssertFalse(versions.versions.isEmpty, "versions shouldn't be empty") + guard let unstableFeatures = versions.unstableFeatures else { + XCTFail("MXMatrixVersions instance should have unstableFeatures") + return + } + XCTAssertFalse(unstableFeatures.isEmpty, "unstableFeatures shouldn't be empty") + XCTAssertTrue(versions.supportLazyLoadMembers, "versions should support Lazy Load Members") + XCTAssertTrue(versions.supportsThreads, "versions should support threads") + XCTAssertTrue(versions.doesServerSupportSeparateAddAndBind, "versions should support separate Add And Bind") + XCTAssertTrue(versions.supportsRemotelyTogglingPushNotifications, "versions should support remotely toggling push notifications") + } + + func testNoSupportVersions() throws { + guard let versions = MXMatrixVersions(fromJSON: Self.noSupportVersions) else { + XCTFail("Unable to instantiate MXMatrixVersions") + return + } + + XCTAssertFalse(versions.versions.isEmpty, "versions shouldn't be empty") + guard let unstableFeatures = versions.unstableFeatures else { + XCTFail("MXMatrixVersions instance should have unstableFeatures") + return + } + XCTAssertFalse(unstableFeatures.isEmpty, "unstableFeatures shouldn't be empty") + XCTAssertFalse(versions.supportLazyLoadMembers, "versions shouldn't support Lazy Load Members") + XCTAssertFalse(versions.supportsThreads, "versions shouldn't support threads") + XCTAssertFalse(versions.doesServerSupportSeparateAddAndBind, "versions shouldn't support separate Add And Bind") + XCTAssertFalse(versions.supportsRemotelyTogglingPushNotifications, "versions shouldn't support remotely toggling push notifications") + } +} diff --git a/changelog.d/6797.change b/changelog.d/6797.change new file mode 100644 index 0000000000..b5e4c79baf --- /dev/null +++ b/changelog.d/6797.change @@ -0,0 +1 @@ +Add support for m.local_notification_settings. in account_data