Completed
Push — EZP-26146-location-swap-urlali... ( 334d77...8d4853 )
by
unknown
63:56 queued 37:49
created

TestCase   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 318
Duplicated Lines 5.97 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
dl 19
loc 318
rs 8.6
c 0
b 0
f 0
wmc 37
lcom 1
cbo 5

19 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 19 4
A sendHttpRequest() 0 7 1
A getHttpHost() 0 4 1
A getLoginUsername() 0 4 1
A getLoginPassword() 0 4 1
C createHttpRequest() 0 22 7
A assertHttpResponseCodeEquals() 0 16 4
A getHttpResponseCodeErrorMessage() 0 18 2
A assertHttpResponseHasHeader() 0 8 2
A generateMediaTypeString() 0 4 1
A addCreatedElement() 0 9 1
A tearDownAfterClass() 0 4 1
A clearCreatedElement() 0 6 2
B createFolder() 0 32 1
B createContent() 0 25 2
A getContentLocations() 10 10 1
A addTestSuffix() 0 8 2
A login() 9 9 1
A setSessionInput() 0 6 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/**
4
 * File containing the Functional\TestCase class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 *
9
 * @version //autogentag//
10
 */
11
namespace eZ\Bundle\EzPublishRestBundle\Tests\Functional;
12
13
use Buzz\Message\Request as HttpRequest;
14
use Buzz\Message\Response as HttpResponse;
15
use PHPUnit_Framework_TestCase;
16
17
class TestCase extends PHPUnit_Framework_TestCase
18
{
19
    /**
20
     * @var \Buzz\Client\ClientInterface
21
     */
22
    private $httpClient;
23
24
    /**
25
     * @var string
26
     */
27
    private $httpHost;
28
29
    /**
30
     * @var string
31
     * Basic auth login:password
32
     */
33
    private $httpAuth;
34
35
    protected static $testSuffix;
36
37
    /**
38
     * @var array
39
     */
40
    private $headers = [];
41
42
    /**
43
     * The username to use for login.
44
     * @var string
45
     */
46
    private $loginUsername;
47
48
    /**
49
     * The password to use for login.
50
     * @var string
51
     */
52
    private $loginPassword;
53
54
    /**
55
     * If true, a login request is automatically done during setUp().
56
     * @var bool
57
     */
58
    protected $autoLogin = true;
59
60
    /**
61
     * List of REST contentId (/content/objects/12345) created by tests.
62
     *
63
     * @var array
64
     */
65
    private static $createdContent = array();
66
67
    protected function setUp()
68
    {
69
        parent::setUp();
70
71
        $this->httpHost = getenv('EZP_TEST_REST_HOST') ?: 'localhost';
72
        $this->httpAuth = getenv('EZP_TEST_REST_AUTH') ?: 'admin:publish';
73
        list($this->loginUsername, $this->loginPassword) = explode(':', $this->httpAuth);
74
75
        $this->httpClient = new \Buzz\Client\Curl();
76
        $this->httpClient->setVerifyPeer(false);
77
        $this->httpClient->setTimeout(90);
78
        $this->httpClient->setOption(CURLOPT_FOLLOWLOCATION, false);
79
80
        if ($this->autoLogin) {
81
            $session = $this->login();
82
            $this->headers[] = sprintf('Cookie: %s=%s', $session->name, $session->identifier);
83
            $this->headers[] = sprintf('X-CSRF-Token: %s', $session->csrfToken);
84
        }
85
    }
86
87
    /**
88
     * @return HttpResponse
89
     */
90
    public function sendHttpRequest(HttpRequest $request)
91
    {
92
        $response = new HttpResponse();
93
        $this->httpClient->send($request, $response);
94
95
        return $response;
96
    }
97
98
    protected function getHttpHost()
99
    {
100
        return $this->httpHost;
101
    }
102
103
    protected function getLoginUsername()
104
    {
105
        return $this->loginUsername;
106
    }
107
108
    protected function getLoginPassword()
109
    {
110
        return $this->loginPassword;
111
    }
112
113
    /**
114
     * @return HttpRequest
115
     */
116
    public function createHttpRequest($method, $uri, $contentType = '', $acceptType = '')
117
    {
118
        $headers = array_merge(
119
            $method === 'POST' && $uri === '/api/ezp/v2/user/sessions' ? [] : $this->headers,
120
            [
121
                'Content-Type: ' . $this->generateMediaTypeString($contentType),
122
                'Accept: ' . $this->generateMediaTypeString($acceptType),
123
            ]
124
        );
125
126
        switch ($method) {
127
            case 'PUBLISH': $method = 'POST';  $headers[] = 'X-HTTP-Method-Override: PUBLISH'; break;
128
            case 'MOVE':    $method = 'POST';  $headers[] = 'X-HTTP-Method-Override: MOVE';    break;
129
            case 'PATCH':   $method = 'PATCH'; $headers[] = 'X-HTTP-Method-Override: PATCH';   break;
130
            case 'COPY':    $method = 'POST';  $headers[] = 'X-HTTP-Method-Override: COPY';    break;
131
        }
132
133
        $request = new HttpRequest($method, $uri, $this->httpHost);
134
        $request->addHeaders($headers);
135
136
        return $request;
137
    }
138
139
    protected function assertHttpResponseCodeEquals(HttpResponse $response, $expected)
140
    {
141
        $responseCode = $response->getStatusCode();
142
        if ($responseCode != $expected) {
143
            $errorMessageString = '';
144
            if (strpos($response->getHeader('Content-Type'), 'application/vnd.ez.api.ErrorMessage+xml') !== false) {
145
                $body = \simplexml_load_string($response->getContent());
146
                $errorMessageString = $this->getHttpResponseCodeErrorMessage($body);
147
            } elseif (strpos($response->getHeader('Content-Type'), 'application/vnd.ez.api.ErrorMessage+json') !== false) {
148
                $body = json_decode($response->getContent());
149
                $errorMessageString = $this->getHttpResponseCodeErrorMessage($body->ErrorMessage);
150
            }
151
152
            self::assertEquals($expected, $responseCode, $errorMessageString);
153
        }
154
    }
155
156
    private function getHttpResponseCodeErrorMessage($errorMessage)
157
    {
158
        $errorMessageString = <<< EOF
159
Server error message ({$errorMessage->errorCode}): {$errorMessage->errorMessage}
160
161
{$errorMessage->errorDescription}
162
163
EOF;
164
165
        // If server is in debug mode it will return file, line and trace.
166
        if (!empty($errorMessage->file)) {
167
            $errorMessageString .= "\nIn {$errorMessage->file}:{$errorMessage->line}\n\n{$errorMessage->trace}";
168
        } else {
169
            $errorMessageString .= "\nIn \<no trace, debug disabled\>";
170
        }
171
172
        return $errorMessageString;
173
    }
174
175
    protected function assertHttpResponseHasHeader(HttpResponse $response, $header, $expectedValue = null)
176
    {
177
        $headerValue = $response->getHeader($header);
178
        self::assertNotNull($headerValue, "Failed asserting that response has a $header header");
179
        if ($expectedValue !== null) {
180
            self::assertEquals($expectedValue, $headerValue);
181
        }
182
    }
183
184
    protected function generateMediaTypeString($typeString)
185
    {
186
        return "application/vnd.ez.api.$typeString";
187
    }
188
189
    protected function addCreatedElement($href)
190
    {
191
        $testCase = $this;
192
        self::$createdContent[$href] = function () use ($href, $testCase) {
193
            $testCase->sendHttpRequest(
194
                $testCase->createHttpRequest('DELETE', $href)
195
            );
196
        };
197
    }
198
199
    public static function tearDownAfterClass()
200
    {
201
        self::clearCreatedElement(self::$createdContent);
202
    }
203
204
    private static function clearCreatedElement(array $contentArray)
205
    {
206
        foreach (array_reverse($contentArray) as $href => $callback) {
207
            $callback();
208
        }
209
    }
210
211
    /**
212
     * @param string $parentLocationId The REST id of the parent location
213
     *
214
     * @return array created Content, as an array
215
     */
216
    protected function createFolder($string, $parentLocationId)
217
    {
218
        $string = $this->addTestSuffix($string);
219
        $xml = <<< XML
220
<?xml version="1.0" encoding="UTF-8"?>
221
<ContentCreate>
222
  <ContentType href="/api/ezp/v2/content/types/1" />
223
  <mainLanguageCode>eng-GB</mainLanguageCode>
224
  <LocationCreate>
225
    <ParentLocation href="{$parentLocationId}" />
226
    <priority>0</priority>
227
    <hidden>false</hidden>
228
    <sortField>PATH</sortField>
229
    <sortOrder>ASC</sortOrder>
230
  </LocationCreate>
231
  <Section href="/api/ezp/v2/content/sections/1" />
232
  <alwaysAvailable>true</alwaysAvailable>
233
  <remoteId>{$string}</remoteId>
234
  <User href="/api/ezp/v2/user/users/14" />
235
  <modificationDate>2012-09-30T12:30:00</modificationDate>
236
  <fields>
237
    <field>
238
      <fieldDefinitionIdentifier>name</fieldDefinitionIdentifier>
239
      <languageCode>eng-GB</languageCode>
240
      <fieldValue>{$string}</fieldValue>
241
    </field>
242
  </fields>
243
</ContentCreate>
244
XML;
245
246
        return $this->createContent($xml);
247
    }
248
249
    /**
250
     * @param $xml
251
     *
252
     * @return array Content key of the Content struct array
253
     */
254
    protected function createContent($xml)
255
    {
256
        $request = $this->createHttpRequest('POST', '/api/ezp/v2/content/objects', 'ContentCreate+xml', 'Content+json');
257
        $request->setContent($xml);
258
259
        $response = $this->sendHttpRequest($request);
260
261
        self::assertHttpResponseCodeEquals($response, 201);
262
263
        $content = json_decode($response->getContent(), true);
264
265
        if (!isset($content['Content']['CurrentVersion']['Version'])) {
266
            self::fail("Incomplete response (no version):\n" . $response->getContent() . "\n");
267
        }
268
269
        $response = $this->sendHttpRequest(
270
            $request = $this->createHttpRequest('PUBLISH', $content['Content']['CurrentVersion']['Version']['_href'])
271
        );
272
273
        self::assertHttpResponseCodeEquals($response, 204);
274
275
        $this->addCreatedElement($content['Content']['_href'], true);
276
277
        return $content['Content'];
278
    }
279
280
    /**
281
     * @param string $contentHref
282
     *
283
     * @return array
284
     */
285 View Code Duplication
    protected function getContentLocations($contentHref)
286
    {
287
        $response = $this->sendHttpRequest(
288
            $this->createHttpRequest('GET', "$contentHref/locations", '', 'LocationList+json')
289
        );
290
        self::assertHttpResponseCodeEquals($response, 200);
291
        $folderLocations = json_decode($response->getContent(), true);
292
293
        return $folderLocations;
294
    }
295
296
    protected function addTestSuffix($string)
297
    {
298
        if (!isset(self::$testSuffix)) {
299
            self::$testSuffix = uniqid();
300
        }
301
302
        return $string . '_' . self::$testSuffix;
303
    }
304
305
    /**
306
     * Sends a login request to the REST server.
307
     *
308
     * @return \stdClass an object with the name, identifier, csrftoken properties.
309
     */
310 View Code Duplication
    protected function login()
311
    {
312
        $request = $this->createHttpRequest('POST', '/api/ezp/v2/user/sessions', 'SessionInput+json', 'Session+json');
313
        $this->setSessionInput($request);
314
        $response = $this->sendHttpRequest($request);
315
        self::assertHttpResponseCodeEquals($response, 201);
316
317
        return json_decode($response->getContent())->Session;
318
    }
319
320
    /**
321
     * Sets the request's content to a JSON session creation payload.
322
     *
323
     * @param HttpRequest $request
324
     * @param string $password The password to use in the input. Will use the default one if not set.
325
     *
326
     * @return string
327
     */
328
    protected function setSessionInput(HttpRequest $request, $password = null)
329
    {
330
        $request->setContent(
331
            sprintf('{"SessionInput": {"login": "admin", "password": "%s"}}', $password ?: $this->loginPassword)
332
        );
333
    }
334
}
335