diff --git a/Code/Kavenegar.Core/BaseKavenegarApi.cs b/Code/Kavenegar.Core/BaseKavenegarApi.cs new file mode 100644 index 0000000..6ccb08c --- /dev/null +++ b/Code/Kavenegar.Core/BaseKavenegarApi.cs @@ -0,0 +1,35 @@ +using Kavenegar.Core.Dto.Result; +using Shared.Infrastructure; + +namespace Kavenegar.Core; + +public class BaseKavenegarApi +{ + private const string ApiAddress = "https://api.kavenegar.com/v1"; + private readonly IHttpClientHelper _httpClientHelper; + + protected BaseKavenegarApi( + IHttpClientHelper httpClientHelper, + string apiKey) + { + _httpClientHelper = httpClientHelper; + _httpClientHelper.BaseAddress = Path.Combine(ApiAddress, apiKey); + } + + protected async Task RequestSender( + string requestUri, + object? body, + Dictionary? queryParams, + CancellationToken cancellationToken) + { + var httpResponseMessage = await _httpClientHelper.PostAsync( + requestUri, + body, + queryParams, + cancellationToken); + + var deserializedObj = await httpResponseMessage.Deserialize>(cancellationToken); + + return deserializedObj == null ? default : deserializedObj.Value; + } +} \ No newline at end of file diff --git a/Code/Kavenegar.Core/DependencyManager.cs b/Code/Kavenegar.Core/DependencyManager.cs new file mode 100644 index 0000000..8a71252 --- /dev/null +++ b/Code/Kavenegar.Core/DependencyManager.cs @@ -0,0 +1,27 @@ +using Microsoft.Extensions.DependencyInjection; +using Shared.Infrastructure; + +namespace Kavenegar.Core; + +public static class DependencyManager +{ + public static IServiceCollection AddKavenegar( + this IServiceCollection serviceCollection, + string apiKey) + { + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + + serviceCollection.AddScoped( + serviceProvider => new KavenegarProfileApi( + serviceProvider.GetRequiredService(), + apiKey)); + + serviceCollection.AddScoped( + serviceProvider => new KavenegarMessageSender( + serviceProvider.GetRequiredService(), + apiKey)); + + return serviceCollection; + } +} \ No newline at end of file diff --git a/Code/Kavenegar.Core/Dto/Message/MessageInfo.cs b/Code/Kavenegar.Core/Dto/Message/MessageInfo.cs new file mode 100644 index 0000000..ade3c35 --- /dev/null +++ b/Code/Kavenegar.Core/Dto/Message/MessageInfo.cs @@ -0,0 +1,16 @@ +using Kavenegar.Core.Enums; + +namespace Kavenegar.Core.Dto.Message; + +public class MessageInfo +{ + public MessageInfo( + string message) + { + Message = message; + } + + public string? Sender { get; set; } + public string Message { get; set; } + public MessageType Type { get; set; } = MessageType.Flash; +} \ No newline at end of file diff --git a/Code/Kavenegar.Core/Dto/Message/SendMessageInfo.cs b/Code/Kavenegar.Core/Dto/Message/SendMessageInfo.cs new file mode 100644 index 0000000..bfb9505 --- /dev/null +++ b/Code/Kavenegar.Core/Dto/Message/SendMessageInfo.cs @@ -0,0 +1,16 @@ +namespace Kavenegar.Core.Dto.Message; + +public class SendMessageInfo +{ + public SendMessageInfo( + MessageInfo messageInfo, + string receptor) + { + MessageInfo = messageInfo; + Receptor = receptor; + } + + public MessageInfo MessageInfo { get; set; } + public string Receptor { get; set; } + public string LocalMessageId { get; set; } = null!; +} \ No newline at end of file diff --git a/Kavenegar.Core/Dto/Message/SendMultiMessageRequest.cs b/Code/Kavenegar.Core/Dto/Message/SendMultiMessageRequest.cs similarity index 58% rename from Kavenegar.Core/Dto/Message/SendMultiMessageRequest.cs rename to Code/Kavenegar.Core/Dto/Message/SendMultiMessageRequest.cs index 4be63d1..cd12628 100644 --- a/Kavenegar.Core/Dto/Message/SendMultiMessageRequest.cs +++ b/Code/Kavenegar.Core/Dto/Message/SendMultiMessageRequest.cs @@ -2,7 +2,13 @@ public class SendMultiMessageRequest { - public IEnumerable SendMessageInfos { get; set; } = null!; + public SendMultiMessageRequest( + IEnumerable sendMessageInfos) + { + SendMessageInfos = sendMessageInfos; + } + + public IEnumerable SendMessageInfos { get; set; } public DateTime Date { get; set; } public bool Hide { get; set; } } \ No newline at end of file diff --git a/Code/Kavenegar.Core/Dto/Message/SendSingleMessageRequest.cs b/Code/Kavenegar.Core/Dto/Message/SendSingleMessageRequest.cs new file mode 100644 index 0000000..a46ec14 --- /dev/null +++ b/Code/Kavenegar.Core/Dto/Message/SendSingleMessageRequest.cs @@ -0,0 +1,23 @@ +namespace Kavenegar.Core.Dto.Message; + +public class SendSingleMessageRequest +{ + public SendSingleMessageRequest( + MessageInfo messageInfo, + Dictionary receptorLocalMessageIds) + { + MessageInfo = messageInfo; + ReceptorLocalMessageIds = receptorLocalMessageIds; + } + + public MessageInfo MessageInfo { get; set; } + + /// + /// Key is receptor + /// Value is local message id + /// + public Dictionary ReceptorLocalMessageIds { get; set; } + + public DateTime? Date { get; set; } + public bool Hide { get; set; } +} \ No newline at end of file diff --git a/Code/Kavenegar.Core/Dto/Message/VerifyLookupRequest.cs b/Code/Kavenegar.Core/Dto/Message/VerifyLookupRequest.cs new file mode 100644 index 0000000..18a8de1 --- /dev/null +++ b/Code/Kavenegar.Core/Dto/Message/VerifyLookupRequest.cs @@ -0,0 +1,25 @@ +using Kavenegar.Core.Enums; + +namespace Kavenegar.Core.Dto.Message; + +public class VerifyLookupRequest +{ + public VerifyLookupRequest( + string receptor, + string template, + string token1) + { + Receptor = receptor; + Template = template; + Token1 = token1; + } + + public string Receptor { get; set; } + public string Template { get; set; } + public string Token1 { get; set; } + public string? Token2 { get; set; } + public string? Token3 { get; set; } + public string? Token4 { get; set; } + public string? Token5 { get; set; } + public VerifyLookupType? VerifyLookupType { get; set; } = null!; +} \ No newline at end of file diff --git a/Kavenegar.Core/Dto/Result/AccountConfigDto.cs b/Code/Kavenegar.Core/Dto/Result/AccountConfigDto.cs similarity index 100% rename from Kavenegar.Core/Dto/Result/AccountConfigDto.cs rename to Code/Kavenegar.Core/Dto/Result/AccountConfigDto.cs diff --git a/Kavenegar.Core/Dto/Result/AccountInfoDto.cs b/Code/Kavenegar.Core/Dto/Result/AccountInfoDto.cs similarity index 100% rename from Kavenegar.Core/Dto/Result/AccountInfoDto.cs rename to Code/Kavenegar.Core/Dto/Result/AccountInfoDto.cs diff --git a/Kavenegar.Core/Dto/Result/CountInboxDto.cs b/Code/Kavenegar.Core/Dto/Result/CountInboxDto.cs similarity index 100% rename from Kavenegar.Core/Dto/Result/CountInboxDto.cs rename to Code/Kavenegar.Core/Dto/Result/CountInboxDto.cs diff --git a/Kavenegar.Core/Dto/Result/CountOutboxDto.cs b/Code/Kavenegar.Core/Dto/Result/CountOutboxDto.cs similarity index 100% rename from Kavenegar.Core/Dto/Result/CountOutboxDto.cs rename to Code/Kavenegar.Core/Dto/Result/CountOutboxDto.cs diff --git a/Kavenegar.Core/Dto/Result/LocalStatusDto.cs b/Code/Kavenegar.Core/Dto/Result/LocalStatusDto.cs similarity index 100% rename from Kavenegar.Core/Dto/Result/LocalStatusDto.cs rename to Code/Kavenegar.Core/Dto/Result/LocalStatusDto.cs diff --git a/Kavenegar.Core/Dto/Result/ReceivedMessageDto.cs b/Code/Kavenegar.Core/Dto/Result/ReceivedMessageDto.cs similarity index 100% rename from Kavenegar.Core/Dto/Result/ReceivedMessageDto.cs rename to Code/Kavenegar.Core/Dto/Result/ReceivedMessageDto.cs diff --git a/Kavenegar.Core/Dto/Result/ResultDto.cs b/Code/Kavenegar.Core/Dto/Result/ResultDto.cs similarity index 100% rename from Kavenegar.Core/Dto/Result/ResultDto.cs rename to Code/Kavenegar.Core/Dto/Result/ResultDto.cs diff --git a/Kavenegar.Core/Dto/Result/ResultStatus.cs b/Code/Kavenegar.Core/Dto/Result/ResultStatus.cs similarity index 100% rename from Kavenegar.Core/Dto/Result/ResultStatus.cs rename to Code/Kavenegar.Core/Dto/Result/ResultStatus.cs diff --git a/Code/Kavenegar.Core/Dto/Result/SendResultDto.cs b/Code/Kavenegar.Core/Dto/Result/SendResultDto.cs new file mode 100644 index 0000000..8cff73f --- /dev/null +++ b/Code/Kavenegar.Core/Dto/Result/SendResultDto.cs @@ -0,0 +1,32 @@ +using System.Text.Json.Serialization; +using Kavenegar.Core.Enums; +using Shared.Infrastructure; + +namespace Kavenegar.Core.Dto.Result; + +public class SendResultDto +{ + public long MessageId { get; set; } + public string Message { get; set; } = null!; + + [JsonPropertyName("Status")] + public int StatusNumber { get; set; } + + public MessageStatus MessageStatus => StatusCaster(StatusNumber); + public string StatusText { get; set; } = null!; + public string Sender { get; set; } = null!; + public string Receptor { get; set; } = null!; + + [JsonPropertyName("Date")] + public long UnixDate { get; set; } + + public DateTime DateTime => UnixDate.ToDateTime(); + public int Cost { get; set; } + + private MessageStatus StatusCaster( + int status) + { + if (Enum.IsDefined(typeof(MessageStatus), StatusNumber)) return (MessageStatus)status; + return status == 5 ? MessageStatus.SentToCenter : MessageStatus.Unknown; + } +} \ No newline at end of file diff --git a/Kavenegar.Core/Dto/Result/StatusMessageDto.cs b/Code/Kavenegar.Core/Dto/Result/StatusMessageDto.cs similarity index 100% rename from Kavenegar.Core/Dto/Result/StatusMessageDto.cs rename to Code/Kavenegar.Core/Dto/Result/StatusMessageDto.cs diff --git a/Kavenegar.Core/Enums/MessageStatus.cs b/Code/Kavenegar.Core/Enums/MessageStatus.cs similarity index 91% rename from Kavenegar.Core/Enums/MessageStatus.cs rename to Code/Kavenegar.Core/Enums/MessageStatus.cs index 9f00180..ecc71c5 100644 --- a/Kavenegar.Core/Enums/MessageStatus.cs +++ b/Code/Kavenegar.Core/Enums/MessageStatus.cs @@ -2,10 +2,10 @@ namespace Kavenegar.Core.Enums; public enum MessageStatus { + Unknown = 0, Queued = 1, Scheduled = 2, SentToCenter = 4, - SentToCenter2 = 5, Delivered = 10, Undelivered = 11, Canceled = 13, diff --git a/Kavenegar.Core/Enums/MessageType.cs b/Code/Kavenegar.Core/Enums/MessageType.cs similarity index 100% rename from Kavenegar.Core/Enums/MessageType.cs rename to Code/Kavenegar.Core/Enums/MessageType.cs diff --git a/Kavenegar.Core/Enums/VerifyLookupType.cs b/Code/Kavenegar.Core/Enums/VerifyLookupType.cs similarity index 100% rename from Kavenegar.Core/Enums/VerifyLookupType.cs rename to Code/Kavenegar.Core/Enums/VerifyLookupType.cs diff --git a/Code/Kavenegar.Core/IKavenegarMessageSender.cs b/Code/Kavenegar.Core/IKavenegarMessageSender.cs new file mode 100644 index 0000000..076c359 --- /dev/null +++ b/Code/Kavenegar.Core/IKavenegarMessageSender.cs @@ -0,0 +1,75 @@ +using Kavenegar.Core.Dto.Message; +using Kavenegar.Core.Dto.Result; +using Kavenegar.Core.Enums; + +namespace Kavenegar.Core; + +public interface IKavenegarMessageSender +{ + /// + /// Send one message for only the receptor + /// + /// Message text. + /// Who receives message. + /// Number to send message if you set it empty the default number will be used. + /// Unique id which you set for the id. + /// The date time you wand the message to be sent. If it is null message will be send asap. + /// If true receptor number will be hidden. + /// Type of message. + /// Token to cancel request. + /// + Task Send( + string message, + string receptor, + string sender = "", + string localMessageId = "", + DateTime? dateTime = null, + bool hide = false, + MessageType messageType = MessageType.AppMemory, + CancellationToken cancellationToken = default); + + /// + /// Send message text for each receptor with the localMessageId + /// + /// Message text. + /// Key for receptor and value is for local message id. + /// Number to send message if you set it empty the default number will be used. + /// The date time you wand the message to be sent. If it is null message will be send asap. + /// If true receptor number will be hidden. + /// Type of message. + /// Token to cancel request. + /// + Task?> Send( + string message, + Dictionary receptors, + string sender = "", + DateTime? dateTime = null, + bool hide = false, + MessageType messageType = MessageType.AppMemory, + CancellationToken cancellationToken = default); + + public Task?> Send( + SendSingleMessageRequest message, + CancellationToken cancellationToken = default); + + Task?> Send( + IEnumerable sendMessageInfos, + bool hide = false, + DateTime? dateTime = null, + CancellationToken cancellationToken = default); + + Task?> Send( + SendMultiMessageRequest messages, + CancellationToken cancellationToken = default); + + Task VerifyLookup( + string receptor, + string template, + string token1, + string? token2 = null, + string? token3 = null, + string? token4 = null, + string? token5 = null, + VerifyLookupType? type = null, + CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/Code/Kavenegar.Core/IKavenegarProfileApi.cs b/Code/Kavenegar.Core/IKavenegarProfileApi.cs new file mode 100644 index 0000000..c2e78a1 --- /dev/null +++ b/Code/Kavenegar.Core/IKavenegarProfileApi.cs @@ -0,0 +1,80 @@ +using Kavenegar.Core.Dto.Result; +using Kavenegar.Core.Enums; + +namespace Kavenegar.Core; + +public interface IKavenegarProfileApi +{ + Task Status( + string messageId, + CancellationToken cancellationToken = default); + + Task?> Status( + IEnumerable messageIds, + CancellationToken cancellationToken = default); + + Task StatusLocalMessageId( + string messageId, + CancellationToken cancellationToken = default); + + Task?> StatusLocalMessageId( + IEnumerable messageIds, + CancellationToken cancellationToken = default); + + Task Select( + string messageId, + CancellationToken cancellationToken = default); + + Task?> Select( + IEnumerable messageIds, + CancellationToken cancellationToken = default); + + Task?> SelectOutbox( + DateTime startDate, + DateTime? endDate = null, + string? sender = null, + CancellationToken cancellationToken = default); + + Task?> LatestOutbox( + int? pageSize = null, + string? sender = null, + CancellationToken cancellationToken = default); + + Task CountOutbox( + DateTime startDate, + DateTime? endDate = null, + MessageStatus? status = null, + CancellationToken cancellationToken = default); + + Task Cancel( + string messageId, + CancellationToken cancellationToken = default); + + Task?> Cancel( + IEnumerable ids, + CancellationToken cancellationToken = default); + + Task?> Receive( + string line, + bool isRead, + CancellationToken cancellationToken = default); + + Task CountInbox( + DateTime startDate, + DateTime? endDate, + string? lineNumber, + bool? isRead, + CancellationToken cancellationToken = default); + + Task AccountInfo( + CancellationToken cancellationToken = default); + + Task AccountConfig( + string? apiLogs = null, + string? dailyReport = null, + string? debugMode = null, + string? defaultSender = null, + int? minCreditAlarm = null, + string? resendFailed = null, + CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/Code/Kavenegar.Core/Kavenegar.Core.csproj b/Code/Kavenegar.Core/Kavenegar.Core.csproj new file mode 100644 index 0000000..28afc84 --- /dev/null +++ b/Code/Kavenegar.Core/Kavenegar.Core.csproj @@ -0,0 +1,33 @@ + + + + 1.1.0 + enable + enable + A cross-platform library for the kavenegar sms provider; written in C# + Kavenegar.Core + Kavenegar.Core + Kavenegar.Core + KavenegarDotNetCore + Kavenegar Core kavenegar.Core kavenegarCore Sms + https://github.com/kavenegar/Kavenegar.Core + Library + true + true + MohamadAminSayedBagheri HadiEskandari Ardavan HosseinRezaei Mberneti MohammadAmirriazi + git + https://github.com/kavenegar/Kavenegar.Core + Kavenegar + true + net6.0;net6.0-windows + + + + + + + + + + + diff --git a/Code/Kavenegar.Core/KavenegarMessageSender.cs b/Code/Kavenegar.Core/KavenegarMessageSender.cs new file mode 100644 index 0000000..94a540d --- /dev/null +++ b/Code/Kavenegar.Core/KavenegarMessageSender.cs @@ -0,0 +1,250 @@ +using System.Net; +using Kavenegar.Core.Dto.Message; +using Kavenegar.Core.Dto.Result; +using Kavenegar.Core.Enums; +using Shared.Infrastructure; + +namespace Kavenegar.Core; + +public class KavenegarMessageSender + : BaseKavenegarApi, + IKavenegarMessageSender +{ + public KavenegarMessageSender( + IHttpClientHelper httpClientHelper, + string apiKey) : base(httpClientHelper, apiKey) + { + } + + /// + /// Send one message for only the receptor + /// + /// Message text. + /// Who receives message. + /// Number to send message if you set it empty the default number will be used. + /// Unique id which you set for the id. + /// The date time you wand the message to be sent. If it is null message will be send asap. + /// If true receptor number will be hidden. + /// Type of message. + /// Token to cancel request. + /// + public async Task Send( + string message, + string receptor, + string sender = "", + string localMessageId = "", + DateTime? dateTime = null, + bool hide = false, + MessageType messageType = MessageType.Flash, + CancellationToken cancellationToken = default) + { + var messageInfo = new MessageInfo(message) + { + Sender = sender, + Type = messageType + }; + + var receptorLocalMessageIds = new Dictionary + { + { + receptor, localMessageId + } + }; + + var sendSingleMessageRequest = new SendSingleMessageRequest(messageInfo, receptorLocalMessageIds) + { + Hide = hide + }; + + if (dateTime.HasValue) sendSingleMessageRequest.Date = dateTime; + + return (await Send(sendSingleMessageRequest, cancellationToken))?.FirstOrDefault(); + } + + /// + /// Send message text for each receptor with the localMessageId + /// + /// Message text. + /// Key for receptor and value is for local message id. + /// Number to send message if you set it empty the default number will be used. + /// The date time you wand the message to be sent. If it is null message will be send asap. + /// If true receptor number will be hidden. + /// Type of message. + /// Token to cancel request. + /// + public async Task?> Send( + string message, + Dictionary receptors, + string sender = "", + DateTime? dateTime = null, + bool hide = false, + MessageType messageType = MessageType.Flash, + CancellationToken cancellationToken = default) + { + var sendSingleMessageRequest = new SendSingleMessageRequest( + new MessageInfo(message) + { + Sender = sender, + Type = messageType + }, + receptors) + { + Hide = hide + }; + + if (dateTime.HasValue) sendSingleMessageRequest.Date = dateTime; + + return await Send(sendSingleMessageRequest, cancellationToken); + } + + public async Task?> Send( + SendSingleMessageRequest message, + CancellationToken cancellationToken = default) + { + var queryParams = new Dictionary + { + { + "receptor", string.Join(',', message.ReceptorLocalMessageIds.Keys) + }, + { + "message", message.MessageInfo.Message + }, + { + "type", (int)message.MessageInfo.Type + }, + { + "date", message.Date?.ToUnixTimestamp() ?? 0 + } + }; + + if (message.MessageInfo.Sender.IsNotNullOrWhiteSpace()) queryParams.Add("sender", message.MessageInfo.Sender); + + if (message.ReceptorLocalMessageIds.Values.All(i => i.IsNotNullOrWhiteSpace())) + queryParams.Add("localId", string.Join(',', message.ReceptorLocalMessageIds.Values)); + + return await RequestSender>( + "sms/send.json", + null, + queryParams, + cancellationToken); + } + + public async Task?> Send( + IEnumerable sendMessageInfos, + bool hide = false, + DateTime? dateTime = null, + CancellationToken cancellationToken = default) + { + return await Send( + new SendMultiMessageRequest(sendMessageInfos) + { + Date = dateTime ?? DateTime.Now, + Hide = hide + }, + cancellationToken); + } + + public async Task?> Send( + SendMultiMessageRequest messages, + CancellationToken cancellationToken = default) + { + var requestParams = new Dictionary + { + { + "message", + messages.SendMessageInfos + .Select(sendMessageInfo => WebUtility.HtmlEncode(sendMessageInfo.MessageInfo.Message)) + .ToList() + .Serialize() + }, + { + "receptor", + messages.SendMessageInfos.Select(sendMessageInfo => sendMessageInfo.Receptor).ToList().Serialize() + }, + { + "type", + messages.SendMessageInfos.Select(sendMessageInfo => (int)sendMessageInfo.MessageInfo.Type).Serialize() + }, + { + "date", messages.Date == DateTime.MinValue ? 0 : messages.Date.ToUnixTimestamp() + } + }; + + if (messages.SendMessageInfos.All( + sendMessageInfo => sendMessageInfo.MessageInfo.Sender.IsNotNullOrWhiteSpace())) + requestParams.Add( + "sender", + messages.SendMessageInfos.Select(sendMessageInfo => sendMessageInfo.MessageInfo.Sender) + .ToList() + .Serialize()); + + if (messages.SendMessageInfos.All( + sendMessageInfo => !string.IsNullOrWhiteSpace(sendMessageInfo.LocalMessageId))) + requestParams.Add( + "localMessageIds", + string.Join(",", messages.SendMessageInfos.Select(sendMessageInfo => sendMessageInfo.LocalMessageId))); + + return await RequestSender>( + "sms/sendarray.json", + null, + requestParams, + cancellationToken); + } + + public async Task VerifyLookup( + string receptor, + string template, + string token1, + string? token2 = null, + string? token3 = null, + string? token4 = null, + string? token5 = null, + VerifyLookupType? type = null, + CancellationToken cancellationToken = default) + { + return await VerifyLookup( + new VerifyLookupRequest( + receptor, + template, + token1) + { + Token2 = token2, + Token3 = token3, + Token4 = token4, + Token5 = token5, + VerifyLookupType = type + }, + cancellationToken); + } + + public async Task VerifyLookup( + VerifyLookupRequest verifyLookupRequest, + CancellationToken cancellationToken = default) + { + var queryParams = new Dictionary + { + { + "receptor", verifyLookupRequest.Receptor + }, + { + "template", verifyLookupRequest.Template + }, + { + "token", verifyLookupRequest.Token1 + } + }; + + if (verifyLookupRequest.Token2.IsNotNullOrWhiteSpace()) queryParams.Add("token2", verifyLookupRequest.Token2); + if (verifyLookupRequest.Token3.IsNotNullOrWhiteSpace()) queryParams.Add("token3", verifyLookupRequest.Token3); + if (verifyLookupRequest.Token4.IsNotNullOrWhiteSpace()) queryParams.Add("token10", verifyLookupRequest.Token4); + if (verifyLookupRequest.Token5.IsNotNullOrWhiteSpace()) queryParams.Add("token20", verifyLookupRequest.Token5); + if (verifyLookupRequest.VerifyLookupType.HasValue) + queryParams.Add("type", (int)verifyLookupRequest.VerifyLookupType.Value); + + return (await RequestSender>( + "verify/lookup.json", + null, + queryParams, + cancellationToken))?.FirstOrDefault(); + } +} \ No newline at end of file diff --git a/Code/Kavenegar.Core/KavenegarProfileApi.cs b/Code/Kavenegar.Core/KavenegarProfileApi.cs new file mode 100644 index 0000000..cb6c0a9 --- /dev/null +++ b/Code/Kavenegar.Core/KavenegarProfileApi.cs @@ -0,0 +1,320 @@ +using Kavenegar.Core.Dto.Result; +using Kavenegar.Core.Enums; +using Shared.Infrastructure; + +namespace Kavenegar.Core; + +public class KavenegarProfileApi + : BaseKavenegarApi, + IKavenegarProfileApi +{ + public KavenegarProfileApi( + IHttpClientHelper httpClientHelper, + string apiKey) : base(httpClientHelper, apiKey) + { + } + + public async Task Status( + string messageId, + CancellationToken cancellationToken = default) + { + return (await Status( + new List + { + messageId + }, + cancellationToken))?.FirstOrDefault()!; + } + + public async Task?> Status( + IEnumerable messageIds, + CancellationToken cancellationToken = default) + { + var queryParams = new Dictionary + { + { + "messageid", string.Join(',', messageIds) + } + }; + + return await RequestSender>( + "sms/status.json", + null, + queryParams, + cancellationToken); + } + + public async Task StatusLocalMessageId( + string messageId, + CancellationToken cancellationToken = default) + { + return (await StatusLocalMessageId( + new List + { + messageId + }, + cancellationToken))?.FirstOrDefault()!; + } + + public async Task?> StatusLocalMessageId( + IEnumerable messageIds, + CancellationToken cancellationToken = default) + { + var queryParams = new Dictionary + { + { + "messageid", string.Join(',', messageIds) + } + }; + + return await RequestSender>( + "sms/statuslocalmessageid.json", + null, + queryParams, + cancellationToken); + } + + public async Task Select( + string messageId, + CancellationToken cancellationToken = default) + { + return (await Select( + new List + { + messageId + }, + cancellationToken))?.FirstOrDefault()!; + } + + public async Task?> Select( + IEnumerable messageIds, + CancellationToken cancellationToken = default) + { + var queryParams = new Dictionary + { + { + "messageid", string.Join(',', messageIds) + } + }; + + return await RequestSender>( + "sms/select.json", + null, + queryParams, + cancellationToken); + } + + public async Task?> SelectOutbox( + DateTime startDate, + DateTime? endDate = null, + string? sender = null, + CancellationToken cancellationToken = default) + { + var error = ValidateDatePeriod(startDate, endDate); + if (error.IsNotNullOrWhiteSpace()) throw new ArgumentException(error); + + var queryParams = new Dictionary + { + { + "startdate", startDate.ToUnixTimestamp() + } + }; + + if (endDate.HasValue) queryParams.Add("enddate", endDate.Value.ToUnixTimestamp()); + if (sender.IsNotNullOrWhiteSpace()) queryParams.Add("sender", sender); + + return await RequestSender>( + "sms/selectoutbox.json", + null, + queryParams, + cancellationToken); + } + + public async Task?> LatestOutbox( + int? pageSize = null, + string? sender = null, + CancellationToken cancellationToken = default) + { + if (pageSize is > 500) throw new ArgumentException("تعداد رکورد های خروجی این متد حداکثر 500 رکورد می‌باشد."); + + pageSize ??= 500; + + var queryParams = new Dictionary + { + { + "pagesize", pageSize + } + }; + + if (sender.IsNotNullOrWhiteSpace()) queryParams.Add("sender", sender); + + return await RequestSender>( + "sms/latestoutbox.json", + null, + queryParams, + cancellationToken); + } + + public async Task CountOutbox( + DateTime startDate, + DateTime? endDate = null, + MessageStatus? status = null, + CancellationToken cancellationToken = default) + { + var error = ValidateDatePeriod(startDate, endDate); + if (error.IsNotNullOrWhiteSpace()) throw new ArgumentException(error); + + var queryParams = new Dictionary + { + { + "startdate", startDate.ToUnixTimestamp() + } + }; + + if (endDate.HasValue) queryParams.Add("enddate", endDate.Value.ToUnixTimestamp()); + if (status.HasValue) queryParams.Add("status", (int)status); + + return (await RequestSender>( + "sms/countoutbox.json", + null, + queryParams, + cancellationToken))?.FirstOrDefault(); + } + + public async Task Cancel( + string messageId, + CancellationToken cancellationToken = default) + { + return (await Cancel( + new List + { + messageId + }, + cancellationToken))?.FirstOrDefault()!; + } + + public async Task?> Cancel( + IEnumerable ids, + CancellationToken cancellationToken = default) + { + var queryParams = new Dictionary + { + { + "messageid", string.Join(',', ids) + } + }; + return await RequestSender>( + "sms/cancel.json", + null, + queryParams, + cancellationToken); + } + + public async Task?> Receive( + string line, + bool isRead, + CancellationToken cancellationToken = default) + { + var queryParams = new Dictionary + { + { + "linenumber", line + }, + { + "isread", isRead ? 1 : 0 + } + }; + + return await RequestSender>( + "sms/receive.json", + null, + queryParams, + cancellationToken); + } + + public async Task CountInbox( + DateTime startDate, + DateTime? endDate = null, + string? lineNumber = null, + bool? isRead = null, + CancellationToken cancellationToken = default) + { + var error = ValidateDatePeriod(startDate, endDate); + if (error.IsNotNullOrWhiteSpace()) throw new ArgumentException(error); + + var queryParams = new Dictionary + { + { + "startdate", startDate.ToUnixTimestamp() + } + }; + + if (endDate.HasValue) queryParams.Add("enddate", endDate.Value.ToUnixTimestamp()); + if (lineNumber.IsNotNullOrWhiteSpace()) queryParams.Add("linenumber", lineNumber); + if (isRead.HasValue) queryParams.Add("isread", isRead.Value ? 1 : 0); + + return (await RequestSender>( + "sms/countinbox.json", + null, + queryParams, + cancellationToken))?.FirstOrDefault(); + } + + public async Task AccountInfo( + CancellationToken cancellationToken = default) + { + return await RequestSender( + "account/info.json", + null, + null, + cancellationToken); + } + + public async Task AccountConfig( + string? apiLogs = null, + string? dailyReport = null, + string? debugMode = null, + string? defaultSender = null, + int? minCreditAlarm = null, + string? resendFailed = null, + CancellationToken cancellationToken = default) + { + if (apiLogs.IsNullOrWhiteSpace() && + dailyReport.IsNullOrWhiteSpace() && + debugMode.IsNullOrWhiteSpace() && + defaultSender.IsNullOrWhiteSpace() && + !minCreditAlarm.HasValue && + resendFailed.IsNullOrWhiteSpace()) + throw new ArgumentException("حداقل یکی از مقادیر باید وارد شده باشند."); + + var queryParams = new Dictionary(); + + if (apiLogs.IsNotNullOrWhiteSpace()) queryParams.Add("apilogs", apiLogs); + if (dailyReport.IsNotNullOrWhiteSpace()) queryParams.Add("dailyreport", dailyReport); + if (debugMode.IsNotNullOrWhiteSpace()) queryParams.Add("debugmode", debugMode); + if (defaultSender.IsNotNullOrWhiteSpace()) queryParams.Add("defaultsender", defaultSender); + if (minCreditAlarm.HasValue) queryParams.Add("mincreditalarm", minCreditAlarm); + if (resendFailed.IsNotNullOrWhiteSpace()) queryParams.Add("resendfailed", resendFailed); + + return await RequestSender( + "account/config.json", + null, + queryParams, + cancellationToken); + } + + private string ValidateDatePeriod( + DateTime startDate, + DateTime? endDate = null) + { + if (startDate < DateTime.Now.AddDays(-60)) return "تاریخ شروع startDate حداکثر باید تا 60 روز قبل باشد."; + + if (endDate <= startDate) return "تاریخ پایان باید از تاریخ شروع بزرگتر باشد."; + + if (endDate.HasValue && + (endDate - startDate).Value.TotalDays > 1) + return "حداکثر فاصله زمانی بین متغیر startDate تا متغیر endDate برابر با 1 روز می باشد."; + + return string.Empty; + } +} \ No newline at end of file diff --git a/Shared/Shared.Infrastructure/DateHelper.cs b/Code/Shared/Shared.Infrastructure/DateHelper.cs similarity index 82% rename from Shared/Shared.Infrastructure/DateHelper.cs rename to Code/Shared/Shared.Infrastructure/DateHelper.cs index 686df89..e22e768 100644 --- a/Shared/Shared.Infrastructure/DateHelper.cs +++ b/Code/Shared/Shared.Infrastructure/DateHelper.cs @@ -18,12 +18,6 @@ public static DateTime ToDateTime( return MinUnixDateTime.AddSeconds(unixTimeStamp); } - public static DateTime ToDateTime( - this double unixTimeStamp) - { - return MinUnixDateTime.AddSeconds(unixTimeStamp); - } - public static double ToUnixTimestamp( this DateTime dt) { diff --git a/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs b/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs new file mode 100644 index 0000000..8520003 --- /dev/null +++ b/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs @@ -0,0 +1,30 @@ +namespace Shared.Infrastructure; + +public class HttpClientHelper : IHttpClientHelper +{ + private readonly HttpClient _httpClient; + + public HttpClientHelper( + HttpClient httpClient) + { + _httpClient = httpClient; + } + + public string BaseAddress { get; set; } = ""; + + public async Task PostAsync( + string requestUri, + object? body = null, + Dictionary? queryParams = null, + CancellationToken cancellationToken = default) + { + var address = queryParams == null ? + $"{BaseAddress}/{requestUri}" : + QueryParamHelper.AddQueryParamToUri($"{BaseAddress}/{requestUri}", queryParams); + + return await _httpClient.PostAsync( + address, + body == null ? null : new StringContent(body.Serialize()), + cancellationToken); + } +} \ No newline at end of file diff --git a/Code/Shared/Shared.Infrastructure/IHttpClientHelper.cs b/Code/Shared/Shared.Infrastructure/IHttpClientHelper.cs new file mode 100644 index 0000000..97f650d --- /dev/null +++ b/Code/Shared/Shared.Infrastructure/IHttpClientHelper.cs @@ -0,0 +1,12 @@ +namespace Shared.Infrastructure; + +public interface IHttpClientHelper +{ + string BaseAddress { get; set; } + + Task PostAsync( + string requestUri, + object? body = null, + Dictionary? queryParams = null, + CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/Code/Shared/Shared.Infrastructure/JsonUtility.cs b/Code/Shared/Shared.Infrastructure/JsonUtility.cs new file mode 100644 index 0000000..c6706b1 --- /dev/null +++ b/Code/Shared/Shared.Infrastructure/JsonUtility.cs @@ -0,0 +1,20 @@ +using System.Text.Json; + +namespace Shared.Infrastructure; + +public static class JsonUtility +{ + public static string Serialize( + this T obj) + { + return JsonSerializer.Serialize(obj, obj!.GetType()); + } + + public static async Task Deserialize( + this HttpResponseMessage httpResponseMessage, + CancellationToken cancellationToken = default) + { + var content = await httpResponseMessage.Content.ReadAsStringAsync(cancellationToken); + return JsonSerializer.Deserialize(content); + } +} \ No newline at end of file diff --git a/Code/Shared/Shared.Infrastructure/QueryParamHelper.cs b/Code/Shared/Shared.Infrastructure/QueryParamHelper.cs new file mode 100644 index 0000000..1934bb3 --- /dev/null +++ b/Code/Shared/Shared.Infrastructure/QueryParamHelper.cs @@ -0,0 +1,18 @@ +using System.Web; + +namespace Shared.Infrastructure; + +public static class QueryParamHelper +{ + public static string AddQueryParamToUri( + string requestUri, + Dictionary queryParams) + { + var uriBuilder = new UriBuilder(requestUri); + var queryString = HttpUtility.ParseQueryString(uriBuilder.Query); + foreach (var parameter in queryParams) queryString[parameter.Key] = parameter.Value?.ToString(); + + uriBuilder.Query = queryString.ToString(); + return uriBuilder.Uri.AbsoluteUri; + } +} \ No newline at end of file diff --git a/Shared/Shared.Infrastructure/Shared.Infrastructure.csproj b/Code/Shared/Shared.Infrastructure/Shared.Infrastructure.csproj similarity index 100% rename from Shared/Shared.Infrastructure/Shared.Infrastructure.csproj rename to Code/Shared/Shared.Infrastructure/Shared.Infrastructure.csproj index eb2460e..8277f69 100644 --- a/Shared/Shared.Infrastructure/Shared.Infrastructure.csproj +++ b/Code/Shared/Shared.Infrastructure/Shared.Infrastructure.csproj @@ -1,9 +1,9 @@ - net6.0 enable enable + net6.0 diff --git a/Code/Shared/Shared.Infrastructure/StringUtility.cs b/Code/Shared/Shared.Infrastructure/StringUtility.cs new file mode 100644 index 0000000..cbb6eae --- /dev/null +++ b/Code/Shared/Shared.Infrastructure/StringUtility.cs @@ -0,0 +1,16 @@ +namespace Shared.Infrastructure; + +public static class StringUtility +{ + public static bool IsNullOrWhiteSpace( + this string? text) + { + return string.IsNullOrWhiteSpace(text); + } + + public static bool IsNotNullOrWhiteSpace( + this string? text) + { + return !text.IsNullOrWhiteSpace(); + } +} \ No newline at end of file diff --git a/Kavenegar.Core/DependencyManager.cs b/Kavenegar.Core/DependencyManager.cs deleted file mode 100644 index 9d37983..0000000 --- a/Kavenegar.Core/DependencyManager.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; - -namespace Kavenegar.Core; - -public static class DependencyManager -{ - public static IServiceCollection AddKavenegar( - this IServiceCollection serviceCollection, - string apiKey) - { - return serviceCollection.AddTransient(_ => new KavenegarApi(apiKey)); - } -} \ No newline at end of file diff --git a/Kavenegar.Core/Dto/Message/MessageInfo.cs b/Kavenegar.Core/Dto/Message/MessageInfo.cs deleted file mode 100644 index c7053bc..0000000 --- a/Kavenegar.Core/Dto/Message/MessageInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Kavenegar.Core.Enums; - -namespace Kavenegar.Core.Dto.Message; - -public class MessageInfo -{ - public string Sender { get; set; } = null!; - public string Message { get; set; } = null!; - public MessageType Type { get; set; } -} \ No newline at end of file diff --git a/Kavenegar.Core/Dto/Message/SendMessageInfo.cs b/Kavenegar.Core/Dto/Message/SendMessageInfo.cs deleted file mode 100644 index 6a09e09..0000000 --- a/Kavenegar.Core/Dto/Message/SendMessageInfo.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Kavenegar.Core.Dto.Message; - -public class SendMessageInfo -{ - public MessageInfo MessageInfo { get; set; } = null!; - public string Receptor { get; set; } = null!; - public string LocalMessageId { get; set; } = null!; -} \ No newline at end of file diff --git a/Kavenegar.Core/Dto/Message/SendSingleMessageRequest.cs b/Kavenegar.Core/Dto/Message/SendSingleMessageRequest.cs deleted file mode 100644 index a16414f..0000000 --- a/Kavenegar.Core/Dto/Message/SendSingleMessageRequest.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Kavenegar.Core.Dto.Message; - -public class SendSingleMessageRequest -{ - public MessageInfo MessageInfo { get; set; } = null!; - - /// - /// Key is receptor - /// Value is local message id - /// - public Dictionary ReceptorLocalMessageIds { get; set; } = null!; - - public DateTime? Date { get; set; } - public bool Hide { get; set; } -} \ No newline at end of file diff --git a/Kavenegar.Core/Dto/Result/SendResult.cs b/Kavenegar.Core/Dto/Result/SendResult.cs deleted file mode 100644 index 21852ea..0000000 --- a/Kavenegar.Core/Dto/Result/SendResult.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Kavenegar.Core.Dto.Result; - -public class SendResult -{ - public long MessageId { get; set; } - public string Message { get; set; } = null!; - public int Status { get; set; } - public string StatusText { get; set; } = null!; - public string Sender { get; set; } = null!; - public string Receptor { get; set; } = null!; - public long Date { get; set; } - public int Cost { get; set; } -} \ No newline at end of file diff --git a/Kavenegar.Core/IKavenegarApi.cs b/Kavenegar.Core/IKavenegarApi.cs deleted file mode 100644 index 379ce1f..0000000 --- a/Kavenegar.Core/IKavenegarApi.cs +++ /dev/null @@ -1,100 +0,0 @@ -using Kavenegar.Core.Dto.Message; -using Kavenegar.Core.Dto.Result; -using Kavenegar.Core.Enums; - -namespace Kavenegar.Core; - -public interface IKavenegarApi -{ - Task Send( - SendSingleMessageRequest message, - CancellationToken cancellationToken = default); - - Task> Send( - SendMultiMessageRequest messages, - CancellationToken cancellationToken = default); - - Task Status( - string messageId, - CancellationToken cancellationToken = default); - - Task> Status( - List messageIds, - CancellationToken cancellationToken = default); - - Task StatusLocalMessageId( - string messageId, - CancellationToken cancellationToken = default); - - Task> StatusLocalMessageId( - List messageIds, - CancellationToken cancellationToken = default); - - Task Select( - string messageId, - CancellationToken cancellationToken = default); - - Task> Select( - List messageIds, - CancellationToken cancellationToken = default); - - Task> SelectOutbox( - DateTime startDate, - DateTime? endDate, - string? sender, - CancellationToken cancellationToken = default); - - Task> LatestOutbox( - long? pageSize, - string? sender, - CancellationToken cancellationToken = default); - - Task CountOutbox( - DateTime startDate, - DateTime? endDate, - int? status, - CancellationToken cancellationToken = default); - - Task Cancel( - string messageId, - CancellationToken cancellationToken = default); - - Task> Cancel( - List ids, - CancellationToken cancellationToken = default); - - Task> Receive( - string line, - bool isRead, - CancellationToken cancellationToken = default); - - Task CountInbox( - DateTime startDate, - DateTime? endDate, - string? lineNumber, - bool? isRead, - CancellationToken cancellationToken = default); - - Task AccountInfo( - CancellationToken cancellationToken = default); - - Task AccountConfig( - string apiLogs, - string dailyReport, - string debugMode, - string defaultSender, - int? minCreditAlarm, - string resendFailed, - CancellationToken cancellationToken = default); - - Task VerifyLookup( - string receptor, - string template, - string token1, - string? token2 = null, - string? token3 = null, - string? token4 = null, - string? token5 = null, - VerifyLookupType? type = null, - CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/Kavenegar.Core/Kavenegar.Core.csproj b/Kavenegar.Core/Kavenegar.Core.csproj deleted file mode 100644 index 7117abf..0000000 --- a/Kavenegar.Core/Kavenegar.Core.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net6.0 - enable - enable - - - - - - - - - - - diff --git a/Kavenegar.Core/KavenegarApi.cs b/Kavenegar.Core/KavenegarApi.cs deleted file mode 100644 index 2052d5f..0000000 --- a/Kavenegar.Core/KavenegarApi.cs +++ /dev/null @@ -1,497 +0,0 @@ -using System.Net; -using Kavenegar.Core.Dto.Message; -using Kavenegar.Core.Dto.Result; -using Kavenegar.Core.Enums; -using Shared.Infrastructure; - -namespace Kavenegar.Core; - -internal class KavenegarApi : IKavenegarApi -{ - private readonly HttpClientHelper _httpClientHelper; - - public KavenegarApi( - string apiKey) - { - _httpClientHelper = new HttpClientHelper - { - BaseAddress = $"https://api.kavenegar.com/v1/{apiKey}" - }; - } - - public async Task Send( - SendSingleMessageRequest message, - CancellationToken cancellationToken = default) - { - var queryParams = new Dictionary - { - { - "sender", message.MessageInfo.Sender - }, - { - "receptor", string.Join(',', message.ReceptorLocalMessageIds.Keys) - }, - { - "message", message.MessageInfo.Message - }, - { - "type", (int)message.MessageInfo.Type - }, - { - "date", message.Date?.ToUnixTimestamp() ?? 0 - } - }; - - if (message.ReceptorLocalMessageIds.Values.All(string.IsNullOrWhiteSpace)) - queryParams.Add("localId", string.Join(',', message.ReceptorLocalMessageIds.Values)); - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "sms/sendarray.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))!.Value - .FirstOrDefault(); - } - - public async Task> Send( - SendMultiMessageRequest messages, - CancellationToken cancellationToken = default) - { - var requestParams = new Dictionary - { - { - "message", - await messages.SendMessageInfos - .Select(sendMessageInfo => WebUtility.HtmlEncode(sendMessageInfo.MessageInfo.Message)) - .ToList() - .Serialize(cancellationToken) - }, - { - "sender", - await messages.SendMessageInfos.Select(sendMessageInfo => sendMessageInfo.MessageInfo.Sender) - .ToList() - .Serialize(cancellationToken) - }, - { - "receptor", - await messages.SendMessageInfos.Select(sendMessageInfo => sendMessageInfo.Receptor) - .ToList() - .Serialize(cancellationToken) - }, - { - "type", - await messages.SendMessageInfos.Select(sendMessageInfo => sendMessageInfo.MessageInfo.Type.ToString()) - .Serialize(cancellationToken) - }, - { - "date", messages.Date == DateTime.MinValue ? 0 : messages.Date.ToUnixTimestamp() - } - }; - - if (messages.SendMessageInfos.All( - sendMessageInfo => !string.IsNullOrWhiteSpace(sendMessageInfo.LocalMessageId))) - requestParams.Add( - "localMessageIds", - string.Join( - ",", - messages.SendMessageInfos.Select( - sendMessageInfo => !string.IsNullOrWhiteSpace(sendMessageInfo.LocalMessageId)))); - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "sms/send.json", - null, - requestParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))!.Value; - } - - public async Task Status( - string messageId, - CancellationToken cancellationToken = default) - { - return (await Status( - new List - { - messageId - }, - cancellationToken)).FirstOrDefault()!; - } - - public async Task> Status( - List messageIds, - CancellationToken cancellationToken = default) - { - var queryParams = new Dictionary - { - { - "messageid", string.Join(',', messageIds) - } - }; - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "sms/status.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))?.Value ?? - new List(); - } - - public async Task StatusLocalMessageId( - string messageId, - CancellationToken cancellationToken = default) - { - return (await StatusLocalMessageId( - new List - { - messageId - }, - cancellationToken)).FirstOrDefault()!; - } - - public async Task> StatusLocalMessageId( - List messageIds, - CancellationToken cancellationToken = default) - { - var queryParams = new Dictionary - { - { - "messageid", string.Join(',', messageIds) - } - }; - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "sms/statuslocalmessageid.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))?.Value ?? - new List(); - } - - public async Task Select( - string messageId, - CancellationToken cancellationToken = default) - { - return (await Select( - new List - { - messageId - }, - cancellationToken)).FirstOrDefault()!; - } - - public async Task> Select( - List messageIds, - CancellationToken cancellationToken = default) - { - var queryParams = new Dictionary - { - { - "messageid", string.Join(',', messageIds) - } - }; - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "sms/select.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))?.Value ?? - new List(); - } - - public async Task> SelectOutbox( - DateTime startDate, - DateTime? endDate, - string? sender, - CancellationToken cancellationToken = default) - { - if (endDate <= startDate) throw new ArgumentException("تاریخ پایان باید از تاریخ شروع بزرگتر باشد."); - - if ((endDate - startDate)!.Value.TotalDays > 1) - throw new ArgumentException( - "حداکثر فاصله زمانی بین متغیر startDate تا متغیر endDate برابر با 1 روز می باشد."); - - if (startDate < DateTime.Now.AddDays(-60)) - throw new ArgumentException("تاریخ شروع startDate حداکثر باید تا 60 روز قبل باشد."); - - var queryParams = new Dictionary - { - { - "startdate", startDate.ToUnixTimestamp() - } - }; - - if (endDate.HasValue) queryParams.Add("enddate", endDate.Value.ToUnixTimestamp()); - - if (string.IsNullOrWhiteSpace(sender)) queryParams.Add("sender", sender); - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "sms/selectoutbox.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))?.Value ?? - new List(); - } - - public async Task> LatestOutbox( - long? pageSize, - string? sender, - CancellationToken cancellationToken = default) - { - if (pageSize is > 500) throw new ArgumentException("تعداد رکورد های خروجی این متد حداکثر 500 رکورد می‌باشد."); - - pageSize ??= 500; - - var queryParams = new Dictionary - { - { - "pagesize", pageSize - } - }; - - if (string.IsNullOrWhiteSpace(sender)) queryParams.Add("sender", sender); - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "sms/latestoutbox.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))?.Value ?? - new List(); - } - - public async Task CountOutbox( - DateTime startDate, - DateTime? endDate, - int? status, - CancellationToken cancellationToken = default) - { - if (endDate <= startDate) throw new ArgumentException("تاریخ پایان باید از تاریخ شروع بزرگتر باشد."); - - if ((endDate - startDate)!.Value.TotalDays > 1) - throw new ArgumentException( - "حداکثر فاصله زمانی بین متغیر startdate تا متغیر endDate برابر با 1 روز می باشد."); - - if (startDate < DateTime.Now.AddDays(-60)) - throw new ArgumentException("تاریخ شروع startdate حداکثر باید تا 60 روز قبل باشد."); - - var queryParams = new Dictionary - { - { - "startdate", startDate.ToUnixTimestamp() - } - }; - - if (endDate.HasValue) queryParams.Add("enddate", endDate.Value.ToUnixTimestamp()); - - if (status.HasValue) queryParams.Add("status", status); - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "sms/countoutbox.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))?.Value - .FirstOrDefault() ?? - new CountOutboxDto(); - } - - public async Task Cancel( - string messageId, - CancellationToken cancellationToken = default) - { - return (await Cancel( - new List - { - messageId - }, - cancellationToken)).FirstOrDefault()!; - } - - public async Task> Cancel( - List ids, - CancellationToken cancellationToken = default) - { - var queryParams = new Dictionary - { - { - "messageid", string.Join(',', ids) - } - }; - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "sms/cancel.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))?.Value ?? - new List(); - } - - public async Task> Receive( - string line, - bool isRead, - CancellationToken cancellationToken = default) - { - var queryParams = new Dictionary - { - { - "linenumber", line - }, - { - "isread", isRead ? 1 : 0 - } - }; - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "sms/receive.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))?.Value ?? - new List(); - } - - public async Task CountInbox( - DateTime startDate, - DateTime? endDate, - string? lineNumber, - bool? isRead, - CancellationToken cancellationToken = default) - { - if (endDate <= startDate) throw new ArgumentException("تاریخ پایان باید از تاریخ شروع بزرگتر باشد."); - - if ((endDate - startDate)!.Value.TotalDays > 1) - throw new ArgumentException( - "حداکثر فاصله زمانی بین متغیر startdate تا متغیر endDate برابر با 1 روز می باشد."); - - if (startDate < DateTime.Now.AddDays(-60)) - throw new ArgumentException("تاریخ شروع startdate حداکثر باید تا 60 روز قبل باشد."); - - var queryParams = new Dictionary - { - { - "startdate", startDate.ToUnixTimestamp() - } - }; - - if (endDate.HasValue) queryParams.Add("enddate", endDate.Value.ToUnixTimestamp()); - if (string.IsNullOrWhiteSpace(lineNumber)) queryParams.Add("linenumber", lineNumber); - if (isRead.HasValue) queryParams.Add("isread", isRead.Value ? 1 : 0); - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "sms/countinbox.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))?.Value - .FirstOrDefault() ?? - new CountOutboxDto(); - } - - public async Task AccountInfo( - CancellationToken cancellationToken = default) - { - var httpResponseMessage = await _httpClientHelper.PostAsync( - "account/info.json", - null, - null, - cancellationToken); - - return (await httpResponseMessage.Deserialize>(cancellationToken))?.Value ?? - new AccountInfoDto(); - } - - public async Task AccountConfig( - string? apiLogs, - string? dailyReport, - string? debugMode, - string? defaultSender, - int? minCreditAlarm, - string? resendFailed, - CancellationToken cancellationToken = default) - { - var queryParams = new Dictionary(); - - if (string.IsNullOrWhiteSpace(apiLogs)) queryParams.Add("apilogs", apiLogs); - - if (string.IsNullOrWhiteSpace(dailyReport)) queryParams.Add("dailyreport", dailyReport); - - if (string.IsNullOrWhiteSpace(debugMode)) queryParams.Add("debugmode", debugMode); - - if (string.IsNullOrWhiteSpace(defaultSender)) queryParams.Add("defaultsender", defaultSender); - - queryParams.Add("mincreditalarm", minCreditAlarm); - - if (string.IsNullOrWhiteSpace(resendFailed)) queryParams.Add("resendfailed", resendFailed); - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "account/config.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>(cancellationToken))?.Value ?? - new AccountConfigDto(); - } - - public async Task VerifyLookup( - string receptor, - string template, - string token1, - string? token2 = null, - string? token3 = null, - string? token4 = null, - string? token5 = null, - VerifyLookupType? type = null, - CancellationToken cancellationToken = default) - { - var queryParams = new Dictionary - { - { - "receptor", receptor - }, - { - "template", template - }, - { - "token", token1 - } - }; - - if (string.IsNullOrWhiteSpace(token2)) queryParams.Add("token2", token2); - - if (string.IsNullOrWhiteSpace(token3)) queryParams.Add("token3", token3); - - if (string.IsNullOrWhiteSpace(token4)) queryParams.Add("token10", token4); - - if (string.IsNullOrWhiteSpace(token5)) queryParams.Add("token20", token5); - - if (type.HasValue) queryParams.Add("type", type.Value.ToString()); - - var httpResponseMessage = await _httpClientHelper.PostAsync( - "verify/lookup.json", - null, - queryParams, - cancellationToken); - - return (await httpResponseMessage.Deserialize>>(cancellationToken))?.Value - .FirstOrDefault() ?? - new SendResult(); - } -} \ No newline at end of file diff --git a/Kavenegar.sln b/Kavenegar.sln index a636930..b9f0d75 100644 --- a/Kavenegar.sln +++ b/Kavenegar.sln @@ -1,8 +1,16 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared.Infrastructure", "Shared\Shared.Infrastructure\Shared.Infrastructure.csproj", "{5A102430-241D-46A1-A615-0149411194D5}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared.Infrastructure", "Code\Shared\Shared.Infrastructure\Shared.Infrastructure.csproj", "{5A102430-241D-46A1-A615-0149411194D5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kavenegar.Core", "Kavenegar.Core\Kavenegar.Core.csproj", "{35D0DBF6-25F0-4DEB-9BC8-D3C3B65933EB}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kavenegar.Core", "Code\Kavenegar.Core\Kavenegar.Core.csproj", "{35D0DBF6-25F0-4DEB-9BC8-D3C3B65933EB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code", "Code", "{67BC444E-84C9-493C-B776-55FE5D54D560}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{17B39BF3-CC26-40C5-AEB0-87CA2D71B93E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Kavenegar.Core", "Test\Test.Kavenegar.Core\Test.Kavenegar.Core.csproj", "{6E36B3F6-2B1D-4506-BA92-007AC00EF317}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Shared.Infrastructure", "Test\Test.Shared.Infrastructure\Test.Shared.Infrastructure.csproj", "{F7A2FE83-BE4B-4A9D-BEF5-A14FC8E05AFD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -18,7 +26,19 @@ Global {35D0DBF6-25F0-4DEB-9BC8-D3C3B65933EB}.Debug|Any CPU.Build.0 = Debug|Any CPU {35D0DBF6-25F0-4DEB-9BC8-D3C3B65933EB}.Release|Any CPU.ActiveCfg = Release|Any CPU {35D0DBF6-25F0-4DEB-9BC8-D3C3B65933EB}.Release|Any CPU.Build.0 = Release|Any CPU + {6E36B3F6-2B1D-4506-BA92-007AC00EF317}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E36B3F6-2B1D-4506-BA92-007AC00EF317}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E36B3F6-2B1D-4506-BA92-007AC00EF317}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E36B3F6-2B1D-4506-BA92-007AC00EF317}.Release|Any CPU.Build.0 = Release|Any CPU + {F7A2FE83-BE4B-4A9D-BEF5-A14FC8E05AFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F7A2FE83-BE4B-4A9D-BEF5-A14FC8E05AFD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F7A2FE83-BE4B-4A9D-BEF5-A14FC8E05AFD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F7A2FE83-BE4B-4A9D-BEF5-A14FC8E05AFD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution + {35D0DBF6-25F0-4DEB-9BC8-D3C3B65933EB} = {67BC444E-84C9-493C-B776-55FE5D54D560} + {5A102430-241D-46A1-A615-0149411194D5} = {67BC444E-84C9-493C-B776-55FE5D54D560} + {6E36B3F6-2B1D-4506-BA92-007AC00EF317} = {17B39BF3-CC26-40C5-AEB0-87CA2D71B93E} + {F7A2FE83-BE4B-4A9D-BEF5-A14FC8E05AFD} = {17B39BF3-CC26-40C5-AEB0-87CA2D71B93E} EndGlobalSection EndGlobal diff --git a/Kavenegar.sln.DotSettings b/Kavenegar.sln.DotSettings index 17fefcb..cc70dac 100644 --- a/Kavenegar.sln.DotSettings +++ b/Kavenegar.sln.DotSettings @@ -21,11 +21,13 @@ True True True + True True True True True True + True True True True @@ -33,4 +35,6 @@ True True True + True + True True \ No newline at end of file diff --git a/Shared/Shared.Infrastructure/HttpClientHelper.cs b/Shared/Shared.Infrastructure/HttpClientHelper.cs deleted file mode 100644 index a871bf4..0000000 --- a/Shared/Shared.Infrastructure/HttpClientHelper.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace Shared.Infrastructure; - -public class HttpClientHelper -{ - private readonly HttpClient _httpClient = new(); - - public string BaseAddress { get; set; } = null!; - - public async Task PostAsync( - string requestUri, - object? body = null, - Dictionary? queryParams = null, - CancellationToken cancellationToken = default) - { - var address = queryParams == null ? - Path.Combine(BaseAddress, requestUri) : - QueryParamHelper.AddQueryParamToUri(Path.Combine(BaseAddress, requestUri), queryParams); - - return await _httpClient.PostAsync( - address, - body == null ? null : await SerializeBody(body, cancellationToken), - cancellationToken); - } - - private async Task SerializeBody( - object obj, - CancellationToken cancellationToken) - { - return new StringContent(await obj.Serialize(cancellationToken)); - } -} \ No newline at end of file diff --git a/Shared/Shared.Infrastructure/JsonUtility.cs b/Shared/Shared.Infrastructure/JsonUtility.cs deleted file mode 100644 index 566f80c..0000000 --- a/Shared/Shared.Infrastructure/JsonUtility.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Text; -using System.Text.Json; - -namespace Shared.Infrastructure; - -public static class JsonUtility -{ - public static async Task Serialize( - this T obj, - CancellationToken cancellationToken = default) - { - var stream = new MemoryStream(); - await JsonSerializer.SerializeAsync( - stream, - obj, - cancellationToken: cancellationToken); - - var streamReader = new StreamReader(stream, Encoding.UTF8); - return await streamReader.ReadToEndAsync(); - } - - public static async Task Deserialize( - Stream json, - CancellationToken cancellationToken = default) - { - return await JsonSerializer.DeserializeAsync(json, cancellationToken: cancellationToken); - } - - public static async Task Deserialize( - this HttpResponseMessage httpResponseMessage, - CancellationToken cancellationToken = default) - { - var content = await httpResponseMessage.Content.ReadAsStringAsync(cancellationToken); - var stream = new MemoryStream(); - var streamWriter = new StreamWriter(stream, Encoding.UTF8); - await streamWriter.WriteAsync(content); - return await Deserialize(stream, cancellationToken); - } -} \ No newline at end of file diff --git a/Shared/Shared.Infrastructure/QueryParamHelper.cs b/Shared/Shared.Infrastructure/QueryParamHelper.cs deleted file mode 100644 index eed186a..0000000 --- a/Shared/Shared.Infrastructure/QueryParamHelper.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.ComponentModel.DataAnnotations.Schema; -using System.Web; - -namespace Shared.Infrastructure; - -public static class QueryParamHelper -{ - public static string AddQueryParamToUri( - string requestUri, - Dictionary queryParams = null!) - { - var uriBuilder = new UriBuilder(requestUri); - var queryString = HttpUtility.ParseQueryString(uriBuilder.Query); - foreach (var parameter in queryParams) queryString[parameter.Key] = parameter.Value?.ToString(); - - uriBuilder.Query = queryString.ToString(); - return uriBuilder.ToString(); - } - - public static Dictionary ParametrizeObject( - this T obj) - { - var properties = obj!.GetType() - .GetProperties() - .OrderBy( - propertyInfo => ((ColumnAttribute)propertyInfo.GetCustomAttributes(typeof(ColumnAttribute), false)[0]) - .Order); - - return properties.ToDictionary( - propertyInfo => - ((ColumnAttribute)propertyInfo.GetCustomAttributes(typeof(ColumnAttribute), false)[0]).Name ?? - propertyInfo.Name, - propertyInfo => propertyInfo.GetValue(obj)); - } -} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/DependencyManagerTests.cs b/Test/Test.Kavenegar.Core/DependencyManagerTests.cs new file mode 100644 index 0000000..f816321 --- /dev/null +++ b/Test/Test.Kavenegar.Core/DependencyManagerTests.cs @@ -0,0 +1,82 @@ +using System.Linq; +using System.Net.Http; +using Kavenegar.Core; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; +using Shared.Infrastructure; + +namespace Test.Kavenegar.Core; + +[TestFixture] +public class DependencyManagerTests +{ + [SetUp] + public void SetUp() + { + _serviceCollection = new ServiceCollection().AddKavenegar("apiKey"); + } + + private IServiceCollection _serviceCollection = null!; + + [Test] + public void AddKavenegar_WhenCalled_IKavenegarProfileApiServiceAdded() + { + var serviceExistence = _serviceCollection.Any( + i => i.Lifetime == ServiceLifetime.Scoped && + i.ServiceType == typeof(IKavenegarProfileApi) && + i.ImplementationFactory!.Method.ReturnType == typeof(global::Kavenegar.Core.KavenegarProfileApi)); + + Assert.That(serviceExistence, Is.True); + } + + [Test] + public void AddKavenegar_WhenCalled_IKavenegarMessageSenderServiceAdded() + { + var serviceExistence = _serviceCollection.Any( + i => i.Lifetime == ServiceLifetime.Scoped && + i.ServiceType == typeof(IKavenegarMessageSender) && + i.ImplementationFactory!.Method.ReturnType == typeof(global::Kavenegar.Core.KavenegarMessageSender)); + + Assert.That(serviceExistence, Is.True); + } + + [Test] + public void AddKavenegar_WhenCalled_IHttpClientHelperServiceAdded() + { + var serviceExistence = _serviceCollection.Any( + i => i.Lifetime == ServiceLifetime.Scoped && + i.ServiceType == typeof(IHttpClientHelper) && + i.ImplementationType == typeof(HttpClientHelper)); + + Assert.That(serviceExistence, Is.True); + } + + [Test] + public void AddKavenegar_WhenCalled_HttpClientServiceAdded() + { + var serviceExistence = _serviceCollection.Any( + i => i.Lifetime == ServiceLifetime.Scoped && + i.ServiceType == typeof(HttpClient) && + i.ImplementationType == typeof(HttpClient)); + + Assert.That(serviceExistence, Is.True); + } + + [Test] + public void AddKavenegar_WhenCalled_CheckBuiltServices() + { + var provider = _serviceCollection.BuildServiceProvider(); + + Assert.That( + provider.GetService(), + Is.TypeOf()); + + Assert.That( + provider.GetService(), + Is.TypeOf()); + + Assert.That(provider.GetService(), Is.TypeOf()); + + Assert.That(provider.GetService(), Is.TypeOf()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarMessageSender/MultiMessage/SendWithDtoTests.cs b/Test/Test.Kavenegar.Core/KavenegarMessageSender/MultiMessage/SendWithDtoTests.cs new file mode 100644 index 0000000..bc90b1e --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarMessageSender/MultiMessage/SendWithDtoTests.cs @@ -0,0 +1,381 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Message; +using Kavenegar.Core.Enums; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using MessageSender = Kavenegar.Core.KavenegarMessageSender; + +namespace Test.Kavenegar.Core.KavenegarMessageSender.MultiMessage; + +[TestFixture] +public class SendWithDtoTests +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarMessageSender = new MessageSender(_mockHttpClientHelper.Object, ""); + } + + private MessageSender _kavenegarMessageSender = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task Send_WhenCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send(new SendMultiMessageRequest(new List())); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase("test")] + [TestCase("تست")] + public async Task Send_WhenCalled_CheckMessageQueryParam( + string message) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new SendMultiMessageRequest( + new List + { + new(new MessageInfo(message), ""), + new(new MessageInfo(message), "") + })); + + var expectedMessages = new List + { + WebUtility.HtmlEncode(message), + WebUtility.HtmlEncode(message) + }.Serialize(); + + Assert.That(passedQueryParams["message"], Is.EqualTo(expectedMessages)); + } + + [Test] + public async Task Send_WithNoSender_QueryParamsNotIncludeSender() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new SendMultiMessageRequest( + new List + { + new(new MessageInfo(""), "") + })); + + Assert.That(passedQueryParams.ContainsKey("sender"), Is.False); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Send_WithSender_QueryParamsIncludeSender( + string sender) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new SendMultiMessageRequest( + new List + { + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + { + Sender = sender + } + }, + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + { + Sender = sender + } + } + })); + + Assert.That(passedQueryParams["sender"], Is.EqualTo($"[\"{sender}\",\"{sender}\"]")); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Send_WhenCalled_CheckReceptorQueryParam( + string receptor) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new SendMultiMessageRequest( + new List + { + new(new MessageInfo(""), receptor) + { + MessageInfo = new MessageInfo("") + }, + new(new MessageInfo(""), receptor) + { + MessageInfo = new MessageInfo("") + } + })); + + Assert.That(passedQueryParams["receptor"], Is.EqualTo($"[\"{receptor}\",\"{receptor}\"]")); + } + + [Test] + [TestCase(MessageType.Flash)] + [TestCase(MessageType.AppMemory)] + public async Task Send_WhenCalled_CheckTypeQueryParam( + MessageType messageType) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new SendMultiMessageRequest( + new List + { + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + { + Type = messageType + } + }, + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + { + Type = messageType + } + } + })); + + Assert.That(passedQueryParams["type"], Is.EqualTo($"[{(int)messageType},{(int)messageType}]")); + } + + [Test] + public async Task Send_WhenCalled_CheckDateQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var dt = DateTime.Now; + + await _kavenegarMessageSender.Send( + new SendMultiMessageRequest( + new List + { + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + }, + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + } + }) + { + Date = dt + }); + + Assert.That(passedQueryParams["date"], Is.EqualTo(dt.ToUnixTimestamp())); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Send_WithLocalMessageId_QueryParamsIncludeLocalMessageId( + string localMessageId) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new SendMultiMessageRequest( + new List + { + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo(""), + LocalMessageId = localMessageId + }, + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo(""), + LocalMessageId = localMessageId + } + })); + + Assert.That(passedQueryParams["localMessageIds"], Is.EqualTo($"{localMessageId},{localMessageId}")); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarMessageSender/MultiMessage/SendWithParamsTests.cs b/Test/Test.Kavenegar.Core/KavenegarMessageSender/MultiMessage/SendWithParamsTests.cs new file mode 100644 index 0000000..2a40091 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarMessageSender/MultiMessage/SendWithParamsTests.cs @@ -0,0 +1,375 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Message; +using Kavenegar.Core.Enums; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using MessageSender = Kavenegar.Core.KavenegarMessageSender; + +namespace Test.Kavenegar.Core.KavenegarMessageSender.MultiMessage; + +[TestFixture] +public class SendWithParamsTests +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarMessageSender = new MessageSender(_mockHttpClientHelper.Object, ""); + } + + private MessageSender _kavenegarMessageSender = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task Send_WhenCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send(new List()); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase("test")] + [TestCase("تست")] + public async Task Send_WhenCalled_CheckMessageQueryParam( + string message) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new List + { + new(new MessageInfo(message), ""), + new(new MessageInfo(message), "") + }); + + var expectedMessages = new List + { + WebUtility.HtmlEncode(message), + WebUtility.HtmlEncode(message) + }.Serialize(); + + Assert.That(passedQueryParams["message"], Is.EqualTo(expectedMessages)); + } + + [Test] + public async Task Send_WithNoSender_QueryParamsNotIncludeSender() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new List + { + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + } + }); + + Assert.That(passedQueryParams.ContainsKey("sender"), Is.False); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Send_WithSender_QueryParamsIncludeSender( + string sender) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new List + { + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + { + Sender = sender + } + }, + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + { + Sender = sender + } + } + }); + + Assert.That(passedQueryParams["sender"], Is.EqualTo($"[\"{sender}\",\"{sender}\"]")); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Send_WhenCalled_CheckReceptorQueryParam( + string receptor) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new List + { + new(new MessageInfo(""), receptor) + { + MessageInfo = new MessageInfo("") + }, + new(new MessageInfo(""), receptor) + { + MessageInfo = new MessageInfo("") + } + }); + + Assert.That(passedQueryParams["receptor"], Is.EqualTo($"[\"{receptor}\",\"{receptor}\"]")); + } + + [Test] + [TestCase(MessageType.Flash)] + [TestCase(MessageType.AppMemory)] + public async Task Send_WhenCalled_CheckTypeQueryParam( + MessageType messageType) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new List + { + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + { + Type = messageType + } + }, + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + { + Type = messageType + } + } + }); + + Assert.That(passedQueryParams["type"], Is.EqualTo($"[{(int)messageType},{(int)messageType}]")); + } + + [Test] + public async Task Send_WhenCalled_CheckDateQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var dt = DateTime.Now; + + await _kavenegarMessageSender.Send( + new List + { + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + }, + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo("") + } + }, + dateTime: dt); + + Assert.That(passedQueryParams["date"], Is.EqualTo(dt.ToUnixTimestamp())); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Send_WithLocalMessageId_QueryParamsIncludeLocalMessageId( + string localMessageId) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/sendarray.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.Send( + new List + { + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo(""), + LocalMessageId = localMessageId + }, + new(new MessageInfo(""), "") + { + MessageInfo = new MessageInfo(""), + LocalMessageId = localMessageId + } + }); + + Assert.That(passedQueryParams["localMessageIds"], Is.EqualTo($"{localMessageId},{localMessageId}")); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessage/SendToManyBaseMethodTests.cs b/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessage/SendToManyBaseMethodTests.cs new file mode 100644 index 0000000..5802e28 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessage/SendToManyBaseMethodTests.cs @@ -0,0 +1,482 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Message; +using Kavenegar.Core.Dto.Result; +using Kavenegar.Core.Enums; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using MessageSender = Kavenegar.Core.KavenegarMessageSender; + +namespace Test.Kavenegar.Core.KavenegarMessageSender.SingleMessage; + +[TestFixture] +public class SendToManyBaseMethodTests +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarMessageSender = new MessageSender(_mockHttpClientHelper.Object, ""); + } + + private MessageSender _kavenegarMessageSender = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task Send_WhenCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message"), + new Dictionary + { + { + "receptor", null + } + })); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + public async Task Send_SenderIsEmpty_SenderNotInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message") + { + Message = "message" + }, + new Dictionary + { + { + "receptor", null + } + })); + + Assert.That(passedQueryParams.ContainsKey("sender"), Is.False); + } + + [Test] + public async Task Send_SenderNotEmpty_SenderInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message") + { + Sender = "sender" + }, + new Dictionary + { + { + "receptor", null + } + })); + + Assert.That(passedQueryParams["sender"], Is.EqualTo("sender")); + } + + [Test] + public async Task Send_LocalMessageIdsAreNotQualified_LocalIdNotInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message"), + new Dictionary + { + { + "receptor", null + } + })); + + Assert.That(passedQueryParams.ContainsKey("localId"), Is.False); + } + + [Test] + public async Task Send_LocalMessageIdsAreQualified_LocalIdInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message"), + new Dictionary + { + { + "receptor", "localMessageId" + } + })); + + Assert.That(passedQueryParams["localId"], Is.EqualTo("localMessageId")); + } + + [Test] + public async Task Send_WhenCalled_CheckStaticParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message"), + new Dictionary + { + { + "receptor1", "" + }, + { + "receptor2", "" + } + })); + + Assert.That(passedQueryParams["receptor"], Is.EqualTo("receptor1,receptor2")); + Assert.That(passedQueryParams["message"], Is.EqualTo("message")); + } + + [Test] + public async Task Send_DefaultDate_DateParamIsZero() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message"), + new Dictionary + { + { + "receptor", null + } + })); + + Assert.That(passedQueryParams["date"], Is.EqualTo(0)); + } + + [Test] + public async Task Send_SetDate_DateParamHasValue() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + var dt = DateTime.Now; + + await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message"), + new Dictionary + { + { + "receptor", null + } + }) + { + Date = dt + }); + + Assert.That(passedQueryParams["date"], Is.EqualTo(dt.ToUnixTimestamp())); + } + + [Test] + public async Task Send_TypeNotSet_TypeValueIsDefault() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message"), + new Dictionary + { + { + "receptor", null + } + })); + + Assert.That(passedQueryParams["type"], Is.EqualTo((int)MessageType.Flash)); + } + + [Test] + [TestCase(MessageType.AppMemory)] + [TestCase(MessageType.MobileMemory)] + [TestCase(MessageType.SimMemory)] + public async Task Send_TypeSet_CheckTypeValue( + MessageType messageType) + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message") + { + Type = messageType + }, + new Dictionary + { + { + "receptor", null + } + })); + + Assert.That(passedQueryParams["type"], Is.EqualTo((int)messageType)); + } + + [Test] + public async Task Send_PostRequestReturnsNoResult_ResultIsNull() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + var result = await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message"), + new Dictionary + { + { + "receptor", null + } + })); + + Assert.That(result, Is.Null); + } + + [Test] + public async Task Send_PostRequestReturnsResult_ResultSendResultDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}", Encoding.UTF8) + }); + + var result = await _kavenegarMessageSender.Send( + new SendSingleMessageRequest( + new MessageInfo("message"), + new Dictionary + { + { + "receptor", null + } + })); + + Assert.That(result, Is.TypeOf>()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessage/SendToManyTests.cs b/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessage/SendToManyTests.cs new file mode 100644 index 0000000..eb93dc6 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessage/SendToManyTests.cs @@ -0,0 +1,439 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Kavenegar.Core.Enums; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using MessageSender = Kavenegar.Core.KavenegarMessageSender; + +namespace Test.Kavenegar.Core.KavenegarMessageSender.SingleMessage; + +[TestFixture] +public class SendToManyTests +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarMessageSender = new MessageSender(_mockHttpClientHelper.Object, ""); + } + + private MessageSender _kavenegarMessageSender = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task Send_WhenCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + "message", + new Dictionary + { + { + "receptor", "" + } + }); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + public async Task Send_SenderIsEmpty_SenderNotInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + "message", + new Dictionary + { + { + "receptor", "" + } + }); + Assert.That(passedQueryParams.ContainsKey("sender"), Is.False); + } + + [Test] + public async Task Send_SenderNotEmpty_SenderInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + "message", + new Dictionary + { + { + "receptor", "" + } + }, + "sender"); + + Assert.That(passedQueryParams["sender"], Is.EqualTo("sender")); + } + + [Test] + public async Task Send_LocalMessageIdsAreNotQualified_LocalIdNotInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + await _kavenegarMessageSender.Send( + "message", + new Dictionary + { + { + "receptor", "" + } + }); + + Assert.That(passedQueryParams.ContainsKey("localId"), Is.False); + } + + [Test] + public async Task Send_LocalMessageIdsAreQualified_LocalIdInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + await _kavenegarMessageSender.Send( + "message", + new Dictionary + { + { + "receptor", "localMessageId" + } + }); + + Assert.That(passedQueryParams["localId"], Is.EqualTo("localMessageId")); + } + + [Test] + public async Task Send_WhenCalled_CheckStaticParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + await _kavenegarMessageSender.Send( + "message", + new Dictionary + { + { + "receptor1", "" + }, + { + "receptor2", "" + } + }); + + Assert.That(passedQueryParams["receptor"], Is.EqualTo("receptor1,receptor2")); + Assert.That(passedQueryParams["message"], Is.EqualTo("message")); + } + + [Test] + public async Task Send_DefaultDate_DateParamIsZero() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + await _kavenegarMessageSender.Send( + "message", + new Dictionary + { + { + "receptor", "" + } + }); + + Assert.That(passedQueryParams["date"], Is.EqualTo(0)); + } + + [Test] + public async Task Send_SetDate_DateParamHasValue() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + var dt = DateTime.Now; + + await _kavenegarMessageSender.Send( + "message", + new Dictionary + { + { + "receptor", "" + } + }, + dateTime: dt); + + Assert.That(passedQueryParams["date"], Is.EqualTo(dt.ToUnixTimestamp())); + } + + [Test] + public async Task Send_TypeNotSet_TypeValueIsDefault() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + await _kavenegarMessageSender.Send( + "message", + new Dictionary + { + { + "receptor", "" + } + }); + + Assert.That(passedQueryParams["type"], Is.EqualTo((int)MessageType.Flash)); + } + + [Test] + [TestCase(MessageType.AppMemory)] + [TestCase(MessageType.MobileMemory)] + [TestCase(MessageType.SimMemory)] + public async Task Send_TypeSet_CheckTypeValue( + MessageType messageType) + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + await _kavenegarMessageSender.Send( + "message", + new Dictionary + { + { + "receptor", "" + } + }, + messageType: messageType); + + Assert.That(passedQueryParams["type"], Is.EqualTo((int)messageType)); + } + + [Test] + public async Task Send_PostRequestReturnsNoResult_ResultIsNull() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + var result = await _kavenegarMessageSender.Send("message", "receptor"); + + Assert.That(result, Is.Null); + } + + [Test] + public async Task Send_PostRequestReturnsResult_ResultSendResultDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}", Encoding.UTF8) + }); + + var result = await _kavenegarMessageSender.Send("message", "receptor"); + + Assert.That(result, Is.TypeOf()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessage/SendToOneTests.cs b/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessage/SendToOneTests.cs new file mode 100644 index 0000000..6185664 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessage/SendToOneTests.cs @@ -0,0 +1,381 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Kavenegar.Core.Enums; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using MessageSender = Kavenegar.Core.KavenegarMessageSender; + +namespace Test.Kavenegar.Core.KavenegarMessageSender.SingleMessage; + +[TestFixture] +public class SendToOneTests +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarMessageSender = new MessageSender(_mockHttpClientHelper.Object, ""); + } + + private MessageSender _kavenegarMessageSender = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task Send_WhenCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send("message", "receptor"); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + public async Task Send_SenderIsEmpty_SenderNotInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send("message", "receptor"); + + Assert.That(passedQueryParams.ContainsKey("sender"), Is.False); + } + + [Test] + public async Task Send_SenderNotEmpty_SenderInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + "message", + "receptor", + "sender"); + + Assert.That(passedQueryParams["sender"], Is.EqualTo("sender")); + } + + [Test] + public async Task Send_LocalMessageIdsAreNotQualified_LocalIdNotInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send("message", "receptor"); + + Assert.That(passedQueryParams.ContainsKey("localId"), Is.False); + } + + [Test] + public async Task Send_LocalMessageIdsAreQualified_LocalIdInParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + "message", + "receptor", + localMessageId: "localMessageId"); + + Assert.That(passedQueryParams.ContainsKey("localId"), Is.True); + } + + [Test] + public async Task Send_WhenCalled_CheckStaticParams() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send("message", "receptor"); + + Assert.That(passedQueryParams["receptor"], Is.EqualTo("receptor")); + Assert.That(passedQueryParams["message"], Is.EqualTo("message")); + } + + [Test] + public async Task Send_DefaultDate_DateParamIsZero() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send("message", "receptor"); + + Assert.That(passedQueryParams["date"], Is.EqualTo(0)); + } + + [Test] + public async Task Send_SpecificDate_DateParamHasValue() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + var dt = DateTime.Now; + await _kavenegarMessageSender.Send( + "message", + "receptor", + dateTime: dt); + + Assert.That(passedQueryParams["date"], Is.EqualTo(dt.ToUnixTimestamp())); + } + + [Test] + public async Task Send_TypeNotSet_TypeValueIsDefault() + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send("message", "receptor"); + + Assert.That(passedQueryParams["type"], Is.EqualTo((int)MessageType.Flash)); + } + + [Test] + [TestCase(MessageType.AppMemory)] + [TestCase(MessageType.MobileMemory)] + [TestCase(MessageType.SimMemory)] + public async Task Send_TypeSet_CheckTypeValue( + MessageType messageType) + { + Dictionary passedQueryParams = null!; + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + await _kavenegarMessageSender.Send( + "message", + "receptor", + messageType: messageType); + + Assert.That(passedQueryParams["type"], Is.EqualTo((int)messageType)); + } + + [Test] + public async Task Send_PostRequestReturnsNoResult_ResultIsNull() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}", Encoding.UTF8) + }); + + var result = await _kavenegarMessageSender.Send("message", "receptor"); + + Assert.That(result, Is.Null); + } + + [Test] + public async Task Send_PostRequestReturnsResult_ResultSendResultDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/send.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}", Encoding.UTF8) + }); + + var result = await _kavenegarMessageSender.Send("message", "receptor"); + + Assert.That(result, Is.TypeOf()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarMessageSender/VerifyLookup/VerifyLookupWithDto.cs b/Test/Test.Kavenegar.Core/KavenegarMessageSender/VerifyLookup/VerifyLookupWithDto.cs new file mode 100644 index 0000000..66827bb --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarMessageSender/VerifyLookup/VerifyLookupWithDto.cs @@ -0,0 +1,550 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Message; +using Kavenegar.Core.Dto.Result; +using Kavenegar.Core.Enums; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using MessageSender = Kavenegar.Core.KavenegarMessageSender; + +namespace Test.Kavenegar.Core.KavenegarMessageSender.VerifyLookup; + +[TestFixture] +public class VerifyLookupWithDto +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarMessageSender = new MessageSender(_mockHttpClientHelper.Object, ""); + } + + private MessageSender _kavenegarMessageSender = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task VerifyLookup_WhenCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "")); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + public async Task VerifyLookup_WhenCalled_CheckReceptorQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "receptor", + "", + "")); + + Assert.That(passedQueryParams["receptor"], Is.EqualTo("receptor")); + } + + [Test] + public async Task VerifyLookup_WhenCalled_CheckTemplateQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "template", + "")); + + Assert.That(passedQueryParams["template"], Is.EqualTo("template")); + } + + [Test] + public async Task VerifyLookup_WhenCalled_CheckFirstTokenQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "token")); + + Assert.That(passedQueryParams["token"], Is.EqualTo("token")); + } + + [Test] + public async Task VerifyLookup_WithNoToken2_QueryParamsNotIncludeToken2() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "")); + + Assert.That(passedQueryParams.ContainsKey("token2"), Is.False); + } + + [Test] + public async Task VerifyLookup_WithToken2_QueryParamsIncludeToken2() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "") + { + Token2 = "token2" + }); + + Assert.That(passedQueryParams["token2"], Is.EqualTo("token2")); + } + + [Test] + public async Task VerifyLookup_WithNoToken3_QueryParamsNotIncludeToken3() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "")); + + Assert.That(passedQueryParams.ContainsKey("token3"), Is.False); + } + + [Test] + public async Task VerifyLookup_WithToken3_QueryParamsIncludeToken3() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "") + { + Token3 = "token3" + }); + + Assert.That(passedQueryParams["token3"], Is.EqualTo("token3")); + } + + [Test] + public async Task VerifyLookup_WithNoToken4_QueryParamsNotIncludeToken10() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "")); + + Assert.That(passedQueryParams.ContainsKey("token10"), Is.False); + } + + [Test] + public async Task VerifyLookup_WithToken4_QueryParamsIncludeToken10() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "") + { + Token4 = "token10" + }); + + Assert.That(passedQueryParams["token10"], Is.EqualTo("token10")); + } + + [Test] + public async Task VerifyLookup_WithNoToken5_QueryParamsNotIncludeToken20() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "")); + + Assert.That(passedQueryParams.ContainsKey("token20"), Is.False); + } + + [Test] + public async Task VerifyLookup_WithToken5_QueryParamsIncludeToken20() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "") + { + Token5 = "token20" + }); + + Assert.That(passedQueryParams["token20"], Is.EqualTo("token20")); + } + + [Test] + public async Task VerifyLookup_WithNoType_QueryParamsNotIncludeType() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "")); + + Assert.That(passedQueryParams.ContainsKey("type"), Is.False); + } + + [Test] + public async Task VerifyLookup_WithType_QueryParamsIncludeType() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "") + { + VerifyLookupType = VerifyLookupType.Call + }); + + Assert.That(passedQueryParams["type"], Is.EqualTo((int)VerifyLookupType.Call)); + } + + [Test] + public async Task VerifyLookup_WhenCalled_ReturnsSendResult() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarMessageSender.VerifyLookup( + new VerifyLookupRequest( + "", + "", + "")); + + Assert.That(result, Is.TypeOf()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarMessageSender/VerifyLookup/VerifyLookupWithParam.cs b/Test/Test.Kavenegar.Core/KavenegarMessageSender/VerifyLookup/VerifyLookupWithParam.cs new file mode 100644 index 0000000..7f5a6da --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarMessageSender/VerifyLookup/VerifyLookupWithParam.cs @@ -0,0 +1,524 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Kavenegar.Core.Enums; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using MessageSender = Kavenegar.Core.KavenegarMessageSender; + +namespace Test.Kavenegar.Core.KavenegarMessageSender.VerifyLookup; + +[TestFixture] +public class VerifyLookupWithParam +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarMessageSender = new MessageSender(_mockHttpClientHelper.Object, ""); + } + + private MessageSender _kavenegarMessageSender = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task VerifyLookup_WhenCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + ""); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + public async Task VerifyLookup_WhenCalled_CheckReceptorQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "receptor", + "", + ""); + + Assert.That(passedQueryParams["receptor"], Is.EqualTo("receptor")); + } + + [Test] + public async Task VerifyLookup_WhenCalled_CheckTemplateQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "template", + ""); + + Assert.That(passedQueryParams["template"], Is.EqualTo("template")); + } + + [Test] + public async Task VerifyLookup_WhenCalled_CheckFirstTokenQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + "token"); + + Assert.That(passedQueryParams["token"], Is.EqualTo("token")); + } + + [Test] + public async Task VerifyLookup_WithNoSender_QueryParamsNotIncludeToken2() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + ""); + + Assert.That(passedQueryParams.ContainsKey("token2"), Is.False); + } + + [Test] + public async Task VerifyLookup_WithSender_QueryParamsIncludeToken2() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + "", + "token2"); + + Assert.That(passedQueryParams["token2"], Is.EqualTo("token2")); + } + + [Test] + public async Task VerifyLookup_WithNoSender_QueryParamsNotIncludeToken3() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + ""); + + Assert.That(passedQueryParams.ContainsKey("token3"), Is.False); + } + + [Test] + public async Task VerifyLookup_WithSender_QueryParamsIncludeToken3() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + "", + token3: "token3"); + + Assert.That(passedQueryParams["token3"], Is.EqualTo("token3")); + } + + [Test] + public async Task VerifyLookup_WithNoSender_QueryParamsNotIncludeToken10() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + ""); + + Assert.That(passedQueryParams.ContainsKey("token10"), Is.False); + } + + [Test] + public async Task VerifyLookup_WithSender_QueryParamsIncludeToken10() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + "", + token4: "token10"); + + Assert.That(passedQueryParams["token10"], Is.EqualTo("token10")); + } + + [Test] + public async Task VerifyLookup_WithNoSender_QueryParamsNotIncludeToken20() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + ""); + + Assert.That(passedQueryParams.ContainsKey("token20"), Is.False); + } + + [Test] + public async Task VerifyLookup_WithSender_QueryParamsIncludeToken20() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + "", + token5: "token20"); + + Assert.That(passedQueryParams["token20"], Is.EqualTo("token20")); + } + + [Test] + public async Task VerifyLookup_WithNoSender_QueryParamsNotIncludeType() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + ""); + + Assert.That(passedQueryParams.ContainsKey("type"), Is.False); + } + + [Test] + public async Task VerifyLookup_WithSender_QueryParamsIncludeType() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarMessageSender.VerifyLookup( + "", + "", + "", + type: VerifyLookupType.Call); + + Assert.That(passedQueryParams["type"], Is.EqualTo((int)VerifyLookupType.Call)); + } + + [Test] + public async Task VerifyLookup_WhenCalled_ReturnsSendResult() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "verify/lookup.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarMessageSender.VerifyLookup( + "", + "", + ""); + + Assert.That(result, Is.TypeOf()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarProfileApi/AccountConfig.cs b/Test/Test.Kavenegar.Core/KavenegarProfileApi/AccountConfig.cs new file mode 100644 index 0000000..7caae3b --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarProfileApi/AccountConfig.cs @@ -0,0 +1,426 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using Profile = Kavenegar.Core.KavenegarProfileApi; + +namespace Test.Kavenegar.Core.KavenegarProfileApi; + +public class AccountConfig +{ + private Profile _kavenegarProfileApi = null!; + private Mock _mockHttpClientHelper = null!; + + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarProfileApi = new Profile(_mockHttpClientHelper.Object, ""); + } + + [Test] + public async Task AccountConfig_WithAtLeastOneArgumentPassed_ReturnsAccountConfigDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":{}}") + }); + + var result = await _kavenegarProfileApi.AccountConfig(dailyReport: "a"); + + Assert.That(result, Is.TypeOf()); + } + + [Test] + public void AccountConfig_NoSettingArgumentIsSet_ThrowsArgumentException() + { + Assert.That(async () => await _kavenegarProfileApi.AccountConfig(), Throws.ArgumentException); + } + + [Test] + public async Task AccountConfig_WithNoApiLogs_QueryParamsNotIncludeApiLogs() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig(dailyReport: "a"); + + Assert.That(passedQueryParams.ContainsKey("apilogs"), Is.False); + } + + [Test] + public async Task AccountConfig_WithApiLogs_QueryParamsIncludeApiLogs() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig("apilogs"); + + Assert.That(passedQueryParams["apilogs"], Is.EqualTo("apilogs")); + } + + [Test] + public async Task AccountConfig_WithNoDailyReport_QueryParamsNotIncludeDailyReport() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig("a"); + + Assert.That(passedQueryParams.ContainsKey("dailyreport"), Is.False); + } + + [Test] + public async Task AccountConfig_WithDailyReport_QueryParamsIncludeDailyReport() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig(dailyReport: "dailyreport"); + + Assert.That(passedQueryParams["dailyreport"], Is.EqualTo("dailyreport")); + } + + [Test] + public async Task AccountConfig_WithNoDebugMode_QueryParamsNotIncludeDebugMode() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig("a"); + + Assert.That(passedQueryParams.ContainsKey("debugmode"), Is.False); + } + + [Test] + public async Task AccountConfig_WithDebugMode_QueryParamsIncludeDebugMode() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig(debugMode: "debugmode"); + + Assert.That(passedQueryParams["debugmode"], Is.EqualTo("debugmode")); + } + + [Test] + public async Task AccountConfig_WithNoDefaultSender_QueryParamsNotIncludeDefaultSender() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig("a"); + + Assert.That(passedQueryParams.ContainsKey("defaultsender"), Is.False); + } + + [Test] + public async Task AccountConfig_WithDefaultSender_QueryParamsIncludeDefaultSender() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig(defaultSender: "defaultsender"); + + Assert.That(passedQueryParams["defaultsender"], Is.EqualTo("defaultsender")); + } + + [Test] + public async Task AccountConfig_WithNoMinCreditAlarm_QueryParamsNotIncludeMinCreditAlarm() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig("a"); + + Assert.That(passedQueryParams.ContainsKey("mincreditalarm"), Is.False); + } + + [Test] + [TestCase(1)] + [TestCase(10)] + [TestCase(100)] + public async Task AccountConfig_WithMinCreditAlarm_QueryParamsIncludeMinCreditAlarm( + int mincreditalarm) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig(minCreditAlarm: mincreditalarm); + + Assert.That(passedQueryParams["mincreditalarm"], Is.EqualTo(mincreditalarm)); + } + + [Test] + public async Task AccountConfig_WithNoResendFailed_QueryParamsNotIncludeResendFailed() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig("a"); + + Assert.That(passedQueryParams.ContainsKey("resendfailed"), Is.False); + } + + [Test] + public async Task AccountConfig_WithResendFailed_QueryParamsIncludeResendFailed() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/config.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountConfig(resendFailed: "resendfailed"); + + Assert.That(passedQueryParams["resendfailed"], Is.EqualTo("resendfailed")); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarProfileApi/AccountInfo.cs b/Test/Test.Kavenegar.Core/KavenegarProfileApi/AccountInfo.cs new file mode 100644 index 0000000..b69c347 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarProfileApi/AccountInfo.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using Profile = Kavenegar.Core.KavenegarProfileApi; + +namespace Test.Kavenegar.Core.KavenegarProfileApi; + +[TestFixture] +public class AccountInfo +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarProfileApi = new Profile(_mockHttpClientHelper.Object, ""); + } + + private Profile _kavenegarProfileApi = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task AccountInfo_WhenCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/info.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.AccountInfo(); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "account/info.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + public async Task AccountInfo_WhenCalled_ReturnsAccountInfoDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "account/info.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":{}}") + }); + + var result = await _kavenegarProfileApi.AccountInfo(); + + Assert.That(result, Is.TypeOf()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarProfileApi/Cancel.cs b/Test/Test.Kavenegar.Core/KavenegarProfileApi/Cancel.cs new file mode 100644 index 0000000..e280da7 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarProfileApi/Cancel.cs @@ -0,0 +1,196 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using Profile = Kavenegar.Core.KavenegarProfileApi; + +namespace Test.Kavenegar.Core.KavenegarProfileApi; + +[TestFixture] +public class Cancel +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarProfileApi = new Profile(_mockHttpClientHelper.Object, ""); + } + + private Profile _kavenegarProfileApi = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task Cancel_SingleCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/cancel.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Cancel("messageid"); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/cancel.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Cancel_SingleCalled_CheckMessageIdsQueryParam( + string messageId) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/cancel.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Cancel(messageId); + + Assert.That(passedQueryParams["messageid"], Is.EqualTo(messageId)); + } + + [Test] + public async Task Cancel_SingleCalled_ReturnsStatusMessageDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/cancel.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.Cancel(""); + + Assert.That(result, Is.TypeOf()); + } + + [Test] + public async Task Cancel_MultiCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/cancel.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Cancel( + new List + { + "" + }); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/cancel.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Cancel_MultiCalled_CheckMessageIdsQueryParam( + string messageId) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/cancel.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Cancel( + new List + { + messageId, + messageId + }); + + Assert.That(passedQueryParams["messageid"], Is.EqualTo($"{messageId},{messageId}")); + } + + [Test] + public async Task Cancel_MultiCalled_ReturnsStatusMessageDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/cancel.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.Cancel( + new List + { + "" + }); + + Assert.That(result, Is.TypeOf>()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarProfileApi/CountInbox.cs b/Test/Test.Kavenegar.Core/KavenegarProfileApi/CountInbox.cs new file mode 100644 index 0000000..e0ef2d7 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarProfileApi/CountInbox.cs @@ -0,0 +1,367 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using Profile = Kavenegar.Core.KavenegarProfileApi; + +namespace Test.Kavenegar.Core.KavenegarProfileApi; + +public class CountInbox +{ + private Profile _kavenegarProfileApi = null!; + private Mock _mockHttpClientHelper = null!; + + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarProfileApi = new Profile(_mockHttpClientHelper.Object, ""); + } + + [Test] + public async Task CountInbox_WhenCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countinbox.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.CountInbox(DateTime.Now); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/countinbox.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase(61)] + [TestCase(71)] + [TestCase(81)] + public void CountInbox_StartDate61DaysAgo_ThrowsArgumentException( + int daysAgo) + { + Assert.That( + async () => await _kavenegarProfileApi.CountInbox(DateTime.Now.AddDays(-1 * daysAgo)), + Throws.ArgumentException); + } + + [Test] + [TestCase(1)] + [TestCase(10)] + [TestCase(100)] + public void CountInbox_StartDateGreaterThanOrEqualEndDate_ThrowsArgumentException( + int secondsBeforeStartDate) + { + Assert.That( + async () => await _kavenegarProfileApi.CountInbox( + DateTime.Now, + DateTime.Now.AddSeconds(-1 * secondsBeforeStartDate)), + Throws.ArgumentException); + } + + [Test] + [TestCase(2)] + [TestCase(10)] + [TestCase(100)] + public void CountInbox_StartDateEndDateDifferenceMoreThan1Day_ThrowsArgumentException( + int daysBeforeStartDate) + { + Assert.That( + async () => await _kavenegarProfileApi.CountInbox(DateTime.Now, DateTime.Now.AddDays(daysBeforeStartDate)), + Throws.ArgumentException); + } + + [Test] + public async Task CountInbox_WhenCalled_CheckStartDateQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countinbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.CountInbox(expectedStartDateTime); + + Assert.That(passedQueryParams["startdate"], Is.EqualTo(expectedStartDateTime.ToUnixTimestamp())); + } + + [Test] + public async Task CountInbox_WithNoEndDate_QueryParamsNotIncludeEndDate() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countinbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.CountInbox(expectedStartDateTime); + + Assert.That(passedQueryParams.ContainsKey("enddate"), Is.False); + } + + [Test] + public async Task CountInbox_WithEndDate_QueryParamsIncludeEndDate() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countinbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + var expectedEndDateDateTime = expectedStartDateTime.AddHours(1); + + await _kavenegarProfileApi.CountInbox(expectedStartDateTime, expectedEndDateDateTime); + + Assert.That(passedQueryParams["enddate"], Is.EqualTo(expectedEndDateDateTime.ToUnixTimestamp())); + } + + [Test] + public async Task CountInbox_WithNoLineNumber_QueryParamsNotIncludeLineNumber() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countinbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.CountInbox(expectedStartDateTime); + + Assert.That(passedQueryParams.ContainsKey("linenumber"), Is.False); + } + + [Test] + public async Task CountInbox_WithLineNumber_QueryParamsIncludeLineNumber() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countinbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.CountInbox(DateTime.Now, lineNumber: "linenumber"); + + Assert.That(passedQueryParams["linenumber"], Is.EqualTo("linenumber")); + } + + [Test] + public async Task CountInbox_WithNoIsRead_QueryParamsNotIncludeIsRead() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countinbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.CountInbox(expectedStartDateTime); + + Assert.That(passedQueryParams.ContainsKey("isread"), Is.False); + } + + [Test] + public async Task CountInbox_WithIsReadSetTrue_QueryParamsIsReadEqual1() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countinbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.CountInbox(DateTime.Now, isRead: true); + + Assert.That(passedQueryParams["isread"], Is.EqualTo(1)); + } + + [Test] + public async Task CountInbox_WithIsReadSetFalse_QueryParamsIsReadEqual0() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countinbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.CountInbox(DateTime.Now, isRead: false); + + Assert.That(passedQueryParams["isread"], Is.EqualTo(0)); + } + + [Test] + public async Task CountInbox_WhenCalled_ReturnsSendResultDtoList() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countinbox.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.CountInbox(DateTime.Now); + + Assert.That(result, Is.TypeOf()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarProfileApi/CountOutbox.cs b/Test/Test.Kavenegar.Core/KavenegarProfileApi/CountOutbox.cs new file mode 100644 index 0000000..149fec3 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarProfileApi/CountOutbox.cs @@ -0,0 +1,275 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Kavenegar.Core.Enums; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using Profile = Kavenegar.Core.KavenegarProfileApi; + +namespace Test.Kavenegar.Core.KavenegarProfileApi; + +public class CountOutbox +{ + private Profile _kavenegarProfileApi = null!; + private Mock _mockHttpClientHelper = null!; + + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarProfileApi = new Profile(_mockHttpClientHelper.Object, ""); + } + + [Test] + public async Task CountOutbox_WhenCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.CountOutbox(DateTime.Now); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/countoutbox.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase(61)] + [TestCase(71)] + [TestCase(81)] + public void CountOutbox_StartDate61DaysAgo_ThrowsArgumentException( + int daysAgo) + { + Assert.That( + async () => await _kavenegarProfileApi.CountOutbox(DateTime.Now.AddDays(-1 * daysAgo)), + Throws.ArgumentException); + } + + [Test] + [TestCase(1)] + [TestCase(10)] + [TestCase(100)] + public void CountOutbox_StartDateGreaterThanOrEqualEndDate_ThrowsArgumentException( + int secondsBeforeStartDate) + { + Assert.That( + async () => await _kavenegarProfileApi.CountOutbox( + DateTime.Now, + DateTime.Now.AddSeconds(-1 * secondsBeforeStartDate)), + Throws.ArgumentException); + } + + [Test] + [TestCase(2)] + [TestCase(10)] + [TestCase(100)] + public void CountOutbox_StartDateEndDateDifferenceMoreThan1Day_ThrowsArgumentException( + int daysBeforeStartDate) + { + Assert.That( + async () => await _kavenegarProfileApi.CountOutbox(DateTime.Now, DateTime.Now.AddDays(daysBeforeStartDate)), + Throws.ArgumentException); + } + + [Test] + public async Task CountOutbox_WhenCalled_CheckStartDateQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.CountOutbox(expectedStartDateTime); + + Assert.That(passedQueryParams["startdate"], Is.EqualTo(expectedStartDateTime.ToUnixTimestamp())); + } + + [Test] + public async Task CountOutbox_WithNoEndDate_QueryParamsNotIncludeEndDate() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.CountOutbox(expectedStartDateTime); + + Assert.That(passedQueryParams.ContainsKey("enddate"), Is.False); + } + + [Test] + public async Task CountOutbox_WithEndDate_QueryParamsIncludeEndDate() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + var expectedEndDateDateTime = expectedStartDateTime.AddHours(1); + + await _kavenegarProfileApi.CountOutbox(expectedStartDateTime, expectedEndDateDateTime); + + Assert.That(passedQueryParams["enddate"], Is.EqualTo(expectedEndDateDateTime.ToUnixTimestamp())); + } + + [Test] + public async Task CountOutbox_WithNoStatus_QueryParamsNotIncludeStatus() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.CountOutbox(expectedStartDateTime); + + Assert.That(passedQueryParams.ContainsKey("status"), Is.False); + } + + [Test] + public async Task CountOutbox_WithStatus_QueryParamsIncludeStatus() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.CountOutbox(expectedStartDateTime, status: MessageStatus.Canceled); + + Assert.That(passedQueryParams["status"], Is.EqualTo((int)MessageStatus.Canceled)); + } + + [Test] + public async Task CountOutbox_WhenCalled_ReturnsSendResultDtoList() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/countoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.CountOutbox(DateTime.Now); + + Assert.That(result, Is.TypeOf()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarProfileApi/LatestOutbox.cs b/Test/Test.Kavenegar.Core/KavenegarProfileApi/LatestOutbox.cs new file mode 100644 index 0000000..8f04e35 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarProfileApi/LatestOutbox.cs @@ -0,0 +1,186 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using Profile = Kavenegar.Core.KavenegarProfileApi; + +namespace Test.Kavenegar.Core.KavenegarProfileApi; + +public class LatestOutbox +{ + private Profile _kavenegarProfileApi = null!; + private Mock _mockHttpClientHelper = null!; + + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarProfileApi = new Profile(_mockHttpClientHelper.Object, ""); + } + + [Test] + [TestCase(501)] + [TestCase(601)] + [TestCase(701)] + public void LatestOutbox_PageSizeLargerThan500_ThrowsArgumentException( + int pageSize) + { + Assert.That(async () => await _kavenegarProfileApi.LatestOutbox(501), Throws.ArgumentException); + } + + [Test] + public async Task LatestOutbox_NullPageSize_PageSizeIs500() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/latestoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.LatestOutbox(); + + Assert.That(passedQueryParams["pagesize"], Is.EqualTo(500)); + } + + [Test] + [TestCase(1)] + [TestCase(2)] + [TestCase(100)] + public async Task LatestOutbox_SetPageSize_CheckPageSizeQueryParam( + int pageSize) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/latestoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.LatestOutbox(pageSize); + + Assert.That(passedQueryParams["pagesize"], Is.EqualTo(pageSize)); + } + + [Test] + public async Task LatestOutbox_WithNoSender_QueryParamsNotIncludeSender() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/latestoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.LatestOutbox(); + + Assert.That(passedQueryParams.ContainsKey("sender"), Is.False); + } + + [Test] + [TestCase("a")] + [TestCase("b")] + [TestCase("c")] + public async Task LatestOutbox_WithSender_QueryParamsIncludeSender( + string sender) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/latestoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.LatestOutbox(sender: sender); + + Assert.That(passedQueryParams["sender"], Is.EqualTo(sender)); + } + + [Test] + public async Task LatestOutbox_WhenCalled_ReturnsSendResultDtoList() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/latestoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.LatestOutbox(); + + Assert.That(result, Is.TypeOf>()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarProfileApi/Receive.cs b/Test/Test.Kavenegar.Core/KavenegarProfileApi/Receive.cs new file mode 100644 index 0000000..543aab6 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarProfileApi/Receive.cs @@ -0,0 +1,163 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using Profile = Kavenegar.Core.KavenegarProfileApi; + +namespace Test.Kavenegar.Core.KavenegarProfileApi; + +[TestFixture] +public class Receive +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarProfileApi = new Profile(_mockHttpClientHelper.Object, ""); + } + + private Profile _kavenegarProfileApi = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task Receive_WhenCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/receive.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Receive("line", false); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/receive.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + public async Task Receive_WhenCalled_CheckLineNumberValueInQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/receive.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Receive("linenumber", false); + + Assert.That(passedQueryParams["linenumber"], Is.EqualTo("linenumber")); + } + + [Test] + public async Task Receive_IsReadSetFalse_CheckIsReadValueIs0() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/receive.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Receive("", false); + + Assert.That(passedQueryParams["isread"], Is.EqualTo(0)); + } + + [Test] + public async Task Receive_IsReadSetTrue_CheckIsReadValueIs1() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/receive.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Receive("", true); + + Assert.That(passedQueryParams["isread"], Is.EqualTo(1)); + } + + [Test] + public async Task Receive_WhenCalled_ReturnsReceivedMessageDtoList() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/receive.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.Receive("", true); + + Assert.That(result, Is.TypeOf>()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarProfileApi/Select.cs b/Test/Test.Kavenegar.Core/KavenegarProfileApi/Select.cs new file mode 100644 index 0000000..8f55eb4 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarProfileApi/Select.cs @@ -0,0 +1,196 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using Profile = Kavenegar.Core.KavenegarProfileApi; + +namespace Test.Kavenegar.Core.KavenegarProfileApi; + +[TestFixture] +public class Select +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarProfileApi = new Profile(_mockHttpClientHelper.Object, ""); + } + + private Profile _kavenegarProfileApi = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task Select_SingleCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/select.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Select("messageid"); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/select.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Select_SingleCalled_CheckMessageIdsQueryParam( + string messageId) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/select.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Select(messageId); + + Assert.That(passedQueryParams["messageid"], Is.EqualTo(messageId)); + } + + [Test] + public async Task Select_SingleCalled_ReturnsSendResultDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/select.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.Select(""); + + Assert.That(result, Is.TypeOf()); + } + + [Test] + public async Task Select_MultiCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/select.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Select( + new List + { + "" + }); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/select.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Select_MultiCalled_CheckMessageIdsQueryParam( + string messageId) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/select.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Select( + new List + { + messageId, + messageId + }); + + Assert.That(passedQueryParams["messageid"], Is.EqualTo($"{messageId},{messageId}")); + } + + [Test] + public async Task Select_MultiCalled_ReturnsSendResultDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/select.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.Select( + new List + { + "" + }); + + Assert.That(result, Is.TypeOf>()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarProfileApi/SelectOutbox.cs b/Test/Test.Kavenegar.Core/KavenegarProfileApi/SelectOutbox.cs new file mode 100644 index 0000000..c9b1289 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarProfileApi/SelectOutbox.cs @@ -0,0 +1,278 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using Profile = Kavenegar.Core.KavenegarProfileApi; + +namespace Test.Kavenegar.Core.KavenegarProfileApi; + +public class SelectOutbox +{ + private Profile _kavenegarProfileApi = null!; + private Mock _mockHttpClientHelper = null!; + + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarProfileApi = new Profile(_mockHttpClientHelper.Object, ""); + } + + [Test] + public async Task SelectOutbox_WhenCalled_ThrowsArgumentException() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/selectoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.SelectOutbox(DateTime.Now); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/selectoutbox.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase(61)] + [TestCase(71)] + [TestCase(81)] + public void SelectOutbox_StartDate61DaysAgo_ThrowsArgumentException( + int daysAgo) + { + Assert.That( + async () => await _kavenegarProfileApi.SelectOutbox(DateTime.Now.AddDays(-1 * daysAgo)), + Throws.ArgumentException); + } + + [Test] + [TestCase(1)] + [TestCase(10)] + [TestCase(100)] + public void SelectOutbox_StartDateGreaterThanOrEqualEndDate_ThrowsArgumentException( + int secondsBeforeStartDate) + { + Assert.That( + async () => await _kavenegarProfileApi.SelectOutbox( + DateTime.Now, + DateTime.Now.AddSeconds(-1 * secondsBeforeStartDate)), + Throws.ArgumentException); + } + + [Test] + [TestCase(2)] + [TestCase(10)] + [TestCase(100)] + public void SelectOutbox_StartDateEndDateDifferenceMoreThan1Day_ThrowsArgumentException( + int daysBeforeStartDate) + { + Assert.That( + async () => await _kavenegarProfileApi.SelectOutbox( + DateTime.Now, + DateTime.Now.AddDays(daysBeforeStartDate)), + Throws.ArgumentException); + } + + [Test] + public async Task SelectOutbox_WhenCalled_CheckStartDateQueryParam() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/selectoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.SelectOutbox(expectedStartDateTime); + + Assert.That(passedQueryParams["startdate"], Is.EqualTo(expectedStartDateTime.ToUnixTimestamp())); + } + + [Test] + public async Task SelectOutbox_WithNoEndDate_QueryParamsNotIncludeEndDate() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/selectoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.SelectOutbox(expectedStartDateTime); + + Assert.That(passedQueryParams.ContainsKey("enddate"), Is.False); + } + + [Test] + public async Task SelectOutbox_WithEndDate_QueryParamsIncludeEndDate() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/selectoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + var expectedEndDateDateTime = expectedStartDateTime.AddHours(1); + + await _kavenegarProfileApi.SelectOutbox(expectedStartDateTime, expectedEndDateDateTime); + + Assert.That(passedQueryParams["enddate"], Is.EqualTo(expectedEndDateDateTime.ToUnixTimestamp())); + } + + [Test] + public async Task SelectOutbox_WithNoSender_QueryParamsNotIncludeSender() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/selectoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.SelectOutbox(expectedStartDateTime); + + Assert.That(passedQueryParams.ContainsKey("sender"), Is.False); + } + + [Test] + public async Task SelectOutbox_WithSender_QueryParamsIncludeSender() + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/selectoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + var expectedStartDateTime = DateTime.Now; + + await _kavenegarProfileApi.SelectOutbox(expectedStartDateTime, sender: "sender"); + + Assert.That(passedQueryParams["sender"], Is.EqualTo("sender")); + } + + [Test] + public async Task SelectOutbox_WhenCalled_ReturnsSendResultDtoList() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/selectoutbox.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var expectedStartDateTime = DateTime.Now; + + var result = await _kavenegarProfileApi.SelectOutbox(expectedStartDateTime, sender: "sender"); + + Assert.That(result, Is.TypeOf>()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarProfileApi/Status.cs b/Test/Test.Kavenegar.Core/KavenegarProfileApi/Status.cs new file mode 100644 index 0000000..4339c2e --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarProfileApi/Status.cs @@ -0,0 +1,196 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using Profile = Kavenegar.Core.KavenegarProfileApi; + +namespace Test.Kavenegar.Core.KavenegarProfileApi; + +[TestFixture] +public class Status +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarProfileApi = new Profile(_mockHttpClientHelper.Object, ""); + } + + private Profile _kavenegarProfileApi = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task Status_SingleCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/status.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Status("messageid"); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/status.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Status_SingleCalled_CheckMessageIdsQueryParam( + string messageId) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/status.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Status(messageId); + + Assert.That(passedQueryParams["messageid"], Is.EqualTo(messageId)); + } + + [Test] + public async Task Status_SingleCalled_ReturnsStatusMessageDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/status.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.Status(""); + + Assert.That(result, Is.TypeOf()); + } + + [Test] + public async Task Status_MultiCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/status.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Status( + new List + { + "" + }); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/status.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task Status_MultiCalled_CheckMessageIdsQueryParam( + string messageId) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/status.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.Status( + new List + { + messageId, + messageId + }); + + Assert.That(passedQueryParams["messageid"], Is.EqualTo($"{messageId},{messageId}")); + } + + [Test] + public async Task Status_MultiCalled_ReturnsStatusMessageDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/status.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.Status( + new List + { + "" + }); + + Assert.That(result, Is.TypeOf>()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/KavenegarProfileApi/StatusLocalMessageId.cs b/Test/Test.Kavenegar.Core/KavenegarProfileApi/StatusLocalMessageId.cs new file mode 100644 index 0000000..5940091 --- /dev/null +++ b/Test/Test.Kavenegar.Core/KavenegarProfileApi/StatusLocalMessageId.cs @@ -0,0 +1,196 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Kavenegar.Core.Dto.Result; +using Moq; +using NUnit.Framework; +using Shared.Infrastructure; +using Profile = Kavenegar.Core.KavenegarProfileApi; + +namespace Test.Kavenegar.Core.KavenegarProfileApi; + +[TestFixture] +public class StatusLocalMessageId +{ + [SetUp] + public void SetUp() + { + _mockHttpClientHelper = new Mock(); + _kavenegarProfileApi = new Profile(_mockHttpClientHelper.Object, ""); + } + + private Profile _kavenegarProfileApi = null!; + private Mock _mockHttpClientHelper = null!; + + [Test] + public async Task StatusLocalMessageId_SingleCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/statuslocalmessageid.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.StatusLocalMessageId("messageid"); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/statuslocalmessageid.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task StatusLocalMessageId_SingleCalled_CheckMessageIdsQueryParam( + string messageId) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/statuslocalmessageid.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.StatusLocalMessageId(messageId); + + Assert.That(passedQueryParams["messageid"], Is.EqualTo(messageId)); + } + + [Test] + public async Task StatusLocalMessageId_SingleCalled_ReturnsStatusMessageDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/statuslocalmessageid.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.StatusLocalMessageId(""); + + Assert.That(result, Is.TypeOf()); + } + + [Test] + public async Task StatusLocalMessageId_MultiCalled_CallsPostAsync() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/statuslocalmessageid.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.StatusLocalMessageId( + new List + { + "" + }); + + _mockHttpClientHelper.Verify( + i => i.PostAsync( + "sms/statuslocalmessageid.json", + null, + It.IsAny>(), + It.IsAny())); + } + + [Test] + [TestCase("1")] + [TestCase("2")] + public async Task StatusLocalMessageId_MultiCalled_CheckMessageIdsQueryParam( + string messageId) + { + Dictionary passedQueryParams = null!; + + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/statuslocalmessageid.json", + null, + It.IsAny>(), + It.IsAny())) + .Callback, CancellationToken>( + ( + _, + _, + queryParams, + _) => + { + passedQueryParams = queryParams; + }) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{}") + }); + + await _kavenegarProfileApi.StatusLocalMessageId( + new List + { + messageId, + messageId + }); + + Assert.That(passedQueryParams["messageid"], Is.EqualTo($"{messageId},{messageId}")); + } + + [Test] + public async Task StatusLocalMessageId_MultiCalled_ReturnsStatusMessageDto() + { + _mockHttpClientHelper.Setup( + i => i.PostAsync( + "sms/statuslocalmessageid.json", + null, + It.IsAny>(), + It.IsAny())) + .ReturnsAsync( + new HttpResponseMessage + { + Content = new StringContent("{\"entries\":[{}]}") + }); + + var result = await _kavenegarProfileApi.StatusLocalMessageId( + new List + { + "" + }); + + Assert.That(result, Is.TypeOf>()); + } +} \ No newline at end of file diff --git a/Test/Test.Kavenegar.Core/Test.Kavenegar.Core.csproj b/Test/Test.Kavenegar.Core/Test.Kavenegar.Core.csproj new file mode 100644 index 0000000..2e2ef6c --- /dev/null +++ b/Test/Test.Kavenegar.Core/Test.Kavenegar.Core.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + + false + + + + + + + + + + + + + + + + diff --git a/Test/Test.Shared.Infrastructure/DateHelperTests.cs b/Test/Test.Shared.Infrastructure/DateHelperTests.cs new file mode 100644 index 0000000..7aa71d3 --- /dev/null +++ b/Test/Test.Shared.Infrastructure/DateHelperTests.cs @@ -0,0 +1,47 @@ +using System; +using NUnit.Framework; +using Shared.Infrastructure; + +namespace Test.Shared.Infrastructure; + +public class DateHelperTests +{ + [Test] + public void ToDateTime_WhenCalled_EqualsToConvertedDateTime() + { + const long unixTimeStamp = 1577836800L; + + var result = unixTimeStamp.ToDateTime(); + + var expectedDateTime = new DateTime( + 2020, + 1, + 1); + + Assert.That(result, Is.EqualTo(expectedDateTime)); + } + + [Test] + public void ToUnixTimestamp_DateBeforeMinDateTime_ThrowsArgumentException() + { + var dt = new DateTime( + 1969, + 12, + 1); + + Assert.That(() => dt.ToUnixTimestamp(), Throws.ArgumentException); + } + + [Test] + public void ToUnixTimestamp_DateAfterMinDateTime_ReturnsUnixTimestamp() + { + var dt = new DateTime( + 2020, + 1, + 1); + + var unixTimestamp = dt.ToUnixTimestamp(); + + Assert.That(unixTimestamp, Is.EqualTo(1577836800)); + } +} \ No newline at end of file diff --git a/Test/Test.Shared.Infrastructure/HttpClientHelperTests.cs b/Test/Test.Shared.Infrastructure/HttpClientHelperTests.cs new file mode 100644 index 0000000..462ceea --- /dev/null +++ b/Test/Test.Shared.Infrastructure/HttpClientHelperTests.cs @@ -0,0 +1,62 @@ +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Moq; +using Moq.Protected; +using NUnit.Framework; +using Shared.Infrastructure; + +namespace Test.Shared.Infrastructure; + +[TestFixture] +public class HttpClientHelperTests +{ + [SetUp] + public void SetUp() + { + _httpClientMock = new Mock(); + var httpClient = new HttpClient(_httpClientMock.Object); + _httpClientHelper = new HttpClientHelper(httpClient) + { + BaseAddress = "https://aaa.com" + }; + } + + private HttpClientHelper _httpClientHelper = null!; + private Mock _httpClientMock = null!; + + [Test] + public async Task PostAsync_WhenCalled_ReturnsHttpResponseMessage() + { + _httpClientMock.Protected() + .Setup>( + "SendAsync", + ItExpr.Is(req => req.Method == HttpMethod.Post), + ItExpr.IsAny()) + .ReturnsAsync(new HttpResponseMessage()); + + var result = await _httpClientHelper.PostAsync("c"); + + Assert.That(result, Is.TypeOf()); + } + + [Test] + public async Task PostAsync_WhenCalled_ReturnsCallsPostAsync() + { + _httpClientMock.Protected() + .Setup>( + "SendAsync", + ItExpr.Is(req => req.Method == HttpMethod.Post), + ItExpr.IsAny()) + .ReturnsAsync(new HttpResponseMessage()); + + await _httpClientHelper.PostAsync("c"); + + _httpClientMock.Protected() + .Verify( + "SendAsync", + Times.Exactly(1), + ItExpr.Is(req => req.Method == HttpMethod.Post), + ItExpr.IsAny()); + } +} \ No newline at end of file diff --git a/Test/Test.Shared.Infrastructure/JsonUtilityTests.cs b/Test/Test.Shared.Infrastructure/JsonUtilityTests.cs new file mode 100644 index 0000000..87a3e39 --- /dev/null +++ b/Test/Test.Shared.Infrastructure/JsonUtilityTests.cs @@ -0,0 +1,31 @@ +using System.Net.Http; +using System.Threading.Tasks; +using NUnit.Framework; +using Shared.Infrastructure; + +namespace Test.Shared.Infrastructure; + +[TestFixture] +public class JsonUtilityTests +{ + [Test] + public void Serialize_WhenCalled_ReturnsObjectJson() + { + var result = new object().Serialize(); + + Assert.That(result, Is.EqualTo("{}")); + } + + [Test] + public async Task Deserialize_WhenCalled_ReturnsDeserializedObject() + { + var httpResponseMessage = new HttpResponseMessage + { + Content = new StringContent("[{}]") + }; + + var result = await httpResponseMessage.Deserialize(); + + Assert.That(result, Is.TypeOf()); + } +} \ No newline at end of file diff --git a/Test/Test.Shared.Infrastructure/QueryParamHelperTests.cs b/Test/Test.Shared.Infrastructure/QueryParamHelperTests.cs new file mode 100644 index 0000000..20f5d95 --- /dev/null +++ b/Test/Test.Shared.Infrastructure/QueryParamHelperTests.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using NUnit.Framework; +using Shared.Infrastructure; + +namespace Test.Shared.Infrastructure; + +[TestFixture] +public class QueryParamHelperTests +{ + [Test] + public void AddQueryParamToUri_WhnCalled_ReturnsFullUri() + { + var result = QueryParamHelper.AddQueryParamToUri( + "http://a.b", + new Dictionary + { + { + "param", "value" + } + }); + + Assert.That(result, Is.EqualTo("http://a.b/?param=value")); + } +} \ No newline at end of file diff --git a/Test/Test.Shared.Infrastructure/StringUtilityTests.cs b/Test/Test.Shared.Infrastructure/StringUtilityTests.cs new file mode 100644 index 0000000..d25d3ff --- /dev/null +++ b/Test/Test.Shared.Infrastructure/StringUtilityTests.cs @@ -0,0 +1,108 @@ +using NUnit.Framework; +using Shared.Infrastructure; + +namespace Test.Shared.Infrastructure; + +[TestFixture] +public class StringUtilityTests +{ + [Test] + public void IsNullOrWhiteSpace_EmptyString_ReturnsTrue() + { + var result = string.Empty.IsNullOrWhiteSpace(); + + Assert.That(result, Is.True); + } + + [Test] + public void IsNullOrWhiteSpace_StringWithZeroLength_ReturnsTrue() + { + var result = "".IsNullOrWhiteSpace(); + + Assert.That(result, Is.True); + } + + [Test] + public void IsNullOrWhiteSpace_NullString_ReturnsTrue() + { + string? s = null; + + var result = s.IsNullOrWhiteSpace(); + + Assert.That(result, Is.True); + } + + [Test] + [TestCase(" ")] + [TestCase(" ")] + [TestCase(" ")] + public void IsNullOrWhiteSpace_WhiteSpaceString_ReturnsTrue( + string s) + { + var result = s.IsNullOrWhiteSpace(); + + Assert.That(result, Is.True); + } + + [Test] + [TestCase("a")] + [TestCase("ab")] + [TestCase("abc")] + public void IsNullOrWhiteSpace_StringWithCharacter_ReturnsFalse( + string s) + { + var result = s.IsNullOrWhiteSpace(); + + Assert.That(result, Is.False); + } + + [Test] + public void IsNotNullOrWhiteSpace_EmptyString_ReturnsTrue() + { + var result = string.Empty.IsNotNullOrWhiteSpace(); + + Assert.That(result, Is.False); + } + + [Test] + public void IsNotNullOrWhiteSpace_StringWithZeroLength_ReturnsTrue() + { + var result = "".IsNotNullOrWhiteSpace(); + + Assert.That(result, Is.False); + } + + [Test] + public void IsNotNullOrWhiteSpace_NullString_ReturnsTrue() + { + string? s = null; + + var result = s.IsNotNullOrWhiteSpace(); + + Assert.That(result, Is.False); + } + + [Test] + [TestCase(" ")] + [TestCase(" ")] + [TestCase(" ")] + public void IsNotNullOrWhiteSpace_WhiteSpaceString_ReturnsTrue( + string s) + { + var result = s.IsNotNullOrWhiteSpace(); + + Assert.That(result, Is.False); + } + + [Test] + [TestCase("a")] + [TestCase("ab")] + [TestCase("abc")] + public void IsNotNullOrWhiteSpace_StringWithCharacter_ReturnsFalse( + string s) + { + var result = s.IsNotNullOrWhiteSpace(); + + Assert.That(result, Is.True); + } +} \ No newline at end of file diff --git a/Test/Test.Shared.Infrastructure/Test.Shared.Infrastructure.csproj b/Test/Test.Shared.Infrastructure/Test.Shared.Infrastructure.csproj new file mode 100644 index 0000000..308d2ca --- /dev/null +++ b/Test/Test.Shared.Infrastructure/Test.Shared.Infrastructure.csproj @@ -0,0 +1,24 @@ + + + + net6.0 + enable + + false + + Test.Shared.Infrastructure + + + + + + + + + + + + + + +