Completed
Push — master ( 0eb530...d0e9e2 )
by
unknown
28:41 queued 14s
created
apps/updatenotification/lib/Settings/Admin.php 1 patch
Indentation   +123 added lines, -123 removed lines patch added patch discarded remove patch
@@ -23,127 +23,127 @@
 block discarded – undo
23 23
 use Psr\Log\LoggerInterface;
24 24
 
25 25
 class Admin implements ISettings {
26
-	public function __construct(
27
-		private IConfig $config,
28
-		private IAppConfig $appConfig,
29
-		private UpdateChecker $updateChecker,
30
-		private IGroupManager $groupManager,
31
-		private IDateTimeFormatter $dateTimeFormatter,
32
-		private IFactory $l10nFactory,
33
-		private IRegistry $subscriptionRegistry,
34
-		private IUserManager $userManager,
35
-		private LoggerInterface $logger,
36
-		private IInitialState $initialState,
37
-	) {
38
-	}
39
-
40
-	public function getForm(): TemplateResponse {
41
-		$lastUpdateCheckTimestamp = $this->appConfig->getValueInt('core', 'lastupdatedat');
42
-		$lastUpdateCheck = $this->dateTimeFormatter->formatDateTime($lastUpdateCheckTimestamp);
43
-
44
-		$channels = [
45
-			'daily',
46
-			'beta',
47
-			'stable',
48
-			'production',
49
-		];
50
-		$currentChannel = Util::getChannel();
51
-		if ($currentChannel === 'git') {
52
-			$channels[] = 'git';
53
-		}
54
-
55
-		$updateState = $this->updateChecker->getUpdateState();
56
-
57
-		$notifyGroups = json_decode($this->config->getAppValue('updatenotification', 'notify_groups', '["admin"]'), true);
58
-
59
-		$defaultUpdateServerURL = 'https://updates.nextcloud.com/updater_server/';
60
-		$updateServerURL = $this->config->getSystemValue('updater.server.url', $defaultUpdateServerURL);
61
-		$defaultCustomerUpdateServerURLPrefix = 'https://updates.nextcloud.com/customers/';
62
-
63
-		$isDefaultUpdateServerURL = $updateServerURL === $defaultUpdateServerURL
64
-			|| strpos($updateServerURL, $defaultCustomerUpdateServerURLPrefix) === 0;
65
-
66
-		$hasValidSubscription = $this->subscriptionRegistry->delegateHasValidSubscription();
67
-
68
-		$params = [
69
-			'isNewVersionAvailable' => !empty($updateState['updateAvailable']),
70
-			'isUpdateChecked' => $lastUpdateCheckTimestamp > 0,
71
-			'lastChecked' => $lastUpdateCheck,
72
-			'currentChannel' => $currentChannel,
73
-			'channels' => $channels,
74
-			'newVersion' => empty($updateState['updateVersion']) ? '' : $updateState['updateVersion'],
75
-			'newVersionString' => empty($updateState['updateVersionString']) ? '' : $updateState['updateVersionString'],
76
-			'downloadLink' => empty($updateState['downloadLink']) ? '' : $updateState['downloadLink'],
77
-			'changes' => $this->filterChanges($updateState['changes'] ?? []),
78
-			'webUpdaterEnabled' => !$this->config->getSystemValue('upgrade.disable-web', false),
79
-			'isWebUpdaterRecommended' => $this->isWebUpdaterRecommended(),
80
-			'updaterEnabled' => empty($updateState['updaterEnabled']) ? false : $updateState['updaterEnabled'],
81
-			'versionIsEol' => empty($updateState['versionIsEol']) ? false : $updateState['versionIsEol'],
82
-			'isDefaultUpdateServerURL' => $isDefaultUpdateServerURL,
83
-			'updateServerURL' => $updateServerURL,
84
-			'notifyGroups' => $this->getSelectedGroups($notifyGroups),
85
-			'hasValidSubscription' => $hasValidSubscription,
86
-		];
87
-		$this->initialState->provideInitialState('data', $params);
88
-
89
-		return new TemplateResponse('updatenotification', 'admin', [], '');
90
-	}
91
-
92
-	protected function filterChanges(array $changes): array {
93
-		$filtered = [];
94
-		if (isset($changes['changelogURL'])) {
95
-			$filtered['changelogURL'] = $changes['changelogURL'];
96
-		}
97
-		if (!isset($changes['whatsNew'])) {
98
-			return $filtered;
99
-		}
100
-
101
-		$iterator = $this->l10nFactory->getLanguageIterator();
102
-		do {
103
-			$lang = $iterator->current();
104
-			if (isset($changes['whatsNew'][$lang])) {
105
-				$filtered['whatsNew'] = $changes['whatsNew'][$lang];
106
-				return $filtered;
107
-			}
108
-			$iterator->next();
109
-		} while ($lang !== 'en' && $iterator->valid());
110
-
111
-		return $filtered;
112
-	}
113
-
114
-	/**
115
-	 * @param list<string> $groupIds
116
-	 * @return list<array{id: string, displayname: string}>
117
-	 */
118
-	protected function getSelectedGroups(array $groupIds): array {
119
-		$result = [];
120
-		foreach ($groupIds as $groupId) {
121
-			$group = $this->groupManager->get($groupId);
122
-
123
-			if ($group === null) {
124
-				continue;
125
-			}
126
-
127
-			$result[] = ['id' => $group->getGID(), 'displayname' => $group->getDisplayName()];
128
-		}
129
-
130
-		return $result;
131
-	}
132
-
133
-	public function getSection(): ?string {
134
-		if (!$this->config->getSystemValueBool('updatechecker', true)) {
135
-			// update checker is disabled so we do not show the section at all
136
-			return null;
137
-		}
138
-
139
-		return 'overview';
140
-	}
141
-
142
-	public function getPriority(): int {
143
-		return 11;
144
-	}
145
-
146
-	private function isWebUpdaterRecommended(): bool {
147
-		return (int)$this->userManager->countUsersTotal(100) < 100;
148
-	}
26
+    public function __construct(
27
+        private IConfig $config,
28
+        private IAppConfig $appConfig,
29
+        private UpdateChecker $updateChecker,
30
+        private IGroupManager $groupManager,
31
+        private IDateTimeFormatter $dateTimeFormatter,
32
+        private IFactory $l10nFactory,
33
+        private IRegistry $subscriptionRegistry,
34
+        private IUserManager $userManager,
35
+        private LoggerInterface $logger,
36
+        private IInitialState $initialState,
37
+    ) {
38
+    }
39
+
40
+    public function getForm(): TemplateResponse {
41
+        $lastUpdateCheckTimestamp = $this->appConfig->getValueInt('core', 'lastupdatedat');
42
+        $lastUpdateCheck = $this->dateTimeFormatter->formatDateTime($lastUpdateCheckTimestamp);
43
+
44
+        $channels = [
45
+            'daily',
46
+            'beta',
47
+            'stable',
48
+            'production',
49
+        ];
50
+        $currentChannel = Util::getChannel();
51
+        if ($currentChannel === 'git') {
52
+            $channels[] = 'git';
53
+        }
54
+
55
+        $updateState = $this->updateChecker->getUpdateState();
56
+
57
+        $notifyGroups = json_decode($this->config->getAppValue('updatenotification', 'notify_groups', '["admin"]'), true);
58
+
59
+        $defaultUpdateServerURL = 'https://updates.nextcloud.com/updater_server/';
60
+        $updateServerURL = $this->config->getSystemValue('updater.server.url', $defaultUpdateServerURL);
61
+        $defaultCustomerUpdateServerURLPrefix = 'https://updates.nextcloud.com/customers/';
62
+
63
+        $isDefaultUpdateServerURL = $updateServerURL === $defaultUpdateServerURL
64
+            || strpos($updateServerURL, $defaultCustomerUpdateServerURLPrefix) === 0;
65
+
66
+        $hasValidSubscription = $this->subscriptionRegistry->delegateHasValidSubscription();
67
+
68
+        $params = [
69
+            'isNewVersionAvailable' => !empty($updateState['updateAvailable']),
70
+            'isUpdateChecked' => $lastUpdateCheckTimestamp > 0,
71
+            'lastChecked' => $lastUpdateCheck,
72
+            'currentChannel' => $currentChannel,
73
+            'channels' => $channels,
74
+            'newVersion' => empty($updateState['updateVersion']) ? '' : $updateState['updateVersion'],
75
+            'newVersionString' => empty($updateState['updateVersionString']) ? '' : $updateState['updateVersionString'],
76
+            'downloadLink' => empty($updateState['downloadLink']) ? '' : $updateState['downloadLink'],
77
+            'changes' => $this->filterChanges($updateState['changes'] ?? []),
78
+            'webUpdaterEnabled' => !$this->config->getSystemValue('upgrade.disable-web', false),
79
+            'isWebUpdaterRecommended' => $this->isWebUpdaterRecommended(),
80
+            'updaterEnabled' => empty($updateState['updaterEnabled']) ? false : $updateState['updaterEnabled'],
81
+            'versionIsEol' => empty($updateState['versionIsEol']) ? false : $updateState['versionIsEol'],
82
+            'isDefaultUpdateServerURL' => $isDefaultUpdateServerURL,
83
+            'updateServerURL' => $updateServerURL,
84
+            'notifyGroups' => $this->getSelectedGroups($notifyGroups),
85
+            'hasValidSubscription' => $hasValidSubscription,
86
+        ];
87
+        $this->initialState->provideInitialState('data', $params);
88
+
89
+        return new TemplateResponse('updatenotification', 'admin', [], '');
90
+    }
91
+
92
+    protected function filterChanges(array $changes): array {
93
+        $filtered = [];
94
+        if (isset($changes['changelogURL'])) {
95
+            $filtered['changelogURL'] = $changes['changelogURL'];
96
+        }
97
+        if (!isset($changes['whatsNew'])) {
98
+            return $filtered;
99
+        }
100
+
101
+        $iterator = $this->l10nFactory->getLanguageIterator();
102
+        do {
103
+            $lang = $iterator->current();
104
+            if (isset($changes['whatsNew'][$lang])) {
105
+                $filtered['whatsNew'] = $changes['whatsNew'][$lang];
106
+                return $filtered;
107
+            }
108
+            $iterator->next();
109
+        } while ($lang !== 'en' && $iterator->valid());
110
+
111
+        return $filtered;
112
+    }
113
+
114
+    /**
115
+     * @param list<string> $groupIds
116
+     * @return list<array{id: string, displayname: string}>
117
+     */
118
+    protected function getSelectedGroups(array $groupIds): array {
119
+        $result = [];
120
+        foreach ($groupIds as $groupId) {
121
+            $group = $this->groupManager->get($groupId);
122
+
123
+            if ($group === null) {
124
+                continue;
125
+            }
126
+
127
+            $result[] = ['id' => $group->getGID(), 'displayname' => $group->getDisplayName()];
128
+        }
129
+
130
+        return $result;
131
+    }
132
+
133
+    public function getSection(): ?string {
134
+        if (!$this->config->getSystemValueBool('updatechecker', true)) {
135
+            // update checker is disabled so we do not show the section at all
136
+            return null;
137
+        }
138
+
139
+        return 'overview';
140
+    }
141
+
142
+    public function getPriority(): int {
143
+        return 11;
144
+    }
145
+
146
+    private function isWebUpdaterRecommended(): bool {
147
+        return (int)$this->userManager->countUsersTotal(100) < 100;
148
+    }
149 149
 }
Please login to merge, or discard this patch.
apps/updatenotification/lib/BackgroundJob/UpdateAvailableNotifications.php 1 patch
Indentation   +214 added lines, -214 removed lines patch added patch discarded remove patch
@@ -21,218 +21,218 @@
 block discarded – undo
21 21
 use OCP\ServerVersion;
22 22
 
23 23
 class UpdateAvailableNotifications extends TimedJob {
24
-	protected $connectionNotifications = [3, 7, 14, 30];
25
-
26
-	/** @var string[] */
27
-	protected $users;
28
-
29
-	public function __construct(
30
-		ITimeFactory $timeFactory,
31
-		protected ServerVersion $serverVersion,
32
-		protected IConfig $config,
33
-		protected IAppConfig $appConfig,
34
-		protected IManager $notificationManager,
35
-		protected IGroupManager $groupManager,
36
-		protected IAppManager $appManager,
37
-		protected Installer $installer,
38
-		protected VersionCheck $versionCheck,
39
-	) {
40
-		parent::__construct($timeFactory);
41
-		// Run once a day
42
-		$this->setInterval(60 * 60 * 24);
43
-		$this->setTimeSensitivity(self::TIME_INSENSITIVE);
44
-	}
45
-
46
-	protected function run($argument) {
47
-		// Do not check for updates if not connected to the internet
48
-		if (!$this->config->getSystemValueBool('has_internet_connection', true)) {
49
-			return;
50
-		}
51
-
52
-		if (\OC::$CLI && !$this->config->getSystemValueBool('debug', false)) {
53
-			try {
54
-				// Jitter the pinging of the updater server and the appstore a bit.
55
-				// Otherwise all Nextcloud installations are pinging the servers
56
-				// in one of 288
57
-				sleep(random_int(1, 180));
58
-			} catch (\Exception $e) {
59
-			}
60
-		}
61
-
62
-		$this->checkCoreUpdate();
63
-		$this->checkAppUpdates();
64
-	}
65
-
66
-	/**
67
-	 * Check for Nextcloud server update
68
-	 */
69
-	protected function checkCoreUpdate() {
70
-		if (!$this->config->getSystemValueBool('updatechecker', true)) {
71
-			// update checker is disabled so no core update check!
72
-			return;
73
-		}
74
-
75
-		if (\in_array($this->serverVersion->getChannel(), ['daily', 'git'], true)) {
76
-			// "These aren't the update channels you're looking for." - Ben Obi-Wan Kenobi
77
-			return;
78
-		}
79
-
80
-		$status = $this->versionCheck->check();
81
-		if ($status === false) {
82
-			$errors = 1 + $this->appConfig->getAppValueInt('update_check_errors', 0);
83
-			$this->appConfig->setAppValueInt('update_check_errors', $errors);
84
-
85
-			if (\in_array($errors, $this->connectionNotifications, true)) {
86
-				$this->sendErrorNotifications($errors);
87
-			}
88
-		} elseif (\is_array($status)) {
89
-			$this->appConfig->setAppValueInt('update_check_errors', 0);
90
-			$this->clearErrorNotifications();
91
-
92
-			if (isset($status['version'])) {
93
-				$this->createNotifications('core', $status['version'], $status['versionstring']);
94
-			}
95
-		}
96
-	}
97
-
98
-	/**
99
-	 * Send a message to the admin when the update server could not be reached
100
-	 * @param int $numDays
101
-	 */
102
-	protected function sendErrorNotifications($numDays) {
103
-		$this->clearErrorNotifications();
104
-
105
-		$notification = $this->notificationManager->createNotification();
106
-		try {
107
-			$notification->setApp('updatenotification')
108
-				->setDateTime(new \DateTime())
109
-				->setObject('updatenotification', 'error')
110
-				->setSubject('connection_error', ['days' => $numDays]);
111
-
112
-			foreach ($this->getUsersToNotify() as $uid) {
113
-				$notification->setUser($uid);
114
-				$this->notificationManager->notify($notification);
115
-			}
116
-		} catch (\InvalidArgumentException $e) {
117
-			return;
118
-		}
119
-	}
120
-
121
-	/**
122
-	 * Remove error notifications again
123
-	 */
124
-	protected function clearErrorNotifications() {
125
-		$notification = $this->notificationManager->createNotification();
126
-		try {
127
-			$notification->setApp('updatenotification')
128
-				->setSubject('connection_error')
129
-				->setObject('updatenotification', 'error');
130
-		} catch (\InvalidArgumentException $e) {
131
-			return;
132
-		}
133
-		$this->notificationManager->markProcessed($notification);
134
-	}
135
-
136
-	/**
137
-	 * Check all installed apps for updates
138
-	 */
139
-	protected function checkAppUpdates() {
140
-		$apps = $this->appManager->getEnabledApps();
141
-		foreach ($apps as $app) {
142
-			$update = $this->isUpdateAvailable($app);
143
-			if ($update !== false) {
144
-				$this->createNotifications($app, $update);
145
-			}
146
-		}
147
-	}
148
-
149
-	/**
150
-	 * Create notifications for this app version
151
-	 *
152
-	 * @param string $app
153
-	 * @param string $version
154
-	 * @param string $visibleVersion
155
-	 */
156
-	protected function createNotifications($app, $version, $visibleVersion = '') {
157
-		$lastNotification = $this->appConfig->getAppValueString($app, '');
158
-		if ($lastNotification === $version) {
159
-			// We already notified about this update
160
-			return;
161
-		}
162
-
163
-		if ($lastNotification !== '') {
164
-			// Delete old updates
165
-			$this->deleteOutdatedNotifications($app, $lastNotification);
166
-		}
167
-
168
-		$notification = $this->notificationManager->createNotification();
169
-		try {
170
-			$notification->setApp('updatenotification')
171
-				->setDateTime(new \DateTime())
172
-				->setObject($app, $version);
173
-
174
-			if ($visibleVersion !== '') {
175
-				$notification->setSubject('update_available', ['version' => $visibleVersion]);
176
-			} else {
177
-				$notification->setSubject('update_available');
178
-			}
179
-
180
-			foreach ($this->getUsersToNotify() as $uid) {
181
-				$notification->setUser($uid);
182
-				$this->notificationManager->notify($notification);
183
-			}
184
-		} catch (\InvalidArgumentException $e) {
185
-			return;
186
-		}
187
-
188
-		$this->appConfig->setAppValueString($app, $version);
189
-	}
190
-
191
-	/**
192
-	 * @return string[]
193
-	 */
194
-	protected function getUsersToNotify(): array {
195
-		if ($this->users !== null) {
196
-			return $this->users;
197
-		}
198
-
199
-		$notifyGroups = $this->appConfig->getAppValueArray('notify_groups', ['admin']);
200
-		$this->users = [];
201
-		foreach ($notifyGroups as $group) {
202
-			$groupToNotify = $this->groupManager->get($group);
203
-			if ($groupToNotify instanceof IGroup) {
204
-				foreach ($groupToNotify->getUsers() as $user) {
205
-					$this->users[] = $user->getUID();
206
-				}
207
-			}
208
-		}
209
-
210
-		$this->users = array_values(array_unique($this->users));
211
-		return $this->users;
212
-	}
213
-
214
-	/**
215
-	 * Delete notifications for old updates
216
-	 *
217
-	 * @param string $app
218
-	 * @param string $version
219
-	 */
220
-	protected function deleteOutdatedNotifications($app, $version) {
221
-		$notification = $this->notificationManager->createNotification();
222
-		try {
223
-			$notification->setApp('updatenotification')
224
-				->setObject($app, $version);
225
-		} catch (\InvalidArgumentException $e) {
226
-			return;
227
-		}
228
-		$this->notificationManager->markProcessed($notification);
229
-	}
230
-
231
-	/**
232
-	 * @param string $app
233
-	 * @return string|false
234
-	 */
235
-	protected function isUpdateAvailable($app) {
236
-		return $this->installer->isUpdateAvailable($app);
237
-	}
24
+    protected $connectionNotifications = [3, 7, 14, 30];
25
+
26
+    /** @var string[] */
27
+    protected $users;
28
+
29
+    public function __construct(
30
+        ITimeFactory $timeFactory,
31
+        protected ServerVersion $serverVersion,
32
+        protected IConfig $config,
33
+        protected IAppConfig $appConfig,
34
+        protected IManager $notificationManager,
35
+        protected IGroupManager $groupManager,
36
+        protected IAppManager $appManager,
37
+        protected Installer $installer,
38
+        protected VersionCheck $versionCheck,
39
+    ) {
40
+        parent::__construct($timeFactory);
41
+        // Run once a day
42
+        $this->setInterval(60 * 60 * 24);
43
+        $this->setTimeSensitivity(self::TIME_INSENSITIVE);
44
+    }
45
+
46
+    protected function run($argument) {
47
+        // Do not check for updates if not connected to the internet
48
+        if (!$this->config->getSystemValueBool('has_internet_connection', true)) {
49
+            return;
50
+        }
51
+
52
+        if (\OC::$CLI && !$this->config->getSystemValueBool('debug', false)) {
53
+            try {
54
+                // Jitter the pinging of the updater server and the appstore a bit.
55
+                // Otherwise all Nextcloud installations are pinging the servers
56
+                // in one of 288
57
+                sleep(random_int(1, 180));
58
+            } catch (\Exception $e) {
59
+            }
60
+        }
61
+
62
+        $this->checkCoreUpdate();
63
+        $this->checkAppUpdates();
64
+    }
65
+
66
+    /**
67
+     * Check for Nextcloud server update
68
+     */
69
+    protected function checkCoreUpdate() {
70
+        if (!$this->config->getSystemValueBool('updatechecker', true)) {
71
+            // update checker is disabled so no core update check!
72
+            return;
73
+        }
74
+
75
+        if (\in_array($this->serverVersion->getChannel(), ['daily', 'git'], true)) {
76
+            // "These aren't the update channels you're looking for." - Ben Obi-Wan Kenobi
77
+            return;
78
+        }
79
+
80
+        $status = $this->versionCheck->check();
81
+        if ($status === false) {
82
+            $errors = 1 + $this->appConfig->getAppValueInt('update_check_errors', 0);
83
+            $this->appConfig->setAppValueInt('update_check_errors', $errors);
84
+
85
+            if (\in_array($errors, $this->connectionNotifications, true)) {
86
+                $this->sendErrorNotifications($errors);
87
+            }
88
+        } elseif (\is_array($status)) {
89
+            $this->appConfig->setAppValueInt('update_check_errors', 0);
90
+            $this->clearErrorNotifications();
91
+
92
+            if (isset($status['version'])) {
93
+                $this->createNotifications('core', $status['version'], $status['versionstring']);
94
+            }
95
+        }
96
+    }
97
+
98
+    /**
99
+     * Send a message to the admin when the update server could not be reached
100
+     * @param int $numDays
101
+     */
102
+    protected function sendErrorNotifications($numDays) {
103
+        $this->clearErrorNotifications();
104
+
105
+        $notification = $this->notificationManager->createNotification();
106
+        try {
107
+            $notification->setApp('updatenotification')
108
+                ->setDateTime(new \DateTime())
109
+                ->setObject('updatenotification', 'error')
110
+                ->setSubject('connection_error', ['days' => $numDays]);
111
+
112
+            foreach ($this->getUsersToNotify() as $uid) {
113
+                $notification->setUser($uid);
114
+                $this->notificationManager->notify($notification);
115
+            }
116
+        } catch (\InvalidArgumentException $e) {
117
+            return;
118
+        }
119
+    }
120
+
121
+    /**
122
+     * Remove error notifications again
123
+     */
124
+    protected function clearErrorNotifications() {
125
+        $notification = $this->notificationManager->createNotification();
126
+        try {
127
+            $notification->setApp('updatenotification')
128
+                ->setSubject('connection_error')
129
+                ->setObject('updatenotification', 'error');
130
+        } catch (\InvalidArgumentException $e) {
131
+            return;
132
+        }
133
+        $this->notificationManager->markProcessed($notification);
134
+    }
135
+
136
+    /**
137
+     * Check all installed apps for updates
138
+     */
139
+    protected function checkAppUpdates() {
140
+        $apps = $this->appManager->getEnabledApps();
141
+        foreach ($apps as $app) {
142
+            $update = $this->isUpdateAvailable($app);
143
+            if ($update !== false) {
144
+                $this->createNotifications($app, $update);
145
+            }
146
+        }
147
+    }
148
+
149
+    /**
150
+     * Create notifications for this app version
151
+     *
152
+     * @param string $app
153
+     * @param string $version
154
+     * @param string $visibleVersion
155
+     */
156
+    protected function createNotifications($app, $version, $visibleVersion = '') {
157
+        $lastNotification = $this->appConfig->getAppValueString($app, '');
158
+        if ($lastNotification === $version) {
159
+            // We already notified about this update
160
+            return;
161
+        }
162
+
163
+        if ($lastNotification !== '') {
164
+            // Delete old updates
165
+            $this->deleteOutdatedNotifications($app, $lastNotification);
166
+        }
167
+
168
+        $notification = $this->notificationManager->createNotification();
169
+        try {
170
+            $notification->setApp('updatenotification')
171
+                ->setDateTime(new \DateTime())
172
+                ->setObject($app, $version);
173
+
174
+            if ($visibleVersion !== '') {
175
+                $notification->setSubject('update_available', ['version' => $visibleVersion]);
176
+            } else {
177
+                $notification->setSubject('update_available');
178
+            }
179
+
180
+            foreach ($this->getUsersToNotify() as $uid) {
181
+                $notification->setUser($uid);
182
+                $this->notificationManager->notify($notification);
183
+            }
184
+        } catch (\InvalidArgumentException $e) {
185
+            return;
186
+        }
187
+
188
+        $this->appConfig->setAppValueString($app, $version);
189
+    }
190
+
191
+    /**
192
+     * @return string[]
193
+     */
194
+    protected function getUsersToNotify(): array {
195
+        if ($this->users !== null) {
196
+            return $this->users;
197
+        }
198
+
199
+        $notifyGroups = $this->appConfig->getAppValueArray('notify_groups', ['admin']);
200
+        $this->users = [];
201
+        foreach ($notifyGroups as $group) {
202
+            $groupToNotify = $this->groupManager->get($group);
203
+            if ($groupToNotify instanceof IGroup) {
204
+                foreach ($groupToNotify->getUsers() as $user) {
205
+                    $this->users[] = $user->getUID();
206
+                }
207
+            }
208
+        }
209
+
210
+        $this->users = array_values(array_unique($this->users));
211
+        return $this->users;
212
+    }
213
+
214
+    /**
215
+     * Delete notifications for old updates
216
+     *
217
+     * @param string $app
218
+     * @param string $version
219
+     */
220
+    protected function deleteOutdatedNotifications($app, $version) {
221
+        $notification = $this->notificationManager->createNotification();
222
+        try {
223
+            $notification->setApp('updatenotification')
224
+                ->setObject($app, $version);
225
+        } catch (\InvalidArgumentException $e) {
226
+            return;
227
+        }
228
+        $this->notificationManager->markProcessed($notification);
229
+    }
230
+
231
+    /**
232
+     * @param string $app
233
+     * @return string|false
234
+     */
235
+    protected function isUpdateAvailable($app) {
236
+        return $this->installer->isUpdateAvailable($app);
237
+    }
238 238
 }
Please login to merge, or discard this patch.
apps/updatenotification/tests/Settings/AdminTest.php 1 patch
Indentation   +448 added lines, -448 removed lines patch added patch discarded remove patch
@@ -26,452 +26,452 @@
 block discarded – undo
26 26
 use Test\TestCase;
27 27
 
28 28
 class AdminTest extends TestCase {
29
-	/** @var IFactory|\PHPUnit\Framework\MockObject\MockObject */
30
-	protected $l10nFactory;
31
-	/** @var Admin */
32
-	private $admin;
33
-	/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
34
-	private $config;
35
-	/** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */
36
-	private $appConfig;
37
-	/** @var UpdateChecker|\PHPUnit\Framework\MockObject\MockObject */
38
-	private $updateChecker;
39
-	/** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */
40
-	private $groupManager;
41
-	/** @var IDateTimeFormatter|\PHPUnit\Framework\MockObject\MockObject */
42
-	private $dateTimeFormatter;
43
-	/** @var IRegistry|\PHPUnit\Framework\MockObject\MockObject */
44
-	private $subscriptionRegistry;
45
-	/** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */
46
-	private $userManager;
47
-	/** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
48
-	private $logger;
49
-	/** IInitialState|\PHPUnit\Framework\MockObject\MockObject */
50
-	private $initialState;
51
-
52
-	protected function setUp(): void {
53
-		parent::setUp();
54
-
55
-		$this->config = $this->createMock(IConfig::class);
56
-		$this->appConfig = $this->createMock(IAppConfig::class);
57
-		$this->updateChecker = $this->createMock(UpdateChecker::class);
58
-		$this->groupManager = $this->createMock(IGroupManager::class);
59
-		$this->dateTimeFormatter = $this->createMock(IDateTimeFormatter::class);
60
-		$this->l10nFactory = $this->createMock(IFactory::class);
61
-		$this->subscriptionRegistry = $this->createMock(IRegistry::class);
62
-		$this->userManager = $this->createMock(IUserManager::class);
63
-		$this->logger = $this->createMock(LoggerInterface::class);
64
-		$this->initialState = $this->createMock(IInitialState::class);
65
-
66
-		$this->admin = new Admin(
67
-			$this->config,
68
-			$this->appConfig,
69
-			$this->updateChecker,
70
-			$this->groupManager,
71
-			$this->dateTimeFormatter,
72
-			$this->l10nFactory,
73
-			$this->subscriptionRegistry,
74
-			$this->userManager,
75
-			$this->logger,
76
-			$this->initialState
77
-		);
78
-	}
79
-
80
-	public function testGetFormWithUpdate(): void {
81
-		$this->userManager
82
-			->expects($this->once())
83
-			->method('countUsersTotal')
84
-			->willReturn(5);
85
-		$channels = [
86
-			'daily',
87
-			'beta',
88
-			'stable',
89
-			'production',
90
-		];
91
-		$currentChannel = Util::getChannel();
92
-		if ($currentChannel === 'git') {
93
-			$channels[] = 'git';
94
-		}
95
-		$this->appConfig
96
-			->expects($this->once())
97
-			->method('getValueInt')
98
-			->with('core', 'lastupdatedat', 0)
99
-			->willReturn(12345);
100
-		$this->config
101
-			->expects($this->once())
102
-			->method('getAppValue')
103
-			->with('updatenotification', 'notify_groups', '["admin"]')
104
-			->willReturn('["admin"]');
105
-		$this->config
106
-			->method('getSystemValue')
107
-			->willReturnMap([
108
-				['updater.server.url', 'https://updates.nextcloud.com/updater_server/', 'https://updates.nextcloud.com/updater_server/'],
109
-				['upgrade.disable-web', false, false],
110
-			]);
111
-		$this->config
112
-			->expects(self::any())
113
-			->method('getSystemValueBool')
114
-			->with('updatechecker', true)
115
-			->willReturn(true);
116
-		$this->dateTimeFormatter
117
-			->expects($this->once())
118
-			->method('formatDateTime')
119
-			->with(12345)
120
-			->willReturn('LastCheckedReturnValue');
121
-		$this->updateChecker
122
-			->expects($this->once())
123
-			->method('getUpdateState')
124
-			->willReturn([
125
-				'updateAvailable' => true,
126
-				'updateVersion' => '8.1.2',
127
-				'updateVersionString' => 'Nextcloud 8.1.2',
128
-				'downloadLink' => 'https://downloads.nextcloud.org/server',
129
-				'changes' => [],
130
-				'updaterEnabled' => true,
131
-				'versionIsEol' => false,
132
-			]);
133
-
134
-		$group = $this->createMock(IGroup::class);
135
-		$group->expects($this->any())
136
-			->method('getDisplayName')
137
-			->willReturn('Administrators');
138
-		$group->expects($this->any())
139
-			->method('getGID')
140
-			->willReturn('admin');
141
-		$this->groupManager->expects($this->once())
142
-			->method('get')
143
-			->with('admin')
144
-			->willReturn($group);
145
-
146
-		$this->subscriptionRegistry
147
-			->expects($this->once())
148
-			->method('delegateHasValidSubscription')
149
-			->willReturn(true);
150
-
151
-		$this->initialState->expects($this->once())
152
-			->method('provideInitialState')
153
-			->with('data', [
154
-				'isNewVersionAvailable' => true,
155
-				'isUpdateChecked' => true,
156
-				'lastChecked' => 'LastCheckedReturnValue',
157
-				'currentChannel' => Util::getChannel(),
158
-				'channels' => $channels,
159
-				'newVersion' => '8.1.2',
160
-				'newVersionString' => 'Nextcloud 8.1.2',
161
-				'downloadLink' => 'https://downloads.nextcloud.org/server',
162
-				'changes' => [],
163
-				'webUpdaterEnabled' => true,
164
-				'isWebUpdaterRecommended' => true,
165
-				'updaterEnabled' => true,
166
-				'versionIsEol' => false,
167
-				'isDefaultUpdateServerURL' => true,
168
-				'updateServerURL' => 'https://updates.nextcloud.com/updater_server/',
169
-				'notifyGroups' => [
170
-					['id' => 'admin', 'displayname' => 'Administrators'],
171
-				],
172
-				'hasValidSubscription' => true,
173
-			]);
174
-
175
-		$expected = new TemplateResponse('updatenotification', 'admin', [], '');
176
-		$this->assertEquals($expected, $this->admin->getForm());
177
-	}
178
-
179
-	public function testGetFormWithUpdateAndChangedUpdateServer(): void {
180
-		$this->userManager
181
-			->expects($this->once())
182
-			->method('countUsersTotal')
183
-			->willReturn(5);
184
-		$channels = [
185
-			'daily',
186
-			'beta',
187
-			'stable',
188
-			'production',
189
-		];
190
-		$currentChannel = Util::getChannel();
191
-		if ($currentChannel === 'git') {
192
-			$channels[] = 'git';
193
-		}
194
-
195
-		$this->appConfig
196
-			->expects($this->once())
197
-			->method('getValueInt')
198
-			->with('core', 'lastupdatedat', 0)
199
-			->willReturn(12345);
200
-		$this->config
201
-			->expects(self::any())
202
-			->method('getSystemValueBool')
203
-			->with('updatechecker', true)
204
-			->willReturn(true);
205
-		$this->config
206
-			->expects($this->once())
207
-			->method('getAppValue')
208
-			->with('updatenotification', 'notify_groups', '["admin"]')
209
-			->willReturn('["admin"]');
210
-		$this->config
211
-			->method('getSystemValue')
212
-			->willReturnMap([
213
-				['updater.server.url', 'https://updates.nextcloud.com/updater_server/', 'https://updates.nextcloud.com/updater_server_changed/'],
214
-				['upgrade.disable-web', false, true],
215
-			]);
216
-		$this->dateTimeFormatter
217
-			->expects($this->once())
218
-			->method('formatDateTime')
219
-			->with('12345')
220
-			->willReturn('LastCheckedReturnValue');
221
-		$this->updateChecker
222
-			->expects($this->once())
223
-			->method('getUpdateState')
224
-			->willReturn([
225
-				'updateAvailable' => true,
226
-				'updateVersion' => '8.1.2',
227
-				'updateVersionString' => 'Nextcloud 8.1.2',
228
-				'downloadLink' => 'https://downloads.nextcloud.org/server',
229
-				'changes' => [],
230
-				'updaterEnabled' => true,
231
-				'versionIsEol' => false,
232
-			]);
233
-
234
-		$group = $this->createMock(IGroup::class);
235
-		$group->expects($this->any())
236
-			->method('getDisplayName')
237
-			->willReturn('Administrators');
238
-		$group->expects($this->any())
239
-			->method('getGID')
240
-			->willReturn('admin');
241
-		$this->groupManager->expects($this->once())
242
-			->method('get')
243
-			->with('admin')
244
-			->willReturn($group);
245
-
246
-		$this->subscriptionRegistry
247
-			->expects($this->once())
248
-			->method('delegateHasValidSubscription')
249
-			->willReturn(true);
250
-
251
-		$this->initialState->expects($this->once())
252
-			->method('provideInitialState')
253
-			->with('data', [
254
-				'isNewVersionAvailable' => true,
255
-				'isUpdateChecked' => true,
256
-				'lastChecked' => 'LastCheckedReturnValue',
257
-				'currentChannel' => Util::getChannel(),
258
-				'channels' => $channels,
259
-				'newVersion' => '8.1.2',
260
-				'newVersionString' => 'Nextcloud 8.1.2',
261
-				'downloadLink' => 'https://downloads.nextcloud.org/server',
262
-				'changes' => [],
263
-				'webUpdaterEnabled' => false,
264
-				'isWebUpdaterRecommended' => true,
265
-				'updaterEnabled' => true,
266
-				'versionIsEol' => false,
267
-				'isDefaultUpdateServerURL' => false,
268
-				'updateServerURL' => 'https://updates.nextcloud.com/updater_server_changed/',
269
-				'notifyGroups' => [
270
-					['id' => 'admin', 'displayname' => 'Administrators'],
271
-				],
272
-				'hasValidSubscription' => true,
273
-			]);
274
-
275
-		$expected = new TemplateResponse('updatenotification', 'admin', [], '');
276
-		$this->assertEquals($expected, $this->admin->getForm());
277
-	}
278
-
279
-	public function testGetFormWithUpdateAndCustomersUpdateServer(): void {
280
-		$this->userManager
281
-			->expects($this->once())
282
-			->method('countUsersTotal')
283
-			->willReturn(5);
284
-		$channels = [
285
-			'daily',
286
-			'beta',
287
-			'stable',
288
-			'production',
289
-		];
290
-		$currentChannel = Util::getChannel();
291
-		if ($currentChannel === 'git') {
292
-			$channels[] = 'git';
293
-		}
294
-
295
-		$this->appConfig
296
-			->expects($this->once())
297
-			->method('getValueInt')
298
-			->with('core', 'lastupdatedat', 0)
299
-			->willReturn(12345);
300
-		$this->config
301
-			->expects(self::any())
302
-			->method('getSystemValueBool')
303
-			->with('updatechecker', true)
304
-			->willReturn(true);
305
-		$this->config
306
-			->expects($this->once())
307
-			->method('getAppValue')
308
-			->with('updatenotification', 'notify_groups', '["admin"]')
309
-			->willReturn('["admin"]');
310
-		$this->config
311
-			->method('getSystemValue')
312
-			->willReturnMap([
313
-				['updater.server.url', 'https://updates.nextcloud.com/updater_server/', 'https://updates.nextcloud.com/customers/ABC-DEF/'],
314
-				['upgrade.disable-web', false, false],
315
-			]);
316
-		$this->dateTimeFormatter
317
-			->expects($this->once())
318
-			->method('formatDateTime')
319
-			->with('12345')
320
-			->willReturn('LastCheckedReturnValue');
321
-		$this->updateChecker
322
-			->expects($this->once())
323
-			->method('getUpdateState')
324
-			->willReturn([
325
-				'updateAvailable' => true,
326
-				'updateVersion' => '8.1.2',
327
-				'updateVersionString' => 'Nextcloud 8.1.2',
328
-				'downloadLink' => 'https://downloads.nextcloud.org/server',
329
-				'changes' => [],
330
-				'updaterEnabled' => true,
331
-				'versionIsEol' => false,
332
-			]);
333
-
334
-		$group = $this->createMock(IGroup::class);
335
-		$group->expects($this->any())
336
-			->method('getDisplayName')
337
-			->willReturn('Administrators');
338
-		$group->expects($this->any())
339
-			->method('getGID')
340
-			->willReturn('admin');
341
-		$this->groupManager->expects($this->once())
342
-			->method('get')
343
-			->with('admin')
344
-			->willReturn($group);
345
-
346
-		$this->subscriptionRegistry
347
-			->expects($this->once())
348
-			->method('delegateHasValidSubscription')
349
-			->willReturn(true);
350
-
351
-		$this->initialState->expects($this->once())
352
-			->method('provideInitialState')
353
-			->with('data', [
354
-				'isNewVersionAvailable' => true,
355
-				'isUpdateChecked' => true,
356
-				'lastChecked' => 'LastCheckedReturnValue',
357
-				'currentChannel' => Util::getChannel(),
358
-				'channels' => $channels,
359
-				'newVersion' => '8.1.2',
360
-				'newVersionString' => 'Nextcloud 8.1.2',
361
-				'downloadLink' => 'https://downloads.nextcloud.org/server',
362
-				'changes' => [],
363
-				'webUpdaterEnabled' => true,
364
-				'isWebUpdaterRecommended' => true,
365
-				'updaterEnabled' => true,
366
-				'versionIsEol' => false,
367
-				'isDefaultUpdateServerURL' => true,
368
-				'updateServerURL' => 'https://updates.nextcloud.com/customers/ABC-DEF/',
369
-				'notifyGroups' => [
370
-					['id' => 'admin', 'displayname' => 'Administrators'],
371
-				],
372
-				'hasValidSubscription' => true,
373
-			]);
374
-
375
-		$expected = new TemplateResponse('updatenotification', 'admin', [], '');
376
-		$this->assertEquals($expected, $this->admin->getForm());
377
-	}
378
-
379
-
380
-	public function testGetSection(): void {
381
-		$this->config
382
-			->expects(self::atLeastOnce())
383
-			->method('getSystemValueBool')
384
-			->with('updatechecker', true)
385
-			->willReturn(true);
386
-
387
-		$this->assertSame('overview', $this->admin->getSection());
388
-	}
389
-
390
-	public function testGetSectionDisabled(): void {
391
-		$this->config
392
-			->expects(self::atLeastOnce())
393
-			->method('getSystemValueBool')
394
-			->with('updatechecker', true)
395
-			->willReturn(false);
396
-
397
-		$this->assertNull($this->admin->getSection());
398
-	}
399
-
400
-	public function testGetPriority(): void {
401
-		$this->assertSame(11, $this->admin->getPriority());
402
-	}
403
-
404
-	public function changesProvider() {
405
-		return [
406
-			[ #0, all info, en
407
-				[
408
-					'changelogURL' => 'https://go.to.changelog',
409
-					'whatsNew' => [
410
-						'en' => [
411
-							'regular' => ['content'],
412
-						],
413
-						'de' => [
414
-							'regular' => ['inhalt'],
415
-						]
416
-					],
417
-				],
418
-				'en',
419
-				[
420
-					'changelogURL' => 'https://go.to.changelog',
421
-					'whatsNew' => [
422
-						'regular' => ['content'],
423
-					],
424
-				]
425
-			],
426
-			[ #1, all info, de
427
-				[
428
-					'changelogURL' => 'https://go.to.changelog',
429
-					'whatsNew' => [
430
-						'en' => [
431
-							'regular' => ['content'],
432
-						],
433
-						'de' => [
434
-							'regular' => ['inhalt'],
435
-						]
436
-					],
437
-				],
438
-				'de',
439
-				[
440
-					'changelogURL' => 'https://go.to.changelog',
441
-					'whatsNew' => [
442
-						'regular' => ['inhalt'],
443
-					]
444
-				],
445
-			],
446
-			[ #2, just changelog
447
-				[ 'changelogURL' => 'https://go.to.changelog' ],
448
-				'en',
449
-				[ 'changelogURL' => 'https://go.to.changelog' ],
450
-			],
451
-			[ #3 nothing
452
-				[],
453
-				'ru',
454
-				[]
455
-			]
456
-		];
457
-	}
458
-
459
-	/**
460
-	 * @dataProvider changesProvider
461
-	 */
462
-	public function testFilterChanges($changes, $userLang, $expectation): void {
463
-		$iterator = $this->createMock(ILanguageIterator::class);
464
-		$iterator->expects($this->any())
465
-			->method('current')
466
-			->willReturnOnConsecutiveCalls('es', $userLang, 'it', 'en');
467
-		$iterator->expects($this->any())
468
-			->method('valid')
469
-			->willReturn(true);
470
-
471
-		$this->l10nFactory->expects($this->atMost(1))
472
-			->method('getLanguageIterator')
473
-			->willReturn($iterator);
474
-		$result = $this->invokePrivate($this->admin, 'filterChanges', [$changes]);
475
-		$this->assertSame($expectation, $result);
476
-	}
29
+    /** @var IFactory|\PHPUnit\Framework\MockObject\MockObject */
30
+    protected $l10nFactory;
31
+    /** @var Admin */
32
+    private $admin;
33
+    /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
34
+    private $config;
35
+    /** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */
36
+    private $appConfig;
37
+    /** @var UpdateChecker|\PHPUnit\Framework\MockObject\MockObject */
38
+    private $updateChecker;
39
+    /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */
40
+    private $groupManager;
41
+    /** @var IDateTimeFormatter|\PHPUnit\Framework\MockObject\MockObject */
42
+    private $dateTimeFormatter;
43
+    /** @var IRegistry|\PHPUnit\Framework\MockObject\MockObject */
44
+    private $subscriptionRegistry;
45
+    /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */
46
+    private $userManager;
47
+    /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
48
+    private $logger;
49
+    /** IInitialState|\PHPUnit\Framework\MockObject\MockObject */
50
+    private $initialState;
51
+
52
+    protected function setUp(): void {
53
+        parent::setUp();
54
+
55
+        $this->config = $this->createMock(IConfig::class);
56
+        $this->appConfig = $this->createMock(IAppConfig::class);
57
+        $this->updateChecker = $this->createMock(UpdateChecker::class);
58
+        $this->groupManager = $this->createMock(IGroupManager::class);
59
+        $this->dateTimeFormatter = $this->createMock(IDateTimeFormatter::class);
60
+        $this->l10nFactory = $this->createMock(IFactory::class);
61
+        $this->subscriptionRegistry = $this->createMock(IRegistry::class);
62
+        $this->userManager = $this->createMock(IUserManager::class);
63
+        $this->logger = $this->createMock(LoggerInterface::class);
64
+        $this->initialState = $this->createMock(IInitialState::class);
65
+
66
+        $this->admin = new Admin(
67
+            $this->config,
68
+            $this->appConfig,
69
+            $this->updateChecker,
70
+            $this->groupManager,
71
+            $this->dateTimeFormatter,
72
+            $this->l10nFactory,
73
+            $this->subscriptionRegistry,
74
+            $this->userManager,
75
+            $this->logger,
76
+            $this->initialState
77
+        );
78
+    }
79
+
80
+    public function testGetFormWithUpdate(): void {
81
+        $this->userManager
82
+            ->expects($this->once())
83
+            ->method('countUsersTotal')
84
+            ->willReturn(5);
85
+        $channels = [
86
+            'daily',
87
+            'beta',
88
+            'stable',
89
+            'production',
90
+        ];
91
+        $currentChannel = Util::getChannel();
92
+        if ($currentChannel === 'git') {
93
+            $channels[] = 'git';
94
+        }
95
+        $this->appConfig
96
+            ->expects($this->once())
97
+            ->method('getValueInt')
98
+            ->with('core', 'lastupdatedat', 0)
99
+            ->willReturn(12345);
100
+        $this->config
101
+            ->expects($this->once())
102
+            ->method('getAppValue')
103
+            ->with('updatenotification', 'notify_groups', '["admin"]')
104
+            ->willReturn('["admin"]');
105
+        $this->config
106
+            ->method('getSystemValue')
107
+            ->willReturnMap([
108
+                ['updater.server.url', 'https://updates.nextcloud.com/updater_server/', 'https://updates.nextcloud.com/updater_server/'],
109
+                ['upgrade.disable-web', false, false],
110
+            ]);
111
+        $this->config
112
+            ->expects(self::any())
113
+            ->method('getSystemValueBool')
114
+            ->with('updatechecker', true)
115
+            ->willReturn(true);
116
+        $this->dateTimeFormatter
117
+            ->expects($this->once())
118
+            ->method('formatDateTime')
119
+            ->with(12345)
120
+            ->willReturn('LastCheckedReturnValue');
121
+        $this->updateChecker
122
+            ->expects($this->once())
123
+            ->method('getUpdateState')
124
+            ->willReturn([
125
+                'updateAvailable' => true,
126
+                'updateVersion' => '8.1.2',
127
+                'updateVersionString' => 'Nextcloud 8.1.2',
128
+                'downloadLink' => 'https://downloads.nextcloud.org/server',
129
+                'changes' => [],
130
+                'updaterEnabled' => true,
131
+                'versionIsEol' => false,
132
+            ]);
133
+
134
+        $group = $this->createMock(IGroup::class);
135
+        $group->expects($this->any())
136
+            ->method('getDisplayName')
137
+            ->willReturn('Administrators');
138
+        $group->expects($this->any())
139
+            ->method('getGID')
140
+            ->willReturn('admin');
141
+        $this->groupManager->expects($this->once())
142
+            ->method('get')
143
+            ->with('admin')
144
+            ->willReturn($group);
145
+
146
+        $this->subscriptionRegistry
147
+            ->expects($this->once())
148
+            ->method('delegateHasValidSubscription')
149
+            ->willReturn(true);
150
+
151
+        $this->initialState->expects($this->once())
152
+            ->method('provideInitialState')
153
+            ->with('data', [
154
+                'isNewVersionAvailable' => true,
155
+                'isUpdateChecked' => true,
156
+                'lastChecked' => 'LastCheckedReturnValue',
157
+                'currentChannel' => Util::getChannel(),
158
+                'channels' => $channels,
159
+                'newVersion' => '8.1.2',
160
+                'newVersionString' => 'Nextcloud 8.1.2',
161
+                'downloadLink' => 'https://downloads.nextcloud.org/server',
162
+                'changes' => [],
163
+                'webUpdaterEnabled' => true,
164
+                'isWebUpdaterRecommended' => true,
165
+                'updaterEnabled' => true,
166
+                'versionIsEol' => false,
167
+                'isDefaultUpdateServerURL' => true,
168
+                'updateServerURL' => 'https://updates.nextcloud.com/updater_server/',
169
+                'notifyGroups' => [
170
+                    ['id' => 'admin', 'displayname' => 'Administrators'],
171
+                ],
172
+                'hasValidSubscription' => true,
173
+            ]);
174
+
175
+        $expected = new TemplateResponse('updatenotification', 'admin', [], '');
176
+        $this->assertEquals($expected, $this->admin->getForm());
177
+    }
178
+
179
+    public function testGetFormWithUpdateAndChangedUpdateServer(): void {
180
+        $this->userManager
181
+            ->expects($this->once())
182
+            ->method('countUsersTotal')
183
+            ->willReturn(5);
184
+        $channels = [
185
+            'daily',
186
+            'beta',
187
+            'stable',
188
+            'production',
189
+        ];
190
+        $currentChannel = Util::getChannel();
191
+        if ($currentChannel === 'git') {
192
+            $channels[] = 'git';
193
+        }
194
+
195
+        $this->appConfig
196
+            ->expects($this->once())
197
+            ->method('getValueInt')
198
+            ->with('core', 'lastupdatedat', 0)
199
+            ->willReturn(12345);
200
+        $this->config
201
+            ->expects(self::any())
202
+            ->method('getSystemValueBool')
203
+            ->with('updatechecker', true)
204
+            ->willReturn(true);
205
+        $this->config
206
+            ->expects($this->once())
207
+            ->method('getAppValue')
208
+            ->with('updatenotification', 'notify_groups', '["admin"]')
209
+            ->willReturn('["admin"]');
210
+        $this->config
211
+            ->method('getSystemValue')
212
+            ->willReturnMap([
213
+                ['updater.server.url', 'https://updates.nextcloud.com/updater_server/', 'https://updates.nextcloud.com/updater_server_changed/'],
214
+                ['upgrade.disable-web', false, true],
215
+            ]);
216
+        $this->dateTimeFormatter
217
+            ->expects($this->once())
218
+            ->method('formatDateTime')
219
+            ->with('12345')
220
+            ->willReturn('LastCheckedReturnValue');
221
+        $this->updateChecker
222
+            ->expects($this->once())
223
+            ->method('getUpdateState')
224
+            ->willReturn([
225
+                'updateAvailable' => true,
226
+                'updateVersion' => '8.1.2',
227
+                'updateVersionString' => 'Nextcloud 8.1.2',
228
+                'downloadLink' => 'https://downloads.nextcloud.org/server',
229
+                'changes' => [],
230
+                'updaterEnabled' => true,
231
+                'versionIsEol' => false,
232
+            ]);
233
+
234
+        $group = $this->createMock(IGroup::class);
235
+        $group->expects($this->any())
236
+            ->method('getDisplayName')
237
+            ->willReturn('Administrators');
238
+        $group->expects($this->any())
239
+            ->method('getGID')
240
+            ->willReturn('admin');
241
+        $this->groupManager->expects($this->once())
242
+            ->method('get')
243
+            ->with('admin')
244
+            ->willReturn($group);
245
+
246
+        $this->subscriptionRegistry
247
+            ->expects($this->once())
248
+            ->method('delegateHasValidSubscription')
249
+            ->willReturn(true);
250
+
251
+        $this->initialState->expects($this->once())
252
+            ->method('provideInitialState')
253
+            ->with('data', [
254
+                'isNewVersionAvailable' => true,
255
+                'isUpdateChecked' => true,
256
+                'lastChecked' => 'LastCheckedReturnValue',
257
+                'currentChannel' => Util::getChannel(),
258
+                'channels' => $channels,
259
+                'newVersion' => '8.1.2',
260
+                'newVersionString' => 'Nextcloud 8.1.2',
261
+                'downloadLink' => 'https://downloads.nextcloud.org/server',
262
+                'changes' => [],
263
+                'webUpdaterEnabled' => false,
264
+                'isWebUpdaterRecommended' => true,
265
+                'updaterEnabled' => true,
266
+                'versionIsEol' => false,
267
+                'isDefaultUpdateServerURL' => false,
268
+                'updateServerURL' => 'https://updates.nextcloud.com/updater_server_changed/',
269
+                'notifyGroups' => [
270
+                    ['id' => 'admin', 'displayname' => 'Administrators'],
271
+                ],
272
+                'hasValidSubscription' => true,
273
+            ]);
274
+
275
+        $expected = new TemplateResponse('updatenotification', 'admin', [], '');
276
+        $this->assertEquals($expected, $this->admin->getForm());
277
+    }
278
+
279
+    public function testGetFormWithUpdateAndCustomersUpdateServer(): void {
280
+        $this->userManager
281
+            ->expects($this->once())
282
+            ->method('countUsersTotal')
283
+            ->willReturn(5);
284
+        $channels = [
285
+            'daily',
286
+            'beta',
287
+            'stable',
288
+            'production',
289
+        ];
290
+        $currentChannel = Util::getChannel();
291
+        if ($currentChannel === 'git') {
292
+            $channels[] = 'git';
293
+        }
294
+
295
+        $this->appConfig
296
+            ->expects($this->once())
297
+            ->method('getValueInt')
298
+            ->with('core', 'lastupdatedat', 0)
299
+            ->willReturn(12345);
300
+        $this->config
301
+            ->expects(self::any())
302
+            ->method('getSystemValueBool')
303
+            ->with('updatechecker', true)
304
+            ->willReturn(true);
305
+        $this->config
306
+            ->expects($this->once())
307
+            ->method('getAppValue')
308
+            ->with('updatenotification', 'notify_groups', '["admin"]')
309
+            ->willReturn('["admin"]');
310
+        $this->config
311
+            ->method('getSystemValue')
312
+            ->willReturnMap([
313
+                ['updater.server.url', 'https://updates.nextcloud.com/updater_server/', 'https://updates.nextcloud.com/customers/ABC-DEF/'],
314
+                ['upgrade.disable-web', false, false],
315
+            ]);
316
+        $this->dateTimeFormatter
317
+            ->expects($this->once())
318
+            ->method('formatDateTime')
319
+            ->with('12345')
320
+            ->willReturn('LastCheckedReturnValue');
321
+        $this->updateChecker
322
+            ->expects($this->once())
323
+            ->method('getUpdateState')
324
+            ->willReturn([
325
+                'updateAvailable' => true,
326
+                'updateVersion' => '8.1.2',
327
+                'updateVersionString' => 'Nextcloud 8.1.2',
328
+                'downloadLink' => 'https://downloads.nextcloud.org/server',
329
+                'changes' => [],
330
+                'updaterEnabled' => true,
331
+                'versionIsEol' => false,
332
+            ]);
333
+
334
+        $group = $this->createMock(IGroup::class);
335
+        $group->expects($this->any())
336
+            ->method('getDisplayName')
337
+            ->willReturn('Administrators');
338
+        $group->expects($this->any())
339
+            ->method('getGID')
340
+            ->willReturn('admin');
341
+        $this->groupManager->expects($this->once())
342
+            ->method('get')
343
+            ->with('admin')
344
+            ->willReturn($group);
345
+
346
+        $this->subscriptionRegistry
347
+            ->expects($this->once())
348
+            ->method('delegateHasValidSubscription')
349
+            ->willReturn(true);
350
+
351
+        $this->initialState->expects($this->once())
352
+            ->method('provideInitialState')
353
+            ->with('data', [
354
+                'isNewVersionAvailable' => true,
355
+                'isUpdateChecked' => true,
356
+                'lastChecked' => 'LastCheckedReturnValue',
357
+                'currentChannel' => Util::getChannel(),
358
+                'channels' => $channels,
359
+                'newVersion' => '8.1.2',
360
+                'newVersionString' => 'Nextcloud 8.1.2',
361
+                'downloadLink' => 'https://downloads.nextcloud.org/server',
362
+                'changes' => [],
363
+                'webUpdaterEnabled' => true,
364
+                'isWebUpdaterRecommended' => true,
365
+                'updaterEnabled' => true,
366
+                'versionIsEol' => false,
367
+                'isDefaultUpdateServerURL' => true,
368
+                'updateServerURL' => 'https://updates.nextcloud.com/customers/ABC-DEF/',
369
+                'notifyGroups' => [
370
+                    ['id' => 'admin', 'displayname' => 'Administrators'],
371
+                ],
372
+                'hasValidSubscription' => true,
373
+            ]);
374
+
375
+        $expected = new TemplateResponse('updatenotification', 'admin', [], '');
376
+        $this->assertEquals($expected, $this->admin->getForm());
377
+    }
378
+
379
+
380
+    public function testGetSection(): void {
381
+        $this->config
382
+            ->expects(self::atLeastOnce())
383
+            ->method('getSystemValueBool')
384
+            ->with('updatechecker', true)
385
+            ->willReturn(true);
386
+
387
+        $this->assertSame('overview', $this->admin->getSection());
388
+    }
389
+
390
+    public function testGetSectionDisabled(): void {
391
+        $this->config
392
+            ->expects(self::atLeastOnce())
393
+            ->method('getSystemValueBool')
394
+            ->with('updatechecker', true)
395
+            ->willReturn(false);
396
+
397
+        $this->assertNull($this->admin->getSection());
398
+    }
399
+
400
+    public function testGetPriority(): void {
401
+        $this->assertSame(11, $this->admin->getPriority());
402
+    }
403
+
404
+    public function changesProvider() {
405
+        return [
406
+            [ #0, all info, en
407
+                [
408
+                    'changelogURL' => 'https://go.to.changelog',
409
+                    'whatsNew' => [
410
+                        'en' => [
411
+                            'regular' => ['content'],
412
+                        ],
413
+                        'de' => [
414
+                            'regular' => ['inhalt'],
415
+                        ]
416
+                    ],
417
+                ],
418
+                'en',
419
+                [
420
+                    'changelogURL' => 'https://go.to.changelog',
421
+                    'whatsNew' => [
422
+                        'regular' => ['content'],
423
+                    ],
424
+                ]
425
+            ],
426
+            [ #1, all info, de
427
+                [
428
+                    'changelogURL' => 'https://go.to.changelog',
429
+                    'whatsNew' => [
430
+                        'en' => [
431
+                            'regular' => ['content'],
432
+                        ],
433
+                        'de' => [
434
+                            'regular' => ['inhalt'],
435
+                        ]
436
+                    ],
437
+                ],
438
+                'de',
439
+                [
440
+                    'changelogURL' => 'https://go.to.changelog',
441
+                    'whatsNew' => [
442
+                        'regular' => ['inhalt'],
443
+                    ]
444
+                ],
445
+            ],
446
+            [ #2, just changelog
447
+                [ 'changelogURL' => 'https://go.to.changelog' ],
448
+                'en',
449
+                [ 'changelogURL' => 'https://go.to.changelog' ],
450
+            ],
451
+            [ #3 nothing
452
+                [],
453
+                'ru',
454
+                []
455
+            ]
456
+        ];
457
+    }
458
+
459
+    /**
460
+     * @dataProvider changesProvider
461
+     */
462
+    public function testFilterChanges($changes, $userLang, $expectation): void {
463
+        $iterator = $this->createMock(ILanguageIterator::class);
464
+        $iterator->expects($this->any())
465
+            ->method('current')
466
+            ->willReturnOnConsecutiveCalls('es', $userLang, 'it', 'en');
467
+        $iterator->expects($this->any())
468
+            ->method('valid')
469
+            ->willReturn(true);
470
+
471
+        $this->l10nFactory->expects($this->atMost(1))
472
+            ->method('getLanguageIterator')
473
+            ->willReturn($iterator);
474
+        $result = $this->invokePrivate($this->admin, 'filterChanges', [$changes]);
475
+        $this->assertSame($expectation, $result);
476
+    }
477 477
 }
Please login to merge, or discard this patch.
updatenotification/tests/BackgroundJob/UpdateAvailableNotificationsTest.php 2 patches
Indentation   +444 added lines, -444 removed lines patch added patch discarded remove patch
@@ -25,448 +25,448 @@
 block discarded – undo
25 25
 use Test\TestCase;
26 26
 
27 27
 class UpdateAvailableNotificationsTest extends TestCase {
28
-	private ServerVersion&MockObject $serverVersion;
29
-	private IConfig|MockObject $config;
30
-	private IManager|MockObject $notificationManager;
31
-	private IGroupManager|MockObject $groupManager;
32
-	private IAppManager|MockObject $appManager;
33
-	private IAppConfig|MockObject $appConfig;
34
-	private ITimeFactory|MockObject $timeFactory;
35
-	private Installer|MockObject $installer;
36
-	private VersionCheck|MockObject $versionCheck;
37
-
38
-	protected function setUp(): void {
39
-		parent::setUp();
40
-
41
-		$this->serverVersion = $this->createMock(ServerVersion::class);
42
-		$this->config = $this->createMock(IConfig::class);
43
-		$this->appConfig = $this->createMock(IAppConfig::class);
44
-		$this->notificationManager = $this->createMock(IManager::class);
45
-		$this->groupManager = $this->createMock(IGroupManager::class);
46
-		$this->appManager = $this->createMock(IAppManager::class);
47
-		$this->timeFactory = $this->createMock(ITimeFactory::class);
48
-		$this->installer = $this->createMock(Installer::class);
49
-		$this->versionCheck = $this->createMock(VersionCheck::class);
50
-	}
51
-
52
-	/**
53
-	 * @param array $methods
54
-	 * @return UpdateAvailableNotifications|MockObject
55
-	 */
56
-	protected function getJob(array $methods = []) {
57
-		if (empty($methods)) {
58
-			return new UpdateAvailableNotifications(
59
-				$this->timeFactory,
60
-				$this->serverVersion,
61
-				$this->config,
62
-				$this->appConfig,
63
-				$this->notificationManager,
64
-				$this->groupManager,
65
-				$this->appManager,
66
-				$this->installer,
67
-				$this->versionCheck,
68
-			);
69
-		}
70
-		{
71
-			return $this->getMockBuilder(UpdateAvailableNotifications::class)
72
-				->setConstructorArgs([
73
-					$this->timeFactory,
74
-					$this->serverVersion,
75
-					$this->config,
76
-					$this->appConfig,
77
-					$this->notificationManager,
78
-					$this->groupManager,
79
-					$this->appManager,
80
-					$this->installer,
81
-					$this->versionCheck,
82
-				])
83
-				->onlyMethods($methods)
84
-				->getMock();
85
-		}
86
-	}
87
-
88
-	public function testRun(): void {
89
-		$job = $this->getJob([
90
-			'checkCoreUpdate',
91
-			'checkAppUpdates',
92
-		]);
93
-
94
-		$job->expects($this->once())
95
-			->method('checkCoreUpdate');
96
-		$job->expects($this->once())
97
-			->method('checkAppUpdates');
98
-
99
-		$this->config->expects(self::exactly(2))
100
-			->method('getSystemValueBool')
101
-			->willReturnMap([
102
-				['debug', false, true],
103
-				['has_internet_connection', true, true],
104
-			]);
105
-		self::invokePrivate($job, 'run', [null]);
106
-	}
107
-
108
-	public function testRunNoInternet(): void {
109
-		$job = $this->getJob([
110
-			'checkCoreUpdate',
111
-			'checkAppUpdates',
112
-		]);
113
-
114
-		$job->expects($this->never())
115
-			->method('checkCoreUpdate');
116
-		$job->expects($this->never())
117
-			->method('checkAppUpdates');
118
-
119
-		$this->config
120
-			->expects(self::once())
121
-			->method('getSystemValueBool')
122
-			->with('has_internet_connection', true)
123
-			->willReturn(false);
124
-
125
-		self::invokePrivate($job, 'run', [null]);
126
-	}
127
-
128
-	public function dataCheckCoreUpdate(): array {
129
-		return [
130
-			['daily', null, null, null, null],
131
-			['git', null, null, null, null],
132
-			['beta', [], null, null, null],
133
-			['beta', false, false, null, null],
134
-			['beta', false, false, null, 13],
135
-			['beta', [
136
-				'version' => '9.2.0',
137
-				'versionstring' => 'Nextcloud 11.0.0',
138
-			], '9.2.0', 'Nextcloud 11.0.0', null],
139
-			['stable', [], null, null, null],
140
-			['stable', false, false, null, null],
141
-			['stable', false, false, null, 6],
142
-			['stable', [
143
-				'version' => '9.2.0',
144
-				'versionstring' => 'Nextcloud 11.0.0',
145
-			], '9.2.0', 'Nextcloud 11.0.0', null],
146
-			['production', [], null, null, null],
147
-			['production', false, false, null, null],
148
-			['production', false, false, null, 2],
149
-			['production', [
150
-				'version' => '9.2.0',
151
-				'versionstring' => 'Nextcloud 11.0.0',
152
-			], '9.2.0', 'Nextcloud 11.0.0', null],
153
-		];
154
-	}
155
-
156
-	/**
157
-	 * @dataProvider dataCheckCoreUpdate
158
-	 *
159
-	 * @param string $channel
160
-	 * @param mixed $versionCheck
161
-	 * @param null|string $version
162
-	 * @param null|string $readableVersion
163
-	 * @param null|int $errorDays
164
-	 */
165
-	public function testCheckCoreUpdate(string $channel, $versionCheck, $version, $readableVersion, $errorDays): void {
166
-		$job = $this->getJob([
167
-			'createNotifications',
168
-			'clearErrorNotifications',
169
-			'sendErrorNotifications',
170
-		]);
171
-
172
-		$this->serverVersion->expects($this->once())
173
-			->method('getChannel')
174
-			->willReturn($channel);
175
-
176
-		if ($versionCheck === null) {
177
-			$this->versionCheck->expects($this->never())
178
-				->method('check');
179
-		} else {
180
-			$this->versionCheck->expects($this->once())
181
-				->method('check')
182
-				->willReturn($versionCheck);
183
-		}
184
-
185
-		if ($version === null) {
186
-			$job->expects($this->never())
187
-				->method('createNotifications');
188
-			$job->expects($versionCheck === null ? $this->never() : $this->once())
189
-				->method('clearErrorNotifications');
190
-		} elseif ($version === false) {
191
-			$job->expects($this->never())
192
-				->method('createNotifications');
193
-			$job->expects($this->never())
194
-				->method('clearErrorNotifications');
195
-
196
-			$this->appConfig->expects($this->once())
197
-				->method('getAppValueInt')
198
-				->willReturn($errorDays ?? 0);
199
-			$this->appConfig->expects($this->once())
200
-				->method('setAppValueInt')
201
-				->with('update_check_errors', $errorDays + 1);
202
-			$job->expects($errorDays !== null ? $this->once() : $this->never())
203
-				->method('sendErrorNotifications')
204
-				->with($errorDays + 1);
205
-		} else {
206
-			$this->appConfig->expects($this->once())
207
-				->method('setAppValueInt')
208
-				->with('update_check_errors', 0);
209
-			$job->expects($this->once())
210
-				->method('clearErrorNotifications');
211
-			$job->expects($this->once())
212
-				->method('createNotifications')
213
-				->with('core', $version, $readableVersion);
214
-		}
215
-
216
-		$this->config->expects(self::any())
217
-			->method('getSystemValueBool')
218
-			->willReturnMap([
219
-				['updatechecker', true, true],
220
-				['has_internet_connection', true, true],
221
-			]);
222
-
223
-		self::invokePrivate($job, 'checkCoreUpdate');
224
-	}
225
-
226
-	public function dataCheckAppUpdates(): array {
227
-		return [
228
-			[
229
-				['app1', 'app2'],
230
-				[
231
-					['app1', false],
232
-					['app2', '1.9.2'],
233
-				],
234
-				[
235
-					['app2', '1.9.2', ''],
236
-				],
237
-			],
238
-		];
239
-	}
240
-
241
-	/**
242
-	 * @dataProvider dataCheckAppUpdates
243
-	 *
244
-	 * @param string[] $apps
245
-	 * @param array $isUpdateAvailable
246
-	 * @param array $notifications
247
-	 */
248
-	public function testCheckAppUpdates(array $apps, array $isUpdateAvailable, array $notifications): void {
249
-		$job = $this->getJob([
250
-			'isUpdateAvailable',
251
-			'createNotifications',
252
-		]);
253
-
254
-		$this->appManager->expects($this->once())
255
-			->method('getEnabledApps')
256
-			->willReturn($apps);
257
-
258
-		$job->expects($this->exactly(\count($apps)))
259
-			->method('isUpdateAvailable')
260
-			->willReturnMap($isUpdateAvailable);
261
-
262
-		$i = 0;
263
-		$job->expects($this->exactly(\count($notifications)))
264
-			->method('createNotifications')
265
-			->willReturnCallback(function () use ($notifications, &$i): void {
266
-				$this->assertEquals($notifications[$i], func_get_args());
267
-				$i++;
268
-			});
269
-
270
-
271
-		self::invokePrivate($job, 'checkAppUpdates');
272
-	}
273
-
274
-	public function dataCreateNotifications(): array {
275
-		return [
276
-			['app1', '1.0.0', '1.0.0', false, false, null, null],
277
-			['app2', '1.0.1', '1.0.0', '1.0.0', true, ['user1'], [['user1']]],
278
-			['app3', '1.0.1', false, false, true, ['user2', 'user3'], [['user2'], ['user3']]],
279
-		];
280
-	}
281
-
282
-	/**
283
-	 * @dataProvider dataCreateNotifications
284
-	 *
285
-	 * @param string $app
286
-	 * @param string $version
287
-	 * @param string|false $lastNotification
288
-	 * @param string|false $callDelete
289
-	 * @param bool $createNotification
290
-	 * @param string[]|null $users
291
-	 * @param array|null $userNotifications
292
-	 */
293
-	public function testCreateNotifications(string $app, string $version, $lastNotification, $callDelete, $createNotification, $users, $userNotifications): void {
294
-		$job = $this->getJob([
295
-			'deleteOutdatedNotifications',
296
-			'getUsersToNotify',
297
-		]);
298
-
299
-		$this->appConfig->expects($this->once())
300
-			->method('getAppValueString')
301
-			->with($app, '')
302
-			->willReturn($lastNotification ?: '');
303
-
304
-		if ($lastNotification !== $version) {
305
-			$this->appConfig->expects($this->once())
306
-				->method('setAppValueString')
307
-				->with($app, $version);
308
-		}
309
-
310
-		if ($callDelete === false) {
311
-			$job->expects($this->never())
312
-				->method('deleteOutdatedNotifications');
313
-		} else {
314
-			$job->expects($this->once())
315
-				->method('deleteOutdatedNotifications')
316
-				->with($app, $callDelete);
317
-		}
318
-
319
-		if ($users === null) {
320
-			$job->expects($this->never())
321
-				->method('getUsersToNotify');
322
-		} else {
323
-			$job->expects($this->once())
324
-				->method('getUsersToNotify')
325
-				->willReturn($users);
326
-		}
327
-
328
-		if ($createNotification) {
329
-			$notification = $this->createMock(INotification::class);
330
-			$notification->expects($this->once())
331
-				->method('setApp')
332
-				->with('updatenotification')
333
-				->willReturnSelf();
334
-			$notification->expects($this->once())
335
-				->method('setDateTime')
336
-				->willReturnSelf();
337
-			$notification->expects($this->once())
338
-				->method('setObject')
339
-				->with($app, $version)
340
-				->willReturnSelf();
341
-			$notification->expects($this->once())
342
-				->method('setSubject')
343
-				->with('update_available')
344
-				->willReturnSelf();
345
-
346
-			if ($userNotifications !== null) {
347
-				$notification->expects($this->exactly(\count($userNotifications)))
348
-					->method('setUser')
349
-					->willReturnSelf();
350
-
351
-				$this->notificationManager->expects($this->exactly(\count($userNotifications)))
352
-					->method('notify');
353
-			}
354
-
355
-			$this->notificationManager->expects($this->once())
356
-				->method('createNotification')
357
-				->willReturn($notification);
358
-		} else {
359
-			$this->notificationManager->expects($this->never())
360
-				->method('createNotification');
361
-		}
362
-
363
-		self::invokePrivate($job, 'createNotifications', [$app, $version]);
364
-	}
365
-
366
-	public function dataGetUsersToNotify(): array {
367
-		return [
368
-			[['g1', 'g2'], ['g1' => null, 'g2' => ['u1', 'u2']], ['u1', 'u2']],
369
-			[['g3', 'g4'], ['g3' => ['u1', 'u2'], 'g4' => ['u2', 'u3']], ['u1', 'u2', 'u3']],
370
-		];
371
-	}
372
-
373
-	/**
374
-	 * @dataProvider dataGetUsersToNotify
375
-	 * @param string[] $groups
376
-	 * @param array $groupUsers
377
-	 * @param string[] $expected
378
-	 */
379
-	public function testGetUsersToNotify(array $groups, array $groupUsers, array $expected): void {
380
-		$job = $this->getJob();
381
-
382
-		$this->appConfig->expects($this->once())
383
-			->method('getAppValueArray')
384
-			->with('notify_groups', ['admin'])
385
-			->willReturn($groups);
386
-
387
-		$groupMap = [];
388
-		foreach ($groupUsers as $gid => $uids) {
389
-			if ($uids === null) {
390
-				$group = null;
391
-			} else {
392
-				$group = $this->getGroup($gid);
393
-				$group->expects($this->any())
394
-					->method('getUsers')
395
-					->willReturn($this->getUsers($uids));
396
-			}
397
-			$groupMap[] = [$gid, $group];
398
-		}
399
-		$this->groupManager->expects($this->exactly(\count($groups)))
400
-			->method('get')
401
-			->willReturnMap($groupMap);
402
-
403
-		$result = self::invokePrivate($job, 'getUsersToNotify');
404
-		$this->assertEquals($expected, $result);
405
-
406
-		// Test caching
407
-		$result = self::invokePrivate($job, 'getUsersToNotify');
408
-		$this->assertEquals($expected, $result);
409
-	}
410
-
411
-	public function dataDeleteOutdatedNotifications(): array {
412
-		return [
413
-			['app1', '1.1.0'],
414
-			['app2', '1.2.0'],
415
-		];
416
-	}
417
-
418
-	/**
419
-	 * @dataProvider dataDeleteOutdatedNotifications
420
-	 * @param string $app
421
-	 * @param string $version
422
-	 */
423
-	public function testDeleteOutdatedNotifications(string $app, string $version): void {
424
-		$notification = $this->createMock(INotification::class);
425
-		$notification->expects($this->once())
426
-			->method('setApp')
427
-			->with('updatenotification')
428
-			->willReturnSelf();
429
-		$notification->expects($this->once())
430
-			->method('setObject')
431
-			->with($app, $version)
432
-			->willReturnSelf();
433
-
434
-		$this->notificationManager->expects($this->once())
435
-			->method('createNotification')
436
-			->willReturn($notification);
437
-		$this->notificationManager->expects($this->once())
438
-			->method('markProcessed')
439
-			->with($notification);
440
-
441
-		$job = $this->getJob();
442
-		self::invokePrivate($job, 'deleteOutdatedNotifications', [$app, $version]);
443
-	}
444
-
445
-	/**
446
-	 * @param string[] $userIds
447
-	 * @return IUser[]|MockObject[]
448
-	 */
449
-	protected function getUsers(array $userIds): array {
450
-		$users = [];
451
-		foreach ($userIds as $uid) {
452
-			$user = $this->createMock(IUser::class);
453
-			$user->expects($this->any())
454
-				->method('getUID')
455
-				->willReturn($uid);
456
-			$users[] = $user;
457
-		}
458
-		return $users;
459
-	}
460
-
461
-	/**
462
-	 * @param string $gid
463
-	 * @return IGroup|MockObject
464
-	 */
465
-	protected function getGroup(string $gid) {
466
-		$group = $this->createMock(IGroup::class);
467
-		$group->expects($this->any())
468
-			->method('getGID')
469
-			->willReturn($gid);
470
-		return $group;
471
-	}
28
+    private ServerVersion&MockObject $serverVersion;
29
+    private IConfig|MockObject $config;
30
+    private IManager|MockObject $notificationManager;
31
+    private IGroupManager|MockObject $groupManager;
32
+    private IAppManager|MockObject $appManager;
33
+    private IAppConfig|MockObject $appConfig;
34
+    private ITimeFactory|MockObject $timeFactory;
35
+    private Installer|MockObject $installer;
36
+    private VersionCheck|MockObject $versionCheck;
37
+
38
+    protected function setUp(): void {
39
+        parent::setUp();
40
+
41
+        $this->serverVersion = $this->createMock(ServerVersion::class);
42
+        $this->config = $this->createMock(IConfig::class);
43
+        $this->appConfig = $this->createMock(IAppConfig::class);
44
+        $this->notificationManager = $this->createMock(IManager::class);
45
+        $this->groupManager = $this->createMock(IGroupManager::class);
46
+        $this->appManager = $this->createMock(IAppManager::class);
47
+        $this->timeFactory = $this->createMock(ITimeFactory::class);
48
+        $this->installer = $this->createMock(Installer::class);
49
+        $this->versionCheck = $this->createMock(VersionCheck::class);
50
+    }
51
+
52
+    /**
53
+     * @param array $methods
54
+     * @return UpdateAvailableNotifications|MockObject
55
+     */
56
+    protected function getJob(array $methods = []) {
57
+        if (empty($methods)) {
58
+            return new UpdateAvailableNotifications(
59
+                $this->timeFactory,
60
+                $this->serverVersion,
61
+                $this->config,
62
+                $this->appConfig,
63
+                $this->notificationManager,
64
+                $this->groupManager,
65
+                $this->appManager,
66
+                $this->installer,
67
+                $this->versionCheck,
68
+            );
69
+        }
70
+        {
71
+            return $this->getMockBuilder(UpdateAvailableNotifications::class)
72
+                ->setConstructorArgs([
73
+                    $this->timeFactory,
74
+                    $this->serverVersion,
75
+                    $this->config,
76
+                    $this->appConfig,
77
+                    $this->notificationManager,
78
+                    $this->groupManager,
79
+                    $this->appManager,
80
+                    $this->installer,
81
+                    $this->versionCheck,
82
+                ])
83
+                ->onlyMethods($methods)
84
+                ->getMock();
85
+        }
86
+    }
87
+
88
+    public function testRun(): void {
89
+        $job = $this->getJob([
90
+            'checkCoreUpdate',
91
+            'checkAppUpdates',
92
+        ]);
93
+
94
+        $job->expects($this->once())
95
+            ->method('checkCoreUpdate');
96
+        $job->expects($this->once())
97
+            ->method('checkAppUpdates');
98
+
99
+        $this->config->expects(self::exactly(2))
100
+            ->method('getSystemValueBool')
101
+            ->willReturnMap([
102
+                ['debug', false, true],
103
+                ['has_internet_connection', true, true],
104
+            ]);
105
+        self::invokePrivate($job, 'run', [null]);
106
+    }
107
+
108
+    public function testRunNoInternet(): void {
109
+        $job = $this->getJob([
110
+            'checkCoreUpdate',
111
+            'checkAppUpdates',
112
+        ]);
113
+
114
+        $job->expects($this->never())
115
+            ->method('checkCoreUpdate');
116
+        $job->expects($this->never())
117
+            ->method('checkAppUpdates');
118
+
119
+        $this->config
120
+            ->expects(self::once())
121
+            ->method('getSystemValueBool')
122
+            ->with('has_internet_connection', true)
123
+            ->willReturn(false);
124
+
125
+        self::invokePrivate($job, 'run', [null]);
126
+    }
127
+
128
+    public function dataCheckCoreUpdate(): array {
129
+        return [
130
+            ['daily', null, null, null, null],
131
+            ['git', null, null, null, null],
132
+            ['beta', [], null, null, null],
133
+            ['beta', false, false, null, null],
134
+            ['beta', false, false, null, 13],
135
+            ['beta', [
136
+                'version' => '9.2.0',
137
+                'versionstring' => 'Nextcloud 11.0.0',
138
+            ], '9.2.0', 'Nextcloud 11.0.0', null],
139
+            ['stable', [], null, null, null],
140
+            ['stable', false, false, null, null],
141
+            ['stable', false, false, null, 6],
142
+            ['stable', [
143
+                'version' => '9.2.0',
144
+                'versionstring' => 'Nextcloud 11.0.0',
145
+            ], '9.2.0', 'Nextcloud 11.0.0', null],
146
+            ['production', [], null, null, null],
147
+            ['production', false, false, null, null],
148
+            ['production', false, false, null, 2],
149
+            ['production', [
150
+                'version' => '9.2.0',
151
+                'versionstring' => 'Nextcloud 11.0.0',
152
+            ], '9.2.0', 'Nextcloud 11.0.0', null],
153
+        ];
154
+    }
155
+
156
+    /**
157
+     * @dataProvider dataCheckCoreUpdate
158
+     *
159
+     * @param string $channel
160
+     * @param mixed $versionCheck
161
+     * @param null|string $version
162
+     * @param null|string $readableVersion
163
+     * @param null|int $errorDays
164
+     */
165
+    public function testCheckCoreUpdate(string $channel, $versionCheck, $version, $readableVersion, $errorDays): void {
166
+        $job = $this->getJob([
167
+            'createNotifications',
168
+            'clearErrorNotifications',
169
+            'sendErrorNotifications',
170
+        ]);
171
+
172
+        $this->serverVersion->expects($this->once())
173
+            ->method('getChannel')
174
+            ->willReturn($channel);
175
+
176
+        if ($versionCheck === null) {
177
+            $this->versionCheck->expects($this->never())
178
+                ->method('check');
179
+        } else {
180
+            $this->versionCheck->expects($this->once())
181
+                ->method('check')
182
+                ->willReturn($versionCheck);
183
+        }
184
+
185
+        if ($version === null) {
186
+            $job->expects($this->never())
187
+                ->method('createNotifications');
188
+            $job->expects($versionCheck === null ? $this->never() : $this->once())
189
+                ->method('clearErrorNotifications');
190
+        } elseif ($version === false) {
191
+            $job->expects($this->never())
192
+                ->method('createNotifications');
193
+            $job->expects($this->never())
194
+                ->method('clearErrorNotifications');
195
+
196
+            $this->appConfig->expects($this->once())
197
+                ->method('getAppValueInt')
198
+                ->willReturn($errorDays ?? 0);
199
+            $this->appConfig->expects($this->once())
200
+                ->method('setAppValueInt')
201
+                ->with('update_check_errors', $errorDays + 1);
202
+            $job->expects($errorDays !== null ? $this->once() : $this->never())
203
+                ->method('sendErrorNotifications')
204
+                ->with($errorDays + 1);
205
+        } else {
206
+            $this->appConfig->expects($this->once())
207
+                ->method('setAppValueInt')
208
+                ->with('update_check_errors', 0);
209
+            $job->expects($this->once())
210
+                ->method('clearErrorNotifications');
211
+            $job->expects($this->once())
212
+                ->method('createNotifications')
213
+                ->with('core', $version, $readableVersion);
214
+        }
215
+
216
+        $this->config->expects(self::any())
217
+            ->method('getSystemValueBool')
218
+            ->willReturnMap([
219
+                ['updatechecker', true, true],
220
+                ['has_internet_connection', true, true],
221
+            ]);
222
+
223
+        self::invokePrivate($job, 'checkCoreUpdate');
224
+    }
225
+
226
+    public function dataCheckAppUpdates(): array {
227
+        return [
228
+            [
229
+                ['app1', 'app2'],
230
+                [
231
+                    ['app1', false],
232
+                    ['app2', '1.9.2'],
233
+                ],
234
+                [
235
+                    ['app2', '1.9.2', ''],
236
+                ],
237
+            ],
238
+        ];
239
+    }
240
+
241
+    /**
242
+     * @dataProvider dataCheckAppUpdates
243
+     *
244
+     * @param string[] $apps
245
+     * @param array $isUpdateAvailable
246
+     * @param array $notifications
247
+     */
248
+    public function testCheckAppUpdates(array $apps, array $isUpdateAvailable, array $notifications): void {
249
+        $job = $this->getJob([
250
+            'isUpdateAvailable',
251
+            'createNotifications',
252
+        ]);
253
+
254
+        $this->appManager->expects($this->once())
255
+            ->method('getEnabledApps')
256
+            ->willReturn($apps);
257
+
258
+        $job->expects($this->exactly(\count($apps)))
259
+            ->method('isUpdateAvailable')
260
+            ->willReturnMap($isUpdateAvailable);
261
+
262
+        $i = 0;
263
+        $job->expects($this->exactly(\count($notifications)))
264
+            ->method('createNotifications')
265
+            ->willReturnCallback(function () use ($notifications, &$i): void {
266
+                $this->assertEquals($notifications[$i], func_get_args());
267
+                $i++;
268
+            });
269
+
270
+
271
+        self::invokePrivate($job, 'checkAppUpdates');
272
+    }
273
+
274
+    public function dataCreateNotifications(): array {
275
+        return [
276
+            ['app1', '1.0.0', '1.0.0', false, false, null, null],
277
+            ['app2', '1.0.1', '1.0.0', '1.0.0', true, ['user1'], [['user1']]],
278
+            ['app3', '1.0.1', false, false, true, ['user2', 'user3'], [['user2'], ['user3']]],
279
+        ];
280
+    }
281
+
282
+    /**
283
+     * @dataProvider dataCreateNotifications
284
+     *
285
+     * @param string $app
286
+     * @param string $version
287
+     * @param string|false $lastNotification
288
+     * @param string|false $callDelete
289
+     * @param bool $createNotification
290
+     * @param string[]|null $users
291
+     * @param array|null $userNotifications
292
+     */
293
+    public function testCreateNotifications(string $app, string $version, $lastNotification, $callDelete, $createNotification, $users, $userNotifications): void {
294
+        $job = $this->getJob([
295
+            'deleteOutdatedNotifications',
296
+            'getUsersToNotify',
297
+        ]);
298
+
299
+        $this->appConfig->expects($this->once())
300
+            ->method('getAppValueString')
301
+            ->with($app, '')
302
+            ->willReturn($lastNotification ?: '');
303
+
304
+        if ($lastNotification !== $version) {
305
+            $this->appConfig->expects($this->once())
306
+                ->method('setAppValueString')
307
+                ->with($app, $version);
308
+        }
309
+
310
+        if ($callDelete === false) {
311
+            $job->expects($this->never())
312
+                ->method('deleteOutdatedNotifications');
313
+        } else {
314
+            $job->expects($this->once())
315
+                ->method('deleteOutdatedNotifications')
316
+                ->with($app, $callDelete);
317
+        }
318
+
319
+        if ($users === null) {
320
+            $job->expects($this->never())
321
+                ->method('getUsersToNotify');
322
+        } else {
323
+            $job->expects($this->once())
324
+                ->method('getUsersToNotify')
325
+                ->willReturn($users);
326
+        }
327
+
328
+        if ($createNotification) {
329
+            $notification = $this->createMock(INotification::class);
330
+            $notification->expects($this->once())
331
+                ->method('setApp')
332
+                ->with('updatenotification')
333
+                ->willReturnSelf();
334
+            $notification->expects($this->once())
335
+                ->method('setDateTime')
336
+                ->willReturnSelf();
337
+            $notification->expects($this->once())
338
+                ->method('setObject')
339
+                ->with($app, $version)
340
+                ->willReturnSelf();
341
+            $notification->expects($this->once())
342
+                ->method('setSubject')
343
+                ->with('update_available')
344
+                ->willReturnSelf();
345
+
346
+            if ($userNotifications !== null) {
347
+                $notification->expects($this->exactly(\count($userNotifications)))
348
+                    ->method('setUser')
349
+                    ->willReturnSelf();
350
+
351
+                $this->notificationManager->expects($this->exactly(\count($userNotifications)))
352
+                    ->method('notify');
353
+            }
354
+
355
+            $this->notificationManager->expects($this->once())
356
+                ->method('createNotification')
357
+                ->willReturn($notification);
358
+        } else {
359
+            $this->notificationManager->expects($this->never())
360
+                ->method('createNotification');
361
+        }
362
+
363
+        self::invokePrivate($job, 'createNotifications', [$app, $version]);
364
+    }
365
+
366
+    public function dataGetUsersToNotify(): array {
367
+        return [
368
+            [['g1', 'g2'], ['g1' => null, 'g2' => ['u1', 'u2']], ['u1', 'u2']],
369
+            [['g3', 'g4'], ['g3' => ['u1', 'u2'], 'g4' => ['u2', 'u3']], ['u1', 'u2', 'u3']],
370
+        ];
371
+    }
372
+
373
+    /**
374
+     * @dataProvider dataGetUsersToNotify
375
+     * @param string[] $groups
376
+     * @param array $groupUsers
377
+     * @param string[] $expected
378
+     */
379
+    public function testGetUsersToNotify(array $groups, array $groupUsers, array $expected): void {
380
+        $job = $this->getJob();
381
+
382
+        $this->appConfig->expects($this->once())
383
+            ->method('getAppValueArray')
384
+            ->with('notify_groups', ['admin'])
385
+            ->willReturn($groups);
386
+
387
+        $groupMap = [];
388
+        foreach ($groupUsers as $gid => $uids) {
389
+            if ($uids === null) {
390
+                $group = null;
391
+            } else {
392
+                $group = $this->getGroup($gid);
393
+                $group->expects($this->any())
394
+                    ->method('getUsers')
395
+                    ->willReturn($this->getUsers($uids));
396
+            }
397
+            $groupMap[] = [$gid, $group];
398
+        }
399
+        $this->groupManager->expects($this->exactly(\count($groups)))
400
+            ->method('get')
401
+            ->willReturnMap($groupMap);
402
+
403
+        $result = self::invokePrivate($job, 'getUsersToNotify');
404
+        $this->assertEquals($expected, $result);
405
+
406
+        // Test caching
407
+        $result = self::invokePrivate($job, 'getUsersToNotify');
408
+        $this->assertEquals($expected, $result);
409
+    }
410
+
411
+    public function dataDeleteOutdatedNotifications(): array {
412
+        return [
413
+            ['app1', '1.1.0'],
414
+            ['app2', '1.2.0'],
415
+        ];
416
+    }
417
+
418
+    /**
419
+     * @dataProvider dataDeleteOutdatedNotifications
420
+     * @param string $app
421
+     * @param string $version
422
+     */
423
+    public function testDeleteOutdatedNotifications(string $app, string $version): void {
424
+        $notification = $this->createMock(INotification::class);
425
+        $notification->expects($this->once())
426
+            ->method('setApp')
427
+            ->with('updatenotification')
428
+            ->willReturnSelf();
429
+        $notification->expects($this->once())
430
+            ->method('setObject')
431
+            ->with($app, $version)
432
+            ->willReturnSelf();
433
+
434
+        $this->notificationManager->expects($this->once())
435
+            ->method('createNotification')
436
+            ->willReturn($notification);
437
+        $this->notificationManager->expects($this->once())
438
+            ->method('markProcessed')
439
+            ->with($notification);
440
+
441
+        $job = $this->getJob();
442
+        self::invokePrivate($job, 'deleteOutdatedNotifications', [$app, $version]);
443
+    }
444
+
445
+    /**
446
+     * @param string[] $userIds
447
+     * @return IUser[]|MockObject[]
448
+     */
449
+    protected function getUsers(array $userIds): array {
450
+        $users = [];
451
+        foreach ($userIds as $uid) {
452
+            $user = $this->createMock(IUser::class);
453
+            $user->expects($this->any())
454
+                ->method('getUID')
455
+                ->willReturn($uid);
456
+            $users[] = $user;
457
+        }
458
+        return $users;
459
+    }
460
+
461
+    /**
462
+     * @param string $gid
463
+     * @return IGroup|MockObject
464
+     */
465
+    protected function getGroup(string $gid) {
466
+        $group = $this->createMock(IGroup::class);
467
+        $group->expects($this->any())
468
+            ->method('getGID')
469
+            ->willReturn($gid);
470
+        return $group;
471
+    }
472 472
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -26,14 +26,14 @@  discard block
 block discarded – undo
26 26
 
27 27
 class UpdateAvailableNotificationsTest extends TestCase {
28 28
 	private ServerVersion&MockObject $serverVersion;
29
-	private IConfig|MockObject $config;
30
-	private IManager|MockObject $notificationManager;
31
-	private IGroupManager|MockObject $groupManager;
32
-	private IAppManager|MockObject $appManager;
33
-	private IAppConfig|MockObject $appConfig;
34
-	private ITimeFactory|MockObject $timeFactory;
35
-	private Installer|MockObject $installer;
36
-	private VersionCheck|MockObject $versionCheck;
29
+	private IConfig | MockObject $config;
30
+	private IManager | MockObject $notificationManager;
31
+	private IGroupManager | MockObject $groupManager;
32
+	private IAppManager | MockObject $appManager;
33
+	private IAppConfig | MockObject $appConfig;
34
+	private ITimeFactory | MockObject $timeFactory;
35
+	private Installer | MockObject $installer;
36
+	private VersionCheck | MockObject $versionCheck;
37 37
 
38 38
 	protected function setUp(): void {
39 39
 		parent::setUp();
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
 		$i = 0;
263 263
 		$job->expects($this->exactly(\count($notifications)))
264 264
 			->method('createNotifications')
265
-			->willReturnCallback(function () use ($notifications, &$i): void {
265
+			->willReturnCallback(function() use ($notifications, &$i): void {
266 266
 				$this->assertEquals($notifications[$i], func_get_args());
267 267
 				$i++;
268 268
 			});
Please login to merge, or discard this patch.