Files
work-club-manager/backend/WorkClub.Tests.Unit/Domain/WorkItemStatusTests.cs
WorkClub Automation ba024c45be feat(domain): add core entities — Club, Member, WorkItem, Shift with state machine
- Create domain entities in WorkClub.Domain/Entities: Club, Member, WorkItem, Shift, ShiftSignup
- Implement enums: SportType, ClubRole, WorkItemStatus
- Add ITenantEntity interface for multi-tenancy support
- Implement state machine validation on WorkItem with C# 14 switch expressions
- Valid transitions: Open→Assigned→InProgress→Review→Done, Review→InProgress (rework)
- All invalid transitions throw InvalidOperationException
- TDD approach: Write tests first, 12/12 passing
- Use required properties with explicit Guid/Guid? for foreign keys
- DateTimeOffset for timestamps (timezone-aware, multi-tenant friendly)
- RowVersion byte[] for optimistic concurrency control
- No navigation properties yet (deferred to EF Core task)
- No domain events or validation attributes (YAGNI for MVP)
2026-03-03 14:09:25 +01:00

169 lines
4.3 KiB
C#

using WorkClub.Domain.Entities;
using WorkClub.Domain.Enums;
namespace WorkClub.Tests.Unit.Domain;
public class WorkItemStatusTests
{
private static WorkItem CreateWorkItem(WorkItemStatus status = WorkItemStatus.Open)
{
return new WorkItem
{
Id = Guid.NewGuid(),
TenantId = "test-tenant",
Title = "Test Work Item",
Status = status,
CreatedById = Guid.NewGuid(),
ClubId = Guid.NewGuid(),
CreatedAt = DateTimeOffset.UtcNow,
UpdatedAt = DateTimeOffset.UtcNow
};
}
[Fact]
public void Open_ToAssigned_Succeeds()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.Open);
// Act
workItem.TransitionTo(WorkItemStatus.Assigned);
// Assert
Assert.Equal(WorkItemStatus.Assigned, workItem.Status);
}
[Fact]
public void Assigned_ToInProgress_Succeeds()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.Assigned);
// Act
workItem.TransitionTo(WorkItemStatus.InProgress);
// Assert
Assert.Equal(WorkItemStatus.InProgress, workItem.Status);
}
[Fact]
public void InProgress_ToReview_Succeeds()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.InProgress);
// Act
workItem.TransitionTo(WorkItemStatus.Review);
// Assert
Assert.Equal(WorkItemStatus.Review, workItem.Status);
}
[Fact]
public void Review_ToDone_Succeeds()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.Review);
// Act
workItem.TransitionTo(WorkItemStatus.Done);
// Assert
Assert.Equal(WorkItemStatus.Done, workItem.Status);
}
[Fact]
public void Review_ToInProgress_Succeeds()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.Review);
// Act
workItem.TransitionTo(WorkItemStatus.InProgress);
// Assert
Assert.Equal(WorkItemStatus.InProgress, workItem.Status);
}
[Fact]
public void Open_ToDone_Throws()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.Open);
// Act & Assert
Assert.Throws<InvalidOperationException>(() =>
workItem.TransitionTo(WorkItemStatus.Done));
}
[Fact]
public void Open_ToInProgress_Throws()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.Open);
// Act & Assert
Assert.Throws<InvalidOperationException>(() =>
workItem.TransitionTo(WorkItemStatus.InProgress));
}
[Fact]
public void Assigned_ToDone_Throws()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.Assigned);
// Act & Assert
Assert.Throws<InvalidOperationException>(() =>
workItem.TransitionTo(WorkItemStatus.Done));
}
[Fact]
public void InProgress_ToOpen_Throws()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.InProgress);
// Act & Assert
Assert.Throws<InvalidOperationException>(() =>
workItem.TransitionTo(WorkItemStatus.Open));
}
[Fact]
public void Done_ToAnyStatus_Throws()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.Done);
// Act & Assert
Assert.Throws<InvalidOperationException>(() =>
workItem.TransitionTo(WorkItemStatus.Open));
Assert.Throws<InvalidOperationException>(() =>
workItem.TransitionTo(WorkItemStatus.Assigned));
Assert.Throws<InvalidOperationException>(() =>
workItem.TransitionTo(WorkItemStatus.InProgress));
Assert.Throws<InvalidOperationException>(() =>
workItem.TransitionTo(WorkItemStatus.Review));
}
[Fact]
public void CanTransitionTo_ValidTransition_ReturnsTrue()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.Open);
// Act & Assert
Assert.True(workItem.CanTransitionTo(WorkItemStatus.Assigned));
}
[Fact]
public void CanTransitionTo_InvalidTransition_ReturnsFalse()
{
// Arrange
var workItem = CreateWorkItem(WorkItemStatus.Open);
// Act & Assert
Assert.False(workItem.CanTransitionTo(WorkItemStatus.Done));
}
}