Completed
Push — master ( 9a2e94...dbda34 )
by Vincent
05:01 queued 12s
created

assertIsNotForbiddenResourceFieldName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 9
ccs 6
cts 6
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace VGirol\JsonApiAssert\Asserts\Structure;
6
7
use PHPUnit\Framework\Assert as PHPUnit;
8
use VGirol\JsonApiAssert\Members;
9
use VGirol\JsonApiAssert\Messages;
10
11
/**
12
 * Assertions relating to the resource object
13
 */
14
trait AssertResourceObject
15
{
16
    /**
17
     * Asserts that a json fragment is a valid collection of resource objects.
18
     *
19
     * It will do the following checks :
20
     * 1) asserts that the provided resource collection is either an empty array or an array of objects
21
     * (@see assertIsArrayOfObjects).
22
     * 2) asserts that the collection of resources is valid (@see assertIsValidResourceObject).
23
     *
24
     * @param array|null $json
25
     * @param boolean    $strict If true, unsafe characters are not allowed when checking members name.
26
     *
27
     * @return void
28
     * @throws \PHPUnit\Framework\ExpectationFailedException
29
     */
30 36
    public static function assertIsValidResourceObjectCollection($json, bool $strict): void
31
    {
32 36
        PHPUnit::assertIsArray(
33 36
            $json,
34 36
            Messages::RESOURCE_COLLECTION_NOT_ARRAY
35
        );
36
37 33
        if (empty($json)) {
38 3
            return;
39
        }
40
41 30
        static::assertIsArrayOfObjects($json);
42
43 21
        foreach ($json as $resource) {
44 21
            static::assertIsValidResourceObject($resource, $strict);
45
        }
46 15
    }
47
48
    /**
49
     * Asserts that a json fragment is a valid resource.
50
     *
51
     * It will do the following checks :
52
     * 1) asserts that the resource object has valid top-level structure
53
     * (@see assertResourceObjectHasValidTopLevelStructure).
54
     * 2) asserts that the resource object has valid "type" and "id" members
55
     * (@see assertResourceIdMember and @see assertResourceTypeMember).
56
     * 3) asserts that the resource object has valid fields (@see assertHasValidFields).
57
     *
58
     * Optionaly, if presents, it will checks :
59
     * 4) asserts thats the resource object has valid "attributes" member.
60
     * 5) asserts thats the resource object has valid "relationships" member.
61
     * 6) asserts thats the resource object has valid "links" member.
62
     * 7) asserts thats the resource object has valid "meta" member.
63
     *
64
     * @param array   $json
65
     * @param boolean $strict If true, unsafe characters are not allowed when checking members name.
66
     *
67
     * @return void
68
     * @throws \PHPUnit\Framework\ExpectationFailedException
69
     */
70 81
    public static function assertIsValidResourceObject($json, bool $strict): void
71
    {
72 81
        static::assertResourceObjectHasValidTopLevelStructure($json);
73 69
        static::assertResourceIdMember($json);
74 60
        static::assertResourceTypeMember($json, $strict);
75
76 57
        if (isset($json[Members::ATTRIBUTES])) {
77 57
            static::assertIsValidAttributesObject($json[Members::ATTRIBUTES], $strict);
0 ignored issues
show
Bug introduced by
The method assertIsValidAttributesObject() does not exist on VGirol\JsonApiAssert\Ass...re\AssertResourceObject. Did you maybe mean assertIsValidResourceObject()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

77
            static::/** @scrutinizer ignore-call */ 
78
                    assertIsValidAttributesObject($json[Members::ATTRIBUTES], $strict);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
78
        }
79
80 54
        if (isset($json[Members::RELATIONSHIPS])) {
81 15
            static::assertIsValidRelationshipsObject($json[Members::RELATIONSHIPS], $strict);
0 ignored issues
show
Bug introduced by
The method assertIsValidRelationshipsObject() does not exist on VGirol\JsonApiAssert\Ass...re\AssertResourceObject. Did you maybe mean assertIsValidResourceObject()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

81
            static::/** @scrutinizer ignore-call */ 
82
                    assertIsValidRelationshipsObject($json[Members::RELATIONSHIPS], $strict);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
82
        }
83
84 51
        if (isset($json[Members::LINKS])) {
85 6
            static::assertIsValidResourceLinksObject($json[Members::LINKS], $strict);
86
        }
87
88 48
        if (isset($json[Members::META])) {
89 9
            static::assertIsValidMetaObject($json[Members::META], $strict);
0 ignored issues
show
Bug introduced by
The method assertIsValidMetaObject() does not exist on VGirol\JsonApiAssert\Ass...re\AssertResourceObject. Did you maybe mean assertIsValidResourceObject()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

89
            static::/** @scrutinizer ignore-call */ 
90
                    assertIsValidMetaObject($json[Members::META], $strict);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
90
        }
91
92 42
        static::assertHasValidFields($json);
93 36
    }
94
95
    /**
96
     * Asserts that a resource object has a valid top-level structure.
97
     *
98
     * It will do the following checks :
99
     * 1) asserts that the resource has an "id" member.
100
     * 2) asserts that the resource has a "type" member.
101
     * 3) asserts that the resource contains at least one of the following members :
102
     * "attributes", "relationships", "links", "meta" (@see assertContainsAtLeastOneMember).
103
     * 4) asserts that the resource contains only the following allowed members :
104
     * "id", "type", "meta", "attributes", "links", "relationships" (@see assertContainsOnlyAllowedMembers).
105
     *
106
     * @param array $resource
107
     *
108
     * @return void
109
     * @throws \PHPUnit\Framework\ExpectationFailedException
110
     */
111 99
    public static function assertResourceObjectHasValidTopLevelStructure($resource): void
112
    {
113 99
        PHPUnit::assertIsArray(
114 99
            $resource,
115 99
            Messages::RESOURCE_IS_NOT_ARRAY
116
        );
117
118 93
        PHPUnit::assertArrayHasKey(
119 93
            Members::ID,
120 93
            $resource,
121 93
            Messages::RESOURCE_ID_MEMBER_IS_ABSENT
122
        );
123
124 90
        PHPUnit::assertArrayHasKey(
125 90
            Members::TYPE,
126 90
            $resource,
127 90
            Messages::RESOURCE_TYPE_MEMBER_IS_ABSENT
128
        );
129
130 87
        static::assertContainsAtLeastOneMember(
131
            [
132 87
                Members::ATTRIBUTES,
133 87
                Members::RELATIONSHIPS,
134 87
                Members::LINKS,
135 87
                Members::META
136
            ],
137 29
            $resource
138
        );
139
140 78
        static::assertContainsOnlyAllowedMembers(
141
            [
142 78
                Members::ID,
143 78
                Members::TYPE,
144 78
                Members::META,
145 78
                Members::ATTRIBUTES,
146 78
                Members::LINKS,
147 78
                Members::RELATIONSHIPS
148
            ],
149 26
            $resource
150
        );
151 72
    }
152
153
    /**
154
     * Asserts that a resource id member is valid.
155
     *
156
     * It will do the following checks :
157
     * 1) asserts that the "id" member is not empty.
158
     * 2) asserts that the "id" member is a string.
159
     *
160
     * @param array $resource
161
     *
162
     * @return void
163
     * @throws \PHPUnit\Framework\ExpectationFailedException
164
     */
165 162
    public static function assertResourceIdMember($resource): void
166
    {
167 162
        PHPUnit::assertIsString(
168 162
            $resource[Members::ID],
169 162
            Messages::RESOURCE_ID_MEMBER_IS_NOT_STRING
170
        );
171
172 147
        PHPUnit::assertNotEmpty(
173
            // PHP treats 0 and '0' as empty.
174 147
            str_replace('0', 'zero', $resource[Members::ID]),
175 147
            Messages::RESOURCE_ID_MEMBER_IS_EMPTY
176
        );
177 144
    }
178
179
    /**
180
     * Asserts that a resource type member is valid.
181
     *
182
     * It will do the following checks :
183
     * 1) asserts that the "type" member is not empty.
184
     * 2) asserts that the "type" member is a string.
185
     * 3) asserts that the "type" member has a valid value (@see assertIsValidMemberName).
186
     *
187
     * @param array   $resource
188
     * @param boolean $strict   If true, excludes not safe characters when checking members name
189
     *
190
     * @return void
191
     * @throws \PHPUnit\Framework\ExpectationFailedException
192
     */
193 153
    public static function assertResourceTypeMember($resource, bool $strict): void
194
    {
195 153
        PHPUnit::assertNotEmpty(
196 153
            $resource[Members::TYPE],
197 153
            Messages::RESOURCE_TYPE_MEMBER_IS_EMPTY
198
        );
199
200 150
        PHPUnit::assertIsString(
201 150
            $resource[Members::TYPE],
202 150
            Messages::RESOURCE_TYPE_MEMBER_IS_NOT_STRING
203
        );
204
205 141
        static::assertIsValidMemberName(
206 141
            $resource[Members::TYPE],
207 47
            $strict
208
        );
209 135
    }
210
211
    /**
212
     * Asserts that a json fragment is a valid resource links object.
213
     *
214
     * It will do the following checks :
215
     * 1) asserts that le links object is valid (@see assertIsValidLinksObject) with only "self" member allowed.
216
     *
217
     * @param array   $json
218
     * @param boolean $strict If true, excludes not safe characters when checking members name
219
     *
220
     * @return void
221
     * @throws \PHPUnit\Framework\ExpectationFailedException
222
     */
223 12
    public static function assertIsValidResourceLinksObject($json, bool $strict): void
224
    {
225 12
        static::assertIsValidLinksObject(
0 ignored issues
show
Bug introduced by
The method assertIsValidLinksObject() does not exist on VGirol\JsonApiAssert\Ass...re\AssertResourceObject. Did you maybe mean assertIsValidResourceLinksObject()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

225
        static::/** @scrutinizer ignore-call */ 
226
                assertIsValidLinksObject(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
226 12
            $json,
227
            [
228 12
                Members::LINK_SELF
229
            ],
230 4
            $strict
231
        );
232 6
    }
233
234
    /**
235
     * Asserts that a resource object has valid fields (i.e., resource object’s attributes and its relationships).
236
     *
237
     * It will do the following checks :
238
     * 1) asserts that each attributes member and each relationship name is valid
239
     * (@see assertIsNotForbiddenResourceFieldName)
240
     *
241
     * @param array $resource
242
     *
243
     * @return void
244
     * @throws \PHPUnit\Framework\ExpectationFailedException
245
     */
246 54
    public static function assertHasValidFields($resource): void
247
    {
248 54
        if (isset($resource[Members::ATTRIBUTES])) {
249 54
            foreach (array_keys($resource[Members::ATTRIBUTES]) as $name) {
250 54
                static::assertIsNotForbiddenResourceFieldName($name);
251
            }
252
        }
253
254 48
        if (isset($resource[Members::RELATIONSHIPS])) {
255 21
            foreach (array_keys($resource[Members::RELATIONSHIPS]) as $name) {
256 21
                static::assertIsNotForbiddenResourceFieldName($name);
257
258 18
                if (isset($resource[Members::ATTRIBUTES])) {
259 18
                    PHPUnit::assertArrayNotHasKey(
260 18
                        $name,
261 18
                        $resource[Members::ATTRIBUTES],
262 18
                        Messages::FIELDS_HAVE_SAME_NAME
263
                    );
264
                }
265
            }
266
        }
267 39
    }
268
269
    /**
270
     * Asserts that a resource field name is not a forbidden name (like "type" or "id").
271
     *
272
     * @param string $name
273
     *
274
     * @return void
275
     * @throws \PHPUnit\Framework\ExpectationFailedException
276
     */
277 63
    public static function assertIsNotForbiddenResourceFieldName(string $name): void
278
    {
279 63
        PHPUnit::assertNotContains(
280 63
            $name,
281
            [
282 63
                Members::TYPE,
283 63
                Members::ID
284
            ],
285 63
            Messages::FIELDS_NAME_NOT_ALLOWED
286
        );
287 57
    }
288
}
289