Jak vytvořit ajaxový \Nette\Http\Request pro účely testování
- kastanekdavid
- Člen | 39
Zdar!
Píšu testy presenteru a potřeboval bych simulovat XMLHttpRequest, aby mi
presenter při spuštění vrátil správný response. Jinými slovy, potřebuju
v tomto případě donutit \Nette\Http\Request
k tomu, aby na
->isAjax()
vrátil true
.
<?php
public function testRenderDashboardAjaxComponent()
{
$request = new Nette\Application\Request('Front:Index', 'GET', ['action' => 'dashboard', 'id' => 2880, 'do' => 'status-1230-detail']);
$response = $this->presenter->run($request); // tady by měl být JSON string se snippetama
}
?>
Je nějaký fundovaný způsob, jak toho docílit? Napadlo mě vytvořit si
vlastní Request
a Response
, které bych nalil do
presenteru pomocí
$presenter->injectPrimary($myRequest, $myResponse)
, ale to se mi
zdá moc divoký.
Nebo bych to neměl potřebovat? Jsem připraven na jakoukoliv odpověď :D
- Martk
- Člen | 661
Napadlo mě něco jako:
class Presenter extends BasePresenter {
public $forceAjax = FALSE;
public function isAjax() {
if ($this->forceAjax) {
return TRUE;
}
return parent::isAjax();
}
}
public function testRenderDashboardAjaxComponent()
{
$request = new Nette\Application\Request('Front:Index', 'GET', ['action' => 'dashboard', 'id' => 2880, 'do' => 'status-1230-detail']);
$this->presenter->forceAjax = TRUE;
$response = $this->presenter->run($request); // tady by měl být JSON string se snippetama
}
Editoval Antik (12. 2. 2016 10:15)
- pata.kusik111
- Člen | 78
Definice $presenter->isAjax()
:
public function isAjax()
{
if ($this->ajaxMode === NULL) {
$this->ajaxMode = $this->httpRequest->isAjax();
}
return $this->ajaxMode;
}
Z toho je patrné, že rozlišení jde udělat takto:
Podědit \Nette\Application\Request
a implementovat metodu
isAjax
aby vracela true
.
- pata.kusik111
- Člen | 78
iguana007 napsal(a):
Nebo jen přidat hlavičku X-Requested-With s hodnotou: XMLHttpRequest
Tím ale spoléháš na to, že ajaxový požadavek lze vždy touto hlavičkou rozeznat. Děláš nějaký předpoklad, který sice v tuto chvíli je pravdivý (nebo by alespoň měl), ale v budoucnu být pravdivý nemusí. A navíc ten předpoklad ani dělat nemusíš.
- kastanekdavid
- Člen | 39
pata.kusik111 napsal(a):
Definice
$presenter->isAjax()
:public function isAjax() { if ($this->ajaxMode === NULL) { $this->ajaxMode = $this->httpRequest->isAjax(); } return $this->ajaxMode; }
Z toho je patrné, že rozlišení jde udělat takto:
Podědit\Nette\Application\Request
a implementovat metoduisAjax
aby vracelatrue
.
Na teoretické rovině souhlasím, můžeš ale pls „zpatrnět“
i postup, jakým tento poděděný Request jednoduše vpravíš do
$presenter->httpRequest
? :)
- kastanekdavid
- Člen | 39
iguana007 napsal(a):
Nebo jen přidat hlavičku X-Requested-With s hodnotou: XMLHttpRequest
Pokud se nepletu, hlavičky se drží přímo
$presenter->httpRequest
v private property
headers
, která nemá setter. Jakým způsobem se tedy pls
jednoduše hlavička přidá? :)
- pata.kusik111
- Člen | 78
@kastanekdavid Na tohle je Nette trošku náročné, takhle nějak to řeším já v Codeception testech:
public function testActionDefault()
{
$this->specify("Access granted to secured presenter action", function() {
$presenter = new \Kusebauch\NetteSecurityAnnotation\Tests\SecurePresenterDummy();
$request = new \Nette\Http\Request(new \Nette\Http\UrlScript);
$response = new \Nette\Http\Response();
$session = new \Nette\Http\Session($request, $response);
$user = new \Nette\Security\User(new \Nette\Http\UserStorage($session));
$presenter->injectPrimary(NULL, NULL, NULL, $request, $response, $session, $user);
$presenter->run(new \Nette\Application\Request("SecurePresenterDummy", "default", []));
});
}
Kde si tedy poděděním nahradíš ten HTTP request.
- kastanekdavid
- Člen | 39
@pata.kusik111 Jj, myslel jsem, že to uděláš přes
$presenter->injectPrimary
, ostatně jsem o tohle způsobu
i přemýšlel (jak zmiňuju v původním dotazu), akorát jsem se tomu
raději vyhnul právě kvůli šílené režii, která okolo toho vzniká.
Antikova metoda sice není tak „čistá“, jako tato (protože mění testovaný presenter jenom kvůli testu), ale přijde mi praktičnější.
I tak díky za námět :)