Skip to content

Commit

Permalink
Merge pull request #170 from sinch/DEVEXP-648-support-additional-prop…
Browse files Browse the repository at this point in the history
…erties-serialization

feat (Java): Support 'AdditionalProperty' interface for form parameters serialization
  • Loading branch information
JPPortier authored Nov 28, 2024
2 parents 7b57bcb + b2ce7e3 commit de0802f
Show file tree
Hide file tree
Showing 22 changed files with 705 additions and 227 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.sinch.sdk.domains.mailgun.api.v1.adapters;

import com.sinch.sdk.core.databind.FormSerializer;
import java.util.Map;

public class DeliveryTimeFormSerializer extends FormSerializer<Integer> {

@Override
public String serialize(Integer in) {
return String.format("%dh", in);
public void serialize(Integer in, String fieldName, Map<String, Object> out) {
out.put(fieldName, String.format("%dh", in));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ public MailgunService(
credentials.getApiUser(), "Mailgun service requires 'apiUser' to be defined");
StringUtil.requireNonEmpty(
credentials.getApiKey(), "Mailgun service requires 'apiKey' to be defined");
StringUtil.requireNonEmpty(
context.getUrl(), "'Mailgun service requires mailgunUrl' to be defined");
StringUtil.requireNonEmpty(context.getUrl(), "'Mailgun service requires 'url' to be defined");

LOGGER.fine("Activate Mailgun API with server='" + context.getServer().getUrl() + "'");

Expand Down
11 changes: 8 additions & 3 deletions client/src/main/com/sinch/sdk/http/HttpClientApache.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public HttpResponse invokeAPI(
addBody(requestBuilder, body);
}

addFormParams(requestBuilder, formParams);
addFormParams(requestBuilder, contentType, formParams);

addAuth(requestBuilder, authManagersByOasSecuritySchemes, authNames, body);

Expand Down Expand Up @@ -225,14 +225,19 @@ private void addBody(ClassicRequestBuilder requestBuilder, String body) {
requestBuilder.setEntity(new StringEntity(body, charset));
}

private void addFormParams(ClassicRequestBuilder requestBuilder, Map<String, Object> formParams) {
private void addFormParams(
ClassicRequestBuilder requestBuilder,
Collection<String> contentType,
Map<String, Object> formParams) {

if (null == formParams) {
return;
}

MultipartEntityBuilder multiPartBuilder = MultipartEntityBuilder.create();

if (contentType.stream().noneMatch(cType -> cType.toLowerCase().contains("charset="))) {
multiPartBuilder.setCharset(StandardCharsets.UTF_8);
}
formParams.forEach((key, value) -> addMultiPart(requestBuilder, multiPartBuilder, key, value));

requestBuilder.setEntity(multiPartBuilder.build());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.sinch.sdk.domains.mailgun.api.v1.adapters;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.adelean.inject.resources.junit.jupiter.TestWithResources;
import com.sinch.sdk.BaseTest;
import com.sinch.sdk.core.TestHelpers;
import com.sinch.sdk.core.http.AuthManager;
import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.domains.mailgun.api.v1.internal.EmailsApi;
import com.sinch.sdk.domains.mailgun.models.v1.emails.request.SendEmailRequestTest;
import com.sinch.sdk.domains.mailgun.models.v1.emails.request.SendMimeEmailRequestTest;
import com.sinch.sdk.domains.mailgun.models.v1.emails.response.GetStoredEmailResponse;
import com.sinch.sdk.domains.mailgun.models.v1.emails.response.GetStoredEmailResponseTest;
import com.sinch.sdk.domains.mailgun.models.v1.emails.response.SendEmailResponse;
import com.sinch.sdk.domains.mailgun.models.v1.emails.response.SendEmailResponseTest;
import com.sinch.sdk.domains.mailgun.models.v1.emails.response.SendingQueuesStatusResponse;
import com.sinch.sdk.domains.mailgun.models.v1.emails.response.SendingQueuesStatusResponseTest;
import com.sinch.sdk.models.MailgunContext;
import java.util.Map;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;

@TestWithResources
class EmailsServiceTest extends BaseTest {

@Mock MailgunContext context;
@Mock EmailsApi api;
@Mock HttpClient httpClient;
@Mock Map<String, AuthManager> authManagers;
@Captor ArgumentCaptor<String> domainNameCaptor;

EmailsService service;

String domainName = "fooDomain";
String storageKey = "fooStorageKey";

@BeforeEach
public void initMocks() {
service = spy(new EmailsService(context, httpClient, authManagers));
doReturn(api).when(service).getApi();
}

@Test
void send() {
when(api.sendEmail(eq(domainName), eq(SendEmailRequestTest.sendEmailRequest)))
.thenReturn(SendEmailResponseTest.expectedSendEmailResponse);

SendEmailResponse response = service.send(domainName, SendEmailRequestTest.sendEmailRequest);

TestHelpers.recursiveEquals(response, SendEmailResponseTest.expectedSendEmailResponse);
}

@Test
void sendMime() {
when(api.sendMimeEmail(eq(domainName), eq(SendMimeEmailRequestTest.sendMimEmailRequest)))
.thenReturn(SendEmailResponseTest.expectedSendEmailResponse);

SendEmailResponse response =
service.sendMime(domainName, SendMimeEmailRequestTest.sendMimEmailRequest);

TestHelpers.recursiveEquals(response, SendEmailResponseTest.expectedSendEmailResponse);
}

@Test
void get() {
when(api.getStoredEmail(eq(domainName), eq(storageKey)))
.thenReturn(GetStoredEmailResponseTest.expectedGetEmailResponse);

GetStoredEmailResponse response = service.get(domainName, storageKey);

TestHelpers.recursiveEquals(response, GetStoredEmailResponseTest.expectedGetEmailResponse);
}

@Test
void getSendingQueuesStatus() {
when(api.getSendingQueuesStatus(eq(domainName)))
.thenReturn(SendingQueuesStatusResponseTest.expectedSendingQueuesStatusResponse);

SendingQueuesStatusResponse response = service.getSendingQueuesStatus(domainName);

TestHelpers.recursiveEquals(
response, SendingQueuesStatusResponseTest.expectedSendingQueuesStatusResponse);
}

@Test
void purgeDomainQueues() {

service.purgeDomainQueues(domainName);

verify(api).purgeDomainQueues(domainNameCaptor.capture());

Assertions.assertThat(domainNameCaptor.getValue()).isEqualTo(domainName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.sinch.sdk.domains.mailgun.api.v1.adapters;

import static org.junit.jupiter.api.Assertions.*;

import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.models.MailgunContext;
import com.sinch.sdk.models.MailgunCredentials;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;

class MailgunServiceTest {
@Mock HttpClient httpClient;

@Test
void doNotAcceptNullKey() {
MailgunCredentials credentials = MailgunCredentials.builder().setApiKey(null).build();
MailgunContext context = MailgunContext.builder().build();
Exception exception =
assertThrows(
IllegalArgumentException.class,
() -> new MailgunService(credentials, context, httpClient));
assertTrue(exception.getMessage().contains("apiKey"));
}

@Test
void doNotAcceptNullContext() {
MailgunCredentials credentials = MailgunCredentials.builder().setApiKey("foo").build();
Exception exception =
assertThrows(
NullPointerException.class, () -> new MailgunService(credentials, null, httpClient));
assertTrue(exception.getMessage().contains("Mailgun service requires context to be defined"));
}

@Test
void doNotAcceptEmptyURL() {
MailgunCredentials credentials = MailgunCredentials.builder().setApiKey("foo").build();
MailgunContext context = MailgunContext.builder().setUrl("").build();
Exception exception =
assertThrows(
IllegalArgumentException.class,
() -> new MailgunService(credentials, context, httpClient));
assertTrue(exception.getMessage().contains("Mailgun service requires 'url' to be defined"));
}

@Test
void doNotAcceptNullURL() {
MailgunCredentials credentials = MailgunCredentials.builder().setApiKey("foo").build();
MailgunContext context = MailgunContext.builder().build();
Exception exception =
assertThrows(
IllegalArgumentException.class,
() -> new MailgunService(credentials, context, httpClient));
assertTrue(exception.getMessage().contains("Mailgun service requires 'url' to be defined"));
}

@Test
void passInit() {
MailgunCredentials credentials = MailgunCredentials.builder().setApiKey("foo").build();
MailgunContext context = MailgunContext.builder().setUrl("foo").build();
assertDoesNotThrow(() -> new MailgunService(credentials, context, httpClient), "Init passed");
}
}
10 changes: 10 additions & 0 deletions client/src/test/java/com/sinch/sdk/e2e/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import com.sinch.sdk.models.Configuration;
import com.sinch.sdk.models.ConversationContext;
import com.sinch.sdk.models.ConversationRegion;
import com.sinch.sdk.models.MailgunContext;
import com.sinch.sdk.models.VoiceContext;
import java.util.Arrays;

public class Config {

Expand All @@ -21,6 +23,10 @@ public class Config {
public static final String VOICE_HOST_NAME = "http://localhost:3019";
public static final String VOICE_MANAGEMENT_HOST_NAME = "http://localhost:3020";

public static final String MAILGUN_HOST_NAME = "http://localhost:3021";
public static final String MAILGUN_API_KEY = "apiKey";
public static final String MAILGUN_STORAGE = "http://localhost:3021";

private final SinchClient client;

private Config() {
Expand All @@ -44,6 +50,10 @@ private Config() {
.setVoiceApplicationMngmtUrl(VOICE_MANAGEMENT_HOST_NAME)
.setVoiceUrl(VOICE_HOST_NAME)
.build())
.setMailgunContext(
MailgunContext.builder().setStorageUrls(Arrays.asList(MAILGUN_STORAGE)).build())
.setMailgunApiKey(MAILGUN_API_KEY)
.setMailgunUrl(MAILGUN_HOST_NAME)
.build();

client = new SinchClient(configuration);
Expand Down
Loading

0 comments on commit de0802f

Please sign in to comment.