Skip to content

Commit

Permalink
Fix UI 5.0.0 compatibility and tests (#111)
Browse files Browse the repository at this point in the history
* composer changes

* use create app trait from ui for tests

* demo fixes

* actual compatibility fixes

* do not ignore phpstan errors

* Update build-release.yml

* Update test-unit.yml

* rollback phpstan ignores

* cant get rid of @var nicely, so they stay

* create custom test models and add test for them

* cleanup magic

* set to be compatible with 5.0.0

* Address suggestions

* switch back to dev-develop

* force 5.0.0

* Update composer.json

Co-authored-by: Michael Voříšek <[email protected]>

* downgrade phpunit

* Update test-unit.yml

* Update test-unit.yml

* Update test-unit.yml

* oh, no filter ?

* Update test-unit.yml

* switch back to dev-develop

---------

Co-authored-by: Michael Voříšek <[email protected]>
  • Loading branch information
DarkSide666 and mvorisek authored Mar 25, 2024
1 parent 69f1a8a commit 4432822
Show file tree
Hide file tree
Showing 23 changed files with 265 additions and 208 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
container:
image: ghcr.io/mvorisek/image-php:latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}

Expand Down
115 changes: 53 additions & 62 deletions .github/workflows/test-unit.yml

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@
},
"require-release": {
"php": ">=7.4 <8.4",
"atk4/ui": "~5.1.0"
"atk4/ui": "~5.0.0"
},
"require-dev": {
"atk4/behat-mink-selenium2-driver": "^1.6.2",
"behat/mink-extension": "^2.3.1",
"ergebnis/composer-normalize": "^2.13",
"johnkary/phpunit-speedtrap": "^3.3",
"ergebnis/phpunit-slow-test-detector": "^2.9",
"friendsofphp/php-cs-fixer": "^3.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.0",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-strict-rules": "^1.3",
"phpunit/phpunit": "^9.5.5 || ^10.0"
"phpunit/phpunit": "^9.5.5"
},
"conflict": {
"behat/behat": "<3.9",
Expand All @@ -63,7 +63,10 @@
"autoload-dev": {
"psr-4": {
"Atk4\\Login\\Tests\\": "tests/"
}
},
"files": [
"vendor/atk4/ui/tests/CreateAppTrait.php"
]
},
"config": {
"allow-plugins": {
Expand Down
3 changes: 3 additions & 0 deletions demos/_includes/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class App extends \Atk4\Ui\App

public $title = 'Demo App';

/** @var Layout\Admin */
public $layout; // @phpstan-ignore-line

public function init(): void
{
$this->initLayout([Layout\Admin::class]);
Expand Down
5 changes: 3 additions & 2 deletions demos/admin-setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Atk4\Ui\Button;
use Atk4\Ui\Console;
use Atk4\Ui\Header;
use Atk4\Ui\Js\JsBlock;
use Atk4\Ui\Message;
use Atk4\Ui\View;

Expand Down Expand Up @@ -106,8 +107,8 @@
// button to execute migration
$b = Button::addTo($v, ['Run migration', 'icon' => 'check']);
$b->on('click', static function () use ($c1, $b) {
return [
return new JsBlock([
$c1->jsExecute(),
$b->js()->hide(),
];
]);
});
3 changes: 2 additions & 1 deletion demos/db.default.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Atk4\Login\Demos;

use Atk4\Core\Exception;
use Atk4\Data\Persistence;

// to use MySQL database:
Expand All @@ -14,7 +15,7 @@

$sqliteFile = __DIR__ . '/_demo-data/db.sqlite';
if (!file_exists($sqliteFile)) {
throw new \Exception('Sqlite database does not exist, create it first');
throw new Exception('Sqlite database does not exist, create it first. Call _demo-data/create-db.php file from console.');
}
$db = new Persistence\Sql('sqlite:' . $sqliteFile);
unset($sqliteFile);
8 changes: 5 additions & 3 deletions demos/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Atk4\Ui\Button;
use Atk4\Ui\Header;
use Atk4\Ui\Message;
use Atk4\Ui\Text;
use Atk4\Ui\View;

/** @var App $app */
Expand All @@ -21,12 +22,13 @@
// Info
if ($app->auth->isLoggedIn()) {
$a = Message::addTo($app, ['type' => 'info'])->set('Currently logged in: ' . $app->auth->user->getTitle());
Button::addTo($a, ['Logout', 'icon' => 'sign out'])->link([$app->auth->pageDashboard, 'logout' => true]);
Button::addTo($a, ['Logout', 'icon' => 'sign out'])->link([$app->auth->pageDashboard, 'logout' => 1]);
} else {
$a = Message::addTo($app, ['type' => 'info'])->set('Currently there is no user logged in');
Button::addTo($a, ['Login', 'icon' => 'key'])->link(['form-login']);
}

// Addon description
$v = View::addTo($app, ['ui' => 'segment']);
$v->set('Here goes small description of this addon');
Text::addTo(View::addTo($app, ['ui' => 'segment']))
->addParagraph('ATK UI implements a high-level User Interface for Web App - such as Admin System. One of the most common things for the Admin system is a log-in screen.')
->addParagraph('Although you can implement log-in form easily, this add-on does everything for you.');
68 changes: 32 additions & 36 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,35 @@ parameters:
- '~^Only booleans are allowed in .+, .+ given( on the (left|right) side)?\.~'

# TODO these rules are generated, this ignores should be fixed in the code
-
message: '~^Access to an undefined property Atk4\\Ui\\Layout::\$menuLeft\.$~'
count: 5
path: demos/_includes/App.php
-
message: '~^Call to an undefined method Atk4\\Ui\\Form\\Control::addAction\(\)\.$~'
count: 1
path: src/Form/Login.php
-
message: '~^Call to an undefined method Atk4\\Ui\\Form\\Control::setInputAttr\(\)\.$~'
count: 2
path: src/Form/Register.php
-
message: '~^Call to an undefined method Atk4\\Data\\Reference\\HasOne::addTitle\(\)\.$~'
count: 1
path: src/Model/AccessRule.php
-
message: '~^Call to an undefined method Atk4\\Data\\Reference\\HasOne::addTitle\(\)\.$~'
count: 1
path: src/Model/User.php
-
message: '~^Call to an undefined method Atk4\\Ui\\Table\\Column::addModal\(\)\.$~'
count: 1
path: src/RoleAdmin.php
-
message: '~^Call to an undefined method Atk4\\Ui\\Table\\Column::addModal\(\)\.$~'
count: 1
path: src/UserAdmin.php
-
message: '~^Call to an undefined method Atk4\\Ui\\Form\\Control::addAction\(\)\.$~'
count: 1
path: src/UserAdmin.php
-
message: '~^Call to an undefined method Atk4\\Ui\\View::jsHide\(\)\.$~'
count: 1
path: src/UserAdmin.php
#-
# message: '~^Call to an undefined method Atk4\\Ui\\Form\\Control::addAction\(\)\.$~'
# count: 1
# path: src/Form/Login.php
#-
# message: '~^Call to an undefined method Atk4\\Ui\\Form\\Control::setInputAttr\(\)\.$~'
# count: 2
# path: src/Form/Register.php
#-
# message: '~^Call to an undefined method Atk4\\Data\\Reference\\HasOne::addTitle\(\)\.$~'
# count: 1
# path: src/Model/AccessRule.php
#-
# message: '~^Call to an undefined method Atk4\\Data\\Reference\\HasOne::addTitle\(\)\.$~'
# count: 1
# path: src/Model/User.php
#-
# message: '~^Call to an undefined method Atk4\\Ui\\Table\\Column::addModal\(\)\.$~'
# count: 1
# path: src/RoleAdmin.php
#-
# message: '~^Call to an undefined method Atk4\\Ui\\Table\\Column::addModal\(\)\.$~'
# count: 1
# path: src/UserAdmin.php
#-
# message: '~^Call to an undefined method Atk4\\Ui\\Form\\Control::addAction\(\)\.$~'
# count: 1
# path: src/UserAdmin.php
#-
# message: '~^Call to an undefined method Atk4\\Ui\\View::jsHide\(\)\.$~'
# count: 1
# path: src/UserAdmin.php
12 changes: 9 additions & 3 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@
<directory>tests</directory>
</testsuite>
</testsuites>
<listeners>
<listener class="JohnKary\PHPUnit\Listener\SpeedTrapListener" />
</listeners>
<extensions>
<bootstrap class="Ergebnis\PHPUnit\SlowTestDetector\Extension" />
</extensions>
<source>
<include>
<directory>src</directory>
<directory>tests</directory>
</include>
</source>
<coverage>
<include>
<directory>src</directory>
Expand Down
3 changes: 1 addition & 2 deletions src/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ public function addUserMenu(): void
$menu->addItem(['Preferences', 'icon' => 'user'], $userPage->getUrl());
}

$menu->addItem(['Logout', 'icon' => 'sign out'], [$this->pageDashboard, 'logout' => true]);
$menu->addItem(['Logout', 'icon' => 'sign out'], [$this->pageDashboard, 'logout' => 1]);
}
}

Expand All @@ -302,7 +302,6 @@ public function displayLoginForm(array $seed = []): void
{
$app = $this->getApp();

$app->catchRunawayCallbacks = false;
$app->html = null;
$app->initLayout([Narrow::class]);
$app->title .= ' - Login Required';
Expand Down
8 changes: 7 additions & 1 deletion src/Feature/SetupUserModelTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Atk4\Login\Feature;

// use Atk4\Data\Persistence; // for 5.1.0 compatibility

trait SetupUserModelTrait
{
use UniqueFieldValueTrait;
Expand All @@ -19,7 +21,11 @@ public function setupUserModel(): void
// all AccessRules for all user roles
// @TODO in future when there can be multiple, then merge them together
$this->hasMany('AccessRules', [
'model' => static function (self $m) {
// for 5.1.0 compatibility
// 'model' => function (Persistence $p, array $defaults = []) {
// return $this->ref('role_id')->ref('AccessRules');
// }
'model' => static function ($m) {
return $m->ref('role_id')->ref('AccessRules');
},
'ourField' => 'role_id',
Expand Down
2 changes: 1 addition & 1 deletion src/Form/Control/GenericDropdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
abstract class GenericDropdown extends Form\Control\Dropdown
{
/** @var bool Dropdown with multiselect */
public $isMultiple = true;
public $multiple = true;

/**
* Get AccessRule->model and initialize it.
Expand Down
24 changes: 19 additions & 5 deletions src/Form/Register.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@
use Atk4\Data\Model;
use Atk4\Login\Auth;
use Atk4\Ui\Form;
use Atk4\Ui\Form\Control;

/**
* Register form view.
*/
class Register extends Form
{
/** @var Auth object */
/** @var array Page to redirect after succesful creating of user */
public $linkSuccess = [null];

/** @var Auth|null object */
public $auth;

#[\Override]
Expand All @@ -25,6 +29,12 @@ protected function init(): void
$this->buttonSave->set('Register');
$this->buttonSave->addClass('large fluid');
$this->buttonSave->iconRight = 'right arrow';

if ($this->linkSuccess !== [null]) {
$this->onHook(self::HOOK_DISPLAY_SUCCESS, function () {
return $this->getApp()->jsRedirect($this->linkSuccess);
});
}
}

#[\Override]
Expand All @@ -34,10 +44,14 @@ public function setModel(Model $user, array $fields = null): void

$this->addControl('name', [], ['required' => true]);
$this->addControl('email', [], ['required' => true]);
$this->addControl('password', [], ['type' => 'string', 'required' => true])
->setInputAttr('autocomplete', 'new-password');
$this->addControl('password2', [], ['type' => 'string', 'neverPersist' => true, 'required' => true, 'caption' => 'Repeat Password'])
->setInputAttr('autocomplete', 'new-password');

/** @var Control\Input */
$p1 = $this->addControl('password', [Control\Password::class], ['type' => 'string', 'required' => true]);
$p1->setInputAttr('autocomplete', 'new-password');

/** @var Control\Input */
$p2 = $this->addControl('password2', [Control\Password::class], ['type' => 'string', 'neverPersist' => true, 'required' => true, 'caption' => 'Repeat Password']);
$p2->setInputAttr('autocomplete', 'new-password');

// on form submit save new user in persistence
$this->onSubmit(function (self $form) {
Expand Down
5 changes: 4 additions & 1 deletion src/Model/AccessRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@ class AccessRule extends Model
public $table = 'login_access_rule';
public $caption = 'Access Rule';

/** @var array<mixed> Default Role model. */
protected array $roleModelSeed = [Role::class];

#[\Override]
protected function init(): void
{
parent::init();

/** @var HasOneSql */
$r = $this->hasOne('role_id', [
'model' => [Role::class],
'model' => $this->roleModelSeed,
'ourField' => 'role_id',
'theirField' => 'id',
'caption' => 'Role',
Expand Down
10 changes: 8 additions & 2 deletions src/Model/Role.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ class Role extends Model
public $table = 'login_role';
public $caption = 'Role';

/** @var array<mixed> Default User model. */
protected array $userModelSeed = [User::class];

/** @var array<mixed> Default AccessRule model. */
protected array $accessRuleModelSeed = [AccessRule::class];

#[\Override]
protected function init(): void
{
Expand All @@ -22,12 +28,12 @@ protected function init(): void
$this->addField('name');

$this->hasMany('Users', [
'model' => [User::class],
'model' => $this->userModelSeed,
'ourField' => 'id',
'theirField' => 'role_id',
]);
$this->hasMany('AccessRules', [
'model' => [AccessRule::class],
'model' => $this->accessRuleModelSeed,
'ourField' => 'id',
'theirField' => 'role_id',
]);
Expand Down
10 changes: 7 additions & 3 deletions src/Model/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Atk4\Login\Feature\SendEmailActionTrait;
use Atk4\Login\Feature\SetupUserModelTrait;
use Atk4\Login\Feature\SignupTrait;
use Atk4\Ui\Form\Control\Password;

class User extends Model
{
Expand All @@ -22,19 +23,22 @@ class User extends Model
public $table = 'login_user';
public $caption = 'User';

/** @var array<mixed> Default Role model. */
protected array $roleModelSeed = [Role::class];

#[\Override]
protected function init(): void
{
parent::init();

$this->addField('name');
$this->addField('email');
$this->addField('password', [PasswordField::class]);
$this->addField('email', ['caption' => 'Email/Login']);
$this->addField('password', [PasswordField::class, 'ui' => ['form' => [Password::class]]]);

// currently user can have only one role. In future it should be n:n relation
/** @var HasOneSql */
$r = $this->hasOne('role_id', [
'model' => [Role::class],
'model' => $this->roleModelSeed,
'ourField' => 'role_id',
'theirField' => 'id',
'caption' => 'Role',
Expand Down
Loading

0 comments on commit 4432822

Please sign in to comment.