using JobTrackerApi.Services; using Xunit; namespace JobTrackerApi.Tests; public sealed class JobPipelineTests { [Theory] [InlineData("applied", "Applied")] [InlineData("APPLIED", "Applied")] [InlineData(" Offer ", "Offer")] [InlineData("Interviewing", "Interview")] [InlineData("interviews", "Interview")] [InlineData("declined", "Rejected")] [InlineData("no response", "Ghosted")] public void Normalize_canonicalizes_casing_and_synonyms(string input, string expected) => Assert.Equal(expected, JobPipeline.Normalize(input)); [Theory] [InlineData("")] [InlineData(" ")] [InlineData(null)] public void Normalize_empty_becomes_default(string? input) => Assert.Equal("Applied", JobPipeline.Normalize(input)); [Fact] public void Normalize_preserves_unknown_custom_status() => Assert.Equal("Take-home assignment", JobPipeline.Normalize(" Take-home assignment ")); [Fact] public void Stages_are_ordered_and_unique() { var orders = JobPipeline.Stages.Select(s => s.Order).ToList(); Assert.Equal(orders.OrderBy(x => x), orders); Assert.Equal(orders.Count, orders.Distinct().Count()); } [Fact] public void OrderOf_sorts_canonical_before_custom() { Assert.True(JobPipeline.OrderOf("Applied") < JobPipeline.OrderOf("Offer")); Assert.True(JobPipeline.OrderOf("Offer") < JobPipeline.OrderOf("Custom stage")); Assert.Equal(JobPipeline.OrderOf("Interview"), JobPipeline.OrderOf("Interviewing")); } [Fact] public void IsCanonical_only_true_for_known_stages() { Assert.True(JobPipeline.IsCanonical("Offer")); Assert.True(JobPipeline.IsCanonical("offer")); Assert.False(JobPipeline.IsCanonical("Interviewing")); // synonym, not canonical Assert.False(JobPipeline.IsCanonical("Whatever")); } }