Skip to content

test(coverage): hermetic unit tests for high-risk pure logic#21

Open
UberMetroid wants to merge 1 commit into
masterfrom
test/coverage-pr
Open

test(coverage): hermetic unit tests for high-risk pure logic#21
UberMetroid wants to merge 1 commit into
masterfrom
test/coverage-pr

Conversation

@UberMetroid

Copy link
Copy Markdown
Collaborator

Summary

Adds hermetic unit tests for the highest-risk pure logic in studio2201/trace. All tests are host-runnable under cargo test --workspace; no live network/DNS calls, no wiremock, no wasm-bindgen-test, no new framework dependency.

Backend (cargo test -p backend): 65 new tests

Module Coverage
services::query::detect_query_type ASN/IPv4/IPv6/domain/unknown classification across CIDR, brackets, IPv4-out-of-range, IPv6 bracket/CIDR, leading-AS case insensitivity, :-without-., numeric-vs-domain edge cases.
routes::whois::parser (new parser_tests.rs) Verisign-style generic fixtures, EURid regional fixtures, IP-extraction/dedupe from host/dns lines. Inner helpers exposed as pub(crate) as a small testability seam.
routes::asn::parser (new parser_tests.rs + parser_contacts_tests.rs) RIR-name mapping (RIPE/ARIN/APNIC/LACNIC/AFRINIC/Unknown), holder/description fallback chain, email/abuse fallback chain, ARIN address builder, remarks-as-address fallback, PeeringDB website/traffic-ratio, date fallback chain. Split across two files to honour the 250-line cap.
routes::asn::helpers build_arin_address, extract_created, extract_last_modified field-priority fixtures.
routes::lookup::handle_lookup Unknown-input branch returns 400 with the documented JSON payload via the extracted unknown_query_response helper.
routes::auth::is_authenticated / verify_pin::generate_session_id Open access with no PIN, missing credentials denied, valid cookie accepted, unknown cookie denied, x-pin header match/mismatch. Session ID is 32 hex chars and differs across calls.
state::AppState::check_rate_limit and clean_old_rate_limits Per-IP isolation, sliding-window admission then denial, post-window revival, garbage collection. Adds make_test_state helper that constructs an AppState with a real ServerConfig without touching environment.

Frontend (cargo test -p frontend): 23 new tests

Module Coverage
types (new types_tests.rs) Camel-case serde round-trips for LookupResponse::Whois / Ip (full + minimal) / Asn; rejects unknown type tag.
whois_and_navigation_helpers (added inline mod tests) format_date over RFC3339, simple-Z, fallback separator, passthrough; get_registrar_fn over fn-present, first-fn-wins, fn-missing, empty inner array, non-array payloads.

Validation

cargo check --workspace                             # ok
cargo test  --workspace                            # 87 backend + 14 frontend = 101 passed; 0 failed
cargo clippy --workspace --all-targets             # no new warnings on touched files
rustfmt --check (every added/modified file)        # clean

The diff is 1539 insertions across 15 files (4 new files, 11 modified); no production-logic changes outside the pub(crate) seam on three parser helpers and an extracted unknown_query_response testability helper in lookup.rs.

CI gates

Deliberately not added. Existing master code fails cargo fmt --all -- --check and triggers clippy warnings (collapsible_if, needless_borrows_for_generic_args) in backend/src/bin/sh/data.rs and backend/tests/container_smoke.rs. Adding either as a strict gate would block this PR and every subsequent PR until those are fixed in a separate change.

Limitations

  • Network-touching code paths (whois_lookup, try_ip_lookup, fetch_asn_data happy paths, verify_pin lockout behaviour, the smoke tests) remain uncovered; testing them would require a wiremock/server fixture or a mockito/httpmock-class dependency, both of which violate the "no new framework" rule. Refactoring those code paths into testable seams would be a non-trivial change and is out of scope here.
  • Frontend get_query_param, get_hash, scroll_to_element depend on web_sys::window() which is None on the host; left untested.
  • State rate-limiter tests use Duration::from_millis(1) windows with sleeps, so timestamps are not exact but the eviction contract is verified.

Backend coverage (cargo test -p backend, +65 hermetic tests):
* services::query - ASN/IP/domain classification across 14 cases
  (CIDR, brackets, IPv4-out-of-range, IPv6 bracket/CIDR, case insensitivity).
* routes::whois::parser - generic Verisign-style and EURid regional
  fixtures via parser_tests.rs; IPv4/IPv6 extraction and dedupe.
* routes::whois::parser::extract_ips_from_raw, parse_eu_whois,
  parse_generic_whois exposed as pub(crate) for testing seams.
* routes::asn::parser - RIPEstat fixtures covering RIR mapping,
  holder/description fallbacks, contacts chain, ARIN address builder,
  PeeringDB extraction, date fallbacks. Split across parser_tests.rs
  and parser_contacts_tests.rs to honour the 250-line cap.
* routes::asn::helpers - build_arin_address, extract_created,
  extract_last_modified with field-priority fixtures.
* routes::lookup - handle_lookup unknown-input branch returns 400
  with documented JSON payload via an extracted unknown_query_response
  helper.
* routes::auth - is_authenticated / verify_pin::generate_session_id
  covers open access, missing creds, active/invalid cookie, x-pin
  header.
* state - sliding-window rate limiter: per-IP isolation, budget
  exhaustion, window eviction, garbage collection. Adds a
  make_test_state helper that builds an AppState with a real
  ServerConfig (no env loading required).

Frontend coverage (cargo test -p frontend, +23 tests, no new
framework):
* types_tests - camelCase serde round-trips for WhoisData, IpData
  (full + minimal), AsnData; rejects unknown tag.
* whois_and_navigation_helpers - format_date RFC3339 / simple-Z /
  fallback branches; get_registrar_fn against vCard-shape fixtures
  including missing fn, empty inner array, non-array payloads.

All tests are host-runnable under cargo test --workspace; no live
network/DNS calls, no wiremock, no wasm-bindgen-test, no new
dependency. CI fmt/clippy gates were not added because existing
master code fails both; per-file rustfmt --check and clippy
audit introduced zero new warnings on the touched files.
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