Skip to content

🍒 [PM-37642] feat: Add debug menu flag to disable self-host premium checks#2670

Merged
andrebispo5 merged 1 commit into
release/2026.5-rc48from
cherry-pick/pm-37642-rc48
May 20, 2026
Merged

🍒 [PM-37642] feat: Add debug menu flag to disable self-host premium checks#2670
andrebispo5 merged 1 commit into
release/2026.5-rc48from
cherry-pick/pm-37642-rc48

Conversation

@andrebispo5
Copy link
Copy Markdown
Contributor

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-37642

📔 Objective

Cherry-pick of #2657 into release/2026.5-rc48.

Adds a debug menu toggle (debug-disable-self-host-premium-check) that allows QA to test premium upgrade flows in self-hosted test environments.

When enabled, BillingService.isSelfHosted() returns false regardless of the actual region, which unblocks:

  • The "Plan" row in Settings (previously hidden for self-hosted users)
  • The PremiumUpgradeView upgrade UI (previously showed a read-only banner)
  • BillingService.premiumStatusChanged() premium sync (previously short-circuited)

Copilot AI review requested due to automatic review settings May 20, 2026 09:37
@andrebispo5 andrebispo5 requested a review from a team as a code owner May 20, 2026 09:37
@andrebispo5 andrebispo5 added app:password-manager Bitwarden Password Manager app context t:feature labels May 20, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a QA-focused debug feature flag to bypass “self-hosted” gating in premium-upgrade related UI/logic by routing self-host detection through BillingService.isSelfHosted() (which can be overridden via the new debug flag).

Changes:

  • Introduces FeatureFlag.debugDisableSelfHostPremiumCheck and adds BillingService.isSelfHosted() to centralize effective self-host detection.
  • Updates Settings and Premium Upgrade processors (and their tests) to use billingService.isSelfHosted() instead of environmentService.region == .selfHosted.
  • Extends BillingService test coverage to validate the new self-host override behavior and its impact on premiumStatusChanged().

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
BitwardenShared/UI/Platform/Settings/SettingsCoordinator.swift Updates coordinator service requirements to provide BillingService to Settings flows.
BitwardenShared/UI/Platform/Settings/Settings/SettingsProcessor.swift Uses billingService.isSelfHosted() to determine plan-row visibility.
BitwardenShared/UI/Platform/Settings/Settings/SettingsProcessorTests.swift Adapts tests to mock BillingService.isSelfHosted() instead of environment region.
BitwardenShared/UI/Billing/PremiumUpgrade/PremiumUpgradeProcessor.swift Uses billingService.isSelfHosted() to decide whether to fetch pricing / show self-host banner.
BitwardenShared/UI/Billing/PremiumUpgrade/PremiumUpgradeProcessorTests.swift Adapts tests to mock BillingService.isSelfHosted() rather than environment region.
BitwardenShared/Core/Platform/Models/Enum/FeatureFlag.swift Adds the new debug feature flag and includes it in FeatureFlag.allCases for Debug Menu listing.
BitwardenShared/Core/Billing/Services/BillingService.swift Adds isSelfHosted() and updates premiumStatusChanged() to use it.
BitwardenShared/Core/Billing/Services/BillingServiceTests.swift Adds tests for isSelfHosted() and debug-override impact on premiumStatusChanged().

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


func isSelfHosted() async -> Bool {
guard environmentService.region == .selfHosted else { return false }
return await !configService.getFeatureFlag(.debugDisableSelfHostPremiumCheck)

func premiumStatusChanged() async {
guard environmentService.region != .selfHosted,
guard await !isSelfHosted(),
Comment on lines +155 to +158
func isSelfHosted() async -> Bool {
guard environmentService.region == .selfHosted else { return false }
return await !configService.getFeatureFlag(.debugDisableSelfHostPremiumCheck)
}
Comment on lines +229 to +231
/// `perform(.appeared)` shows the plan row for a self-hosted user when the debug override is enabled.
@MainActor
func test_perform_appeared_showsPlanRow_selfHosted_debugOverrideEnabled() async {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ @andrebispo5 missed this on the review for main but yes it should be renamed as in here there's nothing referring the debug override, actually you just change the return value of isSelfHosted which would have the debug flag inside but is a black box so this shouldn't need to know about it. It can be done in another tech-debt PR though.

Comment on lines +97 to +105
/// `perform(_:)` with `.appeared` fetches price when billing service overrides self-hosted for QA.
@Test
func perform_appeared_selfHosted_debugOverrideEnabled_fetchesPremiumPrice() async {
billingService.isSelfHostedReturnValue = false

await subject.perform(.appeared)

#expect(subject.state.isSelfHosted == false)
#expect(billingService.getPremiumPlanCalled)
@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

❌ Patch coverage is 98.52941% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 87.34%. Comparing base (7f75e9a) to head (828f5b4).

Files with missing lines Patch % Lines
...Shared/Core/Platform/Models/Enum/FeatureFlag.swift 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                 Coverage Diff                  @@
##           release/2026.5-rc48    #2670   +/-   ##
====================================================
  Coverage                87.34%   87.34%           
====================================================
  Files                     1920     1920           
  Lines                   171170   171220   +50     
====================================================
+ Hits                    149512   149559   +47     
- Misses                   21658    21661    +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines +229 to +231
/// `perform(.appeared)` shows the plan row for a self-hosted user when the debug override is enabled.
@MainActor
func test_perform_appeared_showsPlanRow_selfHosted_debugOverrideEnabled() async {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ @andrebispo5 missed this on the review for main but yes it should be renamed as in here there's nothing referring the debug override, actually you just change the return value of isSelfHosted which would have the debug flag inside but is a black box so this shouldn't need to know about it. It can be done in another tech-debt PR though.

@andrebispo5 andrebispo5 merged commit 013f418 into release/2026.5-rc48 May 20, 2026
26 checks passed
@andrebispo5 andrebispo5 deleted the cherry-pick/pm-37642-rc48 branch May 20, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app:password-manager Bitwarden Password Manager app context t:feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants