Issue #2002116 by damiankloip, jhedstrom, ParisLiakos, dawehner: Convert core/modules/update/lib/Drupal/update/Tests/UpdateCoreUnitTest.php to phpunit.
parent
4d6724c151
commit
332530474e
|
@ -1,77 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\update\Tests\UpdateCoreUnitTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\update\Tests;
|
||||
|
||||
use Drupal\simpletest\UnitTestBase;
|
||||
|
||||
/**
|
||||
* Tests update functionality unrelated to the database.
|
||||
*/
|
||||
class UpdateCoreUnitTest extends UnitTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('update');
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => "Unit tests",
|
||||
'description' => 'Test update functionality unrelated to the database.',
|
||||
'group' => 'Update',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
module_load_include('inc', 'update', 'update.fetch');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that _update_build_fetch_url() builds the URL correctly.
|
||||
*/
|
||||
function testUpdateBuildFetchUrl() {
|
||||
//first test that we didn't break the trivial case
|
||||
$project['name'] = 'update_test';
|
||||
$project['project_type'] = '';
|
||||
$project['info']['version'] = '';
|
||||
$project['info']['project status url'] = 'http://www.example.com';
|
||||
$project['includes'] = array('module1' => 'Module 1', 'module2' => 'Module 2');
|
||||
$site_key = '';
|
||||
$expected = 'http://www.example.com/' . $project['name'] . '/' . \Drupal::CORE_COMPATIBILITY;
|
||||
$url = _update_build_fetch_url($project, $site_key);
|
||||
$this->assertEqual($url, $expected, "'$url' when no site_key provided should be '$expected'.");
|
||||
|
||||
//For disabled projects it shouldn't add the site key either.
|
||||
$site_key = 'site_key';
|
||||
$project['project_type'] = 'disabled';
|
||||
$expected = 'http://www.example.com/' . $project['name'] . '/' . \Drupal::CORE_COMPATIBILITY;
|
||||
$url = _update_build_fetch_url($project, $site_key);
|
||||
$this->assertEqual($url, $expected, "'$url' should be '$expected' for disabled projects.");
|
||||
|
||||
//for enabled projects, adding the site key
|
||||
$project['project_type'] = '';
|
||||
$expected = 'http://www.example.com/' . $project['name'] . '/' . \Drupal::CORE_COMPATIBILITY;
|
||||
$expected .= '?site_key=site_key';
|
||||
$expected .= '&list=' . rawurlencode('module1,module2');
|
||||
$url = _update_build_fetch_url($project, $site_key);
|
||||
$this->assertEqual($url, $expected, "When site_key provided, '$url' should be '$expected'.");
|
||||
|
||||
// http://drupal.org/node/1481156 test incorrect logic when URL contains
|
||||
// a question mark.
|
||||
$project['info']['project status url'] = 'http://www.example.com/?project=';
|
||||
$expected = 'http://www.example.com/?project=/' . $project['name'] . '/' . \Drupal::CORE_COMPATIBILITY;
|
||||
$expected .= '&site_key=site_key';
|
||||
$expected .= '&list=' . rawurlencode('module1,module2');
|
||||
$url = _update_build_fetch_url($project, $site_key);
|
||||
$this->assertEqual($url, $expected, "When ? is present, '$url' should be '$expected'.");
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\update\UpdateFetcher.
|
||||
*/
|
||||
|
||||
namespace Drupal\update;
|
||||
|
||||
use Drupal\Core\Config\ConfigFactory;
|
||||
use Guzzle\Http\ClientInterface;
|
||||
use Guzzle\Http\Exception\RequestException;
|
||||
|
||||
/**
|
||||
* Fetches project information from remote locations.
|
||||
*/
|
||||
class UpdateFetcher {
|
||||
|
||||
/**
|
||||
* URL to check for updates, if a given project doesn't define its own.
|
||||
*/
|
||||
const UPDATE_DEFAULT_URL = 'http://updates.drupal.org/release-history';
|
||||
|
||||
/**
|
||||
* The fetch url configured in the update settings.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fetchUrl;
|
||||
|
||||
/**
|
||||
* The HTTP client to fetch the feed data with.
|
||||
*
|
||||
* @var \Guzzle\Http\ClientInterface
|
||||
*/
|
||||
protected $httpClient;
|
||||
|
||||
/**
|
||||
* Constructs a UpdateFetcher.
|
||||
*
|
||||
* @param \Drupal\Core\Config\ConfigFactory $config_factory
|
||||
* The config factory.
|
||||
* @param \Guzzle\Http\ClientInterface $http_client
|
||||
* A Guzzle client object.
|
||||
*/
|
||||
public function __construct(ConfigFactory $config_factory, ClientInterface $http_client) {
|
||||
$this->fetchUrl = $config_factory->get('update.settings')->get('fetch.url');
|
||||
$this->httpClient = $http_client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the project information.
|
||||
*
|
||||
* @param array $project
|
||||
* The array of project information from update_get_projects().
|
||||
* @param string $site_key
|
||||
* (optional) The anonymous site key hash. Defaults to an empty string.
|
||||
*
|
||||
* @return string
|
||||
* The project information fetched as string. Empty string upon failure.
|
||||
*/
|
||||
public function fetchProjectData(array $project, $site_key = '') {
|
||||
$url = $this->buildFetchUrl($project, $site_key);
|
||||
$data = '';
|
||||
try {
|
||||
$data = $this->httpClient
|
||||
->get($url, array('Accept' => 'text/xml'))
|
||||
->send()
|
||||
->getBody(TRUE);
|
||||
}
|
||||
catch (RequestException $exception) {
|
||||
watchdog_exception('update', $exception);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the URL to fetch information about project updates.
|
||||
*
|
||||
* This figures out the right URL to use, based on the project's .info.yml file
|
||||
* and the global defaults. Appends optional query arguments when the site is
|
||||
* configured to report usage stats.
|
||||
*
|
||||
* @param array $project
|
||||
* The array of project information from update_get_projects().
|
||||
* @param string $site_key
|
||||
* (optional) The anonymous site key hash. Defaults to an empty string.
|
||||
*
|
||||
* @return string
|
||||
* The URL for fetching information about updates to the specified project.
|
||||
*
|
||||
* @see update_fetch_data()
|
||||
* @see _update_process_fetch_task()
|
||||
* @see update_get_projects()
|
||||
*/
|
||||
public function buildFetchUrl(array $project, $site_key = '') {
|
||||
$name = $project['name'];
|
||||
$url = $this->getFetchBaseUrl($project);
|
||||
$url .= '/' . $name . '/' . \Drupal::CORE_COMPATIBILITY;
|
||||
|
||||
// Only append usage infomation if we have a site key and the project is
|
||||
// enabled. We do not want to record usage statistics for disabled projects.
|
||||
if (!empty($site_key) && (strpos($project['project_type'], 'disabled') === FALSE)) {
|
||||
// Append the site key.
|
||||
$url .= (strpos($url, '?') !== FALSE) ? '&' : '?';
|
||||
$url .= 'site_key=';
|
||||
$url .= rawurlencode($site_key);
|
||||
|
||||
// Append the version.
|
||||
if (!empty($project['info']['version'])) {
|
||||
$url .= '&version=';
|
||||
$url .= rawurlencode($project['info']['version']);
|
||||
}
|
||||
|
||||
// Append the list of modules or themes enabled.
|
||||
$list = array_keys($project['includes']);
|
||||
$url .= '&list=';
|
||||
$url .= rawurlencode(implode(',', $list));
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base of the URL to fetch available update data for a project.
|
||||
*
|
||||
* @param array $project
|
||||
* The array of project information from update_get_projects().
|
||||
*
|
||||
* @return string
|
||||
* The base of the URL used for fetching available update data. This does
|
||||
* not include the path elements to specify a particular project, version,
|
||||
* site_key, etc.
|
||||
*
|
||||
* @see \Drupal\update\UpdateFetcher::getFetchBaseUrl()
|
||||
*/
|
||||
public function getFetchBaseUrl($project) {
|
||||
if (isset($project['info']['project status url'])) {
|
||||
$url = $project['info']['project status url'];
|
||||
}
|
||||
else {
|
||||
$url = $this->fetchUrl;
|
||||
if (empty($url)) {
|
||||
$url = static::UPDATE_DEFAULT_URL;
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\update\Tests\UpdateFetcherTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\update\Tests;
|
||||
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\update\UpdateFetcher;
|
||||
|
||||
if (!defined('DRUPAL_CORE_COMPATIBILITY')) {
|
||||
define('DRUPAL_CORE_COMPATIBILITY', '8.x');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests update functionality unrelated to the database.
|
||||
*/
|
||||
class UpdateFetcherTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The update fetcher to use.
|
||||
*
|
||||
* @var \Drupal\update\UpdateFetcher
|
||||
*/
|
||||
protected $updateFetcher;
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Core update tests',
|
||||
'description' => 'Test update functionality unrelated to the database.',
|
||||
'group' => 'Update',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$config_factory = $this->getConfigFactoryStub(array('update.settings' => array('fetch_url' => 'http://www.example.com')));
|
||||
$this->updateFetcher = new UpdateFetcher($config_factory, $this->getMock('Guzzle\Http\Client'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that buildFetchUrl() builds the URL correctly.
|
||||
*
|
||||
* @param array $project
|
||||
* A keyed array of project information matching results from update_get_projects().
|
||||
* @param string $site_key
|
||||
* A string to mimic an anonymous site key hash.
|
||||
* @param string $expected
|
||||
* The expected url returned from UpdateFetcher::buildFetchUrl()
|
||||
*
|
||||
* @dataProvider providerTestUpdateBuildFetchUrl
|
||||
*
|
||||
* @see \Drupal\update\UpdateFetcher::buildFetchUrl()
|
||||
*/
|
||||
public function testUpdateBuildFetchUrl(array $project, $site_key, $expected) {
|
||||
$url = $this->updateFetcher->buildFetchUrl($project, $site_key);
|
||||
$this->assertEquals($url, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide test data for self::testUpdateBuildFetchUrl().
|
||||
*
|
||||
* @return array
|
||||
* An array of arrays, each containing:
|
||||
* - 'project' - An array matching a project's .info file structure.
|
||||
* - 'site_key' - An arbitrary site key.
|
||||
* - 'expected' - The expected url from UpdateFetcher::buildFetchUrl().
|
||||
*/
|
||||
public function providerTestUpdateBuildFetchUrl() {
|
||||
$data = array();
|
||||
|
||||
// First test that we didn't break the trivial case.
|
||||
$project['name'] = 'update_test';
|
||||
$project['project_type'] = '';
|
||||
$project['info']['version'] = '';
|
||||
$project['info']['project status url'] = 'http://www.example.com';
|
||||
$project['includes'] = array('module1' => 'Module 1', 'module2' => 'Module 2');
|
||||
$site_key = '';
|
||||
$expected = 'http://www.example.com/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY;
|
||||
|
||||
$data[] = array($project, $site_key, $expected);
|
||||
|
||||
// For disabled projects it shouldn't add the site key either.
|
||||
$site_key = 'site_key';
|
||||
$project['project_type'] = 'disabled';
|
||||
$expected = 'http://www.example.com/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY;
|
||||
|
||||
$data[] = array($project, $site_key, $expected);
|
||||
|
||||
// For enabled projects, adding the site key
|
||||
$project['project_type'] = '';
|
||||
$expected = 'http://www.example.com/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY;
|
||||
$expected .= '?site_key=site_key';
|
||||
$expected .= '&list=' . rawurlencode('module1,module2');
|
||||
|
||||
$data[] = array($project, $site_key, $expected);
|
||||
|
||||
// http://drupal.org/node/1481156 test incorrect logic when URL contains
|
||||
// a question mark.
|
||||
$project['info']['project status url'] = 'http://www.example.com/?project=';
|
||||
$expected = 'http://www.example.com/?project=/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY;
|
||||
$expected .= '&site_key=site_key';
|
||||
$expected .= '&list=' . rawurlencode('module1,module2');
|
||||
|
||||
$data[] = array($project, $site_key, $expected);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
|
@ -5,8 +5,8 @@
|
|||
* Code required only when fetching information about available updates.
|
||||
*/
|
||||
|
||||
use Guzzle\Http\Exception\RequestException;
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\update\UpdateFetcher;
|
||||
|
||||
/**
|
||||
* Page callback: Checks for updates and displays the update status report.
|
||||
|
@ -148,21 +148,13 @@ function _update_process_fetch_task($project) {
|
|||
|
||||
$success = FALSE;
|
||||
$available = array();
|
||||
$site_key = Crypt::hmacBase64($base_url, drupal_get_private_key());
|
||||
$url = _update_build_fetch_url($project, $site_key);
|
||||
$fetch_url_base = _update_get_fetch_url_base($project);
|
||||
$site_key = Crypt::hmacBase64($base_url, \Drupal::service('private_key')->get());
|
||||
$update_fetcher = new UpdateFetcher(\Drupal::service('config.factory'), \Drupal::service('http_default_client'));
|
||||
$fetch_url_base = $update_fetcher->getFetchBaseUrl($project);
|
||||
$project_name = $project['name'];
|
||||
|
||||
if (empty($fail[$fetch_url_base]) || $fail[$fetch_url_base] < $max_fetch_attempts) {
|
||||
try {
|
||||
$data = \Drupal::httpClient()
|
||||
->get($url, array('Accept' => 'text/xml'))
|
||||
->send()
|
||||
->getBody(TRUE);
|
||||
}
|
||||
catch (RequestException $exception) {
|
||||
watchdog_exception('update', $exception);
|
||||
}
|
||||
$data = $update_fetcher->fetchProjectData($project, $site_key);
|
||||
}
|
||||
|
||||
if (!empty($data)) {
|
||||
|
@ -257,78 +249,6 @@ function _update_create_fetch_task($project) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the URL to fetch information about project updates.
|
||||
*
|
||||
* This figures out the right URL to use, based on the project's .info.yml file
|
||||
* and the global defaults. Appends optional query arguments when the site is
|
||||
* configured to report usage stats.
|
||||
*
|
||||
* @param $project
|
||||
* The array of project information from update_get_projects().
|
||||
* @param $site_key
|
||||
* (optional) The anonymous site key hash. Defaults to an empty string.
|
||||
*
|
||||
* @return
|
||||
* The URL for fetching information about updates to the specified project.
|
||||
*
|
||||
* @see update_fetch_data()
|
||||
* @see _update_process_fetch_task()
|
||||
* @see update_get_projects()
|
||||
*/
|
||||
function _update_build_fetch_url($project, $site_key = '') {
|
||||
$name = $project['name'];
|
||||
$url = _update_get_fetch_url_base($project);
|
||||
$url .= '/' . $name . '/' . \Drupal::CORE_COMPATIBILITY;
|
||||
|
||||
// Only append usage infomation if we have a site key and the project is
|
||||
// enabled. We do not want to record usage statistics for disabled projects.
|
||||
if (!empty($site_key) && (strpos($project['project_type'], 'disabled') === FALSE)) {
|
||||
// Append the site key.
|
||||
$url .= (strpos($url, '?') !== FALSE) ? '&' : '?';
|
||||
$url .= 'site_key=';
|
||||
$url .= rawurlencode($site_key);
|
||||
|
||||
// Append the version.
|
||||
if (!empty($project['info']['version'])) {
|
||||
$url .= '&version=';
|
||||
$url .= rawurlencode($project['info']['version']);
|
||||
}
|
||||
|
||||
// Append the list of modules or themes enabled.
|
||||
$list = array_keys($project['includes']);
|
||||
$url .= '&list=';
|
||||
$url .= rawurlencode(implode(',', $list));
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base of the URL to fetch available update data for a project.
|
||||
*
|
||||
* @param $project
|
||||
* The array of project information from update_get_projects().
|
||||
*
|
||||
* @return
|
||||
* The base of the URL used for fetching available update data. This does
|
||||
* not include the path elements to specify a particular project, version,
|
||||
* site_key, etc.
|
||||
*
|
||||
* @see _update_build_fetch_url()
|
||||
*/
|
||||
function _update_get_fetch_url_base($project) {
|
||||
if (isset($project['info']['project status url'])) {
|
||||
$url = $project['info']['project status url'];
|
||||
}
|
||||
else {
|
||||
$url = \Drupal::config('update.settings')->get('fetch.url');
|
||||
if (empty($url)) {
|
||||
$url = UPDATE_DEFAULT_URL;
|
||||
}
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs any notifications that should be done once cron fetches new data.
|
||||
*
|
||||
|
|
|
@ -11,11 +11,6 @@
|
|||
* ability to install contributed modules and themes via an user interface.
|
||||
*/
|
||||
|
||||
/**
|
||||
* URL to check for updates, if a given project doesn't define its own.
|
||||
*/
|
||||
const UPDATE_DEFAULT_URL = 'http://updates.drupal.org/release-history';
|
||||
|
||||
// These are internally used constants for this code, do not modify.
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue