1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Resets the fake database used for fake web services |
4
|
|
|
* after a test scenario finishes. The database is initialized |
5
|
|
|
* on each request. |
6
|
|
|
*/ |
7
|
|
|
class FakeManagerTestSessionExtension extends Extension { |
8
|
|
|
|
9
|
|
|
public function updateBaseFields($fields) { |
10
|
|
|
// Don't need YAML fixtures |
11
|
|
|
$fields->removeByname('fixture'); |
12
|
|
|
} |
13
|
|
|
|
14
|
|
|
public function fakeDatabasePath() { |
15
|
|
|
return TEMP_FOLDER . '/' . uniqid() . '.json'; |
16
|
|
|
} |
17
|
|
|
|
18
|
|
|
public function templatePathRelative() { |
19
|
|
|
return '/mysite/tests/fixtures/FakeDatabase.json'; |
20
|
|
|
} |
21
|
|
|
|
22
|
|
|
public function updateStartForm($form) { |
23
|
|
|
$fields = $form->Fields(); |
24
|
|
|
|
25
|
|
|
// Default to last database template |
26
|
|
|
$templateField = $fields->dataFieldByName('importDatabasePath'); |
27
|
|
|
$templates = $templateField->getSource(); |
28
|
|
|
end($templates); |
29
|
|
|
|
30
|
|
|
$templateField->setValue(key($templates)); |
31
|
|
|
|
32
|
|
|
$fields->push(new CheckboxField('useFakeManager', 'Use webservice fakes?', 1)); |
33
|
|
|
$fields->push(new HiddenField('fakeDatabasePath', null, $this->fakeDatabasePath())); |
34
|
|
|
$templatePathRelative = $this->templatePathRelative(); |
35
|
|
|
|
36
|
|
|
$fields->push( |
37
|
|
|
DropdownField::create( |
38
|
|
|
'fakeDatabaseTemplatePath', |
39
|
|
|
false, |
40
|
|
|
array( |
41
|
|
|
BASE_PATH . $templatePathRelative => $templatePathRelative |
42
|
|
|
) |
43
|
|
|
) |
44
|
|
|
->setEmptyString('none') |
45
|
|
|
->setValue(BASE_PATH . $templatePathRelative) |
46
|
|
|
); |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* This needs to handle two distinct cases: |
51
|
|
|
* - Test Session being created by behat (calling TestSessionEnvironment directly), and |
52
|
|
|
* - Test Session being created by browsing to dev/testsession and submitting the form. |
53
|
|
|
* |
54
|
|
|
* The form is modified above (@see self::updateStartForm()) and we need to ensure we respect those selections, if |
55
|
|
|
* necessary. If it wasn't submitted via a form, then we can set the fakes up as required for behat. |
56
|
|
|
* |
57
|
|
|
* @param $state Array of state passed from TestSessionEnvironment |
58
|
|
|
*/ |
59
|
|
|
public function onBeforeStartTestSession(&$state) { |
60
|
|
|
// Only set fake database paths when using fake manager |
61
|
|
|
if(empty($state['useFakeManager'])) { |
62
|
|
|
unset($state['fakeDatabasePath']); |
63
|
|
|
unset($state['fakeDatabaseTemplatePath']); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
if( |
67
|
|
|
$state |
68
|
|
|
&& !empty($state['useFakeManager']) |
69
|
|
|
&& !empty($state['fakeDatabaseTemplatePath']) |
70
|
|
|
&& !empty($state['fakeDatabasePath']) |
71
|
|
|
) { |
72
|
|
|
// Copy template database, to keep it clean for other runs |
73
|
|
|
copy($state['fakeDatabaseTemplatePath'], $state['fakeDatabasePath']); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
// Running via behat, so we figure out the fake stuff for ourself |
77
|
|
|
// @see self::updateStartForm() |
78
|
|
|
if($state && !empty($state['useFakeManager'])) { |
79
|
|
|
$state['useFakeManager'] = 1; |
80
|
|
|
$state['fakeDatabaseTemplatePath'] = BASE_PATH . $this->templatePathRelative(); |
81
|
|
|
if(empty($state['fakeDatabasePath'])) { |
82
|
|
|
$state['fakeDatabasePath'] = $this->fakeDatabasePath(); |
83
|
|
|
} |
84
|
|
|
copy($state['fakeDatabaseTemplatePath'], $state['fakeDatabasePath']); |
85
|
|
|
chmod($state['fakeDatabasePath'], 0777); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
return $state; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Only used for manual testing, not on Behat runs. |
93
|
|
|
*/ |
94
|
|
|
public function onBeforeClear() { |
95
|
|
|
$testEnv = Injector::inst()->get('TestSessionEnvironment'); |
96
|
|
|
$state = $testEnv->getState(); |
97
|
|
|
|
98
|
|
|
if($state && isset($state->useFakeManager) && $state->useFakeManager) { |
99
|
|
|
$this->resetFakeManager(); |
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Only used for manual testing, not on Behat runs. |
105
|
|
|
*/ |
106
|
|
|
public function onBeforeEndTestSession() { |
107
|
|
|
$state = $this->owner->getState(); |
108
|
|
|
|
109
|
|
|
if($state && isset($state->useFakeManager) && $state->useFakeManager) { |
110
|
|
|
$this->resetFakeManager(); |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* A similar reset is also performed in Mysite\Tests\Behaviour\FeatureContext->resetFakeDatabase(). |
116
|
|
|
* We can't reset Behat CLI runs through this measure because the CLI has a persistent connection |
117
|
|
|
* to the underlying SQLite database file, so the browser can't remove it. |
118
|
|
|
*/ |
119
|
|
View Code Duplication |
protected function resetFakeManager() { |
|
|
|
|
120
|
|
|
$state = $this->owner->getState(); |
121
|
|
|
|
122
|
|
|
if($state) { |
123
|
|
|
$manager = Injector::inst()->get( |
124
|
|
|
'FakeManager', |
125
|
|
|
true, |
126
|
|
|
array(new FakeDatabase($state->fakeDatabasePath)) |
127
|
|
|
); |
128
|
|
|
$manager->getDb()->reset(); |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
} |
133
|
|
|
|
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.