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

329 lines
13 KiB
PHP

<?php
use App\Models\School;
use App\Models\SchoolEmailDomain;
use App\Models\Student;
use App\Models\User;
use App\Services\Invoice\InvoiceDataService;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
beforeEach(function () {
/** @noinspection PhpUnhandledExceptionInspection */
$mockInvoice = $this->createMock(InvoiceDataService::class);
$mockInvoice->method('getGrandTotal')->willReturn(40.00);
$this->app->instance(InvoiceDataService::class, $mockInvoice);
});
describe('SchoolController::index', function () {
it('denies access to a non-admin user', function () {
$this->get(route('admin.schools.index'))
->assertRedirect(route('home'));
actAsNormal();
$this->get(route('admin.schools.index'))
->assertRedirect(route('dashboard'));
actAsTab();
$this->get(route('admin.schools.index'))
->assertRedirect(route('dashboard'));
});
it('shows all schools', function () {
School::factory()->count(3)->create();
actAsAdmin();
$response = $this->get(route('admin.schools.index'));
$response->assertOk();
foreach (School::all() as $school) {
$response->assertSee($school->name);
}
$response->assertSee('$40.00');
});
});
describe('SchoolController::show', function () {
beforeEach(function () {
$this->school = School::factory()->create();
});
it('denies access to a non-admin user', function () {
$this->get(route('admin.schools.show', $this->school))
->assertRedirect(route('home'));
actAsNormal();
$this->get(route('admin.schools.show', $this->school))
->assertRedirect(route('dashboard'));
actAsTab();
$this->get(route('admin.schools.show', $this->school))
->assertRedirect(route('dashboard'));
});
it('shows the school details', function () {
actAsAdmin();
$response = $this->get(route('admin.schools.show', $this->school));
$response->assertOk();
$response->assertSee($this->school->name);
});
});
describe('SchoolController::edit', function () {
beforeEach(function () {
$this->school = School::factory()->create();
});
it('denies access to a non-admin user', function () {
$this->get(route('admin.schools.edit', $this->school))
->assertRedirect(route('home'));
actAsNormal();
$this->get(route('admin.schools.edit', $this->school))
->assertRedirect(route('dashboard'));
actAsTab();
$this->get(route('admin.schools.edit', $this->school))
->assertRedirect(route('dashboard'));
});
it('shows the school details', function () {
actAsAdmin();
$response = $this->get(route('admin.schools.edit', $this->school));
$response->assertOk();
$response->assertSee($this->school->name);
});
});
describe('SchoolController::update', function () {
beforeEach(function () {
$this->school = School::create([
'name' => 'Test School',
'address' => '123 4th street',
'city' => 'New York',
'state' => 'NY',
'zip' => '10001',
]);
$this->newData = [
'name' => 'New Name',
'address' => '567 8th street',
'city' => 'New Orleans',
'state' => 'LA',
'zip' => '70110',
];
});
it('denies access to a non-admin user', function () {
$this->patch(route('admin.schools.update', $this->school), $this->newData)
->assertRedirect(route('home'));
actAsNormal();
$this->patch(route('admin.schools.update', $this->school), $this->newData)
->assertRedirect(route('dashboard'));
actAsTab();
$this->patch(route('admin.schools.update', $this->school), $this->newData)
->assertRedirect(route('dashboard'));
});
it('updates the school', function () {
actAsAdmin();
$this->patch(route('admin.schools.update', $this->school), $this->newData);
$this->school->refresh();
$this->assertEquals($this->newData['name'], $this->newData['name']);
$this->assertEquals($this->newData['address'], $this->newData['address']);
$this->assertEquals($this->newData['city'], $this->newData['city']);
$this->assertEquals($this->newData['state'], $this->newData['state']);
$this->assertEquals($this->newData['zip'], $this->newData['zip']);
});
it('will not let us duplicate a name', function () {
$otherSchool = School::factory()->create();
$this->newData['name'] = $otherSchool->name;
actAsAdmin();
$response = $this->patch(route('admin.schools.update', $this->school), $this->newData);
$response->assertSessionHasErrors('name');
$this->school->refresh();
$this->assertNotEquals($this->school->name, $otherSchool->name);
});
it('will let us update other data and retain the name', function () {
$this->newData['name'] = 'Test School';
actAsAdmin();
$response = $this->patch(route('admin.schools.update', $this->school), $this->newData);
/** @noinspection PhpUnhandledExceptionInspection */
$response->assertSessionHasNoErrors();
$this->school->refresh();
$this->assertEquals($this->newData['address'], $this->newData['address']);
});
});
describe('SchoolController::create', function () {
it('denies access to a non-admin user', function () {
$this->get(route('admin.schools.create'))
->assertRedirect(route('home'));
actAsNormal();
$this->get(route('admin.schools.create'))
->assertRedirect(route('dashboard'));
actAsTab();
$this->get(route('admin.schools.create'))
->assertRedirect(route('dashboard'));
});
it('shows the school creation form', function () {
actAsAdmin();
$response = $this->get(route('admin.schools.create'));
$response->assertOk();
$response->assertSee('Create School');
});
});
describe('SchoolController::store', function () {
beforeEach(function () {
$this->newData = [
'name' => 'Test School',
'address' => '123 4th street',
'city' => 'New York',
'state' => 'NY',
'zip' => '10001',
];
});
it('denies access to a non-admin user', function () {
$this->post(route('admin.schools.store'), $this->newData)
->assertRedirect(route('home'));
actAsNormal();
$this->post(route('admin.schools.store'), $this->newData)
->assertRedirect(route('dashboard'));
actAsTab();
$this->post(route('admin.schools.store'), $this->newData)
->assertRedirect(route('dashboard'));
});
it('creates a new school', function () {
actAsAdmin();
/** @noinspection PhpUnhandledExceptionInspection */
$this->post(route('admin.schools.store'),
$this->newData)->assertRedirect(route('admin.schools.index'))->assertSessionHasNoErrors();
$newSchool = School::first();
expect($newSchool)->toBeInstanceOf(School::class)
->and($newSchool->name)->toEqual($this->newData['name'])
->and($newSchool->address)->toEqual($this->newData['address'])
->and($newSchool->city)->toEqual($this->newData['city'])
->and($newSchool->state)->toEqual($this->newData['state'])
->and($newSchool->zip)->toEqual($this->newData['zip']);
});
it('will not let us duplicate a name', function () {
$otherSchool = School::factory()->create();
$this->newData['name'] = $otherSchool->name;
actAsAdmin();
$this->post(route('admin.schools.store'), $this->newData)->assertSessionHasErrors('name');
$this->assertEquals(School::count(), 1);
});
});
describe('SchoolController::destroy', function () {
beforeEach(function () {
$this->school = School::factory()->create();
});
it('denies access to a non-admin user', function () {
$this->delete(route('admin.schools.destroy', $this->school))
->assertRedirect(route('home'));
actAsNormal();
$this->delete(route('admin.schools.destroy', $this->school))
->assertRedirect(route('dashboard'));
actAsTab();
$this->delete(route('admin.schools.destroy', $this->school))
->assertRedirect(route('dashboard'));
});
it('deletes a school', function () {
actAsAdmin();
$this->delete(route('admin.schools.destroy', $this->school))->assertRedirect(route('admin.schools.index'));
expect(School::count())->toEqual(0);
});
it('will not delete a school with students', function () {
Student::factory()->forSchool($this->school)->create();
actAsAdmin();
$response = $this->delete(route('admin.schools.destroy', $this->school));
$response->assertRedirect(route('admin.schools.index'))
->assertSessionHas('error', 'You cannot delete a school that has students.');
expect(School::count())->toEqual(1);
});
});
describe('SchoolController::add_domain', function () {
beforeEach(function () {
$this->school = School::factory()->create();
});
it('denies access to a non-admin user', function () {
$this->post(route('admin.schools.add_domain', $this->school))
->assertRedirect(route('home'));
actAsNormal();
$this->post(route('admin.schools.add_domain', $this->school))
->assertRedirect(route('dashboard'));
actAsTab();
$this->post(route('admin.schools.add_domain', $this->school))
->assertRedirect(route('dashboard'));
});
it('can add a domain to a school', function () {
actAsAdmin();
$this->post(route('admin.schools.add_domain', $this->school),
['domain' => 'test.com'])->assertRedirect(route('admin.schools.show', $this->school));
$this->school->refresh();
expect($this->school->emailDomains)->toHaveCount(1)
->and($this->school->emailDomains->first()->domain)->toEqual('test.com');
});
});
describe('SchoolController::remove_domain', function () {
beforeEach(function () {
$this->school = School::factory()->create();
$this->domain = SchoolEmailDomain::create([
'school_id' => $this->school->id,
'domain' => 'test.com',
]);
});
it('denies access to a non-admin user', function () {
$this->delete(route('admin.schools.destroy_domain', $this->domain))
->assertRedirect(route('home'));
actAsNormal();
$this->delete(route('admin.schools.destroy_domain', $this->domain))
->assertRedirect(route('dashboard'));
actAsTab();
$this->delete(route('admin.schools.destroy_domain', $this->domain))
->assertRedirect(route('dashboard'));
});
it('can remove a domain from a school', function () {
actAsAdmin();
$this->delete(route('admin.schools.destroy_domain', $this->domain))->assertSessionHas('success',
'Domain removed successfully.');
$this->school->refresh();
expect($this->school->emailDomains)->toHaveCount(0);
});
});
describe('SchoolController::setHeadDirector', function () {
beforeEach(function () {
$this->school = School::factory()->create();
$this->oldHeadDirector = User::factory()->forSchool($this->school)->create();
$this->oldHeadDirector->addFlag('head_director');
$this->newHeadDirector = User::factory()->forSchool($this->school)->create();
$this->uneployedDirector = User::factory()->create();
});
it('denies access to a non-admin user', function () {
$this->get(route('admin.schools.set_head_director', [$this->school, $this->newHeadDirector]))
->assertRedirect(route('home'));
actAsNormal();
$this->get(route('admin.schools.set_head_director', [$this->school, $this->newHeadDirector]))
->assertRedirect(route('dashboard'));
actAsTab();
$this->get(route('admin.schools.set_head_director', [$this->school, $this->newHeadDirector]))
->assertRedirect(route('dashboard'));
});
it('can set a new head director', function () {
actAsAdmin();
$this->get(route('admin.schools.set_head_director', [$this->school, $this->newHeadDirector]))
->assertSessionHas('success', 'Head director set successfully.');
$this->school->refresh();
$this->oldHeadDirector->refresh();
$this->newHeadDirector->refresh();
expect($this->oldHeadDirector->hasFlag('head_director'))->toBeFalse()
->and($this->newHeadDirector->hasFlag('head_director'))->toBeTrue();
});
it('will not promote a user a the wrong school', function () {
actAsAdmin();
$this->get(route('admin.schools.set_head_director', [$this->school, $this->uneployedDirector]))
->assertSessionHas('error', 'That user is not at that school');
$this->school->refresh();
$this->oldHeadDirector->refresh();
$this->newHeadDirector->refresh();
expect($this->oldHeadDirector->hasFlag('head_director'))->toBeTrue()
->and($this->newHeadDirector->hasFlag('head_director'))->toBeFalse()
->and($this->uneployedDirector->hasFlag('head_director'))->toBeFalse();
});
});