using FluentAssertions; using HihaArvio.Models; namespace HihaArvio.Tests.Models; /// /// Tests for the model, verifying construction, property validation, and the factory method. /// public class EstimateResultTests { /// /// Verifies that all properties are correctly assigned during object initialization. /// [Fact] public void EstimateResult_ShouldCreateWithAllProperties() { // Arrange var id = Guid.NewGuid(); var timestamp = DateTimeOffset.UtcNow; var estimateText = "2 weeks"; var mode = EstimateMode.Work; var intensity = 0.75; var duration = TimeSpan.FromSeconds(5); // Act var result = new EstimateResult { Id = id, Timestamp = timestamp, EstimateText = estimateText, Mode = mode, ShakeIntensity = intensity, ShakeDuration = duration }; // Assert result.Id.Should().Be(id); result.Timestamp.Should().Be(timestamp); result.EstimateText.Should().Be(estimateText); result.Mode.Should().Be(mode); result.ShakeIntensity.Should().Be(intensity); result.ShakeDuration.Should().Be(duration); } /// /// Verifies that ShakeIntensity accepts valid values within the 0.0 to 1.0 range. /// [Theory] [InlineData(0.0)] [InlineData(0.3)] [InlineData(0.7)] [InlineData(1.0)] public void EstimateResult_ShouldAcceptValidIntensityValues(double intensity) { // Act var result = new EstimateResult { ShakeIntensity = intensity }; // Assert result.ShakeIntensity.Should().Be(intensity); } /// /// Verifies that ShakeIntensity throws ArgumentOutOfRangeException for values outside 0.0 to 1.0. /// [Theory] [InlineData(-0.1)] [InlineData(1.1)] [InlineData(2.0)] public void EstimateResult_ShouldThrowForInvalidIntensity(double invalidIntensity) { // Act Action act = () => _ = new EstimateResult { ShakeIntensity = invalidIntensity }; // Assert act.Should().Throw() .WithMessage("*must be between 0.0 and 1.0*"); } /// /// Verifies that setting EstimateText to null throws an ArgumentNullException. /// [Fact] public void EstimateResult_ShouldThrowForNullEstimateText() { // Act Action act = () => _ = new EstimateResult { EstimateText = null! }; // Assert act.Should().Throw() .WithParameterName("value"); } /// /// Verifies that setting EstimateText to empty or whitespace-only strings throws an ArgumentException. /// [Theory] [InlineData("")] [InlineData(" ")] public void EstimateResult_ShouldThrowForEmptyOrWhitespaceEstimateText(string invalidText) { // Act Action act = () => _ = new EstimateResult { EstimateText = invalidText }; // Assert act.Should().Throw() .WithMessage("*cannot be empty or whitespace*"); } /// /// Verifies that ShakeDuration accepts a zero TimeSpan value. /// [Fact] public void EstimateResult_ShouldAcceptZeroDuration() { // Act var result = new EstimateResult { ShakeDuration = TimeSpan.Zero }; // Assert result.ShakeDuration.Should().Be(TimeSpan.Zero); } /// /// Verifies that the Create factory method generates unique non-empty IDs for each instance. /// [Fact] public void EstimateResult_ShouldGenerateUniqueIds() { // Arrange & Act var result1 = EstimateResult.Create("test1", EstimateMode.Work, 0.5, TimeSpan.FromSeconds(1)); var result2 = EstimateResult.Create("test2", EstimateMode.Work, 0.5, TimeSpan.FromSeconds(1)); // Assert result1.Id.Should().NotBe(result2.Id); result1.Id.Should().NotBeEmpty(); result2.Id.Should().NotBeEmpty(); } /// /// Verifies that the Create factory method automatically sets the Timestamp to the current UTC time. /// [Fact] public void EstimateResult_Create_ShouldSetTimestampAutomatically() { // Arrange var before = DateTimeOffset.UtcNow; // Act var result = EstimateResult.Create("test", EstimateMode.Work, 0.5, TimeSpan.FromSeconds(1)); var after = DateTimeOffset.UtcNow; // Assert result.Timestamp.Should().BeOnOrAfter(before); result.Timestamp.Should().BeOnOrBefore(after); } /// /// Verifies that the Create factory method correctly assigns all provided property values. /// [Fact] public void EstimateResult_Create_ShouldSetAllProperties() { // Arrange var estimateText = "3 months"; var mode = EstimateMode.Generic; var intensity = 0.8; var duration = TimeSpan.FromSeconds(10); // Act var result = EstimateResult.Create(estimateText, mode, intensity, duration); // Assert result.EstimateText.Should().Be(estimateText); result.Mode.Should().Be(mode); result.ShakeIntensity.Should().Be(intensity); result.ShakeDuration.Should().Be(duration); } }