diff --git a/Passepartout.xcodeproj/project.pbxproj b/Passepartout.xcodeproj/project.pbxproj index a39930b0..48e5fb8c 100644 --- a/Passepartout.xcodeproj/project.pbxproj +++ b/Passepartout.xcodeproj/project.pbxproj @@ -16,6 +16,8 @@ 0E483E812CE64D6B00584B32 /* Shared+Tunnel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E483E7F2CE64D6B00584B32 /* Shared+Tunnel.swift */; }; 0E483E842CE6501100584B32 /* Shared+App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E483E822CE6501100584B32 /* Shared+App.swift */; }; 0E60512C2CE5393C00F763D4 /* PassepartoutImplementations in Frameworks */ = {isa = PBXBuildFile; productRef = 0E60512B2CE5393C00F763D4 /* PassepartoutImplementations */; }; + 0E6EEEE32CF8CABA0076E2B0 /* AppContext+Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6EEEE12CF8CABA0076E2B0 /* AppContext+Testing.swift */; }; + 0E6EEEE42CF8CABA0076E2B0 /* ProfileManager+Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6EEEE22CF8CABA0076E2B0 /* ProfileManager+Testing.swift */; }; 0E757F132CD0CFFC006E13E1 /* PassepartoutLoginItemApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E757F122CD0CFFC006E13E1 /* PassepartoutLoginItemApp.swift */; }; 0E757F202CD0D22B006E13E1 /* PassepartoutLoginItem.app in Embed Login Item */ = {isa = PBXBuildFile; fileRef = 0E757F102CD0CFFC006E13E1 /* PassepartoutLoginItem.app */; platformFilters = (macos, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 0E757F232CD0D2BD006E13E1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E757F212CD0D2B7006E13E1 /* AppDelegate.swift */; }; @@ -134,6 +136,8 @@ 0E483E7F2CE64D6B00584B32 /* Shared+Tunnel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Shared+Tunnel.swift"; sourceTree = ""; }; 0E483E822CE6501100584B32 /* Shared+App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Shared+App.swift"; sourceTree = ""; }; 0E5DFDDC2CDB8F9100F2DE70 /* Passepartout.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = Passepartout.storekit; sourceTree = ""; }; + 0E6EEEE12CF8CABA0076E2B0 /* AppContext+Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppContext+Testing.swift"; sourceTree = ""; }; + 0E6EEEE22CF8CABA0076E2B0 /* ProfileManager+Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProfileManager+Testing.swift"; sourceTree = ""; }; 0E757F102CD0CFFC006E13E1 /* PassepartoutLoginItem.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PassepartoutLoginItem.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0E757F122CD0CFFC006E13E1 /* PassepartoutLoginItemApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassepartoutLoginItemApp.swift; sourceTree = ""; }; 0E757F182CD0CFFD006E13E1 /* LoginItem.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LoginItem.entitlements; sourceTree = ""; }; @@ -277,6 +281,15 @@ path = Resources; sourceTree = ""; }; + 0E6EEEE62CF8CB090076E2B0 /* Testing */ = { + isa = PBXGroup; + children = ( + 0E6EEEE12CF8CABA0076E2B0 /* AppContext+Testing.swift */, + 0E6EEEE22CF8CABA0076E2B0 /* ProfileManager+Testing.swift */, + ); + path = Testing; + sourceTree = ""; + }; 0E757F112CD0CFFC006E13E1 /* LoginItem */ = { isa = PBXGroup; children = ( @@ -323,6 +336,7 @@ 0E7E3D612B9345FD002BBDB4 /* Shared */ = { isa = PBXGroup; children = ( + 0E6EEEE62CF8CB090076E2B0 /* Testing */, 0EC797402B9378E000C093B7 /* AppContext+Shared.swift */, 0EC797412B9378E000C093B7 /* Shared.swift */, 0E483E822CE6501100584B32 /* Shared+App.swift */, @@ -673,6 +687,8 @@ 0E7E3D6B2B9345FD002BBDB4 /* PassepartoutApp.swift in Sources */, 0EC797422B9378E000C093B7 /* AppContext+Shared.swift in Sources */, 0EE8D7E12CD112C200F6600C /* App+tvOS.swift in Sources */, + 0E6EEEE32CF8CABA0076E2B0 /* AppContext+Testing.swift in Sources */, + 0E6EEEE42CF8CABA0076E2B0 /* ProfileManager+Testing.swift in Sources */, 0E483E842CE6501100584B32 /* Shared+App.swift in Sources */, 0EC797432B9378E000C093B7 /* Shared.swift in Sources */, ); diff --git a/Passepartout/App/AppDelegate.swift b/Passepartout/App/AppDelegate.swift index 71f72c4f..37f04089 100644 --- a/Passepartout/App/AppDelegate.swift +++ b/Passepartout/App/AppDelegate.swift @@ -32,9 +32,9 @@ import UITesting @MainActor final class AppDelegate: NSObject { let context: AppContext = { - guard !AppCommandLine.contains(.uiTesting) else { + if AppCommandLine.contains(.uiTesting) { pp_log(.app, .info, "UI tests: mock AppContext") - return .mock(withRegistry: .shared) + return .forUITesting(withRegistry: .shared) } return .shared }() diff --git a/Passepartout/Library/.swiftpm/xcode/xcshareddata/xcschemes/Library-Package.xcscheme b/Passepartout/Library/.swiftpm/xcode/xcshareddata/xcschemes/Library-Package.xcscheme index d7706a69..fca74069 100644 --- a/Passepartout/Library/.swiftpm/xcode/xcshareddata/xcschemes/Library-Package.xcscheme +++ b/Passepartout/Library/.swiftpm/xcode/xcshareddata/xcschemes/Library-Package.xcscheme @@ -133,6 +133,20 @@ ReferencedContainer = "container:"> + + + + ProfilePreview - private nonisolated let _verify: (IAPManager, Profile) -> Set? + private nonisolated let _requiredFeatures: (IAPManager, Profile) -> Set? private nonisolated let _willRebuild: (IAPManager, Profile.Builder) throws -> Profile.Builder @@ -46,7 +46,7 @@ public final class InAppProcessor: ObservableObject, Sendable { title: @escaping (Profile) -> String, isIncluded: @escaping (IAPManager, Profile) -> Bool, preview: @escaping (Profile) -> ProfilePreview, - verify: @escaping (IAPManager, Profile) -> Set?, + requiredFeatures: @escaping (IAPManager, Profile) -> Set?, willRebuild: @escaping (IAPManager, Profile.Builder) throws -> Profile.Builder, willInstall: @escaping (IAPManager, Profile) throws -> Profile ) { @@ -54,7 +54,7 @@ public final class InAppProcessor: ObservableObject, Sendable { _title = title _isIncluded = isIncluded _preview = preview - _verify = verify + _requiredFeatures = requiredFeatures _willRebuild = willRebuild _willInstall = willInstall } @@ -75,8 +75,8 @@ extension InAppProcessor: ProfileProcessor { _preview(profile) } - public func verify(_ profile: Profile) -> Set? { - _verify(iapManager, profile) + public func requiredFeatures(_ profile: Profile) -> Set? { + _requiredFeatures(iapManager, profile) } public func willRebuild(_ builder: Profile.Builder) throws -> Profile.Builder { diff --git a/Passepartout/Library/Sources/CommonLibrary/Strategy/ProfileProcessor.swift b/Passepartout/Library/Sources/CommonLibrary/Strategy/ProfileProcessor.swift index ce1753df..01b8ee97 100644 --- a/Passepartout/Library/Sources/CommonLibrary/Strategy/ProfileProcessor.swift +++ b/Passepartout/Library/Sources/CommonLibrary/Strategy/ProfileProcessor.swift @@ -31,7 +31,7 @@ public protocol ProfileProcessor { func preview(from profile: Profile) -> ProfilePreview - func willRebuild(_ builder: Profile.Builder) throws -> Profile.Builder + func requiredFeatures(_ profile: Profile) -> Set? - func verify(_ profile: Profile) -> Set? + func willRebuild(_ builder: Profile.Builder) throws -> Profile.Builder } diff --git a/Passepartout/Library/Sources/UILibrary/Extensions/View+Environment.swift b/Passepartout/Library/Sources/UILibrary/Extensions/View+Environment.swift index 9bca78c0..04a2c08a 100644 --- a/Passepartout/Library/Sources/UILibrary/Extensions/View+Environment.swift +++ b/Passepartout/Library/Sources/UILibrary/Extensions/View+Environment.swift @@ -36,8 +36,8 @@ extension View { public func withMockEnvironment() -> some View { task { - try? await AppContext.mock.profileManager.observeLocal() + try? await AppContext.forPreviews.profileManager.observeLocal() } - .withEnvironment(from: .mock, theme: Theme()) + .withEnvironment(from: .forPreviews, theme: Theme()) } } diff --git a/Passepartout/Library/Sources/UILibrary/Mock/AppContext+Mock.swift b/Passepartout/Library/Sources/UILibrary/Previews/AppContext+Previews.swift similarity index 76% rename from Passepartout/Library/Sources/UILibrary/Mock/AppContext+Mock.swift rename to Passepartout/Library/Sources/UILibrary/Previews/AppContext+Previews.swift index 2c2b6e45..40a003ab 100644 --- a/Passepartout/Library/Sources/UILibrary/Mock/AppContext+Mock.swift +++ b/Passepartout/Library/Sources/UILibrary/Previews/AppContext+Previews.swift @@ -1,5 +1,5 @@ // -// AppContext+Mock.swift +// AppContext+Previews.swift // Passepartout // // Created by Davide De Rosa on 6/22/24. @@ -23,25 +23,18 @@ // along with Passepartout. If not, see . // -import Combine import CommonLibrary import CommonUtils import Foundation import PassepartoutKit extension AppContext { - public static let mock: AppContext = .mock(withRegistry: Registry()) - - public static func mock(withRegistry registry: Registry) -> AppContext { + public static let forPreviews: AppContext = { let iapManager = IAPManager( customUserLevel: .subscriber, inAppHelper: FakeAppProductHelper(), receiptReader: FakeAppReceiptReader(), betaChecker: TestFlightChecker(), - unrestrictedFeatures: [ - .interactiveLogin, - .onDemand - ], productsAtBuild: { _ in [] } @@ -57,17 +50,23 @@ extension AppContext { preview: { $0.localizedPreview }, - verify: { _, _ in + requiredFeatures: { _, _ in nil }, willRebuild: { _, builder in builder }, willInstall: { _, profile in - try profile.withProviderModules() + profile } ) - let profileManager: ProfileManager = .mock(withRegistry: registry, processor: processor) + let profileManager = { + let profiles: [Profile] = (0..<20) + .reduce(into: []) { list, _ in + list.append(.newMockProfile()) + } + return ProfileManager(profiles: profiles) + }() let tunnelEnvironment = InMemoryEnvironment() let tunnel = ExtendedTunnel( tunnel: Tunnel(strategy: FakeTunnelStrategy(environment: tunnelEnvironment)), @@ -84,35 +83,35 @@ extension AppContext { migrationManager: migrationManager, profileManager: profileManager, providerManager: providerManager, - registry: registry, + registry: Registry(), tunnel: tunnel, tunnelReceiptURL: BundleConfiguration.urlForBetaReceipt ) - } + }() } // MARK: - Shortcuts extension IAPManager { - public static var mock: IAPManager { - AppContext.mock.iapManager + public static var forPreviews: IAPManager { + AppContext.forPreviews.iapManager } } extension ProfileManager { - public static var mock: ProfileManager { - AppContext.mock.profileManager + public static var forPreviews: ProfileManager { + AppContext.forPreviews.profileManager } } extension ExtendedTunnel { - public static var mock: ExtendedTunnel { - AppContext.mock.tunnel + public static var forPreviews: ExtendedTunnel { + AppContext.forPreviews.tunnel } } extension ProviderManager { - public static var mock: ProviderManager { - AppContext.mock.providerManager + public static var forPreviews: ProviderManager { + AppContext.forPreviews.providerManager } } diff --git a/Passepartout/Library/Sources/UILibrary/Mock/Profile+Mock.swift b/Passepartout/Library/Sources/UILibrary/Previews/Profile+Previews.swift similarity index 94% rename from Passepartout/Library/Sources/UILibrary/Mock/Profile+Mock.swift rename to Passepartout/Library/Sources/UILibrary/Previews/Profile+Previews.swift index 790e6723..82ed43ff 100644 --- a/Passepartout/Library/Sources/UILibrary/Mock/Profile+Mock.swift +++ b/Passepartout/Library/Sources/UILibrary/Previews/Profile+Previews.swift @@ -1,5 +1,5 @@ // -// Profile+Mock.swift +// Profile+Previews.swift // Passepartout // // Created by Davide De Rosa on 11/4/24. @@ -27,7 +27,7 @@ import Foundation import PassepartoutKit extension Profile { - public static let mock: Profile = { + public static let forPreviews: Profile = { var profile = Profile.Builder() profile.name = "Mock profile" do { @@ -63,7 +63,7 @@ extension Profile { public static func newMockProfile(withName name: String? = nil) -> Profile { do { - var copy = mock.builder(withNewId: true) + var copy = forPreviews.builder(withNewId: true) copy.name = name ?? String(copy.id.uuidString.prefix(8)) return try copy.tryBuild() } catch { diff --git a/Passepartout/Library/Sources/UILibrary/Views/UI/ConnectionStatusText.swift b/Passepartout/Library/Sources/UILibrary/Views/UI/ConnectionStatusText.swift index 1ce01b67..5d9a22d1 100644 --- a/Passepartout/Library/Sources/UILibrary/Views/UI/ConnectionStatusText.swift +++ b/Passepartout/Library/Sources/UILibrary/Views/UI/ConnectionStatusText.swift @@ -76,9 +76,9 @@ private extension ConnectionStatusText { } #Preview("Connected") { - ConnectionStatusText(tunnel: .mock) + ConnectionStatusText(tunnel: .forPreviews) .task { - try? await ExtendedTunnel.mock.connect(with: .mock) + try? await ExtendedTunnel.forPreviews.connect(with: .forPreviews) } .frame(width: 100, height: 100) .withMockEnvironment() @@ -95,9 +95,9 @@ private extension ConnectionStatusText { } catch { fatalError() } - return ConnectionStatusText(tunnel: .mock) + return ConnectionStatusText(tunnel: .forPreviews) .task { - try? await ExtendedTunnel.mock.connect(with: profile) + try? await ExtendedTunnel.forPreviews.connect(with: profile) } .frame(width: 100, height: 100) .withMockEnvironment() diff --git a/Passepartout/Library/Tests/CommonLibraryTests/Mock/MockProfileProcessor.swift b/Passepartout/Library/Tests/CommonLibraryTests/Mock/MockProfileProcessor.swift index dec161a2..9923a1a8 100644 --- a/Passepartout/Library/Tests/CommonLibraryTests/Mock/MockProfileProcessor.swift +++ b/Passepartout/Library/Tests/CommonLibraryTests/Mock/MockProfileProcessor.swift @@ -30,14 +30,14 @@ import PassepartoutKit final class MockProfileProcessor: ProfileProcessor { var isIncludedCount = 0 - var willRebuildCount = 0 - - var verifyCount = 0 - var isIncludedBlock: (Profile) -> Bool = { _ in true } + var requiredFeaturesCount = 0 + var requiredFeatures: Set? + var willRebuildCount = 0 + func title(for profile: Profile) -> String { profile.name } @@ -51,13 +51,13 @@ final class MockProfileProcessor: ProfileProcessor { ProfilePreview(profile) } + func requiredFeatures(_ profile: Profile) -> Set? { + requiredFeaturesCount += 1 + return requiredFeatures + } + func willRebuild(_ builder: Profile.Builder) throws -> Profile.Builder { willRebuildCount += 1 return builder } - - func verify(_ profile: Profile) -> Set? { - verifyCount += 1 - return requiredFeatures - } } diff --git a/Passepartout/Library/Tests/CommonLibraryTests/ProfileManagerTests.swift b/Passepartout/Library/Tests/CommonLibraryTests/ProfileManagerTests.swift index 8f66a525..0a9cb1b3 100644 --- a/Passepartout/Library/Tests/CommonLibraryTests/ProfileManagerTests.swift +++ b/Passepartout/Library/Tests/CommonLibraryTests/ProfileManagerTests.swift @@ -100,8 +100,8 @@ extension ProfileManagerTests { XCTAssertTrue(sut.isReady) XCTAssertEqual(processor.isIncludedCount, 1) + XCTAssertEqual(processor.requiredFeaturesCount, 1) XCTAssertEqual(processor.willRebuildCount, 0) - XCTAssertEqual(processor.verifyCount, 1) XCTAssertEqual(sut.requiredFeatures(forProfileWithId: profile.id), processor.requiredFeatures) } diff --git a/Passepartout/Shared/AppContext+Shared.swift b/Passepartout/Shared/AppContext+Shared.swift index 45f28d27..66953238 100644 --- a/Passepartout/Shared/AppContext+Shared.swift +++ b/Passepartout/Shared/AppContext+Shared.swift @@ -38,6 +38,10 @@ import UITesting extension AppContext { static let shared: AppContext = { + let iapManager: IAPManager = .sharedForApp + let processor = InAppProcessor.shared(iapManager) { + $0.localizedPreview + } // MARK: ProfileManager @@ -65,7 +69,7 @@ extension AppContext { backupRepository: Configuration.ProfileManager.backupProfileRepository, remoteRepositoryBlock: remoteRepositoryBlock, mirrorsRemoteRepository: Configuration.ProfileManager.mirrorsRemoteRepository, - processor: IAPManager.sharedProcessor + processor: processor ) }() @@ -74,7 +78,7 @@ extension AppContext { let tunnel = ExtendedTunnel( tunnel: Tunnel(strategy: Configuration.ExtendedTunnel.strategy), environment: .shared, - processor: IAPManager.sharedProcessor, + processor: processor, interval: Constants.shared.tunnel.refreshInterval ) @@ -118,7 +122,7 @@ extension AppContext { let migrationManager = MigrationManager(profileStrategy: profileStrategy, simulation: migrationSimulation) return AppContext( - iapManager: .sharedForApp, + iapManager: iapManager, migrationManager: migrationManager, profileManager: profileManager, providerManager: providerManager, diff --git a/Passepartout/Shared/Shared+App.swift b/Passepartout/Shared/Shared+App.swift index cb6eda36..52c95ca2 100644 --- a/Passepartout/Shared/Shared+App.swift +++ b/Passepartout/Shared/Shared+App.swift @@ -37,44 +37,6 @@ extension IAPManager { betaChecker: Configuration.IAPManager.betaChecker, productsAtBuild: Configuration.IAPManager.productsAtBuild ) - - static let sharedProcessor = InAppProcessor( - iapManager: sharedForApp, - title: { - Configuration.ProfileManager.sharedTitle($0) - }, - isIncluded: { - Configuration.ProfileManager.isIncluded($0, $1) - }, - preview: { - $0.localizedPreview - }, - verify: { iap, profile in - do { - try iap.verify(profile) - return nil - } catch AppError.ineligibleProfile(let requiredFeatures) { - return requiredFeatures - } catch { - return nil - } - }, - willRebuild: { _, builder in - builder - }, - willInstall: { iap, profile in - try iap.verify(profile) - - // validate provider modules - do { - _ = try profile.withProviderModules() - return profile - } catch { - pp_log(.app, .error, "Unable to inject provider modules: \(error)") - throw error - } - } - ) } // MARK: - Configuration @@ -90,7 +52,7 @@ private extension Configuration.IAPManager { @MainActor static let simulatedInAppHelper: any AppProductHelper = { - guard !AppCommandLine.contains(.fakeIAP) else { + if AppCommandLine.contains(.fakeIAP) { return FakeAppProductHelper() } return inAppHelper @@ -98,7 +60,7 @@ private extension Configuration.IAPManager { @MainActor static var simulatedAppReceiptReader: AppReceiptReader { - guard !AppCommandLine.contains(.fakeIAP) else { + if AppCommandLine.contains(.fakeIAP) { guard let mockHelper = inAppHelper as? FakeAppProductHelper else { fatalError("When .isFakeIAP, productHelper is expected to be MockAppProductHelper") } diff --git a/Passepartout/Shared/Shared.swift b/Passepartout/Shared/Shared.swift index b0487c6d..84e9c961 100644 --- a/Passepartout/Shared/Shared.swift +++ b/Passepartout/Shared/Shared.swift @@ -89,6 +89,50 @@ extension TunnelEnvironment where Self == AppGroupEnvironment { } } +// MARK: InAppProcessor + +extension InAppProcessor { + + @MainActor + static func shared(_ iapManager: IAPManager, preview: @escaping (Profile) -> ProfilePreview) -> InAppProcessor { + InAppProcessor( + iapManager: iapManager, + title: { + Configuration.ProfileManager.sharedTitle($0) + }, + isIncluded: { + Configuration.ProfileManager.isIncluded($0, $1) + }, + preview: preview, + requiredFeatures: { iap, profile in + do { + try iap.verify(profile) + return nil + } catch AppError.ineligibleProfile(let requiredFeatures) { + return requiredFeatures + } catch { + return nil + } + }, + willRebuild: { _, builder in + builder + }, + willInstall: { iap, profile in + try iap.verify(profile) + + // validate provider modules + do { + _ = try profile.withProviderModules() + return profile + } catch { + pp_log(.app, .error, "Unable to inject provider modules: \(error)") + throw error + } + } + ) + } +} + // MARK: - Configuration enum Configuration { diff --git a/Passepartout/Shared/Testing/AppContext+Testing.swift b/Passepartout/Shared/Testing/AppContext+Testing.swift new file mode 100644 index 00000000..8ce3f217 --- /dev/null +++ b/Passepartout/Shared/Testing/AppContext+Testing.swift @@ -0,0 +1,73 @@ +// +// AppContext+Testing.swift +// Passepartout +// +// Created by Davide De Rosa on 11/28/24. +// Copyright (c) 2024 Davide De Rosa. All rights reserved. +// +// https://github.com/passepartoutvpn +// +// This file is part of Passepartout. +// +// Passepartout is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Passepartout is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Passepartout. If not, see . +// + +import CommonLibrary +import CommonUtils +import Foundation +import PassepartoutKit +import UILibrary + +extension AppContext { + static func forUITesting(withRegistry registry: Registry) -> AppContext { + let iapManager = IAPManager( + customUserLevel: .subscriber, + inAppHelper: FakeAppProductHelper(), + receiptReader: FakeAppReceiptReader(), + betaChecker: TestFlightChecker(), + productsAtBuild: { _ in + [] + } + ) + let processor = InAppProcessor.shared(iapManager) { + $0.localizedPreview + } + + let profileManager: ProfileManager = .forTesting( + withRegistry: .shared, + processor: processor + ) + let tunnelEnvironment = InMemoryEnvironment() + let tunnel = ExtendedTunnel( + tunnel: Tunnel(strategy: FakeTunnelStrategy(environment: tunnelEnvironment)), + environment: tunnelEnvironment, + processor: processor, + interval: Constants.shared.tunnel.refreshInterval + ) + let providerManager = ProviderManager( + repository: InMemoryProviderRepository() + ) + let migrationManager = MigrationManager() + + return AppContext( + iapManager: iapManager, + migrationManager: migrationManager, + profileManager: profileManager, + providerManager: providerManager, + registry: registry, + tunnel: tunnel, + tunnelReceiptURL: BundleConfiguration.urlForBetaReceipt + ) + } +} diff --git a/Passepartout/Library/Sources/UILibrary/Mock/ProfileManager+Mock.swift b/Passepartout/Shared/Testing/ProfileManager+Testing.swift similarity index 95% rename from Passepartout/Library/Sources/UILibrary/Mock/ProfileManager+Mock.swift rename to Passepartout/Shared/Testing/ProfileManager+Testing.swift index 6533277c..f897cd1d 100644 --- a/Passepartout/Library/Sources/UILibrary/Mock/ProfileManager+Mock.swift +++ b/Passepartout/Shared/Testing/ProfileManager+Testing.swift @@ -1,5 +1,5 @@ // -// ProfileManager+Mock.swift +// ProfileManager+Testing.swift // Passepartout // // Created by Davide De Rosa on 11/28/24. @@ -28,7 +28,7 @@ import Foundation import PassepartoutKit extension ProfileManager { - public static func mock(withRegistry registry: Registry, processor: ProfileProcessor) -> ProfileManager { + public static func forTesting(withRegistry registry: Registry, processor: ProfileProcessor) -> ProfileManager { let repository = InMemoryProfileRepository() let remoteRepository = InMemoryProfileRepository() let manager = ProfileManager(repository: repository, remoteRepositoryBlock: { _ in