From b9571683d62a9de2a2151424a852bba074b8c57f Mon Sep 17 00:00:00 2001 From: vtasun Date: Wed, 27 Aug 2025 02:16:44 +0300 Subject: [PATCH 1/4] Implemented Contact Imports API --- .../contactimports/ContactImports.java | 42 +++++++++ .../api/contactimports/ContactImports.java | 27 ++++++ .../contactimports/ContactImportsImpl.java | 39 +++++++++ .../client/api/MailtrapContactsApi.java | 2 + .../factory/MailtrapClientFactory.java | 8 +- .../model/request/contactimports/Contact.java | 22 +++++ .../contactimports/ImportContactsRequest.java | 17 ++++ .../contactimports/ContactImportStatus.java | 33 +++++++ .../ImportContactsResponse.java | 21 +++++ .../AccountAccessesImplTest.java | 4 +- .../mailtrap/api/billing/BillingImplTest.java | 4 +- .../ContactImportsImplTest.java | 85 +++++++++++++++++++ .../mailtrap/api/inboxes/InboxesImplTest.java | 22 ++--- .../java/io/mailtrap/testutils/BaseTest.java | 1 + .../createContactsImportRequest.json | 28 ++++++ .../createContactsImportResponse.json | 4 + .../getContactsImportResponse.json | 7 ++ 17 files changed, 348 insertions(+), 18 deletions(-) create mode 100644 examples/java/io/mailtrap/examples/contactimports/ContactImports.java create mode 100644 src/main/java/io/mailtrap/api/contactimports/ContactImports.java create mode 100644 src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java create mode 100644 src/main/java/io/mailtrap/model/request/contactimports/Contact.java create mode 100644 src/main/java/io/mailtrap/model/request/contactimports/ImportContactsRequest.java create mode 100644 src/main/java/io/mailtrap/model/response/contactimports/ContactImportStatus.java create mode 100644 src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java create mode 100644 src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java create mode 100644 src/test/resources/api/contactimports/createContactsImportRequest.json create mode 100644 src/test/resources/api/contactimports/createContactsImportResponse.json create mode 100644 src/test/resources/api/contactimports/getContactsImportResponse.json diff --git a/examples/java/io/mailtrap/examples/contactimports/ContactImports.java b/examples/java/io/mailtrap/examples/contactimports/ContactImports.java new file mode 100644 index 0000000..c97bdf2 --- /dev/null +++ b/examples/java/io/mailtrap/examples/contactimports/ContactImports.java @@ -0,0 +1,42 @@ +package io.mailtrap.contactimports; + +import io.mailtrap.config.MailtrapConfig; +import io.mailtrap.factory.MailtrapClientFactory; +import io.mailtrap.model.request.contactimports.Contact; +import io.mailtrap.model.request.contactimports.ImportContactsRequest; +import io.mailtrap.model.request.contacts.UpdateContact; +import io.mailtrap.model.request.contacts.UpdateContactRequest; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class ContactImports { + + private static final String TOKEN = ""; + private static final long ACCOUNT_ID = 1L; + private static final long LIST_1_ID = 1L; + private static final long LIST_2_ID = 2L; + private static final String EMAIL = "contact_email@email.com"; + + public static void main(String[] args) { + final var config = new MailtrapConfig.Builder() + .token(TOKEN) + .build(); + + final var client = MailtrapClientFactory.createMailtrapClient(config); + + var importRequest = new ImportContactsRequest( + List.of(new Contact(EMAIL, Map.of("first_name", "Nick"), List.of(LIST_1_ID), List.of(LIST_2_ID)))); + + var createResponse = client.contactsApi().contactImports() + .importContacts(ACCOUNT_ID, importRequest); + + System.out.println(createResponse); + + var updateResponse = client.contactsApi().contactImports() + .getContactImport(ACCOUNT_ID, createResponse.getId()); + + System.out.println(updateResponse); + } +} diff --git a/src/main/java/io/mailtrap/api/contactimports/ContactImports.java b/src/main/java/io/mailtrap/api/contactimports/ContactImports.java new file mode 100644 index 0000000..f798e66 --- /dev/null +++ b/src/main/java/io/mailtrap/api/contactimports/ContactImports.java @@ -0,0 +1,27 @@ +package io.mailtrap.api.contactimports; + +import io.mailtrap.model.request.contactimports.ImportContactsRequest; +import io.mailtrap.model.response.contactimports.ImportContactsResponse; + +public interface ContactImports { + + /** + * Import contacts in bulk with support for custom fields and list management. + * Existing contacts with matching email addresses will be updated automatically. + * Up to 50,000 contacts per request + * + * @param accountId unique account ID + * @param request request body + * @return contact data + */ + ImportContactsResponse importContacts(long accountId, ImportContactsRequest request); + + /** + * Get Contact Import + * + * @param accountId unique account ID + * @param contactId unique Contact Import ID + * @return contact data + */ + ImportContactsResponse getContactImport(long accountId, long contactId); +} diff --git a/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java b/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java new file mode 100644 index 0000000..94a7eb2 --- /dev/null +++ b/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java @@ -0,0 +1,39 @@ +package io.mailtrap.api.contactimports; + +import io.mailtrap.Constants; +import io.mailtrap.CustomValidator; +import io.mailtrap.api.apiresource.ApiResourceWithValidation; +import io.mailtrap.config.MailtrapConfig; +import io.mailtrap.http.RequestData; +import io.mailtrap.model.request.contactimports.ImportContactsRequest; +import io.mailtrap.model.response.contactimports.ImportContactsResponse; + +public class ContactImportsImpl extends ApiResourceWithValidation implements ContactImports { + + public ContactImportsImpl(final MailtrapConfig config, final CustomValidator validator) { + super(config, validator); + this.apiHost = Constants.GENERAL_HOST; + } + + @Override + public ImportContactsResponse importContacts(long accountId, ImportContactsRequest request) { + + validateRequestBodyAndThrowException(request); + + return httpClient.post( + String.format(apiHost + "/api/accounts/%s/contacts/imports", accountId), + request, + new RequestData(), + ImportContactsResponse.class + ); + } + + @Override + public ImportContactsResponse getContactImport(long accountId, long contactId) { + return httpClient.get( + String.format(apiHost + "/api/accounts/%s/contacts/imports/%s", accountId, contactId), + new RequestData(), + ImportContactsResponse.class + ); + } +} diff --git a/src/main/java/io/mailtrap/client/api/MailtrapContactsApi.java b/src/main/java/io/mailtrap/client/api/MailtrapContactsApi.java index ebb482a..190664d 100644 --- a/src/main/java/io/mailtrap/client/api/MailtrapContactsApi.java +++ b/src/main/java/io/mailtrap/client/api/MailtrapContactsApi.java @@ -1,5 +1,6 @@ package io.mailtrap.client.api; +import io.mailtrap.api.contactimports.ContactImports; import io.mailtrap.api.contactlists.ContactLists; import io.mailtrap.api.contacts.Contacts; import lombok.Getter; @@ -15,4 +16,5 @@ public class MailtrapContactsApi { private final ContactLists contactLists; private final Contacts contacts; + private final ContactImports contactImports; } diff --git a/src/main/java/io/mailtrap/factory/MailtrapClientFactory.java b/src/main/java/io/mailtrap/factory/MailtrapClientFactory.java index e642c59..f0ad798 100644 --- a/src/main/java/io/mailtrap/factory/MailtrapClientFactory.java +++ b/src/main/java/io/mailtrap/factory/MailtrapClientFactory.java @@ -6,6 +6,7 @@ import io.mailtrap.api.attachments.AttachmentsImpl; import io.mailtrap.api.billing.BillingImpl; import io.mailtrap.api.bulkemails.BulkEmailsImpl; +import io.mailtrap.api.contactimports.ContactImportsImpl; import io.mailtrap.api.contactlists.ContactListsImpl; import io.mailtrap.api.contacts.ContactsImpl; import io.mailtrap.api.inboxes.InboxesImpl; @@ -43,18 +44,19 @@ public static MailtrapClient createMailtrapClient(MailtrapConfig config) { final var testingApi = createTestingApi(config, customValidator); final var bulkSendingApi = createBulkSendingApi(config, customValidator); final var generalApi = createGeneralApi(config); - final var contactsApi = createContactsApi(config); + final var contactsApi = createContactsApi(config, customValidator); final var sendingContextHolder = configureSendingContext(config); return new MailtrapClient(sendingApi, testingApi, bulkSendingApi, generalApi, contactsApi, sendingContextHolder); } - private static MailtrapContactsApi createContactsApi(MailtrapConfig config) { + private static MailtrapContactsApi createContactsApi(MailtrapConfig config, CustomValidator customValidator) { final var contactLists = new ContactListsImpl(config); final var contacts = new ContactsImpl(config); + final var contactImports = new ContactImportsImpl(config, customValidator); - return new MailtrapContactsApi(contactLists, contacts); + return new MailtrapContactsApi(contactLists, contacts, contactImports); } private static MailtrapGeneralApi createGeneralApi(MailtrapConfig config) { diff --git a/src/main/java/io/mailtrap/model/request/contactimports/Contact.java b/src/main/java/io/mailtrap/model/request/contactimports/Contact.java new file mode 100644 index 0000000..16f02ea --- /dev/null +++ b/src/main/java/io/mailtrap/model/request/contactimports/Contact.java @@ -0,0 +1,22 @@ +package io.mailtrap.model.request.contactimports; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class Contact { + + private String email; + + private Map fields; + + @JsonProperty("list_ids_included") + private List listIdsIncluded; + + @JsonProperty("list_ids_excluded") + private List listIdsExcluded; +} diff --git a/src/main/java/io/mailtrap/model/request/contactimports/ImportContactsRequest.java b/src/main/java/io/mailtrap/model/request/contactimports/ImportContactsRequest.java new file mode 100644 index 0000000..df86be5 --- /dev/null +++ b/src/main/java/io/mailtrap/model/request/contactimports/ImportContactsRequest.java @@ -0,0 +1,17 @@ +package io.mailtrap.model.request.contactimports; + +import io.mailtrap.model.AbstractModel; +import java.util.List; + +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ImportContactsRequest extends AbstractModel { + + @Size(max = 50_000, message = "Maximum 50000 contacts per request") + private List contacts; + +} diff --git a/src/main/java/io/mailtrap/model/response/contactimports/ContactImportStatus.java b/src/main/java/io/mailtrap/model/response/contactimports/ContactImportStatus.java new file mode 100644 index 0000000..788cb6d --- /dev/null +++ b/src/main/java/io/mailtrap/model/response/contactimports/ContactImportStatus.java @@ -0,0 +1,33 @@ +package io.mailtrap.model.response.contactimports; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum ContactImportStatus { + CREATED("created"), + STARTED("started"), + FINISHED("finished"), + FAILED("failed"),; + + private final String value; + + ContactImportStatus(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @JsonCreator + public static ContactImportStatus fromValue(Object value) { + for (ContactImportStatus level : ContactImportStatus.values()) { + if (level.value.equalsIgnoreCase((String) value)) { + return level; + } + } + + throw new IllegalArgumentException("Unknown value: " + value); + } +} diff --git a/src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java b/src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java new file mode 100644 index 0000000..dbde059 --- /dev/null +++ b/src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java @@ -0,0 +1,21 @@ +package io.mailtrap.model.response.contactimports; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class ImportContactsResponse { + + private long id; + + private ContactImportStatus status; + + @JsonProperty("created_contacts_count") + private Long createdContactsCount; + + @JsonProperty("updated_contacts_count") + private Long updatedContactsCount; + + @JsonProperty("contacts_over_limit_count") + private Long contactsOverLimitCount; +} diff --git a/src/test/java/io/mailtrap/api/accountaccesses/AccountAccessesImplTest.java b/src/test/java/io/mailtrap/api/accountaccesses/AccountAccessesImplTest.java index b2cb255..fb87867 100644 --- a/src/test/java/io/mailtrap/api/accountaccesses/AccountAccessesImplTest.java +++ b/src/test/java/io/mailtrap/api/accountaccesses/AccountAccessesImplTest.java @@ -66,8 +66,8 @@ void test_listUserAndInviteAccountAccessesWithProjectIdsQueryParam() { AccountAccessResponse accountAccessResponse = accountAccessResponses.get(0); assertEquals(accountAccessResponse.getId(), accountAccessId); assertEquals(SpecifierType.API_TOKEN, accountAccessResponse.getSpecifierType()); - assertEquals(((ApiTokenSpecifier) accountAccessResponse.getSpecifier()).getToken(), "token-value-11-22-33"); - assertEquals(accountAccessResponse.getResources().size(), 2); + assertEquals("token-value-11-22-33", ((ApiTokenSpecifier) accountAccessResponse.getSpecifier()).getToken()); + assertEquals(2, accountAccessResponse.getResources().size()); assertEquals(accountAccessResponse.getResources().get(0).getResourceId(), projectId); } diff --git a/src/test/java/io/mailtrap/api/billing/BillingImplTest.java b/src/test/java/io/mailtrap/api/billing/BillingImplTest.java index 6c23d48..b7f63c6 100644 --- a/src/test/java/io/mailtrap/api/billing/BillingImplTest.java +++ b/src/test/java/io/mailtrap/api/billing/BillingImplTest.java @@ -38,7 +38,7 @@ void getCurrentBillingCycleUsage() { BillingResponse billingResponse = api.getCurrentBillingCycleUsage(accountId); assertNotNull(billingResponse); - assertEquals(billingResponse.getTestingBillingInfo().getPlan().getName(), "Individual"); - assertEquals(billingResponse.getSendingBillingInfo().getPlan().getName(), "Basic 10K"); + assertEquals("Individual", billingResponse.getTestingBillingInfo().getPlan().getName()); + assertEquals("Basic 10K", billingResponse.getSendingBillingInfo().getPlan().getName()); } } diff --git a/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java b/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java new file mode 100644 index 0000000..7bf52ef --- /dev/null +++ b/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java @@ -0,0 +1,85 @@ +package io.mailtrap.api.contactimports; + +import io.mailtrap.Constants; +import io.mailtrap.config.MailtrapConfig; +import io.mailtrap.exception.InvalidRequestBodyException; +import io.mailtrap.factory.MailtrapClientFactory; +import io.mailtrap.model.request.contactimports.Contact; +import io.mailtrap.model.request.contactimports.ImportContactsRequest; +import io.mailtrap.model.response.contactimports.ContactImportStatus; +import io.mailtrap.model.response.contactimports.ImportContactsResponse; +import io.mailtrap.testutils.BaseTest; +import io.mailtrap.testutils.DataMock; +import io.mailtrap.testutils.TestHttpClient; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +public class ContactImportsImplTest extends BaseTest { + + private ContactImports api; + + @BeforeEach + public void init() { + TestHttpClient httpClient = new TestHttpClient(List.of( + DataMock.build(Constants.GENERAL_HOST + "/api/accounts/" + accountId + "/contacts/imports", + "POST", "api/contactimports/createContactsImportRequest.json", "api/contactimports/createContactsImportResponse.json"), + + DataMock.build(Constants.GENERAL_HOST + "/api/accounts/" + accountId + "/contacts/imports/" + contactId, + "GET", null, "api/contactimports/getContactsImportResponse.json") + )); + + MailtrapConfig testConfig = new MailtrapConfig.Builder() + .httpClient(httpClient) + .token("dummy_token") + .build(); + + api = MailtrapClientFactory.createMailtrapClient(testConfig).contactsApi().contactImports(); + } + + @Test + void test_importContacts() { + final var firstContact = new Contact("customer1@example.com", Map.of("full_name", "Jane Doe"), List.of(1L), List.of(2L)); + final var secondContact = new Contact("customer2@example.com", Map.of("full_name", "John Doe"), List.of(3L), List.of(4L)); + final var request = new ImportContactsRequest(List.of(firstContact, secondContact)); + + ImportContactsResponse importContactsResponse = api.importContacts(accountId, request); + + assertEquals(contactId, importContactsResponse.getId()); + assertSame(ContactImportStatus.STARTED, importContactsResponse.getStatus()); + assertNull(importContactsResponse.getCreatedContactsCount()); + } + + @Test + void test_importContacts_should_fail_validation() { + InvalidRequestBodyException exception = assertThrows(InvalidRequestBodyException.class, () -> api.importContacts(accountId, new ImportContactsRequest(generateContacts()))); + + assertEquals("Invalid request body. Violations: contacts=Maximum 50000 contacts per request", exception.getMessage()); + } + + private List generateContacts() { + List contacts = new ArrayList<>(); + + for (int i = 0; i < 50001; i++) { + contacts.add(new Contact("stub_contact_%d@example.com".formatted(i), Map.of(), List.of(), List.of())); + } + + return contacts; + } + + @Test + void test_getContactImport() { + ImportContactsResponse contactImport = api.getContactImport(accountId, contactId); + + assertEquals(contactId, contactImport.getId()); + assertSame(ContactImportStatus.FINISHED, contactImport.getStatus()); + assertEquals(1L, contactImport.getCreatedContactsCount()); + assertEquals(3L, contactImport.getUpdatedContactsCount()); + assertEquals(3L, contactImport.getContactsOverLimitCount()); + } +} diff --git a/src/test/java/io/mailtrap/api/inboxes/InboxesImplTest.java b/src/test/java/io/mailtrap/api/inboxes/InboxesImplTest.java index d436183..c0e0066 100644 --- a/src/test/java/io/mailtrap/api/inboxes/InboxesImplTest.java +++ b/src/test/java/io/mailtrap/api/inboxes/InboxesImplTest.java @@ -70,7 +70,7 @@ void test_createInbox() { assertNotNull(createdInbox); assertEquals(createdInbox.getProjectId(), projectId); - assertEquals(createdInbox.getName(), "Test inbox"); + assertEquals("Test inbox", createdInbox.getName()); } @Test @@ -80,7 +80,7 @@ void test_getInboxAttributes() { assertNotNull(inboxAttributes); assertTrue(inboxAttributes.getPermission().isCanRead()); assertEquals(inboxAttributes.getProjectId(), projectId); - assertEquals(inboxAttributes.getName(), "Test inbox"); + assertEquals("Test inbox", inboxAttributes.getName()); } @Test @@ -90,7 +90,7 @@ void test_deleteInbox() { assertNotNull(deletedInbox); assertTrue(deletedInbox.getPermission().isCanRead()); assertEquals(deletedInbox.getId(), inboxId); - assertEquals(deletedInbox.getName(), "Test inbox"); + assertEquals("Test inbox", deletedInbox.getName()); } @Test @@ -100,8 +100,8 @@ void test_updateInbox() { assertNotNull(updatedInbox); assertTrue(updatedInbox.getPermission().isCanRead()); assertEquals(updatedInbox.getId(), inboxId); - assertEquals(updatedInbox.getName(), "Updated Inbox Name"); - assertEquals(updatedInbox.getEmailUsername(), "updated-email-username"); + assertEquals("Updated Inbox Name", updatedInbox.getName()); + assertEquals("updated-email-username", updatedInbox.getEmailUsername()); } @Test @@ -111,7 +111,7 @@ void test_cleanInbox() { assertNotNull(cleanedInbox); assertTrue(cleanedInbox.getPermission().isCanRead()); assertEquals(cleanedInbox.getId(), inboxId); - assertEquals(cleanedInbox.getName(), "Test inbox"); + assertEquals("Test inbox", cleanedInbox.getName()); } @Test @@ -121,7 +121,7 @@ void test_markAsRead() { assertNotNull(markedAsRead); assertTrue(markedAsRead.getPermission().isCanRead()); assertEquals(markedAsRead.getId(), inboxId); - assertEquals(markedAsRead.getName(), "Test inbox"); + assertEquals("Test inbox", markedAsRead.getName()); } @Test @@ -131,7 +131,7 @@ void test_resetCredentials() { assertNotNull(resetCredentials); assertTrue(resetCredentials.getPermission().isCanRead()); assertEquals(resetCredentials.getId(), inboxId); - assertEquals(resetCredentials.getName(), "Test inbox"); + assertEquals("Test inbox", resetCredentials.getName()); } @Test @@ -141,7 +141,7 @@ void test_enableEmailAddress() { assertNotNull(enableEmailAddress); assertTrue(enableEmailAddress.getPermission().isCanRead()); assertEquals(enableEmailAddress.getId(), inboxId); - assertEquals(enableEmailAddress.getName(), "Test inbox"); + assertEquals("Test inbox", enableEmailAddress.getName()); } @Test @@ -151,7 +151,7 @@ void test_resetEmailAddresses() { assertNotNull(resetEmailAddresses); assertTrue(resetEmailAddresses.getPermission().isCanRead()); assertEquals(resetEmailAddresses.getId(), inboxId); - assertEquals(resetEmailAddresses.getName(), "Test inbox"); + assertEquals("Test inbox", resetEmailAddresses.getName()); } @Test @@ -162,7 +162,7 @@ void test_getInboxes() { assertEquals(1, inboxes.size()); assertTrue(inboxes.get(0).getPermission().isCanRead()); assertEquals(inboxes.get(0).getId(), inboxId); - assertEquals(inboxes.get(0).getName(), "Test inbox"); + assertEquals("Test inbox", inboxes.get(0).getName()); } } diff --git a/src/test/java/io/mailtrap/testutils/BaseTest.java b/src/test/java/io/mailtrap/testutils/BaseTest.java index 65e0360..2676f10 100644 --- a/src/test/java/io/mailtrap/testutils/BaseTest.java +++ b/src/test/java/io/mailtrap/testutils/BaseTest.java @@ -18,4 +18,5 @@ public class BaseTest { protected final String emailEncoded = URLEncoder.encode(email, Charset.defaultCharset()); protected final String contactUUID = "018dd5e3-f6d2-7c00-8f9b-e5c3f2d8a132"; protected final String contactUUIDEncoded = URLEncoder.encode(contactUUID, Charset.defaultCharset()); + protected final long contactId = 1L; } diff --git a/src/test/resources/api/contactimports/createContactsImportRequest.json b/src/test/resources/api/contactimports/createContactsImportRequest.json new file mode 100644 index 0000000..fca1047 --- /dev/null +++ b/src/test/resources/api/contactimports/createContactsImportRequest.json @@ -0,0 +1,28 @@ +{ + "contacts": [ + { + "email": "customer1@example.com", + "fields": { + "full_name": "Jane Doe" + }, + "list_ids_included": [ + 1 + ], + "list_ids_excluded": [ + 2 + ] + }, + { + "email": "customer2@example.com", + "fields": { + "full_name": "John Doe" + }, + "list_ids_included": [ + 3 + ], + "list_ids_excluded": [ + 4 + ] + } + ] +} diff --git a/src/test/resources/api/contactimports/createContactsImportResponse.json b/src/test/resources/api/contactimports/createContactsImportResponse.json new file mode 100644 index 0000000..3bbdd48 --- /dev/null +++ b/src/test/resources/api/contactimports/createContactsImportResponse.json @@ -0,0 +1,4 @@ +{ + "id": 1, + "status": "started" +} diff --git a/src/test/resources/api/contactimports/getContactsImportResponse.json b/src/test/resources/api/contactimports/getContactsImportResponse.json new file mode 100644 index 0000000..1331ae9 --- /dev/null +++ b/src/test/resources/api/contactimports/getContactsImportResponse.json @@ -0,0 +1,7 @@ +{ + "id": 1, + "status": "finished", + "created_contacts_count": 1, + "updated_contacts_count": 3, + "contacts_over_limit_count": 3 +} From 2c6c473479f72342b8967b19989b6b59c291fa44 Mon Sep 17 00:00:00 2001 From: vtasun Date: Thu, 28 Aug 2025 00:33:18 +0300 Subject: [PATCH 2/4] Code review improvements --- .../examples/contactimports/ContactImports.java | 6 +++--- .../api/contactimports/ContactImports.java | 9 +++++---- .../api/contactimports/ContactImportsImpl.java | 13 +++++++------ ...sResponse.java => ContactImportResponse.java} | 3 ++- .../contactimports/ContactImportStatus.java | 2 +- .../contactimports/ImportContactResponse.java | 12 ++++++++++++ .../contactimports/ContactImportsImplTest.java | 16 ++++++++-------- .../java/io/mailtrap/testutils/BaseTest.java | 3 +-- 8 files changed, 39 insertions(+), 25 deletions(-) rename src/main/java/io/mailtrap/model/response/contactimports/{ImportContactsResponse.java => ContactImportResponse.java} (92%) create mode 100644 src/main/java/io/mailtrap/model/response/contactimports/ImportContactResponse.java diff --git a/examples/java/io/mailtrap/examples/contactimports/ContactImports.java b/examples/java/io/mailtrap/examples/contactimports/ContactImports.java index c97bdf2..fa3cde1 100644 --- a/examples/java/io/mailtrap/examples/contactimports/ContactImports.java +++ b/examples/java/io/mailtrap/examples/contactimports/ContactImports.java @@ -1,4 +1,4 @@ -package io.mailtrap.contactimports; +package io.mailtrap.examples.contactimports; import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; @@ -34,9 +34,9 @@ public static void main(String[] args) { System.out.println(createResponse); - var updateResponse = client.contactsApi().contactImports() + var contactImportResponse = client.contactsApi().contactImports() .getContactImport(ACCOUNT_ID, createResponse.getId()); - System.out.println(updateResponse); + System.out.println(contactImportResponse); } } diff --git a/src/main/java/io/mailtrap/api/contactimports/ContactImports.java b/src/main/java/io/mailtrap/api/contactimports/ContactImports.java index f798e66..a283cb5 100644 --- a/src/main/java/io/mailtrap/api/contactimports/ContactImports.java +++ b/src/main/java/io/mailtrap/api/contactimports/ContactImports.java @@ -1,7 +1,8 @@ package io.mailtrap.api.contactimports; import io.mailtrap.model.request.contactimports.ImportContactsRequest; -import io.mailtrap.model.response.contactimports.ImportContactsResponse; +import io.mailtrap.model.response.contactimports.ContactImportResponse; +import io.mailtrap.model.response.contactimports.ImportContactResponse; public interface ContactImports { @@ -14,14 +15,14 @@ public interface ContactImports { * @param request request body * @return contact data */ - ImportContactsResponse importContacts(long accountId, ImportContactsRequest request); + ImportContactResponse importContacts(long accountId, ImportContactsRequest request); /** * Get Contact Import * * @param accountId unique account ID - * @param contactId unique Contact Import ID + * @param importId unique Contact Import ID * @return contact data */ - ImportContactsResponse getContactImport(long accountId, long contactId); + ContactImportResponse getContactImport(long accountId, long importId); } diff --git a/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java b/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java index 94a7eb2..e974a58 100644 --- a/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java +++ b/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java @@ -6,7 +6,8 @@ import io.mailtrap.config.MailtrapConfig; import io.mailtrap.http.RequestData; import io.mailtrap.model.request.contactimports.ImportContactsRequest; -import io.mailtrap.model.response.contactimports.ImportContactsResponse; +import io.mailtrap.model.response.contactimports.ContactImportResponse; +import io.mailtrap.model.response.contactimports.ImportContactResponse; public class ContactImportsImpl extends ApiResourceWithValidation implements ContactImports { @@ -16,7 +17,7 @@ public ContactImportsImpl(final MailtrapConfig config, final CustomValidator val } @Override - public ImportContactsResponse importContacts(long accountId, ImportContactsRequest request) { + public ImportContactResponse importContacts(long accountId, ImportContactsRequest request) { validateRequestBodyAndThrowException(request); @@ -24,16 +25,16 @@ public ImportContactsResponse importContacts(long accountId, ImportContactsReque String.format(apiHost + "/api/accounts/%s/contacts/imports", accountId), request, new RequestData(), - ImportContactsResponse.class + ImportContactResponse.class ); } @Override - public ImportContactsResponse getContactImport(long accountId, long contactId) { + public ContactImportResponse getContactImport(long accountId, long importId) { return httpClient.get( - String.format(apiHost + "/api/accounts/%s/contacts/imports/%s", accountId, contactId), + String.format(apiHost + "/api/accounts/%s/contacts/imports/%s", accountId, importId), new RequestData(), - ImportContactsResponse.class + ContactImportResponse.class ); } } diff --git a/src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java b/src/main/java/io/mailtrap/model/response/contactimports/ContactImportResponse.java similarity index 92% rename from src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java rename to src/main/java/io/mailtrap/model/response/contactimports/ContactImportResponse.java index dbde059..1814cad 100644 --- a/src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java +++ b/src/main/java/io/mailtrap/model/response/contactimports/ContactImportResponse.java @@ -4,7 +4,7 @@ import lombok.Data; @Data -public class ImportContactsResponse { +public class ContactImportResponse { private long id; @@ -18,4 +18,5 @@ public class ImportContactsResponse { @JsonProperty("contacts_over_limit_count") private Long contactsOverLimitCount; + } diff --git a/src/main/java/io/mailtrap/model/response/contactimports/ContactImportStatus.java b/src/main/java/io/mailtrap/model/response/contactimports/ContactImportStatus.java index 788cb6d..b33b88c 100644 --- a/src/main/java/io/mailtrap/model/response/contactimports/ContactImportStatus.java +++ b/src/main/java/io/mailtrap/model/response/contactimports/ContactImportStatus.java @@ -7,7 +7,7 @@ public enum ContactImportStatus { CREATED("created"), STARTED("started"), FINISHED("finished"), - FAILED("failed"),; + FAILED("failed"); private final String value; diff --git a/src/main/java/io/mailtrap/model/response/contactimports/ImportContactResponse.java b/src/main/java/io/mailtrap/model/response/contactimports/ImportContactResponse.java new file mode 100644 index 0000000..d2bb698 --- /dev/null +++ b/src/main/java/io/mailtrap/model/response/contactimports/ImportContactResponse.java @@ -0,0 +1,12 @@ +package io.mailtrap.model.response.contactimports; + +import lombok.Data; + +@Data +public class ImportContactResponse { + + private long id; + + private ContactImportStatus status; + +} diff --git a/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java b/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java index 7bf52ef..53abfaa 100644 --- a/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java +++ b/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java @@ -7,7 +7,8 @@ import io.mailtrap.model.request.contactimports.Contact; import io.mailtrap.model.request.contactimports.ImportContactsRequest; import io.mailtrap.model.response.contactimports.ContactImportStatus; -import io.mailtrap.model.response.contactimports.ImportContactsResponse; +import io.mailtrap.model.response.contactimports.ContactImportResponse; +import io.mailtrap.model.response.contactimports.ImportContactResponse; import io.mailtrap.testutils.BaseTest; import io.mailtrap.testutils.DataMock; import io.mailtrap.testutils.TestHttpClient; @@ -30,7 +31,7 @@ public void init() { DataMock.build(Constants.GENERAL_HOST + "/api/accounts/" + accountId + "/contacts/imports", "POST", "api/contactimports/createContactsImportRequest.json", "api/contactimports/createContactsImportResponse.json"), - DataMock.build(Constants.GENERAL_HOST + "/api/accounts/" + accountId + "/contacts/imports/" + contactId, + DataMock.build(Constants.GENERAL_HOST + "/api/accounts/" + accountId + "/contacts/imports/" + importId, "GET", null, "api/contactimports/getContactsImportResponse.json") )); @@ -48,11 +49,10 @@ void test_importContacts() { final var secondContact = new Contact("customer2@example.com", Map.of("full_name", "John Doe"), List.of(3L), List.of(4L)); final var request = new ImportContactsRequest(List.of(firstContact, secondContact)); - ImportContactsResponse importContactsResponse = api.importContacts(accountId, request); + ImportContactResponse contactImportResponse = api.importContacts(accountId, request); - assertEquals(contactId, importContactsResponse.getId()); - assertSame(ContactImportStatus.STARTED, importContactsResponse.getStatus()); - assertNull(importContactsResponse.getCreatedContactsCount()); + assertEquals(importId, contactImportResponse.getId()); + assertSame(ContactImportStatus.STARTED, contactImportResponse.getStatus()); } @Test @@ -74,9 +74,9 @@ private List generateContacts() { @Test void test_getContactImport() { - ImportContactsResponse contactImport = api.getContactImport(accountId, contactId); + ContactImportResponse contactImport = api.getContactImport(accountId, importId); - assertEquals(contactId, contactImport.getId()); + assertEquals(importId, contactImport.getId()); assertSame(ContactImportStatus.FINISHED, contactImport.getStatus()); assertEquals(1L, contactImport.getCreatedContactsCount()); assertEquals(3L, contactImport.getUpdatedContactsCount()); diff --git a/src/test/java/io/mailtrap/testutils/BaseTest.java b/src/test/java/io/mailtrap/testutils/BaseTest.java index 2676f10..9939ac7 100644 --- a/src/test/java/io/mailtrap/testutils/BaseTest.java +++ b/src/test/java/io/mailtrap/testutils/BaseTest.java @@ -2,7 +2,6 @@ import java.net.URLEncoder; import java.nio.charset.Charset; -import java.util.UUID; public class BaseTest { protected final Long accountId = 1L; @@ -18,5 +17,5 @@ public class BaseTest { protected final String emailEncoded = URLEncoder.encode(email, Charset.defaultCharset()); protected final String contactUUID = "018dd5e3-f6d2-7c00-8f9b-e5c3f2d8a132"; protected final String contactUUIDEncoded = URLEncoder.encode(contactUUID, Charset.defaultCharset()); - protected final long contactId = 1L; + protected final long importId = 1L; } From c35ed0edc83fa5dc79186321de10af1208018c3f Mon Sep 17 00:00:00 2001 From: vtasun Date: Fri, 29 Aug 2025 00:13:32 +0300 Subject: [PATCH 3/4] Minor name change --- .../java/io/mailtrap/api/contactimports/ContactImports.java | 4 ++-- .../io/mailtrap/api/contactimports/ContactImportsImpl.java | 6 +++--- ...portContactResponse.java => ImportContactsResponse.java} | 2 +- .../mailtrap/api/contactimports/ContactImportsImplTest.java | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/main/java/io/mailtrap/model/response/contactimports/{ImportContactResponse.java => ImportContactsResponse.java} (78%) diff --git a/src/main/java/io/mailtrap/api/contactimports/ContactImports.java b/src/main/java/io/mailtrap/api/contactimports/ContactImports.java index a283cb5..d716335 100644 --- a/src/main/java/io/mailtrap/api/contactimports/ContactImports.java +++ b/src/main/java/io/mailtrap/api/contactimports/ContactImports.java @@ -2,7 +2,7 @@ import io.mailtrap.model.request.contactimports.ImportContactsRequest; import io.mailtrap.model.response.contactimports.ContactImportResponse; -import io.mailtrap.model.response.contactimports.ImportContactResponse; +import io.mailtrap.model.response.contactimports.ImportContactsResponse; public interface ContactImports { @@ -15,7 +15,7 @@ public interface ContactImports { * @param request request body * @return contact data */ - ImportContactResponse importContacts(long accountId, ImportContactsRequest request); + ImportContactsResponse importContacts(long accountId, ImportContactsRequest request); /** * Get Contact Import diff --git a/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java b/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java index e974a58..61f74de 100644 --- a/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java +++ b/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java @@ -7,7 +7,7 @@ import io.mailtrap.http.RequestData; import io.mailtrap.model.request.contactimports.ImportContactsRequest; import io.mailtrap.model.response.contactimports.ContactImportResponse; -import io.mailtrap.model.response.contactimports.ImportContactResponse; +import io.mailtrap.model.response.contactimports.ImportContactsResponse; public class ContactImportsImpl extends ApiResourceWithValidation implements ContactImports { @@ -17,7 +17,7 @@ public ContactImportsImpl(final MailtrapConfig config, final CustomValidator val } @Override - public ImportContactResponse importContacts(long accountId, ImportContactsRequest request) { + public ImportContactsResponse importContacts(long accountId, ImportContactsRequest request) { validateRequestBodyAndThrowException(request); @@ -25,7 +25,7 @@ public ImportContactResponse importContacts(long accountId, ImportContactsReques String.format(apiHost + "/api/accounts/%s/contacts/imports", accountId), request, new RequestData(), - ImportContactResponse.class + ImportContactsResponse.class ); } diff --git a/src/main/java/io/mailtrap/model/response/contactimports/ImportContactResponse.java b/src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java similarity index 78% rename from src/main/java/io/mailtrap/model/response/contactimports/ImportContactResponse.java rename to src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java index d2bb698..3d13265 100644 --- a/src/main/java/io/mailtrap/model/response/contactimports/ImportContactResponse.java +++ b/src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java @@ -3,7 +3,7 @@ import lombok.Data; @Data -public class ImportContactResponse { +public class ImportContactsResponse { private long id; diff --git a/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java b/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java index 53abfaa..6d5a551 100644 --- a/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java +++ b/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java @@ -8,7 +8,7 @@ import io.mailtrap.model.request.contactimports.ImportContactsRequest; import io.mailtrap.model.response.contactimports.ContactImportStatus; import io.mailtrap.model.response.contactimports.ContactImportResponse; -import io.mailtrap.model.response.contactimports.ImportContactResponse; +import io.mailtrap.model.response.contactimports.ImportContactsResponse; import io.mailtrap.testutils.BaseTest; import io.mailtrap.testutils.DataMock; import io.mailtrap.testutils.TestHttpClient; @@ -49,7 +49,7 @@ void test_importContacts() { final var secondContact = new Contact("customer2@example.com", Map.of("full_name", "John Doe"), List.of(3L), List.of(4L)); final var request = new ImportContactsRequest(List.of(firstContact, secondContact)); - ImportContactResponse contactImportResponse = api.importContacts(accountId, request); + ImportContactsResponse contactImportResponse = api.importContacts(accountId, request); assertEquals(importId, contactImportResponse.getId()); assertSame(ContactImportStatus.STARTED, contactImportResponse.getStatus()); From b98abe3f704bcf57bac9fbd6aa17057d864a7668 Mon Sep 17 00:00:00 2001 From: vtasun Date: Sat, 30 Aug 2025 01:38:39 +0300 Subject: [PATCH 4/4] Minor name change --- .../mailtrap/api/contactimports/ContactImports.java | 8 ++++---- .../api/contactimports/ContactImportsImpl.java | 12 ++++++------ ...portResponse.java => ContactsImportResponse.java} | 2 +- ...sponse.java => CreateContactsImportResponse.java} | 2 +- .../api/contactimports/ContactImportsImplTest.java | 8 ++++---- 5 files changed, 16 insertions(+), 16 deletions(-) rename src/main/java/io/mailtrap/model/response/contactimports/{ContactImportResponse.java => ContactsImportResponse.java} (92%) rename src/main/java/io/mailtrap/model/response/contactimports/{ImportContactsResponse.java => CreateContactsImportResponse.java} (76%) diff --git a/src/main/java/io/mailtrap/api/contactimports/ContactImports.java b/src/main/java/io/mailtrap/api/contactimports/ContactImports.java index d716335..540b238 100644 --- a/src/main/java/io/mailtrap/api/contactimports/ContactImports.java +++ b/src/main/java/io/mailtrap/api/contactimports/ContactImports.java @@ -1,8 +1,8 @@ package io.mailtrap.api.contactimports; import io.mailtrap.model.request.contactimports.ImportContactsRequest; -import io.mailtrap.model.response.contactimports.ContactImportResponse; -import io.mailtrap.model.response.contactimports.ImportContactsResponse; +import io.mailtrap.model.response.contactimports.ContactsImportResponse; +import io.mailtrap.model.response.contactimports.CreateContactsImportResponse; public interface ContactImports { @@ -15,7 +15,7 @@ public interface ContactImports { * @param request request body * @return contact data */ - ImportContactsResponse importContacts(long accountId, ImportContactsRequest request); + CreateContactsImportResponse importContacts(long accountId, ImportContactsRequest request); /** * Get Contact Import @@ -24,5 +24,5 @@ public interface ContactImports { * @param importId unique Contact Import ID * @return contact data */ - ContactImportResponse getContactImport(long accountId, long importId); + ContactsImportResponse getContactImport(long accountId, long importId); } diff --git a/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java b/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java index 61f74de..16d7a58 100644 --- a/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java +++ b/src/main/java/io/mailtrap/api/contactimports/ContactImportsImpl.java @@ -6,8 +6,8 @@ import io.mailtrap.config.MailtrapConfig; import io.mailtrap.http.RequestData; import io.mailtrap.model.request.contactimports.ImportContactsRequest; -import io.mailtrap.model.response.contactimports.ContactImportResponse; -import io.mailtrap.model.response.contactimports.ImportContactsResponse; +import io.mailtrap.model.response.contactimports.ContactsImportResponse; +import io.mailtrap.model.response.contactimports.CreateContactsImportResponse; public class ContactImportsImpl extends ApiResourceWithValidation implements ContactImports { @@ -17,7 +17,7 @@ public ContactImportsImpl(final MailtrapConfig config, final CustomValidator val } @Override - public ImportContactsResponse importContacts(long accountId, ImportContactsRequest request) { + public CreateContactsImportResponse importContacts(long accountId, ImportContactsRequest request) { validateRequestBodyAndThrowException(request); @@ -25,16 +25,16 @@ public ImportContactsResponse importContacts(long accountId, ImportContactsReque String.format(apiHost + "/api/accounts/%s/contacts/imports", accountId), request, new RequestData(), - ImportContactsResponse.class + CreateContactsImportResponse.class ); } @Override - public ContactImportResponse getContactImport(long accountId, long importId) { + public ContactsImportResponse getContactImport(long accountId, long importId) { return httpClient.get( String.format(apiHost + "/api/accounts/%s/contacts/imports/%s", accountId, importId), new RequestData(), - ContactImportResponse.class + ContactsImportResponse.class ); } } diff --git a/src/main/java/io/mailtrap/model/response/contactimports/ContactImportResponse.java b/src/main/java/io/mailtrap/model/response/contactimports/ContactsImportResponse.java similarity index 92% rename from src/main/java/io/mailtrap/model/response/contactimports/ContactImportResponse.java rename to src/main/java/io/mailtrap/model/response/contactimports/ContactsImportResponse.java index 1814cad..f554e5a 100644 --- a/src/main/java/io/mailtrap/model/response/contactimports/ContactImportResponse.java +++ b/src/main/java/io/mailtrap/model/response/contactimports/ContactsImportResponse.java @@ -4,7 +4,7 @@ import lombok.Data; @Data -public class ContactImportResponse { +public class ContactsImportResponse { private long id; diff --git a/src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java b/src/main/java/io/mailtrap/model/response/contactimports/CreateContactsImportResponse.java similarity index 76% rename from src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java rename to src/main/java/io/mailtrap/model/response/contactimports/CreateContactsImportResponse.java index 3d13265..34959cb 100644 --- a/src/main/java/io/mailtrap/model/response/contactimports/ImportContactsResponse.java +++ b/src/main/java/io/mailtrap/model/response/contactimports/CreateContactsImportResponse.java @@ -3,7 +3,7 @@ import lombok.Data; @Data -public class ImportContactsResponse { +public class CreateContactsImportResponse { private long id; diff --git a/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java b/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java index 6d5a551..f86b88a 100644 --- a/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java +++ b/src/test/java/io/mailtrap/api/contactimports/ContactImportsImplTest.java @@ -7,8 +7,8 @@ import io.mailtrap.model.request.contactimports.Contact; import io.mailtrap.model.request.contactimports.ImportContactsRequest; import io.mailtrap.model.response.contactimports.ContactImportStatus; -import io.mailtrap.model.response.contactimports.ContactImportResponse; -import io.mailtrap.model.response.contactimports.ImportContactsResponse; +import io.mailtrap.model.response.contactimports.ContactsImportResponse; +import io.mailtrap.model.response.contactimports.CreateContactsImportResponse; import io.mailtrap.testutils.BaseTest; import io.mailtrap.testutils.DataMock; import io.mailtrap.testutils.TestHttpClient; @@ -49,7 +49,7 @@ void test_importContacts() { final var secondContact = new Contact("customer2@example.com", Map.of("full_name", "John Doe"), List.of(3L), List.of(4L)); final var request = new ImportContactsRequest(List.of(firstContact, secondContact)); - ImportContactsResponse contactImportResponse = api.importContacts(accountId, request); + CreateContactsImportResponse contactImportResponse = api.importContacts(accountId, request); assertEquals(importId, contactImportResponse.getId()); assertSame(ContactImportStatus.STARTED, contactImportResponse.getStatus()); @@ -74,7 +74,7 @@ private List generateContacts() { @Test void test_getContactImport() { - ContactImportResponse contactImport = api.getContactImport(accountId, importId); + ContactsImportResponse contactImport = api.getContactImport(accountId, importId); assertEquals(importId, contactImport.getId()); assertSame(ContactImportStatus.FINISHED, contactImport.getStatus());