Skip to content

Release v1.2.0 - Add Stats API#49

Open
piobeny wants to merge 1 commit intostats-apifrom
release-v1.2.0
Open

Release v1.2.0 - Add Stats API#49
piobeny wants to merge 1 commit intostats-apifrom
release-v1.2.0

Conversation

@piobeny
Copy link

@piobeny piobeny commented Mar 9, 2026

Motivation

  • Release version 1.2.0

Changes

  • Add Stats API

How to test

N/A

Summary by CodeRabbit

Release Notes

  • New Features

    • Added statistics API to retrieve sending metrics including delivery, bounce, open, click, and spam rates. Supports aggregated statistics and filtering by domain, category, email service provider, or date.
  • Documentation

    • Updated dependency version references to 1.2.0 in README and getting started guides.
  • Tests

    • Added comprehensive test coverage for the new statistics API.

@piobeny piobeny requested a review from VladimirTaytor March 9, 2026 10:06
@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 43bef53b-ca30-444f-a0d8-d025a73946f5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR releases version 1.2.0 of the Mailtrap Java library, introducing a new Stats API module. It adds a Stats interface with methods to fetch aggregated and grouped sending statistics, implements the interface with HTTP client integration, and adds supporting filter and response model classes. The changes integrate the new module into the client factory and update documentation and tests accordingly.

Changes

Cohort / File(s) Summary
Version Updates
README.md, docs/getting-started.md, pom.xml
Updated Mailtrap Java library version from 1.1.0 to 1.2.0 across Maven and Gradle dependency declarations and project configuration.
Stats API Interface & Filter
src/main/java/io/mailtrap/api/stats/Stats.java, src/main/java/io/mailtrap/api/stats/StatsFilter.java
Introduced public interface Stats with methods to fetch aggregated and grouped statistics (getStats, byDomain, byCategory, byEmailServiceProvider, byDate). Introduced data container StatsFilter with fields for startDate, endDate, sendingDomainIds, sendingStreams, categories, and emailServiceProviders, with Lombok boilerplate.
Stats API Implementation
src/main/java/io/mailtrap/api/stats/StatsImpl.java
Implemented Stats interface extending ApiResource with HTTP client integration. Methods build URLs, assemble query parameters from filters, and invoke HTTP client to retrieve statistics. Includes private helpers for URL building and query parameter mapping.
Client Integration
src/main/java/io/mailtrap/client/api/MailtrapGeneralApi.java, src/main/java/io/mailtrap/factory/MailtrapClientFactory.java
Added Stats field to MailtrapGeneralApi. Updated MailtrapClientFactory to instantiate StatsImpl and inject it into MailtrapGeneralApi constructor, integrating the new module into the client architecture.
Response Models
src/main/java/io/mailtrap/model/response/stats/SendingStatsResponse.java, src/main/java/io/mailtrap/model/response/stats/SendingStatGroupResponse.java
Introduced SendingStatsResponse with Lombok-generated accessors mapping JSON snake_case fields (delivery_count, bounce_count, open_count, click_count, spam_count and rates) to camelCase Java properties. Introduced SendingStatGroupResponse with name, value, and stats fields, with dynamic JSON field mapping via @JsonAnySetter.
Test Resources
src/test/resources/api/stats/*.json
Added test data files (getStats.json, byDomain.json, byCategory.json, byEmailServiceProvider.json, byDate.json) containing sample statistics payloads for API verification.
Tests & Examples
src/test/java/io/mailtrap/api/stats/StatsImplTest.java, examples/java/io/mailtrap/examples/general/StatsExample.java
Added comprehensive test suite validating all Stats API methods with mocked HTTP client and predefined responses. Added example demonstrating StatsExample usage showing how to configure client, build filters, and invoke all stats endpoints.

Sequence Diagram

sequenceDiagram
    participant Client as Client Code
    participant Factory as MailtrapClientFactory
    participant StatsImpl as StatsImpl
    participant HTTPClient as HTTP Client
    participant Response as Statistics Response

    Client->>Factory: Create MailtrapClient with config
    Factory->>Factory: Create StatsImpl with config
    Factory->>Factory: Create MailtrapGeneralApi with StatsImpl
    Client->>Client: Build StatsFilter (dates, categories)
    Client->>StatsImpl: Call getStats(accountId, filter)
    StatsImpl->>StatsImpl: Build URL: /accounts/{accountId}/stats
    StatsImpl->>StatsImpl: Build query params from filter
    StatsImpl->>HTTPClient: GET with query params
    HTTPClient->>Response: Fetch from API
    Response-->>HTTPClient: SendingStatsResponse JSON
    HTTPClient-->>StatsImpl: Parsed SendingStatsResponse
    StatsImpl-->>Client: Return SendingStatsResponse
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PR #39: Modifies client wiring and MailtrapClientFactory with similar integration pattern for new API components.
  • PR #36: Updates MailtrapClientFactory and client constructor signatures by adding new API modules and updating dependency injection patterns.

Suggested reviewers

  • mklocek
  • IgorDobryn

Poem

🐰 Hop, hop, hop! Stats have come to play,
Filtered dates and domains on their way,
Delivery counts and open rates so bright,
StatsImpl hops through the client's night,
Version 1.2, a version done right! 📊✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.74% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description is incomplete compared to the template. While Motivation and Changes sections are present, they are minimal/vague, and the How to test section lacks detail. Critical sections like testing instructions and proper change itemization are missing or underdeveloped. Expand the Changes section with specific items (new Stats interface, StatsFilter, StatsImpl, response models, integration into MailtrapGeneralApi) and provide detailed testing instructions or checkboxes, or explain why testing is N/A more thoroughly.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely summarizes the main change: releasing version 1.2.0 with Stats API support, matching the substantial API additions in the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch release-v1.2.0

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.

@piobeny piobeny requested a review from mklocek March 9, 2026 10:07
@piobeny piobeny changed the base branch from main to stats-api March 10, 2026 13:22
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/io/mailtrap/client/api/MailtrapGeneralApi.java (1)

15-23: ⚠️ Potential issue | 🔴 Critical

The breaking constructor change remains unresolved; suggested fix was not applied.

The code still uses @RequiredArgsConstructor on line 17 without a backward-compatible 4-arg constructor overload. Adding the stats field to this annotation changes the generated public constructor from 4 args to 5 args. External consumers upgrading to 1.2.0 and calling new MailtrapGeneralApi(accountAccesses, accounts, billing, permissions) will encounter a compilation error or NoSuchMethodError, making this a breaking change for a minor version.

To preserve API compatibility, either remove @RequiredArgsConstructor and provide explicit constructors (including a 4-arg overload that delegates to the 5-arg version), or bump to version 2.0.0.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/io/mailtrap/client/api/MailtrapGeneralApi.java` around lines 15
- 23, The class MailtrapGeneralApi currently uses `@RequiredArgsConstructor` which
generates a 5-arg public constructor after adding the stats field and thereby
breaks the existing 4-arg API; restore backward compatibility by removing
`@RequiredArgsConstructor` and adding explicit constructors: a public
four-argument constructor MailtrapGeneralApi(AccountAccesses, Accounts, Billing,
Permissions) that delegates to a new five-argument constructor, and a public
five-argument constructor MailtrapGeneralApi(AccountAccesses, Accounts, Billing,
Permissions, Stats) that initializes all fields (or keep the five-arg and have
the four-arg call it with a default/null stats), ensuring both constructors
exist to avoid breaking callers of MailtrapGeneralApi(accountAccesses, accounts,
billing, permissions).
🧹 Nitpick comments (3)
src/main/java/io/mailtrap/api/stats/StatsFilter.java (1)

8-16: Prefer LocalDate for the date filters.

startDate and endDate as raw Strings create a type-safety gap; the builder currently passes them directly to query parameters without format validation. Exposing LocalDate here aligns with the pattern used elsewhere in the codebase for temporal data and ensures date-range bounds are type-checked at compile time.

♻️ Proposed refactor
-import java.util.List;
+import java.time.LocalDate;
+import java.util.List;
@@
-    private String startDate;
-    private String endDate;
+    private LocalDate startDate;
+    private LocalDate endDate;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/io/mailtrap/api/stats/StatsFilter.java` around lines 8 - 16,
Change StatsFilter.startDate and endDate from String to java.time.LocalDate to
gain type safety: update the class fields in StatsFilter, replace the imports
(add java.time.LocalDate), keep Lombok annotations (`@Data`, `@Builder`, etc.), and
adjust any call sites or builders that pass String values so they parse/format
using LocalDate.parse(...) or accept LocalDate directly; also update any
serialization or query-parameter construction logic that previously relied on
raw strings to format the LocalDate (e.g., .toString() or a DateTimeFormatter)
before sending to downstream queries.
src/main/java/io/mailtrap/model/response/stats/SendingStatGroupResponse.java (1)

9-18: name is the group field key, not the grouped value.

Line 16 stores keys like "sending_domain_id" / "category" in name, while the actual grouped value ends up in value. Since this is a brand-new public model, I’d make that explicit now with something like groupField / groupValue before 1.2.0 locks the API shape.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/io/mailtrap/model/response/stats/SendingStatGroupResponse.java`
around lines 9 - 18, The current SendingStatGroupResponse stores the group key
in name and the grouped value in value, which is confusing for a public model;
rename the fields name -> groupField and value -> groupValue (update their
declarations and usages) and adjust the JsonAnySetter method
setDynamicField(String key, Object value) to set groupField/groupValue (keeping
stats as-is), and update any getters/setters/serializers referencing name or
value to the new identifiers so the public API clearly reflects "group field" vs
"group value".
src/test/java/io/mailtrap/api/stats/StatsImplTest.java (1)

28-40: Add one test that exercises the list-based filters.

This suite only validates start_date/end_date. StatsImpl also serializes sending_domain_ids[], sending_streams[], categories[], and email_service_providers[], and TestHttpClient requires an exact query-param match. A regression in any of those keys would still pass here, even though list-filter serialization is part of the new API surface.

Also applies to: 51-144

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/test/java/io/mailtrap/api/stats/StatsImplTest.java` around lines 28 - 40,
The tests only cover the start_date/end_date query params but miss verifying
list-based filters; add a new unit test in StatsImplTest that calls the
StatsImpl method (via the same setup using TestHttpClient) with non-empty lists
for sending_domain_ids, sending_streams, categories, and email_service_providers
so the client serializes keys like sending_domain_ids[], sending_streams[],
categories[], and email_service_providers[]; register a matching DataMock in the
TestHttpClient (use the same baseUrl endpoints as in init) that includes the
exact list query params and assert the request was matched, ensuring StatsImpl’s
serialization logic for those parameters is exercised (refer to StatsImpl,
StatsImplTest, TestHttpClient, and DataMock to locate relevant code).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/main/java/io/mailtrap/client/api/MailtrapGeneralApi.java`:
- Around line 15-23: The class MailtrapGeneralApi currently uses
`@RequiredArgsConstructor` which generates a 5-arg public constructor after adding
the stats field and thereby breaks the existing 4-arg API; restore backward
compatibility by removing `@RequiredArgsConstructor` and adding explicit
constructors: a public four-argument constructor
MailtrapGeneralApi(AccountAccesses, Accounts, Billing, Permissions) that
delegates to a new five-argument constructor, and a public five-argument
constructor MailtrapGeneralApi(AccountAccesses, Accounts, Billing, Permissions,
Stats) that initializes all fields (or keep the five-arg and have the four-arg
call it with a default/null stats), ensuring both constructors exist to avoid
breaking callers of MailtrapGeneralApi(accountAccesses, accounts, billing,
permissions).

---

Nitpick comments:
In `@src/main/java/io/mailtrap/api/stats/StatsFilter.java`:
- Around line 8-16: Change StatsFilter.startDate and endDate from String to
java.time.LocalDate to gain type safety: update the class fields in StatsFilter,
replace the imports (add java.time.LocalDate), keep Lombok annotations (`@Data`,
`@Builder`, etc.), and adjust any call sites or builders that pass String values
so they parse/format using LocalDate.parse(...) or accept LocalDate directly;
also update any serialization or query-parameter construction logic that
previously relied on raw strings to format the LocalDate (e.g., .toString() or a
DateTimeFormatter) before sending to downstream queries.

In
`@src/main/java/io/mailtrap/model/response/stats/SendingStatGroupResponse.java`:
- Around line 9-18: The current SendingStatGroupResponse stores the group key in
name and the grouped value in value, which is confusing for a public model;
rename the fields name -> groupField and value -> groupValue (update their
declarations and usages) and adjust the JsonAnySetter method
setDynamicField(String key, Object value) to set groupField/groupValue (keeping
stats as-is), and update any getters/setters/serializers referencing name or
value to the new identifiers so the public API clearly reflects "group field" vs
"group value".

In `@src/test/java/io/mailtrap/api/stats/StatsImplTest.java`:
- Around line 28-40: The tests only cover the start_date/end_date query params
but miss verifying list-based filters; add a new unit test in StatsImplTest that
calls the StatsImpl method (via the same setup using TestHttpClient) with
non-empty lists for sending_domain_ids, sending_streams, categories, and
email_service_providers so the client serializes keys like sending_domain_ids[],
sending_streams[], categories[], and email_service_providers[]; register a
matching DataMock in the TestHttpClient (use the same baseUrl endpoints as in
init) that includes the exact list query params and assert the request was
matched, ensuring StatsImpl’s serialization logic for those parameters is
exercised (refer to StatsImpl, StatsImplTest, TestHttpClient, and DataMock to
locate relevant code).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8b5fd282-a6b4-4f26-aa55-7d2d6c2444e1

📥 Commits

Reviewing files that changed from the base of the PR and between 1136e25 and ed5e9a0.

📒 Files selected for processing (17)
  • README.md
  • docs/getting-started.md
  • examples/java/io/mailtrap/examples/general/StatsExample.java
  • pom.xml
  • src/main/java/io/mailtrap/api/stats/Stats.java
  • src/main/java/io/mailtrap/api/stats/StatsFilter.java
  • src/main/java/io/mailtrap/api/stats/StatsImpl.java
  • src/main/java/io/mailtrap/client/api/MailtrapGeneralApi.java
  • src/main/java/io/mailtrap/factory/MailtrapClientFactory.java
  • src/main/java/io/mailtrap/model/response/stats/SendingStatGroupResponse.java
  • src/main/java/io/mailtrap/model/response/stats/SendingStatsResponse.java
  • src/test/java/io/mailtrap/api/stats/StatsImplTest.java
  • src/test/resources/api/stats/byCategory.json
  • src/test/resources/api/stats/byDate.json
  • src/test/resources/api/stats/byDomain.json
  • src/test/resources/api/stats/byEmailServiceProvider.json
  • src/test/resources/api/stats/getStats.json

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.

2 participants