ManagerTest.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
  4. *
  5. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  6. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  7. * @author Joas Schilling <coding@schilljs.com>
  8. * @author Julius Härtl <jus@bitgrid.net>
  9. * @author Roeland Jago Douma <roeland@famdouma.nl>
  10. *
  11. * @license GNU AGPL version 3 or any later version
  12. *
  13. * This program is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Affero General Public License as
  15. * published by the Free Software Foundation, either version 3 of the
  16. * License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Affero General Public License
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  25. *
  26. */
  27. namespace OCA\WorkflowEngine\Tests;
  28. use OC\L10N\L10N;
  29. use OCA\WorkflowEngine\Entity\File;
  30. use OCA\WorkflowEngine\Helper\ScopeContext;
  31. use OCA\WorkflowEngine\Manager;
  32. use OCP\AppFramework\QueryException;
  33. use OCP\EventDispatcher\IEventDispatcher;
  34. use OCP\Files\IRootFolder;
  35. use OCP\IConfig;
  36. use OCP\IDBConnection;
  37. use OCP\IL10N;
  38. use OCP\ILogger;
  39. use OCP\IServerContainer;
  40. use OCP\IURLGenerator;
  41. use OCP\IUserManager;
  42. use OCP\IUserSession;
  43. use OCP\SystemTag\ISystemTagManager;
  44. use OCP\WorkflowEngine\ICheck;
  45. use OCP\WorkflowEngine\IEntity;
  46. use OCP\WorkflowEngine\IEntityEvent;
  47. use OCP\WorkflowEngine\IManager;
  48. use OCP\WorkflowEngine\IOperation;
  49. use PHPUnit\Framework\MockObject\MockObject;
  50. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  51. use Test\TestCase;
  52. /**
  53. * Class ManagerTest
  54. *
  55. * @package OCA\WorkflowEngine\Tests
  56. * @group DB
  57. */
  58. class ManagerTest extends TestCase {
  59. /** @var Manager */
  60. protected $manager;
  61. /** @var MockObject|IDBConnection */
  62. protected $db;
  63. /** @var \PHPUnit\Framework\MockObject\MockObject|ILogger */
  64. protected $logger;
  65. /** @var \PHPUnit\Framework\MockObject\MockObject|EventDispatcherInterface */
  66. protected $legacyDispatcher;
  67. /** @var MockObject|IServerContainer */
  68. protected $container;
  69. /** @var MockObject|IUserSession */
  70. protected $session;
  71. /** @var MockObject|L10N */
  72. protected $l;
  73. /** @var MockObject|IEventDispatcher */
  74. protected $dispatcher;
  75. /** @var MockObject|IConfig */
  76. protected $config;
  77. protected function setUp(): void {
  78. parent::setUp();
  79. $this->db = \OC::$server->getDatabaseConnection();
  80. $this->container = $this->createMock(IServerContainer::class);
  81. /** @var IL10N|MockObject $l */
  82. $this->l = $this->createMock(IL10N::class);
  83. $this->l->method('t')
  84. ->willReturnCallback(function ($text, $parameters = []) {
  85. return vsprintf($text, $parameters);
  86. });
  87. $this->legacyDispatcher = $this->createMock(EventDispatcherInterface::class);
  88. $this->logger = $this->createMock(ILogger::class);
  89. $this->session = $this->createMock(IUserSession::class);
  90. $this->dispatcher = $this->createMock(IEventDispatcher::class);
  91. $this->config = $this->createMock(IConfig::class);
  92. $this->manager = new Manager(
  93. \OC::$server->getDatabaseConnection(),
  94. $this->container,
  95. $this->l,
  96. $this->legacyDispatcher,
  97. $this->logger,
  98. $this->session,
  99. $this->dispatcher,
  100. $this->config
  101. );
  102. $this->clearTables();
  103. }
  104. protected function tearDown(): void {
  105. $this->clearTables();
  106. parent::tearDown();
  107. }
  108. /**
  109. * @return MockObject|ScopeContext
  110. */
  111. protected function buildScope(string $scopeId = null): MockObject {
  112. $scopeContext = $this->createMock(ScopeContext::class);
  113. $scopeContext->expects($this->any())
  114. ->method('getScope')
  115. ->willReturn($scopeId ? IManager::SCOPE_USER : IManager::SCOPE_ADMIN);
  116. $scopeContext->expects($this->any())
  117. ->method('getScopeId')
  118. ->willReturn($scopeId ?? '');
  119. $scopeContext->expects($this->any())
  120. ->method('getHash')
  121. ->willReturn(md5($scopeId ?? ''));
  122. return $scopeContext;
  123. }
  124. public function clearTables() {
  125. $query = $this->db->getQueryBuilder();
  126. foreach (['flow_checks', 'flow_operations', 'flow_operations_scope'] as $table) {
  127. $query->delete($table)
  128. ->execute();
  129. }
  130. }
  131. public function testChecks() {
  132. $check1 = $this->invokePrivate($this->manager, 'addCheck', ['Test', 'equal', 1]);
  133. $check2 = $this->invokePrivate($this->manager, 'addCheck', ['Test', '!equal', 2]);
  134. $data = $this->manager->getChecks([$check1]);
  135. $this->assertArrayHasKey($check1, $data);
  136. $this->assertArrayNotHasKey($check2, $data);
  137. $data = $this->manager->getChecks([$check1, $check2]);
  138. $this->assertArrayHasKey($check1, $data);
  139. $this->assertArrayHasKey($check2, $data);
  140. $data = $this->manager->getChecks([$check2, $check1]);
  141. $this->assertArrayHasKey($check1, $data);
  142. $this->assertArrayHasKey($check2, $data);
  143. $data = $this->manager->getChecks([$check2]);
  144. $this->assertArrayNotHasKey($check1, $data);
  145. $this->assertArrayHasKey($check2, $data);
  146. }
  147. public function testScope() {
  148. $adminScope = $this->buildScope();
  149. $userScope = $this->buildScope('jackie');
  150. $entity = File::class;
  151. $opId1 = $this->invokePrivate(
  152. $this->manager,
  153. 'insertOperation',
  154. ['OCA\WFE\TestOp', 'Test01', [11, 22], 'foo', $entity, []]
  155. );
  156. $this->invokePrivate($this->manager, 'addScope', [$opId1, $adminScope]);
  157. $opId2 = $this->invokePrivate(
  158. $this->manager,
  159. 'insertOperation',
  160. ['OCA\WFE\TestOp', 'Test02', [33, 22], 'bar', $entity, []]
  161. );
  162. $this->invokePrivate($this->manager, 'addScope', [$opId2, $userScope]);
  163. $opId3 = $this->invokePrivate(
  164. $this->manager,
  165. 'insertOperation',
  166. ['OCA\WFE\TestOp', 'Test03', [11, 44], 'foobar', $entity, []]
  167. );
  168. $this->invokePrivate($this->manager, 'addScope', [$opId3, $userScope]);
  169. $this->assertTrue($this->invokePrivate($this->manager, 'canModify', [$opId1, $adminScope]));
  170. $this->assertFalse($this->invokePrivate($this->manager, 'canModify', [$opId2, $adminScope]));
  171. $this->assertFalse($this->invokePrivate($this->manager, 'canModify', [$opId3, $adminScope]));
  172. $this->assertFalse($this->invokePrivate($this->manager, 'canModify', [$opId1, $userScope]));
  173. $this->assertTrue($this->invokePrivate($this->manager, 'canModify', [$opId2, $userScope]));
  174. $this->assertTrue($this->invokePrivate($this->manager, 'canModify', [$opId3, $userScope]));
  175. }
  176. public function testGetAllOperations() {
  177. $adminScope = $this->buildScope();
  178. $userScope = $this->buildScope('jackie');
  179. $entity = File::class;
  180. $adminOperation = $this->createMock(IOperation::class);
  181. $adminOperation->expects($this->any())
  182. ->method('isAvailableForScope')
  183. ->willReturnMap([
  184. [IManager::SCOPE_ADMIN, true],
  185. [IManager::SCOPE_USER, false],
  186. ]);
  187. $userOperation = $this->createMock(IOperation::class);
  188. $userOperation->expects($this->any())
  189. ->method('isAvailableForScope')
  190. ->willReturnMap([
  191. [IManager::SCOPE_ADMIN, false],
  192. [IManager::SCOPE_USER, true],
  193. ]);
  194. $this->container->expects($this->any())
  195. ->method('query')
  196. ->willReturnCallback(function ($className) use ($adminOperation, $userOperation) {
  197. switch ($className) {
  198. case 'OCA\WFE\TestAdminOp':
  199. return $adminOperation;
  200. case 'OCA\WFE\TestUserOp':
  201. return $userOperation;
  202. }
  203. });
  204. $opId1 = $this->invokePrivate(
  205. $this->manager,
  206. 'insertOperation',
  207. ['OCA\WFE\TestAdminOp', 'Test01', [11, 22], 'foo', $entity, []]
  208. );
  209. $this->invokePrivate($this->manager, 'addScope', [$opId1, $adminScope]);
  210. $opId2 = $this->invokePrivate(
  211. $this->manager,
  212. 'insertOperation',
  213. ['OCA\WFE\TestUserOp', 'Test02', [33, 22], 'bar', $entity, []]
  214. );
  215. $this->invokePrivate($this->manager, 'addScope', [$opId2, $userScope]);
  216. $opId3 = $this->invokePrivate(
  217. $this->manager,
  218. 'insertOperation',
  219. ['OCA\WFE\TestUserOp', 'Test03', [11, 44], 'foobar', $entity, []]
  220. );
  221. $this->invokePrivate($this->manager, 'addScope', [$opId3, $userScope]);
  222. $opId4 = $this->invokePrivate(
  223. $this->manager,
  224. 'insertOperation',
  225. ['OCA\WFE\TestAdminOp', 'Test04', [41, 10, 4], 'NoBar', $entity, []]
  226. );
  227. $this->invokePrivate($this->manager, 'addScope', [$opId4, $userScope]);
  228. $adminOps = $this->manager->getAllOperations($adminScope);
  229. $userOps = $this->manager->getAllOperations($userScope);
  230. $this->assertSame(1, count($adminOps));
  231. $this->assertTrue(array_key_exists('OCA\WFE\TestAdminOp', $adminOps));
  232. $this->assertFalse(array_key_exists('OCA\WFE\TestUserOp', $adminOps));
  233. $this->assertSame(1, count($userOps));
  234. $this->assertFalse(array_key_exists('OCA\WFE\TestAdminOp', $userOps));
  235. $this->assertTrue(array_key_exists('OCA\WFE\TestUserOp', $userOps));
  236. $this->assertSame(2, count($userOps['OCA\WFE\TestUserOp']));
  237. }
  238. public function testGetOperations() {
  239. $adminScope = $this->buildScope();
  240. $userScope = $this->buildScope('jackie');
  241. $entity = File::class;
  242. $opId1 = $this->invokePrivate(
  243. $this->manager,
  244. 'insertOperation',
  245. ['OCA\WFE\TestOp', 'Test01', [11, 22], 'foo', $entity, []]
  246. );
  247. $this->invokePrivate($this->manager, 'addScope', [$opId1, $adminScope]);
  248. $opId4 = $this->invokePrivate(
  249. $this->manager,
  250. 'insertOperation',
  251. ['OCA\WFE\OtherTestOp', 'Test04', [5], 'foo', $entity, []]
  252. );
  253. $this->invokePrivate($this->manager, 'addScope', [$opId4, $adminScope]);
  254. $opId2 = $this->invokePrivate(
  255. $this->manager,
  256. 'insertOperation',
  257. ['OCA\WFE\TestOp', 'Test02', [33, 22], 'bar', $entity, []]
  258. );
  259. $this->invokePrivate($this->manager, 'addScope', [$opId2, $userScope]);
  260. $opId3 = $this->invokePrivate(
  261. $this->manager,
  262. 'insertOperation',
  263. ['OCA\WFE\TestOp', 'Test03', [11, 44], 'foobar', $entity, []]
  264. );
  265. $this->invokePrivate($this->manager, 'addScope', [$opId3, $userScope]);
  266. $opId5 = $this->invokePrivate(
  267. $this->manager,
  268. 'insertOperation',
  269. ['OCA\WFE\OtherTestOp', 'Test05', [5], 'foobar', $entity, []]
  270. );
  271. $this->invokePrivate($this->manager, 'addScope', [$opId5, $userScope]);
  272. $operation = $this->createMock(IOperation::class);
  273. $operation->expects($this->any())
  274. ->method('isAvailableForScope')
  275. ->willReturnMap([
  276. [IManager::SCOPE_ADMIN, true],
  277. [IManager::SCOPE_USER, true],
  278. ]);
  279. $this->container->expects($this->any())
  280. ->method('query')
  281. ->willReturnCallback(function ($className) use ($operation) {
  282. switch ($className) {
  283. case 'OCA\WFE\TestOp':
  284. return $operation;
  285. case 'OCA\WFE\OtherTestOp':
  286. throw new QueryException();
  287. }
  288. });
  289. $adminOps = $this->manager->getOperations('OCA\WFE\TestOp', $adminScope);
  290. $userOps = $this->manager->getOperations('OCA\WFE\TestOp', $userScope);
  291. $this->assertSame(1, count($adminOps));
  292. array_walk($adminOps, function ($op) {
  293. $this->assertTrue($op['class'] === 'OCA\WFE\TestOp');
  294. });
  295. $this->assertSame(2, count($userOps));
  296. array_walk($userOps, function ($op) {
  297. $this->assertTrue($op['class'] === 'OCA\WFE\TestOp');
  298. });
  299. }
  300. public function testUpdateOperation() {
  301. $adminScope = $this->buildScope();
  302. $userScope = $this->buildScope('jackie');
  303. $entity = File::class;
  304. $operationMock = $this->createMock(IOperation::class);
  305. $operationMock->expects($this->any())
  306. ->method('isAvailableForScope')
  307. ->withConsecutive(
  308. [IManager::SCOPE_ADMIN],
  309. [IManager::SCOPE_USER]
  310. )
  311. ->willReturn(true);
  312. $this->container->expects($this->any())
  313. ->method('query')
  314. ->willReturnCallback(function ($class) use ($operationMock) {
  315. if (substr($class, -2) === 'Op') {
  316. return $operationMock;
  317. } elseif ($class === File::class) {
  318. return $this->getMockBuilder(File::class)
  319. ->setConstructorArgs([
  320. $this->l,
  321. $this->createMock(IURLGenerator::class),
  322. $this->createMock(IRootFolder::class),
  323. $this->createMock(ILogger::class),
  324. $this->createMock(\OCP\Share\IManager::class),
  325. $this->createMock(IUserSession::class),
  326. $this->createMock(ISystemTagManager::class),
  327. $this->createMock(IUserManager::class),
  328. ])
  329. ->setMethodsExcept(['getEvents'])
  330. ->getMock();
  331. }
  332. return $this->createMock(ICheck::class);
  333. });
  334. $opId1 = $this->invokePrivate(
  335. $this->manager,
  336. 'insertOperation',
  337. ['OCA\WFE\TestAdminOp', 'Test01', [11, 22], 'foo', $entity, []]
  338. );
  339. $this->invokePrivate($this->manager, 'addScope', [$opId1, $adminScope]);
  340. $opId2 = $this->invokePrivate(
  341. $this->manager,
  342. 'insertOperation',
  343. ['OCA\WFE\TestUserOp', 'Test02', [33, 22], 'bar', $entity, []]
  344. );
  345. $this->invokePrivate($this->manager, 'addScope', [$opId2, $userScope]);
  346. $check1 = ['class' => 'OCA\WFE\C22', 'operator' => 'eq', 'value' => 'asdf'];
  347. $check2 = ['class' => 'OCA\WFE\C33', 'operator' => 'eq', 'value' => 23456];
  348. /** @noinspection PhpUnhandledExceptionInspection */
  349. $op = $this->manager->updateOperation($opId1, 'Test01a', [$check1, $check2], 'foohur', $adminScope, $entity, ['\OCP\Files::postDelete']);
  350. $this->assertSame('Test01a', $op['name']);
  351. $this->assertSame('foohur', $op['operation']);
  352. /** @noinspection PhpUnhandledExceptionInspection */
  353. $op = $this->manager->updateOperation($opId2, 'Test02a', [$check1], 'barfoo', $userScope, $entity, ['\OCP\Files::postDelete']);
  354. $this->assertSame('Test02a', $op['name']);
  355. $this->assertSame('barfoo', $op['operation']);
  356. foreach ([[$adminScope, $opId2], [$userScope, $opId1]] as $run) {
  357. try {
  358. /** @noinspection PhpUnhandledExceptionInspection */
  359. $this->manager->updateOperation($run[1], 'Evil', [$check2], 'hackx0r', $run[0], $entity, []);
  360. $this->assertTrue(false, 'DomainException not thrown');
  361. } catch (\DomainException $e) {
  362. $this->assertTrue(true);
  363. }
  364. }
  365. }
  366. public function testDeleteOperation() {
  367. $adminScope = $this->buildScope();
  368. $userScope = $this->buildScope('jackie');
  369. $entity = File::class;
  370. $opId1 = $this->invokePrivate(
  371. $this->manager,
  372. 'insertOperation',
  373. ['OCA\WFE\TestAdminOp', 'Test01', [11, 22], 'foo', $entity, []]
  374. );
  375. $this->invokePrivate($this->manager, 'addScope', [$opId1, $adminScope]);
  376. $opId2 = $this->invokePrivate(
  377. $this->manager,
  378. 'insertOperation',
  379. ['OCA\WFE\TestUserOp', 'Test02', [33, 22], 'bar', $entity, []]
  380. );
  381. $this->invokePrivate($this->manager, 'addScope', [$opId2, $userScope]);
  382. foreach ([[$adminScope, $opId2], [$userScope, $opId1]] as $run) {
  383. try {
  384. /** @noinspection PhpUnhandledExceptionInspection */
  385. $this->manager->deleteOperation($run[1], $run[0]);
  386. $this->assertTrue(false, 'DomainException not thrown');
  387. } catch (\Exception $e) {
  388. $this->assertInstanceOf(\DomainException::class, $e);
  389. }
  390. }
  391. /** @noinspection PhpUnhandledExceptionInspection */
  392. $this->manager->deleteOperation($opId1, $adminScope);
  393. /** @noinspection PhpUnhandledExceptionInspection */
  394. $this->manager->deleteOperation($opId2, $userScope);
  395. foreach ([$opId1, $opId2] as $opId) {
  396. try {
  397. $this->invokePrivate($this->manager, 'getOperation', [$opId]);
  398. $this->assertTrue(false, 'UnexpectedValueException not thrown');
  399. } catch (\Exception $e) {
  400. $this->assertInstanceOf(\UnexpectedValueException::class, $e);
  401. }
  402. }
  403. }
  404. public function testGetEntitiesListBuildInOnly() {
  405. $fileEntityMock = $this->createMock(File::class);
  406. $this->container->expects($this->once())
  407. ->method('query')
  408. ->with(File::class)
  409. ->willReturn($fileEntityMock);
  410. $entities = $this->manager->getEntitiesList();
  411. $this->assertCount(1, $entities);
  412. $this->assertInstanceOf(IEntity::class, $entities[0]);
  413. }
  414. public function testGetEntitiesList() {
  415. $fileEntityMock = $this->createMock(File::class);
  416. $this->container->expects($this->once())
  417. ->method('query')
  418. ->with(File::class)
  419. ->willReturn($fileEntityMock);
  420. /** @var MockObject|IEntity $extraEntity */
  421. $extraEntity = $this->createMock(IEntity::class);
  422. $this->legacyDispatcher->expects($this->once())
  423. ->method('dispatch')
  424. ->with('OCP\WorkflowEngine::registerEntities', $this->anything())
  425. ->willReturnCallback(function () use ($extraEntity) {
  426. $this->manager->registerEntity($extraEntity);
  427. });
  428. $entities = $this->manager->getEntitiesList();
  429. $this->assertCount(2, $entities);
  430. $entityTypeCounts = array_reduce($entities, function (array $carry, IEntity $entity) {
  431. if ($entity instanceof File) {
  432. $carry[0]++;
  433. } elseif ($entity instanceof IEntity) {
  434. $carry[1]++;
  435. }
  436. return $carry;
  437. }, [0, 0]);
  438. $this->assertSame(1, $entityTypeCounts[0]);
  439. $this->assertSame(1, $entityTypeCounts[1]);
  440. }
  441. public function testValidateOperationOK() {
  442. $check = [
  443. 'class' => ICheck::class,
  444. 'operator' => 'is',
  445. 'value' => 'barfoo',
  446. ];
  447. $operationMock = $this->createMock(IOperation::class);
  448. $entityMock = $this->createMock(IEntity::class);
  449. $eventEntityMock = $this->createMock(IEntityEvent::class);
  450. $checkMock = $this->createMock(ICheck::class);
  451. $scopeMock = $this->createMock(ScopeContext::class);
  452. $scopeMock->expects($this->any())
  453. ->method('getScope')
  454. ->willReturn(IManager::SCOPE_ADMIN);
  455. $operationMock->expects($this->once())
  456. ->method('isAvailableForScope')
  457. ->with(IManager::SCOPE_ADMIN)
  458. ->willReturn(true);
  459. $operationMock->expects($this->once())
  460. ->method('validateOperation')
  461. ->with('test', [$check], 'operationData');
  462. $entityMock->expects($this->any())
  463. ->method('getEvents')
  464. ->willReturn([$eventEntityMock]);
  465. $eventEntityMock->expects($this->any())
  466. ->method('getEventName')
  467. ->willReturn('MyEvent');
  468. $checkMock->expects($this->any())
  469. ->method('supportedEntities')
  470. ->willReturn([IEntity::class]);
  471. $checkMock->expects($this->atLeastOnce())
  472. ->method('validateCheck');
  473. $this->container->expects($this->any())
  474. ->method('query')
  475. ->willReturnCallback(function ($className) use ($operationMock, $entityMock, $eventEntityMock, $checkMock) {
  476. switch ($className) {
  477. case IOperation::class:
  478. return $operationMock;
  479. case IEntity::class:
  480. return $entityMock;
  481. case IEntityEvent::class:
  482. return $eventEntityMock;
  483. case ICheck::class:
  484. return $checkMock;
  485. default:
  486. return $this->createMock($className);
  487. }
  488. });
  489. $this->manager->validateOperation(IOperation::class, 'test', [$check], 'operationData', $scopeMock, IEntity::class, ['MyEvent']);
  490. }
  491. public function testValidateOperationCheckInputLengthError() {
  492. $check = [
  493. 'class' => ICheck::class,
  494. 'operator' => 'is',
  495. 'value' => str_pad('', IManager::MAX_CHECK_VALUE_BYTES + 1, 'FooBar'),
  496. ];
  497. $operationMock = $this->createMock(IOperation::class);
  498. $entityMock = $this->createMock(IEntity::class);
  499. $eventEntityMock = $this->createMock(IEntityEvent::class);
  500. $checkMock = $this->createMock(ICheck::class);
  501. $scopeMock = $this->createMock(ScopeContext::class);
  502. $scopeMock->expects($this->any())
  503. ->method('getScope')
  504. ->willReturn(IManager::SCOPE_ADMIN);
  505. $operationMock->expects($this->once())
  506. ->method('isAvailableForScope')
  507. ->with(IManager::SCOPE_ADMIN)
  508. ->willReturn(true);
  509. $operationMock->expects($this->once())
  510. ->method('validateOperation')
  511. ->with('test', [$check], 'operationData');
  512. $entityMock->expects($this->any())
  513. ->method('getEvents')
  514. ->willReturn([$eventEntityMock]);
  515. $eventEntityMock->expects($this->any())
  516. ->method('getEventName')
  517. ->willReturn('MyEvent');
  518. $checkMock->expects($this->any())
  519. ->method('supportedEntities')
  520. ->willReturn([IEntity::class]);
  521. $checkMock->expects($this->never())
  522. ->method('validateCheck');
  523. $this->container->expects($this->any())
  524. ->method('query')
  525. ->willReturnCallback(function ($className) use ($operationMock, $entityMock, $eventEntityMock, $checkMock) {
  526. switch ($className) {
  527. case IOperation::class:
  528. return $operationMock;
  529. case IEntity::class:
  530. return $entityMock;
  531. case IEntityEvent::class:
  532. return $eventEntityMock;
  533. case ICheck::class:
  534. return $checkMock;
  535. default:
  536. return $this->createMock($className);
  537. }
  538. });
  539. try {
  540. $this->manager->validateOperation(IOperation::class, 'test', [$check], 'operationData', $scopeMock, IEntity::class, ['MyEvent']);
  541. } catch (\UnexpectedValueException $e) {
  542. $this->assertSame('The provided check value is too long', $e->getMessage());
  543. }
  544. }
  545. public function testValidateOperationDataLengthError() {
  546. $check = [
  547. 'class' => ICheck::class,
  548. 'operator' => 'is',
  549. 'value' => 'barfoo',
  550. ];
  551. $operationData = str_pad('', IManager::MAX_OPERATION_VALUE_BYTES + 1, 'FooBar');
  552. $operationMock = $this->createMock(IOperation::class);
  553. $entityMock = $this->createMock(IEntity::class);
  554. $eventEntityMock = $this->createMock(IEntityEvent::class);
  555. $checkMock = $this->createMock(ICheck::class);
  556. $scopeMock = $this->createMock(ScopeContext::class);
  557. $scopeMock->expects($this->any())
  558. ->method('getScope')
  559. ->willReturn(IManager::SCOPE_ADMIN);
  560. $operationMock->expects($this->once())
  561. ->method('isAvailableForScope')
  562. ->with(IManager::SCOPE_ADMIN)
  563. ->willReturn(true);
  564. $operationMock->expects($this->never())
  565. ->method('validateOperation');
  566. $entityMock->expects($this->any())
  567. ->method('getEvents')
  568. ->willReturn([$eventEntityMock]);
  569. $eventEntityMock->expects($this->any())
  570. ->method('getEventName')
  571. ->willReturn('MyEvent');
  572. $checkMock->expects($this->any())
  573. ->method('supportedEntities')
  574. ->willReturn([IEntity::class]);
  575. $checkMock->expects($this->never())
  576. ->method('validateCheck');
  577. $this->container->expects($this->any())
  578. ->method('query')
  579. ->willReturnCallback(function ($className) use ($operationMock, $entityMock, $eventEntityMock, $checkMock) {
  580. switch ($className) {
  581. case IOperation::class:
  582. return $operationMock;
  583. case IEntity::class:
  584. return $entityMock;
  585. case IEntityEvent::class:
  586. return $eventEntityMock;
  587. case ICheck::class:
  588. return $checkMock;
  589. default:
  590. return $this->createMock($className);
  591. }
  592. });
  593. try {
  594. $this->manager->validateOperation(IOperation::class, 'test', [$check], $operationData, $scopeMock, IEntity::class, ['MyEvent']);
  595. } catch (\UnexpectedValueException $e) {
  596. $this->assertSame('The provided operation data is too long', $e->getMessage());
  597. }
  598. }
  599. public function testValidateOperationScopeNotAvailable() {
  600. $check = [
  601. 'class' => ICheck::class,
  602. 'operator' => 'is',
  603. 'value' => 'barfoo',
  604. ];
  605. $operationData = str_pad('', IManager::MAX_OPERATION_VALUE_BYTES + 1, 'FooBar');
  606. $operationMock = $this->createMock(IOperation::class);
  607. $entityMock = $this->createMock(IEntity::class);
  608. $eventEntityMock = $this->createMock(IEntityEvent::class);
  609. $checkMock = $this->createMock(ICheck::class);
  610. $scopeMock = $this->createMock(ScopeContext::class);
  611. $scopeMock->expects($this->any())
  612. ->method('getScope')
  613. ->willReturn(IManager::SCOPE_ADMIN);
  614. $operationMock->expects($this->once())
  615. ->method('isAvailableForScope')
  616. ->with(IManager::SCOPE_ADMIN)
  617. ->willReturn(false);
  618. $operationMock->expects($this->never())
  619. ->method('validateOperation');
  620. $entityMock->expects($this->any())
  621. ->method('getEvents')
  622. ->willReturn([$eventEntityMock]);
  623. $eventEntityMock->expects($this->any())
  624. ->method('getEventName')
  625. ->willReturn('MyEvent');
  626. $checkMock->expects($this->any())
  627. ->method('supportedEntities')
  628. ->willReturn([IEntity::class]);
  629. $checkMock->expects($this->never())
  630. ->method('validateCheck');
  631. $this->container->expects($this->any())
  632. ->method('query')
  633. ->willReturnCallback(function ($className) use ($operationMock, $entityMock, $eventEntityMock, $checkMock) {
  634. switch ($className) {
  635. case IOperation::class:
  636. return $operationMock;
  637. case IEntity::class:
  638. return $entityMock;
  639. case IEntityEvent::class:
  640. return $eventEntityMock;
  641. case ICheck::class:
  642. return $checkMock;
  643. default:
  644. return $this->createMock($className);
  645. }
  646. });
  647. try {
  648. $this->manager->validateOperation(IOperation::class, 'test', [$check], $operationData, $scopeMock, IEntity::class, ['MyEvent']);
  649. } catch (\UnexpectedValueException $e) {
  650. $this->assertSame('Operation OCP\WorkflowEngine\IOperation is invalid', $e->getMessage());
  651. }
  652. }
  653. }