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

386 lines
14 KiB
PHP

<?php
use App\Models\School;
use App\Models\SchoolEmailDomain;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use function Pest\Laravel\actingAs;
uses(RefreshDatabase::class);
describe('store method', function () {
it('will not allow a user to create a school if they already have one', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$response = $this->post(route('schools.store'), [
'name' => 'Test School',
'address' => '123 Test St',
'city' => 'Testville',
'state' => 'TX',
'zip' => '12345',
'phone' => '123-456-7890',
'email' => '<EMAIL>',
'website' => 'https://test.com',
]);
$response->assertStatus(403);
});
it('will allow a user with no schools to create one', function () {
$user = User::factory()->create();
actingAs($user);
$response = $this->post(route('schools.store'), [
'name' => 'Test School',
'address' => '123 Test St',
'city' => 'Testville',
'state' => 'TX',
'zip' => '12345',
]);
$school = School::first();
expect($school->name)->toEqual('Test School')
->and($school->address)->toEqual('123 Test St')
->and($school->city)->toEqual('Testville')
->and($school->state)->toEqual('TX')
->and($school->zip)->toEqual('12345');
});
it('will redirect on success', function () {
$user = User::factory()->create();
actingAs($user);
$response = $this->post(route('schools.store'), [
'name' => 'Test School',
'address' => '123 Test St',
'city' => 'Testville',
'state' => 'TX',
'zip' => '12345',
]);
$response->assertRedirect(route('schools.show', $user->school_id));
});
it('will assign the user to the new school', function () {
$user = User::factory()->create();
actingAs($user);
$response = $this->post(route('schools.store'), [
'name' => 'Test School',
'address' => '123 Test St',
'city' => 'Testville',
'state' => 'TX',
'zip' => '12345',
]);
$user->refresh();
expect($user->school_id)->toEqual(School::first()->id);
});
it('will make the user head director', function () {
$user = User::factory()->create();
actingAs($user);
$response = $this->post(route('schools.store'), [
'name' => 'Test School',
'address' => '123 Test St',
'city' => 'Testville',
'state' => 'TX',
'zip' => '12345',
]);
$user->refresh();
expect($user->hasFlag('head_director'))->toBeTrue();
});
});
describe('show method', function () {
it('will not allow the user to view a school they are not a member of', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$otherSchool = School::factory()->create();
$response = $this->get(route('schools.show', $otherSchool->id));
$response->assertStatus(403);
});
it('shows the view page for the users school', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$response = $this->get(route('schools.show', $school->id));
$response->assertStatus(200);
});
});
describe('create method', function () {
it('will not allow a user to create a school if they already have one', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$response = $this->get(route('schools.create'));
$response->assertStatus(403);
});
it('shows a school creation form', function () {
$user = User::factory()->create();
actingAs($user);
$response = $this->get(route('schools.create'));
$response->assertStatus(200)
->assertViewIs('schools.create');
});
});
describe('edit method', function () {
it('will not allow a user to edit a school that is not theirs', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$otherSchool = School::factory()->create();
$response = $this->get(route('schools.edit', $otherSchool));
$response->assertStatus(403);
});
it('shows a school edit form for the users school', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$response = $this->get(route('schools.edit', $school));
$response->assertStatus(200)
->assertViewIs('schools.edit');
});
});
describe('update method', function () {
it('will not allow a user to update a school that is not theirs', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$otherSchool = School::factory()->create();
$response = $this->patch(route('schools.update', $otherSchool));
$response->assertStatus(403);
});
it('will update the users school', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
expect($school->name === 'Eastman')->toBeFalse();
$response = $this->patch(route('schools.update', $school), [
'name' => 'Eastman',
'address' => '26 Gibbs Street',
'city' => 'Rochester',
'state' => 'NY',
'zip' => '14604',
]);
$response->assertSessionHasNoErrors()
->assertRedirect(route('schools.show', $school));
expect($school->name === 'Eastman')->toBeFalse();
});
});
describe('addDirector method', function () {
it('will not all the user to add users to another school', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$otherSchool = School::factory()->create();
$response = $this->post(route('schools.add_director', $otherSchool));
$response->assertStatus(403);
});
it('will only add users for the head director role', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$response = $this->post(route('schools.add_director', $school));
$response->assertStatus(403);
});
it('will add a user to the school for the head director', function () {
Mail::fake();
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
$user->addFlag('head_director');
actingAs($user);
expect(User::count())->toEqual(1);
$response = $this->post(route('schools.add_director', $school), [
'first_name' => 'Jean Luc',
'last_name' => 'Picard',
'email' => 'j.picard@starfleet.com',
'cell_phone' => '1701',
'judging_preference' => 'Shut up Wesley',
]);
expect(User::count())->toEqual(2);
Mail::assertSentCount(1);
});
});
describe('setHeadDirector method', function () {
it('will not allow a director to alter another school', function () {
$school = School::factory()->create();
$user = User::factory()->create();
$otherUser = User::factory()->create();
$user->school_id = $school->id;
$user->save();
$otherUser->school_id = $school->id;
$otherUser->save();
$user->addFlag('head_director');
actingAs($user);
$otherSchool = School::factory()->create();
$response = $this->get(route('schools.set_head_director', [$otherSchool, $otherUser]));
$response->assertStatus(403);
});
it('only a head director can replace themselves', function () {
$school = School::factory()->create();
$user = User::factory()->create();
$otherUser = User::factory()->create();
$user->school_id = $school->id;
$user->save();
$otherUser->school_id = $school->id;
$otherUser->save();
actingAs($user);
$response = $this->get(route('schools.set_head_director', [$school, $otherUser]));
$response->assertStatus(403);
});
it('you can only promote users at your school', function () {
$school = School::factory()->create();
$user = User::factory()->create();
$otherUser = User::factory()->create();
$user->school_id = $school->id;
$user->save();
$user->addFlag('head_director');
actingAs($user);
$response = $this->get(route('schools.set_head_director', [$school, $otherUser]));
$response->assertStatus(403);
});
it('promotes another director', function () {
$school = School::factory()->create();
$user = User::factory()->create();
$otherUser = User::factory()->create();
$user->school_id = $school->id;
$user->save();
$otherUser->school_id = $school->id;
$otherUser->save();
$user->addFlag('head_director');
actingAs($user);
$response = $this->get(route('schools.set_head_director', [$school, $otherUser]));
$response->assertRedirect(route('schools.show', $school))
->assertSessionHas('success');
$user->refresh();
$otherUser->refresh();
expect($user->hasFlag('head_director'))->toBeFalse();
expect($otherUser->hasFlag('head_director'))->toBeTrue();
// TODO: Mock the promoter action so we can test the exception handling
});
});
describe('addDomain method', function () {
it('will not allow a user to add a domain to a school they are not a member of', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$otherSchool = School::factory()->create();
$response = $this->post(route('schools.add_domain', $otherSchool));
$response->assertStatus(403);
});
it('will only allow a head director to add a domain', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$response = $this->post(route('schools.add_domain', $school));
$response->assertStatus(403);
});
it('will add a domain to the school', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
$user->addFlag('head_director');
$user->refresh();
actingAs($user);
$response = $this->post(route('schools.add_domain', $school), [
'domain' => 'test.com',
]);
$response->assertRedirect(route('schools.show', $school))
->assertSessionHas('success');
$school->refresh();
expect(SchoolEmailDomain::where('domain', 'test.com')
->where('school_id', $school->id)
->exists())->toBeTrue();
});
});
describe('removeDomain method', function () {
it('will not allow a user to remove a domain from a school they are not a member of', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$otherSchool = School::factory()->create();
$domain = SchoolEmailDomain::create([
'school_id' => $otherSchool->id,
'domain' => 'test.com',
]);
$response = $this->get(route('schools.delete_domain', $domain));
$response->assertStatus(403);
});
it('will only allow a head director to remove a domain', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
actingAs($user);
$domain = SchoolEmailDomain::create([
'school_id' => $school->id,
'domain' => 'test.com',
]);
$response = $this->get(route('schools.delete_domain', $domain));
$response->assertStatus(403);
});
it('will remove a domain from the school', function () {
$user = User::factory()->create();
$school = School::factory()->create();
$user->school_id = $school->id;
$user->save();
$user->addFlag('head_director');
$domain = SchoolEmailDomain::create([
'school_id' => $school->id,
'domain' => 'test.com',
]);
actingAs($user);
$response = $this->get(route('schools.delete_domain', $domain));
$response->assertRedirect(route('schools.show', $school))
->assertSessionHas('success');
$school->refresh();
expect(SchoolEmailDomain::where('domain', 'test.com')
->where('school_id', $school->id)
->exists())->toBeFalse();
});
});