Completed
Push — master ( 5e0286...c67546 )
by Bjørn
02:37
created

CustomTester::realRun()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 31
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5.0187

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 10
c 3
b 0
f 0
dl 0
loc 31
ccs 10
cts 11
cp 0.9091
rs 9.6111
cc 5
nc 7
nop 2
crap 5.0187
1
<?php
2
3
namespace HtaccessCapabilityTester\Testers;
4
5
use \HtaccessCapabilityTester\HtaccessCapabilityTester;
6
use \HtaccessCapabilityTester\HttpRequesterInterface;
7
use \HtaccessCapabilityTester\HttpResponse;
8
use \HtaccessCapabilityTester\SimpleHttpRequester;
9
use \HtaccessCapabilityTester\TestResult;
10
use \HtaccessCapabilityTester\Testers\Helpers\ResponseInterpreter;
11
12
class CustomTester extends AbstractTester
13
{
14
    /** @var array  A definition defining the test */
15
    protected $test;
16
17
    /** @var array  For convenience, all tests */
18
    private $tests;
19
20
    /**
21
     * Constructor.
22
     *
23
     * @param  array   $test     The test (may contain subtests)
24
     *
25
     * @return void
26
     */
27 80
    public function __construct($test)
28
    {
29 80
        $this->test = $test;
30
31 80
        if (isset($test['subtests'])) {
32 38
            $this->tests = $test['subtests'];
33
34
            // Add main subdir to subdir for all subtests
35 38
            foreach ($this->tests as &$subtest) {
36 38
                if (isset($subtest['subdir'])) {
37 38
                    $subtest['subdir'] = $test['subdir'] . '/' . $subtest['subdir'];
38
                }
39
            }
40
        } else {
41 65
            $this->tests = [$test];
42
        }
43
44
        //echo '<pre>' . print_r($this->tests, true) . '</pre>';
45
        //echo json_encode($this->tests) . '<br>';
46 80
        parent::__construct();
47 80
    }
48
49
    /**
50
     * Register the test files using the "registerTestFile" method
51
     *
52
     * @return  void
53
     */
54 80
    protected function registerTestFiles()
55
    {
56
57 80
        foreach ($this->tests as $test) {
58 80
            if (isset($test['files'])) {
59 80
                foreach ($test['files'] as $file) {
60
                    // Two syntaxes are allowed:
61
                    // - Simple array (ie: ['0.txt', '0']
62
                    // - Named, ie:  ['filename' => '0.txt', 'content' => '0']
63
                    // The second makes more readable YAML definitions
64 80
                    if (isset($file['filename'])) {
65
                        $filename = $file['filename'];
66
                        $content = $file['content'];
67
                    } else {
68 80
                        list ($filename, $content) = $file;
69
                    }
70 80
                    $this->registerTestFile($test['subdir'] . '/' . $filename, $content);
71
                }
72
            }
73
        }
74 80
    }
75
76 75
    public function getSubDir()
77
    {
78 75
        return $this->test['subdir'];
79
    }
80
81
    /**
82
     *  Run single test
83
     *
84
     * @param  array  $test  the subtest to run
85
     *
86
     * @return TestResult  Returns a test result
87
     */
88 80
    private function realRunSubTest($test)
89
    {
90 80
        $requestUrl = $this->baseUrl . '/' . $test['subdir'] . '/';
91 80
        if (isset($test['request']['url'])) {
92 46
            $requestUrl .= $test['request']['url'];
93
        } else {
94 65
            $requestUrl .= $test['request'];
95
        }
96
        //echo $requestUrl . '<br>';
97 80
        $response = $this->makeHttpRequest($requestUrl);
98
99
        // Standard error handling
100 80
        $bypassErrors = [];
101 80
        $byPass = false;
102 80
        if (isset($test['request']['bypass-standard-error-handling'])) {
103 35
            $bypassErrors = $test['request']['bypass-standard-error-handling'];
104
        }
105 80
        if (in_array($response->statusCode, $bypassErrors) || in_array('all', $bypassErrors)) {
106 30
            $byPass = true;
107
        }
108
109 80
        if (!$byPass) {
110 71
            if ($response->statusCode == '403') {
111 9
                return new TestResult(null, '403 Forbidden');
112 62
            } elseif ($response->statusCode == '404') {
113
                return new TestResult(null, '404 Not Found');
114 62
            } elseif ($response->statusCode == '500') {
115 10
                $hct = $this->getHtaccessCapabilityTester();
116
117
                // Run innocent request / get it from cache. This sets
118
                // $statusCodeOfLastRequest, which we need now
119 10
                $hct->innocentRequestWorks();
120 10
                if ($hct->statusCodeOfLastRequest == '500') {
121 2
                    return new TestResult(null, 'Errored with 500. Everything errors with 500.');
122
                } else {
123 8
                    return new TestResult(
124 8
                        false,
125
                        'Errored with 500. ' .
126 8
                        'Not all goes 500, so it must be a forbidden directive in the .htaccess'
127
                    );
128
                }
129
            }
130
        }
131 71
        return ResponseInterpreter::interpret($response, $test['interpretation']);
132
    }
133
134
    /**
135
     *  Run
136
     *
137
     * @param  string  $baseDir  Directory on the server where the test files can be put
138
     * @param  string  $baseUrl  The base URL of the test files
139
     *
140
     * @return TestResult  Returns a test result
141
     * @throws \Exception  In case the test cannot be run due to serious issues
142
     */
143 80
    private function realRun($baseDir, $baseUrl)
144
    {
145 80
        $this->prepareForRun($baseDir, $baseUrl);
146
147 80
        $result = null;
148 80
        foreach ($this->tests as $i => $test) {
149
            /*
150
            Disabled, as I'm no longer sure if it is that useful
151
152
            if (isset($test['requirements'])) {
153
                $hct = $this->getHtaccessCapabilityTester();
154
155
                foreach ($test['requirements'] as $requirement) {
156
                    $requirementResult = $hct->callMethod($requirement);
157
                    if (!$requirementResult) {
158
                        // Skip test
159
                        continue 2;
160
                    }
161
                }
162
            }*/
163 80
            if (isset($test['request'])) {
164 80
                $result = $this->realRunSubTest($test);
165 80
                if ($result->info != 'no-match') {
166 79
                    return $result;
167
                }
168
            }
169
        }
170 13
        if (is_null($result)) {
171
            $result = new TestResult(null, 'Nothing to test!');
172
        }
173 13
        return $result;
174
    }
175
176
    /**
177
     *  Run
178
     *
179
     * @param  string  $baseDir  Directory on the server where the test files can be put
180
     * @param  string  $baseUrl  The base URL of the test files
181
     *
182
     * @return TestResult  Returns a test result
183
     * @throws \Exception  In case the test cannot be run due to serious issues
184
     */
185 80
    public function run($baseDir, $baseUrl)
186
    {
187 80
        $testResult = $this->realRun($baseDir, $baseUrl);
188
189
        // A test might not create a request if it has an unfulfilled requirement
190 80
        if (isset($this->lastHttpResponse)) {
191 80
            $testResult->statusCodeOfLastRequest = $this->lastHttpResponse->statusCode;
192
        }
193 80
        return $testResult;
194
    }
195
}
196