Created a test for app/Rules/UniqueFullNameAtSchool

This commit is contained in:
Matt Young 2025-07-04 14:41:35 -05:00
parent 07c7a27e28
commit 409aa939c3
2 changed files with 87 additions and 8 deletions

View File

@ -5,12 +5,15 @@ namespace App\Rules;
use App\Models\Student; use App\Models\Student;
use Closure; use Closure;
use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Translation\PotentiallyTranslatedString;
class UniqueFullNameAtSchool implements ValidationRule class UniqueFullNameAtSchool implements ValidationRule
{ {
protected $first_name; protected string $first_name;
protected $last_name;
protected $school_id; protected string $last_name;
protected int $school_id;
public function __construct($firstName, $lastName, $schoolID) public function __construct($firstName, $lastName, $schoolID)
{ {
@ -19,7 +22,7 @@ class UniqueFullNameAtSchool implements ValidationRule
$this->school_id = $schoolID; $this->school_id = $schoolID;
} }
public function studentExists() public function studentExists(): bool
{ {
return Student::where('first_name', $this->first_name) return Student::where('first_name', $this->first_name)
->where('last_name', $this->last_name) ->where('last_name', $this->last_name)
@ -27,18 +30,19 @@ class UniqueFullNameAtSchool implements ValidationRule
->exists(); ->exists();
} }
public function message() public function message(): string
{ {
return "There is already a student with that name at the school you are trying to add them to"; return 'There is already a student with that name at the school you are trying to add them to';
} }
/** /**
* Run the validation rule. * Run the validation rule.
* *
* @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail * @param Closure(string): PotentiallyTranslatedString $fail
*/ */
public function validate(string $attribute, mixed $value, Closure $fail): void public function validate(string $attribute, mixed $value, Closure $fail): void
{ {
if($this->studentExists()) { if ($this->studentExists()) {
$fail($this->message()); $fail($this->message());
} }
} }

View File

@ -0,0 +1,75 @@
<?php
use App\Models\School;
use App\Models\Student;
use App\Rules\UniqueFullNameAtSchool;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
describe('UniqueFullNameAtSchool validation rule', function () {
it('fails validation when student with same name exists at school', function () {
// Arrange
$school = School::factory()->create();
Student::factory()->create([
'first_name' => 'John',
'last_name' => 'Doe',
'school_id' => $school->id,
]);
$rule = new UniqueFullNameAtSchool('John', 'Doe', $school->id);
$fails = false;
// Act
$rule->validate('name', 'value', function ($message) use (&$fails) {
$fails = true;
});
// Assert
expect($fails)->toBeTrue()
->and($rule->message())->toBe('There is already a student with that name at the school you are trying to add them to');
});
it('passes validation when no student with same name exists at school', function () {
// Arrange
$school = School::factory()->create();
Student::factory()->create([
'first_name' => 'Jane',
'last_name' => 'Doe',
'school_id' => $school->id,
]);
$rule = new UniqueFullNameAtSchool('John', 'Doe', $school->id);
$fails = false;
// Act
$rule->validate('name', 'value', function ($message) use (&$fails) {
$fails = true;
});
// Assert
expect($fails)->toBeFalse();
});
it('passes validation when student with same name exists at different school', function () {
// Arrange
$school1 = School::factory()->create();
$school2 = School::factory()->create();
Student::factory()->create([
'first_name' => 'John',
'last_name' => 'Doe',
'school_id' => $school1->id,
]);
$rule = new UniqueFullNameAtSchool('John', 'Doe', $school2->id);
$fails = false;
// Act
$rule->validate('name', 'value', function ($message) use (&$fails) {
$fails = true;
});
// Assert
expect($fails)->toBeFalse();
});
});