function ContextualDynamicContextTest::testDifferentPermissions

Same name in other branches
  1. 9 core/modules/contextual/tests/src/Functional/ContextualDynamicContextTest.php \Drupal\Tests\contextual\Functional\ContextualDynamicContextTest::testDifferentPermissions()
  2. 8.9.x core/modules/contextual/tests/src/Functional/ContextualDynamicContextTest.php \Drupal\Tests\contextual\Functional\ContextualDynamicContextTest::testDifferentPermissions()
  3. 10 core/modules/contextual/tests/src/Functional/ContextualDynamicContextTest.php \Drupal\Tests\contextual\Functional\ContextualDynamicContextTest::testDifferentPermissions()

Tests contextual links with different permissions.

Ensures that contextual link placeholders always exist, even if the user is not allowed to use contextual links.

File

core/modules/contextual/tests/src/Functional/ContextualDynamicContextTest.php, line 89

Class

ContextualDynamicContextTest
Tests contextual link display on the front page based on permissions.

Namespace

Drupal\Tests\contextual\Functional

Code

public function testDifferentPermissions() : void {
    $this->drupalLogin($this->editorUser);
    // Create three nodes in the following order:
    // - An article, which should be user-editable.
    // - A page, which should not be user-editable.
    // - A second article, which should also be user-editable.
    $node1 = $this->drupalCreateNode([
        'type' => 'article',
        'promote' => 1,
    ]);
    $node2 = $this->drupalCreateNode([
        'type' => 'page',
        'promote' => 1,
    ]);
    $node3 = $this->drupalCreateNode([
        'type' => 'article',
        'promote' => 1,
    ]);
    // Now, on the front page, all article nodes should have contextual links
    // placeholders, as should the view that contains them.
    $ids = [
        'node:node=' . $node1->id() . ':changed=' . $node1->getChangedTime() . '&langcode=en',
        'node:node=' . $node2->id() . ':changed=' . $node2->getChangedTime() . '&langcode=en',
        'node:node=' . $node3->id() . ':changed=' . $node3->getChangedTime() . '&langcode=en',
        'entity.view.edit_form:view=frontpage:location=page&name=frontpage&display_id=page_1&langcode=en',
    ];
    // Editor user: can access contextual links and can edit articles.
    $this->drupalGet('node');
    for ($i = 0; $i < count($ids); $i++) {
        $this->assertContextualLinkPlaceHolder($ids[$i]);
    }
    $response = $this->renderContextualLinks([], 'node');
    $this->assertSame(400, $response->getStatusCode());
    $this->assertStringContainsString('No contextual ids specified.', (string) $response->getBody());
    $response = $this->renderContextualLinks($ids, 'node');
    $this->assertSame(200, $response->getStatusCode());
    $json = Json::decode((string) $response->getBody());
    $this->assertSame('<ul class="contextual-links"><li><a href="' . base_path() . 'node/1/edit">Edit</a></li></ul>', $json[$ids[0]]);
    $this->assertSame('', $json[$ids[1]]);
    $this->assertSame('<ul class="contextual-links"><li><a href="' . base_path() . 'node/3/edit">Edit</a></li></ul>', $json[$ids[2]]);
    $this->assertSame('', $json[$ids[3]]);
    // Verify that link language is properly handled.
    $node3->addTranslation('it')
        ->set('title', $this->randomString())
        ->save();
    $id = 'node:node=' . $node3->id() . ':changed=' . $node3->getChangedTime() . '&langcode=it';
    $this->drupalGet('node', [
        'language' => ConfigurableLanguage::createFromLangcode('it'),
    ]);
    $this->assertContextualLinkPlaceHolder($id);
    // Authenticated user: can access contextual links, cannot edit articles.
    $this->drupalLogin($this->authenticatedUser);
    $this->drupalGet('node');
    for ($i = 0; $i < count($ids); $i++) {
        $this->assertContextualLinkPlaceHolder($ids[$i]);
    }
    $response = $this->renderContextualLinks([], 'node');
    $this->assertSame(400, $response->getStatusCode());
    $this->assertStringContainsString('No contextual ids specified.', (string) $response->getBody());
    $response = $this->renderContextualLinks($ids, 'node');
    $this->assertSame(200, $response->getStatusCode());
    $json = Json::decode((string) $response->getBody());
    $this->assertSame('', $json[$ids[0]]);
    $this->assertSame('', $json[$ids[1]]);
    $this->assertSame('', $json[$ids[2]]);
    $this->assertSame('', $json[$ids[3]]);
    // Anonymous user: cannot access contextual links.
    $this->drupalLogin($this->anonymousUser);
    $this->drupalGet('node');
    for ($i = 0; $i < count($ids); $i++) {
        $this->assertNoContextualLinkPlaceHolder($ids[$i]);
    }
    $response = $this->renderContextualLinks([], 'node');
    $this->assertSame(403, $response->getStatusCode());
    $this->renderContextualLinks($ids, 'node');
    $this->assertSame(403, $response->getStatusCode());
    // Get a page where contextual links are directly rendered.
    $this->drupalGet(Url::fromRoute('menu_test.contextual_test'));
    $this->assertSession()
        ->assertEscaped("<script>alert('Welcome to the jungle!')</script>");
    $this->assertSession()
        ->responseContains('<li><a href="' . base_path() . 'menu-test-contextual/1/edit" class="use-ajax" data-dialog-type="modal" data-is-something>Edit menu - contextual</a></li>');
    // Test contextual links respects the weight set in *.links.contextual.yml.
    $firstLink = $this->assertSession()
        ->elementExists('css', 'ul.contextual-links li:nth-of-type(1) a');
    $secondLink = $this->assertSession()
        ->elementExists('css', 'ul.contextual-links li:nth-of-type(2) a');
    $this->assertEquals(base_path() . 'menu-test-contextual/1/edit', $firstLink->getAttribute('href'));
    $this->assertEquals(base_path() . 'menu-test-contextual/1', $secondLink->getAttribute('href'));
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.