ScopeTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. <?php namespace League\Fractal\Test;
  2. use League\Fractal\Manager;
  3. use League\Fractal\Pagination\Cursor;
  4. use League\Fractal\Resource\Collection;
  5. use League\Fractal\Resource\Item;
  6. use League\Fractal\Scope;
  7. use League\Fractal\Serializer\ArraySerializer;
  8. use League\Fractal\Test\Stub\Transformer\DefaultIncludeBookTransformer;
  9. use Mockery;
  10. class ScopeTest extends \PHPUnit_Framework_TestCase
  11. {
  12. protected $simpleItem = array('foo' => 'bar');
  13. protected $simpleCollection = array(array('foo' => 'bar'));
  14. public function testEmbedChildScope()
  15. {
  16. $manager = new Manager();
  17. $resource = new Item(array('foo' => 'bar'), function () {
  18. });
  19. $scope = new Scope($manager, $resource, 'book');
  20. $this->assertEquals($scope->getScopeIdentifier(), 'book');
  21. $childScope = $scope->embedChildScope('author', $resource);
  22. $this->assertInstanceOf('League\Fractal\Scope', $childScope);
  23. }
  24. public function testGetManager()
  25. {
  26. $resource = new Item(array('foo' => 'bar'), function () {
  27. });
  28. $scope = new Scope(new Manager(), $resource, 'book');
  29. $this->assertInstanceOf('League\Fractal\Manager', $scope->getManager());
  30. }
  31. /**
  32. * @covers League\Fractal\Scope::toArray
  33. */
  34. public function testToArray()
  35. {
  36. $manager = new Manager();
  37. $resource = new Item(array('foo' => 'bar'), function ($data) {
  38. return $data;
  39. });
  40. $scope = new Scope($manager, $resource);
  41. $this->assertEquals(array('data' => array('foo' => 'bar')), $scope->toArray());
  42. }
  43. public function testGetCurrentScope()
  44. {
  45. $manager = new Manager();
  46. $resource = new Item(array('name' => 'Larry Ullman'), function () {
  47. });
  48. $scope = new Scope($manager, $resource, 'book');
  49. $this->assertEquals('book', $scope->getScopeIdentifier());
  50. $childScope = $scope->embedChildScope('author', $resource);
  51. $this->assertEquals('author', $childScope->getScopeIdentifier());
  52. $grandChildScope = $childScope->embedChildScope('profile', $resource);
  53. $this->assertEquals('profile', $grandChildScope->getScopeIdentifier());
  54. }
  55. public function testGetIdentifier()
  56. {
  57. $manager = new Manager();
  58. $resource = new Item(array('name' => 'Larry Ullman'), function () {
  59. });
  60. $scope = new Scope($manager, $resource, 'book');
  61. $this->assertEquals('book', $scope->getIdentifier());
  62. $childScope = $scope->embedChildScope('author', $resource);
  63. $this->assertEquals('book.author', $childScope->getIdentifier());
  64. $grandChildScope = $childScope->embedChildScope('profile', $resource);
  65. $this->assertEquals('book.author.profile', $grandChildScope->getIdentifier());
  66. }
  67. public function testGetParentScopes()
  68. {
  69. $manager = new Manager();
  70. $resource = new Item(array('name' => 'Larry Ullman'), function () {
  71. });
  72. $scope = new Scope($manager, $resource, 'book');
  73. $childScope = $scope->embedChildScope('author', $resource);
  74. $this->assertEquals(array('book'), $childScope->getParentScopes());
  75. $grandChildScope = $childScope->embedChildScope('profile', $resource);
  76. $this->assertEquals(array('book', 'author'), $grandChildScope->getParentScopes());
  77. }
  78. public function testIsRequested()
  79. {
  80. $manager = new Manager();
  81. $manager->parseIncludes(array('foo', 'bar', 'baz.bart'));
  82. $scope = new Scope($manager, Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
  83. $this->assertTrue($scope->isRequested('foo'));
  84. $this->assertTrue($scope->isRequested('bar'));
  85. $this->assertTrue($scope->isRequested('baz'));
  86. $this->assertTrue($scope->isRequested('baz.bart'));
  87. $this->assertFalse($scope->isRequested('nope'));
  88. $childScope = $scope->embedChildScope('baz', Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
  89. $this->assertTrue($childScope->isRequested('bart'));
  90. $this->assertFalse($childScope->isRequested('foo'));
  91. $this->assertFalse($childScope->isRequested('bar'));
  92. $this->assertFalse($childScope->isRequested('baz'));
  93. }
  94. /**
  95. * @expectedException InvalidArgumentException
  96. */
  97. public function testScopeRequiresConcreteImplementation()
  98. {
  99. $manager = new Manager();
  100. $manager->parseIncludes('book');
  101. $resource = Mockery::mock('League\Fractal\Resource\ResourceAbstract', array(
  102. array('bar' => 'baz'),
  103. function() {}
  104. ))->makePartial();
  105. $scope = new Scope($manager, $resource);
  106. $scope->toArray();
  107. }
  108. public function testToArrayWithIncludes()
  109. {
  110. $manager = new Manager();
  111. $manager->parseIncludes('book');
  112. $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
  113. $transformer->shouldReceive('getAvailableIncludes')->twice()->andReturn(array('book'));
  114. $transformer->shouldReceive('transform')->once()->andReturnUsing(function (array $data) {
  115. return $data;
  116. });
  117. $transformer->shouldReceive('processIncludedResources')->once()->andReturn(array('book' => array('yin' => 'yang')));
  118. $resource = new Item(array('bar' => 'baz'), $transformer);
  119. $scope = new Scope($manager, $resource);
  120. $this->assertEquals(array('data' => array('bar' => 'baz', 'book' => array('yin' => 'yang'))), $scope->toArray());
  121. }
  122. public function testToArrayWithSideloadedIncludes()
  123. {
  124. $serializer = Mockery::mock('League\Fractal\Serializer\ArraySerializer')->makePartial();
  125. $serializer->shouldReceive('sideloadIncludes')->andReturn(true);
  126. $serializer->shouldReceive('item')->andReturnUsing(function ($key, $data) {
  127. return array('data' => $data);
  128. });
  129. $serializer->shouldReceive('includedData')->andReturnUsing(function ($key, $data) {
  130. return array('sideloaded' => array_pop($data));
  131. });
  132. $manager = new Manager();
  133. $manager->parseIncludes('book');
  134. $manager->setSerializer($serializer);
  135. $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
  136. $transformer->shouldReceive('getAvailableIncludes')->twice()->andReturn(array('book'));
  137. $transformer->shouldReceive('transform')->once()->andReturnUsing(function (array $data) {
  138. return $data;
  139. });
  140. $transformer->shouldReceive('processIncludedResources')->once()->andReturn(array('book' => array('yin' => 'yang')));
  141. $resource = new Item(array('bar' => 'baz'), $transformer);
  142. $scope = new Scope($manager, $resource);
  143. $expected = array(
  144. 'data' => array('bar' => 'baz'),
  145. 'sideloaded' => array('book' => array('yin' => 'yang')),
  146. );
  147. $this->assertEquals($expected, $scope->toArray());
  148. }
  149. public function testPushParentScope()
  150. {
  151. $manager = new Manager();
  152. $resource = new Item(array('name' => 'Larry Ullman'), function () {
  153. });
  154. $scope = new Scope($manager, $resource);
  155. $this->assertEquals(1, $scope->pushParentScope('book'));
  156. $this->assertEquals(2, $scope->pushParentScope('author'));
  157. $this->assertEquals(3, $scope->pushParentScope('profile'));
  158. $this->assertEquals(array('book', 'author', 'profile'), $scope->getParentScopes());
  159. }
  160. public function testRunAppropriateTransformerWithItem()
  161. {
  162. $manager = new Manager();
  163. $transformer = Mockery::mock('League\Fractal\TransformerAbstract');
  164. $transformer->shouldReceive('transform')->once()->andReturn($this->simpleItem);
  165. $transformer->shouldReceive('getAvailableIncludes')->once()->andReturn(array());
  166. $transformer->shouldReceive('getDefaultIncludes')->once()->andReturn(array());
  167. $resource = new Item($this->simpleItem, $transformer);
  168. $scope = $manager->createData($resource);
  169. $this->assertEquals(array('data' => $this->simpleItem), $scope->toArray());
  170. }
  171. public function testRunAppropriateTransformerWithCollection()
  172. {
  173. $manager = new Manager();
  174. $transformer = Mockery::mock('League\Fractal\TransformerAbstract');
  175. $transformer->shouldReceive('transform')->once()->andReturn(array('foo' => 'bar'));
  176. $transformer->shouldReceive('getAvailableIncludes')->once()->andReturn(array());
  177. $transformer->shouldReceive('getDefaultIncludes')->once()->andReturn(array());
  178. $resource = new Collection(array(array('foo' => 'bar')), $transformer);
  179. $scope = $manager->createData($resource);
  180. $this->assertEquals(array('data' => array(array('foo' => 'bar'))), $scope->toArray());
  181. }
  182. /**
  183. * @covers League\Fractal\Scope::executeResourceTransformers
  184. * @expectedException InvalidArgumentException
  185. * @expectedExceptionMessage Argument $resource should be an instance of League\Fractal\Resource\Item or League\Fractal\Resource\Collection
  186. */
  187. public function testCreateDataWithClassFuckKnows()
  188. {
  189. $manager = new Manager();
  190. $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
  191. $resource = Mockery::mock('League\Fractal\Resource\ResourceAbstract', array($this->simpleItem, $transformer))->makePartial();
  192. $scope = $manager->createData($resource);
  193. $scope->toArray();
  194. }
  195. public function testPaginatorOutput()
  196. {
  197. $manager = new Manager();
  198. $collection = new Collection(array(array('foo' => 'bar', 'baz' => 'ban')), function (array $data) {
  199. return $data;
  200. });
  201. $paginator = Mockery::mock('League\Fractal\Pagination\IlluminatePaginatorAdapter')->makePartial();
  202. $total = 100;
  203. $perPage = $count = 5;
  204. $currentPage = 2;
  205. $lastPage = 20;
  206. $paginator->shouldReceive('getTotal')->once()->andReturn($total);
  207. $paginator->shouldReceive('getCount')->once()->andReturn($count);
  208. $paginator->shouldReceive('getPerPage')->once()->andReturn($perPage);
  209. $paginator->shouldReceive('getCurrentPage')->once()->andReturn($currentPage);
  210. $paginator->shouldReceive('getLastPage')->once()->andReturn($lastPage);
  211. $paginator->shouldReceive('getUrl')->times(2)->andReturnUsing(function ($page) {
  212. return 'http://example.com/foo?page='.$page;
  213. });
  214. $collection->setPaginator($paginator);
  215. $rootScope = $manager->createData($collection);
  216. $expectedOutput = array(
  217. 'meta' => array(
  218. 'pagination' => array(
  219. 'total' => $total,
  220. 'count' => $count,
  221. 'per_page' => $perPage,
  222. 'current_page' => $currentPage,
  223. 'total_pages' => $lastPage,
  224. 'links' => array(
  225. 'previous' => 'http://example.com/foo?page=1',
  226. 'next' => 'http://example.com/foo?page=3',
  227. ),
  228. ),
  229. ),
  230. 'data' => array(
  231. array(
  232. 'foo' => 'bar',
  233. 'baz' => 'ban',
  234. ),
  235. )
  236. );
  237. $this->assertEquals($expectedOutput, $rootScope->toArray());
  238. }
  239. public function testCursorOutput()
  240. {
  241. $manager = new Manager();
  242. $inputData = array(
  243. array(
  244. 'foo' => 'bar',
  245. 'baz' => 'ban',
  246. )
  247. );
  248. $collection = new Collection($inputData, function (array $data) {
  249. return $data;
  250. });
  251. $cursor = new Cursor(0, 'ban', 'ban', 2);
  252. $collection->setCursor($cursor);
  253. $rootScope = $manager->createData($collection);
  254. $expectedOutput = array(
  255. 'meta' => array(
  256. 'cursor' => array(
  257. 'current' => 0,
  258. 'prev' => 'ban',
  259. 'next' => 'ban',
  260. 'count' => 2,
  261. ),
  262. ),
  263. 'data' => $inputData,
  264. );
  265. $this->assertEquals($expectedOutput, $rootScope->toArray());
  266. }
  267. public function testDefaultIncludeSuccess()
  268. {
  269. $manager = new Manager();
  270. $manager->setSerializer(new ArraySerializer());
  271. // Send this stub junk, it has a specific format anyhow
  272. $resource = new Item(array(), new DefaultIncludeBookTransformer());
  273. // Try without metadata
  274. $scope = new Scope($manager, $resource);
  275. $expected = array(
  276. 'a' => 'b',
  277. 'author' => array(
  278. 'c' => 'd',
  279. ),
  280. );
  281. $this->assertEquals($expected, $scope->toArray());
  282. }
  283. public function tearDown()
  284. {
  285. Mockery::close();
  286. }
  287. }