Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Application/Common/Models/Dtos/Physical/RoomDto.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ public class RoomDto : IMapFrom<Room>
public string Name { get; set; } = null!;
public string? Description { get; set; }
public StaffDto? Staff { get; set; }
public DepartmentDto? Department { get; set; }
public DepartmentDto Department { get; set; }
public int Capacity { get; set; }
public int NumberOfLockers { get; set; }
public bool IsAvailable { get; set; }
Expand Down
47 changes: 47 additions & 0 deletions src/Application/Rooms/Commands/EnableRoom.cs
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,59 @@
using Application.Common.Exceptions;
using Application.Common.Interfaces;
using Application.Common.Models.Dtos.Physical;
using AutoMapper;
using FluentValidation;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Application.Rooms.Commands;

public class EnableRoom
{
public class Validator : AbstractValidator<RemoveRoom.Command>
{
public Validator()
{
RuleLevelCascadeMode = CascadeMode.Stop;
RuleFor(x => x.RoomId)
.NotEmpty().WithMessage("RoomId is required.");
}
}
public record Command : IRequest<RoomDto>
{
public Guid RoomId { get; init; }
}

public class CommandHandler : IRequestHandler<Command, RoomDto>
{
private readonly IApplicationDbContext _context;
private readonly IMapper _mapper;

public CommandHandler(IApplicationDbContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}

public async Task<RoomDto> Handle(Command request, CancellationToken cancellationToken)
{
var room = await _context.Rooms
.FirstOrDefaultAsync(x => x.Id.Equals(request.RoomId), cancellationToken: cancellationToken);

if (room is null)
{
throw new KeyNotFoundException("Room does not exist.");
}

if (room.IsAvailable)
{
throw new ConflictException("Room has already been enabled.");
}

room.IsAvailable = true;
var result = _context.Rooms.Update(room);
await _context.SaveChangesAsync(cancellationToken);
return _mapper.Map<RoomDto>(result.Entity);
}
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
using Application.Common.Exceptions;
using Application.Rooms.Commands;
using Domain.Entities;
using Domain.Entities.Physical;
using FluentAssertions;
using Xunit;

namespace Application.Tests.Integration.Rooms.Commands;

public class EnableRoomTests : BaseClassFixture
{
public EnableRoomTests(CustomApiFactory apiFactory) : base(apiFactory)
{
}

[Fact]
public async Task ShouldEnableRoom_WhenRoomExistsAndIsDisabled()
{
// Arrange
var department = CreateDepartment();
var folder = CreateFolder();
var locker = CreateLocker(folder);
var room = CreateRoom(department, locker);
folder.IsAvailable = false;
locker.IsAvailable = false;
room.IsAvailable = false;
await AddAsync(room);

var command = new EnableRoom.Command()
{
RoomId = room.Id
};

// Act
var result = await SendAsync(command);

// Assert
var folderResult = await FindAsync<Folder>(folder.Id);
var lockerResult = await FindAsync<Locker>(locker.Id);

result.IsAvailable.Should().BeTrue();
folderResult!.IsAvailable.Should().BeFalse();
lockerResult!.IsAvailable.Should().BeFalse();

// Cleanup
Remove(folder);
Remove(locker);
Remove(room);
Remove(await FindAsync<Department>(department.Id));
}

[Fact]
public async Task ShouldThrowKeyNotFoundException_WhenRoomDoesNotExist()
{
// Arrange
var command = new EnableRoom.Command()
{
RoomId = Guid.NewGuid()
};

// Act
var action = async () => await SendAsync(command);

// Assert
await action.Should().ThrowAsync<KeyNotFoundException>()
.WithMessage("Room does not exist.");
}

[Fact]
public async Task ShouldThrowConflictException_WhenRoomIsAlreadyAvailable()
{
// Arrange
var department = CreateDepartment();
var room = CreateRoom(department);
room.IsAvailable = true;
await AddAsync(room);

var command = new EnableRoom.Command()
{
RoomId = room.Id
};

// Act
var action = async () => await SendAsync(command);

// Assert
await action.Should().ThrowAsync<ConflictException>()
.WithMessage("Room has already been enabled.");

// Cleanup
Remove(room);
Remove(await FindAsync<Department>(department.Id));
}
}