diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index 755cf05..8e4c1ab 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -12,9 +12,9 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Setup .NET
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: 7.0.x
- name: Restore dependencies
@@ -22,4 +22,4 @@ jobs:
- name: Build
run: dotnet build --no-restore /p:TreatWarningsAsErrors=false
- name: Test
- run: dotnet test --no-build --verbosity normal
+ run: dotnet test --no-build --verbosity normal -e telegram_test_token=${{secrets.TELEGRAM_TEST_TOKEN}}
\ No newline at end of file
diff --git a/Examples/Telegram.Examples/Telegram.Examples.csproj b/Examples/Telegram.Examples/Telegram.Examples.csproj
index 1622ed8..2891280 100644
--- a/Examples/Telegram.Examples/Telegram.Examples.csproj
+++ b/Examples/Telegram.Examples/Telegram.Examples.csproj
@@ -5,6 +5,7 @@
net7.0
enable
enable
+ true
diff --git a/Telegram.Net/Services/TelegramHostedService.cs b/Telegram.Net/Services/TelegramHostedService.cs
index 7793223..3f05c4f 100644
--- a/Telegram.Net/Services/TelegramHostedService.cs
+++ b/Telegram.Net/Services/TelegramHostedService.cs
@@ -14,14 +14,14 @@ namespace Telegram.Net.Services;
public class TelegramHostedService : IHostedService
{
private IServiceCollection isc { get; }
- private TelegramBotClient Client { get; }
+ internal TelegramBotClient Client { get; set; }
private ITelegramBotConfig Config { get; }
- internal static Dictionary> CommandHandler { get; } = new();
- internal static List> EditedMessageHandler { get; } = new();
- internal static Dictionary> CallbackQueryHandler { get; } = new();
- internal static Dictionary> InlineHandler { get; } = new();
- internal static Func? PreCheckoutHandler { get; set; }
- internal static List> DefaultUpdateHandler { get; } = new();
+ internal Dictionary> CommandHandler { get; } = new();
+ internal List> EditedMessageHandler { get; } = new();
+ internal Dictionary> CallbackQueryHandler { get; } = new();
+ internal Dictionary> InlineHandler { get; } = new();
+ internal Func? PreCheckoutHandler { get; set; }
+ internal List> DefaultUpdateHandler { get; } = new();
public TelegramHostedService(ITelegramBotConfig config, IServiceCollection isc)
{
@@ -47,10 +47,8 @@ public class TelegramHostedService : IHostedService
internal async Task AddAttributes(CancellationToken cancellationToken)
{
- var mutex = new Mutex();
await Task.Run(async () =>
{
- mutex.WaitOne();
var implementations = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => typeof(IUpdatePollingService).IsAssignableFrom(t) && !t.IsInterface);
@@ -82,7 +80,7 @@ public class TelegramHostedService : IHostedService
if (IsValidHandlerMethod(method, typeof(Message)))
{
var handler = CreateDelegate(method);
- CommandHandler.Add(commandAttr.Command, handler);
+ CommandHandler.TryAdd(commandAttr.Command, handler);
}
continue;
}
@@ -93,7 +91,7 @@ public class TelegramHostedService : IHostedService
if (IsValidHandlerMethod(method, typeof(CallbackQuery)))
{
var handler = CreateDelegate(method);
- CallbackQueryHandler.Add(callbackAttr.QueryId, handler);
+ CallbackQueryHandler.TryAdd(callbackAttr.QueryId, handler);
}
continue;
}
@@ -115,7 +113,7 @@ public class TelegramHostedService : IHostedService
if (IsValidHandlerMethod(method, typeof(InlineQuery)))
{
var handler = CreateDelegate(method);
- InlineHandler.Add(inlineAttr.InlineId, handler);
+ InlineHandler.TryAdd(inlineAttr.InlineId, handler);
}
continue;
}
@@ -142,44 +140,44 @@ public class TelegramHostedService : IHostedService
continue;
}
}
- mutex.ReleaseMutex();
}, cancellationToken);
}
+ internal async Task UpdateHandler(ITelegramBotClient client, Update update, CancellationToken ctx)
+ {
+ switch (update)
+ {
+ case { Message: { } message }:
+ await CommandHandler.FirstOrDefault(k => message.Text!.StartsWith(k.Key)).Value(client, message, ctx);
+ break;
+ case { EditedMessage: { } message }:
+ EditedMessageHandler.ForEach(async k => await k(client, message, ctx));
+ break;
+ case { CallbackQuery: { } callbackQuery }:
+ await CallbackQueryHandler.FirstOrDefault(k => callbackQuery.Data!.StartsWith(k.Key)).Value(client, callbackQuery, ctx);
+ break;
+ case { InlineQuery: { } inlineQuery }:
+ await InlineHandler.FirstOrDefault(k => inlineQuery.Id.StartsWith(k.Key)).Value(client, inlineQuery, ctx);
+ break;
+ case { PreCheckoutQuery: { } preCheckoutQuery }:
+ if (PreCheckoutHandler != null) await PreCheckoutHandler(client, preCheckoutQuery, ctx);
+ break;
+ default:
+ DefaultUpdateHandler.ForEach(async k => await k(client, update, ctx));
+ break;
+ }
+ }
+
[SuppressMessage("ReSharper", "AsyncVoidLambda")]
public async Task StartAsync(CancellationToken cancellationToken)
{
await AddAttributes(cancellationToken);
-
-
+
+
+
Client.StartReceiving(
- async (client, update, ctx) =>
- {
- switch (update)
- {
- case { Message: { } message }:
- await CommandHandler.FirstOrDefault(k => message.Text!.StartsWith(k.Key)).Value(client, message, cancellationToken);
- break;
- case { EditedMessage: { } message }:
- EditedMessageHandler.ForEach(async k => await k(client, message, cancellationToken));
- break;
- case { CallbackQuery: { } callbackQuery }:
- await CallbackQueryHandler.FirstOrDefault(k => callbackQuery.Data!.StartsWith(k.Key)).Value(client, callbackQuery, cancellationToken);
- break;
- case { InlineQuery: { } inlineQuery }:
- await InlineHandler.FirstOrDefault(k => inlineQuery.Id.StartsWith(k.Key)).Value(client, inlineQuery, cancellationToken);
- break;
- case {PreCheckoutQuery: { } preCheckoutQuery}:
- if (PreCheckoutHandler != null)
- await PreCheckoutHandler(client, preCheckoutQuery, cancellationToken);
- break;
- default:
- DefaultUpdateHandler.ForEach(async k => await k(client, update, ctx));
- break;
- }
-
- },
+ UpdateHandler,
Config.errorHandler ?? ((_, _, _) => Task.CompletedTask),
Config.ReceiverOptions,
cancellationToken);
diff --git a/Telegram.Net/Telegram.Net.csproj b/Telegram.Net/Telegram.Net.csproj
index eae3820..f612b35 100644
--- a/Telegram.Net/Telegram.Net.csproj
+++ b/Telegram.Net/Telegram.Net.csproj
@@ -1,6 +1,7 @@
+ true
net7.0
enable
enable
diff --git a/tests/Telegram.Tests/Telegram.Tests.csproj b/tests/Telegram.Tests/Telegram.Tests.csproj
index 2eed84f..0b9b510 100644
--- a/tests/Telegram.Tests/Telegram.Tests.csproj
+++ b/tests/Telegram.Tests/Telegram.Tests.csproj
@@ -4,7 +4,7 @@
net7.0
enable
enable
-
+ true
false
true
diff --git a/tests/Telegram.Tests/TestTelegramHostedService.cs b/tests/Telegram.Tests/TestTelegramHostedService.cs
index c6d70d4..656485f 100644
--- a/tests/Telegram.Tests/TestTelegramHostedService.cs
+++ b/tests/Telegram.Tests/TestTelegramHostedService.cs
@@ -13,13 +13,14 @@ using Microsoft.Extensions.DependencyInjection;
using Moq;
using Telegram.Bot.Types.Enums;
using Telegram.Bot.Types.ReplyMarkups;
+using Telegram.Net.Models;
namespace Telegram.Tests
{
[TestFixture]
public class TelegramHostedServiceTests
{
- private Mock _configMock;
+ private TelegramBotConfig _configMock;
private ServiceCollection _services;
[SetUp]
@@ -30,14 +31,14 @@ namespace Telegram.Tests
.AddJsonFile("appsettings.json", false)
.AddEnvironmentVariables()
.Build();
- _configMock = new Mock();
- _configMock.Setup(c => c.Token).Returns(conf.GetValue("telegram_test_token"));
+
+ _configMock = new TelegramBotConfig(conf.GetValue("telegram_test_token") ?? throw new Exception("Provide telegram token first"));
_services = new ServiceCollection();
}
public class TestHandler : IUpdatePollingService
{
- [Command("start")]
+ [Command("/start")]
public async Task HandleStart(ITelegramBotClient client, Message message, CancellationToken ct)
=> await client.SendTextMessageAsync(message.Chat.Id, "Started", cancellationToken: ct);
@@ -66,18 +67,18 @@ namespace Telegram.Tests
public void AddAttributes_RegistersCommandHandlersCorrectly()
{
_services.AddSingleton();
- var service = new TelegramHostedService(_configMock.Object, _services);
+ var service = new TelegramHostedService(_configMock, _services);
service.AddAttributes(CancellationToken.None).Wait();
Assert.Multiple(() =>
{
- Assert.That(TelegramHostedService.CommandHandler, Contains.Key("start"));
- Assert.That(TelegramHostedService.CallbackQueryHandler, Contains.Key("test_callback"));
- Assert.That(TelegramHostedService.EditedMessageHandler, Has.Count.EqualTo(1));
- Assert.That(TelegramHostedService.InlineHandler, Contains.Key("search"));
- Assert.That(TelegramHostedService.PreCheckoutHandler, Is.Not.Null);
- Assert.That(TelegramHostedService.DefaultUpdateHandler, Has.Count.EqualTo(1));
+ Assert.That(service.CommandHandler, Contains.Key("/start"));
+ Assert.That(service.CallbackQueryHandler, Contains.Key("test_callback"));
+ Assert.That(service.EditedMessageHandler, Has.Count.EqualTo(1));
+ Assert.That(service.InlineHandler, Contains.Key("search"));
+ Assert.That(service.PreCheckoutHandler, Is.Not.Null);
+ Assert.That(service.DefaultUpdateHandler, Has.Count.EqualTo(1));
});
}
@@ -118,8 +119,14 @@ namespace Telegram.Tests
[SetUp]
public void Setup()
{
+ var conf = new ConfigurationBuilder()
+ .SetBasePath(AppContext.BaseDirectory)
+ .AddJsonFile("appsettings.json", false)
+ .AddEnvironmentVariables()
+ .Build();
+
_configMock = new Mock();
- _configMock.Setup(c => c.Token).Returns("test_token");
+ _configMock.Setup(c => c.Token).Returns(conf.GetValue("telegram_test_token") ?? throw new Exception("Provide token first"));
_configMock.Setup(c => c.ReceiverOptions).Returns(new ReceiverOptions());
var services = new ServiceCollection();
@@ -137,23 +144,6 @@ namespace Telegram.Tests
var message = new Message { Text = "/start", Chat = new Chat { Id = 123 } };
var update = new Update { Message = message };
- _botClientMock.Setup(b => b.SendMessage(
- It.IsAny(),
- "Started",
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny>(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny()
- )).Verifiable();
-
// Act
await _hostedService.StartAsync(CancellationToken.None);
await InvokeUpdateHandler(update);
@@ -169,15 +159,6 @@ namespace Telegram.Tests
var callback = new CallbackQuery { Data = "test_callback", Id = "cb_id" };
var update = new Update { CallbackQuery = callback };
- _botClientMock.Setup(b => b.AnswerCallbackQueryAsync(
- "cb_id",
- "Callback handled",
- It.IsAny(),
- It.IsAny(),
- It.IsAny(),
- It.IsAny()
- )).Verifiable();
-
// Act
await _hostedService.StartAsync(CancellationToken.None);
await InvokeUpdateHandler(update);
@@ -188,14 +169,7 @@ namespace Telegram.Tests
private async Task InvokeUpdateHandler(Update update)
{
- var clientField = typeof(TelegramHostedService).GetField("Client", BindingFlags.NonPublic | BindingFlags.Instance);
- clientField.SetValue(_hostedService, _botClientMock.Object);
-
- var updateHandler = _botClientMock.Invocations
- .First(i => i.Method.Name == "StartReceiving")
- .Arguments[0] as Func;
-
- await updateHandler(_botClientMock.Object, update, CancellationToken.None);
+ await _hostedService.UpdateHandler(_botClientMock.Object, update, CancellationToken.None);
}
}
}
\ No newline at end of file