PageRenderTime 42ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/inc/RequestTest.php

https://github.com/rdohms/joindin-api
PHP | 682 lines | 299 code | 71 blank | 312 comment | 0 complexity | 7273fa3fc16240c56981d8b9cb7fd555 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-3.0, LGPL-2.1
  1. <?php
  2. namespace JoindinTest\Inc;
  3. require_once __DIR__ . '/../../src/inc/Request.php';
  4. class RequestTest extends \PHPUnit_Framework_TestCase
  5. {
  6. /**
  7. * Make sure we have everything we need - in this case the config
  8. */
  9. public function setUp() {
  10. include __DIR__ . '/../../src/config.php';
  11. $this->config = $config;
  12. }
  13. /**
  14. * Ensures that if a parameter was sent in, calling getParameter for it will
  15. * return the value it was set to.
  16. *
  17. * @return void
  18. *
  19. * @test
  20. * @backupGlobals
  21. */
  22. public function getParameterReturnsValueOfRequestedParameter()
  23. {
  24. $queryString = http_build_query(
  25. array(
  26. 'foo' => 'bar',
  27. 'baz' => 'samoflange',
  28. )
  29. );
  30. $_SERVER['QUERY_STRING'] = $queryString;
  31. $request = new \Request($this->config);
  32. $this->assertEquals('bar', $request->getParameter('foo'));
  33. $this->assertEquals('samoflange', $request->getParameter('baz'));
  34. }
  35. /**
  36. * Ensures that getParameter returns the default value if the parameter requested
  37. * was not set.
  38. *
  39. * @return void
  40. *
  41. * @test
  42. */
  43. public function getParameterReturnsDefaultIfParameterNotSet()
  44. {
  45. $uniq = uniqid();
  46. $request = new \Request($this->config);
  47. $result = $request->getParameter('samoflange', $uniq);
  48. $this->assertSame($uniq, $result);
  49. }
  50. /**
  51. * Ensures that methods are properly loaded from the
  52. * $_SERVER['REQUEST_METHOD'] variable
  53. *
  54. * @param string $method Method to try
  55. *
  56. * @return void
  57. *
  58. * @test
  59. * @dataProvider methodProvider
  60. * @backupGlobals
  61. */
  62. public function requestMethodIsProperlyLoaded($method)
  63. {
  64. $_SERVER['REQUEST_METHOD'] = $method;
  65. $request = new \Request($this->config);
  66. $this->assertEquals($method, $request->getVerb());
  67. }
  68. /**
  69. * Ensures that a verb can be set on the request with setVerb
  70. *
  71. * @param string $verb Verb to set
  72. *
  73. * @return void
  74. *
  75. * @test
  76. * @dataProvider methodProvider
  77. */
  78. public function setVerbAllowsForSettingRequestVerb($verb)
  79. {
  80. $request = new \Request($this->config);
  81. $request->setVerb($verb);
  82. $this->assertEquals($verb, $request->getVerb());
  83. }
  84. /**
  85. * Ensure the setVerb method is fluent
  86. *
  87. * @return void
  88. *
  89. * @test
  90. */
  91. public function setVerbIsFluent()
  92. {
  93. $request = new \Request($this->config);
  94. $this->assertSame($request, $request->setVerb(uniqid()));
  95. }
  96. /**
  97. * Provides a list of valid HTTP verbs to test with
  98. *
  99. * @return array
  100. */
  101. public function methodProvider()
  102. {
  103. return array(
  104. array('GET'),
  105. array('POST'),
  106. array('PUT'),
  107. array('DELETE'),
  108. array('TRACE'),
  109. array('HEAD'),
  110. array('OPTIONS')
  111. );
  112. }
  113. /**
  114. * Ensures that the default value is returned if the requested index is
  115. * not found on getUrlElement
  116. *
  117. * @return void
  118. *
  119. * @test
  120. */
  121. public function getUrlElementReturnsDefaultIfIndexIsNotFound()
  122. {
  123. $request = new \Request($this->config);
  124. $default = uniqid();
  125. $result = $request->getUrlElement(22, $default);
  126. $this->assertEquals($default, $result);
  127. }
  128. /**
  129. * Ensures that url elements can be properly fetched with a call to
  130. * getUrlElement
  131. *
  132. * @return void
  133. *
  134. * @test
  135. * @backupGlobals
  136. */
  137. public function getUrlElementReturnsRequestedElementFromPath()
  138. {
  139. $_SERVER['PATH_INFO'] = 'foo/bar/baz';
  140. $request = new \Request($this->config);
  141. $this->assertEquals('foo', $request->getUrlElement(0));
  142. $this->assertEquals('bar', $request->getUrlElement(1));
  143. $this->assertEquals('baz', $request->getUrlElement(2));
  144. }
  145. /**
  146. * Ensures the accept headers are properly parsed
  147. *
  148. * @return void
  149. *
  150. * @test
  151. * @backupGlobals
  152. */
  153. public function acceptsHeadersAreParsedCorrectly()
  154. {
  155. $_SERVER['HTTP_ACCEPT'] =
  156. 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
  157. $request = new \Request($this->config);
  158. $this->assertFalse($request->accepts('image/png'));
  159. $this->assertTrue($request->accepts('text/html'));
  160. $this->assertTrue($request->accepts('application/xhtml+xml'));
  161. $this->assertTrue($request->accepts('application/xml'));
  162. $this->assertTrue($request->accepts('*/*'));
  163. }
  164. /**
  165. * Ensures that if we're accepting something that the accept headers
  166. * say, then we get back that format
  167. *
  168. * @return void
  169. *
  170. * @test
  171. * @backupGlobals
  172. */
  173. public function preferredContentTypeOfReturnsADesiredFormatIfItIsAccepted()
  174. {
  175. $_SERVER['HTTP_ACCEPT'] =
  176. 'text/text,application/xhtml+xml,application/json;q=0.9,*/*;q=0.8';
  177. $request = new \Request($this->config);
  178. $result = $request->preferredContentTypeOutOf(
  179. array('text/html', 'application/json')
  180. );
  181. $this->assertEquals('application/json', $result);
  182. }
  183. /**
  184. * Ensures that if the browser doesn't send an accept header we can deal with
  185. * we return json
  186. *
  187. * @return void
  188. *
  189. * @test
  190. * @backupGlobals
  191. */
  192. public function ifPreferredFormatIsNotAcceptedReturnJson()
  193. {
  194. $_SERVER['HTTP_ACCEPT'] =
  195. 'text/text,application/xhtml+xml,application/json;q=0.9,*/*;q=0.8';
  196. $request = new \Request($this->config);
  197. $result = $request->preferredContentTypeOutOf(
  198. array('text/html'),
  199. array('application/xml')
  200. );
  201. $this->assertEquals('json', $result);
  202. }
  203. /**
  204. * Ensures host is set correctly from headers
  205. *
  206. * @return void
  207. *
  208. * @test
  209. * @backupGlobals
  210. */
  211. public function hostIsSetCorrectlyFromTheHeaders()
  212. {
  213. $_SERVER['HTTP_HOST'] = 'joind.in';
  214. $request = new \Request($this->config);
  215. $this->assertEquals('joind.in', $request->host);
  216. $this->assertEquals('joind.in', $request->getHost());
  217. }
  218. /**
  219. * Ensures that the setHost method is fluent
  220. *
  221. * @return void
  222. *
  223. * @test
  224. */
  225. public function setHostIsFluent()
  226. {
  227. $request = new \Request($this->config);
  228. $this->assertSame($request, $request->setHost(uniqid()));
  229. }
  230. /**
  231. * Ensures that setHost can be used to set a host
  232. *
  233. * @return void
  234. *
  235. * @test
  236. */
  237. public function hostCanBeSetWithSetHost()
  238. {
  239. $host = uniqid() . '.com';
  240. $request = new \Request($this->config);
  241. $request->setHost($host);
  242. $this->assertEquals($host, $request->getHost());
  243. }
  244. /**
  245. * Ensures that if a json body is provided on a POST or PUT request, it
  246. * gets parsed as parameters
  247. *
  248. * @param string $method Method to use
  249. *
  250. * @return void
  251. *
  252. * @test
  253. * @dataProvider postPutProvider
  254. * @backupGlobals
  255. */
  256. public function jsonBodyIsParsedAsParameters($method)
  257. {
  258. $body = json_encode(
  259. array(
  260. 'a' => 'b',
  261. 'array' => array('joind' => 'in')
  262. )
  263. );
  264. $inside = new \stdClass();
  265. $inside->joind = 'in';
  266. $_SERVER['REQUEST_METHOD'] = $method;
  267. $_SERVER['CONTENT_TYPE'] = 'application/json';
  268. /* @var $request \Request */
  269. $request = $this->getMock('\Request', array('getRawBody'), array(false));
  270. $request->expects($this->once())
  271. ->method('getRawBody')
  272. ->will($this->returnValue($body));
  273. $request->setVerb($method);
  274. $request->parseParameters();
  275. $this->assertEquals('b', $request->getParameter('a'));
  276. $this->assertEquals($inside, $request->getParameter('array'));
  277. }
  278. /**
  279. * Provider for methods
  280. *
  281. * @return array
  282. */
  283. public function postPutProvider()
  284. {
  285. return array(
  286. array('POST'),
  287. array('PUT')
  288. );
  289. }
  290. /**
  291. * Ensures that the scheme is set to http unless https is on
  292. *
  293. * @return void
  294. *
  295. * @test
  296. */
  297. public function schemeIsHttpByDefault()
  298. {
  299. $request = new \Request($this->config);
  300. $this->assertEquals('http://', $request->scheme);
  301. $this->assertEquals('http://', $request->getScheme());
  302. }
  303. /**
  304. * Ensures that the scheme is set to https:// if the HTTPS value is
  305. * set to 'on'
  306. *
  307. * @return void
  308. *
  309. * @test
  310. * @backupGlobals
  311. */
  312. public function schemeIsHttpsIfHttpsValueIsOn()
  313. {
  314. $_SERVER['HTTPS'] = 'on';
  315. $request = new \Request($this->config);
  316. $this->assertEquals('https://', $request->scheme);
  317. $this->assertEquals('https://', $request->getScheme());
  318. }
  319. /**
  320. * Ensures setScheme provides a fluent interface
  321. *
  322. * @return void
  323. *
  324. * @test
  325. */
  326. public function setSchemeIsFluent()
  327. {
  328. $request = new \Request($this->config);
  329. $this->assertSame($request, $request->setScheme('http://'));
  330. }
  331. /**
  332. * Ensures that the scheme can be set by the set scheme method
  333. *
  334. * @param string $scheme Scheme to set
  335. *
  336. * @return void
  337. *
  338. * @test
  339. * @dataProvider schemeProvider
  340. */
  341. public function schemeCanBeSetBySetSchemeMethod($scheme)
  342. {
  343. $request = new \Request($this->config);
  344. $request->setScheme($scheme);
  345. $this->assertEquals($scheme, $request->getScheme());
  346. }
  347. /**
  348. * Provides schemes for tests
  349. *
  350. * @return array
  351. */
  352. public function schemeProvider()
  353. {
  354. return array(
  355. array('http://'),
  356. array('https://'),
  357. );
  358. }
  359. /**
  360. * Ensures that an exception is thrown if the authorization header
  361. * doesn't have two parts
  362. *
  363. * @return void
  364. *
  365. * @test
  366. * @expectedException \InvalidArgumentException
  367. * @expectedExceptionMessage Invalid Authorization Header
  368. * @expectedExceptionCode 400
  369. */
  370. public function ifIdentificationDoesNotHaveTwoPartsExceptionIsThrown()
  371. {
  372. $request = new \Request($this->config);
  373. $request->identifyUser(null, 'This is a bad header');
  374. }
  375. /**
  376. * Ensures that an exception is thrown if the authorization header doesn't
  377. * start with oauth
  378. *
  379. * @return void
  380. *
  381. * @test
  382. * @expectedException \InvalidArgumentException
  383. * @expectedExceptionMessage Unknown Authorization Header Received
  384. * @expectedExceptionCode 400
  385. */
  386. public function ifIdentificationHeaderDoesNotStartWithOauthThrowException()
  387. {
  388. $request = new \Request($this->config);
  389. $request->identifyUser(null, 'Auth Me');
  390. }
  391. /**
  392. * Ensures that if getOAuthModel is called, an instance of OAuthModel
  393. * is returned
  394. *
  395. * @return void
  396. *
  397. * @test
  398. */
  399. public function getOauthModelProvidesAnOauthModel()
  400. {
  401. // Please see below for explanation of why we're mocking a "mock" PDO
  402. // class
  403. $db = $this->getMock(
  404. '\JoindinTest\Inc\mockPDO',
  405. array('getAvailableDrivers')
  406. );
  407. $request = new \Request($this->config);
  408. $result = $request->getOAuthModel($db);
  409. $this->assertInstanceOf('OAuthModel', $result);
  410. }
  411. /**
  412. * Ensures that if the getOauthModel method is called and no model is already
  413. * set, and no PDO adapter is provided, an exception is thrown
  414. *
  415. * @return void
  416. *
  417. * @test
  418. * @expectedException \InvalidArgumentException
  419. * @expectedExceptionMessage Db Must be provided to get Oauth Model
  420. */
  421. public function callingGetOauthModelWithoutADatabaseAdapterThrowsAnException()
  422. {
  423. $request = new \Request($this->config);
  424. $request->getOauthModel();
  425. }
  426. /**
  427. * Ensures that the setOauthModel method is fluent
  428. *
  429. * @return void
  430. *
  431. * @test
  432. */
  433. public function setOauthModelMethodIsFluent()
  434. {
  435. /* @var $mockOauth \OAuthModel */
  436. $mockOauth = $this->getMock('OAuthModel', array(), array(), '', false);
  437. $request = new \Request($this->config);
  438. $this->assertSame($request, $request->setOauthModel($mockOauth));
  439. }
  440. /**
  441. * Ensures that the setOauthModel method allows for an OAuthModel
  442. * to be set and retrieved
  443. *
  444. * @return void
  445. *
  446. * @test
  447. */
  448. public function setOauthModelAllowsSettingOfOauthModel()
  449. {
  450. /* @var $mockOauth \OAuthModel */
  451. $mockOauth = $this->getMock('OAuthModel', array(), array(), '', false);
  452. $request = new \Request($this->config);
  453. $request->setOauthModel($mockOauth);
  454. $this->assertSame($mockOauth, $request->getOauthModel());
  455. }
  456. /**
  457. * Ensures that identifyUser method sets a user id on the request model
  458. *
  459. * @return void
  460. *
  461. * @test
  462. */
  463. public function identifyUserSetsUserIdForValidHeader()
  464. {
  465. $request = new \Request($this->config);
  466. $mockOauth = $this->getMock('OAuthModel', array(), array(), '', false);
  467. $mockOauth->expects($this->once())
  468. ->method('verifyAccessToken')
  469. ->with('authPart')
  470. ->will($this->returnValue('TheUserId'));
  471. $request->setOauthModel($mockOauth);
  472. $request->identifyUser(null, 'oauth authPart');
  473. $this->assertEquals('TheUserId', $request->user_id);
  474. $this->assertEquals('TheUserId', $request->getUserId());
  475. }
  476. /**
  477. * Ensures that the setUserId method is fluent
  478. *
  479. * @return void
  480. *
  481. * @test
  482. */
  483. public function setUserIdIsFluent()
  484. {
  485. $request = new \Request($this->config);
  486. $this->assertSame($request, $request->setUserId('TheUserToSet'));
  487. }
  488. /**
  489. * Ensures that setUserId can set a user id into the model that can be
  490. * retrieved with getUserId
  491. *
  492. * @return void
  493. *
  494. * @test
  495. */
  496. public function setUserIdAllowsForSettingOfUserId()
  497. {
  498. $request = new \Request($this->config);
  499. $user = uniqid();
  500. $request->setUserId($user);
  501. $this->assertEquals($user, $request->getUserId());
  502. }
  503. /**
  504. * Ensures the setPathInfo method allows setting of a path
  505. *
  506. * @return void
  507. *
  508. * @test
  509. */
  510. public function setPathInfoAllowsSettingOfPathInfo()
  511. {
  512. $path = uniqid() . '/' . uniqid() . '/' . uniqid();
  513. $parts = explode('/', $path);
  514. $request = new \Request($this->config);
  515. $request->setPathInfo($path);
  516. $this->assertEquals($path, $request->getPathInfo());
  517. $this->assertEquals($path, $request->path_info);
  518. $this->assertEquals($parts[0], $request->getUrlElement(0));
  519. $this->assertEquals($parts[1], $request->getUrlElement(1));
  520. $this->assertEquals($parts[2], $request->getUrlElement(2));
  521. }
  522. /**
  523. * Ensures the setPath method is fluent
  524. *
  525. * @return void
  526. *
  527. * @test
  528. */
  529. public function setPathIsFluent()
  530. {
  531. $request = new \Request($this->config);
  532. $this->assertSame($request, $request->setPathInfo(uniqid()));
  533. }
  534. /**
  535. * Ensures the setAccept header sets the accept variable
  536. *
  537. * @return void
  538. *
  539. * @test
  540. */
  541. public function setAcceptSetsTheAcceptVariable()
  542. {
  543. $accept = uniqid() . ',' . uniqid() . ',' . uniqid();
  544. $acceptParts = explode(',', $accept);
  545. $request = new \Request($this->config);
  546. $request->setAccept($accept);
  547. $this->assertEquals($acceptParts, $request->accept);
  548. foreach ($acceptParts as $thing) {
  549. $this->assertTrue($request->accepts($thing));
  550. }
  551. }
  552. /**
  553. * Ensures that the setAccept method is fluent
  554. *
  555. * @return void
  556. *
  557. * @test
  558. */
  559. public function setAcceptsIsFluent()
  560. {
  561. $request = new \Request($this->config);
  562. $this->assertSame($request, $request->setAccept(uniqid()));
  563. }
  564. /**
  565. * Ensures the setBase method allows setting of the base variable
  566. *
  567. * @return void
  568. *
  569. * @test
  570. */
  571. public function setBaseAllowsSettingOfBase()
  572. {
  573. $request = new \Request($this->config);
  574. $base = uniqid();
  575. $request->setBase($base);
  576. $this->assertEquals($base, $request->getBase());
  577. $this->assertEquals($base, $request->base);
  578. }
  579. /**
  580. * Ensures the setBase method is fluent
  581. *
  582. * @return void
  583. *
  584. * @test
  585. */
  586. public function setBaseIsFluent()
  587. {
  588. $request = new \Request($this->config);
  589. $this->assertSame($request, $request->setBase(uniqid()));
  590. }
  591. }
  592. /**
  593. * Class to allow for mocking PDO to send to the OAuthModel
  594. */
  595. class mockPDO extends \PDO
  596. {
  597. /**
  598. * Constructor that does nothing but helps us test with fake database
  599. * adapters
  600. */
  601. public function __construct()
  602. {
  603. // We need to do this crap because PDO has final on the __sleep and
  604. // __wakeup methods. PDO requires a parameter in the constructor but we don't
  605. // want to create a real DB adapter. If you tell getMock to not call the
  606. // original constructor, it fakes stuff out by unserializing a fake
  607. // serialized string. This way, we've got a "PDO" object but we don't need
  608. // PHPUnit to fake it by unserializing a made-up string. We've neutered
  609. // the constructor in mockPDO.
  610. }
  611. }