Compare commits
91 commits
feature/te
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
c0fa37d697 |
|||
|
d4d9bd7fec |
|||
|
898d65a3f8 |
|||
|
56cd22158a |
|||
| 63bc4cde1c | |||
|
2b43f97315 |
|||
|
10564e6d37 |
|||
| ebbb4c01e0 | |||
|
43fb25d122 |
|||
|
4253985bc3 |
|||
| 79d549254f | |||
|
c79e96e291 |
|||
| 092b490ae2 | |||
|
fcecf74f90 |
|||
|
|
c00723a246 | ||
|
|
e81b11c5ec |
||
|
|
af2212ac8c | ||
|
|
b57b0e3770 |
||
|
|
ba76a83163 | ||
|
|
2874f579dc |
||
|
|
287e1d66cb |
||
|
|
b23a4fe9c5 |
||
|
|
59bbd24b76 |
||
|
|
2dfe6ef1ca | ||
|
|
66f82ecc13 |
||
|
|
8432fc123e | ||
|
|
627927a11e |
||
|
|
67871179a8 |
||
|
|
dbec7a884e |
||
|
|
8c6ad05cbd |
||
|
|
cc0296e6e2 |
||
|
|
4f94bd5640 |
||
|
|
9d8d6b510a | ||
|
|
edb51485e1 |
||
|
|
c596f1d62d |
||
|
|
813aa8c618 |
||
|
|
39e92e949a | ||
|
|
e550bc54e2 |
||
|
|
ab808ee511 |
||
| 75a29b6372 | |||
| 69ad422624 | |||
| 310c5076a0 | |||
| 65b3583411 | |||
| a0b4137fb3 | |||
| ab14728bec | |||
| c364cafd17 | |||
| 58b5252986 | |||
| 5f942a904b | |||
| 325401f37d | |||
| bda7a4a195 | |||
| 1113c0a91f | |||
| b26738fe49 | |||
| c4c5aa867a | |||
| 52be00fc77 | |||
| 5f1111d2a0 | |||
| f19fdb0ecf | |||
| 3c52a00bc4 | |||
| 3c274a14b9 | |||
| bb62d1ce78 | |||
| 2a91b5917f | |||
| 22d7389183 | |||
| 933e360e26 | |||
| 9dd0f7376b | |||
| f240db7ba4 | |||
| bb01163e84 | |||
| 2a5d0ae1f4 | |||
| 27bccc9acd | |||
| 246c4621c0 | |||
| 68c6ee8081 | |||
| 7623546c10 | |||
| 63237d50e7 | |||
| 81d1fa9cad | |||
| 6086ceaf35 | |||
| a3ef3540c1 | |||
| a3a1822339 | |||
| 59d5fed75e | |||
| 73b82578e2 | |||
| dc34a954f6 | |||
| 0424a9457e | |||
| b32133e7cb | |||
| 4e1166c19d | |||
| 23802898b5 | |||
| 4be92913a5 | |||
| f3a48cea18 | |||
| 3b6e89dc63 | |||
| 4b4a28aee4 | |||
| 3d8a4de100 | |||
| 8d02608681 | |||
| 56eb728821 | |||
| bf4bd48775 | |||
| 321c7ed960 |
27 changed files with 3012 additions and 13796 deletions
|
|
@ -2,5 +2,6 @@
|
|||
KERNEL_CLASS='App\Kernel'
|
||||
APP_SECRET='$ecretf0rt3st'
|
||||
SYMFONY_DEPRECATIONS_HELPER=999999
|
||||
PANTHER_APP_ENV=test
|
||||
PANTHER_APP_ENV=panther
|
||||
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots
|
||||
DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_tests.db"
|
||||
|
|
|
|||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -33,6 +33,3 @@ yarn-error.log
|
|||
/phpunit.xml
|
||||
.phpunit.result.cache
|
||||
###< phpunit/phpunit ###
|
||||
|
||||
# Tests
|
||||
/drivers/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
matrix:
|
||||
PHP_VERSION:
|
||||
# - 8.0
|
||||
- 8.0
|
||||
- 8.1
|
||||
|
||||
services:
|
||||
|
|
@ -9,25 +9,23 @@ services:
|
|||
environment:
|
||||
- MARIADB_ROOT_PASSWORD=root
|
||||
|
||||
pipeline:
|
||||
wait_db:
|
||||
steps:
|
||||
db_wait:
|
||||
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:
|
||||
db_create:
|
||||
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
|
||||
image: deblan/php:${PHP_VERSION}
|
||||
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}
|
||||
|
|
@ -35,7 +33,7 @@ pipeline:
|
|||
- apt-get update && apt-get -y install git
|
||||
- composer install --no-scripts
|
||||
|
||||
migrate:
|
||||
db_migrate:
|
||||
image: deblan/php:${PHP_VERSION}
|
||||
environment:
|
||||
- PHP=php
|
||||
|
|
@ -49,14 +47,3 @@ pipeline:
|
|||
- 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
|
||||
|
|
|
|||
71
CHANGELOG.md
71
CHANGELOG.md
|
|
@ -1,6 +1,75 @@
|
|||
## [Unreleased]
|
||||
|
||||
## [1.17.0] 2022-11-19
|
||||
## [v1.26.0] - 2025-03-17
|
||||
### Changed
|
||||
* upgrade murph/murph-core
|
||||
|
||||
## [v1.25.1] - 2024-05-13
|
||||
### Fixed
|
||||
* fix murph-npm version
|
||||
|
||||
## [v1.25.0] - 2024-05-12
|
||||
### Changed
|
||||
* upgrade murph/murph-core
|
||||
|
||||
## [v1.23.0] - 2023-09-28
|
||||
### Changed
|
||||
* upgrade murph/murph-core
|
||||
|
||||
## [v1.22.0] - 2023-09-28
|
||||
### Added
|
||||
* update woodpecker ci base file
|
||||
### Fixed
|
||||
* fix #1: add UniqueEntity constraint in the User entity
|
||||
### Changed
|
||||
* upgrade murph/murph-core
|
||||
|
||||
## [1.21.0] - 2023-08-11
|
||||
### Changed
|
||||
* upgrade murph/murph-core
|
||||
|
||||
## [1.20.0] - 2023-07-27
|
||||
### Fixed
|
||||
* fix collection widget: allow_add/allow_delete and prototype
|
||||
### Added
|
||||
* add user admin controller and simples views in default files
|
||||
* add chdir in the console entrypoint
|
||||
### Changed
|
||||
* upgrade murph/murph-core
|
||||
|
||||
## [1.19.0] - 2023-04-15
|
||||
### Changed
|
||||
* upgrade murph/murph-core
|
||||
|
||||
## [1.18.0] - 2023-01-13
|
||||
### Added
|
||||
* feat(dep): update dependencies
|
||||
* feat(update): apply new recipe for phpunit
|
||||
* feat(update): apply recipes:update doctrine/doctrine-bundle
|
||||
* feat(update): apply recipes:update doctrine/doctrine-migrations-bundle
|
||||
* feat(update): apply recipes:update liip/imagine-bundle
|
||||
* feat(update): apply recipes:update stof/doctrine-extensions-bundle
|
||||
* feat(update): apply recipes:update symfony/apache-pack
|
||||
* feat(update): apply recipes:update symfony/console
|
||||
* feat(update): apply recipes:update symfony/debug-bundle
|
||||
* feat(update): apply recipes:update symfony/flex
|
||||
* feat(update): apply recipes:update symfony/mailer
|
||||
* feat(update): apply recipes:update symfony/framework-bundle
|
||||
* feat(update): apply recipes:update symfony/monolog-bundle
|
||||
* feat(update): apply recipes:update symfony/routing
|
||||
* feat(update): apply recipes:update symfony/security-bundle
|
||||
* feat(update): apply recipes:update symfony/translation
|
||||
* feat(update): apply recipes:update symfony/twig-bundle
|
||||
* feat(update): apply recipes:update symfony/validator
|
||||
* feat(update): apply recipes:update symfony/web-profiler-bundle
|
||||
* feat(update): apply recipes:update symfony/webpack-encore-bundle
|
||||
* feat(update): apply recipes:update scheb/2fa-bundle
|
||||
### Fixed
|
||||
* fix(config): fix typo in 2fa conf
|
||||
* fix(config): fix firewall config
|
||||
|
||||
|
||||
## [1.17.0] - 2022-11-19
|
||||
### Changed
|
||||
* upgrade murph/murph-core
|
||||
* replace annotation with attributes
|
||||
|
|
|
|||
3
Makefile
3
Makefile
|
|
@ -24,6 +24,3 @@ doctrine-migration:
|
|||
PHP=$(PHP_BIN) ./bin/doctrine-migrate
|
||||
|
||||
build: clean js-routing asset
|
||||
|
||||
run-tests:
|
||||
$(PHP_BIN) bin/phpunit tests/
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
|
|||
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
chdir(__DIR__.'/../');
|
||||
|
||||
return function (array $context) {
|
||||
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
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)"
|
||||
CLASS_NAME="$(echo "yes" | "$PHP" ./bin/console doctrine:migration:diff -e dev | 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 "$APP_ENV"
|
||||
echo "yes" | "$PHP" ./bin/console doctrine:migration:exec --up "DoctrineMigrations\\$CLASS_NAME" -e dev
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -7,15 +7,13 @@
|
|||
"prefer-stable": true,
|
||||
"require": {
|
||||
"php": ">=8.0.0",
|
||||
"murph/murph-core": "dev-master"
|
||||
"murph/murph-core": "^1.26"
|
||||
},
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ core:
|
|||
# - image/png
|
||||
# - image/jpg
|
||||
# - image/jpeg
|
||||
# - image/webp
|
||||
# - image/gif
|
||||
# - image/svg+xml
|
||||
# - video/mp4
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@ security:
|
|||
App\Entity\User:
|
||||
algorithm: auto
|
||||
|
||||
access_decision_manager:
|
||||
strategy: consensus
|
||||
allow_if_all_abstain: false
|
||||
|
||||
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
|
||||
enable_authenticator_manager: true
|
||||
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
|
||||
|
|
|
|||
11023
package-lock.json
generated
11023
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -13,22 +13,13 @@
|
|||
<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="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 name="Project Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
|
|
@ -42,7 +33,10 @@
|
|||
<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>
|
||||
|
|
|
|||
79
src/Controller/UserAdminController.php
Normal file
79
src/Controller/UserAdminController.php
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Core\Controller\User\UserAdminController as BaseUserAdminController;
|
||||
use App\Core\Crud\CrudConfiguration;
|
||||
use App\Core\Factory\UserFactory as Factory;
|
||||
use App\Core\Manager\EntityManager;
|
||||
use App\Core\Security\TokenGenerator;
|
||||
use App\Entity\User as Entity;
|
||||
use App\Repository\UserRepositoryQuery as RepositoryQuery;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class UserAdminController extends BaseUserAdminController
|
||||
{
|
||||
#[Route(path: '/admin/user/{page}', name: 'admin_user_index', methods: ['GET'], requirements: ['page' => '\d+'])]
|
||||
public function index(RepositoryQuery $query, Request $request, Session $session, int $page = 1): Response
|
||||
{
|
||||
return parent::index($query, $request, $session, $page);
|
||||
}
|
||||
|
||||
#[Route(path: '/admin/user/new', name: 'admin_user_new', methods: ['GET', 'POST'])]
|
||||
public function new(Factory $factory, EntityManager $entityManager, Request $request, TokenGenerator $tokenGenerator): Response
|
||||
{
|
||||
return parent::new($factory, $entityManager, $request, $tokenGenerator);
|
||||
}
|
||||
|
||||
#[Route(path: '/admin/user/show/{entity}', name: 'admin_user_show', methods: ['GET'])]
|
||||
public function show(Entity $entity): Response
|
||||
{
|
||||
return parent::show($entity);
|
||||
}
|
||||
|
||||
#[Route(path: '/admin/user/filter', name: 'admin_user_filter', methods: ['GET'])]
|
||||
public function filter(Session $session): Response
|
||||
{
|
||||
return parent::filter($session);
|
||||
}
|
||||
|
||||
#[Route(path: '/admin/user/edit/{entity}', name: 'admin_user_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Entity $entity, EntityManager $entityManager, Request $request): Response
|
||||
{
|
||||
return parent::edit($entity, $entityManager, $request);
|
||||
}
|
||||
|
||||
#[Route(path: '/admin/user/inline_edit/{entity}/{context}/{label}', name: 'admin_user_inline_edit', methods: ['GET', 'POST'])]
|
||||
public function inlineEdit(string $context, string $label, Entity $entity, EntityManager $entityManager, Request $request): Response
|
||||
{
|
||||
return parent::inlineEdit($context, $label, $entity, $entityManager, $request);
|
||||
}
|
||||
|
||||
#[Route(path: '/admin/user/delete/{entity}', name: 'admin_user_delete', methods: ['DELETE', 'POST'])]
|
||||
public function delete(Entity $entity, EntityManager $entityManager, Request $request): Response
|
||||
{
|
||||
return parent::delete($entity, $entityManager, $request);
|
||||
}
|
||||
|
||||
#[Route(path: '/admin/user/resetting_request/{entity}', name: 'admin_user_resetting_request', methods: ['POST'])]
|
||||
public function requestResetting(Entity $entity, EventDispatcherInterface $eventDispatcher, Request $request): Response
|
||||
{
|
||||
return parent::requestResetting($entity, $eventDispatcher, $request);
|
||||
}
|
||||
|
||||
protected function getConfiguration(): CrudConfiguration
|
||||
{
|
||||
if ($this->configuration) {
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
return parent::getConfiguration()
|
||||
->setView('form', 'admin/user_admin/_form.html.twig')
|
||||
->setView('show_entity', 'admin/user_admin/_show.html.twig')
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
@ -9,9 +9,11 @@ use Doctrine\ORM\Mapping as ORM;
|
|||
use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
|
||||
#[ORM\Entity(repositoryClass: UserRepository::class)]
|
||||
#[ORM\HasLifecycleCallbacks]
|
||||
#[UniqueEntity('email')]
|
||||
class User implements PasswordAuthenticatedUserInterface, UserInterface, TwoFactorInterface, EntityInterface
|
||||
{
|
||||
use Timestampable;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,17 @@
|
|||
|
||||
namespace App;
|
||||
|
||||
use App\Core\DependencyInjection\Compiler\BuilderBlockPass;
|
||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
class Kernel extends BaseKernel
|
||||
{
|
||||
use MicroKernelTrait;
|
||||
|
||||
protected function build(ContainerBuilder $container): void
|
||||
{
|
||||
$container->addCompilerPass(new BuilderBlockPass());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
51
src/Security/Voter/EntityVoter.php
Normal file
51
src/Security/Voter/EntityVoter.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace App\Security\Voter;
|
||||
|
||||
use App\Core\Entity\EntityInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
class EntityVoter extends Voter
|
||||
{
|
||||
public const EDIT = 'edit';
|
||||
public const VIEW = 'show';
|
||||
public const DELETE = 'delete';
|
||||
|
||||
protected function supports(string $attribute, mixed $subject): bool
|
||||
{
|
||||
// replace with your own logic
|
||||
// https://symfony.com/doc/current/security/voters.html
|
||||
return in_array($attribute, [self::EDIT, self::VIEW, self::DELETE])
|
||||
&& $subject instanceof EntityInterface;
|
||||
}
|
||||
|
||||
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
|
||||
{
|
||||
$user = $token->getUser();
|
||||
|
||||
if (!$user instanceof UserInterface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ($attribute) {
|
||||
case self::EDIT:
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
||||
case self::VIEW:
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
||||
case self::DELETE:
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
1
templates/admin/user_admin/_form.html.twig
Normal file
1
templates/admin/user_admin/_form.html.twig
Normal file
|
|
@ -0,0 +1 @@
|
|||
{{ include('@Core/user/user_admin/_form.html.twig') }}
|
||||
1
templates/admin/user_admin/_show.html.twig
Normal file
1
templates/admin/user_admin/_show.html.twig
Normal file
|
|
@ -0,0 +1 @@
|
|||
{{ include('@Core/user/user_admin/_show.html.twig') }}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<?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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
<?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());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
<?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');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
<?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');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
<?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');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<?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');
|
||||
}
|
||||
}
|
||||
|
|
@ -13,9 +13,3 @@ 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__
|
||||
));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue