Completed
Push — master ( c44703...1db852 )
by Marcus
02:49
created

WorkflowImportExportTest   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 232
Duplicated Lines 9.91 %

Coupling/Cohesion

Components 0
Dependencies 8
Metric Value
wmc 9
lcom 0
cbo 8
dl 23
loc 232
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A createDefinition() 23 23 1
A testFormatWithActions() 0 19 1
A testFormatWithoutActions() 0 19 1
B testParseBadYAMLNoHeaderImport() 0 29 1
B testParseBadYAMLMalformedImport() 0 32 1
B testParseGoodYAMLImport() 0 31 1
A testGetImportedWorkflowsNone() 0 6 1
A testGetImportedWorkflowsOne() 0 13 1
A testGetImportedWorkflowsMany() 0 12 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Tests for workflow import/export logic.
4
 *
5
 * @author     [email protected]
6
 * @license    BSD License (http://silverstripe.org/bsd-license/)
7
 * @package    advancedworkflow
8
 * @subpackage tests
9
 */
10
class WorkflowImportExportTest extends SapphireTest {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
11
	
12
	public static $fixture_file = 'advancedworkflow/tests/workflowtemplateimport.yml';
13
	
14
	/**
15
	 * Utility method, used in tests
16
	 * @return \WorkflowDefinition
17
	 */
18 View Code Duplication
	protected function createDefinition() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
19
		$definition = new WorkflowDefinition();
20
		$definition->Title = "Dummy Workflow Definition";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<WorkflowDefinition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
21
		$definition->write();
22
23
		$stepOne = new WorkflowAction();
24
		$stepOne->Title = "Step One";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<WorkflowAction>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
25
		$stepOne->WorkflowDefID = $definition->ID;
0 ignored issues
show
Documentation introduced by
The property WorkflowDefID does not exist on object<WorkflowAction>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
26
		$stepOne->write();
27
28
		$stepTwo = new WorkflowAction();
29
		$stepTwo->Title = "Step Two";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<WorkflowAction>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
30
		$stepTwo->WorkflowDefID = $definition->ID;
0 ignored issues
show
Documentation introduced by
The property WorkflowDefID does not exist on object<WorkflowAction>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
31
		$stepTwo->write();
32
33
		$transitionOne = new WorkflowTransition();
34
		$transitionOne->Title = 'Step One T1';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<WorkflowTransition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
35
		$transitionOne->ActionID = $stepOne->ID;
0 ignored issues
show
Documentation introduced by
The property ActionID does not exist on object<WorkflowTransition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
36
		$transitionOne->NextActionID = $stepTwo->ID;
0 ignored issues
show
Documentation introduced by
The property NextActionID does not exist on object<WorkflowTransition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
37
		$transitionOne->write();
38
39
		return $definition;
40
	}	
41
42
	/**
43
	 * Create a WorkflowDefinition with some actions. Ensure an expected length of formatted template.
44
	 */
45
	public function testFormatWithActions() {
46
		$definition = $this->createDefinition();
47
		$exporter = Injector::inst()->createWithArgs('WorkflowDefinitionExporter', array($definition->ID));
48
		$member = new Member();
49
		$member->FirstName = 'joe';
50
		$member->Surname = 'bloggs';
51
		$exporter->setMember($member);
52
		$templateData = new ArrayData(array(
53
			'ExportMetaData' => $exporter->ExportMetaData(),
54
			'ExportActions' => $exporter->getDefinition()->Actions()
55
		));
56
		
57
		$formatted = $exporter->format($templateData);
58
		$numActions = count(preg_split("#\R#", $formatted)); 
59
		
60
		$this->assertNotEmpty($formatted);
0 ignored issues
show
Bug introduced by
The method assertNotEmpty() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
61
		// Seems arbitrary, but if no actions, then the resulting YAML file is exactly 18 lines long
62
		$this->assertGreaterThan(18, $numActions);				
0 ignored issues
show
Bug introduced by
The method assertGreaterThan() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
63
	}
64
	
65
	/**
66
	 * Create a WorkflowDefinition with NO actions. Ensure an expected length of formatted template.
67
	 */
68
	public function testFormatWithoutActions() {
69
		$definition = $this->createDefinition();
70
		$exporter = Injector::inst()->createWithArgs('WorkflowDefinitionExporter', array($definition->ID));
71
		$member = new Member();
72
		$member->FirstName = 'joe';
73
		$member->Surname = 'bloggs';
74
		$exporter->setMember($member);
75
		$templateData = new ArrayData(array());
76
		
77
		$formatted = $exporter->format($templateData);
78
		$numActions = count(preg_split("#\R#", $formatted)); 
79
		
80
		// Seems arbitrary, but if no actions, then the resulting YAML file is exactly 18 lines long
81
		$this->assertEquals(18, $numActions);
0 ignored issues
show
Bug introduced by
The method assertEquals() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
82
		
83
		// Ensure outputted YAML has no blank lines, where SS's control structures would normally be
84
		$numBlanks = preg_match("#^\s*$#m", $formatted);
85
		$this->assertEquals(0, $numBlanks);		
0 ignored issues
show
Bug introduced by
The method assertEquals() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
86
	}
87
	
88
	/**
89
	 * Tests a badly formatted YAML import for parsing (no headers)
90
	 * Note: The available test-cases we can expect to get out of sfYamlParser is limited..
91
	 */
92
	public function testParseBadYAMLNoHeaderImport() {
93
		$importer = new WorkflowDefinitionImporter();
94
		$this->setExpectedException('Exception', 'Invalid YAML format.');
0 ignored issues
show
Bug introduced by
The method setExpectedException() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
95
		$source = <<<'EOD'
96
Injector:
97
  ExportedWorkflow:
98
    class: WorkflowTemplate
99
    constructor:
100
      - 'My Workflow 4 20/02/2014 03-12-55'
101
      - 'Exported from localhost on 20/02/2014 03:12:55 by joe bloggs using SilverStripe versions Framework 3.1.2, CMS 3.1.2'
102
      - 0.2
103
      - 0
104
      - 3
105
    properties:
106
      structure:
107
        'Step One':
108
          type: WorkflowAction
109
          transitions:
110
            - Step One T1: 'Step Two'
111
        'Step Two':
112
          type: WorkflowAction
113
  WorkflowService:
114
    properties:
115
      templates:
116
        - %$ExportedWorkflow
117
EOD;
118
		
119
		$importer->parseYAMLImport($source);
120
	}	
121
	
122
	/**
123
	 * Tests a badly formatted YAML import for parsing (missing YML colon)
124
	 * Note: The available test-cases we can expect to get out of sfYamlParser is limited..
125
	 */
126
	public function testParseBadYAMLMalformedImport() {
127
		$importer = new WorkflowDefinitionImporter();
128
		$this->setExpectedException('ValidationException', 'Invalid YAML format. Unable to parse.');
0 ignored issues
show
Bug introduced by
The method setExpectedException() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
129
		$source = <<<'EOD'
130
---
131
Name: exportedworkflow
132
---
133
Injector:
134
  ExportedWorkflow:
135
    class: WorkflowTemplate
136
    constructor:
137
      - 'My Workflow 4 20/02/2014 03-12-55'
138
      - 'Exported from localhost on 20/02/2014 03-12-55 by joe bloggs using SilverStripe versions Framework 3.1.2, CMS 3.1.2'
139
      - 0.2
140
      - 0
141
      - 3
142
    properties:
143
      structure:
144
        'Step One'
145
          type: WorkflowAction
146
          transitions:
147
            - Step One T1: 'Step Two'
148
        'Step Two':
149
          type: WorkflowAction
150
  WorkflowService:
151
    properties:
152
      templates:
153
        - %$ExportedWorkflow
154
EOD;
155
		
156
		$importer->parseYAMLImport($source);
157
	}	
158
	
159
	/**
160
	 * Tests a well-formatted YAML import for parsing
161
	 * Note: The available test-cases we can expect to get out of sfYamlParser is limited..
162
	 */
163
	public function testParseGoodYAMLImport() {
164
		$importer = new WorkflowDefinitionImporter();
165
		$source = <<<'EOD'
166
---
167
Name: exportedworkflow
168
---
169
Injector:
170
  ExportedWorkflow:
171
    class: WorkflowTemplate
172
    constructor:
173
      - 'My Workflow 4 20/02/2014 03-12-55'
174
      - 'Exported from localhost on 20/02/2014 03-12-55 by joe bloggs using SilverStripe versions Framework 3.1.2, CMS 3.1.2'
175
      - 0.2
176
      - 0
177
      - 3
178
    properties:
179
      structure:
180
        'Step One':
181
          type: WorkflowAction
182
          transitions:
183
            - Step One T1: 'Step Two'
184
        'Step Two':
185
          type: WorkflowAction
186
  WorkflowService:
187
    properties:
188
      templates:
189
        - %$ExportedWorkflow
190
EOD;
191
		
192
		$this->assertNotEmpty($importer->parseYAMLImport($source));
0 ignored issues
show
Bug introduced by
The method assertNotEmpty() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
193
	}
194
	
195
	/**
196
	 * Given no ImportedWorkflowTemplate fixture/input data, tests an empty array is returned 
197
	 * by WorkflowDefinitionImporter#getImportedWorkflows()
198
	 */
199
	public function testGetImportedWorkflowsNone() {
200
		$this->clearFixtures();
201
		$importer = new WorkflowDefinitionImporter();
202
		$imports = $importer->getImportedWorkflows();
203
		$this->assertEmpty($imports);
0 ignored issues
show
Bug introduced by
The method assertEmpty() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
204
	}
205
	
206
	/**
207
	 * Given a single ImportedWorkflowTemplate fixture/input data, tests an non-empty array is returned 
208
	 * by WorkflowDefinitionImporter#getImportedWorkflows()
209
	 */	
210
	public function testGetImportedWorkflowsOne() {
211
		$name = 'My Workflow 21/02/2014 09-01-29';
212
		// Pretend a ImportedWorkflowTemplate object has been created by WorkflowBulkLoader
213
		$this->objFromFixture('ImportedWorkflowTemplate', 'Import01');		
214
		
215
		$importer = singleton('WorkflowDefinitionImporter');
216
		$import = $importer->getImportedWorkflows($name);
217
218
		$this->assertNotEmpty($import);
0 ignored issues
show
Bug introduced by
The method assertNotEmpty() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
219
		$this->assertInstanceOf('WorkflowTemplate', $import);
0 ignored issues
show
Bug introduced by
The method assertInstanceOf() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
220
		$this->assertEquals(1, count($import));
0 ignored issues
show
Bug introduced by
The method assertEquals() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
221
		$this->assertEquals($name, $import->getName());
0 ignored issues
show
Bug introduced by
The method assertEquals() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
222
	}
223
	
224
	/**
225
	 * Given many ImportedWorkflowTemplate fixture/input data, tests an non-empty array is returned 
226
	 * by WorkflowDefinitionImporter#getImportedWorkflows()
227
	 */	
228
	public function testGetImportedWorkflowsMany() {
229
		// Pretend some ImportedWorkflowTemplate objects have been created by WorkflowBulkLoader
230
		$this->objFromFixture('ImportedWorkflowTemplate', 'Import02');
231
		$this->objFromFixture('ImportedWorkflowTemplate', 'Import03');
232
		
233
		$importer = singleton('WorkflowDefinitionImporter');
234
		$imports = $importer->getImportedWorkflows();
235
236
		$this->assertNotEmpty($imports);
0 ignored issues
show
Bug introduced by
The method assertNotEmpty() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
237
		$this->assertInternalType('array', $imports);
0 ignored issues
show
Bug introduced by
The method assertInternalType() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
238
		$this->assertGreaterThan(1, count($imports));
0 ignored issues
show
Bug introduced by
The method assertGreaterThan() does not seem to exist on object<WorkflowImportExportTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
239
	}	
240
	
241
}