Merge branch 'unit-tests'
This commit is contained in:
commit
b03a58fc92
|
|
@ -7,3 +7,5 @@ Bullet6/bin/
|
||||||
Bullet6/obj/
|
Bullet6/obj/
|
||||||
BlazorApp.Shared/bin/
|
BlazorApp.Shared/bin/
|
||||||
.vs/BlazorApp/
|
.vs/BlazorApp/
|
||||||
|
BlazorApp.Tests/bin/
|
||||||
|
BlazorApp.Tests/obj/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Bunit" Version="1.40.0" />
|
||||||
|
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||||
|
<PackageReference Include="Moq" Version="4.20.72" />
|
||||||
|
<PackageReference Include="xunit" Version="2.5.3" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\BlazorApp\BlazorApp.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Using Include="Xunit" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
using BlazorApp.Controllers;
|
||||||
|
using BlazorApp.Interfaces.Services;
|
||||||
|
using BlazorApp.Shared.Models;
|
||||||
|
using BlazorApp.Shared.Models.Pagination;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Moq;
|
||||||
|
|
||||||
|
namespace BlazorApp.Tests.Controllers;
|
||||||
|
|
||||||
|
public class CustomerControllerTests
|
||||||
|
{
|
||||||
|
private readonly Mock<ICustomerService> _mockService;
|
||||||
|
private readonly CustomerController _controller;
|
||||||
|
|
||||||
|
public CustomerControllerTests()
|
||||||
|
{
|
||||||
|
_mockService = new Mock<ICustomerService>();
|
||||||
|
_controller = new CustomerController(_mockService.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Query_OK()
|
||||||
|
{
|
||||||
|
var customers = new PaginatedResult<Customer>
|
||||||
|
{
|
||||||
|
TotalCount = 1,
|
||||||
|
Results = new List<Customer>() { new Customer { Id = "blabla", CompanyName = "blabla" } }
|
||||||
|
};
|
||||||
|
_mockService.Setup(s => s.Query(It.IsAny<Shared.Queries.CustomerQuery>())).ReturnsAsync(customers);
|
||||||
|
|
||||||
|
var actionResult = await _controller.Query(new Shared.Queries.CustomerQuery());
|
||||||
|
|
||||||
|
var okResult = Assert.IsType<OkObjectResult>(actionResult.Result);
|
||||||
|
|
||||||
|
var returnResult = Assert.IsType<PaginatedResult<Customer>>(okResult.Value);
|
||||||
|
|
||||||
|
Assert.Single(returnResult.Results);
|
||||||
|
Assert.Equal(1, returnResult.TotalCount);
|
||||||
|
_mockService.Verify(s => s.Query(It.IsAny<Shared.Queries.CustomerQuery>()), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Get_OK()
|
||||||
|
{
|
||||||
|
var customer = new Customer
|
||||||
|
{
|
||||||
|
Id = "blabla",
|
||||||
|
CompanyName = "blabla"
|
||||||
|
};
|
||||||
|
_mockService.Setup(s => s.Get(It.IsAny<string>())).ReturnsAsync(customer);
|
||||||
|
|
||||||
|
var actionResult = await _controller.Get("blabla");
|
||||||
|
|
||||||
|
var okResult = Assert.IsType<OkObjectResult>(actionResult.Result);
|
||||||
|
|
||||||
|
var returnResult = Assert.IsType<Customer>(okResult.Value);
|
||||||
|
|
||||||
|
Assert.NotNull(returnResult);
|
||||||
|
_mockService.Verify(s => s.Get("blabla"), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Delete_ReturnsNoContent()
|
||||||
|
{
|
||||||
|
_mockService.Setup(s => s.Delete(It.IsAny<string>())).Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var actionResult = await _controller.Delete("blabla");
|
||||||
|
|
||||||
|
Assert.IsType<NoContentResult>(actionResult);
|
||||||
|
_mockService.Verify(s => s.Delete("blabla"), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Save_ReturnsNoContent()
|
||||||
|
{
|
||||||
|
var customer = new Customer
|
||||||
|
{
|
||||||
|
Id = "blabla",
|
||||||
|
CompanyName = "blabla"
|
||||||
|
};
|
||||||
|
_mockService.Setup(s => s.Save(It.IsAny<Customer>())).Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var actionResult = await _controller.Save(customer);
|
||||||
|
|
||||||
|
Assert.IsType<NoContentResult>(actionResult);
|
||||||
|
_mockService.Verify(s => s.Save(customer), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Update_ReturnsNoContent()
|
||||||
|
{
|
||||||
|
var customer = new Customer
|
||||||
|
{
|
||||||
|
Id = "blabla",
|
||||||
|
CompanyName = "blabla"
|
||||||
|
};
|
||||||
|
_mockService.Setup(s => s.Update(It.IsAny<Customer>())).Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var actionResult = await _controller.Update(customer);
|
||||||
|
|
||||||
|
Assert.IsType<NoContentResult>(actionResult);
|
||||||
|
_mockService.Verify(s => s.Update(customer), Times.Once);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
using BlazorApp.Middlewares;
|
||||||
|
using BlazorApp.Models.Exceptions;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Moq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace BlazorApp.Tests.Middlewares
|
||||||
|
{
|
||||||
|
public class ErrorHandlingMiddlewareTests
|
||||||
|
{
|
||||||
|
private readonly Mock<ILogger<ErrorHandlingMiddleware>> _loggerMock;
|
||||||
|
|
||||||
|
public ErrorHandlingMiddlewareTests()
|
||||||
|
{
|
||||||
|
_loggerMock = new Mock<ILogger<ErrorHandlingMiddleware>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpContext CreateHttpContext()
|
||||||
|
{
|
||||||
|
var context = new DefaultHttpContext();
|
||||||
|
context.Response.Body = new MemoryStream();
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetResponseBody(HttpContext context)
|
||||||
|
{
|
||||||
|
context.Response.Body.Seek(0, SeekOrigin.Begin);
|
||||||
|
using var reader = new StreamReader(context.Response.Body, Encoding.UTF8);
|
||||||
|
return reader.ReadToEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Invoke_WhenNotFoundException_Returns404()
|
||||||
|
{
|
||||||
|
var context = CreateHttpContext();
|
||||||
|
RequestDelegate next = (ctx) => throw new NotFoundException("blabla");
|
||||||
|
|
||||||
|
var middleware = new ErrorHandlingMiddleware(next, _loggerMock.Object);
|
||||||
|
|
||||||
|
await middleware.Invoke(context);
|
||||||
|
|
||||||
|
Assert.Equal((int)HttpStatusCode.NotFound, context.Response.StatusCode);
|
||||||
|
var body = GetResponseBody(context);
|
||||||
|
Assert.Contains("blabla", body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Invoke_WhenBusinessException_Returns500()
|
||||||
|
{
|
||||||
|
var context = CreateHttpContext();
|
||||||
|
RequestDelegate next = (ctx) => throw new BusinessException("blabla");
|
||||||
|
|
||||||
|
var middleware = new ErrorHandlingMiddleware(next, _loggerMock.Object);
|
||||||
|
|
||||||
|
await middleware.Invoke(context);
|
||||||
|
|
||||||
|
Assert.Equal((int)HttpStatusCode.InternalServerError, context.Response.StatusCode);
|
||||||
|
var body = GetResponseBody(context);
|
||||||
|
Assert.Contains("blabla", body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Invoke_WhenValidationException_Returns400()
|
||||||
|
{
|
||||||
|
var context = CreateHttpContext();
|
||||||
|
RequestDelegate next = (ctx) => throw new ValidationException("blabla");
|
||||||
|
|
||||||
|
var middleware = new ErrorHandlingMiddleware(next, _loggerMock.Object);
|
||||||
|
|
||||||
|
await middleware.Invoke(context);
|
||||||
|
|
||||||
|
Assert.Equal((int)HttpStatusCode.BadRequest, context.Response.StatusCode);
|
||||||
|
var body = GetResponseBody(context);
|
||||||
|
Assert.Contains("blabla", body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Invoke_WhenUnhandledException_Returns500()
|
||||||
|
{
|
||||||
|
var context = CreateHttpContext();
|
||||||
|
RequestDelegate next = (ctx) => throw new Exception("blabla");
|
||||||
|
|
||||||
|
var middleware = new ErrorHandlingMiddleware(next, _loggerMock.Object);
|
||||||
|
|
||||||
|
await middleware.Invoke(context);
|
||||||
|
|
||||||
|
Assert.Equal((int)HttpStatusCode.InternalServerError, context.Response.StatusCode);
|
||||||
|
var body = GetResponseBody(context);
|
||||||
|
Assert.Contains("blabla", body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorApp.Client", "BlazorA
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorApp.Shared", "BlazorApp.Shared\BlazorApp.Shared.csproj", "{C6627F01-4882-40B1-890C-D70AA74B9BD1}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorApp.Shared", "BlazorApp.Shared\BlazorApp.Shared.csproj", "{C6627F01-4882-40B1-890C-D70AA74B9BD1}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bullet6", "Bullet6\Bullet6.csproj", "{8FA67E47-DDAB-4712-B628-F904086B1F77}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bullet6", "Bullet6\Bullet6.csproj", "{8FA67E47-DDAB-4712-B628-F904086B1F77}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorApp.Tests", "BlazorApp.Tests\BlazorApp.Tests.csproj", "{80656871-78E1-49BF-8935-34F42BDCF6A6}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|
@ -33,6 +35,10 @@ Global
|
||||||
{8FA67E47-DDAB-4712-B628-F904086B1F77}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{8FA67E47-DDAB-4712-B628-F904086B1F77}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{8FA67E47-DDAB-4712-B628-F904086B1F77}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{8FA67E47-DDAB-4712-B628-F904086B1F77}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{8FA67E47-DDAB-4712-B628-F904086B1F77}.Release|Any CPU.Build.0 = Release|Any CPU
|
{8FA67E47-DDAB-4712-B628-F904086B1F77}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{80656871-78E1-49BF-8935-34F42BDCF6A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{80656871-78E1-49BF-8935-34F42BDCF6A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{80656871-78E1-49BF-8935-34F42BDCF6A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{80656871-78E1-49BF-8935-34F42BDCF6A6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="Scrutor" Version="6.1.0" />
|
<PackageReference Include="Scrutor" Version="6.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ else
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
// Simulate asynchronous loading to demonstrate streaming rendering
|
|
||||||
await Task.Delay(500);
|
await Task.Delay(500);
|
||||||
forecasts = await ForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
|
forecasts = await ForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
using System.Net;
|
||||||
|
using BlazorApp.Models.Exceptions;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace BlazorApp.Middlewares
|
||||||
|
{
|
||||||
|
public class ErrorHandlingMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate next;
|
||||||
|
private readonly ILogger<ErrorHandlingMiddleware> _logger;
|
||||||
|
|
||||||
|
public ErrorHandlingMiddleware(
|
||||||
|
RequestDelegate next,
|
||||||
|
ILogger<ErrorHandlingMiddleware> logger)
|
||||||
|
{
|
||||||
|
this.next = next;
|
||||||
|
this._logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Invoke(HttpContext context)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await next(context);
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
await this.HandleAsync(context, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task HandleAsync(HttpContext context, System.Exception exception)
|
||||||
|
{
|
||||||
|
HandledException handled = this.HandleException(exception);
|
||||||
|
|
||||||
|
this._logger.LogError(exception, $"returning code {handled.StatusCode} and payload {handled.Message}");
|
||||||
|
|
||||||
|
context.Response.ContentType = "application/json";
|
||||||
|
context.Response.StatusCode = (int)handled.StatusCode;
|
||||||
|
await context.Response.WriteAsync(handled.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HandledException HandleException(System.Exception exception)
|
||||||
|
{
|
||||||
|
HttpStatusCode statusCode;
|
||||||
|
|
||||||
|
if (exception is NotFoundException)
|
||||||
|
{
|
||||||
|
statusCode = HttpStatusCode.NotFound;
|
||||||
|
}
|
||||||
|
else if (exception is ValidationException)
|
||||||
|
{
|
||||||
|
statusCode = HttpStatusCode.BadRequest;
|
||||||
|
}
|
||||||
|
else if (exception is BusinessException)
|
||||||
|
{
|
||||||
|
statusCode = HttpStatusCode.InternalServerError;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statusCode = HttpStatusCode.InternalServerError;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HandledException()
|
||||||
|
{
|
||||||
|
StatusCode = statusCode,
|
||||||
|
Message = JsonConvert.SerializeObject(new { error = exception.Message })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace BlazorApp.Models.Exceptions
|
||||||
|
{
|
||||||
|
public class BusinessException : System.Exception
|
||||||
|
{
|
||||||
|
public BusinessException() : base() { }
|
||||||
|
public BusinessException(String message) : base(message) { }
|
||||||
|
public BusinessException(String message, System.Exception innerException) : base(message, innerException) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace BlazorApp.Models.Exceptions
|
||||||
|
{
|
||||||
|
public class HandledException
|
||||||
|
{
|
||||||
|
public HttpStatusCode StatusCode { get; set; }
|
||||||
|
public string Message { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace BlazorApp.Models.Exceptions
|
||||||
|
{
|
||||||
|
public class NotFoundException : System.Exception
|
||||||
|
{
|
||||||
|
public NotFoundException() : base() { }
|
||||||
|
public NotFoundException(String message) : base(message) { }
|
||||||
|
public NotFoundException(String message, System.Exception innerException) : base(message, innerException) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace BlazorApp.Models.Exceptions
|
||||||
|
{
|
||||||
|
public class ValidationException : System.Exception
|
||||||
|
{
|
||||||
|
public ValidationException() : base() { }
|
||||||
|
public ValidationException(String message) : base(message) { }
|
||||||
|
public ValidationException(String message, System.Exception innerException) : base(message, innerException) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ using BlazorApp.Components;
|
||||||
using BlazorApp.Data.Context;
|
using BlazorApp.Data.Context;
|
||||||
using BlazorApp.Interfaces.Repositories;
|
using BlazorApp.Interfaces.Repositories;
|
||||||
using BlazorApp.Interfaces.Services;
|
using BlazorApp.Interfaces.Services;
|
||||||
|
using BlazorApp.Middlewares;
|
||||||
using BlazorApp.Models.Config;
|
using BlazorApp.Models.Config;
|
||||||
using BlazorApp.Repositories.Database;
|
using BlazorApp.Repositories.Database;
|
||||||
using BlazorApp.Repositories.InMemory;
|
using BlazorApp.Repositories.InMemory;
|
||||||
|
|
@ -12,7 +13,6 @@ using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
// Add services to the container.
|
|
||||||
builder.Services.AddRazorComponents()
|
builder.Services.AddRazorComponents()
|
||||||
.AddInteractiveServerComponents()
|
.AddInteractiveServerComponents()
|
||||||
.AddInteractiveWebAssemblyComponents();
|
.AddInteractiveWebAssemblyComponents();
|
||||||
|
|
@ -41,9 +41,9 @@ builder.Services.AddClientServices();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
app.UseMiddleware(typeof(ErrorHandlingMiddleware));
|
||||||
app.ExecuteDbMigration();
|
app.ExecuteDbMigration();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
|
||||||
if (app.Environment.IsDevelopment())
|
if (app.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
app.UseWebAssemblyDebugging();
|
app.UseWebAssemblyDebugging();
|
||||||
|
|
@ -51,7 +51,6 @@ if (app.Environment.IsDevelopment())
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
||||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
|
||||||
app.UseHsts();
|
app.UseHsts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
using BlazorApp.Data;
|
using BlazorApp.Data;
|
||||||
using BlazorApp.Data.Context;
|
using BlazorApp.Data.Context;
|
||||||
using BlazorApp.Interfaces.Repositories;
|
using BlazorApp.Interfaces.Repositories;
|
||||||
|
using BlazorApp.Models.Exceptions;
|
||||||
using BlazorApp.Shared.Queries;
|
using BlazorApp.Shared.Queries;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace BlazorApp.Repositories.Database
|
namespace BlazorApp.Repositories.Database
|
||||||
{
|
{
|
||||||
|
|
@ -27,7 +27,7 @@ namespace BlazorApp.Repositories.Database
|
||||||
Customer data = await this._dbContext.Customers.FindAsync(id);
|
Customer data = await this._dbContext.Customers.FindAsync(id);
|
||||||
if (data is null)
|
if (data is null)
|
||||||
{
|
{
|
||||||
throw new KeyNotFoundException($"Customer with id: {id} not found");
|
throw new NotFoundException($"Customer with id: {id} not found");
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
namespace BlazorApp.Services
|
||||||
|
{
|
||||||
|
public class BaseService<T>
|
||||||
|
{
|
||||||
|
protected readonly ILogger<T> _logger;
|
||||||
|
public BaseService(ILogger<T> logger)
|
||||||
|
{
|
||||||
|
this._logger = logger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,32 +1,38 @@
|
||||||
using BlazorApp.Interfaces.Repositories;
|
using BlazorApp.Interfaces.Repositories;
|
||||||
using BlazorApp.Interfaces.Services;
|
using BlazorApp.Interfaces.Services;
|
||||||
|
using BlazorApp.Models.Exceptions;
|
||||||
using BlazorApp.Shared.Models;
|
using BlazorApp.Shared.Models;
|
||||||
using BlazorApp.Shared.Models.Pagination;
|
using BlazorApp.Shared.Models.Pagination;
|
||||||
using BlazorApp.Shared.Queries;
|
using BlazorApp.Shared.Queries;
|
||||||
|
|
||||||
namespace BlazorApp.Services
|
namespace BlazorApp.Services
|
||||||
{
|
{
|
||||||
public class CustomerService : ICustomerService
|
public class CustomerService : BaseService<CustomerService>, ICustomerService
|
||||||
{
|
{
|
||||||
private readonly ICustomerRepository _customerRepository;
|
private readonly ICustomerRepository _customerRepository;
|
||||||
public CustomerService(ICustomerRepository customerRepository)
|
public CustomerService(ICustomerRepository customerRepository, ILogger<CustomerService> logger) : base(logger)
|
||||||
{
|
{
|
||||||
this._customerRepository = customerRepository;
|
this._customerRepository = customerRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Delete(string id)
|
public async Task Delete(string id)
|
||||||
{
|
{
|
||||||
|
this._logger.LogInformation($"Gonna delete customer with id: {id}");
|
||||||
await this._customerRepository.Delete(id);
|
await this._customerRepository.Delete(id);
|
||||||
|
this._logger.LogInformation($"Deleted customer with id: {id}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Customer> Get(string id)
|
public async Task<Customer> Get(string id)
|
||||||
{
|
{
|
||||||
|
this._logger.LogInformation($"Gonna get customer with id: {id}");
|
||||||
Data.Customer data = await this._customerRepository.Get(id);
|
Data.Customer data = await this._customerRepository.Get(id);
|
||||||
|
this._logger.LogInformation($"Got customer with id: {id}");
|
||||||
return data.Convert();
|
return data.Convert();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PaginatedResult<Customer>> Query(CustomerQuery query)
|
public async Task<PaginatedResult<Customer>> Query(CustomerQuery query)
|
||||||
{
|
{
|
||||||
|
this._logger.LogInformation($"Querying customers");
|
||||||
IEnumerable<Data.Customer> datas = await this._customerRepository.Query(query);
|
IEnumerable<Data.Customer> datas = await this._customerRepository.Query(query);
|
||||||
return new PaginatedResult<Customer>()
|
return new PaginatedResult<Customer>()
|
||||||
{
|
{
|
||||||
|
|
@ -37,12 +43,16 @@ namespace BlazorApp.Services
|
||||||
|
|
||||||
public async Task Save(Customer customer)
|
public async Task Save(Customer customer)
|
||||||
{
|
{
|
||||||
|
this._logger.LogInformation($"Gonna save new customer");
|
||||||
await this._customerRepository.Save(customer);
|
await this._customerRepository.Save(customer);
|
||||||
|
this._logger.LogInformation($"New customer saved successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Update(Customer customer)
|
public async Task Update(Customer customer)
|
||||||
{
|
{
|
||||||
|
this._logger.LogInformation($"Gonna update customer with id: {customer.Id}");
|
||||||
await this._customerRepository.Update(customer);
|
await this._customerRepository.Update(customer);
|
||||||
|
this._logger.LogInformation($"Customer with id: {customer.Id} updated successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> Count() => await this._customerRepository.Count();
|
public async Task<int> Count() => await this._customerRepository.Count();
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,6 @@
|
||||||
"CustomerCacheKey": "customer",
|
"CustomerCacheKey": "customer",
|
||||||
"CustomerCacheSeconds": 5
|
"CustomerCacheSeconds": 5
|
||||||
},
|
},
|
||||||
"MockCustomers": true,
|
"MockCustomers": false,
|
||||||
"MockCustomersCount": 238
|
"MockCustomersCount": 238
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue