UpdateCoreTest.php 14.5 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Contains \Drupal\update\Tests\UpdateCoreTest.
6 7 8 9
 */

namespace Drupal\update\Tests;

10 11
use Drupal\Core\Url;

12
/**
13 14 15 16
 * Tests the Update Manager module through a series of functional tests using
 * mock XML data.
 *
 * @group update
17
 */
18 19
class UpdateCoreTest extends UpdateTestBase {

20 21 22 23 24
  /**
   * Modules to enable.
   *
   * @var array
   */
25
  public static $modules = ['update_test', 'update', 'language', 'block'];
26

27
  protected function setUp() {
28
    parent::setUp();
29
    $admin_user = $this->drupalCreateUser(array('administer site configuration', 'administer modules', 'administer themes'));
30
    $this->drupalLogin($admin_user);
31
    $this->drupalPlaceBlock('local_actions_block');
32 33
  }

34 35 36 37 38 39 40 41 42 43 44 45
  /**
   * Sets the version to x.x.x when no project-specific mapping is defined.
   *
   * @param string $version
   *   The version.
   */
  protected function setSystemInfo($version) {
    $setting = array(
      '#all' => array(
        'version' => $version,
      ),
    );
46
    $this->config('update_test.settings')->set('system_info', $setting)->save();
47
  }
48

49
  /**
50
   * Tests the Update Manager module when no updates are available.
51 52
   */
  function testNoUpdatesAvailable() {
53 54 55 56 57 58 59 60 61
    foreach (array(0, 1) as $minor_version) {
      foreach (array(0, 1) as $patch_version) {
        foreach (array('-alpha1', '-beta1', '') as $extra_version) {
          $this->setSystemInfo("8.$minor_version.$patch_version" . $extra_version);
          $this->refreshUpdateStatus(array('drupal' => "$minor_version.$patch_version" . $extra_version));
          $this->standardTests();
          $this->assertText(t('Up to date'));
          $this->assertNoText(t('Update available'));
          $this->assertNoText(t('Security update required!'));
62
          $this->assertRaw('check.svg', 'Check icon was found.');
63 64 65
        }
      }
    }
66 67 68
  }

  /**
69
   * Tests the Update Manager module when one normal update is available.
70 71
   */
  function testNormalUpdateAvailable() {
72 73 74 75 76 77 78
    $this->setSystemInfo('8.0.0');
    foreach (array(0, 1) as $minor_version) {
      foreach (array('-alpha1', '-beta1', '') as $extra_version) {
        $this->refreshUpdateStatus(array('drupal' => "$minor_version.1" . $extra_version));
        $this->standardTests();
        $this->drupalGet('admin/reports/updates/check');
        $this->assertNoText(t('Security update required!'));
79 80 81
        $this->assertRaw(\Drupal::l("8.$minor_version.1" . $extra_version, Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to release appears.');
        $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version.tar.gz")), 'Link to download appears.');
        $this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to release notes appears.');
82 83 84 85 86 87 88 89 90 91

        switch ($minor_version) {
          case 0:
            // Both stable and unstable releases are available.
            // A stable release is the latest.
            if ($extra_version == '') {
              $this->assertNoText(t('Up to date'));
              $this->assertText(t('Update available'));
              $this->assertText(t('Recommended version:'));
              $this->assertNoText(t('Latest version:'));
92
              $this->assertRaw('warning.svg', 'Warning icon was found.');
93 94 95 96 97 98 99 100
            }
            // Only unstable releases are available.
            // An unstable release is the latest.
            else {
              $this->assertText(t('Up to date'));
              $this->assertNoText(t('Update available'));
              $this->assertNoText(t('Recommended version:'));
              $this->assertText(t('Latest version:'));
101
              $this->assertRaw('check.svg', 'Check icon was found.');
102 103 104 105 106 107 108 109 110 111
            }
            break;
          case 1:
            // Both stable and unstable releases are available.
            // A stable release is the latest.
            if ($extra_version == '') {
              $this->assertNoText(t('Up to date'));
              $this->assertText(t('Update available'));
              $this->assertText(t('Recommended version:'));
              $this->assertNoText(t('Latest version:'));
112
              $this->assertRaw('warning.svg', 'Warning icon was found.');
113 114 115 116 117 118 119 120
            }
            // Both stable and unstable releases are available.
            // An unstable release is the latest.
            else {
              $this->assertNoText(t('Up to date'));
              $this->assertText(t('Update available'));
              $this->assertText(t('Recommended version:'));
              $this->assertText(t('Latest version:'));
121
              $this->assertRaw('warning.svg', 'Warning icon was found.');
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
            }
            break;
        }
      }
    }
  }

  /**
   * Tests the Update Manager module when a major update is available.
   */
  function testMajorUpdateAvailable() {
    foreach (array(0, 1) as $minor_version) {
      foreach (array(0, 1) as $patch_version) {
        foreach (array('-alpha1', '-beta1', '') as $extra_version) {
          $this->setSystemInfo("8.$minor_version.$patch_version" . $extra_version);
          $this->refreshUpdateStatus(array('drupal' => '9'));
          $this->standardTests();
          $this->drupalGet('admin/reports/updates/check');
          $this->assertNoText(t('Security update required!'));
141 142 143
          $this->assertRaw(\Drupal::l('9.0.0', Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to release appears.');
          $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-9-0-0.tar.gz")), 'Link to download appears.');
          $this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to release notes appears.');
144 145 146 147
          $this->assertNoText(t('Up to date'));
          $this->assertText(t('Not supported!'));
          $this->assertText(t('Recommended version:'));
          $this->assertNoText(t('Latest version:'));
148
          $this->assertRaw('error.svg', 'Error icon was found.');
149 150 151
        }
      }
    }
152 153 154
  }

  /**
155
   * Tests the Update Manager module when a security update is available.
156 157
   */
  function testSecurityUpdateAvailable() {
158 159 160 161 162 163 164
    foreach (array(0, 1) as $minor_version) {
      $this->setSystemInfo("8.$minor_version.0");
      $this->refreshUpdateStatus(array('drupal' => "$minor_version.2-sec"));
      $this->standardTests();
      $this->assertNoText(t('Up to date'));
      $this->assertNoText(t('Update available'));
      $this->assertText(t('Security update required!'));
165 166 167
      $this->assertRaw(\Drupal::l("8.$minor_version.2", Url::fromUri("http://example.com/drupal-8-$minor_version-2-release")), 'Link to release appears.');
      $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-2.tar.gz")), 'Link to download appears.');
      $this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-8-$minor_version-2-release")), 'Link to release notes appears.');
168
      $this->assertRaw('error.svg', 'Error icon was found.');
169
    }
170 171 172
  }

  /**
173
   * Ensures proper results where there are date mismatches among modules.
174 175 176 177 178
   */
  function testDatestampMismatch() {
    $system_info = array(
      '#all' => array(
        // We need to think we're running a -dev snapshot to see dates.
179
        'version' => '8.1.0-dev',
180 181 182 183 184 185 186
        'datestamp' => time(),
      ),
      'block' => array(
        // This is 2001-09-09 01:46:40 GMT, so test for "2001-Sep-".
        'datestamp' => '1000000000',
      ),
    );
187
    $this->config('update_test.settings')->set('system_info', $system_info)->save();
188 189 190 191 192 193 194 195
    $this->refreshUpdateStatus(array('drupal' => 'dev'));
    $this->assertNoText(t('2001-Sep-'));
    $this->assertText(t('Up to date'));
    $this->assertNoText(t('Update available'));
    $this->assertNoText(t('Security update required!'));
  }

  /**
196
   * Checks that running cron updates the list of available updates.
197 198
   */
  function testModulePageRunCron() {
199
    $this->setSystemInfo('8.0.0');
200
    $this->config('update.settings')
201
      ->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
202
      ->save();
203
    $this->config('update_test.settings')
204 205
      ->set('xml_map', array('drupal' => '0.0'))
      ->save();
206 207 208 209 210 211 212

    $this->cronRun();
    $this->drupalGet('admin/modules');
    $this->assertNoText(t('No update information available.'));
  }

  /**
213
   * Checks the messages at admin/modules when the site is up to date.
214 215
   */
  function testModulePageUpToDate() {
216
    $this->setSystemInfo('8.0.0');
217
    // Instead of using refreshUpdateStatus(), set these manually.
218
    $this->config('update.settings')
219
      ->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
220
      ->save();
221
    $this->config('update_test.settings')
222 223
      ->set('xml_map', array('drupal' => '0.0'))
      ->save();
224 225 226 227 228 229 230 231 232 233

    $this->drupalGet('admin/reports/updates');
    $this->clickLink(t('Check manually'));
    $this->assertText(t('Checked available update data for one project.'));
    $this->drupalGet('admin/modules');
    $this->assertNoText(t('There are updates available for your version of Drupal.'));
    $this->assertNoText(t('There is a security update available for your version of Drupal.'));
  }

  /**
234
   * Checks the messages at admin/modules when an update is missing.
235 236
   */
  function testModulePageRegularUpdate() {
237
    $this->setSystemInfo('8.0.0');
238
    // Instead of using refreshUpdateStatus(), set these manually.
239
    $this->config('update.settings')
240
      ->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
241
      ->save();
242
    $this->config('update_test.settings')
243 244
      ->set('xml_map', array('drupal' => '0.1'))
      ->save();
245 246 247 248 249 250 251 252 253 254

    $this->drupalGet('admin/reports/updates');
    $this->clickLink(t('Check manually'));
    $this->assertText(t('Checked available update data for one project.'));
    $this->drupalGet('admin/modules');
    $this->assertText(t('There are updates available for your version of Drupal.'));
    $this->assertNoText(t('There is a security update available for your version of Drupal.'));
  }

  /**
255
   * Checks the messages at admin/modules when a security update is missing.
256 257
   */
  function testModulePageSecurityUpdate() {
258
    $this->setSystemInfo('8.0.0');
259
    // Instead of using refreshUpdateStatus(), set these manually.
260
    $this->config('update.settings')
261
      ->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
262
      ->save();
263
    $this->config('update_test.settings')
264 265
      ->set('xml_map', array('drupal' => '0.2-sec'))
      ->save();
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293

    $this->drupalGet('admin/reports/updates');
    $this->clickLink(t('Check manually'));
    $this->assertText(t('Checked available update data for one project.'));
    $this->drupalGet('admin/modules');
    $this->assertNoText(t('There are updates available for your version of Drupal.'));
    $this->assertText(t('There is a security update available for your version of Drupal.'));

    // Make sure admin/appearance warns you you're missing a security update.
    $this->drupalGet('admin/appearance');
    $this->assertNoText(t('There are updates available for your version of Drupal.'));
    $this->assertText(t('There is a security update available for your version of Drupal.'));

    // Make sure duplicate messages don't appear on Update status pages.
    $this->drupalGet('admin/reports/status');
    // We're expecting "There is a security update..." inside the status report
    // itself, but the drupal_set_message() appears as an li so we can prefix
    // with that and search for the raw HTML.
    $this->assertNoRaw('<li>' . t('There is a security update available for your version of Drupal.'));

    $this->drupalGet('admin/reports/updates');
    $this->assertNoText(t('There is a security update available for your version of Drupal.'));

    $this->drupalGet('admin/reports/updates/settings');
    $this->assertNoText(t('There is a security update available for your version of Drupal.'));
  }

  /**
294
   * Tests the Update Manager module when the update server returns 503 errors.
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
   */
  function testServiceUnavailable() {
    $this->refreshUpdateStatus(array(), '503-error');
    // Ensure that no "Warning: SimpleXMLElement..." parse errors are found.
    $this->assertNoText('SimpleXMLElement');
    $this->assertUniqueText(t('Failed to get available update data for one project.'));
  }

  /**
   * Tests that exactly one fetch task per project is created and not more.
   */
  function testFetchTasks() {
    $projecta = array(
      'name' => 'aaa_update_test',
    );
    $projectb = array(
      'name' => 'bbb_update_test',
    );
313
    $queue = \Drupal::queue('update_fetch_tasks');
314 315 316 317 318 319 320 321 322
    $this->assertEqual($queue->numberOfItems(), 0, 'Queue is empty');
    update_create_fetch_task($projecta);
    $this->assertEqual($queue->numberOfItems(), 1, 'Queue contains one item');
    update_create_fetch_task($projectb);
    $this->assertEqual($queue->numberOfItems(), 2, 'Queue contains two items');
    // Try to add project a again.
    update_create_fetch_task($projecta);
    $this->assertEqual($queue->numberOfItems(), 2, 'Queue still contains two items');

323 324
    // Clear storage and try again.
    update_storage_clear();
325 326 327 328
    update_create_fetch_task($projecta);
    $this->assertEqual($queue->numberOfItems(), 2, 'Queue contains two items');
  }

329 330 331 332
  /**
   * Checks language module in core package at admin/reports/updates.
   */
  function testLanguageModuleUpdate() {
333
    $this->setSystemInfo('8.0.0');
334
    // Instead of using refreshUpdateStatus(), set these manually.
335
    $this->config('update.settings')
336
      ->set('fetch.url', Url::fromRoute('update_test.update_test')->setAbsolute()->toString())
337
      ->save();
338
    $this->config('update_test.settings')
339 340
      ->set('xml_map', array('drupal' => '0.1'))
      ->save();
341 342 343 344 345

    $this->drupalGet('admin/reports/updates');
    $this->assertText(t('Language'));
  }

346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
  /**
   * Ensures that the local actions appear.
   */
  public function testLocalActions() {
    $admin_user = $this->drupalCreateUser(array('administer site configuration', 'administer modules', 'administer software updates', 'administer themes'));
    $this->drupalLogin($admin_user);

    $this->drupalGet('admin/modules');
    $this->clickLink(t('Install new module'));
    $this->assertUrl('admin/modules/install');

    $this->drupalGet('admin/appearance');
    $this->clickLink(t('Install new theme'));
    $this->assertUrl('admin/theme/install');

    $this->drupalGet('admin/reports/updates');
    $this->clickLink(t('Install new module or theme'));
    $this->assertUrl('admin/reports/updates/install');
  }

366
}