using ColaFlow.Modules.ProjectManagement.Domain.Events; using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects; using FluentAssertions; namespace ColaFlow.Domain.Tests.Events; /// /// Unit tests for Domain Events /// public class DomainEventsTests { #region ProjectCreatedEvent Tests [Fact] public void ProjectCreatedEvent_Constructor_ShouldSetProperties() { // Arrange var projectId = ProjectId.Create(); var projectName = "Test Project"; var createdBy = UserId.Create(); // Act var @event = new ProjectCreatedEvent(projectId, projectName, createdBy); // Assert @event.ProjectId.Should().Be(projectId); @event.ProjectName.Should().Be(projectName); @event.CreatedBy.Should().Be(createdBy); @event.OccurredOn.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(5)); } [Fact] public void ProjectCreatedEvent_ShouldBeRecord() { // Arrange var projectId = ProjectId.Create(); var projectName = "Test Project"; var createdBy = UserId.Create(); // Act var event1 = new ProjectCreatedEvent(projectId, projectName, createdBy); var event2 = new ProjectCreatedEvent(projectId, projectName, createdBy); // Assert - Records with same values should be equal event1.ProjectId.Should().Be(event2.ProjectId); event1.ProjectName.Should().Be(event2.ProjectName); event1.CreatedBy.Should().Be(event2.CreatedBy); } #endregion #region ProjectUpdatedEvent Tests [Fact] public void ProjectUpdatedEvent_Constructor_ShouldSetProperties() { // Arrange var projectId = ProjectId.Create(); var name = "Updated Project"; var description = "Updated Description"; // Act var @event = new ProjectUpdatedEvent(projectId, name, description); // Assert @event.ProjectId.Should().Be(projectId); @event.Name.Should().Be(name); @event.Description.Should().Be(description); @event.OccurredOn.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(5)); } [Fact] public void ProjectUpdatedEvent_WithNullDescription_ShouldAcceptNull() { // Arrange var projectId = ProjectId.Create(); var name = "Updated Project"; // Act var @event = new ProjectUpdatedEvent(projectId, name, null!); // Assert @event.Description.Should().BeNull(); } #endregion #region ProjectArchivedEvent Tests [Fact] public void ProjectArchivedEvent_Constructor_ShouldSetProperties() { // Arrange var projectId = ProjectId.Create(); // Act var @event = new ProjectArchivedEvent(projectId); // Assert @event.ProjectId.Should().Be(projectId); @event.OccurredOn.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(5)); } [Fact] public void ProjectArchivedEvent_ShouldBeRecord() { // Arrange var projectId = ProjectId.Create(); // Act var event1 = new ProjectArchivedEvent(projectId); var event2 = new ProjectArchivedEvent(projectId); // Assert - Records with same values should be equal event1.ProjectId.Should().Be(event2.ProjectId); } #endregion #region EpicCreatedEvent Tests [Fact] public void EpicCreatedEvent_Constructor_ShouldSetProperties() { // Arrange var epicId = EpicId.Create(); var epicName = "Epic 1"; var projectId = ProjectId.Create(); // Act var @event = new EpicCreatedEvent(epicId, epicName, projectId); // Assert @event.EpicId.Should().Be(epicId); @event.EpicName.Should().Be(epicName); @event.ProjectId.Should().Be(projectId); @event.OccurredOn.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(5)); } [Fact] public void EpicCreatedEvent_ShouldBeRecord() { // Arrange var epicId = EpicId.Create(); var epicName = "Epic 1"; var projectId = ProjectId.Create(); // Act var event1 = new EpicCreatedEvent(epicId, epicName, projectId); var event2 = new EpicCreatedEvent(epicId, epicName, projectId); // Assert - Records with same values should be equal event1.EpicId.Should().Be(event2.EpicId); event1.EpicName.Should().Be(event2.EpicName); event1.ProjectId.Should().Be(event2.ProjectId); } #endregion #region Event Timing Tests [Fact] public void DomainEvents_OccurredOn_ShouldBeUtcTime() { // Arrange & Act var projectCreatedEvent = new ProjectCreatedEvent(ProjectId.Create(), "Test", UserId.Create()); var projectUpdatedEvent = new ProjectUpdatedEvent(ProjectId.Create(), "Test", "Desc"); var projectArchivedEvent = new ProjectArchivedEvent(ProjectId.Create()); var epicCreatedEvent = new EpicCreatedEvent(EpicId.Create(), "Epic", ProjectId.Create()); // Assert projectCreatedEvent.OccurredOn.Kind.Should().Be(DateTimeKind.Utc); projectUpdatedEvent.OccurredOn.Kind.Should().Be(DateTimeKind.Utc); projectArchivedEvent.OccurredOn.Kind.Should().Be(DateTimeKind.Utc); epicCreatedEvent.OccurredOn.Kind.Should().Be(DateTimeKind.Utc); } [Fact] public void DomainEvents_OccurredOn_ShouldBeSetAutomatically() { // Arrange var beforeCreation = DateTime.UtcNow; // Act var @event = new ProjectCreatedEvent(ProjectId.Create(), "Test", UserId.Create()); // Assert var afterCreation = DateTime.UtcNow; @event.OccurredOn.Should().BeOnOrAfter(beforeCreation); @event.OccurredOn.Should().BeOnOrBefore(afterCreation); } #endregion #region Event Immutability Tests [Fact] public void DomainEvents_ShouldBeImmutable() { // Arrange var projectId = ProjectId.Create(); var projectName = "Test Project"; var createdBy = UserId.Create(); // Act var @event = new ProjectCreatedEvent(projectId, projectName, createdBy); var originalProjectId = @event.ProjectId; var originalProjectName = @event.ProjectName; var originalCreatedBy = @event.CreatedBy; var originalOccurredOn = @event.OccurredOn; // Try to access properties multiple times var projectId1 = @event.ProjectId; var projectName1 = @event.ProjectName; var createdBy1 = @event.CreatedBy; var occurredOn1 = @event.OccurredOn; // Assert - Properties should not change projectId1.Should().Be(originalProjectId); projectName1.Should().Be(originalProjectName); createdBy1.Should().Be(originalCreatedBy); occurredOn1.Should().Be(originalOccurredOn); } #endregion }