View source
<?php
namespace Drupal\Tests\decoupled_router\Functional;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Language\Language;
use Drupal\Core\Url;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\node\NodeInterface;
use Drupal\redirect\Entity\Redirect;
use Drupal\Tests\BrowserTestBase;
class DecoupledRouterFunctionalTest extends BrowserTestBase {
const DRUPAL_CI_BASE_URL = 'http://localhost/subdir';
protected $defaultTheme = 'stark';
protected $user;
protected $nodes = [];
public static $modules = [
'language',
'node',
'path',
'decoupled_router',
'redirect',
'jsonapi',
];
protected function setUp() {
parent::setUp();
$language = ConfigurableLanguage::createFromLangcode('ca');
$language
->save();
$this
->rebuildContainer();
\Drupal::configFactory()
->getEditable('language.negotiation')
->set('url.prefixes.ca', 'ca')
->save();
$this
->drupalCreateContentType([
'type' => 'article',
'name' => 'Article',
]);
$this->user = $this
->drupalCreateUser([
'access content',
'create article content',
'edit any article content',
'delete any article content',
]);
$this
->createDefaultContent(3);
$redirect = Redirect::create([
'status_code' => '301',
]);
$redirect
->setSource('/foo');
$redirect
->setRedirect('/node--0');
$redirect
->setLanguage(Language::LANGCODE_NOT_SPECIFIED);
$redirect
->save();
$redirect = Redirect::create([
'status_code' => '301',
]);
$redirect
->setSource('/bar');
$redirect
->setRedirect('/foo');
$redirect
->setLanguage(Language::LANGCODE_NOT_SPECIFIED);
$redirect
->save();
$redirect = Redirect::create([
'status_code' => '301',
]);
$redirect
->setSource('/foo--ca');
$redirect
->setRedirect('/node--0--ca');
$redirect
->setLanguage('ca');
$redirect
->save();
\Drupal::service('router.builder')
->rebuild();
}
protected function createDefaultContent($num_articles) {
$random = $this
->getRandomGenerator();
for ($created_nodes = 0; $created_nodes < $num_articles; $created_nodes++) {
$values = [
'uid' => [
'target_id' => $this->user
->id(),
],
'type' => 'article',
'path' => '/node--' . $created_nodes,
'title' => $random
->name(),
];
$node = $this
->createNode($values);
$values['title'] = $node
->getTitle() . ' (ca)';
$values['field_image']['alt'] = 'alt text (ca)';
$values['path'] = '/node--' . $created_nodes . '--ca';
$node
->addTranslation('ca', $values);
$node
->save();
$this->nodes[] = $node;
}
}
public function testNegotiationNoMultilingual() {
$make_assertions = function ($path, DecoupledRouterFunctionalTest $test) {
$res = $test
->drupalGet(Url::fromRoute('decoupled_router.path_translation'), [
'query' => [
'path' => $path,
'_format' => 'json',
],
]);
$test
->assertSession()
->statusCodeEquals(200);
$output = Json::decode($res);
$test
->assertStringEndsWith('/node--0', $output['resolved']);
$test
->assertSame($test->nodes[0]
->id(), $output['entity']['id']);
$test
->assertSame('node--article', $output['jsonapi']['resourceName']);
$test
->assertStringEndsWith('/jsonapi/node/article/' . $test->nodes[0]
->uuid(), $output['jsonapi']['individual']);
};
$base_path = $this
->getBasePath();
$test_cases = [
$base_path . '/node/1',
$base_path . '/node--0',
$base_path . '/bar',
];
array_walk($test_cases, function ($test_case) use ($make_assertions) {
$make_assertions($test_case, $this);
});
}
public function testUnpublishedContent() {
$values = [
'uid' => [
'target_id' => $this->user
->id(),
],
'type' => 'article',
'path' => '/node--unpublished',
'title' => $this
->getRandomGenerator()
->name(),
'status' => NodeInterface::NOT_PUBLISHED,
];
$node = $this
->createNode($values);
$redirect = Redirect::create([
'status_code' => '301',
]);
$redirect
->setSource('/unp');
$redirect
->setRedirect('/node--unpublished');
$redirect
->setLanguage(Language::LANGCODE_NOT_SPECIFIED);
$redirect
->save();
$res = $this
->drupalGet(Url::fromRoute('decoupled_router.path_translation'), [
'query' => [
'path' => '/unp',
'_format' => 'json',
],
]);
$output = Json::decode($res);
$this
->assertArrayNotHasKey('redirect', $output);
$this
->assertEquals([
'message' => 'Access denied for entity.',
'details' => 'This user does not have access to view the resolved entity. Please authenticate and try again.',
], $output);
$this
->assertSession()
->statusCodeEquals(403);
$admin_user = $this
->drupalCreateUser([
'administer nodes',
'bypass node access',
]);
$this
->drupalLogin($admin_user);
$res = $this
->drupalGet(Url::fromRoute('decoupled_router.path_translation'), [
'query' => [
'path' => '/unp',
'_format' => 'json',
],
]);
$output = Json::decode($res);
$this
->assertSession()
->statusCodeEquals(200);
$expected = [
'resolved' => $this
->buildUrl('/node--unpublished'),
'isHomePath' => FALSE,
'entity' => [
'canonical' => $this
->buildUrl('/node--unpublished'),
'type' => 'node',
'bundle' => 'article',
'id' => $node
->id(),
'uuid' => $node
->uuid(),
],
'label' => $node
->label(),
'jsonapi' => [
'individual' => $this
->buildUrl('/jsonapi/node/article/' . $node
->uuid()),
'resourceName' => 'node--article',
'pathPrefix' => 'jsonapi',
'basePath' => '/jsonapi',
'entryPoint' => $this
->buildUrl('/jsonapi'),
],
'meta' => [
'deprecated' => [
'jsonapi.pathPrefix' => 'This property has been deprecated and will be removed in the next version of Decoupled Router. Use basePath instead.',
],
],
'redirect' => [
[
'from' => '/unp',
'to' => '/' . implode('/', array_filter([
trim($this
->getBasePath(), '/'),
'node--unpublished',
])),
'status' => '301',
],
],
];
$this
->assertEquals($expected, $output);
}
public function testHomPathCheck() {
$this
->createNode([
'uid' => [
'target_id' => $this->user
->id(),
],
'type' => 'article',
'path' => '/node--homepage',
'title' => $this
->getRandomGenerator()
->name(),
'status' => NodeInterface::NOT_PUBLISHED,
]);
\Drupal::configFactory()
->getEditable('system.site')
->set('page.front', '/node--homepage')
->save();
$user = $this
->drupalCreateUser([
'bypass node access',
]);
$this
->drupalLogin($user);
$res = $this
->drupalGet(Url::fromRoute('decoupled_router.path_translation'), [
'query' => [
'path' => '/node--homepage',
'_format' => 'json',
],
]);
$this
->assertSession()
->statusCodeEquals(200);
$output = Json::decode($res);
$this
->assertTrue($output['isHomePath']);
$res = $this
->drupalGet(Url::fromRoute('decoupled_router.path_translation'), [
'query' => [
'path' => '/node--1',
'_format' => 'json',
],
]);
$this
->assertSession()
->statusCodeEquals(200);
$output = Json::decode($res);
$this
->assertFalse($output['isHomePath']);
}
private function getBasePath() {
$parts = parse_url(getenv('SIMPLETEST_BASE_URL') ?: getenv('WEB_HOST') ?: self::DRUPAL_CI_BASE_URL);
return empty($parts['path']) ? '/' : $parts['path'];
}
}