1

I have a context aware block I've created.

/**
 * Provide a context aware block.
 *
 * @Block(
 *   id = "my_context_aware_block",
 *   admin_label = @Translation("My context aware block"),
 *   category = @Translation("Display some node information"),
 *   context = {
 *     "node" = @ContextDefinition(
 *       "entity:node",
 *       label = @Translation("Current Node")
 *     )
 *   }
 * )
 */

It references the current node in the build method.

$node = $this->getContextValue('node');

Everything works as expected in my "live" environment. The issue I am encountering is that my functional test is NOT displaying the block when it IS in a context in which it should show. (I haven't bothered testing a context in which the block is not supposed to show.)

  public function testSomeStuff() {
    // Create a piece of content
    $node = $this->drupalCreateNode(array(
      'title' => t('My sample node'),
      'type' => 'a_valid_node_type',
    ));
    $node->save();

    // Place the block in the sidebar
    $this->drupalPlaceBlock('my_context_aware_block');

    $this->drupalGet('node/' . $node->id());

    // Note: Whether I check the page content or the response, I don't see
    //       the block there. I am showing examples of both just for the
    //       sake of providing detail in this question.
    $this->assertContains('force phpunit to fail so that I can manually look at the text content', $this->getTextContent());
    $this->assertSession()->responseContains('some valid markup that appears in the block');
  }

I have even tested setting

protected $profile = 'standard';

and the block still doesn't appear when I'm viewing the node I created [$this->drupalGet('node/' . $node->id());].

This is on Drupal 8.2.5.

I am inside of /drupal/root/directory/core running PHPUnit from the command line as such

sudo -u www-data ../vendor/bin/phpunit ../modules/custom/my_module/tests/src/Functional/MyFunctionalTest.php

Have I discovered a bug or is there something I am missing and doing wrong?

Edit: Here are more details of the complete solution.

First off, you will need to create a user that has administrative rights and log that user in to the site.

$adminUser = $this->drupalCreateUser(array(
  'administer blocks',
  'access administration pages',
));
$this->drupalLogin($adminUser);

Then, instead of using $this->drupalPlaceBlock('my_context_aware_block');, do the following:

// Place the block in the content area
$block_url = 'admin/structure/block/add/my_context_aware_block/classy';
$edit = [
  'region' => 'content',
];
$this->drupalPostForm($block_url, $edit, 'Save block');

Note: My block didn't need any context configuration. If it did, I could have included that with the $edit array.

1

As discussed in IRC, pretty sure your problem is $this->drupalPlaceBlock('my_context_aware_block'); which doesn't configure the necessary context mapping. That's not visible in the UI if you only have a single context, but it's still there and then stored in the settings.

See \Drupal\block\Tests\BlockUiTest::testContextAwareBlocks(), go to a URL like admin/structure/block/add/test_context_aware/classy, and save the block. ,

| improve this answer | |
  • I will follow your suggestion to see if I can get this to work by having the functional test manually "click" through the UI. If it fixes it, then I'll leave another comment on this answer and mark it as accepted. – vegantriathlete Mar 2 '17 at 18:52
  • Yes! Instead of doing $this->drupalPlaceBlock('my_context_aware_block'); do a $this->drupalPostForm. See the edit in the question for more complete details. – vegantriathlete Mar 2 '17 at 21:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.