auditionadmin/tests/Feature/app/Http/Controllers/StudentControllerTest.php

226 lines
9.1 KiB
PHP

<?php
use App\Models\Audition;
use App\Models\School;
use App\Models\Student;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->school = School::factory()->create();
$this->submitData = [
'first_name' => 'John',
'last_name' => 'Doe',
'grade' => 8,
];
$this->updateData = [
'first_name' => 'George',
'last_name' => 'Washington',
'grade' => 53,
];
});
describe('Test the index method of the student controller', function () {
it('redirects to the dashboard if the user does not have a school', function () {
$user = User::factory()->create();
$this->actingAs($user);
$response = $this->get(route('students.index'));
$response->assertRedirect(route('dashboard'));
actAsAdmin();
$response = $this->get(route('students.index'));
$response->assertRedirect(route('dashboard'));
});
it('redirects to the students index if the user has a school', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
$this->actingAs($user);
$response = $this->get(route('students.index'));
$response->assertOk();
});
it('returns the view students.index', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$audition = Audition::factory()->create();
$student = Student::factory()->forSchool($school)->create();
$user->school_id = $school->id;
$user->save();
$this->actingAs($user);
$response = $this->get(route('students.index'));
$response->assertViewIs('students.index')
->assertViewHas('students', function ($students) use ($student) {
return $students->contains($student);
})
->assertViewHas('auditions', function ($auditions) use ($audition) {
return $auditions->contains($audition);
})
->assertSee(route('students.store'));
});
});
describe('Test the store method of the student controller', function () {
it('redirects to the dashboard if the user does not have a school', function () {
$user = User::factory()->create();
//$user->update(['school_id' => School::factory()->create()->id]);;
$this->actingAs($user);
$response = $this->post(route('students.store'), $this->submitData);
$response->assertStatus(403);
});
it('creates a student with only basic information', function () {
$user = User::factory()->create();
$user->school_id = $this->school->id;
$user->save();
$this->actingAs($user);
$response = $this->post(route('students.store'), $this->submitData);
$response->assertRedirect(route('students.index'));
expect(Student::first())->toBeInstanceOf(Student::class)
->and(Student::first()->first_name)->toEqual('John')
->and(Student::first()->last_name)->toEqual('Doe')
->and(Student::first()->grade)->toEqual(8)
->and(Student::first()->school_id)->toEqual($this->school->id);
});
it('does not allow a user to create a student for another school', function () {
$user = User::factory()->create();
$user->school_id = $this->school->id;
$user->save();
$this->actingAs($user);
$otherSchool = School::factory()->create();
$localData = $this->submitData;
$localData['school_id'] = $otherSchool->id;
$response = $this->post(route('students.store'), $localData);
$response->assertRedirect(route('students.index'));
expect(Student::first())->toBeInstanceOf(Student::class)
->and(Student::first()->first_name)->toEqual('John')
->and(Student::first()->last_name)->toEqual('Doe')
->and(Student::first()->grade)->toEqual(8)
->and(Student::first()->school_id)->toEqual($this->school->id);
});
it('creates a student with optional data', function () {
$user = User::factory()->create();
$user->school_id = $this->school->id;
$user->save();
$this->actingAs($user);
$localData = $this->submitData;
$localData['optional_data'] = ['shirt_size' => 'M'];
$response = $this->post(route('students.store'), $localData);
$response->assertRedirect(route('students.index'));
expect(Student::first()->optional_data['shirt_size'])->toEqual('M');
});
it('will not allow a user to create a student for another school', function () {
$otherSchool = School::factory()->create();
$user = User::factory()->create();
$user->school_id = $this->school->id;
$user->save();
$this->actingAs($user);
$localData = $this->submitData;
$localData['school_id'] = $otherSchool->id;
$response = $this->post(route('students.store'), $localData);
expect(Student::first()->school_id)->toBe($this->school->id);
});
});
describe('Test the edit method of the student controller', function () {
it('will not allow a user to edit a student from another school', function () {
$otherStudent = Student::factory()->create();
$user = User::factory()->create();
$user->school_id = $this->school->id;
$user->save();
$this->actingAs($user);
$response = $this->get(route('students.edit', $otherStudent));
$response->assertStatus(403);
});
it('produces an edit for for a student', function () {
$user = User::factory()->create();
$user->school_id = $this->school->id;
$user->save();
$student = Student::factory()->forSchool($this->school)->create();
$this->actingAs($user);
$response = $this->get(route('students.edit', $student));
$response->assertViewIs('students.edit')
->assertViewHas('student', $student)
->assertSee(route('students.update', $student));
});
});
describe('Test the update method of the student controller', function () {
it('will not allow a user to edit a student from another school', function () {
$otherStudent = Student::factory()->create();
$user = User::factory()->create();
$user->school_id = $this->school->id;
$user->save();
$this->actingAs($user);
expect($otherStudent->school_id)->not->toEqual($this->school->id);
$response = $this->patch(route('students.update', $otherStudent), $this->submitData);
$response->assertStatus(403);
});
it('modifies a student with only basic information', function () {
$user = User::factory()->create();
$user->school_id = $this->school->id;
$user->save();
$this->actingAs($user);
$this->post(route('students.store'), $this->submitData);
$response = $this->patch(route('students.update', Student::first()), $this->updateData);
$response->assertRedirect(route('students.index'));
expect(Student::first())->toBeInstanceOf(Student::class)
->and(Student::first()->first_name)->toEqual('George')
->and(Student::first()->last_name)->toEqual('Washington')
->and(Student::first()->grade)->toEqual(53)
->and(Student::first()->school_id)->toEqual($this->school->id);
});
it('modifies a student with optional data', function () {
$user = User::factory()->create();
$user->school_id = $this->school->id;
$user->save();
$this->actingAs($user);
$localData = $this->submitData;
$localData['optional_data'] = ['shirt_size' => 'M'];
$this->post(route('students.store'), $localData);
$localUpdateData = $this->updateData;
$localUpdateData['optional_data'] = ['shirt_size' => 'XL'];
$response = $this->patch(route('students.update', Student::first()), $localUpdateData);
$response->assertRedirect(route('students.index'));
expect(Student::first()->optional_data['shirt_size'])->toEqual('XL');
});
});
describe('Test the destroy method of the student controller', function () {
it('will not allow a user to delete a student from another school', function () {
$otherStudent = Student::factory()->create();
$user = User::factory()->create();
$user->school_id = $this->school->id;
$user->save();
$this->actingAs($user);
expect($otherStudent->school_id)->not->toEqual($this->school->id);
$response = $this->delete(route('students.destroy', $otherStudent));
$response->assertStatus(403);
});
it('allows a user to delete their own students', function () {
$student = Student::factory()->forSchool($this->school)->create();
$user = User::factory()->create();
$user->school_id = $this->school->id;
$user->save();
$this->actingAs($user);
$response = $this->delete(route('students.destroy', $student));
$response->assertRedirect(route('students.index'));
expect(Student::first())->toBeNull();
});
});