Skip to content

chore: increase coverage#4

Merged
gustavosett merged 8 commits intomainfrom
gc-chore-increase-coverage
Dec 7, 2025
Merged

chore: increase coverage#4
gustavosett merged 8 commits intomainfrom
gc-chore-increase-coverage

Conversation

@gustavosett
Copy link
Copy Markdown
Owner

@gustavosett gustavosett commented Dec 7, 2025

Description

Increase coverage

Type of change

chore

Summary by Sourcery

Increase test coverage and observability around GeoIP models, service, HTTP/API behavior, and application wiring while adding basic changelog automation.

Build:

  • Adjust golangci-lint configuration to use versioned format and exclude specific generated and third-party paths, while backing up the previous configuration.

CI:

  • Introduce a GitHub Actions workflow to generate and auto-commit a changelog using git-cliff on pushes and releases.

Documentation:

  • Mark increased test coverage as completed in the roadmap and add an initial CHANGELOG generated via git-cliff.

Tests:

  • Add comprehensive unit and integration tests for GeoIP models, database type handling, reader methods, error formatting, and option application.
  • Extend GeoIP service tests to cover service construction, invalid IP handling, and real database lookups when test data is available.
  • Add HTTP handler and server integration tests to verify routing, lookup responses, health checks, and JSON serialization/deserialization.

Chores:

  • Factor out server construction into a reusable NewServer function to support testing and future reuse.
  • Add git-cliff configuration and baseline CHANGELOG for automated changelog management.

@gustavosett gustavosett added the enhancement New feature or request label Dec 7, 2025
@codecov-commenter
Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment

Thanks for integrating Codecov - We've got you covered ☂️

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Dec 7, 2025

Reviewer's Guide

Expands GeoIP, HTTP handler, and API server test coverage with integration and error-path tests, refactors server startup into a testable constructor, and introduces changelog tooling and updated lint configuration.

Sequence diagram for API server startup via NewServer

sequenceDiagram
    participant main
    participant NewServer
    participant geoip
    participant handlers
    participant echo

    main->>NewServer: NewServer("data/city.db")
    activate NewServer
    NewServer->>geoip: NewService(dbPath)
    alt GeoIP service init fails
        geoip-->>NewServer: error
        NewServer-->>main: nil, nil, error
        main->>main: log.Fatalf("Failed to initialize GeoIP service")
    else GeoIP service init succeeds
        geoip-->>NewServer: geoip.Service
        NewServer->>handlers: create GeoIPHandler
        NewServer->>echo: echo.New()
        echo-->>NewServer: *echo.Echo
        NewServer-->>main: *echo.Echo, *geoip.Service, nil
        main->>main: defer geoService.DB.Close()
        main->>echo: e.Start(":" + port)
    end
    deactivate NewServer
Loading

Updated class diagram for API server construction and dependencies

classDiagram
    class main {
        +NewServer(dbPath string) *echo_Echo, *geoip_Service, error
        +main()
    }

    class echo_Echo {
        +GET(path string, handler func)
        +Start(address string) error
    }

    class geoip_Service {
        +DB *geoip_DB
    }

    class geoip_DB {
        +Close() error
    }

    class handlers_GeoIPHandler {
        +GeoService *geoip_Service
        +Lookup(c echo_Context) error
    }

    class echo_Context {
    }

    main --> geoip_Service : uses
    main --> echo_Echo : constructs
    main --> handlers_GeoIPHandler : constructs
    handlers_GeoIPHandler --> geoip_Service : depends on
    geoip_Service --> geoip_DB : owns
    echo_Echo --> echo_Context : uses in handlers
Loading

File-Level Changes

Change Details Files
Greatly expanded unit and integration tests for the GeoIP reader, data models, and service logic, including error handling and forced execution paths.
  • Replaced minimal HasData tests with a table-driven suite covering all GeoIP model types, subdivision logic, and Location coordinates behavior.
  • Added getDBType tests for all supported MaxMind database types and unknown type error handling.
  • Introduced Reader method restriction tests ensuring InvalidMethodError is returned when calling methods incompatible with the configured databaseType.
  • Added tests for custom error formatting, option application, integration happy-path for Open/OpenBytes and lookups, and forced execution of different databaseType modes.
  • Implemented corruption-based tests to verify decode error propagation for all reader lookup methods without misclassifying them as InvalidMethodError.
internal/geoip/reader_test.go
Improved GeoIP service tests to validate service construction, IP validation behavior, and real database lookups when a test database is available.
  • Added NewService tests for invalid path failures and successful initialization with cleanup when a city database is present.
  • Replaced low-value netip.ParseAddr tests with LookupIP validation tests that assert ErrInvalidIP and nil results for malformed or out-of-range IP strings.
  • Introduced integration tests for LookupIP that hit a real database and assert HasData and expected ISO codes when data should exist, and empty results for localhost.
  • Ensured tests are skipped gracefully when the GeoIP database file is missing in the environment.
internal/geoip/service_test.go
Expanded HTTP handler and API server coverage by adding integration tests for the lookup endpoint, DB error behavior, JSON serialization, health check routing, and introducing a NewServer constructor.
  • Added Lookup integration tests that exercise GeoIPHandler with a real service, asserting 200 for valid IPs, 400 for invalid IPs, and validating JSON response structure.
  • Added tests that simulate DB errors by closing the DB before lookup to assert a 404 response from the handler.
  • Refactored main to extract a NewServer(dbPath) function returning echo.Echo and *geoip.Service, simplifying startup error handling and enabling direct testing of route registration and DB lifecycle.
  • Created tests for JSONSerializer Serialize/Deserialize paths and server initialization/health route behavior, including failure cases for invalid DB paths and health check integration.
  • Removed obsolete benchmark test file for handlers to focus on functional coverage.
internal/handlers/http_test.go
cmd/api/main.go
cmd/api/main_test.go
internal/handlers/benchmark_test.go
Introduced changelog generation tooling, initial CHANGELOG, and adjusted lint configuration while updating project documentation to reflect increased test coverage.
  • Added git-cliff configuration (cliff.toml), a GitHub Actions workflow to auto-generate and commit CHANGELOG updates, and an initial CHANGELOG.md entry.
  • Updated README roadmap to mark "Increase test coverage" as completed.
  • Reworked .golangci.yml to use version 2 format with test-enabled runs, configured linter disables and exclusions, and added a backup of the previous configuration for reference.
cliff.toml
.github/workflows/changelog.yml
CHANGELOG.md
.golangci.yml
.golangci.bck.yml
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • In TestJSONSerializer_Serialize, using assert.JSONEq means the indented vs non-indented cases don’t actually validate the indent behavior (whitespace is ignored); consider using direct string equality at least for the indented case to ensure formatting is exercised.
  • In TestReader_ForcedExecution, the returned error from each action is explicitly discarded (_ = err), which can hide real failures; either assert on the expected error behavior or document why errors are intentionally ignored.
  • The repo now contains both .golangci.yml and .golangci.bck.yml; keeping two similar config files can be confusing, so consider removing or clearly marking the backup to avoid ambiguity about which configuration is authoritative.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `TestJSONSerializer_Serialize`, using `assert.JSONEq` means the indented vs non-indented cases don’t actually validate the `indent` behavior (whitespace is ignored); consider using direct string equality at least for the indented case to ensure formatting is exercised.
- In `TestReader_ForcedExecution`, the returned error from each action is explicitly discarded (`_ = err`), which can hide real failures; either assert on the expected error behavior or document why errors are intentionally ignored.
- The repo now contains both `.golangci.yml` and `.golangci.bck.yml`; keeping two similar config files can be confusing, so consider removing or clearly marking the backup to avoid ambiguity about which configuration is authoritative.

## Individual Comments

### Comment 1
<location> `.golangci.yml:7-12` </location>
<code_context>
-
-issues:
-  exclude-use-default: false
+  exclusions:
+    generated: lax
+    paths:
+      - third_party$
+      - builtin$
+      - examples$
+formatters:
+  exclusions:
</code_context>

<issue_to_address>
**issue (bug_risk):** The `exclusions` keys under `linters` and `formatters` don't match golangci-lint's documented schema and may be ignored

This config shape isn’t part of the documented golangci-lint schema, so these exclusions are likely ignored and `generated`, `third_party`, `builtin`, and `examples` won’t actually be skipped. Please switch to supported fields like `run.skip-dirs`, `run.skip-files`, or `issues.exclude-rules` so the exclusions take effect as intended.
</issue_to_address>

### Comment 2
<location> `internal/geoip/service_test.go:83` </location>
<code_context>
+			name:        "Valid Google DNS (US)",
+			ipStr:       "8.8.8.8",
+			expectFound: true,
+			expectedISO: "US", // Usually resolves to US
+		},
+		{
</code_context>

<issue_to_address>
**suggestion (testing):** Avoid depending on a specific country ISO for `8.8.8.8` to reduce flakiness

Hard-asserting `expectedISO: "US"` ties this test to a specific GeoIP dataset and will likely become flaky as databases/providers change. Consider either dropping the ISO assertion here or making it softer (e.g., only asserting `HasData()` or conditionally asserting ISO when it matches a known value and otherwise logging/skipping) so the test validates behavior rather than a particular dataset.
</issue_to_address>

### Comment 3
<location> `cmd/api/main_test.go:34` </location>
<code_context>
+		{
+			name:         "Indented Serialization",
</code_context>

<issue_to_address>
**issue (testing):** The indented JSON case in `TestJSONSerializer_Serialize` is not actually validating indentation

Since `assert.JSONEq` ignores whitespace, this case doesn’t actually verify that `Serialize` applies the indent string; it just rechecks semantic equality already covered elsewhere. To test indentation, either compare `rec.Body.String()` to `expectedBody` with `assert.Equal`, or add a specific formatting check (for example, `assert.Contains(t, rec.Body.String(), "\n  \"hello\": \"world\"")`).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@gustavosett gustavosett force-pushed the gc-chore-increase-coverage branch from b827a9a to a1cae6e Compare December 7, 2025 22:19
@gustavosett gustavosett merged commit b070381 into main Dec 7, 2025
5 checks passed
@gustavosett gustavosett deleted the gc-chore-increase-coverage branch December 7, 2025 22:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants