Wrote tests for most services, applied EF core optimisations
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using LiteCharms.Features.MidrandBooks.Abstractions;
|
||||
using LiteCharms.Features.MidrandBooks.AuthorBooks.Models;
|
||||
using LiteCharms.Features.MidrandBooks.Authors.Models;
|
||||
using LiteCharms.Features.MidrandBooks.Extensions;
|
||||
using LiteCharms.Features.MidrandBooks.Postgres;
|
||||
@@ -9,53 +8,21 @@ namespace LiteCharms.Features.MidrandBooks.Authors;
|
||||
|
||||
public sealed class AuthorService(IDbContextFactory<MidrandBooksDbContext> contextFactory) : IService
|
||||
{
|
||||
public async ValueTask<Result<AuthorBook[]>> GetAuthorBooksAsync(long authorId, CancellationToken cancellationToken)
|
||||
public async ValueTask<Result> UpdateAuthorStatusAsync(long authorId, bool isEnabled, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var author = await context.Authors.FirstOrDefaultAsync(a => a.Id == authorId, cancellationToken);
|
||||
var rowsUpdated = await context.Authors
|
||||
.Where(a => a.Id == authorId)
|
||||
.ExecuteUpdateAsync(setters => setters
|
||||
.SetProperty(a => a.Enabled, isEnabled)
|
||||
.SetProperty(a => a.UpdatedAt, DateTime.UtcNow), cancellationToken);
|
||||
|
||||
if (author is null)
|
||||
return Result.Fail<AuthorBook[]>(new Error($"Author with ID {authorId} not found"));
|
||||
|
||||
var books = await context.Books
|
||||
.AsNoTracking()
|
||||
.Include(b => b.Author)
|
||||
.Include(b => b.Product!.Price)
|
||||
.OrderByDescending(b => b.CreatedAt)
|
||||
.Where(p => p.AuthorId == authorId)
|
||||
.AsSplitQuery()
|
||||
.ToArrayAsync(cancellationToken);
|
||||
|
||||
return books?.Length > 0
|
||||
? Result.Ok(books.Select(b => b.ToModel()).ToArray())
|
||||
: Result.Fail<AuthorBook[]>(new Error($"No books found for author with ID {authorId}"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail<AuthorBook[]>(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result> UpdateAuthorStatusAsync(long authorId, bool isEnabled, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var author = await context.Authors.FirstOrDefaultAsync(a => a.Id == authorId, cancellationToken);
|
||||
|
||||
if (author is null)
|
||||
return Result.Fail(new Error($"Author with ID {authorId} not found"));
|
||||
|
||||
author.UpdatedAt = DateTime.UtcNow;
|
||||
author.Enabled = isEnabled;
|
||||
|
||||
return await context.SaveChangesAsync(cancellationToken) > 0
|
||||
return rowsUpdated > 0
|
||||
? Result.Ok()
|
||||
: Result.Fail(new Error($"Failed to change status of author with ID {authorId}"));
|
||||
: Result.Fail(new Error($"Author with ID {authorId} not found"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -81,12 +48,12 @@ public sealed class AuthorService(IDbContextFactory<MidrandBooksDbContext> conte
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result<Author[]>> GetAuthors(DateRange range, CancellationToken cancellationToken)
|
||||
public async ValueTask<Result<Author[]>> GetAuthorsAsync(DateRange range, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fromDate = range.From.ToDateTime(TimeOnly.MinValue);
|
||||
var toDate = range.To.ToDateTime(TimeOnly.MaxValue);
|
||||
var fromDate = range.From.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
|
||||
var toDate = range.To.ToDateTime(TimeOnly.MaxValue, DateTimeKind.Utc);
|
||||
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
@@ -107,18 +74,12 @@ public sealed class AuthorService(IDbContextFactory<MidrandBooksDbContext> conte
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result> UpdateAuthorAsync(long authorId, UpdateAuthor request, CancellationToken cancellationToken)
|
||||
public async ValueTask<Result> UpdateAuthorAsync(long authorId, UpdateAuthor request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
if (await context.Authors.AnyAsync(a => a.Name == request.Name && a.LastName == request.LastName, cancellationToken))
|
||||
return Result.Fail(new Error($"An author with the name {request.Name} {request.LastName} already exists"));
|
||||
|
||||
if (await context.Authors.AnyAsync(a => a.Email == request.Email, cancellationToken))
|
||||
return Result.Fail(new Error($"An author with the email {request.Email} already exists"));
|
||||
|
||||
var author = await context.Authors.FirstOrDefaultAsync(a => a.Id == authorId, cancellationToken);
|
||||
|
||||
if (author is null)
|
||||
@@ -151,12 +112,12 @@ public sealed class AuthorService(IDbContextFactory<MidrandBooksDbContext> conte
|
||||
{
|
||||
try
|
||||
{
|
||||
using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
if(await context.Authors.AnyAsync(a => a.Name == request.Name && a.LastName == request.LastName, cancellationToken))
|
||||
if (await context.Authors.AnyAsync(a => a.Name == request.Name && a.LastName == request.LastName, cancellationToken))
|
||||
return Result.Fail<long>(new Error($"An author with the name {request.Name} {request.LastName} already exists"));
|
||||
|
||||
if(await context.Authors.AnyAsync(a => a.Email == request.Email, cancellationToken))
|
||||
if (await context.Authors.AnyAsync(a => a.Email == request.Email, cancellationToken))
|
||||
return Result.Fail<long>(new Error($"An author with the email {request.Email} already exists"));
|
||||
|
||||
var newAuthor = context.Authors.Add(new Entities.Author
|
||||
|
||||
@@ -30,7 +30,7 @@ public class Author
|
||||
|
||||
public string? ThumbnailImageUrl { get; set; }
|
||||
|
||||
public SocialMedia[]? SocialMedia { get; set; }
|
||||
public ICollection<SocialMedia>? SocialMedia { get; set; }
|
||||
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user