Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
93.85% |
61 / 65 |
|
62.50% |
5 / 8 |
CRAP | |
0.00% |
0 / 1 |
CustomTester | |
93.85% |
61 / 65 |
|
62.50% |
5 / 8 |
31.22 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
4 | |||
registerTestFiles | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
5.39 | |||
getSubDir | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
standardErrorHandling | |
94.44% |
17 / 18 |
|
0.00% |
0 / 1 |
6.01 | |||
bypassStandardErrorHandling | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
4 | |||
realRunSubTest | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
4 | |||
realRun | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
5.03 | |||
run | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 |
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 | public function __construct($test) |
28 | { |
29 | $this->test = $test; |
30 | |
31 | if (isset($test['subtests'])) { |
32 | $this->tests = $test['subtests']; |
33 | |
34 | // Add main subdir to subdir for all subtests |
35 | foreach ($this->tests as &$subtest) { |
36 | if (isset($subtest['subdir'])) { |
37 | $subtest['subdir'] = $test['subdir'] . '/' . $subtest['subdir']; |
38 | } |
39 | } |
40 | } else { |
41 | $this->tests = [$test]; |
42 | } |
43 | |
44 | //echo '<pre>' . print_r($this->tests, true) . '</pre>'; |
45 | //echo json_encode($this->tests) . '<br>'; |
46 | parent::__construct(); |
47 | } |
48 | |
49 | /** |
50 | * Register the test files using the "registerTestFile" method |
51 | * |
52 | * @return void |
53 | */ |
54 | protected function registerTestFiles() |
55 | { |
56 | |
57 | foreach ($this->tests as $test) { |
58 | if (isset($test['files'])) { |
59 | 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 | if (isset($file['filename'])) { |
65 | $filename = $file['filename']; |
66 | $content = $file['content']; |
67 | } else { |
68 | list ($filename, $content) = $file; |
69 | } |
70 | $this->registerTestFile($test['subdir'] . '/' . $filename, $content); |
71 | } |
72 | } |
73 | } |
74 | } |
75 | |
76 | public function getSubDir() |
77 | { |
78 | return $this->test['subdir']; |
79 | } |
80 | |
81 | /** |
82 | * Standard Error handling |
83 | * |
84 | * @param HttpResponse $response |
85 | * |
86 | * @return TestResult|null If no errors, null is returned, otherwise a TestResult |
87 | */ |
88 | private function standardErrorHandling($response) |
89 | { |
90 | switch ($response->statusCode) { |
91 | case '0': |
92 | return new TestResult(null, $response->body); |
93 | case '403': |
94 | return new TestResult(null, '403 Forbidden'); |
95 | case '404': |
96 | return new TestResult(null, '404 Not Found'); |
97 | case '500': |
98 | $hct = $this->getHtaccessCapabilityTester(); |
99 | |
100 | // Run innocent request / get it from cache. This sets |
101 | // $statusCodeOfLastRequest, which we need now |
102 | $hct->innocentRequestWorks(); |
103 | if ($hct->statusCodeOfLastRequest == '500') { |
104 | return new TestResult(null, 'Errored with 500. Everything errors with 500.'); |
105 | } else { |
106 | return new TestResult( |
107 | false, |
108 | 'Errored with 500. ' . |
109 | 'Not all goes 500, so it must be a forbidden directive in the .htaccess' |
110 | ); |
111 | } |
112 | } |
113 | return null; |
114 | } |
115 | |
116 | /** |
117 | * Checks if standard error handling should be bypassed on the test. |
118 | * |
119 | * This stuff is controlled in the test definition. More precisely, by the "bypass-standard-error-handling" |
120 | * property bellow the "request" property. If this property is set to ie ['404', '500'], the standard error |
121 | * handler will be bypassed for those codes (but still be in effect for ie '403'). If set to ['all'], all |
122 | * standard error handling will be bypassed. |
123 | * |
124 | * @param array $test the subtest |
125 | * @param HttpResponse $response the response |
126 | * |
127 | * @return bool true if error handling should be bypassed |
128 | */ |
129 | private function bypassStandardErrorHandling($test, $response) |
130 | { |
131 | if (!(isset($test['request']['bypass-standard-error-handling']))) { |
132 | return false; |
133 | } |
134 | $bypassErrors = $test['request']['bypass-standard-error-handling']; |
135 | if (in_array($response->statusCode, $bypassErrors) || in_array('all', $bypassErrors)) { |
136 | return true; |
137 | } |
138 | return false; |
139 | } |
140 | |
141 | /** |
142 | * Run single test |
143 | * |
144 | * @param array $test the subtest to run |
145 | * |
146 | * @return TestResult Returns a test result |
147 | */ |
148 | private function realRunSubTest($test) |
149 | { |
150 | $requestUrl = $this->baseUrl . '/' . $test['subdir'] . '/'; |
151 | if (isset($test['request']['url'])) { |
152 | $requestUrl .= $test['request']['url']; |
153 | } else { |
154 | $requestUrl .= $test['request']; |
155 | } |
156 | //echo $requestUrl . '<br>'; |
157 | $response = $this->makeHttpRequest($requestUrl); |
158 | |
159 | // Standard error handling |
160 | if (!($this->bypassStandardErrorHandling($test, $response))) { |
161 | $errorResult = $this->standardErrorHandling($response); |
162 | if (!is_null($errorResult)) { |
163 | return $errorResult; |
164 | } |
165 | } |
166 | return ResponseInterpreter::interpret($response, $test['interpretation']); |
167 | } |
168 | |
169 | /** |
170 | * Run |
171 | * |
172 | * @param string $baseDir Directory on the server where the test files can be put |
173 | * @param string $baseUrl The base URL of the test files |
174 | * |
175 | * @return TestResult Returns a test result |
176 | * @throws \Exception In case the test cannot be run due to serious issues |
177 | */ |
178 | private function realRun($baseDir, $baseUrl) |
179 | { |
180 | $this->prepareForRun($baseDir, $baseUrl); |
181 | |
182 | $result = null; |
183 | foreach ($this->tests as $i => $test) { |
184 | /* |
185 | Disabled, as I'm no longer sure if it is that useful |
186 | |
187 | if (isset($test['requirements'])) { |
188 | $hct = $this->getHtaccessCapabilityTester(); |
189 | |
190 | foreach ($test['requirements'] as $requirement) { |
191 | $requirementResult = $hct->callMethod($requirement); |
192 | if (!$requirementResult) { |
193 | // Skip test |
194 | continue 2; |
195 | } |
196 | } |
197 | }*/ |
198 | if (isset($test['request'])) { |
199 | $result = $this->realRunSubTest($test); |
200 | if ($result->info != 'no-match') { |
201 | return $result; |
202 | } |
203 | } |
204 | } |
205 | if (is_null($result)) { |
206 | $result = new TestResult(null, 'Nothing to test!'); |
207 | } |
208 | return $result; |
209 | } |
210 | |
211 | /** |
212 | * Run |
213 | * |
214 | * @param string $baseDir Directory on the server where the test files can be put |
215 | * @param string $baseUrl The base URL of the test files |
216 | * |
217 | * @return TestResult Returns a test result |
218 | * @throws \Exception In case the test cannot be run due to serious issues |
219 | */ |
220 | public function run($baseDir, $baseUrl) |
221 | { |
222 | $testResult = $this->realRun($baseDir, $baseUrl); |
223 | |
224 | // A test might not create a request if it has an unfulfilled requirement |
225 | if (isset($this->lastHttpResponse)) { |
226 | $testResult->statusCodeOfLastRequest = $this->lastHttpResponse->statusCode; |
227 | } |
228 | return $testResult; |
229 | } |
230 | } |