Completed
Pull Request — master (#105)
by
unknown
08:51
created

onBeforeStartTestSession()   D

Complexity

Conditions 9
Paths 12

Size

Total Lines 31
Code Lines 18

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 31
rs 4.909
cc 9
eloc 18
nc 12
nop 1
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 SampleTestSessionExtension 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 App\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
	protected function resetFakeManager() {
120
		$state = $this->owner->getState();
121
122
		if($state) {
123
			$manager = Injector::inst()->get(
124
				'SampleFakeManager',
125
				true,
126
				array(new FakeDatabase($state->fakeDatabasePath))
127
			);
128
			$manager->getDb()->reset();
129
		}
130
	}
131
132
}
133