Completed
Push — master ( 83fb2b...0f847f )
by
unknown
42:12 queued 20:32
created

providerForCreateAndPublishContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
c 0
b 0
f 0
cc 1
nc 1
nop 0
rs 9.7998
1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
declare(strict_types=1);
8
9
namespace eZ\Publish\API\Repository\Tests\Limitation;
10
11
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
12
use eZ\Publish\API\Repository\Tests\BaseTest;
13
use eZ\Publish\API\Repository\Values\User\Limitation\LanguageLimitation;
14
use eZ\Publish\API\Repository\Values\User\User;
15
16
/**
17
 * Test cases for ContentService APIs calls made by user with LanguageLimitation on chosen policies.
18
 *
19
 * @uses \eZ\Publish\API\Repository\Values\User\Limitation\LanguageLimitation
20
 *
21
 * @group integration
22
 * @group authorization
23
 * @group language-limited-content-mgm
24
 */
25
class LanguageLimitationTest extends BaseTest
26
{
27
    /**
28
     * Create editor who is allowed to modify only specific translations of a Content item.
29
     *
30
     * @param array $allowedTranslationsList list of translations (language codes) which editor can modify.
31
     *
32
     * @return \eZ\Publish\API\Repository\Values\User\User
33
     *
34
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
35
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
36
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
37
     */
38
    private function createEditorUserWithLanguageLimitation(array $allowedTranslationsList): User
39
    {
40
        $limitations = [
41
            // limitation for specific translations
42
            new LanguageLimitation(['limitationValues' => $allowedTranslationsList]),
43
        ];
44
45
        return $this->createUserWithPolicies(
46
            'editor',
47
            [
48
                ['module' => 'content', 'function' => 'read'],
49
                ['module' => 'content', 'function' => 'versionread'],
50
                ['module' => 'content', 'function' => 'view_embed'],
51
                ['module' => 'content', 'function' => 'create', 'limitations' => $limitations],
52
                ['module' => 'content', 'function' => 'edit', 'limitations' => $limitations],
53
                ['module' => 'content', 'function' => 'publish', 'limitations' => $limitations],
54
            ]
55
        );
56
    }
57
58
    /**
59
     * @return array
60
     * @see testCreateAndPublishContent
61
     */
62
    public function providerForCreateAndPublishContent(): array
63
    {
64
        // $names (as admin), $allowedTranslationsList (editor limitations)
65
        return [
66
            [
67
                ['ger-DE' => 'German Folder'],
68
                ['ger-DE'],
69
            ],
70
            [
71
                ['ger-DE' => 'German Folder', 'eng-GB' => 'British Folder'],
72
                ['ger-DE', 'eng-GB'],
73
            ],
74
        ];
75
    }
76
77
    /**
78
     * Test creating and publishing a fresh Content item in a language restricted by LanguageLimitation.
79
     *
80
     * @param array $names
81
     * @param array $allowedTranslationsList
82
     *
83
     * @dataProvider providerForCreateAndPublishContent
84
     *
85
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
86
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
87
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
88
     */
89
    public function testCreateAndPublishContent(array $names, array $allowedTranslationsList): void
90
    {
91
        $repository = $this->getRepository();
92
        $repository->getPermissionResolver()->setCurrentUserReference(
93
            $this->createEditorUserWithLanguageLimitation($allowedTranslationsList)
94
        );
95
96
        $folder = $this->createFolder($names, 2);
97
98
        foreach ($names as $languageCode => $translatedName) {
99
            self::assertEquals(
100
                $translatedName,
101
                $folder->getField('name', $languageCode)->value->text
102
            );
103
        }
104
    }
105
106
    /**
107
     * Data provider for testPublishVersionWithLanguageLimitation.
108
     *
109
     * @return array
110
     * @see testPublishVersionIsNotAllowedIfModifiedOtherTranslations
111
     *
112
     * @see testPublishVersion
113
     */
114
    public function providerForPublishVersionWithLanguageLimitation(): array
115
    {
116
        // $names (as admin), $namesToUpdate (as editor), $allowedTranslationsList (editor limitations)
117
        return [
118
            [
119
                ['eng-US' => 'American Folder'],
120
                ['ger-DE' => 'Updated German Folder'],
121
                ['ger-DE'],
122
            ],
123
            [
124
                ['eng-US' => 'American Folder', 'ger-DE' => 'German Folder'],
125
                ['ger-DE' => 'Updated German Folder'],
126
                ['ger-DE'],
127
            ],
128
            [
129
                [
130
                    'eng-US' => 'American Folder',
131
                    'eng-GB' => 'British Folder',
132
                    'ger-DE' => 'German Folder',
133
                ],
134
                ['ger-DE' => 'Updated German Folder', 'eng-GB' => 'British Folder'],
135
                ['ger-DE', 'eng-GB'],
136
            ],
137
            [
138
                ['eng-US' => 'American Folder', 'ger-DE' => 'German Folder'],
139
                ['ger-DE' => 'Updated German Folder', 'eng-GB' => 'British Folder'],
140
                ['ger-DE', 'eng-GB'],
141
            ],
142
        ];
143
    }
144
145
    /**
146
     * Test publishing Version with translations restricted by LanguageLimitation.
147
     *
148
     * @param array $names
149
     * @param array $namesToUpdate
150
     * @param array $allowedTranslationsList
151
     *
152
     * @dataProvider providerForPublishVersionWithLanguageLimitation
153
     *
154
     * @covers \eZ\Publish\API\Repository\ContentService::createContentDraft
155
     * @covers \eZ\Publish\API\Repository\ContentService::updateContent
156
     * @covers \eZ\Publish\API\Repository\ContentService::publishVersion
157
     *
158
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
159
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
160
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
161
     * @throws \Exception
162
     */
163
    public function testPublishVersion(
164
        array $names,
165
        array $namesToUpdate,
166
        array $allowedTranslationsList
167
    ): void {
168
        $repository = $this->getRepository();
169
        $contentService = $repository->getContentService();
170
171
        $folder = $this->createFolder($names, 2);
172
173
        $repository->getPermissionResolver()->setCurrentUserReference(
174
            $this->createEditorUserWithLanguageLimitation($allowedTranslationsList)
175
        );
176
177
        $folderDraft = $contentService->createContentDraft($folder->contentInfo);
178
        $folderUpdateStruct = $contentService->newContentUpdateStruct();
179
        // set modified translation of Version to the first modified as multiple are not supported yet
180
        $folderUpdateStruct->initialLanguageCode = array_keys($namesToUpdate)[0];
0 ignored issues
show
Documentation Bug introduced by
It seems like array_keys($namesToUpdate)[0] can also be of type integer. However, the property $initialLanguageCode is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
181
        foreach ($namesToUpdate as $languageCode => $translatedName) {
182
            $folderUpdateStruct->setField('name', $translatedName, $languageCode);
183
        }
184
        $folderDraft = $contentService->updateContent(
185
            $folderDraft->getVersionInfo(),
186
            $folderUpdateStruct
187
        );
188
        $contentService->publishVersion($folderDraft->getVersionInfo());
189
190
        $folder = $contentService->loadContent($folder->id);
191
        $updatedNames = array_merge($names, $namesToUpdate);
192
        foreach ($updatedNames as $languageCode => $expectedValue) {
193
            self::assertEquals(
194
                $expectedValue,
195
                $folder->getField('name', $languageCode)->value->text,
196
                "Unexpected Field value for {$languageCode}"
197
            );
198
        }
199
    }
200
201
    /**
202
     * Test that publishing version with changes to translations outside limitation values throws unauthorized exception.
203
     *
204
     * @param array $names
205
     *
206
     * @dataProvider providerForPublishVersionWithLanguageLimitation
207
     *
208
     * @covers \eZ\Publish\API\Repository\ContentService::createContentDraft
209
     * @covers \eZ\Publish\API\Repository\ContentService::updateContent
210
     * @covers \eZ\Publish\API\Repository\ContentService::publishVersion
211
     *
212
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
213
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
214
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
215
     */
216
    public function testPublishVersionIsNotAllowedIfModifiedOtherTranslations(array $names): void
217
    {
218
        $repository = $this->getRepository();
219
        $contentService = $repository->getContentService();
220
221
        $folder = $this->createFolder($names, 2);
222
        $folderDraft = $contentService->createContentDraft($folder->contentInfo);
223
        $folderUpdateStruct = $contentService->newContentUpdateStruct();
224
        $folderUpdateStruct->setField('name', 'Updated American Folder', 'eng-US');
225
        $folderDraft = $contentService->updateContent(
226
            $folderDraft->getVersionInfo(),
227
            $folderUpdateStruct
228
        );
229
230
        // switch context to the user not allowed to publish eng-US
231
        $repository->getPermissionResolver()->setCurrentUserReference(
232
            $this->createEditorUserWithLanguageLimitation(['ger-DE'])
233
        );
234
235
        $this->expectException(UnauthorizedException::class);
236
        $contentService->publishVersion($folderDraft->getVersionInfo());
237
    }
238
}
239