1<?php
2/**
3 * This file is part of the Tmdb PHP API created by Michael Roterman.
4 *
5 * For the full copyright and license information, please view the LICENSE
6 * file that was distributed with this source code.
7 *
8 * @package Tmdb
9 * @author Michael Roterman <michael@wtfz.net>
10 * @copyright (c) 2013, Michael Roterman
11 * @version 0.0.1
12 */
13namespace Tmdb\Tests\Repository;
14
15use Tmdb\HttpClient\Response;
16use Tmdb\Model\Search\SearchQuery\CollectionSearchQuery;
17use Tmdb\Model\Search\SearchQuery\CompanySearchQuery;
18use Tmdb\Model\Search\SearchQuery\KeywordSearchQuery;
19use Tmdb\Model\Search\SearchQuery\ListSearchQuery;
20use Tmdb\Model\Search\SearchQuery\MovieSearchQuery;
21use Tmdb\Model\Search\SearchQuery\PersonSearchQuery;
22use Tmdb\Model\Search\SearchQuery\TvSearchQuery;
23use Tmdb\Repository\SearchRepository;
24
25class SearchRepositoryTest extends TestCase
26{
27    const MOVIE_QUERY      = 'rush hour';
28    const COLLECTION_QUERY = 'the matrix';
29    const TV_QUERY         = 'breaking bad';
30    const PERSON_QUERY     = 'johnny knoxville';
31    const LIST_QUERY       = 'golden';
32    const COMPANY_QUERY    = 'disney';
33    const KEYWORD_QUERY    = 'alien';
34    const MULTI_QUERY      = 'jack';
35
36    /**
37     * @test
38     */
39    public function shouldSearchMovie()
40    {
41        /**
42         * @var SearchRepository $repository
43         */
44        $repository = $this->getRepositoryWithMockedHttpAdapter();
45
46        $this->getAdapter()->expects($this->once())
47            ->method('get')
48            ->with($this->getRequest(
49                'https://api.themoviedb.org/3/search/movie',
50                ['page' => 1, 'query' => self::MOVIE_QUERY]
51            ))
52        ;
53
54        $repository->searchMovie(self::MOVIE_QUERY, new MovieSearchQuery());
55    }
56
57    /**
58     * @test
59     */
60    public function shouldSearchCollection()
61    {
62        /**
63         * @var SearchRepository $repository
64         */
65        $repository = $this->getRepositoryWithMockedHttpAdapter();
66
67        $this->getAdapter()->expects($this->once())
68            ->method('get')
69            ->with($this->getRequest(
70                'https://api.themoviedb.org/3/search/collection',
71                ['page' => 1, 'query' => self::COLLECTION_QUERY]
72            ))
73        ;
74
75        $repository->searchCollection(self::COLLECTION_QUERY, new CollectionSearchQuery());
76    }
77
78    /**
79     * @test
80     */
81    public function shouldSearchTv()
82    {
83        /**
84         * @var SearchRepository $repository
85         */
86        $repository = $this->getRepositoryWithMockedHttpAdapter();
87
88        $this->getAdapter()->expects($this->once())
89            ->method('get')
90            ->with($this->getRequest(
91                'https://api.themoviedb.org/3/search/tv',
92                ['page' => 1, 'query' => self::TV_QUERY]
93            ))
94        ;
95
96        $repository->searchTv(self::TV_QUERY, new TvSearchQuery());
97    }
98
99    /**
100     * @test
101     */
102    public function shouldSearchPerson()
103    {
104        /**
105         * @var SearchRepository $repository
106         */
107        $repository = $this->getRepositoryWithMockedHttpAdapter();
108
109        $this->getAdapter()->expects($this->once())
110            ->method('get')
111            ->with($this->getRequest(
112                'https://api.themoviedb.org/3/search/person',
113                ['page' => 1, 'query' => self::PERSON_QUERY]
114            ))
115        ;
116
117        $repository->searchPerson(self::PERSON_QUERY, new PersonSearchQuery());
118    }
119
120    /**
121     * @test
122     */
123    public function shouldSearchList()
124    {
125        /**
126         * @var SearchRepository $repository
127         */
128        $repository = $this->getRepositoryWithMockedHttpAdapter();
129
130        $this->getAdapter()->expects($this->once())
131            ->method('get')
132            ->with($this->getRequest(
133                'https://api.themoviedb.org/3/search/list',
134                ['page' => 1, 'query' => self::LIST_QUERY]
135            ))
136        ;
137
138        $repository->searchList(self::LIST_QUERY, new ListSearchQuery());
139    }
140
141    /**
142     * @test
143     */
144    public function shouldSearchCompany()
145    {
146        /**
147         * @var SearchRepository $repository
148         */
149        $repository = $this->getRepositoryWithMockedHttpAdapter();
150
151        $this->getAdapter()->expects($this->once())
152            ->method('get')
153            ->with($this->getRequest(
154                'https://api.themoviedb.org/3/search/company',
155                ['page' => 1, 'query' => self::COMPANY_QUERY]
156            ))
157        ;
158
159        $repository->searchCompany(self::COMPANY_QUERY, new CompanySearchQuery());
160    }
161
162    /**
163     * @test
164     */
165    public function shouldSearchKeyword()
166    {
167        /**
168         * @var SearchRepository $repository
169         */
170        $repository = $this->getRepositoryWithMockedHttpAdapter();
171
172        $this->getAdapter()->expects($this->once())
173            ->method('get')
174            ->with($this->getRequest(
175                'https://api.themoviedb.org/3/search/keyword',
176                ['page' => 1, 'query' => self::KEYWORD_QUERY]
177            ))
178        ;
179
180        $repository->searchKeyword(self::KEYWORD_QUERY, new KeywordSearchQuery());
181    }
182
183    /**
184     * @test
185     */
186    public function shouldSearchMulti()
187    {
188        /**
189         * @var SearchRepository $repository
190         */
191        $repository = $this->getRepositoryWithMockedHttpAdapter();
192
193        $this->getAdapter()->expects($this->once())
194            ->method('get')
195            ->with($this->getRequest(
196                'https://api.themoviedb.org/3/search/multi',
197                ['page' => 1, 'query' => self::MULTI_QUERY]
198            ))
199            ->will($this->returnValue(new Response(200, json_encode([
200                'page' => 1,
201                'total_pages' => 1,
202                'total_results' => 3,
203                'results' => json_decode('[{"backdrop_path":null,"id":9766,"original_name":"Jackpot","first_air_date":null,"origin_country":["US","CA"],"poster_path":null,"popularity":5.1137023644823e-40,"name":"Jackpot","vote_average":0,"vote_count":0,"media_type":"tv"},{"backdrop_path":null,"id":9766,"original_name":"Jackpot","first_air_date":null,"origin_country":["US","CA"],"poster_path":null,"popularity":5.1137023644823e-40,"name":"Jackpot","vote_average":0,"vote_count":0,"media_type":"tv"},{"backdrop_path":null,"id":9766,"original_name":"Jackpot","first_air_date":null,"origin_country":["US","CA"],"poster_path":null,"popularity":5.1137023644823e-40,"name":"Jackpot","vote_average":0,"vote_count":0,"media_type":"tv"}]', true)
204            ]))))
205        ;
206
207        $collection = $repository->searchMulti(self::MULTI_QUERY, new KeywordSearchQuery());
208        $this->assertEquals(3, $collection->count());
209    }
210
211    /**
212     * @test
213     */
214    public function shouldReturnResultCollectionWhenResultIsNull()
215    {
216        /**
217         * @var SearchRepository $repository
218         */
219        $repository = $this->getRepositoryWithMockedHttpAdapter();
220
221        $this->getAdapter()->expects($this->once())
222            ->method('get')
223            ->with($this->getRequest(
224                'https://api.themoviedb.org/3/search/multi',
225                ['page' => 1, 'query' => self::MULTI_QUERY]
226            ))
227            ->will($this->returnValue(null))
228        ;
229
230        $collection = $repository->searchMulti(self::MULTI_QUERY, new KeywordSearchQuery());
231        $this->assertInstanceOf('\Tmdb\Model\Collection\ResultCollection', $collection);
232        $this->assertEquals(0, $collection->count());
233    }
234
235    /**
236     * @test
237     * @expectedException Tmdb\Exception\NotImplementedException
238     */
239    public function shouldGetFactory()
240    {
241        /**
242         * @var SearchRepository $repository
243         */
244        $repository = $this->getRepositoryWithMockedHttpClient();
245
246        $repository->getFactory();
247    }
248
249    /**
250     * @test
251     */
252    public function shouldBeAbleToSetFactories()
253    {
254        /**
255         * @var SearchRepository $repository
256         */
257        $repository = $this->getRepositoryWithMockedHttpClient();
258        $class      = new \stdClass();
259
260        $repository->setMovieFactory($class);
261        $repository->setCollectionFactory($class);
262        $repository->setCompanyFactory($class);
263        $repository->setKeywordFactory($class);
264        $repository->setListItemFactory($class);
265        $repository->setPeopleFactory($class);
266        $repository->setTvFactory($class);
267
268        $this->assertInstanceOf('stdClass', $repository->getMovieFactory());
269        $this->assertInstanceOf('stdClass', $repository->getCollectionFactory());
270        $this->assertInstanceOf('stdClass', $repository->getCompanyFactory());
271        $this->assertInstanceOf('stdClass', $repository->getKeywordFactory());
272        $this->assertInstanceOf('stdClass', $repository->getListItemFactory());
273        $this->assertInstanceOf('stdClass', $repository->getPeopleFactory());
274        $this->assertInstanceOf('stdClass', $repository->getTvFactory());
275    }
276
277    protected function getApiClass()
278    {
279        return 'Tmdb\Api\Search';
280    }
281
282    protected function getRepositoryClass()
283    {
284        return 'Tmdb\Repository\SearchRepository';
285    }
286}
287