Clean up and fixed some broken tests
This commit is contained in:
parent
691acf2a42
commit
4f10277a48
|
@ -276,7 +276,7 @@
|
|||
C328255225CA64470062D0A7 /* ContextMenuVC+ActionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C328255125CA64470062D0A7 /* ContextMenuVC+ActionView.swift */; };
|
||||
C32C598A256D0664003C73A2 /* SNProtoEnvelope+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38EEF09255B49A8007E1867 /* SNProtoEnvelope+Conversion.swift */; };
|
||||
C32C599E256DB02B003C73A2 /* TypingIndicators.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA87255A57FC00E217F9 /* TypingIndicators.swift */; };
|
||||
C32C5A24256DB7DB003C73A2 /* UserDefaultsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB6B255A580F00E217F9 /* UserDefaultsInfo.swift */; };
|
||||
C32C5A24256DB7DB003C73A2 /* UserDefaultsConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB6B255A580F00E217F9 /* UserDefaultsConfig.swift */; };
|
||||
C32C5A48256DB8F0003C73A2 /* BuildConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAA8255A57FF00E217F9 /* BuildConfiguration.swift */; };
|
||||
C32C5A88256DBCF9003C73A2 /* MessageReceiver+LegacyClosedGroups.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32C5A87256DBCF9003C73A2 /* MessageReceiver+LegacyClosedGroups.swift */; };
|
||||
C32C5C3D256DCBAF003C73A2 /* AppReadiness.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB75255A581000E217F9 /* AppReadiness.m */; };
|
||||
|
@ -523,7 +523,7 @@
|
|||
FD23CE282A67755C0000B97C /* MockCrypto.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD23CE272A67755C0000B97C /* MockCrypto.swift */; };
|
||||
FD23CE292A6775650000B97C /* MockCrypto.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD23CE272A67755C0000B97C /* MockCrypto.swift */; };
|
||||
FD23CE2A2A6775660000B97C /* MockCrypto.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD23CE272A67755C0000B97C /* MockCrypto.swift */; };
|
||||
FD23CE302A67B8820000B97C /* CacheInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD23CE2F2A67B8820000B97C /* CacheInfo.swift */; };
|
||||
FD23CE302A67B8820000B97C /* CacheConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD23CE2F2A67B8820000B97C /* CacheConfig.swift */; };
|
||||
FD23CE332A67C4D90000B97C /* MockNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD23CE312A67C38D0000B97C /* MockNetwork.swift */; };
|
||||
FD23CE342A67C4D90000B97C /* MockNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD23CE312A67C38D0000B97C /* MockNetwork.swift */; };
|
||||
FD23CE352A67C4DA0000B97C /* MockNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD23CE312A67C38D0000B97C /* MockNetwork.swift */; };
|
||||
|
@ -757,6 +757,8 @@
|
|||
FDA8EAFE280E8B78002B68E5 /* FailedMessageSendsJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDA8EAFD280E8B78002B68E5 /* FailedMessageSendsJob.swift */; };
|
||||
FDA8EB00280E8D58002B68E5 /* FailedAttachmentDownloadsJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDA8EAFF280E8D58002B68E5 /* FailedAttachmentDownloadsJob.swift */; };
|
||||
FDA8EB10280F8238002B68E5 /* Codable+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDA8EB0F280F8238002B68E5 /* Codable+Utilities.swift */; };
|
||||
FDAA16762AC28A3B00DDBF77 /* UserDefaultsType.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDAA16752AC28A3B00DDBF77 /* UserDefaultsType.swift */; };
|
||||
FDAA167B2AC28E2F00DDBF77 /* SnodeRequestSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDAA167A2AC28E2F00DDBF77 /* SnodeRequestSpec.swift */; };
|
||||
FDAED05C2A7C6CE600091B25 /* MigrationRequirement.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDAED05B2A7C6CE600091B25 /* MigrationRequirement.swift */; };
|
||||
FDB4BBC72838B91E00B7C95D /* LinkPreviewError.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB4BBC62838B91E00B7C95D /* LinkPreviewError.swift */; };
|
||||
FDB4BBC92839BEF000B7C95D /* ProfileManagerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB4BBC82839BEF000B7C95D /* ProfileManagerError.swift */; };
|
||||
|
@ -853,8 +855,8 @@
|
|||
FDC438C927BB706500C60D73 /* SendDirectMessageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC438C827BB706500C60D73 /* SendDirectMessageRequest.swift */; };
|
||||
FDC438CB27BB7DB100C60D73 /* UpdateMessageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC438CA27BB7DB100C60D73 /* UpdateMessageRequest.swift */; };
|
||||
FDC438CD27BC641200C60D73 /* Set+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC438CC27BC641200C60D73 /* Set+Utilities.swift */; };
|
||||
FDC498B32ABD82D000EDD897 /* MessageReceiverSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6ACADD2A32D3A9009AFB73 /* MessageReceiverSpec.swift */; };
|
||||
FDC439632AC2492700A56963 /* MessageReceiverSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6ACADD2A32D3A9009AFB73 /* MessageReceiverSpec.swift */; };
|
||||
FDC498B32ABD82D000EDD897 /* MessageReceiverSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6ACADD2A32D3A9009AFB73 /* MessageReceiverSpec.swift */; };
|
||||
FDC498B72AC15F7D00EDD897 /* AppNotificationCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC498B62AC15F7D00EDD897 /* AppNotificationCategory.swift */; };
|
||||
FDC498B92AC15FE300EDD897 /* AppNotificationAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC498B82AC15FE300EDD897 /* AppNotificationAction.swift */; };
|
||||
FDC498BB2AC1606C00EDD897 /* AppNotificationUserInfoKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC498BA2AC1606C00EDD897 /* AppNotificationUserInfoKey.swift */; };
|
||||
|
@ -890,7 +892,7 @@
|
|||
FDE77F6B280FEB28002CFC5D /* ControlMessageProcessRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDE77F6A280FEB28002CFC5D /* ControlMessageProcessRecord.swift */; };
|
||||
FDED2E3C282E1B5D00B2CD2A /* UICollectionView+ReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDED2E3B282E1B5D00B2CD2A /* UICollectionView+ReusableView.swift */; };
|
||||
FDF01FAB2A9EBAD500CAF969 /* MessageSenderGroupsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDF01FAA2A9EBAD500CAF969 /* MessageSenderGroupsSpec.swift */; };
|
||||
FDF01FAD2A9ECC4200CAF969 /* SingletonInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDF01FAC2A9ECC4200CAF969 /* SingletonInfo.swift */; };
|
||||
FDF01FAD2A9ECC4200CAF969 /* SingletonConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDF01FAC2A9ECC4200CAF969 /* SingletonConfig.swift */; };
|
||||
FDF0B73C27FFD3D6004C14C5 /* LinkPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDF0B73B27FFD3D6004C14C5 /* LinkPreview.swift */; };
|
||||
FDF0B7422804EA4F004C14C5 /* _002_SetupStandardJobs.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDF0B7412804EA4F004C14C5 /* _002_SetupStandardJobs.swift */; };
|
||||
FDF0B7472804F0CE004C14C5 /* DisappearingMessagesJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDF0B7462804F0CE004C14C5 /* DisappearingMessagesJob.swift */; };
|
||||
|
@ -1510,7 +1512,7 @@
|
|||
C33FDB54255A580D00E217F9 /* DataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataSource.h; sourceTree = "<group>"; };
|
||||
C33FDB68255A580F00E217F9 /* ContentProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentProxy.swift; sourceTree = "<group>"; };
|
||||
C33FDB69255A580F00E217F9 /* FeatureFlags.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureFlags.swift; sourceTree = "<group>"; };
|
||||
C33FDB6B255A580F00E217F9 /* UserDefaultsInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsInfo.swift; sourceTree = "<group>"; };
|
||||
C33FDB6B255A580F00E217F9 /* UserDefaultsConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsConfig.swift; sourceTree = "<group>"; };
|
||||
C33FDB75255A581000E217F9 /* AppReadiness.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppReadiness.m; sourceTree = "<group>"; };
|
||||
C33FDB80255A581100E217F9 /* Notification+Loki.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Notification+Loki.swift"; sourceTree = "<group>"; };
|
||||
C33FDB81255A581100E217F9 /* UIImage+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+OWS.m"; sourceTree = "<group>"; };
|
||||
|
@ -1743,7 +1745,7 @@
|
|||
FD23CE232A675C440000B97C /* Crypto+SessionMessagingKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Crypto+SessionMessagingKit.swift"; sourceTree = "<group>"; };
|
||||
FD23CE252A676B5B0000B97C /* DependenciesSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DependenciesSpec.swift; sourceTree = "<group>"; };
|
||||
FD23CE272A67755C0000B97C /* MockCrypto.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCrypto.swift; sourceTree = "<group>"; };
|
||||
FD23CE2F2A67B8820000B97C /* CacheInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheInfo.swift; sourceTree = "<group>"; };
|
||||
FD23CE2F2A67B8820000B97C /* CacheConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheConfig.swift; sourceTree = "<group>"; };
|
||||
FD23CE312A67C38D0000B97C /* MockNetwork.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockNetwork.swift; sourceTree = "<group>"; };
|
||||
FD23EA6028ED0B260058676E /* CombineExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineExtensions.swift; sourceTree = "<group>"; };
|
||||
FD245C612850664300B966DD /* Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = "<group>"; };
|
||||
|
@ -1752,7 +1754,6 @@
|
|||
FD29598C2A43BC0B00888A17 /* Version.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Version.swift; sourceTree = "<group>"; };
|
||||
FD29598F2A43BE5F00888A17 /* VersionSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionSpec.swift; sourceTree = "<group>"; };
|
||||
FD2AAAEF28ED57B500A49611 /* SynchronousStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SynchronousStorage.swift; sourceTree = "<group>"; };
|
||||
FD2B4AFA29429D1000AB4848 /* ConfigContacts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigContacts.swift; sourceTree = "<group>"; };
|
||||
FD2B4AFC294688D000AB4848 /* SessionUtil+Contacts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionUtil+Contacts.swift"; sourceTree = "<group>"; };
|
||||
FD2B4AFE2946C93200AB4848 /* ConfigurationSyncJob.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationSyncJob.swift; sourceTree = "<group>"; };
|
||||
FD2B4B032949887A00AB4848 /* QueryInterfaceRequest+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "QueryInterfaceRequest+Utilities.swift"; sourceTree = "<group>"; };
|
||||
|
@ -1911,7 +1912,6 @@
|
|||
FD8ECF7A29340FFD00C0D1BB /* SessionUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionUtil.swift; sourceTree = "<group>"; };
|
||||
FD8ECF7C2934293A00C0D1BB /* _013_SessionUtilChanges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _013_SessionUtilChanges.swift; sourceTree = "<group>"; };
|
||||
FD8ECF7E2934298100C0D1BB /* ConfigDump.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigDump.swift; sourceTree = "<group>"; };
|
||||
FD8ECF812934387A00C0D1BB /* ConfigUserProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigUserProfile.swift; sourceTree = "<group>"; };
|
||||
FD8ECF882935AB7200C0D1BB /* SessionUtilError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionUtilError.swift; sourceTree = "<group>"; };
|
||||
FD8ECF8F29381FC200C0D1BB /* SessionUtil+UserProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionUtil+UserProfile.swift"; sourceTree = "<group>"; };
|
||||
FD8ECF912938552800C0D1BB /* Threading.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Threading.swift; sourceTree = "<group>"; };
|
||||
|
@ -1970,13 +1970,14 @@
|
|||
FD9B30F2293EA0BF008DEE3E /* BatchResponseSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatchResponseSpec.swift; sourceTree = "<group>"; };
|
||||
FD9BDDF82A5D2294005F1EBC /* libSessionUtil.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSessionUtil.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FD9DD2702A72516D00ECB68E /* TestExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestExtensions.swift; sourceTree = "<group>"; };
|
||||
FDA1E83529A5748F00C5C3BD /* ConfigUserGroups.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigUserGroups.swift; sourceTree = "<group>"; };
|
||||
FDA1E83829A5771A00C5C3BD /* LibSessionSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibSessionSpec.swift; sourceTree = "<group>"; };
|
||||
FDA1E83A29A5F2D500C5C3BD /* SessionUtil+Shared.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionUtil+Shared.swift"; sourceTree = "<group>"; };
|
||||
FDA1E83C29AC71A800C5C3BD /* SessionUtilSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionUtilSpec.swift; sourceTree = "<group>"; };
|
||||
FDA8EAFD280E8B78002B68E5 /* FailedMessageSendsJob.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FailedMessageSendsJob.swift; sourceTree = "<group>"; };
|
||||
FDA8EAFF280E8D58002B68E5 /* FailedAttachmentDownloadsJob.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FailedAttachmentDownloadsJob.swift; sourceTree = "<group>"; };
|
||||
FDA8EB0F280F8238002B68E5 /* Codable+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Codable+Utilities.swift"; sourceTree = "<group>"; };
|
||||
FDAA16752AC28A3B00DDBF77 /* UserDefaultsType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsType.swift; sourceTree = "<group>"; };
|
||||
FDAA167A2AC28E2F00DDBF77 /* SnodeRequestSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnodeRequestSpec.swift; sourceTree = "<group>"; };
|
||||
FDAED05B2A7C6CE600091B25 /* MigrationRequirement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationRequirement.swift; sourceTree = "<group>"; };
|
||||
FDB4BBC62838B91E00B7C95D /* LinkPreviewError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkPreviewError.swift; sourceTree = "<group>"; };
|
||||
FDB4BBC82839BEF000B7C95D /* ProfileManagerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileManagerError.swift; sourceTree = "<group>"; };
|
||||
|
@ -1986,8 +1987,6 @@
|
|||
FDB5DAC62A9447E7002C8721 /* _018_GroupsRebuildChanges.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _018_GroupsRebuildChanges.swift; sourceTree = "<group>"; };
|
||||
FDB5DAC82A944E12002C8721 /* SessionUtil+GroupMembers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionUtil+GroupMembers.swift"; sourceTree = "<group>"; };
|
||||
FDB5DACA2A944E72002C8721 /* SessionUtil+GroupKeys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionUtil+GroupKeys.swift"; sourceTree = "<group>"; };
|
||||
FDB5DACC2A9452F0002C8721 /* ConfigGroupMembers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigGroupMembers.swift; sourceTree = "<group>"; };
|
||||
FDB5DACE2A945307002C8721 /* ConfigGroupKeys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigGroupKeys.swift; sourceTree = "<group>"; };
|
||||
FDB5DAD02A94838C002C8721 /* GroupInviteMemberJob.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupInviteMemberJob.swift; sourceTree = "<group>"; };
|
||||
FDB5DAD32A9483F3002C8721 /* GroupUpdateInviteMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupUpdateInviteMessage.swift; sourceTree = "<group>"; };
|
||||
FDB5DAD72A95D830002C8721 /* GroupUpdateDeleteMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupUpdateDeleteMessage.swift; sourceTree = "<group>"; };
|
||||
|
@ -2010,7 +2009,6 @@
|
|||
FDB947142A9C23AF001F271A /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = "<group>"; };
|
||||
FDB947162A9D69A8001F271A /* MockSessionUtilCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSessionUtilCache.swift; sourceTree = "<group>"; };
|
||||
FDB9471A2A9D70A6001F271A /* CommonSMKMockExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonSMKMockExtensions.swift; sourceTree = "<group>"; };
|
||||
FDBB25E02983909300F1508E /* ConfigConvoInfoVolatile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigConvoInfoVolatile.swift; sourceTree = "<group>"; };
|
||||
FDBB25E22988B13800F1508E /* _004_AddJobPriority.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _004_AddJobPriority.swift; sourceTree = "<group>"; };
|
||||
FDBB25E62988BBBD00F1508E /* UIContextualAction+Theming.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIContextualAction+Theming.swift"; sourceTree = "<group>"; };
|
||||
FDC13D462A16E4CA007267C7 /* SubscribeRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscribeRequest.swift; sourceTree = "<group>"; };
|
||||
|
@ -2035,7 +2033,6 @@
|
|||
FDC2909D27D85751005DAE71 /* OpenGroupManagerSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupManagerSpec.swift; sourceTree = "<group>"; };
|
||||
FDC290A527D860CE005DAE71 /* Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mock.swift; sourceTree = "<group>"; };
|
||||
FDC290A727D9B46D005DAE71 /* NimbleExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NimbleExtensions.swift; sourceTree = "<group>"; };
|
||||
FDC3833A2A9344C700FFD6A2 /* ConfigGroupInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigGroupInfo.swift; sourceTree = "<group>"; };
|
||||
FDC4380827B31D4E00C60D73 /* OpenGroupAPIError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupAPIError.swift; sourceTree = "<group>"; };
|
||||
FDC4381627B32EC700C60D73 /* Personalization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Personalization.swift; sourceTree = "<group>"; };
|
||||
FDC4381F27B36ADC00C60D73 /* SOGSEndpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SOGSEndpoint.swift; sourceTree = "<group>"; };
|
||||
|
@ -2098,7 +2095,7 @@
|
|||
FDE77F6A280FEB28002CFC5D /* ControlMessageProcessRecord.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlMessageProcessRecord.swift; sourceTree = "<group>"; };
|
||||
FDED2E3B282E1B5D00B2CD2A /* UICollectionView+ReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionView+ReusableView.swift"; sourceTree = "<group>"; };
|
||||
FDF01FAA2A9EBAD500CAF969 /* MessageSenderGroupsSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSenderGroupsSpec.swift; sourceTree = "<group>"; };
|
||||
FDF01FAC2A9ECC4200CAF969 /* SingletonInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingletonInfo.swift; sourceTree = "<group>"; };
|
||||
FDF01FAC2A9ECC4200CAF969 /* SingletonConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingletonConfig.swift; sourceTree = "<group>"; };
|
||||
FDF0B73B27FFD3D6004C14C5 /* LinkPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkPreview.swift; sourceTree = "<group>"; };
|
||||
FDF0B73F280402C4004C14C5 /* Job.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Job.swift; sourceTree = "<group>"; };
|
||||
FDF0B7412804EA4F004C14C5 /* _002_SetupStandardJobs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _002_SetupStandardJobs.swift; sourceTree = "<group>"; };
|
||||
|
@ -2509,13 +2506,6 @@
|
|||
path = "Emoji Picker";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B6ACADC2A32D38D009AFB73 /* MessagingKit */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
path = MessagingKit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B7CB18C270D06350079FF93 /* Views & Modals */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -3628,7 +3618,6 @@
|
|||
D221A08C169C9E5E00537ABF /* Frameworks */,
|
||||
D221A08A169C9E5E00537ABF /* Products */,
|
||||
2BADBA206E0B8D297E313FBA /* Pods */,
|
||||
FDC498B22ABD6DC700EDD897 /* Recovered References */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
|
@ -3742,6 +3731,7 @@
|
|||
FDE519F62AB7CDC700450C53 /* Result+Utilities.swift */,
|
||||
C33FDB38255A580B00E217F9 /* OWSBackgroundTask.h */,
|
||||
C33FDC1B255A581F00E217F9 /* OWSBackgroundTask.m */,
|
||||
FDAA16752AC28A3B00DDBF77 /* UserDefaultsType.swift */,
|
||||
FD29598C2A43BC0B00888A17 /* Version.swift */,
|
||||
);
|
||||
path = Utilities;
|
||||
|
@ -4021,7 +4011,6 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
FDF01FAA2A9EBAD500CAF969 /* MessageSenderGroupsSpec.swift */,
|
||||
7B6ACADD2A32D3A9009AFB73 /* MessageReceiverSpec.swift */,
|
||||
FD3C907027E445E500CD579F /* MessageReceiverDecryptionSpec.swift */,
|
||||
7B6ACADD2A32D3A9009AFB73 /* MessageReceiverSpec.swift */,
|
||||
FD3C906C27E43C4B00CD579F /* MessageSenderEncryptionSpec.swift */,
|
||||
|
@ -4325,6 +4314,14 @@
|
|||
path = Networking;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FDAA16792AC28E2200DDBF77 /* Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FDAA167A2AC28E2F00DDBF77 /* SnodeRequestSpec.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FDB5DAD22A9483D4002C8721 /* Group Update Messages */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -4344,6 +4341,7 @@
|
|||
FDB5DAFB2A981C43002C8721 /* SessionSnodeKitTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FDAA16792AC28E2200DDBF77 /* Models */,
|
||||
FDB5DB042A981C55002C8721 /* Networking */,
|
||||
);
|
||||
path = SessionSnodeKitTests;
|
||||
|
@ -4504,20 +4502,6 @@
|
|||
path = _TestUtilities;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FDC498B22ABD6DC700EDD897 /* Recovered References */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FDBB25E02983909300F1508E /* ConfigConvoInfoVolatile.swift */,
|
||||
FDB5DACE2A945307002C8721 /* ConfigGroupKeys.swift */,
|
||||
FDA1E83529A5748F00C5C3BD /* ConfigUserGroups.swift */,
|
||||
FD2B4AFA29429D1000AB4848 /* ConfigContacts.swift */,
|
||||
FDC3833A2A9344C700FFD6A2 /* ConfigGroupInfo.swift */,
|
||||
FDB5DACC2A9452F0002C8721 /* ConfigGroupMembers.swift */,
|
||||
FD8ECF812934387A00C0D1BB /* ConfigUserProfile.swift */,
|
||||
);
|
||||
name = "Recovered References";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FDC498B52AC15F6D00EDD897 /* Types */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -4560,10 +4544,10 @@
|
|||
FDF01FAE2A9ED0C800CAF969 /* Dependency Injection */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FD23CE2F2A67B8820000B97C /* CacheInfo.swift */,
|
||||
FD23CE2F2A67B8820000B97C /* CacheConfig.swift */,
|
||||
FDC6D75F2862B3F600B04575 /* Dependencies.swift */,
|
||||
FDF01FAC2A9ECC4200CAF969 /* SingletonInfo.swift */,
|
||||
C33FDB6B255A580F00E217F9 /* UserDefaultsInfo.swift */,
|
||||
FDF01FAC2A9ECC4200CAF969 /* SingletonConfig.swift */,
|
||||
C33FDB6B255A580F00E217F9 /* UserDefaultsConfig.swift */,
|
||||
);
|
||||
path = "Dependency Injection";
|
||||
sourceTree = "<group>";
|
||||
|
@ -6148,11 +6132,11 @@
|
|||
FD23CE1F2A65269C0000B97C /* Crypto.swift in Sources */,
|
||||
B8BC00C0257D90E30032E807 /* General.swift in Sources */,
|
||||
FDF8488629405A61007DCAE5 /* Request.swift in Sources */,
|
||||
FD23CE302A67B8820000B97C /* CacheInfo.swift in Sources */,
|
||||
FD23CE302A67B8820000B97C /* CacheConfig.swift in Sources */,
|
||||
FD17D7A127F40D2500122BE0 /* Storage.swift in Sources */,
|
||||
FD1A94FB2900D1C2000D73D3 /* PersistableRecord+Utilities.swift in Sources */,
|
||||
FD5D201E27B0D87C00FEA984 /* SessionId.swift in Sources */,
|
||||
C32C5A24256DB7DB003C73A2 /* UserDefaultsInfo.swift in Sources */,
|
||||
C32C5A24256DB7DB003C73A2 /* UserDefaultsConfig.swift in Sources */,
|
||||
FD8ECF922938552800C0D1BB /* Threading.swift in Sources */,
|
||||
B8856D7B256F14F4001CE70E /* UIView+OWS.m in Sources */,
|
||||
FDF22211281B5E0B000A4995 /* TableRecord+Utilities.swift in Sources */,
|
||||
|
@ -6180,6 +6164,7 @@
|
|||
FD17D7E527F6A09900122BE0 /* Identity.swift in Sources */,
|
||||
FD9004142818AD0B00ABAAF6 /* _002_SetupStandardJobs.swift in Sources */,
|
||||
FDF8487A29405906007DCAE5 /* HTTPError.swift in Sources */,
|
||||
FDAA16762AC28A3B00DDBF77 /* UserDefaultsType.swift in Sources */,
|
||||
FDDF074429C3E3D000E5E8B5 /* FetchRequest+Utilities.swift in Sources */,
|
||||
B87EF18126377A1D00124B3C /* Features.swift in Sources */,
|
||||
FD09797727FAB7A600936362 /* Data+Image.swift in Sources */,
|
||||
|
@ -6190,7 +6175,7 @@
|
|||
FDF8488929405B27007DCAE5 /* Data+Utilities.swift in Sources */,
|
||||
FD09797227FAA2F500936362 /* Optional+Utilities.swift in Sources */,
|
||||
FD7162DB281B6C440060647B /* TypedTableAlias.swift in Sources */,
|
||||
FDF01FAD2A9ECC4200CAF969 /* SingletonInfo.swift in Sources */,
|
||||
FDF01FAD2A9ECC4200CAF969 /* SingletonConfig.swift in Sources */,
|
||||
FD7115F828C8151C00B47552 /* DisposableBarButtonItem.swift in Sources */,
|
||||
FD17D7E727F6A16700122BE0 /* _003_YDBToGRDBMigration.swift in Sources */,
|
||||
);
|
||||
|
@ -6704,6 +6689,7 @@
|
|||
FDB5DB162A9821DF002C8721 /* CommonMockedExtensions.swift in Sources */,
|
||||
FDB5DB112A981FA6002C8721 /* TestExtensions.swift in Sources */,
|
||||
FDB5DB092A981F8D002C8721 /* MockCrypto.swift in Sources */,
|
||||
FDAA167B2AC28E2F00DDBF77 /* SnodeRequestSpec.swift in Sources */,
|
||||
FD65318C2AA025C500DFEEAA /* TestDependencies.swift in Sources */,
|
||||
FDB5DB102A981FA3002C8721 /* TestConstants.swift in Sources */,
|
||||
FDB5DB0C2A981F96002C8721 /* MockNetwork.swift in Sources */,
|
||||
|
|
|
@ -175,7 +175,7 @@ public extension Profile {
|
|||
profileEncryptionKey: profileKey,
|
||||
lastProfilePictureUpdate: sentTimestamp,
|
||||
blocksCommunityMessageRequests: (proto.hasBlocksCommunityMessageRequests ? proto.blocksCommunityMessageRequests : nil),
|
||||
lastBlocksCommunityMessageRequests: (proto.hasBlocksCommunityMessageRequests ? sentTimestamp : 0)
|
||||
lastBlocksCommunityMessageRequests: (proto.hasBlocksCommunityMessageRequests ? sentTimestamp : nil)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@ public enum MessageSendJob: JobExecutor {
|
|||
/// If we got an error when trying to retrieve the attachment state then this job is actually invalid so it
|
||||
/// should permanently fail
|
||||
guard attachmentState.error == nil else {
|
||||
SNLog("[MessageSendJob] Failed due to invalid attachment state")
|
||||
return failure(job, (attachmentState.error ?? MessageSenderError.invalidMessage), true, dependencies)
|
||||
}
|
||||
|
||||
|
|
|
@ -1260,7 +1260,7 @@ public extension OpenGroupManager {
|
|||
}
|
||||
|
||||
public extension Cache {
|
||||
static let openGroupManager: CacheInfo.Config<OGMCacheType, OGMImmutableCacheType> = CacheInfo.create(
|
||||
static let openGroupManager: CacheConfig<OGMCacheType, OGMImmutableCacheType> = Dependencies.create(
|
||||
createInstance: { _ in OpenGroupManager.Cache() },
|
||||
mutableInstance: { $0 },
|
||||
immutableInstance: { $0 }
|
||||
|
|
|
@ -9,7 +9,7 @@ import SessionUtilitiesKit
|
|||
// MARK: - Singleton
|
||||
|
||||
public extension Singleton {
|
||||
static let closedGroupPoller: SingletonInfo.Config<ClosedGroupPoller> = SingletonInfo.create { _ in
|
||||
static let closedGroupPoller: SingletonConfig<ClosedGroupPoller> = Dependencies.create { _ in
|
||||
ClosedGroupPoller()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ internal extension SessionUtil {
|
|||
)
|
||||
),
|
||||
lastProfilePictureUpdate: (TimeInterval(serverTimestampMs) / 1000),
|
||||
lastBlocksCommunityMessageRequests: 0
|
||||
lastBlocksCommunityMessageRequests: nil
|
||||
)
|
||||
|
||||
result.append(
|
||||
|
|
|
@ -608,7 +608,7 @@ public extension SessionUtil {
|
|||
}
|
||||
|
||||
public extension Cache {
|
||||
static let sessionUtil: CacheInfo.Config<SessionUtilCacheType, SessionUtilImmutableCacheType> = CacheInfo.create(
|
||||
static let sessionUtil: CacheConfig<SessionUtilCacheType, SessionUtilImmutableCacheType> = Dependencies.create(
|
||||
createInstance: { _ in SessionUtil.Cache() },
|
||||
mutableInstance: { $0 },
|
||||
immutableInstance: { $0 }
|
||||
|
|
|
@ -57,7 +57,13 @@ class SessionUtilSpec: QuickSpec {
|
|||
)
|
||||
@TestState(cache: .sessionUtil, in: dependencies) var mockSessionUtilCache: MockSessionUtilCache! = MockSessionUtilCache(
|
||||
initialSetup: { cache in
|
||||
var conf: UnsafeMutablePointer<config_object>!
|
||||
var secretKey: [UInt8] = Array(Data(hex: TestConstants.edSecretKey))
|
||||
_ = user_groups_init(&conf, &secretKey, nil, 0, nil)
|
||||
|
||||
cache.when { $0.setConfig(for: any(), publicKey: any(), to: any()) }.thenReturn(())
|
||||
cache.when { $0.config(for: .userGroups, publicKey: any()) }
|
||||
.thenReturn(Atomic(.object(conf)))
|
||||
}
|
||||
)
|
||||
@TestState var createGroupOutput: SessionUtil.CreatedGroupInfo!
|
||||
|
@ -355,10 +361,7 @@ class SessionUtilSpec: QuickSpec {
|
|||
id: "123456",
|
||||
profile: Profile(
|
||||
id: "123456",
|
||||
name: "",
|
||||
lastNameUpdate: 0,
|
||||
lastProfilePictureUpdate: 0,
|
||||
lastBlocksCommunityMessageRequests: 0
|
||||
name: ""
|
||||
)
|
||||
)],
|
||||
admins: [],
|
||||
|
@ -447,21 +450,15 @@ class SessionUtilSpec: QuickSpec {
|
|||
profile: Profile(
|
||||
id: "051111111111111111111111111111111111111111111111111111111111111111",
|
||||
name: "TestName",
|
||||
lastNameUpdate: 0,
|
||||
profilePictureUrl: "testUrl",
|
||||
profileEncryptionKey: Data([1, 2, 3]),
|
||||
lastProfilePictureUpdate: 0,
|
||||
lastBlocksCommunityMessageRequests: 0
|
||||
profileEncryptionKey: Data([1, 2, 3])
|
||||
)
|
||||
)],
|
||||
admins: [(
|
||||
id: "05\(TestConstants.publicKey)",
|
||||
profile: Profile(
|
||||
id: "05\(TestConstants.publicKey)",
|
||||
name: "TestName2",
|
||||
lastNameUpdate: 0,
|
||||
lastProfilePictureUpdate: 0,
|
||||
lastBlocksCommunityMessageRequests: 0
|
||||
name: "TestName2"
|
||||
)
|
||||
)],
|
||||
using: dependencies
|
||||
|
@ -504,10 +501,7 @@ class SessionUtilSpec: QuickSpec {
|
|||
id: "051111111111111111111111111111111111111111111111111111111111111111",
|
||||
profile: Profile(
|
||||
id: "051111111111111111111111111111111111111111111111111111111111111111",
|
||||
name: "TestName",
|
||||
lastNameUpdate: 0,
|
||||
lastProfilePictureUpdate: 0,
|
||||
lastBlocksCommunityMessageRequests: 0
|
||||
name: "TestName"
|
||||
)
|
||||
)],
|
||||
admins: [],
|
||||
|
@ -594,11 +588,14 @@ class SessionUtilSpec: QuickSpec {
|
|||
)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - when saving a created a group
|
||||
context("when saving a created a group") {
|
||||
// MARK: -- saves config dumps for the stored configs
|
||||
it("saves config dumps for the stored configs") {
|
||||
createGroupOutput = mockStorage.write(using: dependencies) { db in
|
||||
try SessionUtil.createGroup(
|
||||
mockStorage.write(using: dependencies) { db in
|
||||
createGroupOutput = try SessionUtil.createGroup(
|
||||
db,
|
||||
name: "Testname",
|
||||
displayPictureUrl: nil,
|
||||
|
@ -611,6 +608,13 @@ class SessionUtilSpec: QuickSpec {
|
|||
admins: [],
|
||||
using: dependencies
|
||||
)
|
||||
|
||||
try SessionUtil.saveCreatedGroup(
|
||||
db,
|
||||
group: createGroupOutput.group,
|
||||
groupState: createGroupOutput.groupState,
|
||||
using: dependencies
|
||||
)
|
||||
}
|
||||
|
||||
let result: [ConfigDump]? = mockStorage.read(using: dependencies) { db in
|
||||
|
@ -618,11 +622,44 @@ class SessionUtilSpec: QuickSpec {
|
|||
}
|
||||
|
||||
expect(result?.map { $0.variant }.asSet())
|
||||
.to(equal([.groupInfo, .groupKeys, .groupMembers]))
|
||||
.to(contain([.groupInfo, .groupKeys, .groupMembers]))
|
||||
expect(result?.map { $0.publicKey }.asSet())
|
||||
.to(equal(["03cbd569f56fb13ea95a3f0c05c331cc24139c0090feb412069dc49fab34406ece"]))
|
||||
.to(contain(["03cbd569f56fb13ea95a3f0c05c331cc24139c0090feb412069dc49fab34406ece"]))
|
||||
expect(result?.map { $0.timestampMs }.asSet())
|
||||
.to(equal([1234567890000]))
|
||||
.to(contain([1234567890000]))
|
||||
}
|
||||
|
||||
// MARK: -- adds the group to the user groups config
|
||||
it("adds the group to the user groups config") {
|
||||
mockStorage.write(using: dependencies) { db in
|
||||
createGroupOutput = try SessionUtil.createGroup(
|
||||
db,
|
||||
name: "Testname",
|
||||
displayPictureUrl: nil,
|
||||
displayPictureFilename: nil,
|
||||
displayPictureEncryptionKey: nil,
|
||||
members: [(
|
||||
id: "051111111111111111111111111111111111111111111111111111111111111111",
|
||||
profile: nil
|
||||
)],
|
||||
admins: [],
|
||||
using: dependencies
|
||||
)
|
||||
|
||||
try SessionUtil.saveCreatedGroup(
|
||||
db,
|
||||
group: createGroupOutput.group,
|
||||
groupState: createGroupOutput.groupState,
|
||||
using: dependencies
|
||||
)
|
||||
}
|
||||
|
||||
let result: [ConfigDump]? = mockStorage.read(using: dependencies) { db in
|
||||
try ConfigDump.fetchAll(db)
|
||||
}
|
||||
|
||||
expect(result?.map { $0.variant }.asSet()).to(contain([.userGroups]))
|
||||
expect(result?.map { $0.timestampMs }.asSet()).to(contain([1234567890000]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,7 +214,7 @@ class OpenGroupManagerSpec: QuickSpec {
|
|||
it("defaults the time since last open to greatestFiniteMagnitude") {
|
||||
mockUserDefaults
|
||||
.when { (defaults: inout any UserDefaultsType) -> Any? in
|
||||
defaults.object(forKey: UserDefaultsInfo.DateKey.lastOpen.rawValue)
|
||||
defaults.object(forKey: UserDefaults.DateKey.lastOpen.rawValue)
|
||||
}
|
||||
.thenReturn(nil)
|
||||
|
||||
|
@ -226,7 +226,7 @@ class OpenGroupManagerSpec: QuickSpec {
|
|||
it("returns the time since the last open") {
|
||||
mockUserDefaults
|
||||
.when { (defaults: inout any UserDefaultsType) -> Any? in
|
||||
defaults.object(forKey: UserDefaultsInfo.DateKey.lastOpen.rawValue)
|
||||
defaults.object(forKey: UserDefaults.DateKey.lastOpen.rawValue)
|
||||
}
|
||||
.thenReturn(Date(timeIntervalSince1970: 1234567880))
|
||||
dependencies.dateNow = Date(timeIntervalSince1970: 1234567890)
|
||||
|
@ -239,7 +239,7 @@ class OpenGroupManagerSpec: QuickSpec {
|
|||
it("caches the time since the last open") {
|
||||
mockUserDefaults
|
||||
.when { (defaults: inout any UserDefaultsType) -> Any? in
|
||||
defaults.object(forKey: UserDefaultsInfo.DateKey.lastOpen.rawValue)
|
||||
defaults.object(forKey: UserDefaults.DateKey.lastOpen.rawValue)
|
||||
}
|
||||
.thenReturn(Date(timeIntervalSince1970: 1234567770))
|
||||
dependencies.dateNow = Date(timeIntervalSince1970: 1234567780)
|
||||
|
@ -249,7 +249,7 @@ class OpenGroupManagerSpec: QuickSpec {
|
|||
|
||||
mockUserDefaults
|
||||
.when { (defaults: inout any UserDefaultsType) -> Any? in
|
||||
defaults.object(forKey: UserDefaultsInfo.DateKey.lastOpen.rawValue)
|
||||
defaults.object(forKey: UserDefaults.DateKey.lastOpen.rawValue)
|
||||
}
|
||||
.thenReturn(Date(timeIntervalSince1970: 1234567890))
|
||||
|
||||
|
@ -289,7 +289,7 @@ class OpenGroupManagerSpec: QuickSpec {
|
|||
|
||||
mockUserDefaults
|
||||
.when { (defaults: inout any UserDefaultsType) -> Any? in
|
||||
defaults.object(forKey: UserDefaultsInfo.DateKey.lastOpen.rawValue)
|
||||
defaults.object(forKey: UserDefaults.DateKey.lastOpen.rawValue)
|
||||
}
|
||||
.thenReturn(Date(timeIntervalSince1970: 1234567890))
|
||||
}
|
||||
|
@ -745,7 +745,7 @@ class OpenGroupManagerSpec: QuickSpec {
|
|||
|
||||
mockUserDefaults
|
||||
.when { (defaults: inout any UserDefaultsType) -> Any? in
|
||||
defaults.object(forKey: UserDefaultsInfo.DateKey.lastOpen.rawValue)
|
||||
defaults.object(forKey: UserDefaults.DateKey.lastOpen.rawValue)
|
||||
}
|
||||
.thenReturn(Date(timeIntervalSince1970: 1234567890))
|
||||
}
|
||||
|
@ -890,7 +890,7 @@ class OpenGroupManagerSpec: QuickSpec {
|
|||
|
||||
mockUserDefaults
|
||||
.when { (defaults: inout any UserDefaultsType) -> Any? in
|
||||
defaults.object(forKey: UserDefaultsInfo.DateKey.lastOpen.rawValue)
|
||||
defaults.object(forKey: UserDefaults.DateKey.lastOpen.rawValue)
|
||||
}
|
||||
.thenReturn(Date(timeIntervalSince1970: 1234567890))
|
||||
}
|
||||
|
@ -1171,7 +1171,7 @@ class OpenGroupManagerSpec: QuickSpec {
|
|||
|
||||
mockUserDefaults
|
||||
.when { (defaults: inout any UserDefaultsType) -> Any? in
|
||||
defaults.object(forKey: UserDefaultsInfo.DateKey.lastOpen.rawValue)
|
||||
defaults.object(forKey: UserDefaults.DateKey.lastOpen.rawValue)
|
||||
}
|
||||
.thenReturn(nil)
|
||||
}
|
||||
|
@ -3207,7 +3207,7 @@ class OpenGroupManagerSpec: QuickSpec {
|
|||
.to(call(matchingParameters: .all) {
|
||||
$0.set(
|
||||
testDate,
|
||||
forKey: UserDefaultsInfo.DateKey.lastOpenGroupImageUpdate.rawValue
|
||||
forKey: UserDefaults.DateKey.lastOpenGroupImageUpdate.rawValue
|
||||
)
|
||||
})
|
||||
expect(
|
||||
|
@ -3316,7 +3316,7 @@ class OpenGroupManagerSpec: QuickSpec {
|
|||
.toNot(call(matchingParameters: .all) {
|
||||
$0.set(
|
||||
dependencies.dateNow,
|
||||
forKey: UserDefaultsInfo.DateKey.lastOpenGroupImageUpdate.rawValue
|
||||
forKey: UserDefaults.DateKey.lastOpenGroupImageUpdate.rawValue
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -3398,7 +3398,7 @@ class OpenGroupManagerSpec: QuickSpec {
|
|||
.to(call(matchingParameters: .all) {
|
||||
$0.set(
|
||||
dependencies.dateNow,
|
||||
forKey: UserDefaultsInfo.DateKey.lastOpenGroupImageUpdate.rawValue
|
||||
forKey: UserDefaults.DateKey.lastOpenGroupImageUpdate.rawValue
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,3 +1,188 @@
|
|||
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import GRDB
|
||||
import SessionUtil
|
||||
import SessionUtilitiesKit
|
||||
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
@testable import SessionMessagingKit
|
||||
|
||||
class MessageSenderGroupsSpec: QuickSpec {
|
||||
override class func spec() {
|
||||
// MARK: Configuration
|
||||
|
||||
@TestState var dependencies: TestDependencies! = TestDependencies { dependencies in
|
||||
dependencies.dateNow = Date(timeIntervalSince1970: 1234567890)
|
||||
dependencies.forceSynchronous = true
|
||||
}
|
||||
@TestState(singleton: .storage, in: dependencies) var mockStorage: Storage! = SynchronousStorage(
|
||||
customWriter: try! DatabaseQueue(),
|
||||
customMigrationTargets: [
|
||||
SNUtilitiesKit.self,
|
||||
SNMessagingKit.self
|
||||
],
|
||||
using: dependencies,
|
||||
initialData: { db in
|
||||
try Identity(variant: .x25519PublicKey, data: Data(hex: TestConstants.publicKey)).insert(db)
|
||||
try Identity(variant: .x25519PrivateKey, data: Data(hex: TestConstants.privateKey)).insert(db)
|
||||
try Identity(variant: .ed25519PublicKey, data: Data(hex: TestConstants.edPublicKey)).insert(db)
|
||||
try Identity(variant: .ed25519SecretKey, data: Data(hex: TestConstants.edSecretKey)).insert(db)
|
||||
}
|
||||
)
|
||||
@TestState(singleton: .network, in: dependencies) var mockNetwork: MockNetwork! = MockNetwork()
|
||||
@TestState(singleton: .crypto, in: dependencies) var mockCrypto: MockCrypto! = MockCrypto(
|
||||
initialSetup: { crypto in
|
||||
crypto
|
||||
.when { crypto in crypto.generate(.ed25519KeyPair(seed: any(), using: any())) }
|
||||
.thenReturn(
|
||||
KeyPair(
|
||||
publicKey: Data.data(
|
||||
fromHex: "cbd569f56fb13ea95a3f0c05c331cc24139c0090feb412069dc49fab34406ece"
|
||||
)!.bytes,
|
||||
secretKey: Data.data(
|
||||
fromHex: "0123456789abcdef0123456789abcdeffedcba9876543210fedcba9876543210" +
|
||||
"cbd569f56fb13ea95a3f0c05c331cc24139c0090feb412069dc49fab34406ece"
|
||||
)!.bytes
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
@TestState(cache: .general, in: dependencies) var mockGeneralCache: MockGeneralCache! = MockGeneralCache(
|
||||
initialSetup: { cache in
|
||||
cache.when { $0.encodedPublicKey }.thenReturn("05\(TestConstants.publicKey)")
|
||||
}
|
||||
)
|
||||
@TestState(cache: .sessionUtil, in: dependencies) var mockSessionUtilCache: MockSessionUtilCache! = MockSessionUtilCache(
|
||||
initialSetup: { cache in
|
||||
cache
|
||||
.when { $0.setConfig(for: any(), publicKey: any(), to: any()) }
|
||||
.thenReturn(())
|
||||
}
|
||||
)
|
||||
@TestState var disposables: [AnyCancellable]! = []
|
||||
@TestState var error: Error?
|
||||
@TestState var thread: SessionThread?
|
||||
|
||||
// MARK: - a MessageSender dealing with Groups
|
||||
describe("a MessageSender dealing with Groups") {
|
||||
// MARK: -- when creating a group
|
||||
context("when creating a group") {
|
||||
beforeEach {
|
||||
var userGroupsConf: UnsafeMutablePointer<config_object>!
|
||||
var secretKey: [UInt8] = Array(Data(hex: TestConstants.edSecretKey))
|
||||
_ = user_groups_init(&userGroupsConf, &secretKey, nil, 0, nil)
|
||||
let userGroupsConfig: SessionUtil.Config = .object(userGroupsConf)
|
||||
|
||||
mockSessionUtilCache
|
||||
.when { $0.config(for: .userGroups, publicKey: any()) }
|
||||
.thenReturn(Atomic(userGroupsConfig))
|
||||
}
|
||||
|
||||
// MARK: ---- stores the thread in the db
|
||||
it("stores the thread in the db") {
|
||||
MessageSender
|
||||
.createGroup(
|
||||
name: "Test",
|
||||
displayPicture: nil,
|
||||
members: [
|
||||
("051111111111111111111111111111111111111111111111111111111111111111", nil)
|
||||
],
|
||||
using: dependencies
|
||||
)
|
||||
.handleEvents(receiveOutput: { result in thread = result })
|
||||
.mapError { error.setting(to: $0) }
|
||||
.sinkAndStore(in: &disposables)
|
||||
|
||||
expect(error).to(beNil())
|
||||
expect(thread).toNot(beNil())
|
||||
|
||||
let dbValue: SessionThread? = mockStorage.read { db in try SessionThread.fetchOne(db) }
|
||||
expect(dbValue).to(equal(thread))
|
||||
expect(dbValue?.id)
|
||||
.to(equal("03cbd569f56fb13ea95a3f0c05c331cc24139c0090feb412069dc49fab34406ece"))
|
||||
expect(dbValue?.variant).to(equal(.group))
|
||||
expect(dbValue?.creationDateTimestamp).to(equal(1234567890))
|
||||
expect(dbValue?.shouldBeVisible).to(beTrue())
|
||||
expect(dbValue?.notificationSound).to(beNil())
|
||||
expect(dbValue?.mutedUntilTimestamp).to(beNil())
|
||||
expect(dbValue?.onlyNotifyForMentions).to(beFalse())
|
||||
expect(dbValue?.pinnedPriority).to(equal(0))
|
||||
}
|
||||
|
||||
// MARK: ---- stores the group in the db
|
||||
it("stores the group in the db") {
|
||||
MessageSender
|
||||
.createGroup(
|
||||
name: "TestGroupName",
|
||||
displayPicture: nil,
|
||||
members: [
|
||||
("051111111111111111111111111111111111111111111111111111111111111111", nil)
|
||||
],
|
||||
using: dependencies
|
||||
)
|
||||
.handleEvents(receiveOutput: { result in thread = result })
|
||||
.mapError { error.setting(to: $0) }
|
||||
.sinkAndStore(in: &disposables)
|
||||
|
||||
expect(error).to(beNil())
|
||||
expect(thread).toNot(beNil())
|
||||
|
||||
let dbValue: ClosedGroup? = mockStorage.read { db in try ClosedGroup.fetchOne(db) }
|
||||
expect(dbValue?.id)
|
||||
.to(equal("03cbd569f56fb13ea95a3f0c05c331cc24139c0090feb412069dc49fab34406ece"))
|
||||
expect(dbValue?.name).to(equal("TestGroupName"))
|
||||
expect(dbValue?.formationTimestamp).to(equal(1234567890))
|
||||
expect(dbValue?.displayPictureUrl).to(beNil())
|
||||
expect(dbValue?.displayPictureFilename).to(beNil())
|
||||
expect(dbValue?.displayPictureEncryptionKey).to(beNil())
|
||||
expect(dbValue?.lastDisplayPictureUpdate).to(equal(1234567890))
|
||||
expect(dbValue?.groupIdentityPrivateKey?.toHexString())
|
||||
.to(equal(
|
||||
"0123456789abcdef0123456789abcdeffedcba9876543210fedcba9876543210" +
|
||||
"cbd569f56fb13ea95a3f0c05c331cc24139c0090feb412069dc49fab34406ece"
|
||||
))
|
||||
expect(dbValue?.authData).to(beNil())
|
||||
expect(dbValue?.invited).to(beFalse())
|
||||
}
|
||||
|
||||
// MARK: ---- stores the group members in the db
|
||||
it("stores the group members in the db") {
|
||||
MessageSender
|
||||
.createGroup(
|
||||
name: "TestGroupName",
|
||||
displayPicture: nil,
|
||||
members: [
|
||||
("051111111111111111111111111111111111111111111111111111111111111111", nil)
|
||||
],
|
||||
using: dependencies
|
||||
)
|
||||
.handleEvents(receiveOutput: { result in thread = result })
|
||||
.mapError { error.setting(to: $0) }
|
||||
.sinkAndStore(in: &disposables)
|
||||
|
||||
expect(error).to(beNil())
|
||||
expect(thread).toNot(beNil())
|
||||
expect(mockStorage.read { db in try GroupMember.fetchSet(db) })
|
||||
.to(equal([
|
||||
GroupMember(
|
||||
groupId: "03cbd569f56fb13ea95a3f0c05c331cc24139c0090feb412069dc49fab34406ece",
|
||||
profileId: "051111111111111111111111111111111111111111111111111111111111111111",
|
||||
role: .standard,
|
||||
isHidden: false
|
||||
),
|
||||
GroupMember(
|
||||
groupId: "03cbd569f56fb13ea95a3f0c05c331cc24139c0090feb412069dc49fab34406ece",
|
||||
profileId: "05\(TestConstants.publicKey)",
|
||||
role: .admin,
|
||||
isHidden: false
|
||||
)
|
||||
]))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -865,7 +865,7 @@ public extension OnionRequestAPI {
|
|||
}
|
||||
|
||||
public extension Cache {
|
||||
static let onionRequestAPI: CacheInfo.Config<ORAPICacheType, ORAPIImmutableCacheType> = CacheInfo.create(
|
||||
static let onionRequestAPI: CacheConfig<ORAPICacheType, ORAPIImmutableCacheType> = Dependencies.create(
|
||||
createInstance: { dependencies in OnionRequestAPI.Cache(using: dependencies) },
|
||||
mutableInstance: { $0 },
|
||||
immutableInstance: { $0 }
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import SessionUtilitiesKit
|
||||
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
@testable import SessionSnodeKit
|
||||
|
||||
class SnodeRequestSpec: QuickSpec {
|
||||
override class func spec() {
|
||||
// MARK: Configuration
|
||||
|
||||
@TestState var dependencies: TestDependencies! = TestDependencies()
|
||||
@TestState var batchRequest: HTTP.BatchRequest!
|
||||
|
||||
// MARK: - a SnodeRequest
|
||||
describe("a SnodeRequest") {
|
||||
// MARK: -- when encoding a HTTP.BatchRequest storage server type endpoint
|
||||
context("when encoding a HTTP.BatchRequest storage server type endpoint") {
|
||||
// MARK: ---- successfully encodes a SnodeRequest body
|
||||
it("successfully encodes a SnodeRequest body") {
|
||||
batchRequest = HTTP.BatchRequest(
|
||||
requestsKey: .requests,
|
||||
requests: [
|
||||
HTTP.PreparedRequest<NoResponse>(
|
||||
request: Request<SnodeRequest<TestType>, TestEndpoint>(
|
||||
method: .post,
|
||||
server: "testServer",
|
||||
endpoint: .endpoint,
|
||||
queryParameters: [:],
|
||||
headers: [:],
|
||||
x25519PublicKey: "05\(TestConstants.publicKey)",
|
||||
body: SnodeRequest<TestType>(
|
||||
endpoint: .sendMessage,
|
||||
body: TestType(stringValue: "testValue")
|
||||
)
|
||||
),
|
||||
urlRequest: URLRequest(url: URL(string: "https://www.oxen.io")!),
|
||||
responseType: NoResponse.self,
|
||||
timeout: 0
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
let requestData: Data? = try? JSONEncoder().encode(batchRequest)
|
||||
let requestJson: [String: [[String: Any]]]? = requestData
|
||||
.map { try? JSONSerialization.jsonObject(with: $0) as? [String: [[String: Any]]] }
|
||||
let request: [String: Any]? = requestJson?["requests"]?.first
|
||||
expect(request?["method"] as? String).to(equal("store"))
|
||||
expect(request?["params"] as? [String: String]).to(equal(["stringValue": "testValue"]))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Test Types
|
||||
|
||||
fileprivate enum TestEndpoint: EndpointType {
|
||||
case endpoint
|
||||
|
||||
static var name: String { "TestEndpoint" }
|
||||
static var batchRequestVariant: HTTP.BatchRequest.Child.Variant { .storageServer }
|
||||
static var excludedSubRequestHeaders: [HTTPHeader] { [] }
|
||||
|
||||
var path: String { return "endpoint" }
|
||||
}
|
||||
|
||||
fileprivate struct TestType: Codable, Equatable {
|
||||
let stringValue: String
|
||||
}
|
|
@ -9,9 +9,7 @@ import Curve25519Kit
|
|||
// MARK: - Singleton
|
||||
|
||||
public extension Singleton {
|
||||
static let crypto: SingletonInfo.Config<CryptoType> = SingletonInfo.create { _ in
|
||||
Crypto()
|
||||
}
|
||||
static let crypto: SingletonConfig<CryptoType> = Dependencies.create { _ in Crypto() }
|
||||
}
|
||||
|
||||
// MARK: - CryptoType
|
||||
|
|
|
@ -11,10 +11,10 @@ import SignalCoreKit
|
|||
// MARK: - Singleton
|
||||
|
||||
public extension Singleton {
|
||||
static let storage: SingletonInfo.Config<Storage> = SingletonInfo.create { dependencies in
|
||||
static let storage: SingletonConfig<Storage> = Dependencies.create { dependencies in
|
||||
Storage(using: dependencies)
|
||||
}
|
||||
static let scheduler: SingletonInfo.Config<ValueObservationScheduler> = SingletonInfo.create { _ in
|
||||
static let scheduler: SingletonConfig<ValueObservationScheduler> = Dependencies.create { _ in
|
||||
AsyncValueObservationScheduler.async(onQueue: .main)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Cache
|
||||
|
||||
public class Cache {}
|
||||
|
||||
// MARK: - Cache Types
|
||||
|
||||
public protocol MutableCacheType {}
|
||||
public protocol ImmutableCacheType {}
|
||||
|
||||
// MARK: - CacheInfo
|
||||
|
||||
public class CacheConfig<M, I>: Cache {
|
||||
public let key: Int
|
||||
public let createInstance: (Dependencies) -> M
|
||||
public let mutableInstance: (M) -> MutableCacheType
|
||||
public let immutableInstance: (M) -> I
|
||||
|
||||
fileprivate init(
|
||||
createInstance: @escaping (Dependencies) -> M,
|
||||
mutableInstance: @escaping (M) -> MutableCacheType,
|
||||
immutableInstance: @escaping (M) -> I
|
||||
) {
|
||||
self.key = ObjectIdentifier(M.self).hashValue
|
||||
self.createInstance = createInstance
|
||||
self.mutableInstance = mutableInstance
|
||||
self.immutableInstance = immutableInstance
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Creation
|
||||
|
||||
public extension Dependencies {
|
||||
static func create<M, I>(
|
||||
createInstance: @escaping (Dependencies) -> M,
|
||||
mutableInstance: @escaping (M) -> MutableCacheType,
|
||||
immutableInstance: @escaping (M) -> I
|
||||
) -> CacheConfig<M, I> {
|
||||
return CacheConfig(
|
||||
createInstance: createInstance,
|
||||
mutableInstance: mutableInstance,
|
||||
immutableInstance: immutableInstance
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Cache
|
||||
|
||||
public class Cache {}
|
||||
|
||||
// MARK: - Cache Types
|
||||
|
||||
public protocol MutableCacheType {}
|
||||
public protocol ImmutableCacheType {}
|
||||
|
||||
// MARK: - CacheInfo
|
||||
|
||||
public enum CacheInfo {
|
||||
public class Config<M, I>: Cache {
|
||||
public let key: Int
|
||||
public let createInstance: (Dependencies) -> M
|
||||
public let mutableInstance: (M) -> MutableCacheType
|
||||
public let immutableInstance: (M) -> I
|
||||
|
||||
fileprivate init(
|
||||
createInstance: @escaping (Dependencies) -> M,
|
||||
mutableInstance: @escaping (M) -> MutableCacheType,
|
||||
immutableInstance: @escaping (M) -> I
|
||||
) {
|
||||
self.key = ObjectIdentifier(M.self).hashValue
|
||||
self.createInstance = createInstance
|
||||
self.mutableInstance = mutableInstance
|
||||
self.immutableInstance = immutableInstance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension CacheInfo {
|
||||
static func create<M, I>(
|
||||
createInstance: @escaping (Dependencies) -> M,
|
||||
mutableInstance: @escaping (M) -> MutableCacheType,
|
||||
immutableInstance: @escaping (M) -> I
|
||||
) -> CacheInfo.Config<M, I> {
|
||||
return CacheInfo.Config(
|
||||
createInstance: createInstance,
|
||||
mutableInstance: mutableInstance,
|
||||
immutableInstance: immutableInstance
|
||||
)
|
||||
}
|
||||
}
|
|
@ -12,15 +12,15 @@ public class Dependencies {
|
|||
|
||||
// MARK: - Subscript Access
|
||||
|
||||
public subscript<S>(singleton singleton: SingletonInfo.Config<S>) -> S {
|
||||
public subscript<S>(singleton singleton: SingletonConfig<S>) -> S {
|
||||
getValueSettingIfNull(singleton: singleton, &Dependencies.singletonInstances)
|
||||
}
|
||||
|
||||
public subscript<M, I>(cache cache: CacheInfo.Config<M, I>) -> I {
|
||||
public subscript<M, I>(cache cache: CacheConfig<M, I>) -> I {
|
||||
getValueSettingIfNull(cache: cache, &Dependencies.cacheInstances)
|
||||
}
|
||||
|
||||
public subscript(defaults defaults: UserDefaultsInfo.Config) -> UserDefaultsType {
|
||||
public subscript(defaults defaults: UserDefaultsConfig) -> UserDefaultsType {
|
||||
getValueSettingIfNull(defaults: defaults, &Dependencies.userDefaultsInstances)
|
||||
}
|
||||
|
||||
|
@ -28,9 +28,7 @@ public class Dependencies {
|
|||
|
||||
public var dateNow: Date { Date() }
|
||||
public var fixedTime: Int { 0 }
|
||||
|
||||
public var forceSynchronous: Bool = false
|
||||
public var asyncExecutions: [Int: [() -> Void]] = [:]
|
||||
public var forceSynchronous: Bool { false }
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
|
@ -38,8 +36,14 @@ public class Dependencies {
|
|||
|
||||
// MARK: - Functions
|
||||
|
||||
public func async(at fixedTime: Int, closure: @escaping () -> Void) {
|
||||
async(at: TimeInterval(fixedTime), closure: closure)
|
||||
}
|
||||
|
||||
public func async(at timestamp: TimeInterval, closure: @escaping () -> Void) {}
|
||||
|
||||
@discardableResult public func mutate<M, I, R>(
|
||||
cache: CacheInfo.Config<M, I>,
|
||||
cache: CacheConfig<M, I>,
|
||||
_ mutation: (inout M) -> R
|
||||
) -> R {
|
||||
return Dependencies.cacheInstances.mutate { caches in
|
||||
|
@ -49,7 +53,7 @@ public class Dependencies {
|
|||
}
|
||||
|
||||
@discardableResult public func mutate<M, I, R>(
|
||||
cache: CacheInfo.Config<M, I>,
|
||||
cache: CacheConfig<M, I>,
|
||||
_ mutation: (inout M) throws -> R
|
||||
) throws -> R {
|
||||
return try Dependencies.cacheInstances.mutate { caches in
|
||||
|
@ -61,7 +65,7 @@ public class Dependencies {
|
|||
// MARK: - Instance upserting
|
||||
|
||||
@discardableResult private func getValueSettingIfNull<S>(
|
||||
singleton: SingletonInfo.Config<S>,
|
||||
singleton: SingletonConfig<S>,
|
||||
_ store: inout Atomic<[Int: Any]>
|
||||
) -> S {
|
||||
guard let value: S = (store.wrappedValue[singleton.key] as? S) else {
|
||||
|
@ -74,7 +78,7 @@ public class Dependencies {
|
|||
}
|
||||
|
||||
@discardableResult private func getValueSettingIfNull<M, I>(
|
||||
cache: CacheInfo.Config<M, I>,
|
||||
cache: CacheConfig<M, I>,
|
||||
_ store: inout Atomic<[Int: MutableCacheType]>
|
||||
) -> I {
|
||||
guard let value: M = (store.wrappedValue[cache.key] as? M) else {
|
||||
|
@ -88,7 +92,7 @@ public class Dependencies {
|
|||
}
|
||||
|
||||
@discardableResult private func getValueSettingIfNull(
|
||||
defaults: UserDefaultsInfo.Config,
|
||||
defaults: UserDefaultsConfig,
|
||||
_ store: inout Atomic<[Int: UserDefaultsType]>
|
||||
) -> UserDefaultsType {
|
||||
guard let value: UserDefaultsType = store.wrappedValue[defaults.key] else {
|
||||
|
@ -104,33 +108,33 @@ public class Dependencies {
|
|||
// MARK: - Storage Setting Convenience
|
||||
|
||||
public extension Dependencies {
|
||||
subscript(singleton singleton: SingletonInfo.Config<Storage>, key key: Setting.BoolKey) -> Bool {
|
||||
subscript(singleton singleton: SingletonConfig<Storage>, key key: Setting.BoolKey) -> Bool {
|
||||
return self[singleton: singleton]
|
||||
.read { db in db[key] }
|
||||
.defaulting(to: false) // Default to false if it doesn't exist
|
||||
}
|
||||
|
||||
subscript(singleton singleton: SingletonInfo.Config<Storage>, key key: Setting.DoubleKey) -> Double? {
|
||||
subscript(singleton singleton: SingletonConfig<Storage>, key key: Setting.DoubleKey) -> Double? {
|
||||
return self[singleton: singleton].read { db in db[key] }
|
||||
}
|
||||
|
||||
subscript(singleton singleton: SingletonInfo.Config<Storage>, key key: Setting.IntKey) -> Int? {
|
||||
subscript(singleton singleton: SingletonConfig<Storage>, key key: Setting.IntKey) -> Int? {
|
||||
return self[singleton: singleton].read { db in db[key] }
|
||||
}
|
||||
|
||||
subscript(singleton singleton: SingletonInfo.Config<Storage>, key key: Setting.StringKey) -> String? {
|
||||
subscript(singleton singleton: SingletonConfig<Storage>, key key: Setting.StringKey) -> String? {
|
||||
return self[singleton: singleton].read { db in db[key] }
|
||||
}
|
||||
|
||||
subscript(singleton singleton: SingletonInfo.Config<Storage>, key key: Setting.DateKey) -> Date? {
|
||||
subscript(singleton singleton: SingletonConfig<Storage>, key key: Setting.DateKey) -> Date? {
|
||||
return self[singleton: singleton].read { db in db[key] }
|
||||
}
|
||||
|
||||
subscript<T: EnumIntSetting>(singleton singleton: SingletonInfo.Config<Storage>, key key: Setting.EnumKey) -> T? {
|
||||
subscript<T: EnumIntSetting>(singleton singleton: SingletonConfig<Storage>, key key: Setting.EnumKey) -> T? {
|
||||
return self[singleton: singleton].read { db in db[key] }
|
||||
}
|
||||
|
||||
subscript<T: EnumStringSetting>(singleton singleton: SingletonInfo.Config<Storage>, key key: Setting.EnumKey) -> T? {
|
||||
subscript<T: EnumStringSetting>(singleton singleton: SingletonConfig<Storage>, key key: Setting.EnumKey) -> T? {
|
||||
return self[singleton: singleton].read { db in db[key] }
|
||||
}
|
||||
}
|
||||
|
@ -138,27 +142,27 @@ public extension Dependencies {
|
|||
// MARK: - UserDefaults Convenience
|
||||
|
||||
public extension Dependencies {
|
||||
subscript(defaults defaults: UserDefaultsInfo.Config, key key: UserDefaultsInfo.BoolKey) -> Bool {
|
||||
subscript(defaults defaults: UserDefaultsConfig, key key: UserDefaults.BoolKey) -> Bool {
|
||||
get { return self[defaults: defaults].bool(forKey: key.rawValue) }
|
||||
set { self[defaults: defaults].set(newValue, forKey: key.rawValue) }
|
||||
}
|
||||
|
||||
subscript(defaults defaults: UserDefaultsInfo.Config, key key: UserDefaultsInfo.DateKey) -> Date? {
|
||||
subscript(defaults defaults: UserDefaultsConfig, key key: UserDefaults.DateKey) -> Date? {
|
||||
get { return self[defaults: defaults].object(forKey: key.rawValue) as? Date }
|
||||
set { self[defaults: defaults].set(newValue, forKey: key.rawValue) }
|
||||
}
|
||||
|
||||
subscript(defaults defaults: UserDefaultsInfo.Config, key key: UserDefaultsInfo.DoubleKey) -> Double {
|
||||
subscript(defaults defaults: UserDefaultsConfig, key key: UserDefaults.DoubleKey) -> Double {
|
||||
get { return self[defaults: defaults].double(forKey: key.rawValue) }
|
||||
set { self[defaults: defaults].set(newValue, forKey: key.rawValue) }
|
||||
}
|
||||
|
||||
subscript(defaults defaults: UserDefaultsInfo.Config, key key: UserDefaultsInfo.IntKey) -> Int {
|
||||
subscript(defaults defaults: UserDefaultsConfig, key key: UserDefaults.IntKey) -> Int {
|
||||
get { return self[defaults: defaults].integer(forKey: key.rawValue) }
|
||||
set { self[defaults: defaults].set(newValue, forKey: key.rawValue) }
|
||||
}
|
||||
|
||||
subscript(defaults defaults: UserDefaultsInfo.Config, key key: UserDefaultsInfo.StringKey) -> String? {
|
||||
subscript(defaults defaults: UserDefaultsConfig, key key: UserDefaults.StringKey) -> String? {
|
||||
get { return self[defaults: defaults].string(forKey: key.rawValue) }
|
||||
set { self[defaults: defaults].set(newValue, forKey: key.rawValue) }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Singleton
|
||||
|
||||
public class Singleton {}
|
||||
|
||||
// MARK: - SingletonConfig<S>
|
||||
|
||||
public class SingletonConfig<S>: Singleton {
|
||||
public let key: Int
|
||||
public let createInstance: (Dependencies) -> S
|
||||
|
||||
/// `fileprivate` to hide when accessing via `dependencies[singleton: ]`
|
||||
fileprivate init(
|
||||
createInstance: @escaping (Dependencies) -> S
|
||||
) {
|
||||
self.key = ObjectIdentifier(S.self).hashValue
|
||||
self.createInstance = createInstance
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Creation
|
||||
|
||||
public extension Dependencies {
|
||||
static func create<S>(
|
||||
createInstance: @escaping (Dependencies) -> S
|
||||
) -> SingletonConfig<S> {
|
||||
return SingletonConfig(
|
||||
createInstance: createInstance
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Singleton
|
||||
|
||||
public class Singleton {}
|
||||
|
||||
// MARK: - SingletonInfo
|
||||
|
||||
public enum SingletonInfo {
|
||||
public class Config<S>: Singleton {
|
||||
public let key: Int
|
||||
public let createInstance: (Dependencies) -> S
|
||||
|
||||
fileprivate init(
|
||||
createInstance: @escaping (Dependencies) -> S
|
||||
) {
|
||||
self.key = ObjectIdentifier(S.self).hashValue
|
||||
self.createInstance = createInstance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension SingletonInfo {
|
||||
static func create<S>(
|
||||
createInstance: @escaping (Dependencies) -> S
|
||||
) -> SingletonInfo.Config<S> {
|
||||
return SingletonInfo.Config(
|
||||
createInstance: createInstance
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - UserDefaultsStorage
|
||||
|
||||
public class UserDefaultsStorage {}
|
||||
|
||||
// MARK: - UserDefaultsConfig
|
||||
|
||||
public class UserDefaultsConfig: UserDefaultsStorage {
|
||||
public let key: Int
|
||||
public let createInstance: (Dependencies) -> UserDefaultsType
|
||||
|
||||
/// `fileprivate` to hide when accessing via `dependencies[defaults: ]`
|
||||
fileprivate init(
|
||||
identifier: String,
|
||||
createInstance: @escaping (Dependencies) -> UserDefaultsType
|
||||
) {
|
||||
self.key = identifier.hashValue
|
||||
self.createInstance = createInstance
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Creation
|
||||
|
||||
public extension Dependencies {
|
||||
static func create(
|
||||
identifier: String,
|
||||
createInstance: @escaping (Dependencies) -> UserDefaultsType
|
||||
) -> UserDefaultsConfig {
|
||||
return UserDefaultsConfig(
|
||||
identifier: identifier,
|
||||
createInstance: createInstance
|
||||
)
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ public enum General {
|
|||
}
|
||||
|
||||
public extension Cache {
|
||||
static let general: CacheInfo.Config<GeneralCacheType, ImmutableGeneralCacheType> = CacheInfo.create(
|
||||
static let general: CacheConfig<GeneralCacheType, ImmutableGeneralCacheType> = Dependencies.create(
|
||||
createInstance: { _ in General.Cache() },
|
||||
mutableInstance: { $0 },
|
||||
immutableInstance: { $0 }
|
||||
|
|
|
@ -15,7 +15,7 @@ extension Timer {
|
|||
// timeInterval for execution and append it to the execution set so the test can
|
||||
// trigger the logic in a synchronous way)
|
||||
guard !dependencies.forceSynchronous else {
|
||||
dependencies.asyncExecutions.appendTo(Int(ceil(dependencies.dateNow.timeIntervalSince1970 + timeInterval))) {
|
||||
dependencies.async(at: dependencies.dateNow.timeIntervalSince1970 + timeInterval) {
|
||||
block(timer)
|
||||
}
|
||||
return timer
|
||||
|
|
|
@ -8,7 +8,7 @@ import GRDB
|
|||
// MARK: - Singleton
|
||||
|
||||
public extension Singleton {
|
||||
static let jobRunner: SingletonInfo.Config<JobRunnerType> = SingletonInfo.create { _ in JobRunner() }
|
||||
static let jobRunner: SingletonConfig<JobRunnerType> = Dependencies.create { _ in JobRunner() }
|
||||
}
|
||||
|
||||
// MARK: - JobRunnerType
|
||||
|
|
|
@ -6,9 +6,7 @@ import Combine
|
|||
// MARK: - Singleton
|
||||
|
||||
public extension Singleton {
|
||||
static let network: SingletonInfo.Config<NetworkType> = SingletonInfo.create { _ in
|
||||
Network()
|
||||
}
|
||||
static let network: SingletonConfig<NetworkType> = Dependencies.create { _ in Network() }
|
||||
}
|
||||
|
||||
// MARK: - NetworkType
|
||||
|
|
|
@ -88,14 +88,14 @@ public class AppVersion {
|
|||
|
||||
// MARK: - UserDefaults Keys
|
||||
|
||||
private extension UserDefaultsInfo.StringKey {
|
||||
private extension UserDefaults.StringKey {
|
||||
/// The version of the app when it was first launched
|
||||
static let firstAppVersion: UserDefaultsInfo.StringKey = "kNSUserDefaults_FirstAppVersion"
|
||||
static let firstAppVersion: UserDefaults.StringKey = "kNSUserDefaults_FirstAppVersion"
|
||||
|
||||
/// The version of the app when it was last launched
|
||||
static let lastAppVersion: UserDefaultsInfo.StringKey = "kNSUserDefaults_LastVersion"
|
||||
static let lastAppVersion: UserDefaults.StringKey = "kNSUserDefaults_LastVersion"
|
||||
|
||||
static let lastCompletedLaunchAppVersion: UserDefaultsInfo.StringKey = "kNSUserDefaults_LastCompletedLaunchAppVersion"
|
||||
static let lastCompletedLaunchMainAppVersion: UserDefaultsInfo.StringKey = "kNSUserDefaults_LastCompletedLaunchAppVersion_MainApp"
|
||||
static let lastCompletedLaunchSAEAppVersion: UserDefaultsInfo.StringKey = "kNSUserDefaults_LastCompletedLaunchAppVersion_SAE"
|
||||
static let lastCompletedLaunchAppVersion: UserDefaults.StringKey = "kNSUserDefaults_LastCompletedLaunchAppVersion"
|
||||
static let lastCompletedLaunchMainAppVersion: UserDefaults.StringKey = "kNSUserDefaults_LastCompletedLaunchAppVersion_MainApp"
|
||||
static let lastCompletedLaunchSAEAppVersion: UserDefaults.StringKey = "kNSUserDefaults_LastCompletedLaunchAppVersion_SAE"
|
||||
}
|
||||
|
|
|
@ -1,48 +1,16 @@
|
|||
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - UserDefaultsStorage
|
||||
|
||||
public class UserDefaultsStorage {}
|
||||
|
||||
public extension UserDefaultsStorage {
|
||||
static var standard: UserDefaultsInfo.Config = UserDefaultsInfo.create(identifier: "standard") { _ in
|
||||
static var standard: UserDefaultsConfig = Dependencies.create(identifier: "standard") { _ in
|
||||
UserDefaults.standard
|
||||
}
|
||||
static var appGroup: UserDefaultsInfo.Config = UserDefaultsInfo.create(identifier: UserDefaults.applicationGroup) { _ in
|
||||
static var appGroup: UserDefaultsConfig = Dependencies.create(identifier: UserDefaults.applicationGroup) { _ in
|
||||
UserDefaults(suiteName: UserDefaults.applicationGroup)!
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UserDefaultsInfo
|
||||
|
||||
public enum UserDefaultsInfo {
|
||||
public class Config: UserDefaultsStorage {
|
||||
public let key: Int
|
||||
public let createInstance: (Dependencies) -> UserDefaultsType
|
||||
|
||||
fileprivate init(
|
||||
identifier: String,
|
||||
createInstance: @escaping (Dependencies) -> UserDefaultsType
|
||||
) {
|
||||
self.key = identifier.hashValue
|
||||
self.createInstance = createInstance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension UserDefaultsInfo {
|
||||
static func create(
|
||||
identifier: String,
|
||||
createInstance: @escaping (Dependencies) -> UserDefaultsType
|
||||
) -> UserDefaultsInfo.Config {
|
||||
return UserDefaultsInfo.Config(
|
||||
identifier: identifier,
|
||||
createInstance: createInstance
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - UserDefaultsType
|
||||
|
||||
public protocol UserDefaultsType: AnyObject {
|
||||
|
@ -85,8 +53,87 @@ public extension UserDefaults {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - UserDefault Values
|
||||
|
||||
public extension UserDefaultsInfo {
|
||||
public extension UserDefaults.BoolKey {
|
||||
/// Indicates whether the user has synced an initial config message from this device
|
||||
static let hasSyncedInitialConfiguration: UserDefaults.BoolKey = "hasSyncedConfiguration"
|
||||
|
||||
/// Indicates whether the user has seen the suggestion to enable link previews
|
||||
static let hasSeenLinkPreviewSuggestion: UserDefaults.BoolKey = "hasSeenLinkPreviewSuggestion"
|
||||
|
||||
/// Indicates whether the user has seen the IP exposure warning when enabling calls
|
||||
///
|
||||
/// **Note:** This is currently not in use (it was decided that it's better to warn the user every time they enable calls instead
|
||||
/// of just the first time)
|
||||
static let hasSeenCallIPExposureWarning: UserDefaults.BoolKey = "hasSeenCallIPExposureWarning"
|
||||
|
||||
/// Indicates whether the user has seen the missed call tips modal
|
||||
static let hasSeenCallMissedTips: UserDefaults.BoolKey = "hasSeenCallMissedTips"
|
||||
|
||||
/// Indicates whether the user is registered for APNS (ie. "Fast Mode" notifications)
|
||||
static let isUsingFullAPNs: UserDefaults.BoolKey = "isUsingFullAPNs"
|
||||
|
||||
/// Indicates whether the device was unlinked from an account
|
||||
///
|
||||
/// **Note:** This doesn't seem to be properly used (we basically just maintain the existing value)
|
||||
static let wasUnlinked: UserDefaults.BoolKey = "wasUnlinked"
|
||||
|
||||
/// Indicates whether the main app is active, this is set to `true` while the app is in the foreground and `false` when
|
||||
/// the app is in the background
|
||||
static let isMainAppActive: UserDefaults.BoolKey = "isMainAppActive"
|
||||
|
||||
/// Indicates whether there is an ongoing call
|
||||
static let isCallOngoing: UserDefaults.BoolKey = "isCallOngoing"
|
||||
}
|
||||
|
||||
public extension UserDefaults.DateKey {
|
||||
/// The date/time when the users profile picture was last uploaded to the server (used to rate-limit re-uploading)
|
||||
static let lastProfilePictureUpload: UserDefaults.DateKey = "lastProfilePictureUpload"
|
||||
|
||||
/// The date/time when the device last updated the default open group room images (used to rate-limit re-downloading)
|
||||
static let lastOpenGroupImageUpdate: UserDefaults.DateKey = "lastOpenGroupImageUpdate"
|
||||
|
||||
/// The date/time when any open group last had a successful poll (used as a fallback date/time if the open group hasn't been polled
|
||||
/// this session)
|
||||
static let lastOpen: UserDefaults.DateKey = "lastOpen"
|
||||
|
||||
/// The date/time when the last garbage collection was performed (used to rate-limit garbage collection)
|
||||
static let lastGarbageCollection: UserDefaults.DateKey = "lastGarbageCollection"
|
||||
|
||||
/// The date/time when we last subscribed for push notifications (used to rate-limit calling our subscription endpoint)
|
||||
static let lastPushNotificationSync: UserDefaults.DateKey = "lastPushNotificationSync"
|
||||
|
||||
/// The date/time when we received a call pre-offer (used to suppress call notifications which are too old)
|
||||
static let lastCallPreOffer: UserDefaults.DateKey = "lastCallPreOffer"
|
||||
}
|
||||
|
||||
public extension UserDefaults.DoubleKey {
|
||||
/// The timestamp when we last uploaded the users push token (used to rate-limit calling our subscription endpoint)
|
||||
///
|
||||
/// **Note:** Looks like this replicates the `lastPushNotificationSync` behaviour
|
||||
static let lastDeviceTokenUpload: UserDefaults.DoubleKey = "lastDeviceTokenUploadTime"
|
||||
}
|
||||
|
||||
public extension UserDefaults.IntKey {
|
||||
/// The latest hardfork value returned when interacting with a service node
|
||||
static let hardfork: UserDefaults.IntKey = "hardfork"
|
||||
|
||||
/// The latest softfork value returned when interacting with a service node
|
||||
static let softfork: UserDefaults.IntKey = "softfork"
|
||||
}
|
||||
|
||||
public extension UserDefaults.StringKey {
|
||||
/// The most recently subscribed APNS token
|
||||
static let deviceToken: UserDefaults.StringKey = "deviceToken"
|
||||
|
||||
/// The warning to show at the top of the app
|
||||
static let topBannerWarningToShow: UserDefaults.StringKey = "topBannerWarningToShow"
|
||||
}
|
||||
|
||||
// MARK: - Keys
|
||||
|
||||
public extension UserDefaults {
|
||||
struct BoolKey: RawRepresentable, ExpressibleByStringLiteral, Hashable {
|
||||
public let rawValue: String
|
||||
|
||||
|
@ -137,81 +184,3 @@ public extension UserDefaultsInfo {
|
|||
public init(extendedGraphemeClusterLiteral value: String) { self.init(value) }
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UserDefault Values
|
||||
|
||||
public extension UserDefaultsInfo.BoolKey {
|
||||
/// Indicates whether the user has synced an initial config message from this device
|
||||
static let hasSyncedInitialConfiguration: UserDefaultsInfo.BoolKey = "hasSyncedConfiguration"
|
||||
|
||||
/// Indicates whether the user has seen the suggestion to enable link previews
|
||||
static let hasSeenLinkPreviewSuggestion: UserDefaultsInfo.BoolKey = "hasSeenLinkPreviewSuggestion"
|
||||
|
||||
/// Indicates whether the user has seen the IP exposure warning when enabling calls
|
||||
///
|
||||
/// **Note:** This is currently not in use (it was decided that it's better to warn the user every time they enable calls instead
|
||||
/// of just the first time)
|
||||
static let hasSeenCallIPExposureWarning: UserDefaultsInfo.BoolKey = "hasSeenCallIPExposureWarning"
|
||||
|
||||
/// Indicates whether the user has seen the missed call tips modal
|
||||
static let hasSeenCallMissedTips: UserDefaultsInfo.BoolKey = "hasSeenCallMissedTips"
|
||||
|
||||
/// Indicates whether the user is registered for APNS (ie. "Fast Mode" notifications)
|
||||
static let isUsingFullAPNs: UserDefaultsInfo.BoolKey = "isUsingFullAPNs"
|
||||
|
||||
/// Indicates whether the device was unlinked from an account
|
||||
///
|
||||
/// **Note:** This doesn't seem to be properly used (we basically just maintain the existing value)
|
||||
static let wasUnlinked: UserDefaultsInfo.BoolKey = "wasUnlinked"
|
||||
|
||||
/// Indicates whether the main app is active, this is set to `true` while the app is in the foreground and `false` when
|
||||
/// the app is in the background
|
||||
static let isMainAppActive: UserDefaultsInfo.BoolKey = "isMainAppActive"
|
||||
|
||||
/// Indicates whether there is an ongoing call
|
||||
static let isCallOngoing: UserDefaultsInfo.BoolKey = "isCallOngoing"
|
||||
}
|
||||
|
||||
public extension UserDefaultsInfo.DateKey {
|
||||
/// The date/time when the users profile picture was last uploaded to the server (used to rate-limit re-uploading)
|
||||
static let lastProfilePictureUpload: UserDefaultsInfo.DateKey = "lastProfilePictureUpload"
|
||||
|
||||
/// The date/time when the device last updated the default open group room images (used to rate-limit re-downloading)
|
||||
static let lastOpenGroupImageUpdate: UserDefaultsInfo.DateKey = "lastOpenGroupImageUpdate"
|
||||
|
||||
/// The date/time when any open group last had a successful poll (used as a fallback date/time if the open group hasn't been polled
|
||||
/// this session)
|
||||
static let lastOpen: UserDefaultsInfo.DateKey = "lastOpen"
|
||||
|
||||
/// The date/time when the last garbage collection was performed (used to rate-limit garbage collection)
|
||||
static let lastGarbageCollection: UserDefaultsInfo.DateKey = "lastGarbageCollection"
|
||||
|
||||
/// The date/time when we last subscribed for push notifications (used to rate-limit calling our subscription endpoint)
|
||||
static let lastPushNotificationSync: UserDefaultsInfo.DateKey = "lastPushNotificationSync"
|
||||
|
||||
/// The date/time when we received a call pre-offer (used to suppress call notifications which are too old)
|
||||
static let lastCallPreOffer: UserDefaultsInfo.DateKey = "lastCallPreOffer"
|
||||
}
|
||||
|
||||
public extension UserDefaultsInfo.DoubleKey {
|
||||
/// The timestamp when we last uploaded the users push token (used to rate-limit calling our subscription endpoint)
|
||||
///
|
||||
/// **Note:** Looks like this replicates the `lastPushNotificationSync` behaviour
|
||||
static let lastDeviceTokenUpload: UserDefaultsInfo.DoubleKey = "lastDeviceTokenUploadTime"
|
||||
}
|
||||
|
||||
public extension UserDefaultsInfo.IntKey {
|
||||
/// The latest hardfork value returned when interacting with a service node
|
||||
static let hardfork: UserDefaultsInfo.IntKey = "hardfork"
|
||||
|
||||
/// The latest softfork value returned when interacting with a service node
|
||||
static let softfork: UserDefaultsInfo.IntKey = "softfork"
|
||||
}
|
||||
|
||||
public extension UserDefaultsInfo.StringKey {
|
||||
/// The most recently subscribed APNS token
|
||||
static let deviceToken: UserDefaultsInfo.StringKey = "deviceToken"
|
||||
|
||||
/// The warning to show at the top of the app
|
||||
static let topBannerWarningToShow: UserDefaultsInfo.StringKey = "topBannerWarningToShow"
|
||||
}
|
|
@ -1737,7 +1737,7 @@ fileprivate enum TestJob: JobExecutor {
|
|||
}
|
||||
}
|
||||
|
||||
dependencies.asyncExecutions.appendTo(details.completeTime) {
|
||||
dependencies.async(at: details.completeTime) {
|
||||
queue.async(using: dependencies) {
|
||||
completeJob()
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
import Foundation
|
||||
import Combine
|
||||
import SessionSnodeKit
|
||||
|
||||
import Quick
|
||||
import Nimble
|
||||
|
@ -179,23 +178,20 @@ class BatchRequestSpec: QuickSpec {
|
|||
|
||||
// MARK: -- when encoding a storage server type endpoint
|
||||
context("when encoding a storage server type endpoint") {
|
||||
// MARK: ---- successfully encodes a SnodeRequest body
|
||||
it("successfully encodes a SnodeRequest body") {
|
||||
// MARK: ---- ignores a string body
|
||||
it("ignores a string body") {
|
||||
request = HTTP.BatchRequest(
|
||||
requestsKey: .requests,
|
||||
requests: [
|
||||
HTTP.PreparedRequest<NoResponse>(
|
||||
request: Request<SnodeRequest<TestType>, TestEndpoint2>(
|
||||
request: Request<String, TestEndpoint2>(
|
||||
method: .get,
|
||||
server: "testServer",
|
||||
endpoint: .endpoint2,
|
||||
queryParameters: [:],
|
||||
headers: [:],
|
||||
x25519PublicKey: "05\(TestConstants.publicKey)",
|
||||
body: SnodeRequest<TestType>(
|
||||
endpoint: .sendMessage,
|
||||
body: TestType(stringValue: "testValue")
|
||||
)
|
||||
body: "testValue"
|
||||
),
|
||||
urlRequest: URLRequest(url: URL(string: "https://www.oxen.io")!),
|
||||
responseType: NoResponse.self,
|
||||
|
@ -207,9 +203,70 @@ class BatchRequestSpec: QuickSpec {
|
|||
let requestData: Data? = try? JSONEncoder().encode(request)
|
||||
let requestJson: [String: [[String: Any]]]? = requestData
|
||||
.map { try? JSONSerialization.jsonObject(with: $0) as? [String: [[String: Any]]] }
|
||||
let request: [String: Any]? = requestJson?["requests"]?.first
|
||||
expect(request?["method"] as? String).to(equal("store"))
|
||||
expect(request?["params"] as? [String: String]).to(equal(["stringValue": "testValue"]))
|
||||
let requests: [[String: Any]]? = requestJson?["requests"]
|
||||
expect(requests?.count).to(equal(1))
|
||||
expect(requests?.first?.count).to(equal(0))
|
||||
}
|
||||
|
||||
// MARK: ---- ignores a byte body
|
||||
it("ignores a byte body") {
|
||||
request = HTTP.BatchRequest(
|
||||
requestsKey: .requests,
|
||||
requests: [
|
||||
HTTP.PreparedRequest<NoResponse>(
|
||||
request: Request<[UInt8], TestEndpoint2>(
|
||||
method: .get,
|
||||
server: "testServer",
|
||||
endpoint: .endpoint2,
|
||||
queryParameters: [:],
|
||||
headers: [:],
|
||||
x25519PublicKey: "05\(TestConstants.publicKey)",
|
||||
body: [1, 2, 3]
|
||||
),
|
||||
urlRequest: URLRequest(url: URL(string: "https://www.oxen.io")!),
|
||||
responseType: NoResponse.self,
|
||||
timeout: 0
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
let requestData: Data? = try? JSONEncoder().encode(request)
|
||||
let requestJson: [String: [[String: Any]]]? = requestData
|
||||
.map { try? JSONSerialization.jsonObject(with: $0) as? [String: [[String: Any]]] }
|
||||
let requests: [[String: Any]]? = requestJson?["requests"]
|
||||
expect(requests?.count).to(equal(1))
|
||||
expect(requests?.first?.count).to(equal(0))
|
||||
}
|
||||
|
||||
// MARK: ---- successfully encodes a JSON body
|
||||
it("successfully encodes a JSON body") {
|
||||
request = HTTP.BatchRequest(
|
||||
requestsKey: .requests,
|
||||
requests: [
|
||||
HTTP.PreparedRequest<NoResponse>(
|
||||
request: Request<TestType, TestEndpoint2>(
|
||||
method: .get,
|
||||
server: "testServer",
|
||||
endpoint: .endpoint2,
|
||||
queryParameters: [:],
|
||||
headers: [:],
|
||||
x25519PublicKey: "05\(TestConstants.publicKey)",
|
||||
body: TestType(stringValue: "testValue")
|
||||
),
|
||||
urlRequest: URLRequest(url: URL(string: "https://www.oxen.io")!),
|
||||
responseType: NoResponse.self,
|
||||
timeout: 0
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
let requestData: Data? = try? JSONEncoder().encode(request)
|
||||
let requestJson: [String: [[String: Any]]]? = requestData
|
||||
.map { try? JSONSerialization.jsonObject(with: $0) as? [String: [[String: Any]]] }
|
||||
let requests: [[String: Any]]? = requestJson?["requests"]
|
||||
expect(requests?.count).to(equal(1))
|
||||
expect(requests?.first as? [String: String])
|
||||
.to(equal(["stringValue": "testValue"]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,29 +12,29 @@ public class TestDependencies: Dependencies {
|
|||
|
||||
// MARK: - Subscript Access
|
||||
|
||||
override public subscript<S>(singleton singleton: SingletonInfo.Config<S>) -> S {
|
||||
override public subscript<S>(singleton singleton: SingletonConfig<S>) -> S {
|
||||
return getValueSettingIfNull(singleton: singleton, &singletonInstances)
|
||||
}
|
||||
|
||||
public subscript<S>(singleton singleton: SingletonInfo.Config<S>) -> S? {
|
||||
public subscript<S>(singleton singleton: SingletonConfig<S>) -> S? {
|
||||
get { return (singletonInstances[singleton.key] as? S) }
|
||||
set { singletonInstances[singleton.key] = newValue }
|
||||
}
|
||||
|
||||
override public subscript<M, I>(cache cache: CacheInfo.Config<M, I>) -> I {
|
||||
override public subscript<M, I>(cache cache: CacheConfig<M, I>) -> I {
|
||||
return getValueSettingIfNull(cache: cache, &cacheInstances)
|
||||
}
|
||||
|
||||
public subscript<M, I>(cache cache: CacheInfo.Config<M, I>) -> M? {
|
||||
public subscript<M, I>(cache cache: CacheConfig<M, I>) -> M? {
|
||||
get { return (cacheInstances[cache.key] as? M) }
|
||||
set { cacheInstances[cache.key] = newValue.map { cache.mutableInstance($0) } }
|
||||
}
|
||||
|
||||
override public subscript(defaults defaults: UserDefaultsInfo.Config) -> UserDefaultsType {
|
||||
override public subscript(defaults defaults: UserDefaultsConfig) -> UserDefaultsType {
|
||||
return getValueSettingIfNull(defaults: defaults, &defaultsInstances)
|
||||
}
|
||||
|
||||
public subscript(defaults defaults: UserDefaultsInfo.Config) -> UserDefaultsType? {
|
||||
public subscript(defaults defaults: UserDefaultsConfig) -> UserDefaultsType? {
|
||||
get { return defaultsInstances[defaults.key] }
|
||||
set { defaultsInstances[defaults.key] = newValue }
|
||||
}
|
||||
|
@ -52,6 +52,14 @@ public class TestDependencies: Dependencies {
|
|||
get { (_fixedTime.wrappedValue ?? 0) }
|
||||
set { _fixedTime.mutate { $0 = newValue } }
|
||||
}
|
||||
|
||||
public var _forceSynchronous: Bool = false
|
||||
override public var forceSynchronous: Bool {
|
||||
get { _forceSynchronous }
|
||||
set { _forceSynchronous = newValue }
|
||||
}
|
||||
|
||||
private var asyncExecutions: [Int: [() -> Void]] = [:]
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
|
@ -63,8 +71,12 @@ public class TestDependencies: Dependencies {
|
|||
|
||||
// MARK: - Functions
|
||||
|
||||
override public func async(at timestamp: TimeInterval, closure: @escaping () -> Void) {
|
||||
asyncExecutions.append(closure, toArrayOn: Int(ceil(timestamp)))
|
||||
}
|
||||
|
||||
@discardableResult override public func mutate<M, I, R>(
|
||||
cache: CacheInfo.Config<M, I>,
|
||||
cache: CacheConfig<M, I>,
|
||||
_ mutation: (inout M) -> R
|
||||
) -> R {
|
||||
var value: M = ((cacheInstances[cache.key] as? M) ?? cache.createInstance(self))
|
||||
|
@ -72,7 +84,7 @@ public class TestDependencies: Dependencies {
|
|||
}
|
||||
|
||||
@discardableResult override public func mutate<M, I, R>(
|
||||
cache: CacheInfo.Config<M, I>,
|
||||
cache: CacheConfig<M, I>,
|
||||
_ mutation: (inout M) throws -> R
|
||||
) throws -> R {
|
||||
var value: M = ((cacheInstances[cache.key] as? M) ?? cache.createInstance(self))
|
||||
|
@ -99,7 +111,7 @@ public class TestDependencies: Dependencies {
|
|||
// MARK: - Instance upserting
|
||||
|
||||
@discardableResult private func getValueSettingIfNull<S>(
|
||||
singleton: SingletonInfo.Config<S>,
|
||||
singleton: SingletonConfig<S>,
|
||||
_ store: inout [Int: Any]
|
||||
) -> S {
|
||||
guard let value: S = (store[singleton.key] as? S) else {
|
||||
|
@ -112,7 +124,7 @@ public class TestDependencies: Dependencies {
|
|||
}
|
||||
|
||||
@discardableResult private func getValueSettingIfNull<M, I>(
|
||||
cache: CacheInfo.Config<M, I>,
|
||||
cache: CacheConfig<M, I>,
|
||||
_ store: inout [Int: MutableCacheType]
|
||||
) -> I {
|
||||
guard let value: M = (store[cache.key] as? M) else {
|
||||
|
@ -126,7 +138,7 @@ public class TestDependencies: Dependencies {
|
|||
}
|
||||
|
||||
@discardableResult private func getValueSettingIfNull(
|
||||
defaults: UserDefaultsInfo.Config,
|
||||
defaults: UserDefaultsConfig,
|
||||
_ store: inout [Int: (any UserDefaultsType)]
|
||||
) -> UserDefaultsType {
|
||||
guard let value: UserDefaultsType = store[defaults.key] else {
|
||||
|
@ -144,7 +156,7 @@ public class TestDependencies: Dependencies {
|
|||
internal extension TestState {
|
||||
init<M, I>(
|
||||
wrappedValue: @escaping @autoclosure () -> T?,
|
||||
cache: CacheInfo.Config<M, I>,
|
||||
cache: CacheConfig<M, I>,
|
||||
in dependencies: @escaping @autoclosure () -> TestDependencies?
|
||||
) where T: MutableCacheType {
|
||||
self.init(wrappedValue: {
|
||||
|
@ -157,7 +169,7 @@ internal extension TestState {
|
|||
|
||||
init<S>(
|
||||
wrappedValue: @escaping @autoclosure () -> T?,
|
||||
singleton: SingletonInfo.Config<S>,
|
||||
singleton: SingletonConfig<S>,
|
||||
in dependencies: @escaping @autoclosure () -> TestDependencies?
|
||||
) {
|
||||
self.init(wrappedValue: {
|
||||
|
@ -170,7 +182,7 @@ internal extension TestState {
|
|||
|
||||
init(
|
||||
wrappedValue: @escaping @autoclosure () -> T?,
|
||||
defaults: UserDefaultsInfo.Config,
|
||||
defaults: UserDefaultsConfig,
|
||||
in dependencies: @escaping @autoclosure () -> TestDependencies?
|
||||
) where T: UserDefaultsType {
|
||||
self.init(wrappedValue: {
|
||||
|
|
Loading…
Reference in New Issue