Completed
Push — master ( a787fa...dc9af5 )
by Vincent
05:35
created

assertResourceObjectHasValidTopLevelStructure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 39
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 25
c 0
b 0
f 0
dl 0
loc 39
rs 9.52
cc 1
nc 1
nop 1
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
     * @param array|null    $json
20
     * @param boolean       $strict     If true, unsafe characters are not allowed when checking members name.
21
     * @return void
22
     * @throws \PHPUnit\Framework\ExpectationFailedException
23
     */
24
    public static function assertIsValidResourceObjectCollection($json, bool $strict): void
25
    {
26
        PHPUnit::assertIsArray(
27
            $json,
28
            Messages::RESOURCE_COLLECTION_NOT_ARRAY
29
        );
30
31
        if (empty($json)) {
32
            return;
33
        }
34
35
        static::assertIsArrayOfObjects($json);
36
37
        foreach ($json as $resource) {
38
            static::assertIsValidResourceObject($resource, $strict);
39
        }
40
    }
41
42
    /**
43
     * Asserts that a json fragment is a valid resource.
44
     *
45
     * @param array     $json
46
     * @param boolean   $strict         If true, unsafe characters are not allowed when checking members name.
47
     * @return void
48
     * @throws \PHPUnit\Framework\ExpectationFailedException
49
     */
50
    public static function assertIsValidResourceObject($json, bool $strict): void
51
    {
52
        static::assertResourceObjectHasValidTopLevelStructure($json);
53
        static::assertResourceIdMember($json);
54
        static::assertResourceTypeMember($json, $strict);
55
56
        if (isset($json[Members::ATTRIBUTES])) {
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

57
            static::/** @scrutinizer ignore-call */ 
58
                    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...
58
        }
59
60
        if (isset($json[Members::RELATIONSHIPS])) {
61
            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

61
            static::/** @scrutinizer ignore-call */ 
62
                    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...
62
        }
63
64
        if (isset($json[Members::LINKS])) {
65
            static::assertIsValidResourceLinksObject($json[Members::LINKS], $strict);
66
        }
67
68
        if (isset($json[Members::META])) {
69
            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

69
            static::/** @scrutinizer ignore-call */ 
70
                    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...
70
        }
71
72
        static::assertHasValidFields($json);
73
    }
74
75
    /**
76
     * Asserts that a resource object has a valid top-level structure.
77
     *
78
     * @param array $resource
79
     * @return void
80
     * @throws \PHPUnit\Framework\ExpectationFailedException
81
     */
82
    public static function assertResourceObjectHasValidTopLevelStructure($resource): void
83
    {
84
        PHPUnit::assertIsArray(
85
            $resource,
86
            Messages::RESOURCE_IS_NOT_ARRAY
87
        );
88
89
        PHPUnit::assertArrayHasKey(
90
            Members::ID,
91
            $resource,
92
            Messages::RESOURCE_ID_MEMBER_IS_ABSENT
93
        );
94
95
        PHPUnit::assertArrayHasKey(
96
            Members::TYPE,
97
            $resource,
98
            Messages::RESOURCE_TYPE_MEMBER_IS_ABSENT
99
        );
100
101
        static::assertContainsAtLeastOneMember(
102
            [
103
                Members::ATTRIBUTES,
104
                Members::RELATIONSHIPS,
105
                Members::LINKS,
106
                Members::META
107
            ],
108
            $resource
109
        );
110
111
        static::assertContainsOnlyAllowedMembers(
112
            [
113
                Members::ID,
114
                Members::TYPE,
115
                Members::META,
116
                Members::ATTRIBUTES,
117
                Members::LINKS,
118
                Members::RELATIONSHIPS
119
            ],
120
            $resource
121
        );
122
    }
123
124
    /**
125
     * Asserts that a resource id member is valid.
126
     *
127
     * @param array $resource
128
     * @return void
129
     * @throws \PHPUnit\Framework\ExpectationFailedException
130
     */
131
    public static function assertResourceIdMember($resource): void
132
    {
133
        PHPUnit::assertIsString(
134
            $resource[Members::ID],
135
            Messages::RESOURCE_ID_MEMBER_IS_NOT_STRING
136
        );
137
138
        PHPUnit::assertNotEmpty(
139
            // PHP treats 0 and '0' as empty.
140
            str_replace('0', 'zero', $resource[Members::ID]),
141
            Messages::RESOURCE_ID_MEMBER_IS_EMPTY
142
        );
143
    }
144
145
    /**
146
     * Asserts that a resource type member is valid.
147
     *
148
     * @param array     $resource
149
     * @param boolean   $strict         If true, excludes not safe characters when checking members name
150
     * @return void
151
     * @throws \PHPUnit\Framework\ExpectationFailedException
152
     */
153
    public static function assertResourceTypeMember($resource, bool $strict): void
154
    {
155
        PHPUnit::assertNotEmpty(
156
            $resource[Members::TYPE],
157
            Messages::RESOURCE_TYPE_MEMBER_IS_EMPTY
158
        );
159
160
        PHPUnit::assertIsString(
161
            $resource[Members::TYPE],
162
            Messages::RESOURCE_TYPE_MEMBER_IS_NOT_STRING
163
        );
164
165
        static::assertIsValidMemberName(
166
            $resource[Members::TYPE],
167
            $strict
168
        );
169
    }
170
171
    /**
172
     * Asserts that a json fragment is a valid resource links object.
173
     *
174
     * @param array     $json
175
     * @param boolean   $strict         If true, excludes not safe characters when checking members name
176
     * @return void
177
     * @throws \PHPUnit\Framework\ExpectationFailedException
178
     */
179
    public static function assertIsValidResourceLinksObject($json, bool $strict): void
180
    {
181
        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

181
        static::/** @scrutinizer ignore-call */ 
182
                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...
182
            $json,
183
            [
184
                Members::SELF
185
            ],
186
            $strict
187
        );
188
    }
189
190
    /**
191
     * Asserts that a resource object has valid fields (i.e., a resource object’s attributes and its relationships).
192
     *
193
     * @param array $resource
194
     * @return void
195
     * @throws \PHPUnit\Framework\ExpectationFailedException
196
     */
197
    public static function assertHasValidFields($resource): void
198
    {
199
        if (isset($resource[Members::ATTRIBUTES])) {
200
            foreach (array_keys($resource[Members::ATTRIBUTES]) as $name) {
201
                static::assertIsNotForbiddenResourceFieldName($name);
202
            }
203
        }
204
205
        if (isset($resource[Members::RELATIONSHIPS])) {
206
            foreach (array_keys($resource[Members::RELATIONSHIPS]) as $name) {
207
                static::assertIsNotForbiddenResourceFieldName($name);
208
209
                if (isset($resource[Members::ATTRIBUTES])) {
210
                    PHPUnit::assertArrayNotHasKey(
211
                        $name,
212
                        $resource[Members::ATTRIBUTES],
213
                        Messages::FIELDS_HAVE_SAME_NAME
214
                    );
215
                }
216
            }
217
        }
218
    }
219
220
    /**
221
     * Asserts that a resource field name is not a forbidden name (like "type" or "id").
222
     *
223
     * @param string $name
224
     * @return void
225
     * @throws \PHPUnit\Framework\ExpectationFailedException
226
     */
227
    public static function assertIsNotForbiddenResourceFieldName(string $name): void
228
    {
229
        PHPUnit::assertNotContains(
230
            $name,
231
            [
232
                Members::TYPE,
233
                Members::ID
234
            ],
235
            Messages::FIELDS_NAME_NOT_ALLOWED
236
        );
237
    }
238
}
239