Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Napoli <matthieu@mnapoli.fr>2015-03-13 06:04:35 +0300
committerMatthieu Napoli <matthieu@mnapoli.fr>2015-03-16 00:37:32 +0300
commit3f2d8e0bdcd62887dfa800c5391954f26bb98871 (patch)
treedd9c46a5ee6d6b0cdbf2ba54956743c15a373652 /plugins
parent36214a73090b91cb322329fe39d2e1a718229c58 (diff)
Refactor Piwik update with a Updater class + UI tests
Diffstat (limited to 'plugins')
-rw-r--r--plugins/CoreUpdater/Controller.php205
-rw-r--r--plugins/CoreUpdater/Updater.php266
-rw-r--r--plugins/CoreUpdater/UpdaterException.php31
-rw-r--r--plugins/CoreUpdater/config/config.php6
-rw-r--r--plugins/CoreUpdater/tests/Fixtures/FailUpdateHttpsFixture.php24
-rw-r--r--plugins/CoreUpdater/tests/Mock/UpdaterMock.php52
-rw-r--r--plugins/CoreUpdater/tests/UI/PiwikUpdater_spec.js22
-rw-r--r--plugins/CoreUpdater/tests/UI/expected-ui-screenshots/PiwikUpdater_newVersion.pngbin0 -> 27898 bytes
8 files changed, 420 insertions, 186 deletions
diff --git a/plugins/CoreUpdater/Controller.php b/plugins/CoreUpdater/Controller.php
index c8f3e927b5..be860af8bd 100644
--- a/plugins/CoreUpdater/Controller.php
+++ b/plugins/CoreUpdater/Controller.php
@@ -9,10 +9,8 @@
namespace Piwik\Plugins\CoreUpdater;
use Exception;
-use Piwik\ArchiveProcessor\Rules;
use Piwik\Common;
use Piwik\Config;
-use Piwik\Container\StaticContainer;
use Piwik\DbHelper;
use Piwik\Filechecks;
use Piwik\Filesystem;
@@ -24,51 +22,34 @@ use Piwik\Plugin;
use Piwik\Plugins\CorePluginsAdmin\Marketplace;
use Piwik\Plugins\LanguagesManager\LanguagesManager;
use Piwik\SettingsServer;
-use Piwik\Unzip;
-use Piwik\UpdateCheck;
-use Piwik\Updater;
+use Piwik\Updater as DbUpdater;
use Piwik\Version;
use Piwik\View\OneClickDone;
use Piwik\View;
-/**
- *
- */
class Controller extends \Piwik\Plugin\Controller
{
- const PATH_TO_EXTRACT_LATEST_VERSION = '/latest/';
- const LATEST_VERSION_URL = '://builds.piwik.org/piwik.zip';
- const LATEST_BETA_VERSION_URL = '://builds.piwik.org/piwik-%s.zip';
-
private $coreError = false;
private $warningMessages = array();
private $errorMessages = array();
private $deactivatedPlugins = array();
- private $pathPiwikZip = false;
- private $newVersion;
-
- protected static function getLatestZipUrl($newVersion)
- {
- if (@Config::getInstance()->Debug['allow_upgrades_to_beta']) {
- $url = sprintf(self::LATEST_BETA_VERSION_URL, $newVersion);
- } else {
- $url = self::LATEST_VERSION_URL;
- }
- if (self::isUpdatingOverHttps()) {
- $url = 'https' . $url;
- } else {
- $url = 'http' . $url;
- }
+ /**
+ * @var Updater
+ */
+ private $updater;
- return $url;
+ public function __construct(Updater $updater)
+ {
+ $this->updater = $updater;
}
public function newVersionAvailable()
{
Piwik::checkUserHasSuperUserAccess();
+ $this->checkNewVersionIsAvailableOrDie();
- $newVersion = $this->checkNewVersionIsAvailableOrDie();
+ $newVersion = $this->updater->getLatestVersion();
$view = new View('@CoreUpdater/newVersionAvailable');
$this->addCustomLogoInfo($view);
@@ -88,7 +69,7 @@ class Controller extends \Piwik\Plugin\Controller
$view->marketplacePlugins = $marketplacePlugins;
$view->incompatiblePlugins = $incompatiblePlugins;
- $view->piwik_latest_version_url = self::getLatestZipUrl($newVersion);
+ $view->piwik_latest_version_url = $this->updater->getArchiveUrl($newVersion);
$view->can_auto_update = Filechecks::canAutoUpdate();
$view->makeWritableCommands = Filechecks::getAutoUpdateMakeWritableMessage();
@@ -98,40 +79,13 @@ class Controller extends \Piwik\Plugin\Controller
public function oneClickUpdate()
{
Piwik::checkUserHasSuperUserAccess();
- $this->newVersion = $this->checkNewVersionIsAvailableOrDie();
-
- SettingsServer::setMaxExecutionTime(0);
-
- $url = self::getLatestZipUrl($this->newVersion);
- $steps = array(
- array('oneClick_Download', Piwik::translate('CoreUpdater_DownloadingUpdateFromX', $url)),
- array('oneClick_Unpack', Piwik::translate('CoreUpdater_UnpackingTheUpdate')),
- array('oneClick_Verify', Piwik::translate('CoreUpdater_VerifyingUnpackedFiles')),
- );
- $incompatiblePlugins = $this->getIncompatiblePlugins($this->newVersion);
- if (!empty($incompatiblePlugins)) {
- $namesToDisable = array();
- foreach ($incompatiblePlugins as $incompatiblePlugin) {
- $namesToDisable[] = $incompatiblePlugin->getPluginName();
- }
- $steps[] = array('oneClick_DisableIncompatiblePlugins', Piwik::translate('CoreUpdater_DisablingIncompatiblePlugins', implode(', ', $namesToDisable)));
- }
- $steps[] = array('oneClick_Copy', Piwik::translate('CoreUpdater_InstallingTheLatestVersion'));
- $steps[] = array('oneClick_Finished', Piwik::translate('CoreUpdater_PiwikUpdatedSuccessfully'));
-
- $errorMessage = false;
- $messages = array();
- foreach ($steps as $step) {
- try {
- $method = $step[0];
- $message = $step[1];
- $this->$method();
- $messages[] = $message;
- } catch (Exception $e) {
- $errorMessage = $e->getMessage();
- break;
- }
+ try {
+ $messages = $this->updater->updatePiwik();
+ $errorMessage = false;
+ } catch (UpdaterException $e) {
+ $errorMessage = $e->getMessage();
+ $messages = $e->getUpdateLogMessages();
}
$view = new OneClickDone(Piwik::getCurrentUserTokenAuth());
@@ -166,130 +120,9 @@ class Controller extends \Piwik\Plugin\Controller
private function checkNewVersionIsAvailableOrDie()
{
- $newVersion = UpdateCheck::isNewestVersionAvailable();
- if (!$newVersion) {
+ if (!$this->updater->isNewVersionAvailable()) {
throw new Exception(Piwik::translate('CoreUpdater_ExceptionAlreadyLatestVersion', Version::VERSION));
}
- return $newVersion;
- }
-
- private function oneClick_Download()
- {
- $path = StaticContainer::get('path.tmp') . self::PATH_TO_EXTRACT_LATEST_VERSION;
- $this->pathPiwikZip = $path . 'latest.zip';
-
- Filechecks::dieIfDirectoriesNotWritable(array($path));
-
- // we catch exceptions in the caller (i.e., oneClickUpdate)
- $url = self::getLatestZipUrl($this->newVersion) . '?cb=' . $this->newVersion;
-
- Http::fetchRemoteFile($url, $this->pathPiwikZip, 0, 120);
- }
-
- private function oneClick_Unpack()
- {
- $pathExtracted = StaticContainer::get('path.tmp') . self::PATH_TO_EXTRACT_LATEST_VERSION;
-
- $this->pathRootExtractedPiwik = $pathExtracted . 'piwik';
-
- if (file_exists($this->pathRootExtractedPiwik)) {
- Filesystem::unlinkRecursive($this->pathRootExtractedPiwik, true);
- }
-
- $archive = Unzip::factory('PclZip', $this->pathPiwikZip);
-
- if (0 == ($archive_files = $archive->extract($pathExtracted))) {
- throw new Exception(Piwik::translate('CoreUpdater_ExceptionArchiveIncompatible', $archive->errorInfo()));
- }
-
- if (0 == count($archive_files)) {
- throw new Exception(Piwik::translate('CoreUpdater_ExceptionArchiveEmpty'));
- }
- unlink($this->pathPiwikZip);
- }
-
- private function oneClick_Verify()
- {
- $someExpectedFiles = array(
- '/config/global.ini.php',
- '/index.php',
- '/core/Piwik.php',
- '/piwik.php',
- '/plugins/API/API.php'
- );
- foreach ($someExpectedFiles as $file) {
- if (!is_file($this->pathRootExtractedPiwik . $file)) {
- throw new Exception(Piwik::translate('CoreUpdater_ExceptionArchiveIncomplete', $file));
- }
- }
- }
-
- private function oneClick_DisableIncompatiblePlugins()
- {
- $plugins = $this->getIncompatiblePlugins($this->newVersion);
-
- foreach ($plugins as $plugin) {
- PluginManager::getInstance()->deactivatePlugin($plugin->getPluginName());
- }
- }
-
- private function oneClick_Copy()
- {
- /*
- * Make sure the execute bit is set for this shell script
- */
- if (!Rules::isBrowserTriggerEnabled()) {
- @chmod($this->pathRootExtractedPiwik . '/misc/cron/archive.sh', 0755);
- }
-
- $model = new Model();
-
- /*
- * Copy all files to PIWIK_INCLUDE_PATH.
- * These files are accessed through the dispatcher.
- */
- Filesystem::copyRecursive($this->pathRootExtractedPiwik, PIWIK_INCLUDE_PATH);
- $model->removeGoneFiles($this->pathRootExtractedPiwik, PIWIK_INCLUDE_PATH);
-
- /*
- * These files are visible in the web root and are generally
- * served directly by the web server. May be shared.
- */
- if (PIWIK_INCLUDE_PATH !== PIWIK_DOCUMENT_ROOT) {
- /*
- * Copy PHP files that expect to be in the document root
- */
- $specialCases = array(
- '/index.php',
- '/piwik.php',
- '/js/index.php',
- );
-
- foreach ($specialCases as $file) {
- Filesystem::copy($this->pathRootExtractedPiwik . $file, PIWIK_DOCUMENT_ROOT . $file);
- }
-
- /*
- * Copy the non-PHP files (e.g., images, css, javascript)
- */
- Filesystem::copyRecursive($this->pathRootExtractedPiwik, PIWIK_DOCUMENT_ROOT, true);
- $model->removeGoneFiles($this->pathRootExtractedPiwik, PIWIK_DOCUMENT_ROOT);
- }
-
- /*
- * Config files may be user (account) specific
- */
- if (PIWIK_INCLUDE_PATH !== PIWIK_USER_PATH) {
- Filesystem::copyRecursive($this->pathRootExtractedPiwik . '/config', PIWIK_USER_PATH . '/config');
- }
-
- Filesystem::unlinkRecursive($this->pathRootExtractedPiwik, true);
-
- Filesystem::clearPhpCaches();
- }
-
- private function oneClick_Finished()
- {
}
public function index()
@@ -308,7 +141,7 @@ class Controller extends \Piwik\Plugin\Controller
public function runUpdaterAndExit($doDryRun = null)
{
- $updater = new Updater();
+ $updater = new DbUpdater();
$componentsWithUpdateFile = CoreUpdater::getComponentUpdates($updater);
if (empty($componentsWithUpdateFile)) {
throw new NoUpdatesFoundException("Everything is already up to date.");
diff --git a/plugins/CoreUpdater/Updater.php b/plugins/CoreUpdater/Updater.php
new file mode 100644
index 0000000000..18ed1e6e09
--- /dev/null
+++ b/plugins/CoreUpdater/Updater.php
@@ -0,0 +1,266 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+namespace Piwik\Plugins\CoreUpdater;
+
+use Exception;
+use Piwik\ArchiveProcessor\Rules;
+use Piwik\Config;
+use Piwik\Filechecks;
+use Piwik\Filesystem;
+use Piwik\Http;
+use Piwik\Option;
+use Piwik\Plugin\Manager as PluginManager;
+use Piwik\SettingsServer;
+use Piwik\Translation\Translator;
+use Piwik\Unzip;
+use Piwik\Version;
+
+class Updater
+{
+ const OPTION_LATEST_VERSION = 'UpdateCheck_LatestVersion';
+ const PATH_TO_EXTRACT_LATEST_VERSION = '/latest/';
+
+ const LATEST_VERSION_URL = '://builds.piwik.org/piwik.zip';
+ const LATEST_BETA_VERSION_URL = '://builds.piwik.org/piwik-%s.zip';
+
+ /**
+ * @var Translator
+ */
+ private $translator;
+
+ /**
+ * @var string
+ */
+ private $tmpPath;
+
+ public function __construct(Translator $translator, $tmpPath)
+ {
+ $this->translator = $translator;
+ $this->tmpPath = $tmpPath;
+ }
+
+ /**
+ * Returns the latest available version number. Does not perform a check whether a later version is available.
+ *
+ * @return false|string
+ */
+ public function getLatestVersion()
+ {
+ return Option::get(self::OPTION_LATEST_VERSION);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isNewVersionAvailable()
+ {
+ $latestVersion = self::getLatestVersion();
+ return $latestVersion && version_compare(Version::VERSION, $latestVersion) === -1;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isUpdatingOverHttps()
+ {
+ $openSslEnabled = extension_loaded('openssl');
+ $usingMethodSupportingHttps = (Http::getTransportMethod() !== 'socket');
+
+ return $openSslEnabled && $usingMethodSupportingHttps;
+ }
+
+ /**
+ * Update Piwik codebase by downloading and installing the latest version.
+ *
+ * @param bool $https Whether to use HTTPS if supported of not. If false, will use HTTP.
+ * @return string[] Return an array of messages for the user.
+ * @throws Exception
+ * @throws UpdaterException
+ */
+ public function updatePiwik($https = true)
+ {
+ if (!$this->isNewVersionAvailable()) {
+ throw new Exception($this->translator->translate('CoreUpdater_ExceptionAlreadyLatestVersion', Version::VERSION));
+ }
+
+ SettingsServer::setMaxExecutionTime(0);
+
+ $newVersion = $this->getLatestVersion();
+ $url = $this->getArchiveUrl($newVersion, $https);
+ $messages = array();
+
+ try {
+ $archiveFile = $this->downloadArchive($newVersion, $url);
+ $messages[] = $this->translator->translate('CoreUpdater_DownloadingUpdateFromX', $url);
+
+ $extractedArchiveDirectory = $this->decompressArchive($archiveFile);
+ $messages[] = $this->translator->translate('CoreUpdater_UnpackingTheUpdate');
+
+ $this->verifyDecompressedArchive($extractedArchiveDirectory);
+ $messages[] = $this->translator->translate('CoreUpdater_VerifyingUnpackedFiles');
+
+ $disabledPluginNames = $this->disableIncompatiblePlugins($newVersion);
+ if (!empty($disabledPluginNames)) {
+ $messages[] = $this->translator->translate('CoreUpdater_DisablingIncompatiblePlugins', implode(', ', $disabledPluginNames));
+ }
+
+ $this->installNewFiles($extractedArchiveDirectory);
+ $messages[] = $this->translator->translate('CoreUpdater_InstallingTheLatestVersion');
+ } catch (Exception $e) {
+ throw new UpdaterException($e, $messages);
+ }
+
+ return $messages;
+ }
+
+ private function downloadArchive($version, $url)
+ {
+ $path = $this->tmpPath . self::PATH_TO_EXTRACT_LATEST_VERSION;
+ $archiveFile = $path . 'latest.zip';
+
+ Filechecks::dieIfDirectoriesNotWritable(array($path));
+
+ $url .= '?cb=' . $version;
+
+ Http::fetchRemoteFile($url, $archiveFile, 0, 120);
+
+ return $archiveFile;
+ }
+
+ private function decompressArchive($archiveFile)
+ {
+ $extractionPath = $this->tmpPath . self::PATH_TO_EXTRACT_LATEST_VERSION;
+
+ $extractedArchiveDirectory = $extractionPath . 'piwik';
+
+ // Remove previous decompressed archive
+ if (file_exists($extractedArchiveDirectory)) {
+ Filesystem::unlinkRecursive($extractedArchiveDirectory, true);
+ }
+
+ $archive = Unzip::factory('PclZip', $archiveFile);
+ $archiveFiles = $archive->extract($extractionPath);
+
+ if (0 == $archiveFiles) {
+ throw new Exception($this->translator->translate('CoreUpdater_ExceptionArchiveIncompatible', $archive->errorInfo()));
+ }
+
+ if (0 == count($archiveFiles)) {
+ throw new Exception($this->translator->translate('CoreUpdater_ExceptionArchiveEmpty'));
+ }
+
+ unlink($archiveFile);
+
+ return $extractedArchiveDirectory;
+ }
+
+ private function verifyDecompressedArchive($extractedArchiveDirectory)
+ {
+ $someExpectedFiles = array(
+ '/config/global.ini.php',
+ '/index.php',
+ '/core/Piwik.php',
+ '/piwik.php',
+ '/plugins/API/API.php'
+ );
+ foreach ($someExpectedFiles as $file) {
+ if (!is_file($extractedArchiveDirectory . $file)) {
+ throw new Exception($this->translator->translate('CoreUpdater_ExceptionArchiveIncomplete', $file));
+ }
+ }
+ }
+
+ private function disableIncompatiblePlugins($version)
+ {
+ $incompatiblePlugins = $this->getIncompatiblePlugins($version);
+ $disabledPluginNames = array();
+
+ foreach ($incompatiblePlugins as $plugin) {
+ $name = $plugin->getPluginName();
+ PluginManager::getInstance()->deactivatePlugin($name);
+ $disabledPluginNames[] = $name;
+ }
+
+ return $disabledPluginNames;
+ }
+
+ private function installNewFiles($extractedArchiveDirectory)
+ {
+ // Make sure the execute bit is set for this shell script
+ if (!Rules::isBrowserTriggerEnabled()) {
+ @chmod($extractedArchiveDirectory . '/misc/cron/archive.sh', 0755);
+ }
+
+ $model = new Model();
+
+ /*
+ * Copy all files to PIWIK_INCLUDE_PATH.
+ * These files are accessed through the dispatcher.
+ */
+ Filesystem::copyRecursive($extractedArchiveDirectory, PIWIK_INCLUDE_PATH);
+ $model->removeGoneFiles($extractedArchiveDirectory, PIWIK_INCLUDE_PATH);
+
+ /*
+ * These files are visible in the web root and are generally
+ * served directly by the web server. May be shared.
+ */
+ if (PIWIK_INCLUDE_PATH !== PIWIK_DOCUMENT_ROOT) {
+ // Copy PHP files that expect to be in the document root
+ $specialCases = array(
+ '/index.php',
+ '/piwik.php',
+ '/js/index.php',
+ );
+
+ foreach ($specialCases as $file) {
+ Filesystem::copy($extractedArchiveDirectory . $file, PIWIK_DOCUMENT_ROOT . $file);
+ }
+
+ // Copy the non-PHP files (e.g., images, css, javascript)
+ Filesystem::copyRecursive($extractedArchiveDirectory, PIWIK_DOCUMENT_ROOT, true);
+ $model->removeGoneFiles($extractedArchiveDirectory, PIWIK_DOCUMENT_ROOT);
+ }
+
+ // Config files may be user (account) specific
+ if (PIWIK_INCLUDE_PATH !== PIWIK_USER_PATH) {
+ Filesystem::copyRecursive($extractedArchiveDirectory . '/config', PIWIK_USER_PATH . '/config');
+ }
+
+ Filesystem::unlinkRecursive($extractedArchiveDirectory, true);
+
+ Filesystem::clearPhpCaches();
+ }
+
+ /**
+ * @param string $version
+ * @param bool $https Whether to use HTTPS if supported of not. If false, will use HTTP.
+ * @return string
+ */
+ public function getArchiveUrl($version, $https = true)
+ {
+ if (@Config::getInstance()->Debug['allow_upgrades_to_beta']) {
+ $url = sprintf(self::LATEST_BETA_VERSION_URL, $version);
+ } else {
+ $url = self::LATEST_VERSION_URL;
+ }
+
+ if ($this->isUpdatingOverHttps() && $https) {
+ $url = 'https' . $url;
+ } else {
+ $url = 'http' . $url;
+ }
+
+ return $url;
+ }
+
+ private function getIncompatiblePlugins($piwikVersion)
+ {
+ return PluginManager::getInstance()->getIncompatiblePlugins($piwikVersion);
+ }
+}
diff --git a/plugins/CoreUpdater/UpdaterException.php b/plugins/CoreUpdater/UpdaterException.php
new file mode 100644
index 0000000000..d9a543f30f
--- /dev/null
+++ b/plugins/CoreUpdater/UpdaterException.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Piwik\Plugins\CoreUpdater;
+
+use Exception;
+
+/**
+ * Exception during the updating of Piwik to a new version.
+ */
+class UpdaterException extends Exception
+{
+ /**
+ * @var string[]
+ */
+ private $updateLogMessages;
+
+ public function __construct(Exception $exception, array $updateLogMessages)
+ {
+ parent::__construct($exception->getMessage(), 0, $exception);
+
+ $this->updateLogMessages = $updateLogMessages;
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getUpdateLogMessages()
+ {
+ return $this->updateLogMessages;
+ }
+}
diff --git a/plugins/CoreUpdater/config/config.php b/plugins/CoreUpdater/config/config.php
new file mode 100644
index 0000000000..419e43cc7b
--- /dev/null
+++ b/plugins/CoreUpdater/config/config.php
@@ -0,0 +1,6 @@
+<?php
+
+return array(
+ 'Piwik\Plugins\CoreUpdater\Updater' => DI\object()
+ ->constructorParameter('tmpPath', DI\link('path.tmp')),
+);
diff --git a/plugins/CoreUpdater/tests/Fixtures/FailUpdateHttpsFixture.php b/plugins/CoreUpdater/tests/Fixtures/FailUpdateHttpsFixture.php
new file mode 100644
index 0000000000..13b8868eaa
--- /dev/null
+++ b/plugins/CoreUpdater/tests/Fixtures/FailUpdateHttpsFixture.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+namespace Piwik\Plugins\CoreUpdater\Tests\Fixtures;
+
+use Piwik\Tests\Framework\Fixture;
+
+/**
+ * Fixture that makes the update over HTTPS fail to be able to test that users can still update over HTTP.
+ */
+class FailUpdateHttpsFixture extends Fixture
+{
+ public function provideContainerConfig()
+ {
+ return array(
+ 'Piwik\Plugins\CoreUpdater\Updater' => \DI\object('Piwik\Plugins\CoreUpdater\tests\Mock\UpdaterMock'),
+ );
+ }
+}
diff --git a/plugins/CoreUpdater/tests/Mock/UpdaterMock.php b/plugins/CoreUpdater/tests/Mock/UpdaterMock.php
new file mode 100644
index 0000000000..e1eaee61a1
--- /dev/null
+++ b/plugins/CoreUpdater/tests/Mock/UpdaterMock.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+namespace Piwik\Plugins\CoreUpdater\tests\Mock;
+
+use Piwik\Plugins\CoreUpdater\Updater;
+use Piwik\Plugins\CoreUpdater\UpdaterException;
+use Piwik\Translation\Translator;
+
+class UpdaterMock extends Updater
+{
+ /**
+ * @var Translator
+ */
+ private $translator;
+
+ public function __construct(Translator $translator)
+ {
+ $this->translator = $translator;
+ }
+
+ public function getLatestVersion()
+ {
+ return '4.0.0';
+ }
+
+ public function isNewVersionAvailable()
+ {
+ return true;
+ }
+
+ public function updatePiwik($https = true)
+ {
+ // Simulate that the update over HTTPS fails
+ if ($https) {
+ throw new UpdaterException(new \Exception('Error while downloading Piwik'), array());
+ }
+
+ // Simulate that the update over HTTP succeeds
+ return array(
+ $this->translator->translate('CoreUpdater_DownloadingUpdateFromX', ''),
+ $this->translator->translate('CoreUpdater_UnpackingTheUpdate'),
+ $this->translator->translate('CoreUpdater_VerifyingUnpackedFiles'),
+ $this->translator->translate('CoreUpdater_InstallingTheLatestVersion'),
+ );
+ }
+}
diff --git a/plugins/CoreUpdater/tests/UI/PiwikUpdater_spec.js b/plugins/CoreUpdater/tests/UI/PiwikUpdater_spec.js
new file mode 100644
index 0000000000..4438c1b48b
--- /dev/null
+++ b/plugins/CoreUpdater/tests/UI/PiwikUpdater_spec.js
@@ -0,0 +1,22 @@
+/*!
+ * Piwik - free/libre analytics platform
+ *
+ * Installation screenshot tests.
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+describe("PiwikUpdater", function () {
+ this.timeout(0);
+
+ this.fixture = "Piwik\\Plugins\\CoreUpdater\\Tests\\Fixtures\\FailUpdateHttpsFixture";
+
+ var url = "?module=CoreUpdater&action=newVersionAvailable";
+
+ it("should show a new version is available", function (done) {
+ expect.screenshot("newVersion").to.be.capture(function (page) {
+ page.load(url);
+ }, done);
+ });
+});
diff --git a/plugins/CoreUpdater/tests/UI/expected-ui-screenshots/PiwikUpdater_newVersion.png b/plugins/CoreUpdater/tests/UI/expected-ui-screenshots/PiwikUpdater_newVersion.png
new file mode 100644
index 0000000000..483dde95f8
--- /dev/null
+++ b/plugins/CoreUpdater/tests/UI/expected-ui-screenshots/PiwikUpdater_newVersion.png
Binary files differ