You are here

public function SecurityAdvisoryTest::testPsa in Drupal 9

Tests that a security advisory is displayed.

File

core/modules/system/tests/src/Functional/SecurityAdvisories/SecurityAdvisoryTest.php, line 116

Class

SecurityAdvisoryTest
Tests of security advisories functionality.

Namespace

Drupal\Tests\system\Functional\SecurityAdvisories

Code

public function testPsa() : void {
  $assert = $this
    ->assertSession();

  // Setup test PSA endpoint.
  AdvisoriesTestHttpClient::setTestEndpoint($this->workingEndpointMixed);
  $mixed_advisory_links = [
    'Critical Release - SA-2019-02-19',
    'Critical Release - PSA-Really Old',
    // The info for the test modules 'generic_module1_test' and
    // 'generic_module2_test' are altered for this test so match the items in
    // the test json feeds.
    // @see advisory_feed_test_system_info_alter()
    'Generic Module1 Project - Moderately critical - Access bypass - SA-CONTRIB-2019-02-02',
    'Generic Module2 project - Moderately critical - Access bypass - SA-CONTRIB-2019-02-02',
  ];

  // Confirm that links are not displayed if they are enabled.
  $this
    ->config('system.advisories')
    ->set('enabled', FALSE)
    ->save();
  $this
    ->assertAdvisoriesNotDisplayed($mixed_advisory_links);
  $this
    ->config('system.advisories')
    ->set('enabled', TRUE)
    ->save();

  // A new request for the JSON feed will not be made on admin pages besides
  // the status report.
  $this
    ->assertAdvisoriesNotDisplayed($mixed_advisory_links, [
    'system.admin',
  ]);

  // If both PSA and non-PSA advisories are displayed they should be displayed
  // as errors.
  $this
    ->assertStatusReportLinks($mixed_advisory_links, REQUIREMENT_ERROR);

  // The advisories will be displayed on admin pages if the response was
  // stored from the status report request.
  $this
    ->assertAdminPageLinks($mixed_advisory_links, REQUIREMENT_ERROR);

  // Confirm that a user without the correct permission will not see the
  // advisories on admin pages.
  $this
    ->drupalLogin($this
    ->drupalCreateUser([
    'access administration pages',
  ]));
  $this
    ->assertAdvisoriesNotDisplayed($mixed_advisory_links, [
    'system.admin',
  ]);

  // Log back in with user with permission to see the advisories.
  $this
    ->drupalLogin($this->user);

  // Test cache.
  AdvisoriesTestHttpClient::setTestEndpoint($this->nonWorkingEndpoint);
  $this
    ->assertAdminPageLinks($mixed_advisory_links, REQUIREMENT_ERROR);
  $this
    ->assertStatusReportLinks($mixed_advisory_links, REQUIREMENT_ERROR);

  // Tests transmit errors with a JSON endpoint.
  $this->tempStore
    ->delete('advisories_response');
  $this
    ->assertAdvisoriesNotDisplayed($mixed_advisory_links);

  // Test that the site status report displays an error.
  $this
    ->drupalGet(Url::fromRoute('system.status'));
  $assert
    ->pageTextContains('Failed to fetch security advisory data:');

  // Test a PSA endpoint that returns invalid JSON.
  AdvisoriesTestHttpClient::setTestEndpoint($this->invalidJsonEndpoint, TRUE);

  // Assert that are no logged error messages before attempting to fetch the
  // invalid endpoint.
  $this
    ->assertServiceAdvisoryLoggedErrors([]);

  // On admin pages no message should be displayed if the feed is malformed.
  $this
    ->assertAdvisoriesNotDisplayed($mixed_advisory_links);

  // Assert that there was an error logged for the invalid endpoint.
  $this
    ->assertServiceAdvisoryLoggedErrors([
    'The security advisory JSON feed from Drupal.org could not be decoded.',
  ]);

  // On the status report there should be no announcements section.
  $this
    ->drupalGet(Url::fromRoute('system.status'));
  $assert
    ->pageTextNotContains('Failed to fetch security advisory data:');

  // Assert the error was logged again.
  $this
    ->assertServiceAdvisoryLoggedErrors([
    'The security advisory JSON feed from Drupal.org could not be decoded.',
  ]);
  AdvisoriesTestHttpClient::setTestEndpoint($this->workingEndpointPsaOnly, TRUE);
  $psa_advisory_links = [
    'Critical Release - PSA-Really Old',
    'Generic Module2 project - Moderately critical - Access bypass - SA-CONTRIB-2019-02-02',
  ];

  // Admin page will not display the new links because a new feed request is
  // not attempted.
  $this
    ->assertAdvisoriesNotDisplayed($psa_advisory_links, [
    'system.admin',
  ]);

  // If only PSA advisories are displayed they should be displayed as
  // warnings.
  $this
    ->assertStatusReportLinks($psa_advisory_links, REQUIREMENT_WARNING);
  $this
    ->assertAdminPageLinks($psa_advisory_links, REQUIREMENT_WARNING);
  AdvisoriesTestHttpClient::setTestEndpoint($this->workingEndpointNonPsaOnly, TRUE);
  $non_psa_advisory_links = [
    'Critical Release - SA-2019-02-19',
    'Generic Module1 Project - Moderately critical - Access bypass - SA-CONTRIB-2019-02-02',
  ];

  // If only non-PSA advisories are displayed they should be displayed as
  // errors.
  $this
    ->assertStatusReportLinks($non_psa_advisory_links, REQUIREMENT_ERROR);
  $this
    ->assertAdminPageLinks($non_psa_advisory_links, REQUIREMENT_ERROR);

  // Confirm that advisory fetching can be disabled after enabled.
  $this
    ->config('system.advisories')
    ->set('enabled', FALSE)
    ->save();
  $this
    ->assertAdvisoriesNotDisplayed($non_psa_advisory_links);

  // Assert no other errors were logged.
  $this
    ->assertServiceAdvisoryLoggedErrors([]);
}