diff --git a/app/Models/User.php b/app/Models/User.php index 78968d5..bcb94e8 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -67,6 +67,7 @@ class User extends Authenticatable implements MustVerifyEmail return $this->first_name.' '.$this->last_name; } + // TODO: Consider for deprecation public function short_name(): string { // 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'); } - 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; } - 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; } } diff --git a/tests/Feature/app/Models/UserTest.php b/tests/Feature/app/Models/UserTest.php new file mode 100644 index 0000000..d9839b9 --- /dev/null +++ b/tests/Feature/app/Models/UserTest.php @@ -0,0 +1,210 @@ +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); +});