Skip to content

[Prototype] Task 2/6 with first-party HttpMessageHandler (compare vs #129)#130

Draft
elahmed-microsoft wants to merge 10 commits into
mainfrom
users/elahmed/mock-http-handler-prototype
Draft

[Prototype] Task 2/6 with first-party HttpMessageHandler (compare vs #129)#130
elahmed-microsoft wants to merge 10 commits into
mainfrom
users/elahmed/mock-http-handler-prototype

Conversation

@elahmed-microsoft

@elahmed-microsoft elahmed-microsoft commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Purpose: comparison prototype (do not merge as-is)

This is a throwaway prototype to compare against #129 (the WireMock.Net implementation of Task 2/6). It implements the same mock integration test suite using a first-party, BCL-only approach instead of the third-party WireMock.Net package, in response to review feedback preferring first-party tooling. Same public test surface, same 7 integration tests, all passing.

Approach: in-memory HttpMessageHandler (Option A)

PackageUploader is an HTTP client, so the idiomatic first-party way to fake its dependencies is a custom HttpMessageHandler plugged in as the primary handler of the Ingestion and XFUS named clients — no server to host, no external package.

  • StubHttpMessageHandler — BCL-only base: wildcard path matching, request recording, sequential responses (polling/retry).
  • IngestionMockHandler / XfusMockHandler — same fluent stub API as the WireMock fixtures.
  • MockServerTestHost — overrides the IIngestionHttpClient and xfus primary handlers; auth handler and Polly policies still run.

#130 (this) vs #129

#129 WireMock.Net #130 this prototype
First-party No Yes
New packages ~140 transitive 0
CI feed provisioning Required (blocking #129) None
restore --locked-mode needs feed promotion passes as-is
Built-in retry/polling DSL Yes Hand-rolled (small)
Real socket exercised Yes No (in-memory)

Trade-off

The only capability lost is exercising XFUS's real SocketsHttpHandler/ConnectCallback over a socket — infrastructure plumbing, not business logic. For business-logic/integration coverage the in-memory transport is equivalent.

Verification

Recommendation

If the team prefers first-party + unblocked CI, adopt this in place of #129. If real-socket fidelity or the built-in scenario DSL is worth the third-party dependency and feed overhead, keep #129.

Add the WireMock.Net package reference and lock-file entries; it provides the in-process HTTP mock server used to build the Ingestion and XFUS fixtures in later phases. The package is saved to the private feed and is publicly readable, so CI restores it without authentication.
Add IngestionMockServer, a reusable WireMock.Net-backed fake of the Partner Center Ingestion API with fluent stubs for the endpoints PackageUploader uses (GetProduct, GetBranches, CreatePackage, package processing poll, package configuration, CreateSubmission, submission poll) and configurable success/error/retry/polling scenarios. Polling and retry use WireMock stateful scenarios with self-looping terminal states.
Add XfusMockServer, a reusable WireMock.Net-backed fake of the XFUS upload service serving the three-step chunked upload (initialize, block payload PUT, continue) rooted at /api/v2/assets/. Omits directUploadParameters.sasUri so the client uses the proxy PUT path, and emits the upload status as a number to match the client serializer. Provides a no-delta success convenience plus initialize/block/continue primitives and stateful continue-progression and block-retry scenarios.
…se 3)

Add MockServerTestHost, which owns the Ingestion and XFUS WireMock fakes and composes the real IPackageUploaderService pointed at them (Ingestion via IngestionConfig:BaseAddress, XFUS via the upload domain returned in the package response), keeping FakeAccessTokenProvider. Extend IngestionMockServer.StubCreatePackage to embed the XFUS upload info, and add IntegrationTestBase.CreateMockServerHost().
Remove the superseded in-process PackageUploaderTestHost and MockHttpMessageHandler, migrate the smoke test to CreateMockServerHost() (real HTTP to the WireMock Ingestion fake), and drop the CreateHost overload. MockServerTestHost is now the single canonical integration test host.
…Task 2/6 Phase 4)

Add IngestionApiTests (success, NotFound, transient-error retry, branches), UploadFlowTests (full no-delta upload tying the Ingestion and XFUS fakes together), and PublishFlowTests (submission create + poll to Published). Enhance IngestionMockServer with submission pendingUpdateInfo (mapper NRE guard), package-config market group, StubProcessPackage, and a flights stub; add fast retry config to MockServerTestHost.
- IngestionMockServer: emit null (not an empty object) for absent uploadInfo so the client's Guid mapping doesn't throw on a null XfusId; short-circuit StubRetryThenSuccess(failures<=0) to an unconditional success instead of an unmatched 404.
- XfusMockServer: short-circuit StubBlockUploadRetryThenSuccess(failures<=0); document the single-asset-per-server assumption of StubContinueProgression.
- MockServerTestHost: dispose the WireMock servers if composition throws, to avoid leaking listeners.
- UploadFlowTests: assert a block payload PUT actually reached XFUS rather than any request.
… HttpMessageHandler

Swap the WireMock.Net mock servers for a BCL-only StubHttpMessageHandler (plus IngestionMockHandler and XfusMockHandler) plugged in as the primary handler of the Ingestion and XFUS named clients. Removes the WireMock.Net package and its ~140 transitive dependencies, so CI restores with no feed provisioning. Same fluent stub API and the same 7 integration tests pass.
@elahmed-microsoft elahmed-microsoft changed the title probe [Prototype] Task 2/6 with first-party HttpMessageHandler (compare vs #129) Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant