Commit 4275843c authored by Kingdutch's avatar Kingdutch

2839553 by Kingdutch: Create PHPUnit based configuration test

The added test tests the administration screen of the Real-Time
SEO module. It ensures that the module can be succesfully enabled
for simple nodes.

To achieve a passing test some of the classes have been refactored

slightly.
parent c2c8e2b3
......@@ -287,6 +287,8 @@
/**
* retuns a string that is used as a CSS class, based on the numeric score
*
* TODO: This can probably be replaced by the seoAssessorPresentor which includes a presenter configuration that does this.
*
* @param score
* @returns rating
*/
......
......@@ -23,9 +23,10 @@ class FieldManager {
public function getFieldDefinitions() {
return [
'field_yoast_seo' => [
'type' => 'yoast_seo',
'field_name' => 'field_yoast_seo',
'field_label' => 'Real-time SEO',
'storage_type' => 'yoast_seo',
'field_type' => 'yoast_seo',
'translatable' => TRUE,
],
];
......@@ -155,6 +156,23 @@ class FieldManager {
}
}
/**
* Check whether this module is enabled for a certain entity/bundle.
*
* @param string $entity_type_id
* The entity to check.
* @param string $bundle
* The bundle of the entity to check.
*
* @return bool
* Whether SEO analysis is enabled.
*/
public function isEnabledFor($entity_type_id, $bundle) {
// Simply check if one of our fields is attached.
$field_name = array_keys($this->getFieldDefinitions())[0];
return $this->isAttached($entity_type_id, $bundle, $field_name);
}
/**
* Check if a field has been already attached to a bundle.
*
......
......@@ -70,7 +70,7 @@ class ConfigForm extends FormBase {
'#title' => $this->t('@label', ['@label' => $entity_label]),
'#options' => $supported_bundles[$entity_type],
'#required' => FALSE,
'#default_value' => array_keys($enabled_bundles[$entity_type]),
'#default_value' => !empty($enabled_bundles[$entity_type]) ? array_keys($enabled_bundles[$entity_type]) : [],
];
}
......@@ -91,55 +91,30 @@ class ConfigForm extends FormBase {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// Get the available entity types Yoast SEO supports.
$entity_types = $this->seoManager->getSupportedEntityTypes();
// Get the available entity/bundles that the module supports.
$entity_bundles = $this->seoManager->getEntityBundles();
// Retrieve the form values.
$values = $form_state->getValues();
// Fields to attach.
$to_attach = [];
// Fields to detach.
$to_detach = [];
// Foreach entity types Yoast SEO can be enable for, check the bundle the
// administrator wants to enable/disable Yoast SEO for.
// TODO: Try and simplify the below logic.
foreach ($entity_types as $entity_type_id => $entity_type_label) {
// Get the available bundles Yoast SEO supports.
$bundles = $this->seoManager->getEntityBundles([$entity_type_id])[$entity_type_id];
// Get the bundles Yoast SEO has been enabled for.
$enabled_bundles = array_keys($this->seoManager->getEnabledBundles([$entity_type_id])[$entity_type_id]);
// Foreach available bundles.
// Iterate over all supported entities.
foreach ($entity_bundles as $entity_type_id => $bundles) {
// Then over all bundles for that entity.
foreach ($bundles as $bundle_id => $bundle_label) {
// Yoast SEO is required to be enabled for.
if (isset($values[$entity_type_id][$bundle_id])
&& $values[$entity_type_id][$bundle_id] !== 0
&& !in_array($bundle_id, $enabled_bundles)
) {
$to_attach[$entity_type_id][] = $bundle_id;
}
// Yoast SEO is required to be disabled for.
elseif (isset($values[$entity_type_id][$bundle_id])
&& $values[$entity_type_id][$bundle_id] === 0
&& in_array($bundle_id, $enabled_bundles)
) {
$to_detach[$entity_type_id][] = $bundle_id;
// If this value was not in our form we skip it.
if (!isset($values[$entity_type_id][$bundle_id])) {
continue;
}
}
}
// Attach fields to content types.
foreach ($to_attach as $entity_type_id => $bundles) {
foreach ($bundles as $bundle_id) {
$this->fieldManager->attachSeoFields($entity_type_id, $bundle_id);
}
}
// Detach fields from content types.
foreach ($to_detach as $entity_type_id => $bundles) {
foreach ($bundles as $bundle_id) {
$this->fieldManager->detachSeoFields($entity_type_id, $bundle_id);
// If it's checked now but wasn't enabled, enable it.
if ($values[$entity_type_id][$bundle_id] !== 0
&& !$this->fieldManager->isEnabledFor($entity_type_id, $bundle_id)) {
$this->fieldManager->attachSeoFields($entity_type_id, $bundle_id);
}
// If it's not checked but it was enabled, disable it.
elseif ($values[$entity_type_id][$bundle_id] === 0
&& $this->fieldManager->isEnabledFor($entity_type_id, $bundle_id)) {
$this->fieldManager->detachSeoFields($entity_type_id, $bundle_id);
}
}
}
......
......@@ -107,12 +107,10 @@ class SeoManager {
*/
public function getEnabledBundles(array $entity_types = NULL) {
$entities = $this->getEntityBundles($entity_types);
// TODO: Clean up the next line.
$field_name = array_keys($this->fieldManager->getFieldDefinitions())[0];
foreach ($entities as $entity_type => &$bundles) {
foreach ($bundles as $bundle_id => $bundle_label) {
if (!$this->fieldManager->isAttached($entity_type, $bundle_id, $field_name)) {
if (!$this->fieldManager->isEnabledFor($entity_type, $bundle_id)) {
unset($bundles[$bundle_id]);
}
}
......
<?php
namespace Drupal\yoast_seo\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Ensures that the Yoast Seo works correctly.
*
* @group YoastSeo
*/
class YoastSeoTest extends WebTestBase {
/**
* Profile to use.
*/
protected $profile = 'testing';
/**
* Admin user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $adminUser;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = [
'field_ui',
'metatag',
'yoast_seo',
'entity_test',
'node',
];
/**
* Permissions to grant admin user.
*
* @var array
*/
protected $permissions = [
'access administration pages',
'administer content types',
'administer nodes',
'administer meta tags',
'administer yoast seo',
'view test entity',
'access content',
];
/**
* Sets the test up.
*/
protected function setUp() {
parent::setUp();
$this->adminUser = $this->drupalCreateUser($this->permissions);
$this->entityManager = \Drupal::entityManager();
}
/**
* Enable Yoast SEO for a given bundle.
*/
protected function enableYoastSeo($entity_type, $bundle) {
// Configure yoast seo for the given bundle.
$this->drupalGet('admin/config/yoast_seo');
$edit = array($entity_type . '[' . $bundle . ']' => $bundle);
json_decode($this->drupalPostForm(NULL, $edit, t('Save')));
$this->assertFieldChecked('edit-node-page');
}
/**
* Disable Yoast SEO for a given bundle.
*/
protected function disableYoastSeo($entity_type, $bundle) {
// Configure yoast seo for the given bundle.
$this->drupalGet('admin/config/yoast_seo');
$edit = array($entity_type . '[' . $bundle . ']' => FALSE);
json_decode($this->drupalPostForm(NULL, $edit, t('Save')));
$this->assertNoFieldChecked('edit-node-page');
}
/**
* Only available when it has been previously enabled on the content type.
*
* Given I am logged in as admin
* When I am adding a content on a content type which doesn't have a Meta
* Tag field
* Then Then I should not see the Yoast SEO section active
* When I am adding a content on a content type which have a Meta Tag
* field.
*/
public function testYoastSeoEnabledDisabled() {
// Given I am logged in as admin.
$this->drupalLogin($this->adminUser);
// Create a page node type.
$this->entityManager->getStorage('node_type')->create(array(
'type' => 'page',
'name' => 'page',
))->save();
// When I am adding an Entity Test content.
$this->drupalGet('node/add/page');
// Then I should not see the Yoast SEO section active.
$this->assertNoText('Yoast SEO for drupal');
// When I enable Yoast SEO for the page bundle.
$this->enableYoastSeo('node', 'page');
// And I am adding an Entity Test content.
$this->drupalGet('node/add/page');
// Then I should see the Yoast SEO section active.
$this->assertText('Real-time SEO for drupal');
// When I disable Yoast SEO for the page bundle.
$this->disableYoastSeo('node', 'page');
// And I am adding an Entity Test content.
$this->drupalGet('node/add/page');
// Then I should not see the Yoast SEO section active.
$this->assertNoText('Real-time SEO for drupal');
}
}
<?php
namespace Drupal\Tests\yoast_seo\Functional;
use Drupal\Tests\BrowserTestBase;
/**
* Tests for the Real-Time SEO configuration page.
*
* @group yoast_seo_ui
*/
class ConfigurationPageTest extends BrowserTestBase {
/**
* Modules to enable.
*
* @var array
*/
protected static $modules = [
'node',
// CKEditor module is required to avoid loading errors during node creation.
'ckeditor',
'yoast_seo',
];
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
// Create an article content type that we will use for testing.
$this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
$this->container->get('router.builder')->rebuild();
}
/**
* Tests that a user requires the 'administer yoast seo' permission.
*
* The permission is required to access the configuration page.
*/
public function testAdministerPermissionRequirement() {
$unauthorized = $this->drupalCreateUser();
$authorized = $this->drupalCreateUser(['administer yoast seo']);
// Test that a user without the permission is denied.
$this->drupalLogin($unauthorized);
$this->drupalGet('/admin/config/yoast_seo');
$this->assertSession()->statusCodeEquals(403);
// Test that a user with the permission can see the page.
$this->drupalLogin($authorized);
$this->drupalGet('/admin/config/yoast_seo');
$this->assertSession()->statusCodeEquals(200);
}
/**
* Tests that analysis is not enabled for any entities on first install.
*/
public function testInstallAnalysisState() {
$account = $this->drupalCreateUser(['administer yoast seo']);
$this->drupalLogin($account);
$this->drupalGet('/admin/config/yoast_seo');
// Check that the checkbox indicates disabled.
$checked = $this->assertSession()->fieldExists('Article')->getAttribute('checked');
$this->assertFalse($checked, "Expected Real-Time SEO module to be disabled for 'Article'");
}
/**
* Tests that analysis can be enabled for the node article bundle.
*/
public function testEnableForNodeBundle() {
$account = $this->drupalCreateUser([
'administer yoast seo',
'create article content',
// TODO: The administer url aliases shouldn't be necessary anymore.
'administer url aliases',
]);
$this->drupalLogin($account);
$this->drupalGet('/admin/config/yoast_seo');
// Select the article bundle to enable.
$this->assertSession()->fieldExists('Article')->check();
$this->getSession()->getPage()->pressButton('Save');
// Check that the enabled status is reflected in the interface.
$checked = $this->assertSession()->fieldExists('Article')->getAttribute('checked');
$this->assertTrue($checked, "Expected Real-Time SEO module to be enabled for 'Article'");
// Check that the SEO analyzer shows up on the article add page.
$this->drupalGet('node/add/article');
$this->assertSession()->pageTextContains('Real-time SEO for drupal');
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment