Skip to content
This repository has been archived by the owner on Feb 1, 2023. It is now read-only.

#89 - unit tests #104

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
18 changes: 18 additions & 0 deletions .env.ci
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
24 changes: 24 additions & 0 deletions bootstrap/app.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

$app = new Illuminate\Foundation\Application(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

$app->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;
2 changes: 2 additions & 0 deletions bootstrap/cache/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
4 changes: 2 additions & 2 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
</coverage>
<php>
<server name="APP_ENV" value="testing"/>
<server name="APP_URL" value="localhost"/>
<server name="DB_CONNECTION" value="testing"/>
<server name="APP_KEY" value="base64:fDr4dLzbpxwzo9eDpy8of5b6/Dt2Pnvnd3lng8cf348="/>
<server name="DB_CONNECTION" value="sqlite"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="MAIL_MAILER" value="array"/>
Expand Down
12 changes: 6 additions & 6 deletions src/Http/Controllers/OrganizationProfileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
6 changes: 3 additions & 3 deletions src/Http/Routing/WebRouting.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,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 {
Expand Down
3 changes: 2 additions & 1 deletion src/Services/InvitationsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
20 changes: 20 additions & 0 deletions tests/CreatesApplication.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Tests;

use Illuminate\Contracts\Console\Kernel;
use Illuminate\Foundation\Application;

trait CreatesApplication
{
public function createApplication(): Application
{
$app = require __DIR__ . "/../bootstrap/app.php";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need bootstrapping file. You can bootstrap application from Blumilk\Meetup\Core\MeetupApplication class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I get the RuntimeException "A facade root has not been set".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What facade do you want to use and where?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nowhere, I just create object of MeetupApplication class and use getApplication method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't get it. Behat tests were working fine with this packaged app approach. Please take care about removing /bootstrap/app.php file and wire application in your test cases bootstrap.


$app->make(Kernel::class)->bootstrap();

return $app;
}
}
57 changes: 57 additions & 0 deletions tests/Feature/ContactTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace Tests\Feature;

use Blumilk\Meetup\Core\Models\Contact;
use Blumilk\Meetup\Core\Notifications\ContactEmailNotification;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;

class ContactTest extends TestCase
{
use RefreshDatabase;

public function testUserCanSeeContactPage(): void
{
$this->get("/contact")
->assertOk();
}

public function testUserCanSendContactForm(): void
{
Notification::fake();

$this->post("/contact", [
"name" => "John",
"email" => "[email protected]",
"subject" => "Test subject",
"message" => "Test message",
])
->assertSessionHasNoErrors();

$this->assertDatabaseHas("contacts", [
"name" => "John",
"email" => "[email protected]",
"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",
]);
}
}
59 changes: 59 additions & 0 deletions tests/Feature/InviteAdminTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace Tests\Feature;

use Blumilk\Meetup\Core\Models\User;
use Blumilk\Meetup\Core\Notifications\InvitationEmailNotification;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;
use Spatie\Permission\Models\Role;
use Tests\TestCase;

class InviteAdminTest extends TestCase
{
use RefreshDatabase;

public User $admin;

protected function setUp(): void
{
parent::setUp();

Role::create(["name" => "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" => "[email protected]",
])
->assertSessionHasNoErrors();

Notification::assertSentOnDemand(
InvitationEmailNotification::class,
fn ($notification, $channels, $notifiable) => $notifiable->routes["mail"] === "[email protected]",
);
}

public function testUserCannotSendInvitation(): void
{
$user = User::factory()->create();

$this->actingAs($user)
->get("/invitation")
->assertLocation("/");
}
}
71 changes: 71 additions & 0 deletions tests/Feature/Meetups/BrowseMeetupsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace Tests\Feature\Meetups;

use Blumilk\Meetup\Core\Models\Meetup;
use Blumilk\Meetup\Core\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Spatie\Permission\Models\Role;
use Tests\TestCase;

class BrowseMeetupsTest extends TestCase
{
use RefreshDatabase;

public User $admin;

protected function setUp(): void
{
parent::setUp();

Role::create(["name" => "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);
}
}
}
Loading