2222use JsonApiPhp \JsonApi \Test \HasAssertEqualsAsJson ;
2323use PHPUnit \Framework \TestCase ;
2424
25+ /**
26+ * To reduce the number of HTTP requests, servers MAY allow responses that include related resources
27+ * along with the requested primary resources. Such responses are called “compound documents”.
28+ *
29+ * In a compound document, all included resources MUST be represented as an array
30+ * of resource objects in a top-level included member.
31+ *
32+ * Compound documents require “full linkage”, meaning that every included resource
33+ * MUST be identified by at least one resource identifier object in the same document.
34+ * These resource identifier objects could either be primary data or represent resource linkage
35+ * contained within primary or included resources.
36+ *
37+ * The only exception to the full linkage requirement is when relationship fields
38+ * that would otherwise contain linkage data are excluded via sparse fieldsets.
39+ *
40+ * Note: Full linkage ensures that included resources are related to either the primary data
41+ * (which could be resource objects or resource identifier objects) or to each other.
42+ *
43+ * @link http://jsonapi.org/format/#document-compound-documents
44+ */
2545class CompoundDocumentTest extends TestCase
2646{
2747 use HasAssertEqualsAsJson;
@@ -44,45 +64,24 @@ public function testIncludedResourcesRepresentedAsArray()
4464 );
4565 $ doc = Document::fromResource ($ basket );
4666 $ doc ->setIncluded ($ apple , $ orange );
47- $ this ->assertEqualsAsJson (
67+ $ this ->assertEquals (
4868 [
49- ' data ' => [
50- 'type ' => 'basket ' ,
69+ [
70+ 'type ' => 'apples ' ,
5171 'id ' => '1 ' ,
52- 'relationships ' => [
53- 'fruits ' => [
54- 'data ' => [
55- [
56- 'type ' => 'apples ' ,
57- 'id ' => '1 ' ,
58- ],
59- [
60- 'type ' => 'oranges ' ,
61- 'id ' => '1 ' ,
62- ],
63- ]
64- ]
72+ 'attributes ' => [
73+ 'color ' => 'red ' ,
6574 ],
6675 ],
67- 'included ' => [
68- [
69- 'type ' => 'apples ' ,
70- 'id ' => '1 ' ,
71- 'attributes ' => [
72- 'color ' => 'red ' ,
73- ],
74- ],
75- [
76- 'type ' => 'oranges ' ,
77- 'id ' => '1 ' ,
78- 'attributes ' => [
79- 'color ' => 'orange ' ,
80- ],
76+ [
77+ 'type ' => 'oranges ' ,
78+ 'id ' => '1 ' ,
79+ 'attributes ' => [
80+ 'color ' => 'orange ' ,
8181 ],
82- ]
83-
82+ ],
8483 ],
85- $ doc
84+ $ this -> convertToArray ( $ doc)[ ' included ' ]
8685 );
8786 }
8887
@@ -93,19 +92,34 @@ public function testIncludedResourcesRepresentedAsArray()
9392 public function testFullLinkageIsRequired ()
9493 {
9594 $ doc = Document::fromResource (new NullData );
96- $ doc ->setIncluded (
97- new ResourceObject ('apples ' , '1 ' )
98- );
95+ $ doc ->setIncluded (new ResourceObject ('apples ' , '1 ' ));
9996 json_encode ($ doc );
10097 }
10198
10299 public function testFullLinkageIsNotRequiredIfSparse ()
103100 {
104101 $ doc = Document::fromResource (new NullData );
105102 $ doc ->markSparse ();
106- $ doc ->setIncluded (
107- new ResourceObject ('apples ' , '1 ' )
108- );
103+ $ doc ->setIncluded (new ResourceObject ('apples ' , '1 ' ));
104+ $ this ->assertCanBeBuilt ($ doc );
105+ }
106+
107+ public function testIncludedResourceMayBeIdentifiedByPrimaryData ()
108+ {
109+ $ apple = new ResourceObject ('apples ' , '1 ' );
110+ $ apple ->setAttribute ('color ' , 'red ' );
111+ $ doc = Document::fromResource ($ apple ->toId ());
112+ $ doc ->setIncluded ($ apple );
113+ $ this ->assertCanBeBuilt ($ doc );
114+ }
115+
116+ private function convertToArray ($ object ): array
117+ {
118+ return json_decode (json_encode ($ object ), true );
119+ }
120+
121+ private function assertCanBeBuilt ($ doc )
122+ {
109123 $ this ->assertInternalType ('string ' , json_encode ($ doc ));
110124 }
111125}
0 commit comments