-
Couldn't load subscription status.
- Fork 1
Feature - Add support of Contact Exports API into .NET client #159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Added Contact Exports management interfaces, models, requests, and validation - Added example project to demonstrate Contact Exports API usage - Updated Contacts interface to provide access to Contact Exports - Added Contact Exports unit tests and integration tests - Extended Contacts unit tests to cover new methods for accessing events - Sealed few classes from Contacts API
…re - Contact Exports (#155)
WalkthroughAdds Contact Exports feature: new example project, abstraction interfaces, models (filters, status, export), validators, resource implementations, defensive-copy utilities, sealed record adjustments, solution updates, and comprehensive unit and integration tests. Integrates Exports endpoints under Contacts collection. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client
participant ContactsResource
participant ExportCollectionResource
participant ExportResource
participant RestFactory
participant API
Client->>ContactsResource: Exports()
ContactsResource->>ExportCollectionResource: new(factory, /contacts/.../exports)
ContactsResource-->>Client: IContactExportCollectionResource
Client->>ExportCollectionResource: Create(CreateContactExportRequest)
ExportCollectionResource->>RestFactory: Create<CreateContactExportRequest, ContactExport>()
RestFactory->>API: POST /contacts/.../exports
API-->>RestFactory: 201 {ContactExport}
RestFactory-->>ExportCollectionResource: Task<ContactExport>
ExportCollectionResource-->>Client: ContactExport
Client->>ContactsResource: Export(exportId)
ContactsResource->>ExportResource: new(factory, /contacts/.../exports/{id})
ContactsResource-->>Client: IContactExportResource
Client->>ExportResource: GetDetails()
ExportResource->>RestFactory: Get<ContactExport>()
RestFactory->>API: GET /contacts/.../exports/{id}
API-->>RestFactory: 200 {ContactExport}
RestFactory-->>ExportResource: Task<ContactExport>
ExportResource-->>Client: ContactExport
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🧬 Code graph analysis (1)tests/Mailtrap.UnitTests/ContactExports/Model/ContactExportSubscriptionStatusFilterTests.cs (2)
🔇 Additional comments (1)
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. Comment |
There was a problem hiding this 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 (6)
src/Mailtrap.Abstractions/AccountAccesses/Requests/UpdatePermissionsRequest.cs (1)
33-56: Consider using.Clone()consistently in both constructors.Both constructors perform defensive copying, but use different methods: the
paramsconstructor uses.ToList()(line 37) while theIEnumerableconstructor uses.Clone()(line 55). For consistency, consider using.Clone()in both places since it's the standardized pattern introduced in this PR.Apply this diff to align the
paramsconstructor:- Permissions = permissions.ToList(); // Defensive copy to prevent post-ctor mutation. + Permissions = permissions.Clone(); // Defensive copy to prevent post-ctor mutation.src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterBase.cs (1)
28-30: Consider making Operator init-only or removing the setter.The public setter on
Operatorallows post-construction mutation, which can bypass validation and introduce invalid state (e.g., setting it back toUnknownafter construction). Since this is a record type intended for immutability, consider usinginitinstead ofset:- public ContactExportFilterOperator Operator { get; set; } = ContactExportFilterOperator.Unknown; + public ContactExportFilterOperator Operator { get; init; } = ContactExportFilterOperator.Unknown;This maintains the ability to use with-expressions while preventing arbitrary mutation.
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportListIdFilter.cs (1)
29-31: Consider usingIReadOnlyList<int>for Value property.While the property has only a getter,
IList<int>is mutable, allowing external code to modify the collection after construction:var filter = new ContactExportListIdFilter(1, 2, 3); filter.Value.Add(4); // This works!This undermines the defensive copying and record immutability. Consider changing to
IReadOnlyList<int>:- public IList<int> Value { get; } = []; + public IReadOnlyList<int> Value { get; } = [];You'll also need to update the constructors to return a read-only wrapper:
- Value = value.Clone(); // defensive copy to prevent post-ctor mutation + Value = value.Clone().AsReadOnly(); // defensive copy to prevent post-ctor mutation- Value = new List<int>(values); + Value = Array.AsReadOnly(values);This ensures true immutability consistent with the record type design.
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportSubscriptionStatusFilter.cs (1)
29-31: Consider making Value init-only instead of settable.The public setter on
Valueallows post-construction mutation and can bypass validation. Since this is a record type, consider usinginitinstead:- public ContactExportFilterSubscriptionStatus Value { get; set; } = ContactExportFilterSubscriptionStatus.Unknown; + public ContactExportFilterSubscriptionStatus Value { get; init; } = ContactExportFilterSubscriptionStatus.Unknown;This maintains record semantics and with-expression support while preventing arbitrary mutation after construction.
tests/Mailtrap.IntegrationTests/ContactExports/ContactExportIntegrationTests.cs (1)
244-262: Extract duplicated RandomContactExportFilter to shared test utility.This method is duplicated in
tests/Mailtrap.UnitTests/ContactExports/Requests/CreateContactExportRequestTests.cs(lines 89-107) with identical implementation. Consider extracting it to a shared test utility class to reduce duplication:// Create a new file: tests/Mailtrap.TestUtilities/ContactExports/ContactExportTestHelpers.cs namespace Mailtrap.TestUtilities.ContactExports; public static class ContactExportTestHelpers { public static ContactExportFilterBase RandomContactExportFilter() { if (TestContext.CurrentContext.Random.NextBool()) { return new ContactExportListIdFilter( TestContext.CurrentContext.Random.Next(), TestContext.CurrentContext.Random.Next() ); } else { var status = TestContext.CurrentContext.Random.NextBool() switch { true => ContactExportFilterSubscriptionStatus.Subscribed, false => ContactExportFilterSubscriptionStatus.Unsubscribed, }; return new ContactExportSubscriptionStatusFilter(status); } } }Then reference it from both test files.
tests/Mailtrap.UnitTests/ContactExports/Model/ContactExportSubscriptionStatusFilterTests.cs (1)
7-15: Fix misleading test name.The test name references "Collection" but the parameter is a single value, not a collection. This is inconsistent with the actual test behavior:
- public void Constructor_Should_ThrowArgumentNullException_WhenProvidedCollectionIsNull() + public void Constructor_Should_ThrowArgumentNullException_WhenProvidedValueIsNull()
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (47)
Mailtrap.sln(3 hunks)examples/Mailtrap.Example.ContactExports/Mailtrap.Example.ContactExports.csproj(1 hunks)examples/Mailtrap.Example.ContactExports/Program.cs(1 hunks)examples/Mailtrap.Example.ContactExports/Properties/launchSettings.json(1 hunks)examples/Mailtrap.Example.ContactExports/appsettings.json(1 hunks)src/Mailtrap.Abstractions/AccountAccesses/Requests/UpdatePermissionsRequest.cs(1 hunks)src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/IContactExportCollectionResource.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/IContactExportResource.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/Models/ContactExport.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterBase.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterName.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterOperator.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterSubscriptionStatus.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportListIdFilter.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportStatus.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportSubscriptionStatusFilter.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/Requests/CreateContactExportRequest.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/Validators/ContactExportFilterValidator.cs(1 hunks)src/Mailtrap.Abstractions/ContactExports/Validators/CreateContactExportRequestValidator.cs(1 hunks)src/Mailtrap.Abstractions/ContactImports/Models/ContactImport.cs(1 hunks)src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs(2 hunks)src/Mailtrap.Abstractions/ContactLists/Requests/ContactListRequest.cs(1 hunks)src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs(1 hunks)src/Mailtrap.Abstractions/Core/Extensions/InternalCollectionExtensions.cs(1 hunks)src/Mailtrap.Abstractions/Core/Models/StringEnum.cs(3 hunks)src/Mailtrap.Abstractions/GlobalUsings.cs(1 hunks)src/Mailtrap/ContactExports/ContactExportCollectionResource.cs(1 hunks)src/Mailtrap/ContactExports/ContactExportResource.cs(1 hunks)src/Mailtrap/Contacts/ContactCollectionResource.cs(2 hunks)src/Mailtrap/GlobalUsings.cs(1 hunks)tests/Mailtrap.IntegrationTests/ContactExports/ContactExportIntegrationTests.cs(1 hunks)tests/Mailtrap.IntegrationTests/ContactExports/Create_Success_Request.json(1 hunks)tests/Mailtrap.IntegrationTests/ContactExports/Create_Success_Response.json(1 hunks)tests/Mailtrap.IntegrationTests/ContactExports/GetDetails_ShouldCorrectlyHandleUri.json(1 hunks)tests/Mailtrap.IntegrationTests/ContactExports/GetDetails_Success.json(1 hunks)tests/Mailtrap.IntegrationTests/GlobalUsings.cs(1 hunks)tests/Mailtrap.IntegrationTests/TestConstants/UrlSegmentsTestConstants.cs(1 hunks)tests/Mailtrap.UnitTests/ContactExports/ContactExportCollectionResourceTests.cs(1 hunks)tests/Mailtrap.UnitTests/ContactExports/ContactExportResourceTests.cs(1 hunks)tests/Mailtrap.UnitTests/ContactExports/Model/ContactExportFilterBaseTests.cs(1 hunks)tests/Mailtrap.UnitTests/ContactExports/Model/ContactExportListIdFilterTests.cs(1 hunks)tests/Mailtrap.UnitTests/ContactExports/Model/ContactExportSubscriptionStatusFilterTests.cs(1 hunks)tests/Mailtrap.UnitTests/ContactExports/Requests/CreateContactExportRequestTests.cs(1 hunks)tests/Mailtrap.UnitTests/Contacts/ContactCollectionResourceTests.cs(1 hunks)tests/Mailtrap.UnitTests/GlobalUsings.cs(1 hunks)tests/Mailtrap.UnitTests/TestConstants/UrlSegmentsTestConstants.cs(1 hunks)
🧰 Additional context used
🧠 Learnings (14)
📚 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:
tests/Mailtrap.IntegrationTests/GlobalUsings.cssrc/Mailtrap/GlobalUsings.cstests/Mailtrap.UnitTests/GlobalUsings.cssrc/Mailtrap.Abstractions/GlobalUsings.cs
📚 Learning: 2025-09-22T08:20:27.736Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#150
File: src/Mailtrap.Abstractions/ContactFields/Validators/CreateContactsFieldRequestValidator.cs:1-1
Timestamp: 2025-09-22T08:20:27.736Z
Learning: In the Mailtrap .NET project, FluentValidation is imported globally through GlobalUsings.cs files, making explicit using statements for FluentValidation unnecessary in individual validator files within the project.
Applied to files:
tests/Mailtrap.IntegrationTests/GlobalUsings.cssrc/Mailtrap/GlobalUsings.cstests/Mailtrap.UnitTests/GlobalUsings.cssrc/Mailtrap.Abstractions/GlobalUsings.cs
📚 Learning: 2025-09-25T10:10:41.714Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#153
File: examples/Mailtrap.Example.ContactFields/Mailtrap.Example.ContactFields.csproj:1-1
Timestamp: 2025-09-25T10:10:41.714Z
Learning: In the Mailtrap .NET client project, example projects automatically inherit configuration from mailtrap-example.props through examples/Directory.Build.props, which imports build/mailtrap-example.props. This means example .csproj files don't need explicit Import statements and can be simplified to just the SDK declaration.
Applied to files:
tests/Mailtrap.IntegrationTests/GlobalUsings.csMailtrap.slnexamples/Mailtrap.Example.ContactExports/Mailtrap.Example.ContactExports.csprojexamples/Mailtrap.Example.ContactExports/Properties/launchSettings.jsonexamples/Mailtrap.Example.ContactExports/Program.cssrc/Mailtrap.Abstractions/GlobalUsings.cs
📚 Learning: 2025-09-25T10:10:38.229Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#153
File: examples/Mailtrap.Example.Email.Send/Mailtrap.Example.Email.Send.csproj:1-1
Timestamp: 2025-09-25T10:10:38.229Z
Learning: In the Mailtrap .NET client project, example projects automatically get their shared properties (TargetFramework, ProjectReference to Mailtrap.csproj, etc.) through the examples/Directory.Build.props file which imports mailtrap-example.props, so individual example .csproj files don't need explicit <Import> statements.
Applied to files:
tests/Mailtrap.IntegrationTests/GlobalUsings.cssrc/Mailtrap/GlobalUsings.csMailtrap.slnexamples/Mailtrap.Example.ContactExports/Mailtrap.Example.ContactExports.csprojexamples/Mailtrap.Example.ContactExports/Properties/launchSettings.jsonexamples/Mailtrap.Example.ContactExports/Program.cssrc/Mailtrap.Abstractions/GlobalUsings.cs
📚 Learning: 2025-09-25T10:10:28.647Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#153
File: examples/Mailtrap.Example.Billing/Mailtrap.Example.Billing.csproj:1-1
Timestamp: 2025-09-25T10:10:28.647Z
Learning: In the Mailtrap .NET client project, example projects automatically inherit shared build configuration through Directory.Build.props mechanism - the examples/Directory.Build.props imports ../build/mailtrap-example.props, so individual .csproj files don't need explicit import statements and can remain minimal.
Applied to files:
tests/Mailtrap.IntegrationTests/GlobalUsings.csMailtrap.slnexamples/Mailtrap.Example.ContactExports/Mailtrap.Example.ContactExports.csprojexamples/Mailtrap.Example.ContactExports/Properties/launchSettings.jsonexamples/Mailtrap.Example.ContactExports/Program.cssrc/Mailtrap.Abstractions/GlobalUsings.cs
📚 Learning: 2025-09-25T10:10:41.714Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#153
File: examples/Mailtrap.Example.ContactFields/Mailtrap.Example.ContactFields.csproj:1-1
Timestamp: 2025-09-25T10:10:41.714Z
Learning: In the Mailtrap .NET client project, example projects automatically inherit configuration from mailtrap-example.props through Directory.Build.props, which conditionally imports build/mailtrap-example.props for any project in the examples directory. This means example .csproj files don't need explicit Import statements.
Applied to files:
tests/Mailtrap.IntegrationTests/GlobalUsings.csMailtrap.slnexamples/Mailtrap.Example.ContactExports/Mailtrap.Example.ContactExports.csprojexamples/Mailtrap.Example.ContactExports/Properties/launchSettings.jsonexamples/Mailtrap.Example.ContactExports/Program.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/ContactExports/Validators/ContactExportFilterValidator.cssrc/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cssrc/Mailtrap.Abstractions/ContactExports/Validators/CreateContactExportRequestValidator.cs
📚 Learning: 2025-09-25T13:46:15.548Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#153
File: tests/Mailtrap.IntegrationTests/ContactLists/ContactsListIntegrationTests.cs:86-87
Timestamp: 2025-09-25T13:46:15.548Z
Learning: The ContactListRequest class has both a parameterized constructor ContactListRequest(string name) and a parameterless constructor ContactListRequest(), so both instantiation patterns are valid.
Applied to files:
src/Mailtrap.Abstractions/ContactLists/Requests/ContactListRequest.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.UnitTests/Contacts/ContactCollectionResourceTests.cssrc/Mailtrap/Contacts/ContactCollectionResource.cs
📚 Learning: 2025-09-25T10:10:41.714Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#153
File: examples/Mailtrap.Example.ContactFields/Mailtrap.Example.ContactFields.csproj:1-1
Timestamp: 2025-09-25T10:10:41.714Z
Learning: In the Mailtrap .NET client project, example projects automatically inherit configuration from build/mailtrap-example.props through examples/Directory.Build.props, which imports $(BuildConfigurationDirectory)mailtrap-example.props. This means example .csproj files don't need explicit Import statements and can be simplified to just the SDK declaration, as they get TargetFrameworks, OutputType, project references, and other shared settings automatically.
Applied to files:
Mailtrap.slnexamples/Mailtrap.Example.ContactExports/Mailtrap.Example.ContactExports.csprojexamples/Mailtrap.Example.ContactExports/Properties/launchSettings.jsonexamples/Mailtrap.Example.ContactExports/Program.cs
📚 Learning: 2025-09-25T10:10:41.519Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#153
File: examples/Mailtrap.Example.ContactLists/Mailtrap.Example.ContactLists.csproj:1-1
Timestamp: 2025-09-25T10:10:41.519Z
Learning: In the Mailtrap .NET client project, example projects inherit their dependencies through MSBuild's hierarchical property system via examples/Directory.Build.props and build/mailtrap-example.props, allowing individual .csproj files to be minimal (just <Project Sdk="Microsoft.NET.Sdk"/>) while still having access to all required project references, package dependencies, and build configuration.
Applied to files:
Mailtrap.slnexamples/Mailtrap.Example.ContactExports/Mailtrap.Example.ContactExports.csprojexamples/Mailtrap.Example.ContactExports/Program.cs
📚 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:
Mailtrap.slnexamples/Mailtrap.Example.ContactExports/Mailtrap.Example.ContactExports.csprojexamples/Mailtrap.Example.ContactExports/Properties/launchSettings.jsonexamples/Mailtrap.Example.ContactExports/Program.cs
📚 Learning: 2025-09-25T10:13:09.845Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#153
File: examples/Mailtrap.Example.Factory/Mailtrap.Example.Factory.csproj:5-7
Timestamp: 2025-09-25T10:13:09.845Z
Learning: The Mailtrap.Example.Factory project doesn't use host builder or configuration loading, so it doesn't require appsettings.json. It uses `<None Remove="appsettings.json"/>` to override the default inclusion rule from mailtrap-example.props.
Applied to files:
Mailtrap.slnexamples/Mailtrap.Example.ContactExports/appsettings.jsonexamples/Mailtrap.Example.ContactExports/Mailtrap.Example.ContactExports.csprojexamples/Mailtrap.Example.ContactExports/Properties/launchSettings.jsonexamples/Mailtrap.Example.ContactExports/Program.cs
📚 Learning: 2025-09-25T10:13:09.845Z
Learnt from: dr-3lo
PR: railsware/mailtrap-dotnet#153
File: examples/Mailtrap.Example.Factory/Mailtrap.Example.Factory.csproj:5-7
Timestamp: 2025-09-25T10:13:09.845Z
Learning: The Mailtrap.Example.Factory project demonstrates standalone MailtrapClientFactory usage without configuration files or host builder. It uses `<None Remove="appsettings.json"/>` to override the default inclusion rule from mailtrap-example.props since it doesn't require appsettings.json.
Applied to files:
examples/Mailtrap.Example.ContactExports/appsettings.jsonexamples/Mailtrap.Example.ContactExports/Mailtrap.Example.ContactExports.csprojexamples/Mailtrap.Example.ContactExports/Program.cs
🧬 Code graph analysis (29)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (1)
src/Mailtrap/Contacts/ContactCollectionResource.cs (2)
IContactExportCollectionResource(17-18)IContactExportResource(20-21)
src/Mailtrap/ContactExports/ContactExportResource.cs (5)
tests/Mailtrap.UnitTests/ContactExports/ContactExportResourceTests.cs (1)
ContactExportResource(51-51)src/Mailtrap/Contacts/ContactCollectionResource.cs (3)
IContactExportResource(20-21)Task(44-45)Task(47-48)src/Mailtrap.Abstractions/ContactExports/IContactExportResource.cs (1)
Task(19-19)src/Mailtrap/ContactExports/ContactExportCollectionResource.cs (1)
Task(11-12)src/Mailtrap/ContactImports/ContactImportResource.cs (1)
ContactImportResource(6-13)
src/Mailtrap.Abstractions/AccountAccesses/Requests/UpdatePermissionsRequest.cs (1)
src/Mailtrap.Abstractions/Core/Extensions/Ensure.cs (2)
Ensure(9-106)NotNull(18-33)
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportStatus.cs (1)
src/Mailtrap.Abstractions/Core/Models/StringEnum.cs (1)
StringEnum(41-49)
src/Mailtrap.Abstractions/ContactExports/Validators/ContactExportFilterValidator.cs (4)
tests/Mailtrap.IntegrationTests/ContactExports/ContactExportIntegrationTests.cs (1)
ContactExportFilterBase(244-262)tests/Mailtrap.UnitTests/ContactExports/Requests/CreateContactExportRequestTests.cs (1)
ContactExportFilterBase(90-108)src/Mailtrap.Abstractions/Core/Models/StringEnum.cs (1)
IsDefined(111-118)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportListIdFilter.cs (2)
ContactExportListIdFilter(63-69)ContactExportListIdFilter(83-89)
src/Mailtrap.Abstractions/ContactExports/IContactExportResource.cs (5)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (3)
IContactExportResource(32-32)Task(136-136)Task(153-153)src/Mailtrap/Contacts/ContactCollectionResource.cs (3)
IContactExportResource(20-21)Task(44-45)Task(47-48)src/Mailtrap.Abstractions/ContactExports/IContactExportCollectionResource.cs (1)
Task(23-23)src/Mailtrap/ContactExports/ContactExportCollectionResource.cs (1)
Task(11-12)src/Mailtrap/ContactExports/ContactExportResource.cs (1)
Task(11-12)
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterName.cs (2)
src/Mailtrap.Abstractions/Core/Models/StringEnum.cs (1)
StringEnum(41-49)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportListIdFilter.cs (2)
ContactExportListIdFilter(63-69)ContactExportListIdFilter(83-89)
src/Mailtrap/ContactExports/ContactExportCollectionResource.cs (6)
tests/Mailtrap.UnitTests/ContactExports/ContactExportCollectionResourceTests.cs (1)
ContactExportCollectionResource(51-51)src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (3)
IContactExportCollectionResource(15-15)Task(136-136)Task(153-153)src/Mailtrap/Contacts/ContactCollectionResource.cs (3)
IContactExportCollectionResource(17-18)Task(44-45)Task(47-48)src/Mailtrap.Abstractions/ContactExports/IContactExportCollectionResource.cs (1)
Task(23-23)src/Mailtrap/ContactExports/ContactExportResource.cs (1)
Task(11-12)src/Mailtrap.Abstractions/ContactExports/Requests/CreateContactExportRequest.cs (1)
CreateContactExportRequest(38-44)
tests/Mailtrap.UnitTests/Contacts/ContactCollectionResourceTests.cs (6)
tests/Mailtrap.UnitTests/TestExtensions/ResourceValidator.cs (2)
ResourceValidator(4-16)Validate(6-15)src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (2)
IContactExportCollectionResource(15-15)IContactExportResource(32-32)src/Mailtrap/Contacts/ContactCollectionResource.cs (2)
IContactExportCollectionResource(17-18)IContactExportResource(20-21)src/Mailtrap/ContactExports/ContactExportCollectionResource.cs (2)
ContactExportCollectionResource(6-13)ContactExportCollectionResource(8-9)tests/Mailtrap.UnitTests/TestConstants/UrlSegmentsTestConstants.cs (1)
UrlSegmentsTestConstants(4-24)src/Mailtrap/ContactExports/ContactExportResource.cs (2)
ContactExportResource(6-13)ContactExportResource(8-9)
src/Mailtrap.Abstractions/Core/Extensions/InternalCollectionExtensions.cs (1)
src/Mailtrap.Abstractions/Core/Extensions/Ensure.cs (2)
Ensure(9-106)NotNull(18-33)
src/Mailtrap.Abstractions/ContactExports/IContactExportCollectionResource.cs (4)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (3)
IContactExportCollectionResource(15-15)Task(136-136)Task(153-153)src/Mailtrap/Contacts/ContactCollectionResource.cs (3)
IContactExportCollectionResource(17-18)Task(44-45)Task(47-48)src/Mailtrap/ContactExports/ContactExportCollectionResource.cs (1)
Task(11-12)src/Mailtrap.Abstractions/ContactExports/Requests/CreateContactExportRequest.cs (1)
CreateContactExportRequest(38-44)
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportSubscriptionStatusFilter.cs (3)
tests/Mailtrap.IntegrationTests/ContactExports/ContactExportIntegrationTests.cs (1)
ContactExportFilterBase(244-262)tests/Mailtrap.UnitTests/ContactExports/Requests/CreateContactExportRequestTests.cs (1)
ContactExportFilterBase(90-108)src/Mailtrap.Abstractions/Core/Extensions/Ensure.cs (2)
Ensure(9-106)NotNull(18-33)
src/Mailtrap.Abstractions/ContactExports/Models/ContactExport.cs (1)
src/Mailtrap.Abstractions/Contacts/Converters/DateTimeToUnixMsJsonConverter.cs (1)
DateTimeOffset(8-22)
src/Mailtrap/Contacts/ContactCollectionResource.cs (3)
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (2)
IContactExportCollectionResource(15-15)IContactExportResource(32-32)src/Mailtrap/ContactExports/ContactExportCollectionResource.cs (2)
ContactExportCollectionResource(6-13)ContactExportCollectionResource(8-9)src/Mailtrap/ContactExports/ContactExportResource.cs (2)
ContactExportResource(6-13)ContactExportResource(8-9)
tests/Mailtrap.UnitTests/ContactExports/Model/ContactExportFilterBaseTests.cs (4)
src/Mailtrap/Configuration/MailtrapClientOptions.cs (1)
JsonSerializerOptions(148-154)src/Mailtrap/Configuration/MailtrapJsonSerializerOptions.cs (1)
MailtrapJsonSerializerOptions(4-19)src/Mailtrap.Abstractions/ContactExports/Requests/CreateContactExportRequest.cs (1)
CreateContactExportRequest(38-44)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportListIdFilter.cs (2)
ContactExportListIdFilter(63-69)ContactExportListIdFilter(83-89)
tests/Mailtrap.UnitTests/ContactExports/Model/ContactExportListIdFilterTests.cs (2)
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportListIdFilter.cs (2)
ContactExportListIdFilter(63-69)ContactExportListIdFilter(83-89)src/Mailtrap.Abstractions/ContactExports/Validators/ContactExportFilterValidator.cs (2)
ContactExportFilterValidator(9-51)ContactExportFilterValidator(16-50)
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterBase.cs (3)
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportListIdFilter.cs (2)
ContactExportListIdFilter(63-69)ContactExportListIdFilter(83-89)tests/Mailtrap.IntegrationTests/ContactExports/ContactExportIntegrationTests.cs (1)
ContactExportFilterBase(244-262)tests/Mailtrap.UnitTests/ContactExports/Requests/CreateContactExportRequestTests.cs (1)
ContactExportFilterBase(90-108)
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterSubscriptionStatus.cs (1)
src/Mailtrap.Abstractions/Core/Models/StringEnum.cs (1)
StringEnum(41-49)
tests/Mailtrap.IntegrationTests/ContactExports/ContactExportIntegrationTests.cs (11)
tests/Mailtrap.UnitTests/ContactExports/Requests/CreateContactExportRequestTests.cs (1)
ContactExportFilterBase(90-108)src/Mailtrap/Configuration/MailtrapClientOptions.cs (1)
JsonSerializerOptions(148-154)tests/Mailtrap.IntegrationTests/TestConstants/UrlSegmentsTestConstants.cs (1)
UrlSegmentsTestConstants(4-27)src/Mailtrap.Abstractions/ContactExports/IContactExportCollectionResource.cs (1)
Task(23-23)src/Mailtrap.Abstractions/ContactExports/IContactExportResource.cs (1)
Task(19-19)src/Mailtrap/ContactExports/ContactExportCollectionResource.cs (1)
Task(11-12)src/Mailtrap/ContactExports/ContactExportResource.cs (1)
Task(11-12)src/Mailtrap.Abstractions/ContactExports/Requests/CreateContactExportRequest.cs (1)
CreateContactExportRequest(38-44)src/Mailtrap/Core/Constants/MimeTypes.cs (2)
MimeTypes(4-19)Application(6-11)src/Mailtrap/Core/Constants/HeaderValues.cs (1)
HeaderValues(7-12)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportListIdFilter.cs (2)
ContactExportListIdFilter(63-69)ContactExportListIdFilter(83-89)
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterOperator.cs (1)
src/Mailtrap.Abstractions/Core/Models/StringEnum.cs (1)
StringEnum(41-49)
tests/Mailtrap.UnitTests/ContactExports/ContactExportCollectionResourceTests.cs (3)
tests/Mailtrap.UnitTests/ContactExports/ContactExportResourceTests.cs (1)
TestFixture(4-52)tests/Mailtrap.UnitTests/TestConstants/UrlSegmentsTestConstants.cs (1)
UrlSegmentsTestConstants(4-24)src/Mailtrap/ContactExports/ContactExportCollectionResource.cs (2)
ContactExportCollectionResource(6-13)ContactExportCollectionResource(8-9)
src/Mailtrap.Abstractions/ContactExports/Requests/CreateContactExportRequest.cs (3)
src/Mailtrap.Abstractions/Core/Extensions/InternalCollectionExtensions.cs (1)
IList(23-31)src/Mailtrap.Abstractions/Core/Extensions/Ensure.cs (1)
Ensure(9-106)src/Mailtrap.Abstractions/ContactExports/Validators/CreateContactExportRequestValidator.cs (2)
CreateContactExportRequestValidator(8-33)CreateContactExportRequestValidator(21-32)
src/Mailtrap.Abstractions/Core/Models/StringEnum.cs (1)
src/Mailtrap/Core/Converters/StringEnumJsonConverter.cs (1)
T(11-23)
examples/Mailtrap.Example.ContactExports/Program.cs (1)
src/Mailtrap.Abstractions/ContactExports/Requests/CreateContactExportRequest.cs (1)
CreateContactExportRequest(38-44)
src/Mailtrap.Abstractions/ContactExports/Validators/CreateContactExportRequestValidator.cs (2)
src/Mailtrap.Abstractions/ContactExports/Requests/CreateContactExportRequest.cs (1)
CreateContactExportRequest(38-44)src/Mailtrap.Abstractions/ContactExports/Validators/ContactExportFilterValidator.cs (2)
ContactExportFilterValidator(9-51)ContactExportFilterValidator(16-50)
tests/Mailtrap.UnitTests/ContactExports/ContactExportResourceTests.cs (4)
tests/Mailtrap.UnitTests/ContactExports/ContactExportCollectionResourceTests.cs (1)
TestFixture(4-52)tests/Mailtrap.UnitTests/Contacts/ContactCollectionResourceTests.cs (1)
TestFixture(4-254)tests/Mailtrap.UnitTests/TestConstants/UrlSegmentsTestConstants.cs (1)
UrlSegmentsTestConstants(4-24)src/Mailtrap/ContactExports/ContactExportResource.cs (2)
ContactExportResource(6-13)ContactExportResource(8-9)
tests/Mailtrap.UnitTests/ContactExports/Requests/CreateContactExportRequestTests.cs (3)
src/Mailtrap.Abstractions/ContactExports/Requests/CreateContactExportRequest.cs (1)
CreateContactExportRequest(38-44)src/Mailtrap.Abstractions/ContactExports/Validators/CreateContactExportRequestValidator.cs (2)
CreateContactExportRequestValidator(8-33)CreateContactExportRequestValidator(21-32)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportListIdFilter.cs (2)
ContactExportListIdFilter(63-69)ContactExportListIdFilter(83-89)
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportListIdFilter.cs (5)
tests/Mailtrap.IntegrationTests/ContactExports/ContactExportIntegrationTests.cs (1)
ContactExportFilterBase(244-262)tests/Mailtrap.UnitTests/ContactExports/Requests/CreateContactExportRequestTests.cs (1)
ContactExportFilterBase(90-108)src/Mailtrap.Abstractions/Core/Extensions/InternalCollectionExtensions.cs (1)
IList(23-31)src/Mailtrap.Abstractions/ContactExports/Models/ContactExportSubscriptionStatusFilter.cs (1)
JsonConstructor(45-52)src/Mailtrap.Abstractions/Core/Extensions/Ensure.cs (1)
Ensure(9-106)
tests/Mailtrap.UnitTests/ContactExports/Model/ContactExportSubscriptionStatusFilterTests.cs (1)
src/Mailtrap.Abstractions/ContactExports/Validators/ContactExportFilterValidator.cs (2)
ContactExportFilterValidator(9-51)ContactExportFilterValidator(16-50)
🔇 Additional comments (50)
tests/Mailtrap.IntegrationTests/GlobalUsings.cs (1)
18-19: LGTM!The new global using directives for ContactExports follow the established project pattern and are correctly placed near the related Contacts namespaces. This change is necessary to support the new ContactExports integration tests added in this PR.
src/Mailtrap/GlobalUsings.cs (1)
36-38: LGTM – No changes needed.The global using directives are correct as written. While validators exist for ContactExports (they're internal sealed classes in Abstractions), the pattern in the main project is intentionally selective: only Contacts, EmailTemplates, and Projects expose Validators globally. ContactExports correctly follows the same pattern as ContactImports, ContactLists, ContactFields, and ContactEvents—omitting the Validators namespace.
src/Mailtrap.Abstractions/ContactImports/Models/ContactImport.cs (1)
6-6: LGTM! Sealing the record is appropriate.Sealing this data model prevents unintended inheritance and is consistent with best practices for DTOs.
src/Mailtrap.Abstractions/ContactExports/IContactExportResource.cs (1)
1-20: LGTM! Interface follows established patterns.The interface design is consistent with existing REST resource interfaces in the codebase, with proper async/await support and cancellation token handling.
src/Mailtrap.Abstractions/Core/Extensions/InternalCollectionExtensions.cs (1)
1-65: LGTM! Defensive copying implementation is correct and efficient.The Clone extension methods properly prevent post-constructor mutation while optimizing for common collection types. The null checks and documentation are thorough.
src/Mailtrap.Abstractions/ContactImports/Requests/CreateContactImportRequest.cs (2)
6-6: LGTM! Sealing the request is appropriate.Sealing this request model prevents unintended inheritance and is consistent with the PR's objective to seal classes from the Contacts API.
39-45: LGTM! Simplified defensive copying using the new Clone extension.The uniform Clone() call replaces conditional branching logic while maintaining the defensive copy behavior, improving code clarity and consistency.
examples/Mailtrap.Example.ContactExports/Mailtrap.Example.ContactExports.csproj (1)
1-1: LGTM! Project file follows established conventions.The minimal project file is correct, as example projects automatically inherit shared configuration through the Directory.Build.props mechanism.
Based on learnings
examples/Mailtrap.Example.ContactExports/Properties/launchSettings.json (1)
1-10: LGTM! Standard launch settings configuration.The launch settings properly configure the Development environment for the example project, consistent with .NET conventions.
tests/Mailtrap.IntegrationTests/ContactExports/Create_Success_Response.json (1)
1-7: LGTM! Test fixture correctly models initial export state.The fixture appropriately shows status "started" for a newly created export, with url as null until the export completes.
tests/Mailtrap.IntegrationTests/ContactExports/GetDetails_Success.json (1)
1-7: LGTM! Test fixture correctly models export details state.The fixture appropriately shows status "created" for a completed export, representing progression from the "started" state in the create response.
tests/Mailtrap.UnitTests/TestConstants/UrlSegmentsTestConstants.cs (1)
19-19: LGTM!The new
ExportsSegmentconstant follows the established pattern and naming conventions in this file.examples/Mailtrap.Example.ContactExports/appsettings.json (1)
1-17: LGTM!The configuration structure follows standard .NET conventions with appropriate logging levels and a placeholder for the API token.
tests/Mailtrap.IntegrationTests/ContactExports/GetDetails_ShouldCorrectlyHandleUri.json (1)
1-6: LGTM!The test fixture structure is appropriate for testing URI handling with query parameters.
src/Mailtrap.Abstractions/ContactEvents/Requests/CreateContactEventRequest.cs (1)
55-59: LGTM!The defensive copy using
.Clone()prevents post-constructor mutation of theParamsdictionary, which is a solid improvement for immutability.tests/Mailtrap.IntegrationTests/TestConstants/UrlSegmentsTestConstants.cs (1)
22-22: LGTM!The
ExportsSegmentconstant mirrors the unit test constants file and follows the established pattern.tests/Mailtrap.UnitTests/GlobalUsings.cs (1)
28-31: LGTM!The global using directives for ContactExports namespaces follow the established pattern and make the new types conveniently available throughout the unit tests. Based on learnings.
tests/Mailtrap.IntegrationTests/ContactExports/Create_Success_Request.json (1)
1-17: LGTM!The test fixture appropriately represents a contact export creation request with multiple filter types (array-valued and string-valued).
src/Mailtrap.Abstractions/GlobalUsings.cs (1)
34-37: LGTM!The global using directives for ContactExports namespaces follow the established pattern and are properly ordered alphabetically between ContactImports and ContactLists.
src/Mailtrap.Abstractions/ContactLists/Requests/ContactListRequest.cs (1)
6-6: LGTM - Sealing the record.Sealing the record prevents further inheritance, which is a sound design choice for request DTOs. Note that this is a breaking change if any external code was inheriting from this class, but it aligns with best practices for sealed abstractions.
src/Mailtrap.Abstractions/ContactExports/IContactExportCollectionResource.cs (1)
1-24: LGTM!The interface follows the established REST resource pattern with clear documentation and a well-defined Create operation. The method signature is consistent with other collection resources in the codebase.
tests/Mailtrap.UnitTests/ContactExports/ContactExportCollectionResourceTests.cs (1)
1-52: LGTM!Comprehensive constructor tests covering null checks for both dependencies and correct initialization of the ResourceUri property. The test structure follows the established pattern used in other resource tests.
tests/Mailtrap.UnitTests/ContactExports/Model/ContactExportListIdFilterTests.cs (1)
1-130: LGTM!Comprehensive test coverage for ContactExportListIdFilter including constructor validation, initialization from different collection types, copy behavior with
withexpressions, and thorough validator testing for various edge cases.src/Mailtrap.Abstractions/Core/Models/StringEnum.cs (1)
99-118: LGTM!The IsDefined method provides essential validation capability for StringEnum-based types. The implementation correctly validates singleton identity by checking null/None/Unknown, dictionary presence via ToString(), and reference equality. This supports the validation logic used in ContactExports filters and validators.
tests/Mailtrap.UnitTests/ContactExports/Requests/CreateContactExportRequestTests.cs (1)
1-109: LGTM!Excellent test coverage for CreateContactExportRequest including constructor validation, comprehensive boundary testing for collection size limits (0, 1, 200, 50000, 50001), null element detection, and a well-designed helper method for generating random filter variants.
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportStatus.cs (1)
1-35: LGTM!The ContactExportStatus enum follows the StringEnum pattern correctly with three well-defined lifecycle states (Created, Started, Finished). The sealed record design and comprehensive documentation align with best practices.
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterOperator.cs (1)
1-17: LGTM! Clean StringEnum implementation.The implementation correctly follows the StringEnum pattern and provides the required filter operator. The single "equal" operator aligns with the Contact Exports API requirements.
src/Mailtrap.Abstractions/Contacts/IContactCollectionResource.cs (1)
8-32: LGTM! Consistent API extension.The new Exports() and Export(long exportId) methods are well-documented and follow the established pattern for nested resources (Imports, Lists, Fields). The exception documentation is appropriate.
src/Mailtrap.Abstractions/ContactExports/Validators/ContactExportFilterValidator.cs (1)
1-51: LGTM! Well-structured validator implementation.The validator correctly implements:
- Singleton pattern for reuse (consistent with existing validators)
- Common validation rules for all filter types
- Type-specific conditional validation using When() guards
- Appropriate use of CascadeMode.Stop to short-circuit validation
The null-forgiving operators in the conditional blocks are safe since they're guarded by type checks.
src/Mailtrap/Contacts/ContactCollectionResource.cs (1)
8-21: LGTM! Consistent resource implementation.The new export methods correctly follow the established pattern for nested resources (Imports, Lists, Fields). The implementation is clean and consistent with the existing codebase.
src/Mailtrap/ContactExports/ContactExportResource.cs (1)
1-13: LGTM! Clean resource implementation.The implementation correctly follows the RestResource pattern and is consistent with similar resources like ContactImportResource. The use of ConfigureAwait(false) is appropriate for library code.
src/Mailtrap.Abstractions/ContactExports/Models/ContactExport.cs (2)
39-52: Verify DateTimeOffset serialization format.The
CreatedAtandUpdatedAtproperties useDateTimeOffset?without a custom JSON converter. The codebase includes aDateTimeToUnixMsJsonConverterfor handling Unix milliseconds (seen insrc/Mailtrap.Abstractions/Contacts/Converters/DateTimeToUnixMsJsonConverter.cs).Please confirm that the Contact Exports API returns timestamps in ISO8601 format (which .NET handles by default) rather than Unix milliseconds. If the API returns Unix milliseconds, these properties will need the
[JsonConverter(typeof(DateTimeToUnixMsJsonConverter))]attribute.
1-67: Well-structured model with comprehensive documentation.The ContactExport model is well-designed with:
- Appropriate property types and nullability
- Clear JSON serialization attributes with proper naming and ordering
- Comprehensive XML documentation
- Sensible default values (Status = Unknown)
src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterSubscriptionStatus.cs (1)
1-26: LGTM! Clean StringEnum implementation.The implementation correctly follows the StringEnum pattern and provides the two expected subscription status values. Documentation is clear and comprehensive.
src/Mailtrap/ContactExports/ContactExportCollectionResource.cs (1)
1-13: LGTM! Clean collection resource implementation.The implementation correctly follows the RestResource pattern and is consistent with other collection resources in the codebase. The Create method properly forwards to the base implementation with ConfigureAwait(false).
tests/Mailtrap.UnitTests/ContactExports/Model/ContactExportFilterBaseTests.cs (3)
9-42: LGTM! Solid serialization test.The test properly normalizes both expected and actual JSON using the same serializer options, which prevents false negatives from formatting differences.
44-72: LGTM! Thorough deserialization test.The test validates polymorphic deserialization correctly, checking both type discrimination and nested values.
74-93: LGTM! Effective round-trip test.The test ensures data integrity is preserved through serialization/deserialization cycles.
examples/Mailtrap.Example.ContactExports/Program.cs (3)
14-23: LGTM! Standard example setup.The host builder configuration and dependency injection setup follows the established patterns from other example projects in the codebase.
25-65: LGTM! Clear API usage demonstration.The example effectively demonstrates the Contact Exports API workflow: creating filters, creating an export, and retrieving export details. The hardcoded values are appropriate for example code.
67-71: Note: Unreachable throw statement.Line 71's
throwis unreachable sinceEnvironment.FailFastterminates the process. However, this pattern appears consistently across example projects, likely to satisfy compiler or static analysis requirements.src/Mailtrap.Abstractions/ContactExports/Models/ContactExportFilterName.cs (1)
1-26: LGTM! Clean string enum implementation.The implementation follows the established StringEnum pattern and properly references the discriminators from the filter classes.
tests/Mailtrap.UnitTests/ContactExports/ContactExportResourceTests.cs (1)
1-52: LGTM! Standard resource constructor tests.The tests follow the established pattern for validating resource constructors and URI initialization. The URI construction correctly includes both the exports segment and the export ID.
src/Mailtrap.Abstractions/ContactExports/Requests/CreateContactExportRequest.cs (3)
8-17: LGTM! Proper immutable collection property.The property correctly uses
JsonObjectCreationHandling.Populateto work with the parameterless constructor pattern, and the get-only property with collection initialization provides appropriate immutability.
19-44: LGTM! Proper defensive copying.The constructor correctly creates a defensive copy of the filters collection to prevent post-construction mutation, and the parameterless constructor supports JSON deserialization.
46-52: LGTM! Standard validation implementation.The validation method follows the established pattern of delegating to a singleton validator instance and converting the result to the Mailtrap ValidationResult type.
Mailtrap.sln (1)
102-103: LGTM! Correct solution configuration.The new Mailtrap.Example.ContactExports project is properly configured with Debug/Release builds and correctly nested under the examples folder.
Also applies to: 202-205, 234-234
src/Mailtrap.Abstractions/ContactExports/Validators/CreateContactExportRequestValidator.cs (2)
10-27: Verify the maximum filters limit.The
MaxFiltersPerRequest = 50_000seems exceptionally high for an export request. Please confirm this limit aligns with:
- API performance capabilities
- Backend resource constraints
- Realistic use cases
Consider whether a lower limit (e.g., 100-1000) would be more appropriate for most practical scenarios.
29-31: LGTM! Proper per-item validation.The per-item validation correctly delegates to the ContactExportFilterValidator.Instance, following the established pattern of reusing validators for collection elements.
tests/Mailtrap.UnitTests/Contacts/ContactCollectionResourceTests.cs (1)
50-94: LGTM! Consistent test coverage for exports endpoints.The new test methods follow the established patterns for testing nested resource access, covering both the collection resource and individual resource methods, including proper validation of invalid IDs.
…criptionStatusFilter constructor
Motivation
Contact Exports API support into .NET client (issue #155)
Changes
How to test
Summary by CodeRabbit