Compare commits

...

28 commits

Author SHA1 Message Date
Simon Vieille 6c248452df
ci(conf): add chrome
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-01-10 10:36:01 +01:00
Simon Vieille bbe14360d9
ci(conf): add chrome
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-01-10 10:30:03 +01:00
Simon Vieille 7769e25c75
ci(conf): add chrome driver
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-01-10 10:23:14 +01:00
Simon Vieille 56be2ebec7
ci(conf): add chrome driver
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-01-10 10:10:29 +01:00
Simon Vieille 8aa1b2f8c3
ci(conf): dbrekelmans/bdi
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-01-10 10:00:38 +01:00
Simon Vieille f8094c45f8
ci(conf): webserver is now run as daemon
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-01-09 23:11:56 +01:00
Simon Vieille f55605bea0
ci(conf): rollback images
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-01-09 22:52:24 +01:00
Simon Vieille b1bf3a42a1
ci(conf): use deblan php images
Some checks are pending
ci/woodpecker/push/woodpecker Pipeline is pending
2023-01-09 22:51:39 +01:00
Simon Vieille c16e4652cb
feat(tests): update default env
Some checks are pending
ci/woodpecker/push/woodpecker Pipeline is pending
2023-01-09 22:28:57 +01:00
Simon Vieille 2ed04163b4
feat(tests): add phpunit conf 2023-01-09 22:28:25 +01:00
Simon Vieille 496cd46db7
ci(tests): add web server start 2023-01-09 22:26:12 +01:00
Simon Vieille dd3630237c
test(backoffice): add base functional tests
test creation of a navigation
test creation of a menu
test creation of a page
2023-01-09 22:25:39 +01:00
Simon Vieille 5dbcc51309
ci(test): update commands
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-01-09 10:20:19 +01:00
Simon Vieille 4b1fdb8652
ci(test): configure test database
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-01-09 10:09:05 +01:00
Simon Vieille 2aab5310d2
feat(test): remove doctrine prefix on test 2023-01-09 10:06:59 +01:00
Simon Vieille 3df5aba320
ci(test): add test database
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-01-09 09:59:21 +01:00
Simon Vieille 85e04205cd
feat(test): add dependencies
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-01-09 09:49:30 +01:00
Simon Vieille 40633fa567
ci(conf): use mariadb for tests
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-01-08 23:14:16 +01:00
Simon Vieille 8535ef9082
refactor(test): apply php-cs-fixer
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
add select user by email
2023-01-08 23:10:57 +01:00
Simon Vieille f6c932314b
feat(test): configure phpunit
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-01-08 22:51:53 +01:00
Simon Vieille 80af94a95e
refactor(test): rename LoginTest 2023-01-08 22:51:27 +01:00
Simon Vieille a22725ad6d
ci(command): add for murph:user:create 2023-01-08 22:51:01 +01:00
Simon Vieille 49b90f6e6c
fix(ci): create directory public/js in CI
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-01-08 21:58:23 +01:00
Simon Vieille 919edfe664
test(auth): add test of admin page access
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-01-08 21:49:34 +01:00
Simon Vieille 518c98710e
feat(ci): add base of CI 2023-01-08 21:48:56 +01:00
Simon Vieille 9937160ae0
feat(test): update murph/murph-core version 2023-01-08 21:48:34 +01:00
Simon Vieille d4eabf1937
feat(db): add APP_ENV in doctrine-migrate script 2023-01-08 21:47:59 +01:00
Simon Vieille fdc6c423ff
feat(tests): configure tests 2023-01-08 21:47:33 +01:00
15 changed files with 357 additions and 15 deletions

View file

@ -2,6 +2,5 @@
KERNEL_CLASS='App\Kernel'
APP_SECRET='$ecretf0rt3st'
SYMFONY_DEPRECATIONS_HELPER=999999
PANTHER_APP_ENV=panther
PANTHER_APP_ENV=test
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots
DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_tests.db"

3
.gitignore vendored
View file

@ -33,3 +33,6 @@ yarn-error.log
/phpunit.xml
.phpunit.result.cache
###< phpunit/phpunit ###
# Tests
/drivers/

62
.woodpecker.yml Normal file
View file

@ -0,0 +1,62 @@
matrix:
PHP_VERSION:
# - 8.0
- 8.1
services:
db:
image: mariadb:10.3
environment:
- MARIADB_ROOT_PASSWORD=root
pipeline:
wait_db:
image: gitnet.fr/deblan/timeout:latest
commands:
- /bin/timeout -t 30 -v -c 'while true; do nc -z -v db 3306 2>&1 | grep succeeded && exit 0; sleep 0.5; done'
create_db:
image: mariadb:10.3
commands:
- mysql -hdb -uroot -proot -e "CREATE DATABASE app"
- mysql -hdb -uroot -proot -e "CREATE DATABASE app_test"
config:
image: deblan/php:8.1
commands:
- echo APP_ENV=prod >> .env.local
- echo APP_SECRET=$(openssl rand -hex 32) >> .env.local
- echo DATABASE_URL=mysql://root:root@db/app >> .env.local
- echo DATABASE_URL=mysql://root:root@db/app_test >> .env.test.local
composer:
image: deblan/php:${PHP_VERSION}
commands:
- apt-get update && apt-get -y install git
- composer install --no-scripts
migrate:
image: deblan/php:${PHP_VERSION}
environment:
- PHP=php
commands:
- ./bin/doctrine-migrate
node:
image: node:16-slim
commands:
- yarn
- test -d public/js || mkdir public/js
- test -f public/js/fos_js_routes.json || echo "{}" > public/js/fos_js_routes.json
- npm run build
tests:
image: deblan/php:${PHP_VERSION}
commands:
- apt-get update && apt-get install -y unzip
- composer install --no-scripts --dev
- curl -o chromedriver_linux64.zip https://chromedriver.storage.googleapis.com/108.0.5359.71/chromedriver_linux64.zip && unzip -d drivers chromedriver_linux64.zip
- curl -o /tmp/chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && apt install -y /tmp/chrome.deb
- vendor/bin/bdi detect drivers
- symfony server:start --port=9080 --no-tls -d
- php bin/phpunit

View file

@ -24,3 +24,6 @@ doctrine-migration:
PHP=$(PHP_BIN) ./bin/doctrine-migrate
build: clean js-routing asset
run-tests:
$(PHP_BIN) bin/phpunit tests/

View file

@ -1,7 +1,9 @@
#!/bin/sh
CLASS_NAME="$(echo "yes" | "$PHP" ./bin/console doctrine:migration:diff -e dev | grep -o "Version[0-9]*" | tail -n 1)"
APP_ENV="${APP_ENV:-dev}"
CLASS_NAME="$(echo "yes" | "$PHP" ./bin/console doctrine:migration:diff -e "$APP_ENV" | grep -o "Version[0-9]*" | tail -n 1)"
if [ -n "$CLASS_NAME" ]; then
echo "yes" | "$PHP" ./bin/console doctrine:migration:exec --up "DoctrineMigrations\\$CLASS_NAME" -e dev
echo "yes" | "$PHP" ./bin/console doctrine:migration:exec --up "DoctrineMigrations\\$CLASS_NAME" -e "$APP_ENV"
fi

View file

@ -7,13 +7,15 @@
"prefer-stable": true,
"require": {
"php": ">=8.0.0",
"murph/murph-core": "^1.17"
"murph/murph-core": "dev-master"
},
"require-dev": {
"dbrekelmans/bdi": "^1.0",
"symfony/browser-kit": "^5.4",
"symfony/css-selector": "^5.4",
"symfony/debug-bundle": "^5.4",
"symfony/maker-bundle": "^1.0",
"symfony/panther": "^2.0",
"symfony/phpunit-bridge": "^6.2",
"symfony/stopwatch": "^5.4",
"symfony/var-dumper": "^5.4",

View file

@ -29,11 +29,11 @@ doctrine:
alias: GedmoTree # (optional) it will default to the name set for the mapping
is_bundle: false
when@test:
doctrine:
dbal:
# "TEST_TOKEN" is typically set by ParaTest
dbname_suffix: '_test%env(default::TEST_TOKEN)%'
# when@test:
# doctrine:
# dbal:
# # "TEST_TOKEN" is typically set by ParaTest
# dbname_suffix: '_test%env(default::TEST_TOKEN)%'
when@prod:
doctrine:

View file

@ -13,13 +13,22 @@
<ini name="error_reporting" value="-1" />
<server name="APP_ENV" value="test" force="true" />
<server name="SHELL_VERBOSITY" value="-1" />
<server name="SYMFONY_DEPRECATIONS_HELPER" value="weak" />
<server name="SYMFONY_PHPUNIT_REMOVE" value="" />
<server name="SYMFONY_PHPUNIT_VERSION" value="9.5" />
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
<testsuite name="CLI">
<file>tests/Core/Command/CreateUserTest.php</file>
</testsuite>
<testsuite name="Login">
<file>tests/Core/Auth/LoginTest.php</file>
</testsuite>
<testsuite name="Site">
<file>tests/Core/Site/NavigationTest.php</file>
<file>tests/Core/Site/TreeTest.php</file>
<file>tests/Core/Site/PageTest.php</file>
</testsuite>
</testsuites>
@ -33,10 +42,7 @@
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
</listeners>
<!-- Run `composer require symfony/panther` before enabling this extension -->
<!--
<extensions>
<extension class="Symfony\Component\Panther\ServerExtension" />
</extensions>
-->
</phpunit>

View file

@ -0,0 +1,40 @@
<?php
namespace App\Tests\Core\Auth;
use App\Repository\UserRepositoryQuery;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
* @internal
* @coversNothing
*/
class LoginTest extends WebTestCase
{
protected UserRepositoryQuery $query;
protected KernelBrowser $client;
protected function setUp(): void
{
$this->client = static::createClient();
$this->query = self::$container->get(UserRepositoryQuery::class);
}
public function testLoginRedirect(): void
{
$crawler = $this->client->request('GET', '/admin');
$this->assertResponseStatusCodeSame(302);
$this->client->followRedirect();
$this->assertResponseIsSuccessful();
}
public function testLoginUser(): void
{
$user = $this->query->create()->andWhere('.email=\'admin@localhost\'')->findOne();
$this->client->loginUser($user);
$this->client->request('GET', '/admin/account/');
$this->assertResponseStatusCodeSame(200);
}
}

View file

@ -0,0 +1,68 @@
<?php
namespace App\Tests\Core\Command;
use App\Repository\UserRepositoryQuery;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Console\Tester\CommandTester;
/**
* @internal
* @coversNothing
*/
class CreateUserTest extends KernelTestCase
{
protected UserRepositoryQuery $query;
protected function setUp(): void
{
self::bootKernel();
$this->query = self::$container->get(UserRepositoryQuery::class);
}
public function testCommandExecute(): void
{
$kernel = static::createKernel();
$application = new Application($kernel);
$command = $application->find('murph:user:create');
$commandTester = new CommandTester($command);
$commandTester->setInputs([
'admin@localhost',
'admin_password',
'y',
'n',
]);
$commandTester->execute(['command' => $command->getName()]);
$output = $commandTester->getDisplay();
$this->assertStringContainsString('User created!', $output);
$commandTester->setInputs([
'writer@localhost',
'writer_password',
'n',
'y',
]);
$commandTester->execute(['command' => $command->getName()]);
$output = $commandTester->getDisplay();
$this->assertStringContainsString('User created!', $output);
}
public function testCreatedUsers(): void
{
$users = $this->query->create()->find();
$this->assertEquals(2, count($users));
$this->assertEquals('admin@localhost', $users[0]->getEmail());
$this->assertEquals('admin@localhost', $users[0]->getUsername());
$this->assertEquals('writer@localhost', $users[1]->getEmail());
$this->assertEquals('writer@localhost', $users[1]->getUsername());
$this->assertEquals(true, $users[0]->getIsAdmin());
$this->assertEquals(false, $users[0]->getIsWriter());
$this->assertEquals(false, $users[1]->getIsAdmin());
$this->assertEquals(true, $users[1]->getIsWriter());
}
}

View file

@ -0,0 +1,50 @@
<?php
namespace App\Tests\Core;
use App\Repository\UserRepositoryQuery;
use Symfony\Component\Panther\Client as PantherClient;
use Symfony\Component\Panther\PantherTestCase as BasePantherTestCase;
abstract class PantherTestCase extends BasePantherTestCase
{
protected UserRepositoryQuery $query;
protected PantherClient $client;
protected function container()
{
if (null === self::$container) {
static::bootKernel();
}
return self::$container;
}
protected function setUp(): void
{
$this->client = static::createPantherClient([
'external_base_uri' => 'http://localhost:9080'
]);
$this->query = $this->container()->get(UserRepositoryQuery::class);
}
protected function authenticateAdmin(): void
{
$this->client->request('GET', '/login');
$this->client->submitForm('Login', [
'_username' => 'admin@localhost',
'_password' => 'admin_password',
]);
$this->client->waitFor('.nav-item-label');
}
protected function authenticateWriter(): void
{
$this->client->request('GET', '/login');
$this->client->submitForm('Login', [
'_username' => 'writer@localhost',
'_password' => 'writer_password',
]);
$this->client->waitFor('.nav-item-label');
}
}

View file

@ -0,0 +1,39 @@
<?php
namespace App\Tests\Core\Site;
use App\Tests\Core\PantherTestCase;
/**
* @internal
* @coversNothing
*/
class NavigationTest extends PantherTestCase
{
public function testCreateNavigation(): void
{
$this->authenticateAdmin();
$this->client->request('GET', '/admin/site/tree');
$this->client->waitFor('.toast-body.text-text-warning');
$this->assertSelectorTextContains('.toast-body.text-text-warning', 'You must add a navigation.');
$this->client->request('GET', '/admin/site/navigation');
$this->assertSelectorTextContains('h1', 'Navigations');
$this->client->request('GET', '/admin/site/navigation/new');
$this->assertSelectorTextContains('h1', 'New navigation');
$this->client->submitForm('Save', [
'navigation[label]' => 'Test navigation',
'navigation[locale]' => 'en',
'navigation[code]' => 'nav',
'navigation[domain]' => 'localhost',
]);
$this->client->waitFor('.toast-body.text-text-success');
$this->assertSelectorTextContains('.toast-body.text-text-success', 'The data has been saved.');
$this->client->request('GET', '/admin/site/navigation');
$this->assertSelectorTextContains('.table tbody tr td', 'Test navigation');
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace App\Tests\Core\Site;
use App\Tests\Core\PantherTestCase;
/**
* @internal
* @coversNothing
*/
class PageTest extends PantherTestCase
{
public function testCreatePage(): void
{
$this->client->request('GET', '/admin/site/tree');
$this->client->executeScript("document.querySelector('#node-2 .float-right button[data-modal]').click()");
$this->client->waitFor('#form-node-edit');
$this->client->executeScript("document.querySelector('#node-page-action .card-header label').click()");
$this->client->executeScript("document.querySelector('a[href=\"#form-node-edit-routing\"]').click()");
$this->client->executeScript("document.querySelector('#node_url').value='/foo'");
$this->client->executeScript("document.querySelector('#node_code').value='/foo'");
$this->client->executeScript("document.querySelector('.modal.show .modal-footer button[type=\"submit\"]').click()");
$this->client->waitFor('.toast-body.text-text-success');
$this->assertSelectorTextContains('.toast-body.text-text-success', 'The data has been saved.');
$this->assertSelectorTextContains('#node-2 .float-right a', 'Page');
}
}

View file

@ -0,0 +1,32 @@
<?php
namespace App\Tests\Core\Site;
use App\Tests\Core\PantherTestCase;
/**
* @internal
* @coversNothing
*/
class TreeTest extends PantherTestCase
{
public function testCreateTree(): void
{
$this->client->request('GET', '/admin/site/tree');
$this->assertSelectorTextContains('button[data-toggle="modal"]', 'Add a menu');
$this->client->executeScript("document.querySelector('button[data-toggle=\"modal\"]').click()");
$this->client->waitFor('#form-menu-new');
$this->client->submitForm('Save', [
'menu[label]' => 'Test menu',
'menu[code]' => 'menu',
]);
$this->client->waitFor('.toast-body.text-text-success');
$this->assertSelectorTextContains('.toast-body.text-text-success', 'The data has been saved.');
$this->client->request('GET', '/admin/site/tree');
$this->assertSelectorTextContains('.h4', 'Test menu');
$this->assertSelectorTextContains('#node-2 .col-6', 'First element');
}
}

View file

@ -13,3 +13,9 @@ if (file_exists(dirname(__DIR__).'/config/bootstrap.php')) {
if ($_SERVER['APP_DEBUG']) {
umask(0000);
}
passthru(sprintf(
'APP_ENV=test PHP=%s "%s/../bin/doctrine-migrate"',
$_ENV['PHP_BIN'] ?? $_ENV['PHP'] ?? 'php',
__DIR__
));