1<?php
2/* Copyright (c) 1998-2014 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4/**
5 * ilBasicNodeTest is part of the petri net based workflow engine.
6 *
7 * This class holds all tests for the class
8 * nodes/class.ilBasicNode
9 *
10 * @author Maximilian Becker <mbecker@databay.de>
11 * @version $Id$
12 *
13 * @ingroup Services/WorkflowEngine
14 */
15class ilBasicNodeTest extends PHPUnit_Framework_TestCase
16{
17    public function setUp()
18    {
19        include_once("./Services/PHPUnit/classes/class.ilUnitUtil.php");
20        //ilUnitUtil::performInitialisation();
21
22        // Empty workflow.
23        require_once './Services/WorkflowEngine/classes/workflows/class.ilEmptyWorkflow.php';
24        $this->workflow = new ilEmptyWorkflow();
25    }
26
27    public function tearDown()
28    {
29        global $ilSetting;
30        if ($ilSetting != null) {
31            $ilSetting->delete('IL_PHPUNIT_TEST_TIME');
32            $ilSetting->delete('IL_PHPUNIT_TEST_MICROTIME');
33        }
34    }
35
36    public function testConstructorValidContext()
37    {
38        // Act
39        $node = new ilBasicNode($this->workflow);
40
41        // Assert
42        // No exception - good
43        $this->assertTrue(
44            true,
45            'Construction failed with valid context passed to constructor.'
46        );
47    }
48
49    public function testGetContext()
50    {
51        // Arrange
52        $node = new ilBasicNode($this->workflow);
53
54        // Act
55        $actual = $node->getContext();
56
57        // Assert
58        if ($actual === $this->workflow) {
59            $this->assertEquals($actual, $this->workflow);
60        } else {
61            $this->assertTrue(false, 'Context not identical.');
62        }
63    }
64
65    public function testIsActiveAndActivate()
66    {
67        // Arrange
68        $node = new ilBasicNode($this->workflow);
69        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
70        $detector = new ilSimpleDetector($node);
71        $node->addDetector($detector);
72
73        // Act
74        $node->activate();
75
76        // Assert
77        $actual = $node->isActive();
78        $this->assertTrue($actual);
79    }
80
81    public function testDeactivate()
82    {
83        // Arrange
84        $node = new ilBasicNode($this->workflow);
85        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
86        $detector = new ilSimpleDetector($node);
87        $node->addDetector($detector);
88
89        // Act
90        $node->activate();
91        $was_activated = $node->isActive();
92        $node->deactivate();
93        $was_deactivated = !$node->isActive();
94
95        // Assert
96        $this->assertEquals($was_activated, $was_deactivated);
97    }
98
99    public function testCheckTransitionPreconditionsValid()
100    {
101        // Arrange
102        $node = new ilBasicNode($this->workflow);
103        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
104        $detector = new ilSimpleDetector($node);
105        $node->addDetector($detector);
106
107        // Act
108        $detector->trigger(array());
109        $preconditions = $node->checkTransitionPreconditions();
110
111        // Assert
112        $this->assertTrue($preconditions);
113    }
114
115    public function testCheckTransitionPreconditionsInvalid()
116    {
117        // Arrange
118        $node = new ilBasicNode($this->workflow);
119        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
120        $detector = new ilSimpleDetector($node);
121        $node->addDetector($detector);
122
123
124        // Act
125        $preconditions = $node->checkTransitionPreconditions();
126
127        // Assert
128        $this->assertFalse($preconditions);
129    }
130
131    public function testAttemptTransitionValid()
132    {
133        // Arrange
134        $node = new ilBasicNode($this->workflow);
135        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
136        $detector = new ilSimpleDetector($node);
137        $node->addDetector($detector);
138
139        // Act
140        $detector->trigger(array());
141        $result = $node->attemptTransition();
142
143        // Assert
144        $this->assertTrue($result);
145    }
146
147    public function testAttemptTransitionInvalid()
148    {
149        // Arrange
150        $node = new ilBasicNode($this->workflow);
151        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
152        $detector = new ilSimpleDetector($node);
153        $node->addDetector($detector);
154
155        // Act
156        $result = $node->attemptTransition();
157
158        // Assert
159        $this->assertFalse($result);
160    }
161
162    public function testExecuteTransition()
163    { // This is test #100 of the WorkflowEngine, written on 9th of May, 2012
164        // @ 14:15
165
166        // Arrange
167        $node = new ilBasicNode($this->workflow);
168        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
169        $detector = new ilSimpleDetector($node);
170        $node->addDetector($detector);
171        $node->activate();
172
173        // Act
174        $node->executeTransition();
175        $state = $node->isActive();
176
177        // Assert
178        $this->assertFalse($state);
179    }
180
181    public function testExecuteActivitiesViaExecuteTransition()
182    {
183        // Arrange
184        $node = new ilBasicNode($this->workflow);
185        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
186        $detector = new ilSimpleDetector($node);
187        $node->addDetector($detector);
188
189        require_once './Services/WorkflowEngine/classes/activities/class.ilLoggingActivity.php';
190        $activity = new ilLoggingActivity($node);
191        $activity->setLogFile('ilTransitionLog.txt');
192        $activity->setLogLevel('MESSAGE');
193        $activity->setLogMessage('TEST');
194        $node->addActivity($activity);
195
196        // Act
197        $node->activate();
198        $node->executeTransition();
199
200        // Assert
201        $expected = ' :: MESSAGE :: TEST';
202        $fp = fopen('ilTransitionLog.txt', 'r');
203        $line = fgets($fp);
204        $actual = substr($line, 25, strlen($line) - 27);
205        @unlink('ilTransitionLog.txt'); // TODO: Use vfsStream
206        $this->assertEquals(
207            $actual,
208            $expected
209        );
210    }
211
212    public function testExecuteEmitterViaExecuteTransition()
213    {
214        // Arrange
215        $node = new ilBasicNode($this->workflow);
216        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
217        $detector = new ilSimpleDetector($node);
218        $node->addDetector($detector);
219
220        require_once './Services/WorkflowEngine/classes/emitters/class.ilActivationEmitter.php';
221        $t_node = new ilBasicNode($this->workflow);
222        $t_detector = new ilSimpleDetector($t_node);
223        $t_node->addDetector($t_detector);
224        $foo_detector = new ilSimpleDetector($t_node);
225        $t_node->addDetector($foo_detector);
226        // again a foo_detector to keep the t_node from transitting
227
228        $emitter = new ilActivationEmitter($node);
229        $emitter->setTargetDetector($t_detector);
230        $node->addEmitter($emitter);
231
232        // Act
233        $node->activate();
234        $node->executeTransition();
235
236        // Assert
237        $this->assertTrue($t_node->isActive());
238    }
239
240    public function testAddDetector()
241    {
242        // Arrange
243        $node = new ilBasicNode($this->workflow);
244        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
245        $detector = new ilSimpleDetector($node);
246
247        // Act
248        $node->addDetector($detector);
249        $detectors = $node->getDetectors();
250
251        // Assert
252        $this->assertEquals($detector, $detectors[0]);
253    }
254
255    public function testAddEmitter()
256    {
257        // Arrange
258        $node = new ilBasicNode($this->workflow);
259        require_once './Services/WorkflowEngine/classes/emitters/class.ilSimpleEmitter.php';
260        $emitter = new ilSimpleEmitter($node);
261
262        // Act
263        $node->addEmitter($emitter);
264        $emitters = $node->getEmitters();
265
266        // Assert
267        $this->assertEquals($emitter, $emitters[0]);
268    }
269
270    public function testAddActivity()
271    {
272        // Arrange
273        $node = new ilBasicNode($this->workflow);
274        require_once './Services/WorkflowEngine/classes/activities/class.ilLoggingActivity.php';
275        $activity = new ilLoggingActivity($node);
276
277        // Act
278        $node->addActivity($activity);
279        $activities = $node->getActivities();
280
281        // Assert
282        $this->assertEquals($activity, $activities[0]);
283    }
284
285    public function testNotifyDetectorSatisfaction()
286    {
287        // Arrange
288        $node = new ilBasicNode($this->workflow);
289
290        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
291        $detector = new ilSimpleDetector($node);
292        $node->addDetector($detector);
293
294        // Note: Order is important. Setting detector state prior to activation
295        // will be voided.
296        $node->activate();
297        $detector->setDetectorState(true);
298        /* Setting the detector to true will actually be reported
299         * with notifyDetectorSatisfaction.
300         * To isolate this call, we need to reset the node back
301         * to active prior to evaluating if it successfully executes
302         * the transition and sets itself to inactive.
303         */
304
305        // Act
306        $node->notifyDetectorSatisfaction($detector);
307
308        // Assert
309        $this->assertFalse($node->isActive());
310    }
311
312    public function testSetGetIsForwardConditionNode()
313    {
314        // Arrange
315        $node = new ilBasicNode($this->workflow);
316        require_once './Services/WorkflowEngine/classes/detectors/class.ilSimpleDetector.php';
317        $detector = new ilSimpleDetector($node);
318        $node->addDetector($detector);
319
320        // Act
321        $node->activate();
322
323        // Assert
324        $this->assertFalse($node->isForwardConditionNode(), 'Forward condition should be false by default.');
325        $node->setIsForwardConditionNode(true);
326        $this->assertTrue($node->isForwardConditionNode(), 'Forward condition node state not properly stored.');
327    }
328}
329