From 9fa13503dc873274c6eabc9b64efa2f69c47dde0 Mon Sep 17 00:00:00 2001 From: MichalMyskow Date: Wed, 11 May 2022 22:43:23 +0200 Subject: [PATCH] Squashed commit of the following: commit 5dd4a7e5cabd451ec2c083aa424b2a9af60e3c8c Author: Anna-Sokolowska Date: Wed May 11 15:39:03 2022 +0200 #89 - cs-fix commit 88dc36601dc593ebb3ade891298e14e82ec7badd Merge: 56b5dfd 86a33bb Author: Anna-Sokolowska Date: Wed May 11 13:33:24 2022 +0200 Merge remote-tracking branch 'origin/#89-unit-tests' into #89-unit-tests commit 56b5dfdbcb4772295f343b0f303877cccc4341ef Author: Anna-Sokolowska Date: Wed May 11 13:32:32 2022 +0200 #89 - fix wrong admin invitation receiver commit d6cd83472a5458520ef62ca6c99d53224641ed29 Author: Anna-Sokolowska Date: Wed May 11 13:29:20 2022 +0200 #89 - add organization profile scope bindings commit 86a33bb26240c8af20e098d2a0cc6028fccec226 Author: Anna-Sokolowska Date: Wed May 11 11:34:21 2022 +0200 #89 - add cache views commit d95551eaf6dcbac42070d367e673af602d773702 Author: Anna-Sokolowska Date: Wed May 11 09:21:08 2022 +0200 #89 - add .env.ci commit 202c4d7b48b82553aa836ef7921a96da5ce76153 Author: Anna-Sokolowska Date: Wed May 11 06:37:01 2022 +0200 #89 - refactor tests commit a851f81d27d0fe08dd81a459053ddaa35389ebc7 Merge: 5ae0b73 e554018 Author: Anna-Sokolowska Date: Tue May 10 19:57:25 2022 +0200 Merge branch 'main' into #89-unit-tests commit 5ae0b73af3dcda1f183a71f36cc86edb69da3337 Author: Anna-Sokolowska Date: Tue May 10 19:53:53 2022 +0200 #89 - cs-fix commit 7d7edd2e3bda26b904583b408e4c4c408759b82e Merge: dbcba11 9a47c51 Author: Anna-Sokolowska Date: Tue May 10 09:53:13 2022 +0200 Merge branch 'main' into #89-unit-tests commit dbcba1154fe5fca4ee85c668d08de7c3da44ed5e Author: Anna-Sokolowska Date: Tue May 10 09:41:43 2022 +0200 #89 - basic features tests commit 8120c8dd49860d7b1dd093f90ad94228d49c69bb Merge: bd8c792 b24753d Author: Anna-Sokolowska Date: Sat May 7 20:40:04 2022 +0200 Merge branch 'main' into #89-unit-tests commit bd8c7922dde05bd956efb90d148e55076f9c541e Author: Anna-Sokolowska Date: Fri May 6 13:22:59 2022 +0200 #89 - unit tests init --- .env.ci | 18 +++++ .github/workflows/php.yml | 3 + bootstrap/app.php | 24 ++++++ bootstrap/cache/.gitignore | 2 + phpunit.xml | 4 +- .../OrganizationProfileController.php | 12 +-- src/Http/Routing/WebRouting.php | 6 +- src/Services/InvitationsService.php | 3 +- tests/CreatesApplication.php | 20 +++++ tests/Feature/ContactTest.php | 57 +++++++++++++ tests/Feature/InviteAdminTest.php | 59 ++++++++++++++ tests/Feature/Meetups/BrowseMeetupsTest.php | 71 +++++++++++++++++ tests/Feature/Meetups/CreateMeetupsTest.php | 68 ++++++++++++++++ tests/Feature/Meetups/DeleteMeetupsTest.php | 48 +++++++++++ tests/Feature/Meetups/EditMeetupsTest.php | 74 +++++++++++++++++ tests/Feature/NewsletterTest.php | 39 +++++++++ .../Organizations/BrowseOrganizationsTest.php | 52 ++++++++++++ .../Organizations/CreateOrganizationsTest.php | 69 ++++++++++++++++ .../Organizations/DeleteOrganizationsTest.php | 48 +++++++++++ .../Organizations/EditOrganizationsTest.php | 69 ++++++++++++++++ .../CreateOrganizationProfilesTest.php | 64 +++++++++++++++ .../DeleteOrganizationProfilesTest.php | 63 +++++++++++++++ .../Profiles/EditOrganizationProfilesTest.php | 79 +++++++++++++++++++ .../OrganizationProfilesRequestTest.php | 52 ++++++++++++ tests/Feature/Speakers/BrowseSpeakersTest.php | 51 ++++++++++++ tests/Feature/Speakers/CreateSpeakersTest.php | 62 +++++++++++++++ tests/Feature/Speakers/DeleteSpeakersTest.php | 48 +++++++++++ tests/Feature/Speakers/EditSpeakersTest.php | 67 ++++++++++++++++ tests/TestCase.php | 12 +++ 29 files changed, 1232 insertions(+), 12 deletions(-) create mode 100644 .env.ci create mode 100644 bootstrap/app.php create mode 100644 bootstrap/cache/.gitignore create mode 100644 tests/CreatesApplication.php create mode 100644 tests/Feature/ContactTest.php create mode 100644 tests/Feature/InviteAdminTest.php create mode 100644 tests/Feature/Meetups/BrowseMeetupsTest.php create mode 100644 tests/Feature/Meetups/CreateMeetupsTest.php create mode 100644 tests/Feature/Meetups/DeleteMeetupsTest.php create mode 100644 tests/Feature/Meetups/EditMeetupsTest.php create mode 100644 tests/Feature/NewsletterTest.php create mode 100644 tests/Feature/Organizations/BrowseOrganizationsTest.php create mode 100644 tests/Feature/Organizations/CreateOrganizationsTest.php create mode 100644 tests/Feature/Organizations/DeleteOrganizationsTest.php create mode 100644 tests/Feature/Organizations/EditOrganizationsTest.php create mode 100644 tests/Feature/Organizations/Profiles/CreateOrganizationProfilesTest.php create mode 100644 tests/Feature/Organizations/Profiles/DeleteOrganizationProfilesTest.php create mode 100644 tests/Feature/Organizations/Profiles/EditOrganizationProfilesTest.php create mode 100644 tests/Feature/Organizations/Profiles/OrganizationProfilesRequestTest.php create mode 100644 tests/Feature/Speakers/BrowseSpeakersTest.php create mode 100644 tests/Feature/Speakers/CreateSpeakersTest.php create mode 100644 tests/Feature/Speakers/DeleteSpeakersTest.php create mode 100644 tests/Feature/Speakers/EditSpeakersTest.php create mode 100644 tests/TestCase.php diff --git a/.env.ci b/.env.ci new file mode 100644 index 00000000..9bd273d7 --- /dev/null +++ b/.env.ci @@ -0,0 +1,18 @@ +APP_NAME=Laravel +APP_ENV=testing +APP_KEY=base64:fDr4dLzbpxwzo9eDpy8of5b6/Dt2Pnvnd3lng8cf348= +APP_DEBUG=true +APP_URL=http://localhost +APP_TIMEZONE='Europe/Warsaw' + +LOG_CHANNEL=stack +LOG_LEVEL=debug + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +FILESYSTEM_DRIVER=local +QUEUE_CONNECTION=redis +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +MEMCACHED_HOST=memcached diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 899a93c0..6b0a21fc 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -36,5 +36,8 @@ jobs: - name: Run PHP linter run: composer cs + - name: Cache views + run: php artisan view:cache + - name: Execute tests run: php artisan test --env=ci diff --git a/bootstrap/app.php b/bootstrap/app.php new file mode 100644 index 00000000..b434403e --- /dev/null +++ b/bootstrap/app.php @@ -0,0 +1,24 @@ +singleton( + Illuminate\Contracts\Http\Kernel::class, + Blumilk\Meetup\Core\Http\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Console\Kernel::class, + Blumilk\Meetup\Core\Console\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Debug\ExceptionHandler::class, + Blumilk\Meetup\Core\Exceptions\Handler::class +); + +return $app; diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/phpunit.xml b/phpunit.xml index 96c6ff7a..85cf3cf6 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -16,8 +16,8 @@ - - + + diff --git a/src/Http/Controllers/OrganizationProfileController.php b/src/Http/Controllers/OrganizationProfileController.php index 81127787..4eaab494 100644 --- a/src/Http/Controllers/OrganizationProfileController.php +++ b/src/Http/Controllers/OrganizationProfileController.php @@ -30,26 +30,26 @@ public function store(StoreOrganizationProfileRequest $request, Organization $or return redirect()->route("organizations.edit", $organization); } - public function edit(Organization $organization, OrganizationProfile $profile): View + public function edit(Organization $organization, OrganizationProfile $organizationProfile): View { return view("organizations.profiles.edit") ->with([ "organization" => $organization, - "profile" => $profile, + "profile" => $organizationProfile, "availableProfiles" => AvailableProfiles::casesToSelect(), ]); } - public function update(UpdateOrganizationProfileRequest $request, Organization $organization, OrganizationProfile $profile): RedirectResponse + public function update(UpdateOrganizationProfileRequest $request, Organization $organization, OrganizationProfile $organizationProfile): RedirectResponse { - $profile->update($request->validated()); + $organizationProfile->update($request->validated()); return redirect()->route("organizations.edit", $organization); } - public function destroy(Organization $organization, OrganizationProfile $profile): RedirectResponse + public function destroy(Organization $organization, OrganizationProfile $organizationProfile): RedirectResponse { - $profile->delete(); + $organizationProfile->delete(); return back(); } diff --git a/src/Http/Routing/WebRouting.php b/src/Http/Routing/WebRouting.php index 9582bd47..de1bc95d 100755 --- a/src/Http/Routing/WebRouting.php +++ b/src/Http/Routing/WebRouting.php @@ -95,9 +95,9 @@ public function wire(): void $this->router->controller(OrganizationProfileController::class)->group(function (): void { $this->router->get("/organizations/{organization}/profiles/create", "create")->name("organizations.profiles.create"); $this->router->post("/organizations/{organization}/profiles", "store")->name("organizations.profiles.store"); - $this->router->get("/organizations/{organization}/profiles/{profile}/edit", "edit")->name("organizations.profiles.edit"); - $this->router->put("/organizations/{organization}/profiles/{profile}", "update")->name("organizations.profiles.update"); - $this->router->delete("/organizations/{organization}/profiles/{profile}", "destroy")->name("organizations.profiles.destroy"); + $this->router->get("/organizations/{organization}/profiles/{organizationProfile}/edit", "edit")->name("organizations.profiles.edit")->scopeBindings(); + $this->router->put("/organizations/{organization}/profiles/{organizationProfile}", "update")->name("organizations.profiles.update")->scopeBindings(); + $this->router->delete("/organizations/{organization}/profiles/{organizationProfile}", "destroy")->name("organizations.profiles.destroy")->scopeBindings(); }); $this->router->controller(SpeakersController::class)->group(function (): void { diff --git a/src/Services/InvitationsService.php b/src/Services/InvitationsService.php index 625ef0cd..abc1b7dd 100755 --- a/src/Services/InvitationsService.php +++ b/src/Services/InvitationsService.php @@ -6,11 +6,12 @@ use Blumilk\Meetup\Core\Models\User; use Blumilk\Meetup\Core\Notifications\InvitationEmailNotification; +use Illuminate\Support\Facades\Notification; class InvitationsService { public function sendInvitation(User $senderUser, string $email): void { - $senderUser->notify(new InvitationEmailNotification($senderUser, $email)); + Notification::route("mail", $email)->notify(new InvitationEmailNotification($senderUser, $email)); } } diff --git a/tests/CreatesApplication.php b/tests/CreatesApplication.php new file mode 100644 index 00000000..efeacce9 --- /dev/null +++ b/tests/CreatesApplication.php @@ -0,0 +1,20 @@ +make(Kernel::class)->bootstrap(); + + return $app; + } +} diff --git a/tests/Feature/ContactTest.php b/tests/Feature/ContactTest.php new file mode 100644 index 00000000..d24e5e3f --- /dev/null +++ b/tests/Feature/ContactTest.php @@ -0,0 +1,57 @@ +get("/contact") + ->assertOk(); + } + + public function testUserCanSendContactForm(): void + { + Notification::fake(); + + $this->post("/contact", [ + "name" => "John", + "email" => "john.doe@example.com", + "subject" => "Test subject", + "message" => "Test message", + ]) + ->assertSessionHasNoErrors(); + + $this->assertDatabaseHas("contacts", [ + "name" => "John", + "email" => "john.doe@example.com", + "subject" => "Test subject", + "message" => "Test message", + ]); + + $contact = Contact::query()->first(); + + Notification::assertSentTo([$contact], ContactEmailNotification::class); + } + + public function testContactFormDataIsRequired(): void + { + $this->post("/contact") + ->assertInvalid([ + "name", + "email", + "subject", + "message", + ]); + } +} diff --git a/tests/Feature/InviteAdminTest.php b/tests/Feature/InviteAdminTest.php new file mode 100644 index 00000000..8b55fafb --- /dev/null +++ b/tests/Feature/InviteAdminTest.php @@ -0,0 +1,59 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanSeeSendInvitationPage(): void + { + $this->actingAs($this->admin) + ->get("/invitation") + ->assertOk(); + } + + public function testAdminCanSendInvitation(): void + { + Notification::fake(); + + $this->actingAs($this->admin) + ->post("/invitation", [ + "email" => "invited@example.com", + ]) + ->assertSessionHasNoErrors(); + + Notification::assertSentOnDemand( + InvitationEmailNotification::class, + fn ($notification, $channels, $notifiable) => $notifiable->routes["mail"] === "invited@example.com", + ); + } + + public function testUserCannotSendInvitation(): void + { + $user = User::factory()->create(); + + $this->actingAs($user) + ->get("/invitation") + ->assertLocation("/"); + } +} diff --git a/tests/Feature/Meetups/BrowseMeetupsTest.php b/tests/Feature/Meetups/BrowseMeetupsTest.php new file mode 100644 index 00000000..7e355061 --- /dev/null +++ b/tests/Feature/Meetups/BrowseMeetupsTest.php @@ -0,0 +1,71 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testUserCanSeeMeetupsList(): void + { + $meetups = Meetup::factory() + ->count(15) + ->for($this->admin) + ->create(); + + $this->assertDatabaseCount("meetups", 15); + + $response = $this->get(route("meetups")) + ->assertOk(); + + foreach ($meetups as $meetup) { + $response->assertSee($meetup->logo_path) + ->assertSee($meetup->title) + ->assertSee($meetup->date->toDateString()) + ->assertSee($meetup->place); + } + } + + public function testMeetupsListIsPaginated(): void + { + Meetup::factory() + ->count(30) + ->for($this->admin) + ->create(); + + $meetups = Meetup::query() + ->latest() + ->skip(20) + ->take(10); + + $this->assertDatabaseCount("meetups", 30); + + $response = $this->get(route("meetups") . "?page=2") + ->assertOk(); + + foreach ($meetups as $meetup) { + $response->assertSee($meetup->logo_path) + ->assertSee($meetup->title) + ->assertSee($meetup->date->format("Y-m-d h:i")) + ->assertSee($meetup->place); + } + } +} diff --git a/tests/Feature/Meetups/CreateMeetupsTest.php b/tests/Feature/Meetups/CreateMeetupsTest.php new file mode 100644 index 00000000..73d55ef7 --- /dev/null +++ b/tests/Feature/Meetups/CreateMeetupsTest.php @@ -0,0 +1,68 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanCreateMeetup(): void + { + $this->actingAs($this->admin) + ->get(route("meetups.create")) + ->assertOk(); + + $this->actingAs($this->admin) + ->post(route("meetups.store"), [ + "title" => "Test Meetup", + "description" => "Description", + "date" => Carbon::parse("2022-12-12 12:00:00"), + "place" => "Place", + "language" => "en", + "organizations" => "", + "speakers" => "", + ]) + ->assertSessionHasNoErrors() + ->assertRedirect(); + + $this->assertDatabaseHas("meetups", [ + "user_id" => $this->admin->id, + "title" => "Test Meetup", + "description" => "Description", + "date" => Carbon::parse("2022-12-12 12:00:00"), + "place" => "Place", + "language" => "en", + ]); + } + + public function testUserCannotCreateMeetup(): void + { + $user = User::factory()->create(); + + $this->actingAs($user) + ->get(route("meetups.create")) + ->assertForbidden(); + + $this->actingAs($user) + ->post(route("meetups.store")) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Meetups/DeleteMeetupsTest.php b/tests/Feature/Meetups/DeleteMeetupsTest.php new file mode 100644 index 00000000..c9ba743f --- /dev/null +++ b/tests/Feature/Meetups/DeleteMeetupsTest.php @@ -0,0 +1,48 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanDeleteMeetup(): void + { + $meetup = Meetup::factory()->for($this->admin)->create(); + + $this->actingAs($this->admin) + ->delete(route("meetups.destroy", $meetup)) + ->assertRedirect(); + + $this->assertModelMissing($meetup); + } + + public function testUserCannotDeleteMeetup(): void + { + $meetup = Meetup::factory()->for($this->admin)->create(); + + $user = User::factory()->create(); + + $this->actingAs($user) + ->delete(route("meetups.destroy", $meetup)) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Meetups/EditMeetupsTest.php b/tests/Feature/Meetups/EditMeetupsTest.php new file mode 100644 index 00000000..ced2032a --- /dev/null +++ b/tests/Feature/Meetups/EditMeetupsTest.php @@ -0,0 +1,74 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanEditMeetup(): void + { + $meetup = Meetup::factory()->for($this->admin)->create(); + + $this->actingAs($this->admin) + ->get(route("meetups.edit", $meetup)) + ->assertOk(); + + $this->actingAs($this->admin) + ->put(route("meetups.update", $meetup), [ + "title" => "Test Meetup", + "description" => "Description", + "date" => Carbon::parse("2022-12-12 12:00:00"), + "place" => "Place", + "language" => "en", + "organizations" => "", + "speakers" => "", + ]) + ->assertSessionHasNoErrors() + ->assertRedirect(); + + $this->assertDatabaseHas("meetups", [ + "user_id" => $this->admin->id, + "title" => "Test Meetup", + "description" => "Description", + "date" => Carbon::parse("2022-12-12 12:00:00"), + "place" => "Place", + "language" => "en", + ]); + } + + public function testUserCannotEditMeetup(): void + { + $user = User::factory()->create(); + $meetup = Meetup::factory()->for($user)->create(); + + $user = User::factory()->create(); + + $this->actingAs($user) + ->get(route("meetups.edit", $meetup)) + ->assertForbidden(); + + $this->actingAs($user) + ->put(route("meetups.update", $meetup)) + ->assertForbidden(); + } +} diff --git a/tests/Feature/NewsletterTest.php b/tests/Feature/NewsletterTest.php new file mode 100644 index 00000000..18e16541 --- /dev/null +++ b/tests/Feature/NewsletterTest.php @@ -0,0 +1,39 @@ +get("/newsletter") + ->assertOk(); + } + + public function testUserCanSubscribeNewsletter(): void + { + Notification::fake(); + + $this->post("/newsletter/subscribe", [ + "email" => "subscriber@example.com", + ]) + ->assertSessionHasNoErrors() + ->assertOk(); + + $subscriber = NewsletterSubscriber::query() + ->where("email", "subscriber@example.com") + ->first(); + + Notification::assertSentTo($subscriber, NewsletterNotification::class); + } +} diff --git a/tests/Feature/Organizations/BrowseOrganizationsTest.php b/tests/Feature/Organizations/BrowseOrganizationsTest.php new file mode 100644 index 00000000..ad7d2051 --- /dev/null +++ b/tests/Feature/Organizations/BrowseOrganizationsTest.php @@ -0,0 +1,52 @@ +count(10)->create(); + + $this->assertDatabaseCount("organizations", 10); + + $response = $this->get(route("organizations")) + ->assertOk(); + + foreach ($organizations as $organization) { + $response->assertSee($organization->name) + ->assertSee($organization->logo_path) + ->assertSee($organization->description); + } + } + + public function testOrganizationsListIsPaginated(): void + { + Organization::factory()->count(30)->create(); + + $this->assertDatabaseCount("organizations", 30); + + $organizations = Meetup::query() + ->latest() + ->skip(20) + ->take(10); + + $response = $this->get(route("organizations") . "?page=2") + ->assertOk(); + + foreach ($organizations as $organization) { + $response->assertSee($organization->name) + ->assertSee($organization->logo_path) + ->assertSee($organization->description); + } + } +} diff --git a/tests/Feature/Organizations/CreateOrganizationsTest.php b/tests/Feature/Organizations/CreateOrganizationsTest.php new file mode 100644 index 00000000..3d860fe9 --- /dev/null +++ b/tests/Feature/Organizations/CreateOrganizationsTest.php @@ -0,0 +1,69 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanCreateOrganization(): void + { + $this->actingAs($this->admin) + ->get(route("organizations.create")) + ->assertOk(); + + $this->actingAs($this->admin) + ->post(route("organizations.store"), [ + "name" => "Test organization", + "description" => "Test organization description", + "location" => "Panama", + "organization_type" => "test", + "foundation_date" => Carbon::parse("2022-01-01 10:00:00"), + "number_of_employees" => 1000, + "website_url" => "https://testorganization.info", + ]) + ->assertSessionHasNoErrors() + ->assertRedirect(); + + $this->assertDatabaseHas("organizations", [ + "name" => "Test organization", + "description" => "Test organization description", + "location" => "Panama", + "organization_type" => "test", + "foundation_date" => Carbon::parse("2022-01-01 10:00:00"), + "number_of_employees" => 1000, + "website_url" => "https://testorganization.info", + ]); + } + + public function testUserCannotCreateOrganization(): void + { + $user = User::factory()->create(); + + $this->actingAs($user) + ->get(route("organizations.create")) + ->assertForbidden(); + + $this->actingAs($user) + ->post(route("organizations.store")) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Organizations/DeleteOrganizationsTest.php b/tests/Feature/Organizations/DeleteOrganizationsTest.php new file mode 100644 index 00000000..d318beda --- /dev/null +++ b/tests/Feature/Organizations/DeleteOrganizationsTest.php @@ -0,0 +1,48 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanDeleteOrganization(): void + { + $organization = Organization::factory()->create(); + + $this->actingAs($this->admin) + ->delete(route("organizations.destroy", $organization)) + ->assertRedirect(); + + $this->assertModelMissing($organization); + } + + public function testUserCannotDeleteOrganization(): void + { + $user = User::factory()->create(); + + $organization = Organization::factory()->create(); + + $this->actingAs($user) + ->delete(route("organizations.destroy", $organization)) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Organizations/EditOrganizationsTest.php b/tests/Feature/Organizations/EditOrganizationsTest.php new file mode 100644 index 00000000..2cdff16a --- /dev/null +++ b/tests/Feature/Organizations/EditOrganizationsTest.php @@ -0,0 +1,69 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanEditOrganization(): void + { + $organization = Organization::factory()->create(); + + $this->actingAs($this->admin) + ->get(route("organizations.edit", $organization)) + ->assertOk(); + + $this->actingAs($this->admin) + ->put(route("organizations.update", $organization), [ + "name" => "Test organization", + "description" => "Test description", + "location" => "Panama", + "organization_type" => "test", + "foundation_date" => Carbon::parse("2022-01-01 10:00:00"), + "number_of_employees" => 1000, + "website_url" => "https://testorganization.info", + ]) + ->assertSessionHasNoErrors() + ->assertRedirect(); + + $this->assertDatabaseHas("organizations", [ + "name" => "Test organization", + "description" => "Test description", + "location" => "Panama", + "organization_type" => "test", + "foundation_date" => Carbon::parse("2022-01-01 10:00:00"), + "number_of_employees" => 1000, + "website_url" => "https://testorganization.info", + ]); + } + + public function testUserCannotEditOrganization(): void + { + $organization = Organization::factory()->create(); + $user = User::factory()->create(); + + $this->actingAs($user) + ->get(route("organizations.edit", $organization)) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Organizations/Profiles/CreateOrganizationProfilesTest.php b/tests/Feature/Organizations/Profiles/CreateOrganizationProfilesTest.php new file mode 100644 index 00000000..6584057c --- /dev/null +++ b/tests/Feature/Organizations/Profiles/CreateOrganizationProfilesTest.php @@ -0,0 +1,64 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanCreateOrganizationProfile(): void + { + $organization = Organization::factory()->create(); + + $this->actingAs($this->admin) + ->get(route("organizations.profiles.create", $organization)) + ->assertOk(); + + $this->actingAs($this->admin) + ->post(route("organizations.profiles.store", $organization), [ + "label" => "Facebook", + "link" => "https://facebook.com", + ]) + ->assertSessionHasNoErrors() + ->assertRedirect(); + + $this->assertDatabaseHas("organization_profiles", [ + "organization_id" => $organization->id, + "label" => "Facebook", + "link" => "https://facebook.com", + ]); + } + + public function testUserCannotCreateOrganizationProfile(): void + { + $user = User::factory()->create(); + + $organization = Organization::factory()->create(); + + $this->actingAs($user) + ->get(route("organizations.profiles.create", $organization)) + ->assertForbidden(); + + $this->actingAs($user) + ->post(route("organizations.profiles.store", $organization)) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Organizations/Profiles/DeleteOrganizationProfilesTest.php b/tests/Feature/Organizations/Profiles/DeleteOrganizationProfilesTest.php new file mode 100644 index 00000000..37f96867 --- /dev/null +++ b/tests/Feature/Organizations/Profiles/DeleteOrganizationProfilesTest.php @@ -0,0 +1,63 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanDeleteOrganizationProfile(): void + { + $organization = Organization::factory()->create(); + + OrganizationProfile::factory() + ->for($organization) + ->create(); + + $this->assertDatabaseCount("organization_profiles", 1); + $organizationProfile = OrganizationProfile::query()->first(); + + $this->actingAs($this->admin) + ->delete(route("organizations.profiles.destroy", [$organization, $organizationProfile])) + ->assertRedirect(); + + $this->assertModelMissing($organizationProfile); + } + + public function testUserCannotDeleteOrganizationProfile(): void + { + $user = User::factory()->create(); + + $organization = Organization::factory()->create(); + + OrganizationProfile::factory() + ->for($organization) + ->create(); + + $this->assertDatabaseCount("organization_profiles", 1); + $organizationProfile = OrganizationProfile::query()->first(); + + $this->actingAs($user) + ->delete(route("organizations.profiles.destroy", [$organization, $organizationProfile])) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Organizations/Profiles/EditOrganizationProfilesTest.php b/tests/Feature/Organizations/Profiles/EditOrganizationProfilesTest.php new file mode 100644 index 00000000..a75006f8 --- /dev/null +++ b/tests/Feature/Organizations/Profiles/EditOrganizationProfilesTest.php @@ -0,0 +1,79 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanEditOrganizationProfile(): void + { + $organization = Organization::factory()->create(); + + OrganizationProfile::factory() + ->for($organization) + ->create(); + + $this->assertDatabaseCount("organization_profiles", 1); + $organizationProfile = OrganizationProfile::query()->first(); + + $this->actingAs($this->admin) + ->get(route("organizations.profiles.edit", [$organization, $organizationProfile])) + ->assertOk(); + + $this->actingAs($this->admin) + ->put(route("organizations.profiles.update", [$organization, $organizationProfile]), [ + "label" => "Twitter", + "link" => "https://twitter.com", + ]) + ->assertSessionHasNoErrors() + ->assertRedirect(); + + $this->assertDatabaseHas("organization_profiles", [ + "organization_id" => $organization->id, + "label" => "Twitter", + "link" => "https://twitter.com", + ]); + } + + public function testUserCannotEditOrganizationProfile(): void + { + $user = User::factory()->create(); + + $organization = Organization::factory()->create(); + + OrganizationProfile::factory() + ->for($organization) + ->create(); + + $this->assertDatabaseCount("organization_profiles", 1); + $organizationProfile = OrganizationProfile::query()->first(); + + $this->actingAs($user) + ->get(route("organizations.profiles.edit", [$organization, $organizationProfile])) + ->assertForbidden(); + + $this->actingAs($user) + ->put(route("organizations.profiles.update", [$organization, $organizationProfile])) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Organizations/Profiles/OrganizationProfilesRequestTest.php b/tests/Feature/Organizations/Profiles/OrganizationProfilesRequestTest.php new file mode 100644 index 00000000..b8e58b88 --- /dev/null +++ b/tests/Feature/Organizations/Profiles/OrganizationProfilesRequestTest.php @@ -0,0 +1,52 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testOrganizationProfileRequestHasRelatedOrganization(): void + { + $organization = Organization::factory()->create(); + $foreignOrganization = Organization::factory()->create(); + + OrganizationProfile::factory() + ->for($organization) + ->create(); + + $this->assertDatabaseCount("organization_profiles", 1); + $organizationProfile = OrganizationProfile::query()->first(); + + $this->actingAs($this->admin) + ->get(route("organizations.profiles.edit", [$foreignOrganization, $organizationProfile])) + ->assertNotFound(); + + $this->actingAs($this->admin) + ->put(route("organizations.profiles.update", [$foreignOrganization, $organizationProfile])) + ->assertNotFound(); + + $this->actingAs($this->admin) + ->delete(route("organizations.profiles.destroy", [$foreignOrganization, $organizationProfile])) + ->assertNotFound(); + } +} diff --git a/tests/Feature/Speakers/BrowseSpeakersTest.php b/tests/Feature/Speakers/BrowseSpeakersTest.php new file mode 100644 index 00000000..01f149e3 --- /dev/null +++ b/tests/Feature/Speakers/BrowseSpeakersTest.php @@ -0,0 +1,51 @@ +create(); + $speakers = Speaker::factory()->count(10)->create(); + + $response = $this->actingAs($user) + ->get(route("speakers")) + ->assertOk(); + + foreach ($speakers as $speaker) { + $response->assertSee($speaker->name) + ->assertSee($speaker->avatar_path); + } + } + + public function testSpeakersListIsPaginated(): void + { + $user = User::factory()->create(); + + Speaker::factory()->count(30)->create(); + + $speakers = Speaker::query() + ->latest() + ->skip(20) + ->take(10); + + $response = $this->actingAs($user) + ->get(route("speakers") . "?page=2") + ->assertOk(); + + foreach ($speakers as $speaker) { + $response->assertSee($speaker->name) + ->assertSee($speaker->avatar_path); + } + } +} diff --git a/tests/Feature/Speakers/CreateSpeakersTest.php b/tests/Feature/Speakers/CreateSpeakersTest.php new file mode 100644 index 00000000..aa29999d --- /dev/null +++ b/tests/Feature/Speakers/CreateSpeakersTest.php @@ -0,0 +1,62 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanCreateSpeaker(): void + { + $this->actingAs($this->admin) + ->get(route("speakers.create")) + ->assertOk(); + + $this->actingAs($this->admin) + ->post(route("speakers.store"), [ + "name" => "speaker", + "description" => "speaker description", + "linkedin_url" => "https://linkedin.com/example", + "github_url" => "https://github.com/example", + ]) + ->assertSessionHasNoErrors() + ->assertRedirect(); + + $this->assertDatabaseHas("speakers", [ + "name" => "speaker", + "description" => "speaker description", + "linkedin_url" => "https://linkedin.com/example", + "github_url" => "https://github.com/example", + ]); + } + + public function testUserCannotCreateSpeaker(): void + { + $user = User::factory()->create(); + + $this->actingAs($user) + ->get(route("speakers.create")) + ->assertForbidden(); + + $this->actingAs($user) + ->post(route("speakers.store")) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Speakers/DeleteSpeakersTest.php b/tests/Feature/Speakers/DeleteSpeakersTest.php new file mode 100644 index 00000000..6f44513a --- /dev/null +++ b/tests/Feature/Speakers/DeleteSpeakersTest.php @@ -0,0 +1,48 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanDeleteSpeaker(): void + { + $speaker = Speaker::factory()->create(); + + $this->actingAs($this->admin) + ->delete(route("speakers.destroy", $speaker)) + ->assertRedirect(); + + $this->assertModelMissing($speaker); + } + + public function testUserCannotDeleteSpeaker(): void + { + $user = User::factory()->create(); + + $speaker = Speaker::factory()->create(); + + $this->actingAs($user) + ->delete(route("speakers.destroy", $speaker)) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Speakers/EditSpeakersTest.php b/tests/Feature/Speakers/EditSpeakersTest.php new file mode 100644 index 00000000..6320e7e9 --- /dev/null +++ b/tests/Feature/Speakers/EditSpeakersTest.php @@ -0,0 +1,67 @@ + "admin"]); + $this->admin = User::factory()->create()->assignRole("admin"); + } + + public function testAdminCanEditSpeaker(): void + { + $speaker = Speaker::factory()->create(); + + $this->actingAs($this->admin) + ->get(route("speakers.edit", $speaker)) + ->assertOk(); + + $this->actingAs($this->admin) + ->put(route("speakers.update", $speaker), [ + "name" => "speaker", + "description" => "speaker description", + "linkedin_url" => "https://linkedin.com/", + "github_url" => "https://github.com/", + ]) + ->assertSessionHasNoErrors() + ->assertRedirect(); + + $this->assertDatabaseHas("speakers", [ + "name" => "speaker", + "description" => "speaker description", + "linkedin_url" => "https://linkedin.com/", + "github_url" => "https://github.com/", + ]); + } + + public function testUserCannotEditSpeaker(): void + { + $user = User::factory()->create(); + + $speaker = Speaker::factory()->create(); + + $this->actingAs($user) + ->get(route("speakers.edit", $speaker)) + ->assertForbidden(); + + $this->actingAs($user) + ->put(route("speakers.update", $speaker)) + ->assertForbidden(); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 00000000..53411164 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,12 @@ +