From 6525d6933a5a509a20fe22ba6d94008f5bd22f67 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Tue, 9 Sep 2014 09:40:49 +0200 Subject: [PATCH] Add test for Icinga\Web\Form refs #5525 --- test/php/library/Icinga/Web/FormTest.php | 289 ++++++++++++++++++++--- 1 file changed, 258 insertions(+), 31 deletions(-) diff --git a/test/php/library/Icinga/Web/FormTest.php b/test/php/library/Icinga/Web/FormTest.php index 4e6ec5d92..a2fc9c8b1 100644 --- a/test/php/library/Icinga/Web/FormTest.php +++ b/test/php/library/Icinga/Web/FormTest.php @@ -4,58 +4,285 @@ namespace Tests\Icinga\Web; +use Mockery; use Icinga\Web\Form; +use Icinga\Web\Request; use Icinga\Test\BaseTestCase; +class SuccessfulForm extends Form +{ + public function onSuccess(Request $request) + { + return true; + } +} + class FormTest extends BaseTestCase { - public function testWhetherAddElementDoesNotAddSpecificDecorators() + public function tearDown() + { + Mockery::close(); // Necessary as some tests are running isolated + } + + public function testWhetherASubmitButtonIsAddedWithASubmitLabelBeingSet() { $form = new Form(); - $form->addElement('text', 'someText'); - $element = $form->getElement('someText'); + $form->setTokenDisabled(); + $form->setSubmitLabel('test'); + $form->create(); - $this->assertFalse( - $element->getDecorator('HtmlTag'), - 'Form::addElement does not remove the HtmlTag-Decorator' - ); - $this->assertFalse( - $element->getDecorator('Label'), - 'Form::addElement does not remove the Label-Decorator' - ); - $this->assertFalse( - $element->getDecorator('DtDdWrapper'), - 'Form::addElement does not remove the DtDdWrapper-Decorator' + $this->assertInstanceOf( + '\Zend_Form_Element', + $form->getElement('btn_submit'), + 'Form::create() does not add a submit button in case a submit label is set' ); } - public function testWhetherAddElementDoesNotAddAnyOptionalDecoratorsToHiddenElements() + public function testWhetherNoSubmitButtonIsAddedWithoutASubmitLabelBeingSet() { $form = new Form(); - $form->addElement('hidden', 'somethingHidden'); - $element = $form->getElement('somethingHidden'); + $form->setTokenDisabled(); + $form->create(); + + $this->assertNull( + $form->getElement('btn_submit'), + 'Form::create() adds a submit button in case no submit label is set' + ); + } + + /** + * @depends testWhetherASubmitButtonIsAddedWithASubmitLabelBeingSet + */ + public function testWhetherIsSubmittedReturnsTrueWithASubmitLabelBeingSet() + { + $form = new Form(); + $form->setTokenDisabled(); + $form->setSubmitLabel('test'); + $form->populate(array('btn_submit' => true)); + + $this->assertTrue( + $form->isSubmitted(), + 'Form::isSubmitted() does not return true in case a submit label is set' + ); + } + + /** + * @depends testWhetherNoSubmitButtonIsAddedWithoutASubmitLabelBeingSet + */ + public function testWhetherIsSubmittedReturnsFalseWithoutASubmitLabelBeingSet() + { + $form = new Form(); + + $this->assertFalse( + $form->isSubmitted(), + 'Form::isSubmitted() does not return false in case no submit label is set' + ); + } + + public function testWhetherTheCurrentLocationIsUsedAsDefaultRedirection() + { + $this->getRequestMock()->shouldReceive('getPathInfo')->andReturn('default/route'); + $this->getResponseMock()->shouldReceive('redirectAndExit')->atLeast()->once() + ->with(Mockery::on(function ($url) { return $url->getRelativeUrl() === 'default/route'; })); + + $form = new SuccessfulForm(); + $form->setTokenDisabled(); + $form->setUidDisabled(); + $form->handleRequest(); + } + + public function testWhetherAnExplicitlySetRedirectUrlIsUsedForRedirection() + { + $this->getResponseMock()->shouldReceive('redirectAndExit')->atLeast()->once()->with('special/route'); + + $form = new SuccessfulForm(); + $form->setTokenDisabled(); + $form->setUidDisabled(); + $form->setRedirectUrl('special/route'); + $form->handleRequest(); + } + + /** + * @runInSeparateProcess + */ + public function testWhetherACsrfCounterMeasureIsBeingAdded() + { + Mockery::mock('alias:Icinga\Web\Session')->shouldReceive('getSession->getId')->andReturn('1234567890'); + + $form = new Form(); + $form->create(); + + $this->assertInstanceOf( + '\Zend_Form_Element', + $form->getElement($form->getTokenElementName()), + 'Form::create() does not add a csrf counter measure element' + ); + } + + public function testWhetherACsrfCounterMeasureIsNotBeingAdded() + { + $form = new Form(); + $form->setTokenDisabled(); + $form->create(); + + $this->assertNull( + $form->getElement($form->getTokenElementName()), + 'Form::create() adds a csrf counter measure element in case it\'s disabled' + ); + } + + public function testWhetherAUniqueFormIdIsBeingAdded() + { + $form = new Form(); + $form->setTokenDisabled(); + $form->create(); + + $this->assertInstanceOf( + '\Zend_Form_Element', + $form->getElement($form->getUidElementName()), + 'Form::create() does not add a form identification element' + ); + } + + public function testWhetherAUniqueFormIdIsNotBeingAdded() + { + $form = new Form(); + $form->setTokenDisabled(); + $form->setUidDisabled(); + $form->create(); + + $this->assertNull( + $form->getElement($form->getUidElementName()), + 'Form::create() adds a form identification element in case it\'s disabled' + ); + } + + /** + * @depends testWhetherAUniqueFormIdIsBeingAdded + */ + public function testWhetherAFormIsSentWithAUniqueFormIdBeingAdded() + { + $form = new Form(); + $form->setTokenDisabled(); + $form->create(); + + $this->assertTrue( + $form->wasSent( + array( + $form->getUidElementName() => $form->getElement($form->getUidElementName())->getValue() + ) + ), + 'Form::wasSent() does not return true in case a the form identification value is being sent' + ); + } + + /** + * @depends testWhetherAUniqueFormIdIsNotBeingAdded + */ + public function testWhetherAFormIsNotSentWithoutAUniqueFormIdBeingAdded() + { + $form = new Form(); + $form->setTokenDisabled(); + $form->setUidDisabled(); + $form->create(); + + $this->assertFalse( + $form->wasSent(array()), + 'Form::wasSent() does not return false in case no form identification element was added' + ); + } + + public function testWhetherADefaultActionIsBeingSetOnFormCreation() + { + $this->getRequestMock()->shouldReceive('getPathInfo')->andReturn('some/route'); + + $form = new Form(); + $form->setTokenDisabled(); + $form->create(); + + $this->assertEquals( + '/some/route', + $form->getAction(), + 'Form::create() does not set a default action if none was set explicitly' + ); + } + + /** + * @depends testWhetherAUniqueFormIdIsBeingAdded + * @depends testWhetherASubmitButtonIsAddedWithASubmitLabelBeingSet + */ + public function testWhetherItIsPossibleToRecreateAForm() + { + $form = new Form(); + $form->setTokenDisabled(); + $form->setSubmitLabel('test'); + $form->create(); // sets the flag $this->created to true + $form->clearElements(); // should reset the flag.. + $form->create(); // ..so that we can recreate the form $this->assertCount( - 1, - $element->getDecorators(), - 'Form::addElement adds more decorators than necessary to hidden elements' - ); - $this->assertInstanceOf( - '\Zend_Form_Decorator_ViewHelper', - $element->getDecorator('ViewHelper'), - 'Form::addElement does not add the ViewHelper-Decorator to hidden elements' + 2, + $form->getElements(), + 'Form::clearElements() does not fully reset the form' ); } - public function testWhetherLoadDefaultDecoratorsDoesNotAddTheHtmlTagDecorator() + public function testWhetherGetNameReturnsTheEscapedClassNameByDefault() { $form = new Form(); - $form->loadDefaultDecorators(); - $this->assertArrayNotHasKey( - 'HtmlTag', - $form->getDecorators(), - 'Form::loadDefaultDecorators adds the HtmlTag-Decorator' + $this->assertEquals( + $form->filterName(get_class($form)), + $form->getName(), + 'Form::getName() does not return the escaped class name in case no name was explicitly set' + ); + } + + public function testWhetherGetRequestDataOnlyReturnsFormRelevantData() + { + $form = new Form(); + $form->setMethod('POST'); + + $expectedResult = array('expected_key' => 'expected_value'); + $request = $this->getRequestMock(); + $request->shouldReceive('getMethod')->andReturn('POST') + ->shouldReceive('isPost')->andReturn(true) + ->shouldReceive('getPost')->andReturn($expectedResult); + + $this->assertEquals( + $expectedResult, + $form->getRequestData($request), + 'Form::getRequestData() does not (only) return form relevant data' + ); + } + + /** + * @expectedException LogicException + */ + public function testWhetherTheOnSuccessOptionMustBeCallable() + { + new Form(array('onSuccess' => '_invalid_')); + } + + /** + * @depends testWhetherACsrfCounterMeasureIsNotBeingAdded + * @depends testWhetherAUniqueFormIdIsNotBeingAdded + * @depends testWhetherNoSubmitButtonIsAddedWithoutASubmitLabelBeingSet + */ + public function testWhetherAClosureCanBePassedAsOnSuccessCallback() + { + $request = new Request(); + $form = new Form(array( + 'onSuccess' => function ($req) { $req->setParam('test', 'tset'); return false; } + )); + $form->setTokenDisabled(); + $form->setUidDisabled(); + $form->handleRequest($request); + + $this->assertEquals( + 'tset', + $request->getParam('test'), + 'Form does not utilize the onSuccess callback set with form options on instantiation' ); } }