From ed635cc9bc23c8cd2eb1ec5c4dbb3af45eb4e2a9 Mon Sep 17 00:00:00 2001 From: Ryan Koch <6863534+ryguyk@users.noreply.github.com> Date: Tue, 10 Dec 2024 17:31:39 -0600 Subject: [PATCH] VAGOV-TEAM-97904: Adds Form Builder Page Template (#20052) * VAGOV-TEAM-97904: - Adds Twig template for Form Builder pages. - Applies template to all Form Builder routes. * Adds unit test for va_gov_form_builder_theme_suggestions_page(). --- .../page--va-gov-form-builder.html.twig | 40 +++++++ .../va_gov_form_builder.module | 27 +++++ .../templates/FormBuilderPageTemplateTest.php | 66 ++++++++++++ .../va_gov_form_builder/unit/ModuleTest.php | 102 ++++++++++++++++++ 4 files changed, 235 insertions(+) create mode 100644 docroot/modules/custom/va_gov_form_builder/templates/page--va-gov-form-builder.html.twig create mode 100644 tests/phpunit/va_gov_form_builder/functional/templates/FormBuilderPageTemplateTest.php create mode 100644 tests/phpunit/va_gov_form_builder/unit/ModuleTest.php diff --git a/docroot/modules/custom/va_gov_form_builder/templates/page--va-gov-form-builder.html.twig b/docroot/modules/custom/va_gov_form_builder/templates/page--va-gov-form-builder.html.twig new file mode 100644 index 0000000000..86efcd7ae3 --- /dev/null +++ b/docroot/modules/custom/va_gov_form_builder/templates/page--va-gov-form-builder.html.twig @@ -0,0 +1,40 @@ +{# +/** + * @file + * VA.gov Form Builder's implementation of a single page. + * + * Nearly identical to VAgovClaro's implementation, except: + * - An outermost page container has been added. + * - The header includes additional content (navbar, eventually) + * - Breadcrumbs have been removed + * + * For more information: + * @see docroot/themes/custom/vagovclaro/templates/page/page.html.twig + */ +#} +
diff --git a/docroot/modules/custom/va_gov_form_builder/va_gov_form_builder.module b/docroot/modules/custom/va_gov_form_builder/va_gov_form_builder.module index 015231d072..e3f9b98dca 100644 --- a/docroot/modules/custom/va_gov_form_builder/va_gov_form_builder.module +++ b/docroot/modules/custom/va_gov_form_builder/va_gov_form_builder.module @@ -17,3 +17,30 @@ function va_gov_form_builder_entity_bundle_field_info_alter(&$fields, EntityType return $fields; } + +/** + * Implements hook_theme(). + */ +function va_gov_form_builder_theme() { + return [ + 'va_gov_form_builder_page' => [ + 'template' => 'page--va-gov-form-builder', + 'path' => \Drupal::service('extension.list.module')->getPath('va_gov_form_builder') . '/templates', + ], + ]; +} + +/** + * Implements hook_theme_suggestions_HOOK(). + */ +function va_gov_form_builder_theme_suggestions_page(array &$variables) { + $route_name = \Drupal::routeMatch()->getRouteName(); + $suggestions = []; + + // Apply custom page template for all Form Builder routes. + if (strpos($route_name, 'va_gov_form_builder.') === 0) { + $suggestions[] = 'va_gov_form_builder_page'; + } + + return $suggestions; +} diff --git a/tests/phpunit/va_gov_form_builder/functional/templates/FormBuilderPageTemplateTest.php b/tests/phpunit/va_gov_form_builder/functional/templates/FormBuilderPageTemplateTest.php new file mode 100644 index 0000000000..ab468cc5de --- /dev/null +++ b/tests/phpunit/va_gov_form_builder/functional/templates/FormBuilderPageTemplateTest.php @@ -0,0 +1,66 @@ +drupalLogin($this->createUser(['edit any digital_form content'])); + + // Form Builder entry. + $this->drupalGet('/form-builder'); + } + + /** + * Test that expected elements are present. + */ + public function testExpectedElementsExist() { + $this->assertSession()->statusCodeEquals(200); + + $containerElement = $this->cssSelect('.va-gov-form-builder-page-container'); + $this->assertCount(1, $containerElement); + + $navbarElement = $this->cssSelect('.va-gov-form-builder-navbar'); + $this->assertCount(1, $navbarElement); + } + + /** + * Test that unexpected elements are not present. + */ + public function testUnexpectedElementsDoNotExist() { + $this->assertSession()->statusCodeEquals(200); + + $breadcrumbsElement = $this->cssSelect('#block-vagovclaro-breadcrumbs'); + $this->assertCount(0, $breadcrumbsElement); + } + +} diff --git a/tests/phpunit/va_gov_form_builder/unit/ModuleTest.php b/tests/phpunit/va_gov_form_builder/unit/ModuleTest.php new file mode 100644 index 0000000000..6e41d85f00 --- /dev/null +++ b/tests/phpunit/va_gov_form_builder/unit/ModuleTest.php @@ -0,0 +1,102 @@ +locateRoot(__DIR__); + $drupalRoot = $drupalFinder->getDrupalRoot(); + + // Require the module file so we can test it. + require_once $drupalRoot . '/' . $this->modulePath . '/va_gov_form_builder.module'; + + // Create the mock service container. + $this->container = new ContainerBuilder(); + + // Set the mocked container as the global Drupal container. + \Drupal::setContainer($this->container); + } + + /** + * Tests va_gov_form_builder_theme(). + * + * @covers ::va_gov_form_builder_theme + */ + public function testVaGovFormBuilderHookTheme() { + // Mock the extension.list.module service and add to the container. + $extensionListMock = $this->createMock(ModuleExtensionList::class); + $extensionListMock->expects($this->once()) + ->method('getPath') + ->with('va_gov_form_builder') + ->willReturn($this->modulePath); + $this->container->set('extension.list.module', $extensionListMock); + + // Call the function to test. + $result = va_gov_form_builder_theme(); + + // Assert the expected theme definition exists. + $this->assertArrayHasKey('va_gov_form_builder_page', $result); + $this->assertEquals('page--va-gov-form-builder', $result['va_gov_form_builder_page']['template']); + $this->assertEquals($this->modulePath . '/templates', $result['va_gov_form_builder_page']['path']); + } + + /** + * Tests va_gov_form_builder_theme_suggestions_page(). + * + * @covers va_gov_form_builder_theme_suggestions_page + */ + public function testVaGovFormBuilderThemeSuggestionsPage() { + // Ensure *any* route starting with `va_gov_form_builder.` returns the + // expected theme suggestions. + $exampleRoute = 'va_gov_form_builder.example_route'; + + // Mock the current_route_match service and add to the container. + $currentRouteMatchMock = $this->createMock(RouteMatchInterface::class); + $currentRouteMatchMock->expects($this->once()) + ->method('getRouteName') + ->willReturn($exampleRoute); + $this->container->set('current_route_match', $currentRouteMatchMock); + + // Call the function to test. + $variables = []; + $suggestions = va_gov_form_builder_theme_suggestions_page($variables); + + // Assert the expected theme suggestion is returned. + $this->assertContains('va_gov_form_builder_page', $suggestions); + } + +}