updated core
This commit is contained in:
@@ -16,7 +16,7 @@ class DeleteForm extends ConfirmFormBase {
|
||||
/**
|
||||
* The alias storage service.
|
||||
*
|
||||
* @var AliasStorageInterface
|
||||
* @var \Drupal\Core\Path\AliasStorageInterface
|
||||
*/
|
||||
protected $aliasStorage;
|
||||
|
||||
|
||||
@@ -191,7 +191,6 @@ abstract class PathFormBase extends FormBase {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!$this->pathValidator->isValid(trim($source, '/'))) {
|
||||
$form_state->setErrorByName('source', t("The path '@link_path' is either invalid or you do not have access to it.", ['@link_path' => $source]));
|
||||
}
|
||||
|
||||
@@ -5,12 +5,42 @@ namespace Drupal\path\Plugin\Field\FieldType;
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Field\FieldItemList;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\TypedData\ComputedItemListTrait;
|
||||
|
||||
/**
|
||||
* Represents a configurable entity path field.
|
||||
*/
|
||||
class PathFieldItemList extends FieldItemList {
|
||||
|
||||
use ComputedItemListTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function computeValue() {
|
||||
// Default the langcode to the current language if this is a new entity or
|
||||
// there is no alias for an existent entity.
|
||||
// @todo Set the langcode to not specified for untranslatable fields
|
||||
// in https://www.drupal.org/node/2689459.
|
||||
$value = ['langcode' => $this->getLangcode()];
|
||||
|
||||
$entity = $this->getEntity();
|
||||
if (!$entity->isNew()) {
|
||||
// @todo Support loading languge neutral aliases in
|
||||
// https://www.drupal.org/node/2511968.
|
||||
$alias = \Drupal::service('path.alias_storage')->load([
|
||||
'source' => '/' . $entity->toUrl()->getInternalPath(),
|
||||
'langcode' => $this->getLangcode(),
|
||||
]);
|
||||
|
||||
if ($alias) {
|
||||
$value = $alias;
|
||||
}
|
||||
}
|
||||
|
||||
$this->list[0] = $this->createItem(0, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -34,42 +64,4 @@ class PathFieldItemList extends FieldItemList {
|
||||
\Drupal::service('path.alias_storage')->delete($conditions);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getValue($include_computed = FALSE) {
|
||||
$this->ensureLoaded();
|
||||
return parent::getValue($include_computed);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isEmpty() {
|
||||
$this->ensureLoaded();
|
||||
return parent::isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIterator() {
|
||||
$this->ensureLoaded();
|
||||
return parent::getIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically create the first item for computed fields.
|
||||
*
|
||||
* This ensures that ::getValue() and ::isEmpty() calls will behave like a
|
||||
* non-computed field.
|
||||
*
|
||||
* @todo: Move this to the base class in https://www.drupal.org/node/2392845.
|
||||
*/
|
||||
protected function ensureLoaded() {
|
||||
if (!isset($this->list[0]) && $this->definition->isComputed()) {
|
||||
$this->list[0] = $this->createItem(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,20 +23,6 @@ use Drupal\Core\TypedData\DataDefinition;
|
||||
*/
|
||||
class PathItem extends FieldItemBase {
|
||||
|
||||
/**
|
||||
* Whether the alias has been loaded from the alias storage service yet.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isLoaded = FALSE;
|
||||
|
||||
/**
|
||||
* Whether the alias is currently being set.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isLoading = FALSE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -50,14 +36,6 @@ class PathItem extends FieldItemBase {
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __get($name) {
|
||||
$this->ensureLoaded();
|
||||
return parent::__get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -65,76 +43,20 @@ class PathItem extends FieldItemBase {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getValue() {
|
||||
$this->ensureLoaded();
|
||||
return parent::getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isEmpty() {
|
||||
$this->ensureLoaded();
|
||||
return parent::isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIterator() {
|
||||
$this->ensureLoaded();
|
||||
return parent::getIterator();
|
||||
return ($this->alias === NULL || $this->alias === '') && ($this->pid === NULL || $this->pid === '') && ($this->langcode === NULL || $this->langcode === '');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preSave() {
|
||||
$this->alias = trim($this->alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __set($name, $value) {
|
||||
// Also ensure that existing values are loaded when setting a value, this
|
||||
// ensures that it is possible to set a new value immediately after loading
|
||||
// an entity.
|
||||
$this->ensureLoaded();
|
||||
parent::__set($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($property_name, $value, $notify = TRUE) {
|
||||
// Also ensure that existing values are loaded when setting a value, this
|
||||
// ensures that it is possible to set a new value immediately after loading
|
||||
// an entity.
|
||||
$this->ensureLoaded();
|
||||
return parent::set($property_name, $value, $notify);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($property_name) {
|
||||
$this->ensureLoaded();
|
||||
return parent::get($property_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setValue($values, $notify = TRUE) {
|
||||
// Also ensure that existing values are loaded when setting a value, this
|
||||
// ensures that it is possible to set a new value immediately after loading
|
||||
// an entity.
|
||||
$this->ensureLoaded();
|
||||
return parent::setValue($values, $notify);
|
||||
if ($this->alias !== NULL) {
|
||||
$this->alias = trim($this->alias);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,42 +100,4 @@ class PathItem extends FieldItemBase {
|
||||
return 'alias';
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the alias properties are loaded if available.
|
||||
*
|
||||
* This ensures that the properties will always be loaded and act like
|
||||
* non-computed fields when calling ::__get() and getValue().
|
||||
*
|
||||
* @todo: Determine if this should be moved to the base class in
|
||||
* https://www.drupal.org/node/2392845.
|
||||
*/
|
||||
protected function ensureLoaded() {
|
||||
// Make sure to avoid a infinite loop if setValue() has be called from this
|
||||
// block which calls ensureLoaded().
|
||||
if (!$this->isLoaded && !$this->isLoading) {
|
||||
$entity = $this->getEntity();
|
||||
if (!$entity->isNew()) {
|
||||
// @todo Support loading languge neutral aliases in
|
||||
// https://www.drupal.org/node/2511968.
|
||||
$alias = \Drupal::service('path.alias_storage')->load([
|
||||
'source' => '/' . $entity->toUrl()->getInternalPath(),
|
||||
'langcode' => $this->getLangcode(),
|
||||
]);
|
||||
if ($alias) {
|
||||
$this->isLoading = TRUE;
|
||||
$this->setValue($alias);
|
||||
$this->isLoading = FALSE;
|
||||
}
|
||||
else {
|
||||
// If there is no existing alias, default the langcode to the current
|
||||
// language.
|
||||
// @todo Set the langcode to not specified for untranslatable fields
|
||||
// in https://www.drupal.org/node/2689459.
|
||||
$this->langcode = $this->getLangcode();
|
||||
}
|
||||
}
|
||||
$this->isLoaded = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\path\Tests;
|
||||
|
||||
/**
|
||||
* Tests the Path admin UI.
|
||||
*
|
||||
* @group path
|
||||
*/
|
||||
class PathAdminTest extends PathTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('path');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create test user and log in.
|
||||
$web_user = $this->drupalCreateUser(array('create page content', 'edit own page content', 'administer url aliases', 'create url aliases'));
|
||||
$this->drupalLogin($web_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the filtering aspect of the Path UI.
|
||||
*/
|
||||
public function testPathFiltering() {
|
||||
// Create test nodes.
|
||||
$node1 = $this->drupalCreateNode();
|
||||
$node2 = $this->drupalCreateNode();
|
||||
$node3 = $this->drupalCreateNode();
|
||||
|
||||
// Create aliases.
|
||||
$alias1 = '/' . $this->randomMachineName(8);
|
||||
$edit = array(
|
||||
'source' => '/node/' . $node1->id(),
|
||||
'alias' => $alias1,
|
||||
);
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
$alias2 = '/' . $this->randomMachineName(8);
|
||||
$edit = array(
|
||||
'source' => '/node/' . $node2->id(),
|
||||
'alias' => $alias2,
|
||||
);
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
$alias3 = '/' . $this->randomMachineName(4) . '/' . $this->randomMachineName(4);
|
||||
$edit = array(
|
||||
'source' => '/node/' . $node3->id(),
|
||||
'alias' => $alias3,
|
||||
);
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
// Filter by the first alias.
|
||||
$edit = array(
|
||||
'filter' => $alias1,
|
||||
);
|
||||
$this->drupalPostForm(NULL, $edit, t('Filter'));
|
||||
$this->assertLinkByHref($alias1);
|
||||
$this->assertNoLinkByHref($alias2);
|
||||
$this->assertNoLinkByHref($alias3);
|
||||
|
||||
// Filter by the second alias.
|
||||
$edit = array(
|
||||
'filter' => $alias2,
|
||||
);
|
||||
$this->drupalPostForm(NULL, $edit, t('Filter'));
|
||||
$this->assertNoLinkByHref($alias1);
|
||||
$this->assertLinkByHref($alias2);
|
||||
$this->assertNoLinkByHref($alias3);
|
||||
|
||||
// Filter by the third alias which has a slash.
|
||||
$edit = array(
|
||||
'filter' => $alias3,
|
||||
);
|
||||
$this->drupalPostForm(NULL, $edit, t('Filter'));
|
||||
$this->assertNoLinkByHref($alias1);
|
||||
$this->assertNoLinkByHref($alias2);
|
||||
$this->assertLinkByHref($alias3);
|
||||
|
||||
// Filter by a random string with a different length.
|
||||
$edit = array(
|
||||
'filter' => $this->randomMachineName(10),
|
||||
);
|
||||
$this->drupalPostForm(NULL, $edit, t('Filter'));
|
||||
$this->assertNoLinkByHref($alias1);
|
||||
$this->assertNoLinkByHref($alias2);
|
||||
|
||||
// Reset the filter.
|
||||
$edit = array();
|
||||
$this->drupalPostForm(NULL, $edit, t('Reset'));
|
||||
$this->assertLinkByHref($alias1);
|
||||
$this->assertLinkByHref($alias2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,349 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\path\Tests;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
/**
|
||||
* Add, edit, delete, and change alias and verify its consistency in the
|
||||
* database.
|
||||
*
|
||||
* @group path
|
||||
*/
|
||||
class PathAliasTest extends PathTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('path');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create test user and log in.
|
||||
$web_user = $this->drupalCreateUser(array('create page content', 'edit own page content', 'administer url aliases', 'create url aliases'));
|
||||
$this->drupalLogin($web_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the path cache.
|
||||
*/
|
||||
function testPathCache() {
|
||||
// Create test node.
|
||||
$node1 = $this->drupalCreateNode();
|
||||
|
||||
// Create alias.
|
||||
$edit = array();
|
||||
$edit['source'] = '/node/' . $node1->id();
|
||||
$edit['alias'] = '/' . $this->randomMachineName(8);
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
// Check the path alias whitelist cache.
|
||||
$whitelist = \Drupal::cache()->get('path_alias_whitelist');
|
||||
$this->assertTrue($whitelist->data['node']);
|
||||
$this->assertFalse($whitelist->data['admin']);
|
||||
|
||||
// Visit the system path for the node and confirm a cache entry is
|
||||
// created.
|
||||
\Drupal::cache('data')->deleteAll();
|
||||
// Make sure the path is not converted to the alias.
|
||||
$this->drupalGet(trim($edit['source'], '/'), array('alias' => TRUE));
|
||||
$this->assertTrue(\Drupal::cache('data')->get('preload-paths:' . $edit['source']), 'Cache entry was created.');
|
||||
|
||||
// Visit the alias for the node and confirm a cache entry is created.
|
||||
\Drupal::cache('data')->deleteAll();
|
||||
// @todo Remove this once https://www.drupal.org/node/2480077 lands.
|
||||
Cache::invalidateTags(['rendered']);
|
||||
$this->drupalGet(trim($edit['alias'], '/'));
|
||||
$this->assertTrue(\Drupal::cache('data')->get('preload-paths:' . $edit['source']), 'Cache entry was created.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests alias functionality through the admin interfaces.
|
||||
*/
|
||||
function testAdminAlias() {
|
||||
// Create test node.
|
||||
$node1 = $this->drupalCreateNode();
|
||||
|
||||
// Create alias.
|
||||
$edit = array();
|
||||
$edit['source'] = '/node/' . $node1->id();
|
||||
$edit['alias'] = '/' . $this->getRandomGenerator()->word(8);
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
// Confirm that the alias works.
|
||||
$this->drupalGet($edit['alias']);
|
||||
$this->assertText($node1->label(), 'Alias works.');
|
||||
$this->assertResponse(200);
|
||||
// Confirm that the alias works in a case-insensitive way.
|
||||
$this->assertTrue(ctype_lower(ltrim($edit['alias'], '/')));
|
||||
$this->drupalGet($edit['alias']);
|
||||
$this->assertText($node1->label(), 'Alias works lower case.');
|
||||
$this->assertResponse(200);
|
||||
$this->drupalGet(Unicode::strtoupper($edit['alias']));
|
||||
$this->assertText($node1->label(), 'Alias works upper case.');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Change alias to one containing "exotic" characters.
|
||||
$pid = $this->getPID($edit['alias']);
|
||||
|
||||
$previous = $edit['alias'];
|
||||
$edit['alias'] = '/alias' . // Lower-case letters.
|
||||
// "Special" ASCII characters.
|
||||
"- ._~!$'\"()*@[]?&+%#,;=:" .
|
||||
// Characters that look like a percent-escaped string.
|
||||
"%23%25%26%2B%2F%3F" .
|
||||
// Characters from various non-ASCII alphabets.
|
||||
"中國書۞";
|
||||
$connection = Database::getConnection();
|
||||
if ($connection->databaseType() != 'sqlite') {
|
||||
// When using LIKE for case-insensitivity, the SQLite driver is
|
||||
// currently unable to find the upper-case versions of non-ASCII
|
||||
// characters.
|
||||
// @todo fix this in https://www.drupal.org/node/2607432
|
||||
$edit['alias'] .= "ïвβéø";
|
||||
}
|
||||
$this->drupalPostForm('admin/config/search/path/edit/' . $pid, $edit, t('Save'));
|
||||
|
||||
// Confirm that the alias works.
|
||||
$this->drupalGet(Unicode::strtoupper($edit['alias']));
|
||||
$this->assertText($node1->label(), 'Changed alias works.');
|
||||
$this->assertResponse(200);
|
||||
|
||||
$this->container->get('path.alias_manager')->cacheClear();
|
||||
// Confirm that previous alias no longer works.
|
||||
$this->drupalGet($previous);
|
||||
$this->assertNoText($node1->label(), 'Previous alias no longer works.');
|
||||
$this->assertResponse(404);
|
||||
|
||||
// Create second test node.
|
||||
$node2 = $this->drupalCreateNode();
|
||||
|
||||
// Set alias to second test node.
|
||||
$edit['source'] = '/node/' . $node2->id();
|
||||
// leave $edit['alias'] the same
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
// Confirm no duplicate was created.
|
||||
$this->assertRaw(t('The alias %alias is already in use in this language.', array('%alias' => $edit['alias'])), 'Attempt to move alias was rejected.');
|
||||
|
||||
$edit_upper = $edit;
|
||||
$edit_upper['alias'] = Unicode::strtoupper($edit['alias']);
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit_upper, t('Save'));
|
||||
$this->assertRaw(t('The alias %alias could not be added because it is already in use in this language with different capitalization: %stored_alias.', [
|
||||
'%alias' => $edit_upper['alias'],
|
||||
'%stored_alias' => $edit['alias'],
|
||||
]), 'Attempt to move upper-case alias was rejected.');
|
||||
|
||||
// Delete alias.
|
||||
$this->drupalGet('admin/config/search/path/edit/' . $pid);
|
||||
$this->clickLink(t('Delete'));
|
||||
$this->assertRaw(t('Are you sure you want to delete path alias %name?', array('%name' => $edit['alias'])));
|
||||
$this->drupalPostForm(NULL, array(), t('Confirm'));
|
||||
|
||||
// Confirm that the alias no longer works.
|
||||
$this->drupalGet($edit['alias']);
|
||||
$this->assertNoText($node1->label(), 'Alias was successfully deleted.');
|
||||
$this->assertResponse(404);
|
||||
|
||||
// Create a really long alias.
|
||||
$edit = array();
|
||||
$edit['source'] = '/node/' . $node1->id();
|
||||
$alias = '/' . $this->randomMachineName(128);
|
||||
$edit['alias'] = $alias;
|
||||
// The alias is shortened to 50 characters counting the ellipsis.
|
||||
$truncated_alias = substr($alias, 0, 47);
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
$this->assertNoText($alias, 'The untruncated alias was not found.');
|
||||
// The 'truncated' alias will always be found.
|
||||
$this->assertText($truncated_alias, 'The truncated alias was found.');
|
||||
|
||||
// Create third test node.
|
||||
$node3 = $this->drupalCreateNode();
|
||||
|
||||
// Create absolute path alias.
|
||||
$edit = array();
|
||||
$edit['source'] = '/node/' . $node3->id();
|
||||
$node3_alias = '/' . $this->randomMachineName(8);
|
||||
$edit['alias'] = $node3_alias;
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
// Create fourth test node.
|
||||
$node4 = $this->drupalCreateNode();
|
||||
|
||||
// Create alias with trailing slash.
|
||||
$edit = array();
|
||||
$edit['source'] = '/node/' . $node4->id();
|
||||
$node4_alias = '/' . $this->randomMachineName(8);
|
||||
$edit['alias'] = $node4_alias . '/';
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
// Confirm that the alias with trailing slash is not found.
|
||||
$this->assertNoText($edit['alias'], 'The absolute alias was not found.');
|
||||
// The alias without trailing flash is found.
|
||||
$this->assertText(trim($edit['alias'], '/'), 'The alias without trailing slash was found.');
|
||||
|
||||
// Update an existing alias to point to a different source.
|
||||
$pid = $this->getPID($node4_alias);
|
||||
$edit = [];
|
||||
$edit['alias'] = $node4_alias;
|
||||
$edit['source'] = '/node/' . $node2->id();
|
||||
$this->drupalPostForm('admin/config/search/path/edit/' . $pid, $edit, t('Save'));
|
||||
$this->assertText('The alias has been saved.');
|
||||
$this->drupalGet($edit['alias']);
|
||||
$this->assertNoText($node4->label(), 'Previous alias no longer works.');
|
||||
$this->assertText($node2->label(), 'Alias works.');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Update an existing alias to use a duplicate alias.
|
||||
$pid = $this->getPID($node3_alias);
|
||||
$edit = [];
|
||||
$edit['alias'] = $node4_alias;
|
||||
$edit['source'] = '/node/' . $node3->id();
|
||||
$this->drupalPostForm('admin/config/search/path/edit/' . $pid, $edit, t('Save'));
|
||||
$this->assertRaw(t('The alias %alias is already in use in this language.', array('%alias' => $edit['alias'])));
|
||||
|
||||
// Create an alias without a starting slash.
|
||||
$node5 = $this->drupalCreateNode();
|
||||
|
||||
$edit = array();
|
||||
$edit['source'] = 'node/' . $node5->id();
|
||||
$node5_alias = $this->randomMachineName(8);
|
||||
$edit['alias'] = $node5_alias . '/';
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
$this->assertUrl('admin/config/search/path/add');
|
||||
$this->assertText('The source path has to start with a slash.');
|
||||
$this->assertText('The alias path has to start with a slash.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests alias functionality through the node interfaces.
|
||||
*/
|
||||
function testNodeAlias() {
|
||||
// Create test node.
|
||||
$node1 = $this->drupalCreateNode();
|
||||
|
||||
// Create alias.
|
||||
$edit = array();
|
||||
$edit['path[0][alias]'] = '/' . $this->randomMachineName(8);
|
||||
$this->drupalPostForm('node/' . $node1->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Confirm that the alias works.
|
||||
$this->drupalGet($edit['path[0][alias]']);
|
||||
$this->assertText($node1->label(), 'Alias works.');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Confirm the 'canonical' and 'shortlink' URLs.
|
||||
$elements = $this->xpath("//link[contains(@rel, 'canonical') and contains(@href, '" . $edit['path[0][alias]'] . "')]");
|
||||
$this->assertTrue(!empty($elements), 'Page contains canonical link URL.');
|
||||
$elements = $this->xpath("//link[contains(@rel, 'shortlink') and contains(@href, 'node/" . $node1->id() . "')]");
|
||||
$this->assertTrue(!empty($elements), 'Page contains shortlink URL.');
|
||||
|
||||
$previous = $edit['path[0][alias]'];
|
||||
// Change alias to one containing "exotic" characters.
|
||||
$edit['path[0][alias]'] = '/alias' . // Lower-case letters.
|
||||
// "Special" ASCII characters.
|
||||
"- ._~!$'\"()*@[]?&+%#,;=:" .
|
||||
// Characters that look like a percent-escaped string.
|
||||
"%23%25%26%2B%2F%3F" .
|
||||
// Characters from various non-ASCII alphabets.
|
||||
"中國書۞";
|
||||
$connection = Database::getConnection();
|
||||
if ($connection->databaseType() != 'sqlite') {
|
||||
// When using LIKE for case-insensitivity, the SQLite driver is
|
||||
// currently unable to find the upper-case versions of non-ASCII
|
||||
// characters.
|
||||
// @todo fix this in https://www.drupal.org/node/2607432
|
||||
$edit['path[0][alias]'] .= "ïвβéø";
|
||||
}
|
||||
$this->drupalPostForm('node/' . $node1->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Confirm that the alias works.
|
||||
$this->drupalGet(Unicode::strtoupper($edit['path[0][alias]']));
|
||||
$this->assertText($node1->label(), 'Changed alias works.');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Make sure that previous alias no longer works.
|
||||
$this->drupalGet($previous);
|
||||
$this->assertNoText($node1->label(), 'Previous alias no longer works.');
|
||||
$this->assertResponse(404);
|
||||
|
||||
// Create second test node.
|
||||
$node2 = $this->drupalCreateNode();
|
||||
|
||||
// Set alias to second test node.
|
||||
// Leave $edit['path[0][alias]'] the same.
|
||||
$this->drupalPostForm('node/' . $node2->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Confirm that the alias didn't make a duplicate.
|
||||
$this->assertText(t('The alias is already in use.'), 'Attempt to moved alias was rejected.');
|
||||
|
||||
// Delete alias.
|
||||
$this->drupalPostForm('node/' . $node1->id() . '/edit', array('path[0][alias]' => ''), t('Save'));
|
||||
|
||||
// Confirm that the alias no longer works.
|
||||
$this->drupalGet($edit['path[0][alias]']);
|
||||
$this->assertNoText($node1->label(), 'Alias was successfully deleted.');
|
||||
$this->assertResponse(404);
|
||||
|
||||
// Create third test node.
|
||||
$node3 = $this->drupalCreateNode();
|
||||
|
||||
// Set its path alias to an absolute path.
|
||||
$edit = array('path[0][alias]' => '/' . $this->randomMachineName(8));
|
||||
$this->drupalPostForm('node/' . $node3->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Confirm that the alias was converted to a relative path.
|
||||
$this->drupalGet(trim($edit['path[0][alias]'], '/'));
|
||||
$this->assertText($node3->label(), 'Alias became relative.');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Create fourth test node.
|
||||
$node4 = $this->drupalCreateNode();
|
||||
|
||||
// Set its path alias to have a trailing slash.
|
||||
$edit = array('path[0][alias]' => '/' . $this->randomMachineName(8) . '/');
|
||||
$this->drupalPostForm('node/' . $node4->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Confirm that the alias was converted to a relative path.
|
||||
$this->drupalGet(trim($edit['path[0][alias]'], '/'));
|
||||
$this->assertText($node4->label(), 'Alias trimmed trailing slash.');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path ID.
|
||||
*
|
||||
* @param string $alias
|
||||
* A string containing an aliased path.
|
||||
*
|
||||
* @return int
|
||||
* Integer representing the path ID.
|
||||
*/
|
||||
function getPID($alias) {
|
||||
return db_query("SELECT pid FROM {url_alias} WHERE alias = :alias", array(':alias' => $alias))->fetchField();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that duplicate aliases fail validation.
|
||||
*/
|
||||
function testDuplicateNodeAlias() {
|
||||
// Create one node with a random alias.
|
||||
$node_one = $this->drupalCreateNode();
|
||||
$edit = array();
|
||||
$edit['path[0][alias]'] = '/' . $this->randomMachineName();
|
||||
$this->drupalPostForm('node/' . $node_one->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Now create another node and try to set the same alias.
|
||||
$node_two = $this->drupalCreateNode();
|
||||
$this->drupalPostForm('node/' . $node_two->id() . '/edit', $edit, t('Save'));
|
||||
$this->assertText(t('The alias is already in use.'));
|
||||
$this->assertFieldByXPath("//input[@name='path[0][alias]' and contains(@class, 'error')]", $edit['path[0][alias]'], 'Textfield exists and has the error class.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\path\Tests;
|
||||
|
||||
/**
|
||||
* Confirm that paths work with translated nodes.
|
||||
*
|
||||
* @group path
|
||||
*/
|
||||
class PathLanguageTest extends PathTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('path', 'locale', 'locale_test', 'content_translation');
|
||||
|
||||
/**
|
||||
* An user with permissions to administer content types.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$permissions = array(
|
||||
'access administration pages',
|
||||
'administer content translation',
|
||||
'administer content types',
|
||||
'administer languages',
|
||||
'administer url aliases',
|
||||
'create content translations',
|
||||
'create page content',
|
||||
'create url aliases',
|
||||
'edit any page content',
|
||||
'translate any entity',
|
||||
);
|
||||
// Create and log in user.
|
||||
$this->webUser = $this->drupalCreateUser($permissions);
|
||||
$this->drupalLogin($this->webUser);
|
||||
|
||||
// Enable French language.
|
||||
$edit = array();
|
||||
$edit['predefined_langcode'] = 'fr';
|
||||
|
||||
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
|
||||
|
||||
// Enable URL language detection and selection.
|
||||
$edit = array('language_interface[enabled][language-url]' => 1);
|
||||
$this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
|
||||
|
||||
// Enable translation for page node.
|
||||
$edit = array(
|
||||
'entity_types[node]' => 1,
|
||||
'settings[node][page][translatable]' => 1,
|
||||
'settings[node][page][fields][path]' => 1,
|
||||
'settings[node][page][fields][body]' => 1,
|
||||
'settings[node][page][settings][language][language_alterable]' => 1,
|
||||
);
|
||||
$this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
|
||||
\Drupal::entityManager()->clearCachedDefinitions();
|
||||
|
||||
$definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'page');
|
||||
$this->assertTrue($definitions['path']->isTranslatable(), 'Node path is translatable.');
|
||||
$this->assertTrue($definitions['body']->isTranslatable(), 'Node body is translatable.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test alias functionality through the admin interfaces.
|
||||
*/
|
||||
function testAliasTranslation() {
|
||||
$node_storage = $this->container->get('entity.manager')->getStorage('node');
|
||||
$english_node = $this->drupalCreateNode(array('type' => 'page', 'langcode' => 'en'));
|
||||
$english_alias = $this->randomMachineName();
|
||||
|
||||
// Edit the node to set language and path.
|
||||
$edit = array();
|
||||
$edit['path[0][alias]'] = '/' . $english_alias;
|
||||
$this->drupalPostForm('node/' . $english_node->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Confirm that the alias works.
|
||||
$this->drupalGet($english_alias);
|
||||
$this->assertText($english_node->body->value, 'Alias works.');
|
||||
|
||||
// Translate the node into French.
|
||||
$this->drupalGet('node/' . $english_node->id() . '/translations');
|
||||
$this->clickLink(t('Add'));
|
||||
|
||||
$edit = array();
|
||||
$edit['title[0][value]'] = $this->randomMachineName();
|
||||
$edit['body[0][value]'] = $this->randomMachineName();
|
||||
$french_alias = $this->randomMachineName();
|
||||
$edit['path[0][alias]'] = '/' . $french_alias;
|
||||
$this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
|
||||
|
||||
// Clear the path lookup cache.
|
||||
$this->container->get('path.alias_manager')->cacheClear();
|
||||
|
||||
// Languages are cached on many levels, and we need to clear those caches.
|
||||
$this->container->get('language_manager')->reset();
|
||||
$this->rebuildContainer();
|
||||
$languages = $this->container->get('language_manager')->getLanguages();
|
||||
|
||||
// Ensure the node was created.
|
||||
$node_storage->resetCache(array($english_node->id()));
|
||||
$english_node = $node_storage->load($english_node->id());
|
||||
$english_node_french_translation = $english_node->getTranslation('fr');
|
||||
$this->assertTrue($english_node->hasTranslation('fr'), 'Node found in database.');
|
||||
|
||||
// Confirm that the alias works.
|
||||
$this->drupalGet('fr' . $edit['path[0][alias]']);
|
||||
$this->assertText($english_node_french_translation->body->value, 'Alias for French translation works.');
|
||||
|
||||
// Confirm that the alias is returned for the URL. Languages are cached on
|
||||
// many levels, and we need to clear those caches.
|
||||
$this->container->get('language_manager')->reset();
|
||||
$languages = $this->container->get('language_manager')->getLanguages();
|
||||
$url = $english_node_french_translation->url('canonical', array('language' => $languages['fr']));
|
||||
|
||||
$this->assertTrue(strpos($url, $edit['path[0][alias]']), 'URL contains the path alias.');
|
||||
|
||||
// Confirm that the alias works even when changing language negotiation
|
||||
// options. Enable User language detection and selection over URL one.
|
||||
$edit = array(
|
||||
'language_interface[enabled][language-user]' => 1,
|
||||
'language_interface[weight][language-user]' => -9,
|
||||
'language_interface[enabled][language-url]' => 1,
|
||||
'language_interface[weight][language-url]' => -8,
|
||||
);
|
||||
$this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
|
||||
|
||||
// Change user language preference.
|
||||
$edit = array('preferred_langcode' => 'fr');
|
||||
$this->drupalPostForm("user/" . $this->webUser->id() . "/edit", $edit, t('Save'));
|
||||
|
||||
// Check that the English alias works. In this situation French is the
|
||||
// current UI and content language, while URL language is English (since we
|
||||
// do not have a path prefix we fall back to the site's default language).
|
||||
// We need to ensure that the user language preference is not taken into
|
||||
// account while determining the path alias language, because if this
|
||||
// happens we have no way to check that the path alias is valid: there is no
|
||||
// path alias for French matching the english alias. So the alias manager
|
||||
// needs to use the URL language to check whether the alias is valid.
|
||||
$this->drupalGet($english_alias);
|
||||
$this->assertText($english_node_french_translation->body->value, 'English alias, but French preferred by the user: French translation.');
|
||||
|
||||
// Check that the French alias works.
|
||||
$this->drupalGet("fr/$french_alias");
|
||||
$this->assertText($english_node_french_translation->body->value, 'Alias for French translation works.');
|
||||
|
||||
// Disable URL language negotiation.
|
||||
$edit = array('language_interface[enabled][language-url]' => FALSE);
|
||||
$this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
|
||||
|
||||
// Check that the English alias still works.
|
||||
$this->drupalGet($english_alias);
|
||||
$this->assertText($english_node_french_translation->body->value, 'English alias, but French preferred by the user: French translation.');
|
||||
|
||||
// Check that the French alias is not available. We check the unprefixed
|
||||
// alias because we disabled URL language negotiation above. In this
|
||||
// situation only aliases in the default language and language neutral ones
|
||||
// should keep working.
|
||||
$this->drupalGet($french_alias);
|
||||
$this->assertResponse(404, 'Alias for French translation is unavailable when URL language negotiation is disabled.');
|
||||
|
||||
// The alias manager has an internal path lookup cache. Check to see that
|
||||
// it has the appropriate contents at this point.
|
||||
$this->container->get('path.alias_manager')->cacheClear();
|
||||
$french_node_path = $this->container->get('path.alias_manager')->getPathByAlias('/' . $french_alias, 'fr');
|
||||
$this->assertEqual($french_node_path, '/node/' . $english_node_french_translation->id(), 'Normal path works.');
|
||||
// Second call should return the same path.
|
||||
$french_node_path = $this->container->get('path.alias_manager')->getPathByAlias('/' . $french_alias, 'fr');
|
||||
$this->assertEqual($french_node_path, '/node/' . $english_node_french_translation->id(), 'Normal path is the same.');
|
||||
|
||||
// Confirm that the alias works.
|
||||
$french_node_alias = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $english_node_french_translation->id(), 'fr');
|
||||
$this->assertEqual($french_node_alias, '/' . $french_alias, 'Alias works.');
|
||||
// Second call should return the same alias.
|
||||
$french_node_alias = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $english_node_french_translation->id(), 'fr');
|
||||
$this->assertEqual($french_node_alias, '/' . $french_alias, 'Alias is the same.');
|
||||
|
||||
// Confirm that the alias is removed if the translation is deleted.
|
||||
$english_node->removeTranslation('fr');
|
||||
$english_node->save();
|
||||
$this->assertFalse($this->container->get('path.alias_storage')->aliasExists('/' . $french_alias, 'fr'), 'Alias for French translation is removed when translation is deleted.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\path\Tests;
|
||||
|
||||
/**
|
||||
* Confirm that the Path module user interface works with languages.
|
||||
*
|
||||
* @group path
|
||||
*/
|
||||
class PathLanguageUiTest extends PathTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('path', 'locale', 'locale_test');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create and log in user.
|
||||
$web_user = $this->drupalCreateUser(array('edit any page content', 'create page content', 'administer url aliases', 'create url aliases', 'administer languages', 'access administration pages'));
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
// Enable French language.
|
||||
$edit = array();
|
||||
$edit['predefined_langcode'] = 'fr';
|
||||
|
||||
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
|
||||
|
||||
// Enable URL language detection and selection.
|
||||
$edit = array('language_interface[enabled][language-url]' => 1);
|
||||
$this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a language-neutral URL alias works.
|
||||
*/
|
||||
function testLanguageNeutralUrl() {
|
||||
$name = $this->randomMachineName(8);
|
||||
$edit = array();
|
||||
$edit['source'] = '/admin/config/search/path';
|
||||
$edit['alias'] = '/' . $name;
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
$this->drupalGet($name);
|
||||
$this->assertText(t('Filter aliases'), 'Language-neutral URL alias works');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a default language URL alias works.
|
||||
*/
|
||||
function testDefaultLanguageUrl() {
|
||||
$name = $this->randomMachineName(8);
|
||||
$edit = array();
|
||||
$edit['source'] = '/admin/config/search/path';
|
||||
$edit['alias'] = '/' . $name;
|
||||
$edit['langcode'] = 'en';
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
$this->drupalGet($name);
|
||||
$this->assertText(t('Filter aliases'), 'English URL alias works');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a non-default language URL alias works.
|
||||
*/
|
||||
function testNonDefaultUrl() {
|
||||
$name = $this->randomMachineName(8);
|
||||
$edit = array();
|
||||
$edit['source'] = '/admin/config/search/path';
|
||||
$edit['alias'] = '/' . $name;
|
||||
$edit['langcode'] = 'fr';
|
||||
$this->drupalPostForm('admin/config/search/path/add', $edit, t('Save'));
|
||||
|
||||
$this->drupalGet('fr/' . $name);
|
||||
$this->assertText(t('Filter aliases'), 'Foreign URL alias works');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\path\Tests;
|
||||
|
||||
/**
|
||||
* Tests the Path Node form UI.
|
||||
*
|
||||
* @group path
|
||||
*/
|
||||
class PathNodeFormTest extends PathTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'path');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create test user and log in.
|
||||
$web_user = $this->drupalCreateUser(array('create page content', 'create url aliases'));
|
||||
$this->drupalLogin($web_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the node form ui.
|
||||
*/
|
||||
public function testNodeForm() {
|
||||
$this->drupalGet('node/add/page');
|
||||
|
||||
// Make sure we have a Path fieldset and Path fields.
|
||||
$this->assertRaw(' id="edit-path-settings"', 'Path settings details exists');
|
||||
$this->assertFieldByName('path[0][alias]', NULL, 'Path alias field exists');
|
||||
|
||||
// Disable the Path field for this content type.
|
||||
entity_get_form_display('node', 'page', 'default')
|
||||
->removeComponent('path')
|
||||
->save();
|
||||
|
||||
$this->drupalGet('node/add/page');
|
||||
|
||||
// See if the whole fieldset is gone now.
|
||||
$this->assertNoRaw(' id="edit-path-settings"', 'Path settings details does not exist');
|
||||
$this->assertNoFieldByName('path[0][alias]', NULL, 'Path alias field does not exist');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\path\Tests;
|
||||
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
|
||||
/**
|
||||
* Tests URL aliases for taxonomy terms.
|
||||
*
|
||||
* @group path
|
||||
*/
|
||||
class PathTaxonomyTermTest extends PathTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('taxonomy');
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a Tags vocabulary for the Article node type.
|
||||
$vocabulary = Vocabulary::create([
|
||||
'name' => t('Tags'),
|
||||
'vid' => 'tags',
|
||||
]);
|
||||
$vocabulary->save();
|
||||
|
||||
// Create and log in user.
|
||||
$web_user = $this->drupalCreateUser(array('administer url aliases', 'administer taxonomy', 'access administration pages'));
|
||||
$this->drupalLogin($web_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests alias functionality through the admin interfaces.
|
||||
*/
|
||||
function testTermAlias() {
|
||||
// Create a term in the default 'Tags' vocabulary with URL alias.
|
||||
$vocabulary = Vocabulary::load('tags');
|
||||
$description = $this->randomMachineName();
|
||||
$edit = array(
|
||||
'name[0][value]' => $this->randomMachineName(),
|
||||
'description[0][value]' => $description,
|
||||
'path[0][alias]' => '/' . $this->randomMachineName(),
|
||||
);
|
||||
$this->drupalPostForm('admin/structure/taxonomy/manage/' . $vocabulary->id() . '/add', $edit, t('Save'));
|
||||
$tid = db_query("SELECT tid FROM {taxonomy_term_field_data} WHERE name = :name AND default_langcode = 1", array(':name' => $edit['name[0][value]']))->fetchField();
|
||||
|
||||
// Confirm that the alias works.
|
||||
$this->drupalGet($edit['path[0][alias]']);
|
||||
$this->assertText($description, 'Term can be accessed on URL alias.');
|
||||
|
||||
// Confirm the 'canonical' and 'shortlink' URLs.
|
||||
$elements = $this->xpath("//link[contains(@rel, 'canonical') and contains(@href, '" . $edit['path[0][alias]'] . "')]");
|
||||
$this->assertTrue(!empty($elements), 'Term page contains canonical link URL.');
|
||||
$elements = $this->xpath("//link[contains(@rel, 'shortlink') and contains(@href, 'taxonomy/term/" . $tid . "')]");
|
||||
$this->assertTrue(!empty($elements), 'Term page contains shortlink URL.');
|
||||
|
||||
// Change the term's URL alias.
|
||||
$edit2 = array();
|
||||
$edit2['path[0][alias]'] = '/' . $this->randomMachineName();
|
||||
$this->drupalPostForm('taxonomy/term/' . $tid . '/edit', $edit2, t('Save'));
|
||||
|
||||
// Confirm that the changed alias works.
|
||||
$this->drupalGet(trim($edit2['path[0][alias]'], '/'));
|
||||
$this->assertText($description, 'Term can be accessed on changed URL alias.');
|
||||
|
||||
// Confirm that the old alias no longer works.
|
||||
$this->drupalGet(trim($edit['path[0][alias]'], '/'));
|
||||
$this->assertNoText($description, 'Old URL alias has been removed after altering.');
|
||||
$this->assertResponse(404, 'Old URL alias returns 404.');
|
||||
|
||||
// Remove the term's URL alias.
|
||||
$edit3 = array();
|
||||
$edit3['path[0][alias]'] = '';
|
||||
$this->drupalPostForm('taxonomy/term/' . $tid . '/edit', $edit3, t('Save'));
|
||||
|
||||
// Confirm that the alias no longer works.
|
||||
$this->drupalGet(trim($edit2['path[0][alias]'], '/'));
|
||||
$this->assertNoText($description, 'Old URL alias has been removed after altering.');
|
||||
$this->assertResponse(404, 'Old URL alias returns 404.');
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user