From 0acaa329a794c4d003fb433bdc71766d385dbfe1 Mon Sep 17 00:00:00 2001 From: "Eric Richer eric.richer@vistoconsulting.com" Date: Thu, 12 Sep 2024 16:03:54 -0400 Subject: [PATCH 1/8] Updated AbstractControllerTestCase::searchTemplate to cycle through all children until found. Added test case and supporting assets to test nested views. Signed-off-by: Eric Richer eric.richer@vistoconsulting.com --- .../Controller/AbstractControllerTestCase.php | 6 ++- test/PHPUnit/Controller/TemplateNameTest.php | 40 +++++++++++++++++++ test/_files/Baz/config/module.config.php | 16 +++++++- .../src/Baz/Controller/IndexController.php | 13 ++++++ test/_files/Baz/view/baz/index/child1.phtml | 1 + test/_files/Baz/view/baz/index/child2.phtml | 1 + .../_files/Baz/view/baz/index/childview.phtml | 3 ++ 7 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 test/PHPUnit/Controller/TemplateNameTest.php create mode 100644 test/_files/Baz/view/baz/index/child1.phtml create mode 100644 test/_files/Baz/view/baz/index/child2.phtml create mode 100644 test/_files/Baz/view/baz/index/childview.phtml diff --git a/src/PHPUnit/Controller/AbstractControllerTestCase.php b/src/PHPUnit/Controller/AbstractControllerTestCase.php index 8006e2a8..a55d8e7b 100644 --- a/src/PHPUnit/Controller/AbstractControllerTestCase.php +++ b/src/PHPUnit/Controller/AbstractControllerTestCase.php @@ -817,11 +817,15 @@ public function assertNotTemplateName($templateName) */ protected function searchTemplates($viewModel, $templateName) { + $found = false; if ($viewModel->getTemplate($templateName) === $templateName) { return true; } foreach ($viewModel->getChildren() as $child) { - return $this->searchTemplates($child, $templateName); + $found = $this->searchTemplates($child, $templateName); + if ($found) { + return $found; + } } return false; diff --git a/test/PHPUnit/Controller/TemplateNameTest.php b/test/PHPUnit/Controller/TemplateNameTest.php new file mode 100644 index 00000000..16d4f835 --- /dev/null +++ b/test/PHPUnit/Controller/TemplateNameTest.php @@ -0,0 +1,40 @@ +setApplicationConfig( + include __DIR__ . '/../../_files/application.config.php' + ); + parent::setUp(); + } + + /** + * Test case for a controller returning a view with 2 children + * View hierarchy: + * layout/layout -> baz/index/childview -> child1 + * -> child2 + */ + public function testAssertTemplateWithMultipleChildren(): void + { + $this->dispatch('/childview'); + + // Check that the rendered content + $this->assertQueryContentContains('p', 'Parent'); + $this->assertQueryContentContains('p', 'Child 1'); + $this->assertQueryContentContains('p', 'Child 2'); + + $this->assertTemplateName('layout/layout'); + $this->assertTemplateName('baz/index/childview'); + $this->assertTemplateName('child1'); + $this->assertTemplateName('child2'); + $this->assertNotTemplateName('foo'); + } +} diff --git a/test/_files/Baz/config/module.config.php b/test/_files/Baz/config/module.config.php index 5de1e01a..5eb90628 100644 --- a/test/_files/Baz/config/module.config.php +++ b/test/_files/Baz/config/module.config.php @@ -108,6 +108,16 @@ ], ], ], + 'childview' => [ + 'type' => 'literal', + 'options' => [ + 'route' => '/childview', + 'defaults' => [ + 'controller' => 'baz_index', + 'action' => 'childview', + ], + ], + ], ], ], 'controllers' => [ @@ -117,8 +127,10 @@ ], 'view_manager' => [ 'template_map' => [ - '404' => __DIR__ . '/../view/baz/error/404.phtml', - 'error' => __DIR__ . '/../view/baz/error/error.phtml', + '404' => __DIR__ . '/../view/baz/error/404.phtml', + 'error' => __DIR__ . '/../view/baz/error/error.phtml', + 'child1' => __DIR__ . '/../view/baz/index/child1.phtml', + 'child2' => __DIR__ . '/../view/baz/index/child2.phtml', ], 'template_path_stack' => [ __DIR__ . '/../view', diff --git a/test/_files/Baz/src/Baz/Controller/IndexController.php b/test/_files/Baz/src/Baz/Controller/IndexController.php index 5ed765bd..88118caa 100644 --- a/test/_files/Baz/src/Baz/Controller/IndexController.php +++ b/test/_files/Baz/src/Baz/Controller/IndexController.php @@ -6,6 +6,7 @@ use Laminas\Http\Response; use Laminas\Mvc\Controller\AbstractActionController; +use Laminas\View\Model\ViewModel; use RuntimeException; class IndexController extends AbstractActionController @@ -61,4 +62,16 @@ public function customResponseAction() public function registerxpathnamespaceAction() { } + + public function childViewAction(): ViewModel + { + $child1 = new ViewModel(); + $child1->setTemplate('child1'); + $child2 = new ViewModel(); + $child2->setTemplate('child2'); + $view = new ViewModel(); + $view->addChild($child1, 'child1'); + $view->addChild($child2, 'child2'); + return $view; + } } diff --git a/test/_files/Baz/view/baz/index/child1.phtml b/test/_files/Baz/view/baz/index/child1.phtml new file mode 100644 index 00000000..7c7e3ee9 --- /dev/null +++ b/test/_files/Baz/view/baz/index/child1.phtml @@ -0,0 +1 @@ +

Child 1

diff --git a/test/_files/Baz/view/baz/index/child2.phtml b/test/_files/Baz/view/baz/index/child2.phtml new file mode 100644 index 00000000..a3efbc73 --- /dev/null +++ b/test/_files/Baz/view/baz/index/child2.phtml @@ -0,0 +1 @@ +

Child 2

diff --git a/test/_files/Baz/view/baz/index/childview.phtml b/test/_files/Baz/view/baz/index/childview.phtml new file mode 100644 index 00000000..755b48c3 --- /dev/null +++ b/test/_files/Baz/view/baz/index/childview.phtml @@ -0,0 +1,3 @@ +

Parent

+child1; ?> +child2; ?> From fe7ae8233a4d4d6043ecc70e4c80f707354e4ff8 Mon Sep 17 00:00:00 2001 From: "Eric Richer eric.richer@vistoconsulting.com" Date: Thu, 12 Sep 2024 16:39:18 -0400 Subject: [PATCH 2/8] Improve AbstractControllerTestCase::searchTemplate to reduce code. Improve test case to test deeper viewer hierarchy Signed-off-by: Eric Richer eric.richer@vistoconsulting.com --- src/PHPUnit/Controller/AbstractControllerTestCase.php | 7 +++---- test/PHPUnit/Controller/TemplateNameTest.php | 4 +++- test/_files/Baz/config/module.config.php | 1 + test/_files/Baz/src/Baz/Controller/IndexController.php | 3 +++ test/_files/Baz/view/baz/index/child1.phtml | 1 + test/_files/Baz/view/baz/index/child3.phtml | 1 + 6 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 test/_files/Baz/view/baz/index/child3.phtml diff --git a/src/PHPUnit/Controller/AbstractControllerTestCase.php b/src/PHPUnit/Controller/AbstractControllerTestCase.php index a55d8e7b..74b0563b 100644 --- a/src/PHPUnit/Controller/AbstractControllerTestCase.php +++ b/src/PHPUnit/Controller/AbstractControllerTestCase.php @@ -817,14 +817,13 @@ public function assertNotTemplateName($templateName) */ protected function searchTemplates($viewModel, $templateName) { - $found = false; if ($viewModel->getTemplate($templateName) === $templateName) { return true; } + foreach ($viewModel->getChildren() as $child) { - $found = $this->searchTemplates($child, $templateName); - if ($found) { - return $found; + if ($this->searchTemplates($child, $templateName)) { + return true; } } diff --git a/test/PHPUnit/Controller/TemplateNameTest.php b/test/PHPUnit/Controller/TemplateNameTest.php index 16d4f835..f82e24a5 100644 --- a/test/PHPUnit/Controller/TemplateNameTest.php +++ b/test/PHPUnit/Controller/TemplateNameTest.php @@ -19,7 +19,7 @@ public function setUp(): void /** * Test case for a controller returning a view with 2 children * View hierarchy: - * layout/layout -> baz/index/childview -> child1 + * layout/layout -> baz/index/childview -> child1 -> child3 * -> child2 */ public function testAssertTemplateWithMultipleChildren(): void @@ -30,11 +30,13 @@ public function testAssertTemplateWithMultipleChildren(): void $this->assertQueryContentContains('p', 'Parent'); $this->assertQueryContentContains('p', 'Child 1'); $this->assertQueryContentContains('p', 'Child 2'); + $this->assertQueryContentContains('p', 'Child 3'); $this->assertTemplateName('layout/layout'); $this->assertTemplateName('baz/index/childview'); $this->assertTemplateName('child1'); $this->assertTemplateName('child2'); + $this->assertTemplateName('child3'); $this->assertNotTemplateName('foo'); } } diff --git a/test/_files/Baz/config/module.config.php b/test/_files/Baz/config/module.config.php index 5eb90628..f1f1889d 100644 --- a/test/_files/Baz/config/module.config.php +++ b/test/_files/Baz/config/module.config.php @@ -131,6 +131,7 @@ 'error' => __DIR__ . '/../view/baz/error/error.phtml', 'child1' => __DIR__ . '/../view/baz/index/child1.phtml', 'child2' => __DIR__ . '/../view/baz/index/child2.phtml', + 'child3' => __DIR__ . '/../view/baz/index/child3.phtml', ], 'template_path_stack' => [ __DIR__ . '/../view', diff --git a/test/_files/Baz/src/Baz/Controller/IndexController.php b/test/_files/Baz/src/Baz/Controller/IndexController.php index 88118caa..9063d251 100644 --- a/test/_files/Baz/src/Baz/Controller/IndexController.php +++ b/test/_files/Baz/src/Baz/Controller/IndexController.php @@ -69,8 +69,11 @@ public function childViewAction(): ViewModel $child1->setTemplate('child1'); $child2 = new ViewModel(); $child2->setTemplate('child2'); + $child3 = new ViewModel(); + $child3->setTemplate('child3'); $view = new ViewModel(); $view->addChild($child1, 'child1'); + $child1->addChild($child3, 'child3'); $view->addChild($child2, 'child2'); return $view; } diff --git a/test/_files/Baz/view/baz/index/child1.phtml b/test/_files/Baz/view/baz/index/child1.phtml index 7c7e3ee9..272f39d4 100644 --- a/test/_files/Baz/view/baz/index/child1.phtml +++ b/test/_files/Baz/view/baz/index/child1.phtml @@ -1 +1,2 @@

Child 1

+child3; ?> diff --git a/test/_files/Baz/view/baz/index/child3.phtml b/test/_files/Baz/view/baz/index/child3.phtml new file mode 100644 index 00000000..8aadab86 --- /dev/null +++ b/test/_files/Baz/view/baz/index/child3.phtml @@ -0,0 +1 @@ +

Child 3

From 2ff043c98b47bddcb74c28f85a97112e6f64c6fc Mon Sep 17 00:00:00 2001 From: "Eric Richer eric.richer@vistoconsulting.com" Date: Fri, 13 Sep 2024 12:08:30 -0400 Subject: [PATCH 3/8] Moved test case for nested views into AbstractControllerTestCaseTest.php and deleted TemplateNameTest.php Signed-off-by: Eric Richer eric.richer@vistoconsulting.com --- .../AbstractControllerTestCaseTest.php | 24 +++++++++++ test/PHPUnit/Controller/TemplateNameTest.php | 42 ------------------- 2 files changed, 24 insertions(+), 42 deletions(-) delete mode 100644 test/PHPUnit/Controller/TemplateNameTest.php diff --git a/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php b/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php index 5e36cb63..df6db093 100644 --- a/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php +++ b/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php @@ -538,6 +538,30 @@ public function testAssertNotTemplateName(): void $this->assertNotTemplateName('template/does/not/exist'); } + /** + * Test case for a controller returning a view with deeply nested children + * View hierarchy: + * layout/layout -> baz/index/childview -> child1 -> child3 + * -> child2 + */ + public function testSearchTemplatesVerifiesDeeplyNestedTemplateName(): void + { + $this->dispatch('/childview'); + + // Check that the rendered content + $this->assertQueryContentContains('p', 'Parent'); + $this->assertQueryContentContains('p', 'Child 1'); + $this->assertQueryContentContains('p', 'Child 2'); + $this->assertQueryContentContains('p', 'Child 3'); + + $this->assertTemplateName('layout/layout'); + $this->assertTemplateName('baz/index/childview'); + $this->assertTemplateName('child1'); + $this->assertTemplateName('child2'); + $this->assertTemplateName('child3'); + $this->assertNotTemplateName('foo'); + } + public function testCustomResponseObject(): void { $this->dispatch('/custom-response'); diff --git a/test/PHPUnit/Controller/TemplateNameTest.php b/test/PHPUnit/Controller/TemplateNameTest.php deleted file mode 100644 index f82e24a5..00000000 --- a/test/PHPUnit/Controller/TemplateNameTest.php +++ /dev/null @@ -1,42 +0,0 @@ -setApplicationConfig( - include __DIR__ . '/../../_files/application.config.php' - ); - parent::setUp(); - } - - /** - * Test case for a controller returning a view with 2 children - * View hierarchy: - * layout/layout -> baz/index/childview -> child1 -> child3 - * -> child2 - */ - public function testAssertTemplateWithMultipleChildren(): void - { - $this->dispatch('/childview'); - - // Check that the rendered content - $this->assertQueryContentContains('p', 'Parent'); - $this->assertQueryContentContains('p', 'Child 1'); - $this->assertQueryContentContains('p', 'Child 2'); - $this->assertQueryContentContains('p', 'Child 3'); - - $this->assertTemplateName('layout/layout'); - $this->assertTemplateName('baz/index/childview'); - $this->assertTemplateName('child1'); - $this->assertTemplateName('child2'); - $this->assertTemplateName('child3'); - $this->assertNotTemplateName('foo'); - } -} From a7f952f452de5441f56c06d6fa8adbde4b73c0ca Mon Sep 17 00:00:00 2001 From: "Eric Richer eric.richer@vistoconsulting.com" Date: Mon, 16 Sep 2024 11:35:52 -0400 Subject: [PATCH 4/8] Added more tests to check that 'assertTemplateName' fails as intended when the template is not found and the 'assertNotTemplateName' fails when the template is found Signed-off-by: Eric Richer eric.richer@vistoconsulting.com --- .../AbstractControllerTestCaseTest.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php b/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php index df6db093..045466a5 100644 --- a/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php +++ b/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php @@ -15,6 +15,7 @@ use LaminasTest\Test\ExpectedExceptionTrait; use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStreamWrapper; +use PHPUnit\Exception; use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\ExpectationFailedException; use RuntimeException; @@ -560,6 +561,28 @@ public function testSearchTemplatesVerifiesDeeplyNestedTemplateName(): void $this->assertTemplateName('child2'); $this->assertTemplateName('child3'); $this->assertNotTemplateName('foo'); + + // Check that the test fails when template is NOT found where it was supposed to found + try { + $this->assertTemplateName('foo'); + $receivedException = false; + } catch (Exception $exception) { + $receivedException = true; + } + if (! $receivedException) { + $this->fail('Expected Exception not thrown'); + } + + // Check when template is found where it was NOT supposed to found + try { + $this->assertNotTemplateName('child1'); + $receivedException = false; + } catch (Exception $exception) { + $receivedException = true; + } + if (! $receivedException) { + $this->fail('Expected Exception not thrown'); + } } public function testCustomResponseObject(): void From 3a8099ae1fad5beaf6aaa9dea9db898d140c26d1 Mon Sep 17 00:00:00 2001 From: "Eric Richer eric.richer@vistoconsulting.com" Date: Mon, 16 Sep 2024 13:16:13 -0400 Subject: [PATCH 5/8] Moved tests to check that 'assertTemplateName' fails as intended when the template is not found and the 'assertNotTemplateName' fails when the template is found. to separate test cases. Signed-off-by: Eric Richer eric.richer@vistoconsulting.com --- .../AbstractControllerTestCaseTest.php | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php b/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php index 045466a5..2495b665 100644 --- a/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php +++ b/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php @@ -561,28 +561,36 @@ public function testSearchTemplatesVerifiesDeeplyNestedTemplateName(): void $this->assertTemplateName('child2'); $this->assertTemplateName('child3'); $this->assertNotTemplateName('foo'); + } + + /** + * Check that the assertion fails when template is NOT found where it was supposed to found + */ + public function testAssertTemplateNameFailsWhenNotFound(): void + { + $this->dispatch('/childview'); - // Check that the test fails when template is NOT found where it was supposed to found try { $this->assertTemplateName('foo'); - $receivedException = false; - } catch (Exception $exception) { - $receivedException = true; - } - if (! $receivedException) { - $this->fail('Expected Exception not thrown'); + } catch (ExpectationFailedException $exception) { + return; } + $this->fail('Expected Exception not thrown'); + } + + /** + * Check that the assertion fails when template is found where it was NOT supposed to found + */ + public function testAssertNotTemplateNameFailsWhenFound(): void + { + $this->dispatch('/childview'); - // Check when template is found where it was NOT supposed to found try { $this->assertNotTemplateName('child1'); - $receivedException = false; - } catch (Exception $exception) { - $receivedException = true; - } - if (! $receivedException) { - $this->fail('Expected Exception not thrown'); + } catch (ExpectationFailedException $exception) { + return; } + $this->fail('Expected Exception not thrown'); } public function testCustomResponseObject(): void From 5f9bacdf3ba17d6c3f94eae31b4d97b52267cafb Mon Sep 17 00:00:00 2001 From: "Eric Richer eric.richer@vistoconsulting.com" Date: Mon, 16 Sep 2024 16:27:04 -0400 Subject: [PATCH 6/8] Remove extra unused use statement Signed-off-by: Eric Richer eric.richer@vistoconsulting.com --- test/PHPUnit/Controller/AbstractControllerTestCaseTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php b/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php index 2495b665..a5a98ad4 100644 --- a/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php +++ b/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php @@ -15,7 +15,6 @@ use LaminasTest\Test\ExpectedExceptionTrait; use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStreamWrapper; -use PHPUnit\Exception; use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\ExpectationFailedException; use RuntimeException; From 450ce728df0ea4bbcceed927b4d6a1de7ea4930f Mon Sep 17 00:00:00 2001 From: "Eric Richer eric.richer@vistoconsulting.com" Date: Mon, 16 Sep 2024 16:47:14 -0400 Subject: [PATCH 7/8] Use more explicit and informative assertion failure messages for 'assertTemplateName()' and 'assertNotTemplateName()' Signed-off-by: Eric Richer eric.richer@vistoconsulting.com --- src/PHPUnit/Controller/AbstractControllerTestCase.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/PHPUnit/Controller/AbstractControllerTestCase.php b/src/PHPUnit/Controller/AbstractControllerTestCase.php index 74b0563b..76455766 100644 --- a/src/PHPUnit/Controller/AbstractControllerTestCase.php +++ b/src/PHPUnit/Controller/AbstractControllerTestCase.php @@ -792,7 +792,10 @@ public function assertTemplateName($templateName) } $viewModel = $application->getMvcEvent()->getViewModel(); - $this->assertTrue($this->searchTemplates($viewModel, $templateName)); + $this->assertTrue( + $this->searchTemplates($viewModel, $templateName), + sprintf('Failed asserting that view model tree contains template "%s"', $templateName) + ); } /** @@ -805,7 +808,10 @@ public function assertTemplateName($templateName) public function assertNotTemplateName($templateName) { $viewModel = $this->getApplication()->getMvcEvent()->getViewModel(); - $this->assertFalse($this->searchTemplates($viewModel, $templateName)); + $this->assertFalse( + $this->searchTemplates($viewModel, $templateName), + sprintf('Failed asserting that view model tree does not contain template "%s"', $templateName) + ); } /** From 907d7639219bd7f13f4a953dd14db8b7f5c4633f Mon Sep 17 00:00:00 2001 From: "Eric Richer eric.richer@vistoconsulting.com" Date: Mon, 16 Sep 2024 17:13:53 -0400 Subject: [PATCH 8/8] Added assertion for exception message in test case 'testAssertTemplateNameFailsWhenNotFound()' and 'testAssertNotTemplateNameFailsWhenFound()' Signed-off-by: Eric Richer eric.richer@vistoconsulting.com --- .../PHPUnit/Controller/AbstractControllerTestCaseTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php b/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php index a5a98ad4..29e124c8 100644 --- a/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php +++ b/test/PHPUnit/Controller/AbstractControllerTestCaseTest.php @@ -572,6 +572,10 @@ public function testAssertTemplateNameFailsWhenNotFound(): void try { $this->assertTemplateName('foo'); } catch (ExpectationFailedException $exception) { + $this->assertStringContainsString( + 'Failed asserting that view model tree contains template "foo"', + $exception->getMessage() + ); return; } $this->fail('Expected Exception not thrown'); @@ -587,6 +591,10 @@ public function testAssertNotTemplateNameFailsWhenFound(): void try { $this->assertNotTemplateName('child1'); } catch (ExpectationFailedException $exception) { + $this->assertStringContainsString( + 'Failed asserting that view model tree does not contain template "child1"', + $exception->getMessage() + ); return; } $this->fail('Expected Exception not thrown');