HtaccessCapabilityTester   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 305
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 10
Bugs 2 Features 1
Metric Value
wmc 21
eloc 38
c 10
b 2
f 1
dl 0
loc 305
ccs 51
cts 51
cp 1
rs 10

18 Methods

Rating   Name   Duplication   Size   Complexity  
A innocentRequestWorks() 0 3 1
A crashTest() 0 3 1
A __construct() 0 4 1
A serverSignatureWorks() 0 3 1
A runTest() 0 22 4
A directoryIndexWorks() 0 3 1
A rewriteWorks() 0 3 1
A htaccessEnabled() 0 3 1
A headerSetWorks() 0 3 1
A contentDigestWorks() 0 3 1
A setTestFilesLineUpper() 0 3 1
A setHttpRequester() 0 3 1
A addTypeWorks() 0 3 1
A customTest() 0 3 1
A moduleLoaded() 0 3 1
A passingInfoFromRewriteToScriptThroughRequestHeaderWorks() 0 3 1
A passingInfoFromRewriteToScriptThroughEnvWorks() 0 3 1
A requestHeaderWorks() 0 3 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 <[email protected]>
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 35
    public function __construct($baseDir, $baseUrl)
59
    {
60 35
        $this->baseDir = $baseDir;
61 35
        $this->baseUrl = $baseUrl;
62 35
    }
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 35
    private function runTest($tester)
72
    {
73
        //$tester->setHtaccessCapabilityTester($this);
74 35
        if (isset($this->requester)) {
75 35
            $tester->setHttpRequester($this->requester);
76
        }
77 35
        if (isset($this->testFilesLineUpper)) {
78 35
            $tester->setTestFilesLineUpper($this->testFilesLineUpper);
79
        }
80
        //$tester->setHtaccessCapabilityTester($this);
81
82 35
        $cacheKeys = [$this->baseDir, $tester->getCacheKey()];
83 35
        if (TestResultCache::isCached($cacheKeys)) {
84 18
            $testResult = TestResultCache::getCached($cacheKeys);
85
        } else {
86 35
            $testResult = $tester->run($this->baseDir, $this->baseUrl);
87 35
            TestResultCache::cache($cacheKeys, $testResult);
88
        }
89
90 35
        $this->infoFromLastTest = $testResult->info;
91 35
        $this->statusCodeOfLastRequest = $testResult->statusCodeOfLastRequest;
92 35
        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 35
    public function setHttpRequester($requester)
103
    {
104 35
        $this->requester = $requester;
105 35
    }
106
107
    /**
108
     * Set object responsible for lining up the test files.
109
     *
110
     * @param  TestFilesLineUpperInterface  $testFilesLineUpper
111
     * @return void
112
     */
113 35
    public function setTestFilesLineUpper($testFilesLineUpper)
114
    {
115 35
        $this->testFilesLineUpper = $testFilesLineUpper;
116 35
    }
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 16
    public function htaccessEnabled()
127
    {
128 16
        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 2
    public function moduleLoaded($moduleName)
140
    {
141 2
        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 13
    public function rewriteWorks()
155
    {
156 13
        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 17
    public function addTypeWorks()
169
    {
170 17
        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 10
    public function headerSetWorks()
179
    {
180 10
        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 2
    public function requestHeaderWorks()
189
    {
190 2
        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 19
    public function contentDigestWorks()
199
    {
200 19
        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 22
    public function serverSignatureWorks()
209
    {
210 22
        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 15
    public function directoryIndexWorks()
220
    {
221 15
        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 1
    public function passingInfoFromRewriteToScriptThroughRequestHeaderWorks()
230
    {
231 1
        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 1
    public function passingInfoFromRewriteToScriptThroughEnvWorks()
241
    {
242 1
        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 5
    public function crashTest($rules, $subDir = null)
299
    {
300 5
        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 10
    public function innocentRequestWorks()
319
    {
320 10
        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 14
    public function customTest($definition)
331
    {
332 14
        return $this->runTest(new CustomTester($definition));
333
    }
334
}
335