diff --git a/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/FilaPedidosHostedService.cs b/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/FilaPedidosHostedService.cs index 7a3d385f..1202ec20 100644 --- a/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/FilaPedidosHostedService.cs +++ b/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/FilaPedidosHostedService.cs @@ -1,3 +1,5 @@ +using Microsoft.Extensions.Options; +using TechLanches.Adapter.FilaPedidos.Options; using TechLanches.Application.Ports.Services; using TechLanches.Domain.Enums; @@ -7,13 +9,16 @@ public class FilaPedidosHostedService : BackgroundService { private readonly IFilaPedidoService _filaPedidoService; private readonly ILogger _logger; + private readonly WorkerOptions _workerOptions; public FilaPedidosHostedService( ILogger logger, - IFilaPedidoService filaPedidoService) + IFilaPedidoService filaPedidoService, + IOptions workerOptions) { _logger = logger; _filaPedidoService = filaPedidoService; + _workerOptions = workerOptions.Value; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) @@ -34,7 +39,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) _logger.LogInformation($"Pedido {proximoPedido.Id} em preparação."); - await Task.Delay(1000 * 20, stoppingToken); + await Task.Delay(1000 * _workerOptions.DelayPreparacaoPedidoEmSegundos, stoppingToken); _logger.LogInformation($"Pedido {proximoPedido.Id} preparação finalizada."); @@ -52,7 +57,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) _logger.LogError(ex, "Erro ao processar fila de pedidos."); } - await Task.Delay(5000, stoppingToken); + await Task.Delay(_workerOptions.DelayVerificacaoFilaEmSegundos * 1000, stoppingToken); } } } diff --git a/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/Options/WorkerOptions.cs b/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/Options/WorkerOptions.cs new file mode 100644 index 00000000..5c85c608 --- /dev/null +++ b/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/Options/WorkerOptions.cs @@ -0,0 +1,8 @@ +namespace TechLanches.Adapter.FilaPedidos.Options +{ + public class WorkerOptions + { + public int DelayPreparacaoPedidoEmSegundos { get; set; } + public int DelayVerificacaoFilaEmSegundos { get; set; } + } +} \ No newline at end of file diff --git a/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/Program.cs b/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/Program.cs index 34dc1c82..9181a406 100644 --- a/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/Program.cs +++ b/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/Program.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; using TechLanches.Adapter.FilaPedidos; +using TechLanches.Adapter.FilaPedidos.Options; using TechLanches.Adapter.SqlServer; using TechLanches.Adapter.SqlServer.Repositories; using TechLanches.Application; @@ -17,6 +19,7 @@ .Build(); services.AddDatabaseConfiguration(settingsConfig, ServiceLifetime.Singleton); + services.Configure(settingsConfig.GetSection("Worker")); services.AddSingleton(); services.AddSingleton(); diff --git a/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/appsettings.Development.json b/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/appsettings.Development.json index 42cdddff..f849cd16 100644 --- a/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/appsettings.Development.json +++ b/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/appsettings.Development.json @@ -2,6 +2,10 @@ "ConnectionStrings": { "DefaultConnection": "Server=127.0.0.1,1433;Database=techlanches;User=sa;Password=Qwert@12345" }, + "Worker": { + "DelayPreparacaoPedidoEmSegundos": 20, + "DelayVerificacaoFilaEmSegundos": 5 + }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/appsettings.json b/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/appsettings.json index 42cdddff..f849cd16 100644 --- a/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/appsettings.json +++ b/src/TechLanches/Adapter/Driver/TechLanches.Adapter.FilaPedidos/appsettings.json @@ -2,6 +2,10 @@ "ConnectionStrings": { "DefaultConnection": "Server=127.0.0.1,1433;Database=techlanches;User=sa;Password=Qwert@12345" }, + "Worker": { + "DelayPreparacaoPedidoEmSegundos": 20, + "DelayVerificacaoFilaEmSegundos": 5 + }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/test/TechLanches.UnitTests/Services/FilaPedidoAggregateTest.cs b/test/TechLanches.UnitTests/Services/FilaPedidoAggregateTest.cs new file mode 100644 index 00000000..a318dcc9 --- /dev/null +++ b/test/TechLanches.UnitTests/Services/FilaPedidoAggregateTest.cs @@ -0,0 +1,80 @@ +using NSubstitute; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TechLanches.Application.DTOs; +using TechLanches.Application.Ports.Repositories; +using TechLanches.Application; +using TechLanches.Domain.Enums; +using TechLanches.Domain.Repositories; +using TechLanches.Domain.Aggregates; +using TechLanches.Domain.ValueObjects; + +namespace TechLanches.UnitTests.Services +{ + public class FilaPedidoAggregateTest + { + [Fact] + public async Task RetornarPrimeiroPedidoDaFila_ComPedidosNaFila_DeveRetornarPedido() + { + // Arrange + var mockFilaPedidoRepository = Substitute.For(); + var mockPedidoRepository = Substitute.For(); + + mockFilaPedidoRepository.RetornarFilaPedidos().Returns(Task.FromResult(new List + { + new FilaPedido { PedidoId = 1 }, + new FilaPedido { PedidoId = 2 } + })); + + mockPedidoRepository.BuscarPorId(1).Returns(Task.FromResult(new Pedido(1, new List { new ItemPedido(1, 1, 1) }))); + + var filaPedidoService = new FilaPedidoService(mockPedidoRepository, mockFilaPedidoRepository); + + // Act + var pedido = await filaPedidoService.RetornarPrimeiroPedidoDaFila(); + + // Assert + Assert.NotNull(pedido); + } + + [Fact] + public async Task RetornarPrimeiroPedidoDaFila_ComFilaVazia_DeveRetornarNull() + { + // Arrange + var mockFilaPedidoRepository = Substitute.For(); + var mockPedidoRepository = Substitute.For(); + + mockFilaPedidoRepository.RetornarFilaPedidos().Returns(Task.FromResult(new List())); + + var filaPedidoService = new FilaPedidoService(mockPedidoRepository, mockFilaPedidoRepository); + + // Act + var result = await filaPedidoService.RetornarPrimeiroPedidoDaFila(); + + // Assert + Assert.Null(result); + } + + [Fact] + public async Task TrocarStatus_DeveAtualizarStatusDoPedidoECommit() + { + // Arrange + var mockFilaPedidoRepository = Substitute.For(); + var mockPedidoRepository = Substitute.For(); + + var pedido = new Pedido(1, new List { new ItemPedido(1, 1, 1) }); + + var filaPedidoService = new FilaPedidoService(mockPedidoRepository, mockFilaPedidoRepository); + + // Act + await filaPedidoService.TrocarStatus(pedido, StatusPedido.PedidoEmPreparacao); + + // Assert + Assert.Equal(StatusPedido.PedidoEmPreparacao, pedido.StatusPedido); + await mockPedidoRepository.Received(1).UnitOfWork.Commit(); + } + } +} diff --git a/test/TechLanches.UnitTests/TechLanches.UnitTests.csproj b/test/TechLanches.UnitTests/TechLanches.UnitTests.csproj index 6773d798..5233a884 100644 --- a/test/TechLanches.UnitTests/TechLanches.UnitTests.csproj +++ b/test/TechLanches.UnitTests/TechLanches.UnitTests.csproj @@ -23,6 +23,7 @@ + diff --git a/test/TechLanches.UnitTests/Worker/FilaPedidoWorkerTest.cs b/test/TechLanches.UnitTests/Worker/FilaPedidoWorkerTest.cs new file mode 100644 index 00000000..d09d3b27 --- /dev/null +++ b/test/TechLanches.UnitTests/Worker/FilaPedidoWorkerTest.cs @@ -0,0 +1,103 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using NSubstitute; +using NSubstitute.ExceptionExtensions; +using TechLanches.Adapter.FilaPedidos; +using TechLanches.Adapter.FilaPedidos.Options; +using TechLanches.Application.Ports.Services; +using TechLanches.Domain.Aggregates; +using TechLanches.Domain.Enums; +using TechLanches.Domain.ValueObjects; + +namespace TechLanches.UnitTests.Worker +{ + public class FilaPedidoWorkerTest + { + [Fact] + public async Task ExecuteAsync_ComProximoPedido_DeveProcessarPedido() + { + // Arrange + var mockFilaPedidoService = Substitute.For(); + mockFilaPedidoService.RetornarPrimeiroPedidoDaFila().Returns(new Pedido(1, new List { new ItemPedido(1, 1, 1) })); + var mockLogger = Substitute.For>(); + + var mockOptions = Substitute.For>(); + var workerOptions = new WorkerOptions + { + DelayPreparacaoPedidoEmSegundos = 1, + DelayVerificacaoFilaEmSegundos = 5 + }; + + mockOptions.Value.Returns(workerOptions); + + var workerService = new FilaPedidosHostedService(mockLogger, mockFilaPedidoService, mockOptions); + + // Act + await workerService.StartAsync(CancellationToken.None); + await Task.Delay(1000 * (workerOptions.DelayPreparacaoPedidoEmSegundos + 1)); // Aguardando um período para permitir que o método ExecuteAsync seja executado + + // Assert + await mockFilaPedidoService.Received(1).RetornarPrimeiroPedidoDaFila(); + await mockFilaPedidoService.Received(1).TrocarStatus(Arg.Any(), StatusPedido.PedidoEmPreparacao); + await mockFilaPedidoService.Received(1).TrocarStatus(Arg.Any(), StatusPedido.PedidoPronto); + } + + [Fact] + public async Task ExecuteAsync_SemProximoPedido_NaoDeveProcessar() + { + // Arrange + var mockFilaPedidoService = Substitute.For(); + mockFilaPedidoService.RetornarPrimeiroPedidoDaFila().Returns(Task.FromResult(null)); + + var mockLogger = Substitute.For>(); + + var mockOptions = Substitute.For>(); + var workerOptions = new WorkerOptions + { + DelayPreparacaoPedidoEmSegundos = 1, + DelayVerificacaoFilaEmSegundos = 1 + }; + + mockOptions.Value.Returns(workerOptions); + + var workerService = new FilaPedidosHostedService(mockLogger, mockFilaPedidoService, mockOptions); + + // Act + await workerService.StartAsync(CancellationToken.None); + await Task.Delay(100); + + // Assert + await mockFilaPedidoService.Received(1).RetornarPrimeiroPedidoDaFila(); + await mockFilaPedidoService.DidNotReceive().TrocarStatus(Arg.Any(), Arg.Any()); + } + + [Fact] + public async Task ExecuteAsync_ComExcecao_NoCatch_DeveLogarErro() + { + // Arrange + var mockFilaPedidoService = Substitute.For(); + mockFilaPedidoService.RetornarPrimeiroPedidoDaFila().Throws(x => throw new Exception("Simulando erro")); + + var mockLogger = Substitute.For>(); + var mockOptions = Substitute.For>(); + var workerOptions = new WorkerOptions + { + DelayPreparacaoPedidoEmSegundos = 1, + DelayVerificacaoFilaEmSegundos = 1 + }; + + mockOptions.Value.Returns(workerOptions); + var workerService = new FilaPedidosHostedService(mockLogger, mockFilaPedidoService, mockOptions); + + // Act + await workerService.StartAsync(CancellationToken.None); + await Task.Delay(100); + + // Assert + await mockFilaPedidoService.Received(1).RetornarPrimeiroPedidoDaFila(); + await mockFilaPedidoService.DidNotReceive().TrocarStatus(Arg.Any(), Arg.Any()); + mockLogger.Received(1).Log(LogLevel.Error, Arg.Any(), Arg.Any(), Arg.Any(), + Arg.Any>()); + } + } +}