Create tests for app/Models/User

This commit is contained in:
Matt Young 2025-07-03 22:54:04 -05:00
parent c6b4522f9e
commit efe79d6ad5
2 changed files with 221 additions and 2 deletions

View File

@ -67,6 +67,7 @@ class User extends Authenticatable implements MustVerifyEmail
return $this->first_name.' '.$this->last_name; return $this->first_name.' '.$this->last_name;
} }
// TODO: Consider for deprecation
public function short_name(): string public function short_name(): string
{ {
// return the first letter of $this->first_name and the full $this->last_name // return the first letter of $this->first_name and the full $this->last_name
@ -199,13 +200,21 @@ class User extends Authenticatable implements MustVerifyEmail
$this->load('flags'); $this->load('flags');
} }
public function scoresForEntry($entry) public function scoresForEntry(Entry|int $entry)
{ {
if ($entry instanceof Entry) {
$entry = $entry->id;
}
return $this->scoreSheets->where('entry_id', '=', $entry)->first()?->subscores; return $this->scoreSheets->where('entry_id', '=', $entry)->first()?->subscores;
} }
public function timeForEntryScores($entry) public function timeForEntryScores(Entry|int $entry)
{ {
if ($entry instanceof Entry) {
$entry = $entry->id;
}
return $this->scoreSheets->where('entry_id', '=', $entry)->first()?->created_at; return $this->scoreSheets->where('entry_id', '=', $entry)->first()?->created_at;
} }
} }

View File

@ -0,0 +1,210 @@
<?php
use App\Models\BonusScoreDefinition;
use App\Models\Entry;
use App\Models\Room;
use App\Models\School;
use App\Models\SchoolEmailDomain;
use App\Models\User;
use App\Models\UserFlag;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->user = User::factory()->create();
});
it('can return a full name in either order', function () {
expect($this->user->full_name())->toEqual($this->user->first_name.' '.$this->user->last_name)
->and($this->user->full_name('true'))->toEqual($this->user->last_name.', '.$this->user->first_name);
});
it('can return a short name for the user consisting of first initial and last name', function () {
expect($this->user->short_name())->toEqual($this->user->first_name[0].'. '.$this->user->last_name);
});
it('can check if the user has a school', function () {
expect($this->user->has_school())->toBeFalse();
});
it('can return the users email domain', function () {
$this->user->email = 'someone@example.com';
$this->user->save();
expect($this->user->emailDomain())->toEqual('example.com');
});
it('returns the users school if they have one', function () {
expect($this->user->school)->toBeNull();
$this->user->school_id = School::factory()->create()->id;
$this->user->save();
$this->user->refresh();
expect($this->user->school)->toBeInstanceOf(School::class);
});
it('can return the students at the users school', function () {
$school = School::factory()
->hasStudents(12)->create();
$this->user->school_id = $school->id;
$this->user->save();
$this->user->refresh();
expect($this->user->students->count())->toEqual(12);
});
it('can return entries belonging to students at the users school', function () {
$school = School::factory()
->hasStudents(12)->create();
$school->students->each(function ($student) {
Entry::factory()->count(2)->forStudent($student)->create();
});
$this->user->school_id = $school->id;
$this->user->save();
$this->user->refresh();
expect($this->user->entries->count())->toEqual(24);
});
it('can return the rooms the user is assigned to judge in. Can call rooms or judgingAssignments', function () {
$room = Room::factory()->create();
$room->judges()->attach($this->user);
$this->user->refresh();
expect($this->user->rooms->count())->toEqual(1)
->and($this->user->rooms->first()->id)->toEqual($room->id)
->and($this->user->judgingAssignments->count())->toEqual(1)
->and($this->user->judgingAssignments->first()->id)->toEqual($room->judges->first()->id);
});
it('Can return bonus score judging assignments', function () {
$bs = BonusScoreDefinition::factory()->create();
$bs->judges()->attach($this->user);
$this->user->refresh();
expect($this->user->bonusJudgingAssignments->count())->toEqual(1)
->and($this->user->bonusJudgingAssignments->first()->id)->toEqual($bs->judges->first()->id);
});
it('can identify if the user is a judge', function () {
$room = Room::factory()->create();
$room->judges()->attach($this->user);
$this->user->refresh();
expect($this->user->isJudge())->toBeTrue();
$newUser = User::factory()->create();
$bs = BonusScoreDefinition::factory()->create();
$bs->judges()->attach($newUser);
$newUser->refresh();
expect($newUser->isJudge())->toBeTrue();
});
it('returns a list of possible schools having the same email domain as the user', function () {
$possibleSchool = School::factory()->create();
$otherPossibleSchool = School::factory()->create();
$notPossibleSchool = School::factory()->create();
SchoolEmailDomain::create(['domain' => $this->user->emailDomain(), 'school_id' => $possibleSchool->id]);
SchoolEmailDomain::create(['domain' => $this->user->emailDomain(), 'school_id' => $otherPossibleSchool->id]);
expect($this->user->possibleSchools()->count())->toEqual(2)
->and($this->user->possibleSchools()->first()->id)->toEqual($possibleSchool->id)
->and($this->user->possibleSchools()->contains($notPossibleSchool))->toBeFalse();
$school = School::factory()->create();
$this->user->school_id = $school->id;
$this->user->save();
$this->user->refresh();
expect($this->user->possibleSchools()->count())->toEqual(1);
});
it('identifies if the user has tabulator privileges', function () {
$normalUser = User::factory()->create();
$tabUser = User::factory()->create(['is_tab' => true]);
$adminUser = User::factory()->create(['is_admin' => true]);
expect($normalUser->canTab())->toBeFalse()
->and($tabUser->canTab())->toBeTrue()
->and($adminUser->canTab())->toBeTrue();
});
it('returns score sheets submitted by the user', function () {
$entries = Entry::factory()->count(7)->create();
$entries->each(function ($entry) {
DB::table('score_sheets')->insert([
'user_id' => $this->user->id,
'entry_id' => $entry->id,
'subscores' => json_encode([5, 4, 3]),
'seating_total' => 10,
'advancement_total' => 10,
]);
});
$this->user->refresh();
expect($this->user->scoreSheets->count())->toEqual(7);
});
it('can return all flags assigned to the user', function () {
$this->user->addFlag('head_director');
$this->user->addFlag('monitor');
expect($this->user->flags->count())->toEqual(2)
->and($this->user->flags->first())->toBeInstanceOf(UserFlag::class);
});
it('can check if a user has a specific flag', function () {
DB::table('user_flags')->insert([
'user_id' => $this->user->id,
'flag_name' => 'head_director',
]);
expect($this->user->hasFlag('head_director'))->toBeTrue()
->and($this->user->hasFlag('monitor'))->toBeFalse();
});
it('can add a flag', function () {
$this->user->addFlag('head_director');
$this->user->refresh();
expect(UserFlag::where('user_id', $this->user->id)->where('flag_name', 'head_director')->exists())->toBeTrue()
->and(UserFlag::where('user_id', $this->user->id)->where('flag_name', 'monitor')->exists())->toBeFalse();
});
it('will not add a flag if it already exists', function () {
$this->user->addFlag('head_director');
$this->user->addFlag('head_director');
$this->user->refresh();
expect($this->user->flags()->count())->toEqual(1);
});
it('can remove a flag', function () {
DB::table('user_flags')->insert([
'user_id' => $this->user->id,
'flag_name' => 'head_director',
]);
expect($this->user->hasFlag('head_director'))->toBeTrue();
$this->user->removeFlag('head_director');
$this->user->refresh();
expect($this->user->hasFlag('head_director'))->toBeFalse();
});
it('can return scores assigned to an entry by this user', function () {
$entries = Entry::factory()->count(7)->create();
$n = 10;
foreach ($entries as $entry) {
DB::table('score_sheets')->insert([
'user_id' => $this->user->id,
'entry_id' => $entry->id,
'subscores' => json_encode([$n, $n + 2, $n + 5]),
'seating_total' => 10,
'advancement_total' => 10,
]);
$n += 5;
}
$this->user->refresh();
expect($this->user->scoresForEntry($entries[2]))->toBe([20, 22, 25])
->and($this->user->scoresForEntry($entries[3]->id))->toBe([25, 27, 30]);
});
it('returns the time the user entered a score for an entry', function () {
$entry = Entry::factory()->create();
$fixedTime = now()->subDay()->toDateTimeString(); // e.g., 1 day ago
DB::table('score_sheets')->insert([
'user_id' => $this->user->id,
'entry_id' => $entry->id,
'subscores' => json_encode([5, 5, 5]),
'seating_total' => 10,
'advancement_total' => 10,
'created_at' => $fixedTime,
'updated_at' => $fixedTime,
]);
expect($this->user->timeForEntryScores($entry)->toDateTimeString())->toBe($fixedTime);
});