In progress
This commit is contained in:
@@ -22,6 +22,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\ColaFlow.Application\ColaFlow.Application.csproj" />
|
||||
<ProjectReference Include="..\..\src\Modules\ProjectManagement\ColaFlow.Modules.ProjectManagement.Application\ColaFlow.Modules.ProjectManagement.Application.csproj" />
|
||||
<ProjectReference Include="..\..\src\Modules\ProjectManagement\ColaFlow.Modules.ProjectManagement.Domain\ColaFlow.Modules.ProjectManagement.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.Commands.AssignStory;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
|
||||
|
||||
namespace ColaFlow.Application.Tests.Commands.AssignStory;
|
||||
|
||||
public class AssignStoryCommandHandlerTests
|
||||
{
|
||||
private readonly Mock<IProjectRepository> _projectRepositoryMock;
|
||||
private readonly Mock<IUnitOfWork> _unitOfWorkMock;
|
||||
private readonly AssignStoryCommandHandler _handler;
|
||||
|
||||
public AssignStoryCommandHandlerTests()
|
||||
{
|
||||
_projectRepositoryMock = new Mock<IProjectRepository>();
|
||||
_unitOfWorkMock = new Mock<IUnitOfWork>();
|
||||
_handler = new AssignStoryCommandHandler(_projectRepositoryMock.Object, _unitOfWorkMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Assign_Story_Successfully()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var assigneeId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Description", TaskPriority.Medium, userId);
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(story.Id, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new AssignStoryCommand
|
||||
{
|
||||
StoryId = story.Id.Value,
|
||||
AssigneeId = assigneeId.Value
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.AssigneeId.Should().Be(assigneeId.Value);
|
||||
story.AssigneeId.Should().Be(assigneeId);
|
||||
|
||||
_projectRepositoryMock.Verify(x => x.Update(project), Times.Once);
|
||||
_unitOfWorkMock.Verify(x => x.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Fail_When_Story_Not_Found()
|
||||
{
|
||||
// Arrange
|
||||
var storyId = StoryId.Create();
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(storyId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((Project?)null);
|
||||
|
||||
var command = new AssignStoryCommand
|
||||
{
|
||||
StoryId = storyId.Value,
|
||||
AssigneeId = Guid.NewGuid()
|
||||
};
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<NotFoundException>()
|
||||
.WithMessage("*Story*");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Reassign_Story_To_Different_User()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var firstAssignee = UserId.Create();
|
||||
var secondAssignee = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Description", TaskPriority.Medium, userId);
|
||||
|
||||
// First assign
|
||||
story.AssignTo(firstAssignee);
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(story.Id, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new AssignStoryCommand
|
||||
{
|
||||
StoryId = story.Id.Value,
|
||||
AssigneeId = secondAssignee.Value
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.AssigneeId.Should().Be(secondAssignee.Value);
|
||||
story.AssigneeId.Should().Be(secondAssignee);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.Commands.CreateStory;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
|
||||
|
||||
namespace ColaFlow.Application.Tests.Commands.CreateStory;
|
||||
|
||||
public class CreateStoryCommandHandlerTests
|
||||
{
|
||||
private readonly Mock<IProjectRepository> _projectRepositoryMock;
|
||||
private readonly Mock<IUnitOfWork> _unitOfWorkMock;
|
||||
private readonly CreateStoryCommandHandler _handler;
|
||||
|
||||
public CreateStoryCommandHandlerTests()
|
||||
{
|
||||
_projectRepositoryMock = new Mock<IProjectRepository>();
|
||||
_unitOfWorkMock = new Mock<IUnitOfWork>();
|
||||
_handler = new CreateStoryCommandHandler(_projectRepositoryMock.Object, _unitOfWorkMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Create_Story_Successfully()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var epicId = epic.Id;
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithEpicAsync(epicId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new CreateStoryCommand
|
||||
{
|
||||
EpicId = epicId.Value,
|
||||
Title = "New Story",
|
||||
Description = "Story Description",
|
||||
Priority = "High",
|
||||
EstimatedHours = 8,
|
||||
AssigneeId = userId.Value,
|
||||
CreatedBy = userId.Value
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Title.Should().Be("New Story");
|
||||
result.Description.Should().Be("Story Description");
|
||||
result.EpicId.Should().Be(epicId.Value);
|
||||
result.Status.Should().Be("To Do");
|
||||
result.Priority.Should().Be("High");
|
||||
result.EstimatedHours.Should().Be(8);
|
||||
result.AssigneeId.Should().Be(userId.Value);
|
||||
|
||||
epic.Stories.Should().ContainSingle();
|
||||
_projectRepositoryMock.Verify(x => x.Update(project), Times.Once);
|
||||
_unitOfWorkMock.Verify(x => x.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Fail_When_Epic_Not_Found()
|
||||
{
|
||||
// Arrange
|
||||
var epicId = EpicId.Create();
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithEpicAsync(epicId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((Project?)null);
|
||||
|
||||
var command = new CreateStoryCommand
|
||||
{
|
||||
EpicId = epicId.Value,
|
||||
Title = "New Story",
|
||||
Description = "Description",
|
||||
Priority = "Medium",
|
||||
CreatedBy = Guid.NewGuid()
|
||||
};
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<NotFoundException>()
|
||||
.WithMessage("*Epic*");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Set_Default_Status_To_ToDo()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithEpicAsync(epic.Id, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new CreateStoryCommand
|
||||
{
|
||||
EpicId = epic.Id.Value,
|
||||
Title = "New Story",
|
||||
Description = "Description",
|
||||
Priority = "Low",
|
||||
CreatedBy = userId.Value
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Status.Should().Be("To Do");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.Commands.CreateTask;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
|
||||
|
||||
namespace ColaFlow.Application.Tests.Commands.CreateTask;
|
||||
|
||||
public class CreateTaskCommandHandlerTests
|
||||
{
|
||||
private readonly Mock<IProjectRepository> _projectRepositoryMock;
|
||||
private readonly Mock<IUnitOfWork> _unitOfWorkMock;
|
||||
private readonly CreateTaskCommandHandler _handler;
|
||||
|
||||
public CreateTaskCommandHandlerTests()
|
||||
{
|
||||
_projectRepositoryMock = new Mock<IProjectRepository>();
|
||||
_unitOfWorkMock = new Mock<IUnitOfWork>();
|
||||
_handler = new CreateTaskCommandHandler(_projectRepositoryMock.Object, _unitOfWorkMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Create_Task_Successfully()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var storyId = story.Id;
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(storyId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new CreateTaskCommand
|
||||
{
|
||||
StoryId = storyId.Value,
|
||||
Title = "New Task",
|
||||
Description = "Task Description",
|
||||
Priority = "High",
|
||||
EstimatedHours = 4,
|
||||
AssigneeId = userId.Value,
|
||||
CreatedBy = userId.Value
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Title.Should().Be("New Task");
|
||||
result.Description.Should().Be("Task Description");
|
||||
result.StoryId.Should().Be(storyId.Value);
|
||||
result.Status.Should().Be("To Do");
|
||||
result.Priority.Should().Be("High");
|
||||
result.EstimatedHours.Should().Be(4);
|
||||
result.AssigneeId.Should().Be(userId.Value);
|
||||
|
||||
story.Tasks.Should().ContainSingle();
|
||||
_projectRepositoryMock.Verify(x => x.Update(project), Times.Once);
|
||||
_unitOfWorkMock.Verify(x => x.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Fail_When_Story_Not_Found()
|
||||
{
|
||||
// Arrange
|
||||
var storyId = StoryId.Create();
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(storyId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((Project?)null);
|
||||
|
||||
var command = new CreateTaskCommand
|
||||
{
|
||||
StoryId = storyId.Value,
|
||||
Title = "New Task",
|
||||
Description = "Description",
|
||||
Priority = "Medium",
|
||||
CreatedBy = Guid.NewGuid()
|
||||
};
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<NotFoundException>()
|
||||
.WithMessage("*Story*");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Set_Default_Status_To_ToDo()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(story.Id, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new CreateTaskCommand
|
||||
{
|
||||
StoryId = story.Id.Value,
|
||||
Title = "New Task",
|
||||
Description = "Description",
|
||||
Priority = "Low",
|
||||
CreatedBy = userId.Value
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Status.Should().Be("To Do");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.Commands.DeleteStory;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
|
||||
|
||||
namespace ColaFlow.Application.Tests.Commands.DeleteStory;
|
||||
|
||||
public class DeleteStoryCommandHandlerTests
|
||||
{
|
||||
private readonly Mock<IProjectRepository> _projectRepositoryMock;
|
||||
private readonly Mock<IUnitOfWork> _unitOfWorkMock;
|
||||
private readonly DeleteStoryCommandHandler _handler;
|
||||
|
||||
public DeleteStoryCommandHandlerTests()
|
||||
{
|
||||
_projectRepositoryMock = new Mock<IProjectRepository>();
|
||||
_unitOfWorkMock = new Mock<IUnitOfWork>();
|
||||
_handler = new DeleteStoryCommandHandler(_projectRepositoryMock.Object, _unitOfWorkMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Delete_Story_Successfully()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Story to Delete", "Description", TaskPriority.Medium, userId);
|
||||
var storyId = story.Id;
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(storyId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new DeleteStoryCommand { StoryId = storyId.Value };
|
||||
|
||||
// Act
|
||||
await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
epic.Stories.Should().BeEmpty();
|
||||
_projectRepositoryMock.Verify(x => x.Update(project), Times.Once);
|
||||
_unitOfWorkMock.Verify(x => x.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Fail_When_Story_Not_Found()
|
||||
{
|
||||
// Arrange
|
||||
var storyId = StoryId.Create();
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(storyId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((Project?)null);
|
||||
|
||||
var command = new DeleteStoryCommand { StoryId = storyId.Value };
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<NotFoundException>()
|
||||
.WithMessage("*Story*");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Fail_When_Story_Has_Tasks()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Story with Tasks", "Description", TaskPriority.Medium, userId);
|
||||
|
||||
// Add a task to the story
|
||||
story.CreateTask("Task 1", "Task Description", TaskPriority.High, userId);
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(story.Id, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new DeleteStoryCommand { StoryId = story.Id.Value };
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<DomainException>()
|
||||
.WithMessage("*cannot delete*story*tasks*");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.Commands.DeleteTask;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
|
||||
|
||||
namespace ColaFlow.Application.Tests.Commands.DeleteTask;
|
||||
|
||||
public class DeleteTaskCommandHandlerTests
|
||||
{
|
||||
private readonly Mock<IProjectRepository> _projectRepositoryMock;
|
||||
private readonly Mock<IUnitOfWork> _unitOfWorkMock;
|
||||
private readonly DeleteTaskCommandHandler _handler;
|
||||
|
||||
public DeleteTaskCommandHandlerTests()
|
||||
{
|
||||
_projectRepositoryMock = new Mock<IProjectRepository>();
|
||||
_unitOfWorkMock = new Mock<IUnitOfWork>();
|
||||
_handler = new DeleteTaskCommandHandler(_projectRepositoryMock.Object, _unitOfWorkMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Delete_Task_Successfully()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var task = story.CreateTask("Task to Delete", "Description", TaskPriority.Medium, userId);
|
||||
var taskId = task.Id;
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new DeleteTaskCommand { TaskId = taskId.Value };
|
||||
|
||||
// Act
|
||||
await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
story.Tasks.Should().BeEmpty();
|
||||
_projectRepositoryMock.Verify(x => x.Update(project), Times.Once);
|
||||
_unitOfWorkMock.Verify(x => x.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Fail_When_Task_Not_Found()
|
||||
{
|
||||
// Arrange
|
||||
var taskId = TaskId.Create();
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((Project?)null);
|
||||
|
||||
var command = new DeleteTaskCommand { TaskId = taskId.Value };
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<NotFoundException>()
|
||||
.WithMessage("*Task*");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.Commands.UpdateStory;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
|
||||
|
||||
namespace ColaFlow.Application.Tests.Commands.UpdateStory;
|
||||
|
||||
public class UpdateStoryCommandHandlerTests
|
||||
{
|
||||
private readonly Mock<IProjectRepository> _projectRepositoryMock;
|
||||
private readonly Mock<IUnitOfWork> _unitOfWorkMock;
|
||||
private readonly UpdateStoryCommandHandler _handler;
|
||||
|
||||
public UpdateStoryCommandHandlerTests()
|
||||
{
|
||||
_projectRepositoryMock = new Mock<IProjectRepository>();
|
||||
_unitOfWorkMock = new Mock<IUnitOfWork>();
|
||||
_handler = new UpdateStoryCommandHandler(_projectRepositoryMock.Object, _unitOfWorkMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Update_Story_Successfully()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Original Title", "Original Description", TaskPriority.Low, userId);
|
||||
var storyId = story.Id;
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(storyId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new UpdateStoryCommand
|
||||
{
|
||||
StoryId = storyId.Value,
|
||||
Title = "Updated Title",
|
||||
Description = "Updated Description",
|
||||
Status = "In Progress",
|
||||
Priority = "High",
|
||||
EstimatedHours = 16
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Title.Should().Be("Updated Title");
|
||||
result.Description.Should().Be("Updated Description");
|
||||
result.Status.Should().Be("In Progress");
|
||||
result.Priority.Should().Be("High");
|
||||
result.EstimatedHours.Should().Be(16);
|
||||
|
||||
_projectRepositoryMock.Verify(x => x.Update(project), Times.Once);
|
||||
_unitOfWorkMock.Verify(x => x.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Fail_When_Story_Not_Found()
|
||||
{
|
||||
// Arrange
|
||||
var storyId = StoryId.Create();
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(storyId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((Project?)null);
|
||||
|
||||
var command = new UpdateStoryCommand
|
||||
{
|
||||
StoryId = storyId.Value,
|
||||
Title = "Updated Title",
|
||||
Description = "Updated Description"
|
||||
};
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<NotFoundException>()
|
||||
.WithMessage("*Story*");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Update_All_Fields_Correctly()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Original", "Original", TaskPriority.Low, userId);
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(story.Id, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new UpdateStoryCommand
|
||||
{
|
||||
StoryId = story.Id.Value,
|
||||
Title = "New Title",
|
||||
Description = "New Description",
|
||||
Status = "Done",
|
||||
Priority = "Urgent",
|
||||
EstimatedHours = 24
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
story.Title.Should().Be("New Title");
|
||||
story.Description.Should().Be("New Description");
|
||||
story.Status.Should().Be(WorkItemStatus.Done);
|
||||
story.Priority.Should().Be(TaskPriority.Urgent);
|
||||
story.EstimatedHours.Should().Be(24);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.Commands.UpdateTaskStatus;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
|
||||
|
||||
namespace ColaFlow.Application.Tests.Commands.UpdateTaskStatus;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for UpdateTaskStatusCommandHandler
|
||||
/// </summary>
|
||||
public class UpdateTaskStatusCommandHandlerTests
|
||||
{
|
||||
private readonly Mock<IProjectRepository> _projectRepositoryMock;
|
||||
private readonly Mock<IUnitOfWork> _unitOfWorkMock;
|
||||
private readonly UpdateTaskStatusCommandHandler _handler;
|
||||
|
||||
public UpdateTaskStatusCommandHandlerTests()
|
||||
{
|
||||
_projectRepositoryMock = new Mock<IProjectRepository>();
|
||||
_unitOfWorkMock = new Mock<IUnitOfWork>();
|
||||
_handler = new UpdateTaskStatusCommandHandler(_projectRepositoryMock.Object, _unitOfWorkMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Update_Task_Status_To_InProgress_Successfully()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Test Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var task = story.CreateTask("Test Task", "Task Description", TaskPriority.Medium, userId);
|
||||
var taskId = task.Id;
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new UpdateTaskStatusCommand
|
||||
{
|
||||
TaskId = taskId.Value,
|
||||
NewStatus = "In Progress" // Display name with space
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Id.Should().Be(taskId.Value);
|
||||
result.Status.Should().Be("In Progress");
|
||||
task.Status.Should().Be(WorkItemStatus.InProgress);
|
||||
|
||||
_projectRepositoryMock.Verify(x => x.Update(project), Times.Once);
|
||||
_unitOfWorkMock.Verify(x => x.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Update_Task_Status_To_InProgress_With_CodeName_Successfully()
|
||||
{
|
||||
// Arrange - This tests the bug fix for accepting "InProgress" (without space)
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Test Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var task = story.CreateTask("Test Task", "Task Description", TaskPriority.Medium, userId);
|
||||
var taskId = task.Id;
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new UpdateTaskStatusCommand
|
||||
{
|
||||
TaskId = taskId.Value,
|
||||
NewStatus = "InProgress" // Code name without space (this was causing the bug)
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Id.Should().Be(taskId.Value);
|
||||
result.Status.Should().Be("In Progress");
|
||||
task.Status.Should().Be(WorkItemStatus.InProgress);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Update_Task_Status_To_Done_Successfully()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Test Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var task = story.CreateTask("Test Task", "Task Description", TaskPriority.Medium, userId);
|
||||
var taskId = task.Id;
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new UpdateTaskStatusCommand
|
||||
{
|
||||
TaskId = taskId.Value,
|
||||
NewStatus = "Done"
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Status.Should().Be("Done");
|
||||
task.Status.Should().Be(WorkItemStatus.Done);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Update_Task_Status_To_Blocked_Successfully()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Test Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var task = story.CreateTask("Test Task", "Task Description", TaskPriority.Medium, userId);
|
||||
var taskId = task.Id;
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new UpdateTaskStatusCommand
|
||||
{
|
||||
TaskId = taskId.Value,
|
||||
NewStatus = "Blocked"
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Status.Should().Be("Blocked");
|
||||
task.Status.Should().Be(WorkItemStatus.Blocked);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Update_Task_Status_To_InReview_Successfully()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Test Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var task = story.CreateTask("Test Task", "Task Description", TaskPriority.Medium, userId);
|
||||
var taskId = task.Id;
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new UpdateTaskStatusCommand
|
||||
{
|
||||
TaskId = taskId.Value,
|
||||
NewStatus = "In Review"
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Status.Should().Be("In Review");
|
||||
task.Status.Should().Be(WorkItemStatus.InReview);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Throw_NotFoundException_When_Task_Not_Found()
|
||||
{
|
||||
// Arrange
|
||||
var taskId = TaskId.Create();
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((Project?)null);
|
||||
|
||||
var command = new UpdateTaskStatusCommand
|
||||
{
|
||||
TaskId = taskId.Value,
|
||||
NewStatus = "In Progress"
|
||||
};
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<NotFoundException>()
|
||||
.WithMessage("*Task*");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Throw_Exception_When_Moving_Done_To_ToDo()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Test Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var task = story.CreateTask("Test Task", "Task Description", TaskPriority.Medium, userId);
|
||||
var taskId = task.Id;
|
||||
|
||||
// First set task to Done
|
||||
task.UpdateStatus(WorkItemStatus.Done);
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new UpdateTaskStatusCommand
|
||||
{
|
||||
TaskId = taskId.Value,
|
||||
NewStatus = "To Do"
|
||||
};
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<DomainException>()
|
||||
.WithMessage("*Cannot move a completed task back to ToDo*");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Allow_Blocked_To_Any_Status()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Test Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var task = story.CreateTask("Test Task", "Task Description", TaskPriority.Medium, userId);
|
||||
var taskId = task.Id;
|
||||
|
||||
// Set task to Blocked
|
||||
task.UpdateStatus(WorkItemStatus.Blocked);
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new UpdateTaskStatusCommand
|
||||
{
|
||||
TaskId = taskId.Value,
|
||||
NewStatus = "In Progress"
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Status.Should().Be("In Progress");
|
||||
task.Status.Should().Be(WorkItemStatus.InProgress);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Allow_Any_Status_To_Blocked()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Test Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var task = story.CreateTask("Test Task", "Task Description", TaskPriority.Medium, userId);
|
||||
var taskId = task.Id;
|
||||
|
||||
// Task starts as ToDo
|
||||
task.Status.Should().Be(WorkItemStatus.ToDo);
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new UpdateTaskStatusCommand
|
||||
{
|
||||
TaskId = taskId.Value,
|
||||
NewStatus = "Blocked"
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Status.Should().Be("Blocked");
|
||||
task.Status.Should().Be(WorkItemStatus.Blocked);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Throw_Exception_For_Invalid_Status()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Test Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var task = story.CreateTask("Test Task", "Task Description", TaskPriority.Medium, userId);
|
||||
var taskId = task.Id;
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var command = new UpdateTaskStatusCommand
|
||||
{
|
||||
TaskId = taskId.Value,
|
||||
NewStatus = "InvalidStatus"
|
||||
};
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(command, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<InvalidOperationException>()
|
||||
.WithMessage("*InvalidStatus*");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.Queries.GetStoryById;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
|
||||
|
||||
namespace ColaFlow.Application.Tests.Queries.GetStoryById;
|
||||
|
||||
public class GetStoryByIdQueryHandlerTests
|
||||
{
|
||||
private readonly Mock<IProjectRepository> _projectRepositoryMock;
|
||||
private readonly GetStoryByIdQueryHandler _handler;
|
||||
|
||||
public GetStoryByIdQueryHandlerTests()
|
||||
{
|
||||
_projectRepositoryMock = new Mock<IProjectRepository>();
|
||||
_handler = new GetStoryByIdQueryHandler(_projectRepositoryMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Return_Story_With_Tasks()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.High, userId);
|
||||
var task1 = story.CreateTask("Task 1", "Description 1", TaskPriority.Medium, userId);
|
||||
var task2 = story.CreateTask("Task 2", "Description 2", TaskPriority.Low, userId);
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(story.Id, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var query = new GetStoryByIdQuery(story.Id.Value);
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(query, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Id.Should().Be(story.Id.Value);
|
||||
result.Title.Should().Be("Test Story");
|
||||
result.Description.Should().Be("Story Description");
|
||||
result.Priority.Should().Be("High");
|
||||
result.Tasks.Should().HaveCount(2);
|
||||
result.Tasks.Should().Contain(t => t.Id == task1.Id.Value);
|
||||
result.Tasks.Should().Contain(t => t.Id == task2.Id.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Fail_When_Story_Not_Found()
|
||||
{
|
||||
// Arrange
|
||||
var storyId = StoryId.Create();
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithStoryAsync(storyId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((Project?)null);
|
||||
|
||||
var query = new GetStoryByIdQuery(storyId.Value);
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(query, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<NotFoundException>()
|
||||
.WithMessage("*Story*");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using ColaFlow.Modules.ProjectManagement.Application.Queries.GetTaskById;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
|
||||
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;
|
||||
|
||||
namespace ColaFlow.Application.Tests.Queries.GetTaskById;
|
||||
|
||||
public class GetTaskByIdQueryHandlerTests
|
||||
{
|
||||
private readonly Mock<IProjectRepository> _projectRepositoryMock;
|
||||
private readonly GetTaskByIdQueryHandler _handler;
|
||||
|
||||
public GetTaskByIdQueryHandlerTests()
|
||||
{
|
||||
_projectRepositoryMock = new Mock<IProjectRepository>();
|
||||
_handler = new GetTaskByIdQueryHandler(_projectRepositoryMock.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Return_Task_Details()
|
||||
{
|
||||
// Arrange
|
||||
var userId = UserId.Create();
|
||||
var project = Project.Create("Test Project", "Description", "TST", userId);
|
||||
var epic = project.CreateEpic("Test Epic", "Epic Description", userId);
|
||||
var story = epic.CreateStory("Test Story", "Story Description", TaskPriority.Medium, userId);
|
||||
var task = story.CreateTask("Test Task", "Task Description", TaskPriority.High, userId);
|
||||
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(task.Id, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(project);
|
||||
|
||||
var query = new GetTaskByIdQuery(task.Id.Value);
|
||||
|
||||
// Act
|
||||
var result = await _handler.Handle(query, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
result.Id.Should().Be(task.Id.Value);
|
||||
result.Title.Should().Be("Test Task");
|
||||
result.Description.Should().Be("Task Description");
|
||||
result.StoryId.Should().Be(story.Id.Value);
|
||||
result.Status.Should().Be("To Do");
|
||||
result.Priority.Should().Be("High");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Should_Fail_When_Task_Not_Found()
|
||||
{
|
||||
// Arrange
|
||||
var taskId = TaskId.Create();
|
||||
_projectRepositoryMock
|
||||
.Setup(x => x.GetProjectWithTaskAsync(taskId, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((Project?)null);
|
||||
|
||||
var query = new GetTaskByIdQuery(taskId.Value);
|
||||
|
||||
// Act
|
||||
Func<Task> act = async () => await _handler.Handle(query, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
await act.Should().ThrowAsync<NotFoundException>()
|
||||
.WithMessage("*Task*");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user