Merge branch 'main' into #4-users-crud

# Conflicts:
#	composer.lock
#	resources/js/Shared/MainMenu.vue
This commit is contained in:
Adrian Hopek 2022-01-18 12:23:35 +01:00
commit ffba69319c
15 changed files with 258 additions and 26 deletions

23
.env.ci Normal file
View File

@ -0,0 +1,23 @@
APP_NAME=Laravel
APP_ENV=testing
APP_KEY=base64:4Hjdxw6l/vsqukgRVRk5YwKHNJfX9N+44dJdnDesrcc=
APP_DEBUG=false
APP_URL=http://127.0.0.1
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=toby
DB_USERNAME=toby
DB_PASSWORD=password
BROADCAST_DRIVER=log
CACHE_DRIVER=array
QUEUE_CONNECTION=sync
SESSION_DRIVER=array
SESSION_LIFETIME=120
FILESYSTEM_DRIVER=local
MAIL_MAILER=array

28
.env.dusk.local Normal file
View File

@ -0,0 +1,28 @@
APP_NAME=Laravel
APP_ENV=testing
APP_KEY=base64:uuizKfYGhrBB+ecWuxg570hdUgKwZ1sqEgHPngW15Xw=
APP_DEBUG=false
APP_URL=http://toby-web
DUSK_IN_DOCKER=true
DUSK_DRIVER_URL=http://toby-selenium:4444/wd/hub
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=toby-db-test
DB_PORT=3306
DB_DATABASE=toby
DB_USERNAME=toby
DB_PASSWORD=password
BROADCAST_DRIVER=log
CACHE_DRIVER=array
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
FILESYSTEM_DRIVER=local
MAIL_MAILER=array
TELESCOPE_ENABLED=false

View File

@ -8,18 +8,24 @@ LOG_CHANNEL=stack
LOG_LEVEL=debug LOG_LEVEL=debug
DB_CONNECTION=mysql DB_CONNECTION=mysql
DB_HOST=toby-db DB_HOST=toby-db-dev
DB_PORT=3306 DB_PORT=3306
DB_DATABASE=toby DB_DATABASE=toby
DB_USERNAME=toby DB_USERNAME=toby
DB_PASSWORD=password DB_PASSWORD=password
DB_ROOT_PASSWORD=example DB_ROOT_PASSWORD=example
DOCKER_DB_EXTERNAL_PORT=3306 DOCKER_DEV_DB_EXTERNAL_PORT=3306
DOCKER_DB_DATABASE=${DB_DATABASE} DOCKER_DEV_DB_DATABASE=${DB_DATABASE}
DOCKER_DB_USERNAME=${DB_USERNAME} DOCKER_DEV_DB_USERNAME=${DB_USERNAME}
DOCKER_DB_PASSWORD=${DB_PASSWORD} DOCKER_DEV_DB_PASSWORD=${DB_PASSWORD}
DOCKER_DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD} DOCKER_DEV_DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
DOCKER_TEST_DB_EXTERNAL_PORT=3307
DOCKER_TEST_DB_DATABASE=${DB_DATABASE}
DOCKER_TEST_DB_USERNAME=${DB_USERNAME}
DOCKER_TEST_DB_PASSWORD=${DB_PASSWORD}
DOCKER_TEST_DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
EXTERNAL_WEBSERVER_PORT= EXTERNAL_WEBSERVER_PORT=
XDG_CONFIG_HOME=/tmp XDG_CONFIG_HOME=/tmp

View File

@ -10,6 +10,16 @@ jobs:
test-and-lint-php: test-and-lint-php:
name: Test & lint PHP stuff name: Test & lint PHP stuff
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
services:
mysql:
image: mysql:8.0
env:
MYSQL_DATABASE: toby
MYSQL_USER: toby
MYSQL_PASSWORD: password
MYSQL_ALLOW_EMPTY_PASSWORD: 1
ports:
- 3306:3306
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View File

@ -21,6 +21,7 @@
"enlightn/enlightn": "^1.22", "enlightn/enlightn": "^1.22",
"facade/ignition": "^2.5", "facade/ignition": "^2.5",
"fakerphp/faker": "^1.9.1", "fakerphp/faker": "^1.9.1",
"laravel/dusk": "^6.21",
"mockery/mockery": "^1.4.4", "mockery/mockery": "^1.4.4",
"nunomaduro/collision": "^5.10", "nunomaduro/collision": "^5.10",
"phpunit/phpunit": "^9.5.10" "phpunit/phpunit": "^9.5.10"

View File

@ -5,11 +5,6 @@ declare(strict_types=1);
return [ return [
"default" => env("DB_CONNECTION", "mysql"), "default" => env("DB_CONNECTION", "mysql"),
"connections" => [ "connections" => [
"testing" => [
"driver" => "sqlite",
"database" => ":memory:",
"prefix" => "",
],
"mysql" => [ "mysql" => [
"driver" => "mysql", "driver" => "mysql",
"url" => env("DATABASE_URL"), "url" => env("DATABASE_URL"),

View File

@ -36,12 +36,12 @@ services:
database: database:
image: mysql:8.0 image: mysql:8.0
container_name: toby-db container_name: toby-db-dev
environment: environment:
- MYSQL_ROOT_PASSWORD=${DOCKER_DB_ROOT_PASSWORD} - MYSQL_ROOT_PASSWORD=${DOCKER_DEV_DB_ROOT_PASSWORD}
- MYSQL_DATABASE=${DOCKER_DB_DATABASE} - MYSQL_DATABASE=${DOCKER_DEV_DB_DATABASE}
- MYSQL_USER=${DOCKER_DB_USERNAME} - MYSQL_USER=${DOCKER_DEV_DB_USERNAME}
- MYSQL_PASSWORD=${DOCKER_DB_PASSWORD} - MYSQL_PASSWORD=${DOCKER_DEV_DB_PASSWORD}
ports: ports:
- ${DOCKER_DB_EXTERNAL_PORT:-3306}:3306 - ${DOCKER_DB_EXTERNAL_PORT:-3306}:3306
volumes: volumes:
@ -50,6 +50,20 @@ services:
- toby-dev - toby-dev
restart: unless-stopped restart: unless-stopped
database-test:
image: mysql:8.0
container_name: toby-db-test
environment:
- MYSQL_ROOT_PASSWORD=${DOCKER_TEST_DB_ROOT_PASSWORD}
- MYSQL_DATABASE=${DOCKER_TEST_DB_DATABASE}
- MYSQL_USER=${DOCKER_TEST_DB_USERNAME}
- MYSQL_PASSWORD=${DOCKER_TEST_DB_PASSWORD}
ports:
- ${DOCKER_TEST_DB_EXTERNAL_PORT:-3307}:3306
networks:
- toby-dev
restart: unless-stopped
node: node:
image: node:17.2.0-alpine3.14 image: node:17.2.0-alpine3.14
container_name: toby-node container_name: toby-node
@ -70,6 +84,14 @@ services:
- toby-dev - toby-dev
restart: unless-stopped restart: unless-stopped
selenium:
image: selenium/standalone-chrome
container_name: toby-selenium
volumes:
- /dev/shm:/dev/shm
networks:
- toby-dev
networks: networks:
toby-dev: toby-dev:
driver: bridge driver: bridge

2
package-lock.json generated
View File

@ -1,5 +1,5 @@
{ {
"name": "toby", "name": "application",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {

View File

@ -19,14 +19,17 @@
</coverage> </coverage>
<php> <php>
<server name="APP_ENV" value="testing"/> <server name="APP_ENV" value="testing"/>
<server name="APP_KEY" value="base64:SKEJSy9oF9chQBCMbxqgj5zhtAvug9kwZ+cDiP1Y8A8="/> <env name="APP_KEY" value="base64:SKEJSy9oF9chQBCMbxqgj5zhtAvug9kwZ+cDiP1Y8A8="/>
<server name="BCRYPT_ROUNDS" value="4"/> <env name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/> <env name="CACHE_DRIVER" value="array"/>
<server name="DB_CONNECTION" value="testing"/> <env name="DB_CONNECTION" value="mysql"/>
<server name="DB_DATABASE" value=":memory:"/> <env name="DB_HOST" value="toby-db-test"/>
<server name="MAIL_MAILER" value="array"/> <env name="DB_DATABASE" value="toby"/>
<server name="QUEUE_CONNECTION" value="sync"/> <env name="DB_USERNAME" value="toby"/>
<server name="SESSION_DRIVER" value="array"/> <env name="DB_PASSWORD" value="password"/>
<server name="TELESCOPE_ENABLED" value="false"/> <env name="MAIL_MAILER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="TELESCOPE_ENABLED" value="false"/>
</php> </php>
</phpunit> </phpunit>

View File

@ -38,6 +38,7 @@
</transition> </transition>
<div <div
class="sm:mx-auto sm:w-full sm:max-w-md text-white space-y-4 flex flex-col items-center rounded-lg px-4 py-8" class="sm:mx-auto sm:w-full sm:max-w-md text-white space-y-4 flex flex-col items-center rounded-lg px-4 py-8"
dusk="login-link"
> >
<img <img
class="mx-auto h-50 w-auto" class="mx-auto h-50 w-auto"

View File

@ -38,6 +38,7 @@
<div> <div>
<MenuButton <MenuButton
class="rounded-full flex text-sm ring-2 ring-white ring-opacity-20 focus:outline-none focus:ring-opacity-100" class="rounded-full flex text-sm ring-2 ring-white ring-opacity-20 focus:outline-none focus:ring-opacity-100"
dusk="user-menu"
> >
<span class="sr-only">Open user menu</span> <span class="sr-only">Open user menu</span>
<img <img
@ -54,6 +55,7 @@
> >
<MenuItems <MenuItems
class="origin-top-right z-40 absolute -right-2 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none" class="origin-top-right z-40 absolute -right-2 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none"
dusk="user-menu-list"
> >
<MenuItem <MenuItem
v-for="item in userNavigation" v-for="item in userNavigation"

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Pages\HomePage;
use Tests\DuskTestCase;
use Toby\Models\User;
class AuthenticationTest extends DuskTestCase
{
use DatabaseMigrations;
protected User $user;
protected function setUp(): void
{
parent::setUp();
$this->user = User::factory()->create();
}
public function testUserCanLogout(): void
{
$this->browse(function (Browser $browser): void {
$browser->loginAs($this->user)
->visit(new HomePage())
->assertVisible("@user-menu")
->click("@user-menu")
->assertVisible("@user-menu-list")
->assertSee("Sign out")
->press("Sign out")
->on(new HomePage())
->waitFor("@login-link");
});
}
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Tests\Browser\Pages;
use Laravel\Dusk\Browser;
class HomePage extends Page
{
public function url()
{
return "/";
}
public function assert(Browser $browser): void
{
$browser->assertPathIs($this->url());
}
}

View File

@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace Tests\Browser\Pages;
use Laravel\Dusk\Page as BasePage;
abstract class Page extends BasePage
{
public static function siteElements()
{
return [
"@element" => "#selector",
];
}
}

65
tests/DuskTestCase.php Normal file
View File

@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace Tests;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Laravel\Dusk\TestCase as BaseTestCase;
abstract class DuskTestCase extends BaseTestCase
{
use CreatesApplication;
/**
* @beforeClass
*/
public static function prepare(): void
{
if (!static::runningInDocker()) {
static::startChromeDriver();
}
}
protected function driver(): RemoteWebDriver
{
$options = (new ChromeOptions())->addArguments(
collect(
[
"--window-size=1920,1080",
],
)->unless(
$this->hasHeadlessDisabled(),
function ($items) {
return $items->merge(
[
"--disable-gpu",
"--headless",
],
);
},
)->all(),
);
return RemoteWebDriver::create(
env("DUSK_DRIVER_URL") ?? "http://localhost:" . env("SELENIUM_PORT"),
DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY,
$options,
),
);
}
protected function hasHeadlessDisabled(): bool
{
return isset($_SERVER["DUSK_HEADLESS_DISABLED"]) ||
isset($_ENV["DUSK_HEADLESS_DISABLED"]);
}
protected static function runningInDocker(): bool
{
return isset($_ENV["DUSK_IN_DOCKER"]) && $_ENV["DUSK_IN_DOCKER"] === "true";
}
}