346 lines
15 KiB
PHP
346 lines
15 KiB
PHP
<?php
|
|
|
|
use App\Actions\Entries\CreateEntry;
|
|
use App\Models\Audition;
|
|
use App\Models\Entry;
|
|
use App\Models\Event;
|
|
use App\Models\NominationEnsemble;
|
|
use App\Models\School;
|
|
use App\Models\Student;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
describe('StudentController::index', function () {
|
|
it('denies access to a non-admin user', function () {
|
|
$this->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();
|
|
});
|
|
});
|