Description
A test coverage audit of PlayerValidatorTests.cs identified two missing test cases and one naming inconsistency introduced in #424. All three items are in the same file and can be addressed together.
1. Rename: fix 4-segment test name (naming convention)
The test naming convention for services and validators is {MethodName}_{StateUnderTest}_{ExpectedBehavior} (3 underscore-delimited segments). One test added in #424 breaks this:
| Current (4 segments) |
Corrected (3 segments) |
ValidateAsync_SquadNumber_BelongsToPlayerBeingUpdated_ReturnsNoErrors |
ValidateAsync_SquadNumberBelongsToPlayerBeingUpdated_ReturnsNoErrors |
2. Missing test: GreaterThan(0) on SquadNumber is never exercised
Suggested name: ValidateAsync_SquadNumberNegative_ReturnsValidationError
The existing ValidateAsync_SquadNumberNotGreaterThanZero_ReturnsValidationError uses SquadNumber = 0, which fails the NotEmpty() rule (FluentValidation treats the int default 0 as empty). The GreaterThan(0) rule is never specifically reached because NotEmpty() fires first.
A negative value (e.g. -5) passes NotEmpty() but fails GreaterThan(0), producing the message "SquadNumber must be greater than 0." — a different rule and a different message path, currently untested.
[Fact]
[Trait("Category", "Unit")]
public async Task ValidateAsync_SquadNumberNegative_ReturnsValidationError()
{
// Arrange
var request = PlayerFakes.MakeRequestModelForCreate();
request.SquadNumber = -5;
var validator = CreateValidator();
// Act
var result = await validator.ValidateAsync(
request,
options => options.IncludeRuleSets("Create")
);
// Assert
result.IsValid.Should().BeFalse();
result.Errors.Should().Contain(error =>
error.PropertyName == "SquadNumber" &&
error.ErrorMessage.Contains("greater than 0"));
}
3. Missing test: "Update" rule set has no structural validation test
Suggested name: ValidateAsync_FirstNameEmptyInUpdateRuleSet_ReturnsValidationError
The only test covering the "Update" rule set is ValidateAsync_SquadNumberBelongsToPlayerBeingUpdated_ReturnsNoErrors (after renaming above), which only exercises the happy path. No test verifies that the "Update" rule set actually enforces structural fields. If the rule set were accidentally emptied, no existing test would catch it.
[Fact]
[Trait("Category", "Unit")]
public async Task ValidateAsync_FirstNameEmptyInUpdateRuleSet_ReturnsValidationError()
{
// Arrange
var request = PlayerFakes.MakeRequestModelForUpdate(10);
request.FirstName = string.Empty;
var validator = CreateValidator();
// Act
var result = await validator.ValidateAsync(
request,
options => options.IncludeRuleSets("Update")
);
// Assert
result.IsValid.Should().BeFalse();
result.Errors.Should().Contain(error => error.PropertyName == "FirstName");
}
Audit scope
The full audit covered PlayerControllerTests, PlayerServiceTests, and PlayerValidatorTests against all production branches in their respective layers. Controller and service suites were found to be complete. Other validator gaps considered (date boundary tests, multiple validation errors in one request) were reviewed and ruled redundant or out of scope.
Possible Solution
All changes are confined to PlayerValidatorTests.cs:
- Rename the offending test method
- Add
ValidateAsync_SquadNumberNegative_ReturnsValidationError in the SquadNumber section
- Add
ValidateAsync_FirstNameEmptyInUpdateRuleSet_ReturnsValidationError alongside ValidateAsync_SquadNumberBelongsToPlayerBeingUpdated_ReturnsNoErrors
Description
A test coverage audit of
PlayerValidatorTests.csidentified two missing test cases and one naming inconsistency introduced in #424. All three items are in the same file and can be addressed together.1. Rename: fix 4-segment test name (naming convention)
The test naming convention for services and validators is
{MethodName}_{StateUnderTest}_{ExpectedBehavior}(3 underscore-delimited segments). One test added in #424 breaks this:ValidateAsync_SquadNumber_BelongsToPlayerBeingUpdated_ReturnsNoErrorsValidateAsync_SquadNumberBelongsToPlayerBeingUpdated_ReturnsNoErrors2. Missing test:
GreaterThan(0)onSquadNumberis never exercisedSuggested name:
ValidateAsync_SquadNumberNegative_ReturnsValidationErrorThe existing
ValidateAsync_SquadNumberNotGreaterThanZero_ReturnsValidationErrorusesSquadNumber = 0, which fails theNotEmpty()rule (FluentValidation treats theintdefault0as empty). TheGreaterThan(0)rule is never specifically reached becauseNotEmpty()fires first.A negative value (e.g.
-5) passesNotEmpty()but failsGreaterThan(0), producing the message"SquadNumber must be greater than 0."— a different rule and a different message path, currently untested.3. Missing test:
"Update"rule set has no structural validation testSuggested name:
ValidateAsync_FirstNameEmptyInUpdateRuleSet_ReturnsValidationErrorThe only test covering the
"Update"rule set isValidateAsync_SquadNumberBelongsToPlayerBeingUpdated_ReturnsNoErrors(after renaming above), which only exercises the happy path. No test verifies that the"Update"rule set actually enforces structural fields. If the rule set were accidentally emptied, no existing test would catch it.Audit scope
The full audit covered
PlayerControllerTests,PlayerServiceTests, andPlayerValidatorTestsagainst all production branches in their respective layers. Controller and service suites were found to be complete. Other validator gaps considered (date boundary tests, multiple validation errors in one request) were reviewed and ruled redundant or out of scope.Possible Solution
All changes are confined to
PlayerValidatorTests.cs:ValidateAsync_SquadNumberNegative_ReturnsValidationErrorin theSquadNumbersectionValidateAsync_FirstNameEmptyInUpdateRuleSet_ReturnsValidationErroralongsideValidateAsync_SquadNumberBelongsToPlayerBeingUpdated_ReturnsNoErrors