Test formuláře – podstrčení tlačítka

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Filip111
Člen | 244
+
0
-

Ahoj,
snažím se otestovat odeslání formuláře, ale nedaří se mi nastavit tlačítko, kterým je formulář odeslán.
Podobný způsob testu formuláře jsem tu našel někde na fóru, ale nevím jestli je to správný postup.

<?php
// zpracovani formulare
public function reportSubmitted(BaseForm $form) {
	if ($form['send']->isSubmittedBy()) {
		// tento kod se nevykona, protoze neni formular korektne odeslan pres tlacitko send
		$this->presenter->redirect(':nekam:jinak');
	}
}
?>
<?php
// test formulare
public function testReportSubmitted() {
	$form = $this->control["reportForm"];
	$form->setDefaults(array(
            'name' => 'my name',
			'send' => 'send'
	));

	try {
		$this->control->reportSubmitted($form);
	} catch(\Nette\Application\AbortException $e) {
		// testy toho co mel formular provest
	}
?>

Dotazy:

  1. Jak bych měl formulář odeslat, aby se tvářil jako odeslaný pomocí tlačítka send?
  2. Jak vlastně správně otestovat odeslání a zpracování formuláře? Většina metod, kde se formulář zpracovává provede na konci redirect. Při testu a spuštění $this->control->reportSubmitted($form); to ale vrací Nette\Application\AbortException.

Vyřešil jsme to, odchycením výjimky a následně kontrolou toho co měl formulář provést – že se v DB změnil nějaký záznam apod. Určitě to ale neni nejlepší způsob a než začnu psát další testy na formuláře, chtěl bych si to trochu ujasnit.

Díky.

vymak
Člen | 92
+
+1
-

Řesím to nějak takhle, trošku jsem to ale zjednodušil aby to bylo čitelnější. Jinak ty spodní dvě metody mám v samostatné třídě abych to nemusel psát v každém testu.

Zašleš vlastně jen požadavek na presenter kde se ten tvůj formulář zobrazuje a podstrčíš mu data $post a pak do $do dáš jen name potvrzovacího tlačítka.

	/**
 * @dataProvider getHash
 */
public function testVerify($hash)
{
    $post = [
        'hash' => $hash
    ];

    $this->testForm('PresenterName', 'default', 'feedbackVerify-feedbackVerify-submit', $post);

    $session = $this->getSession();
    Assert::true($session->hasSection('sluzby'));
    $section = $session->getSection('sluzby');
    Assert::true(isset($section->hash));
    Assert::type('string', $section->hash);
}

	public function testForm($presenterName, $action, $do, $post = [], $params = [], $wrong = FALSE, $method = 'POST')
{
    if (!isset($params['do'])) {
        $params['do'] = $do;
    }

    $response = $this->test($presenterName, $action, $method, $params, $post);
    if (!$wrong) {
        Assert::type('Nette\Application\Responses\RedirectResponse', $response);
    } else {
        Assert::type('Nette\Application\Responses\TextResponse', $response);
    }
    return $response;
}

	/**
 * @param string $action
 * @param string $method
 * @param array $params
 * @param array $post
 * @return \Nette\Application\IResponse
 */
public function test($presenterName, $action, $method = 'GET', $params = array(), $post = array())
{
    $params['action'] = $action;
    $request = new Request($presenterName, $method, $params, $post);
    $response = $this->presenter->run($request);
    return $response;
}

Editoval vymak (10. 11. 2014 16:29)

Filip111
Člen | 244
+
0
-

Zkusím tvůj kód použít na formuláře zasazené napevno v presenteru – tam to bude asi ok.

Akorát jsem na začátku špatně popsal, co testuji. Ono se jedná o formuláře v komponentě,
tedy postupuju opačně než ty.
Mám univerzální/libovolný presenter, tomu přidám komponentu a pak pracuji s formulářem komponenty.

<?php
protected function setUp() {
	$control = new NejakyFormControl;
	// vyrobim presenter
	$presenterFactory = $container->getByType('Nette\Application\IPresenterFactory');
	$presenter = $presenterFactory->createPresenter('Cms:Homepage:Frontend');
	$presenter->autoCanonicalize = FALSE;
	// priradim komponentu
	$presenter->addComponent($control, "komponenta");
	$request = new Nette\Application\Request('Cms:Homepage:Frontend', 'GET', array('action' => 'default'));
	// spustim
	$presenter->run($request);
	$this->control = $presenter["komponenta"];
}

// vlastni test formulare
public function testReportSubmitted() {
    $form = $this->control["formularKomponenty"];
	$form->setDefaults(array(
		'name' => 'my name',
		'send' => 'send'
    ));

    try {
        $this->control->reportSubmitted($form);
    } catch(\Nette\Application\AbortException $e) {
        // testy toho co mel formular provest
    }
?>

Když o tom, ale přemýšlím, po sestavení presenteru, přiřazení komponenty, by už měl fungovat i tvůj kód.
Vyzkoušim.

vymak
Člen | 92
+
0
-

Mám taky formulář v samostatné komponentě, ale testuji tak, že si komponentu přidám k presenteru a poté si jej nechám vyrenderovat a otestuji, zda-li obsahuje opravdu to co obsahovat má.

	public function testRenderOther()
{
    $this->presenter->addComponent($this->control, 'partners');

    ob_start();
    $this->presenter['partners']->render();
    $output = ob_get_clean();

    $dom = DomQuery::fromHtml($output);

    Assert::truthy($output);
    Assert::true($dom->has('a'));
    Assert::count(count($this->partners->partnersFooter(FALSE)), $dom->find('a'));
}

Odeslání formuláře a otestování zda-li opravdu provedl to co má již provádím přes ten request co jsem psal výše :)

Editoval vymak (10. 11. 2014 19:16)