diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index de45a8d13..23a2b7b0b 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -667,6 +667,10 @@ FD47E0C02AA83D7300A55E41 /* SwarmDrainBehaviour.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD47E0BF2AA83D7300A55E41 /* SwarmDrainBehaviour.swift */; }; FD4B200E283492210034334B /* InsetLockableTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD4B200D283492210034334B /* InsetLockableTableView.swift */; }; FD4C4E9C2B02E2A300C72199 /* DisplayPictureError.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD4C4E9B2B02E2A300C72199 /* DisplayPictureError.swift */; }; + FD4C4EA22B03093200C72199 /* GRDBExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD4C4E9F2B0308FD00C72199 /* GRDBExtensions.swift */; }; + FD4C4EA32B03093200C72199 /* GRDBExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD4C4E9F2B0308FD00C72199 /* GRDBExtensions.swift */; }; + FD4C4EA42B03093300C72199 /* GRDBExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD4C4E9F2B0308FD00C72199 /* GRDBExtensions.swift */; }; + FD4C4EA52B03093300C72199 /* GRDBExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD4C4E9F2B0308FD00C72199 /* GRDBExtensions.swift */; }; FD52090028AF6153006098F6 /* OWSBackgroundTask.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDC1B255A581F00E217F9 /* OWSBackgroundTask.m */; }; FD52090128AF61BA006098F6 /* OWSBackgroundTask.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB38255A580B00E217F9 /* OWSBackgroundTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; FD52090328B4680F006098F6 /* RadioButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD52090228B4680F006098F6 /* RadioButton.swift */; }; @@ -1888,6 +1892,7 @@ FD47E0BF2AA83D7300A55E41 /* SwarmDrainBehaviour.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwarmDrainBehaviour.swift; sourceTree = ""; }; FD4B200D283492210034334B /* InsetLockableTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsetLockableTableView.swift; sourceTree = ""; }; FD4C4E9B2B02E2A300C72199 /* DisplayPictureError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayPictureError.swift; sourceTree = ""; }; + FD4C4E9F2B0308FD00C72199 /* GRDBExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GRDBExtensions.swift; sourceTree = ""; }; FD52090228B4680F006098F6 /* RadioButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButton.swift; sourceTree = ""; }; FD52090428B4915F006098F6 /* PrivacySettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacySettingsViewModel.swift; sourceTree = ""; }; FD52090628B49738006098F6 /* ConfirmationModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmationModal.swift; sourceTree = ""; }; @@ -4328,6 +4333,7 @@ FDC290A727D9B46D005DAE71 /* NimbleExtensions.swift */, FD078E4727E02561000769AF /* CommonMockedExtensions.swift */, FD23EA6028ED0B260058676E /* CombineExtensions.swift */, + FD4C4E9F2B0308FD00C72199 /* GRDBExtensions.swift */, FD2AAAEF28ED57B500A49611 /* SynchronousStorage.swift */, ); path = _SharedTestUtilities; @@ -6771,6 +6777,7 @@ FD3FAB6C2AF1B28B00DC5421 /* MockFileManager.swift in Sources */, FD23EA6128ED0B260058676E /* CombineExtensions.swift in Sources */, FDFE75B32ABD469500655640 /* MockJobRunner.swift in Sources */, + FD4C4EA22B03093200C72199 /* GRDBExtensions.swift in Sources */, FD9DD2712A72516D00ECB68E /* TestExtensions.swift in Sources */, FD65318A2AA025C500DFEEAA /* TestDependencies.swift in Sources */, FD2AAAED28ED3E1000A49611 /* MockGeneralCache.swift in Sources */, @@ -6810,6 +6817,7 @@ FD0969FB2A6A00B100C5C365 /* Mocked.swift in Sources */, FDC290AA27D9B6FD005DAE71 /* Mock.swift in Sources */, FD2959902A43BE5F00888A17 /* VersionSpec.swift in Sources */, + FD4C4EA52B03093300C72199 /* GRDBExtensions.swift in Sources */, FDB947102A982EF2001F271A /* BatchRequestSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -6828,6 +6836,7 @@ FDB5DB092A981F8D002C8721 /* MockCrypto.swift in Sources */, FDAA167B2AC28E2F00DDBF77 /* SnodeRequestSpec.swift in Sources */, FD65318C2AA025C500DFEEAA /* TestDependencies.swift in Sources */, + FD4C4EA42B03093300C72199 /* GRDBExtensions.swift in Sources */, FDB5DB102A981FA3002C8721 /* TestConstants.swift in Sources */, FDB5DB0C2A981F96002C8721 /* MockNetwork.swift in Sources */, FDB5DB0F2A981FA1002C8721 /* MockJobRunner.swift in Sources */, @@ -6888,6 +6897,7 @@ FDC2908927D70656005DAE71 /* RoomPollInfoSpec.swift in Sources */, FDFD645D27F273F300808CA1 /* MockGeneralCache.swift in Sources */, FD3C906D27E43C4B00CD579F /* MessageSenderEncryptionSpec.swift in Sources */, + FD4C4EA32B03093200C72199 /* GRDBExtensions.swift in Sources */, FDC2908D27D70905005DAE71 /* UpdateMessageRequestSpec.swift in Sources */, FD078E5427E197CA000769AF /* OpenGroupManagerSpec.swift in Sources */, FD3C906727E416AF00CD579F /* BlindedIdLookupSpec.swift in Sources */, diff --git a/SessionMessagingKitTests/Jobs/DisplayPictureDownloadJobSpec.swift b/SessionMessagingKitTests/Jobs/DisplayPictureDownloadJobSpec.swift index dc5b041c6..18bf8283d 100644 --- a/SessionMessagingKitTests/Jobs/DisplayPictureDownloadJobSpec.swift +++ b/SessionMessagingKitTests/Jobs/DisplayPictureDownloadJobSpec.swift @@ -52,7 +52,13 @@ class DisplayPictureDownloadJobSpec: QuickSpec { network .when { $0.send( - .onionRequest(any(), to: any(), with: any(), timeout: FileServerAPI.fileDownloadTimeout) + .selectedNetworkRequest( + any(), + to: any(), + with: any(), + timeout: FileServerAPI.fileDownloadTimeout, + using: any() + ) ) } .thenReturn(MockNetwork.response(data: encryptedData)) @@ -522,13 +528,14 @@ class DisplayPictureDownloadJobSpec: QuickSpec { ) expect(mockNetwork) - .to(call(.exactly(times: 1), matchingParameters: .all) { network in + .to(call(.exactly(times: 1), matchingParameters: .all) { [dependencies = dependencies!] network in network.send( - .onionRequest( + .selectedNetworkRequest( expectedRequest, to: FileServerAPI.server, with: FileServerAPI.serverPublicKey, - timeout: FileServerAPI.fileDownloadTimeout + timeout: FileServerAPI.fileDownloadTimeout, + using: dependencies ) ) }) @@ -582,13 +589,14 @@ class DisplayPictureDownloadJobSpec: QuickSpec { ) expect(mockNetwork) - .to(call(.exactly(times: 1), matchingParameters: .all) { network in + .to(call(.exactly(times: 1), matchingParameters: .all) { [dependencies = dependencies!] network in network.send( - .onionRequest( + .selectedNetworkRequest( expectedRequest, to: "testserver", with: TestConstants.serverPublicKey, - timeout: FileServerAPI.fileDownloadTimeout + timeout: FileServerAPI.fileDownloadTimeout, + using: dependencies ) ) }) diff --git a/SessionMessagingKitTests/Jobs/MessageSendJobSpec.swift b/SessionMessagingKitTests/Jobs/MessageSendJobSpec.swift index f72aa8232..c6c9750fe 100644 --- a/SessionMessagingKitTests/Jobs/MessageSendJobSpec.swift +++ b/SessionMessagingKitTests/Jobs/MessageSendJobSpec.swift @@ -157,7 +157,7 @@ class MessageSendJobSpec: QuickSpec { mockStorage.write { db in try interaction.insert(db) - try job.insert(db) + try job.insert(db, withRowId: 54321) } } @@ -236,7 +236,7 @@ class MessageSendJobSpec: QuickSpec { ) ) ) - mockStorage.write { db in try job.insert(db) } + mockStorage.write { db in try job.insert(db, withRowId: 54321) } var error: Error? = nil var permanentFailure: Bool = false @@ -382,7 +382,7 @@ class MessageSendJobSpec: QuickSpec { shouldSkipLaunchBecomeActive: false, interactionId: 100, details: AttachmentUploadJob.Details( - messageSendJobId: 1, + messageSendJobId: 54321, attachmentId: "200" ) ), @@ -403,7 +403,7 @@ class MessageSendJobSpec: QuickSpec { ) expect(mockStorage.read { db in try JobDependencies.fetchOne(db) }) - .to(equal(JobDependencies(jobId: 9, dependantId: 1000))) + .to(equal(JobDependencies(jobId: 54321, dependantId: 1000))) } } } diff --git a/SessionMessagingKitTests/LibSessionUtil/LibSessionSpec.swift b/SessionMessagingKitTests/LibSessionUtil/LibSessionSpec.swift index 29c182a7d..d6ac75737 100644 --- a/SessionMessagingKitTests/LibSessionUtil/LibSessionSpec.swift +++ b/SessionMessagingKitTests/LibSessionUtil/LibSessionSpec.swift @@ -2138,7 +2138,7 @@ fileprivate extension LibSessionSpec { } // Check that the record count matches the maximum when we last checked - expect(numRecords).to(equal(288)) + expect(numRecords).to(equal(289)) } } @@ -2321,7 +2321,7 @@ fileprivate extension LibSessionSpec { defaultValue: [] ) expect(pushData2.pointee.seqno).to(equal(2)) - expect(pushData2.pointee.config_len).to(equal(768)) + expect(pushData2.pointee.config_len).to(equal(1024)) expect(obsoleteHashes).to(equal(["fakehash1"])) let fakeHash2: String = "fakehash2" @@ -2342,7 +2342,7 @@ fileprivate extension LibSessionSpec { expect(groups_members_get(conf, &member2, &cSessionId2)).to(beTrue()) expect(String(libSessionVal: member2.name)).to(equal("Member 23")) - expect(groups_members_size(conf)).to(equal(62)) + expect(groups_members_size(conf)).to(equal(66)) (0..<62).forEach { index in var cSessionId: [CChar] = sids[index].cArray @@ -2515,7 +2515,7 @@ fileprivate extension LibSessionSpec { mergeHashes3.forEach { $0?.deallocate() } mergedHashes3?.deallocate() - expect(groups_members_size(conf2)).to(equal(44)) // 18 deleted earlier + expect(groups_members_size(conf2)).to(equal(48)) // 18 deleted earlier (0..<66).forEach { index in var cSessionId: [CChar] = sids[index].cArray @@ -2761,7 +2761,7 @@ fileprivate extension LibSessionSpec { // FIXME: Would be good to move these into the libSession-util instead of using Sodium separately let identity = try! Identity.generate(from: userSeed) let keyPair: KeyPair = Crypto().generate(.ed25519KeyPair(seed: seed))! - var userEdSK: [UInt8] = identity.ed25519KeyPair.secretKey + let userEdSK: [UInt8] = identity.ed25519KeyPair.secretKey var edPK: [UInt8] = keyPair.publicKey var edSK: [UInt8] = keyPair.secretKey diff --git a/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift b/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift index 94aca4a67..90b2cda1f 100644 --- a/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift +++ b/SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift @@ -464,7 +464,7 @@ class OpenGroupAPISpec: QuickSpec { // MARK: ---- processes a valid response correctly it("processes a valid response correctly") { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(HTTP.BatchResponse.mockCapabilitiesAndRoomResponse) var response: (info: ResponseInfoType, data: OpenGroupAPI.CapabilitiesAndRoomResponse)? @@ -493,7 +493,7 @@ class OpenGroupAPISpec: QuickSpec { // MARK: ------ errors when not given a room response it("errors when not given a room response") { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(HTTP.BatchResponse.mockCapabilitiesAndBanResponse) var response: (info: ResponseInfoType, data: OpenGroupAPI.CapabilitiesAndRoomResponse)? @@ -519,7 +519,7 @@ class OpenGroupAPISpec: QuickSpec { // MARK: ------ errors when not given a capabilities response it("errors when not given a capabilities response") { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(HTTP.BatchResponse.mockBanAndRoomResponse) var response: (info: ResponseInfoType, data: OpenGroupAPI.CapabilitiesAndRoomResponse)? @@ -569,7 +569,7 @@ class OpenGroupAPISpec: QuickSpec { // MARK: ---- processes a valid response correctly it("processes a valid response correctly") { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(HTTP.BatchResponse.mockCapabilitiesAndRoomsResponse) var response: (info: ResponseInfoType, data: OpenGroupAPI.CapabilitiesAndRoomsResponse)? @@ -597,7 +597,7 @@ class OpenGroupAPISpec: QuickSpec { // MARK: ------ errors when not given a room response it("errors when not given a room response") { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(HTTP.BatchResponse.mockCapabilitiesAndBanResponse) var response: (info: ResponseInfoType, data: OpenGroupAPI.CapabilitiesAndRoomsResponse)? @@ -622,7 +622,7 @@ class OpenGroupAPISpec: QuickSpec { // MARK: ------ errors when not given a capabilities response it("errors when not given a capabilities response") { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(HTTP.BatchResponse.mockBanAndRoomsResponse) var response: (info: ResponseInfoType, data: OpenGroupAPI.CapabilitiesAndRoomsResponse)? diff --git a/SessionMessagingKitTests/Open Groups/OpenGroupManagerSpec.swift b/SessionMessagingKitTests/Open Groups/OpenGroupManagerSpec.swift index fc90919cd..aab39b100 100644 --- a/SessionMessagingKitTests/Open Groups/OpenGroupManagerSpec.swift +++ b/SessionMessagingKitTests/Open Groups/OpenGroupManagerSpec.swift @@ -729,7 +729,7 @@ class OpenGroupManagerSpec: QuickSpec { } mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(HTTP.BatchResponse.mockCapabilitiesAndRoomResponse) mockOGMCache.when { $0.pollers }.thenReturn([:]) @@ -875,7 +875,7 @@ class OpenGroupManagerSpec: QuickSpec { context("with an invalid response") { beforeEach { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(MockNetwork.response(data: Data())) mockUserDefaults @@ -2781,7 +2781,7 @@ class OpenGroupManagerSpec: QuickSpec { context("when getting the default rooms if needed") { beforeEach { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(HTTP.BatchResponse.mockCapabilitiesAndRoomsResponse) mockStorage.write { db in @@ -2894,7 +2894,7 @@ class OpenGroupManagerSpec: QuickSpec { // MARK: ---- will retry fetching rooms 8 times before it fails it("will retry fetching rooms 8 times before it fails") { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(MockNetwork.nullResponse()) var error: Error? @@ -2905,13 +2905,15 @@ class OpenGroupManagerSpec: QuickSpec { expect(error).to(matchError(HTTPError.parsingFailed)) expect(mockNetwork) // First attempt + 8 retries - .to(call(.exactly(times: 9)) { $0.send(.onionRequest(any(), to: any(), with: any())) }) + .to(call(.exactly(times: 9)) { [dependencies = dependencies!] network in + network.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: dependencies)) + }) } // MARK: ---- removes the cache publisher if all retries fail it("removes the cache publisher if all retries fail") { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(MockNetwork.nullResponse()) var error: Error? @@ -2932,10 +2934,11 @@ class OpenGroupManagerSpec: QuickSpec { it("schedules jobs to download any room images") { mockNetwork .when { - $0.send(.onionRequest( + $0.send(.selectedNetworkRequest( URLRequest(url: URL(string: "https://open.getsession.org/sequence")!), to: OpenGroupAPI.defaultServer, - with: OpenGroupAPI.defaultServerPublicKey + with: OpenGroupAPI.defaultServerPublicKey, + using: dependencies )) } .thenReturn( diff --git a/SessionMessagingKitTests/Sending & Receiving/MessageReceiverSpec.swift b/SessionMessagingKitTests/Sending & Receiving/MessageReceiverSpec.swift index 9af12eadb..88784e1fd 100644 --- a/SessionMessagingKitTests/Sending & Receiving/MessageReceiverSpec.swift +++ b/SessionMessagingKitTests/Sending & Receiving/MessageReceiverSpec.swift @@ -14,7 +14,9 @@ class MessageReceiverSpec: QuickSpec { override class func spec() { // MARK: Configuration - @TestState var dependencies: TestDependencies! = TestDependencies() + @TestState var dependencies: TestDependencies! = TestDependencies { dependencies in + dependencies[feature: .updatedDisappearingMessages] = true + } @TestState(singleton: .storage, in: dependencies) var mockStorage: Storage! = SynchronousStorage( customWriter: try! DatabaseQueue(), migrationTargets: [ diff --git a/SessionMessagingKitTests/Sending & Receiving/MessageSenderGroupsSpec.swift b/SessionMessagingKitTests/Sending & Receiving/MessageSenderGroupsSpec.swift index 3bf5984e4..0a4c06aa1 100644 --- a/SessionMessagingKitTests/Sending & Receiving/MessageSenderGroupsSpec.swift +++ b/SessionMessagingKitTests/Sending & Receiving/MessageSenderGroupsSpec.swift @@ -50,7 +50,7 @@ class MessageSenderGroupsSpec: QuickSpec { @TestState(singleton: .network, in: dependencies) var mockNetwork: MockNetwork! = MockNetwork( initialSetup: { network in network - .when { $0.send(.onionRequest(any(), to: any(), timeout: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), timeout: any(), using: any())) } .thenReturn(HTTP.BatchResponse.mockConfigSyncResponse) } ) @@ -376,12 +376,13 @@ class MessageSenderGroupsSpec: QuickSpec { .sinkAndStore(in: &disposables) expect(mockNetwork) - .to(call(.exactly(times: 1), matchingParameters: .all) { network in + .to(call(.exactly(times: 1), matchingParameters: .all) { [dependencies = dependencies!] network in network.send( - .onionRequest( + .selectedNetworkRequest( expectedSendData, to: dependencies.randomElement(mockSwarmCache)!, - timeout: HTTP.defaultTimeout + timeout: HTTP.defaultTimeout, + using: dependencies ) ) }) @@ -391,7 +392,7 @@ class MessageSenderGroupsSpec: QuickSpec { context("and the group configuration sync fails") { beforeEach { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), timeout: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), timeout: any(), using: any())) } .thenReturn(MockNetwork.errorResponse()) } diff --git a/SessionSnodeKitTests/Networking/PreparedRequestOnionRequestsSpec.swift b/SessionSnodeKitTests/Networking/PreparedRequestOnionRequestsSpec.swift index 32aed8150..3e253ec2e 100644 --- a/SessionSnodeKitTests/Networking/PreparedRequestOnionRequestsSpec.swift +++ b/SessionSnodeKitTests/Networking/PreparedRequestOnionRequestsSpec.swift @@ -42,7 +42,7 @@ class PreparedRequestOnionRequestsSpec: QuickSpec { context("when sending") { beforeEach { mockNetwork - .when { $0.send(.onionRequest(any(), to: any(), with: any())) } + .when { $0.send(.selectedNetworkRequest(any(), to: any(), with: any(), using: any())) } .thenReturn(MockNetwork.response(with: 1)) } diff --git a/SessionTests/Conversations/Settings/ThreadDisappearingMessagesViewModelSpec.swift b/SessionTests/Conversations/Settings/ThreadDisappearingMessagesViewModelSpec.swift index b8b2a4af2..491db7803 100644 --- a/SessionTests/Conversations/Settings/ThreadDisappearingMessagesViewModelSpec.swift +++ b/SessionTests/Conversations/Settings/ThreadDisappearingMessagesViewModelSpec.swift @@ -17,6 +17,7 @@ class ThreadDisappearingMessagesSettingsViewModelSpec: QuickSpec { @TestState var dependencies: TestDependencies! = TestDependencies { dependencies in dependencies.forceSynchronous = true dependencies[singleton: .scheduler] = .immediate + dependencies[feature: .updatedDisappearingMessages] = true } @TestState(singleton: .storage, in: dependencies) var mockStorage: Storage! = SynchronousStorage( customWriter: try! DatabaseQueue(), diff --git a/_SharedTestUtilities/GRDBExtensions.swift b/_SharedTestUtilities/GRDBExtensions.swift new file mode 100644 index 000000000..1a84f88b1 --- /dev/null +++ b/_SharedTestUtilities/GRDBExtensions.swift @@ -0,0 +1,14 @@ +// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved. + +import Foundation + +@testable import GRDB + +public extension MutablePersistableRecord { + /// This is a test method which allows for inserting with a pre-defined id (it triggers the `didInsert` function directly before inserting which + /// is likely to cause problems with other tests if we ever use it for anything other than assigning the `id`) + mutating func insert(_ db: Database, withRowId rowID: Int64) throws { + didInsert(InsertionSuccess(rowID: rowID, rowIDColumn: nil, persistenceContainer: PersistenceContainer())) + try insert(db) + } +} diff --git a/_SharedTestUtilities/Mock.swift b/_SharedTestUtilities/Mock.swift index e8de08e71..2b8a64039 100644 --- a/_SharedTestUtilities/Mock.swift +++ b/_SharedTestUtilities/Mock.swift @@ -393,7 +393,7 @@ internal class FunctionConsumer: MockFunctionHandler { allParameterSummaryCombinations: allParameterSummaryCombinations, actionArgs: actionArgs ) -// TODO: If 'Output' is optional and there is no 'returnValue' then just return 'nil' + return (expectation.returnValue as! Output) } diff --git a/_SharedTestUtilities/TestDependencies.swift b/_SharedTestUtilities/TestDependencies.swift index 15fdf75aa..1930f4bcb 100644 --- a/_SharedTestUtilities/TestDependencies.swift +++ b/_SharedTestUtilities/TestDependencies.swift @@ -9,6 +9,7 @@ public class TestDependencies: Dependencies { private var singletonInstances: [String: Any] = [:] private var cacheInstances: [String: MutableCacheType] = [:] private var defaultsInstances: [String: (any UserDefaultsType)] = [:] + private var featureInstances: [String: (any FeatureType)] = [:] private var mockedValues: [Int: Any] = [:] // MARK: - Subscript Access @@ -54,6 +55,27 @@ public class TestDependencies: Dependencies { return value } + override public subscript(feature feature: FeatureConfig) -> T { + guard let value: Feature = (featureInstances[feature.identifier] as? Feature) else { + let value: Feature = feature.createInstance(self) + featureInstances[feature.identifier] = value + return value.currentValue(using: self) + } + + return value.currentValue(using: self) + } + + public subscript(feature feature: FeatureConfig) -> T? { + get { return (featureInstances[feature.identifier] as? T) } + set { + if featureInstances[feature.identifier] == nil { + featureInstances[feature.identifier] = feature.createInstance(self) + } + + set(feature: feature, to: newValue) + } + } + public subscript(defaults defaults: UserDefaultsConfig) -> UserDefaultsType? { get { return defaultsInstances[defaults.identifier] } set { defaultsInstances[defaults.identifier] = newValue }