Skip to content

Commit

Permalink
Subscription refactoring #5 (#2930)
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

**Description**:

This PR updates BSK from
duckduckgo/BrowserServicesKit#874 and contains
all the needed refactoring for the Subscription classes inits.
It also contains new unit test classes with example tests:
- SubscriptionErrorReporterTests
- SubscriptionAppStoreRestorerTests
- SubscriptionRedirectManager

Complete tests will be implemented in follow-up tasks

**Steps to test this PR**:
Subscription must work as usual, manual smoke test script available in
this
[README](https://github.com/duckduckgo/BrowserServicesKit/blob/main/Sources/SubscriptionTestingUtilities/README.md)
  • Loading branch information
federicocappelli authored Jul 5, 2024
1 parent 1a52bd5 commit e581911
Show file tree
Hide file tree
Showing 21 changed files with 779 additions and 569 deletions.
78 changes: 45 additions & 33 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 Expand Up @@ -75,7 +75,7 @@
{
"identity" : "lottie-spm",
"kind" : "remoteSourceControl",
"location" : "https://github.com/airbnb/lottie-spm",
"location" : "https://github.com/airbnb/lottie-spm.git",
"state" : {
"revision" : "1d29eccc24cc8b75bff9f6804155112c0ffc9605",
"version" : "4.4.3"
Expand Down
39 changes: 0 additions & 39 deletions DuckDuckGo/Common/Extensions/TimeIntervalExtension.swift

This file was deleted.

29 changes: 18 additions & 11 deletions DuckDuckGo/Preferences/View/PreferencesRootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ enum Preferences {
@ObservedObject var model: PreferencesSidebarModel

var subscriptionModel: PreferencesSubscriptionModel?
let subscriptionManager: SubscriptionManager
let subscriptionUIHandler: SubscriptionUIHandling

init(model: PreferencesSidebarModel) {
init(model: PreferencesSidebarModel, subscriptionManager: SubscriptionManager, subscriptionUIHandler: SubscriptionUIHandling) {
self.model = model
self.subscriptionManager = subscriptionManager
self.subscriptionUIHandler = subscriptionUIHandler
self.subscriptionModel = makeSubscriptionViewModel()
}

Expand Down Expand Up @@ -138,7 +142,7 @@ enum Preferences {
WindowControllersManager.shared.showTab(with: .dataBrokerProtection)
case .openITR:
PixelKit.fire(PrivacyProPixel.privacyProIdentityRestorationSettings)
let url = Application.appDelegate.subscriptionManager.url(for: .identityTheftRestoration)
let url = subscriptionManager.url(for: .identityTheftRestoration)
WindowControllersManager.shared.showTab(with: .identityTheftRestoration(url))
case .iHaveASubscriptionClick:
PixelKit.fire(PrivacyProPixel.privacyProRestorePurchaseClick)
Expand All @@ -162,25 +166,28 @@ enum Preferences {

let sheetActionHandler = SubscriptionAccessActionHandlers(
openActivateViaEmailURL: {
let url = Application.appDelegate.subscriptionManager.url(for: .activateViaEmail)
let url = subscriptionManager.url(for: .activateViaEmail)
WindowControllersManager.shared.showTab(with: .subscription(url))
},
restorePurchases: {
}, restorePurchases: {
if #available(macOS 12.0, *) {
Task {
let subscriptionAppStoreRestorer = SubscriptionAppStoreRestorer(subscriptionManager: Application.appDelegate.subscriptionManager,
uiHandler: Application.appDelegate.subscriptionUIHandler)
let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(accountManager: subscriptionManager.accountManager,
storePurchaseManager: subscriptionManager.storePurchaseManager(),
subscriptionEndpointService: subscriptionManager.subscriptionEndpointService,
authEndpointService: subscriptionManager.authEndpointService)
let subscriptionAppStoreRestorer = DefaultSubscriptionAppStoreRestorer(
subscriptionManager: subscriptionManager,
appStoreRestoreFlow: appStoreRestoreFlow,
uiHandler: subscriptionUIHandler)
await subscriptionAppStoreRestorer.restoreAppStoreSubscription()
}
}
},
uiActionHandler: handleUIEvent
)
}, uiActionHandler: handleUIEvent)

return PreferencesSubscriptionModel(openURLHandler: openURL,
userEventHandler: handleUIEvent,
sheetActionHandler: sheetActionHandler,
subscriptionManager: Application.appDelegate.subscriptionManager)
subscriptionManager: subscriptionManager)
}
}
}
5 changes: 4 additions & 1 deletion DuckDuckGo/Preferences/View/PreferencesViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ final class PreferencesViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()

let host = NSHostingView(rootView: Preferences.RootView(model: model))
let prefRootView = Preferences.RootView(model: model,
subscriptionManager: Application.appDelegate.subscriptionManager,
subscriptionUIHandler: Application.appDelegate.subscriptionUIHandler)
let host = NSHostingView(rootView: prefRootView)
view.addAndLayout(host)
}

Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/Subscription/SubscriptionRedirectManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ final class PrivacyProSubscriptionRedirectManager: SubscriptionRedirectManager {
}
}

private extension URL {
fileprivate extension URL {

func addingQueryItems(from url: URL) -> URL {
// If the origin value is of type "do+something" appending the percentEncodedQueryItem crashes the browser as + is replaced by a space.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,25 @@ import enum StoreKit.StoreKitError
import PixelKit

@available(macOS 12.0, *)
struct SubscriptionAppStoreRestorer {
protocol SubscriptionAppStoreRestorer {
var uiHandler: SubscriptionUIHandling { get }
func restoreAppStoreSubscription() async
}

@available(macOS 12.0, *)
struct DefaultSubscriptionAppStoreRestorer: SubscriptionAppStoreRestorer {
private let subscriptionManager: SubscriptionManager
@MainActor var window: NSWindow? { WindowControllersManager.shared.lastKeyMainWindowController?.window }
let subscriptionErrorReporter = SubscriptionErrorReporter()
private let subscriptionErrorReporter: SubscriptionErrorReporter
private let appStoreRestoreFlow: AppStoreRestoreFlow
let uiHandler: SubscriptionUIHandling

public init(subscriptionManager: SubscriptionManager,
subscriptionErrorReporter: SubscriptionErrorReporter = DefaultSubscriptionErrorReporter(),
appStoreRestoreFlow: AppStoreRestoreFlow,
uiHandler: SubscriptionUIHandling) {
self.subscriptionManager = subscriptionManager
self.subscriptionErrorReporter = subscriptionErrorReporter
self.appStoreRestoreFlow = appStoreRestoreFlow
self.uiHandler = uiHandler
}

Expand All @@ -59,7 +68,6 @@ struct SubscriptionAppStoreRestorer {
}

private func continueRestore() async {
let appStoreRestoreFlow = DefaultAppStoreRestoreFlow(subscriptionManager: subscriptionManager)
let result = await appStoreRestoreFlow.restoreAccountFromPastPurchase()
await uiHandler.dismissProgressViewController()
switch result {
Expand Down Expand Up @@ -87,12 +95,12 @@ struct SubscriptionAppStoreRestorer {

// MARK: - UI interactions

func showSomethingWentWrongAlert() async {
private func showSomethingWentWrongAlert() async {
PixelKit.fire(PrivacyProPixel.privacyProPurchaseFailure, frequency: .dailyAndCount)
await uiHandler.show(alertType: .somethingWentWrong)
}

func showSubscriptionNotFoundAlert() async {
private func showSubscriptionNotFoundAlert() async {
switch await uiHandler.show(alertType: .subscriptionNotFound) {
case .alertFirstButtonReturn:
let url = subscriptionManager.url(for: .purchase)
Expand All @@ -102,7 +110,7 @@ struct SubscriptionAppStoreRestorer {
}
}

func showSubscriptionInactiveAlert() async {
private func showSubscriptionInactiveAlert() async {
switch await uiHandler.show(alertType: .subscriptionInactive) {
case .alertFirstButtonReturn:
let url = subscriptionManager.url(for: .purchase)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ enum SubscriptionError: Error {
generalError
}

struct SubscriptionErrorReporter {
protocol SubscriptionErrorReporter {
func report(subscriptionActivationError: SubscriptionError)
}

struct DefaultSubscriptionErrorReporter: SubscriptionErrorReporter {

// swiftlint:disable:next cyclomatic_complexity
func report(subscriptionActivationError: SubscriptionError) {
Expand Down
Loading

0 comments on commit e581911

Please sign in to comment.