auditionadmin/tests/Feature/Pages/StudentsIndexTest.php

229 lines
6.1 KiB
PHP

<?php
use App\Models\Entry;
use App\Models\School;
use App\Models\Student;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use function Pest\Laravel\delete;
use function Pest\Laravel\get;
use function Pest\Laravel\post;
uses(RefreshDatabase::class);
it('cannot be accessed by a guest', function () {
// Act & Assert
get(route('students.index'))
->assertStatus(302)
->assertRedirect(route('home'));
});
it('cannot be accessed by a user without a school', function () {
// Arrange
$user = User::factory()->create();
$userWithSchool = User::factory()->create([
'school_id' => School::factory()->create()->id,
]);
// Act & Assert
$this->actingAs($user);
get('/students')
->assertStatus(403);
$this->actingAs($userWithSchool);
get('/students')
->assertStatus(200);
});
it('Shows a student for the user', function () {
// Arrange
$school = School::factory()->create();
$user = User::factory()->create([
'school_id' => $school->id,
]);
$student = Student::factory()->create([
'school_id' => $school->id,
]);
$students = [
['first_name' => 'John', 'last_name' => 'Lennon'],
['first_name' => 'Paul', 'last_name' => 'McCartney'],
['first_name' => 'George', 'last_name' => 'Harrison'],
['first_name' => 'Ringo', 'last_name' => 'Starr'],
];
foreach ($students as $s) {
Student::factory()->create([
'school_id' => $school->id,
'first_name' => $s['first_name'],
'last_name' => $s['last_name'],
]);
}
// Act and Assert
$this->actingAs($user);
get(route('students.index'))
->assertStatus(200)
->assertSeeText($student->name)
->assertSeeText(['Lennon, John', 'McCartney, Paul', 'Harrison, George', 'Starr, Ringo']);
});
it('does not show a student from another school', function () {
// Arrange
$school = School::factory()->create();
$user = User::factory()->create([
'school_id' => $school->id,
]);
$student = Student::factory()->create([
'school_id' => $school->id,
]);
$otherSchool = School::factory()->create();
$otherStudent = Student::factory()->create([
'school_id' => $otherSchool->id,
]);
// Act & Assert
$this->actingAs($user);
get(route('students.index'))
->assertStatus(200)
->assertSeeText($student->name)
->assertDontSeeText($otherStudent->name);
// Assert
});
it('can accept a new student entry', function () {
// Act and Assert
$school = School::factory()->create();
$user = User::factory()->create([
'school_id' => $school->id,
]);
$this->actingAs($user);
post(route('students.store'), [
'first_name' => 'James',
'last_name' => 'Brown',
'grade' => 10,
])
->assertSessionHasNoErrors()
->assertRedirect(route('students.index'));
get(route('students.index'))
->assertSeeText('Brown, James');
expect(Student::count())->toBe(1);
});
it('cannot have two students with identical names at a school', function () {
$school = School::factory()->create();
$user = User::factory()->create([
'school_id' => $school->id,
]);
Student::factory()->create([
'school_id' => $school->id,
'first_name' => 'James',
'last_name' => 'Brown',
]);
$this->actingAs($user);
post(route('students.store'), [
'first_name' => 'James',
'last_name' => 'Brown',
'grade' => 10,
])
->assertSessionHasErrors('last_name');
});
it('shows a delete link only if the student has no entries', function () {
// Arrange
$school = School::factory()->create();
$user = User::factory()->create([
'school_id' => $school->id,
]);
$studentWithNoEntries = Student::factory()->create([
'school_id' => $school->id,
]);
$studentWithEntries = Student::factory()->create([
'school_id' => $school->id,
]);
Entry::factory()->create([
'student_id' => $studentWithEntries->id,
]);
// Act & Assert
$this->actingAs($user);
get(route('students.index'))
->assertSee(route('students.destroy', $studentWithNoEntries))
->assertDontSeeText(route('students.destroy', $studentWithEntries));
});
it('shows an edit link for each student', function () {
// Arrange
$school = School::factory()->create();
$user = User::factory()->create([
'school_id' => $school->id,
]);
$students = Student::factory(3)->create([
'school_id' => $school->id,
]);
// Act & Assert
foreach ($students as $student) {
$this->actingAs($user);
get(route('students.index'))
->assertSee(route('students.edit', $student));
}
});
it('deletes a student with no entries', function () {
// Arrange
$school = School::factory()->create();
$user = User::factory()->create([
'school_id' => $school->id,
]);
$student = Student::factory()->create([
'school_id' => $school->id,
'first_name' => 'John Jacob',
]);
// Act & Assert
$this->actingAs($user);
get(route('students.index'))
->assertSee('John Jacob');
expect($student->exists())->toBeTrue();
delete(route('students.destroy', $student))
->assertSessionHasNoErrors()
->assertRedirect(route('students.index'));
expect($student->exists())->toBeFalse();
get(route('students.index'))
->assertOk()
->assertDontSee('John Jacob');
});
it('will not delete a student from another school', function () {
// Arrange
$school = School::factory()->create();
$user = User::factory()->create([
'school_id' => $school->id,
]);
$student = Student::factory()->create([
'first_name' => 'John Jacob',
]);
// Act & Assert
expect($student->exists())->toBeTrue();
$this->actingAs($user);
get(route('students.index'))
->assertOk()
->assertDontSee('John Jacob');
delete(route('students.destroy', $student))
->assertStatus(403);
expect($student->exists())->toBeTrue();
});