diff --git a/CaptchaBot.Tests/WelcomeServiceTests.cs b/CaptchaBot.Tests/WelcomeServiceTests.cs index e09d15d..c834a7e 100644 --- a/CaptchaBot.Tests/WelcomeServiceTests.cs +++ b/CaptchaBot.Tests/WelcomeServiceTests.cs @@ -1,7 +1,9 @@ using System.Globalization; using CaptchaBot.Services; +using CaptchaBot.Services.Translation; using FakeItEasy; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Telegram.Bot; using Telegram.Bot.Requests; using Telegram.Bot.Requests.Abstractions; @@ -17,10 +19,13 @@ public class WelcomeServiceTests private readonly ITelegramBotClient _botMock; private readonly ILogger _logger; private readonly List _deletedMessages = new(); + private readonly TranslationService _translationService; public WelcomeServiceTests(ITestOutputHelper outputHelper) { _logger = outputHelper.BuildLoggerFor(); + _translationService = new(Options.Create(new())); + _botMock = A.Fake(); A.CallTo(() => _botMock.MakeRequestAsync(A._, A._)) .Returns(new Message()); @@ -73,7 +78,7 @@ private async Task ProcessAnswer(IWelcomeService service, bool successful) public async Task BotShouldProcessEventWithinTimeout() { var config = new AppSettings {ProcessEventTimeout = TimeSpan.FromSeconds(5.0)}; - var welcomeService = new WelcomeService(config, _usersStore, _logger, _botMock); + var welcomeService = new WelcomeService(config, _usersStore, _logger, _botMock, _translationService); const long testUserId = 123L; await ProcessNewChatMember(welcomeService, testUserId, DateTime.UtcNow); @@ -102,7 +107,7 @@ public async Task BotShouldProcessEventWithinTimeout() public async Task BotShouldNotProcessEventOutsideTimeout() { var config = new AppSettings {ProcessEventTimeout = TimeSpan.FromMinutes(5.0)}; - var welcomeService = new WelcomeService(config, _usersStore, _logger, _botMock); + var welcomeService = new WelcomeService(config, _usersStore, _logger, _botMock, _translationService); const int testUserId = 345; await ProcessNewChatMember(welcomeService, testUserId, DateTime.UtcNow - TimeSpan.FromMinutes(6.0)); @@ -115,7 +120,7 @@ public async Task BotShouldNotProcessEventOutsideTimeout() public async Task BotShouldRestrictTheEnteringUserAndNotTheMessageAuthor() { var config = new AppSettings(); - var welcomeService = new WelcomeService(config, _usersStore, _logger, _botMock); + var welcomeService = new WelcomeService(config, _usersStore, _logger, _botMock, _translationService); const long enteringUserId = 123L; const long invitingUserId = 345L; @@ -140,7 +145,7 @@ public async Task BotShouldNotFailIfMessageCouldNotBeDeleted() .Throws(new Exception("This exception should not fail the message processing.")); var config = new AppSettings(); - var welcomeService = new WelcomeService(config, _usersStore, _logger, _botMock); + var welcomeService = new WelcomeService(config, _usersStore, _logger, _botMock, _translationService); const long newUserId = 124L; @@ -159,7 +164,7 @@ private async Task DoRemoveJoinTest( const long userId = 100L; var config = new AppSettings { DeleteJoinMessages = policy }; - var welcomeService = new WelcomeService(config, _usersStore, _logger, _botMock); + var welcomeService = new WelcomeService(config, _usersStore, _logger, _botMock, _translationService); await ProcessNewChatMember(welcomeService, userId, DateTime.UtcNow, joinMessageId: joinMessageId); await ProcessAnswer(welcomeService, successful); diff --git a/CaptchaBot/Properties/launchSettings.json b/CaptchaBot/Properties/launchSettings.json index fcafc3c..12b1f20 100644 --- a/CaptchaBot/Properties/launchSettings.json +++ b/CaptchaBot/Properties/launchSettings.json @@ -1,20 +1,5 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:58687/", - "sslPort": 44352 - } - }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, "CaptchaBot": { "commandName": "Project", "launchBrowser": true, @@ -31,4 +16,4 @@ "useSSL": true } } -} \ No newline at end of file +} diff --git a/CaptchaBot/Services/Translation/TranslationService.cs b/CaptchaBot/Services/Translation/TranslationService.cs new file mode 100644 index 0000000..4cbe2b3 --- /dev/null +++ b/CaptchaBot/Services/Translation/TranslationService.cs @@ -0,0 +1,28 @@ +using Microsoft.Extensions.Options; + +namespace CaptchaBot.Services.Translation; + +public interface ITranslationService +{ + string GetWelcomeMessage(string prettyUserName, in int answer); +} + +public class TranslationService : ITranslationService +{ + public TranslationService(IOptions options) + { + var settings = options.Value; + + NumberTexts = settings.NumberTexts.Split(','); + WelcomeMessageTemplate = settings.WelcomeMessageTemplate; + } + + private string[] NumberTexts { get; } + + private string WelcomeMessageTemplate { get; } + + private string GetRequestedNumberText(in int answer) => NumberTexts[answer]; + + public string GetWelcomeMessage(string prettyUserName, in int answer) + => string.Format(WelcomeMessageTemplate, prettyUserName, GetRequestedNumberText(answer)); +} diff --git a/CaptchaBot/Services/Translation/TranslationSettings.cs b/CaptchaBot/Services/Translation/TranslationSettings.cs new file mode 100644 index 0000000..7dcdd62 --- /dev/null +++ b/CaptchaBot/Services/Translation/TranslationSettings.cs @@ -0,0 +1,8 @@ +namespace CaptchaBot.Services.Translation; + +public class TranslationSettings +{ + public string NumberTexts { get; set; } = "ноль,один,два,три,четыре,пять,шесть,семь,восемь"; + + public string WelcomeMessageTemplate { get; set; } = "Привет, {0}, нажми кнопку {1}, чтобы тебя не забанили!"; +} \ No newline at end of file diff --git a/CaptchaBot/Services/UsersStore.cs b/CaptchaBot/Services/UsersStore.cs index c0ad5a2..722578e 100644 --- a/CaptchaBot/Services/UsersStore.cs +++ b/CaptchaBot/Services/UsersStore.cs @@ -5,12 +5,7 @@ namespace CaptchaBot.Services; public class UsersStore : IUsersStore { - private readonly ConcurrentDictionary _users; - - public UsersStore() - { - _users = new ConcurrentDictionary(); - } + private readonly ConcurrentDictionary _users = new(); public void Add( User user, @@ -34,10 +29,7 @@ public void Add( _users.AddOrUpdate(key, newValue, (_, _) => newValue); } - public IReadOnlyCollection GetAll() - { - return _users.Values.ToArray(); - } + public IReadOnlyCollection GetAll() => _users.Values.ToArray(); public NewUser? Get(long chatId, long userId) { diff --git a/CaptchaBot/Services/WelcomeService.cs b/CaptchaBot/Services/WelcomeService.cs index c67a218..a9059ca 100644 --- a/CaptchaBot/Services/WelcomeService.cs +++ b/CaptchaBot/Services/WelcomeService.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using CaptchaBot.Services.Translation; using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -8,36 +9,27 @@ namespace CaptchaBot.Services; public class WelcomeService : IWelcomeService { - private static readonly string[] NumberTexts = - { - "ноль", - "один", - "два", - "три", - "четыре", - "пять", - "шесть", - "семь", - "восемь", - }; - private const int ButtonsCount = 8; private static readonly Random Random = new Random(); + private readonly AppSettings _settings; private readonly IUsersStore _usersStore; private readonly ILogger _logger; private readonly ITelegramBotClient _telegramBot; + private readonly ITranslationService _translationService; public WelcomeService( AppSettings settings, IUsersStore usersStore, ILogger logger, - ITelegramBotClient telegramBot) + ITelegramBotClient telegramBot, + ITranslationService translationService) { _settings = settings; _usersStore = usersStore; _logger = logger; _telegramBot = telegramBot; + _translationService = translationService; } public async Task ProcessCallback(CallbackQuery query) @@ -234,7 +226,7 @@ await _telegramBot.RestrictChatMemberAsync( var sentMessage = await _telegramBot .SendTextMessageAsync( message.Chat.Id, - $"Привет, {prettyUserName}, нажми кнопку {GetText(answer)}, чтобы тебя не забанили!", + _translationService.GetWelcomeMessage(prettyUserName, answer), replyToMessageId: message.MessageId, replyMarkup: new InlineKeyboardMarkup(GetKeyboardButtons())); @@ -248,8 +240,6 @@ await _telegramBot.RestrictChatMemberAsync( } } - private static string GetText(in int answer) => NumberTexts[answer]; - private static string GetPrettyName(User messageNewChatMember) { var names = new List(3); diff --git a/CaptchaBot/Startup.cs b/CaptchaBot/Startup.cs index 6c6fd29..810bb6e 100644 --- a/CaptchaBot/Startup.cs +++ b/CaptchaBot/Startup.cs @@ -1,4 +1,5 @@ using CaptchaBot.Services; +using CaptchaBot.Services.Translation; using Microsoft.Extensions.Options; using Telegram.Bot; @@ -20,6 +21,7 @@ public void ConfigureServices(IServiceCollection services) services.AddOptions(); services.Configure(Configuration.GetSection("Configuration")); + services.Configure(Configuration.GetSection("Translation")); services.AddTransient(ser => ser.GetRequiredService>().Value); @@ -32,6 +34,7 @@ public void ConfigureServices(IServiceCollection services) services.AddSingleton(); services.AddTransient(); + services.AddTransient(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.