Skip to content

Commit

Permalink
Merge pull request #8716 from nextcloud/enh/thread-summary-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kesselb authored Aug 14, 2023
2 parents dc6c209 + 66b56df commit 3a99a6b
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/Service/AiIntegrations/AiIntegrationsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function summarizeThread(string $threadId, array $messages, string $curre
try {
$manager = $this->container->get(IManager::class);
} catch (\Throwable $e) {
throw new ServiceException('Text processing is not available in your current Nextcloud version', $e);
throw new ServiceException('Text processing is not available in your current Nextcloud version', 0, $e);
}
if(in_array(SummaryTaskType::class, $manager->getAvailableTaskTypes(), true)) {
$messagesBodies = array_map(function ($message) {
Expand Down
46 changes: 46 additions & 0 deletions tests/Unit/Controller/ThreadControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,4 +242,50 @@ public function testDeleteTrash(): void {

$this->assertEquals(Http::STATUS_OK, $response->getStatus());
}

public function testSummarizeThread(): void {
$mailAccount = new MailAccount();
$mailAccount->setId(1);
$this->accountService
->expects(self::once())
->method('find')
->with('john', 1)
->willReturn(new Account($mailAccount));
$mailbox = new Mailbox();
$mailbox->setId(20);
$mailbox->setAccountId($mailAccount->getId());
$this->mailManager
->method('getMailbox')
->willReturn($mailbox);
$message1 = new Message();
$message1->setId(300);
$message1->setMailboxId($mailbox->getId());
$message1->setPreviewText('message1');
$message1->setThreadRootId('some-thread-root-id-1');

$message2 = new Message();
$message2->setId(301);
$message2->setMailboxId($mailbox->getId());
$message2->setThreadRootId('some-thread-root-id-1');

$message3 = new Message();
$message3->setId(302);
$message3->setMailboxId($mailbox->getId());
$message3->setThreadRootId('some-thread-root-id-1');

$this->mailManager
->method('getMessage')
->willReturn($message1);
$this->aiIntergrationsService
->expects(self::once())
->method('summarizeThread')
->willReturn('example summary');


$response = $this->controller->summarize(300);
$this->assertEquals(Http::STATUS_OK, $response->getStatus());
$this->assertEquals(['data' => 'example summary'], $response->getData());

}

}
156 changes: 156 additions & 0 deletions tests/Unit/Service/AiIntegrationsServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php

declare(strict_types=1);

/**
* @copyright 2023 Hamza Mahjoubi <[email protected]>
*
* @author 2023 Hamza Mahjoubi <[email protected]>
*
* @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\TestCase;
use OCA\Mail\Db\Message;
use OCA\Mail\Exception\ServiceException;
use OCA\Mail\Service\AiIntegrations\AiIntegrationsService;
use OCA\Mail\Service\AiIntegrations\Cache;
use OCP\TextProcessing\FreePromptTaskType;
use OCP\TextProcessing\IManager;
use OCP\TextProcessing\SummaryTaskType;
use OCP\TextProcessing\TopicsTaskType;
use PHPUnit\Framework\Exception;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\UnknownTypeException;
use Psr\Container\ContainerInterface;

class AiIntegrationsServiceTest extends TestCase {

/** @var ContainerInterface|MockObject */
private $container;

/** @var IManager|MockObject */
private $manager;

/** @var AiIntegrationsService */
private $aiIntegrationsService;

/** @var Cache */
private $cache;


protected function setUp(): void {
parent::setUp();
$this->container = $this->createMock(ContainerInterface::class);
try {
$this->manager = $this->createMock(IManager::class);
} catch (UnknownTypeException $e) {
$this->manager = null;
}

$this->cache = $this->createMock(Cache::class);

$this->aiIntegrationsService = new AiIntegrationsService(
$this->container,
$this->cache
);
}

public function testSummarizeThreadNoBackend() {
if($this->manager !== null) {
$this->container->method('get')->willReturn($this->manager);
$this->manager
->method('getAvailableTaskTypes')
->willReturn([]);
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('No language model available for summary');
$this->aiIntegrationsService->summarizeThread('', [], '');
}
$this->container->method('get')->willThrowException(new ServiceException());
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('Text processing is not available in your current Nextcloud version');
$this->aiIntegrationsService->summarizeThread('', [], '');

}

public function testLlmAvailable() {
if($this->manager !== null) {
$this->container->method('get')->willReturn($this->manager);
$this->manager
->method('getAvailableTaskTypes')
->willReturn([SummaryTaskType::class, TopicsTaskType::class, FreePromptTaskType::class]);
$isAvailable = $this->aiIntegrationsService->isLlmAvailable();
$this->assertTrue($isAvailable);
} else {
$this->container->method('get')->willThrowException(new Exception());
$isAvailable = $this->aiIntegrationsService->isLlmAvailable();
$this->assertFalse($isAvailable);
}

}

public function testLlmUnavailable() {
if($this->manager !== null) {
$this->container->method('get')->willReturn($this->manager);
$this->manager
->method('getAvailableTaskTypes')
->willReturn([TopicsTaskType::class, FreePromptTaskType::class]);
$isAvailable = $this->aiIntegrationsService->isLlmAvailable();
$this->assertFalse($isAvailable);
} else {
$this->container->method('get')->willThrowException(new Exception());
$isAvailable = $this->aiIntegrationsService->isLlmAvailable();
$this->assertFalse($isAvailable);
}

}

public function testCached() {
if($this->manager !== null) {
$this->container->method('get')->willReturn($this->manager);
$this->manager
->method('getAvailableTaskTypes')
->willReturn([SummaryTaskType::class]);

$message1 = new Message();
$message1->setMessageId('300');
$message1->setPreviewText('message1');
$message1->setThreadRootId('some-thread-root-id-1');

$message2 = new Message();
$message2->setMessageId('301');
$message2->setPreviewText('message2');
$message2->setThreadRootId('some-thread-root-id-1');

$message3 = new Message();
$message3->setMessageId('302');
$message3->setPreviewText('message3');
$message3->setThreadRootId('some-thread-root-id-1');

$messages = [ $message1,$message2,$message3];
$messageIds = [ $message1->getMessageId(),$message2->getMessageId(),$message3->getMessageId()];

$this->cache
->method('getSummary')
->with($messageIds)
->willReturn('this is a cached summary');

$this->assertEquals('this is a cached summary', $this->aiIntegrationsService->summarizeThread('some-thread-root-id-1', $messages, 'admin'));
}
}
}

0 comments on commit 3a99a6b

Please sign in to comment.