Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
30 / 30 |
|
100.00% |
18 / 18 |
CRAP | |
100.00% |
1 / 1 |
HtaccessCapabilityTester | |
100.00% |
30 / 30 |
|
100.00% |
18 / 18 |
21 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
runTest | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
4 | |||
setHttpRequester | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setTestFilesLineUpper | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
htaccessEnabled | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
moduleLoaded | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
rewriteWorks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
addTypeWorks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
headerSetWorks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
requestHeaderWorks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
contentDigestWorks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
serverSignatureWorks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
directoryIndexWorks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
passingInfoFromRewriteToScriptThroughRequestHeaderWorks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
passingInfoFromRewriteToScriptThroughEnvWorks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
crashTest | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
innocentRequestWorks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
customTest | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace HtaccessCapabilityTester; |
4 | |
5 | use \HtaccessCapabilityTester\Testers\AbstractTester; |
6 | use \HtaccessCapabilityTester\Testers\AddTypeTester; |
7 | use \HtaccessCapabilityTester\Testers\ContentDigestTester; |
8 | use \HtaccessCapabilityTester\Testers\CrashTester; |
9 | use \HtaccessCapabilityTester\Testers\CustomTester; |
10 | use \HtaccessCapabilityTester\Testers\DirectoryIndexTester; |
11 | use \HtaccessCapabilityTester\Testers\HeaderSetTester; |
12 | use \HtaccessCapabilityTester\Testers\HtaccessEnabledTester; |
13 | use \HtaccessCapabilityTester\Testers\InnocentRequestTester; |
14 | use \HtaccessCapabilityTester\Testers\ModuleLoadedTester; |
15 | use \HtaccessCapabilityTester\Testers\PassInfoFromRewriteToScriptThroughRequestHeaderTester; |
16 | use \HtaccessCapabilityTester\Testers\PassInfoFromRewriteToScriptThroughEnvTester; |
17 | use \HtaccessCapabilityTester\Testers\RewriteTester; |
18 | use \HtaccessCapabilityTester\Testers\RequestHeaderTester; |
19 | use \HtaccessCapabilityTester\Testers\ServerSignatureTester; |
20 | |
21 | /** |
22 | * Main entrance. |
23 | * |
24 | * @package HtaccessCapabilityTester |
25 | * @author Bjørn Rosell <it@rosell.dk> |
26 | * @since Class available since 0.7 |
27 | */ |
28 | class HtaccessCapabilityTester |
29 | { |
30 | |
31 | /** @var string The dir where the test files should be put */ |
32 | protected $baseDir; |
33 | |
34 | /** @var string The base url that the tests can be run from (corresponds to $baseDir) */ |
35 | protected $baseUrl; |
36 | |
37 | /** @var string Additional info regarding last test (often empty) */ |
38 | public $infoFromLastTest; |
39 | |
40 | /** @var string Status code from last test (can be empty) */ |
41 | public $statusCodeOfLastRequest; |
42 | |
43 | |
44 | /** @var HttpRequesterInterface The object used to make the HTTP request */ |
45 | private $requester; |
46 | |
47 | /** @var TestFilesLineUpperInterface The object used to line up the test files */ |
48 | private $testFilesLineUpper; |
49 | |
50 | /** |
51 | * Constructor. |
52 | * |
53 | * @param string $baseDir Directory on the server where the test files can be put |
54 | * @param string $baseUrl The base URL of the test files |
55 | * |
56 | * @return void |
57 | */ |
58 | public function __construct($baseDir, $baseUrl) |
59 | { |
60 | $this->baseDir = $baseDir; |
61 | $this->baseUrl = $baseUrl; |
62 | } |
63 | |
64 | /** |
65 | * Run a test, store the info and return the status. |
66 | * |
67 | * @param AbstractTester $tester |
68 | * |
69 | * @return bool|null true=success, false=failure, null=inconclusive |
70 | */ |
71 | private function runTest($tester) |
72 | { |
73 | //$tester->setHtaccessCapabilityTester($this); |
74 | if (isset($this->requester)) { |
75 | $tester->setHttpRequester($this->requester); |
76 | } |
77 | if (isset($this->testFilesLineUpper)) { |
78 | $tester->setTestFilesLineUpper($this->testFilesLineUpper); |
79 | } |
80 | //$tester->setHtaccessCapabilityTester($this); |
81 | |
82 | $cacheKeys = [$this->baseDir, $tester->getCacheKey()]; |
83 | if (TestResultCache::isCached($cacheKeys)) { |
84 | $testResult = TestResultCache::getCached($cacheKeys); |
85 | } else { |
86 | $testResult = $tester->run($this->baseDir, $this->baseUrl); |
87 | TestResultCache::cache($cacheKeys, $testResult); |
88 | } |
89 | |
90 | $this->infoFromLastTest = $testResult->info; |
91 | $this->statusCodeOfLastRequest = $testResult->statusCodeOfLastRequest; |
92 | return $testResult->status; |
93 | } |
94 | |
95 | /** |
96 | * Run a test, store the info and return the status. |
97 | * |
98 | * @param HttpRequesterInterface $requester |
99 | * |
100 | * @return void |
101 | */ |
102 | public function setHttpRequester($requester) |
103 | { |
104 | $this->requester = $requester; |
105 | } |
106 | |
107 | /** |
108 | * Set object responsible for lining up the test files. |
109 | * |
110 | * @param TestFilesLineUpperInterface $testFilesLineUpper |
111 | * @return void |
112 | */ |
113 | public function setTestFilesLineUpper($testFilesLineUpper) |
114 | { |
115 | $this->testFilesLineUpper = $testFilesLineUpper; |
116 | } |
117 | |
118 | /** |
119 | * Test if .htaccess files are enabled |
120 | * |
121 | * Apache can be configured to completely ignore .htaccess files. This test examines |
122 | * if .htaccess files are proccesed. |
123 | * |
124 | * @return bool|null true=success, false=failure, null=inconclusive |
125 | */ |
126 | public function htaccessEnabled() |
127 | { |
128 | return $this->runTest(new HtaccessEnabledTester()); |
129 | } |
130 | |
131 | /** |
132 | * Test if a module is loaded. |
133 | * |
134 | * This test detects if directives inside a "IfModule" is run for a given module |
135 | * |
136 | * @param string $moduleName A valid Apache module name (ie "rewrite") |
137 | * @return bool|null true=success, false=failure, null=inconclusive |
138 | */ |
139 | public function moduleLoaded($moduleName) |
140 | { |
141 | return $this->runTest(new ModuleLoadedTester($moduleName)); |
142 | } |
143 | |
144 | /** |
145 | * Test if rewriting works. |
146 | * |
147 | * The .htaccess in this test uses the following directives: |
148 | * - IfModule |
149 | * - RewriteEngine |
150 | * - Rewrite |
151 | * |
152 | * @return bool|null true=success, false=failure, null=inconclusive |
153 | */ |
154 | public function rewriteWorks() |
155 | { |
156 | return $this->runTest(new RewriteTester()); |
157 | } |
158 | |
159 | /** |
160 | * Test if AddType works. |
161 | * |
162 | * The .htaccess in this test uses the following directives: |
163 | * - IfModule (core) |
164 | * - AddType (mod_mime, FileInfo) |
165 | * |
166 | * @return bool|null true=success, false=failure, null=inconclusive |
167 | */ |
168 | public function addTypeWorks() |
169 | { |
170 | return $this->runTest(new AddTypeTester()); |
171 | } |
172 | |
173 | /** |
174 | * Test if setting a Response Header with the Header directive works. |
175 | * |
176 | * @return bool|null true=success, false=failure, null=inconclusive |
177 | */ |
178 | public function headerSetWorks() |
179 | { |
180 | return $this->runTest(new HeaderSetTester()); |
181 | } |
182 | |
183 | /** |
184 | * Test if setting a Request Header with the RequestHeader directive works. |
185 | * |
186 | * @return bool|null true=success, false=failure, null=inconclusive |
187 | */ |
188 | public function requestHeaderWorks() |
189 | { |
190 | return $this->runTest(new RequestHeaderTester()); |
191 | } |
192 | |
193 | /** |
194 | * Test if ContentDigest directive works. |
195 | * |
196 | * @return bool|null true=success, false=failure, null=inconclusive |
197 | */ |
198 | public function contentDigestWorks() |
199 | { |
200 | return $this->runTest(new ContentDigestTester()); |
201 | } |
202 | |
203 | /** |
204 | * Test if ServerSignature directive works. |
205 | * |
206 | * @return bool|null true=success, false=failure, null=inconclusive |
207 | */ |
208 | public function serverSignatureWorks() |
209 | { |
210 | return $this->runTest(new ServerSignatureTester()); |
211 | } |
212 | |
213 | |
214 | /** |
215 | * Test if DirectoryIndex works. |
216 | * |
217 | * @return bool|null true=success, false=failure, null=inconclusive |
218 | */ |
219 | public function directoryIndexWorks() |
220 | { |
221 | return $this->runTest(new DirectoryIndexTester()); |
222 | } |
223 | |
224 | /** |
225 | * Test a complex construct for passing information from a rewrite to a script through a request header. |
226 | * |
227 | * @return bool|null true=success, false=failure, null=inconclusive |
228 | */ |
229 | public function passingInfoFromRewriteToScriptThroughRequestHeaderWorks() |
230 | { |
231 | return $this->runTest(new PassInfoFromRewriteToScriptThroughRequestHeaderTester()); |
232 | } |
233 | |
234 | |
235 | /** |
236 | * Test if an environment variable can be set in a rewrite rule and received in PHP. |
237 | * |
238 | * @return bool|null true=success, false=failure, null=inconclusive |
239 | */ |
240 | public function passingInfoFromRewriteToScriptThroughEnvWorks() |
241 | { |
242 | return $this->runTest(new PassInfoFromRewriteToScriptThroughEnvTester()); |
243 | } |
244 | |
245 | /** |
246 | * Call one of the methods of this class (not all allowed). |
247 | * |
248 | * @param string $functionCall ie "rewriteWorks()" |
249 | * |
250 | * @return bool|null true=success, false=failure, null=inconclusive |
251 | */ |
252 | /* |
253 | public function callMethod($functionCall) |
254 | { |
255 | switch ($functionCall) { |
256 | case 'htaccessEnabled()': |
257 | return $this->htaccessEnabled(); |
258 | case 'rewriteWorks()': |
259 | return $this->rewriteWorks(); |
260 | case 'addTypeWorks()': |
261 | return $this->addTypeWorks(); |
262 | case 'headerSetWorks()': |
263 | return $this->headerSetWorks(); |
264 | case 'requestHeaderWorks()': |
265 | return $this->requestHeaderWorks(); |
266 | case 'contentDigestWorks()': |
267 | return $this->contentDigestWorks(); |
268 | case 'directoryIndexWorks()': |
269 | return $this->directoryIndexWorks(); |
270 | case 'passingInfoFromRewriteToScriptThroughRequestHeaderWorks()': |
271 | return $this->passingInfoFromRewriteToScriptThroughRequestHeaderWorks(); |
272 | case 'passingInfoFromRewriteToScriptThroughEnvWorks()': |
273 | return $this->passingInfoFromRewriteToScriptThroughEnvWorks(); |
274 | default: |
275 | throw new \Exception('The method is not callable'); |
276 | } |
277 | |
278 | // TODO: moduleLoaded($moduleName) |
279 | }*/ |
280 | |
281 | /** |
282 | * Crash-test some .htaccess rules. |
283 | * |
284 | * Tests if the server can withstand the given rules without going fatal. |
285 | * |
286 | * - success: if the rules does not result in status 500. |
287 | * - failure: if the rules results in status 500 while a request to a file in a directory |
288 | * without any .htaccess succeeds (<> 500) |
289 | * - inconclusive: if the rules results in status 500 while a request to a file in a directory |
290 | * without any .htaccess also fails (500) |
291 | * |
292 | * @param string $rules Rules to crash-test |
293 | * @param string $subDir (optional) Subdir for the .htaccess to reside. |
294 | * if left out, a unique string will be generated |
295 | * |
296 | * @return bool|null true=success, false=failure, null=inconclusive |
297 | */ |
298 | public function crashTest($rules, $subDir = null) |
299 | { |
300 | return $this->runTest(new CrashTester($rules, $subDir)); |
301 | } |
302 | |
303 | /** |
304 | * Test an innocent request to a text file. |
305 | * |
306 | * If this fails, everything else will also fail. |
307 | * |
308 | * Possible reasons for failure: |
309 | * - A .htaccess in a parent folder has forbidden tags / syntax errors |
310 | * |
311 | * Possible reasons for inconclusive (= test could not be run) |
312 | * - 403 Forbidden |
313 | * - 404 Not Found |
314 | * - Request fails (ie due to timeout) |
315 | * |
316 | * @return bool|null true=success, false=failure, null=inconclusive |
317 | */ |
318 | public function innocentRequestWorks() |
319 | { |
320 | return $this->runTest(new InnocentRequestTester()); |
321 | } |
322 | |
323 | /** |
324 | * Run a custom test. |
325 | * |
326 | * @param array $definition |
327 | * |
328 | * @return bool|null true=success, false=failure, null=inconclusive |
329 | */ |
330 | public function customTest($definition) |
331 | { |
332 | return $this->runTest(new CustomTester($definition)); |
333 | } |
334 | } |