diff --git a/README.md b/README.md
index 190a8c27..dc7bf8bd 100755
--- a/README.md
+++ b/README.md
@@ -21,13 +21,25 @@ Example call: updater_server/?version=9x0x0x12x1448709225.0768x1448709281xstable
```
+Deployed URL: https://updates.nextcloud.com/updater_server/
+Example call: updater_server/?channel=stable
+```xml
+
+
+ 9.0.51
+ Nextcloud 9.0.51
+ https://download.nextcloud.com/server/releases/nextcloud-9.0.51.zip
+ https://docs.nextcloud.com/server/9/admin_manual/maintenance/upgrade.html
+
+```
+
## Webhook deployment
-If you wish to receive webhooks and then automatically deploy the lastest version of the updater server there is one special API endpoint available.
+If you wish to receive webhooks and then automatically deploy the latest version of the updater server there is one special API endpoint available.
-For this the [Github Webhook](https://developer.github.com/webhooks/) needs to be configured to send `push` events to the endpoint `/hook` of the updater server. There only the ending part is crucial. That means that any URL ending in `/hook` which is served by the `index.php` of the updater server will trigger this behaviour.
+For this the [GitHub Webhook](https://developer.github.com/webhooks/) needs to be configured to send `push` events to the endpoint `/hook` of the updater server. There only the ending part is crucial. That means that any URL ending in `/hook` which is served by the `index.php` of the updater server will trigger this behaviour.
-Configure a webhook on Github in the repository of choice with `application/json` as content type, a random secret and the `push` event to be sent.
+Configure a webhook on GitHub in the repository of choice with `application/json` as content type, a random secret and the `push` event to be sent.
![](docs/webhook.png)
diff --git a/index.php b/index.php
index e95ce119..96777f8e 100755
--- a/index.php
+++ b/index.php
@@ -63,24 +63,28 @@
exit();
}
-// Return empty response if no version is supplied
-if(!isset($_GET['version']) || !is_string($_GET['version'])) {
- exit();
-}
-
-// Parse the request
+// Read config
try {
- $request = new \UpdateServer\Request($_GET['version'], $_SERVER);
-} catch (\UpdateServer\Exceptions\UnsupportedReleaseException $e) {
+ $config = new \UpdateServer\Config(__DIR__ . '/config/config.php');
+} catch (\RuntimeException $e) {
exit();
}
-try {
- $config = new \UpdateServer\Config(__DIR__ . '/config/config.php');
-} catch (\RuntimeException $e) {
+// Check the request parameters
+if(isset($_GET['version']) && is_string($_GET['version'])) {
+ try {
+ $request = new \UpdateServer\Requests\VersionRequest($_GET['version'], $_SERVER);
+ } catch (\UpdateServer\Exceptions\UnsupportedReleaseException $e) {
+ exit();
+ }
+ $response = new \UpdateServer\Responses\VersionResponse($request, $config);
+} else if (isset($_GET['channel']) && is_string($_GET['channel'])) {
+ $request = new \UpdateServer\Requests\ChannelRequest($_GET['channel']);
+ $response = new \UpdateServer\Responses\ChannelResponse($request, $config);
+} else {
+ // Return empty response if no version or channel is supplied
exit();
}
-// Return a response
-$response = new \UpdateServer\Response($request, $config);
+// Return the response
echo $response->buildResponse();
diff --git a/src/Requests/ChannelRequest.php b/src/Requests/ChannelRequest.php
new file mode 100755
index 00000000..176e6809
--- /dev/null
+++ b/src/Requests/ChannelRequest.php
@@ -0,0 +1,26 @@
+
+ */
+
+namespace UpdateServer\Requests;
+
+class ChannelRequest {
+ /** @var string */
+ private $channel;
+
+ /**
+ * ChannelRequest constructor.
+ * @param string $channel
+ */
+ public function __construct(string $channel) {
+ $this->channel = $channel;
+ }
+
+ /**
+ * @return string
+ */
+ public function getChannel(): string {
+ return $this->channel;
+ }
+}
diff --git a/src/Request.php b/src/Requests/VersionRequest.php
similarity index 97%
rename from src/Request.php
rename to src/Requests/VersionRequest.php
index 1109c643..1a2121b8 100755
--- a/src/Request.php
+++ b/src/Requests/VersionRequest.php
@@ -3,11 +3,11 @@
* @license MIT
*/
-namespace UpdateServer;
+namespace UpdateServer\Requests;
use UpdateServer\Exceptions\UnsupportedReleaseException;
-class Request {
+class VersionRequest {
/** @var int|null */
private $majorVersion = null;
/** @var int|null */
@@ -41,8 +41,7 @@ class Request {
* @param array $server
* @throws UnsupportedReleaseException If the release is not supported by this update script.
*/
- public function __construct($versionString,
- array $server) {
+ public function __construct(string $versionString, array $server) {
$this->readVersion($versionString, $server);
}
diff --git a/src/Response.php b/src/Response.php
deleted file mode 100755
index b2f2f844..00000000
--- a/src/Response.php
+++ /dev/null
@@ -1,210 +0,0 @@
-
- */
-
-namespace UpdateServer;
-
-class Response {
- /** @var Config */
- private $config;
- /** @var Request */
- private $request;
-
- /**
- * @param Request $request
- * @param Config $config
- */
- public function __construct(Request $request,
- Config $config
- ) {
- $this->request = $request;
- $this->config = $config;
- }
-
- /**
- * @return array
- */
- private function getFuzzySearches() {
- // The search scheme is defined as following:
- // 1. Major.Minor.Maintenance.Revision
- $searches[] = $this->request->getMajorVersion().'.'.$this->request->getMinorVersion().'.'.$this->request->getMaintenanceVersion().'.'.$this->request->getRevisionVersion();
- // 2. Major.Minor.Maintenance
- $searches[] = $this->request->getMajorVersion().'.'.$this->request->getMinorVersion().'.'.$this->request->getMaintenanceVersion();
- // 3. Major.Minor
- $searches[] = $this->request->getMajorVersion().'.'.$this->request->getMinorVersion();
- // 4. Major
- $searches[] = $this->request->getMajorVersion();
- return $searches;
- }
-
- /**
- * @param \XMLWriter $writer
- * @param $version
- */
- private function addChangelogURLIfApplicable(\XMLWriter $writer, $version) {
- if(version_compare($version, '13.99.0', '<')) {
- return;
- }
-
- $versionString = implode('.', array_slice(explode('.', $version), 0, 3));
- $preReleasePos = strpos($versionString, ' ');
- if($preReleasePos !== false) {
- $versionString = substr($versionString, 0, $preReleasePos);
- }
-
- $changesUrl = rtrim($this->config->get('_settings')['changelogServer'], '/')
- . '/?version=' . urlencode($versionString);
-
- $writer->writeElement('changes', $changesUrl);
- }
-
- /**
- * Code for the stable editions
- *
- * @param array $versions
- * @param string $completeCurrentVersion
- * @param string $phpVersion
- * @param int $installationMtime
- * @return string
- */
- private function getStableResponse(array $versions,
- $completeCurrentVersion,
- $phpVersion,
- $installationMtime) {
- $newVersion = '';
- foreach($this->getFuzzySearches() as $search) {
- if(isset($versions[$search])) {
- /** @var array $newVersions */
- $newVersions = $versions[$search];
-
- $counter = 100;
- $instanceChance = (int)substr($installationMtime, -2);
- if($instanceChance !== 0) {
- ksort($newVersions);
- }
-
- foreach($newVersions as $chance => $updateOptions) {
- $counter -= $chance;
- if($instanceChance <= (100 - $counter)) {
- // skip incompatible releases due to PHP version
- if(isset($newVersions[$chance]['minPHPVersion']) && version_compare($newVersions[$chance]['minPHPVersion'], $phpVersion, '>')) {
- continue;
- }
- // skip incompatible releases due to lower version number
- if(version_compare($newVersions[$chance]['internalVersion'], $completeCurrentVersion, '<=')) {
- continue;
- }
- $newVersion = $newVersions[$chance];
- break 2;
- }
- }
- }
- }
-
- if($newVersion === '') {
- return '';
- }
-
- $downloadUrl = 'https://download.nextcloud.com/server/releases/nextcloud-'.$newVersion['latest'].'.zip';
- if(isset($newVersion['downloadUrl'])) {
- $downloadUrl = $newVersion['downloadUrl'];
- }
-
- $writer = new \XMLWriter();
- $writer->openMemory();
- $writer->startDocument('1.0','UTF-8');
- $writer->setIndent(4);
- $writer->startElement('nextcloud');
- $writer->writeElement('version', $newVersion['internalVersion']);
- $writer->writeElement('versionstring', 'Nextcloud '.$newVersion['latest']);
- $writer->writeElement('url', $downloadUrl);
- $writer->writeElement('web', $newVersion['web']);
- $this->addChangelogURLIfApplicable($writer, $newVersion['latest']);
- $writer->writeElement('autoupdater', isset($newVersion['autoupdater']) ? (int)$newVersion['autoupdater'] : 1);
- $writer->writeElement('eol', (int) $newVersion['eol']);
- if(isset($newVersion['signature'])) {
- $writer->writeElement('signature', $newVersion['signature']);
- }
- $writer->endElement();
- $writer->endDocument();
- return $writer->flush();
- }
-
- /**
- * Code for the daily builds
- *
- * @param array $versions
- * @return string
- */
- private function getDailyResponse(array $versions) {
- foreach($this->getFuzzySearches() as $search) {
- if(isset($versions[$search])) {
- if((time() - strtotime($this->request->getBuild())) > 172800) {
- $newVersion = $versions[$search];
- $writer = new \XMLWriter();
- $writer->openMemory();
- $writer->startDocument('1.0','UTF-8');
- $writer->setIndent(4);
- $writer->startElement('nextcloud');
- $writer->writeElement('version', '100.0.0.0');
- $writer->writeElement('versionstring', 'Nextcloud daily');
- $writer->writeElement('url', $newVersion['downloadUrl']);
- $writer->writeElement('web', $newVersion['web']);
- $writer->writeElement('autoupdater', isset($newVersion['autoupdater']) ? (int)$newVersion['autoupdater'] : 1);
- $writer->writeElement('eol', (int) $newVersion['eol']);
- $writer->endElement();
- $writer->endDocument();
- return $writer->flush();
- }
- }
- }
-
- return '';
- }
-
- /**
- * @return string
- */
- public function buildResponse() {
- $completeCurrentVersion = $this->request->getMajorVersion().'.'.$this->request->getMinorVersion().'.'.$this->request->getMaintenanceVersion().'.'.$this->request->getRevisionVersion();
- $phpVersion = implode(
- '.',
- [
- $this->request->getPHPMajorVersion(),
- $this->request->getPHPMinorVersion(),
- $this->request->getPHPReleaseVersion(),
- ]
- );
-
- $completeCurrentVersion = rtrim($completeCurrentVersion, '.');
-
- switch ($this->request->getChannel()) {
- case 'enterprise':
- return $this->getStableResponse(
- $this->config->getWithAlternative('enterprise', 'stable'),
- $completeCurrentVersion,
- $phpVersion,
- $this->request->getInstallationMtime()
- );
- case 'stable':
- return $this->getStableResponse(
- $this->config->get('stable'),
- $completeCurrentVersion,
- $phpVersion,
- $this->request->getInstallationMtime()
- );
- case 'beta':
- return $this->getStableResponse(
- $this->config->get('beta'),
- $completeCurrentVersion,
- $phpVersion,
- $this->request->getInstallationMtime()
- );
- case 'daily':
- return $this->getDailyResponse($this->config->get('daily'));
- default:
- return '';
- }
- }
-}
diff --git a/src/Responses/BaseResponse.php b/src/Responses/BaseResponse.php
new file mode 100755
index 00000000..a1a7b7e3
--- /dev/null
+++ b/src/Responses/BaseResponse.php
@@ -0,0 +1,112 @@
+
+ */
+
+namespace UpdateServer\Responses;
+
+use UpdateServer\Config;
+
+abstract class BaseResponse {
+ /** @var Config */
+ private $config;
+
+ /**
+ * @param Config $config
+ */
+ protected function __construct(Config $config) {
+ $this->config = $config;
+ }
+
+ /**
+ * @param string $channel
+ */
+ protected function getChannelConfig(string $channel): array {
+ switch ($channel) {
+ case 'enterprise':
+ return $this->config->getWithAlternative('enterprise', 'stable');
+ case 'stable':
+ return $this->config->get('stable');
+ case 'beta':
+ return $this->config->get('beta');
+ case 'daily':
+ return $this->config->get('daily');
+ default:
+ return [];
+ }
+ }
+
+ /**
+ * @param \XMLWriter $writer
+ * @param $version
+ */
+ private function addChangelogURLIfApplicable(\XMLWriter $writer, $version) {
+ if(version_compare($version, '13.99.0', '<')) {
+ return;
+ }
+
+ $versionString = implode('.', array_slice(explode('.', $version), 0, 3));
+ $preReleasePos = strpos($versionString, ' ');
+ if($preReleasePos !== false) {
+ $versionString = substr($versionString, 0, $preReleasePos);
+ }
+
+ $changesUrl = rtrim($this->config->get('_settings')['changelogServer'], '/')
+ . '/?version=' . urlencode($versionString);
+
+ $writer->writeElement('changes', $changesUrl);
+ }
+
+ /**
+ * @param array $newVersion
+ * @return string
+ */
+ protected function buildXMLForVersion(array $newVersion): string {
+ $downloadUrl = 'https://download.nextcloud.com/server/releases/nextcloud-'.$newVersion['latest'].'.zip';
+ if(isset($newVersion['downloadUrl'])) {
+ $downloadUrl = $newVersion['downloadUrl'];
+ }
+
+ $writer = new \XMLWriter();
+ $writer->openMemory();
+ $writer->startDocument('1.0','UTF-8');
+ $writer->setIndent(4);
+ $writer->startElement('nextcloud');
+ $writer->writeElement('version', $newVersion['internalVersion']);
+ $writer->writeElement('versionstring', 'Nextcloud '.$newVersion['latest']);
+ $writer->writeElement('url', $downloadUrl);
+ $writer->writeElement('web', $newVersion['web']);
+ $this->addChangelogURLIfApplicable($writer, $newVersion['latest']);
+ $writer->writeElement('autoupdater', isset($newVersion['autoupdater']) ? (int)$newVersion['autoupdater'] : 1);
+ $writer->writeElement('eol', (int) $newVersion['eol']);
+ if(isset($newVersion['signature'])) {
+ $writer->writeElement('signature', $newVersion['signature']);
+ }
+ $writer->endElement();
+ $writer->endDocument();
+ return $writer->flush();
+ }
+
+ /**
+ * @param array $newVersion
+ * @return string
+ */
+ protected function buildXMLForDailyVersion(array $newVersion): string {
+ $writer = new \XMLWriter();
+ $writer->openMemory();
+ $writer->startDocument('1.0','UTF-8');
+ $writer->setIndent(4);
+ $writer->startElement('nextcloud');
+ $writer->writeElement('version', '100.0.0.0');
+ $writer->writeElement('versionstring', 'Nextcloud daily');
+ $writer->writeElement('url', $newVersion['downloadUrl']);
+ $writer->writeElement('web', $newVersion['web']);
+ $writer->writeElement('autoupdater', isset($newVersion['autoupdater']) ? (int)$newVersion['autoupdater'] : 1);
+ $writer->writeElement('eol', (int) $newVersion['eol']);
+ $writer->endElement();
+ $writer->endDocument();
+ return $writer->flush();
+ }
+
+ public abstract function buildResponse(): string;
+}
diff --git a/src/Responses/ChannelResponse.php b/src/Responses/ChannelResponse.php
new file mode 100755
index 00000000..10ead0a9
--- /dev/null
+++ b/src/Responses/ChannelResponse.php
@@ -0,0 +1,86 @@
+
+ */
+
+namespace UpdateServer\Responses;
+
+use UpdateServer\Config;
+use UpdateServer\Requests\ChannelRequest;
+
+class ChannelResponse extends BaseResponse {
+ /** @var ChannelRequest */
+ private $request;
+
+ /**
+ * @param ChannelRequest $request
+ * @param Config $config
+ */
+ public function __construct(ChannelRequest $request, Config $config) {
+ parent::__construct($config);
+ $this->request = $request;
+ }
+
+ /**
+ * @param string $channel
+ * @return array|null
+ */
+ private function getBestVersionConfigForRegularChannel(string $channel): ?array {
+ $channelConfig = $this->getChannelConfig($channel);
+ $bestVersionConfig = null;
+ $highestVersionNumber = null;
+ foreach($channelConfig as $versionNumber => $releaseConfig) {
+ if($highestVersionNumber === null || version_compare($highestVersionNumber, $versionNumber, '<')) {
+ $highestProbability = 0;
+ foreach($releaseConfig as $probability => $versionConfig) {
+ if((int)$probability > $highestProbability && (!isset($versionConfig['eol']) || $versionConfig['eol'] !== true)) {
+ $highestProbability = $probability;
+ $bestVersionConfig = $versionConfig;
+ }
+ }
+ if($highestProbability !== 0) {
+ // Only increase the highestVersionNumber if we actually found a new version config.
+ $highestVersionNumber = $versionNumber;
+ }
+ }
+ }
+ return $bestVersionConfig;
+ }
+
+ /**
+ * @return array|null
+ */
+ private function getBestVersionConfigForDailyChannel(): ?array {
+ $channelConfig = $this->getChannelConfig('daily');
+ $bestVersionConfig = null;
+ $highestVersionNumber = null;
+ foreach($channelConfig as $versionNumber => $versionConfig) {
+ if($highestVersionNumber === null || version_compare($highestVersionNumber, $versionNumber, '<')
+ && (!isset($versionConfig['eol']) || $versionConfig['eol'] !== true)) {
+ $bestVersionConfig = $versionConfig;
+ $highestVersionNumber = $versionNumber;
+ }
+ }
+ return $bestVersionConfig;
+ }
+
+ /**
+ * @param string $channel
+ * @return array|null
+ */
+ private function getBestVersionConfig(string $channel): ?array {
+ return $channel !== 'daily' ? $this->getBestVersionConfigForRegularChannel($channel) : $this->getBestVersionConfigForDailyChannel();
+ }
+
+ public function buildResponse(): string {
+ $bestVersion = $this->getBestVersionConfig($this->request->getChannel());
+ if($bestVersion === null) {
+ return '';
+ }
+ if ($this->request->getChannel() !== 'daily') {
+ return $this->buildXMLForVersion($bestVersion);
+ } else {
+ return $this->buildXMLForDailyVersion($bestVersion);
+ }
+ }
+}
diff --git a/src/Responses/VersionResponse.php b/src/Responses/VersionResponse.php
new file mode 100755
index 00000000..bebbf9b5
--- /dev/null
+++ b/src/Responses/VersionResponse.php
@@ -0,0 +1,137 @@
+
+ */
+
+namespace UpdateServer\Responses;
+
+use UpdateServer\Config;
+use UpdateServer\Requests\VersionRequest;
+
+class VersionResponse extends BaseResponse {
+ /** @var VersionRequest */
+ private $request;
+
+ /**
+ * @param VersionRequest $request
+ * @param Config $config
+ */
+ public function __construct(VersionRequest $request, Config $config) {
+ parent::__construct($config);
+ $this->request = $request;
+ }
+
+ /**
+ * @return array
+ */
+ private function getFuzzySearches() {
+ // The search scheme is defined as following:
+ // 1. Major.Minor.Maintenance.Revision
+ $searches[] = $this->request->getMajorVersion().'.'.$this->request->getMinorVersion().'.'.$this->request->getMaintenanceVersion().'.'.$this->request->getRevisionVersion();
+ // 2. Major.Minor.Maintenance
+ $searches[] = $this->request->getMajorVersion().'.'.$this->request->getMinorVersion().'.'.$this->request->getMaintenanceVersion();
+ // 3. Major.Minor
+ $searches[] = $this->request->getMajorVersion().'.'.$this->request->getMinorVersion();
+ // 4. Major
+ $searches[] = $this->request->getMajorVersion();
+ return $searches;
+ }
+
+ /**
+ * Code for the stable editions
+ *
+ * @param array $versions
+ * @param string $completeCurrentVersion
+ * @param string $phpVersion
+ * @param int $installationMtime
+ * @return string
+ */
+ private function getStableResponse(array $versions,
+ $completeCurrentVersion,
+ $phpVersion,
+ $installationMtime) {
+ $newVersion = '';
+ foreach($this->getFuzzySearches() as $search) {
+ if(isset($versions[$search])) {
+ /** @var array $newVersions */
+ $newVersions = $versions[$search];
+
+ $counter = 100;
+ $instanceChance = (int)substr($installationMtime, -2);
+ if($instanceChance !== 0) {
+ ksort($newVersions);
+ }
+
+ foreach($newVersions as $chance => $updateOptions) {
+ $counter -= $chance;
+ if($instanceChance <= (100 - $counter)) {
+ // skip incompatible releases due to PHP version
+ if(isset($newVersions[$chance]['minPHPVersion']) && version_compare($newVersions[$chance]['minPHPVersion'], $phpVersion, '>')) {
+ continue;
+ }
+ // skip incompatible releases due to lower version number
+ if(version_compare($newVersions[$chance]['internalVersion'], $completeCurrentVersion, '<=')) {
+ continue;
+ }
+ $newVersion = $newVersions[$chance];
+ break 2;
+ }
+ }
+ }
+ }
+
+ if($newVersion === '') {
+ return '';
+ }
+
+ return $this->buildXMLForVersion($newVersion);
+ }
+
+ /**
+ * Code for the daily builds
+ *
+ * @param array $versions
+ * @return string
+ */
+ private function getDailyResponse(array $versions) {
+ if ((time() - strtotime($this->request->getBuild())) <= 172800) {
+ return '';
+ }
+
+ foreach($this->getFuzzySearches() as $search) {
+ if(isset($versions[$search])) {
+ return $this->buildXMLForDailyVersion($versions[$search]);
+ }
+ }
+
+ return '';
+ }
+
+ /**
+ * @return string
+ */
+ public function buildResponse(): string {
+ $completeCurrentVersion = $this->request->getMajorVersion().'.'.$this->request->getMinorVersion().'.'.$this->request->getMaintenanceVersion().'.'.$this->request->getRevisionVersion();
+ $completeCurrentVersion = rtrim($completeCurrentVersion, '.');
+ $phpVersion = implode(
+ '.',
+ [
+ $this->request->getPHPMajorVersion(),
+ $this->request->getPHPMinorVersion(),
+ $this->request->getPHPReleaseVersion(),
+ ]
+ );
+ $channelConfig = $this->getChannelConfig($this->request->getChannel());
+
+ if ($this->request->getChannel() !== 'daily') {
+ return $this->getStableResponse(
+ $channelConfig,
+ $completeCurrentVersion,
+ $phpVersion,
+ $this->request->getInstallationMtime()
+ );
+ } else {
+ return $this->getDailyResponse($channelConfig);
+ }
+ }
+}
diff --git a/tests/integration/features/beta.feature b/tests/integration/features/beta.feature
index 0b299982..eaa94a7c 100644
--- a/tests/integration/features/beta.feature
+++ b/tests/integration/features/beta.feature
@@ -493,4 +493,23 @@ Feature: Testing the update scenario of beta releases
lqcZSGdY+smeb7ciFf0hykivKZATXHLczvYO3FUu/HVqlgRUxi+Q+wNjFmfFL3Vr
RGlZGz7bpa48/2sprNJ2CYGVLMjxtktUrUIH6NB0diVMK8kAd7+OIqtjCmUG307S
qRc0DHdtzXMmzq4t4PfZhg==
- """
\ No newline at end of file
+ """
+
+ Scenario: Requesting the latest release of the beta channel
+ Given The request is channel based
+ And The requested channel is "beta"
+ When The request is sent
+ Then The response is non-empty
+ And Update to version "21.0.1.1" is available
+ And URL to download is "https://download.nextcloud.com/server/releases/nextcloud-21.0.1.zip"
+ And URL to documentation is "https://docs.nextcloud.com/server/21/admin_manual/maintenance/upgrade.html"
+ And EOL is set to "0"
+ And The signature is
+ """
+ YJQMb8iq13NhbvfEddaSjNeqlMe/dB0nJ27EwmiAuqSMMRpvVg4BjijfNjoG8lY9
+ rs0k+YN4EkGSr1lhZvdWZ9LpmP1wug/l1wj8lWzjxp/588yp5jHs24XBsi14GrDY
+ tgcx/V6E2ELFfgXJY6R4y2bIaaDPPjDfi+a2nq5ut0RTalGaUh6jr1dzaKQ0rJXm
+ lqcZSGdY+smeb7ciFf0hykivKZATXHLczvYO3FUu/HVqlgRUxi+Q+wNjFmfFL3Vr
+ RGlZGz7bpa48/2sprNJ2CYGVLMjxtktUrUIH6NB0diVMK8kAd7+OIqtjCmUG307S
+ qRc0DHdtzXMmzq4t4PfZhg==
+ """
diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php
index 12083edd..5b390753 100755
--- a/tests/integration/features/bootstrap/FeatureContext.php
+++ b/tests/integration/features/bootstrap/FeatureContext.php
@@ -7,6 +7,8 @@
use Behat\Behat\Context\SnippetAcceptingContext;
class FeatureContext implements Context, SnippetAcceptingContext {
+ /** @var string */
+ private $requestKind = 'version';
/** @var string */
private $releaseChannel = '';
/** @var string */
@@ -36,6 +38,27 @@ class FeatureContext implements Context, SnippetAcceptingContext {
/** @var array */
private $resultArray = [];
+ /**
+ * @Given The request is version based
+ */
+ public function theRequestIsVersionBased() {
+ $this->requestKind = 'version';
+ }
+
+ /**
+ * @Given The request is channel based
+ */
+ public function theRequestIsChannelBased() {
+ $this->requestKind = 'channel';
+ }
+
+ /**
+ * @Given The requested channel is :arg1
+ */
+ public function theRequestedChannelIs($arg1) {
+ $this->releaseChannel = $arg1;
+ }
+
/**
* @Given There is a release with channel :arg1
*/
@@ -114,9 +137,18 @@ private function buildVersionToSend() {
* @When The request is sent
*/
public function theRequestIsSent() {
+ $url = 'http://localhost:8888/?';
+ switch ($this->requestKind) {
+ case 'version':
+ $url .= 'version='.$this->buildVersionToSend();
+ break;
+ case 'channel':
+ $url .= 'channel='.$this->releaseChannel;
+ break;
+ }
$ch = curl_init();
$optArray = array(
- CURLOPT_URL => 'http://localhost:8888/?version='.$this->buildVersionToSend(),
+ CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true
);
curl_setopt_array($ch, $optArray);
diff --git a/tests/integration/features/daily.feature b/tests/integration/features/daily.feature
index 76bf36a0..75226baa 100644
--- a/tests/integration/features/daily.feature
+++ b/tests/integration/features/daily.feature
@@ -18,3 +18,14 @@ Feature: Testing the update scenario of daily releases
And the received build is "2099-10-19T18:44:30+00:00"
When The request is sent
Then The response is empty
+
+ Scenario: Requesting the latest release of the daily channel
+ Given The request is channel based
+ And The requested channel is "daily"
+ When The request is sent
+ Then The response is non-empty
+ And Update to version "100.0.0.0" is available
+ And URL to download is "https://download.nextcloud.com/server/daily/latest-master.zip"
+ And URL to documentation is "https://docs.nextcloud.com/server/latest/admin_manual/maintenance/upgrade.html"
+ And EOL is set to "0"
+ And No signature is set
diff --git a/tests/integration/features/stable.feature b/tests/integration/features/stable.feature
index ba86a4e5..e086ee25 100644
--- a/tests/integration/features/stable.feature
+++ b/tests/integration/features/stable.feature
@@ -762,4 +762,21 @@ Feature: Testing the update scenario of stable releases
qRc0DHdtzXMmzq4t4PfZhg==
"""
-
+ Scenario: Requesting the latest release of the stable channel
+ Given The request is channel based
+ And The requested channel is "stable"
+ When The request is sent
+ Then The response is non-empty
+ And Update to version "21.0.1.1" is available
+ And URL to download is "https://download.nextcloud.com/server/releases/nextcloud-21.0.1.zip"
+ And URL to documentation is "https://docs.nextcloud.com/server/21/admin_manual/maintenance/upgrade.html"
+ And EOL is set to "0"
+ And The signature is
+ """
+ YJQMb8iq13NhbvfEddaSjNeqlMe/dB0nJ27EwmiAuqSMMRpvVg4BjijfNjoG8lY9
+ rs0k+YN4EkGSr1lhZvdWZ9LpmP1wug/l1wj8lWzjxp/588yp5jHs24XBsi14GrDY
+ tgcx/V6E2ELFfgXJY6R4y2bIaaDPPjDfi+a2nq5ut0RTalGaUh6jr1dzaKQ0rJXm
+ lqcZSGdY+smeb7ciFf0hykivKZATXHLczvYO3FUu/HVqlgRUxi+Q+wNjFmfFL3Vr
+ RGlZGz7bpa48/2sprNJ2CYGVLMjxtktUrUIH6NB0diVMK8kAd7+OIqtjCmUG307S
+ qRc0DHdtzXMmzq4t4PfZhg==
+ """
diff --git a/tests/unit/ChannelRequestTest.php b/tests/unit/ChannelRequestTest.php
new file mode 100755
index 00000000..bf135698
--- /dev/null
+++ b/tests/unit/ChannelRequestTest.php
@@ -0,0 +1,16 @@
+
+ */
+
+namespace Tests;
+
+use UpdateServer\Requests\ChannelRequest;
+
+class ChannelRequestTest extends \PHPUnit_Framework_TestCase {
+ public function testRequest()
+ {
+ $request = new ChannelRequest('stable');
+ $this->assertSame('stable', $request->getChannel());
+ }
+}
diff --git a/tests/unit/ChannelResponseTest.php b/tests/unit/ChannelResponseTest.php
new file mode 100755
index 00000000..956f1406
--- /dev/null
+++ b/tests/unit/ChannelResponseTest.php
@@ -0,0 +1,197 @@
+
+ */
+
+namespace Tests;
+
+use UpdateServer\Config;
+use UpdateServer\Requests\ChannelRequest;
+use UpdateServer\Responses\ChannelResponse;
+
+class ChannelResponseTest extends \PHPUnit_Framework_TestCase
+{
+ /** @var ChannelRequest */
+ private $request;
+ /** @var Config|\PHPUnit_Framework_MockObject_MockObject */
+ private $config;
+ /** @var ChannelResponse */
+ private $response;
+
+ public function setUp()
+ {
+ date_default_timezone_set('Europe/Berlin');
+
+ $this->request = $this->getMockBuilder(ChannelRequest::class)
+ ->disableOriginalConstructor()->getMock();
+ $this->config = $this->getMockBuilder(Config::class)
+ ->disableOriginalConstructor()->getMock();
+ $this->response = new ChannelResponse($this->request, $this->config);
+ }
+
+ public function updateDataProvider() {
+ return [
+ [
+ 'beta',
+ '
+
+ 9.0.0
+ Nextcloud 9.0.0
+ https://download.nextcloud.com/server/releases/nextcloud-9.0.0.zip
+ https://doc.owncloud.org/server/9.0/admin_manual/maintenance/upgrade.html
+ 0
+ 0
+
+',
+ ],
+ [
+ 'stable',
+ '
+
+ 8.2.2
+ Nextcloud 8.2.2
+ https://download.nextcloud.com/server/releases/nextcloud-8.2.2.zip
+ https://doc.owncloud.org/server/8.2/admin_manual/maintenance/upgrade.html
+ 0
+ 1
+
+',
+ ],
+ [
+ '',
+ '',
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider updateDataProvider
+ * @param string $channel
+ * @param string $expected
+ */
+ public function testBuildChannelResponse($channel, $expected) {
+ $betaConfig = [
+ '9.0' => [
+ '100' => [
+ 'latest' => '9.0.0',
+ 'internalVersion' => '9.0.0',
+ 'web' => 'https://doc.owncloud.org/server/9.0/admin_manual/maintenance/upgrade.html',
+ 'autoupdater' => false,
+ 'minPHPVersion' => '5.6',
+ 'eol' => false,
+ ]
+ ],
+ '8.2' => [
+ '95' => [
+ 'latest' => '8.2.2',
+ 'internalVersion' => '8.2.2',
+ 'web' => 'https://doc.owncloud.org/server/8.2/admin_manual/maintenance/upgrade.html',
+ 'autoupdater' => false,
+ 'minPHPVersion' => '5.4',
+ 'eol' => true,
+ ],
+ '5' => [
+ 'latest' => '9.0.0',
+ 'internalVersion' => '9.0.0',
+ 'web' => 'https://doc.owncloud.org/server/9.0/admin_manual/maintenance/upgrade.html',
+ 'autoupdater' => false,
+ 'minPHPVersion' => '5.6',
+ 'eol' => false,
+ ]
+ ],
+ ];
+ $stableConfig = [
+ '8.2' => [
+ '95' => [
+ 'latest' => '8.2.2',
+ 'internalVersion' => '8.2.2',
+ 'web' => 'https://doc.owncloud.org/server/8.2/admin_manual/maintenance/upgrade.html',
+ 'autoupdater' => false,
+ 'minPHPVersion' => '5.4',
+ 'eol' => true,
+ ],
+ '5' => [
+ 'latest' => '9.0.0',
+ 'internalVersion' => '9.0.0',
+ 'web' => 'https://doc.owncloud.org/server/9.0/admin_manual/maintenance/upgrade.html',
+ 'autoupdater' => false,
+ 'minPHPVersion' => '5.6',
+ 'eol' => false,
+ ]
+ ],
+ ];
+
+ $this->request
+ ->expects($this->any())
+ ->method('getChannel')
+ ->willReturn($channel);
+ $this->config
+ ->expects($this->any())
+ ->method('get')
+ ->with('stable')
+ ->willReturn($stableConfig);
+ $this->config
+ ->expects($this->any())
+ ->method('get')
+ ->with('beta')
+ ->willReturn($betaConfig);
+ $this->assertSame($expected, $this->response->buildResponse());
+ }
+
+ public function dailyVersionProvider() {
+ return [
+ [
+ '
+
+ 100.0.0.0
+ Nextcloud daily
+ https://download.nextcloud.com/server/daily/latest-master.zip
+ https://docs.nextcloud.com/server/latest/admin_manual/maintenance/upgrade.html
+ 1
+ 0
+
+',
+ ]
+ ];
+ }
+
+ /**
+ * @dataProvider dailyVersionProvider
+ */
+ public function testBuildResponseForDailyChannel($expected) {
+ $this->request
+ ->expects($this->any())
+ ->method('getChannel')
+ ->willReturn('daily');
+ $this->config
+ ->expects($this->once())
+ ->method('get')
+ ->with('daily')
+ ->willReturn(
+ [
+ '21.1' => [
+ 'downloadUrl' => 'https://download.nextcloud.com/server/daily/latest-master-eol.zip',
+ 'web' => 'https://docs.nextcloud.com/server/eol/admin_manual/maintenance/upgrade.html',
+ 'eol' => true,
+ ],
+ '21' => [
+ 'downloadUrl' => 'https://download.nextcloud.com/server/daily/latest-master.zip',
+ 'web' => 'https://docs.nextcloud.com/server/latest/admin_manual/maintenance/upgrade.html',
+ 'eol' => false,
+ ],
+ '20' => [
+ 'downloadUrl' => 'https://download.nextcloud.com/server/daily/latest-stable20.zip',
+ 'web' => 'https://docs.nextcloud.com/server/20/admin_manual/maintenance/upgrade.html',
+ 'eol' => false,
+ ],
+ '19' => [
+ 'downloadUrl' => 'https://download.nextcloud.com/server/daily/latest-stable19.zip',
+ 'web' => 'https://docs.nextcloud.com/server/19/admin_manual/maintenance/upgrade.html',
+ 'eol' => false,
+ ],
+ ]
+ );
+
+ $this->assertSame($expected, $this->response->buildResponse());
+ }
+}
diff --git a/tests/unit/RequestTest.php b/tests/unit/VersionRequestTest.php
similarity index 74%
rename from tests/unit/RequestTest.php
rename to tests/unit/VersionRequestTest.php
index d9ebb86e..19ea4e73 100755
--- a/tests/unit/RequestTest.php
+++ b/tests/unit/VersionRequestTest.php
@@ -5,11 +5,11 @@
namespace Tests;
-use UpdateServer\Request;
+use UpdateServer\Requests\VersionRequest;
-class RequestTest extends \PHPUnit_Framework_TestCase {
+class VersionRequestTest extends \PHPUnit_Framework_TestCase {
public function testRequest() {
- $request = new Request('8x2x0x12x1448709225.0768x1448709281xtestingxx2015-10-19T18:44:30+00:00%208ee2009de36e01a9866404f07722892f84c16e3e', []);
+ $request = new VersionRequest('8x2x0x12x1448709225.0768x1448709281xtestingxx2015-10-19T18:44:30+00:00%208ee2009de36e01a9866404f07722892f84c16e3e', []);
$this->assertSame(8, $request->getMajorVersion());
$this->assertSame(2, $request->getMinorVersion());
$this->assertSame(0, $request->getMaintenanceVersion());
@@ -23,7 +23,7 @@ public function testRequest() {
}
public function testRequestPHP() {
- $request = new Request('8x2x0x12x1448709225.0768x1448709281xtestingxx2015-10-19T18:44:30+00:00%208ee2009de36e01a9866404f07722892f84c16e3ex5x6x36', []);
+ $request = new VersionRequest('8x2x0x12x1448709225.0768x1448709281xtestingxx2015-10-19T18:44:30+00:00%208ee2009de36e01a9866404f07722892f84c16e3ex5x6x36', []);
$this->assertSame(8, $request->getMajorVersion());
$this->assertSame(2, $request->getMinorVersion());
$this->assertSame(0, $request->getMaintenanceVersion());
@@ -43,6 +43,6 @@ public function testRequestPHP() {
* @expectedException \UpdateServer\Exceptions\UnsupportedReleaseException
*/
public function testRequestInvalidEntry() {
- new Request('x8x2x0x12x1448709225.0768x1448709281xtestingxx2015-10-19T18:44:30+00:00%208ee2009de36e01a9866404f07722892f84c16e3e', []);
+ new VersionRequest('x8x2x0x12x1448709225.0768x1448709281xtestingxx2015-10-19T18:44:30+00:00%208ee2009de36e01a9866404f07722892f84c16e3e', []);
}
}
diff --git a/tests/unit/ResponseTest.php b/tests/unit/VersionResponseTest.php
similarity index 98%
rename from tests/unit/ResponseTest.php
rename to tests/unit/VersionResponseTest.php
index 16b209cf..db0263d9 100755
--- a/tests/unit/ResponseTest.php
+++ b/tests/unit/VersionResponseTest.php
@@ -6,25 +6,25 @@
namespace Tests;
use UpdateServer\Config;
-use UpdateServer\Request;
-use UpdateServer\Response;
+use UpdateServer\Requests\VersionRequest;
+use UpdateServer\Responses\VersionResponse;
-class ResponseTest extends \PHPUnit_Framework_TestCase {
- /** @var Request */
+class VersionResponseTest extends \PHPUnit_Framework_TestCase {
+ /** @var VersionRequest */
private $request;
/** @var Config|\PHPUnit_Framework_MockObject_MockObject */
private $config;
- /** @var Response */
+ /** @var VersionResponse */
private $response;
public function setUp() {
date_default_timezone_set('Europe/Berlin');
- $this->request = $this->getMockBuilder(Request::class)
+ $this->request = $this->getMockBuilder(VersionRequest::class)
->disableOriginalConstructor()->getMock();
$this->config = $this->getMockBuilder(Config::class)
->disableOriginalConstructor()->getMock();
- $this->response = new Response($this->request, $this->config);
+ $this->response = new VersionResponse($this->request, $this->config);
}
public function dailyVersionProvider() {
@@ -958,11 +958,11 @@ public function testBuildResponseForChannel($channel,
* @dataProvider responseProviderWithDisabledUpdates
*/
public function testBuildResponseWithDisabledUpdaterChannel($channel,
- $majorVersion,
- $minorVersion,
- $maintenanceVersion,
- $revisionVersion,
- $expected) {
+ $majorVersion,
+ $minorVersion,
+ $maintenanceVersion,
+ $revisionVersion,
+ $expected) {
$config = [
'8.2' => [
'100' => [