diff --git a/demos/_unit-test/callback-nested.php b/demos/_unit-test/callback-nested.php index 5d4e9a569e..746313fe4c 100644 --- a/demos/_unit-test/callback-nested.php +++ b/demos/_unit-test/callback-nested.php @@ -10,6 +10,7 @@ use Atk4\Ui\Button; use Atk4\Ui\Crud; +use Atk4\Ui\Exception; use Atk4\Ui\Header; use Atk4\Ui\Loader; use Atk4\Ui\UserAction\ExecutorFactory; @@ -25,26 +26,37 @@ ); $loader = Loader::addTo($app); +$loader->cb->setUrlTrigger('trigger_main_loader'); $loader->loadEvent = false; -$loader->set(function ($p) use ($m) { - $loader_1 = Loader::addTo($p); - $loader_1->loadEvent = false; - +$loader->set(function (Loader $p) use ($m) { Header::addTo($p, ['Loader-1', 'size' => 4]); - $loader_1->set(function ($p) use ($m) { + if (isset($_GET['err_main_loader'])) { + throw new Exception('Exception from Main Loader'); + } + + $loaderSub = Loader::addTo($p); + $loaderSub->cb->setUrlTrigger('trigger_sub_loader'); + $loaderSub->loadEvent = false; + + $loaderSub->set(function (Loader $p) use ($m) { Header::addTo($p, ['Loader-2', 'size' => 4]); - $loader_3 = Loader::addTo($p); - $loader_3->set(function ($p) use ($m) { + if (isset($_GET['err_mid_loader'])) { + throw new Exception('Exception from Sub Loader'); + } + + $loaderSubSub = Loader::addTo($p); + + $loaderSubSub->set(function (Loader $p) use ($m) { Header::addTo($p, ['Loader-3', 'size' => 4]); $c = Crud::addTo($p, ['ipp' => 4]); $c->setModel($m, [$m->fieldName()->name]); }); }); - \Atk4\Ui\Button::addTo($p, ['Load2'])->js('click', $loader_1->jsLoad()); + \Atk4\Ui\Button::addTo($p, ['Load2'])->js('click', $loaderSub->jsLoad()); }); \Atk4\Ui\Button::addTo($app, ['Load1'])->js('click', $loader->jsLoad()); diff --git a/src/Loader.php b/src/Loader.php index dbff967ea7..830fff5b7e 100644 --- a/src/Loader.php +++ b/src/Loader.php @@ -21,7 +21,7 @@ class Loader extends View public $shim; /** - * Specify which event will cause Loader to begen fetching it's actual data. In some cases + * Specify which event will cause Loader to begin fetching it's actual data. In some cases * you would want to wait. You can set a custom JavaScript event name then trigger() it. * * Default value is `true` which means loading will take place as soon as possible. Setting this @@ -35,7 +35,7 @@ class Loader extends View public $ui = 'ui segment'; /** @var Callback for triggering */ - protected $cb; + public $cb; /** @var array Url arguments. */ public $urlArgs = []; diff --git a/tests/DemosTest.php b/tests/DemosTest.php index 5c62bbd567..8179a5c92f 100644 --- a/tests/DemosTest.php +++ b/tests/DemosTest.php @@ -8,6 +8,7 @@ use Atk4\Data\Persistence; use Atk4\Ui\App; use Atk4\Ui\Callback; +use Atk4\Ui\Exception\UnhandledCallbackExceptionError; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; @@ -479,23 +480,44 @@ public function testDemoAssertJsonResponsePost(string $uri, array $postData): vo $this->assertMatchesRegularExpression($this->regexJson, $response->getBody()->getContents()); } - public function testDemoCallbackError(): void + /** + * @dataProvider demoCallbackErrorProvider + */ + public function testDemoCallbackError(string $uri, string $expectedExceptionMessage): void { if (static::class === self::class) { $this->expectException(\Atk4\Ui\Exception::class); - $this->expectExceptionMessage('Callback requested, but never reached. You may be missing some arguments in request URL.'); + $this->expectExceptionMessage($expectedExceptionMessage); } - $uri = 'obsolete/notify2.php?' . Callback::URL_QUERY_TRIGGER_PREFIX . 'test_notify=ajax&' . Callback::URL_QUERY_TARGET . '=non_existing_target'; - try { - $response = $this->getResponseFromRequest($uri, ['form_params' => ['width' => '25%']]); + $response = $this->getResponseFromRequest($uri); } catch (\GuzzleHttp\Exception\ServerException $e) { $response = $e->getResponse(); + } catch (UnhandledCallbackExceptionError $e) { + while ($e instanceof UnhandledCallbackExceptionError) { + $e = $e->getPrevious(); + } + + throw $e; } $this->assertSame(500, $response->getStatusCode()); - $this->assertStringContainsString('Callback requested, but never reached. You may be missing some arguments in request URL.', $response->getBody()->getContents()); + $this->assertStringContainsString($expectedExceptionMessage, $response->getBody()->getContents()); + } + + public function demoCallbackErrorProvider(): array + { + return [ + [ + '_unit-test/callback-nested.php?' . Callback::URL_QUERY_TRIGGER_PREFIX . 'trigger_main_loader=callback&' . Callback::URL_QUERY_TARGET . '=non_existing_target', + 'Callback requested, but never reached. You may be missing some arguments in request URL.', + ], + [ + '_unit-test/callback-nested.php?err_main_loader&' . Callback::URL_QUERY_TRIGGER_PREFIX . 'trigger_main_loader=callback&' . Callback::URL_QUERY_TARGET . '=trigger_main_loader', + 'Exception from Main Loader', + ], + ]; } }