CustomTester   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 217
Duplicated Lines 0 %

Test Coverage

Coverage 94.37%

Importance

Changes 9
Bugs 0 Features 0
Metric Value
wmc 31
eloc 71
c 9
b 0
f 0
dl 0
loc 217
ccs 67
cts 71
cp 0.9437
rs 9.92

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getSubDir() 0 3 1
A __construct() 0 20 4
A registerTestFiles() 0 17 5
A standardErrorHandling() 0 26 6
A realRunSubTest() 0 19 4
A run() 0 9 2
A realRun() 0 31 5
A bypassStandardErrorHandling() 0 10 4
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
     *  Standard Error handling
83
     *
84
     * @param  HttpResponse  $response
85
     *
86
     * @return TestResult|null  If no errors, null is returned, otherwise a TestResult
87
     */
88 71
    private function standardErrorHandling($response)
89
    {
90 71
        switch ($response->statusCode) {
91 71
            case '0':
92 9
                return new TestResult(null, $response->body);
93 62
            case '403':
94
                return new TestResult(null, '403 Forbidden');
95 62
            case '404':
96 10
                return new TestResult(null, '404 Not Found');
97
            case '500':
98
                $hct = $this->getHtaccessCapabilityTester();
99
100 10
                // Run innocent request / get it from cache. This sets
101 10
                // $statusCodeOfLastRequest, which we need now
102 2
                $hct->innocentRequestWorks();
103
                if ($hct->statusCodeOfLastRequest == '500') {
104 8
                    return new TestResult(null, 'Errored with 500. Everything errors with 500.');
105 8
                } else {
106
                    return new TestResult(
107 8
                        false,
108
                        'Errored with 500. ' .
109
                        'Not all goes 500, so it must be a forbidden directive in the .htaccess'
110
                    );
111 52
                }
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 80
     * @return bool          true if error handling should be bypassed
128
     */
129 80
    private function bypassStandardErrorHandling($test, $response)
130 68
    {
131
        if (!(isset($test['request']['bypass-standard-error-handling']))) {
132 35
            return false;
133 35
        }
134 30
        $bypassErrors = $test['request']['bypass-standard-error-handling'];
135
        if (in_array($response->statusCode, $bypassErrors) || in_array('all', $bypassErrors)) {
136 7
            return true;
137
        }
138
        return false;
139
    }
140
141
    /**
142
     *  Run single test
143
     *
144
     * @param  array  $test  the subtest to run
145
     *
146 80
     * @return TestResult  Returns a test result
147
     */
148 80
    private function realRunSubTest($test)
149 80
    {
150 46
        $requestUrl = $this->baseUrl . '/' . $test['subdir'] . '/';
151
        if (isset($test['request']['url'])) {
152 65
            $requestUrl .= $test['request']['url'];
153
        } else {
154
            $requestUrl .= $test['request'];
155 80
        }
156
        //echo $requestUrl . '<br>';
157
        $response = $this->makeHttpRequest($requestUrl);
158 80
159 71
        // Standard error handling
160 71
        if (!($this->bypassStandardErrorHandling($test, $response))) {
161 19
            $errorResult = $this->standardErrorHandling($response);
162
            if (!is_null($errorResult)) {
163
                return $errorResult;
164 71
            }
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 80
     * @throws \Exception  In case the test cannot be run due to serious issues
177
     */
178 80
    private function realRun($baseDir, $baseUrl)
179
    {
180 80
        $this->prepareForRun($baseDir, $baseUrl);
181 80
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 80
            }
197 80
            }*/
198 80
            if (isset($test['request'])) {
199 79
                $result = $this->realRunSubTest($test);
200
                if ($result->info != 'no-match') {
201
                    return $result;
202
                }
203 13
            }
204
        }
205
        if (is_null($result)) {
206 13
            $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 80
     * @throws \Exception  In case the test cannot be run due to serious issues
219
     */
220 80
    public function run($baseDir, $baseUrl)
221
    {
222
        $testResult = $this->realRun($baseDir, $baseUrl);
223 80
224 80
        // A test might not create a request if it has an unfulfilled requirement
225
        if (isset($this->lastHttpResponse)) {
226 80
            $testResult->statusCodeOfLastRequest = $this->lastHttpResponse->statusCode;
227
        }
228
        return $testResult;
229
    }
230
}
231