bb736d1183
New JobPipeline: ordered canonical stages (Applied, Waiting, Interview, Offer, Rejected, Ghosted) with category grouping and a Normalize() that canonicalizes casing and known synonyms (Interviewing->Interview, declined->Rejected, ...) while preserving unknown custom statuses. - normalize status on every write path (Create/Update/PATCH status) so the stored value stays canonical without destroying custom values - GET /api/jobapplications/pipeline exposes the ordered stages so the UI renders from one source instead of duplicated hardcoded lists - 14 unit tests; full backend suite green (120) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
55 lines
1.9 KiB
C#
55 lines
1.9 KiB
C#
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"));
|
|
}
|
|
}
|