Skip to content

test(github): cover client request path and REST resource functions - #232

Merged
getappz merged 5 commits into
masterfrom
devin/1784314920-github-test-coverage
Jul 17, 2026
Merged

test(github): cover client request path and REST resource functions#232
getappz merged 5 commits into
masterfrom
devin/1784314920-github-test-coverage

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds unit tests for the least-covered modules in the crate. I measured coverage
with cargo llvm-cov --workspace; the lowest-covered modules were the src/github/*
resource wrappers, whose gaps were entirely the network functions (pure JSON/query
helpers were already tested). These functions were untestable before because there
was no way to point the Client at anything other than api.github.com.

Changes:

  • src/github/test_support.rs (new, #[cfg(test)] only) — a tiny mock HTTP
    server (std::net::TcpListener on an ephemeral localhost port) that serves a
    fixed queue of canned responses and records the requests it saw (method, path,
    body). Lets tests drive the real ureq request path without the network.
  • src/github/client.rs — added a test-only Client::for_test(base_url, token)
    constructor (production still goes through new/anonymous, which always target
    GitHub). New tests cover the request path end-to-end: GET JSON parse, JSON body
    on writes, empty-body→Null, on-the-wire status→GitHubError mapping (incl.
    rate-limit header), malformed-JSON parse error, and the no-token write guard
    short-circuiting before any network call.
  • pulls.rs / issues.rs / releases.rs / actions.rs — end-to-end tests for
    every resource function (create/list/get/merge/comment/request_review/close/
    add_labels/latest/rerun/dispatch/list_runs), asserting method, path, request body,
    and response deserialization against the mock server.
  • identity.rs — added normalize_repo edge cases (ssh:// with port, deeper
    path than owner/repo, trailing / + .git, bare single segment, empty input).
  • mod.rsGitHubError::Display for every variant, and a multibyte-UTF-8
    encode_query case.

Coverage impact (line %, this crate's github modules):

module before after
github/pulls.rs 20.6% 96.2%
github/issues.rs 37.5% 96.0%
github/releases.rs 42.9% 95.0%
github/actions.rs 47.0% 98.3%
github/client.rs 30.2% 90.4%
github/mod.rs 66.7% 100%
github/identity.rs 90.0% 90.0%→ (branches closed)

Test-only changes — no production behavior is modified.

Test plan

  • cargo test (611 passed)
  • cargo clippy --all-targets --all-features -- -D warnings (clean)
  • cargo fmt --check

Notes for reviewers

  • Risk areas / edge cases: the mock server responds with Connection: close and
    serves exactly responses.len() connections, so each test's request count must
    match its queued responses. It binds 127.0.0.1:0, so no fixed-port collisions.
  • Backwards compatibility: none affected; all additions are #[cfg(test)].

Link to Devin session: https://app.devin.ai/sessions/84d4f9d9b8f14ba8a08ac2d75d65ded3
Requested by: @getappz

Summary by CodeRabbit

  • Tests
    • Expanded unit/integration-style coverage for GitHub Actions, issues, pull requests, and releases, validating HTTP methods, endpoint paths, query encoding, and JSON request/response parsing.
    • Added client request behavior checks (auth handling, JSON/body handling, 204 handling, rate-limit mapping, and parse errors).
    • Added regression tests for repository normalization, repository ID parsing, UTF-8 query percent-encoding, and human-readable error messages.
    • Introduced test-only local HTTP mock-server utilities to reliably assert outgoing requests and returned responses.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@getappz getappz self-assigned this Jul 17, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Test-only changes add a localhost HTTP mock server and expand coverage for GitHub client behavior, Actions, issues, pulls, releases, repository normalization, query encoding, and error formatting.

Changes

GitHub API test coverage

Layer / File(s) Summary
Mock HTTP foundation
src/github/test_support.rs, src/github/mod.rs
Adds queued HTTP responses, recorded requests, request parsing, response writing, and test-only module wiring.
Client request behavior
src/github/client.rs, src/github/mod.rs
Tests client construction, authentication checks, JSON and empty responses, rate-limit mapping, malformed JSON, status mapping, and error display.
API wrapper request coverage
src/github/actions.rs, src/github/issues.rs, src/github/pulls.rs, src/github/releases.rs
Verifies endpoint paths, methods, query parameters, JSON payloads, and response parsing across GitHub API wrappers.
Repository parsing regressions
src/github/identity.rs
Adds coverage for SSH URLs, suffix and slash trimming, bare inputs, and empty repository identifiers.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: expanded GitHub client and REST resource test coverage.
Description check ✅ Passed The description includes the required Summary, Test plan, and Notes for reviewers sections with substantive details.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch devin/1784314920-github-test-coverage

Comment @coderabbitai help to get the list of available commands.

@getappz
getappz enabled auto-merge (squash) July 17, 2026 19:29

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/github/releases.rs (1)

25-25: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Exercise non-empty and multi-page responses in the list test.

The new get_paginated path is only tested with an empty first page, so regressions in release deserialization or page aggregation could pass unnoticed. Return a page containing REL, follow it with [], and assert the parsed release plus both requests.

Suggested test adjustment
-        let server = MockServer::start(vec![MockResponse::json(200, "[]")]);
+        let server = MockServer::start(vec![
+            MockResponse::json(200, &format!("[{}]", REL)),
+            MockResponse::json(200, "[]"),
+        ]);
         let client = server.client(None);
-        assert!(list(&client, &repo()).unwrap().is_empty());
+        let releases = list(&client, &repo()).unwrap();
+        assert_eq!(releases.len(), 1);
+        assert_eq!(releases[0].tag_name, "v1.0.0");

Also applies to: 88-96

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/github/releases.rs` at line 25, Update the list test around the
get_paginated call to mock a first page containing REL followed by an empty
second page, then assert the parsed release result and both page requests.
Preserve the existing pagination setup while covering release deserialization
and multi-page aggregation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/github/releases.rs`:
- Line 25: Update the list test around the get_paginated call to mock a first
page containing REL followed by an empty second page, then assert the parsed
release result and both page requests. Preserve the existing pagination setup
while covering release deserialization and multi-page aggregation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 211db1ed-b86b-48e6-89ef-b408364d3912

📥 Commits

Reviewing files that changed from the base of the PR and between c27cbbc and e043ca6.

📒 Files selected for processing (5)
  • src/github/actions.rs
  • src/github/client.rs
  • src/github/issues.rs
  • src/github/pulls.rs
  • src/github/releases.rs
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/github/issues.rs
  • src/github/client.rs
  • src/github/actions.rs
  • src/github/pulls.rs

@getappz
getappz merged commit ba258fa into master Jul 17, 2026
16 checks passed
@getappz
getappz deleted the devin/1784314920-github-test-coverage branch July 17, 2026 20: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