Skip to content

Commit

Permalink
[feat]: Equipment Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kamil-oberaj committed May 7, 2024
1 parent 1423948 commit fc91757
Show file tree
Hide file tree
Showing 29 changed files with 606 additions and 59 deletions.
5 changes: 0 additions & 5 deletions StudioManager.API.Contracts/Equipment/EquipmentReadDto.cs

This file was deleted.

5 changes: 5 additions & 0 deletions StudioManager.API.Contracts/Equipments/EquipmentReadDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using StudioManager.API.Contracts.EquipmentTypes;

namespace StudioManager.API.Contracts.Equipments;

public sealed record EquipmentReadDto(Guid Id, string Name, int Quantity, int InitialQuantity, string ImageUrl, EquipmentTypeReadDto EquipmentType);
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
namespace StudioManager.API.Contracts.Equipment;
namespace StudioManager.API.Contracts.Equipments;

public sealed record EquipmentWriteDto(string Name, Guid EquipmentTypeId, int Quantity/*, byte[] Image*/);
2 changes: 1 addition & 1 deletion StudioManager.API.Contracts/Pagination/PagingResultDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

public sealed class PagingResultDto<TData>
{
public IReadOnlyList<TData> Data { get; set; } = default!;
public List<TData> Data { get; set; } = default!;
public PaginationDetailsDto Pagination { get; set; } = default!;
}
2 changes: 1 addition & 1 deletion StudioManager.API/Controllers/V1/EquipmentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using MediatR;
using Microsoft.AspNetCore.Mvc;
using StudioManager.API.Base;
using StudioManager.API.Contracts.Equipment;
using StudioManager.API.Contracts.Equipments;
using StudioManager.API.Contracts.Pagination;
using StudioManager.Application.Equipments.Create;
using StudioManager.Application.Equipments.Delete;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,103 @@
using StudioManager.Tests.Common;
using FluentAssertions;
using NUnit.Framework;
using StudioManager.API.Contracts.Equipments;
using StudioManager.Application.Equipments.Create;
using StudioManager.Domain.Entities;
using StudioManager.Domain.ErrorMessages;
using StudioManager.Infrastructure;
using StudioManager.Tests.Common;
using StudioManager.Tests.Common.DbContextExtensions;

namespace StudioManager.Application.Tests.Equipments.CreateEquipmentCommandHandlerTests;

public class Handle : IntegrationTestBase
{
private static CreateEquipmentCommandHandler _testCandidate = null!;
private static TestDbContextFactory<StudioManagerDbContext> _testDbContextFactory = null!;

[SetUp]
public async Task SetUpAsync()
{
var connectionString = await DbMigrator.MigrateDbAsync();
_testDbContextFactory = new TestDbContextFactory<StudioManagerDbContext>(connectionString);
_testCandidate = new CreateEquipmentCommandHandler(_testDbContextFactory);
}

[Test]
public async Task should_return_error_when_equipment_type_does_not_exist_async()
{
// Arrange
var dto = new EquipmentWriteDto("Equipment-Test-Name", Guid.NewGuid(), 1);
var command = new CreateEquipmentCommand(dto);

// Act
var result = await _testCandidate.Handle(command, Cts.Token);

// Assert
result.Should().NotBeNull();
result.Succeeded.Should().BeFalse();
result.StatusCode.Should().Be(NotFoundStatusCode);
result.Data.Should().BeNull();
result.Error.Should().NotBeNullOrWhiteSpace();
result.Error.Should().Be($"[NOT FOUND] {nameof(EquipmentType)} with id '{dto.EquipmentTypeId}' does not exist");
}

[Test]
public async Task should_return_error_when_equipment_has_duplicated_name_and_type_async()
{
// Arrange

var equipmentType = EquipmentType.Create("Test-Equipment-Type");
var existing = Equipment.Create("Equipment-Test-Name", equipmentType.Id, 1);
await using (var dbContext = await _testDbContextFactory.CreateDbContextAsync(Cts.Token))
{
await AddEntitiesToTable(dbContext, equipmentType);
await AddEntitiesToTable(dbContext, existing);
}

var dto = new EquipmentWriteDto("Equipment-Test-Name", existing.EquipmentTypeId, 1);
var command = new CreateEquipmentCommand(dto);

// Act
var result = await _testCandidate.Handle(command, Cts.Token);

// Assert
result.Should().NotBeNull();
result.Succeeded.Should().BeFalse();
result.StatusCode.Should().Be(ConflictStatusCode);
result.Data.Should().BeNull();
result.Error.Should().NotBeNullOrWhiteSpace();
result.Error.Should().Be(string.Format(DB_FORMAT.EQUIPMENT_DUPLICATE_NAME_TYPE,
existing.Name, existing.EquipmentTypeId));
}

[Test]
public async Task should_return_success_async()
{
// Arrange

var equipmentType = EquipmentType.Create("Test-Equipment-Type");
await using (var dbContext = await _testDbContextFactory.CreateDbContextAsync(Cts.Token))
{
await ClearTableContentsForAsync<EquipmentType>(dbContext);
await ClearTableContentsForAsync<Equipment>(dbContext);
await AddEntitiesToTable(dbContext, equipmentType);
}

var dto = new EquipmentWriteDto("Equipment-Test-Name", equipmentType.Id, 1);
var command = new CreateEquipmentCommand(dto);

// Act
var result = await _testCandidate.Handle(command, Cts.Token);

// Assert
result.Should().NotBeNull();
result.Succeeded.Should().BeTrue();
result.StatusCode.Should().Be(OkStatusCode);
result.Data.Should().NotBeNull();
result.Error.Should().BeNullOrWhiteSpace();
var parseResult = Guid.TryParse(result.Data!.ToString(), out var guid);
parseResult.Should().BeTrue();
guid.Should().NotBeEmpty();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using FluentAssertions;
using NUnit.Framework;
using StudioManager.API.Contracts.Equipment;
using StudioManager.API.Contracts.Equipments;
using StudioManager.Application.Equipments.Create;
using StudioManager.Application.Equipments.Validators;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using FluentAssertions;
using NUnit.Framework;
using StudioManager.Application.Equipments.Delete;
using StudioManager.Domain.Common.Results;
using StudioManager.Domain.Entities;
using StudioManager.Domain.ErrorMessages;
using StudioManager.Infrastructure;
using StudioManager.Tests.Common;
using StudioManager.Tests.Common.DbContextExtensions;

namespace StudioManager.Application.Tests.Equipments.DeleteEquipmentCommandHandlerTests;

public sealed class Handle : IntegrationTestBase
{
private static DeleteEquipmentCommandHandler _testCandidate = null!;
private static TestDbContextFactory<StudioManagerDbContext> _testDbContextFactory = null!;


[SetUp]
public async Task SetUpAsync()
{
var connectionString = await DbMigrator.MigrateDbAsync();
_testDbContextFactory = new TestDbContextFactory<StudioManagerDbContext>(connectionString);
_testCandidate = new DeleteEquipmentCommandHandler(_testDbContextFactory);
}

[Test]
public async Task should_return_not_found_when_updating_non_existing_entity_async()
{
// Arrange
await using (var dbContext = await _testDbContextFactory.CreateDbContextAsync(Cts.Token))
{
await ClearTableContentsForAsync<Equipment>(dbContext);
}

var id = Guid.NewGuid();

var command = new DeleteEquipmentCommand(id);

// Act
var result = await _testCandidate.Handle(command, Cts.Token);

result.Should().NotBeNull();
result.Should().BeOfType<CommandResult>();
result.Data.Should().BeNull();
result.Succeeded.Should().BeFalse();
result.StatusCode.Should().Be(NotFoundStatusCode);
result.Error.Should().NotBeNullOrWhiteSpace();
result.Error.Should().Be($"[NOT FOUND] {nameof(Equipment)} with id '{id}' does not exist");
}

[Test]
public async Task should_return_error_when_initial_count_is_invalid_async()
{
// Arrange
var equipmentType = EquipmentType.Create("Test-Equipment-Type");
var equipment = Equipment.Create("Test-Equipment", equipmentType.Id, 10);
await using (var dbContext = await _testDbContextFactory.CreateDbContextAsync(Cts.Token))
{
await ClearTableContentsForAsync<EquipmentType>(dbContext);
await ClearTableContentsForAsync<Equipment>(dbContext);
await AddEntitiesToTable(dbContext, equipmentType);
await AddEntitiesToTable(dbContext, equipment);
equipment.Reserve(1);
dbContext.Equipments.Update(equipment);
await dbContext.SaveChangesAsync(Cts.Token);
}

var command = new DeleteEquipmentCommand(equipment.Id);

// Act
var result = await _testCandidate.Handle(command, Cts.Token);

result.Should().NotBeNull();
result.Should().BeOfType<CommandResult>();
result.Data.Should().BeNull();
result.Succeeded.Should().BeFalse();
result.StatusCode.Should().Be(ConflictStatusCode);
result.Error.Should().NotBeNullOrWhiteSpace();
result.Error.Should().Be(string.Format(DB_FORMAT.EQUIPMENT_QUANTITY_MISSING_WHEN_REMOVING,
equipment.InitialQuantity,
equipment.Quantity));
}

[Test]
public async Task should_return_success_async()
{
// Arrange
var equipmentType = EquipmentType.Create("Test-Equipment-Type");
var equipment = Equipment.Create("Test-Equipment", equipmentType.Id, 1);
await using (var dbContext = await _testDbContextFactory.CreateDbContextAsync(Cts.Token))
{
await ClearTableContentsForAsync<EquipmentType>(dbContext);
await ClearTableContentsForAsync<Equipment>(dbContext);
await AddEntitiesToTable(dbContext, equipmentType);
await AddEntitiesToTable(dbContext, equipment);
}

var command = new DeleteEquipmentCommand(equipment.Id);

// Act
var result = await _testCandidate.Handle(command, Cts.Token);

result.Should().NotBeNull();
result.Should().BeOfType<CommandResult>();
result.Data.Should().BeNull();
result.Succeeded.Should().BeTrue();
result.StatusCode.Should().Be(OkStatusCode);
result.Error.Should().BeNullOrWhiteSpace();

await using (var dbContext = await _testDbContextFactory.CreateDbContextAsync(Cts.Token))
{
var databaseCheck = await dbContext.Equipments.FindAsync(equipment.Id);
databaseCheck.Should().BeNull();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using FluentAssertions;
using NUnit.Framework;
using StudioManager.Application.Equipments.Delete;

namespace StudioManager.Application.Tests.Equipments.DeleteEquipmentCommandHandlerTests;

public sealed class Validator
{
[Test]
public async Task validator_should_return_validation_error_when_name_is_empty()
{
// Arrange
var command = new DeleteEquipmentCommand(Guid.Empty);
var validator = new DeleteEquipmentCommandValidator();

// Act
var result = await validator.ValidateAsync(command, CancellationToken.None);

// Assert
result.IsValid.Should().BeFalse();
result.Errors.Should().Contain(x => x.PropertyName == "Id" && x.ErrorMessage == "'Id' must not be empty.");
}

[Test]
public async Task validator_should_return_success_when_name_is_not_empty()
{
// Arrange
var command = new DeleteEquipmentCommand(Guid.NewGuid());
var validator = new DeleteEquipmentCommandValidator();

// Act
var result = await validator.ValidateAsync(command, CancellationToken.None);

// Assert
result.IsValid.Should().BeTrue();
result.Errors.Should().BeEmpty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using AutoMapper;
using FluentAssertions;
using NUnit.Framework;
using StudioManager.API.Contracts.Equipments;
using StudioManager.API.Contracts.Pagination;
using StudioManager.Application.Equipments.GetAll;
using StudioManager.Domain.Entities;
using StudioManager.Domain.Filters;
using StudioManager.Infrastructure;
using StudioManager.Tests.Common;
using StudioManager.Tests.Common.AutoMapperExtensions;
using StudioManager.Tests.Common.DbContextExtensions;

namespace StudioManager.Application.Tests.Equipments.GetAllEquipmentsQueryHandlerTests;

public sealed class Handle : IntegrationTestBase
{
private static GetAllEquipmentsQueryHandler _testCandidate = null!;
private static IMapper _mapper = null!;
private static TestDbContextFactory<StudioManagerDbContext> _testDbContextFactory = null!;

[SetUp]
public async Task SetUpAsync()
{
_mapper = MappingTestHelper.Mapper;
var connectionString = await DbMigrator.MigrateDbAsync();
_testDbContextFactory = new TestDbContextFactory<StudioManagerDbContext>(connectionString);
_testCandidate = new GetAllEquipmentsQueryHandler(_mapper, _testDbContextFactory);
}

[Test]
public async Task should_return_empty_data_with_pagination_async()
{
// Arrange
var query = new GetAllEquipmentsQuery(new EquipmentFilter(), PaginationDto.Default());

// Act
var result = await _testCandidate.Handle(query, CancellationToken.None);

// Assert
result.Should().NotBeNull();
result.Error.Should().BeNullOrWhiteSpace();
result.StatusCode.Should().Be(OkStatusCode);
result.Succeeded.Should().BeTrue();
result.Data.Should().NotBeNull();
result.Data.Should().BeOfType<PagingResultDto<EquipmentReadDto>>();
result.Data!.Data.Should().BeEmpty();
result.Data.Data.Should().BeOfType<List<EquipmentReadDto>>();
}

[Test]
public async Task should_return_mapped_data_with_pagination_async()
{
// Arrange
await using (var dbContext = await _testDbContextFactory.CreateDbContextAsync())
{
await ClearTableContentsForAsync<EquipmentType>(dbContext);
await ClearTableContentsForAsync<Equipment>(dbContext);
var equipmentType = EquipmentType.Create("Test-Equipment-Type");
await AddEntitiesToTable(dbContext, equipmentType);
var equipments = Enumerable.Range(0, 5)
.Select(x =>
Equipment.Create(x.ToString(), equipmentType.Id, x))
.ToArray();
await AddEntitiesToTable(dbContext, equipments);
}
var query = new GetAllEquipmentsQuery(new EquipmentFilter(), PaginationDto.Default());

// Act
var result = await _testCandidate.Handle(query, CancellationToken.None);

// Assert
result.Should().NotBeNull();
result.Error.Should().BeNullOrWhiteSpace();
result.StatusCode.Should().Be(OkStatusCode);
result.Succeeded.Should().BeTrue();
result.Data.Should().NotBeNull();
result.Data.Should().BeOfType<PagingResultDto<EquipmentReadDto>>();
result.Data!.Pagination.Should().NotBeNull();
result.Data.Pagination.Limit.Should().Be(25);
result.Data.Pagination.Page.Should().Be(1);
result.Data.Pagination.Total.Should().Be(5);
result.Data.Data.Should().NotBeEmpty();
result.Data.Data.Should().HaveCount(5);
result.Data.Data.Should().BeOfType<List<EquipmentReadDto>>();
}
}
Loading

0 comments on commit fc91757

Please sign in to comment.