diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/BatchesServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/BatchesServiceTest.java new file mode 100644 index 00000000..6a66dfaf --- /dev/null +++ b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/BatchesServiceTest.java @@ -0,0 +1,509 @@ +package com.sinch.sdk.domains.sms.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.GivenJsonResource; +import com.adelean.inject.resources.junit.jupiter.TestWithResources; +import com.sinch.sdk.BaseTest; +import com.sinch.sdk.core.TestHelpers; +import com.sinch.sdk.core.exceptions.ApiException; +import com.sinch.sdk.core.http.AuthManager; +import com.sinch.sdk.core.http.HttpClient; +import com.sinch.sdk.domains.sms.api.v1.internal.BatchesApi; +import com.sinch.sdk.domains.sms.models.v1.batches.DeliveryReportType; +import com.sinch.sdk.domains.sms.models.v1.batches.MediaBody; +import com.sinch.sdk.domains.sms.models.v1.batches.MediaBodyDtoTest; +import com.sinch.sdk.domains.sms.models.v1.batches.request.BinaryRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.request.MediaRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.request.SendDeliveryFeedbackRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.request.TextRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.request.UpdateBinaryRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.request.UpdateMediaRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.request.UpdateTextRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.response.Batch; +import com.sinch.sdk.domains.sms.models.v1.batches.response.BatchBinary; +import com.sinch.sdk.domains.sms.models.v1.batches.response.BatchMedia; +import com.sinch.sdk.domains.sms.models.v1.batches.response.BatchText; +import com.sinch.sdk.domains.sms.models.v1.batches.response.DryRunResponse; +import com.sinch.sdk.domains.sms.models.v1.batches.response.ListBatchesResponse; +import com.sinch.sdk.domains.sms.models.v1.batches.response.internal.ApiBatchList; +import com.sinch.sdk.models.SmsContext; +import java.time.Instant; +import java.util.AbstractMap; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; +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 +public class BatchesServiceTest extends BaseTest { + + static final String id = "01FC66621XXXXX119Z8PMV1QPQ"; + static final List to = Arrays.asList("+15551231234", "+15551256344"); + static final String from = "+15551231234"; + static final boolean canceled = false; + static final Instant createdAt = Instant.parse("2019-08-24T14:15:22Z"); + static final Instant modifiedAt = Instant.parse("2019-08-24T14:17:22Z"); + static final DeliveryReportType deliveryReport = DeliveryReportType.NONE; + static final Instant sendAt = Instant.parse("2019-08-24T14:19:22Z"); + static final Instant expireAt = Instant.parse("2019-08-24T14:21:22Z"); + static final String callbackUrl = "callback url"; + static final String clientReference = "myReference"; + static final boolean flashMessage = true; + static final boolean feedbackEnabled = false; + static final boolean truncateConcat = true; + static final int maxNumberOfMessageParts = 1; + static final int fromTon = 6; + static final int fromNpi = 18; + static final String udh = "foo udh"; + static final String body = "Hi ${name} ({an identifier}) ! How are you?"; + public static final BatchBinary batchBinary = + BatchBinary.builder() + .setId(id) + .setTo(to) + .setFrom(from) + .setCanceled(canceled) + .setBody(body) + .setCreatedAt(createdAt) + .setModifiedAt(modifiedAt) + .setDeliveryReport(deliveryReport) + .setSendAt(sendAt) + .setExpireAt(expireAt) + .setCallbackUrl(callbackUrl) + .setClientReference(clientReference) + .setFeedbackEnabled(feedbackEnabled) + .setFromTon(fromTon) + .setFromNpi(fromNpi) + .setUdh(udh) + .build(); + + static final Map anIdentifierParameters = + Stream.of( + new AbstractMap.SimpleEntry<>("15551231234", "an identifier value for 15551231234"), + new AbstractMap.SimpleEntry<>("15551256344", "an identifier value for 15551256344")) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + static final Map nameParameters = + Stream.of( + new AbstractMap.SimpleEntry<>("15551231234", "name value for 15551231234"), + new AbstractMap.SimpleEntry<>("15551256344", "name value for 15551256344"), + new AbstractMap.SimpleEntry<>("default", "default value")) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + static final Map> parameters = + Stream.of( + new AbstractMap.SimpleEntry<>("name", nameParameters), + new AbstractMap.SimpleEntry<>("an identifier", anIdentifierParameters)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + public static final BatchMedia batchMedia = + BatchMedia.builder() + .setId(id) + .setTo(to) + .setFrom(from) + .setCanceled(canceled) + .setBody( + MediaBody.builder() + .setSubject("subject field") + .setUrl( + "https://en.wikipedia.org/wiki/Sinch_(company)#/media/File:Sinch_LockUp_RGB.png") + .setMessage("Hi ${name} ({an identifier}) ! How are you?") + .build()) + .setCreatedAt(Instant.parse("2019-08-24T14:14:22Z")) + .setModifiedAt(Instant.parse("2019-08-24T14:15:22Z")) + .setDeliveryReport(DeliveryReportType.SUMMARY) + .setSendAt(Instant.parse("2019-08-24T14:16:22Z")) + .setExpireAt(Instant.parse("2019-08-24T14:17:22Z")) + .setCallbackUrl(callbackUrl) + .setClientReference("client reference") + .setFeedbackEnabled(feedbackEnabled) + .setStrictValidation(true) + .setParameters(parameters) + .build(); + public static final BatchText batchText = + BatchText.builder() + .setId(id) + .setTo(to) + .setFrom(from) + .setCanceled(canceled) + .setBody(body) + .setCreatedAt(createdAt) + .setModifiedAt(modifiedAt) + .setDeliveryReport(deliveryReport) + .setSendAt(sendAt) + .setExpireAt(expireAt) + .setCallbackUrl(callbackUrl) + .setClientReference(clientReference) + .setFlashMessage(flashMessage) + .setFeedbackEnabled(feedbackEnabled) + .setTruncateConcat(truncateConcat) + .setMaxNumberOfMessageParts(maxNumberOfMessageParts) + .setFromTon(fromTon) + .setFromNpi(fromNpi) + .setParameters(parameters) + .build(); + + public static final BinaryRequest sendSmsBatchBinaryRequest = + BinaryRequest.builder() + .setTo(to) + .setFrom(from) + .setBody(body) + .setDeliveryReport(deliveryReport) + .setSendAt(sendAt) + .setExpireAt(expireAt) + .setCallbackUrl(callbackUrl) + .setClientReference(clientReference) + .setFeedbackEnabled(feedbackEnabled) + .setFromTon(fromTon) + .setFromNpi(fromNpi) + .setUdh(udh) + .build(); + + public static final MediaRequest sendSmsBatchMediaRequest = + MediaRequest.builder() + .setTo(to) + .setFrom(from) + .setBody( + MediaBody.builder() + .setUrl( + "https://en.wikipedia.org/wiki/Sinch_(company)#/media/File:Sinch_LockUp_RGB.png") + .setMessage("Hi ${name} ({an identifier}) ! How are you?") + .build()) + .setDeliveryReport(DeliveryReportType.SUMMARY) + .setSendAt(Instant.parse("2019-08-24T14:16:22Z")) + .setExpireAt(Instant.parse("2019-08-24T14:17:22Z")) + .setCallbackUrl(callbackUrl) + .setClientReference("client reference") + .setFeedbackEnabled(feedbackEnabled) + .setStrictValidation(true) + .setParameters(parameters) + .build(); + public static final TextRequest sendSmsBatchTextRequest = + TextRequest.builder() + .setTo(to) + .setFrom(from) + .setBody(body) + .setDeliveryReport(deliveryReport) + .setSendAt(sendAt) + .setExpireAt(expireAt) + .setCallbackUrl(callbackUrl) + .setClientReference(clientReference) + .setFlashMessage(flashMessage) + .setFeedbackEnabled(feedbackEnabled) + .setTruncateConcat(truncateConcat) + .setMaxNumberOfMessageParts(maxNumberOfMessageParts) + .setFromTon(fromTon) + .setFromNpi(fromNpi) + .setParameters(parameters) + .build(); + + public static final UpdateTextRequest updateSmsBatchTextRequest = + UpdateTextRequest.builder() + .setToAdd(to) + .setFrom(from) + .setBody(body) + .setDeliveryReport(deliveryReport) + .setSendAt(sendAt) + .setExpireAt(expireAt) + .setCallbackUrl(callbackUrl) + .setParameters(parameters) + .build(); + + public static final UpdateMediaRequest updateSmsBatchMediaRequest = + UpdateMediaRequest.builder() + .setToRemove(to) + .setFrom(from) + .setBody(MediaBodyDtoTest.mediaBodyDto) + .setDeliveryReport(DeliveryReportType.SUMMARY) + .setSendAt(Instant.parse("2019-08-24T14:16:22Z")) + .setExpireAt(Instant.parse("2019-08-24T14:17:22Z")) + .setCallbackUrl(callbackUrl) + .setStrictValidation(true) + .setParameters(parameters) + .build(); + + public static final UpdateBinaryRequest updateSmsBatchBinaryRequest = + UpdateBinaryRequest.builder() + .setToAdd(Arrays.asList("+15551231234", "+15987365412")) + .setToRemove(Arrays.asList("+0123456789", "+9876543210")) + .setFrom(from) + .setBody(body) + .setDeliveryReport(DeliveryReportType.FULL) + .setSendAt(sendAt) + .setExpireAt(expireAt) + .setCallbackUrl(callbackUrl) + .setUdh(udh) + .build(); + + @GivenJsonResource("/domains/sms/v1/batches/response/BatchBinaryDto.json") + public Batch binaryResponseDto; + + @GivenJsonResource("/domains/sms/v1/batches/response/BatchMediaDto.json") + Batch mediaResponseDto; + + @GivenJsonResource("/domains/sms/v1/batches/response/BatchTextDto.json") + Batch textResponseDto; + + @GivenJsonResource("/domains/sms/v1/batches/response/DryRunResponseDto.json") + DryRunResponse dryRunResponseDto; + + @GivenJsonResource("/domains/sms/v1/batches/response/ListBatchesResponseDtoPage0.json") + ApiBatchList listBatchesResponseDtoPage0; + + @GivenJsonResource("/domains/sms/v1/batches/response/ListBatchesResponseDtoPage1.json") + ApiBatchList listBatchesResponseDtoPage1; + + @GivenJsonResource("/domains/sms/v1/batches/response/ListBatchesResponseDtoPage2.json") + ApiBatchList listBatchesResponseDtoPage2; + + @Mock SmsContext context; + @Mock HttpClient httpClient; + @Mock Map authManagers; + @Mock BatchesApi api; + BatchesService service; + String uriPartID = "foovalue"; + + @Captor ArgumentCaptor recipientsCaptor; + + @BeforeEach + public void initMocks() { + service = spy(new BatchesService(uriPartID, context, httpClient, authManagers)); + doReturn(api).when(service).getApi(); + } + + @Test + void getBinary() throws ApiException { + + when(api.get(eq("foo binary batch id"))).thenReturn(binaryResponseDto); + + Batch response = service.get("foo binary batch id"); + + TestHelpers.recursiveEquals(response, batchBinary); + } + + @Test + void getMedia() throws ApiException { + + when(api.get(eq("foo media batch id"))).thenReturn(mediaResponseDto); + + Batch response = service.get("foo media batch id"); + + TestHelpers.recursiveEquals(response, batchMedia); + } + + @Test + void getText() throws ApiException { + + when(api.get(eq("foo text batch id"))).thenReturn(textResponseDto); + + Batch response = service.get("foo text batch id"); + + TestHelpers.recursiveEquals(response, batchText); + } + + @Test + void sendBinary() throws ApiException { + + when(api.send(sendSmsBatchBinaryRequest)).thenReturn(binaryResponseDto); + + Batch response = service.send(sendSmsBatchBinaryRequest); + + TestHelpers.recursiveEquals(response, batchBinary); + } + + @Test + void sendMedia() throws ApiException { + + when(api.send(sendSmsBatchMediaRequest)).thenReturn(mediaResponseDto); + + Batch response = service.send(sendSmsBatchMediaRequest); + + TestHelpers.recursiveEquals(response, batchMedia); + } + + @Test + void sendText() throws ApiException { + + when(api.send(sendSmsBatchTextRequest)).thenReturn(textResponseDto); + + Batch response = service.send(sendSmsBatchTextRequest); + + TestHelpers.recursiveEquals(response, batchText); + } + + @Test + void dryRun() throws ApiException { + + when(api.dryRun(eq(true), eq(456), eq(sendSmsBatchTextRequest))).thenReturn(dryRunResponseDto); + + DryRunResponse response = service.dryRun(true, 456, sendSmsBatchTextRequest); + + TestHelpers.recursiveEquals(response, dryRunResponseDto); + } + + @Test + void list() throws ApiException { + + when(api.list(eq(null), eq(null), eq(null), eq(null), eq(null), eq(null))) + .thenReturn(listBatchesResponseDtoPage0); + when(api.list(eq(1), eq(null), eq(null), eq(null), eq(null), eq(null))) + .thenReturn(listBatchesResponseDtoPage1); + when(api.list(eq(2), eq(null), eq(null), eq(null), eq(null), eq(null))) + .thenReturn(listBatchesResponseDtoPage2); + ListBatchesResponse response = service.list(null); + + Iterator iterator = response.iterator(); + Batch batch = iterator.next(); + Assertions.assertThat(iterator.hasNext()).isEqualTo(true); + TestHelpers.recursiveEquals( + batch, + BatchBinary.builder() + .setId("01HEAWCHESCXG8SDG5R10VF8E1") + .setTo(Collections.singletonList("339876543213")) + .setFrom("33123456789") + .setCanceled(false) + .setBody("the body") + .setCreatedAt(Instant.parse("2023-11-03T15:21:21.113Z")) + .setModifiedAt(Instant.parse("2023-11-03T15:21:21.568Z")) + .setDeliveryReport(DeliveryReportType.NONE) + .setExpireAt(Instant.parse("2023-11-06T15:21:21.973Z")) + .setClientReference("a client reference") + .setFeedbackEnabled(false) + .build()); + + batch = iterator.next(); + Assertions.assertThat(iterator.hasNext()).isEqualTo(true); + TestHelpers.recursiveEquals( + batch, + BatchText.builder() + .setId("01HEAC0AG69SVYYQ675VPYT28Q") + .setTo(Collections.singletonList("3300000000")) + .setCanceled(false) + .setBody("the body") + .setCreatedAt(Instant.parse("2023-11-03T10:35:03.558Z")) + .setModifiedAt(Instant.parse("2023-11-03T10:35:03.666Z")) + .setDeliveryReport(DeliveryReportType.NONE) + .setExpireAt(Instant.parse("2023-11-03T10:35:03.558Z")) + .setFeedbackEnabled(true) + .setFlashMessage(false) + .build()); + + batch = iterator.next(); + Assertions.assertThat(iterator.hasNext()).isEqualTo(false); + TestHelpers.recursiveEquals( + batch, + BatchMedia.builder() + .setId("01HEABZ9S80D4ENE3X6CPMATZR") + .setTo(Collections.singletonList("331111111")) + .setCanceled(false) + .setBody(MediaBody.builder().setUrl("an URL").build()) + .setCreatedAt(Instant.parse("2023-11-03T10:34:30.056Z")) + .setModifiedAt(Instant.parse("2023-11-03T10:34:30.156Z")) + .setDeliveryReport(DeliveryReportType.SUMMARY) + .setExpireAt(Instant.parse("2023-11-06T10:34:30.256Z")) + .setFeedbackEnabled(false) + .build()); + } + + @Test + void updateText() throws ApiException { + + when(api.update(eq("foo text batch id"), eq(updateSmsBatchTextRequest))) + .thenReturn(textResponseDto); + + Batch response = service.update("foo text batch id", updateSmsBatchTextRequest); + + TestHelpers.recursiveEquals(response, batchText); + } + + @Test + void updateMedia() throws ApiException { + + when(api.update(eq("foo text batch id"), eq(updateSmsBatchMediaRequest))) + .thenReturn(mediaResponseDto); + + Batch response = service.update("foo text batch id", updateSmsBatchMediaRequest); + + TestHelpers.recursiveEquals(response, batchMedia); + } + + @Test + void updateBinary() throws ApiException { + + when(api.update(eq("foo text batch id"), eq(updateSmsBatchBinaryRequest))) + .thenReturn(binaryResponseDto); + + Batch response = service.update("foo text batch id", updateSmsBatchBinaryRequest); + + TestHelpers.recursiveEquals(response, batchBinary); + } + + @Test + void replaceBinary() throws ApiException { + + when(api.replace(eq("foo text batch id"), eq(sendSmsBatchBinaryRequest))) + .thenReturn(binaryResponseDto); + + Batch response = service.replace("foo text batch id", sendSmsBatchBinaryRequest); + + TestHelpers.recursiveEquals(response, batchBinary); + } + + @Test + void replaceMedia() throws ApiException { + + when(api.replace(eq("foo text batch id"), eq(sendSmsBatchMediaRequest))) + .thenReturn(mediaResponseDto); + + Batch response = service.replace("foo text batch id", sendSmsBatchMediaRequest); + + TestHelpers.recursiveEquals(response, batchMedia); + } + + @Test + void replaceText() throws ApiException { + + when(api.replace(eq("foo text batch id"), eq(sendSmsBatchTextRequest))) + .thenReturn(textResponseDto); + + Batch response = service.replace("foo text batch id", sendSmsBatchTextRequest); + + TestHelpers.recursiveEquals(response, batchText); + } + + @Test + void cancelBatch() throws ApiException { + + when(api.cancel(eq("foo text batch id"))).thenReturn(textResponseDto); + + Batch response = service.cancel("foo text batch id"); + + TestHelpers.recursiveEquals(response, batchText); + } + + @Test + void sendDeliveryFeedback() throws ApiException { + SendDeliveryFeedbackRequest request = + SendDeliveryFeedbackRequest.builder().setRecipients(Arrays.asList("foo", "foo2")).build(); + + service.sendDeliveryFeedback("foo text batch id", request); + + verify(api).sendDeliveryFeedback(eq("foo text batch id"), recipientsCaptor.capture()); + + SendDeliveryFeedbackRequest dto = recipientsCaptor.getValue(); + TestHelpers.recursiveEquals(dto, request); + } +} diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/SMSServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/SMSServiceTest.java new file mode 100644 index 00000000..c09a2330 --- /dev/null +++ b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/SMSServiceTest.java @@ -0,0 +1,83 @@ +package com.sinch.sdk.domains.sms.api.v1.adapters; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.sinch.sdk.core.http.HttpClient; +import com.sinch.sdk.core.models.ServerConfiguration; +import com.sinch.sdk.models.SmsContext; +import com.sinch.sdk.models.UnifiedCredentials; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +class SMSServiceTest { + + @Mock HttpClient httpClient; + + @Test + void doNotAcceptNullKey() { + UnifiedCredentials credentials = + UnifiedCredentials.builder().setKeyId(null).setKeySecret("foo").setProjectId("foo").build(); + SmsContext context = SmsContext.builder().build(); + ServerConfiguration server = new ServerConfiguration(""); + Exception exception = + assertThrows( + IllegalArgumentException.class, + () -> new SMSService(credentials, context, server, httpClient)); + assertTrue(exception.getMessage().contains("keyId")); + } + + @Test + void doNotAcceptNullKeySecret() { + UnifiedCredentials credentials = + UnifiedCredentials.builder().setKeyId("foo").setKeySecret(null).setProjectId("foo").build(); + SmsContext context = SmsContext.builder().build(); + ServerConfiguration server = new ServerConfiguration(""); + Exception exception = + assertThrows( + IllegalArgumentException.class, + () -> new SMSService(credentials, context, server, httpClient)); + assertTrue(exception.getMessage().contains("keySecret")); + } + + @Test + void doNotAcceptNullProject() { + UnifiedCredentials credentials = + UnifiedCredentials.builder().setKeyId("foo").setKeySecret("foo").setProjectId(null).build(); + SmsContext context = SmsContext.builder().build(); + ServerConfiguration server = new ServerConfiguration(""); + + Exception exception = + assertThrows( + IllegalArgumentException.class, + () -> new SMSService(credentials, context, server, httpClient)); + assertTrue(exception.getMessage().contains("projectId")); + } + + @Test + void doNotAcceptNullCredentials() { + + SmsContext context = SmsContext.builder().build(); + ServerConfiguration server = new ServerConfiguration(""); + Exception exception = + assertThrows( + NullPointerException.class, () -> new SMSService(null, context, server, httpClient)); + assertTrue(exception.getMessage().contains("Credentials must be defined")); + } + + @Test + void doNotAcceptNullContext() { + UnifiedCredentials credentials = + UnifiedCredentials.builder() + .setKeyId("foo") + .setKeySecret("foo") + .setProjectId("foo") + .build(); + ServerConfiguration server = new ServerConfiguration(""); + Exception exception = + assertThrows( + NullPointerException.class, + () -> new SMSService(credentials, null, server, httpClient)); + assertTrue(exception.getMessage().contains("Context must be defined")); + } +} diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/BatchesSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/BatchesSteps.java new file mode 100644 index 00000000..4db3b56d --- /dev/null +++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/BatchesSteps.java @@ -0,0 +1,404 @@ +package com.sinch.sdk.e2e.domains.sms.v1; + +import com.sinch.sdk.core.TestHelpers; +import com.sinch.sdk.domains.sms.api.v1.BatchesService; +import com.sinch.sdk.domains.sms.models.v1.batches.DeliveryReportType; +import com.sinch.sdk.domains.sms.models.v1.batches.request.ListBatchesRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.request.SendDeliveryFeedbackRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.request.TextRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.request.UpdateTextRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.response.Batch; +import com.sinch.sdk.domains.sms.models.v1.batches.response.BatchText; +import com.sinch.sdk.domains.sms.models.v1.batches.response.DryRunPerRecipientDetails; +import com.sinch.sdk.domains.sms.models.v1.batches.response.DryRunResponse; +import com.sinch.sdk.domains.sms.models.v1.batches.response.ListBatchesResponse; +import com.sinch.sdk.e2e.Config; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import java.time.Instant; +import java.util.AbstractMap; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; + +public class BatchesSteps { + + BatchesService service; + + Batch sendTextResponse; + Batch sendTextWithParametersResponse; + DryRunResponse dryRunResponse; + ListBatchesResponse listOnePageResponse; + ListBatchesResponse listAllResponse; + ListBatchesResponse listAllByPageResponse; + Batch getBatchResponse; + Batch updateResponse; + Batch replaceResponse; + Batch cancelResponse; + Boolean sendDeliveryFeedbackPassed; + + @Given("^the SMS service \"Batches\" is available") + public void serviceAvailable() { + + service = Config.getSinchClient().sms().v1().batches(); + } + + @When("^I send a request to send a text message$") + public void send() { + TextRequest request = + TextRequest.builder() + .setBody("SMS body message") + .setTo(Collections.singletonList("+12017777777")) + .setFrom("+12015555555") + .setSendAt(Instant.parse("2024-06-06T09:25:00Z")) + .setDeliveryReport(DeliveryReportType.FULL) + .setFeedbackEnabled(true) + .build(); + + sendTextResponse = service.send(request); + } + + @When("^I send a request to send a text message with multiple parameters$") + public void sendWithParameters() { + + Map nameParameters = + Stream.of( + new AbstractMap.SimpleEntry<>("+12017777777", "John"), + new AbstractMap.SimpleEntry<>("+12018888888", "Paul"), + new AbstractMap.SimpleEntry<>("default", "there")) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + Map codeParameters = + Stream.of(new AbstractMap.SimpleEntry<>("+12017777777", "HALLOWEEN20 \uD83C\uDF83")) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + Map> parameters = + Stream.of( + new AbstractMap.SimpleEntry<>("name", nameParameters), + new AbstractMap.SimpleEntry<>("code", codeParameters)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + TextRequest request = + TextRequest.builder() + .setBody("Hello ${name}! Get 20% off with this discount code ${code}") + .setTo(Arrays.asList("+12017777777", "+12018888888")) + .setFrom("+12015555555") + .setParameters(parameters) + .setDeliveryReport(DeliveryReportType.FULL) + .build(); + + sendTextWithParametersResponse = service.send(request); + } + + @When("^I send a request to perform a dry run of a batch$") + public void dryRun() { + + Map nameParameters = + Stream.of( + new AbstractMap.SimpleEntry<>("+12017777777", "John"), + new AbstractMap.SimpleEntry<>("default", "there")) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + Map> parameters = + Stream.of(new AbstractMap.SimpleEntry<>("name", nameParameters)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + TextRequest request = + TextRequest.builder() + .setBody("Hello ${name}!") + .setTo(Arrays.asList("+12017777777", "+12018888888", "+12019999999")) + .setFrom("+12015555555") + .setParameters(parameters) + .setDeliveryReport(DeliveryReportType.NONE) + .build(); + + dryRunResponse = service.dryRun(true, 3, request); + } + + @When("^I send a request to list the SMS batches$") + public void listOnePage() { + ListBatchesRequest request = ListBatchesRequest.builder().setPageSize(2).build(); + + listOnePageResponse = service.list(request); + } + + @When("^I send a request to list all the SMS batches$") + public void listAll() { + ListBatchesRequest request = ListBatchesRequest.builder().setPageSize(2).build(); + + listAllResponse = service.list(request); + } + + @When("^I iterate manually over the SMS batches pages$") + public void listAllByPage() { + ListBatchesRequest request = ListBatchesRequest.builder().setPageSize(2).build(); + + listAllByPageResponse = service.list(request); + } + + @When("^I send a request to retrieve an SMS batch$") + public void get() { + + getBatchResponse = service.get("foo"); + } + + @When("^I send a request to update an SMS batch$") + public void update() { + + UpdateTextRequest request = + UpdateTextRequest.builder() + .setFrom("+12016666666") + .setToAdd(Collections.singletonList("01W4FFL35P4NC4K35SMSGROUP1")) + .setDeliveryReport(DeliveryReportType.SUMMARY) + .build(); + updateResponse = service.update("foo", request); + } + + @When("^I send a request to replace an SMS batch$") + public void replace() { + + TextRequest request = + TextRequest.builder() + .setFrom("+12016666666") + .setTo(Collections.singletonList("+12018888888")) + .setBody("This is the replacement batch") + .setSendAt(Instant.parse("2024-06-06T09:35:00Z")) + .build(); + replaceResponse = service.replace("foo", request); + } + + @When("^I send a request to cancel an SMS batch$") + public void cancel() { + + cancelResponse = service.cancel("foo"); + } + + @When("^I send a request to send delivery feedbacks$") + public void sendDeliveryFeedback() { + + SendDeliveryFeedbackRequest request = + SendDeliveryFeedbackRequest.builder() + .setRecipients(Collections.singletonList("+12017777777")) + .build(); + service.sendDeliveryFeedback("foo", request); + sendDeliveryFeedbackPassed = true; + } + + @Then("the response contains the text SMS details") + public void sendResult() { + BatchText expected = + BatchText.builder() + .setId("01W4FFL35P4NC4K35SMSBATCH1") + .setTo(Collections.singletonList("12017777777")) + .setFrom("12015555555") + .setCanceled(false) + .setBody("SMS body message") + .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z")) + .setModifiedAt(Instant.parse("2024-06-06T09:22:14.304Z")) + .setDeliveryReport(DeliveryReportType.FULL) + .setSendAt(Instant.parse("2024-06-06T09:25:00Z")) + .setExpireAt(Instant.parse("2024-06-09T09:25:00Z")) + .setFeedbackEnabled(true) + .setFlashMessage(false) + .build(); + + TestHelpers.recursiveEquals(sendTextResponse, expected); + } + + @Then("the response contains the text SMS details with multiple parameters") + public void sendWithParametersResult() { + + Map nameParameters = + Stream.of( + new AbstractMap.SimpleEntry<>("+12017777777", "John"), + new AbstractMap.SimpleEntry<>("+12018888888", "Paul"), + new AbstractMap.SimpleEntry<>("default", "there")) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + Map codeParameters = + Stream.of(new AbstractMap.SimpleEntry<>("+12017777777", "HALLOWEEN20 \uD83C\uDF83")) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + Map> parameters = + Stream.of( + new AbstractMap.SimpleEntry<>("name", nameParameters), + new AbstractMap.SimpleEntry<>("code", codeParameters)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + BatchText expected = + BatchText.builder() + .setId("01W4FFL35P4NC4K35SMSBATCH2") + .setTo(Arrays.asList("12017777777", "12018888888")) + .setFrom("12015555555") + .setCanceled(false) + .setParameters(parameters) + .setBody("Hello ${name}! Get 20% off with this discount code ${code}") + .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z")) + .setModifiedAt(Instant.parse("2024-06-06T09:22:14.304Z")) + .setDeliveryReport(DeliveryReportType.FULL) + .setExpireAt(Instant.parse("2024-06-06T09:22:14.304Z")) + .setFlashMessage(false) + .build(); + + TestHelpers.recursiveEquals(sendTextWithParametersResponse, expected); + } + + @Then( + "the response contains the calculated bodies and number of parts for all messages in the" + + " batch") + public void dryRunResult() { + DryRunResponse expected = + DryRunResponse.builder() + .setNumberOfRecipients(3) + .setNumberOfMessages(3) + .setPerRecipient( + Arrays.asList( + DryRunPerRecipientDetails.builder() + .setRecipient("12017777777") + .setNumberOfParts(1) + .setBody("Hello John!") + .setEncoding("text") + .build(), + DryRunPerRecipientDetails.builder() + .setRecipient("12019999999") + .setNumberOfParts(1) + .setBody("Hello there!") + .setEncoding("text") + .build(), + DryRunPerRecipientDetails.builder() + .setRecipient("12018888888") + .setNumberOfParts(1) + .setBody("Hello there!") + .setEncoding("text") + .build())) + .build(); + + TestHelpers.recursiveEquals(dryRunResponse, expected); + } + + @Then("the response contains \"{int}\" SMS batches") + public void onePageResult(int expected) { + + Assertions.assertEquals(listOnePageResponse.getContent().size(), expected); + } + + @Then("the SMS batches list contains \"{int}\" SMS batches") + public void listAllResult(int expected) { + + ListBatchesResponse response = + null != listAllResponse ? listAllResponse : listAllByPageResponse; + + AtomicInteger count = new AtomicInteger(); + response.iterator().forEachRemaining(_unused -> count.getAndIncrement()); + + Assertions.assertEquals(count.get(), expected); + } + + @Then("the SMS batches iteration result contains the data from \"{int}\" pages") + public void listAllByPageResult(int expected) { + + int count = listAllByPageResponse.getContent().isEmpty() ? 0 : 1; + while (listAllByPageResponse.hasNextPage()) { + count++; + listAllByPageResponse = listAllByPageResponse.nextPage(); + } + Assertions.assertEquals(count, expected); + } + + @Then("the response contains the SMS batch details") + public void getResult() { + + BatchText expected = + BatchText.builder() + .setId("01W4FFL35P4NC4K35SMSBATCH1") + .setTo(Collections.singletonList("12017777777")) + .setFrom("12015555555") + .setCanceled(false) + .setBody("SMS body message") + .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z")) + .setModifiedAt(Instant.parse("2024-06-06T09:22:14.304Z")) + .setDeliveryReport(DeliveryReportType.FULL) + .setSendAt(Instant.parse("2024-06-06T09:25:00Z")) + .setExpireAt(Instant.parse("2024-06-09T09:25:00Z")) + .setFeedbackEnabled(true) + .setFlashMessage(false) + .build(); + + TestHelpers.recursiveEquals(getBatchResponse, expected); + } + + @Then("the response contains the SMS batch details with updated data") + public void updateResult() { + + BatchText expected = + BatchText.builder() + .setId("01W4FFL35P4NC4K35SMSBATCH1") + .setTo(Arrays.asList("12017777777", "01W4FFL35P4NC4K35SMSGROUP1")) + .setFrom("12016666666") + .setCanceled(false) + .setBody("SMS body message") + .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z")) + .setModifiedAt(Instant.parse("2024-06-06T09:22:48.054Z")) + .setDeliveryReport(DeliveryReportType.SUMMARY) + .setSendAt(Instant.parse("2024-06-06T09:25:00Z")) + .setExpireAt(Instant.parse("2024-06-09T09:25:00Z")) + .setFeedbackEnabled(true) + .setFlashMessage(false) + .build(); + + TestHelpers.recursiveEquals(updateResponse, expected); + } + + @Then("the response contains the new SMS batch details with the provided data for replacement") + public void replaceResult() { + + BatchText expected = + BatchText.builder() + .setId("01W4FFL35P4NC4K35SMSBATCH1") + .setTo(Arrays.asList("12018888888")) + .setFrom("12016666666") + .setCanceled(false) + .setBody("This is the replacement batch") + .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z")) + .setModifiedAt(Instant.parse("2024-06-06T09:23:32.504Z")) + .setDeliveryReport(DeliveryReportType.NONE) + .setSendAt(Instant.parse("2024-06-06T09:35:00Z")) + .setExpireAt(Instant.parse("2024-06-09T09:35:00Z")) + .setFlashMessage(false) + .build(); + + TestHelpers.recursiveEquals(replaceResponse, expected); + } + + @Then("the response contains the SMS batch details with a cancelled status") + public void cancelResult() { + + BatchText expected = + BatchText.builder() + .setId("01W4FFL35P4NC4K35SMSBATCH1") + .setTo(Arrays.asList("12017777777")) + .setFrom("12015555555") + .setCanceled(true) + .setBody("SMS body message") + .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z")) + .setModifiedAt(Instant.parse("2024-06-06T09:22:29.978Z")) + .setDeliveryReport(DeliveryReportType.FULL) + .setSendAt(Instant.parse("2024-06-06T09:25:00Z")) + .setExpireAt(Instant.parse("2024-06-09T09:25:00Z")) + .setFeedbackEnabled(true) + .setFlashMessage(false) + .build(); + + TestHelpers.recursiveEquals(cancelResponse, expected); + } + + @Then("the delivery feedback response contains no data") + public void setSendDeliveryFeedbackResult() { + Assertions.assertTrue(sendDeliveryFeedbackPassed); + } +} diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/SmsIT.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/SmsIT.java new file mode 100644 index 00000000..4229a276 --- /dev/null +++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/SmsIT.java @@ -0,0 +1,16 @@ +package com.sinch.sdk.e2e.domains.sms.v1; + +import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME; + +import org.junit.platform.suite.api.ConfigurationParameter; +import org.junit.platform.suite.api.IncludeEngines; +import org.junit.platform.suite.api.SelectClasspathResource; +import org.junit.platform.suite.api.Suite; +import org.junit.platform.suite.api.SuiteDisplayName; + +@Suite +@SuiteDisplayName("SMS V1") +@IncludeEngines("cucumber") +@SelectClasspathResource("features/sms/batches.feature") +@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.sinch.sdk.e2e.domains.sms.v1") +public class SmsIT {} diff --git a/pom.xml b/pom.xml index bb8469c9..d50d1e59 100644 --- a/pom.xml +++ b/pom.xml @@ -323,6 +323,7 @@ com.sinch.sdk.e2e.domains.conversation.ConversationIT com.sinch.sdk.e2e.domains.sms.v0.SmsIT + com.sinch.sdk.e2e.domains.sms.v1.SmsIT com.sinch.sdk.e2e.domains.voice.v0.VoiceIT com.sinch.sdk.e2e.domains.voice.v1.VoiceIT