get(route('admin.students.index'))->assertRedirect(route('home')); actAsNormal(); $this->get(route('admin.students.index'))->assertRedirect(route('dashboard')); actAsTab(); $this->get(route('admin.students.index'))->assertRedirect(route('dashboard')); }); it('it shows an index of students', function () { actAsAdmin(); $students = Student::factory()->count(3)->create(); $response = $this->get(route('admin.students.index'))->assertOk(); $studentToView = $response->viewData('students'); expect($studentToView)->toHaveCount(3); foreach ($students as $student) { expect(in_array($student->id, $studentToView->pluck('id')->toArray())); } $response->assertViewIs( 'admin.students.index'); }); it('can filter by first name', function () { $names = ['name1', 'name2', 'name3']; foreach ($names as $name) { $students[] = Student::factory()->create(['first_name' => $name]); } actAsAdmin(); $response = $this->withSession([ 'adminStudentFilters' => [ 'first_name' => 'name3', 'last_name' => '', 'school' => 'all', 'grade' => 'all', ], ]) ->get(route('admin.students.index')); file_put_contents(storage_path('debug.html'), $response->getContent()); $response->assertOk() ->assertViewIs('admin.students.index'); $returnedStudentIds = $response->viewData('students')->pluck('id')->toArray(); expect($returnedStudentIds)->toHaveCount(1) ->and(in_array($students[0]->id, $returnedStudentIds))->toBeFalsy() ->and(in_array($students[1]->id, $returnedStudentIds))->toBeFalsy() ->and(in_array($students[2]->id, $returnedStudentIds))->toBeTruthy(); }); it('can filter by last name', function () { $names = ['name1', 'name2', 'name3']; foreach ($names as $name) { $students[] = Student::factory()->create(['last_name' => $name]); } actAsAdmin(); $response = $this->withSession([ 'adminStudentFilters' => [ 'first_name' => '', 'last_name' => 'name2', 'school' => 'all', 'grade' => 'all', ], ]) ->get(route('admin.students.index')); file_put_contents(storage_path('debug.html'), $response->getContent()); $response->assertOk() ->assertViewIs('admin.students.index'); $returnedStudentIds = $response->viewData('students')->pluck('id')->toArray(); expect($returnedStudentIds)->toHaveCount(1) ->and(in_array($students[0]->id, $returnedStudentIds))->toBeFalsy() ->and(in_array($students[1]->id, $returnedStudentIds))->toBeTruthy() ->and(in_array($students[2]->id, $returnedStudentIds))->toBeFalsy(); }); it('can filter by grade', function () { $grades = [6, 7, 8]; foreach ($grades as $grade) { $students[] = Student::factory()->create(['grade' => $grade]); } actAsAdmin(); $response = $this->withSession([ 'adminStudentFilters' => [ 'first_name' => '', 'last_name' => '', 'school' => 'all', 'grade' => '8', ], ]) ->get(route('admin.students.index')); file_put_contents(storage_path('debug.html'), $response->getContent()); $response->assertOk() ->assertViewIs('admin.students.index'); $returnedStudentIds = $response->viewData('students')->pluck('id')->toArray(); expect($returnedStudentIds)->toHaveCount(1) ->and(in_array($students[0]->id, $returnedStudentIds))->toBeFalsy() ->and(in_array($students[1]->id, $returnedStudentIds))->toBeFalsy() ->and(in_array($students[2]->id, $returnedStudentIds))->toBeTruthy(); }); it('can filter by school', function () { $schools[1] = School::factory()->create(); $schools[2] = School::factory()->create(); $schools[3] = School::factory()->create(); foreach ($schools as $school) { $students[] = Student::factory()->create(['school_id' => $school->id]); } actAsAdmin(); $response = $this->withSession([ 'adminStudentFilters' => [ 'first_name' => '', 'last_name' => '', 'school' => $schools[3]->id, 'grade' => 'all', ], ]) ->get(route('admin.students.index')); $response->assertOk() ->assertViewIs('admin.students.index'); $returnedStudentIds = $response->viewData('students')->pluck('id')->toArray(); expect($returnedStudentIds)->toHaveCount(1) ->and(in_array($students[0]->id, $returnedStudentIds))->toBeFalsy() ->and(in_array($students[1]->id, $returnedStudentIds))->toBeFalsy() ->and(in_array($students[2]->id, $returnedStudentIds))->toBeTruthy(); }); }); describe('StudentController::create', function () { it('denies access to a non-admin user', function () { $this->get(route('admin.students.create'))->assertRedirect(route('home')); actAsNormal(); $this->get(route('admin.students.create'))->assertRedirect(route('dashboard')); actAsTab(); $this->get(route('admin.students.create'))->assertRedirect(route('dashboard')); }); it('shows a form to create a student', function () { School::factory()->count(5)->create(); Audition::factory()->create(['minimum_grade' => 6, 'maximum_grade' => 8]); Audition::factory()->create(['minimum_grade' => 7, 'maximum_grade' => 11]); actAsAdmin(); $response = $this->get(route('admin.students.create'))->assertOk(); $response->assertViewIs('admin.students.create') ->assertViewHas('schools') ->assertViewHas('minGrade', 6) ->assertViewHas('maxGrade', 11); }); it('still works when there are nomination ensembles', function () { School::factory()->count(5)->create(); Audition::factory()->create(['minimum_grade' => 6, 'maximum_grade' => 8]); Audition::factory()->create(['minimum_grade' => 7, 'maximum_grade' => 11]); NominationEnsemble::factory()->create(['minimum_grade' => 6, 'maximum_grade' => 8]); actAsAdmin(); $response = $this->get(route('admin.students.create'))->assertOk(); $response->assertViewIs('admin.students.create') ->assertViewHas('schools') ->assertViewHas('minGrade', 6) ->assertViewHas('maxGrade', 11); }); }); describe('StudentController::store', function () { it('denies access to a non-admin user', function () { $this->post(route('admin.students.store'))->assertRedirect(route('home')); actAsNormal(); $this->post(route('admin.students.store'))->assertRedirect(route('dashboard')); actAsTab(); $this->post(route('admin.students.store'))->assertRedirect(route('dashboard')); }); it('creates a student', function () { $school = School::factory()->create(); actAsAdmin(); $response = $this->post(route('admin.students.store'), [ 'first_name' => 'John', 'last_name' => 'Doe', 'school_id' => $school->id, 'grade' => 6, ]); file_put_contents(storage_path('debug.html'), $response->getContent()); $response->assertRedirect(route('admin.students.index')) ->assertSessionHas('success', 'Student created successfully'); $student = Student::first(); expect($student->first_name)->toEqual('John') ->and($student->last_name)->toEqual('Doe') ->and($student->school_id)->toEqual($school->id) ->and($student->grade)->toEqual(6); }); it('does not allow a duplicate student', function () { $school = School::factory()->create(); Student::create([ 'first_name' => 'John', 'last_name' => 'Doe', 'school_id' => $school->id, 'grade' => 6, ]); actAsAdmin(); $response = $this->post(route('admin.students.store'), [ 'first_name' => 'John', 'last_name' => 'Doe', 'school_id' => $school->id, 'grade' => 6, ]); $response->assertRedirect(route('home')); }); }); describe('StudentController::edit', function () { beforeEach(function () { $this->student = Student::factory()->create(); Audition::factory()->create(['minimum_grade' => 6, 'maximum_grade' => 8]); }); it('denies access to a non-admin user', function () { $this->get(route('admin.students.edit', 1))->assertRedirect(route('home')); actAsNormal(); $this->get(route('admin.students.edit', 1))->assertRedirect(route('dashboard')); actAsTab(); $this->get(route('admin.students.edit', 1))->assertRedirect(route('dashboard')); }); it('shows a form to edit a student', function () { actAsAdmin(); $response = $this->get(route('admin.students.edit', $this->student->id))->assertOk(); $response->assertViewIs('admin.students.edit') ->assertViewHas('student', $this->student) ->assertViewHas('schools') ->assertViewHas('minGrade', 6) ->assertViewHas('maxGrade', 8) ->assertViewHas('events') ->assertViewHas('event_entries'); }); it('has all schools on the edit form', function () { $schools = School::factory()->count(5)->create(); actAsAdmin(); $response = $this->get(route('admin.students.edit', $this->student->id))->assertOk(); $response->assertViewIs('admin.students.edit') ->assertViewHas('student', $this->student) ->assertViewHas('schools'); $returnedSchools = $response->viewData('schools'); expect($returnedSchools)->toHaveCount(6); foreach ($schools as $school) { expect(in_array($school->id, $returnedSchools->pluck('id')->toArray()))->toBeTruthy(); } expect(in_array($this->student->school->id, $returnedSchools->pluck('id')->toArray()))->toBeTruthy(); }); it('has all entries grouped by event on the edit form', function () { $schools = School::factory()->count(5)->create(); $concertEvent = Event::create(['name' => 'Concert']); Audition::truncate(); $ca = Audition::factory()->forEvent($concertEvent)->create(['name' => 'Alto Saxophone']); $ct = Audition::factory()->forEvent($concertEvent)->create(['name' => 'Tenor Saxophone']); $jazzEvent = Event::create(['name' => 'Jazz']); $ja = Audition::factory()->forEvent($jazzEvent)->create(['name' => 'Jazz Alto']); $jt = Audition::factory()->forEvent($jazzEvent)->create(['name' => 'Jazz Tenor']); $scribe = app(CreateEntry::class); foreach (Audition::all() as $audition) { $scribe($this->student, $audition); } actAsAdmin(); $response = $this->get(route('admin.students.edit', $this->student->id))->assertOk(); $response->assertViewIs('admin.students.edit') ->assertViewHas('student', $this->student) ->assertViewHas('event_entries'); expect($response->viewData('event_entries'))->toHaveCount(2) ->and($response->viewData('event_entries')[$concertEvent->id])->toHaveCount(2) ->and($response->viewData('event_entries')[$jazzEvent->id])->toHaveCount(2) ->and($response->viewData('event_entries')[$concertEvent->id][0]['audition_id'])->toEqual($ca->id) ->and($response->viewData('event_entries')[$concertEvent->id][1]['audition_id'])->toEqual($ct->id) ->and($response->viewData('event_entries')[$jazzEvent->id][0]['audition_id'])->toEqual($ja->id) ->and($response->viewData('event_entries')[$jazzEvent->id][1]['audition_id'])->toEqual($jt->id); }); }); describe('StudentController::update', function () { beforeEach(function () { $this->school = School::factory()->create(); $this->student = Student::create([ 'first_name' => 'Jean Luc', 'last_name' => 'Picard', 'grade' => 12, 'school_id' => $this->school->id, ]); }); it('denies access to a non-admin user', function () { $this->patch(route('admin.students.update', $this->student->id))->assertRedirect(route('home')); actAsNormal(); $this->patch(route('admin.students.update', $this->student->id))->assertRedirect(route('dashboard')); }); it('updates a student', function () { actAsAdmin(); $newSchool = School::factory()->create(); $response = $this->patch(route('admin.students.update', $this->student->id), [ 'first_name' => 'James', 'last_name' => 'Kirk', 'school_id' => $newSchool->id, 'grade' => 6, ]); $this->student->refresh(); $response->assertRedirect(route('admin.students.index')); expect($this->student->first_name)->toEqual('James') ->and($this->student->last_name)->toEqual('Kirk') ->and($this->student->school_id)->toEqual($newSchool->id) ->and($this->student->grade)->toEqual(6); }); }); describe('StudentController::destroy', function () { beforeEach(function () { $this->student = Student::factory()->create(); }); it('denies access to a non-admin user', function () { $this->delete(route('admin.students.destroy', $this->student->id))->assertRedirect(route('home')); actAsNormal(); $this->delete(route('admin.students.destroy', $this->student->id))->assertRedirect(route('dashboard')); }); it('deletes a student', function () { actAsAdmin(); $response = $this->delete(route('admin.students.destroy', $this->student->id)); $response->assertRedirect(route('admin.students.index')); expect(Student::where('id', $this->student->id)->exists())->toBeFalsy(); }); it('will not delete a student with entries', function () { actAsAdmin(); $entry = Entry::create([ 'student_id' => $this->student->id, 'audition_id' => Audition::factory()->create()->id, ]); $response = $this->delete(route('admin.students.destroy', $this->student->id)); $response->assertRedirect(route('admin.students.index')) ->assertSessionHas('error', 'Student has entries and cannot be deleted'); expect(Student::where('id', $this->student->id)->exists())->toBeTruthy(); }); });