Commit 33253047 authored by webchick's avatar webchick

Issue #2002116 by damiankloip, jhedstrom, ParisLiakos, dawehner: Convert...

Issue #2002116 by damiankloip, jhedstrom, ParisLiakos, dawehner: Convert core/modules/update/lib/Drupal/update/Tests/UpdateCoreUnitTest.php to phpunit.
parent 4d6724c1
<?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;
}
}
...@@ -2,76 +2,113 @@ ...@@ -2,76 +2,113 @@
/** /**
* @file * @file
* Definition of Drupal\update\Tests\UpdateCoreUnitTest. * Contains \Drupal\update\Tests\UpdateFetcherTest.
*/ */
namespace Drupal\update\Tests; namespace Drupal\update\Tests;
use Drupal\simpletest\UnitTestBase; 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. * Tests update functionality unrelated to the database.
*/ */
class UpdateCoreUnitTest extends UnitTestBase { class UpdateFetcherTest extends UnitTestCase {
/** /**
* Modules to enable. * The update fetcher to use.
* *
* @var array * @var \Drupal\update\UpdateFetcher
*/ */
public static $modules = array('update'); protected $updateFetcher;
public static function getInfo() { public static function getInfo() {
return array( return array(
'name' => "Unit tests", 'name' => 'Core update tests',
'description' => 'Test update functionality unrelated to the database.', 'description' => 'Test update functionality unrelated to the database.',
'group' => 'Update', 'group' => 'Update',
); );
} }
function setUp() { /**
parent::setUp(); * {@inheritdoc}
module_load_include('inc', 'update', 'update.fetch'); */
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);
} }
/** /**
* Tests that _update_build_fetch_url() builds the URL correctly. * 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().
*/ */
function testUpdateBuildFetchUrl() { public function providerTestUpdateBuildFetchUrl() {
//first test that we didn't break the trivial case $data = array();
// First test that we didn't break the trivial case.
$project['name'] = 'update_test'; $project['name'] = 'update_test';
$project['project_type'] = ''; $project['project_type'] = '';
$project['info']['version'] = ''; $project['info']['version'] = '';
$project['info']['project status url'] = 'http://www.example.com'; $project['info']['project status url'] = 'http://www.example.com';
$project['includes'] = array('module1' => 'Module 1', 'module2' => 'Module 2'); $project['includes'] = array('module1' => 'Module 1', 'module2' => 'Module 2');
$site_key = ''; $site_key = '';
$expected = 'http://www.example.com/' . $project['name'] . '/' . \Drupal::CORE_COMPATIBILITY; $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'."); $data[] = array($project, $site_key, $expected);
//For disabled projects it shouldn't add the site key either. // For disabled projects it shouldn't add the site key either.
$site_key = 'site_key'; $site_key = 'site_key';
$project['project_type'] = 'disabled'; $project['project_type'] = 'disabled';
$expected = 'http://www.example.com/' . $project['name'] . '/' . \Drupal::CORE_COMPATIBILITY; $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 $data[] = array($project, $site_key, $expected);
// For enabled projects, adding the site key
$project['project_type'] = ''; $project['project_type'] = '';
$expected = 'http://www.example.com/' . $project['name'] . '/' . \Drupal::CORE_COMPATIBILITY; $expected = 'http://www.example.com/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY;
$expected .= '?site_key=site_key'; $expected .= '?site_key=site_key';
$expected .= '&list=' . rawurlencode('module1,module2'); $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'."); $data[] = array($project, $site_key, $expected);
// http://drupal.org/node/1481156 test incorrect logic when URL contains // http://drupal.org/node/1481156 test incorrect logic when URL contains
// a question mark. // a question mark.
$project['info']['project status url'] = 'http://www.example.com/?project='; $project['info']['project status url'] = 'http://www.example.com/?project=';
$expected = 'http://www.example.com/?project=/' . $project['name'] . '/' . \Drupal::CORE_COMPATIBILITY; $expected = 'http://www.example.com/?project=/' . $project['name'] . '/' . DRUPAL_CORE_COMPATIBILITY;
$expected .= '&site_key=site_key'; $expected .= '&site_key=site_key';
$expected .= '&list=' . rawurlencode('module1,module2'); $expected .= '&list=' . rawurlencode('module1,module2');
$url = _update_build_fetch_url($project, $site_key);
$this->assertEqual($url, $expected, "When ? is present, '$url' should be '$expected'.");
$data[] = array($project, $site_key, $expected);
return $data;
} }
} }
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
* Code required only when fetching information about available updates. * Code required only when fetching information about available updates.
*/ */
use Guzzle\Http\Exception\RequestException;
use Drupal\Component\Utility\Crypt; use Drupal\Component\Utility\Crypt;
use Drupal\update\UpdateFetcher;
/** /**
* Page callback: Checks for updates and displays the update status report. * Page callback: Checks for updates and displays the update status report.
...@@ -148,21 +148,13 @@ function _update_process_fetch_task($project) { ...@@ -148,21 +148,13 @@ function _update_process_fetch_task($project) {
$success = FALSE; $success = FALSE;
$available = array(); $available = array();
$site_key = Crypt::hmacBase64($base_url, drupal_get_private_key()); $site_key = Crypt::hmacBase64($base_url, \Drupal::service('private_key')->get());
$url = _update_build_fetch_url($project, $site_key); $update_fetcher = new UpdateFetcher(\Drupal::service('config.factory'), \Drupal::service('http_default_client'));
$fetch_url_base = _update_get_fetch_url_base($project); $fetch_url_base = $update_fetcher->getFetchBaseUrl($project);
$project_name = $project['name']; $project_name = $project['name'];
if (empty($fail[$fetch_url_base]) || $fail[$fetch_url_base] < $max_fetch_attempts) { if (empty($fail[$fetch_url_base]) || $fail[$fetch_url_base] < $max_fetch_attempts) {
try { $data = $update_fetcher->fetchProjectData($project, $site_key);
$data = \Drupal::httpClient()
->get($url, array('Accept' => 'text/xml'))
->send()
->getBody(TRUE);
}
catch (RequestException $exception) {
watchdog_exception('update', $exception);
}
} }
if (!empty($data)) { if (!empty($data)) {
...@@ -257,78 +249,6 @@ function _update_create_fetch_task($project) { ...@@ -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. * Performs any notifications that should be done once cron fetches new data.
* *
......
...@@ -11,11 +11,6 @@ ...@@ -11,11 +11,6 @@
* ability to install contributed modules and themes via an user interface. * 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. // These are internally used constants for this code, do not modify.
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment