Completed
Push — ezp26179-rest_session_refresh_... ( a3e80a...8fb71d )
by
unknown
184:38 queued 169:13
created

TestCase::createHttpRequest()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 12
c 1
b 0
f 0
nc 4
nop 4
dl 0
loc 22
rs 8.9197
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
    protected function setUp()
43
    {
44
        parent::setUp();
45
46
        $this->httpHost = getenv('EZP_TEST_REST_HOST') ?: 'localhost';
47
        $this->httpAuth = getenv('EZP_TEST_REST_AUTH') ?: 'admin:publish';
48
49
        $this->httpClient = new \Buzz\Client\Curl();
50
        $this->httpClient->setVerifyPeer(false);
51
        $this->httpClient->setTimeout(90);
52
        $this->httpClient->setOption(CURLOPT_FOLLOWLOCATION, false);
53
        $this->httpClient->setOption(CURLOPT_COOKIEFILE, null);
54
55
        $request = $this->createHttpRequest('POST', '/api/ezp/v2/user/sessions', 'SessionInput+json', 'Session+json');
56
        $request->setContent('{"SessionInput": {"login": "admin", "password": "publish"}}');
57
        $response = $this->sendHttpRequest($request);
58
        $session = json_decode($response->getContent())->Session;
59
        $this->headers[] = sprintf('Cookie: %s=%s', $session->name, $session->identifier);
60
        $this->headers[] = sprintf('X-CSRF-Token: %s', $session->csrfToken);
61
    }
62
63
    /**
64
     * @return HttpResponse
65
     */
66
    public function sendHttpRequest(HttpRequest $request)
67
    {
68
        $response = new HttpResponse();
69
        $this->httpClient->send($request, $response);
70
71
        return $response;
72
    }
73
74
    /**
75
     * @return HttpRequest
76
     */
77
    public function createHttpRequest($method, $uri, $contentType = '', $acceptType = '')
78
    {
79
        $headers = array_merge(
80
            $this->headers,
81
            [
82
                'Content-Type: ' . $this->generateMediaTypeString($contentType),
83
                'Accept: ' . $this->generateMediaTypeString($acceptType),
84
            ]
85
        );
86
87
        switch ($method)
88
        {
89
            case "PUBLISH": $method = "POST";  $headers[] = 'X-HTTP-Method-Override: PUBLISH'; break;
90
            case "MOVE":    $method = "POST";  $headers[] = 'X-HTTP-Method-Override: MOVE';    break;
91
            case "PATCH":   $method = "PATCH"; $headers[] = 'X-HTTP-Method-Override: PATCH';   break;
92
        }
93
94
        $request = new HttpRequest($method, $uri, $this->httpHost);
95
        $request->addHeaders($headers);
96
97
        return $request;
98
    }
99
100
    protected function assertHttpResponseCodeEquals(HttpResponse $response, $expected)
101
    {
102
        $responseCode = $response->getStatusCode();
103
        if ($responseCode != $expected) {
104
            $errorMessageString = '';
105
            if (strpos($response->getHeader('Content-Type'), 'application/vnd.ez.api.ErrorMessage+xml') !== false) {
106
                $body = \simplexml_load_string($response->getContent());
107
                $errorMessageString = $this->getHttpResponseCodeErrorMessage($body);
108
            } elseif (strpos($response->getHeader('Content-Type'), 'application/vnd.ez.api.ErrorMessage+json') !== false) {
109
                $body = json_decode($response->getContent());
110
                $errorMessageString = $this->getHttpResponseCodeErrorMessage($body->ErrorMessage);
111
            }
112
113
            self::assertEquals($expected, $responseCode, $errorMessageString);
114
        }
115
    }
116
117
    private function getHttpResponseCodeErrorMessage($errorMessage)
118
    {
119
        $errorMessageString = <<< EOF
120
Server error message ({$errorMessage->errorCode}): {$errorMessage->errorMessage}
121
122
{$errorMessage->errorDescription}
123
124
EOF;
125
126
        // If server is in debug mode it will return file, line and trace.
127
        if (!empty($errorMessage->file)) {
128
            $errorMessageString .= "\nIn {$errorMessage->file}:{$errorMessage->line}\n\n{$errorMessage->trace}";
129
        } else {
130
            $errorMessageString .= "\nIn \<no trace, debug disabled\>";
131
        }
132
133
        return $errorMessageString;
134
    }
135
136
    protected function assertHttpResponseHasHeader(HttpResponse $response, $header, $expectedValue = null)
137
    {
138
        $headerValue = $response->getHeader($header);
139
        self::assertNotNull($headerValue, "Failed asserting that response has a $header header");
140
        if ($expectedValue !== null) {
141
            self::assertEquals($expectedValue, $headerValue);
142
        }
143
    }
144
145
    protected function generateMediaTypeString($typeString)
146
    {
147
        return "application/vnd.ez.api.$typeString";
148
    }
149
150
    protected function addCreatedElement($href)
151
    {
152
        $testCase = $this;
153
        self::$createdContent[$href] = function () use ($href, $testCase) {
154
            $testCase->sendHttpRequest(
155
                $testCase->createHttpRequest('DELETE', $href)
156
            );
157
        };
158
    }
159
160
    public static function tearDownAfterClass()
161
    {
162
        self::clearCreatedElement(self::$createdContent);
163
    }
164
165
    private static function clearCreatedElement(array $contentArray)
166
    {
167
        foreach (array_reverse($contentArray) as $href => $callback) {
168
            $callback();
169
        }
170
    }
171
172
    /**
173
     * @param string $parentLocationId The REST id of the parent location
174
     *
175
     * @return array created Content, as an array
176
     */
177
    protected function createFolder($string, $parentLocationId)
178
    {
179
        $string = $this->addTestSuffix($string);
180
        $xml = <<< XML
181
<?xml version="1.0" encoding="UTF-8"?>
182
<ContentCreate>
183
  <ContentType href="/api/ezp/v2/content/types/1" />
184
  <mainLanguageCode>eng-GB</mainLanguageCode>
185
  <LocationCreate>
186
    <ParentLocation href="{$parentLocationId}" />
187
    <priority>0</priority>
188
    <hidden>false</hidden>
189
    <sortField>PATH</sortField>
190
    <sortOrder>ASC</sortOrder>
191
  </LocationCreate>
192
  <Section href="/api/ezp/v2/content/sections/1" />
193
  <alwaysAvailable>true</alwaysAvailable>
194
  <remoteId>{$string}</remoteId>
195
  <User href="/api/ezp/v2/user/users/14" />
196
  <modificationDate>2012-09-30T12:30:00</modificationDate>
197
  <fields>
198
    <field>
199
      <fieldDefinitionIdentifier>name</fieldDefinitionIdentifier>
200
      <languageCode>eng-GB</languageCode>
201
      <fieldValue>{$string}</fieldValue>
202
    </field>
203
  </fields>
204
</ContentCreate>
205
XML;
206
207
        return $this->createContent($xml);
208
    }
209
210
    /**
211
     * @param $xml
212
     *
213
     * @return array Content key of the Content struct array
214
     */
215
    protected function createContent($xml)
216
    {
217
        $request = $this->createHttpRequest('POST', '/api/ezp/v2/content/objects', 'ContentCreate+xml', 'Content+json');
218
        $request->setContent($xml);
219
220
        $response = $this->sendHttpRequest($request);
221
222
        self::assertHttpResponseCodeEquals($response, 201);
223
224
        $content = json_decode($response->getContent(), true);
225
226
        if (!isset($content['Content']['CurrentVersion']['Version'])) {
227
            self::fail("Incomplete response (no version):\n" . $response->getContent() . "\n");
228
        }
229
230
        $response = $this->sendHttpRequest(
231
            $request = $this->createHttpRequest('PUBLISH', $content['Content']['CurrentVersion']['Version']['_href'])
232
        );
233
234
        self::assertHttpResponseCodeEquals($response, 204);
235
236
        $this->addCreatedElement($content['Content']['_href'], true);
237
238
        return $content['Content'];
239
    }
240
241
    /**
242
     * @param string $contentHref
243
     *
244
     * @return array
245
     */
246 View Code Duplication
    protected function getContentLocations($contentHref)
247
    {
248
        $response = $this->sendHttpRequest(
249
            $this->createHttpRequest('GET', "$contentHref/locations", '', 'LocationList+json')
250
        );
251
        self::assertHttpResponseCodeEquals($response, 200);
252
        $folderLocations = json_decode($response->getContent(), true);
253
254
        return $folderLocations;
255
    }
256
257
    protected function addTestSuffix($string)
258
    {
259
        if (!isset(self::$testSuffix)) {
260
            self::$testSuffix = uniqid();
261
        }
262
263
        return $string . '_' . self::$testSuffix;
264
    }
265
266
    /**
267
     * List of REST contentId (/content/objects/12345) created by tests.
268
     *
269
     * @var array
270
     */
271
    private static $createdContent = array();
272
}
273