diff --git a/app/Http/Controllers/Admin/SchoolController.php b/app/Http/Controllers/Admin/SchoolController.php index af0ea3c..c081cfb 100644 --- a/app/Http/Controllers/Admin/SchoolController.php +++ b/app/Http/Controllers/Admin/SchoolController.php @@ -56,10 +56,6 @@ class SchoolController extends Controller public function update(School $school) { - if (! Auth::user()->is_admin) { - abort(403); - } - request()->validate([ 'name' => ['required'], 'address' => ['required'], diff --git a/database/factories/SchoolEmailDomainFactory.php b/database/factories/SchoolEmailDomainFactory.php new file mode 100644 index 0000000..e6f4646 --- /dev/null +++ b/database/factories/SchoolEmailDomainFactory.php @@ -0,0 +1,26 @@ + + */ +class SchoolEmailDomainFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + $school = School::factory()->create(); + return [ + 'school_id' => $school->id, + 'domain' => $this->faker->domainName, + ]; + } +} diff --git a/resources/views/admin/schools/edit.blade.php b/resources/views/admin/schools/edit.blade.php index cb3fe60..99b93a9 100644 --- a/resources/views/admin/schools/edit.blade.php +++ b/resources/views/admin/schools/edit.blade.php @@ -1,7 +1,45 @@ - + + Edit School + + + + + + + + + + Update School + + + - + + Associated Domains + + @foreach($school->emailDomains as $domain) + +
+ @csrf + @method('DELETE') + {{ $domain->domain }} +
+
+ @endforeach + +
+ @csrf + Add Domain + +
+
+
diff --git a/tests/Feature/Pages/Admin/SchoolsCreateTest.php b/tests/Feature/Pages/Admin/SchoolsCreateTest.php index 23a26aa..5420d16 100644 --- a/tests/Feature/Pages/Admin/SchoolsCreateTest.php +++ b/tests/Feature/Pages/Admin/SchoolsCreateTest.php @@ -17,11 +17,11 @@ beforeEach(function () { it('only shows for an admin user', function () { // Act & Assert $checkRoute = 'admin.schools.create'; - get(route($checkRoute, $this->school))->assertRedirect(route('home')); + get(route($checkRoute))->assertRedirect(route('home')); actingAs($this->adminUser); - get(route($checkRoute, $this->school))->assertOk(); + get(route($checkRoute))->assertOk(); actingAs($this->nonAdminUser); - get(route($checkRoute, $this->school))->assertRedirect(route('dashboard')); + get(route($checkRoute))->assertRedirect(route('dashboard')); }); it('submits a post request', function () { // Arrange diff --git a/tests/Feature/Pages/Admin/SchoolsEditTest.php b/tests/Feature/Pages/Admin/SchoolsEditTest.php new file mode 100644 index 0000000..149921c --- /dev/null +++ b/tests/Feature/Pages/Admin/SchoolsEditTest.php @@ -0,0 +1,192 @@ +adminUser = User::factory()->admin()->create(); + $this->nonAdminUser = User::factory()->create(); + $this->tabUser = User::factory()->tab()->create(); + $this->school = School::factory()->create(); +}); +it('only shows for an admin user', function () { + // Act & Assert + $checkRoute = 'admin.schools.edit'; + get(route($checkRoute, $this->school))->assertRedirect(route('home')); + actingAs($this->adminUser); + get(route($checkRoute, $this->school))->assertOk(); + actingAs($this->nonAdminUser); + get(route($checkRoute, $this->school))->assertRedirect(route('dashboard')); +}); +it('submits a patch request', function () { + // Arrange + actingAs($this->adminUser); + // Act & Assert + $response = get(route('admin.schools.edit', $this->school)); + $response->assertOk(); + $response->assertSeeInOrder([ + 'form', + 'method', + 'POST', + 'action=', + route('admin.schools.update', $this->school), + '/form', + ]); + $response->assertSee('', false); +}); +it('has all needed fields', function () { + // Arrange + actingAs($this->adminUser); + $fieldNames = [ + 'name', + 'address', + 'city', + 'state', + 'zip', + ]; + // Act & Assert + $response = get(route('admin.schools.edit', $this->school)); + $response->assertOk(); + foreach ($fieldNames as $fieldName) { + $response->assertSeeInOrder([ + 'input', + 'name=', + $fieldName, + '/', + ]); + } +}); +it('rejects a submission by a non administrator', function () { + // Arrange + actingAs($this->nonAdminUser); + // Act & Assert + $response = patch(route('admin.schools.update', $this->school), [ + 'name' => 'Hacker High', + 'address' => 'Lost Highway', + ]); + $response->assertRedirect(route('dashboard')); +}); +it('allows an administrator to update a school', function () { + // Arrange + actingAs($this->adminUser); + $newData = [ + 'name' => fake()->city(), + 'address' => fake()->streetAddress(), + 'city' => fake()->city(), + 'state' => 'OK', + 'zip' => fake()->postcode(), + ]; + // Act + $response = patch(route('admin.schools.update', $this->school), $newData); + /** @noinspection PhpUnhandledExceptionInspection */ + $response + ->assertSessionHasNoErrors() + ->assertRedirect(route('admin.schools.show', $this->school)); + + $this->school->refresh(); + + expect($this->school->name)->toBe($newData['name']) + ->and($this->school->address)->toBe($newData['address']) + ->and($this->school->city)->toBe($newData['city']) + ->and($this->school->state)->toBe($newData['state']) + ->and($this->school->zip)->toEqual($newData['zip']); + + get(route('admin.schools.index')) + ->assertOk() + ->assertSee($newData['name']); +}); +it('has a domain add form', function () { + // Arrange + actingAs($this->adminUser); + // Act & Assert + get(route('admin.schools.edit', $this->school)) + ->assertOk() + ->assertSeeInOrder([ + 'form', + 'method', + 'POST', + 'action=', + route('admin.schools.add_domain', $this->school), + '/form', + ]); +}); +it('as a field to submit a new domain', function () { + // Arrange + actingAs($this->adminUser); + // Act & Assert + get(route('admin.schools.edit', $this->school)) + ->assertOk() + ->assertSeeInOrder([ + 'input', + 'name=', + 'domain', + '/', + ]); +}); +it('allows an administrator to add a domain and shows it on the school edit page', function () { + // Arrange + actingAs($this->adminUser); + $newDomain = 'example.com'; + // Act + $response = post(route('admin.schools.add_domain', $this->school), ['domain' => $newDomain]); + /** @noinspection PhpUnhandledExceptionInspection */ + $response + ->assertSessionHasNoErrors() + ->assertRedirect(route('admin.schools.edit', $this->school)); + + $this->school->refresh(); + + $this->assertDatabaseHas('school_email_domains', ['school_id' => $this->school->id, 'domain' => $newDomain]); + + get(route('admin.schools.edit', $this->school)) + ->assertOk() + ->assertSee($newDomain); +}); +it('rejects a domain submission by a non administrator', function () { + // Arrange + actingAs($this->nonAdminUser); + // Act & Assert + $response = post(route('admin.schools.add_domain', $this->school), ['domain' => 'example.com']); + $response->assertRedirect(route('dashboard')); +}); +it('shows a delete button for each domain', function () { + // Arrange + actingAs($this->adminUser); + $domain = $this->school->emailDomains()->create(['domain' => 'example.com']); + // Act & Assert + get(route('admin.schools.edit', $this->school)) + ->assertOk() + ->assertSee(route('admin.schools.destroy_domain', $domain)); +}); +it('allows an admin to delete a domain', function () { + // Arrange + session()->setPreviousUrl(route('admin.schools.edit', $this->school)); + actingAs($this->adminUser); + $domain = $this->school->emailDomains()->create(['domain' => 'example.com']); + // Act + $response = delete(route('admin.schools.destroy_domain', $domain)); + /** @noinspection PhpUnhandledExceptionInspection */ + $response + ->assertSessionHasNoErrors() + ->assertRedirect(route('admin.schools.edit', $this->school)); + + $this->assertDatabaseMissing('school_email_domains', ['id' => $domain->id]); + +}); +it('does not allow a non admin user to delete a domain', function () { + // Arrange + actingAs($this->nonAdminUser); + $domain = SchoolEmailDomainFactory::new()->create(); + // Act & Assert + $response = delete(route('admin.schools.destroy_domain', $domain)); + $response->assertRedirect(route('dashboard')); +});