Skip to content

test: Isolate network calls in RelationTests and UserTests#428

Merged
mtrezza merged 14 commits into
parse-community:masterfrom
mtrezza:fix/ci-network-isolated-tests
Jul 16, 2026
Merged

test: Isolate network calls in RelationTests and UserTests#428
mtrezza merged 14 commits into
parse-community:masterfrom
mtrezza:fix/ci-network-isolated-tests

Conversation

@mtrezza

@mtrezza mtrezza commented Jul 16, 2026

Copy link
Copy Markdown
Member

Problem

master CI has been failing on every push since ~January 2026. All PRs (including Dependabot bumps such as #425) inherit the failure, so nothing can go green. Exactly 6 tests fail on the Windows runner:

  • RelationTests: AddRelationToUserAsync_ThrowsException_WhenRelationFieldIsNull, UpdateUserRelationAsync_ThrowsException_WhenRelationFieldIsNull, DeleteUserRelationAsync_ThrowsException_WhenRelationFieldIsNull, GetUserRelationsAsync_ThrowsException_WhenRelationFieldIsNull, AddRelationToUserAsync_ThrowsException_WhenRelatedObjectIsUnsaved
  • UserTests.TestLogOut

All fail with the same Windows Schannel error:

System.Net.Http.HttpRequestException → IOException: The decryption operation failed
  → Win32Exception: The message received was unexpected or badly formatted

Root cause

These tests make real network requests that should have been mocked. new ServerConnectionData { Test = true } with no ServerURI defaults to the long-dead https://api.parse.com/1/ server (ParseClient.cs). On the Windows runner the TLS handshake against that endpoint fails; on other platforms it happens not to throw, which is why the failure was invisible locally.

Two separate mocking gaps let the calls escape:

  1. RelationTests.SetUp created a MutableServiceHub with mocked controllers but never passed it to the ParseClient, so await user.SignUpAsync() in the test arrange hit the real network before the assertion was ever reached. (The *_WhenUserIsNull variants pass because they throw ArgumentNullException before any network call.)
  2. UserTests.TestLogOut bound the user to the un-mocked SetUp client, so session revocation during logout (ParseUser.LogOutAsyncServices.RevokeSessionAsync) went to the network. It also used .CallBase() on an interface mock, which throws once the network no longer masks it.

Fix (test-only)

  • RelationTests.SetUp: wire the mock hub into the client (new ParseClient(connectionData, hub)) and make TearDown null-safe for the resulting OrchestrationServiceHub.
  • TestLogOut: user.Bind(client) so session revocation uses the mocked SessionController, and replace the invalid .CallBase() with .Returns(Task.CompletedTask).

No SDK/product code is changed.

Verification

Each fix was verified by first reproducing the failure deterministically (pointing the test client at an unreachable URI → Connection refused, mirroring the CI failure), then confirming the tests pass with that unreachable URI still set — proving the tests no longer depend on the network. Full suite:

Passed! - Failed: 0, Passed: 234, Skipped: 0, Total: 234

(Was Failed: 6, Passed: 228.)

mtrezza added 14 commits May 24, 2024 11:05
The RelationTests and UserTests.TestLogOut tests made real network requests
that failed on the Windows CI runner with a TLS decryption error, which has
kept master's CI red.

Root cause: `new ServerConnectionData { Test = true }` with no ServerURI
defaults to the dead https://api.parse.com server, and these tests were not
fully isolated from the network:

- RelationTests.SetUp built a mock service hub but never passed it to the
  ParseClient, so `user.SignUpAsync()` in the test arrange hit the network.
  Wire the mock hub into the client and make TearDown null-safe for the
  resulting OrchestrationServiceHub.
- UserTests.TestLogOut bound the user to the un-mocked hub, so session
  revocation during logout went to the network. Bind the user to the mocked
  client, and replace the invalid `.CallBase()` on the interface mock with
  `Task.CompletedTask`.

All 234 tests now pass.
@parse-github-assistant

Copy link
Copy Markdown

🚀 Thanks for opening this pull request! We appreciate your effort in improving the project. Please let us know once your pull request is ready for review.

Tip

  • Keep pull requests small. Large PRs will be rejected. Break complex features into smaller, incremental PRs.
  • Use Test Driven Development. Write failing tests before implementing functionality. Ensure tests pass.
  • Group code into logical blocks. Add a short comment before each block to explain its purpose.
  • We offer conceptual guidance. Coding is up to you. PRs must be merge-ready for human review.
  • Our review focuses on concept, not quality. PRs with code issues will be rejected. Use an AI agent.
  • Human review time is precious. Avoid review ping-pong. Inspect and test your AI-generated code.

Note

Please respond to review comments from AI agents just like you would to comments from a human reviewer. Let the reviewer resolve their own comments, unless they have reviewed and accepted your commit, or agreed with your explanation for why the feedback was incorrect.

Caution

Pull requests must be written using an AI agent with human supervision. Pull requests written entirely by a human will likely be rejected, because of lower code quality, higher review effort and the higher risk of introducing bugs. Please note that AI review comments on this pull request alone do not satisfy this requirement. Our CI and AI review are safeguards, not development tools. If many issues are flagged, rethink your development approach. Invest more effort in planning and design rather than using review cycles to fix low-quality code.

@mtrezza
mtrezza merged commit 41d44d5 into parse-community:master Jul 16, 2026
4 checks passed
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