Added unit tests for NotificationManager (#376)

* NotificationManager tests

* More unit tests

* More tests, moved classes to separate files

* Removed warnings

* UserNotificationCenterProtocol as AnyObject

* Reverted back Package.resolved
This commit is contained in:
Aleksandrs Proskurins 2022-12-21 12:06:30 +02:00 committed by GitHub
parent 71f1f044c7
commit a9f2e1bdf8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 577 additions and 22 deletions

View File

@ -22,6 +22,7 @@
071A017E415AD378F2961B11 /* URL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 227AC5D71A4CE43512062243 /* URL.swift */; };
07240B7159A3990C4C2E8FFC /* LoginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D256FEE2F1AF1E51D39B622 /* LoginTests.swift */; };
072BA9DBA932374CCA300125 /* MessageComposerTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6C10032A77AE7DC5AA4C50 /* MessageComposerTextField.swift */; };
08248D02BACA75CDC3B39A96 /* UserNotificationCenterSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69219A908D7C22E6EE6689AE /* UserNotificationCenterSpy.swift */; };
086C2FA7750378EB2BFD0BEE /* UITestsRootCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751BB69BB7C38FD247517B4 /* UITestsRootCoordinator.swift */; };
095C0ACFC234E0550A6404C5 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FC803282F9268D49F4ABF14 /* AppCoordinator.swift */; };
09713669577CDA8D012EE380 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 6647C55D93508C7CE9D954A5 /* MatrixRustSDK */; };
@ -38,6 +39,7 @@
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */; };
0F3F2FDD4021A25A0D57F801 /* MediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885D8C42DD17625B5261BEFF /* MediaProvider.swift */; };
0F9E38A75337D0146652ACAB /* BackgroundTaskTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DFCAA239095A116976E32C4 /* BackgroundTaskTests.swift */; };
1146E9EDCF8344F7D6E0D553 /* MockCoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0376C429FAB1687C3D905F3E /* MockCoder.swift */; };
1281625B25371BE53D36CB3A /* SeparatorRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1ED7E89865201EE7D53E6DA /* SeparatorRoomTimelineItem.swift */; };
12CCA59536EDD99A3272CF77 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC3F82523D6F48B926D6AF68 /* AppSettings.swift */; };
132D241B09F9044711FD70A5 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 91DE43B8815918E590912DDA /* InfoPlist.strings */; };
@ -62,6 +64,7 @@
1A70A2199394B5EC660934A5 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = A678E40E917620059695F067 /* MatrixRustSDK */; };
1A8BDEB96C3B2F033FA563F8 /* EmojiPickerHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB785716B9212C093704E767 /* EmojiPickerHeaderView.swift */; };
1AE4AEA0FA8DEF52671832E0 /* RoomTimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */; };
1B2DADC008EE211AF1DA5292 /* NotificationManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */; };
1B4B3E847BF944DB2C1C217F /* BackgroundTaskServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE73D571D4F9C36DD45255A /* BackgroundTaskServiceProtocol.swift */; };
1CF18DE71D5D23C61BD88852 /* DebugScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9238D3A3A00F45E841FE4EFF /* DebugScreen.swift */; };
1D69E31913DF66426985909B /* EmojiPickerScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11151E78D6BB2B04A8FBD389 /* EmojiPickerScreenViewModelProtocol.swift */; };
@ -267,6 +270,7 @@
8CC12086CBF91A7E10CDC205 /* HomeScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D653265D006E708E4E51AD64 /* HomeScreenCoordinator.swift */; };
8D3E1FADD78E72504DE0E402 /* UserAgentBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */; };
8D9F646387DF656EF91EE4CB /* RoomMessageFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96F37AB24AF5A006521D38D1 /* RoomMessageFactoryProtocol.swift */; };
8E650379587C31D7912ED67B /* UNNotification+Creator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC0AEA686E425F86F6BA0404 /* UNNotification+Creator.swift */; };
8F2FAA98457750D9D664136F /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 7731767AE437BA3BD2CC14A8 /* Sentry */; };
90DF83A6A347F7EE7EDE89EE /* AttributedStringBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF25E364AE85090A70AE4644 /* AttributedStringBuilderTests.swift */; };
90EB25D13AE6EEF034BDE9D2 /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71D52BAA5BADB06E5E8C295D /* Assets.swift */; };
@ -333,9 +337,11 @@
ABF3FAB234AD3565B214309B /* TimelineSenderAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC588051E6572A1AF51D738 /* TimelineSenderAvatarView.swift */; };
AC5CC8250CEAE57B73900C57 /* UserNotificationModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD80F22830C2360F3F39DDCE /* UserNotificationModalView.swift */; };
AC69B6DF15FC451AB2945036 /* UserSessionStoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEBA759D1347CFFB3D84ED1F /* UserSessionStoreProtocol.swift */; };
ACAB49022C2EBD00AFC67729 /* ClientProxySpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1924EF73801E03610E0F2AB /* ClientProxySpy.swift */; };
ACF094CF3BF02DBFA6DFDE60 /* AuthenticationCoordinatorUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D2D0A6F1ABC99D29462FB84 /* AuthenticationCoordinatorUITests.swift */; };
AD2A81B65A9F6163012086F1 /* MXLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111B698739E3410E2CDB7144 /* MXLog.swift */; };
AEE3981A0F090208E4445808 /* MockNotificationServiceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B37DCC9025452F46F91340E /* MockNotificationServiceProxy.swift */; };
AF33B9044498211C3D82F1E1 /* UNTextInputNotificationResponse+Creator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */; };
B037C365CF8A58A0D149A2DB /* AuthenticationIconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97755C01C3971474EFAD5367 /* AuthenticationIconImage.swift */; };
B064D42BA087649ACAE462E8 /* SoftLogoutUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55F30E764BED111C81739844 /* SoftLogoutUITests.swift */; };
B09514A0A3EB3C19A4FD0B71 /* SoftLogoutScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CCBDE671A613B3EB70794C4 /* SoftLogoutScreen.swift */; };
@ -418,6 +424,7 @@
E0A4DCA633D174EB43AD599F /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */; };
E1DF24D085572A55C9758A2D /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; };
E290C78E7F09F47FD2662986 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40C19719687984FD9478FBE /* Task.swift */; };
E3291AD16D7A5CB14781819C /* UserNotificationCenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45D8149FDDA0315CDC553B4B /* UserNotificationCenterProtocol.swift */; };
E3C328EF20C4B3326D263BCD /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */; };
E3CA565A4B9704F191B191F0 /* JoinedRoomSize+MemberCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */; };
E47CD939D8480657D4B706C6 /* AnalyticsPromptCheckmarkItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA7B2E9CC5DC3B76ADC35A43 /* AnalyticsPromptCheckmarkItem.swift */; };
@ -516,6 +523,7 @@
01C4C7DB37597D7D8379511A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
02A07FF019724B6ACEA73076 /* szl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = szl; path = szl.lproj/Localizable.strings; sourceTree = "<group>"; };
033DB41C51865A2E83174E87 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
0376C429FAB1687C3D905F3E /* MockCoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCoder.swift; sourceTree = "<group>"; };
04BBC9E08250EF92ADE89CFD /* sr-Latn */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sr-Latn"; path = "sr-Latn.lproj/Localizable.strings"; sourceTree = "<group>"; };
04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManager.swift; sourceTree = "<group>"; };
054F469E433864CC6FE6EE8E /* ServerSelectionUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionUITests.swift; sourceTree = "<group>"; };
@ -556,6 +564,8 @@
1215A4FC53D2319E81AE8970 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1222DB76B917EB8A55365BA5 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
124D85E85505B6B81845235F /* fy */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fy; path = fy.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
12A626D74BBE9F4A60763B45 /* ImageAnonymizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageAnonymizer.swift; sourceTree = "<group>"; };
130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNTextInputNotificationResponse+Creator.swift"; sourceTree = "<group>"; };
13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
1423AB065857FA546444DB15 /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = "<group>"; };
142808B69851451AC32A2CEA /* RoomSummaryDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryDetails.swift; sourceTree = "<group>"; };
@ -616,6 +626,7 @@
2EEB64CC6F3DF5B68736A6B4 /* AlertInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertInfo.swift; sourceTree = "<group>"; };
2EFE1922F39398ABFB36DF3F /* RoomDetailsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsViewModelTests.swift; sourceTree = "<group>"; };
2F1B28C596DE541DA0AFD16C /* lo */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = lo; path = lo.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManagerTests.swift; sourceTree = "<group>"; };
31B01468022EC826CB2FD2C0 /* LoginModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginModels.swift; sourceTree = "<group>"; };
31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = "<group>"; };
32C5DAA1773F57653BF1C4F9 /* SoftLogoutViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutViewModelTests.swift; sourceTree = "<group>"; };
@ -657,6 +668,7 @@
44D8C8431416EB8DFEC7E235 /* ApplicationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationTests.swift; sourceTree = "<group>"; };
453E722A43D092C06FB8E3FA /* tzm */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tzm; path = tzm.lproj/Localizable.strings; sourceTree = "<group>"; };
4549FCB53F43DB0B278374BC /* TemplateScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreen.swift; sourceTree = "<group>"; };
45D8149FDDA0315CDC553B4B /* UserNotificationCenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationCenterProtocol.swift; sourceTree = "<group>"; };
46C208DA43CE25D13E670F40 /* UITestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsAppCoordinator.swift; sourceTree = "<group>"; };
47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = "<group>"; };
471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineView.swift; sourceTree = "<group>"; };
@ -721,6 +733,7 @@
667DD3A9D932D7D9EB380CAA /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sk; path = sk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
66F2402D738694F98729A441 /* RoomTimelineProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineProvider.swift; sourceTree = "<group>"; };
6920A4869821BF72FFC58842 /* MockMediaProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaProvider.swift; sourceTree = "<group>"; };
69219A908D7C22E6EE6689AE /* UserNotificationCenterSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationCenterSpy.swift; sourceTree = "<group>"; };
6A1AAC8EB2992918D01874AC /* rue */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = rue; path = rue.lproj/Localizable.strings; sourceTree = "<group>"; };
6A580295A56B55A856CC4084 /* InfoPlistReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoPlistReader.swift; sourceTree = "<group>"; };
6A6C4BE591FE5C38CE9C7EF3 /* UserProperties+Element.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserProperties+Element.swift"; sourceTree = "<group>"; };
@ -951,6 +964,7 @@
DA6B262D7584C65BC5B79A0E /* UserNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotification.swift; sourceTree = "<group>"; };
DBD460ED7ED1E03B85DEA25C /* TemplateCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateCoordinator.swift; sourceTree = "<group>"; };
DBFEAC3AC691CBB84983E275 /* ElementXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXTests.swift; sourceTree = "<group>"; };
DC0AEA686E425F86F6BA0404 /* UNNotification+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNNotification+Creator.swift"; sourceTree = "<group>"; };
DC77FC5C4F2000133047AA27 /* SoftLogoutModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutModels.swift; sourceTree = "<group>"; };
DCD5FEE195446A9E458DDDAF /* NotificationServiceProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationServiceProxyProtocol.swift; sourceTree = "<group>"; };
DD667C4BB98CF4F3FE2CE3B0 /* LoginCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginCoordinator.swift; sourceTree = "<group>"; };
@ -1003,6 +1017,7 @@
F118CF7C5548099AACF7E90C /* RoomMembersCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersCoordinator.swift; sourceTree = "<group>"; };
F15BE37BE2FB86E00C8D150A /* AggregratedReaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AggregratedReaction.swift; sourceTree = "<group>"; };
F174A5627CDB3CAF280D1880 /* EmojiPickerScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenModels.swift; sourceTree = "<group>"; };
F1924EF73801E03610E0F2AB /* ClientProxySpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientProxySpy.swift; sourceTree = "<group>"; };
F23BA6D4842D53C5AC9B7584 /* nn */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = nn; path = nn.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
F2D58333B377888012740101 /* LoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = "<group>"; };
F31A4E5941ACBA4BB9FEF94C /* UserNotificationToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationToastView.swift; sourceTree = "<group>"; };
@ -1617,6 +1632,7 @@
96561CC53F7C1E24D4C292E4 /* MockNotificationManager.swift */,
1423AB065857FA546444DB15 /* NotificationManager.swift */,
A057F2FDC14866C3026A89A4 /* NotificationManagerProtocol.swift */,
45D8149FDDA0315CDC553B4B /* UserNotificationCenterProtocol.swift */,
);
path = Manager;
sourceTree = "<group>";
@ -1690,6 +1706,7 @@
EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */,
0DE6C5C756E1393202BA95CD /* UserNotificationControllerTests.swift */,
A3004DFA1B10951962787D90 /* VideoPlayerViewModelTests.swift */,
7DBC911559934065993A5FF4 /* NotificationManager */,
);
path = Sources;
sourceTree = "<group>";
@ -1785,6 +1802,19 @@
path = View;
sourceTree = "<group>";
};
7DBC911559934065993A5FF4 /* NotificationManager */ = {
isa = PBXGroup;
children = (
F1924EF73801E03610E0F2AB /* ClientProxySpy.swift */,
0376C429FAB1687C3D905F3E /* MockCoder.swift */,
30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */,
DC0AEA686E425F86F6BA0404 /* UNNotification+Creator.swift */,
130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */,
69219A908D7C22E6EE6689AE /* UserNotificationCenterSpy.swift */,
);
path = NotificationManager;
sourceTree = "<group>";
};
7B29CA1D663299262BEADF24 /* RoomDetails */ = {
isa = PBXGroup;
children = (
@ -2265,6 +2295,7 @@
4009BE2E791C16AC6EE39A7E /* BugReport */,
F5A65D1D3B83593598DC278D /* EmojiPickerScreen */,
B442FCF47E0A6F28D7D50A4D /* FilePreview */,
FC26FB522EDED4965C5325F0 /* Folder */,
B53CA9BECD3F97805E1432D0 /* HomeScreen */,
3F38EAC92E2281990E65DAF2 /* OnboardingScreen */,
A448A3A8F764174C60CD0CA1 /* Other */,
@ -2348,6 +2379,13 @@
path = EmojiPickerScreen;
sourceTree = "<group>";
};
FC26FB522EDED4965C5325F0 /* Folder */ = {
isa = PBXGroup;
children = (
);
path = Folder;
sourceTree = "<group>";
};
FCDF06BDB123505F0334B4F9 /* Timeline */ = {
isa = PBXGroup;
children = (
@ -2816,6 +2854,7 @@
0F9E38A75337D0146652ACAB /* BackgroundTaskTests.swift in Sources */,
7F61F9ACD5EC9E845EF3EFBF /* BugReportServiceTests.swift in Sources */,
C7CFDB4929DDD9A3B5BA085D /* BugReportViewModelTests.swift in Sources */,
ACAB49022C2EBD00AFC67729 /* ClientProxySpy.swift in Sources */,
9C45CE85325CD591DADBC4CA /* ElementXTests.swift in Sources */,
501304F26B52DF7024011B6C /* EmojiMartJSONLoaderTests.swift in Sources */,
25618589E0DE0F1E95FC7B5C /* EmojiProviderTests.swift in Sources */,
@ -2828,9 +2867,11 @@
149D1942DC005D0485FB8D93 /* LoggingTests.swift in Sources */,
1E59B77A0B2CE83DCC1B203C /* LoginViewModelTests.swift in Sources */,
2E43A3D221BE9587BC19C3F1 /* MatrixEntityRegexTests.swift in Sources */,
1146E9EDCF8344F7D6E0D553 /* MockCoder.swift in Sources */,
981853650217B6C8ECDD998C /* NavigationRootCoordinatorTests.swift in Sources */,
FCB9B475F908765531335859 /* NavigationSplitCoordinator.swift in Sources */,
4BB282209EA82015D0DF8F89 /* NavigationStackCoordinatorTests.swift in Sources */,
1B2DADC008EE211AF1DA5292 /* NotificationManagerTests.swift in Sources */,
F9F6D2883BBEBB9A3789A137 /* OnboardingViewModelTests.swift in Sources */,
27E9263DA75E266690A37EB1 /* PermalinkBuilderTests.swift in Sources */,
EA974337FA7D040E7C74FE6E /* RoomDetailsViewModelTests.swift in Sources */,
@ -2845,7 +2886,10 @@
1FEC0A4EC6E6DF693C16B32A /* StringTests.swift in Sources */,
7AE1FFB132F2B84EB8A2AEBC /* TemplateViewModelTests.swift in Sources */,
282A5F3375DDC774AE09B0C3 /* TracingConfigurationTests.swift in Sources */,
8E650379587C31D7912ED67B /* UNNotification+Creator.swift in Sources */,
AF33B9044498211C3D82F1E1 /* UNTextInputNotificationResponse+Creator.swift in Sources */,
8D3E1FADD78E72504DE0E402 /* UserAgentBuilderTests.swift in Sources */,
08248D02BACA75CDC3B39A96 /* UserNotificationCenterSpy.swift in Sources */,
8196A2E71ACC902DD69F24EE /* UserNotificationControllerTests.swift in Sources */,
1504CE9A609A348D90B69E47 /* VideoPlayerViewModelTests.swift in Sources */,
);
@ -3126,6 +3170,7 @@
071A017E415AD378F2961B11 /* URL.swift in Sources */,
7A71AEF419904209BB8C2833 /* UserAgentBuilder.swift in Sources */,
87BD4F95F9D603C309837378 /* UserNotification.swift in Sources */,
E3291AD16D7A5CB14781819C /* UserNotificationCenterProtocol.swift in Sources */,
5D9F0695DC6C0057F85C12B6 /* UserNotificationController.swift in Sources */,
D79F0F852C6A4255D5E616D2 /* UserNotificationControllerProtocol.swift in Sources */,
AC5CC8250CEAE57B73900C57 /* UserNotificationModalView.swift in Sources */,

View File

@ -302,7 +302,7 @@ class AppCoordinator: AppCoordinatorProtocol {
.sink { [weak self] callback in
switch callback {
case .registeredNotifications(let deviceToken):
self?.notificationManager?.register(with: deviceToken)
self?.notificationManager?.register(with: deviceToken, completion: nil)
case .failedToRegisteredNotifications(let error):
self?.notificationManager?.registrationFailed(with: error)
}

View File

@ -29,7 +29,7 @@ class MockNotificationManager: NotificationManagerProtocol {
delegate?.authorizationStatusUpdated(self, granted: false)
}
func register(with deviceToken: Data) { }
func register(with deviceToken: Data, completion: ((Bool) -> Void)? = nil) { }
func registrationFailed(with error: Error) { }

View File

@ -19,11 +19,12 @@ import UIKit
import UserNotifications
class NotificationManager: NSObject, NotificationManagerProtocol {
private let notificationCenter = UNUserNotificationCenter.current()
private let notificationCenter: UserNotificationCenterProtocol
private let clientProxy: ClientProxyProtocol
init(clientProxy: ClientProxyProtocol) {
init(clientProxy: ClientProxyProtocol, notificationCenter: UserNotificationCenterProtocol = UNUserNotificationCenter.current()) {
self.clientProxy = clientProxy
self.notificationCenter = notificationCenter
super.init()
}
@ -45,22 +46,25 @@ class NotificationManager: NSObject, NotificationManagerProtocol {
options: [])
notificationCenter.setNotificationCategories([replyCategory])
notificationCenter.delegate = self
Task {
do {
let granted = try await notificationCenter.requestAuthorization(options: [.alert, .sound, .badge])
MXLog.debug("[NotificationManager] permission granted: \(granted)")
await MainActor.run {
delegate?.authorizationStatusUpdated(self, granted: granted)
notificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) { [weak self] granted, error in
guard let self else {
return
}
} catch {
if let error {
MXLog.debug("[NotificationManager] request authorization failed: \(error)")
} else {
MXLog.debug("[NotificationManager] permission granted: \(granted)")
DispatchQueue.main.async {
self.delegate?.authorizationStatusUpdated(self, granted: granted)
}
}
}
}
func register(with deviceToken: Data) {
setPusher(with: deviceToken, clientProxy: clientProxy)
func register(with deviceToken: Data, completion: ((Bool) -> Void)? = nil) {
setPusher(with: deviceToken,
clientProxy: clientProxy,
completion: completion)
}
func registrationFailed(with error: Error) { }
@ -74,17 +78,18 @@ class NotificationManager: NSObject, NotificationManagerProtocol {
let request = UNNotificationRequest(identifier: ProcessInfo.processInfo.globallyUniqueString,
content: content,
trigger: nil)
Task {
do {
try await notificationCenter.add(request)
MXLog.debug("[NotificationManager] show local notification succeeded")
} catch {
notificationCenter.add(request) { error in
if let error {
MXLog.debug("[NotificationManager] show local notification failed: \(error)")
} else {
MXLog.debug("[NotificationManager] show local notification succeeded")
}
}
}
private func setPusher(with deviceToken: Data, clientProxy: ClientProxyProtocol) {
private func setPusher(with deviceToken: Data,
clientProxy: ClientProxyProtocol,
completion: ((Bool) -> Void)?) {
Task {
do {
try await clientProxy.setPusher(pushkey: deviceToken.base64EncodedString(),
@ -106,8 +111,10 @@ class NotificationManager: NSObject, NotificationManagerProtocol {
]
])
MXLog.debug("[NotificationManager] set pusher succeeded")
completion?(true)
} catch {
MXLog.debug("[NotificationManager] set pusher failed: \(error)")
completion?(false)
}
}
}
@ -164,3 +171,5 @@ extension NotificationManager: UNUserNotificationCenterDelegate {
}
}
}
extension UNUserNotificationCenter: UserNotificationCenterProtocol { }

View File

@ -36,7 +36,7 @@ protocol NotificationManagerProtocol {
var delegate: NotificationManagerDelegate? { get set }
func start()
func register(with deviceToken: Data)
func register(with deviceToken: Data, completion: ((Bool) -> Void)?)
func registrationFailed(with error: Error)
func showLocalNotification(with title: String, subtitle: String?)
}

View File

@ -0,0 +1,25 @@
//
// 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 Foundation
import UserNotifications
protocol UserNotificationCenterProtocol: AnyObject {
var delegate: UNUserNotificationCenterDelegate? { get set }
func add(_ request: UNNotificationRequest, withCompletionHandler completionHandler: ((Error?) -> Void)?)
func requestAuthorization(options: UNAuthorizationOptions, completionHandler: @escaping (Bool, Error?) -> Void)
func setNotificationCategories(_ categories: Set<UNNotificationCategory>)
}

View File

@ -0,0 +1,116 @@
//
// 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 Combine
@testable import ElementX
import Foundation
class ClientProxySpy: ClientProxyProtocol {
var visibleRoomsSummaryProvider: ElementX.RoomSummaryProviderProtocol?
var allRoomsSummaryProvider: ElementX.RoomSummaryProviderProtocol?
let callbacks = PassthroughSubject<ClientProxyCallback, Never>()
var userIdentifier = ""
var isSoftLogout = false
var deviceId: String? = ""
var homeserver = ""
var restorationToken: ElementX.RestorationToken?
var roomSummaryProvider: ElementX.RoomSummaryProviderProtocol?
internal init() { }
func startSync() { }
func stopSync() { }
func restartSync() { }
func roomForIdentifier(_ identifier: String) async -> ElementX.RoomProxyProtocol? {
nil
}
func loadUserDisplayName() async -> Result<String, ElementX.ClientProxyError> {
.failure(.failedLoadingMedia)
}
func loadUserAvatarURLString() async -> Result<String, ElementX.ClientProxyError> {
.failure(.failedLoadingMedia)
}
func accountDataEvent<Content>(type: String) async -> Result<Content?, ClientProxyError> where Content: Decodable {
.failure(.failedLoadingMedia)
}
func setAccountData<Content>(content: Content, type: String) async -> Result<Void, ClientProxyError> where Content: Encodable {
.failure(.failedLoadingMedia)
}
func sessionVerificationControllerProxy() async -> Result<ElementX.SessionVerificationControllerProxyProtocol, ClientProxyError> {
.failure(.failedLoadingMedia)
}
func logout() async { }
var setPusherCalled = false
var setPusherErrorToThrow: Error?
var setPusherPushkey: String?
var setPusherKind: PusherKind?
var setPusherAppId: String?
var setPusherAppDisplayName: String?
var setPusherDeviceDisplayName: String?
var setPusherProfileTag: String?
var setPusherLang: String?
var setPusherUrl: String?
var setPusherFormat: PushFormat?
var setPusherDefaultPayload: [AnyHashable: Any]?
// swiftlint:disable:next function_parameter_count
func setPusher(pushkey: String, kind: PusherKind?, appId: String, appDisplayName: String, deviceDisplayName: String, profileTag: String?, lang: String, url: String?, format: PushFormat?, defaultPayload: [AnyHashable: Any]?) async throws {
if let setPusherErrorToThrow {
throw setPusherErrorToThrow
}
setPusherCalled = true
setPusherPushkey = pushkey
setPusherKind = kind
setPusherAppId = appId
setPusherAppDisplayName = appDisplayName
setPusherDeviceDisplayName = deviceDisplayName
setPusherProfileTag = profileTag
setPusherLang = lang
setPusherUrl = url
setPusherFormat = format
setPusherDefaultPayload = defaultPayload
}
func mediaSourceForURLString(_ urlString: String) -> ElementX.MediaSourceProxy {
MediaSourceProxy(urlString: "")
}
func loadMediaContentForSource(_ source: ElementX.MediaSourceProxy) async throws -> Data {
Data()
}
func loadMediaThumbnailForSource(_ source: ElementX.MediaSourceProxy, width: UInt, height: UInt) async throws -> Data {
Data()
}
}

View File

@ -0,0 +1,22 @@
//
// 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 Foundation
final class MockCoder: NSKeyedArchiver {
override func decodeObject(forKey _: String) -> Any { "" }
override func decodeInt64(forKey key: String) -> Int64 { 0 }
}

View File

@ -0,0 +1,225 @@
//
// 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
import Combine
@testable import ElementX
final class NotificationManagerTests: XCTestCase {
var sut: NotificationManager!
private let clientProxySpy = ClientProxySpy()
private let notificationCenter = UserNotificationCenterSpy()
private var authorizationStatusWasGranted = false
private var shouldDisplayInAppNotificationReturnValue = false
private var handleInlineReplyDelegateCalled = false
private var notificationTappedDelegateCalled = false
private let settings = ServiceLocator.shared.settings
override func setUp() {
sut = NotificationManager(clientProxy: clientProxySpy, notificationCenter: notificationCenter)
}
func test_whenRegistered_pusherIsCalled() throws {
let expectation = expectation(description: "Callback happened")
sut.register(with: Data(), completion: { _ in
expectation.fulfill()
})
waitForExpectations(timeout: 0.5)
XCTAssertTrue(clientProxySpy.setPusherCalled)
}
func test_whenRegisteredSuccess_completionSuccessIsCalled() throws {
let expectation = expectation(description: "Callback happened")
var success = false
sut.register(with: Data(), completion: { s in
success = s
expectation.fulfill()
})
waitForExpectations(timeout: 0.5)
XCTAssertTrue(success)
}
func test_whenRegisteredAndPusherThrowsError_completionFalseIsCalled() throws {
let expectation = expectation(description: "Callback happened")
var success = true
enum TestError: Error {
case someError
}
clientProxySpy.setPusherErrorToThrow = TestError.someError
sut.register(with: Data(), completion: { s in
success = s
expectation.fulfill()
})
waitForExpectations(timeout: 0.5)
XCTAssertFalse(success)
}
func test_whenRegistered_pusherIsCalledWithCorrectValues() throws {
let expectation = expectation(description: "Callback happened")
let pushkeyData = Data("1234".utf8)
sut.register(with: pushkeyData, completion: { _ in
expectation.fulfill()
})
waitForExpectations(timeout: 0.5)
XCTAssertEqual(clientProxySpy.setPusherPushkey, pushkeyData.base64EncodedString())
XCTAssertEqual(clientProxySpy.setPusherAppId, settings?.pusherAppId)
XCTAssertEqual(clientProxySpy.setPusherKind, .http)
XCTAssertEqual(clientProxySpy.setPusherAppId, settings?.pusherAppId)
XCTAssertEqual(clientProxySpy.setPusherAppDisplayName, "\(InfoPlistReader.target.bundleDisplayName) (iOS)")
XCTAssertEqual(clientProxySpy.setPusherDeviceDisplayName, UIDevice.current.name)
XCTAssertNotNil(clientProxySpy.setPusherProfileTag)
XCTAssertEqual(clientProxySpy.setPusherLang, Bundle.preferredLanguages.first)
XCTAssertEqual(clientProxySpy.setPusherUrl, settings?.pushGatewayBaseURL.absoluteString)
XCTAssertEqual(clientProxySpy.setPusherFormat, .eventIdOnly)
let defaultPayload: [AnyHashable: Any] = [
"aps": [
"mutable-content": 1,
"alert": [
"loc-key": "Notification",
"loc-args": []
]
]
]
let actualPayload = NSDictionary(dictionary: clientProxySpy.setPusherDefaultPayload ?? [:])
XCTAssertTrue(actualPayload.isEqual(to: defaultPayload))
}
func test_whenRegisteredAndPusherTagNotSetInSettings_tagGeneratedAndSavedInSettings() throws {
let expectation = expectation(description: "Callback happened")
settings?.pusherProfileTag = nil
sut.register(with: Data(), completion: { _ in
expectation.fulfill()
})
waitForExpectations(timeout: 0.5)
XCTAssertNotNil(settings?.pusherProfileTag)
}
func test_whenRegisteredAndPusherTagIsSetInSettings_tagNotGenerated() throws {
let expectation = expectation(description: "Callback happened")
settings?.pusherProfileTag = "12345"
sut.register(with: Data(), completion: { _ in
expectation.fulfill()
})
waitForExpectations(timeout: 0.5)
XCTAssertEqual(settings?.pusherProfileTag, "12345")
}
func test_whenShowLocalNotification_notificationRequestGetsAdded() throws {
sut.showLocalNotification(with: "Title", subtitle: "Subtitle")
let request = try XCTUnwrap(notificationCenter.addRequest)
XCTAssertEqual(request.content.title, "Title")
XCTAssertEqual(request.content.subtitle, "Subtitle")
}
func test_whenStart_notificationCategoriesAreSet() throws {
sut.start()
let replyAction = UNTextInputNotificationAction(identifier: NotificationConstants.Action.inlineReply,
title: ElementL10n.actionQuickReply,
options: [])
let replyCategory = UNNotificationCategory(identifier: NotificationConstants.Category.reply,
actions: [replyAction],
intentIdentifiers: [],
options: [])
XCTAssertEqual(notificationCenter.notificationCategoriesValue, [replyCategory])
}
func test_whenStart_delegateIsSet() throws {
sut.start()
let delegate = try XCTUnwrap(notificationCenter.delegate)
XCTAssertTrue(delegate.isEqual(sut))
}
func test_whenStart_requestAuthorizationCalledWithCorrectParams() throws {
sut.start()
XCTAssertEqual(notificationCenter.requestAuthorizationOptions, [.alert, .sound, .badge])
}
func test_whenStartAndAuthorizationGranted_delegateCalled() throws {
authorizationStatusWasGranted = false
notificationCenter.requestAuthorizationGrantedReturnValue = true
sut.delegate = self
sut.start()
let expectation = expectation(description: "Wait for main thread")
DispatchQueue.main.async {
expectation.fulfill()
}
waitForExpectations(timeout: 1, handler: nil)
XCTAssertTrue(authorizationStatusWasGranted)
}
func test_whenWillPresentNotificationsDelegateNotSet_CorrectPresentationOptionsReturned() async throws {
sut.start()
let archiver = MockCoder(requiringSecureCoding: false)
let notification = try XCTUnwrap(UNNotification(coder: archiver))
let options = await sut.userNotificationCenter(UNUserNotificationCenter.current(), willPresent: notification)
XCTAssertEqual(options, [.badge, .sound, .list, .banner])
}
func test_whenWillPresentNotificationsDelegateSetAndNotificationsShoudNotBeDisplayed_CorrectPresentationOptionsReturned() async throws {
shouldDisplayInAppNotificationReturnValue = false
sut.delegate = self
sut.start()
let notification = try UNNotification.with(userInfo: [AnyHashable: Any]())
let options = await sut.userNotificationCenter(UNUserNotificationCenter.current(), willPresent: notification)
XCTAssertEqual(options, [])
}
func test_whenWillPresentNotificationsDelegateSetAndNotificationsShoudBeDisplayed_CorrectPresentationOptionsReturned() async throws {
shouldDisplayInAppNotificationReturnValue = true
sut.delegate = self
sut.start()
let notification = try UNNotification.with(userInfo: [AnyHashable: Any]())
let options = await sut.userNotificationCenter(UNUserNotificationCenter.current(), willPresent: notification)
XCTAssertEqual(options, [.badge, .sound, .list, .banner])
}
func test_whenNotificationCenterReceivedResponseInLineReply_delegateIsCalled() async throws {
handleInlineReplyDelegateCalled = false
sut.delegate = self
sut.start()
let response = try UNTextInputNotificationResponse.with(userInfo: [AnyHashable: Any](), actionIdentifier: NotificationConstants.Action.inlineReply)
await sut.userNotificationCenter(UNUserNotificationCenter.current(), didReceive: response)
XCTAssertTrue(handleInlineReplyDelegateCalled)
}
func test_whenNotificationCenterReceivedResponseWithActionIdentifier_delegateIsCalled() async throws {
notificationTappedDelegateCalled = false
sut.delegate = self
sut.start()
let response = try UNTextInputNotificationResponse.with(userInfo: [AnyHashable: Any](), actionIdentifier: UNNotificationDefaultActionIdentifier)
await sut.userNotificationCenter(UNUserNotificationCenter.current(), didReceive: response)
XCTAssertTrue(notificationTappedDelegateCalled)
}
}
extension NotificationManagerTests: NotificationManagerDelegate {
func authorizationStatusUpdated(_ service: ElementX.NotificationManagerProtocol, granted: Bool) {
authorizationStatusWasGranted = granted
}
func shouldDisplayInAppNotification(_ service: ElementX.NotificationManagerProtocol, content: UNNotificationContent) -> Bool {
shouldDisplayInAppNotificationReturnValue
}
func notificationTapped(_ service: ElementX.NotificationManagerProtocol, content: UNNotificationContent) async {
notificationTappedDelegateCalled = true
}
func handleInlineReply(_ service: ElementX.NotificationManagerProtocol, content: UNNotificationContent, replyText: String) async {
handleInlineReplyDelegateCalled = true
}
}

View File

@ -0,0 +1,35 @@
//
// 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 Foundation
import UserNotifications
import XCTest
extension UNNotification {
static func with(userInfo: [AnyHashable: Any], actionIdentifier: String = UNNotificationDefaultActionIdentifier) throws -> UNNotification {
let content = UNMutableNotificationContent()
content.userInfo = userInfo
let request = UNNotificationRequest(
identifier: "",
content: content,
trigger: nil
)
let archiver = MockCoder(requiringSecureCoding: false)
let notification = try XCTUnwrap(UNNotification(coder: archiver))
notification.setValue(request, forKey: "request")
return notification
}
}

View File

@ -0,0 +1,38 @@
//
// 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 UserNotifications
import XCTest
extension UNTextInputNotificationResponse {
static func with(userInfo: [AnyHashable: Any], actionIdentifier: String = UNNotificationDefaultActionIdentifier) throws -> UNNotificationResponse {
let content = UNMutableNotificationContent()
content.userInfo = userInfo
let request = UNNotificationRequest(
identifier: "",
content: content,
trigger: nil
)
let archiver = MockCoder(requiringSecureCoding: false)
let notification = try XCTUnwrap(UNNotification(coder: archiver))
notification.setValue(request, forKey: "request")
let response = try XCTUnwrap(UNTextInputNotificationResponse(coder: archiver))
response.setValue(notification, forKey: "notification")
response.setValue(actionIdentifier, forKey: "actionIdentifier")
return response
}
}

View File

@ -0,0 +1,40 @@
//
// 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.
//
@testable import ElementX
import Foundation
import UserNotifications
class UserNotificationCenterSpy: UserNotificationCenterProtocol {
weak var delegate: UNUserNotificationCenterDelegate?
var addRequest: UNNotificationRequest?
func add(_ request: UNNotificationRequest, withCompletionHandler completionHandler: ((Error?) -> Void)?) {
addRequest = request
completionHandler?(nil)
}
var requestAuthorizationOptions: UNAuthorizationOptions?
var requestAuthorizationGrantedReturnValue = false
func requestAuthorization(options: UNAuthorizationOptions, completionHandler: @escaping (Bool, Error?) -> Void) {
requestAuthorizationOptions = options
completionHandler(requestAuthorizationGrantedReturnValue, nil)
}
var notificationCategoriesValue: Set<UNNotificationCategory>?
func setNotificationCategories(_ categories: Set<UNNotificationCategory>) {
notificationCategoriesValue = categories
}
}