From 4f996eb7d27abf57162c090981e2695a1cd109d0 Mon Sep 17 00:00:00 2001 From: Brandon Shipley Date: Tue, 17 Mar 2026 01:35:40 -0700 Subject: [PATCH] testing brought in --- composer.json | 32 ++- phpcs.xml | 20 ++ phpstan.neon | 10 + phpunit.xml.dist | 49 +++-- psalm.xml | 15 ++ src/CheeseCakePlugin.php | 56 +++-- src/Controller/AppController.php | 3 +- src/Controller/Traits/OverrideTableTrait.php | 85 ++++---- src/Model/Entity/SecureEntity.php | 9 +- src/View/Helper/ActiveLinkHelper.php | 201 +++++++++++------- .../View/Helper/ActiveLinkHelperTest.php | 118 ++++++++++ tests/bootstrap.php | 56 +++-- tests/test_app/config/bootstrap.php | 1 + tests/test_app/config/routes.php | 95 +++++++++ .../test_app/src/Controller/AppController.php | 16 ++ tests/test_app/src/View/AppView.php | 11 + tests/test_app/templates/Error/error500.php | 44 ++++ tests/test_app/templates/layout/ajax.php | 6 + tests/test_app/templates/layout/default.php | 6 + tests/test_app/webroot/images/cake_icon.png | Bin 0 -> 943 bytes 20 files changed, 641 insertions(+), 192 deletions(-) create mode 100644 phpcs.xml create mode 100644 phpstan.neon create mode 100644 psalm.xml create mode 100644 tests/TestCase/View/Helper/ActiveLinkHelperTest.php create mode 100644 tests/test_app/config/bootstrap.php create mode 100644 tests/test_app/config/routes.php create mode 100644 tests/test_app/src/Controller/AppController.php create mode 100644 tests/test_app/src/View/AppView.php create mode 100644 tests/test_app/templates/Error/error500.php create mode 100644 tests/test_app/templates/layout/ajax.php create mode 100644 tests/test_app/templates/layout/default.php create mode 100644 tests/test_app/webroot/images/cake_icon.png diff --git a/composer.json b/composer.json index 06caf68..4ca05e3 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,17 @@ "cakephp/cakephp": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^10.1" + "cakedc/cakephp-phpstan": "^4.1", + "cakephp/bake": "^3.0.0", + "cakephp/cakephp-codesniffer": "^5.0", + "cakephp/debug_kit": "^5.0.0", + "dereuromark/cakephp-ide-helper": "^2.13", + "dereuromark/cakephp-test-helper": "^2.6", + "fig-r/psr2r-sniffer": "^2.7", + "josegonzalez/dotenv": "^4.0", + "php-collective/decimal-object": "^1.3", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.5.5 || ^11.1.3 || ^12.1" }, "autoload": { "psr-4": { @@ -28,7 +38,25 @@ "autoload-dev": { "psr-4": { "CheeseCake\\Test\\": "tests/", - "Cake\\Test\\": "vendor/cakephp/cakephp/tests/" + "Cake\\Test\\": "vendor/cakephp/cakephp/tests/", + "TestApp\\": "tests/test_app/src/" + } + }, + "scripts": { + "post-install-cmd": "App\\Console\\Installer::postInstall", + "post-create-project-cmd": "App\\Console\\Installer::postInstall", + "check": [ + "@test", + "@cs-check" + ], + "test": "phpunit --colors=always", + "cs-check": "vendor/bin/phpcs --colors --parallel=16", + "cs-fix": "vendor/bin/phpcbf --colors --parallel=16", + "stan": "phpstan analyze" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true } } } diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..15ea8b2 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,20 @@ + + + + + src/ + tests/ + + /tests/test_files/ + /tests/test_app/ + + + + + */config/Migrations/* + + + */config/Migrations/* + + + diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..b251d7d --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,10 @@ +includes: + - vendor/cakedc/cakephp-phpstan/extension.neon + +parameters: + level: 4 + paths: + - src + bootstrapFiles: + - tests/bootstrap.php + treatPhpDocTypesAsCertain: false diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8894447..d4010e7 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,22 +1,31 @@ - - - - - - - - - tests/TestCase/ - - - - - - - - - src/ - - + + + + + + + + + + + tests/TestCase/ + + + + + + + + + + + src/ + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..4e9226b --- /dev/null +++ b/psalm.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/src/CheeseCakePlugin.php b/src/CheeseCakePlugin.php index 491ffe1..e4f1b81 100644 --- a/src/CheeseCakePlugin.php +++ b/src/CheeseCakePlugin.php @@ -13,9 +13,9 @@ use Cake\Routing\RouteBuilder; /** * Plugin for CheeseCake */ -class CheeseCakePlugin extends BasePlugin -{ - /** +class CheeseCakePlugin extends BasePlugin { + + /** * Load all the plugin configuration and bootstrap logic. * * The host application is provided as an argument. This allows you to load @@ -24,11 +24,10 @@ class CheeseCakePlugin extends BasePlugin * @param \Cake\Core\PluginApplicationInterface $app The host application * @return void */ - public function bootstrap(PluginApplicationInterface $app): void - { - } + public function bootstrap(PluginApplicationInterface $app): void { + } - /** + /** * Add routes for the plugin. * * If your plugin has many routes and you would like to isolate them into a separate file, @@ -37,48 +36,45 @@ class CheeseCakePlugin extends BasePlugin * @param \Cake\Routing\RouteBuilder $routes The route builder to update. * @return void */ - public function routes(RouteBuilder $routes): void - { - parent::routes($routes); - } + public function routes(RouteBuilder $routes): void { + parent::routes($routes); + } - /** + /** * Add middleware for the plugin. * * @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to update. * @return \Cake\Http\MiddlewareQueue */ - public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue - { - // Add your middlewares here + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { + // Add your middlewares here - return $middlewareQueue; - } + return $middlewareQueue; + } - /** + /** * Add commands for the plugin. * * @param \Cake\Console\CommandCollection $commands The command collection to update. * @return \Cake\Console\CommandCollection */ - public function console(CommandCollection $commands): CommandCollection - { - // Add your commands here + public function console(CommandCollection $commands): CommandCollection { + // Add your commands here - $commands = parent::console($commands); + $commands = parent::console($commands); - return $commands; - } + return $commands; + } - /** + /** * Register application container services. * + * @link https://book.cakephp.org/4/en/development/dependency-injection.html#dependency-injection * @param \Cake\Core\ContainerInterface $container The Container to update. * @return void - * @link https://book.cakephp.org/4/en/development/dependency-injection.html#dependency-injection */ - public function services(ContainerInterface $container): void - { - // Add your services here - } + public function services(ContainerInterface $container): void { + // Add your services here + } + } diff --git a/src/Controller/AppController.php b/src/Controller/AppController.php index fe569b4..4e3d4e7 100644 --- a/src/Controller/AppController.php +++ b/src/Controller/AppController.php @@ -5,6 +5,5 @@ namespace CheeseCake\Controller; use App\Controller\AppController as BaseController; -class AppController extends BaseController -{ +class AppController extends BaseController { } diff --git a/src/Controller/Traits/OverrideTableTrait.php b/src/Controller/Traits/OverrideTableTrait.php index e4859a3..131cbd1 100644 --- a/src/Controller/Traits/OverrideTableTrait.php +++ b/src/Controller/Traits/OverrideTableTrait.php @@ -6,65 +6,66 @@ use Cake\Core\Configure; use Cake\ORM\Table; use Cake\ORM\TableRegistry; -trait OverrideTableTrait -{ - /** - * @var Table|null - */ - protected ?Table $_table = null; +trait OverrideTableTrait { - /** + /** + * @var \Cake\ORM\Table|null + */ + protected ?Table $_table = null; + + /** * This object's default table alias. * * @var string|null */ - protected ?string $defaultTable = null; + protected ?string $defaultTable = null; - /** + /** * @var string */ - protected string $_tableConfigKey = ''; + protected string $_tableConfigKey = ''; - /** + /** * Gets the table instance * - * @return Table + * @return \Cake\ORM\Table */ - public function getTable(string|null $tableName) - { - if ($this->_table instanceof Table) { - return $this->_table; - } - $this->getTableConfigKey(); - $table = $tableName; - if (!isset($table)) { - $table = $this->defaultTable; - if (Configure::read($this->_tableConfigKey)) { - $table = Configure::read($this->_tableConfigKey); - } - } - $this->_table = TableRegistry::getTableLocator()->get($table); + public function getTable(string|null $tableName) { + if ($this->_table instanceof Table) { + return $this->_table; + } + $this->getTableConfigKey(); + $table = $tableName; + if (!isset($table)) { + $table = $this->defaultTable; + if (Configure::read($this->_tableConfigKey)) { + $table = Configure::read($this->_tableConfigKey); + } + } + $this->_table = TableRegistry::getTableLocator()->get($table); - return $this->_table; - } + return $this->_table; + } - protected function getTableConfigKey() - { - if (!$this->_tableConfigKey) { - $this->_tableConfigKey = $this->getPlugin() . '.' . $this->defaultTable . '.table'; - } + /** + * @return string + */ + protected function getTableConfigKey() { + if (!$this->_tableConfigKey) { + $this->_tableConfigKey = $this->getPlugin() . '.' . $this->defaultTable . '.table'; + } - return $this->_tableConfigKey; - } + return $this->_tableConfigKey; + } - /** + /** * Set the users table * - * @param Table $table table + * @param \Cake\ORM\Table $table table * @return void */ - public function setTable(Table $table) - { - $this->_table = $table; - } -} \ No newline at end of file + public function setTable(Table $table) { + $this->_table = $table; + } + +} diff --git a/src/Model/Entity/SecureEntity.php b/src/Model/Entity/SecureEntity.php index 828ce90..aaa4ce5 100644 --- a/src/Model/Entity/SecureEntity.php +++ b/src/Model/Entity/SecureEntity.php @@ -8,9 +8,9 @@ use Cake\ORM\Entity; /** * Secure Entity - must explicitly pass fields that are acceptable to be updated on each newEntity/patchEntity call */ -class SecureEntity extends Entity -{ - /** +class SecureEntity extends Entity { + + /** * Fields that can be mass assigned using newEntity() or patchEntity(). * * Note that when '*' is set to true, this allows all unspecified fields to @@ -19,5 +19,6 @@ class SecureEntity extends Entity * * @var array */ - protected array $_accessible = []; + protected array $_accessible = []; + } diff --git a/src/View/Helper/ActiveLinkHelper.php b/src/View/Helper/ActiveLinkHelper.php index efc40e0..e274d7f 100644 --- a/src/View/Helper/ActiveLinkHelper.php +++ b/src/View/Helper/ActiveLinkHelper.php @@ -3,120 +3,163 @@ declare(strict_types=1); namespace CheeseCake\View\Helper; -use Cake\Log\Log; use Cake\Routing\Router; use Cake\View\Helper; -use Cake\View\View; /** * ActiveLink helper */ -class ActiveLinkHelper extends Helper -{ - /** +class ActiveLinkHelper extends Helper { + + /** * Default configuration. * * @var array */ - protected array $_defaultConfig = [ - 'activeClass' => 'active', - ]; - /** + protected array $_defaultConfig = [ + 'activeClass' => 'active', + ]; + + /** * List of helpers used by this helper * * @var string[] */ - protected array $helpers = [ - 'Html', - 'Url', - ]; + protected array $helpers = [ + 'Html', + 'Url', + ]; - /** + /** * @param array|string $title * @param array|string|null $url * @param array $options * * @return string */ - public function link(array|string $title, array|string|null $url = null, array $options = []): string - { - $currentUrl = Router::parseRequest($this->getView()->getRequest()); - if (!array_key_exists('target', $options) || !$currentUrl) { - return $this->Html->link($title, $url, $options); - } - $target = $options['target']; + public function link(array|string $title, array|string|null $url = null, array $options = []): string { + $currentUrl = $options['current'] ?? Router::parseRequest($this->getView()->getRequest()); + if (!array_key_exists('target', $options) || !$currentUrl) { + return $this->Html->link($title, $url, $options); + } + $target = $options['target']; + $activeClass = $options['activeClass'] ?? $this->getConfig('activeClass'); + unset($options['target']); - if (is_string($target)) { - return $this->_linkFromStringTarget($currentUrl, $target, $title, $url, $options); - } - if (!is_array($target)) { - return $this->Html->link($title, $url, $options); - } + unset($options['activeClass']); + + if (is_string($target)) { + return $this->_linkFromStringTarget($currentUrl, $target, $title, $url, $activeClass, $options); + } + if (!is_array($target)) { + return $this->Html->link($title, $url, $options); + } - if (!array_key_exists('plugin', $currentUrl)) { - $currentUrl['plugin'] = false; - } - if (!array_key_exists('prefix', $currentUrl)) { - $currentUrl['prefix'] = false; - } - if (isset($target['or']) && $target['or']) { - foreach ($target['or'] as $singleTargetToMatch) { - if ($this->_matchesUrlFromArrayTarget($currentUrl, $singleTargetToMatch)) { - $options['class'] = $this->_addClass($options); + if (!array_key_exists('plugin', $currentUrl)) { + $currentUrl['plugin'] = false; + } + if (!array_key_exists('prefix', $currentUrl)) { + $currentUrl['prefix'] = false; + } + if (isset($target['or']) && $target['or']) { + foreach ($target['or'] as $singleTargetToMatch) { + if ($this->_matchesUrlFromArrayTarget($currentUrl, $singleTargetToMatch)) { + $options['class'] = $this->_addClass($options, $activeClass); - return $this->Html->link($title, $url, $options); - } - } - return $this->Html->link($title, $url, $options); - } + return $this->Html->link($title, $url, $options); + } + } - if (!$this->_matchesUrlFromArrayTarget($currentUrl, $target)) { - return $this->Html->link($title, $url, $options); - } + return $this->Html->link($title, $url, $options); + } - $options['class'] = $this->_addClass($options); + if (!$this->doesUrlMatchTarget($target, $currentUrl)) { + return $this->Html->link($title, $url, $options); + } - return $this->Html->link($title, $url, $options); - } + $options['class'] = $this->_addClass($options, $activeClass); + + return $this->Html->link($title, $url, $options); + } - /** + /** + * @param array|string $targetUrl + * @param array|null $current |null current url + * + * @return bool + */ + public function doesUrlMatchTarget(array|string $targetUrl, array|null $current = null) { + if (!isset($current)) { + $current = Router::parseRequest($this->getView()->getRequest()); + } + if (is_string($targetUrl) && Router::normalize($current) == Router::normalize($targetUrl)) { + return true; + } + if (is_array($targetUrl)) { + if (isset($targetUrl['or']) && $targetUrl['or']) { + foreach ($targetUrl['or'] as $singleTargetToMatch) { + $matched = $this->_matchesUrlFromArrayTarget($current, $singleTargetToMatch); + if ($matched) { + return true; + } + } + } + + return $this->_matchesUrlFromArrayTarget($current, $targetUrl); + } + + return false; + } + + /** * @param array $providedOptions * * @return string */ - protected function _addClass(array $providedOptions): string - { - $activeClass = array_key_exists('activeClass', $providedOptions) ? $providedOptions['activeClass'] : $this->getConfig('activeClass'); - - return array_key_exists('class', $providedOptions) ? $providedOptions['class'] . ' ' . $activeClass : $activeClass; - } + protected function _addClass(array $providedOptions, string $toAdd): string { + return array_key_exists('class', $providedOptions) ? $providedOptions['class'] . ' ' . $toAdd : $toAdd; + } + + /** + * @param array $current + * @param string $targetString + * @param string $title + * @param array|string|null $url + * @param array $options + * + * @return string + */ + protected function _linkFromStringTarget(array $current, string $targetString, string $title, array|string|null $url, string $activeClass, array $options) { + if (Router::normalize($current) == Router::normalize($targetString)) { + $options['class'] = $this->_addClass($options, $activeClass); - protected function _linkFromStringTarget(array $current, string $targetString, string $title, array|string|null $url, array $options) - { - if (Router::normalize($current) == Router::normalize($targetString)) { - $options['class'] = $this->_addClass($options); + return $this->Html->link($title, $url, $options); + } - return $this->Html->link($title, $url, $options); - } + return $this->Html->link($title, $url, $options); + } + + /** + * @param array $current + * @param array $targetUrl + * + * @return bool + */ + protected function _matchesUrlFromArrayTarget(array $current, array $targetUrl) { + foreach ($targetUrl as $targetKey => $targetValue) { + if (is_array($targetValue)) { + if (!in_array($current[$targetKey], $targetValue)) { + return false; + } - return $this->Html->link($title, $url, $options); - } + continue; + } + if (!array_key_exists($targetKey, $current) || $targetValue != $current[$targetKey]) { + return false; + } + } - protected function _matchesUrlFromArrayTarget(array $current, array $targetUrl) - { - foreach ($targetUrl as $targetKey => $targetValue) { - if (is_array($targetValue)) { - if (!in_array($current[$targetKey], $targetValue)) { - return false; - } + return true; + } - continue; - } - if (!array_key_exists($targetKey, $current) || $targetValue != $current[$targetKey]) { - return false; - } - } - - return true; - } } diff --git a/tests/TestCase/View/Helper/ActiveLinkHelperTest.php b/tests/TestCase/View/Helper/ActiveLinkHelperTest.php new file mode 100644 index 0000000..7481dca --- /dev/null +++ b/tests/TestCase/View/Helper/ActiveLinkHelperTest.php @@ -0,0 +1,118 @@ +loadRoutes(); + $routeBuilder = Router::createRouteBuilder('/'); + $routeBuilder->scope('/', function (RouteBuilder $routes) { + $routes->setRouteClass(DashedRoute::class); + $routes->get( + '/', + ['controller' => 'Tests', 'action' => 'index'], + ); + $routes->get( + '/admin/users', + ['prefix' => 'Admin', 'controller' => 'Users', 'action' => 'index'], + ); + $routes->get( + '/admin/users/view', + ['prefix' => 'Admin', 'controller' => 'Users', 'action' => 'view'], + ); + }); + + } + + /** + * @return void + */ + public function testLinkMatchesString(): void { + $request = new ServerRequest(['url' => '/']); + $view = new View($request); + $helper = new ActiveLinkHelper($view); + + $result = $helper->link('goto', '/', [ + 'target' => '/', + 'activeClass' => 'awesome-active-class', + ]); + $this->assertStringContainsString('awesome-active-class', $result); + } + + /** + * @return void + */ + public function testLinkMatchesArrayFromCurrent(): void { + $request = new ServerRequest(); + $view = new View($request); + $helper = new ActiveLinkHelper($view); + + // matches specific controller action + $specificActionResult = $helper->link('goto', ['prefix' => 'Admin', 'controller' => 'Users', 'action' => 'index'], [ + 'target' => ['prefix' => 'Admin', 'controller' => 'Users', 'action' => 'index'], + 'current' => ['prefix' => 'Admin', 'controller' => 'Users', 'action' => 'index'], + 'activeClass' => 'awesome-active-class', + ]); + $this->assertStringContainsString('awesome-active-class', $specificActionResult); + + // match whole controller + $wholeControllerResult = $helper->link('goto', [ + 'plugin' => null, + 'prefix' => 'Admin', + 'controller' => 'Users', + 'action' => 'index', + ], [ + 'current' => ['prefix' => 'Admin', 'controller' => 'Users', 'action' => 'index'], + 'target' => ['prefix' => 'Admin', 'controller' => 'Users'], + 'activeClass' => 'awesome-active-class', + ]); + $this->assertStringContainsString('awesome-active-class', $wholeControllerResult); + + // match whole prefix + $wholePrefixResult = $helper->link('goto', [ + 'prefix' => 'Admin', + 'controller' => 'Users', + 'action' => 'index', + ], [ + 'current' => ['prefix' => 'Admin', 'controller' => 'Users', 'action' => 'index'], + 'target' => ['prefix' => 'Admin'], + 'activeClass' => 'awesome-active-class', + ]); + $this->assertStringContainsString('awesome-active-class', $wholePrefixResult); + } + + /** + * @return void + */ + public function testLinkDoesNotMatchArray(): void { + $request = new ServerRequest(); + $request = $request->withParam('prefix', 'Admin'); + $request = $request->withParam('controller', 'Users'); + $request = $request->withParam('action', 'index'); + $view = new View($request); + $helper = new ActiveLinkHelper($view); + + // matches specific controller action + $specificActionResult = $helper->link('goto', ['prefix' => 'Admin', 'controller' => 'Users', 'action' => 'index'], [ + 'target' => ['controller' => 'Events', 'action' => 'index'], + 'current' => ['prefix' => 'Admin', 'controller' => 'Users', 'action' => 'index'], + 'activeClass' => 'awesome-active-class', + 'class' => 'link-class', + ]); + $this->assertStringNotContainsString('awesome-active-class', $specificActionResult); + } + +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index d9ec65c..9776e6a 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,6 +1,27 @@ 'TestApp', + 'encoding' => 'UTF-8', + 'paths' => [ + 'testWebroot' => PLUGIN_ROOT . DS . 'tests' . DS . 'test_app' . DS . 'webroot' . DS, + 'webroot' => PLUGIN_ROOT . DS . 'webroot' . DS, + 'templates' => [ + PLUGIN_ROOT . DS . 'tests' . DS . 'test_app' . DS . 'templates' . DS, + ], + ], +]); /** * Load schema from a SQL dump file. * @@ -49,7 +80,6 @@ if (file_exists($root . '/config/bootstrap.php')) { * using migrations to provide schema for your plugin, * and using \Migrations\TestSuite\Migrator to load schema. */ -use Cake\TestSuite\Fixture\SchemaLoader; // Load a schema dump file. -(new SchemaLoader())->loadSqlFiles('tests/schema.sql', 'test'); +//(new SchemaLoader())->loadSqlFiles('tests/schema.sql', 'test'); diff --git a/tests/test_app/config/bootstrap.php b/tests/test_app/config/bootstrap.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/tests/test_app/config/bootstrap.php @@ -0,0 +1 @@ +setRouteClass(DashedRoute::class); + + $routes->scope('/', function (RouteBuilder $builder): void { + /* + * Here, we are connecting '/' (base path) to a controller called 'Pages', + * its action called 'display', and we pass a param to select the view file + * to use (in this case, templates/Pages/home.php)... + */ + $builder->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']); + + $builder->prefix('Admin', function (RouteBuilder $adminRouteBuilder): void { + $adminRouteBuilder->connect('/users/view', ['controller' => 'Pages', 'action' => 'view']); + $adminRouteBuilder->connect('/users/index', ['controller' => 'Pages', 'action' => 'index']); + }); + + /* + * Connect catchall routes for all controllers. + * + * The `fallbacks` method is a shortcut for + * + * ``` + * $builder->connect('/{controller}', ['action' => 'index']); + * $builder->connect('/{controller}/{action}/*', []); + * ``` + * + * You can remove these routes once you've connected the + * routes you want in your application. + */ + $builder->fallbacks(); + }); + /* + * If you need a different set of middleware or none at all, + * open new scope and define routes there. + * + * ``` + * $routes->scope('/api', function (RouteBuilder $builder): void { + * // No $builder->applyMiddleware() here. + * + * // Parse specified extensions from URLs + * // $builder->setExtensions(['json', 'xml']); + * + * // Connect API actions here. + * }); + * ``` + */ +}; diff --git a/tests/test_app/src/Controller/AppController.php b/tests/test_app/src/Controller/AppController.php new file mode 100644 index 0000000..7387589 --- /dev/null +++ b/tests/test_app/src/Controller/AppController.php @@ -0,0 +1,16 @@ +loadComponent('Flash'); + } +} diff --git a/tests/test_app/src/View/AppView.php b/tests/test_app/src/View/AppView.php new file mode 100644 index 0000000..e885cc1 --- /dev/null +++ b/tests/test_app/src/View/AppView.php @@ -0,0 +1,11 @@ +layout = 'error'; + +if (Configure::read('debug')): + $this->layout = 'dev_error'; + + $this->assign('title', $message); + $this->assign('templateName', 'error500.ctp'); + + $this->start('file'); +?> +queryString)) : ?> +

+ SQL Query: + queryString) ?> +

+ +params)) : ?> + SQL Query Params: + params) ?> + + + Error in: + getFile()), $error->getLine()) ?> + +element('auto_table_warning'); + + if (extension_loaded('xdebug')): + xdebug_print_function_stack(); + endif; + + $this->end(); +endif; +?> +

+

+ : + +

diff --git a/tests/test_app/templates/layout/ajax.php b/tests/test_app/templates/layout/ajax.php new file mode 100644 index 0000000..13b3dea --- /dev/null +++ b/tests/test_app/templates/layout/ajax.php @@ -0,0 +1,6 @@ + +fetch('content') ?> diff --git a/tests/test_app/templates/layout/default.php b/tests/test_app/templates/layout/default.php new file mode 100644 index 0000000..13b3dea --- /dev/null +++ b/tests/test_app/templates/layout/default.php @@ -0,0 +1,6 @@ + +fetch('content') ?> diff --git a/tests/test_app/webroot/images/cake_icon.png b/tests/test_app/webroot/images/cake_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..394fa42d5131cdc7b0b1246af93b92179f3c887e GIT binary patch literal 943 zcmV;g15o^lP)9q)cr7> zIGsQFGn3| zCzs2iP$-yfVPOGVTU&6sT(-5fwHb2tVsLP9#{Vr9Ct?R7q(rf?v2A5#W$OI=e1YUJ zQ1YRnA&iWSQ1XYAm__>aYb6XIhMiYVD+-z8_pYi6+CsH{*^m;vOjqvbr=H&DFkeqxHQBh$Scsoy0Glw(T zsaSG*ok62V;~yXYNgP*DUw;o98^+0@vGFb{HC+As}XJ=;xg=B7N_;-mKbHH{|lXs_o+aPcs5~J?s%^P2Odb)Uz z$GvY6^!N9(C2-h?28B$qx7%_yHnt2eU%nQ0qThbl6a_+b)EirjBgQ`g1_07Fr&6R? RzIgxu002ovPDHLkV1mdlwUYn< literal 0 HcmV?d00001