diff options
author | Christoph Wurst <christoph@winzerhof-wurst.at> | 2022-03-25 12:15:28 +0300 |
---|---|---|
committer | Christoph Wurst <christoph@winzerhof-wurst.at> | 2022-03-25 12:15:28 +0300 |
commit | 4e4f85d8f29946fedaaa3fa532cf3b1ab38a0def (patch) | |
tree | 1a3449996aa6a5b62cae180ee9361d0bc0b39c66 /tests | |
parent | 9707fea568543401fd226841b1df07f5de284f87 (diff) | |
parent | ecdae8bdd670a149b626e821be798f01b443a97f (diff) |
Merge remote-tracking branch 'origin/main' into chore/update-feature-outbox-II
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Unit/Service/AntiAbuseServiceTest.php | 199 | ||||
-rw-r--r-- | tests/psalm-baseline.xml | 17 |
2 files changed, 214 insertions, 2 deletions
diff --git a/tests/Unit/Service/AntiAbuseServiceTest.php b/tests/Unit/Service/AntiAbuseServiceTest.php new file mode 100644 index 000000000..ffbd22f4f --- /dev/null +++ b/tests/Unit/Service/AntiAbuseServiceTest.php @@ -0,0 +1,199 @@ +<?php + +declare(strict_types=1); + +/* + * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace OCA\Mail\Tests\Unit\Service; + +use ChristophWurst\Nextcloud\Testing\ServiceMockObject; +use ChristophWurst\Nextcloud\Testing\TestCase; +use OCA\Mail\Account; +use OCA\Mail\Address; +use OCA\Mail\AddressList; +use OCA\Mail\Model\NewMessageData; +use OCA\Mail\Service\AntiAbuseService; +use OCP\IMemcache; +use OCP\IUser; +use function array_map; +use function range; + +class AntiAbuseServiceTest extends TestCase { + + /** @var AntiAbuseService */ + private $service; + + /** @var ServiceMockObject */ + private $serviceMock; + + protected function setUp(): void { + parent::setUp(); + + $this->serviceMock = $this->createServiceMock(AntiAbuseService::class); + $this->service = $this->serviceMock->getService(); + } + + public function testThresholdDisabled(): void { + $user = $this->createMock(IUser::class); + $user->method('getUID')->willReturn('user123'); + $account = $this->createMock(Account::class); + $messageData = new NewMessageData( + $account, + new AddressList([]), + new AddressList([]), + new AddressList([]), + 'subject', + 'henlo', + ); + $this->serviceMock->getParameter('config') + ->expects(self::once()) + ->method('getAppValue') + ->withConsecutive( + ['mail', 'abuse_detection', 'off'], + )->willReturnOnConsecutiveCalls( + 'off', + ); + $this->serviceMock->getParameter('logger') + ->expects(self::never()) + ->method('alert'); + + $this->service->onBeforeMessageSent( + $user, + $messageData, + ); + } + + public function testThresholdReached(): void { + $user = $this->createMock(IUser::class); + $user->method('getUID')->willReturn('user123'); + $account = $this->createMock(Account::class); + $messageData = new NewMessageData( + $account, + new AddressList(array_map(static function (int $i) { + return Address::fromRaw( + "user$i@domain.tld", + "user$i@domain.tld", + ); + }, range(1, 50))), + new AddressList(array_map(static function (int $i) { + return Address::fromRaw( + "user$i@domain.tld", + "user$i@domain.tld", + ); + }, range(51, 60))), + new AddressList(array_map(static function (int $i) { + return Address::fromRaw( + "user$i@domain.tld", + "user$i@domain.tld", + ); + }, range(51, 70))), + 'subject', + 'henlo', + ); + $this->serviceMock->getParameter('config') + ->method('getAppValue') + ->withConsecutive( + ['mail', 'abuse_detection', 'off'], + ['mail', 'abuse_number_of_recipients_per_message_threshold', '0'], + )->willReturnOnConsecutiveCalls( + 'on', + '50', + ); + $this->serviceMock->getParameter('logger') + ->expects(self::once()) + ->method('alert') + ->with(self::anything(), [ + 'user' => 'user123', + 'expected' => 50, + 'actual' => 80, + ]); + + $this->service->onBeforeMessageSent( + $user, + $messageData, + ); + } + + public function test15mThreshold(): void { + $user = $this->createMock(IUser::class); + $user->method('getUID')->willReturn('user123'); + $account = $this->createMock(Account::class); + $messageData = new NewMessageData( + $account, + new AddressList([ + Address::fromRaw( + "user@domain.tld", + "user@domain.tld", + ) + ]), + new AddressList([]), + new AddressList([]), + 'subject', + 'henlo', + ); + $this->serviceMock->getParameter('config') + ->method('getAppValue') + ->withConsecutive( + ['mail', 'abuse_detection', 'off'], + ['mail', 'abuse_number_of_recipients_per_message_threshold', '0'], + ['mail', 'abuse_number_of_messages_per_15m', '0'] + )->willReturnOnConsecutiveCalls( + 'on', + '0', + '5', + ); + $this->serviceMock->getParameter('cacheFactory') + ->expects(self::once()) + ->method('isAvailable') + ->willReturn(true); + $cache = $this->createMock(IMemcache::class); + $this->serviceMock->getParameter('cacheFactory') + ->expects(self::once()) + ->method('createDistributed') + ->willReturn($cache); + $this->serviceMock->getParameter('timeFactory') + ->expects(self::once()) + ->method('getTime') + ->willReturn(123456); + $cache->expects(self::once()) + ->method('add') + ->with('counter_15m_123300', 0); + $cache->expects(self::once()) + ->method('inc') + ->with('counter_15m_123300') + ->willReturn(5); + $this->serviceMock->getParameter('logger') + ->expects(self::once()) + ->method('alert') + ->with(self::anything(), [ + 'user' => 'user123', + 'period' => '15m', + 'expected' => 5, + 'actual' => 5, + ]); + + $this->service->onBeforeMessageSent( + $user, + $messageData, + ); + } +} diff --git a/tests/psalm-baseline.xml b/tests/psalm-baseline.xml index 16f0951d4..e2909dab4 100644 --- a/tests/psalm-baseline.xml +++ b/tests/psalm-baseline.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <files psalm-version="4.x-dev@"> <file src="lib/AppInfo/Application.php"> - <MissingDependency occurrences="14"> + <MissingDependency occurrences="15"> + <code>BeforeMessageSentEvent</code> <code>DraftSavedEvent</code> <code>MailboxesSynchronizedEvent</code> <code>MessageDeletedEvent</code> @@ -161,6 +162,11 @@ <code>Event</code> </MissingDependency> </file> + <file src="lib/Events/BeforeMessageSentEvent.php"> + <MissingDependency occurrences="1"> + <code>Event</code> + </MissingDependency> + </file> <file src="lib/Events/DraftSavedEvent.php"> <MissingDependency occurrences="1"> <code>Event</code> @@ -218,6 +224,12 @@ <code>MessageSentEvent</code> </MissingDependency> </file> + <file src="lib/Listener/AntiAbuseListener.php"> + <MissingDependency occurrences="2"> + <code>AntiAbuseListener</code> + <code>BeforeMessageSentEvent</code> + </MissingDependency> + </file> <file src="lib/Listener/DashboardPanelListener.php"> <MissingDependency occurrences="2"> <code>DashboardPanelListener</code> @@ -313,7 +325,8 @@ </MissingDependency> </file> <file src="lib/Service/MailTransmission.php"> - <MissingDependency occurrences="6"> + <MissingDependency occurrences="7"> + <code>BeforeMessageSentEvent</code> <code>DraftSavedEvent</code> <code>DraftSavedEvent</code> <code>MessageSentEvent</code> |