From f307c4ebe063225416e950a05d12fb3b711dfd55 Mon Sep 17 00:00:00 2001
From: alireza995 <88311706+alireza995@users.noreply.github.com>
Date: Sun, 4 Dec 2022 01:22:13 +0330
Subject: [PATCH 1/5] test(Solution) : relocate codes and create test project
relocate codes and create test project
---
.../Kavenegar.Core}/DependencyManager.cs | 0
.../Kavenegar.Core}/Dto/Message/MessageInfo.cs | 0
.../Dto/Message/SendMessageInfo.cs | 0
.../Dto/Message/SendMultiMessageRequest.cs | 0
.../Dto/Message/SendSingleMessageRequest.cs | 0
.../Dto/Result/AccountConfigDto.cs | 0
.../Dto/Result/AccountInfoDto.cs | 0
.../Kavenegar.Core}/Dto/Result/CountInboxDto.cs | 0
.../Dto/Result/CountOutboxDto.cs | 0
.../Dto/Result/LocalStatusDto.cs | 0
.../Dto/Result/ReceivedMessageDto.cs | 0
.../Kavenegar.Core}/Dto/Result/ResultDto.cs | 0
.../Kavenegar.Core}/Dto/Result/ResultStatus.cs | 0
.../Kavenegar.Core}/Dto/Result/SendResult.cs | 0
.../Dto/Result/StatusMessageDto.cs | 0
.../Kavenegar.Core}/Enums/MessageStatus.cs | 0
.../Kavenegar.Core}/Enums/MessageType.cs | 0
.../Kavenegar.Core}/Enums/VerifyLookupType.cs | 0
.../Kavenegar.Core}/IKavenegarApi.cs | 0
.../Kavenegar.Core}/Kavenegar.Core.csproj | 0
.../Kavenegar.Core}/KavenegarApi.cs | 0
.../Shared}/Shared.Infrastructure/DateHelper.cs | 0
.../Shared.Infrastructure/HttpClientHelper.cs | 0
.../Shared.Infrastructure/JsonUtility.cs | 0
.../Shared.Infrastructure/QueryParamHelper.cs | 0
.../Shared.Infrastructure.csproj | 0
Kavenegar.sln | 17 +++++++++++++++--
Test/Kavenegar.Core/Kavenegar.Core.csproj | 17 +++++++++++++++++
28 files changed, 32 insertions(+), 2 deletions(-)
rename {Kavenegar.Core => Code/Kavenegar.Core}/DependencyManager.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Message/MessageInfo.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Message/SendMessageInfo.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Message/SendMultiMessageRequest.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Message/SendSingleMessageRequest.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Result/AccountConfigDto.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Result/AccountInfoDto.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Result/CountInboxDto.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Result/CountOutboxDto.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Result/LocalStatusDto.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Result/ReceivedMessageDto.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Result/ResultDto.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Result/ResultStatus.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Result/SendResult.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Dto/Result/StatusMessageDto.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Enums/MessageStatus.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Enums/MessageType.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Enums/VerifyLookupType.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/IKavenegarApi.cs (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/Kavenegar.Core.csproj (100%)
rename {Kavenegar.Core => Code/Kavenegar.Core}/KavenegarApi.cs (100%)
rename {Shared => Code/Shared}/Shared.Infrastructure/DateHelper.cs (100%)
rename {Shared => Code/Shared}/Shared.Infrastructure/HttpClientHelper.cs (100%)
rename {Shared => Code/Shared}/Shared.Infrastructure/JsonUtility.cs (100%)
rename {Shared => Code/Shared}/Shared.Infrastructure/QueryParamHelper.cs (100%)
rename {Shared => Code/Shared}/Shared.Infrastructure/Shared.Infrastructure.csproj (100%)
create mode 100644 Test/Kavenegar.Core/Kavenegar.Core.csproj
diff --git a/Kavenegar.Core/DependencyManager.cs b/Code/Kavenegar.Core/DependencyManager.cs
similarity index 100%
rename from Kavenegar.Core/DependencyManager.cs
rename to Code/Kavenegar.Core/DependencyManager.cs
diff --git a/Kavenegar.Core/Dto/Message/MessageInfo.cs b/Code/Kavenegar.Core/Dto/Message/MessageInfo.cs
similarity index 100%
rename from Kavenegar.Core/Dto/Message/MessageInfo.cs
rename to Code/Kavenegar.Core/Dto/Message/MessageInfo.cs
diff --git a/Kavenegar.Core/Dto/Message/SendMessageInfo.cs b/Code/Kavenegar.Core/Dto/Message/SendMessageInfo.cs
similarity index 100%
rename from Kavenegar.Core/Dto/Message/SendMessageInfo.cs
rename to Code/Kavenegar.Core/Dto/Message/SendMessageInfo.cs
diff --git a/Kavenegar.Core/Dto/Message/SendMultiMessageRequest.cs b/Code/Kavenegar.Core/Dto/Message/SendMultiMessageRequest.cs
similarity index 100%
rename from Kavenegar.Core/Dto/Message/SendMultiMessageRequest.cs
rename to Code/Kavenegar.Core/Dto/Message/SendMultiMessageRequest.cs
diff --git a/Kavenegar.Core/Dto/Message/SendSingleMessageRequest.cs b/Code/Kavenegar.Core/Dto/Message/SendSingleMessageRequest.cs
similarity index 100%
rename from Kavenegar.Core/Dto/Message/SendSingleMessageRequest.cs
rename to Code/Kavenegar.Core/Dto/Message/SendSingleMessageRequest.cs
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/Kavenegar.Core/Dto/Result/SendResult.cs b/Code/Kavenegar.Core/Dto/Result/SendResult.cs
similarity index 100%
rename from Kavenegar.Core/Dto/Result/SendResult.cs
rename to Code/Kavenegar.Core/Dto/Result/SendResult.cs
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 100%
rename from Kavenegar.Core/Enums/MessageStatus.cs
rename to Code/Kavenegar.Core/Enums/MessageStatus.cs
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/Kavenegar.Core/IKavenegarApi.cs b/Code/Kavenegar.Core/IKavenegarApi.cs
similarity index 100%
rename from Kavenegar.Core/IKavenegarApi.cs
rename to Code/Kavenegar.Core/IKavenegarApi.cs
diff --git a/Kavenegar.Core/Kavenegar.Core.csproj b/Code/Kavenegar.Core/Kavenegar.Core.csproj
similarity index 100%
rename from Kavenegar.Core/Kavenegar.Core.csproj
rename to Code/Kavenegar.Core/Kavenegar.Core.csproj
diff --git a/Kavenegar.Core/KavenegarApi.cs b/Code/Kavenegar.Core/KavenegarApi.cs
similarity index 100%
rename from Kavenegar.Core/KavenegarApi.cs
rename to Code/Kavenegar.Core/KavenegarApi.cs
diff --git a/Shared/Shared.Infrastructure/DateHelper.cs b/Code/Shared/Shared.Infrastructure/DateHelper.cs
similarity index 100%
rename from Shared/Shared.Infrastructure/DateHelper.cs
rename to Code/Shared/Shared.Infrastructure/DateHelper.cs
diff --git a/Shared/Shared.Infrastructure/HttpClientHelper.cs b/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs
similarity index 100%
rename from Shared/Shared.Infrastructure/HttpClientHelper.cs
rename to Code/Shared/Shared.Infrastructure/HttpClientHelper.cs
diff --git a/Shared/Shared.Infrastructure/JsonUtility.cs b/Code/Shared/Shared.Infrastructure/JsonUtility.cs
similarity index 100%
rename from Shared/Shared.Infrastructure/JsonUtility.cs
rename to Code/Shared/Shared.Infrastructure/JsonUtility.cs
diff --git a/Shared/Shared.Infrastructure/QueryParamHelper.cs b/Code/Shared/Shared.Infrastructure/QueryParamHelper.cs
similarity index 100%
rename from Shared/Shared.Infrastructure/QueryParamHelper.cs
rename to Code/Shared/Shared.Infrastructure/QueryParamHelper.cs
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
diff --git a/Kavenegar.sln b/Kavenegar.sln
index a636930..05f8859 100644
--- a/Kavenegar.sln
+++ b/Kavenegar.sln
@@ -1,8 +1,14 @@
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}") = "Kavenegar.Core", "Test\Kavenegar.Core\Kavenegar.Core.csproj", "{6E36B3F6-2B1D-4506-BA92-007AC00EF317}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -18,7 +24,14 @@ 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
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}
EndGlobalSection
EndGlobal
diff --git a/Test/Kavenegar.Core/Kavenegar.Core.csproj b/Test/Kavenegar.Core/Kavenegar.Core.csproj
new file mode 100644
index 0000000..65a4f7b
--- /dev/null
+++ b/Test/Kavenegar.Core/Kavenegar.Core.csproj
@@ -0,0 +1,17 @@
+
+
+
+ net6.0
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
From 1fb3165aa6ef14fb388afd58531c57bbad035acc Mon Sep 17 00:00:00 2001
From: alireza995 <88311706+alireza995@users.noreply.github.com>
Date: Fri, 9 Dec 2022 03:00:35 +0330
Subject: [PATCH 2/5] Refactor(Solution) : refactor and add new methods
refactor with separating classes into related activities
add new methods to send messages easier
dependency manager completed
closes nothing
---
Code/Kavenegar.Core/BaseKavenegarApi.cs | 35 ++
Code/Kavenegar.Core/DependencyManager.cs | 11 +-
.../Kavenegar.Core/Dto/Message/MessageInfo.cs | 2 +-
Code/Kavenegar.Core/Dto/Result/SendResult.cs | 13 -
.../Dto/Result/SendResultDto.cs | 32 ++
Code/Kavenegar.Core/Enums/MessageStatus.cs | 2 +-
.../Kavenegar.Core/IKavenegarMessageSender.cs | 75 +++
...avenegarApi.cs => IKavenegarProfileApi.cs} | 55 +-
Code/Kavenegar.Core/KavenegarApi.cs | 497 ------------------
Code/Kavenegar.Core/KavenegarMessageSender.cs | 234 +++++++++
Code/Kavenegar.Core/KavenegarProfileApi.cs | 314 +++++++++++
.../Shared.Infrastructure/HttpClientHelper.cs | 2 +-
.../IHttpClientHelper.cs | 12 +
.../Shared.Infrastructure/JsonUtility.cs | 2 +-
14 files changed, 733 insertions(+), 553 deletions(-)
create mode 100644 Code/Kavenegar.Core/BaseKavenegarApi.cs
delete mode 100644 Code/Kavenegar.Core/Dto/Result/SendResult.cs
create mode 100644 Code/Kavenegar.Core/Dto/Result/SendResultDto.cs
create mode 100644 Code/Kavenegar.Core/IKavenegarMessageSender.cs
rename Code/Kavenegar.Core/{IKavenegarApi.cs => IKavenegarProfileApi.cs} (55%)
delete mode 100644 Code/Kavenegar.Core/KavenegarApi.cs
create mode 100644 Code/Kavenegar.Core/KavenegarMessageSender.cs
create mode 100644 Code/Kavenegar.Core/KavenegarProfileApi.cs
create mode 100644 Code/Shared/Shared.Infrastructure/IHttpClientHelper.cs
diff --git a/Code/Kavenegar.Core/BaseKavenegarApi.cs b/Code/Kavenegar.Core/BaseKavenegarApi.cs
new file mode 100644
index 0000000..e404acd
--- /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";
+ protected 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
index 9d37983..8e87a0f 100644
--- a/Code/Kavenegar.Core/DependencyManager.cs
+++ b/Code/Kavenegar.Core/DependencyManager.cs
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
+using Shared.Infrastructure;
namespace Kavenegar.Core;
@@ -8,6 +9,14 @@ public static IServiceCollection AddKavenegar(
this IServiceCollection serviceCollection,
string apiKey)
{
- return serviceCollection.AddTransient(_ => new KavenegarApi(apiKey));
+ return serviceCollection.AddScoped()
+ .AddScoped(
+ serviceProvider => new KavenegarProfileApi(
+ serviceProvider.GetRequiredService(),
+ apiKey))
+ .AddScoped(
+ serviceProvider => new KavenegarMessageSender(
+ serviceProvider.GetRequiredService(),
+ apiKey));
}
}
\ No newline at end of file
diff --git a/Code/Kavenegar.Core/Dto/Message/MessageInfo.cs b/Code/Kavenegar.Core/Dto/Message/MessageInfo.cs
index c7053bc..0f0b087 100644
--- a/Code/Kavenegar.Core/Dto/Message/MessageInfo.cs
+++ b/Code/Kavenegar.Core/Dto/Message/MessageInfo.cs
@@ -6,5 +6,5 @@ public class MessageInfo
{
public string Sender { get; set; } = null!;
public string Message { get; set; } = null!;
- public MessageType Type { get; set; }
+ public MessageType Type { get; set; } = MessageType.Flash;
}
\ No newline at end of file
diff --git a/Code/Kavenegar.Core/Dto/Result/SendResult.cs b/Code/Kavenegar.Core/Dto/Result/SendResult.cs
deleted file mode 100644
index 21852ea..0000000
--- a/Code/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/Code/Kavenegar.Core/Dto/Result/SendResultDto.cs b/Code/Kavenegar.Core/Dto/Result/SendResultDto.cs
new file mode 100644
index 0000000..40922aa
--- /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 Status => 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/Code/Kavenegar.Core/Enums/MessageStatus.cs b/Code/Kavenegar.Core/Enums/MessageStatus.cs
index 9f00180..ecc71c5 100644
--- a/Code/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/Code/Kavenegar.Core/IKavenegarMessageSender.cs b/Code/Kavenegar.Core/IKavenegarMessageSender.cs
new file mode 100644
index 0000000..95c70ca
--- /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/IKavenegarApi.cs b/Code/Kavenegar.Core/IKavenegarProfileApi.cs
similarity index 55%
rename from Code/Kavenegar.Core/IKavenegarApi.cs
rename to Code/Kavenegar.Core/IKavenegarProfileApi.cs
index 379ce1f..bf54d6a 100644
--- a/Code/Kavenegar.Core/IKavenegarApi.cs
+++ b/Code/Kavenegar.Core/IKavenegarProfileApi.cs
@@ -1,84 +1,74 @@
-using Kavenegar.Core.Dto.Message;
-using Kavenegar.Core.Dto.Result;
-using Kavenegar.Core.Enums;
+using Kavenegar.Core.Dto.Result;
namespace Kavenegar.Core;
-public interface IKavenegarApi
+public interface IKavenegarProfileApi
{
- Task Send(
- SendSingleMessageRequest message,
- CancellationToken cancellationToken = default);
-
- Task> Send(
- SendMultiMessageRequest messages,
- CancellationToken cancellationToken = default);
-
- Task Status(
+ Task Status(
string messageId,
CancellationToken cancellationToken = default);
- Task> Status(
+ Task?> Status(
List messageIds,
CancellationToken cancellationToken = default);
- Task StatusLocalMessageId(
+ Task StatusLocalMessageId(
string messageId,
CancellationToken cancellationToken = default);
- Task> StatusLocalMessageId(
+ Task?> StatusLocalMessageId(
List messageIds,
CancellationToken cancellationToken = default);
- Task Select(
+ Task Select(
string messageId,
CancellationToken cancellationToken = default);
- Task> Select(
+ Task?> Select(
List messageIds,
CancellationToken cancellationToken = default);
- Task> SelectOutbox(
+ Task?> SelectOutbox(
DateTime startDate,
DateTime? endDate,
string? sender,
CancellationToken cancellationToken = default);
- Task> LatestOutbox(
+ Task?> LatestOutbox(
long? pageSize,
string? sender,
CancellationToken cancellationToken = default);
- Task CountOutbox(
+ Task CountOutbox(
DateTime startDate,
DateTime? endDate,
int? status,
CancellationToken cancellationToken = default);
- Task Cancel(
+ Task Cancel(
string messageId,
CancellationToken cancellationToken = default);
- Task> Cancel(
+ Task?> Cancel(
List ids,
CancellationToken cancellationToken = default);
- Task> Receive(
+ Task?> Receive(
string line,
bool isRead,
CancellationToken cancellationToken = default);
- Task CountInbox(
+ Task CountInbox(
DateTime startDate,
DateTime? endDate,
string? lineNumber,
bool? isRead,
CancellationToken cancellationToken = default);
- Task AccountInfo(
+ Task AccountInfo(
CancellationToken cancellationToken = default);
- Task AccountConfig(
+ Task AccountConfig(
string apiLogs,
string dailyReport,
string debugMode,
@@ -86,15 +76,4 @@ Task AccountConfig(
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/Code/Kavenegar.Core/KavenegarApi.cs b/Code/Kavenegar.Core/KavenegarApi.cs
deleted file mode 100644
index 2052d5f..0000000
--- a/Code/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/Code/Kavenegar.Core/KavenegarMessageSender.cs b/Code/Kavenegar.Core/KavenegarMessageSender.cs
new file mode 100644
index 0000000..1bd18d4
--- /dev/null
+++ b/Code/Kavenegar.Core/KavenegarMessageSender.cs
@@ -0,0 +1,234 @@
+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.AppMemory,
+ CancellationToken cancellationToken = default)
+ {
+ return (await Send(
+ new SendSingleMessageRequest
+ {
+ Date = dateTime ?? DateTime.Now,
+ Hide = hide,
+ MessageInfo = new MessageInfo
+ {
+ Message = message,
+ Sender = sender,
+ Type = messageType
+ },
+ ReceptorLocalMessageIds = new Dictionary
+ {
+ {
+ receptor, localMessageId
+ }
+ }
+ },
+ 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.AppMemory,
+ CancellationToken cancellationToken = default)
+ {
+ return await Send(
+ new SendSingleMessageRequest
+ {
+ Date = dateTime ?? DateTime.Now,
+ Hide = hide,
+ MessageInfo = new MessageInfo
+ {
+ Message = message,
+ Sender = sender,
+ Type = messageType
+ },
+ ReceptorLocalMessageIds = receptors
+ },
+ cancellationToken);
+ }
+
+ 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));
+
+ 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
+ {
+ Date = dateTime ?? DateTime.Now,
+ Hide = hide,
+ SendMessageInfos = sendMessageInfos
+ },
+ cancellationToken);
+ }
+
+ 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))));
+
+ 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)
+ {
+ 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());
+
+ 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..d016e0e
--- /dev/null
+++ b/Code/Kavenegar.Core/KavenegarProfileApi.cs
@@ -0,0 +1,314 @@
+using Kavenegar.Core.Dto.Result;
+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(
+ List 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(
+ List 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(
+ List 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,
+ 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);
+
+ return await RequestSender>(
+ "sms/selectoutbox.json",
+ null,
+ queryParams,
+ cancellationToken);
+ }
+
+ 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);
+
+ return await RequestSender>(
+ "sms/latestoutbox.json",
+ null,
+ queryParams,
+ cancellationToken);
+ }
+
+ 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);
+
+ 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(
+ List 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,
+ 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);
+
+ 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,
+ 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);
+
+ return await RequestSender(
+ "account/config.json",
+ null,
+ queryParams,
+ cancellationToken);
+ }
+}
\ No newline at end of file
diff --git a/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs b/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs
index a871bf4..e5083be 100644
--- a/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs
+++ b/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs
@@ -1,6 +1,6 @@
namespace Shared.Infrastructure;
-public class HttpClientHelper
+public class HttpClientHelper : IHttpClientHelper
{
private readonly HttpClient _httpClient = new();
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
index 566f80c..cc3a95c 100644
--- a/Code/Shared/Shared.Infrastructure/JsonUtility.cs
+++ b/Code/Shared/Shared.Infrastructure/JsonUtility.cs
@@ -5,7 +5,7 @@ namespace Shared.Infrastructure;
public static class JsonUtility
{
- public static async Task Serialize(
+ public static async Task Serialize(
this T obj,
CancellationToken cancellationToken = default)
{
From ab70fc5cfa2d4efbf8879d31e445a86bb220a301 Mon Sep 17 00:00:00 2001
From: alireza995 <88311706+alireza995@users.noreply.github.com>
Date: Fri, 9 Dec 2022 21:00:44 +0330
Subject: [PATCH 3/5] test(KavenegarMessageSender) : Test KavenegarMessage
Sender
Separate KavenegarApi class into and make it testable and create test class for methods which send single message
closes nothing
---
Code/Kavenegar.Core/BaseKavenegarApi.cs | 8 +-
.../Dto/Result/SendResultDto.cs | 2 +-
Code/Kavenegar.Core/KavenegarMessageSender.cs | 69 +--
.../Shared.Infrastructure/HttpClientHelper.cs | 2 +-
.../Shared.Infrastructure/JsonUtility.cs | 12 +-
.../Shared.Infrastructure/StringUtility.cs | 16 +
Kavenegar.sln | 2 +-
.../SingleMessageSendToManyBaseMethodTests.cs | 533 ++++++++++++++++++
.../SingleMessageSendToManyTests.cs | 439 +++++++++++++++
.../SingleMessageSendToOneTests.cs | 381 +++++++++++++
.../Test.Kavenegar.Core.csproj} | 5 +
11 files changed, 1417 insertions(+), 52 deletions(-)
create mode 100644 Code/Shared/Shared.Infrastructure/StringUtility.cs
create mode 100644 Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessageSendToManyBaseMethodTests.cs
create mode 100644 Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessageSendToManyTests.cs
create mode 100644 Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessageSendToOneTests.cs
rename Test/{Kavenegar.Core/Kavenegar.Core.csproj => Test.Kavenegar.Core/Test.Kavenegar.Core.csproj} (74%)
diff --git a/Code/Kavenegar.Core/BaseKavenegarApi.cs b/Code/Kavenegar.Core/BaseKavenegarApi.cs
index e404acd..6ccb08c 100644
--- a/Code/Kavenegar.Core/BaseKavenegarApi.cs
+++ b/Code/Kavenegar.Core/BaseKavenegarApi.cs
@@ -6,14 +6,14 @@ namespace Kavenegar.Core;
public class BaseKavenegarApi
{
private const string ApiAddress = "https://api.kavenegar.com/v1";
- protected readonly IHttpClientHelper HttpClientHelper;
+ private readonly IHttpClientHelper _httpClientHelper;
protected BaseKavenegarApi(
IHttpClientHelper httpClientHelper,
string apiKey)
{
- HttpClientHelper = httpClientHelper;
- HttpClientHelper.BaseAddress = Path.Combine(ApiAddress, apiKey);
+ _httpClientHelper = httpClientHelper;
+ _httpClientHelper.BaseAddress = Path.Combine(ApiAddress, apiKey);
}
protected async Task RequestSender(
@@ -22,7 +22,7 @@ protected BaseKavenegarApi(
Dictionary? queryParams,
CancellationToken cancellationToken)
{
- var httpResponseMessage = await HttpClientHelper.PostAsync(
+ var httpResponseMessage = await _httpClientHelper.PostAsync(
requestUri,
body,
queryParams,
diff --git a/Code/Kavenegar.Core/Dto/Result/SendResultDto.cs b/Code/Kavenegar.Core/Dto/Result/SendResultDto.cs
index 40922aa..8cff73f 100644
--- a/Code/Kavenegar.Core/Dto/Result/SendResultDto.cs
+++ b/Code/Kavenegar.Core/Dto/Result/SendResultDto.cs
@@ -12,7 +12,7 @@ public class SendResultDto
[JsonPropertyName("Status")]
public int StatusNumber { get; set; }
- public MessageStatus Status => StatusCaster(StatusNumber);
+ public MessageStatus MessageStatus => StatusCaster(StatusNumber);
public string StatusText { get; set; } = null!;
public string Sender { get; set; } = null!;
public string Receptor { get; set; } = null!;
diff --git a/Code/Kavenegar.Core/KavenegarMessageSender.cs b/Code/Kavenegar.Core/KavenegarMessageSender.cs
index 1bd18d4..fcf614e 100644
--- a/Code/Kavenegar.Core/KavenegarMessageSender.cs
+++ b/Code/Kavenegar.Core/KavenegarMessageSender.cs
@@ -35,28 +35,29 @@ public KavenegarMessageSender(
string localMessageId = "",
DateTime? dateTime = null,
bool hide = false,
- MessageType messageType = MessageType.AppMemory,
+ MessageType messageType = MessageType.Flash,
CancellationToken cancellationToken = default)
{
- return (await Send(
- new SendSingleMessageRequest
+ var sendSingleMessageRequest = new SendSingleMessageRequest
+ {
+ Hide = hide,
+ MessageInfo = new MessageInfo
+ {
+ Message = message,
+ Sender = sender,
+ Type = messageType
+ },
+ ReceptorLocalMessageIds = new Dictionary
{
- Date = dateTime ?? DateTime.Now,
- Hide = hide,
- MessageInfo = new MessageInfo
- {
- Message = message,
- Sender = sender,
- Type = messageType
- },
- ReceptorLocalMessageIds = new Dictionary
{
- {
- receptor, localMessageId
- }
+ receptor, localMessageId
}
- },
- cancellationToken))?.FirstOrDefault();
+ }
+ };
+
+ if (dateTime.HasValue) sendSingleMessageRequest.Date = dateTime;
+
+ return (await Send(sendSingleMessageRequest, cancellationToken))?.FirstOrDefault();
}
///
@@ -76,23 +77,24 @@ public KavenegarMessageSender(
string sender = "",
DateTime? dateTime = null,
bool hide = false,
- MessageType messageType = MessageType.AppMemory,
+ MessageType messageType = MessageType.Flash,
CancellationToken cancellationToken = default)
{
- return await Send(
- new SendSingleMessageRequest
+ var sendSingleMessageRequest = new SendSingleMessageRequest
+ {
+ Hide = hide,
+ MessageInfo = new MessageInfo
{
- Date = dateTime ?? DateTime.Now,
- Hide = hide,
- MessageInfo = new MessageInfo
- {
- Message = message,
- Sender = sender,
- Type = messageType
- },
- ReceptorLocalMessageIds = receptors
+ Message = message,
+ Sender = sender,
+ Type = messageType
},
- cancellationToken);
+ ReceptorLocalMessageIds = receptors
+ };
+
+ if (dateTime.HasValue) sendSingleMessageRequest.Date = dateTime;
+
+ return await Send(sendSingleMessageRequest, cancellationToken);
}
public async Task?> Send(
@@ -101,9 +103,6 @@ public KavenegarMessageSender(
{
var queryParams = new Dictionary
{
- {
- "sender", message.MessageInfo.Sender
- },
{
"receptor", string.Join(',', message.ReceptorLocalMessageIds.Keys)
},
@@ -118,7 +117,9 @@ public KavenegarMessageSender(
}
};
- if (message.ReceptorLocalMessageIds.Values.All(string.IsNullOrWhiteSpace))
+ 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>(
diff --git a/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs b/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs
index e5083be..6ae1fea 100644
--- a/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs
+++ b/Code/Shared/Shared.Infrastructure/HttpClientHelper.cs
@@ -26,6 +26,6 @@ private async Task SerializeBody(
object obj,
CancellationToken cancellationToken)
{
- return new StringContent(await obj.Serialize(cancellationToken));
+ return new StringContent(await obj.Serialize(cancellationToken) ?? "");
}
}
\ No newline at end of file
diff --git a/Code/Shared/Shared.Infrastructure/JsonUtility.cs b/Code/Shared/Shared.Infrastructure/JsonUtility.cs
index cc3a95c..04f1930 100644
--- a/Code/Shared/Shared.Infrastructure/JsonUtility.cs
+++ b/Code/Shared/Shared.Infrastructure/JsonUtility.cs
@@ -19,21 +19,11 @@ await JsonSerializer.SerializeAsync(
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);
+ return JsonSerializer.Deserialize(content);
}
}
\ No newline at end of file
diff --git a/Code/Shared/Shared.Infrastructure/StringUtility.cs b/Code/Shared/Shared.Infrastructure/StringUtility.cs
new file mode 100644
index 0000000..65bab68
--- /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.sln b/Kavenegar.sln
index 05f8859..7f88a4a 100644
--- a/Kavenegar.sln
+++ b/Kavenegar.sln
@@ -8,7 +8,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code", "Code", "{67BC444E-8
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{17B39BF3-CC26-40C5-AEB0-87CA2D71B93E}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kavenegar.Core", "Test\Kavenegar.Core\Kavenegar.Core.csproj", "{6E36B3F6-2B1D-4506-BA92-007AC00EF317}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Kavenegar.Core", "Test\Test.Kavenegar.Core\Test.Kavenegar.Core.csproj", "{6E36B3F6-2B1D-4506-BA92-007AC00EF317}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessageSendToManyBaseMethodTests.cs b/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessageSendToManyBaseMethodTests.cs
new file mode 100644
index 0000000..a0363fe
--- /dev/null
+++ b/Test/Test.Kavenegar.Core/KavenegarMessageSender/SingleMessageSendToManyBaseMethodTests.cs
@@ -0,0 +1,533 @@
+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;
+
+[TestFixture]
+public class SingleMessageSendToManyBaseMethodTests
+{
+ [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
+ {
+ MessageInfo = new MessageInfo
+ {
+ Message = "message"
+ },
+ ReceptorLocalMessageIds = 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(
+ new SendSingleMessageRequest
+ {
+ MessageInfo = new MessageInfo
+ {
+ Message = "message"
+ },
+ ReceptorLocalMessageIds = 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(
+ new SendSingleMessageRequest
+ {
+ MessageInfo = new MessageInfo
+ {
+ Message = "message",
+ Sender = "sender"
+ },
+ ReceptorLocalMessageIds = new Dictionary
+ {
+ {
+ "receptor", ""
+ }
+ }
+ });
+
+ 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
+ {
+ MessageInfo = new MessageInfo
+ {
+ Message = "message"
+ },
+ ReceptorLocalMessageIds = 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(
+ new SendSingleMessageRequest
+ {
+ MessageInfo = new MessageInfo
+ {
+ Message = "message"
+ },
+ ReceptorLocalMessageIds = 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
+ {
+ MessageInfo = new MessageInfo
+ {
+ Message = "message"
+ },
+ ReceptorLocalMessageIds = 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
+ {
+ MessageInfo = new MessageInfo
+ {
+ Message = "message"
+ },
+ ReceptorLocalMessageIds = 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(
+ new SendSingleMessageRequest
+ {
+ MessageInfo = new MessageInfo
+ {
+ Message = "message"
+ },
+ ReceptorLocalMessageIds = new Dictionary
+ {
+ {
+ "receptor", ""
+ }
+ },
+ 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
+ {
+ MessageInfo = new MessageInfo
+ {
+ Message = "message"
+ },
+ ReceptorLocalMessageIds = 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(
+ new SendSingleMessageRequest
+ {
+ MessageInfo = new MessageInfo
+ {
+ Message = "message",
+ Type = messageType
+ },
+ ReceptorLocalMessageIds = new Dictionary
+ {
+ {
+ "receptor", ""
+ }
+ }
+ });
+
+ 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
+ {
+ MessageInfo = new MessageInfo
+ {
+ Message = "message"
+ },
+ ReceptorLocalMessageIds = new Dictionary
+ {
+ {
+ "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