Skip to content

Commit

Permalink
VAGOV-TEAM-97904: Adds Form Builder Page Template (#20052)
Browse files Browse the repository at this point in the history
* 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().
  • Loading branch information
ryguyk authored Dec 10, 2024
1 parent 8a3434f commit ed635cc
Show file tree
Hide file tree
Showing 4 changed files with 235 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -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
*/
#}
<div class="va-gov-form-builder-page-container">
<header class="content-header clearfix">
<div class="layout-container">
{{ page.header }}

<div class="va-gov-form-builder-navbar">
<!-- This is a placeholder for our navigation bar -->
</div>
</div>
</header>

<div class="layout-container">
{{ page.pre_content }}

<main class="page-content clearfix" role="main">
<div class="visually-hidden"><a id="main-content" tabindex="-1"></a></div>
{{ page.highlighted }}
{% if page.help %}
<div class="help">
{{ page.help }}
</div>
{% endif %}
{{ page.content }}
</main>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace tests\phpunit\va_gov_form_builder\functional\templates;

use Tests\Support\Classes\VaGovExistingSiteBase;

/**
* Functional test of page--va-gov-form-builder.html Twig template.
*
* This test suite takes the approach of testing a single route
* that should result in rendering a page that utilizes the
* page template under test. In this way, we can test the expected
* behavior of the template file in a consistent manner, assuming
* the route properly utilizes the theme (which is tested elswhere).
*
* The route that makes the most sense here
* is the `entry` route, as that should always be present, regardless
* of potential future changes to Form Builder pages. The entry route
* will redirect to the first content page.
*
* @group functional
* @group all
*/
class FormBuilderPageTemplateTest extends VaGovExistingSiteBase {

/**
* {@inheritdoc}
*/
private static $modules = ['va_gov_form_builder'];

/**
* Setup the environment for each test.
*/
public function setUp(): void {
parent::setUp();

$this->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);
}

}
102 changes: 102 additions & 0 deletions tests/phpunit/va_gov_form_builder/unit/ModuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

namespace tests\phpunit\va_gov_form_builder\unit;

use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Extension\ModuleExtensionList;
use Drupal\Core\Routing\RouteMatchInterface;
use DrupalFinder\DrupalFinder;
use Tests\Support\Classes\VaGovUnitTestBase;

/**
* Unit tests for va_gov_form_builder.module.
*
* @group unit
* @group all
*/
class ModuleTest extends VaGovUnitTestBase {

/**
* The path to the module being tested.
*
* @var string
*/
private $modulePath = 'modules/custom/va_gov_form_builder';

/**
* A mock service container.
*
* @var \Drupal\Core\DependencyInjection\ContainerBuilder
*/
private $container;

/**
* Setup the environment for each test.
*/
protected function setUp(): void {
parent::setUp();

// Find Drupal root.
$drupalFinder = new DrupalFinder();
$drupalFinder->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);
}

}

0 comments on commit ed635cc

Please sign in to comment.