Skip to content

Conversation

@dr-3lo
Copy link
Collaborator

@dr-3lo dr-3lo commented Sep 25, 2025

Motivation

In scope of #96: update all Contacts API class names to remove plural identifiers (including file names).

Changes

  • Updated all Contacts API class names to remove plural identifiers (including file names).
  • Updated XML documentation comments to correctly describe where getters and setters are used for class properties.
  • Simplified validation rules where possible.
  • Updated XML documentation for validators to include more information about boundaries.
  • Updated Contact Field Data Type constants in accordance to its value (this change requires suppression of CA1720)
  • Corrected validation in ctor of UpdateContactFieldRequest
  • Updated example project files to remove leftover Dependabot changes.

How to test

  • run all unit and integration tests

Summary by CodeRabbit

  • Refactor

    • Public API types and resources renamed from plural “Contacts…” to singular “Contact…” (breaking change).
  • New Features

    • Added typed ContactField data types and an Update request for contact fields.
    • Added creation endpoints/resources for contact imports, contact lists, contact fields, and contact events.
  • Validation

    • Strengthened validators: name/merge-tag max lengths, import size limits (1–50,000), and refined event name rule.
  • Documentation

    • Updated wording and logs to singular “Contact”.
  • Chores

    • Simplified example project dependencies.

- Updated all Contacts API class names to remove plural identifiers (including file names).
- Updated XML documentation comments to correctly describe where getters and setters are used for class properties.
- Simplified validation rules where possible.
- Updated XML documentation for validators to include more information about boundaries.
- Updated Contact Field Data Type constanst in accordance to its value (required suppression of CA1720)
- Correted validation in ctor of UpdateContactFieldRequest
- One more round of simplification of validation rules.
- Some updates in XML documentation
@coderabbitai
Copy link

coderabbitai bot commented Sep 25, 2025

Walkthrough

Renames plural "Contacts*" APIs and types to singular "Contact*" across abstractions, implementations, examples, and tests; adds singular interfaces/models/requests/validators/resources and removes their plural counterparts; simplifies many example project files; updates XML suppressions and documentation.

Changes

Cohort / File(s) Summary
Abstractions — Contact Events
src/Mailtrap.Abstractions/ContactEvents/*
Added IContactEventCollectionResource; removed IContactsEventCollectionResource; renamed ContactsEventContactEvent, CreateContactsEventRequestCreateContactEventRequest; renamed validator and adjusted Name rule.
Abstractions — Contact Fields
src/Mailtrap.Abstractions/ContactFields/*
Added IContactFieldCollectionResource, IContactFieldResource; removed plural interfaces; renamed ContactsFieldContactField; replaced ContactsFieldDataType with ContactFieldDataType; added UpdateContactFieldRequest; updated/renamed validators; removed old validator files.
Abstractions — Contact Imports
src/Mailtrap.Abstractions/ContactImports/*
Renamed IContactsImportCollectionResourceIContactImportCollectionResource, IContactsImportResourceIContactImportResource; ContactsImportContactImport; ContactsImportRequestCreateContactImportRequest; added CreateContactImportRequestValidator; removed old validator.
Abstractions — Contact Lists
src/Mailtrap.Abstractions/ContactLists/*
IContactsListCollectionResourceIContactListCollectionResource, IContactsListResourceIContactListResource; ContactsListContactList; ContactsListRequestContactListRequest; added ContactListRequestValidator; removed old validator.
Abstractions — Contacts root
src/Mailtrap.Abstractions/Contacts/*, GlobalSuppressions.cs
Updated IContactCollectionResource methods to return singular resource interfaces; added CancellationToken to GetAll; updated assembly suppressions (CA1716/CA1720) and docs.
Implementations — Resources (added)
src/Mailtrap/{ContactEvents,ContactFields,ContactImports,ContactLists}/*
Added singular resource implementations: ContactEventCollectionResource, ContactFieldCollectionResource, ContactFieldResource, ContactImportCollectionResource, ContactImportResource, ContactListCollectionResource, ContactListResource.
Implementations — Resources (removed)
src/Mailtrap/{ContactEvents,ContactFields,ContactImports,ContactLists}/*
Removed plural resource implementations: ContactsEventCollectionResource, ContactsFieldCollectionResource, ContactsFieldResource, ContactsImportCollectionResource, ContactsImportResource, ContactsListCollectionResource, ContactsListResource.
Contacts implementation
src/Mailtrap/Contacts/*
Updated factory-return types from plural to singular resource interfaces; doc summary tweaks in ContactCollectionResource/ContactResource.
Models / Requests / Validators
src/Mailtrap.Abstractions/**
Many public types renamed from plural to singular (records, requests, enums); added ContactFieldDataType, ContactImportStatus, validators for create/update requests; removed corresponding plural types/validators.
Examples — Code
examples/.../ContactEvents/Program.cs, .../ContactFields/Program.cs, .../ContactImports/Program.cs, .../ContactLists/Program.cs
Updated example usages, variable names, and logs to singular types and request names; control flow unchanged.
Examples — Project files
examples/*/*.csproj, build/mailtrap-example.props
Simplified many example csproj files to minimal SDK-only projects; removed explicit PackageReference and many appsettings.json content entries; minor props Include tweak.
Tests — Integration & Unit
tests/Mailtrap.{IntegrationTests,UnitTests}/...
Renamed test fixtures and updated all test usages to singular types, resources, requests, enums, and validators; adjusted a few expected exceptions and test assertions to new types.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Client
  participant Coll as IContactFieldCollectionResource
  participant Res as IContactFieldResource
  note over Dev,Coll: Contact Field flow (singular API)

  Dev->>Coll: GetAll()
  Coll-->>Dev: IList<ContactField>

  Dev->>Coll: Create(CreateContactFieldRequest)
  Coll-->>Dev: ContactField

  Dev->>Coll: (FieldId) Field(fieldId)
  Coll-->>Dev: Res
  Dev->>Res: GetDetails()
  Res-->>Dev: ContactField

  Dev->>Res: Update(UpdateContactFieldRequest)
  Res-->>Dev: ContactField

  Dev->>Res: Delete()
  Res-->>Dev: (status)
Loading
sequenceDiagram
  autonumber
  actor Dev as Client
  participant Coll as IContactImportCollectionResource
  participant Res as IContactImportResource
  note over Dev,Coll: Contact Import flow (singular API)

  Dev->>Coll: Create(CreateContactImportRequest)
  Coll-->>Dev: ContactImport { Id }

  Dev->>Coll: Import(Id)
  Coll-->>Dev: Res
  Dev->>Res: GetDetails()
  Res-->>Dev: ContactImport { Status, Counts }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • zhaparoff
  • mklocek
  • vittorius

Poem

Hop hop, I renamed with care and zest,
Plurals trimmed — now singular's best.
Fields, lists, imports, events in line,
Validators tuned, resources fine.
csproj neat, the rabbit says: “well-done!” 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive The pull request title “Feature- Contacts API” is overly generic and does not clearly indicate the specific change of renaming Contacts API classes from plural to singular identifiers, making it difficult to understand the primary modification at a glance. Consider revising the title to explicitly describe the main change, for example “Rename Contacts API classes to singular identifiers”, to clearly communicate the refactoring performed.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed The pull request description follows the repository’s template by providing clear Motivation, Changes, and How to test sections that outline the scope, detailed list of updates, and verification steps, and the omission of an Images and GIFs section is acceptable for a non-UI change.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/96-Contacts-api

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.

@dr-3lo dr-3lo linked an issue Sep 25, 2025 that may be closed by this pull request
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: 8

Caution

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

⚠️ Outside diff range comments (2)
src/Mailtrap.Abstractions/ContactFields/Validators/UpdateContactFieldRequestValidator.cs (1)

21-23: Whitespace-only values pass validation; tighten checks to IsNullOrWhiteSpace.

Currently, " " (spaces) satisfies the "at least one provided" rule and passes MaximumLength checks. Use IsNullOrWhiteSpace to prevent that.

Apply:

-            .Must(x => !string.IsNullOrEmpty(x.Name) ||
-                       !string.IsNullOrEmpty(x.MergeTag))
+            .Must(x => !string.IsNullOrWhiteSpace(x.Name) ||
+                       !string.IsNullOrWhiteSpace(x.MergeTag))
             .WithMessage(x => $"At least one of {nameof(x.Name)} or {nameof(x.MergeTag)} must be provided.");
@@
-        When(x => !string.IsNullOrEmpty(x.Name), () =>
+        When(x => !string.IsNullOrWhiteSpace(x.Name), () =>
         {
             RuleFor(r => r.Name).MaximumLength(80);
         });
@@
-        When(x => !string.IsNullOrEmpty(x.MergeTag), () =>
+        When(x => !string.IsNullOrWhiteSpace(x.MergeTag), () =>
         {
             RuleFor(r => r.MergeTag).MaximumLength(80);
         });

Also applies to: 25-33

src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (1)

99-110: Bump major version for the package
ContactCollectionResource is updated to match the new GetAll signature, but this change breaks any external IContactCollectionResource implementers. Increment to the next major version and document the interface change in your release notes.

🧹 Nitpick comments (23)
tests/Mailtrap.UnitTests/ContactLists/Requests/ContactListRequestTests.cs (1)

5-5: Rename alignment LGTM; consider adding positive-boundary tests.

Renames and usages align with the new singular API. To tighten coverage, consider adding:

  • A test that length 1 and 255 names validate successfully.
  • Optionally, a test for the parameterless ctor (if supported) followed by setting Name and validating.

Also applies to: 10-10, 18-18, 30-30, 41-41

src/Mailtrap.Abstractions/ContactFields/Models/ContactFieldDataType.cs (1)

1-52: Renamed enum values may be breaking; consider temporary aliases and local CA1720 suppression.

  • Renaming Number→Integer and FloatValue→Float is source-breaking for consumers. If feasible, add obsolete aliases for one release to smooth migration.
  • Prefer scoping CA1720 suppression to this type/members to avoid masking future violations elsewhere.

Example alias additions:

@@
     public static readonly ContactFieldDataType Boolean = Define("boolean");
@@
     public static readonly ContactFieldDataType Date = Define("date");
+
+    // Backwards-compatibility aliases (to be removed in next major)
+    [Obsolete("Use ContactFieldDataType.Integer instead.")]
+    public static readonly ContactFieldDataType Number = Integer;
+    [Obsolete("Use ContactFieldDataType.Float instead.")]
+    public static readonly ContactFieldDataType FloatValue = Float;

Would you like me to add localized suppression attributes for CA1720 on the alias members only?

tests/Mailtrap.UnitTests/ContactEvents/Requests/CreateContactEventRequestTests.cs (1)

5-5: Rename updates and coverage LGTM; consider adding whitespace-only name case.

Tests align with the new type name and cover boundaries/defensive copy. Consider adding a case for a whitespace-only name to assert invalid input, depending on desired semantics.

Also applies to: 10-10, 23-23, 41-41, 53-53, 67-67, 75-75, 85-85, 98-98

src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (1)

86-98: Document ArgumentNullException for invalid contactId
Add

<exception cref="ArgumentNullException">Thrown when <paramref name="contactId"/> is null or whitespace.</exception>

to the XML docs of Events(string contactId) in src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs. Verified that IContactEventCollectionResource does not expose a GetAll method.

src/Mailtrap.Abstractions/ContactImports/Validators/ContactImportRequestValidator.cs (3)

22-26: Add null-safe bounds check and clearer message.

Future changes to cascade behavior could invoke .Must with null. Make the predicate null-safe and add a boundary message.

-        RuleFor(r => r.Contacts)
-            .Cascade(CascadeMode.Stop)
-            .NotEmpty()
-            .Must(list => list.Count is >= MinContactPerRequest and <= MaxContactPerRequest);
+        RuleFor(r => r.Contacts)
+            .Cascade(CascadeMode.Stop)
+            .NotEmpty()
+            .Must(list => list is { Count: >= MinContactPerRequest and <= MaxContactPerRequest })
+            .WithMessage($"Contacts count must be between {MinContactPerRequest} and {MaxContactPerRequest}.");

27-30: Guard RuleForEach against null.

Ensure per-item rules don’t run when the collection is null.

-        RuleForEach(r => r.Contacts)
-            .NotNull()
-            .SetValidator(ContactRequestValidator.Instance);
+        RuleForEach(r => r.Contacts)
+            .NotNull()
+            .SetValidator(ContactRequestValidator.Instance)
+            .When(r => r.Contacts is not null);

8-16: Naming: consider aligning validator name with the request.

To reduce ambiguity with the per-item ContactImportRequest, consider renaming to CreateContactImportRequestValidator.

tests/Mailtrap.IntegrationTests/ContactFields/ContactFieldsIntegrationTests.cs (3)

5-5: Consider renaming the file to match the class

File name is ContactFieldsIntegrationTests.cs while the class is ContactFieldIntegrationTests. For consistency, consider singularizing the file name as well.


126-128: Minor naming nit: singularize local variable

contactsFieldName → contactFieldName for consistency with singular naming across the PR.

-        var contactsFieldName = TestContext.CurrentContext.Random.GetString(length);
-        var request = new CreateContactFieldRequest(contactsFieldName, "validMergeTag", ContactFieldDataType.Integer);
+        var contactFieldName = TestContext.CurrentContext.Random.GetString(length);
+        var request = new CreateContactFieldRequest(contactFieldName, "validMergeTag", ContactFieldDataType.Integer);

166-168: Minor naming nit: singularize local variable

contactsMergeTag → contactMergeTag for consistency with singular naming.

-        var contactsMergeTag = TestContext.CurrentContext.Random.GetString(length);
-        var request = new CreateContactFieldRequest("validName", contactsMergeTag, ContactFieldDataType.Float);
+        var contactMergeTag = TestContext.CurrentContext.Random.GetString(length);
+        var request = new CreateContactFieldRequest("validName", contactMergeTag, ContactFieldDataType.Float);
tests/Mailtrap.UnitTests/ContactFields/Requests/UpdateContactFieldRequestTests.cs (1)

183-195: Optional: add boundary-pass coverage

You test failure at 81; consider adding a pass case at exactly 80 to cover the upper boundary explicitly.

     public void Validate_ShouldFail_WhenProvidedNameLengthIsInvalid([Values(81)] int length)
     {
         // Arrange
         var name = TestContext.CurrentContext.Random.GetString(length);
         var request = new UpdateContactFieldRequest(name, "validMergeTag");
@@
         result.IsValid.Should().BeFalse();
     }
+    
+    [Test]
+    public void Validate_ShouldPass_WhenProvidedNameLengthIsOnUpperBoundary()
+    {
+        var request = new UpdateContactFieldRequest(TestContext.CurrentContext.Random.GetString(80), "validMergeTag");
+        request.Validate().IsValid.Should().BeTrue();
+    }
src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactFieldRequest.cs (1)

51-54: Optional: include paramName for the exception

Providing a paramName improves diagnostics. Picking one is arbitrary; consider using nameof(name).

-        if (string.IsNullOrEmpty(name) && string.IsNullOrEmpty(mergeTag))
-        {
-            throw new ArgumentException($"At least one of {nameof(name)} or {nameof(mergeTag)} must be provided.");
-        }
+        if (string.IsNullOrEmpty(name) && string.IsNullOrEmpty(mergeTag))
+        {
+            throw new ArgumentException($"At least one of {nameof(name)} or {nameof(mergeTag)} must be provided.", nameof(name));
+        }
src/Mailtrap.Abstractions/ContactEvents/Validators/CreateContactEventRequestValidator.cs (1)

21-29: Harden validation: reject whitespace-only names and param keys; extract max lengths as constants.
FluentValidation’s NotEmpty() allows whitespace; enforce non-whitespace and de-dup max values for maintainability.

Apply:

 public sealed class CreateContactEventRequestValidator : AbstractValidator<CreateContactEventRequest>
 {
+    private const int MaxNameLength = 255;
+    private const int MaxParamKeyLength = 255;
@@
-        RuleFor(r => r.Name).NotEmpty().MaximumLength(255);
+        RuleFor(r => r.Name)
+            .Cascade(CascadeMode.Stop)
+            .NotEmpty()
+            .Must(static s => !string.IsNullOrWhiteSpace(s))
+            .WithMessage("'Name' must not be whitespace.")
+            .MaximumLength(MaxNameLength);
@@
-            RuleForEach(r => r.Params.Keys)
+            RuleForEach(r => r.Params.Keys)
                 .Cascade(CascadeMode.Stop)
-                .NotEmpty()
-                .MaximumLength(255);
+                .NotEmpty()
+                .Must(static s => !string.IsNullOrWhiteSpace(s))
+                .WithMessage("Parameter keys must not be whitespace.")
+                .MaximumLength(MaxParamKeyLength);
tests/Mailtrap.IntegrationTests/ContactEvents/ContactEventIntegrationTests.cs (1)

93-101: Boundary test aligns with validator (256 > 255). Consider adding whitespace validation tests.
Name length failure is covered; add whitespace-only cases for Name.

Example tests to add:

[Test]
public async Task Create_ShouldFailValidation_WhenNameIsWhitespace()
{
    var request = new CreateContactEventRequest("   ");
    var client = /* setup as in other tests */;
    var act = () => client.Account(_accountId).Contacts().Events(_contactId).Create(request);
    await act.Should().ThrowAsync<RequestValidationException>();
}

[Test]
public async Task Create_ShouldFailValidation_WhenParamTagIsWhitespace()
{
    var request = new CreateContactEventRequest("valid", new Dictionary<string, object?> { { "   ", 1 } });
    var client = /* setup as in other tests */;
    var act = () => client.Account(_accountId).Contacts().Events(_contactId).Create(request);
    await act.Should().ThrowAsync<RequestValidationException>();
}
tests/Mailtrap.IntegrationTests/ContactLists/ContactsListIntegrationTests.cs (3)

5-5: Rename test class to singular for consistency with PR objective.
Recommend: ContactListIntegrationTests. Consider renaming the file accordingly.

-internal sealed class ContactsListIntegrationTests
+internal sealed class ContactListIntegrationTests

127-131: Minor naming nit: singular variable name.
Use contactListName to align with singular type names.

-        var contactsListName = TestContext.CurrentContext.Random.GetString(length);
+        var contactListName = TestContext.CurrentContext.Random.GetString(length);
         var request = new ContactListRequest
         {
-            Name = contactsListName
+            Name = contactListName
         };

212-214: Minor naming nit: singular variable name.
Use updatedContactListName for consistency.

-        var updatedContactsListName = TestContext.CurrentContext.Random.GetString(10);
-        var request = new ContactListRequest(updatedContactsListName);
+        var updatedContactListName = TestContext.CurrentContext.Random.GetString(10);
+        var request = new ContactListRequest(updatedContactListName);
src/Mailtrap.Abstractions/ContactImports/Models/ContactImport.cs (1)

18-18: Prefer init-only setter for response immutability

If consumers shouldn’t mutate response models, make Id init-only.

-    public long Id { get; set; }
+    public long Id { get; init; }
examples/Mailtrap.Example.ContactLists/Program.cs (3)

45-47: Use property initializer for ContactListRequest and singular variable name

Safer across API changes and aligns with singular naming.

-        // Create contact list
-        var createContactsListRequest = new ContactListRequest("MyFirstContactList");
-        contactList = await contactListsResource.Create(createContactsListRequest);
+        // Create contact list
+        var createContactListRequest = new ContactListRequest { Name = "MyFirstContactList" };
+        contactList = await contactListsResource.Create(createContactListRequest);

62-64: Use property initializer for update request

Keeps example resilient if ctor overloads change.

-    var updateContactListRequest = new ContactListRequest("updatedContactList");
+    var updateContactListRequest = new ContactListRequest { Name = "updatedContactList" };
     ContactList updateContactListResponse = await contactListResource.Update(updateContactListRequest);

36-37: Pass CancellationToken to async calls in examples
All GetAll/Create/Update/Delete methods now accept an optional CancellationToken—update the Program.cs example calls (e.g., await contactListsResource.GetAll(ct)) to include ct.

examples/Mailtrap.Example.ContactFields/Program.cs (1)

36-37: Pass a CancellationToken to async resource calls
All GetAll, Create, GetDetails, Update and Delete methods expose an optional CancellationToken parameter—provide one to enable cancellation:

var ct = CancellationToken.None; // or use a CancellationTokenSource.Token
IList<ContactField> contactFields = await contactFieldsResource.GetAll(ct);
var created = await contactFieldsResource.Create(createContactFieldRequest, ct);
var details = await contactFieldResource.GetDetails(ct);
var updated = await contactFieldResource.Update(updateContactFieldRequest, ct);
await contactFieldResource.Delete(ct);
tests/Mailtrap.UnitTests/Contacts/ContactCollectionResourceTests.cs (1)

191-203: Add negative tests for Events(contactId) argument validation

  • Test null, empty and whitespace contactId to lock in expected ArgumentNullException/ArgumentException.
  • IContactEventCollectionResource correctly exposes no GetAll/list method for events.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a610692 and 8c80488.

📒 Files selected for processing (71)
  • examples/Mailtrap.Example.ContactEvents/Program.cs (1 hunks)
  • examples/Mailtrap.Example.ContactFields/Program.cs (1 hunks)
  • examples/Mailtrap.Example.ContactImports/Program.cs (2 hunks)
  • examples/Mailtrap.Example.ContactLists/Program.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactEvents/IContactEventCollectionResource.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactEvents/IContactsEventCollectionResource.cs (0 hunks)
  • src/Mailtrap.Abstractions/ContactEvents/Models/ContactEvent.cs (3 hunks)
  • src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (3 hunks)
  • src/Mailtrap.Abstractions/ContactEvents/Validators/CreateContactEventRequestValidator.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactFields/IContactFieldCollectionResource.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactFields/IContactFieldResource.cs (2 hunks)
  • src/Mailtrap.Abstractions/ContactFields/IContactsFieldCollectionResource.cs (0 hunks)
  • src/Mailtrap.Abstractions/ContactFields/Models/ContactField.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactFields/Models/ContactFieldDataType.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactFields/Models/ContactsFieldDataType.cs (0 hunks)
  • src/Mailtrap.Abstractions/ContactFields/Requests/CreateContactFieldRequest.cs (4 hunks)
  • src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactFieldRequest.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactsFieldRequest.cs (0 hunks)
  • src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactFieldRequestValidator.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactsFieldRequestValidator.cs (0 hunks)
  • src/Mailtrap.Abstractions/ContactFields/Validators/UpdateContactFieldRequestValidator.cs (2 hunks)
  • src/Mailtrap.Abstractions/ContactImports/IContactImportCollectionResource.cs (2 hunks)
  • src/Mailtrap.Abstractions/ContactImports/IContactImportResource.cs (2 hunks)
  • src/Mailtrap.Abstractions/ContactImports/Models/ContactImport.cs (3 hunks)
  • src/Mailtrap.Abstractions/ContactImports/Models/ContactImportStatus.cs (5 hunks)
  • src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (4 hunks)
  • src/Mailtrap.Abstractions/ContactImports/Validators/ContactImportRequestValidator.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactImports/Validators/ContactsImportRequestValidator.cs (0 hunks)
  • src/Mailtrap.Abstractions/ContactLists/IContactListCollectionResource.cs (3 hunks)
  • src/Mailtrap.Abstractions/ContactLists/IContactListResource.cs (2 hunks)
  • src/Mailtrap.Abstractions/ContactLists/Models/ContactList.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactLists/Requests/ContactListRequest.cs (4 hunks)
  • src/Mailtrap.Abstractions/ContactLists/Validators/ContactListRequestValidator.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactLists/Validators/ContactsListRequestValidator.cs (0 hunks)
  • src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (1 hunks)
  • src/Mailtrap.Abstractions/Contacts/IContactResource.cs (1 hunks)
  • src/Mailtrap.Abstractions/Contacts/Validators/ContactRequestValidator.cs (1 hunks)
  • src/Mailtrap.Abstractions/GlobalSuppressions.cs (1 hunks)
  • src/Mailtrap/ContactEvents/ContactEventCollectionResource.cs (1 hunks)
  • src/Mailtrap/ContactEvents/ContactsEventCollectionResource.cs (0 hunks)
  • src/Mailtrap/ContactFields/ContactFieldCollectionResource.cs (1 hunks)
  • src/Mailtrap/ContactFields/ContactFieldResource.cs (1 hunks)
  • src/Mailtrap/ContactFields/ContactsFieldCollectionResource.cs (0 hunks)
  • src/Mailtrap/ContactFields/ContactsFieldResource.cs (0 hunks)
  • src/Mailtrap/ContactImports/ContactImportCollectionResource.cs (1 hunks)
  • src/Mailtrap/ContactImports/ContactImportResource.cs (1 hunks)
  • src/Mailtrap/ContactImports/ContactsImportCollectionResource.cs (0 hunks)
  • src/Mailtrap/ContactImports/ContactsImportResource.cs (0 hunks)
  • src/Mailtrap/ContactLists/ContactListCollectionResource.cs (1 hunks)
  • src/Mailtrap/ContactLists/ContactListResource.cs (1 hunks)
  • src/Mailtrap/ContactLists/ContactsListCollectionResource.cs (0 hunks)
  • src/Mailtrap/ContactLists/ContactsListResource.cs (0 hunks)
  • src/Mailtrap/Contacts/ContactCollectionResource.cs (1 hunks)
  • src/Mailtrap/Contacts/ContactResource.cs (1 hunks)
  • tests/Mailtrap.IntegrationTests/ContactEvents/ContactEventIntegrationTests.cs (5 hunks)
  • tests/Mailtrap.IntegrationTests/ContactFields/ContactFieldsIntegrationTests.cs (9 hunks)
  • tests/Mailtrap.IntegrationTests/ContactImports/ContactImportIntegrationTests.cs (7 hunks)
  • tests/Mailtrap.IntegrationTests/ContactLists/ContactsListIntegrationTests.cs (6 hunks)
  • tests/Mailtrap.UnitTests/ContactEvents/ContactEventCollectionResourceTests.cs (4 hunks)
  • tests/Mailtrap.UnitTests/ContactEvents/Requests/CreateContactEventRequestTests.cs (7 hunks)
  • tests/Mailtrap.UnitTests/ContactFields/ContactFieldCollectionResourceTests.cs (4 hunks)
  • tests/Mailtrap.UnitTests/ContactFields/ContactFieldResourceTests.cs (4 hunks)
  • tests/Mailtrap.UnitTests/ContactFields/Requests/CreateContactFieldRequestTests.cs (6 hunks)
  • tests/Mailtrap.UnitTests/ContactFields/Requests/UpdateContactFieldRequestTests.cs (14 hunks)
  • tests/Mailtrap.UnitTests/ContactImports/ContactImportCollectionResourceTests.cs (4 hunks)
  • tests/Mailtrap.UnitTests/ContactImports/ContactImportResourceTests.cs (4 hunks)
  • tests/Mailtrap.UnitTests/ContactImports/Requests/CreateContactImportRequestTests.cs (5 hunks)
  • tests/Mailtrap.UnitTests/ContactLists/ContactListCollectionResourceTests.cs (4 hunks)
  • tests/Mailtrap.UnitTests/ContactLists/ContactListResourceTests.cs (4 hunks)
  • tests/Mailtrap.UnitTests/ContactLists/Requests/ContactListRequestTests.cs (3 hunks)
  • tests/Mailtrap.UnitTests/Contacts/ContactCollectionResourceTests.cs (11 hunks)
💤 Files with no reviewable changes (14)
  • src/Mailtrap/ContactImports/ContactsImportResource.cs
  • src/Mailtrap.Abstractions/ContactFields/Models/ContactsFieldDataType.cs
  • src/Mailtrap/ContactLists/ContactsListCollectionResource.cs
  • src/Mailtrap.Abstractions/ContactImports/Validators/ContactsImportRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactsFieldRequest.cs
  • src/Mailtrap/ContactLists/ContactsListResource.cs
  • src/Mailtrap.Abstractions/ContactFields/IContactsFieldCollectionResource.cs
  • src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactsFieldRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactEvents/IContactsEventCollectionResource.cs
  • src/Mailtrap.Abstractions/ContactLists/Validators/ContactsListRequestValidator.cs
  • src/Mailtrap/ContactFields/ContactsFieldCollectionResource.cs
  • src/Mailtrap/ContactFields/ContactsFieldResource.cs
  • src/Mailtrap/ContactEvents/ContactsEventCollectionResource.cs
  • src/Mailtrap/ContactImports/ContactsImportCollectionResource.cs
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#152
File: src/Mailtrap.Abstractions/ContactEvents/IContactsEventsCollectionResource.cs:6-6
Timestamp: 2025-09-23T10:44:34.331Z
Learning: The Contact Events API backend does not provide a GetAll/list method - only Create is supported. The ContactsEventCollectionResource implementation should not include a GetAll method.
📚 Learning: 2025-09-23T10:44:34.331Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#152
File: src/Mailtrap.Abstractions/ContactEvents/IContactsEventsCollectionResource.cs:6-6
Timestamp: 2025-09-23T10:44:34.331Z
Learning: The Contact Events API backend does not provide a GetAll/list method - only Create is supported. The ContactsEventCollectionResource implementation should not include a GetAll method.

Applied to files:

  • src/Mailtrap.Abstractions/ContactEvents/IContactEventCollectionResource.cs
  • src/Mailtrap/ContactEvents/ContactEventCollectionResource.cs
  • examples/Mailtrap.Example.ContactEvents/Program.cs
  • tests/Mailtrap.UnitTests/Contacts/ContactCollectionResourceTests.cs
  • tests/Mailtrap.UnitTests/ContactEvents/ContactEventCollectionResourceTests.cs
📚 Learning: 2025-09-10T17:01:49.270Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#142
File: src/Mailtrap.Abstractions/ContactImports/Validators/ContactsImportRequestValidator.cs:27-30
Timestamp: 2025-09-10T17:01:49.270Z
Learning: In ContactsImportRequestValidator, ContactRequestValidator.Instance is used to validate ContactImportRequest items because ContactImportRequest inherits from ContactRequest and doesn't introduce additional validation rules that would require a separate validator.

Applied to files:

  • src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactFieldRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactLists/Validators/ContactListRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactFields/Validators/UpdateContactFieldRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs
  • src/Mailtrap.Abstractions/ContactLists/Requests/ContactListRequest.cs
  • tests/Mailtrap.UnitTests/ContactImports/Requests/CreateContactImportRequestTests.cs
  • src/Mailtrap.Abstractions/ContactEvents/Validators/CreateContactEventRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactImports/Validators/ContactImportRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactFields/Requests/CreateContactFieldRequest.cs
📚 Learning: 2025-09-22T08:20:57.431Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#150
File: src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactsFieldRequestValidator.cs:8-8
Timestamp: 2025-09-22T08:20:57.431Z
Learning: In the Mailtrap.Abstractions project, global using statements in GlobalUsings.cs make types from Mailtrap.ContactFields.Requests (and other ContactFields namespaces) globally available, so explicit using statements are not needed in individual files like validators.

Applied to files:

  • src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactFieldRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactLists/Validators/ContactListRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactFields/Models/ContactField.cs
  • src/Mailtrap.Abstractions/ContactFields/Validators/UpdateContactFieldRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactFieldRequest.cs
  • src/Mailtrap.Abstractions/GlobalSuppressions.cs
  • src/Mailtrap.Abstractions/Contacts/Validators/ContactRequestValidator.cs
  • tests/Mailtrap.UnitTests/ContactLists/Requests/ContactListRequestTests.cs
  • examples/Mailtrap.Example.ContactFields/Program.cs
  • src/Mailtrap.Abstractions/ContactImports/Validators/ContactImportRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactFields/Requests/CreateContactFieldRequest.cs
📚 Learning: 2025-09-10T14:37:39.872Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#142
File: src/Mailtrap/Contacts/ContactCollectionResource.cs:18-19
Timestamp: 2025-09-10T14:37:39.872Z
Learning: The Import method in ContactCollectionResource does not need explicit importId validation because this validation is already implemented in the URI model's Append method when handling long parameters.

Applied to files:

  • tests/Mailtrap.IntegrationTests/ContactImports/ContactImportIntegrationTests.cs
  • src/Mailtrap/ContactImports/ContactImportCollectionResource.cs
  • src/Mailtrap/ContactImports/ContactImportResource.cs
  • src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs
  • src/Mailtrap.Abstractions/ContactImports/IContactImportCollectionResource.cs
  • tests/Mailtrap.UnitTests/ContactImports/ContactImportResourceTests.cs
  • examples/Mailtrap.Example.ContactImports/Program.cs
  • src/Mailtrap/Contacts/ContactCollectionResource.cs
  • src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs
  • tests/Mailtrap.UnitTests/ContactImports/ContactImportCollectionResourceTests.cs
  • tests/Mailtrap.UnitTests/Contacts/ContactCollectionResourceTests.cs
🧬 Code graph analysis (47)
src/Mailtrap.Abstractions/ContactEvents/IContactEventCollectionResource.cs (5)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (3)
  • IContactEventCollectionResource (97-97)
  • Task (110-110)
  • Task (127-127)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactEventCollectionResource (34-35)
src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (1)
  • CreateContactEventRequest (53-66)
src/Mailtrap.Abstractions/ContactEvents/IContactsEventCollectionResource.cs (1)
  • IContactsEventCollectionResource (6-24)
src/Mailtrap/ContactEvents/ContactsEventCollectionResource.cs (1)
  • ContactsEventCollectionResource (6-13)
src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactFieldRequestValidator.cs (2)
src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactsFieldRequestValidator.cs (1)
  • CreateContactsFieldRequestValidator (8-23)
src/Mailtrap.Abstractions/ContactFields/Validators/UpdateContactsFieldRequestValidator.cs (1)
  • UpdateContactsFieldRequestValidator (8-35)
src/Mailtrap.Abstractions/ContactImports/IContactImportResource.cs (3)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (3)
  • IContactImportResource (32-32)
  • Task (110-110)
  • Task (127-127)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactImportResource (19-20)
src/Mailtrap.Abstractions/ContactImports/IContactImportCollectionResource.cs (1)
  • Task (28-28)
src/Mailtrap/ContactFields/ContactFieldCollectionResource.cs (4)
tests/Mailtrap.UnitTests/ContactFields/ContactFieldCollectionResourceTests.cs (1)
  • ContactFieldCollectionResource (51-51)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactFieldCollectionResource (28-29)
src/Mailtrap.Abstractions/ContactFields/IContactFieldCollectionResource.cs (2)
  • Task (19-19)
  • Task (36-36)
src/Mailtrap/ContactFields/ContactsFieldCollectionResource.cs (1)
  • ContactsFieldCollectionResource (6-16)
tests/Mailtrap.IntegrationTests/ContactImports/ContactImportIntegrationTests.cs (1)
src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (1)
  • CreateContactImportRequest (39-47)
src/Mailtrap.Abstractions/ContactLists/Validators/ContactListRequestValidator.cs (2)
src/Mailtrap.Abstractions/ContactLists/Requests/ContactListRequest.cs (1)
  • ContactListRequest (45-45)
src/Mailtrap.Abstractions/ContactLists/Validators/ContactsListRequestValidator.cs (1)
  • ContactsListRequestValidator (8-22)
src/Mailtrap.Abstractions/ContactFields/Models/ContactFieldDataType.cs (2)
src/Mailtrap.Abstractions/Core/Models/StringEnum.cs (1)
  • StringEnum (41-49)
src/Mailtrap.Abstractions/ContactFields/Models/ContactsFieldDataType.cs (1)
  • ContactsFieldDataType (6-52)
src/Mailtrap/ContactImports/ContactImportCollectionResource.cs (4)
tests/Mailtrap.UnitTests/ContactImports/ContactImportCollectionResourceTests.cs (1)
  • ContactImportCollectionResource (51-51)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactImportCollectionResource (16-17)
src/Mailtrap.Abstractions/ContactImports/IContactImportCollectionResource.cs (1)
  • Task (28-28)
src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (1)
  • CreateContactImportRequest (39-47)
tests/Mailtrap.UnitTests/ContactEvents/Requests/CreateContactEventRequestTests.cs (1)
src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (1)
  • CreateContactEventRequest (53-66)
src/Mailtrap/ContactEvents/ContactEventCollectionResource.cs (5)
tests/Mailtrap.UnitTests/ContactEvents/ContactEventCollectionResourceTests.cs (1)
  • ContactEventCollectionResource (52-52)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactEventCollectionResource (34-35)
src/Mailtrap.Abstractions/ContactEvents/IContactEventCollectionResource.cs (1)
  • Task (23-23)
src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (1)
  • CreateContactEventRequest (53-66)
src/Mailtrap/ContactEvents/ContactsEventCollectionResource.cs (1)
  • ContactsEventCollectionResource (6-13)
src/Mailtrap/ContactImports/ContactImportResource.cs (3)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactImportResource (19-20)
src/Mailtrap.Abstractions/ContactImports/IContactImportResource.cs (1)
  • Task (19-19)
src/Mailtrap/ContactImports/ContactsImportResource.cs (1)
  • ContactsImportResource (6-13)
src/Mailtrap/ContactLists/ContactListCollectionResource.cs (4)
tests/Mailtrap.UnitTests/ContactLists/ContactListCollectionResourceTests.cs (1)
  • ContactListCollectionResource (51-51)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactListCollectionResource (22-23)
src/Mailtrap.Abstractions/ContactLists/IContactListCollectionResource.cs (2)
  • Task (19-19)
  • Task (36-36)
src/Mailtrap/ContactLists/ContactsListCollectionResource.cs (1)
  • ContactsListCollectionResource (6-16)
src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (1)
src/Mailtrap.Abstractions/ContactImports/Validators/ContactImportRequestValidator.cs (2)
  • ContactImportRequestValidator (8-31)
  • ContactImportRequestValidator (20-30)
src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactFieldRequest.cs (3)
src/Mailtrap.Abstractions/ContactFields/Requests/CreateContactFieldRequest.cs (2)
  • JsonConstructor (67-77)
  • ValidationResult (80-85)
src/Mailtrap.Abstractions/ContactFields/Validators/UpdateContactFieldRequestValidator.cs (2)
  • UpdateContactFieldRequestValidator (8-35)
  • UpdateContactFieldRequestValidator (18-34)
src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactsFieldRequest.cs (1)
  • UpdateContactsFieldRequest (6-48)
src/Mailtrap.Abstractions/ContactImports/Models/ContactImportStatus.cs (1)
src/Mailtrap.Abstractions/Core/Models/StringEnum.cs (1)
  • StringEnum (41-49)
src/Mailtrap.Abstractions/ContactLists/Requests/ContactListRequest.cs (1)
src/Mailtrap.Abstractions/ContactLists/Validators/ContactListRequestValidator.cs (2)
  • ContactListRequestValidator (8-22)
  • ContactListRequestValidator (18-21)
tests/Mailtrap.UnitTests/ContactFields/ContactFieldResourceTests.cs (1)
src/Mailtrap/ContactFields/ContactFieldResource.cs (2)
  • ContactFieldResource (6-16)
  • ContactFieldResource (8-9)
src/Mailtrap.Abstractions/ContactLists/IContactListResource.cs (3)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (3)
  • IContactListResource (58-58)
  • Task (110-110)
  • Task (127-127)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactListResource (25-26)
src/Mailtrap.Abstractions/ContactLists/IContactListCollectionResource.cs (2)
  • Task (19-19)
  • Task (36-36)
src/Mailtrap.Abstractions/ContactImports/IContactImportCollectionResource.cs (4)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (3)
  • IContactImportCollectionResource (15-15)
  • Task (110-110)
  • Task (127-127)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactImportCollectionResource (16-17)
src/Mailtrap.Abstractions/ContactImports/IContactImportResource.cs (1)
  • Task (19-19)
src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (1)
  • CreateContactImportRequest (39-47)
src/Mailtrap/ContactLists/ContactListResource.cs (4)
tests/Mailtrap.UnitTests/ContactLists/ContactListResourceTests.cs (1)
  • ContactListResource (51-51)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactListResource (25-26)
src/Mailtrap.Abstractions/ContactLists/IContactListResource.cs (3)
  • Task (19-19)
  • Task (36-36)
  • Task (56-56)
src/Mailtrap/ContactLists/ContactsListResource.cs (1)
  • ContactsListResource (6-16)
src/Mailtrap.Abstractions/ContactFields/IContactFieldCollectionResource.cs (4)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (3)
  • IContactFieldCollectionResource (67-67)
  • Task (110-110)
  • Task (127-127)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactFieldCollectionResource (28-29)
src/Mailtrap.Abstractions/ContactFields/IContactFieldResource.cs (3)
  • Task (19-19)
  • Task (36-36)
  • Task (56-56)
src/Mailtrap.Abstractions/ContactFields/IContactsFieldCollectionResource.cs (1)
  • IContactsFieldCollectionResource (6-37)
tests/Mailtrap.UnitTests/ContactLists/ContactListCollectionResourceTests.cs (1)
src/Mailtrap/ContactLists/ContactListCollectionResource.cs (2)
  • ContactListCollectionResource (6-16)
  • ContactListCollectionResource (8-9)
tests/Mailtrap.UnitTests/ContactImports/Requests/CreateContactImportRequestTests.cs (1)
src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (1)
  • CreateContactImportRequest (39-47)
src/Mailtrap.Abstractions/ContactLists/IContactListCollectionResource.cs (3)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (3)
  • IContactListCollectionResource (41-41)
  • Task (110-110)
  • Task (127-127)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactListCollectionResource (22-23)
src/Mailtrap.Abstractions/ContactLists/IContactListResource.cs (3)
  • Task (19-19)
  • Task (36-36)
  • Task (56-56)
tests/Mailtrap.IntegrationTests/ContactEvents/ContactEventIntegrationTests.cs (1)
src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (1)
  • CreateContactEventRequest (53-66)
examples/Mailtrap.Example.ContactLists/Program.cs (3)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (2)
  • IContactListCollectionResource (41-41)
  • IContactListResource (58-58)
src/Mailtrap/Contacts/ContactCollectionResource.cs (2)
  • IContactListCollectionResource (22-23)
  • IContactListResource (25-26)
src/Mailtrap.Abstractions/ContactLists/Requests/ContactListRequest.cs (1)
  • ContactListRequest (45-45)
src/Mailtrap/ContactFields/ContactFieldResource.cs (3)
tests/Mailtrap.UnitTests/ContactFields/ContactFieldResourceTests.cs (1)
  • ContactFieldResource (51-51)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactFieldResource (31-32)
src/Mailtrap.Abstractions/ContactFields/IContactFieldResource.cs (3)
  • Task (19-19)
  • Task (36-36)
  • Task (56-56)
tests/Mailtrap.UnitTests/ContactImports/ContactImportResourceTests.cs (1)
src/Mailtrap/ContactImports/ContactImportResource.cs (2)
  • ContactImportResource (6-13)
  • ContactImportResource (8-9)
src/Mailtrap.Abstractions/ContactEvents/Validators/CreateContactEventRequestValidator.cs (1)
src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (1)
  • CreateContactEventRequest (53-66)
tests/Mailtrap.UnitTests/ContactLists/Requests/ContactListRequestTests.cs (1)
src/Mailtrap.Abstractions/ContactLists/Requests/ContactListRequest.cs (1)
  • ContactListRequest (45-45)
tests/Mailtrap.UnitTests/ContactFields/ContactFieldCollectionResourceTests.cs (1)
src/Mailtrap/ContactFields/ContactFieldCollectionResource.cs (2)
  • ContactFieldCollectionResource (6-16)
  • ContactFieldCollectionResource (8-9)
examples/Mailtrap.Example.ContactImports/Program.cs (3)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (2)
  • IContactImportCollectionResource (15-15)
  • IContactImportResource (32-32)
src/Mailtrap/Contacts/ContactCollectionResource.cs (2)
  • IContactImportCollectionResource (16-17)
  • IContactImportResource (19-20)
src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (1)
  • CreateContactImportRequest (39-47)
examples/Mailtrap.Example.ContactFields/Program.cs (2)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (2)
  • IContactFieldCollectionResource (67-67)
  • IContactFieldResource (84-84)
src/Mailtrap/Contacts/ContactCollectionResource.cs (2)
  • IContactFieldCollectionResource (28-29)
  • IContactFieldResource (31-32)
src/Mailtrap/Contacts/ContactCollectionResource.cs (8)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (7)
  • IContactImportCollectionResource (15-15)
  • IContactImportResource (32-32)
  • IContactListCollectionResource (41-41)
  • IContactListResource (58-58)
  • IContactFieldCollectionResource (67-67)
  • IContactFieldResource (84-84)
  • IContactEventCollectionResource (97-97)
src/Mailtrap/ContactImports/ContactImportCollectionResource.cs (2)
  • ContactImportCollectionResource (6-13)
  • ContactImportCollectionResource (8-9)
src/Mailtrap/ContactImports/ContactImportResource.cs (2)
  • ContactImportResource (6-13)
  • ContactImportResource (8-9)
src/Mailtrap/ContactLists/ContactListCollectionResource.cs (2)
  • ContactListCollectionResource (6-16)
  • ContactListCollectionResource (8-9)
src/Mailtrap/ContactLists/ContactListResource.cs (2)
  • ContactListResource (6-16)
  • ContactListResource (8-9)
src/Mailtrap/ContactFields/ContactFieldCollectionResource.cs (2)
  • ContactFieldCollectionResource (6-16)
  • ContactFieldCollectionResource (8-9)
src/Mailtrap/ContactFields/ContactFieldResource.cs (2)
  • ContactFieldResource (6-16)
  • ContactFieldResource (8-9)
src/Mailtrap/ContactEvents/ContactEventCollectionResource.cs (2)
  • ContactEventCollectionResource (6-13)
  • ContactEventCollectionResource (8-9)
tests/Mailtrap.UnitTests/ContactLists/ContactListResourceTests.cs (1)
src/Mailtrap/ContactLists/ContactListResource.cs (2)
  • ContactListResource (6-16)
  • ContactListResource (8-9)
src/Mailtrap.Abstractions/ContactFields/IContactFieldResource.cs (3)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (3)
  • IContactFieldResource (84-84)
  • Task (110-110)
  • Task (127-127)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactFieldResource (31-32)
src/Mailtrap.Abstractions/ContactFields/IContactFieldCollectionResource.cs (2)
  • Task (19-19)
  • Task (36-36)
src/Mailtrap.Abstractions/ContactImports/Validators/ContactImportRequestValidator.cs (2)
src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (1)
  • CreateContactImportRequest (39-47)
src/Mailtrap.Abstractions/Contacts/Validators/ContactRequestValidator.cs (2)
  • ContactRequestValidator (8-22)
  • ContactRequestValidator (18-21)
src/Mailtrap.Abstractions/ContactFields/Requests/CreateContactFieldRequest.cs (1)
src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactFieldRequestValidator.cs (2)
  • CreateContactFieldRequestValidator (8-23)
  • CreateContactFieldRequestValidator (18-22)
tests/Mailtrap.UnitTests/ContactFields/Requests/CreateContactFieldRequestTests.cs (1)
tests/Mailtrap.IntegrationTests/ContactFields/ContactFieldsIntegrationTests.cs (9)
  • Test (34-73)
  • Test (75-117)
  • Test (119-157)
  • Test (159-197)
  • Test (199-238)
  • Test (240-283)
  • Test (285-323)
  • Test (325-363)
  • Test (365-399)
tests/Mailtrap.UnitTests/ContactFields/Requests/UpdateContactFieldRequestTests.cs (2)
tests/Mailtrap.IntegrationTests/ContactFields/ContactFieldsIntegrationTests.cs (9)
  • Test (34-73)
  • Test (75-117)
  • Test (119-157)
  • Test (159-197)
  • Test (199-238)
  • Test (240-283)
  • Test (285-323)
  • Test (325-363)
  • Test (365-399)
tests/Mailtrap.UnitTests/ContactFields/Requests/CreateContactFieldRequestTests.cs (7)
  • Test (7-20)
  • Test (32-38)
  • Test (40-46)
  • Test (48-54)
  • Test (56-62)
  • Test (64-70)
  • Test (72-78)
tests/Mailtrap.IntegrationTests/ContactLists/ContactsListIntegrationTests.cs (1)
src/Mailtrap.Abstractions/ContactLists/Requests/ContactListRequest.cs (1)
  • ContactListRequest (45-45)
examples/Mailtrap.Example.ContactEvents/Program.cs (3)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (1)
  • IContactEventCollectionResource (97-97)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactEventCollectionResource (34-35)
src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (1)
  • CreateContactEventRequest (53-66)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (3)
src/Mailtrap/Accounts/AccountResource.cs (1)
  • IContactCollectionResource (56-57)
src/Mailtrap.Abstractions/Accounts/IAccountResource.cs (1)
  • IContactCollectionResource (143-143)
src/Mailtrap/Contacts/ContactCollectionResource.cs (7)
  • IContactImportCollectionResource (16-17)
  • IContactImportResource (19-20)
  • IContactListCollectionResource (22-23)
  • IContactListResource (25-26)
  • IContactFieldCollectionResource (28-29)
  • IContactFieldResource (31-32)
  • IContactEventCollectionResource (34-35)
tests/Mailtrap.UnitTests/ContactImports/ContactImportCollectionResourceTests.cs (1)
src/Mailtrap/ContactImports/ContactImportCollectionResource.cs (2)
  • ContactImportCollectionResource (6-13)
  • ContactImportCollectionResource (8-9)
tests/Mailtrap.UnitTests/Contacts/ContactCollectionResourceTests.cs (3)
tests/Mailtrap.UnitTests/TestExtensions/ResourceValidator.cs (2)
  • ResourceValidator (4-16)
  • Validate (6-15)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (7)
  • IContactImportCollectionResource (15-15)
  • IContactImportResource (32-32)
  • IContactListCollectionResource (41-41)
  • IContactListResource (58-58)
  • IContactFieldCollectionResource (67-67)
  • IContactFieldResource (84-84)
  • IContactEventCollectionResource (97-97)
src/Mailtrap/Contacts/ContactCollectionResource.cs (7)
  • IContactImportCollectionResource (16-17)
  • IContactImportResource (19-20)
  • IContactListCollectionResource (22-23)
  • IContactListResource (25-26)
  • IContactFieldCollectionResource (28-29)
  • IContactFieldResource (31-32)
  • IContactEventCollectionResource (34-35)
src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (2)
src/Mailtrap.Abstractions/Core/Extensions/Ensure.cs (1)
  • Ensure (9-106)
src/Mailtrap.Abstractions/ContactEvents/Validators/CreateContactEventRequestValidator.cs (2)
  • CreateContactEventRequestValidator (9-31)
  • CreateContactEventRequestValidator (19-30)
tests/Mailtrap.UnitTests/ContactEvents/ContactEventCollectionResourceTests.cs (1)
src/Mailtrap/ContactEvents/ContactEventCollectionResource.cs (2)
  • ContactEventCollectionResource (6-13)
  • ContactEventCollectionResource (8-9)

- Corrected command to copy "appsettings.json" to the output directory for all example projects except Factory.
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: 7

🧹 Nitpick comments (1)
build/mailtrap-example.props (1)

5-6: No functional change; optionally drop UseCommonOutputDirectory for single‑TFM examples

Given examples are centralized via this props (per prior learning), with a single TargetFramework (net9.0) this property is redundant. Safe to remove for clarity.

-    <UseCommonOutputDirectory>false</UseCommonOutputDirectory>
     <OutputType>Exe</OutputType>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c80488 and 6a9ccbc.

📒 Files selected for processing (19)
  • build/mailtrap-example.props (2 hunks)
  • examples/Mailtrap.Example.Account/Mailtrap.Example.Account.csproj (1 hunks)
  • examples/Mailtrap.Example.AccountAccess/Mailtrap.Example.AccountAccess.csproj (1 hunks)
  • examples/Mailtrap.Example.ApiUsage/Mailtrap.Example.ApiUsage.csproj (1 hunks)
  • examples/Mailtrap.Example.Attachment/Mailtrap.Example.Attachment.csproj (1 hunks)
  • examples/Mailtrap.Example.Billing/Mailtrap.Example.Billing.csproj (1 hunks)
  • examples/Mailtrap.Example.Contact/Mailtrap.Example.Contact.csproj (1 hunks)
  • examples/Mailtrap.Example.ContactEvents/Mailtrap.Example.ContactEvents.csproj (1 hunks)
  • examples/Mailtrap.Example.ContactFields/Mailtrap.Example.ContactFields.csproj (1 hunks)
  • examples/Mailtrap.Example.ContactImports/Mailtrap.Example.ContactImports.csproj (1 hunks)
  • examples/Mailtrap.Example.ContactLists/Mailtrap.Example.ContactLists.csproj (1 hunks)
  • examples/Mailtrap.Example.DependencyInjection/Mailtrap.Example.DependencyInjection.csproj (0 hunks)
  • examples/Mailtrap.Example.Email.Send/Mailtrap.Example.Email.Send.csproj (1 hunks)
  • examples/Mailtrap.Example.Factory/Mailtrap.Example.Factory.csproj (1 hunks)
  • examples/Mailtrap.Example.Inbox/Mailtrap.Example.Inbox.csproj (1 hunks)
  • examples/Mailtrap.Example.Permissions/Mailtrap.Example.Permissions.csproj (1 hunks)
  • examples/Mailtrap.Example.Project/Mailtrap.Example.Project.csproj (1 hunks)
  • examples/Mailtrap.Example.SendingDomain/Mailtrap.Example.SendingDomain.csproj (1 hunks)
  • examples/Mailtrap.Example.TestingMessage/Mailtrap.Example.TestingMessage.csproj (1 hunks)
💤 Files with no reviewable changes (1)
  • examples/Mailtrap.Example.DependencyInjection/Mailtrap.Example.DependencyInjection.csproj
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-09-22T09:52:44.054Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#150
File: examples/Mailtrap.Example.ContactFields/Mailtrap.Example.ContactFields.csproj:1-10
Timestamp: 2025-09-22T09:52:44.054Z
Learning: In the Mailtrap .NET client project, example projects use a centralized `mailtrap-example.props` file to define common MSBuild properties like TargetFramework, so individual .csproj files don't need to explicitly declare these properties.

Applied to files:

  • examples/Mailtrap.Example.ContactEvents/Mailtrap.Example.ContactEvents.csproj
  • examples/Mailtrap.Example.ContactFields/Mailtrap.Example.ContactFields.csproj
  • examples/Mailtrap.Example.AccountAccess/Mailtrap.Example.AccountAccess.csproj
  • examples/Mailtrap.Example.Billing/Mailtrap.Example.Billing.csproj
  • examples/Mailtrap.Example.ContactImports/Mailtrap.Example.ContactImports.csproj
  • build/mailtrap-example.props
  • examples/Mailtrap.Example.Inbox/Mailtrap.Example.Inbox.csproj
  • examples/Mailtrap.Example.Permissions/Mailtrap.Example.Permissions.csproj
  • examples/Mailtrap.Example.SendingDomain/Mailtrap.Example.SendingDomain.csproj
  • examples/Mailtrap.Example.Contact/Mailtrap.Example.Contact.csproj
  • examples/Mailtrap.Example.ContactLists/Mailtrap.Example.ContactLists.csproj
  • examples/Mailtrap.Example.Attachment/Mailtrap.Example.Attachment.csproj
  • examples/Mailtrap.Example.Factory/Mailtrap.Example.Factory.csproj
  • examples/Mailtrap.Example.ApiUsage/Mailtrap.Example.ApiUsage.csproj
  • examples/Mailtrap.Example.Email.Send/Mailtrap.Example.Email.Send.csproj
  • examples/Mailtrap.Example.Account/Mailtrap.Example.Account.csproj
  • examples/Mailtrap.Example.Project/Mailtrap.Example.Project.csproj
  • examples/Mailtrap.Example.TestingMessage/Mailtrap.Example.TestingMessage.csproj
📚 Learning: 2025-09-22T08:20:57.431Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#150
File: src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactsFieldRequestValidator.cs:8-8
Timestamp: 2025-09-22T08:20:57.431Z
Learning: In the Mailtrap.Abstractions project, global using statements in GlobalUsings.cs make types from Mailtrap.ContactFields.Requests (and other ContactFields namespaces) globally available, so explicit using statements are not needed in individual files like validators.

Applied to files:

  • examples/Mailtrap.Example.ContactEvents/Mailtrap.Example.ContactEvents.csproj
  • examples/Mailtrap.Example.ContactFields/Mailtrap.Example.ContactFields.csproj
  • examples/Mailtrap.Example.AccountAccess/Mailtrap.Example.AccountAccess.csproj
  • examples/Mailtrap.Example.Billing/Mailtrap.Example.Billing.csproj
  • examples/Mailtrap.Example.ContactImports/Mailtrap.Example.ContactImports.csproj
  • examples/Mailtrap.Example.Inbox/Mailtrap.Example.Inbox.csproj
  • examples/Mailtrap.Example.Permissions/Mailtrap.Example.Permissions.csproj
  • examples/Mailtrap.Example.SendingDomain/Mailtrap.Example.SendingDomain.csproj
  • examples/Mailtrap.Example.Contact/Mailtrap.Example.Contact.csproj
  • examples/Mailtrap.Example.ContactLists/Mailtrap.Example.ContactLists.csproj
  • examples/Mailtrap.Example.ApiUsage/Mailtrap.Example.ApiUsage.csproj
  • examples/Mailtrap.Example.Email.Send/Mailtrap.Example.Email.Send.csproj
  • examples/Mailtrap.Example.Account/Mailtrap.Example.Account.csproj
  • examples/Mailtrap.Example.TestingMessage/Mailtrap.Example.TestingMessage.csproj
📚 Learning: 2025-09-04T08:53:06.292Z
Learnt from: vittorius
PR: railsware/mailtrap-dotnet#139
File: src/Mailtrap.Abstractions/Contacts/Models/Contact.cs:67-70
Timestamp: 2025-09-04T08:53:06.292Z
Learning: In the Mailtrap .NET client, DateTimeOffset properties should not use explicit JsonConverter attributes. All models in the codebase (TestingMessage, Inbox, EmailAttachment, etc.) handle DateTimeOffset properties using default JSON serialization without custom converters, and the Contact model should follow this same pattern for consistency.

Applied to files:

  • examples/Mailtrap.Example.ContactEvents/Mailtrap.Example.ContactEvents.csproj
  • examples/Mailtrap.Example.ContactFields/Mailtrap.Example.ContactFields.csproj
  • examples/Mailtrap.Example.Contact/Mailtrap.Example.Contact.csproj
  • examples/Mailtrap.Example.Attachment/Mailtrap.Example.Attachment.csproj
  • examples/Mailtrap.Example.Factory/Mailtrap.Example.Factory.csproj
  • examples/Mailtrap.Example.Email.Send/Mailtrap.Example.Email.Send.csproj
  • examples/Mailtrap.Example.TestingMessage/Mailtrap.Example.TestingMessage.csproj
📚 Learning: 2025-09-04T12:22:07.783Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#139
File: src/Mailtrap/Contacts/Requests/ContactRequestExtensions.cs:6-9
Timestamp: 2025-09-04T12:22:07.783Z
Learning: In the Mailtrap .NET client codebase, internal extension methods with non-nullable reference types don't require explicit null guards as the compiler provides compile-time safety and call sites are controlled within the codebase.

Applied to files:

  • examples/Mailtrap.Example.AccountAccess/Mailtrap.Example.AccountAccess.csproj
  • examples/Mailtrap.Example.Inbox/Mailtrap.Example.Inbox.csproj
  • examples/Mailtrap.Example.Permissions/Mailtrap.Example.Permissions.csproj
  • examples/Mailtrap.Example.SendingDomain/Mailtrap.Example.SendingDomain.csproj
  • examples/Mailtrap.Example.Contact/Mailtrap.Example.Contact.csproj
  • examples/Mailtrap.Example.Attachment/Mailtrap.Example.Attachment.csproj
  • examples/Mailtrap.Example.Factory/Mailtrap.Example.Factory.csproj
  • examples/Mailtrap.Example.Email.Send/Mailtrap.Example.Email.Send.csproj
  • examples/Mailtrap.Example.Account/Mailtrap.Example.Account.csproj
  • examples/Mailtrap.Example.Project/Mailtrap.Example.Project.csproj
  • examples/Mailtrap.Example.TestingMessage/Mailtrap.Example.TestingMessage.csproj
📚 Learning: 2025-09-04T08:53:30.332Z
Learnt from: vittorius
PR: railsware/mailtrap-dotnet#139
File: tests/Mailtrap.IntegrationTests/Contacts/GetDetails_Success.json:15-16
Timestamp: 2025-09-04T08:53:30.332Z
Learning: The DateTimeToTicksJsonConverter in the Mailtrap .NET client was redundant and problematic because System.Text.Json already handles DateTimeOffset serialization natively to ISO 8601 format, and other models in the codebase (TestingMessage, BillingUsagePeriod) successfully use DateTimeOffset properties without custom converters.

Applied to files:

  • examples/Mailtrap.Example.Billing/Mailtrap.Example.Billing.csproj
  • examples/Mailtrap.Example.Factory/Mailtrap.Example.Factory.csproj
📚 Learning: 2025-09-04T12:23:59.276Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#139
File: tests/Mailtrap.IntegrationTests/Contacts/Update_Success.json:16-17
Timestamp: 2025-09-04T12:23:59.276Z
Learning: Test fixtures in the Mailtrap .NET client should accurately represent the actual server response format and should not be modified to match client-side converters or serialization preferences.

Applied to files:

  • examples/Mailtrap.Example.Factory/Mailtrap.Example.Factory.csproj
  • examples/Mailtrap.Example.TestingMessage/Mailtrap.Example.TestingMessage.csproj
🔇 Additional comments (11)
examples/Mailtrap.Example.AccountAccess/Mailtrap.Example.AccountAccess.csproj (1)

1-1: Minimal SDK declaration looks good.

Switching the example project to rely on the shared props achieves the intended simplification without introducing new dependencies. 👍

examples/Mailtrap.Example.ApiUsage/Mailtrap.Example.ApiUsage.csproj (1)

1-1: Aligned with the shared props pattern.

Consistent with the other example projects—keeping only the SDK declaration and inheriting the shared settings keeps the project lean.

examples/Mailtrap.Example.ContactEvents/Mailtrap.Example.ContactEvents.csproj (1)

1-1: Minimal SDK-only project stays compatible with the shared mailtrap-example.props setup.
This fits the pattern we’ve used for other examples that import common settings from mailtrap-example.props, so no issues here.

examples/Mailtrap.Example.Inbox/Mailtrap.Example.Inbox.csproj (1)

1-1: Minimal .csproj is consistent with shared props setup

Given that the example projects pull their common MSBuild configuration (TargetFramework, references, etc.) from mailtrap-example.props, reducing this file to the SDK declaration keeps the project aligned with the rest of the examples and avoids redundant per-project settings. Looks good.

examples/Mailtrap.Example.Permissions/Mailtrap.Example.Permissions.csproj (1)

1-1: Minimal csproj aligns with shared props setup.

Given that the example projects inherit their common MSBuild configuration from mailtrap-example.props, this stripped-down Sdk declaration is sufficient. No further changes needed here.

examples/Mailtrap.Example.SendingDomain/Mailtrap.Example.SendingDomain.csproj (1)

1-1: Minimal project definition aligns with shared props.

Given the examples already pick up common settings via mailtrap-example.props, this trimmed SDK-only project file is consistent with the rest of the examples and keeps the setup clean.

examples/Mailtrap.Example.Attachment/Mailtrap.Example.Attachment.csproj (1)

1-1: Minimal SDK-only project is appropriate

Keeping this example .csproj to the bare SDK declaration works here since the shared mailtrap-example.props already injects the common settings and dependencies for examples (per our previous discussion). Nothing else required.

examples/Mailtrap.Example.Account/Mailtrap.Example.Account.csproj (1)

1-1: Minimal SDK declaration matches our example convention.

Line 1 keeps the project aligned with the shared mailtrap-example.props setup noted earlier, so dropping the local ItemGroups is fine.

examples/Mailtrap.Example.Project/Mailtrap.Example.Project.csproj (1)

1-1: Removing explicit Microsoft.Extensions.Http and System.Text.Json references is safe
No usages of those APIs (e.g. IHttpClientFactory, JsonSerializer or related namespaces) were found in examples/Mailtrap.Example.Project; the example build remains unaffected.

examples/Mailtrap.Example.ContactImports/Mailtrap.Example.ContactImports.csproj (1)

1-1: Central props covers dependencies and assets
The shared mailtrap-example.props adds Microsoft.Extensions.Hosting (transitively providing HTTP+JSON), the Mailtrap project reference, and copies appsettings.json, so the ContactImports example builds and runs as before.

build/mailtrap-example.props (1)

22-24: Change Include to Update for appsettings.json
SDK-style projects glob appsettings.json by default; using Update avoids duplicate None items.
build/mailtrap-example.props:22

-    <None Include="appsettings.json">
+    <None Update="appsettings.json">

Corrections from coderabbit review.
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: 3

Caution

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

⚠️ Outside diff range comments (1)
tests/Mailtrap.IntegrationTests/ContactFields/ContactFieldIntegrationTests.cs (1)

200-238: Restore the Contact Field resource path

The request URI constructed for detail calls still appends ContactsSegment (plural). After the renaming, the server expects contact in that path. Leaving the plural segment here will route every detail request to the old endpoint and return 404s.
Please switch the segment to the singular constant so the tests (and the SDK) hit /contact/fields/{id} again.

Apply this diff to fix the URI construction:

-            .Append(UrlSegmentsTestConstants.ContactsSegment)
+            .Append(UrlSegmentsTestConstants.ContactSegment)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a9ccbc and 3854107.

📒 Files selected for processing (8)
  • examples/Mailtrap.Example.ContactEvents/Program.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (3 hunks)
  • src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (4 hunks)
  • src/Mailtrap.Abstractions/ContactImports/Validators/CreateContactImportRequestValidator.cs (1 hunks)
  • src/Mailtrap.Abstractions/ContactLists/IContactListResource.cs (2 hunks)
  • src/Mailtrap.Abstractions/Contacts/Validators/ContactRequestValidator.cs (1 hunks)
  • tests/Mailtrap.IntegrationTests/ContactFields/ContactFieldIntegrationTests.cs (9 hunks)
  • tests/Mailtrap.IntegrationTests/ContactLists/ContactsListIntegrationTests.cs (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Mailtrap.Abstractions/Contacts/Validators/ContactRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactLists/IContactListResource.cs
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-09-10T17:01:49.270Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#142
File: src/Mailtrap.Abstractions/ContactImports/Validators/ContactsImportRequestValidator.cs:27-30
Timestamp: 2025-09-10T17:01:49.270Z
Learning: In ContactsImportRequestValidator, ContactRequestValidator.Instance is used to validate ContactImportRequest items because ContactImportRequest inherits from ContactRequest and doesn't introduce additional validation rules that would require a separate validator.

Applied to files:

  • src/Mailtrap.Abstractions/ContactImports/Validators/CreateContactImportRequestValidator.cs
  • src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs
📚 Learning: 2025-09-22T08:20:57.431Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#150
File: src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactsFieldRequestValidator.cs:8-8
Timestamp: 2025-09-22T08:20:57.431Z
Learning: In the Mailtrap.Abstractions project, global using statements in GlobalUsings.cs make types from Mailtrap.ContactFields.Requests (and other ContactFields namespaces) globally available, so explicit using statements are not needed in individual files like validators.

Applied to files:

  • src/Mailtrap.Abstractions/ContactImports/Validators/CreateContactImportRequestValidator.cs
  • tests/Mailtrap.IntegrationTests/ContactFields/ContactFieldIntegrationTests.cs
📚 Learning: 2025-09-25T09:57:25.835Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#153
File: src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactFieldRequest.cs:41-47
Timestamp: 2025-09-25T09:57:25.835Z
Learning: In UpdateContactFieldRequest, both the constructor and validator reject empty strings - the constructor throws ArgumentException when both name and mergeTag are null or empty, and the validation requires 1-80 character lengths for provided values. Empty strings are not allowed as valid input.

Applied to files:

  • src/Mailtrap.Abstractions/ContactImports/Validators/CreateContactImportRequestValidator.cs
  • tests/Mailtrap.IntegrationTests/ContactFields/ContactFieldIntegrationTests.cs
📚 Learning: 2025-09-04T12:23:59.276Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#139
File: tests/Mailtrap.IntegrationTests/Contacts/Update_Success.json:16-17
Timestamp: 2025-09-04T12:23:59.276Z
Learning: Test fixtures in the Mailtrap .NET client should accurately represent the actual server response format and should not be modified to match client-side converters or serialization preferences.

Applied to files:

  • tests/Mailtrap.IntegrationTests/ContactFields/ContactFieldIntegrationTests.cs
📚 Learning: 2025-09-10T14:37:39.872Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#142
File: src/Mailtrap/Contacts/ContactCollectionResource.cs:18-19
Timestamp: 2025-09-10T14:37:39.872Z
Learning: The Import method in ContactCollectionResource does not need explicit importId validation because this validation is already implemented in the URI model's Append method when handling long parameters.

Applied to files:

  • src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs
🧬 Code graph analysis (5)
tests/Mailtrap.IntegrationTests/ContactLists/ContactsListIntegrationTests.cs (1)
src/Mailtrap.Abstractions/ContactLists/Requests/ContactListRequest.cs (1)
  • ContactListRequest (45-45)
examples/Mailtrap.Example.ContactEvents/Program.cs (3)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (1)
  • IContactEventCollectionResource (97-97)
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
  • IContactEventCollectionResource (34-35)
src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (1)
  • CreateContactEventRequest (49-62)
src/Mailtrap.Abstractions/ContactImports/Validators/CreateContactImportRequestValidator.cs (3)
src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (1)
  • CreateContactImportRequest (39-47)
src/Mailtrap.Abstractions/Core/Extensions/Ensure.cs (1)
  • NotNull (18-33)
src/Mailtrap.Abstractions/Contacts/Validators/ContactRequestValidator.cs (2)
  • ContactRequestValidator (8-22)
  • ContactRequestValidator (18-21)
src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (2)
src/Mailtrap.Abstractions/Core/Extensions/Ensure.cs (1)
  • Ensure (9-106)
src/Mailtrap.Abstractions/ContactEvents/Validators/CreateContactEventRequestValidator.cs (2)
  • CreateContactEventRequestValidator (9-31)
  • CreateContactEventRequestValidator (19-30)
src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (1)
src/Mailtrap.Abstractions/ContactImports/Validators/CreateContactImportRequestValidator.cs (2)
  • CreateContactImportRequestValidator (8-31)
  • CreateContactImportRequestValidator (20-30)
🔇 Additional comments (9)
examples/Mailtrap.Example.ContactEvents/Program.cs (2)

55-64: LGTM! Plural to singular terminology updated successfully.

The changes correctly implement the singular naming convention by updating:

  • Variable name from contactsEventsResource to contactEventsResource
  • Class references from CreateContactsEventRequest to CreateContactEventRequest
  • Object reference from contactsEvent to contactEvent

The logic and functionality remain intact while aligning with the PR's objective to remove plural identifiers.


66-68: Fix logging terminology and label consistency.

The logging messages still have minor issues that need to be addressed per previous feedback:

  • Line 66: "Contact Event" should be "Contact event" (lowercase 'event')
  • Line 67: The label "ID" should be "Contact ID" to match the value being logged
  • Line 68: Good - the label now correctly matches the value being logged

Apply this diff to improve consistency:

-    logger.LogInformation("Contact Event created: {Name}", contactEvent.Name);
-    logger.LogInformation("ID: {ContactId}", contactEvent.ContactId);
+    logger.LogInformation("Contact event created: {Name}", contactEvent.Name);
+    logger.LogInformation("Contact ID: {ContactId}", contactEvent.ContactId);
     logger.LogInformation("Email: {ContactEmail}", contactEvent.ContactEmail);
src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (3)

35-40: Fix XML documentation parameter references.

The XML documentation contains incorrect <inheritdoc> parameter references:

  • Line 35: References name parameter correctly
  • Line 39: References params parameter but the path selector is malformed

Apply this diff to fix the XML documentation:

-    /// <param name="params">
-    /// <inheritdoc cref="CreateContactEventRequest" path="/param[@name=params]"/>.
-    /// </param>
+    /// <param name="params">
+    /// <inheritdoc cref="CreateContactEventRequest" path="/param[@name='params']"/>.
+    /// </param>

Note: The params parameter name needs proper quoting in the XPath selector.


49-62: LGTM! Constructor implementation is correct.

The constructor properly:

  • Uses @params parameter naming to avoid keyword conflicts
  • Validates the name parameter using Ensure.NotNullOrEmpty
  • Implements defensive copying for the params dictionary with optimization for existing Dictionary<string, object?> instances
  • Handles null params gracefully by leaving the default empty dictionary

The implementation aligns with the validation rules in CreateContactEventRequestValidator and follows good defensive programming practices.


76-78: LGTM! Validator reference updated correctly.

The validation method now correctly references CreateContactEventRequestValidator.Instance, which aligns with the renamed validator class. The validation implementation is consistent with the pattern used throughout the codebase.

src/Mailtrap.Abstractions/ContactImports/Validators/CreateContactImportRequestValidator.cs (2)

1-15: LGTM!

The validator class structure follows best practices with a static singleton instance for reuse and appropriate XML documentation.


10-11: Consider making constants public for API consumers.

The validation constants are currently internal but could be useful for API consumers who want to pre-validate their data before making API calls.

Consider changing the visibility:

-    public const int MaxContactPerRequest = 50_000;
-    public const int MinContactPerRequest = 1;
+    public const int MaxContactPerRequest = 50_000;
+    public const int MinContactPerRequest = 1;

Wait, I notice these constants are already public. The suggestion is not needed.

src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (2)

39-47: LGTM! Robust defensive copying implementation.

The constructor properly validates input with Ensure.NotNullOrEmpty and implements defensive copying to prevent post-construction mutation. The optimization for List<T> input is a good performance consideration.


28-30: Invoke CreateContactImportRequest.Validate() in the generic Create pipeline before API submission. I didn’t find any request.Validate() call in the Create<TRequest, TResponse> implementation—add it if missing.

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 (1)
src/Mailtrap.Abstractions/Contacts/Models/Contact.cs (1)

61-80: Drop the explicit DateTimeOffset converter for consistency.

While revisiting these docs, can we also align with our established pattern (per the earlier guidance on this model) and let System.Text.Json handle DateTimeOffset natively? The custom converter is the lone holdout across our models and leads to inconsistent payload shapes.

Apply this diff to remove the converter attributes:

-    [JsonConverter(typeof(DateTimeToUnixMsNullableJsonConverter))]
     public DateTimeOffset? CreatedAt { get; set; }

...

-    [JsonConverter(typeof(DateTimeToUnixMsNullableJsonConverter))]
     public DateTimeOffset? UpdatedAt { get; set; }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3854107 and 325831c.

📒 Files selected for processing (5)
  • src/Mailtrap.Abstractions/Contacts/Models/Contact.cs (6 hunks)
  • src/Mailtrap.Abstractions/Contacts/Requests/ContactRequest.cs (1 hunks)
  • src/Mailtrap.Abstractions/Contacts/Requests/UpdateContactRequest.cs (1 hunks)
  • src/Mailtrap.Abstractions/Contacts/Responses/ContactResponse.cs (1 hunks)
  • src/Mailtrap/Contacts/Requests/ContactRequestDto.cs (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • src/Mailtrap.Abstractions/Contacts/Requests/ContactRequest.cs
  • src/Mailtrap.Abstractions/Contacts/Responses/ContactResponse.cs
  • src/Mailtrap/Contacts/Requests/ContactRequestDto.cs
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-04T08:53:06.292Z
Learnt from: vittorius
PR: railsware/mailtrap-dotnet#139
File: src/Mailtrap.Abstractions/Contacts/Models/Contact.cs:67-70
Timestamp: 2025-09-04T08:53:06.292Z
Learning: In the Mailtrap .NET client, DateTimeOffset properties should not use explicit JsonConverter attributes. All models in the codebase (TestingMessage, Inbox, EmailAttachment, etc.) handle DateTimeOffset properties using default JSON serialization without custom converters, and the Contact model should follow this same pattern for consistency.

Applied to files:

  • src/Mailtrap.Abstractions/Contacts/Models/Contact.cs
🔇 Additional comments (2)
src/Mailtrap.Abstractions/Contacts/Requests/UpdateContactRequest.cs (1)

9-16: Docstring now matches the property accessor.

The XML comment accurately reflects the property's getter/setter. Looks good.

src/Mailtrap.Abstractions/Contacts/Models/Contact.cs (1)

9-27: Doc updates align with mutability.

Thanks for updating these summaries to reflect the writable properties—matches how consumers interact with Id and Email.

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 (3)
src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactFieldRequest.cs (3)

51-54: Confirm whitespace-only inputs policy (IsNullOrWhiteSpace?)

If whitespace-only strings should be treated as empty, switch to IsNullOrWhiteSpace here (and mirror in the validator for consistency).

-        if (string.IsNullOrEmpty(name) && string.IsNullOrEmpty(mergeTag))
+        if (string.IsNullOrWhiteSpace(name) && string.IsNullOrWhiteSpace(mergeTag))

16-16: Keep invariants: make properties init-only

Prevents mutating into an invalid state post-construction while keeping JSON and with-expressions working.

-    public string? Name { get; set; }
+    public string? Name { get; init; }
-    public string? MergeTag { get; set; }
+    public string? MergeTag { get; init; }

Also applies to: 26-26


61-66: Minor: expression-bodied Validate for brevity

No behavior change.

-    public ValidationResult Validate()
-    {
-        return UpdateContactFieldRequestValidator.Instance
-            .Validate(this)
-            .ToMailtrapValidationResult();
-    }
+    public ValidationResult Validate() =>
+        UpdateContactFieldRequestValidator.Instance
+            .Validate(this)
+            .ToMailtrapValidationResult();
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 325831c and 07d3291.

📒 Files selected for processing (1)
  • src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactFieldRequest.cs (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-22T08:20:57.431Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#150
File: src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactsFieldRequestValidator.cs:8-8
Timestamp: 2025-09-22T08:20:57.431Z
Learning: In the Mailtrap.Abstractions project, global using statements in GlobalUsings.cs make types from Mailtrap.ContactFields.Requests (and other ContactFields namespaces) globally available, so explicit using statements are not needed in individual files like validators.

Applied to files:

  • src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactFieldRequest.cs
📚 Learning: 2025-09-25T13:44:20.661Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#153
File: src/Mailtrap.Abstractions/ContactImports/Validators/CreateContactImportRequestValidator.cs:22-30
Timestamp: 2025-09-25T13:44:20.661Z
Learning: In the Mailtrap .NET repository, validators follow a standard pattern: they rely on FluentValidation's default error messages for simple validation rules (NotEmpty, Length, MaximumLength, etc.) rather than using custom WithMessage calls. Custom messages are only used for complex business logic validations. All validators have comprehensive XML documentation, a static Instance property for reuse, and follow consistent constructor patterns.

Applied to files:

  • src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactFieldRequest.cs
🧬 Code graph analysis (1)
src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactFieldRequest.cs (2)
src/Mailtrap.Abstractions/ContactFields/Requests/CreateContactFieldRequest.cs (1)
  • JsonConstructor (67-77)
src/Mailtrap.Abstractions/ContactFields/Validators/UpdateContactFieldRequestValidator.cs (2)
  • UpdateContactFieldRequestValidator (8-35)
  • UpdateContactFieldRequestValidator (18-34)
🔇 Additional comments (2)
src/Mailtrap.Abstractions/ContactFields/Requests/UpdateContactFieldRequest.cs (2)

6-7: LGTM: solid request model with validator integration

Type shape, JSON mapping, and Validate() delegation look consistent with the patterns in this repo.


41-43: Docs: clarify 0–80 and empty-string semantics (matches validator/tests)

Make it explicit that empty strings are allowed to clear values, and that limits apply when provided.

Apply this diff:

-    /// <paramref name="name"/> should not exceed 80 characters long.<br/>
-    /// <paramref name="mergeTag"/> should not exceed 80 characters long.
+    /// When provided, <paramref name="name"/> and <paramref name="mergeTag"/> must be at most 80 characters long (0–80).<br/>
+    /// Empty strings are allowed to clear a value. At least one of the parameters must be non-empty.

@dr-3lo dr-3lo merged commit 9747625 into main Sep 26, 2025
3 checks passed
@dr-3lo dr-3lo deleted the feature/96-Contacts-api branch September 26, 2025 10:41
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.

Contacts API

4 participants