Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/commands/pre-commit.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ Run the pre-commit checklist for this project:
1. Update `CHANGELOG.md` `[Unreleased]` section — add an entry under the appropriate subsection (Added / Changed / Fixed / Removed) describing the changes made, referencing the issue number.
2. Run `dotnet build --configuration Release` — must succeed.
3. Run `dotnet test --settings .runsettings` — all tests must pass.
4. Run `dotnet csharpier --check .` — must pass (run `dotnet csharpier .` to auto-fix).
4. If `dotnet csharpier` is available, run `dotnet csharpier --check .` — must pass
(run `dotnet csharpier .` to auto-fix). Skip this step with a note if not installed.
5. If `coderabbit` CLI is installed, run `coderabbit review --type uncommitted --prompt-only`:
- If actionable/serious findings are reported, stop and address them before proposing the commit.
- If only nitpick-level findings, report them and continue to the commit proposal.
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ This project uses famous football stadiums (A-Z) that hosted FIFA World Cup matc

### Added

- Add `ValidateAsync_SquadNumberNegative_ReturnsValidationError` test to exercise the `GreaterThan(0)` rule with a negative value, which passes `NotEmpty()` but fails the greater-than rule (#427)
- Add `ValidateAsync_FirstNameEmptyInUpdateRuleSet_ReturnsValidationError` test to verify the `"Update"` rule set enforces structural field validation (#427)
- Add `adr/` directory with 12 Architecture Decision Records documenting architectural choices, technology decisions, and design trade-offs (#372)
- Add ADR index and template at `adr/README.md` (#372)
- Add Architecture Decisions section to `README.md` referencing the ADR index (#372)
Expand All @@ -52,6 +54,8 @@ This project uses famous football stadiums (A-Z) that hosted FIFA World Cup matc

### Changed

- Rename `ValidateAsync_SquadNumber_BelongsToPlayerBeingUpdated_ReturnsNoErrors` to `ValidateAsync_SquadNumberBelongsToPlayerBeingUpdated_ReturnsNoErrors` to align with the 3-segment naming convention for service/validator tests (#427)
- Make CSharpier step in `/pre-commit` conditional (skip with a note if not installed), consistent with the Docker and CodeRabbit steps (#427)
- Add "Verify tag commit is reachable from master" step to CD workflow using `git merge-base --is-ancestor` before any build or publish steps (#439)

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,30 @@ public async Task ValidateAsync_SquadNumberNotGreaterThanZero_ReturnsValidationE
result.Errors.Should().Contain(error => error.PropertyName == "SquadNumber");
}

[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")
);
}

[Fact]
[Trait("Category", "Unit")]
public async Task ValidateAsync_SquadNumberNotUnique_ReturnsValidationError()
Expand Down Expand Up @@ -153,7 +177,7 @@ public async Task ValidateAsync_SquadNumberNotUnique_ReturnsValidationError()

[Fact]
[Trait("Category", "Unit")]
public async Task ValidateAsync_SquadNumber_BelongsToPlayerBeingUpdated_ReturnsNoErrors()
public async Task ValidateAsync_SquadNumberBelongsToPlayerBeingUpdated_ReturnsNoErrors()
{
// Arrange
// Simulate a PUT request for an existing player: the squad number in the
Expand All @@ -178,6 +202,26 @@ public async Task ValidateAsync_SquadNumber_BelongsToPlayerBeingUpdated_ReturnsN
result.Errors.Should().BeEmpty();
}

[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");
}

/* -------------------------------------------------------------------------
* AbbrPosition
* ---------------------------------------------------------------------- */
Expand Down
Loading