Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 210 additions & 0 deletions tests/ConsumerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use OCP\Activity\ActivitySettings;
use OCP\Activity\IEvent;
use OCP\Activity\IManager;
use OCP\Activity\ISetting;
use OCP\Config\IUserConfig;
use OCP\IDBConnection;
use OCP\IL10N;
Expand Down Expand Up @@ -263,4 +264,213 @@ public function testBulkReceiveNotification(string $type, string $author, string
$this->consumer->bulkReceive($this->event, $affectedUsers, $settings);
}

public function testBulkReceiveEmail(): void {
$time = time();
$this->event->setApp('activity')
->setType('type')
->setAuthor('author')
->setTimestamp($time)
->setSubject('subject', ['subjectParam1'])
->setMessage('message', ['messageParam1'])
->setObject('', 0, 'file')
->setLink('link');

$settings = $this->createMock(ActivitySettings::class);
$settings->method('canChangeMail')->willReturn(true);
$settings->method('isDefaultEnabledMail')->willReturn(true);
$settings->method('canChangeNotification')->willReturn(false);

$this->data->expects($this->once())
->method('bulkSend')
->willReturn([1 => 'affectedUser', 2 => 'affectedUser2']);

$this->userConfig->method('getValuesByUsers')
->willReturnCallback(function (string $app, string $key, mixed $type, array $users): array {
if (str_contains($key, 'email')) {
return array_fill_keys($users, true);
}
if (str_contains($key, 'batchtime')) {
return array_fill_keys($users, 10);
}
return [];
});

$this->data->expects($this->exactly(2))
->method('storeMail');

$this->consumer->bulkReceive($this->event, ['affectedUser', 'affectedUser2'], $settings);
}

public function testBulkReceiveNoMailWhenSettingDisabled(): void {
$this->event->setApp('activity')
->setType('type')
->setAuthor('author')
->setTimestamp(time())
->setSubject('subject', ['subjectParam1'])
->setMessage('message', ['messageParam1'])
->setObject('', 0, 'file')
->setLink('link');

$settings = $this->createMock(ActivitySettings::class);
$settings->method('canChangeMail')->willReturn(false);
$settings->method('isDefaultEnabledMail')->willReturn(false);
$settings->method('canChangeNotification')->willReturn(false);

$this->data->expects($this->once())
->method('bulkSend')
->willReturn([1 => 'affectedUser']);

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

$this->consumer->bulkReceive($this->event, ['affectedUser'], $settings);
}

public function testBulkReceiveDeferAndFlushNotifications(): void {
$this->event->setApp('activity')
->setType('type')
->setAuthor('author')
->setTimestamp(time())
->setSubject('subject', ['subjectParam1'])
->setMessage('message', ['messageParam1'])
->setObject('', 0, 'file')
->setLink('link');

$settings = $this->createMock(ActivitySettings::class);
$settings->method('canChangeMail')->willReturn(false);
$settings->method('isDefaultEnabledMail')->willReturn(false);
$settings->method('canChangeNotification')->willReturn(true);

$this->data->expects($this->once())
->method('bulkSend')
->willReturn([1 => 'affectedUser']);

$this->userConfig->method('getValuesByUsers')
->willReturnCallback(function (string $app, string $key, mixed $type, array $users): array {
return array_fill_keys($users, true);
});

$this->notificationGenerator->expects($this->once())
->method('deferNotifications')
->willReturn(true);
$this->notificationGenerator->expects($this->once())
->method('flushNotifications');
$this->notificationGenerator->expects($this->once())
->method('sendNotificationForEvent');

$this->consumer->bulkReceive($this->event, ['affectedUser'], $settings);
}

public function testBulkReceiveNoFlushWhenDeferReturnsFalse(): void {
$this->event->setApp('activity')
->setType('type')
->setAuthor('author')
->setTimestamp(time())
->setSubject('subject', ['subjectParam1'])
->setMessage('message', ['messageParam1'])
->setObject('', 0, 'file')
->setLink('link');

$settings = $this->createMock(ActivitySettings::class);
$settings->method('canChangeMail')->willReturn(false);
$settings->method('isDefaultEnabledMail')->willReturn(false);
$settings->method('canChangeNotification')->willReturn(true);

$this->data->expects($this->once())
->method('bulkSend')
->willReturn([1 => 'affectedUser']);

$this->userConfig->method('getValuesByUsers')
->willReturnCallback(function (string $app, string $key, mixed $type, array $users): array {
return array_fill_keys($users, true);
});

$this->notificationGenerator->expects($this->once())
->method('deferNotifications')
->willReturn(false);
$this->notificationGenerator->expects($this->never())
->method('flushNotifications');

$this->consumer->bulkReceive($this->event, ['affectedUser'], $settings);
}

public function testBulkReceiveMultipleUsersWithMixedSettings(): void {
$time = time();
$this->event->setApp('activity')
->setType('type')
->setAuthor('author')
->setTimestamp($time)
->setSubject('subject', ['subjectParam1'])
->setMessage('message', ['messageParam1'])
->setObject('', 0, 'file')
->setLink('link');

$settings = $this->createMock(ActivitySettings::class);
$settings->method('canChangeMail')->willReturn(true);
$settings->method('isDefaultEnabledMail')->willReturn(true);
$settings->method('canChangeNotification')->willReturn(true);

$this->data->expects($this->once())
->method('bulkSend')
->willReturn([1 => 'user1', 2 => 'user2', 3 => 'author']);

$this->userConfig->method('getValuesByUsers')
->willReturnCallback(function (string $app, string $key, mixed $type, array $users): array {
if (str_contains($key, 'notification')) {
// Only user1 has notifications enabled
return ['user1' => true];
}
if (str_contains($key, 'email')) {
// Only user2 has email enabled
return ['user2' => true];
}
if (str_contains($key, 'batchtime')) {
return ['user2' => 15];
}
return [];
});

// user1 and user2 get notifications (user2 has null setting which defaults to send), author is skipped
$this->notificationGenerator->expects($this->exactly(2))
->method('sendNotificationForEvent');
// user2 gets email, author is skipped
$this->data->expects($this->once())
->method('storeMail')
->with($this->event, $time + 15);

$this->consumer->bulkReceive($this->event, ['user1', 'user2', 'author'], $settings);
}

public function testBulkReceiveWithISetting(): void {
$this->event->setApp('activity')
->setType('type')
->setAuthor('author')
->setTimestamp(time())
->setSubject('subject', ['subjectParam1'])
->setMessage('message', ['messageParam1'])
->setObject('', 0, 'file')
->setLink('link');

// ISetting (not ActivitySettings) — canChangeNotification is not available
$settings = $this->createMock(ISetting::class);
$settings->method('canChangeMail')->willReturn(false);

$this->data->expects($this->once())
->method('bulkSend')
->willReturn([1 => 'affectedUser']);

// Notification is still sent because $notificationSetting defaults to null (not false)
// when ISetting is used (canChangeNotification not available), and null !== false
$this->notificationGenerator->expects($this->once())
->method('sendNotificationForEvent');
$this->data->expects($this->never())
->method('storeMail');

$this->consumer->bulkReceive($this->event, ['affectedUser'], $settings);
}

}
62 changes: 62 additions & 0 deletions tests/DataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,68 @@ public function testStoreMail(string $actionUser, string $affectedUser, string $
$this->deleteTestMails();
}

public function testBulkSend(): void {
$this->deleteTestActivities();

$event = $this->realActivityManager->generateEvent();
$event->setApp('test')
->setType('type')
->setAuthor('author')
->setTimestamp(time())
->setSubject('subject', ['param1'])
->setMessage('message', ['msgParam1'])
->setObject('files', 42, 'file.txt')
->setLink('https://example.com');

$affectedUsers = ['user1', 'user2', 'user3'];
$activityIds = $this->data->bulkSend($event, $affectedUsers);

$this->assertCount(3, $activityIds);
// Values should be the affected user strings
$this->assertEqualsCanonicalizing($affectedUsers, array_values($activityIds));
// Keys should be positive integer IDs
foreach (array_keys($activityIds) as $id) {
$this->assertGreaterThan(0, $id);
}

// Verify rows in DB
$qb = $this->dbConnection->getQueryBuilder();
$query = $qb->select('user', 'affecteduser', 'app', 'subject', 'object_type', 'object_id')
->from('activity')
->where($qb->expr()->eq('app', $qb->createNamedParameter('test')))
->orderBy('activity_id', 'ASC');
$result = $query->executeQuery();
$rows = $result->fetchAll();

$this->assertCount(3, $rows);
foreach ($rows as $i => $row) {
$this->assertSame('author', $row['user']);
$this->assertSame($affectedUsers[$i], $row['affecteduser']);
$this->assertSame('test', $row['app']);
$this->assertSame('subject', $row['subject']);
$this->assertSame('files', $row['object_type']);
$this->assertEquals(42, $row['object_id']);
}

$this->deleteTestActivities();
}

public function testBulkSendEmptyUsers(): void {
$this->deleteTestActivities();

$event = $this->realActivityManager->generateEvent();
$event->setApp('test')
->setType('type')
->setAuthor('author')
->setTimestamp(time())
->setSubject('subject');

$activityIds = $this->data->bulkSend($event, []);
$this->assertEmpty($activityIds);

$this->deleteTestActivities();
}

public static function dataSetOffsetFromSince(): array {
return [
['ASC', '`timestamp` >= \'123465789\'', '`activity_id` > \'{id}\'', null, null, null],
Expand Down
Loading