diff --git a/sdk/communication/Azure.Communication.Sms/src/OptOutsClient.cs b/sdk/communication/Azure.Communication.Sms/src/OptOutsClient.cs
index fefadc9600e0a..c62bb86500229 100644
--- a/sdk/communication/Azure.Communication.Sms/src/OptOutsClient.cs
+++ b/sdk/communication/Azure.Communication.Sms/src/OptOutsClient.cs
@@ -47,9 +47,9 @@ protected OptOutsClient()
/// The server returned an error. See for details returned from the server.
/// is null.
/// is null.
- public virtual async Task> CheckAsync(string from, IEnumerable to, CancellationToken cancellationToken = default)
+ public virtual async Task>> CheckAsync(string from, IEnumerable to, CancellationToken cancellationToken = default)
{
- using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(SmsClient)}.{nameof(OptOutsClient)}.{nameof(CheckAsync)}");
+ using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(OptOutsClient)}.{nameof(Check)}");
scope.Start();
try
{
@@ -58,7 +58,7 @@ public virtual async Task> CheckAsync(string from, IEnu
IEnumerable recipients = to.Select(x => new OptOutRecipient(Argument.CheckNotNullOrEmpty(x, nameof(to))));
Response response = await OptOutsRestClient.CheckAsync(from, recipients, cancellationToken).ConfigureAwait(false);
- return Response.FromValue(response.Value, response.GetRawResponse());
+ return Response.FromValue(response.Value.Value, response.GetRawResponse());
}
catch (Exception ex)
{
@@ -76,9 +76,9 @@ public virtual async Task> CheckAsync(string from, IEnu
/// The server returned an error. See for details returned from the server.
/// is null.
/// is null.
- public virtual Response Check(string from, IEnumerable to, CancellationToken cancellationToken = default)
+ public virtual Response> Check(string from, IEnumerable to, CancellationToken cancellationToken = default)
{
- using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(SmsClient)}.{nameof(OptOutsClient)}.{nameof(Check)}");
+ using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(OptOutsClient)}.{nameof(Check)}");
scope.Start();
try
{
@@ -88,7 +88,7 @@ public virtual Response Check(string from, IEnumerable t
IEnumerable recipients = to.Select(x => new OptOutRecipient(Argument.CheckNotNullOrEmpty(x, nameof(to))));
Response response = OptOutsRestClient.Check(from, recipients, cancellationToken);
- return Response.FromValue(response.Value, response.GetRawResponse());
+ return Response.FromValue(response.Value.Value, response.GetRawResponse());
}
catch (Exception ex)
{
@@ -106,9 +106,9 @@ public virtual Response Check(string from, IEnumerable t
/// The server returned an error. See for details returned from the server.
/// is null.
/// is null.
- public virtual async Task> AddAsync(string from, IEnumerable to, CancellationToken cancellationToken = default)
+ public virtual async Task>> AddAsync(string from, IEnumerable to, CancellationToken cancellationToken = default)
{
- using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(SmsClient)}.{nameof(OptOutsClient)}.{nameof(AddAsync)}");
+ using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(OptOutsClient)}.{nameof(Add)}");
scope.Start();
try
{
@@ -119,7 +119,7 @@ public virtual async Task> AddAsync(string from,
Response response = await OptOutsRestClient.AddAsync(from, recipients, cancellationToken).ConfigureAwait(false);
OptOutChangeResponse result = new OptOutChangeResponse(response.Value.Value.Select(r => new OptOutChangeResponseItem(r.To, r.HttpStatusCode, r.ErrorMessage)));
- return Response.FromValue(result, response.GetRawResponse());
+ return Response.FromValue(result.Value, response.GetRawResponse());
}
catch (Exception ex)
{
@@ -137,9 +137,9 @@ public virtual async Task> AddAsync(string from,
/// The server returned an error. See for details returned from the server.
/// is null.
/// is null.
- public virtual Response Add(string from, IEnumerable to, CancellationToken cancellationToken = default)
+ public virtual Response> Add(string from, IEnumerable to, CancellationToken cancellationToken = default)
{
- using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(SmsClient)}.{nameof(OptOutsClient)}.{nameof(Add)}");
+ using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(OptOutsClient)}.{nameof(Add)}");
scope.Start();
try
{
@@ -150,7 +150,7 @@ public virtual Response Add(string from, IEnumerable response = OptOutsRestClient.Add(from, recipients, cancellationToken);
OptOutChangeResponse result = new OptOutChangeResponse(response.Value.Value.Select(r => new OptOutChangeResponseItem(r.To, r.HttpStatusCode, r.ErrorMessage)));
- return Response.FromValue(result, response.GetRawResponse());
+ return Response.FromValue(result.Value, response.GetRawResponse());
}
catch (Exception ex)
{
@@ -168,9 +168,9 @@ public virtual Response Add(string from, IEnumerableThe server returned an error. See for details returned from the server.
/// is null.
/// is null.
- public virtual async Task> RemoveAsync(string from, IEnumerable to, CancellationToken cancellationToken = default)
+ public virtual async Task>> RemoveAsync(string from, IEnumerable to, CancellationToken cancellationToken = default)
{
- using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(SmsClient)}.{nameof(OptOutsClient)}.{nameof(RemoveAsync)}");
+ using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(OptOutsClient)}.{nameof(Remove)}");
scope.Start();
try
{
@@ -181,7 +181,7 @@ public virtual async Task> RemoveAsync(string fro
Response response = await OptOutsRestClient.RemoveAsync(from, recipients, cancellationToken).ConfigureAwait(false);
OptOutChangeResponse result = new OptOutChangeResponse(response.Value.Value.Select(r => new OptOutChangeResponseItem(r.To, r.HttpStatusCode, r.ErrorMessage)));
- return Response.FromValue(result, response.GetRawResponse());
+ return Response.FromValue(result.Value, response.GetRawResponse());
}
catch (Exception ex)
{
@@ -199,9 +199,9 @@ public virtual async Task> RemoveAsync(string fro
/// The server returned an error. See for details returned from the server.
/// is null.
/// is null.
- public virtual Response Remove(string from, IEnumerable to, CancellationToken cancellationToken = default)
+ public virtual Response> Remove(string from, IEnumerable to, CancellationToken cancellationToken = default)
{
- using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(SmsClient)}.{nameof(OptOutsClient)}.{nameof(Remove)}");
+ using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(OptOutsClient)}.{nameof(Remove)}");
scope.Start();
try
{
@@ -212,7 +212,7 @@ public virtual Response Remove(string from, IEnumerable response = OptOutsRestClient.Remove(from, recipients, cancellationToken);
OptOutChangeResponse result = new OptOutChangeResponse(response.Value.Value.Select(r => new OptOutChangeResponseItem(r.To, r.HttpStatusCode, r.ErrorMessage)));
- return Response.FromValue(result, response.GetRawResponse());
+ return Response.FromValue(result.Value, response.GetRawResponse());
}
catch (Exception ex)
{
diff --git a/sdk/communication/Azure.Communication.Sms/tests/OptOutsClientTest.cs b/sdk/communication/Azure.Communication.Sms/tests/OptOutsClientTest.cs
index a3fdf06404ac1..509d00d6250d0 100644
--- a/sdk/communication/Azure.Communication.Sms/tests/OptOutsClientTest.cs
+++ b/sdk/communication/Azure.Communication.Sms/tests/OptOutsClientTest.cs
@@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
@@ -47,7 +46,7 @@ public void OptOutsClient_ThrowsWithNullEndpoint()
public async Task CheckAsyncOverload_PassesToGeneratedOne(string expectedFrom, IEnumerable expectedTo)
{
Mock mockClient = new Mock() { CallBase = true };
- Response? expectedResponse = default;
+ Response>? expectedResponse = default;
CancellationToken cancellationToken = new CancellationTokenSource().Token;
var callExpression = BuildExpression(x => x.CheckAsync(It.IsAny(), It.IsAny>(), It.IsAny()));
@@ -58,10 +57,10 @@ public async Task CheckAsyncOverload_PassesToGeneratedOne(string expectedFrom, I
Assert.AreEqual(expectedFrom, from);
Assert.AreEqual(expectedTo, to);
Assert.AreEqual(cancellationToken, token);
- return expectedResponse = new Mock>().Object;
+ return expectedResponse = new Mock>>().Object;
});
- Response actualResponse = await mockClient.Object.CheckAsync(expectedFrom, expectedTo, cancellationToken);
+ Response> actualResponse = await mockClient.Object.CheckAsync(expectedFrom, expectedTo, cancellationToken);
mockClient.Verify(callExpression, Times.Once());
Assert.AreEqual(expectedResponse, actualResponse);
@@ -71,7 +70,7 @@ public async Task CheckAsyncOverload_PassesToGeneratedOne(string expectedFrom, I
public void CheckOverload_PassesToGeneratedOne(string expectedFrom, IEnumerable expectedTo)
{
Mock mockClient = new Mock() { CallBase = true };
- Response? expectedResponse = default;
+ Response>? expectedResponse = default;
CancellationToken cancellationToken = new CancellationTokenSource().Token;
var callExpression = BuildExpression(x => x.Check(It.IsAny(), It.IsAny>(), It.IsAny()));
@@ -82,10 +81,10 @@ public void CheckOverload_PassesToGeneratedOne(string expectedFrom, IEnumerable<
Assert.AreEqual(expectedFrom, from);
Assert.AreEqual(expectedTo, to);
Assert.AreEqual(cancellationToken, token);
- return expectedResponse = new Mock>().Object;
+ return expectedResponse = new Mock>>().Object;
});
- Response actualResponse = mockClient.Object.Check(expectedFrom, expectedTo, cancellationToken);
+ Response> actualResponse = mockClient.Object.Check(expectedFrom, expectedTo, cancellationToken);
mockClient.Verify(callExpression, Times.Once());
Assert.AreEqual(expectedResponse, actualResponse);
@@ -95,7 +94,7 @@ public void CheckOverload_PassesToGeneratedOne(string expectedFrom, IEnumerable<
public async Task AddAsyncOverload_PassesToGeneratedOne(string expectedFrom, IEnumerable expectedTo)
{
Mock mockClient = new Mock() { CallBase = true };
- Response? expectedResponse = default;
+ Response>? expectedResponse = default;
CancellationToken cancellationToken = new CancellationTokenSource().Token;
var callExpression = BuildExpression(x => x.AddAsync(It.IsAny(), It.IsAny>(), It.IsAny()));
@@ -106,10 +105,10 @@ public async Task AddAsyncOverload_PassesToGeneratedOne(string expectedFrom, IEn
Assert.AreEqual(expectedFrom, from);
Assert.AreEqual(expectedTo, to);
Assert.AreEqual(cancellationToken, token);
- return expectedResponse = new Mock>().Object;
+ return expectedResponse = new Mock>>().Object;
});
- Response actualResponse = await mockClient.Object.AddAsync(expectedFrom, expectedTo, cancellationToken);
+ Response> actualResponse = await mockClient.Object.AddAsync(expectedFrom, expectedTo, cancellationToken);
mockClient.Verify(callExpression, Times.Once());
Assert.AreEqual(expectedResponse, actualResponse);
@@ -119,7 +118,7 @@ public async Task AddAsyncOverload_PassesToGeneratedOne(string expectedFrom, IEn
public void AddOverload_PassesToGeneratedOne(string expectedFrom, IEnumerable expectedTo)
{
Mock mockClient = new Mock() { CallBase = true };
- Response? expectedResponse = default;
+ Response>? expectedResponse = default;
CancellationToken cancellationToken = new CancellationTokenSource().Token;
var callExpression = BuildExpression(x => x.Add(It.IsAny(), It.IsAny>(), It.IsAny()));
@@ -130,10 +129,10 @@ public void AddOverload_PassesToGeneratedOne(string expectedFrom, IEnumerable>().Object;
+ return expectedResponse = new Mock>>().Object;
});
- Response actualResponse = mockClient.Object.Add(expectedFrom, expectedTo, cancellationToken);
+ Response> actualResponse = mockClient.Object.Add(expectedFrom, expectedTo, cancellationToken);
mockClient.Verify(callExpression, Times.Once());
Assert.AreEqual(expectedResponse, actualResponse);
@@ -143,7 +142,7 @@ public void AddOverload_PassesToGeneratedOne(string expectedFrom, IEnumerable expectedTo)
{
Mock mockClient = new Mock() { CallBase = true };
- Response? expectedResponse = default;
+ Response>? expectedResponse = default;
CancellationToken cancellationToken = new CancellationTokenSource().Token;
var callExpression = BuildExpression(x => x.RemoveAsync(It.IsAny(), It.IsAny>(), It.IsAny()));
@@ -154,10 +153,10 @@ public async Task RemoveAsyncOverload_PassesToGeneratedOne(string expectedFrom,
Assert.AreEqual(expectedFrom, from);
Assert.AreEqual(expectedTo, to);
Assert.AreEqual(cancellationToken, token);
- return expectedResponse = new Mock>().Object;
+ return expectedResponse = new Mock>>().Object;
});
- Response actualResponse = await mockClient.Object.RemoveAsync(expectedFrom, expectedTo, cancellationToken);
+ Response> actualResponse = await mockClient.Object.RemoveAsync(expectedFrom, expectedTo, cancellationToken);
mockClient.Verify(callExpression, Times.Once());
Assert.AreEqual(expectedResponse, actualResponse);
@@ -167,7 +166,7 @@ public async Task RemoveAsyncOverload_PassesToGeneratedOne(string expectedFrom,
public void RemoveOverload_PassesToGeneratedOne(string expectedFrom, IEnumerable expectedTo)
{
Mock mockClient = new Mock() { CallBase = true };
- Response? expectedResponse = default;
+ Response>? expectedResponse = default;
CancellationToken cancellationToken = new CancellationTokenSource().Token;
var callExpression = BuildExpression(x => x.Remove(It.IsAny(), It.IsAny>(), It.IsAny()));
@@ -178,10 +177,10 @@ public void RemoveOverload_PassesToGeneratedOne(string expectedFrom, IEnumerable
Assert.AreEqual(expectedFrom, from);
Assert.AreEqual(expectedTo, to);
Assert.AreEqual(cancellationToken, token);
- return expectedResponse = new Mock>().Object;
+ return expectedResponse = new Mock>>().Object;
});
- Response actualResponse = mockClient.Object.Remove(expectedFrom, expectedTo, cancellationToken);
+ Response> actualResponse = mockClient.Object.Remove(expectedFrom, expectedTo, cancellationToken);
mockClient.Verify(callExpression, Times.Once());
Assert.AreEqual(expectedResponse, actualResponse);
diff --git a/sdk/communication/Azure.Communication.Sms/tests/SmsClientLiveTests.cs b/sdk/communication/Azure.Communication.Sms/tests/SmsClientLiveTests.cs
index 6ca4be841d952..77b83a6296ec2 100644
--- a/sdk/communication/Azure.Communication.Sms/tests/SmsClientLiveTests.cs
+++ b/sdk/communication/Azure.Communication.Sms/tests/SmsClientLiveTests.cs
@@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using NUnit.Framework;
+using Azure.Communication.Sms.Models;
namespace Azure.Communication.Sms.Tests
{
@@ -31,8 +32,8 @@ public async Task SendingSmsMessage()
message: "Hi");
SmsSendResult result = response.Value;
Console.WriteLine($"Sms id: {result.MessageId}");
- AssertHappyPath(result);
- AssertRawResponseHappyPath(response.GetRawResponse().ContentStream ?? new MemoryStream());
+ AssertSmsSendingHappyPath(result);
+ AssertSmsSendingRawResponseHappyPath(response.GetRawResponse().ContentStream ?? new MemoryStream());
}
catch (RequestFailedException ex)
{
@@ -57,8 +58,8 @@ public async Task SendingSmsMessageUsingTokenCredential()
message: "Hi");
SmsSendResult result = response.Value;
Console.WriteLine($"Sms id: {result.MessageId}");
- AssertHappyPath(result);
- AssertRawResponseHappyPath(response.GetRawResponse().ContentStream ?? new MemoryStream());
+ AssertSmsSendingHappyPath(result);
+ AssertSmsSendingRawResponseHappyPath(response.GetRawResponse().ContentStream ?? new MemoryStream());
}
catch (RequestFailedException ex)
{
@@ -110,11 +111,11 @@ public async Task SendingSmsMessageToGroupWithOptions()
Tag = "marketing", // custom tags
DeliveryReportTimeoutInSeconds = 90 // OPTIONAL
});
- AssertRawResponseHappyPath(response.GetRawResponse().ContentStream ?? new MemoryStream());
+ AssertSmsSendingRawResponseHappyPath(response.GetRawResponse().ContentStream ?? new MemoryStream());
foreach (SmsSendResult result in response.Value)
{
Console.WriteLine($"Sms id: {result.MessageId}");
- AssertHappyPath(result);
+ AssertSmsSendingHappyPath(result);
}
}
catch (RequestFailedException ex)
@@ -143,15 +144,15 @@ public async Task SendingTwoSmsMessages()
to: TestEnvironment.ToPhoneNumber,
message: "Hi");
- AssertRawResponseHappyPath(firstMessageResponse.GetRawResponse().ContentStream ?? new MemoryStream());
- AssertRawResponseHappyPath(secondMessageResponse.GetRawResponse().ContentStream ?? new MemoryStream());
+ AssertSmsSendingRawResponseHappyPath(firstMessageResponse.GetRawResponse().ContentStream ?? new MemoryStream());
+ AssertSmsSendingRawResponseHappyPath(secondMessageResponse.GetRawResponse().ContentStream ?? new MemoryStream());
SmsSendResult firstMessageResult = firstMessageResponse.Value;
SmsSendResult secondMessageResult = secondMessageResponse.Value;
Assert.AreNotEqual(firstMessageResult.MessageId, secondMessageResult.MessageId);
- AssertHappyPath(firstMessageResult);
- AssertHappyPath(secondMessageResult);
+ AssertSmsSendingHappyPath(firstMessageResult);
+ AssertSmsSendingHappyPath(secondMessageResult);
}
catch (RequestFailedException ex)
{
@@ -203,14 +204,134 @@ public async Task SendingSmsToNullNumberShouldThrow()
Assert.Fail("SendAsync should have thrown an exception.");
}
- private void AssertHappyPath(SmsSendResult sendResult)
+ [Test]
+ public async Task CheckOptOutFromNullNumberShouldThrow()
+ {
+ SmsClient client = CreateSmsClient();
+ try
+ {
+ IEnumerable? to = new string[] { TestEnvironment.ToPhoneNumber };
+ Response> result = await client.OptOuts.CheckAsync(
+ from: null,
+ to: to);
+ }
+ catch (ArgumentNullException ex)
+ {
+ Assert.AreEqual("from", ex.ParamName);
+ return;
+ }
+ Assert.Fail("CheckAsync should have thrown an exception.");
+ }
+
+ [Test]
+ public async Task CheckOptOutToNullNumberShouldThrow()
+ {
+ SmsClient client = CreateSmsClient();
+ try
+ {
+ IEnumerable? to = null;
+ Response> result = await client.OptOuts.CheckAsync(
+ from: TestEnvironment.FromPhoneNumber,
+ to: to);
+ }
+ catch (ArgumentNullException ex)
+ {
+ Assert.AreEqual("to", ex.ParamName);
+ return;
+ }
+ Assert.Fail("CheckAsync should have thrown an exception.");
+ }
+
+ [Test]
+ public async Task CheckOptOutToCollectionContainingNullShouldThrow()
+ {
+ SmsClient client = CreateSmsClient();
+ try
+ {
+#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
+ IEnumerable? to = new string[]
+ {
+ TestEnvironment.ToPhoneNumber,
+ null
+ };
+#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
+
+ Response> result = await client.OptOuts.CheckAsync(
+ from: TestEnvironment.FromPhoneNumber,
+ to: to);
+ }
+ catch (ArgumentNullException ex)
+ {
+ Assert.AreEqual("to", ex.ParamName);
+ return;
+ }
+ Assert.Fail("CheckAsync should have thrown an exception.");
+ }
+
+ [Test]
+ public async Task AddOptOutEndpointShouldMarkRecipientAsOptedOut()
+ {
+ SmsClient client = CreateSmsClient();
+ try
+ {
+ IEnumerable? to = new[] { TestEnvironment.ToPhoneNumber };
+
+ Response> addResult = await client.OptOuts.AddAsync(
+ from: TestEnvironment.FromPhoneNumber,
+ to: to);
+
+ Response> checkResult = await client.OptOuts.CheckAsync(
+ from: TestEnvironment.FromPhoneNumber,
+ to: to);
+
+ Assert.IsTrue(checkResult.Value[0].IsOptedOut);
+ }
+ catch (Exception ex)
+ {
+ Assert.Fail("Exception should not have been thrown.");
+ Console.WriteLine(ex);
+ return;
+ }
+ }
+
+ [Test]
+ public async Task RemoveOptOutEndpointShouldMarkRecipientAsOptedIn()
+ {
+ SmsClient client = CreateSmsClient();
+ try
+ {
+ IEnumerable? to = new[] { TestEnvironment.ToPhoneNumber };
+
+ Response> addResult = await client.OptOuts.AddAsync(
+ from: TestEnvironment.FromPhoneNumber,
+ to: to);
+
+ Response> removeResult = await client.OptOuts.RemoveAsync(
+ from: TestEnvironment.FromPhoneNumber,
+ to: to);
+
+ Response> checkResult = await client.OptOuts.CheckAsync(
+ from: TestEnvironment.FromPhoneNumber,
+ to: to);
+
+ Assert.IsFalse(checkResult.Value[0].IsOptedOut);
+ }
+ catch (Exception ex)
+ {
+ Assert.Fail("Exception should not have been thrown.");
+ Console.WriteLine(ex);
+ return;
+ }
+ }
+
+ private void AssertSmsSendingHappyPath(SmsSendResult sendResult)
{
Assert.True(sendResult.Successful);
Assert.AreEqual(202, sendResult.HttpStatusCode);
Assert.IsFalse(string.IsNullOrWhiteSpace(sendResult.MessageId));
}
- private void AssertRawResponseHappyPath(Stream contentStream)
+ private void AssertSmsSendingRawResponseHappyPath(Stream contentStream)
{
if (contentStream.Length > 0)
{