forms/tests/Unit/Activity/ProviderTest.php

453 строки
13 KiB
PHP

<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2021 Jonas Rittershofer <jotoeri@users.noreply.github.com>
*
* @author Jonas Rittershofer <jotoeri@users.noreply.github.com>
*
* @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\Forms\Tests\Unit\Activity;
use OCA\Forms\Activity\Provider;
use OCA\Forms\Db\Form;
use OCA\Forms\Db\FormMapper;
use OCP\Activity\IEvent;
use OCP\Activity\IEventMerger;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IL10N;
use OCP\ILogger;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
use OCP\L10N\IFactory;
use OCP\RichObjectStrings\InvalidObjectExeption;
use OCP\RichObjectStrings\IValidator;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
class ProviderTest extends TestCase {
/** @var Provider */
private $provider;
/** @var FormMapper|MockObject */
private $formMapper;
/** @var IEventMerger|MockObject */
private $eventMerger;
/** @var IGroupManager|MockObject */
private $groupManager;
/** @var IL10N|MockObject */
private $l10n;
/** @var ILogger|MockObject */
private $logger;
/** @var IURLGenerator|MockObject */
private $urlGenerator;
/** @var IUserManager|MockObject */
private $userManager;
/** @var IFactory|MockObject */
private $l10nFactory;
/** @var IValidator|MockObject */
private $validator;
public function setUp(): void {
$this->formMapper = $this->createMock(FormMapper::class);
$this->eventMerger = $this->createMock(IEventMerger::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->logger = $this->createMock(ILogger::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->userManager = $this->createMock(IUserManager::class);
$this->l10nFactory = $this->createMock(IFactory::class);
$this->validator = $this->createMock(IValidator::class);
$this->urlGenerator->expects($this->any())
->method('linkToRouteAbsolute')
->with('forms.page.index')
->willReturn('http://localhost/apps/forms');
$this->urlGenerator->expects($this->any())
->method('getAbsoluteUrl')
->will($this->returnCallback(function (string $path) {
return 'http://localhost' . $path;
}));
$this->urlGenerator->expects($this->any())
->method('imagePath')
->will($this->returnValueMap([
['core', 'actions/shared.svg', '/core/img/actions/shared.svg'],
['core', 'actions/add.svg', '/core/img/actions/add.svg'],
['forms', 'forms-dark.svg', '/apps/forms/img/forms-dark.svg']
]));
$this->provider = new Provider('forms',
$this->formMapper,
$this->eventMerger,
$this->groupManager,
$this->logger,
$this->urlGenerator,
$this->userManager,
$this->l10nFactory,
$this->validator);
// Only for the test, Provider creates it from Factory
$this->l10n = $this->createMock(IL10N::class);
}
// Wrong app-name should be blocked
public function testWrongApp() {
$event = $this->createMock(IEvent::class);
$event->expects($this->once())
->method('getApp')
->willReturn('someOtherApp');
$this->expectException(\InvalidArgumentException::class);
$this->provider->parse('de_DE', $event);
}
// Testing the parse function needs a full parse.
public function testFullParse() {
$l10n = $this->createMock(IL10N::class);
$l10n->expects($this->once())
->method('t')
->will($this->returnCallback(function (string $identity) {
return $identity;
}));
$this->l10nFactory->expects($this->once())
->method('get')
->willReturn($l10n);
$user = $this->createMock(IUser::class);
$user->expects($this->any())
->method('getDisplayName')
->willReturn('The affected User');
$this->userManager->expects($this->once())
->method('get')
->with('affectedUser')
->willReturn($user);
$form = new Form;
$form->setTitle('SomeChangedNiceFormTitle');
$this->formMapper->expects($this->once())
->method('findbyHash')
->with('54321gfedcba')
->willReturn($form);
$event = $this->createMock(IEvent::class);
$event->expects($this->once())
->method('getApp')
->willReturn('forms');
$event->expects($this->atLeastOnce())
->method('getSubject')
->willReturn('newsubmission');
$event->expects($this->atLeastOnce())
->method('getSubjectParameters')
->willReturn([
'userId' => 'affectedUser',
'formTitle' => 'SomeNiceFormTitle',
'formHash' => '54321gfedcba'
]);
$event->expects($this->once())
->method('setParsedSubject')
->with('The affected User answered your form SomeChangedNiceFormTitle');
$event->expects($this->once())
->method('setRichSubject')
->with('{user} answered your form {formTitle}', [
'user' => [
'type' => 'user',
'id' => 'affectedUser',
'name' => 'The affected User'
],
'formTitle' => [
'type' => 'forms-form',
'id' => '54321gfedcba',
'name' => 'SomeChangedNiceFormTitle',
'link' => 'http://localhost/apps/forms/54321gfedcba/results'
]]);
$event->expects($this->once())
->method('setIcon')
->with('http://localhost/core/img/actions/add.svg');
$this->eventMerger->expects($this->once())
->method('mergeEvents')
->with('user', $event, $event)
->willReturn($event);
$this->assertEquals($event, $this->provider->parse('de_DE', $event, $event));
}
// Expected data for Subject-Strings
public function dataGetSubjectString() {
return [
['newshare', '{user} has shared the form {formTitle} with you'],
['newgroupshare', '{user} has shared the form {formTitle} with group {group}'],
['newsubmission', '{user} answered your form {formTitle}']
];
}
/**
* @dataProvider dataGetSubjectString
*
* @param string $subject
* @param string $expected
*/
public function testGetSubjectString(string $subject, string $expected) {
$l10n = $this->createMock(IL10N::class);
$l10n->expects($this->once())
->method('t')
->will($this->returnCallback(function (string $identity) {
return $identity;
}));
$this->assertEquals($expected, $this->provider->getSubjectString($l10n, $subject));
}
// Unknown Subject throws exception
public function testGetUnknownSubjectString() {
$l10n = $this->createMock(IL10N::class);
$l10n->expects($this->never())
->method('t');
$this->expectException(\InvalidArgumentException::class);
$this->provider->getSubjectString($l10n, 'someUnknownSubject');
}
// Test insertions of parameters name
public function testParseSubjectString() {
$this->assertEquals('Heinz and Ernst in a Text with Erna',
$this->provider->parseSubjectString('{param1} and {param2} in a Text with {paramz}', [
'param1' => [
'type' => 'xy',
'name' => 'Heinz'
],
'param2' => [
'type' => 'ab',
'name' => 'Ernst',
'link' => 'http://somehost'
],
'paramz' => [
'type' => 'highlight',
'name' => 'Erna',
'unknownprop' => 'prop'
],
]));
}
/**
* Typical cases of RichParams for subjects
*/
public function dataGetRichParams() {
$newShareResult = [
'user' => [
'type' => 'user',
'id' => 'affectedUser',
'name' => 'The affected User'
],
'formTitle' => [
'type' => 'forms-form',
'id' => 'abcdefg',
'name' => 'Some changed Form Title',
'link' => 'http://localhost/apps/forms/abcdefg'
]
];
// Difference only in additional Group-Param
$newGroupShareResult = $newShareResult;
$newGroupShareResult['group'] = [
'type' => 'user-group',
'id' => 'someGroup',
'name' => 'The Group'
];
// Difference only in different Link on formTitle
$newSubmissionResult = $newShareResult;
$newSubmissionResult['formTitle']['link'] .= '/results';
return [
// [subject, [subjectParams], [expectedResult]],
['unknownSubject', [], []],
['newshare', [
'userId' => 'affectedUser',
'formTitle' => 'Some FormTitle',
'formHash' => 'abcdefg'],
$newShareResult
],
['newgroupshare', [
'userId' => 'affectedUser',
'formTitle' => 'Some FormTitle',
'formHash' => 'abcdefg',
'groupId' => 'someGroup'],
$newGroupShareResult
],
['newsubmission', [
'userId' => 'affectedUser',
'formTitle' => 'Some FormTitle',
'formHash' => 'abcdefg'],
$newSubmissionResult
]
];
}
/**
* @dataProvider dataGetRichParams
*
* @param string $subject
* @param array $subjectParams
* @param array $expected
*/
public function testGetRichParams(string $subject, array $subjectParams, array $expected) {
$l10n = $this->createMock(IL10N::class);
$user = $this->createMock(IUser::class);
$user->expects($this->any())
->method('getDisplayName')
->willReturn('The affected User');
$this->userManager->expects($this->any())
->method('get')
->with('affectedUser')
->willReturn($user);
$group = $this->createMock(IGroup::class);
$group->expects($this->any())
->method('getDisplayName')
->willReturn('The Group');
$this->groupManager->expects($this->any())
->method('get')
->with('someGroup')
->willReturn($group);
$form = new Form();
$form->setHash('abcdefg');
$form->setTitle('Some changed Form Title');
$this->formMapper->expects($this->any())
->method('findByHash')
->with('abcdefg')
->willReturn($form);
$this->validator->expects($this->any())
->method('validate')
->willReturn(true);
$this->assertEquals($expected, $this->provider->getRichParams($l10n, $subject, $subjectParams));
}
/**
* Basic ideal functionality tested already in testGetRichParams
* Only testing special cases here
* - Anonymous User
*/
public function testGetAnonymousRichUser() {
$l10n = $this->createMock(IL10N::class);
$l10n->expects($this->any())
->method('t')
->will($this->returnCallback(function (string $identity) {
return $identity;
}));
$this->assertEquals([
'type' => 'highlight',
'id' => 'anon-user-xyz',
'name' => 'Anonymous user'
], $this->provider->getRichUser($l10n, 'anon-user-xyz'));
}
/**
* Basic ideal functionality tested already in testGetRichParams
* Only testing special cases here
* - Deleted User
*/
public function testGetDeletedRichUser() {
$l10n = $this->createMock(IL10N::class);
$this->userManager->expects($this->any())
->method('get')
->with('someDeletedUser')
->willReturn(null);
$this->assertEquals([
'type' => 'user',
'id' => 'someDeletedUser',
'name' => 'someDeletedUser'
], $this->provider->getRichUser($l10n, 'someDeletedUser'));
}
/*
* Basic ideal functionality tested already in testGetRichParams
* Only testing special cases here
* - Deleted Group
*/
public function testGetRichGroup() {
// Group not found
$this->groupManager->expects($this->once())
->method('get')
->with('someDeletedGroup')
->willReturn(null);
$this->assertEquals([
'type' => 'user-group',
'id' => 'someDeletedGroup',
'name' => 'someDeletedGroup'
], $this->provider->getRichGroup('someDeletedGroup'));
}
/*
* Basic ideal functionality tested already in testGetRichParams
* Only testing special cases here
* - Form not found and type invalid (is invalid for <NC21)
*/
public function testGetRichFormTitle() {
$this->formMapper->expects($this->any())
->method('findbyHash')
->with('abcdefg')
->will($this->throwException(new DoesNotExistException('Form not found')));
$this->validator->expects($this->any())
->method('validate')
->will($this->throwException(new InvalidObjectExeption()));
// Test Form not found and type invalid
$this->assertEquals([
'type' => 'highlight',
'id' => 'abcdefg',
'name' => 'Some Form Title',
'link' => 'http://localhost/apps/forms'
], $this->provider->getRichFormTitle('Some Form Title', 'abcdefg'));
}
/**
* IconList for Subjects
*/
public function dataGetEventIcon() {
return [
['newshare', 'http://localhost/core/img/actions/shared.svg'],
['newgroupshare', 'http://localhost/core/img/actions/shared.svg'],
['newsubmission', 'http://localhost/core/img/actions/add.svg'],
['unknownSubject', 'http://localhost/apps/forms/img/forms-dark.svg'],
];
}
/**
* Get right event-icon
*
* @dataProvider dataGetEventIcon
* @param string $subject
* @param string $iconUrl
*/
public function testGetEventIcon(string $subject, string $iconUrl) {
$this->assertEquals($iconUrl, $this->provider->getEventIcon($subject));
}
}