Completed
Pull Request — master (#105)
by
unknown
02:01
created

SampleTestSessionExtension::updateStartForm()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 26
rs 8.8571
cc 1
eloc 17
nc 1
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