Completed
Push — master ( 0ff500...dd6203 )
by André
25:15 queued 09:04
created

ContentTest   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 557
Duplicated Lines 30.88 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 172
loc 557
rs 9.8
c 0
b 0
f 0
wmc 31
lcom 1
cbo 3

25 Methods

Rating   Name   Duplication   Size   Complexity  
A testPublishContent() 0 9 1
A testRedirectContent() 0 9 1
A testLoadContent() 0 9 1
A testUpdateContentMetadata() 17 17 1
A testCreateDraftFromVersion() 11 11 1
A testRedirectCurrentVersion() 0 10 1
A testLoadContentVersion() 0 10 1
A testCopyContent() 0 16 1
A testDeleteContent() 0 9 1
A testLoadContentVersions() 0 8 1
A testCreateDraftFromCurrentVersion() 11 11 1
A testDeleteContentVersion() 0 8 1
A testUpdateVersion() 22 22 1
A testRedirectCurrentVersionRelations() 0 13 1
A testLoadVersionRelations() 0 8 1
A testCreateRelation() 20 20 1
A testLoadVersionRelation() 0 10 1
A loadContent() 0 17 3
B testCreateView() 25 25 1
B testCreateContent() 42 42 1
A testDeleteTranslationFromDraft() 0 19 1
A testLoadContentVersionsProvidesDeleteTranslationFromDraftResourceLink() 0 48 3
B createVersionTranslation() 24 24 1
A ensureLanguageExists() 0 4 1
A getVersionInfoFromJSONVersionListByStatus() 0 10 3

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\ContentTest 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
namespace eZ\Bundle\EzPublishRestBundle\Tests\Functional;
10
11
use eZ\Bundle\EzPublishRestBundle\Tests\Functional\TestCase as RESTFunctionalTestCase;
12
13
class ContentTest extends RESTFunctionalTestCase
14
{
15
    /**
16
     * Covers POST /content/objects.
17
     *
18
     * @return string REST content ID
19
     */
20 View Code Duplication
    public function testCreateContent()
21
    {
22
        $request = $this->createHttpRequest('POST', '/api/ezp/v2/content/objects', 'ContentCreate+xml', 'ContentInfo+json');
23
        $string = $this->addTestSuffix(__FUNCTION__);
24
        $body = <<< XML
25
<?xml version="1.0" encoding="UTF-8"?>
26
<ContentCreate>
27
  <ContentType href="/api/ezp/v2/content/types/1" />
28
  <mainLanguageCode>eng-GB</mainLanguageCode>
29
  <LocationCreate>
30
    <ParentLocation href="/api/ezp/v2/content/locations/1/2" />
31
    <priority>0</priority>
32
    <hidden>false</hidden>
33
    <sortField>PATH</sortField>
34
    <sortOrder>ASC</sortOrder>
35
  </LocationCreate>
36
  <Section href="/api/ezp/v2/content/sections/1" />
37
  <alwaysAvailable>true</alwaysAvailable>
38
  <remoteId>{$string}</remoteId>
39
  <User href="/api/ezp/v2/user/users/14" />
40
  <modificationDate>2012-09-30T12:30:00</modificationDate>
41
  <fields>
42
    <field>
43
      <fieldDefinitionIdentifier>name</fieldDefinitionIdentifier>
44
      <languageCode>eng-GB</languageCode>
45
      <fieldValue>{$string}</fieldValue>
46
    </field>
47
  </fields>
48
</ContentCreate>
49
XML;
50
        $request->setContent($body);
51
52
        $response = $this->sendHttpRequest($request);
53
54
        self::assertHttpResponseCodeEquals($response, 201);
55
        self::assertHttpResponseHasHeader($response, 'Location');
56
57
        $href = $response->getHeader('Location');
58
        $this->addCreatedElement($href);
59
60
        return $href;
61
    }
62
63
    /**
64
     * @depends testCreateContent
65
     * Covers PUBLISH /content/objects/<contentId>/versions/<versionNumber>
66
     *
67
     * @return string REST content ID
68
     */
69
    public function testPublishContent($restContentHref)
70
    {
71
        $response = $this->sendHttpRequest(
72
            $this->createHttpRequest('PUBLISH', "$restContentHref/versions/1")
73
        );
74
        self::assertHttpResponseCodeEquals($response, 204);
75
76
        return $restContentHref;
77
    }
78
79
    /**
80
     * @depends testPublishContent
81
     * Covers GET /content/objects?remoteId=<remoteId>
82
     */
83
    public function testRedirectContent($restContentHref)
84
    {
85
        $response = $this->sendHttpRequest(
86
            $this->createHttpRequest('GET', '/api/ezp/v2/content/objects?remoteId=' . $this->addTestSuffix('testCreateContent'))
87
        );
88
89
        self::assertHttpResponseCodeEquals($response, 307);
90
        self::assertEquals($response->getHeader('Location'), $restContentHref);
91
    }
92
93
    /**
94
     * @depends testPublishContent
95
     */
96
    public function testLoadContent($restContentHref)
97
    {
98
        $response = $this->sendHttpRequest(
99
            $this->createHttpRequest('GET', $restContentHref)
100
        );
101
102
        self::assertHttpResponseCodeEquals($response, 200);
103
        // @todo test data a bit ?
104
    }
105
106
    /**
107
     * @depends testPublishContent
108
     */
109 View Code Duplication
    public function testUpdateContentMetadata($restContentHref)
110
    {
111
        $string = $this->addTestSuffix(__FUNCTION__);
112
        $content = <<< XML
113
<?xml version="1.0" encoding="UTF-8"?>
114
<ContentUpdate>
115
  <Owner href="/api/ezp/v2/user/users/10"/>
116
  <remoteId>{$string}</remoteId>
117
</ContentUpdate>
118
XML;
119
        $request = $this->createHttpRequest('PATCH', $restContentHref, 'ContentUpdate+xml', 'ContentInfo+json');
120
        $request->setContent($content);
121
        $response = $this->sendHttpRequest($request);
122
        self::assertHttpResponseCodeEquals($response, 200);
123
124
        // @todo test data
125
    }
126
127
    /**
128
     * @depends testPublishContent
129
     *
130
     * @return string ContentVersion REST ID
131
     */
132 View Code Duplication
    public function testCreateDraftFromVersion($restContentHref)
133
    {
134
        $response = $this->sendHttpRequest(
135
            $this->createHttpRequest('COPY', "{$restContentHref}/versions/1")
136
        );
137
138
        self::assertHttpResponseCodeEquals($response, 201);
139
        self::assertEquals($response->getHeader('Location'), "{$restContentHref}/versions/2");
140
141
        return $response->getHeader('Location');
142
    }
143
144
    /**
145
     * @depends testPublishContent
146
     * Covers GET /content/objects/<contentId>/currentversion
147
     * @covers \eZ\Publish\Core\REST\Server\Controller\Content::redirectCurrentVersion
148
     */
149
    public function testRedirectCurrentVersion($restContentHref)
150
    {
151
        $response = $this->sendHttpRequest(
152
            $this->createHttpRequest('GET', "$restContentHref/currentversion")
153
        );
154
155
        self::assertHttpResponseCodeEquals($response, 307);
156
157
        self::assertHttpResponseHasHeader($response, 'Location', "$restContentHref/versions/1");
158
    }
159
160
    /**
161
     * @depends testCreateDraftFromVersion
162
     * Covers GET /content/objects/<contentId>/versions/<versionNumber>
163
     *
164
     * @param string $restContentVersionHref
165
     */
166
    public function testLoadContentVersion($restContentVersionHref)
167
    {
168
        $response = $this->sendHttpRequest(
169
            $this->createHttpRequest('GET', $restContentVersionHref)
170
        );
171
172
        self::assertHttpResponseCodeEquals($response, 200);
173
        // @todo test data
174
        // @todo test filtering (language, fields, etc)
175
    }
176
177
    /**
178
     * Covers COPY /content/objects/<contentId>.
179
     * @depends testPublishContent
180
     *
181
     * @return string the copied content href
182
     */
183
    public function testCopyContent($restContentHref)
184
    {
185
        $testContent = $this->loadContent($restContentHref);
186
187
        $request = $this->createHttpRequest('COPY', $restContentHref);
188
        $request->addHeader('Destination: ' . $testContent['MainLocation']['_href']);
189
190
        $response = $this->sendHttpRequest($request);
191
192
        self::assertHttpResponseCodeEquals($response, 201);
193
        self::assertStringStartsWith('/api/ezp/v2/content/objects/', $response->getHeader('Location'));
194
195
        $this->addCreatedElement($response->getHeader('Location'));
196
197
        return $response->getHeader('Location');
198
    }
199
200
    /**
201
     * Covers DELETE /content/objects/<versionNumber>.
202
     * @depends testCopyContent
203
     */
204
    public function testDeleteContent($restContentHref)
205
    {
206
        self::markTestSkipped("Fails as the content created by copyContent isn't found");
207
        $response = $this->sendHttpRequest(
208
            $this->createHttpRequest('DELETE', $restContentHref)
209
        );
210
211
        self::assertHttpResponseCodeEquals($response, 204);
212
    }
213
214
    /**
215
     * @depends testPublishContent
216
     * Covers GET /content/objects/<contentId>/versions
217
     */
218
    public function testLoadContentVersions($restContentHref)
219
    {
220
        $response = $this->sendHttpRequest(
221
            $this->createHttpRequest('GET', "$restContentHref/versions", '', 'VersionList')
222
        );
223
224
        self::assertHttpResponseCodeEquals($response, 200);
225
    }
226
227
    /**
228
     * @depends testPublishContent
229
     *
230
     * @param string $restContentHref /content/objects/<contentId>
231
     * Covers COPY /content/objects/<contentId>/currentversion
232
     *
233
     * @return string the ID of the created version (/content/objects/<contentId>/versions/<versionNumber>
234
     */
235 View Code Duplication
    public function testCreateDraftFromCurrentVersion($restContentHref)
236
    {
237
        $response = $this->sendHttpRequest(
238
            $this->createHttpRequest('COPY', "$restContentHref/currentversion")
239
        );
240
241
        self::assertHttpResponseCodeEquals($response, 201);
242
        self::assertHttpResponseHasHeader($response, 'Location');
243
244
        return $response->getHeader('Location');
245
    }
246
247
    /**
248
     * @depends testCreateDraftFromCurrentVersion
249
     *
250
     * @param string $restContentVersionHref /api/ezp/v2/content/objects/<contentId>/versions>/<versionNumber>
251
     * Covers DELETE /api/ezp/v2/content/objects/<contentId>/versions>/<versionNumber>
252
     */
253
    public function testDeleteContentVersion($restContentVersionHref)
254
    {
255
        $response = $this->sendHttpRequest(
256
            $this->createHttpRequest('DELETE', $restContentVersionHref)
257
        );
258
259
        self::assertHttpResponseCodeEquals($response, 204);
260
    }
261
262
    /**
263
     * @depends testCreateDraftFromVersion
264
     * Covers PATCH /content/objects/<contentId>/versions>/<versionNumber>
265
     *
266
     * @param string $restContentVersionHref /content/objects/<contentId>/versions>/<versionNumber>
267
     */
268 View Code Duplication
    public function testUpdateVersion($restContentVersionHref)
269
    {
270
        $xml = <<< XML
271
<VersionUpdate>
272
    <fields>
273
        <field>
274
            <fieldDefinitionIdentifier>name</fieldDefinitionIdentifier>
275
            <languageCode>eng-GB</languageCode>
276
            <fieldValue>testUpdateVersion</fieldValue>
277
        </field>
278
    </fields>
279
</VersionUpdate>
280
XML;
281
282
        $request = $this->createHttpRequest('PATCH', $restContentVersionHref, 'VersionUpdate+xml', 'Version+json');
283
        $request->setContent($xml);
284
        $response = $this->sendHttpRequest(
285
            $request
286
        );
287
288
        self::assertHttpResponseCodeEquals($response, 200);
289
    }
290
291
    /**
292
     * @depends testPublishContent
293
     * Covers GET /content/objects/<contentId>/relations
294
     */
295
    public function testRedirectCurrentVersionRelations($restContentHref)
296
    {
297
        $response = $this->sendHttpRequest(
298
            $this->createHttpRequest('GET', "$restContentHref/relations")
299
        );
300
301
        self::assertHttpResponseCodeEquals($response, 307);
302
303
        // @todo Fix, see EZP-21059. Meanwhile, the test is skipped if it fails as expected
304
        // self::assertHttpResponseHasHeader( $response, 'Location', "$restContentHref/versions/1/relations" );
305
        self::assertHttpResponseHasHeader($response, 'Location', "$restContentHref/relations?versionNumber=1");
306
        self::markTestIncomplete('@todo Fix issue EZP-21059');
307
    }
308
309
    /**
310
     * @depends testCreateDraftFromVersion
311
     * Covers GET /content/objects/<contentId>/versions/<versionNumber>/relations
312
     */
313
    public function testLoadVersionRelations($restContentVersionHref)
314
    {
315
        $response = $this->sendHttpRequest(
316
            $this->createHttpRequest('GET', "$restContentVersionHref/relations")
317
        );
318
319
        self::assertHttpResponseCodeEquals($response, 200);
320
    }
321
322
    /**
323
     * @depends testCreateDraftFromVersion
324
     * Covers POST /content/objects/<contentId>/versions/<versionNumber>/relations/<relationId>
325
     *
326
     * @return string created relation HREF (/content/objects/<contentId>/versions/<versionNumber>/relations/<relationId>
327
     */
328 View Code Duplication
    public function testCreateRelation($restContentVersionHref)
329
    {
330
        $content = <<< XML
331
<?xml version="1.0" encoding="UTF-8"?>
332
<RelationCreate>
333
  <Destination href="/api/ezp/v2/content/objects/10"/>
334
</RelationCreate>
335
XML;
336
337
        $request = $this->createHttpRequest('POST', "$restContentVersionHref/relations", 'RelationCreate+xml', 'Relation+json');
338
        $request->setContent($content);
339
340
        $response = $this->sendHttpRequest($request);
341
342
        self::assertHttpResponseCodeEquals($response, 201);
343
344
        $response = json_decode($response->getContent(), true);
345
346
        return $response['Relation']['_href'];
347
    }
348
349
    /**
350
     * @depends testCreateRelation
351
     * Covers GET /content/objects/<contentId>/versions/<versionNo>/relations/<relationId>
352
     */
353
    public function testLoadVersionRelation($restContentRelationHref)
354
    {
355
        $response = $this->sendHttpRequest(
356
            $this->createHttpRequest('GET', $restContentRelationHref)
357
        );
358
359
        self::assertHttpResponseCodeEquals($response, 200);
360
361
        // @todo test data
362
    }
363
364
    /**
365
     * Returns the Content key from the decoded JSON of $restContentId's contentInfo.
366
     *
367
     *
368
     * @throws \InvalidArgumentException
369
     *
370
     * @param string $restContentHref /api/ezp/v2/content/objects/<contentId>
371
     *
372
     * @return array
373
     */
374
    private function loadContent($restContentHref)
375
    {
376
        $response = $this->sendHttpRequest(
377
            $this->createHttpRequest('GET', $restContentHref, '', 'ContentInfo+json')
378
        );
379
380
        if ($response->getStatusCode() != 200) {
381
            throw new \InvalidArgumentException("Content with ID $restContentHref could not be loaded");
382
        }
383
384
        $array = json_decode($response->getContent(), true);
385
        if ($array === null) {
386
            self::fail('Error loading content. Response: ' . $response->getContent());
387
        }
388
389
        return $array['Content'];
390
    }
391
392 View Code Duplication
    public function testCreateView()
393
    {
394
        $body = <<< XML
395
<?xml version="1.0" encoding="UTF-8"?>
396
<ViewInput>
397
  <identifier>testCreateView</identifier>
398
  <Query>
399
    <Criteria>
400
      <ContentTypeIdentifierCriterion>folder</ContentTypeIdentifierCriterion>
401
    </Criteria>
402
    <limit>10</limit>
403
    <offset>0</offset>
404
  </Query>
405
</ViewInput>
406
XML;
407
        $request = $this->createHttpRequest('POST', '/api/ezp/v2/content/views', 'ViewInput+xml', 'View+json');
408
        $request->setContent($body);
409
        $response = $this->sendHttpRequest(
410
            $request
411
        );
412
413
        // Returns 301 since 6.0 (deprecated in favour of /views)
414
        self::assertHttpResponseCodeEquals($response, 301);
415
        self::assertHttpResponseHasHeader($response, 'Location');
416
    }
417
418
    /**
419
     * Covers DELETE /content/objects/<contentId>/versions/<versionNo>/translations/<languageCode>.
420
     *
421
     * @depends testCreateDraftFromVersion
422
     *
423
     * @param string $restContentVersionHref
424
     */
425
    public function testDeleteTranslationFromDraft($restContentVersionHref)
426
    {
427
        // create pol-PL Translation
428
        $translationToDelete = 'pol-PL';
429
        $this->createVersionTranslation($restContentVersionHref, $translationToDelete, 'Polish');
430
431
        $response = $this->sendHttpRequest(
432
            $this->createHttpRequest('DELETE', $restContentVersionHref . "/translations/{$translationToDelete}")
433
        );
434
        self::assertHttpResponseCodeEquals($response, 204);
435
436
        // check that the Translation was deleted by reloading Version
437
        $response = $this->sendHttpRequest(
438
            $this->createHttpRequest('GET', $restContentVersionHref, '', 'Version+json')
439
        );
440
441
        $version = json_decode($response->getContent(), true);
442
        self::assertNotContains($translationToDelete, $version['Version']['VersionInfo']['languageCodes']);
443
    }
444
445
    /**
446
     * Test that VersionInfo loaded in VersionList contains working DeleteTranslation resource link.
447
     *
448
     * Covers DELETE /content/objects/<contentId>/versions/<versionNo>/translations/<languageCode>.
449
     * Covers GET /content/objects/<contentId>/versions
450
     *
451
     * @depends testCreateDraftFromVersion
452
     *
453
     * @param string $restContentVersionHref
454
     */
455
    public function testLoadContentVersionsProvidesDeleteTranslationFromDraftResourceLink($restContentVersionHref)
456
    {
457
        $translationToDelete = 'pol-PL';
458
        // create Version Draft containing pol-PL Translation
459
        $this->createVersionTranslation($restContentVersionHref, $translationToDelete, 'Polish');
460
461
        // load Version
462
        $response = $this->sendHttpRequest(
463
            $this->createHttpRequest('GET', $restContentVersionHref, '', 'Version+json')
464
        );
465
        self::assertHttpResponseCodeEquals($response, 200);
466
        $version = json_decode($response->getContent(), true);
467
468
        // load all Versions
469
        self::assertNotEmpty($version['Version']['VersionInfo']['Content']['_href']);
470
        $restLoadContentVersionsHref = $version['Version']['VersionInfo']['Content']['_href'] . '/versions';
471
        $response = $this->sendHttpRequest(
472
            $this->createHttpRequest('GET', $restLoadContentVersionsHref, '', 'VersionList+json')
473
        );
474
        self::assertHttpResponseCodeEquals($response, 200);
475
476
        // load Version list
477
        $versionList = json_decode($response->getContent(), true);
478
        $version = $this->getVersionInfoFromJSONVersionListByStatus(
479
            $versionList['VersionList'],
480
            'DRAFT'
481
        );
482
483
        // validate VersionTranslationInfo structure
484
        self::assertNotEmpty($version['VersionTranslationInfo']['Language']);
485
        foreach ($version['VersionTranslationInfo']['Language'] as $versionTranslationInfo) {
486
            // Other Translation, as the main one, shouldn't be deletable
487
            if ($versionTranslationInfo['languageCode'] !== $translationToDelete) {
488
                // check that endpoint is not provided for non-deletable Translation
489
                self::assertTrue(empty($versionTranslationInfo['DeleteTranslation']['_href']));
490
            } else {
491
                // check that provided endpoint works
492
                self::assertNotEmpty($versionTranslationInfo['DeleteTranslation']['_href']);
493
                $response = $this->sendHttpRequest(
494
                    $this->createHttpRequest(
495
                        'DELETE',
496
                        $versionTranslationInfo['DeleteTranslation']['_href']
497
                    )
498
                );
499
                self::assertHttpResponseCodeEquals($response, 204);
500
            }
501
        }
502
    }
503
504
    /**
505
     * Publish another Version with new Translation.
506
     *
507
     * @param string $restContentVersionHref
508
     *
509
     * @param string $languageCode
510
     * @param string $languageName
511
     *
512
     * @return string
513
     */
514 View Code Duplication
    private function createVersionTranslation($restContentVersionHref, $languageCode, $languageName)
515
    {
516
        $this->ensureLanguageExists($languageCode, $languageName);
517
518
        $xml = <<< XML
519
<VersionUpdate>
520
    <fields>
521
        <field>
522
            <fieldDefinitionIdentifier>name</fieldDefinitionIdentifier>
523
            <languageCode>{$languageCode}</languageCode>
524
            <fieldValue>{$languageName} translated name</fieldValue>
525
        </field>
526
    </fields>
527
</VersionUpdate>
528
XML;
529
530
        $request = $this->createHttpRequest('PATCH', $restContentVersionHref, 'VersionUpdate+xml', 'Version+json');
531
        $request->setContent($xml);
532
        $response = $this->sendHttpRequest(
533
            $request
534
        );
535
536
        self::assertHttpResponseCodeEquals($response, 200);
537
    }
538
539
    /**
540
     * Make REST API calls to check if the given Language exists and create it if it doesn't.
541
     *
542
     * @param string $languageCode
543
     * @param string $languageName
544
     */
545
    private function ensureLanguageExists($languageCode, $languageName)
0 ignored issues
show
Unused Code introduced by
The parameter $languageCode is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $languageName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
546
    {
547
        self::markTestIncomplete('@todo: Implement EZP-21171');
548
    }
549
550
    /**
551
     * Iterate through Version Items returned by REST view for ContentType: VersionList+json
552
     * and return first VersionInfo data matching given status.
553
     *
554
     * @param array $versionList
555
     * @param string $status uppercase string representation of Version status
556
     *
557
     * @return array
558
     */
559
    private function getVersionInfoFromJSONVersionListByStatus(array $versionList, $status)
560
    {
561
        foreach ($versionList['VersionItem'] as $versionItem) {
562
            if ($versionItem['VersionInfo']['status'] === $status) {
563
                return $versionItem['VersionInfo'];
564
            }
565
        }
566
567
        throw new \RuntimeException("Test internal error: Version with status {$status} not found");
568
    }
569
}
570