Skip to content

Commit 4e3129f

Browse files
committed
fix(bulkReceive): honour admin email toggle and ISetting notification defaults
The admin Enable notification emails toggle was not checked in bulkReceive(), so emails could be queued even when the toggle was disabled. Also, ISetting-based settings that do not implement ActivitySettings had canChangeNotification() called on them, which caused a fatal error; the default push-enabled state was also ignored. Injects IAppConfig and uses getValueString() to check the toggle, consistent with the approach used elsewhere. ISetting instances that are not ActivitySettings now fall back to the setting default via isDefaultEnabledNotification() without calling canChangeNotification(). Signed-off-by: Anna Larch <anna@nextcloud.com>
1 parent 29d896c commit 4e3129f

2 files changed

Lines changed: 71 additions & 15 deletions

File tree

lib/Consumer.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use OCP\Config\IUserConfig;
1717
use OCP\Config\ValueType;
1818
use OCP\DB\Exception;
19+
use OCP\IAppConfig;
1920

2021
class Consumer implements IConsumer, IBulkConsumer {
2122

@@ -25,6 +26,7 @@ public function __construct(
2526
protected UserSettings $userSettings,
2627
protected NotificationGenerator $notificationGenerator,
2728
protected IUserConfig $userConfig,
29+
protected IAppConfig $appConfig,
2830
) {
2931
}
3032

@@ -78,13 +80,16 @@ public function bulkReceive(IEvent $event, array $affectedUserIds, ISetting $set
7880

7981
$canChangeMail = $setting->canChangeMail();
8082
$canChangePush = $setting instanceof ActivitySettings && $setting->canChangeNotification() === true;
83+
$defaultPushEnabled = $setting instanceof ActivitySettings && $setting->isDefaultEnabledNotification();
8184

82-
$userPushSettings = $userEmailSettings = $batchTimeSettings = null;
85+
$userPushSettings = null;
8386
if ($canChangePush === true) {
8487
$userPushSettings = $this->userConfig->getValuesByUsers('activity', 'notify_notification_' . $event->getType(), ValueType::BOOL, $affectedUserIds);
8588
}
8689

87-
if ($canChangeMail === true || $setting->isDefaultEnabledMail() === true) {
90+
$userEmailSettings = $batchTimeSettings = null;
91+
$emailEnabled = $this->appConfig->getValueString('activity', 'enable_email', 'yes') !== 'no';
92+
if ($emailEnabled && ($canChangeMail === true || $setting->isDefaultEnabledMail() === true)) {
8893
$userEmailSettings = $this->userConfig->getValuesByUsers('activity', 'notify_email_' . $event->getType(), ValueType::BOOL, $affectedUserIds);
8994
$batchTimeSettings = $this->userConfig->getValuesByUsers('activity', 'notify_setting_batchtime', ValueType::INT, $affectedUserIds);
9095
}
@@ -95,14 +100,17 @@ public function bulkReceive(IEvent $event, array $affectedUserIds, ISetting $set
95100
continue;
96101
}
97102
$event->setAffectedUser($affectedUser);
98-
$notificationSetting = $userPushSettings[$affectedUser] ?? null;
99-
if ($notificationSetting !== null) {
100-
$notificationSetting = (bool)$notificationSetting;
103+
104+
if ($canChangePush === true) {
105+
$notificationSetting = isset($userPushSettings[$affectedUser]) ? (bool)$userPushSettings[$affectedUser] : $defaultPushEnabled;
106+
} else {
107+
$notificationSetting = $defaultPushEnabled;
101108
}
109+
102110
$emailSetting = $userEmailSettings[$affectedUser] ?? false;
103111
$emailSetting = ($emailSetting) ? ($batchTimeSettings[$affectedUser] ?? false) : false;
104112

105-
if ($notificationSetting !== false) {
113+
if ($notificationSetting === true) {
106114
$this->notificationGenerator->sendNotificationForEvent($event, $activityId, $notificationSetting);
107115
}
108116

tests/ConsumerTest.php

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use OCP\Activity\IManager;
3434
use OCP\Activity\ISetting;
3535
use OCP\Config\IUserConfig;
36+
use OCP\IAppConfig;
3637
use OCP\IDBConnection;
3738
use OCP\IL10N;
3839
use OCP\L10N\IFactory;
@@ -53,6 +54,7 @@ class ConsumerTest extends TestCase {
5354
protected NotificationGenerator&MockObject $notificationGenerator;
5455
protected UserSettings $userSettings;
5556
private IUserConfig&MockObject $userConfig;
57+
private IAppConfig&MockObject $appConfig;
5658
private IEvent $event;
5759
private Consumer $consumer;
5860

@@ -70,7 +72,10 @@ protected function setUp(): void {
7072
$this->notificationGenerator = $this->createMock(NotificationGenerator::class);
7173
$this->l10nFactory = $this->createMock(IFactory::class);
7274
$this->userConfig = $this->createMock(IUserConfig::class);
73-
75+
$this->appConfig = $this->createMock(IAppConfig::class);
76+
$this->appConfig->method('getValueString')
77+
->with('activity', 'enable_email', 'yes')
78+
->willReturn('yes');
7479
$this->data->method('send')
7580
->willReturn(1);
7681
$this->l10nFactory
@@ -95,6 +100,7 @@ protected function setUp(): void {
95100
$this->userSettings,
96101
$this->notificationGenerator,
97102
$this->userConfig,
103+
$this->appConfig,
98104
);
99105

100106
$this->event = Server::get(IManager::class)->generateEvent();
@@ -143,6 +149,7 @@ public function testReceiveStream(string $type, string $author, string $affected
143149
$this->userSettings,
144150
$this->notificationGenerator,
145151
$this->userConfig,
152+
$this->appConfig,
146153
);
147154
$event = Server::get(IManager::class)->generateEvent();
148155
$event->setApp('test')
@@ -322,9 +329,7 @@ public function testBulkReceiveNoMailWhenSettingDisabled(): void {
322329

323330
$this->data->expects($this->never())
324331
->method('storeMail');
325-
// Notification is still sent because $notificationSetting defaults to null
326-
// and null !== false, so the default is to send notifications
327-
$this->notificationGenerator->expects($this->once())
332+
$this->notificationGenerator->expects($this->never())
328333
->method('sendNotificationForEvent');
329334

330335
$this->consumer->bulkReceive($this->event, ['affectedUser'], $settings);
@@ -434,8 +439,8 @@ public function testBulkReceiveMultipleUsersWithMixedSettings(): void {
434439
return [];
435440
});
436441

437-
// user1 and user2 get notifications (user2 has null setting which defaults to send), author is skipped
438-
$this->notificationGenerator->expects($this->exactly(2))
442+
// only user1 has an explicit notification=true in DB; user2 has no entry so falls back to isDefaultEnabledNotification()=false
443+
$this->notificationGenerator->expects($this->once())
439444
->method('sendNotificationForEvent');
440445
// user2 gets email, author is skipped
441446
$this->data->expects($this->once())
@@ -445,6 +450,50 @@ public function testBulkReceiveMultipleUsersWithMixedSettings(): void {
445450
$this->consumer->bulkReceive($this->event, ['user1', 'user2', 'author'], $settings);
446451
}
447452

453+
public function testBulkReceiveNoMailWhenAdminEmailDisabled(): void {
454+
$time = time();
455+
$this->event->setApp('activity')
456+
->setType('type')
457+
->setAuthor('author')
458+
->setTimestamp($time)
459+
->setSubject('subject', ['subjectParam1'])
460+
->setMessage('message', ['messageParam1'])
461+
->setObject('', 0, 'file')
462+
->setLink('link');
463+
464+
$appConfig = $this->createMock(IAppConfig::class);
465+
$appConfig->method('getValueString')
466+
->with('activity', 'enable_email', 'yes')
467+
->willReturn('no');
468+
469+
$consumer = new Consumer(
470+
$this->data,
471+
$this->activityManager,
472+
$this->userSettings,
473+
$this->notificationGenerator,
474+
$this->userConfig,
475+
$appConfig,
476+
);
477+
478+
$settings = $this->createMock(ActivitySettings::class);
479+
$settings->method('canChangeMail')->willReturn(true);
480+
$settings->method('isDefaultEnabledMail')->willReturn(true);
481+
$settings->method('canChangeNotification')->willReturn(false);
482+
$settings->method('isDefaultEnabledNotification')->willReturn(false);
483+
484+
$this->data->expects($this->once())
485+
->method('bulkSend')
486+
->willReturn([1 => 'affectedUser']);
487+
488+
$this->userConfig->expects($this->never())
489+
->method('getValuesByUsers');
490+
491+
$this->data->expects($this->never())
492+
->method('storeMail');
493+
494+
$consumer->bulkReceive($this->event, ['affectedUser'], $settings);
495+
}
496+
448497
public function testBulkReceiveWithISetting(): void {
449498
$this->event->setApp('activity')
450499
->setType('type')
@@ -463,9 +512,8 @@ public function testBulkReceiveWithISetting(): void {
463512
->method('bulkSend')
464513
->willReturn([1 => 'affectedUser']);
465514

466-
// Notification is still sent because $notificationSetting defaults to null (not false)
467-
// when ISetting is used (canChangeNotification not available), and null !== false
468-
$this->notificationGenerator->expects($this->once())
515+
// ISetting is not ActivitySettings so $defaultPushEnabled is false — no notification sent
516+
$this->notificationGenerator->expects($this->never())
469517
->method('sendNotificationForEvent');
470518
$this->data->expects($this->never())
471519
->method('storeMail');

0 commit comments

Comments
 (0)