Skip to content

Add Go tests for requests handlers#11

Merged
xenOs76 merged 3 commits intomainfrom
ci/test_requests_handlers
Dec 10, 2025
Merged

Add Go tests for requests handlers#11
xenOs76 merged 3 commits intomainfrom
ci/test_requests_handlers

Conversation

@xenOs76
Copy link
Owner

@xenOs76 xenOs76 commented Dec 10, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Improved error handling for invalid URLs and host URL retrieval; URL validation now auto-adds scheme and default port when missing.
  • Tests

    • Added comprehensive tests for request handling, TLS behavior, header filtering, URL parsing, and certificate rendering.
    • Expanded TLS tests with configurable cipher suites and max protocol version.
  • Chores

    • Pinned stable development environment inputs for reproducible builds.

✏️ Tip: You can customize this high-level summary in your review settings.

@xenOs76 xenOs76 self-assigned this Dec 10, 2025
@xenOs76 xenOs76 marked this pull request as draft December 10, 2025 17:19
@coderabbitai
Copy link

coderabbitai bot commented Dec 10, 2025

Walkthrough

Refactors output to accept io.Writer across request and certificate rendering, adds error handling for URL retrieval/parsing, enhances TLS test configuration, and introduces a comprehensive test suite for request/TLS/URL behaviors.

Changes

Cohort / File(s) Summary
CLI call site
cmd/requests.go
Updated call to pass an io.Writer (e.g., os.Stdout) to HandleRequests to match new signature.
Requests core & handlers
internal/requests/requests.go, internal/requests/requests_handlers.go, internal/requests/main_test.go, internal/requests/requests_handlers_test.go
- HandleRequests now accepts w io.Writer and writes output to it; cfg.PrintCmd uses the provided writer.
- getUrlsFromHost now returns ([]string, error) and callers handle errors.
- parseResponseHeaders renamed to filterResponseHeaders.
- transportAddressFromURLString enhanced (scheme/port handling) and transportAddressFromRequest removed.
- RenderTLSData signature changed to RenderTLSData(w io.Writer, r *http.Response) and all TLS/header/body output routes to the writer.
- Tests extended for TLS config (cipher suites, max version) and many new unit/integration tests added.
Certificate rendering
internal/certinfo/certinfo_handlers.go
CertsToTables signature changed to CertsToTables(w io.Writer, certs []*x509.Certificate) and output now written to provided writer; call sites updated.
Dev environment config
devenv.nix, devenv.yaml
Added nixpkgsStable input and converted devenv.nix to use a let binding; expanded commented languages.go block.
Module manifest
go.mod
Listed in manifest changes (dependency/context updated in diff).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay special attention to all updated call sites of HandleRequests, RenderTLSData, and CertsToTables to ensure writers are passed consistently.
  • Review new error handling paths from getUrlsFromHost for correct propagation and test coverage.
  • Inspect TLS configuration changes in tests for platform-dependent behavior (cipher suites / max version).

Possibly related PRs

Poem

🐰 I hop from func to func with cheer,

I bind the writer close and near,
No stdout shackles hold me tight,
Tests hum softly through the night,
A rabbit's tap—output just right.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary change: adding comprehensive Go tests for the requests handlers. It directly reflects the main addition of the new test file requests_handlers_test.go with extensive test coverage.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ci/test_requests_handlers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@xenOs76 xenOs76 marked this pull request as ready for review December 10, 2025 17:20
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (6)
internal/requests/requests_handlers.go (1)

279-331: Consider accepting io.Writer for consistency.

PrintResponseData still writes directly to stdout via fmt.Println, while other rendering functions (RenderTLSData, CertsToTables, HandleRequests) now accept an io.Writer. For consistent testability and output control, consider updating this method to also accept a writer parameter.

internal/requests/main_test.go (1)

214-237: Consider adding MinVersion to the TLS configuration.

The static analysis tool flags a missing MinVersion. While this is test code and the default TLS 1.3 cipher suites effectively constrain the minimum version, explicitly setting MinVersion is a best practice and silences the warning.

+	// Set default TLS MinVersion to 1.3
+	var tlsMinVersion uint16 = tls.VersionTLS13
+
 	ts.TLS = &tls.Config{
 		Certificates: []tls.Certificate{cert},
 		CipherSuites: tlsCipherSuites,
+		MinVersion:   tlsMinVersion,
 		MaxVersion:   tlsMaxVersion,
 	}

If you need to test with older TLS versions, you could add a tlsMinVersion field to demoHttpServerData similar to tlsMaxVersion.

internal/requests/requests_handlers_test.go (4)

186-201: Understand and document why t.Parallel() breaks TestFilterResponseHeaders

You’ve commented that this test fails when t.Parallel() is enabled, but the current assertions only check membership in the returned slice, which should be order-agnostic. That suggests either hidden shared state or some other concurrency-sensitive behavior in filterResponseHeaders or its dependencies.

It would be good to either:

  • Track down and fix any shared mutable state so the test can safely use t.Parallel(), or
  • Expand the comment (or add a TODO) to briefly describe the concrete reason parallelization is unsafe, so future readers don’t accidentally re-enable it and reintroduce a flaky scenario.

293-310: Avoid strict equality on err.Error() in TestTransportAddressFromURLString

The "Invalid" case asserts exact equality on err.Error(), which couples this test to the precise error message formatting from net/url (including quoting and escape details). Minor changes in Go’s implementation could break the test even though behavior is still correct.

You could make this more robust by, for example:

require.Error(t, err)
assert.ErrorContains(t, err, "invalid URL escape")

or asserting on a stable prefix/suffix you control, rather than the full string.


382-441: TestRenderTLSData: strong coverage; consider avoiding fixed ports if possible

This test does a nice job exercising TLS version/cipher rendering, certificate output, and the resp.TLS == nil branch using an in-process HTTPS server and a buffer-backed writer.

If NewHTTPSTestServer can support binding to :0, you might consider switching from hard-coded ports (4610146103) to ephemeral ports derived from ts.URL (and wiring that into TransportOverrideURL). That would slightly reduce the risk of port-collision flakes when tests are run in parallel or in different environments.


493-537: Tighten TestHandleRequests structure around the error path

The success-path assertions on response map keys, request Name, and effective User-Agent propagation look good and exercise the updated HandleRequests API well.

For the error-path case, after require.Error(t, err) you still:

  • Assert on out := buffer.String() and
  • Range over respMap.

This is safe today (ranging over a nil map is a no-op, and PrintCmd runs before the loop), but for clarity and future-proofing it might be cleaner to:

if tt.expectErr {
    require.Error(t, err)
    return
}
require.NoError(t, err)
// assertions on out and respMap...

so future changes to HandleRequests’s error behavior can’t accidentally make the test read half-populated state.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0798051 and 9276998.

⛔ Files ignored due to path filters (1)
  • devenv.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • cmd/requests.go (1 hunks)
  • devenv.nix (2 hunks)
  • devenv.yaml (1 hunks)
  • internal/certinfo/certinfo_handlers.go (6 hunks)
  • internal/requests/main_test.go (2 hunks)
  • internal/requests/requests.go (1 hunks)
  • internal/requests/requests_handlers.go (6 hunks)
  • internal/requests/requests_handlers_test.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-15T17:16:55.075Z
Learnt from: xenOs76
Repo: xenOs76/https-wrench PR: 5
File: devenv.nix:569-569
Timestamp: 2025-11-15T17:16:55.075Z
Learning: In the xenOs76/https-wrench repository, the devenv.nix test environment is local-only without GitHub CI integration, so automatic dependency updates in enterTest are acceptable for the maintainer's workflow.

Applied to files:

  • devenv.nix
  • devenv.yaml
🧬 Code graph analysis (3)
internal/requests/requests_handlers_test.go (2)
internal/requests/requests.go (5)
  • ResponseHeader (72-72)
  • URI (71-71)
  • Host (75-78)
  • RequestConfig (85-103)
  • RequestsMetaConfig (122-130)
internal/requests/requests_handlers.go (3)
  • TLSVersionName (39-54)
  • RenderTLSData (333-365)
  • HandleRequests (206-225)
internal/requests/requests_handlers.go (4)
internal/requests/requests.go (2)
  • Host (75-78)
  • ResponseData (112-120)
internal/style/style.go (5)
  • CertKeyP4 (61-63)
  • CertValue (69-70)
  • ItemKeyP3 (46-48)
  • Error (100-101)
  • LGDefBorder (13-13)
internal/style/style_handlers.go (1)
  • LgSprintf (21-26)
internal/certinfo/certinfo_handlers.go (1)
  • CertsToTables (166-221)
cmd/requests.go (1)
internal/requests/requests_handlers.go (1)
  • HandleRequests (206-225)
🪛 ast-grep (0.40.0)
internal/requests/main_test.go

[warning] 232-236: MinVersionis missing from this TLS configuration. By default, TLS 1.2 is currently used as the minimum when acting as a client, and TLS 1.0 when acting as a server. General purpose web applications should default to TLS 1.3 with all other protocols disabled. Only where it is known that a web server must support legacy clients with unsupported an insecure browsers (such as Internet Explorer 10), it may be necessary to enable TLS 1.0 to provide support. AddMinVersion: tls.VersionTLS13' to the TLS configuration to bump the minimum version to TLS 1.3.
Context: tls.Config{
Certificates: []tls.Certificate{cert},
CipherSuites: tlsCipherSuites,
MaxVersion: tlsMaxVersion,
}
Note: [CWE-327]: Use of a Broken or Risky Cryptographic Algorithm [OWASP A03:2017]: Sensitive Data Exposure [OWASP A02:2021]: Cryptographic Failures [REFERENCES]
https://owasp.org/Top10/A02_2021-Cryptographic_Failures

(missing-ssl-minversion-go)

🔇 Additional comments (16)
devenv.nix (1)

54-59: LGTM: Good documentation of disabled feature.

The expanded comment clearly documents why the Go language configuration is disabled (version alignment with vim) and provides a reference URL. This is helpful for future maintainers.

devenv.yaml (1)

6-7: The nixos-25.05 branch exists in the NixOS/nixpkgs repository and follows the correct YY.MM versioning scheme. No action required.

internal/requests/requests.go (1)

571-574: LGTM! Proper error handling for URL retrieval.

The addition of error handling for getUrlsFromHost is a good improvement. The error is properly checked and propagated up the call stack, ensuring invalid URIs are caught early rather than causing issues later in the request processing.

internal/certinfo/certinfo_handlers.go (3)

13-13: LGTM!

Import added for io.Writer support.


66-66: LGTM! Consistent writer parameter usage.

All call sites for CertsToTables are correctly updated to pass os.Stdout as the writer, maintaining existing behavior while enabling future flexibility for testing and alternative output destinations.

Also applies to: 100-100, 120-120


166-218: LGTM! Writer-based output for certificate tables.

The refactored CertsToTables function now accepts an io.Writer, making it testable and flexible. The output is correctly written using fmt.Fprintln(w, ...).

cmd/requests.go (1)

97-100: LGTM!

The call site is correctly updated to pass os.Stdout as the writer parameter, aligning with the updated HandleRequests signature.

internal/requests/requests_handlers.go (7)

29-37: LGTM!

The comment clarifies that URIs must start with a slash, and the regex validation is appropriate for this requirement.


56-63: LGTM!

Good check to handle unknown cipher suites by detecting the hex format indicator.


65-96: LGTM! Better function naming.

Renaming from parseResponseHeaders to filterResponseHeaders more accurately describes the function's purpose of filtering headers based on the provided filter list.


98-118: LGTM! Proper error propagation for invalid URIs.

The function now returns an error when URI parsing fails, allowing callers to handle invalid configurations gracefully rather than silently proceeding with malformed URLs.


120-145: LGTM! Improved URL parsing robustness.

The function now handles edge cases:

  • Returns an error for empty input
  • Auto-prefixes https:// when the scheme is missing
  • Appends default port :443 when not specified

This makes the function more forgiving of user input variations.


206-225: LGTM! Writer-based output for request handling.

The HandleRequests function now accepts an io.Writer, enabling testability and flexible output destinations.


333-364: LGTM! Writer-based TLS data rendering.

The RenderTLSData function correctly uses the provided writer for all output operations, enabling consistent output control and testability.

internal/requests/main_test.go (1)

35-41: LGTM! Configurable TLS parameters for test server.

The new fields tlsCipherSuites and tlsMaxVersion enable flexible TLS configuration in tests, allowing verification of behavior with different TLS settings.

internal/requests/requests_handlers_test.go (1)

15-143: Solid table-driven unit tests for core helpers

The tests for ResponseHeader.String, URI.Parse, TLSVersionName, and cipherSuiteName are clean table-driven subtests, cover both normal and unknown values, and correctly use tt := tc with t.Parallel() to avoid closure capture issues. Nothing blocking here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
internal/requests/requests_handlers_test.go (4)

15-34: Broaden TestResponseHeader_Print table for future-proofing

The test is fine as-is, but it only exercises a single value. Consider adding a couple more table entries (e.g., empty header, header with special characters) so the behavior is documented a bit more robustly if ResponseHeader.String() ever changes.


36-60: Minor simplification in TestURI_Parse

Within each subtest you can call Parse() once and assert on the result instead of having two branches that each call tt.uri.Parse(). This slightly reduces duplication and makes the intent clearer:

-            if tt.expectValid {
-                assert.True(t, tt.uri.Parse())
-            }
-
-            if !tt.expectValid {
-                assert.False(t, tt.uri.Parse())
-            }
+            got := tt.uri.Parse()
+            assert.Equal(t, tt.expectValid, got)

145-202: Investigate why t.Parallel() breaks TestFilterResponseHeaders

The comment that the test fails when t.Parallel() is enabled suggests some shared mutable state, either in filterResponseHeaders itself or in the header values passed in. Ideally this function should be side‑effect free on its inputs and safe to exercise in parallel.

If the implementation mutates input headers or uses shared globals, consider:

  • Making it pure (no mutation / shared state), or
  • Cloning the headers inside the test cases so each subtest has isolated data,

and then re‑enable t.Parallel() here.


253-314: Relax exact error-string match for Invalid URL case

For the "Invalid" case you assert full equality on err.Error(), including the exact net/url parse message. This can be brittle across Go versions or subtle changes in url.Parse formatting.

To make the test more stable while still checking behavior, consider asserting on key substrings instead, e.g.:

-            if tt.expectError {
-                require.Error(t, err)
-                assert.Equal(t, tt.expectOutput, err.Error())
-            }
+            if tt.expectError {
+                require.Error(t, err)
+                assert.Contains(t, err.Error(), "invalid URL escape")
+            }

and keep the exact string check only for errors you fully control (like the "EmptyInput" case).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9276998 and 39a84b9.

📒 Files selected for processing (2)
  • devenv.nix (2 hunks)
  • internal/requests/requests_handlers_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • devenv.nix
🔇 Additional comments (5)
internal/requests/requests_handlers_test.go (5)

62-104: Good coverage of TLSVersionName, including unknown version

The table-driven test nicely exercises all known versions plus the unknown-code path, and using assert.Contains gives some resilience against formatting changes. No issues here.


106-143: TestCipherSuiteName cleanly captures known/unknown paths

This test clearly pins expected names for representative cipher suites and the unknown fallback; it’s straightforward and reads well. Looks good as written.


204-252: TestGetUrlsFromHost error-path contract is now explicit

Dropping expectedOutput for the "OneNotParsing" case resolves the earlier ambiguity: the test now clearly documents that, on parse error, you only assert that an error is returned and leave the output unspecified. The success cases look correct and cover both “with URIs” and “no URI list” behaviors.


316-437: Solid end-to-end TLS rendering test; covers happy-path and no-TLS state

This test does a good job of exercising RenderTLSData against real TLS connections, asserting on version, cipher suite, cert fields, and the “no TLS state” branch by zeroing Response.TLS. The use of per-case ports and t.Parallel() is appropriate here. No changes needed from my side.


439-535: TestHandleRequests nicely validates mapping, output, and User-Agent behavior

The test covers both success and error meta-configs, asserts that some request summary is written to the provided writer, and checks that respMap keys line up with Request.Name and that the User-Agent is either the default or overridden value. This gives good coverage of the higher-level flow; I don’t see any correctness issues here.

@xenOs76 xenOs76 merged commit 1fda3ab into main Dec 10, 2025
3 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Dec 14, 2025
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