3 namespace Drupal\Tests\workflows\Unit;
5 use Drupal\Core\DependencyInjection\ContainerBuilder;
6 use Drupal\Tests\UnitTestCase;
7 use Drupal\workflows\Entity\Workflow;
8 use Drupal\workflows\State;
9 use Drupal\workflows\Transition;
10 use Drupal\workflows\WorkflowTypeInterface;
11 use Drupal\workflows\WorkflowTypeManager;
12 use Prophecy\Argument;
15 * @coversDefaultClass \Drupal\workflows\Entity\Workflow
19 class WorkflowTest extends UnitTestCase {
24 protected function setUp() {
26 // Create a container so that the plugin manager and workflow type can be
28 $container = new ContainerBuilder();
29 $workflow_type = $this->prophesize(WorkflowTypeInterface::class);
30 $workflow_type->decorateState(Argument::any())->willReturnArgument(0);
31 $workflow_type->decorateTransition(Argument::any())->willReturnArgument(0);
32 $workflow_manager = $this->prophesize(WorkflowTypeManager::class);
33 $workflow_manager->createInstance('test_type', Argument::any())->willReturn($workflow_type->reveal());
34 $container->set('plugin.manager.workflows.type', $workflow_manager->reveal());
35 \Drupal::setContainer($container);
42 public function testAddAndHasState() {
43 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
44 $this->assertFalse($workflow->hasState('draft'));
46 // By default states are ordered in the order added.
47 $workflow->addState('draft', 'Draft');
48 $this->assertTrue($workflow->hasState('draft'));
49 $this->assertFalse($workflow->hasState('published'));
50 $this->assertEquals(0, $workflow->getState('draft')->weight());
51 // Adding a state does not set up a transition to itself.
52 $this->assertFalse($workflow->hasTransitionFromStateToState('draft', 'draft'));
54 // New states are added with a new weight 1 more than the current highest
56 $workflow->addState('published', 'Published');
57 $this->assertEquals(1, $workflow->getState('published')->weight());
63 public function testAddStateException() {
64 $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' already exists in workflow 'test'");
65 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
66 $workflow->addState('draft', 'Draft');
67 $workflow->addState('draft', 'Draft');
73 public function testAddStateInvalidIdException() {
74 $this->setExpectedException(\InvalidArgumentException::class, "The state ID 'draft-draft' must contain only lowercase letters, numbers, and underscores");
75 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
76 $workflow->addState('draft-draft', 'Draft');
82 public function testGetStates() {
83 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
85 // Getting states works when there are none.
86 $this->assertArrayEquals([], array_keys($workflow->getStates()));
87 $this->assertArrayEquals([], array_keys($workflow->getStates([])));
90 ->addState('draft', 'Draft')
91 ->addState('published', 'Published')
92 ->addState('archived', 'Archived');
94 // States are stored in alphabetical key order.
95 $this->assertArrayEquals([
99 ], array_keys($workflow->get('states')));
101 // Ensure we're returning state objects.
102 $this->assertInstanceOf(State::class, $workflow->getStates()['draft']);
104 // Passing in no IDs returns all states.
105 $this->assertArrayEquals(['draft', 'published', 'archived'], array_keys($workflow->getStates()));
107 // The order of states is by weight.
108 $workflow->setStateWeight('published', -1);
109 $this->assertArrayEquals(['published', 'draft', 'archived'], array_keys($workflow->getStates()));
111 // The label is also used for sorting if weights are equal.
112 $workflow->setStateWeight('archived', 0);
113 $this->assertArrayEquals(['published', 'archived', 'draft'], array_keys($workflow->getStates()));
115 // You can limit the states returned by passing in states IDs.
116 $this->assertArrayEquals(['archived', 'draft'], array_keys($workflow->getStates(['draft', 'archived'])));
118 // An empty array does not load all states.
119 $this->assertArrayEquals([], array_keys($workflow->getStates([])));
123 * @covers ::getStates
125 public function testGetStatesException() {
126 $this->setExpectedException(\InvalidArgumentException::class, "The state 'state_that_does_not_exist' does not exist in workflow 'test'");
127 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
128 $workflow->getStates(['state_that_does_not_exist']);
134 public function testGetState() {
135 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
136 // By default states are ordered in the order added.
138 ->addState('draft', 'Draft')
139 ->addState('published', 'Published')
140 ->addState('archived', 'Archived')
141 ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft')
142 ->addTransition('publish', 'Publish', ['draft'], 'published');
144 // Ensure we're returning state objects and they are set up correctly
145 $this->assertInstanceOf(State::class, $workflow->getState('draft'));
146 $this->assertEquals('archived', $workflow->getState('archived')->id());
147 $this->assertEquals('Archived', $workflow->getState('archived')->label());
149 $draft = $workflow->getState('draft');
150 $this->assertTrue($draft->canTransitionTo('draft'));
151 $this->assertTrue($draft->canTransitionTo('published'));
152 $this->assertFalse($draft->canTransitionTo('archived'));
153 $this->assertEquals('Publish', $draft->getTransitionTo('published')->label());
154 $this->assertEquals(0, $draft->weight());
155 $this->assertEquals(1, $workflow->getState('published')->weight());
156 $this->assertEquals(2, $workflow->getState('archived')->weight());
162 public function testGetStateException() {
163 $this->setExpectedException(\InvalidArgumentException::class, "The state 'state_that_does_not_exist' does not exist in workflow 'test'");
164 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
165 $workflow->getState('state_that_does_not_exist');
169 * @covers ::setStateLabel
171 public function testSetStateLabel() {
172 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
173 $workflow->addState('draft', 'Draft');
174 $this->assertEquals('Draft', $workflow->getState('draft')->label());
175 $workflow->setStateLabel('draft', 'Unpublished');
176 $this->assertEquals('Unpublished', $workflow->getState('draft')->label());
180 * @covers ::setStateLabel
182 public function testSetStateLabelException() {
183 $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' does not exist in workflow 'test'");
184 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
185 $workflow->setStateLabel('draft', 'Draft');
189 * @covers ::setStateWeight
191 public function testSetStateWeight() {
192 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
193 $workflow->addState('draft', 'Draft');
194 $this->assertEquals(0, $workflow->getState('draft')->weight());
195 $workflow->setStateWeight('draft', -10);
196 $this->assertEquals(-10, $workflow->getState('draft')->weight());
200 * @covers ::setStateWeight
202 public function testSetStateWeightException() {
203 $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' does not exist in workflow 'test'");
204 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
205 $workflow->setStateWeight('draft', 10);
209 * @covers ::deleteState
211 public function testDeleteState() {
212 // Create a container so that the plugin manager and workflow type can be
213 // mocked and test that
214 // \Drupal\workflows\WorkflowTypeInterface::deleteState() is called
216 $container = new ContainerBuilder();
217 $workflow_type = $this->prophesize(WorkflowTypeInterface::class);
218 $workflow_type->decorateState(Argument::any())->willReturnArgument(0);
219 $workflow_type->decorateTransition(Argument::any())->willReturnArgument(0);
220 $workflow_type->deleteState('draft')->shouldBeCalled();
221 $workflow_type->deleteTransition('create_new_draft')->shouldBeCalled();
222 $workflow_manager = $this->prophesize(WorkflowTypeManager::class);
223 $workflow_manager->createInstance('test_type', Argument::any())->willReturn($workflow_type->reveal());
224 $container->set('plugin.manager.workflows.type', $workflow_manager->reveal());
225 \Drupal::setContainer($container);
227 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
229 ->addState('draft', 'Draft')
230 ->addState('published', 'Published')
231 ->addTransition('publish', 'Publish', ['draft', 'published'], 'published')
232 ->addTransition('create_new_draft', 'Create new draft', ['draft', 'published'], 'draft');
233 $this->assertCount(2, $workflow->getStates());
234 $this->assertCount(2, $workflow->getState('published')->getTransitions());
235 $workflow->deleteState('draft');
236 $this->assertFalse($workflow->hasState('draft'));
237 $this->assertCount(1, $workflow->getStates());
238 $this->assertCount(1, $workflow->getState('published')->getTransitions());
242 * @covers ::deleteState
244 public function testDeleteStateException() {
245 $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' does not exist in workflow 'test'");
246 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
247 $workflow->deleteState('draft');
251 * @covers ::deleteState
253 public function testDeleteOnlyStateException() {
254 $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' can not be deleted from workflow 'test' as it is the only state");
255 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
256 $workflow->addState('draft', 'Draft');
257 $workflow->deleteState('draft');
261 * @covers ::addTransition
262 * @covers ::hasTransition
264 public function testAddTransition() {
265 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
267 // By default states are ordered in the order added.
269 ->addState('draft', 'Draft')
270 ->addState('published', 'Published');
272 $this->assertFalse($workflow->getState('draft')->canTransitionTo('published'));
273 $workflow->addTransition('publish', 'Publish', ['draft'], 'published');
274 $this->assertTrue($workflow->getState('draft')->canTransitionTo('published'));
275 $this->assertEquals(0, $workflow->getTransition('publish')->weight());
276 $this->assertTrue($workflow->hasTransition('publish'));
277 $this->assertFalse($workflow->hasTransition('draft'));
279 $workflow->addTransition('save_publish', 'Save', ['published'], 'published');
280 $this->assertEquals(1, $workflow->getTransition('save_publish')->weight());
284 * @covers ::addTransition
286 public function testAddTransitionDuplicateException() {
287 $this->setExpectedException(\InvalidArgumentException::class, "The transition 'publish' already exists in workflow 'test'");
288 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
289 $workflow->addState('published', 'Published');
290 $workflow->addTransition('publish', 'Publish', ['published'], 'published');
291 $workflow->addTransition('publish', 'Publish', ['published'], 'published');
295 * @covers ::addTransition
297 public function testAddTransitionInvalidIdException() {
298 $this->setExpectedException(\InvalidArgumentException::class, "The transition ID 'publish-publish' must contain only lowercase letters, numbers, and underscores");
299 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
300 $workflow->addState('published', 'Published');
301 $workflow->addTransition('publish-publish', 'Publish', ['published'], 'published');
305 * @covers ::addTransition
307 public function testAddTransitionMissingFromException() {
308 $this->setExpectedException(\InvalidArgumentException::class, "The state 'draft' does not exist in workflow 'test'");
309 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
310 $workflow->addState('published', 'Published');
311 $workflow->addTransition('publish', 'Publish', ['draft'], 'published');
315 * @covers ::addTransition
317 public function testAddTransitionDuplicateTransitionStatesException() {
318 $this->setExpectedException(\InvalidArgumentException::class, "The 'publish' transition already allows 'draft' to 'published' transitions in workflow 'test'");
319 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
321 ->addState('draft', 'Draft')
322 ->addState('published', 'Published');
323 $workflow->addTransition('publish', 'Publish', ['draft', 'published'], 'published');
324 $workflow->addTransition('draft_to_published', 'Publish a draft', ['draft'], 'published');
328 * @covers ::addTransition
330 public function testAddTransitionConsistentAfterFromCatch() {
331 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
332 $workflow->addState('published', 'Published');
334 $workflow->addTransition('publish', 'Publish', ['draft'], 'published');
336 catch (\InvalidArgumentException $e) {
338 // Ensure that the workflow is not left in an inconsistent state after an
339 // exception is thrown from Workflow::setTransitionFromStates() whilst
340 // calling Workflow::addTransition().
341 $this->assertFalse($workflow->hasTransition('publish'));
345 * @covers ::addTransition
347 public function testAddTransitionMissingToException() {
348 $this->setExpectedException(\InvalidArgumentException::class, "The state 'published' does not exist in workflow 'test'");
349 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
350 $workflow->addState('draft', 'Draft');
351 $workflow->addTransition('publish', 'Publish', ['draft'], 'published');
355 * @covers ::getTransitions
356 * @covers ::setTransitionWeight
358 public function testGetTransitions() {
359 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
361 // Getting transitions works when there are none.
362 $this->assertArrayEquals([], array_keys($workflow->getTransitions()));
363 $this->assertArrayEquals([], array_keys($workflow->getTransitions([])));
365 // By default states are ordered in the order added.
369 ->addTransition('a_b', 'A to B', ['a'], 'b')
370 ->addTransition('a_a', 'A to A', ['a'], 'a');
372 // Transitions are stored in alphabetical key order in configuration.
373 $this->assertArrayEquals(['a_a', 'a_b'], array_keys($workflow->get('transitions')));
375 // Ensure we're returning transition objects.
376 $this->assertInstanceOf(Transition::class, $workflow->getTransitions()['a_a']);
378 // Passing in no IDs returns all transitions.
379 $this->assertArrayEquals(['a_b', 'a_a'], array_keys($workflow->getTransitions()));
381 // The order of states is by weight.
382 $workflow->setTransitionWeight('a_a', -1);
383 $this->assertArrayEquals(['a_a', 'a_b'], array_keys($workflow->getTransitions()));
385 // If all weights are equal it will fallback to labels.
386 $workflow->setTransitionWeight('a_a', 0);
387 $this->assertArrayEquals(['a_a', 'a_b'], array_keys($workflow->getTransitions()));
388 $workflow->setTransitionLabel('a_b', 'A B');
389 $this->assertArrayEquals(['a_b', 'a_a'], array_keys($workflow->getTransitions()));
391 // You can limit the states returned by passing in states IDs.
392 $this->assertArrayEquals(['a_a'], array_keys($workflow->getTransitions(['a_a'])));
394 // An empty array does not load all states.
395 $this->assertArrayEquals([], array_keys($workflow->getTransitions([])));
400 * @covers ::getTransition
402 public function testGetTransition() {
403 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
404 // By default states are ordered in the order added.
406 ->addState('draft', 'Draft')
407 ->addState('published', 'Published')
408 ->addState('archived', 'Archived')
409 ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft')
410 ->addTransition('publish', 'Publish', ['draft'], 'published');
412 // Ensure we're returning state objects and they are set up correctly
413 $this->assertInstanceOf(Transition::class, $workflow->getTransition('create_new_draft'));
414 $this->assertEquals('publish', $workflow->getTransition('publish')->id());
415 $this->assertEquals('Publish', $workflow->getTransition('publish')->label());
417 $transition = $workflow->getTransition('publish');
418 $this->assertEquals($workflow->getState('draft'), $transition->from()['draft']);
419 $this->assertEquals($workflow->getState('published'), $transition->to());
423 * @covers ::getTransition
425 public function testGetTransitionException() {
426 $this->setExpectedException(\InvalidArgumentException::class, "The transition 'transition_that_does_not_exist' does not exist in workflow 'test'");
427 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
428 $workflow->getTransition('transition_that_does_not_exist');
432 * @covers ::getTransitionsForState
434 public function testGetTransitionsForState() {
435 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
436 // By default states are ordered in the order added.
438 ->addState('draft', 'Draft')
439 ->addState('published', 'Published')
440 ->addState('archived', 'Archived')
441 ->addTransition('create_new_draft', 'Create new draft', ['archived', 'draft'], 'draft')
442 ->addTransition('publish', 'Publish', ['draft', 'published'], 'published')
443 ->addTransition('archive', 'Archive', ['published'], 'archived');
445 $this->assertEquals(['create_new_draft', 'publish'], array_keys($workflow->getTransitionsForState('draft')));
446 $this->assertEquals(['create_new_draft'], array_keys($workflow->getTransitionsForState('draft', 'to')));
447 $this->assertEquals(['publish', 'archive'], array_keys($workflow->getTransitionsForState('published')));
448 $this->assertEquals(['publish'], array_keys($workflow->getTransitionsForState('published', 'to')));
449 $this->assertEquals(['create_new_draft'], array_keys($workflow->getTransitionsForState('archived', 'from')));
450 $this->assertEquals(['archive'], array_keys($workflow->getTransitionsForState('archived', 'to')));
455 * @covers ::getTransitionFromStateToState
456 * @covers ::hasTransitionFromStateToState
458 public function testGetTransitionFromStateToState() {
459 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
460 // By default states are ordered in the order added.
462 ->addState('draft', 'Draft')
463 ->addState('published', 'Published')
464 ->addState('archived', 'Archived')
465 ->addTransition('create_new_draft', 'Create new draft', ['archived', 'draft'], 'draft')
466 ->addTransition('publish', 'Publish', ['draft', 'published'], 'published')
467 ->addTransition('archive', 'Archive', ['published'], 'archived');
469 $this->assertTrue($workflow->hasTransitionFromStateToState('draft', 'published'));
470 $this->assertFalse($workflow->hasTransitionFromStateToState('archived', 'archived'));
471 $transition = $workflow->getTransitionFromStateToState('published', 'archived');
472 $this->assertEquals('Archive', $transition->label());
476 * @covers ::getTransitionFromStateToState
478 public function testGetTransitionFromStateToStateException() {
479 $this->setExpectedException(\InvalidArgumentException::class, "The transition from 'archived' to 'archived' does not exist in workflow 'test'");
480 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
481 // By default states are ordered in the order added.
483 ->addState('draft', 'Draft')
484 ->addState('published', 'Published')
485 ->addState('archived', 'Archived')
486 ->addTransition('create_new_draft', 'Create new draft', ['archived', 'draft'], 'draft')
487 ->addTransition('publish', 'Publish', ['draft', 'published'], 'published')
488 ->addTransition('archive', 'Archive', ['published'], 'archived');
490 $workflow->getTransitionFromStateToState('archived', 'archived');
494 * @covers ::setTransitionLabel
496 public function testSetTransitionLabel() {
497 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
499 ->addState('draft', 'Draft')
500 ->addState('published', 'Published')
501 ->addTransition('publish', 'Publish', ['draft'], 'published');
502 $this->assertEquals('Publish', $workflow->getTransition('publish')->label());
503 $workflow->setTransitionLabel('publish', 'Publish!');
504 $this->assertEquals('Publish!', $workflow->getTransition('publish')->label());
508 * @covers ::setTransitionLabel
510 public function testSetTransitionLabelException() {
511 $this->setExpectedException(\InvalidArgumentException::class, "The transition 'draft-published' does not exist in workflow 'test'");
512 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
513 $workflow->addState('published', 'Published');
514 $workflow->setTransitionLabel('draft-published', 'Publish');
518 * @covers ::setTransitionWeight
520 public function testSetTransitionWeight() {
521 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
523 ->addState('draft', 'Draft')
524 ->addState('published', 'Published')
525 ->addTransition('publish', 'Publish', ['draft'], 'published');
526 $this->assertEquals(0, $workflow->getTransition('publish')->weight());
527 $workflow->setTransitionWeight('publish', 10);
528 $this->assertEquals(10, $workflow->getTransition('publish')->weight());
532 * @covers ::setTransitionWeight
534 public function testSetTransitionWeightException() {
535 $this->setExpectedException(\InvalidArgumentException::class, "The transition 'draft-published' does not exist in workflow 'test'");
536 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
537 $workflow->addState('published', 'Published');
538 $workflow->setTransitionWeight('draft-published', 10);
542 * @covers ::setTransitionFromStates
544 public function testSetTransitionFromStates() {
545 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
547 ->addState('draft', 'Draft')
548 ->addState('published', 'Published')
549 ->addState('archived', 'Archived')
550 ->addTransition('test', 'Test', ['draft'], 'draft');
552 $this->assertTrue($workflow->hasTransitionFromStateToState('draft', 'draft'));
553 $this->assertFalse($workflow->hasTransitionFromStateToState('published', 'draft'));
554 $this->assertFalse($workflow->hasTransitionFromStateToState('archived', 'draft'));
555 $workflow->setTransitionFromStates('test', ['draft', 'published', 'archived']);
556 $this->assertTrue($workflow->hasTransitionFromStateToState('draft', 'draft'));
557 $this->assertTrue($workflow->hasTransitionFromStateToState('published', 'draft'));
558 $this->assertTrue($workflow->hasTransitionFromStateToState('archived', 'draft'));
559 $workflow->setTransitionFromStates('test', ['published', 'archived']);
560 $this->assertFalse($workflow->hasTransitionFromStateToState('draft', 'draft'));
561 $this->assertTrue($workflow->hasTransitionFromStateToState('published', 'draft'));
562 $this->assertTrue($workflow->hasTransitionFromStateToState('archived', 'draft'));
566 * @covers ::setTransitionFromStates
568 public function testSetTransitionFromStatesMissingTransition() {
569 $this->setExpectedException(\InvalidArgumentException::class, "The transition 'test' does not exist in workflow 'test'");
570 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
572 ->addState('draft', 'Draft')
573 ->addState('published', 'Published')
574 ->addState('archived', 'Archived')
575 ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft');
577 $workflow->setTransitionFromStates('test', ['draft', 'published', 'archived']);
581 * @covers ::setTransitionFromStates
583 public function testSetTransitionFromStatesMissingState() {
584 $this->setExpectedException(\InvalidArgumentException::class, "The state 'published' does not exist in workflow 'test'");
585 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
587 ->addState('draft', 'Draft')
588 ->addState('archived', 'Archived')
589 ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft');
591 $workflow->setTransitionFromStates('create_new_draft', ['draft', 'published', 'archived']);
595 * @covers ::setTransitionFromStates
597 public function testSetTransitionFromStatesAlreadyExists() {
598 $this->setExpectedException(\InvalidArgumentException::class, "The 'create_new_draft' transition already allows 'draft' to 'draft' transitions in workflow 'test'");
599 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
601 ->addState('draft', 'Draft')
602 ->addState('archived', 'Archived')
603 ->addState('needs_review', 'Needs Review')
604 ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft')
605 ->addTransition('needs_review', 'Needs review', ['needs_review'], 'draft');
607 $workflow->setTransitionFromStates('needs_review', ['draft']);
611 * @covers ::deleteTransition
613 public function testDeleteTransition() {
614 // Create a container so that the plugin manager and workflow type can be
615 // mocked and test that
616 // \Drupal\workflows\WorkflowTypeInterface::deleteState() is called
618 $container = new ContainerBuilder();
619 $workflow_type = $this->prophesize(WorkflowTypeInterface::class);
620 $workflow_type->decorateState(Argument::any())->willReturnArgument(0);
621 $workflow_type->decorateTransition(Argument::any())->willReturnArgument(0);
622 $workflow_type->deleteTransition('publish')->shouldBeCalled();
623 $workflow_manager = $this->prophesize(WorkflowTypeManager::class);
624 $workflow_manager->createInstance('test_type', Argument::any())->willReturn($workflow_type->reveal());
625 $container->set('plugin.manager.workflows.type', $workflow_manager->reveal());
626 \Drupal::setContainer($container);
628 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
630 ->addState('draft', 'Draft')
631 ->addState('published', 'Published')
632 ->addTransition('create_new_draft', 'Create new draft', ['draft'], 'draft')
633 ->addTransition('publish', 'Publish', ['draft'], 'published');
634 $this->assertTrue($workflow->getState('draft')->canTransitionTo('published'));
635 $workflow->deleteTransition('publish');
636 $this->assertFalse($workflow->getState('draft')->canTransitionTo('published'));
637 $this->assertTrue($workflow->getState('draft')->canTransitionTo('draft'));
641 * @covers ::deleteTransition
643 public function testDeleteTransitionException() {
644 $this->setExpectedException(\InvalidArgumentException::class, "The transition 'draft-published' does not exist in workflow 'test'");
645 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
646 $workflow->addState('published', 'Published');
647 $workflow->deleteTransition('draft-published');
653 public function testStatus() {
654 $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
655 $this->assertFalse($workflow->status());
656 $workflow->addState('published', 'Published');
657 $this->assertTrue($workflow->status());