Skip to content

Add offline unit tests for GitHubService.getPublicRepositories - #29

Merged
dmccoystephenson merged 1 commit into
mainfrom
feature/github-service-unit-tests
Oct 1, 2026
Merged

dmccoystephenson merged 1 commit into
mainfrom
feature/github-service-unit-tests

Conversation

@dmccoystephenson

Copy link
Copy Markdown
Member

Summary

Stage B (unit-test expansion) cycle targeting GitHubService.getPublicRepositories, the one piece of behavior-bearing logic in GitHubService. Until now it was exercised only by testGetPublicRepositories_InvalidUser, which calls the live GitHub API and asserts nothing beyond "some IOException".

  • Five offline characterization tests are added to GitHubServiceTest, run against a mocked GitHub client. A helper stubs GitHub.connectAnonymously() (via mockStatic) and GitHubBuilder (via mockConstruction), so the mock is used whether or not GITHUB_TOKEN is set in the environment. No production code is changed.
    • An organization's private repositories are filtered out, and the user lookup is never reached.
    • A name that fails the organization lookup falls back to the user lookup, which is filtered the same way.
    • A user-lookup failure whose message contains 404 is rewrapped as '<name>' not found as GitHub organization or user. Please verify the name is correct., with the original exception kept as the cause.
    • Any other user-lookup failure, including one with a null message, is rethrown as the same instance.
  • The existing tests use the @Mock + MockitoAnnotations.openMocks(this) pattern, and are kept unchanged.
  • A CHANGELOG.md [Unreleased] → Added entry is included, matching how DocumentationVersionTest was recorded.

No tracking issue: this gap was found during triage. Open issue #8 (missing LICENSE file) was skipped this cycle because, as the issue itself states, it needs a maintainer decision on the copyright holder and year.

Test plan

  • mvn verify ran locally: 118 tests run, 0 failures, 1 skipped (the existing GITHUB_TOKEN-gated test)
  • Mutation check: with the organization branch's !repo.isPrivate() filter and the "404" check temporarily changed in GitHubService, testGetPublicRepositories_OrganizationFiltersPrivateRepositories and testGetPublicRepositories_NotFoundAsOrganizationOrUser both failed. Both passed again once the change was reverted.
  • CI Build workflow green on the PR head

This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).

🤖 Generated with Claude Code


drafted by Claude on behalf of Daniel Stephenson

getPublicRepositories was covered only by a test that calls the live
GitHub API. The new tests build the service against a mocked GitHub
client (GitHub.connectAnonymously and GitHubBuilder are stubbed, so the
anonymous and GITHUB_TOKEN paths both get the mock) and pin down the
current behaviour: private repositories are filtered out, a name that
is not an organization falls back to the user lookup, a 404 from the
user lookup is rewrapped with the "not found" message and the original
as cause, and any other failure, including one with no message, is
rethrown unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dmccoystephenson

Copy link
Copy Markdown
Member Author

Self-review rubric (scored against the diff and CI run 36829323434):

  • Scope: PASS — only src/test/java/com/github/backup/GitHubServiceTest.java and CHANGELOG.md are modified, and no production code is touched. The three existing tests are unchanged.
  • Tests-new: PASS (not applicable) — no new public methods are added. All five new tests target the existing getPublicRepositories.
  • Tests-fix: not applicable (no bug fix). A mutation check was run in its place: the !repo.isPrivate() filter in the organization branch and the "404" check were temporarily altered in GitHubService. OrganizationFiltersPrivateRepositories and NotFoundAsOrganizationOrUser both failed under the mutation and passed once it was reverted.
  • Sibling structure: PASS — the tests use @Mock fields with MockitoAnnotations.openMocks(this) in @BeforeEach, test<Method>_<Scenario> naming, and the static Assertions.* / Mockito.* imports, all matching BackupServiceTest.
  • Sibling renames: PASS (not applicable) — nothing is renamed.
  • Docs: PASS — no CLI flag, property, or endpoint changes, so COMMANDS.md, CONFIG.md, USER_GUIDE.md, and README.md are unaffected. CHANGELOG.md [Unreleased] → Added records the tests, following the DocumentationVersionTest precedent.
  • Issue resolution: not applicable — there is no Closes #N. The gap was found during triage, and README links to a LICENSE file that does not exist #8 was skipped because it needs a maintainer decision.
  • CI: PASS — build and docker-build are both green on the PR head.
  • Config-doc / Command-doc parity: PASS (not applicable) — no config keys or commands are added.
  • Package placement: PASS — the test mirrors com.github.backup.GitHubService.
  • No credential leakage: PASS — no token values appear anywhere. withOAuthToken(anyString()) is matched only on a mocked builder.

Judgment notes (folded in from the review, none blocking):

  • src/test/java/com/github/backup/GitHubServiceTest.java:139 — newServiceBackedBy stubs both construction paths, but CI sets no GITHUB_TOKEN, so CI runs only the connectAnonymously branch. The GitHubBuilder stub becomes active only when a token is present locally. This was considered acceptable because the tests target getPublicRepositories, not the constructor.
  • src/test/java/com/github/backup/GitHubServiceTest.java:47 — the isPrivate() stubs in setUp go unused by the three error-path tests. That is harmless because openMocks does not enable strict stubbing.
  • Outside the diff: testGetPublicRepositories_InvalidUser still calls the live GitHub API. It was kept so this PR stays additive, and it could be retired later now that offline coverage exists.

Summary: an additive, test-only change. CI is green and the mutation check confirms the new tests detect regressions.

This review comment was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).


drafted by Claude on behalf of Daniel Stephenson

@dmccoystephenson
dmccoystephenson merged commit a6d901f into main Oct 1, 2026
2 checks passed
@dmccoystephenson
dmccoystephenson deleted the feature/github-service-unit-tests branch October 1, 2026 07:17
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