Added basic WhatsApp implementation
All checks were successful
Branch Build / build-test-deploy (push) Successful in 1m23s
All checks were successful
Branch Build / build-test-deploy (push) Successful in 1m23s
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
using System.Linq;
|
||||
using AMWD.Net.Api.LinkMobility.Webhook.WhatsApp;
|
||||
using AMWD.Net.Api.LinkMobility.WhatsApp;
|
||||
|
||||
namespace LinkMobility.Tests.Webhook.WhatsApp
|
||||
{
|
||||
[TestClass]
|
||||
public class WhatsAppNotificationTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void ShouldDeserializeWhatsAppNotificationWithMessageAndStatus()
|
||||
{
|
||||
// Arrange
|
||||
string json = @"{
|
||||
""customerChannelUuid"": ""11111111-2222-3333-4444-555555555555"",
|
||||
""sender"": ""46701234567"",
|
||||
""recipient"": ""123e4567-e89b-12d3-a456-426614174000"",
|
||||
""type"": ""whatsapp"",
|
||||
""whatsappNotification"": {
|
||||
""object"": ""whatsapp_business_account"",
|
||||
""entry"": [
|
||||
{
|
||||
""id"": ""123456789"",
|
||||
""changes"": [
|
||||
{
|
||||
""field"": ""messages"",
|
||||
""value"": {
|
||||
""messaging_product"": ""whatsapp"",
|
||||
""metadata"": {
|
||||
""display_phone_number"": ""+46701234567"",
|
||||
""phone_number_id"": ""111222333""
|
||||
},
|
||||
""contacts"": [
|
||||
{
|
||||
""profile"": {
|
||||
""name"": ""John Doe""
|
||||
},
|
||||
""wa_id"": ""46701234567""
|
||||
}
|
||||
],
|
||||
""messages"": [
|
||||
{
|
||||
""from"": ""46701234567"",
|
||||
""id"": ""wamid.123"",
|
||||
""timestamp"": 1672531200,
|
||||
""type"": ""text"",
|
||||
""text"": {
|
||||
""body"": ""Hello world""
|
||||
}
|
||||
}
|
||||
],
|
||||
""statuses"": [
|
||||
{
|
||||
""id"": ""wamid.123"",
|
||||
""status"": ""delivered"",
|
||||
""timestamp"": 1672531200,
|
||||
""recipient_id"": ""16505551234"",
|
||||
""recipient_participant_id"": ""16505550000"",
|
||||
""conversation"": {
|
||||
""id"": ""conv-1"",
|
||||
""expiration_timestamp"": 1672617600,
|
||||
""origin"": {
|
||||
""type"": ""service""
|
||||
}
|
||||
},
|
||||
""pricing"": {
|
||||
""billable"": true,
|
||||
""pricing_model"": ""PMP"",
|
||||
""type"": ""regular"",
|
||||
""category"": ""service""
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}";
|
||||
|
||||
// Act
|
||||
var notification = JsonConvert.DeserializeObject<WhatsAppNotification>(json);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(notification);
|
||||
Assert.AreEqual(Guid.Parse("11111111-2222-3333-4444-555555555555"), notification.CustomerChannelUuid);
|
||||
Assert.AreEqual("46701234567", notification.Sender);
|
||||
Assert.AreEqual("123e4567-e89b-12d3-a456-426614174000", notification.Recipient);
|
||||
Assert.AreEqual("whatsapp", notification.Type);
|
||||
|
||||
Assert.IsNotNull(notification.Body);
|
||||
Assert.AreEqual("whatsapp_business_account", notification.Body.Object);
|
||||
Assert.IsNotNull(notification.Body.Entries);
|
||||
Assert.HasCount(1, notification.Body.Entries);
|
||||
|
||||
var entry = notification.Body.Entries.First();
|
||||
Assert.AreEqual("123456789", entry.Id);
|
||||
Assert.IsNotNull(entry.Changes);
|
||||
Assert.HasCount(1, entry.Changes);
|
||||
|
||||
var change = entry.Changes.First();
|
||||
Assert.AreEqual("messages", change.Field);
|
||||
Assert.IsNotNull(change.Value);
|
||||
Assert.AreEqual("whatsapp", change.Value.MessagingProduct);
|
||||
|
||||
Assert.IsNotNull(change.Value.Metadata);
|
||||
Assert.AreEqual("+46701234567", change.Value.Metadata.DisplayPhoneNumber);
|
||||
Assert.AreEqual("111222333", change.Value.Metadata.PhoneNumberId);
|
||||
|
||||
Assert.IsNotNull(change.Value.Contacts);
|
||||
Assert.HasCount(1, change.Value.Contacts);
|
||||
|
||||
var contact = change.Value.Contacts.First();
|
||||
Assert.IsNotNull(contact.Profile);
|
||||
Assert.AreEqual("John Doe", contact.Profile.Name);
|
||||
Assert.AreEqual("46701234567", contact.WhatsAppId);
|
||||
|
||||
Assert.IsNotNull(change.Value.Messages);
|
||||
Assert.HasCount(1, change.Value.Messages);
|
||||
|
||||
var message = change.Value.Messages.First();
|
||||
Assert.AreEqual("46701234567", message.From);
|
||||
Assert.AreEqual("wamid.123", message.Id);
|
||||
Assert.IsNotNull(message.Timestamp);
|
||||
|
||||
// 1672531200 -> 2023-01-01T00:00:00Z
|
||||
var expected = new DateTime(2023, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
Assert.AreEqual(expected, message.Timestamp.Value.ToUniversalTime());
|
||||
Assert.IsTrue(message.Type.HasValue);
|
||||
Assert.AreEqual(MessageType.Text, message.Type.Value);
|
||||
Assert.IsNotNull(message.Text);
|
||||
Assert.IsNotNull(message.Text.Body);
|
||||
Assert.AreEqual("Hello world", message.Text.Body);
|
||||
|
||||
Assert.IsNotNull(change.Value.Statuses);
|
||||
Assert.HasCount(1, change.Value.Statuses);
|
||||
|
||||
var status = change.Value.Statuses.First();
|
||||
Assert.AreEqual("wamid.123", status.Id);
|
||||
Assert.IsTrue(status.DeliveryStatus.HasValue);
|
||||
Assert.AreEqual(DeliveryStatus.Delivered, status.DeliveryStatus.Value);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DeserializeShouldThrowOnInvalidJson()
|
||||
{
|
||||
// Arrange
|
||||
string invalid = "this is not json";
|
||||
|
||||
// Act & Assert
|
||||
Assert.ThrowsExactly<JsonReaderException>(() => JsonConvert.DeserializeObject<WhatsAppNotification>(invalid));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using AMWD.Net.Api.LinkMobility.WhatsApp;
|
||||
|
||||
namespace LinkMobility.Tests.WhatsApp.Contents
|
||||
{
|
||||
[TestClass]
|
||||
public class AudioMessageContentTest
|
||||
{
|
||||
[TestMethod]
|
||||
[DataRow(null)]
|
||||
[DataRow("")]
|
||||
[DataRow("Caption")]
|
||||
public void ShouldValidateSuccessful(string caption)
|
||||
{
|
||||
// Arrange
|
||||
var content = new AudioMessageContent("https://example.com/audio.mp3");
|
||||
content.Body.Caption = caption;
|
||||
|
||||
// Act
|
||||
bool isValid = content.IsValid();
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(isValid);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[DataRow(null)]
|
||||
[DataRow("")]
|
||||
[DataRow(" ")]
|
||||
[DataRow("ftp://example.com/audio.mp3")]
|
||||
[DataRow("www.example.org/audio.mp3")]
|
||||
public void ShouldValidateNotSuccessful(string url)
|
||||
{
|
||||
// Arrange
|
||||
var content = new AudioMessageContent(url);
|
||||
|
||||
// Act
|
||||
bool isValid = content.IsValid();
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(isValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using AMWD.Net.Api.LinkMobility.WhatsApp;
|
||||
|
||||
namespace LinkMobility.Tests.WhatsApp.Contents
|
||||
{
|
||||
[TestClass]
|
||||
public class DocumentMessageContentTest
|
||||
{
|
||||
[TestMethod]
|
||||
[DataRow(null)]
|
||||
[DataRow("")]
|
||||
[DataRow("Caption")]
|
||||
public void ShouldValidateSuccessful(string caption)
|
||||
{
|
||||
// Arrange
|
||||
var content = new DocumentMessageContent("https://example.com/doc.pdf");
|
||||
content.Body.Caption = caption;
|
||||
|
||||
// Act
|
||||
bool isValid = content.IsValid();
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(isValid);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[DataRow(null)]
|
||||
[DataRow("")]
|
||||
[DataRow(" ")]
|
||||
[DataRow("ftp://example.com/doc.pdf")]
|
||||
[DataRow("www.example.org/doc.pdf")]
|
||||
public void ShouldValidateNotSuccessful(string url)
|
||||
{
|
||||
// Arrange
|
||||
var content = new DocumentMessageContent(url);
|
||||
|
||||
// Act
|
||||
bool isValid = content.IsValid();
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(isValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using AMWD.Net.Api.LinkMobility.WhatsApp;
|
||||
|
||||
namespace LinkMobility.Tests.WhatsApp.Contents
|
||||
{
|
||||
[TestClass]
|
||||
public class ImageMessageContentTest
|
||||
{
|
||||
[TestMethod]
|
||||
[DataRow(null)]
|
||||
[DataRow("")]
|
||||
[DataRow("Caption")]
|
||||
public void ShouldValidateSuccessful(string caption)
|
||||
{
|
||||
// Arrange
|
||||
var content = new ImageMessageContent("https://example.com/image.jpg");
|
||||
content.Body.Caption = caption;
|
||||
|
||||
// Act
|
||||
bool isValid = content.IsValid();
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(isValid);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[DataRow(null)]
|
||||
[DataRow("")]
|
||||
[DataRow(" ")]
|
||||
[DataRow("ftp://example.com/image.jpg")]
|
||||
[DataRow("www.example.org/image.jpg")]
|
||||
public void ShouldValidateNotSuccessful(string url)
|
||||
{
|
||||
// Arrange
|
||||
var content = new ImageMessageContent(url);
|
||||
|
||||
// Act
|
||||
bool isValid = content.IsValid();
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(isValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using AMWD.Net.Api.LinkMobility.WhatsApp;
|
||||
|
||||
namespace LinkMobility.Tests.WhatsApp.Contents
|
||||
{
|
||||
[TestClass]
|
||||
public class TextMessageContentTest
|
||||
{
|
||||
[TestMethod]
|
||||
[DataRow(true)]
|
||||
[DataRow(false)]
|
||||
public void ShouldValidateSuccessful(bool previewUrl)
|
||||
{
|
||||
// Arrange
|
||||
var content = new TextMessageContent("Hello, World!");
|
||||
content.Body.PreviewUrl = previewUrl;
|
||||
|
||||
// Act
|
||||
bool isValid = content.IsValid();
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(isValid);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[DataRow(null)]
|
||||
[DataRow("")]
|
||||
[DataRow(" ")]
|
||||
public void ShouldValidateNotSuccessful(string text)
|
||||
{
|
||||
// Arrange
|
||||
var content = new TextMessageContent(text);
|
||||
|
||||
// Act
|
||||
bool isValid = content.IsValid();
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(isValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using AMWD.Net.Api.LinkMobility.WhatsApp;
|
||||
|
||||
namespace LinkMobility.Tests.WhatsApp.Contents
|
||||
{
|
||||
[TestClass]
|
||||
public class VideoMessageContentTest
|
||||
{
|
||||
[TestMethod]
|
||||
[DataRow(null)]
|
||||
[DataRow("")]
|
||||
[DataRow("Caption")]
|
||||
public void ShouldValidateSuccessful(string caption)
|
||||
{
|
||||
// Arrange
|
||||
var content = new VideoMessageContent("https://example.com/video.mp4");
|
||||
content.Body.Caption = caption;
|
||||
|
||||
// Act
|
||||
bool isValid = content.IsValid();
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(isValid);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[DataRow(null)]
|
||||
[DataRow("")]
|
||||
[DataRow(" ")]
|
||||
[DataRow("ftp://example.com/video.mp4")]
|
||||
[DataRow("www.example.org/video.mp4")]
|
||||
public void ShouldValidateNotSuccessful(string url)
|
||||
{
|
||||
// Arrange
|
||||
var content = new VideoMessageContent(url);
|
||||
|
||||
// Act
|
||||
bool isValid = content.IsValid();
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(isValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
202
test/LinkMobility.Tests/WhatsApp/SendWhatsAppMessageTest.cs
Normal file
202
test/LinkMobility.Tests/WhatsApp/SendWhatsAppMessageTest.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AMWD.Net.Api.LinkMobility;
|
||||
using AMWD.Net.Api.LinkMobility.WhatsApp;
|
||||
using LinkMobility.Tests.Helpers;
|
||||
using Moq.Protected;
|
||||
|
||||
namespace LinkMobility.Tests.WhatsApp
|
||||
{
|
||||
[TestClass]
|
||||
public class SendWhatsAppMessageTest
|
||||
{
|
||||
public TestContext TestContext { get; set; }
|
||||
|
||||
private const string BASE_URL = "https://localhost/rest/";
|
||||
|
||||
private Mock<IAuthentication> _authenticationMock;
|
||||
private Mock<ClientOptions> _clientOptionsMock;
|
||||
private HttpMessageHandlerMock _httpMessageHandlerMock;
|
||||
|
||||
private Guid _uuid;
|
||||
private SendWhatsAppMessageRequest _request;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_authenticationMock = new Mock<IAuthentication>();
|
||||
_clientOptionsMock = new Mock<ClientOptions>();
|
||||
_httpMessageHandlerMock = new HttpMessageHandlerMock();
|
||||
|
||||
_authenticationMock
|
||||
.Setup(a => a.AddHeader(It.IsAny<HttpClient>()))
|
||||
.Callback<HttpClient>(c => c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Scheme", "Parameter"));
|
||||
|
||||
_clientOptionsMock.Setup(c => c.BaseUrl).Returns(BASE_URL);
|
||||
_clientOptionsMock.Setup(c => c.Timeout).Returns(TimeSpan.FromSeconds(30));
|
||||
_clientOptionsMock.Setup(c => c.DefaultHeaders).Returns(new Dictionary<string, string>());
|
||||
_clientOptionsMock.Setup(c => c.DefaultQueryParams).Returns(new Dictionary<string, string>());
|
||||
_clientOptionsMock.Setup(c => c.AllowRedirects).Returns(true);
|
||||
_clientOptionsMock.Setup(c => c.UseProxy).Returns(false);
|
||||
|
||||
_uuid = Guid.NewGuid();
|
||||
|
||||
var image = new ImageMessageContent("https://example.com/image.jpg");
|
||||
image.Body.Caption = "Hello World :)";
|
||||
_request = new SendWhatsAppMessageRequest(image, ["436991234567"]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ShouldSendWhatsAppMessage()
|
||||
{
|
||||
// Arrange
|
||||
_httpMessageHandlerMock.Responses.Enqueue(new HttpResponseMessage
|
||||
{
|
||||
StatusCode = HttpStatusCode.OK,
|
||||
Content = new StringContent(@"{ ""clientMessageId"": ""myUniqueId"", ""statusCode"": 2000, ""statusMessage"": ""OK"", ""transferId"": ""0059d0b20100a0a8b803"" }", Encoding.UTF8, "application/json"),
|
||||
});
|
||||
|
||||
var client = GetClient();
|
||||
|
||||
// Act
|
||||
var response = await client.SendWhatsAppMessage(_uuid, _request, TestContext.CancellationToken);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(response);
|
||||
|
||||
Assert.AreEqual("myUniqueId", response.ClientMessageId);
|
||||
Assert.AreEqual(StatusCodes.Ok, response.StatusCode);
|
||||
Assert.AreEqual("OK", response.StatusMessage);
|
||||
Assert.AreEqual("0059d0b20100a0a8b803", response.TransferId);
|
||||
|
||||
Assert.HasCount(1, _httpMessageHandlerMock.RequestCallbacks);
|
||||
|
||||
var callback = _httpMessageHandlerMock.RequestCallbacks.First();
|
||||
Assert.AreEqual(HttpMethod.Post, callback.HttpMethod);
|
||||
Assert.AreEqual($"https://localhost/rest/channels/{_uuid}/send/whatsapp", callback.Url);
|
||||
Assert.AreEqual(@"{""messageContent"":{""type"":""image"",""image"":{""link"":""https://example.com/image.jpg"",""caption"":""Hello World :)""}},""recipientAddressList"":[""436991234567""]}", callback.Content);
|
||||
|
||||
Assert.HasCount(3, callback.Headers);
|
||||
Assert.IsTrue(callback.Headers.ContainsKey("Accept"));
|
||||
Assert.IsTrue(callback.Headers.ContainsKey("Authorization"));
|
||||
Assert.IsTrue(callback.Headers.ContainsKey("User-Agent"));
|
||||
|
||||
Assert.AreEqual("application/json", callback.Headers["Accept"]);
|
||||
Assert.AreEqual("Scheme Parameter", callback.Headers["Authorization"]);
|
||||
Assert.AreEqual("LinkMobilityClient/1.0.0", callback.Headers["User-Agent"]);
|
||||
|
||||
_httpMessageHandlerMock.Protected.Verify("SendAsync", Times.Once(), ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>());
|
||||
|
||||
_clientOptionsMock.VerifyGet(o => o.DefaultQueryParams, Times.Once);
|
||||
VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldThrowOnNullRequest()
|
||||
{
|
||||
// Arrange
|
||||
var client = GetClient();
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.ThrowsExactly<ArgumentNullException>(() => client.SendWhatsAppMessage(_uuid, null, TestContext.CancellationToken));
|
||||
Assert.AreEqual("request", ex.ParamName);
|
||||
|
||||
VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldThrowOnMissingMessage()
|
||||
{
|
||||
// Arrange
|
||||
var req = new SendWhatsAppMessageRequest(null, ["436991234567"]);
|
||||
var client = GetClient();
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.ThrowsExactly<ArgumentException>(() => client.SendWhatsAppMessage(_uuid, req, TestContext.CancellationToken));
|
||||
Assert.AreEqual("MessageContent", ex.ParamName);
|
||||
|
||||
VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldThrowOnNoRecipients()
|
||||
{
|
||||
// Arrange
|
||||
var req = new SendWhatsAppMessageRequest(new TextMessageContent("Hello"), []);
|
||||
var client = GetClient();
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.ThrowsExactly<ArgumentException>(() => client.SendWhatsAppMessage(_uuid, req, TestContext.CancellationToken));
|
||||
Assert.AreEqual("RecipientAddressList", ex.ParamName);
|
||||
|
||||
VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldThrowOnInvalidRecipient()
|
||||
{
|
||||
// Arrange
|
||||
var client = GetClient();
|
||||
var req = new SendWhatsAppMessageRequest(new TextMessageContent("Hello"), ["4791234567", "invalid-recipient"]);
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.ThrowsExactly<ArgumentException>(() => client.SendWhatsAppMessage(_uuid, req, TestContext.CancellationToken));
|
||||
|
||||
Assert.AreEqual("RecipientAddressList", ex.ParamName);
|
||||
Assert.StartsWith($"Recipient address 'invalid-recipient' is not a valid MSISDN format.", ex.Message);
|
||||
|
||||
VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldThrowOnInvalidContentCategory()
|
||||
{
|
||||
// Arrange
|
||||
_request.ContentCategory = 0;
|
||||
var client = GetClient();
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.ThrowsExactly<ArgumentException>(() => client.SendWhatsAppMessage(_uuid, _request, TestContext.CancellationToken));
|
||||
Assert.AreEqual("ContentCategory", ex.ParamName);
|
||||
Assert.StartsWith("Content category '0' is not valid.", ex.Message);
|
||||
|
||||
VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
private void VerifyNoOtherCalls()
|
||||
{
|
||||
_authenticationMock.VerifyNoOtherCalls();
|
||||
_clientOptionsMock.VerifyNoOtherCalls();
|
||||
_httpMessageHandlerMock.Mock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
private LinkMobilityClient GetClient()
|
||||
{
|
||||
var client = new LinkMobilityClient(_authenticationMock.Object, _clientOptionsMock.Object);
|
||||
|
||||
var httpClient = new HttpClient(_httpMessageHandlerMock.Mock.Object)
|
||||
{
|
||||
Timeout = _clientOptionsMock.Object.Timeout,
|
||||
BaseAddress = new Uri(_clientOptionsMock.Object.BaseUrl)
|
||||
};
|
||||
|
||||
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("LinkMobilityClient", "1.0.0"));
|
||||
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
|
||||
_authenticationMock.Object.AddHeader(httpClient);
|
||||
|
||||
_authenticationMock.Invocations.Clear();
|
||||
_clientOptionsMock.Invocations.Clear();
|
||||
|
||||
ReflectionHelper.GetPrivateField<HttpClient>(client, "_httpClient")?.Dispose();
|
||||
ReflectionHelper.SetPrivateField(client, "_httpClient", httpClient);
|
||||
|
||||
return client;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user