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
21 changes: 21 additions & 0 deletions src/Api/Controllers/StaffsController.cs
Original file line numberDiff line numberDiff line change
Expand Up@@ -112,4 +112,25 @@ public async Task<ActionResult<Result<StaffDto>>> RemoveFromRoom(
var result = await Mediator.Send(command);
return Ok(Result<StaffDto>.Succeed(result));
}

/// <summary>
/// Remove a staff
/// </summary>
/// <param name="staffId">Id of the staff to be removed</param>
/// <returns>A StaffDto of the removed staff</returns>
[HttpDelete("{staffId:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<Result<StaffDto>>> Remove(
[FromRoute] Guid staffId)
{
var command = new RemoveStaff.Command()
{
StaffId = staffId
};

var result = await Mediator.Send(command);
return Ok(Result<StaffDto>.Succeed(result));
}
}
45 changes: 45 additions & 0 deletions src/Application/Staffs/Commands/RemoveStaff.cs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
using Application.Common.Interfaces;
using Application.Common.Models.Dtos.Physical;
using AutoMapper;
using FluentValidation;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Application.Staffs.Commands;

public class RemoveStaff
{
public record Command : IRequest<StaffDto>
{
public Guid StaffId { get; init; }
}

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

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

public async Task<StaffDto> Handle(Command request, CancellationToken cancellationToken)
{
var staff = await _context.Staffs
.Include(x => x.User)
.Include(x => x.Room)
.FirstOrDefaultAsync(x => x.User.Id.Equals(request.StaffId), cancellationToken: cancellationToken);

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

var result = _context.Staffs.Remove(staff);
await _context.SaveChangesAsync(cancellationToken);
return _mapper.Map<StaffDto>(result.Entity);
}
}
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
using Application.Identity;
using Application.Staffs.Commands;
using Domain.Entities;
using Domain.Entities.Physical;
using FluentAssertions;
using Xunit;

namespace Application.Tests.Integration.Staffs.Commands;

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

[Fact]
public async Task ShouldRemoveStaff_WhenStaffIdIsValid()
{
// Arrange
var department = CreateDepartment();
var user = CreateUser(IdentityData.Roles.Admin, "123456");
var room = CreateRoom(department);
var staff = CreateStaff(user, room);
await AddAsync(staff);

var command = new RemoveStaff.Command()
{
StaffId = staff.Id
};

// Act
await SendAsync(command);

// Assert
var result = await FindAsync<Staff>(staff.Id);
result.Should().BeNull();

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

[Fact]
public async Task ShouldThrowKeyNotFoundException_WhenStaffDoesNotExist()
{
// Arrange
var command = new RemoveStaff.Command()
{
StaffId = Guid.NewGuid()
};

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

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