Skip to content

Prepare IPushNotificationService for extraction into a push library - #8199

Open
justindbaur wants to merge 7 commits into
mainfrom
preparing-for-push-library
Open

Prepare IPushNotificationService for extraction into a push library#8199
justindbaur wants to merge 7 commits into
mainfrom
preparing-for-push-library

Conversation

@justindbaur

@justindbaur justindbaur commented Aug 13, 2026

Copy link
Copy Markdown
Member

🎟️ Tracking

Part of: https://bitwarden.atlassian.net/browse/PM-34546

📔 Objective

Removes all 16 default interface methods (DIMs) from IPushNotificationService, leaving only PushAsync<T>. Each DIM is extracted as a static extension method in its owning team's domain folder (Auth, Vault, Tools, AdminConsole, NotificationCenter, Billing). Push notification payload types are moved into their owning team's Models folder (namespace kept as Bit.Core.Models to avoid touching callers).

Also adds end-to-end pipeline tests for the Azure Queue push path:

  • AzureQueuePipelineTests — drives the full chain (AzureQueuePushEngine → in-memory ChannelQueueClientAzureQueueHostedServiceHubHelpers → SignalR hub mocks), covering wire-format contracts, routing by user/org/installation/client-type, and the AuthRequestResponse → anonymous hub path
  • PostSendEndpointTests — integration tests for POST /send using a real in-memory Identity server and JWT tokens, including the anonymous hub routing case
  • AzureQueueHostedService gets TimeProvider injection and resolves QueueClient via keyed DI so tests can substitute ChannelQueueClient without touching production wiring

Key changes:

  • Remove all DIMs from IPushNotificationService; retain the three legacy properties marked [Obsolete(DiagnosticId="BWP0001")]
  • Extract extension methods per team domain
  • Move payload types to team-owned Models folders (namespace unchanged)
  • Delete snapshot-style PushTestBase engine tests (migration guards, not living contracts)
  • Add AzureQueuePipelineTests + ChannelQueueClient as the replacement living contract

Once these changes land, Push should be able to be made into a library and Notifications should be able to remove a dependency on Core with only Platform review for future PRs.

📸 Screenshots

N/A

- Remove all 16 default interface methods (DIMs) from IPushNotificationService,
  leaving only PushAsync<T>; the three legacy properties (InstallationId,
  TimeProvider, Logger) are retained but marked [Obsolete(DiagnosticId="BWP0001")]
- Extract each DIM as a static extension method in its owning team's domain folder
  (Auth, Vault, Tools, AdminConsole, NotificationCenter, Billing)
- Move push notification payload types out of PushNotification.cs into their
  owning team's Models folder; namespace stays Bit.Core.Models to avoid touching
  callers (file location is the ownership signal, not the namespace—see comment
  in each file)
- Fix LogOut PushType attribution from "not-specified" to @bitwarden/team-auth-dev
- Update all service-level tests to assert on PushAsync<T> instead of the removed
  DIMs; delete the snapshot-style PushTestBase engine tests that were migration
  guards rather than living contracts
- Add AzureQueuePushEngineWireFormatTests as a wire-format guard and HubHelpers
  routing guard for the Azure Queue push path
Replaces the mock-based AzureQueuePushEngineWireFormatTests with a true
end-to-end pipeline test (AzureQueuePipelineTests) that drives the full
chain: AzureQueuePushEngine → ChannelQueueClient → AzureQueueHostedService
→ HubHelpers → SignalR hub mocks.

- ChannelQueueClient: in-memory QueueClient backed by System.Threading.Channels,
  with a separate capture channel so producer and consumer sides don't race
- AzureQueuePipelineTests: wire-format guard + routing guard + ClientType
  routing, including the AuthRequestResponse → anonymous hub case
- NotificationsApplicationFactory: expose AnonymousHubClients for asserting
  auth-request-response routing
- PostSendEndpointTests: add AuthRequestResponse routing case (anonymous hub)
- AzureQueueHostedService: inject TimeProvider for delay control in tests;
  resolve QueueClient via keyed service provider
- Startup: register TimeProvider.System and QueueClient as keyed singleton
  so tests can substitute ChannelQueueClient
@justindbaur justindbaur added the t:tech-debt Change Type - Tech debt label Aug 13, 2026
Comment thread test/Api.IntegrationTest/Auth/Controllers/AccountsControllerTest.cs Fixed
@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 73.51351% with 98 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.22%. Comparing base (bc45404) to head (5a2c137).

Files with missing lines Patch % Lines
...re/Vault/PushNotificationServiceVaultExtensions.cs 32.00% 51 Missing ⚠️
...NotificationServiceNotificationCenterExtensions.cs 72.34% 21 Missing and 5 partials ⚠️
...e/PushNotificationServiceAdminConsoleExtensions.cs 68.42% 12 Missing ⚠️
...re/Tools/PushNotificationServiceToolsExtensions.cs 92.59% 2 Missing and 2 partials ⚠️
...els/ProviderBankAccountVerifiedPushNotification.cs 0.00% 2 Missing ⚠️
src/Notifications/AzureQueueHostedService.cs 81.81% 1 Missing and 1 partial ⚠️
...OrganizationBankAccountVerifiedPushNotification.cs 0.00% 1 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (bc45404) and HEAD (5a2c137). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (bc45404) HEAD (5a2c137)
2 1
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8199      +/-   ##
==========================================
- Coverage   68.56%   63.22%   -5.35%     
==========================================
  Files        2381     2397      +16     
  Lines      103902   103900       -2     
  Branches     9405     9405              
==========================================
- Hits        71245    65695    -5550     
- Misses      30310    35947    +5637     
+ Partials     2347     2258      -89     

☔ View full report in Codecov by Harness.
📢 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@justindbaur
justindbaur marked this pull request as ready for review August 14, 2026 12:48
@justindbaur
justindbaur requested review from a team as code owners August 14, 2026 12:48
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

Reviewed the removal of all 18 default interface methods from IPushNotificationService, their re-homing as per-team extension methods in Bit.Core.Platform.Push, the payload type moves into team-owned Models folders, and the new Azure Queue / POST /send pipeline tests. The extracted extensions preserve the original Type/Target/TargetId/ExcludeCurrentContext/ClientType semantics for every method, MultiServicePushNotificationService is the only implementer so there is no shadowing risk from moving to extension methods, and the OrganizationBankAccountVerified NotificationInfo payload type correction looks right. The AzureQueueHostedService rewiring keeps behavior equivalent — the self-hosted/empty-connection-string guard moves from DI registration into StartAsync, and resolving the keyed QueueClient inside ExecuteAsync correctly keeps the real client from ever being constructed on those paths.

Code Review Details
  • ♻️ : RelayPushEngine left without any producer-side test coverage after the PushTestBase suite deletion
    • test/Core.Test/Platform/Push/Engines/RelayPushEngineTests.cs

Also noted, not blocking: the extracted UserPushNotification builders now use DateTime.UtcNow instead of the (obsolete) injected TimeProvider, which is behavior-neutral in production but removes the ability to control that timestamp from tests.

Comment thread test/Core.Test/Platform/Push/Engines/RelayPushEngineTests.cs
harr1424
harr1424 previously approved these changes Aug 14, 2026

@harr1424 harr1424 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes to Tools-owned files look good ✅

JaredScar
JaredScar previously approved these changes Aug 14, 2026

@JaredScar JaredScar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AC changes seem fine

jengstrom-bw
jengstrom-bw previously approved these changes Aug 14, 2026
…s-tests

# Conflicts:
#	test/Api.IntegrationTest/KeyManagement/Controllers/AccountsKeyManagementControllerTests.cs
#	test/Core.Test/KeyManagement/UserKey/RotateUserAccountKeysCommandTests.cs
@justindbaur
justindbaur dismissed stale reviews from JaredScar and harr1424 via 5a2c137 August 14, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t:tech-debt Change Type - Tech debt

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants