Skip to content

Commit

Permalink
Subscription refactoring #5 (#3023)
Browse files Browse the repository at this point in the history
Task/Issue URL: https://app.asana.com/0/1205842942115003/1206805455884775/f
Tech Design URL: https://app.asana.com/0/1205842942115003/1207147511614062/f

This PR updates BSK from duckduckgo/BrowserServicesKit#874 and contains all the needed refactoring for the Subscription classes inits.
It also contains a new unit test class:
- SubscriptionPagesUseSubscriptionFeatureTests
Complete tests will be implemented in follow-up tasks
  • Loading branch information
federicocappelli authored Jul 5, 2024
1 parent 950d8ba commit f083e07
Show file tree
Hide file tree
Showing 11 changed files with 250 additions and 137 deletions.
66 changes: 35 additions & 31 deletions DuckDuckGo.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/DuckDuckGo/BrowserServicesKit",
"state" : {
"revision" : "28dd48c5aca37c46402e2a14f7c47aad3877b3aa",
"version" : "164.3.0"
"revision" : "777e5ae1ab890d9ec22e069bc5dc0f0ada4b35af",
"version" : "165.0.0"
}
},
{
Expand Down
5 changes: 4 additions & 1 deletion DuckDuckGo/SettingsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,10 @@ extension SettingsViewModel {
@available(iOS 15.0, *)
func restoreAccountPurchase() async {
DispatchQueue.main.async { self.state.subscription.isRestoring = true }
let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(subscriptionManager: subscriptionManager)
let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(accountManager: subscriptionManager.accountManager,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
authEndpointService: subscriptionManager.authEndpointService)
let result = await appStoreRestoreFlow.restoreAccountFromPastPurchase()
switch result {
case .success:
Expand Down
7 changes: 7 additions & 0 deletions DuckDuckGo/Subscription/SubscriptionManageriOS14.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ class SubscriptionManageriOS14: SubscriptionManager {
func storePurchaseManager() -> StorePurchaseManager {
DefaultStorePurchaseManager()
}

static func loadEnvironmentFrom(userDefaults: UserDefaults) -> SubscriptionEnvironment? {
return nil
}

static func save(subscriptionEnvironment: SubscriptionEnvironment, userDefaults: UserDefaults) {}

var currentEnvironment: SubscriptionEnvironment = SubscriptionEnvironment.default
var canPurchase: Bool = false
func loadInitialData() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ final class SubscriptionPagesUseSubscriptionFeature: Subfeature, ObservableObjec
private let subscriptionManager: SubscriptionManager
private var accountManager: AccountManager { subscriptionManager.accountManager }
private let appStorePurchaseFlow: AppStorePurchaseFlow

private let appStoreRestoreFlow: AppStoreRestoreFlow
private let appStoreAccountManagementFlow: AppStoreAccountManagementFlow

Expand Down Expand Up @@ -177,7 +176,6 @@ final class SubscriptionPagesUseSubscriptionFeature: Subfeature, ObservableObjec

private func resetSubscriptionFlow() {
setTransactionError(nil)

}

private func setTransactionError(_ error: UseSubscriptionError?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,18 @@ import Subscription
enum SubscriptionContainerViewFactory {

static func makeSubscribeFlow(origin: String?, navigationCoordinator: SubscriptionNavigationCoordinator, subscriptionManager: SubscriptionManager) -> some View {
let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(subscriptionManager: subscriptionManager)
let appStorePurchaseFlow = DefaultAppStorePurchaseFlow(subscriptionManager: subscriptionManager,
appStoreRestoreFlow: appStoreRestoreFlow)
let appStoreAccountManagementFlow = DefaultAppStoreAccountManagementFlow(subscriptionManager: subscriptionManager)
let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(accountManager: subscriptionManager.accountManager,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
authEndpointService: subscriptionManager.authEndpointService)
let appStorePurchaseFlow = DefaultAppStorePurchaseFlow(subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
accountManager: subscriptionManager.accountManager,
appStoreRestoreFlow: appStoreRestoreFlow,
authEndpointService: subscriptionManager.authEndpointService)
let appStoreAccountManagementFlow = DefaultAppStoreAccountManagementFlow(authEndpointService: subscriptionManager.authEndpointService,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
accountManager: subscriptionManager.accountManager)

let viewModel = SubscriptionContainerViewModel(
subscriptionManager: subscriptionManager,
Expand All @@ -44,10 +52,18 @@ enum SubscriptionContainerViewFactory {
}

static func makeRestoreFlow(navigationCoordinator: SubscriptionNavigationCoordinator, subscriptionManager: SubscriptionManager) -> some View {
let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(subscriptionManager: subscriptionManager)
let appStorePurchaseFlow = DefaultAppStorePurchaseFlow(subscriptionManager: subscriptionManager,
appStoreRestoreFlow: appStoreRestoreFlow)
let appStoreAccountManagementFlow = DefaultAppStoreAccountManagementFlow(subscriptionManager: subscriptionManager)
let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(accountManager: subscriptionManager.accountManager,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
authEndpointService: subscriptionManager.authEndpointService)
let appStorePurchaseFlow = DefaultAppStorePurchaseFlow(subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
accountManager: subscriptionManager.accountManager,
appStoreRestoreFlow: appStoreRestoreFlow,
authEndpointService: subscriptionManager.authEndpointService)
let appStoreAccountManagementFlow = DefaultAppStoreAccountManagementFlow(authEndpointService: subscriptionManager.authEndpointService,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
accountManager: subscriptionManager.accountManager)

let viewModel = SubscriptionContainerViewModel(
subscriptionManager: subscriptionManager,
Expand All @@ -66,11 +82,18 @@ enum SubscriptionContainerViewFactory {
static func makeEmailFlow(navigationCoordinator: SubscriptionNavigationCoordinator,
subscriptionManager: SubscriptionManager,
onDisappear: @escaping () -> Void) -> some View {
let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(subscriptionManager: subscriptionManager)
let appStorePurchaseFlow = DefaultAppStorePurchaseFlow(subscriptionManager: subscriptionManager,
appStoreRestoreFlow: appStoreRestoreFlow)
let appStoreAccountManagementFlow = DefaultAppStoreAccountManagementFlow(subscriptionManager: subscriptionManager)

let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(accountManager: subscriptionManager.accountManager,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
authEndpointService: subscriptionManager.authEndpointService)
let appStorePurchaseFlow = DefaultAppStorePurchaseFlow(subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
accountManager: subscriptionManager.accountManager,
appStoreRestoreFlow: appStoreRestoreFlow,
authEndpointService: subscriptionManager.authEndpointService)
let appStoreAccountManagementFlow = DefaultAppStoreAccountManagementFlow(authEndpointService: subscriptionManager.authEndpointService,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
accountManager: subscriptionManager.accountManager)
let viewModel = SubscriptionContainerViewModel(
subscriptionManager: subscriptionManager,
origin: nil,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//
// SubscriptionContainerViewModelTests.swift
// DuckDuckGo
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import XCTest
@testable import DuckDuckGo
@testable import Subscription
import SubscriptionTestingUtilities

@available(iOS 15.0, *)
final class SubscriptionContainerViewModelTests: XCTestCase {
var sut: SubscriptionContainerViewModel!
let subscriptionManager = MockDependencyProvider().subscriptionManager

func testWhenInitWithOriginThenSubscriptionFlowPurchaseURLHasOriginSet() {
// GIVEN
let origin = "test_origin"
let queryParameter = URLQueryItem(name: "origin", value: "test_origin")
let expectedURL = SubscriptionURL.purchase.subscriptionURL(environment: .production).appending(percentEncodedQueryItem: queryParameter)
let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(accountManager: subscriptionManager.accountManager,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
authEndpointService: subscriptionManager.authEndpointService)
let appStorePurchaseFlow = DefaultAppStorePurchaseFlow(subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
accountManager: subscriptionManager.accountManager,
appStoreRestoreFlow: appStoreRestoreFlow,
authEndpointService: subscriptionManager.authEndpointService)
let appStoreAccountManagementFlow = DefaultAppStoreAccountManagementFlow(authEndpointService: subscriptionManager.authEndpointService,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
accountManager: subscriptionManager.accountManager)

// WHEN
sut = .init(subscriptionManager: subscriptionManager,
origin: origin,
userScript: .init(),
subFeature: .init(subscriptionManager: subscriptionManager,
subscriptionAttributionOrigin: nil,
appStorePurchaseFlow: appStorePurchaseFlow,
appStoreRestoreFlow: appStoreRestoreFlow,
appStoreAccountManagementFlow: appStoreAccountManagementFlow))

// THEN
XCTAssertEqual(sut.flow.purchaseURL, expectedURL)
}

func testWhenInitWithoutOriginThenSubscriptionFlowPurchaseURLDoesNotHaveOriginSet() {
let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(accountManager: subscriptionManager.accountManager,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
authEndpointService: subscriptionManager.authEndpointService)
let appStorePurchaseFlow = DefaultAppStorePurchaseFlow(subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
accountManager: subscriptionManager.accountManager,
appStoreRestoreFlow: appStoreRestoreFlow,
authEndpointService: subscriptionManager.authEndpointService)
let appStoreAccountManagementFlow = DefaultAppStoreAccountManagementFlow(authEndpointService: subscriptionManager.authEndpointService,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
accountManager: subscriptionManager.accountManager)

// WHEN
sut = .init(subscriptionManager: subscriptionManager,
origin: nil,
userScript: .init(),
subFeature: .init(subscriptionManager: subscriptionManager,
subscriptionAttributionOrigin: nil,
appStorePurchaseFlow: appStorePurchaseFlow,
appStoreRestoreFlow: appStoreRestoreFlow,
appStoreAccountManagementFlow: appStoreAccountManagementFlow))

// THEN
XCTAssertEqual(sut.flow.purchaseURL, SubscriptionURL.purchase.subscriptionURL(environment: .production))
}
}
Loading

0 comments on commit f083e07

Please sign in to comment.