Add debug bypass subscription toggle, tests, and data layer improvements
- Add runtime toggle in Settings (DEBUG only) to bypass subscription/hide trial banner - IAPManager.bypassSubscription is now a @Published var persisted via UserDefaults - Hide upgrade banner in SettingsTabView and trial warnings when bypass is enabled - Add FeelsTests directory with integration tests - Update DataController, DataControllerGET, DataControllerUPDATE - Update Xcode project and scheme configuration - Update localization strings and App Store screen docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -36,11 +36,13 @@ class IAPManager: ObservableObject {
|
||||
// MARK: - Debug Toggle
|
||||
|
||||
/// Set to `true` to bypass all subscription checks and grant full access (for development only)
|
||||
/// Set to `false` to test trial/subscription behavior in DEBUG builds
|
||||
/// Togglable at runtime in DEBUG builds via Settings > Debug > Bypass Subscription
|
||||
#if DEBUG
|
||||
static let bypassSubscription = false
|
||||
@Published var bypassSubscription: Bool {
|
||||
didSet { UserDefaults.standard.set(bypassSubscription, forKey: "debug_bypassSubscription") }
|
||||
}
|
||||
#else
|
||||
static let bypassSubscription = false
|
||||
let bypassSubscription = false
|
||||
#endif
|
||||
|
||||
// MARK: - Constants
|
||||
@@ -96,7 +98,7 @@ class IAPManager: ObservableObject {
|
||||
}
|
||||
|
||||
var hasFullAccess: Bool {
|
||||
if Self.bypassSubscription { return true }
|
||||
if bypassSubscription { return true }
|
||||
switch state {
|
||||
case .subscribed, .billingRetry, .gracePeriod, .inTrial:
|
||||
return true
|
||||
@@ -106,7 +108,7 @@ class IAPManager: ObservableObject {
|
||||
}
|
||||
|
||||
var shouldShowPaywall: Bool {
|
||||
if Self.bypassSubscription { return false }
|
||||
if bypassSubscription { return false }
|
||||
switch state {
|
||||
case .trialExpired, .expired, .revoked:
|
||||
return true
|
||||
@@ -116,6 +118,7 @@ class IAPManager: ObservableObject {
|
||||
}
|
||||
|
||||
var shouldShowTrialWarning: Bool {
|
||||
if bypassSubscription { return false }
|
||||
if case .inTrial = state { return true }
|
||||
return false
|
||||
}
|
||||
@@ -137,6 +140,9 @@ class IAPManager: ObservableObject {
|
||||
// MARK: - Initialization
|
||||
|
||||
init() {
|
||||
#if DEBUG
|
||||
self.bypassSubscription = UserDefaults.standard.bool(forKey: "debug_bypassSubscription")
|
||||
#endif
|
||||
restoreCachedSubscriptionState()
|
||||
updateListenerTask = listenForTransactions()
|
||||
|
||||
@@ -219,7 +225,7 @@ class IAPManager: ObservableObject {
|
||||
|
||||
/// Sync subscription status to UserDefaults for widget access
|
||||
private func syncSubscriptionStatusToUserDefaults() {
|
||||
let accessValue = Self.bypassSubscription ? true : hasFullAccess
|
||||
let accessValue = bypassSubscription ? true : hasFullAccess
|
||||
GroupUserDefaults.groupDefaults.set(accessValue, forKey: UserDefaultsStore.Keys.hasActiveSubscription.rawValue)
|
||||
}
|
||||
|
||||
@@ -373,7 +379,7 @@ class IAPManager: ObservableObject {
|
||||
case .unknown:
|
||||
status = "unknown"
|
||||
isSubscribed = false
|
||||
hasFullAccess = Self.bypassSubscription
|
||||
hasFullAccess = bypassSubscription
|
||||
willAutoRenew = nil
|
||||
isInGracePeriod = nil
|
||||
trialDaysRemaining = nil
|
||||
|
||||
Reference in New Issue
Block a user