JsonApiSerializerTest.php 82 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430
  1. <?php namespace League\Fractal\Test\Serializer;
  2. use League\Fractal\Manager;
  3. use League\Fractal\Resource\Collection;
  4. use League\Fractal\Resource\Item;
  5. use League\Fractal\Scope;
  6. use League\Fractal\Serializer\JsonApiSerializer;
  7. use League\Fractal\Test\Stub\Transformer\JsonApiAuthorTransformer;
  8. use League\Fractal\Test\Stub\Transformer\JsonApiBookTransformer;
  9. use League\Fractal\Test\Stub\Transformer\JsonApiEmptyTransformer;
  10. use Mockery;
  11. use PHPUnit\Framework\TestCase;
  12. class JsonApiSerializerTest extends TestCase
  13. {
  14. private $manager;
  15. public function setUp()
  16. {
  17. $this->manager = new Manager();
  18. $this->manager->setSerializer(new JsonApiSerializer());
  19. }
  20. public function testSerializeCollectionWithExtraMeta()
  21. {
  22. $booksData = [
  23. [
  24. 'id' => 1,
  25. 'title' => 'Foo',
  26. 'year' => '1991',
  27. '_author' => [
  28. 'id' => 1,
  29. 'name' => 'Dave',
  30. ],
  31. 'meta' => [
  32. 'foo' => 'bar'
  33. ]
  34. ],
  35. [
  36. 'id' => 2,
  37. 'title' => 'Bar',
  38. 'year' => '1997',
  39. '_author' => [
  40. 'id' => 2,
  41. 'name' => 'Bob',
  42. ],
  43. 'meta' => [
  44. 'bar' => 'baz'
  45. ]
  46. ],
  47. ];
  48. $resource = new Collection($booksData, new JsonApiBookTransformer(), 'books');
  49. $scope = new Scope($this->manager, $resource);
  50. $expected = [
  51. 'data' => [
  52. [
  53. 'type' => 'books',
  54. 'id' => '1',
  55. 'attributes' => [
  56. 'title' => 'Foo',
  57. 'year' => 1991,
  58. ],
  59. 'meta' => [
  60. 'foo' => 'bar'
  61. ]
  62. ],
  63. [
  64. 'type' => 'books',
  65. 'id' => '2',
  66. 'attributes' => [
  67. 'title' => 'Bar',
  68. 'year' => 1997,
  69. ],
  70. 'meta' => [
  71. 'bar' => 'baz'
  72. ]
  73. ],
  74. ],
  75. ];
  76. $this->assertSame($expected, $scope->toArray());
  77. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"meta":{"foo":"bar"}},{"type":"books","id":"2","attributes":{"title":"Bar","year":1997},"meta":{"bar":"baz"}}]}';
  78. $this->assertSame($expectedJson, $scope->toJson());
  79. }
  80. public function testSerializingItemResourceWithHasOneInclude()
  81. {
  82. $this->manager->parseIncludes('author');
  83. $bookData = [
  84. 'id' => 1,
  85. 'title' => 'Foo',
  86. 'year' => '1991',
  87. '_author' => [
  88. 'id' => 1,
  89. 'name' => 'Dave',
  90. ],
  91. ];
  92. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  93. $scope = new Scope($this->manager, $resource);
  94. $expected = [
  95. 'data' => [
  96. 'type' => 'books',
  97. 'id' => '1',
  98. 'attributes' => [
  99. 'title' => 'Foo',
  100. 'year' => 1991,
  101. ],
  102. 'relationships' => [
  103. 'author' => [
  104. 'data' => [
  105. 'type' => 'people',
  106. 'id' => '1',
  107. ],
  108. ],
  109. ],
  110. ],
  111. 'included' => [
  112. [
  113. 'type' => 'people',
  114. 'id' => '1',
  115. 'attributes' => [
  116. 'name' => 'Dave',
  117. ],
  118. ],
  119. ],
  120. ];
  121. $this->assertSame($expected, $scope->toArray());
  122. $expectedJson = '{"data":{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"relationships":{"author":{"data":{"type":"people","id":"1"}}}},"included":[{"type":"people","id":"1","attributes":{"name":"Dave"}}]}';
  123. $this->assertSame($expectedJson, $scope->toJson());
  124. }
  125. public function testSerializingItemResourceWithMetaOnRelationship()
  126. {
  127. $this->manager->parseIncludes('author-with-meta');
  128. $bookData = [
  129. 'id' => 1,
  130. 'title' => 'Foo',
  131. 'year' => '1991',
  132. '_author' => [
  133. 'id' => 1,
  134. 'name' => 'Dave',
  135. ],
  136. ];
  137. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  138. $scope = new Scope($this->manager, $resource);
  139. $expected = [
  140. 'data' => [
  141. 'type' => 'books',
  142. 'id' => '1',
  143. 'attributes' => [
  144. 'title' => 'Foo',
  145. 'year' => 1991,
  146. ],
  147. 'relationships' => [
  148. 'author-with-meta' => [
  149. 'data' => [
  150. 'type' => 'people',
  151. 'id' => '1',
  152. ],
  153. 'meta' => [ 'foo' => 'bar' ],
  154. ],
  155. ],
  156. ],
  157. 'included' => [
  158. [
  159. 'type' => 'people',
  160. 'id' => '1',
  161. 'attributes' => [
  162. 'name' => 'Dave',
  163. ],
  164. ],
  165. ],
  166. ];
  167. $this->assertSame($expected, $scope->toArray());
  168. $expectedJson = '{"data":{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"relationships":{"author-with-meta":{"data":{"type":"people","id":"1"},"meta":{"foo":"bar"}}}},"included":[{"type":"people","id":"1","attributes":{"name":"Dave"}}]}';
  169. $this->assertSame($expectedJson, $scope->toJson());
  170. }
  171. public function testSerializingItemResourceWithHasOneDasherizedInclude()
  172. {
  173. $this->manager->parseIncludes('co-author');
  174. $bookData = [
  175. 'id' => 1,
  176. 'title' => 'Foo',
  177. 'year' => '1991',
  178. '_author' => [
  179. 'id' => 1,
  180. 'name' => 'Dave',
  181. ],
  182. '_co_author' => [
  183. 'id' => 2,
  184. 'name' => 'Jim',
  185. ],
  186. ];
  187. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  188. $scope = new Scope($this->manager, $resource);
  189. $expected = [
  190. 'data' => [
  191. 'type' => 'books',
  192. 'id' => '1',
  193. 'attributes' => [
  194. 'title' => 'Foo',
  195. 'year' => 1991,
  196. ],
  197. 'relationships' => [
  198. 'co-author' => [
  199. 'data' => [
  200. 'type' => 'people',
  201. 'id' => '2',
  202. ],
  203. ],
  204. ],
  205. ],
  206. 'included' => [
  207. [
  208. 'type' => 'people',
  209. 'id' => '2',
  210. 'attributes' => [
  211. 'name' => 'Jim',
  212. ],
  213. ],
  214. ],
  215. ];
  216. $this->assertSame($expected, $scope->toArray());
  217. $expectedJson = '{"data":{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"relationships":{"co-author":{"data":{"type":"people","id":"2"}}}},"included":[{"type":"people","id":"2","attributes":{"name":"Jim"}}]}';
  218. $this->assertSame($expectedJson, $scope->toJson());
  219. }
  220. public function testSerializingItemResourceWithEmptyHasOneInclude()
  221. {
  222. $this->manager->parseIncludes('author');
  223. $bookData = [
  224. 'id' => 1,
  225. 'title' => 'Foo',
  226. 'year' => '1991',
  227. '_author' => null,
  228. ];
  229. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  230. $scope = new Scope($this->manager, $resource);
  231. $expected = [
  232. 'data' => [
  233. 'type' => 'books',
  234. 'id' => '1',
  235. 'attributes' => [
  236. 'title' => 'Foo',
  237. 'year' => 1991,
  238. ],
  239. 'relationships' => [
  240. 'author' => [
  241. 'data' => null,
  242. ],
  243. ],
  244. ],
  245. ];
  246. $this->assertSame($expected, $scope->toArray());
  247. $expectedJson = '{"data":{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"relationships":{"author":{"data":null}}}}';
  248. $this->assertSame($expectedJson, $scope->toJson());
  249. }
  250. public function testSerializingItemResourceWithHasManyInclude()
  251. {
  252. $this->manager->parseIncludes('published');
  253. $authorData = [
  254. 'id' => 1,
  255. 'name' => 'Dave',
  256. '_published' => [
  257. [
  258. 'id' => 1,
  259. 'title' => 'Foo',
  260. 'year' => '1991',
  261. ],
  262. [
  263. 'id' => 2,
  264. 'title' => 'Bar',
  265. 'year' => '2015',
  266. ],
  267. ],
  268. ];
  269. $resource = new Item($authorData, new JsonApiAuthorTransformer(), 'people');
  270. $scope = new Scope($this->manager, $resource);
  271. $expected = [
  272. 'data' => [
  273. 'type' => 'people',
  274. 'id' => '1',
  275. 'attributes' => [
  276. 'name' => 'Dave',
  277. ],
  278. 'relationships' => [
  279. 'published' => [
  280. 'data' => [
  281. [
  282. 'type' => 'books',
  283. 'id' => 1,
  284. ],
  285. [
  286. 'type' => 'books',
  287. 'id' => 2,
  288. ],
  289. ],
  290. ],
  291. ],
  292. ],
  293. 'included' => [
  294. [
  295. 'type' => 'books',
  296. 'id' => '1',
  297. 'attributes' => [
  298. 'title' => 'Foo',
  299. 'year' => 1991,
  300. ],
  301. ],
  302. [
  303. 'type' => 'books',
  304. 'id' => '2',
  305. 'attributes' => [
  306. 'title' => 'Bar',
  307. 'year' => 2015,
  308. ],
  309. ],
  310. ],
  311. ];
  312. $this->assertEquals($expected, $scope->toArray());
  313. $expectedJson = '{"data":{"type":"people","id":"1","attributes":{"name":"Dave"},"relationships":{"published":{"data":[{"type":"books","id":"1"},{"type":"books","id":"2"}]}}},"included":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991}},{"type":"books","id":"2","attributes":{"title":"Bar","year":2015}}]}';
  314. $this->assertSame($expectedJson, $scope->toJson());
  315. }
  316. public function testSerializingItemResourceWithEmptyHasManyInclude()
  317. {
  318. $this->manager->parseIncludes('published');
  319. $authorData = [
  320. 'id' => 1,
  321. 'name' => 'Dave',
  322. '_published' => [],
  323. ];
  324. $resource = new Item($authorData, new JsonApiAuthorTransformer(), 'people');
  325. $scope = new Scope($this->manager, $resource);
  326. $expected = [
  327. 'data' => [
  328. 'type' => 'people',
  329. 'id' => '1',
  330. 'attributes' => [
  331. 'name' => 'Dave',
  332. ],
  333. 'relationships' => [
  334. 'published' => [
  335. 'data' => [],
  336. ],
  337. ],
  338. ],
  339. ];
  340. $this->assertSame($expected, $scope->toArray());
  341. $expectedJson = '{"data":{"type":"people","id":"1","attributes":{"name":"Dave"},"relationships":{"published":{"data":[]}}}}';
  342. $this->assertSame($expectedJson, $scope->toJson());
  343. }
  344. public function testSerializingItemResourceWithoutIncludes()
  345. {
  346. $bookData = [
  347. 'id' => 1,
  348. 'title' => 'Foo',
  349. 'year' => '1991',
  350. '_author' => [
  351. 'id' => 1,
  352. 'name' => 'Dave',
  353. ],
  354. ];
  355. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  356. $scope = new Scope($this->manager, $resource);
  357. $expected = [
  358. 'data' => [
  359. 'type' => 'books',
  360. 'id' => '1',
  361. 'attributes' => [
  362. 'title' => 'Foo',
  363. 'year' => 1991,
  364. ],
  365. ],
  366. ];
  367. $this->assertSame($expected, $scope->toArray());
  368. $expectedJson = '{"data":{"type":"books","id":"1","attributes":{"title":"Foo","year":1991}}}';
  369. $this->assertSame($expectedJson, $scope->toJson());
  370. }
  371. public function testSerializingItemResourceWithMeta()
  372. {
  373. $bookData = [
  374. 'id' => 1,
  375. 'title' => 'Foo',
  376. 'year' => '1991',
  377. '_author' => [
  378. 'id' => 1,
  379. 'name' => 'Dave',
  380. ],
  381. ];
  382. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  383. $resource->setMetaValue('foo', 'bar');
  384. $scope = new Scope($this->manager, $resource);
  385. $expected = [
  386. 'data' => [
  387. 'type' => 'books',
  388. 'id' => '1',
  389. 'attributes' => [
  390. 'title' => 'Foo',
  391. 'year' => 1991,
  392. ],
  393. ],
  394. 'meta' => [
  395. 'foo' => 'bar',
  396. ],
  397. ];
  398. $this->assertSame($expected, $scope->toArray());
  399. $expectedJson = '{"data":{"type":"books","id":"1","attributes":{"title":"Foo","year":1991}},"meta":{"foo":"bar"}}';
  400. $this->assertSame($expectedJson, $scope->toJson());
  401. }
  402. public function testSerializingItemResourceWithMetaInBody()
  403. {
  404. $bookData = [
  405. 'id' => 1,
  406. 'title' => 'Foo',
  407. 'year' => '1991',
  408. '_author' => [
  409. 'id' => 1,
  410. 'name' => 'Dave',
  411. ],
  412. 'meta' => [
  413. 'something' => 'something'
  414. ]
  415. ];
  416. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  417. $resource->setMetaValue('foo', 'bar');
  418. $scope = new Scope($this->manager, $resource);
  419. $expected = [
  420. 'data' => [
  421. 'type' => 'books',
  422. 'id' => '1',
  423. 'attributes' => [
  424. 'title' => 'Foo',
  425. 'year' => 1991,
  426. ],
  427. 'meta' => [
  428. 'something' => 'something'
  429. ]
  430. ],
  431. 'meta' => [
  432. 'foo' => 'bar'
  433. ],
  434. ];
  435. $this->assertSame($expected, $scope->toArray());
  436. $expectedJson = '{"data":{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"meta":{"something":"something"}},"meta":{"foo":"bar"}}';
  437. $this->assertSame($expectedJson, $scope->toJson());
  438. }
  439. public function testSerializingCollectionResourceWithoutIncludes()
  440. {
  441. $booksData = [
  442. [
  443. 'id' => 1,
  444. 'title' => 'Foo',
  445. 'year' => '1991',
  446. '_author' => [
  447. 'id' => 1,
  448. 'name' => 'Dave',
  449. ],
  450. ],
  451. [
  452. 'id' => 2,
  453. 'title' => 'Bar',
  454. 'year' => '1997',
  455. '_author' => [
  456. 'id' => 2,
  457. 'name' => 'Bob',
  458. ],
  459. ],
  460. ];
  461. $resource = new Collection($booksData, new JsonApiBookTransformer(), 'books');
  462. $scope = new Scope($this->manager, $resource);
  463. $expected = [
  464. 'data' => [
  465. [
  466. 'type' => 'books',
  467. 'id' => '1',
  468. 'attributes' => [
  469. 'title' => 'Foo',
  470. 'year' => 1991,
  471. ],
  472. ],
  473. [
  474. 'type' => 'books',
  475. 'id' => '2',
  476. 'attributes' => [
  477. 'title' => 'Bar',
  478. 'year' => 1997,
  479. ],
  480. ],
  481. ],
  482. ];
  483. $this->assertSame($expected, $scope->toArray());
  484. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991}},{"type":"books","id":"2","attributes":{"title":"Bar","year":1997}}]}';
  485. $this->assertSame($expectedJson, $scope->toJson());
  486. }
  487. public function testSerializingCollectionResourceWithHasOneInclude()
  488. {
  489. $this->manager->parseIncludes('author');
  490. $booksData = [
  491. [
  492. 'id' => 1,
  493. 'title' => 'Foo',
  494. 'year' => '1991',
  495. '_author' => [
  496. 'id' => 1,
  497. 'name' => 'Dave',
  498. ],
  499. ],
  500. [
  501. 'id' => 2,
  502. 'title' => 'Bar',
  503. 'year' => '1997',
  504. '_author' => [
  505. 'id' => 2,
  506. 'name' => 'Bob',
  507. ],
  508. ],
  509. ];
  510. $resource = new Collection($booksData, new JsonApiBookTransformer(), 'books');
  511. $scope = new Scope($this->manager, $resource);
  512. $expected = [
  513. 'data' => [
  514. [
  515. 'type' => 'books',
  516. 'id' => '1',
  517. 'attributes' => [
  518. 'title' => 'Foo',
  519. 'year' => 1991,
  520. ],
  521. 'relationships' => [
  522. 'author' => [
  523. 'data' => [
  524. 'type' => 'people',
  525. 'id' => '1',
  526. ],
  527. ],
  528. ],
  529. ],
  530. [
  531. 'type' => 'books',
  532. 'id' => '2',
  533. 'attributes' => [
  534. 'title' => 'Bar',
  535. 'year' => 1997,
  536. ],
  537. 'relationships' => [
  538. 'author' => [
  539. 'data' => [
  540. 'type' => 'people',
  541. 'id' => '2',
  542. ],
  543. ],
  544. ],
  545. ],
  546. ],
  547. 'included' => [
  548. [
  549. 'type' => 'people',
  550. 'id' => '1',
  551. 'attributes' => [
  552. 'name' => 'Dave',
  553. ],
  554. ],
  555. [
  556. 'type' => 'people',
  557. 'id' => '2',
  558. 'attributes' => [
  559. 'name' => 'Bob',
  560. ],
  561. ],
  562. ],
  563. ];
  564. $this->assertSame($expected, $scope->toArray());
  565. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"relationships":{"author":{"data":{"type":"people","id":"1"}}}},{"type":"books","id":"2","attributes":{"title":"Bar","year":1997},"relationships":{"author":{"data":{"type":"people","id":"2"}}}}],"included":[{"type":"people","id":"1","attributes":{"name":"Dave"}},{"type":"people","id":"2","attributes":{"name":"Bob"}}]}';
  566. $this->assertSame($expectedJson, $scope->toJson());
  567. }
  568. public function testSerializingCollectionResourceWithEmptyHasOneInclude()
  569. {
  570. $this->manager->parseIncludes('author');
  571. $booksData = [
  572. [
  573. 'id' => 1,
  574. 'title' => 'Foo',
  575. 'year' => '1991',
  576. '_author' => null,
  577. ],
  578. [
  579. 'id' => 2,
  580. 'title' => 'Bar',
  581. 'year' => '1997',
  582. '_author' => [
  583. 'id' => 2,
  584. 'name' => 'Bob',
  585. ],
  586. ],
  587. ];
  588. $resource = new Collection($booksData, new JsonApiBookTransformer(), 'books');
  589. $scope = new Scope($this->manager, $resource);
  590. $expected = [
  591. 'data' => [
  592. [
  593. 'type' => 'books',
  594. 'id' => '1',
  595. 'attributes' => [
  596. 'title' => 'Foo',
  597. 'year' => 1991,
  598. ],
  599. 'relationships' => [
  600. 'author' => [
  601. 'data' => null,
  602. ],
  603. ],
  604. ],
  605. [
  606. 'type' => 'books',
  607. 'id' => '2',
  608. 'attributes' => [
  609. 'title' => 'Bar',
  610. 'year' => 1997,
  611. ],
  612. 'relationships' => [
  613. 'author' => [
  614. 'data' => [
  615. 'type' => 'people',
  616. 'id' => '2',
  617. ],
  618. ],
  619. ],
  620. ],
  621. ],
  622. 'included' => [
  623. [
  624. 'type' => 'people',
  625. 'id' => '2',
  626. 'attributes' => [
  627. 'name' => 'Bob',
  628. ],
  629. ],
  630. ],
  631. ];
  632. $this->assertSame($expected, $scope->toArray());
  633. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"relationships":{"author":{"data":null}}},{"type":"books","id":"2","attributes":{"title":"Bar","year":1997},"relationships":{"author":{"data":{"type":"people","id":"2"}}}}],"included":[{"type":"people","id":"2","attributes":{"name":"Bob"}}]}';
  634. $this->assertSame($expectedJson, $scope->toJson());
  635. }
  636. public function testSerializingCollectionResourceWithHasManyInclude()
  637. {
  638. $this->manager->parseIncludes('published');
  639. $authorsData = [
  640. [
  641. 'id' => 1,
  642. 'name' => 'Dave',
  643. '_published' => [
  644. [
  645. 'id' => 1,
  646. 'title' => 'Foo',
  647. 'year' => '1991',
  648. ],
  649. [
  650. 'id' => 2,
  651. 'title' => 'Bar',
  652. 'year' => '2015',
  653. ],
  654. ],
  655. ],
  656. [
  657. 'id' => 2,
  658. 'name' => 'Bob',
  659. '_published' => [
  660. [
  661. 'id' => 3,
  662. 'title' => 'Baz',
  663. 'year' => '1995',
  664. ],
  665. [
  666. 'id' => 4,
  667. 'title' => 'Quux',
  668. 'year' => '2000',
  669. ],
  670. ],
  671. ],
  672. ];
  673. $resource = new Collection($authorsData, new JsonApiAuthorTransformer(), 'people');
  674. $scope = new Scope($this->manager, $resource);
  675. $expected = [
  676. 'data' => [
  677. [
  678. 'type' => 'people',
  679. 'id' => '1',
  680. 'attributes' => [
  681. 'name' => 'Dave',
  682. ],
  683. 'relationships' => [
  684. 'published' => [
  685. 'data' => [
  686. [
  687. 'type' => 'books',
  688. 'id' => 1,
  689. ],
  690. [
  691. 'type' => 'books',
  692. 'id' => 2,
  693. ],
  694. ],
  695. ],
  696. ],
  697. ],
  698. [
  699. 'type' => 'people',
  700. 'id' => '2',
  701. 'attributes' => [
  702. 'name' => 'Bob',
  703. ],
  704. 'relationships' => [
  705. 'published' => [
  706. 'data' => [
  707. [
  708. 'type' => 'books',
  709. 'id' => 3,
  710. ],
  711. [
  712. 'type' => 'books',
  713. 'id' => 4,
  714. ],
  715. ],
  716. ],
  717. ],
  718. ],
  719. ],
  720. 'included' => [
  721. [
  722. 'type' => 'books',
  723. 'id' => '1',
  724. 'attributes' => [
  725. 'title' => 'Foo',
  726. 'year' => 1991,
  727. ],
  728. ],
  729. [
  730. 'type' => 'books',
  731. 'id' => '2',
  732. 'attributes' => [
  733. 'title' => 'Bar',
  734. 'year' => 2015,
  735. ],
  736. ],
  737. [
  738. 'type' => 'books',
  739. 'id' => '3',
  740. 'attributes' => [
  741. 'title' => 'Baz',
  742. 'year' => 1995,
  743. ],
  744. ],
  745. [
  746. 'type' => 'books',
  747. 'id' => '4',
  748. 'attributes' => [
  749. 'title' => 'Quux',
  750. 'year' => 2000,
  751. ],
  752. ],
  753. ],
  754. ];
  755. $this->assertEquals($expected, $scope->toArray());
  756. $expectedJson = '{"data":[{"type":"people","id":"1","attributes":{"name":"Dave"},"relationships":{"published":{"data":[{"type":"books","id":"1"},{"type":"books","id":"2"}]}}},{"type":"people","id":"2","attributes":{"name":"Bob"},"relationships":{"published":{"data":[{"type":"books","id":"3"},{"type":"books","id":"4"}]}}}],"included":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991}},{"type":"books","id":"2","attributes":{"title":"Bar","year":2015}},{"type":"books","id":"3","attributes":{"title":"Baz","year":1995}},{"type":"books","id":"4","attributes":{"title":"Quux","year":2000}}]}';
  757. $this->assertSame($expectedJson, $scope->toJson());
  758. }
  759. public function testSerializingCollectionResourceWithEmptyHasManyInclude()
  760. {
  761. $this->manager->parseIncludes('published');
  762. $authorsData = [
  763. [
  764. 'id' => 1,
  765. 'name' => 'Dave',
  766. '_published' => [],
  767. ],
  768. [
  769. 'id' => 2,
  770. 'name' => 'Bob',
  771. '_published' => [
  772. [
  773. 'id' => 3,
  774. 'title' => 'Baz',
  775. 'year' => '1995',
  776. ],
  777. ],
  778. ],
  779. ];
  780. $resource = new Collection($authorsData, new JsonApiAuthorTransformer(), 'people');
  781. $scope = new Scope($this->manager, $resource);
  782. $expected = [
  783. 'data' => [
  784. [
  785. 'type' => 'people',
  786. 'id' => '1',
  787. 'attributes' => [
  788. 'name' => 'Dave',
  789. ],
  790. 'relationships' => [
  791. 'published' => [
  792. 'data' => [],
  793. ],
  794. ],
  795. ],
  796. [
  797. 'type' => 'people',
  798. 'id' => '2',
  799. 'attributes' => [
  800. 'name' => 'Bob',
  801. ],
  802. 'relationships' => [
  803. 'published' => [
  804. 'data' => [
  805. [
  806. 'type' => 'books',
  807. 'id' => 3,
  808. ],
  809. ],
  810. ],
  811. ],
  812. ],
  813. ],
  814. 'included' => [
  815. [
  816. 'type' => 'books',
  817. 'id' => '3',
  818. 'attributes' => [
  819. 'title' => 'Baz',
  820. 'year' => 1995,
  821. ],
  822. ],
  823. ],
  824. ];
  825. $this->assertEquals($expected, $scope->toArray());
  826. $expectedJson = '{"data":[{"type":"people","id":"1","attributes":{"name":"Dave"},"relationships":{"published":{"data":[]}}},{"type":"people","id":"2","attributes":{"name":"Bob"},"relationships":{"published":{"data":[{"type":"books","id":"3"}]}}}],"included":[{"type":"books","id":"3","attributes":{"title":"Baz","year":1995}}]}';
  827. $this->assertSame($expectedJson, $scope->toJson());
  828. }
  829. public function testSerializingCollectionResourceWithMeta()
  830. {
  831. $booksData = [
  832. [
  833. 'id' => 1,
  834. 'title' => 'Foo',
  835. 'year' => '1991',
  836. '_author' => [
  837. 'name' => 'Dave',
  838. ],
  839. ],
  840. [
  841. 'id' => 2,
  842. 'title' => 'Bar',
  843. 'year' => '1997',
  844. '_author' => [
  845. 'name' => 'Bob',
  846. ],
  847. ],
  848. ];
  849. $resource = new Collection($booksData, new JsonApiBookTransformer(), 'books');
  850. $resource->setMetaValue('foo', 'bar');
  851. $scope = new Scope($this->manager, $resource);
  852. $expected = [
  853. 'data' => [
  854. [
  855. 'type' => 'books',
  856. 'id' => '1',
  857. 'attributes' => [
  858. 'title' => 'Foo',
  859. 'year' => 1991,
  860. ],
  861. ],
  862. [
  863. 'type' => 'books',
  864. 'id' => '2',
  865. 'attributes' => [
  866. 'title' => 'Bar',
  867. 'year' => 1997,
  868. ],
  869. ],
  870. ],
  871. 'meta' => [
  872. 'foo' => 'bar',
  873. ],
  874. ];
  875. $this->assertSame($expected, $scope->toArray());
  876. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991}},{"type":"books","id":"2","attributes":{"title":"Bar","year":1997}}],"meta":{"foo":"bar"}}';
  877. $this->assertSame($expectedJson, $scope->toJson());
  878. }
  879. public function testSerializingCollectionResourceWithDuplicatedIncludeData()
  880. {
  881. $this->manager->parseIncludes('author');
  882. $booksData = [
  883. [
  884. 'id' => 1,
  885. 'title' => 'Foo',
  886. 'year' => '1991',
  887. '_author' => [
  888. 'id' => 1,
  889. 'name' => 'Dave',
  890. ],
  891. ],
  892. [
  893. 'id' => 2,
  894. 'title' => 'Bar',
  895. 'year' => '1997',
  896. '_author' => [
  897. 'id' => 1,
  898. 'name' => 'Dave',
  899. ],
  900. ],
  901. ];
  902. $resource = new Collection($booksData, new JsonApiBookTransformer(), 'books');
  903. $scope = new Scope($this->manager, $resource);
  904. $expected = [
  905. 'data' => [
  906. [
  907. 'type' => 'books',
  908. 'id' => '1',
  909. 'attributes' => [
  910. 'title' => 'Foo',
  911. 'year' => 1991,
  912. ],
  913. 'relationships' => [
  914. 'author' => [
  915. 'data' => [
  916. 'type' => 'people',
  917. 'id' => '1',
  918. ],
  919. ],
  920. ],
  921. ],
  922. [
  923. 'type' => 'books',
  924. 'id' => '2',
  925. 'attributes' => [
  926. 'title' => 'Bar',
  927. 'year' => 1997,
  928. ],
  929. 'relationships' => [
  930. 'author' => [
  931. 'data' => [
  932. 'type' => 'people',
  933. 'id' => '1',
  934. ],
  935. ],
  936. ],
  937. ],
  938. ],
  939. 'included' => [
  940. [
  941. 'type' => 'people',
  942. 'id' => '1',
  943. 'attributes' => [
  944. 'name' => 'Dave',
  945. ],
  946. ],
  947. ],
  948. ];
  949. $this->assertSame($expected, $scope->toArray());
  950. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"relationships":{"author":{"data":{"type":"people","id":"1"}}}},{"type":"books","id":"2","attributes":{"title":"Bar","year":1997},"relationships":{"author":{"data":{"type":"people","id":"1"}}}}],"included":[{"type":"people","id":"1","attributes":{"name":"Dave"}}]}';
  951. $this->assertSame($expectedJson, $scope->toJson());
  952. }
  953. public function testSerializingItemResourceWithNestedIncludes()
  954. {
  955. $this->manager->parseIncludes(['author', 'author.published']);
  956. $bookData = [
  957. 'id' => 1,
  958. 'title' => 'Foo',
  959. 'year' => '1991',
  960. '_author' => [
  961. 'id' => 1,
  962. 'name' => 'Dave',
  963. '_published' => [
  964. [
  965. 'id' => 1,
  966. 'title' => 'Foo',
  967. 'year' => '1991',
  968. ],
  969. [
  970. 'id' => 2,
  971. 'title' => 'Bar',
  972. 'year' => '2015',
  973. ],
  974. ],
  975. ],
  976. ];
  977. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  978. $scope = new Scope($this->manager, $resource);
  979. $expected = [
  980. 'data' => [
  981. 'type' => 'books',
  982. 'id' => '1',
  983. 'attributes' => [
  984. 'title' => 'Foo',
  985. 'year' => 1991,
  986. ],
  987. 'relationships' => [
  988. 'author' => [
  989. 'data' => [
  990. 'type' => 'people',
  991. 'id' => '1',
  992. ],
  993. ],
  994. ],
  995. ],
  996. 'included' => [
  997. [
  998. 'type' => 'books',
  999. 'id' => '2',
  1000. 'attributes' => [
  1001. 'title' => 'Bar',
  1002. 'year' => 2015,
  1003. ],
  1004. ],
  1005. [
  1006. 'type' => 'people',
  1007. 'id' => '1',
  1008. 'attributes' => [
  1009. 'name' => 'Dave',
  1010. ],
  1011. 'relationships' => [
  1012. 'published' => [
  1013. 'data' => [
  1014. [
  1015. 'type' => 'books',
  1016. 'id' => '1',
  1017. ],
  1018. [
  1019. 'type' => 'books',
  1020. 'id' => '2',
  1021. ],
  1022. ],
  1023. ],
  1024. ],
  1025. ],
  1026. ],
  1027. ];
  1028. $this->assertSame($expected, $scope->toArray());
  1029. $expectedJson = '{"data":{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"relationships":{"author":{"data":{"type":"people","id":"1"}}}},"included":[{"type":"books","id":"2","attributes":{"title":"Bar","year":2015}},{"type":"people","id":"1","attributes":{"name":"Dave"},"relationships":{"published":{"data":[{"type":"books","id":"1"},{"type":"books","id":"2"}]}}}]}';
  1030. $this->assertSame($expectedJson, $scope->toJson());
  1031. }
  1032. public function testSerializingItemResourceWithSelfLink()
  1033. {
  1034. $baseUrl = 'http://example.com';
  1035. $this->manager->setSerializer(new JsonApiSerializer($baseUrl));
  1036. $bookData = [
  1037. 'id' => 1,
  1038. 'title' => 'Foo',
  1039. 'year' => '1991',
  1040. '_author' => [
  1041. 'id' => 1,
  1042. 'name' => 'Dave',
  1043. ],
  1044. ];
  1045. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  1046. $scope = new Scope($this->manager, $resource);
  1047. $expected = [
  1048. 'data' => [
  1049. 'type' => 'books',
  1050. 'id' => '1',
  1051. 'attributes' => [
  1052. 'title' => 'Foo',
  1053. 'year' => 1991,
  1054. ],
  1055. 'links' => [
  1056. 'self' => 'http://example.com/books/1',
  1057. ],
  1058. ],
  1059. ];
  1060. $this->assertSame($expected, $scope->toArray());
  1061. $expectedJson = '{"data":{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"links":{"self":"http:\/\/example.com\/books\/1"}}}';
  1062. $this->assertSame($expectedJson, $scope->toJson());
  1063. }
  1064. public function testSerializingCollectionResourceWithSelfLink()
  1065. {
  1066. $baseUrl = 'http://example.com';
  1067. $this->manager->setSerializer(new JsonApiSerializer($baseUrl));
  1068. $booksData = [
  1069. [
  1070. 'id' => 1,
  1071. 'title' => 'Foo',
  1072. 'year' => '1991',
  1073. '_author' => [
  1074. 'id' => 1,
  1075. 'name' => 'Dave',
  1076. ],
  1077. ],
  1078. [
  1079. 'id' => 2,
  1080. 'title' => 'Bar',
  1081. 'year' => '1997',
  1082. '_author' => [
  1083. 'id' => 2,
  1084. 'name' => 'Bob',
  1085. ],
  1086. ],
  1087. ];
  1088. $resource = new Collection($booksData, new JsonApiBookTransformer(), 'books');
  1089. $scope = new Scope($this->manager, $resource);
  1090. $expected = [
  1091. 'data' => [
  1092. [
  1093. 'type' => 'books',
  1094. 'id' => '1',
  1095. 'attributes' => [
  1096. 'title' => 'Foo',
  1097. 'year' => 1991,
  1098. ],
  1099. 'links' => [
  1100. 'self' => 'http://example.com/books/1',
  1101. ],
  1102. ],
  1103. [
  1104. 'type' => 'books',
  1105. 'id' => '2',
  1106. 'attributes' => [
  1107. 'title' => 'Bar',
  1108. 'year' => 1997,
  1109. ],
  1110. 'links' => [
  1111. 'self' => 'http://example.com/books/2',
  1112. ],
  1113. ],
  1114. ],
  1115. ];
  1116. $this->assertSame($expected, $scope->toArray());
  1117. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"links":{"self":"http:\/\/example.com\/books\/1"}},{"type":"books","id":"2","attributes":{"title":"Bar","year":1997},"links":{"self":"http:\/\/example.com\/books\/2"}}]}';
  1118. $this->assertSame($expectedJson, $scope->toJson());
  1119. }
  1120. public function testSerializingItemResourceWithLinksForHasOneRelationship()
  1121. {
  1122. $baseUrl = 'http://example.com';
  1123. $this->manager->setSerializer(new JsonApiSerializer($baseUrl));
  1124. $this->manager->parseIncludes('author');
  1125. $bookData = [
  1126. 'id' => 1,
  1127. 'title' => 'Foo',
  1128. 'year' => '1991',
  1129. '_author' => [
  1130. 'id' => 1,
  1131. 'name' => 'Dave',
  1132. ],
  1133. ];
  1134. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  1135. $scope = new Scope($this->manager, $resource);
  1136. $expected = [
  1137. 'data' => [
  1138. 'type' => 'books',
  1139. 'id' => '1',
  1140. 'attributes' => [
  1141. 'title' => 'Foo',
  1142. 'year' => 1991,
  1143. ],
  1144. 'relationships' => [
  1145. 'author' => [
  1146. 'links' => [
  1147. 'self' => 'http://example.com/books/1/relationships/author',
  1148. 'related' => 'http://example.com/books/1/author',
  1149. ],
  1150. 'data' => [
  1151. 'type' => 'people',
  1152. 'id' => '1',
  1153. ],
  1154. ],
  1155. ],
  1156. 'links' => [
  1157. 'self' => 'http://example.com/books/1',
  1158. ],
  1159. ],
  1160. 'included' => [
  1161. [
  1162. 'type' => 'people',
  1163. 'id' => '1',
  1164. 'attributes' => [
  1165. 'name' => 'Dave',
  1166. ],
  1167. 'links' => [
  1168. 'self' => 'http://example.com/people/1',
  1169. ],
  1170. ],
  1171. ],
  1172. ];
  1173. $this->assertEquals($expected, $scope->toArray());
  1174. $expectedJson = '{"data":{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"links":{"self":"http:\/\/example.com\/books\/1"},"relationships":{"author":{"links":{"self":"http:\/\/example.com\/books\/1\/relationships\/author","related":"http:\/\/example.com\/books\/1\/author"},"data":{"type":"people","id":"1"}}}},"included":[{"type":"people","id":"1","attributes":{"name":"Dave"},"links":{"self":"http:\/\/example.com\/people\/1"}}]}';
  1175. $this->assertSame($expectedJson, $scope->toJson());
  1176. }
  1177. public function testSerializingItemResourceWithLinksForHasManyRelationship()
  1178. {
  1179. $baseUrl = 'http://example.com';
  1180. $this->manager->setSerializer(new JsonApiSerializer($baseUrl));
  1181. $this->manager->parseIncludes('published');
  1182. $authorData = [
  1183. 'id' => 1,
  1184. 'name' => 'Dave',
  1185. '_published' => [
  1186. [
  1187. 'id' => 1,
  1188. 'title' => 'Foo',
  1189. 'year' => '1991',
  1190. ],
  1191. [
  1192. 'id' => 2,
  1193. 'title' => 'Bar',
  1194. 'year' => '2015',
  1195. ],
  1196. ],
  1197. ];
  1198. $resource = new Item($authorData, new JsonApiAuthorTransformer(), 'people');
  1199. $scope = new Scope($this->manager, $resource);
  1200. $expected = [
  1201. 'data' => [
  1202. 'type' => 'people',
  1203. 'id' => '1',
  1204. 'attributes' => [
  1205. 'name' => 'Dave',
  1206. ],
  1207. 'relationships' => [
  1208. 'published' => [
  1209. 'links' => [
  1210. 'self' => 'http://example.com/people/1/relationships/published',
  1211. 'related' => 'http://example.com/people/1/published',
  1212. ],
  1213. 'data' => [
  1214. [
  1215. 'type' => 'books',
  1216. 'id' => 1,
  1217. ],
  1218. [
  1219. 'type' => 'books',
  1220. 'id' => 2,
  1221. ],
  1222. ],
  1223. ],
  1224. ],
  1225. 'links' => [
  1226. 'self' => 'http://example.com/people/1',
  1227. ],
  1228. ],
  1229. 'included' => [
  1230. [
  1231. 'type' => 'books',
  1232. 'id' => '1',
  1233. 'attributes' => [
  1234. 'title' => 'Foo',
  1235. 'year' => 1991,
  1236. ],
  1237. 'links' => [
  1238. 'self' => 'http://example.com/books/1',
  1239. ],
  1240. ],
  1241. [
  1242. 'type' => 'books',
  1243. 'id' => '2',
  1244. 'attributes' => [
  1245. 'title' => 'Bar',
  1246. 'year' => 2015,
  1247. ],
  1248. 'links' => [
  1249. 'self' => 'http://example.com/books/2',
  1250. ],
  1251. ],
  1252. ],
  1253. ];
  1254. $this->assertEquals($expected, $scope->toArray());
  1255. $expectedJson = '{"data":{"type":"people","id":"1","attributes":{"name":"Dave"},"links":{"self":"http:\/\/example.com\/people\/1"},"relationships":{"published":{"links":{"self":"http:\/\/example.com\/people\/1\/relationships\/published","related":"http:\/\/example.com\/people\/1\/published"},"data":[{"type":"books","id":"1"},{"type":"books","id":"2"}]}}},"included":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"links":{"self":"http:\/\/example.com\/books\/1"}},{"type":"books","id":"2","attributes":{"title":"Bar","year":2015},"links":{"self":"http:\/\/example.com\/books\/2"}}]}';
  1256. $this->assertSame($expectedJson, $scope->toJson());
  1257. }
  1258. public function testSerializingCollectionResourceWithLinksForHasOneRelationship()
  1259. {
  1260. $baseUrl = 'http://example.com';
  1261. $this->manager->setSerializer(new JsonApiSerializer($baseUrl));
  1262. $this->manager->parseIncludes('author');
  1263. $bookData = [
  1264. [
  1265. 'id' => 1,
  1266. 'title' => 'Foo',
  1267. 'year' => '1991',
  1268. '_author' => [
  1269. 'id' => 1,
  1270. 'name' => 'Dave',
  1271. ],
  1272. ],
  1273. [
  1274. 'id' => 2,
  1275. 'title' => 'Bar',
  1276. 'year' => '1991',
  1277. '_author' => [
  1278. 'id' => 1,
  1279. 'name' => 'Dave',
  1280. ],
  1281. ],
  1282. ];
  1283. $resource = new Collection($bookData, new JsonApiBookTransformer(), 'books');
  1284. $scope = new Scope($this->manager, $resource);
  1285. $expected = [
  1286. 'data' => [
  1287. [
  1288. 'type' => 'books',
  1289. 'id' => '1',
  1290. 'attributes' => [
  1291. 'title' => 'Foo',
  1292. 'year' => 1991,
  1293. ],
  1294. 'relationships' => [
  1295. 'author' => [
  1296. 'links' => [
  1297. 'self' => 'http://example.com/books/1/relationships/author',
  1298. 'related' => 'http://example.com/books/1/author',
  1299. ],
  1300. 'data' => [
  1301. 'type' => 'people',
  1302. 'id' => '1',
  1303. ],
  1304. ],
  1305. ],
  1306. 'links' => [
  1307. 'self' => 'http://example.com/books/1',
  1308. ],
  1309. ],
  1310. [
  1311. 'type' => 'books',
  1312. 'id' => '2',
  1313. 'attributes' => [
  1314. 'title' => 'Bar',
  1315. 'year' => 1991,
  1316. ],
  1317. 'relationships' => [
  1318. 'author' => [
  1319. 'links' => [
  1320. 'self' => 'http://example.com/books/2/relationships/author',
  1321. 'related' => 'http://example.com/books/2/author',
  1322. ],
  1323. 'data' => [
  1324. 'type' => 'people',
  1325. 'id' => '1',
  1326. ],
  1327. ],
  1328. ],
  1329. 'links' => [
  1330. 'self' => 'http://example.com/books/2',
  1331. ],
  1332. ],
  1333. ],
  1334. 'included' => [
  1335. [
  1336. 'type' => 'people',
  1337. 'id' => '1',
  1338. 'attributes' => [
  1339. 'name' => 'Dave',
  1340. ],
  1341. 'links' => [
  1342. 'self' => 'http://example.com/people/1',
  1343. ],
  1344. ],
  1345. ],
  1346. ];
  1347. $this->assertEquals($expected, $scope->toArray());
  1348. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"links":{"self":"http:\/\/example.com\/books\/1"},"relationships":{"author":{"links":{"self":"http:\/\/example.com\/books\/1\/relationships\/author","related":"http:\/\/example.com\/books\/1\/author"},"data":{"type":"people","id":"1"}}}},{"type":"books","id":"2","attributes":{"title":"Bar","year":1991},"links":{"self":"http:\/\/example.com\/books\/2"},"relationships":{"author":{"links":{"self":"http:\/\/example.com\/books\/2\/relationships\/author","related":"http:\/\/example.com\/books\/2\/author"},"data":{"type":"people","id":"1"}}}}],"included":[{"type":"people","id":"1","attributes":{"name":"Dave"},"links":{"self":"http:\/\/example.com\/people\/1"}}]}';
  1349. $this->assertSame($expectedJson, $scope->toJson());
  1350. }
  1351. public function testSerializingCollectionResourceWithLinksForHasManyRelationship()
  1352. {
  1353. $baseUrl = 'http://example.com';
  1354. $this->manager->setSerializer(new JsonApiSerializer($baseUrl));
  1355. $this->manager->parseIncludes('published');
  1356. $authorData = [
  1357. [
  1358. 'id' => 1,
  1359. 'name' => 'Dave',
  1360. '_published' => [
  1361. [
  1362. 'id' => 1,
  1363. 'title' => 'Foo',
  1364. 'year' => '1991',
  1365. ],
  1366. [
  1367. 'id' => 2,
  1368. 'title' => 'Bar',
  1369. 'year' => '2015',
  1370. ],
  1371. ],
  1372. ],
  1373. [
  1374. 'id' => 2,
  1375. 'name' => 'Bill',
  1376. '_published' => [
  1377. [
  1378. 'id' => 1,
  1379. 'title' => 'Foo',
  1380. 'year' => '1991',
  1381. ],
  1382. [
  1383. 'id' => 2,
  1384. 'title' => 'Bar',
  1385. 'year' => '2015',
  1386. ],
  1387. ],
  1388. ],
  1389. ];
  1390. $resource = new Collection($authorData, new JsonApiAuthorTransformer(), 'people');
  1391. $scope = new Scope($this->manager, $resource);
  1392. $expected = [
  1393. 'data' => [
  1394. [
  1395. 'type' => 'people',
  1396. 'id' => '1',
  1397. 'attributes' => [
  1398. 'name' => 'Dave',
  1399. ],
  1400. 'relationships' => [
  1401. 'published' => [
  1402. 'links' => [
  1403. 'self' => 'http://example.com/people/1/relationships/published',
  1404. 'related' => 'http://example.com/people/1/published',
  1405. ],
  1406. 'data' => [
  1407. [
  1408. 'type' => 'books',
  1409. 'id' => 1,
  1410. ],
  1411. [
  1412. 'type' => 'books',
  1413. 'id' => 2,
  1414. ],
  1415. ],
  1416. ],
  1417. ],
  1418. 'links' => [
  1419. 'self' => 'http://example.com/people/1',
  1420. ],
  1421. ],
  1422. [
  1423. 'type' => 'people',
  1424. 'id' => '2',
  1425. 'attributes' => [
  1426. 'name' => 'Bill',
  1427. ],
  1428. 'relationships' => [
  1429. 'published' => [
  1430. 'links' => [
  1431. 'self' => 'http://example.com/people/2/relationships/published',
  1432. 'related' => 'http://example.com/people/2/published',
  1433. ],
  1434. 'data' => [
  1435. [
  1436. 'type' => 'books',
  1437. 'id' => 1,
  1438. ],
  1439. [
  1440. 'type' => 'books',
  1441. 'id' => 2,
  1442. ],
  1443. ],
  1444. ],
  1445. ],
  1446. 'links' => [
  1447. 'self' => 'http://example.com/people/2',
  1448. ],
  1449. ],
  1450. ],
  1451. 'included' => [
  1452. [
  1453. 'type' => 'books',
  1454. 'id' => '1',
  1455. 'attributes' => [
  1456. 'title' => 'Foo',
  1457. 'year' => 1991,
  1458. ],
  1459. 'links' => [
  1460. 'self' => 'http://example.com/books/1',
  1461. ],
  1462. ],
  1463. [
  1464. 'type' => 'books',
  1465. 'id' => '2',
  1466. 'attributes' => [
  1467. 'title' => 'Bar',
  1468. 'year' => 2015,
  1469. ],
  1470. 'links' => [
  1471. 'self' => 'http://example.com/books/2',
  1472. ],
  1473. ],
  1474. ],
  1475. ];
  1476. $this->assertEquals($expected, $scope->toArray());
  1477. $expectedJson = '{"data":[{"type":"people","id":"1","attributes":{"name":"Dave"},"links":{"self":"http:\/\/example.com\/people\/1"},"relationships":{"published":{"links":{"self":"http:\/\/example.com\/people\/1\/relationships\/published","related":"http:\/\/example.com\/people\/1\/published"},"data":[{"type":"books","id":"1"},{"type":"books","id":"2"}]}}},{"type":"people","id":"2","attributes":{"name":"Bill"},"links":{"self":"http:\/\/example.com\/people\/2"},"relationships":{"published":{"links":{"self":"http:\/\/example.com\/people\/2\/relationships\/published","related":"http:\/\/example.com\/people\/2\/published"},"data":[{"type":"books","id":"1"},{"type":"books","id":"2"}]}}}],"included":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"links":{"self":"http:\/\/example.com\/books\/1"}},{"type":"books","id":"2","attributes":{"title":"Bar","year":2015},"links":{"self":"http:\/\/example.com\/books\/2"}}]}';
  1478. $this->assertSame($expectedJson, $scope->toJson());
  1479. }
  1480. /**
  1481. * @expectedException \InvalidArgumentException
  1482. * @expectedExceptionMessage JSON API resource objects MUST have a valid id
  1483. */
  1484. public function testExceptionThrownIfResourceHasNoId()
  1485. {
  1486. $bookData = [
  1487. 'title' => 'Foo',
  1488. 'year' => '1991',
  1489. ];
  1490. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  1491. $scope = new Scope($this->manager, $resource);
  1492. $scope->toArray();
  1493. }
  1494. public function testSerializingItemWithReferenceToRootObject()
  1495. {
  1496. $this->manager->parseIncludes('published.author');
  1497. $authorData = [
  1498. 'id' => 1,
  1499. 'name' => 'Dave',
  1500. '_published' => [
  1501. [
  1502. 'id' => 1,
  1503. 'title' => 'Foo',
  1504. 'year' => 1991,
  1505. '_author' => ['id' => 1]
  1506. ],
  1507. [
  1508. 'id' => 2,
  1509. 'title' => 'Bar',
  1510. 'year' => 2015,
  1511. '_author' => ['id' => 1]
  1512. ],
  1513. ],
  1514. ];
  1515. $resource = new Item($authorData, new JsonApiAuthorTransformer(), 'people');
  1516. $scope = new Scope($this->manager, $resource);
  1517. $expected = [
  1518. 'data' => [
  1519. 'type' => 'people',
  1520. 'id' => '1',
  1521. 'attributes' => [
  1522. 'name' => 'Dave',
  1523. ],
  1524. 'relationships' => [
  1525. 'published' => [
  1526. 'data' => [
  1527. ['type' => 'books', 'id' => '1'],
  1528. ['type' => 'books', 'id' => '2'],
  1529. ],
  1530. ],
  1531. ],
  1532. ],
  1533. 'included' => [
  1534. [
  1535. 'type' => 'books',
  1536. 'id' => '1',
  1537. 'attributes' => [
  1538. 'title' => 'Foo',
  1539. 'year' => 1991,
  1540. ],
  1541. 'relationships' => [
  1542. 'author' => [
  1543. 'data' => ['type' => 'people', 'id' => '1'],
  1544. ],
  1545. ],
  1546. ],
  1547. [
  1548. 'type' => 'books',
  1549. 'id' => '2',
  1550. 'attributes' => [
  1551. 'title' => 'Bar',
  1552. 'year' => 2015,
  1553. ],
  1554. 'relationships' => [
  1555. 'author' => [
  1556. 'data' => ['type' => 'people', 'id' => '1'],
  1557. ],
  1558. ],
  1559. ],
  1560. ],
  1561. ];
  1562. $this->assertSame($expected, $scope->toArray());
  1563. $expectedJson = '{"data":{"type":"people","id":"1","attributes":{"name":"Dave"},"relationships":{"published":{"data":[{"type":"books","id":"1"},{"type":"books","id":"2"}]}}},"included":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"relationships":{"author":{"data":{"type":"people","id":"1"}}}},{"type":"books","id":"2","attributes":{"title":"Bar","year":2015},"relationships":{"author":{"data":{"type":"people","id":"1"}}}}]}';
  1564. $this->assertSame($expectedJson, $scope->toJson());
  1565. }
  1566. public function testSerializingCollectionWithReferenceToRootObjects()
  1567. {
  1568. $this->manager->parseIncludes('author.published');
  1569. $booksData = [
  1570. [
  1571. 'id' => 1,
  1572. 'title' => 'Foo',
  1573. 'year' => 1991,
  1574. '_author' => [
  1575. 'id' => 1,
  1576. 'name' => 'Dave',
  1577. '_published' => [
  1578. [
  1579. 'id' => 1,
  1580. 'title' => 'Foo',
  1581. 'year' => 1991,
  1582. ],
  1583. [
  1584. 'id' => 2,
  1585. 'title' => 'Bar',
  1586. 'year' => 2015,
  1587. ],
  1588. ],
  1589. ],
  1590. ],
  1591. [
  1592. 'id' => 2,
  1593. 'title' => 'Bar',
  1594. 'year' => 2015,
  1595. '_author' => [
  1596. 'id' => 1,
  1597. '_published' => [
  1598. [
  1599. 'id' => 1,
  1600. 'title' => 'Foo',
  1601. 'year' => 1991,
  1602. ],
  1603. [
  1604. 'id' => 2,
  1605. 'title' => 'Bar',
  1606. 'year' => 2015,
  1607. ],
  1608. ],
  1609. ],
  1610. ],
  1611. ];
  1612. $resource = new Collection($booksData, new JsonApiBookTransformer(), 'books');
  1613. $scope = new Scope($this->manager, $resource);
  1614. $expected = [
  1615. 'data' => [
  1616. [
  1617. 'type' => 'books',
  1618. 'id' => '1',
  1619. 'attributes' => [
  1620. 'title' => 'Foo',
  1621. 'year' => 1991,
  1622. ],
  1623. 'relationships' => [
  1624. 'author' => [
  1625. 'data' => [
  1626. 'type' => 'people',
  1627. 'id' => '1',
  1628. ],
  1629. ],
  1630. ],
  1631. ],
  1632. [
  1633. 'type' => 'books',
  1634. 'id' => '2',
  1635. 'attributes' => [
  1636. 'title' => 'Bar',
  1637. 'year' => 2015,
  1638. ],
  1639. 'relationships' => [
  1640. 'author' => [
  1641. 'data' => [
  1642. 'type' => 'people',
  1643. 'id' => '1',
  1644. ],
  1645. ],
  1646. ],
  1647. ],
  1648. ],
  1649. 'included' => [
  1650. [
  1651. 'type' => 'people',
  1652. 'id' => '1',
  1653. 'attributes' => [
  1654. 'name' => 'Dave',
  1655. ],
  1656. 'relationships' => [
  1657. 'published' => [
  1658. 'data' => [
  1659. ['type' => 'books', 'id' => '1'],
  1660. ['type' => 'books', 'id' => '2'],
  1661. ],
  1662. ],
  1663. ],
  1664. ],
  1665. ],
  1666. ];
  1667. $this->assertSame($expected, $scope->toArray());
  1668. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"relationships":{"author":{"data":{"type":"people","id":"1"}}}},{"type":"books","id":"2","attributes":{"title":"Bar","year":2015},"relationships":{"author":{"data":{"type":"people","id":"1"}}}}],"included":[{"type":"people","id":"1","attributes":{"name":"Dave"},"relationships":{"published":{"data":[{"type":"books","id":"1"},{"type":"books","id":"2"}]}}}]}';
  1669. $this->assertSame($expectedJson, $scope->toJson());
  1670. }
  1671. public function testSerializingCollectionResourceWithPaginator()
  1672. {
  1673. $baseUrl = 'http://example.com';
  1674. $this->manager->setSerializer(new JsonApiSerializer($baseUrl));
  1675. $total = 10;
  1676. $count = 2;
  1677. $perPage = 2;
  1678. $currentPage = 2;
  1679. $lastPage = 5;
  1680. $previousUrl = 'http://example.com/books/?page=1';
  1681. $currentUrl = 'http://example.com/books/?page=2';
  1682. $nextUrl = 'http://example.com/books/?page=3';
  1683. $lastUrl = 'http://example.com/books/?page=5';
  1684. $paginator = Mockery::mock('League\Fractal\Pagination\PaginatorInterface');
  1685. $paginator->shouldReceive('getCurrentPage')->andReturn($currentPage);
  1686. $paginator->shouldReceive('getLastPage')->andReturn($lastPage);
  1687. $paginator->shouldReceive('getTotal')->andReturn($total);
  1688. $paginator->shouldReceive('getCount')->andReturn($count);
  1689. $paginator->shouldReceive('getPerPage')->andReturn($perPage);
  1690. $paginator->shouldReceive('getUrl')->with(1)->andReturn($previousUrl);
  1691. $paginator->shouldReceive('getUrl')->with(2)->andReturn($currentUrl);
  1692. $paginator->shouldReceive('getUrl')->with(3)->andReturn($nextUrl);
  1693. $paginator->shouldReceive('getUrl')->with(5)->andReturn($lastUrl);
  1694. $booksData = [
  1695. [
  1696. 'id' => 1,
  1697. 'title' => 'Foo',
  1698. 'year' => '1991',
  1699. '_author' => [
  1700. 'id' => 1,
  1701. 'name' => 'Dave',
  1702. ],
  1703. ],
  1704. [
  1705. 'id' => 2,
  1706. 'title' => 'Bar',
  1707. 'year' => '1997',
  1708. '_author' => [
  1709. 'id' => 2,
  1710. 'name' => 'Bob',
  1711. ],
  1712. ],
  1713. ];
  1714. $resource = new Collection($booksData, new JsonApiBookTransformer(), 'books');
  1715. $resource->setPaginator($paginator);
  1716. $scope = new Scope($this->manager, $resource);
  1717. $expected = [
  1718. 'data' => [
  1719. [
  1720. 'type' => 'books',
  1721. 'id' => '1',
  1722. 'attributes' => [
  1723. 'title' => 'Foo',
  1724. 'year' => 1991,
  1725. ],
  1726. 'links' => [
  1727. 'self' => 'http://example.com/books/1',
  1728. ],
  1729. ],
  1730. [
  1731. 'type' => 'books',
  1732. 'id' => '2',
  1733. 'attributes' => [
  1734. 'title' => 'Bar',
  1735. 'year' => 1997,
  1736. ],
  1737. 'links' => [
  1738. 'self' => 'http://example.com/books/2',
  1739. ],
  1740. ],
  1741. ],
  1742. 'meta' => [
  1743. 'pagination' => [
  1744. 'total' => 10,
  1745. 'count' => 2,
  1746. 'per_page' => 2,
  1747. 'current_page' => 2,
  1748. 'total_pages' => 5
  1749. ]
  1750. ],
  1751. 'links' => [
  1752. 'self' => 'http://example.com/books/?page=2',
  1753. 'first' => 'http://example.com/books/?page=1',
  1754. 'prev' => 'http://example.com/books/?page=1',
  1755. 'next' => 'http://example.com/books/?page=3',
  1756. 'last' => 'http://example.com/books/?page=5'
  1757. ]
  1758. ];
  1759. $this->assertSame($expected, $scope->toArray());
  1760. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"links":{"self":"http:\/\/example.com\/books\/1"}},{"type":"books","id":"2","attributes":{"title":"Bar","year":1997},"links":{"self":"http:\/\/example.com\/books\/2"}}],"meta":{"pagination":{"total":10,"count":2,"per_page":2,"current_page":2,"total_pages":5}},"links":{"self":"http:\/\/example.com\/books\/?page=2","first":"http:\/\/example.com\/books\/?page=1","prev":"http:\/\/example.com\/books\/?page=1","next":"http:\/\/example.com\/books\/?page=3","last":"http:\/\/example.com\/books\/?page=5"}}';
  1761. $this->assertSame($expectedJson, $scope->toJson());
  1762. }
  1763. public function testSerializingCollectionResourceWithPaginatorWithOmittedUnavailablePreviousLink()
  1764. {
  1765. $baseUrl = 'http://example.com';
  1766. $this->manager->setSerializer(new JsonApiSerializer($baseUrl));
  1767. $total = 10;
  1768. $count = 2;
  1769. $perPage = 2;
  1770. $currentPage = 1;
  1771. $lastPage = 5;
  1772. $currentUrl = 'http://example.com/books/?page=1';
  1773. $nextUrl = 'http://example.com/books/?page=2';
  1774. $lastUrl = 'http://example.com/books/?page=5';
  1775. $paginator = Mockery::mock('League\Fractal\Pagination\PaginatorInterface');
  1776. $paginator->shouldReceive('getCurrentPage')->andReturn($currentPage);
  1777. $paginator->shouldReceive('getLastPage')->andReturn($lastPage);
  1778. $paginator->shouldReceive('getTotal')->andReturn($total);
  1779. $paginator->shouldReceive('getCount')->andReturn($count);
  1780. $paginator->shouldReceive('getPerPage')->andReturn($perPage);
  1781. $paginator->shouldReceive('getUrl')->with(1)->andReturn($currentUrl);
  1782. $paginator->shouldReceive('getUrl')->with(2)->andReturn($nextUrl);
  1783. $paginator->shouldReceive('getUrl')->with(5)->andReturn($lastUrl);
  1784. $booksData = [
  1785. [
  1786. 'id' => 1,
  1787. 'title' => 'Foo',
  1788. 'year' => '1991',
  1789. '_author' => [
  1790. 'id' => 1,
  1791. 'name' => 'Dave',
  1792. ],
  1793. ],
  1794. [
  1795. 'id' => 2,
  1796. 'title' => 'Bar',
  1797. 'year' => '1997',
  1798. '_author' => [
  1799. 'id' => 2,
  1800. 'name' => 'Bob',
  1801. ],
  1802. ],
  1803. ];
  1804. $resource = new Collection($booksData, new JsonApiBookTransformer(), 'books');
  1805. $resource->setPaginator($paginator);
  1806. $scope = new Scope($this->manager, $resource);
  1807. $expected = [
  1808. 'data' => [
  1809. [
  1810. 'type' => 'books',
  1811. 'id' => '1',
  1812. 'attributes' => [
  1813. 'title' => 'Foo',
  1814. 'year' => 1991,
  1815. ],
  1816. 'links' => [
  1817. 'self' => 'http://example.com/books/1',
  1818. ],
  1819. ],
  1820. [
  1821. 'type' => 'books',
  1822. 'id' => '2',
  1823. 'attributes' => [
  1824. 'title' => 'Bar',
  1825. 'year' => 1997,
  1826. ],
  1827. 'links' => [
  1828. 'self' => 'http://example.com/books/2',
  1829. ],
  1830. ],
  1831. ],
  1832. 'meta' => [
  1833. 'pagination' => [
  1834. 'total' => 10,
  1835. 'count' => 2,
  1836. 'per_page' => 2,
  1837. 'current_page' => 1,
  1838. 'total_pages' => 5
  1839. ]
  1840. ],
  1841. 'links' => [
  1842. 'self' => 'http://example.com/books/?page=1',
  1843. 'first' => 'http://example.com/books/?page=1',
  1844. 'next' => 'http://example.com/books/?page=2',
  1845. 'last' => 'http://example.com/books/?page=5'
  1846. ]
  1847. ];
  1848. $this->assertSame($expected, $scope->toArray());
  1849. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"links":{"self":"http:\/\/example.com\/books\/1"}},{"type":"books","id":"2","attributes":{"title":"Bar","year":1997},"links":{"self":"http:\/\/example.com\/books\/2"}}],"meta":{"pagination":{"total":10,"count":2,"per_page":2,"current_page":1,"total_pages":5}},"links":{"self":"http:\/\/example.com\/books\/?page=1","first":"http:\/\/example.com\/books\/?page=1","next":"http:\/\/example.com\/books\/?page=2","last":"http:\/\/example.com\/books\/?page=5"}}';
  1850. $this->assertSame($expectedJson, $scope->toJson());
  1851. }
  1852. public function testSerializingCollectionResourceWithPaginatorWithOmittedUnavailableNextLink()
  1853. {
  1854. $baseUrl = 'http://example.com';
  1855. $this->manager->setSerializer(new JsonApiSerializer($baseUrl));
  1856. $total = 10;
  1857. $count = 2;
  1858. $perPage = 2;
  1859. $currentPage = 5;
  1860. $lastPage = 5;
  1861. $firstUrl = 'http://example.com/books/?page=1';
  1862. $previousUrl = 'http://example.com/books/?page=4';
  1863. $lastUrl = 'http://example.com/books/?page=5';
  1864. $paginator = Mockery::mock('League\Fractal\Pagination\PaginatorInterface');
  1865. $paginator->shouldReceive('getCurrentPage')->andReturn($currentPage);
  1866. $paginator->shouldReceive('getLastPage')->andReturn($lastPage);
  1867. $paginator->shouldReceive('getTotal')->andReturn($total);
  1868. $paginator->shouldReceive('getCount')->andReturn($count);
  1869. $paginator->shouldReceive('getPerPage')->andReturn($perPage);
  1870. $paginator->shouldReceive('getUrl')->with(1)->andReturn($firstUrl);
  1871. $paginator->shouldReceive('getUrl')->with(4)->andReturn($previousUrl);
  1872. $paginator->shouldReceive('getUrl')->with(5)->andReturn($lastUrl);
  1873. $booksData = [
  1874. [
  1875. 'id' => 1,
  1876. 'title' => 'Foo',
  1877. 'year' => '1991',
  1878. '_author' => [
  1879. 'id' => 1,
  1880. 'name' => 'Dave',
  1881. ],
  1882. ],
  1883. [
  1884. 'id' => 2,
  1885. 'title' => 'Bar',
  1886. 'year' => '1997',
  1887. '_author' => [
  1888. 'id' => 2,
  1889. 'name' => 'Bob',
  1890. ],
  1891. ],
  1892. ];
  1893. $resource = new Collection($booksData, new JsonApiBookTransformer(), 'books');
  1894. $resource->setPaginator($paginator);
  1895. $scope = new Scope($this->manager, $resource);
  1896. $expected = [
  1897. 'data' => [
  1898. [
  1899. 'type' => 'books',
  1900. 'id' => '1',
  1901. 'attributes' => [
  1902. 'title' => 'Foo',
  1903. 'year' => 1991,
  1904. ],
  1905. 'links' => [
  1906. 'self' => 'http://example.com/books/1',
  1907. ],
  1908. ],
  1909. [
  1910. 'type' => 'books',
  1911. 'id' => '2',
  1912. 'attributes' => [
  1913. 'title' => 'Bar',
  1914. 'year' => 1997,
  1915. ],
  1916. 'links' => [
  1917. 'self' => 'http://example.com/books/2',
  1918. ],
  1919. ],
  1920. ],
  1921. 'meta' => [
  1922. 'pagination' => [
  1923. 'total' => 10,
  1924. 'count' => 2,
  1925. 'per_page' => 2,
  1926. 'current_page' => 5,
  1927. 'total_pages' => 5
  1928. ]
  1929. ],
  1930. 'links' => [
  1931. 'self' => 'http://example.com/books/?page=5',
  1932. 'first' => 'http://example.com/books/?page=1',
  1933. 'prev' => 'http://example.com/books/?page=4',
  1934. 'last' => 'http://example.com/books/?page=5'
  1935. ]
  1936. ];
  1937. $this->assertSame($expected, $scope->toArray());
  1938. $expectedJson = '{"data":[{"type":"books","id":"1","attributes":{"title":"Foo","year":1991},"links":{"self":"http:\/\/example.com\/books\/1"}},{"type":"books","id":"2","attributes":{"title":"Bar","year":1997},"links":{"self":"http:\/\/example.com\/books\/2"}}],"meta":{"pagination":{"total":10,"count":2,"per_page":2,"current_page":5,"total_pages":5}},"links":{"self":"http:\/\/example.com\/books\/?page=5","first":"http:\/\/example.com\/books\/?page=1","prev":"http:\/\/example.com\/books\/?page=4","last":"http:\/\/example.com\/books\/?page=5"}}';
  1939. $this->assertSame($expectedJson, $scope->toJson());
  1940. }
  1941. public function testCustomLinkMerge()
  1942. {
  1943. $manager = new Manager();
  1944. $manager->setSerializer(new JsonApiSerializer('http://test.de'));
  1945. $bookData = [
  1946. 'id' => 1,
  1947. 'title' => 'Foo',
  1948. 'year' => '1991',
  1949. '_author' => [
  1950. 'id' => 1,
  1951. 'name' => 'Dave',
  1952. ],
  1953. 'links' => [
  1954. 'custom_link' => '/custom/link',
  1955. ],
  1956. ];
  1957. $resource = new Item($bookData, new JsonApiBookTransformer('test.de'), 'books');
  1958. $scope = new Scope($manager, $resource);
  1959. $expected = [
  1960. 'data' => [
  1961. 'type' => 'books',
  1962. 'id' => '1',
  1963. 'attributes' => [
  1964. 'title' => 'Foo',
  1965. 'year' => 1991,
  1966. ],
  1967. 'links' => [
  1968. 'self' => 'http://test.de/books/1',
  1969. 'custom_link' => '/custom/link',
  1970. ]
  1971. ],
  1972. ];
  1973. $this->assertSame(json_encode($expected), $scope->toJson());
  1974. }
  1975. public function testCustomLinkMergeNoLink()
  1976. {
  1977. $manager = new Manager();
  1978. $manager->setSerializer(new JsonApiSerializer('http://test.de'));
  1979. $bookData = [
  1980. 'id' => 1,
  1981. 'title' => 'Foo',
  1982. 'year' => '1991',
  1983. '_author' => [
  1984. 'id' => 1,
  1985. 'name' => 'Dave',
  1986. ],
  1987. ];
  1988. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  1989. $scope = new Scope($manager, $resource);
  1990. $expected = [
  1991. 'data' => [
  1992. 'type' => 'books',
  1993. 'id' => '1',
  1994. 'attributes' => [
  1995. 'title' => 'Foo',
  1996. 'year' => 1991,
  1997. ],
  1998. 'links' => [
  1999. 'self' => 'http://test.de/books/1',
  2000. ]
  2001. ],
  2002. ];
  2003. $this->assertSame(json_encode($expected), $scope->toJson());
  2004. }
  2005. public function testCustomSelfLinkMerge()
  2006. {
  2007. $manager = new Manager();
  2008. $manager->setSerializer(new JsonApiSerializer('http://test.de'));
  2009. $bookData = [
  2010. 'id' => 1,
  2011. 'title' => 'Foo',
  2012. 'year' => '1991',
  2013. '_author' => [
  2014. 'id' => 1,
  2015. 'name' => 'Dave',
  2016. ],
  2017. 'links' => [
  2018. 'self' => '/custom/link',
  2019. ],
  2020. ];
  2021. $resource = new Item($bookData, new JsonApiBookTransformer('test.de'), 'books');
  2022. $scope = new Scope($manager, $resource);
  2023. $expected = [
  2024. 'data' => [
  2025. 'type' => 'books',
  2026. 'id' => '1',
  2027. 'attributes' => [
  2028. 'title' => 'Foo',
  2029. 'year' => 1991,
  2030. ],
  2031. 'links' => [
  2032. 'self' => '/custom/link',
  2033. ]
  2034. ],
  2035. ];
  2036. $this->assertSame(json_encode($expected), $scope->toJson());
  2037. }
  2038. public function testEmptyAttributesIsObject()
  2039. {
  2040. $manager = new Manager();
  2041. $manager->setSerializer(new JsonApiSerializer());
  2042. $data = ['id' => 1];
  2043. $resource = new Item($data, new JsonApiEmptyTransformer(), 'resources');
  2044. $scope = new Scope($manager, $resource);
  2045. $expectedJson = '{"data":{"type":"resources","id":"1","attributes":{}}}';
  2046. $this->assertSame($expectedJson, $scope->toJson());
  2047. }
  2048. /**
  2049. * @dataProvider serializingWithFieldsetsProvider
  2050. */
  2051. public function testSerializingWithFieldsets($fieldsetsToParse, $expected)
  2052. {
  2053. $this->manager->parseIncludes(['author', 'author.published']);
  2054. $bookData = [
  2055. 'id' => 1,
  2056. 'title' => 'Foo',
  2057. 'year' => '1991',
  2058. '_author' => [
  2059. 'id' => 1,
  2060. 'name' => 'Dave',
  2061. '_published' => [
  2062. [
  2063. 'id' => 1,
  2064. 'title' => 'Foo',
  2065. 'year' => '1991',
  2066. ],
  2067. [
  2068. 'id' => 2,
  2069. 'title' => 'Bar',
  2070. 'year' => '2015',
  2071. ],
  2072. ],
  2073. ],
  2074. ];
  2075. $resource = new Item($bookData, new JsonApiBookTransformer(), 'books');
  2076. $scope = new Scope($this->manager, $resource);
  2077. $this->manager->parseFieldsets($fieldsetsToParse);
  2078. $this->assertSame($expected, $scope->toArray());
  2079. }
  2080. public function serializingWithFieldsetsProvider()
  2081. {
  2082. return [
  2083. [
  2084. //Single field
  2085. ['books' => 'title'],
  2086. [
  2087. 'data' => [
  2088. 'type' => 'books',
  2089. 'id' => '1',
  2090. 'attributes' => [
  2091. 'title' => 'Foo'
  2092. ]
  2093. ]
  2094. ]
  2095. ],
  2096. [
  2097. //Multiple fields
  2098. ['books' => 'title,year'],
  2099. [
  2100. 'data' => [
  2101. 'type' => 'books',
  2102. 'id' => '1',
  2103. 'attributes' => [
  2104. 'title' => 'Foo',
  2105. 'year' => 1991
  2106. ]
  2107. ]
  2108. ]
  2109. ],
  2110. [
  2111. //Include 1st level relationship
  2112. ['books' => 'title,author', 'people' => 'name'],
  2113. [
  2114. 'data' => [
  2115. 'type' => 'books',
  2116. 'id' => '1',
  2117. 'attributes' => [
  2118. 'title' => 'Foo'
  2119. ],
  2120. 'relationships' => [
  2121. 'author' => [
  2122. 'data' => [
  2123. 'type' => 'people',
  2124. 'id' => '1'
  2125. ]
  2126. ]
  2127. ]
  2128. ],
  2129. 'included' => [
  2130. [
  2131. 'type' => 'people',
  2132. 'id' => '1',
  2133. 'attributes' => [
  2134. 'name' => 'Dave'
  2135. ]
  2136. ]
  2137. ]
  2138. ]
  2139. ],
  2140. [
  2141. //Include 2nd level relationship
  2142. ['books' => 'title,author', 'people' => 'name,published'],
  2143. [
  2144. 'data' => [
  2145. 'type' => 'books',
  2146. 'id' => '1',
  2147. 'attributes' => [
  2148. 'title' => 'Foo'
  2149. ],
  2150. 'relationships' => [
  2151. 'author' => [
  2152. 'data' => [
  2153. 'type' => 'people',
  2154. 'id' => '1'
  2155. ]
  2156. ]
  2157. ]
  2158. ],
  2159. 'included' => [
  2160. [
  2161. 'type' => 'books',
  2162. 'id' => '2',
  2163. 'attributes' => [
  2164. 'title' => 'Bar'
  2165. ]
  2166. ],
  2167. [
  2168. 'type' => 'people',
  2169. 'id' => '1',
  2170. 'attributes' => [
  2171. 'name' => 'Dave'
  2172. ],
  2173. 'relationships' => [
  2174. 'published' => [
  2175. 'data' => [
  2176. [
  2177. 'type' => 'books',
  2178. 'id' => '1'
  2179. ],
  2180. [
  2181. 'type' => 'books',
  2182. 'id' => '2'
  2183. ]
  2184. ]
  2185. ]
  2186. ]
  2187. ]
  2188. ]
  2189. ]
  2190. ]
  2191. ];
  2192. }
  2193. public function tearDown()
  2194. {
  2195. Mockery::close();
  2196. }
  2197. }