scribe = app(CreateEntry::class); }); it('can create an entry', function () { $student = Student::factory()->create(['grade' => 9]); $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); $this->scribe->createEntry($student, $audition); $thisEntry = Entry::where('student_id', $student->id)->first(); expect($thisEntry)->toBeInstanceOf(Entry::class); }); it('is invokable', function () { $student = Student::factory()->create(['grade' => 9]); $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); ($this->scribe)($student, $audition); $thisEntry = Entry::where('student_id', $student->id)->first(); expect($thisEntry)->toBeInstanceOf(Entry::class); }); it('accepts integer IDs as well as models for arguments', function () { $student = Student::factory()->create(['grade' => 9]); $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); $this->scribe->createEntry($student->id, $audition->id); $thisEntry = Entry::where('student_id', $student->id)->first(); expect($thisEntry)->toBeInstanceOf(Entry::class); }); it('defaults to entering seating and advancement', function () { $student = Student::factory()->create(['grade' => 9]); $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); $this->scribe->createEntry($student, $audition); $thisEntry = Entry::where('student_id', $student->id)->first(); expect($thisEntry->for_seating)->toBeTruthy() ->and($thisEntry->for_advancement)->toBeTruthy(); }); it('allows setting only seating', function () { $student = Student::factory()->create(['grade' => 9]); $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); $this->scribe->createEntry($student, $audition, 'seating'); $thisEntry = Entry::where('student_id', $student->id)->first(); expect($thisEntry->for_seating)->toBeTruthy() ->and($thisEntry->for_advancement)->toBeFalsy(); }); test('allows setting only advancement', function () { $student = Student::factory()->create(['grade' => 9]); $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); $this->scribe->createEntry($student, $audition, 'advancement'); $thisEntry = Entry::where('student_id', $student->id)->first(); expect($thisEntry->for_seating)->toBeFalsy() ->and($thisEntry->for_advancement)->toBeTruthy(); }); it('does not assign a draw number if the audition is not drawn', function () { $student = Student::factory()->create(['grade' => 9]); $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); $this->scribe->createEntry($student, $audition); $thisEntry = Entry::where('student_id', $student->id)->first(); expect($thisEntry->draw_number)->toBeNull(); }); it('assigns the next available draw number if the audition is drawn', function () { $audition = Audition::factory() ->has(Entry::factory()->count(5)) ->create(['minimum_grade' => 9, 'maximum_grade' => 12]); AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => 'drawn']); $n = 1; foreach ($audition->entries as $entry) { $entry->update(['draw_number' => $n]); $n++; } $student = Student::factory()->create(['grade' => 9]); $this->scribe->createEntry($student, $audition); $thisEntry = Entry::where('student_id', $student->id)->first(); expect($thisEntry->draw_number)->toEqual($n); }); it('throws an exception if the audition seating is published', function () { $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => 'seats_published']); $student = Student::factory()->create(['grade' => 9]); $this->scribe->createEntry($student, $audition); })->throws(AuditionAdminException::class, 'Cannot add an entry to an audition where seats are published'); it('throws an exception if the audition advancement is published', function () { $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); AuditionFlag::create(['audition_id' => $audition->id, 'flag_name' => 'advancement_published']); $student = Student::factory()->create(['grade' => 9]); $this->scribe->createEntry($student, $audition); })->throws(AuditionAdminException::class, 'Cannot add an entry to an audition where advancement is published'); it('throws an exception if the student does not exist', function () { $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); $student = Student::factory()->make(['grade' => 9]); $this->scribe->createEntry($student, $audition); })->throws(AuditionAdminException::class, 'Invalid student provided'); it('throws an exception if the audition does not exist', function () { $audition = Audition::factory()->make(['minimum_grade' => 9, 'maximum_grade' => 12]); $student = Student::factory()->create(['grade' => 9]); $this->scribe->createEntry($student, $audition); })->throws(AuditionAdminException::class, 'Invalid audition provided'); it('throws an exception if the student is already entered in the audition', function () { $og_entry = Entry::factory()->create(); $this->scribe->createEntry($og_entry->student, $og_entry->audition); })->throws(AuditionAdminException::class, 'That student is already entered in that audition'); it('throws and exception if the student is below the minimum grade for the audition', function () { $student = Student::factory()->create(['grade' => 8]); $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); $this->scribe->createEntry($student, $audition); })->throws(AuditionAdminException::class, 'The grade of the student does not meet the minimum for that audition'); it('throws and exception if the student is above the maximum grade for the audition', function () { $student = Student::factory()->create(['grade' => 12]); $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 10]); $this->scribe->createEntry($student, $audition); })->throws(AuditionAdminException::class, 'The grade of the student exceeds the maximum for that audition'); it('logs the entry creation', function () { actAsAdmin(); $student = Student::factory()->create(['grade' => 9]); $audition = Audition::factory()->create(['minimum_grade' => 9, 'maximum_grade' => 12]); $this->scribe->createEntry($student, $audition); $thisEntry = Entry::where('student_id', $student->id)->first(); $logEntry = AuditLogEntry::first(); expect($logEntry->message)->toEqual('Entered '.$thisEntry->student->full_name().' from '.$thisEntry->student->school->name.' in '.$audition->name.'.') ->and($logEntry->affected['entries'])->toEqual([$thisEntry->id]) ->and($logEntry->affected['students'])->toEqual([$thisEntry->student_id]) ->and($logEntry->affected['auditions'])->toEqual([$thisEntry->audition_id]) ->and($logEntry->affected['schools'])->toEqual([$thisEntry->student->school->id]) ->and($logEntry->user)->toEqual(auth()->user()->email); });