PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/OData Producer for PHP/Tests/UriProcessor/QueryProcessor/SkipTokenParser/SkipTokenParserTest.php

#
PHP | 569 lines | 438 code | 45 blank | 86 comment | 10 complexity | 9a700bf48deb8b3c3bfe76cf7642b5e0 MD5 | raw file
  1. <?php
  2. use ODataProducer\Providers\Metadata\ResourceProperty;
  3. use ODataProducer\Configuration\EntitySetRights;
  4. use ODataProducer\Providers\MetadataQueryProviderWrapper;
  5. use ODataProducer\Configuration\DataServiceConfiguration;
  6. use ODataProducer\Common\ODataException;
  7. use ODataProducer\UriProcessor\QueryProcessor\OrderByParser\OrderByParser;
  8. use ODataProducer\UriProcessor\QueryProcessor\SkipTokenParser\SkipTokenParser;
  9. require_once 'PHPUnit\Framework\Assert.php';
  10. require_once 'PHPUnit\Framework\Test.php';
  11. require_once 'PHPUnit\Framework\SelfDescribing.php';
  12. require_once 'PHPUnit\Framework\TestCase.php';
  13. require_once 'PHPUnit\Framework\TestSuite.php';
  14. require_once 'ODataProducer\Common\ClassAutoLoader.php';
  15. require_once (dirname(__FILE__) . "\..\..\..\Resources\NorthWindMetadata.php");
  16. ODataProducer\Common\ClassAutoLoader::register();
  17. class TestSkipTokenParser extends PHPUnit_Framework_TestCase
  18. {
  19. protected function setUp()
  20. {
  21. }
  22. /**
  23. * Named values are not allowed in skip token
  24. */
  25. public function testNamedValuesInSkipToken()
  26. {
  27. try {
  28. $northWindMetadata = CreateNorthWindMetadata3::Create();
  29. $configuration = new DataServiceConfiguration($northWindMetadata);
  30. $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
  31. $metaQueryProverWrapper = new MetadataQueryProviderWrapper(
  32. $northWindMetadata, //IDataServiceMetadataProvider implementation
  33. null, //IDataServiceQueryProvider implementation (set to null)
  34. $configuration, //Service configuuration
  35. false
  36. );
  37. $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Orders');
  38. $resourceType = $resourceSetWrapper->getResourceType();
  39. $orderBy = 'ShipName asc, Price';
  40. //Note: library will add prim key as last sort key
  41. $orderBy .= ', OrderID';
  42. $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper);
  43. $skipToken = "'Antonio%20Moreno%20Taquer%C3%ADa',Price=22.0000M,10365";
  44. $skipToken = urldecode($skipToken);
  45. $thrownException = false;
  46. try {
  47. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  48. } catch (ODataException $odataException) {
  49. $thrownException = true;
  50. $this->assertStringStartsWith('Bad Request - Error in the syntax of skiptoken', $odataException->getMessage());
  51. }
  52. if (!$thrownException) {
  53. $this->fail('An expected ODataException for syntax error has not been raised (because of named value)');
  54. }
  55. } catch (\Exception $exception) {
  56. $this->fail('An unexpected Exception has been raised.' . $exception->getMessage());
  57. }
  58. }
  59. /**
  60. * Skiptoken should not contain leading and trailing commas, use
  61. * commas only to seperate token sub-values.
  62. */
  63. public function testSkipTokenWithLeadingAndTrailingCommas()
  64. {
  65. try {
  66. $northWindMetadata = CreateNorthWindMetadata3::Create();
  67. $configuration = new DataServiceConfiguration($northWindMetadata);
  68. $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
  69. $metaQueryProverWrapper = new MetadataQueryProviderWrapper(
  70. $northWindMetadata, //IDataServiceMetadataProvider implementation
  71. null, //IDataServiceQueryProvider implementation (set to null)
  72. $configuration, //Service configuuration
  73. false
  74. );
  75. $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Orders');
  76. $resourceType = $resourceSetWrapper->getResourceType();
  77. $orderBy = 'ShipName asc, Price';
  78. //Note: library will add prim key as last sort key
  79. $orderBy .= ', OrderID';
  80. $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper);
  81. //Test with trailing comma
  82. $skipToken = "'Antonio%20Moreno%20Taquer%C3%ADa',22.000,10365,";
  83. $skipToken = urldecode($skipToken);
  84. $thrownException = false;
  85. try {
  86. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  87. } catch (ODataException $odataException) {
  88. $thrownException = true;
  89. $this->assertStringStartsWith('Bad Request - Error in the syntax of skiptoken', $odataException->getMessage());
  90. }
  91. if (!$thrownException) {
  92. $this->fail('An expected ODataException for syntax error has not been raised (because of trailing comma)');
  93. }
  94. //Test with leading comma
  95. $skipToken = ",'Antonio%20Moreno%20Taquer%C3%ADa',22.000,10365,";
  96. $skipToken = urldecode($skipToken);
  97. $thrownException = false;
  98. try {
  99. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  100. } catch (ODataException $odataException) {
  101. $thrownException = true;
  102. $this->assertStringStartsWith('Bad Request - Error in the syntax of skiptoken', $odataException->getMessage());
  103. }
  104. if (!$thrownException) {
  105. $this->fail('An expected ODataException for syntax error has not been raised (because of leading comma)');
  106. }
  107. //Test with extra comma between values
  108. $skipToken = "'Antonio%20Moreno%20Taquer%C3%ADa',,22.000,10365,";
  109. $skipToken = urldecode($skipToken);
  110. $thrownException = false;
  111. try {
  112. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  113. } catch (ODataException $odataException) {
  114. $thrownException = true;
  115. $this->assertStringStartsWith('Bad Request - Error in the syntax of skiptoken', $odataException->getMessage());
  116. }
  117. if (!$thrownException) {
  118. $this->fail('An expected ODataException for syntax error has not been raised (because of extra comma)');
  119. }
  120. } catch (\Exception $exception) {
  121. $this->fail('An unexpected Exception has been raised.' . $exception->getMessage());
  122. }
  123. }
  124. /**
  125. * Number of sub-values in skiptoken should match with number of
  126. * ordering expressions.
  127. */
  128. public function testSkipTokenHavingCountMismatchWithOrderBy()
  129. {
  130. try {
  131. $northWindMetadata = CreateNorthWindMetadata3::Create();
  132. $configuration = new DataServiceConfiguration($northWindMetadata);
  133. $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
  134. $metaQueryProverWrapper = new MetadataQueryProviderWrapper(
  135. $northWindMetadata, //IDataServiceMetadataProvider implementation
  136. null, //IDataServiceQueryProvider implementation (set to null)
  137. $configuration, //Service configuuration
  138. false
  139. );
  140. $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Orders');
  141. $resourceType = $resourceSetWrapper->getResourceType();
  142. $orderBy = 'ShipName asc, Price';
  143. //Note: library will add prim key as last sort key
  144. $orderBy .= ', OrderID';
  145. $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper);
  146. //zero skiptoken values
  147. $skipToken = "";
  148. $thrownException = false;
  149. try {
  150. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  151. } catch (ODataException $odataException) {
  152. $thrownException = true;
  153. $this->assertStringStartsWith('The number of keys \'0\' in skip token with value \'\' did not match the number of ordering constraints \'3\'', $odataException->getMessage());
  154. }
  155. if (!$thrownException) {
  156. $this->fail('An expected ODataException for syntax error has not been raised for skiptoken and ordering constraint count mismatch');
  157. }
  158. //two skiptoken values
  159. $skipToken = "'Antonio%20Moreno%20Taquer%C3%ADa',22.000";
  160. $skipToken = urldecode($skipToken);
  161. $thrownException = false;
  162. try {
  163. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  164. } catch (ODataException $odataException) {
  165. $thrownException = true;
  166. $this->assertStringStartsWith('The number of keys \'2\' in skip token with value', $odataException->getMessage());
  167. }
  168. if (!$thrownException) {
  169. $this->fail('An expected ODataException for syntax error has not been raised for skiptoken and ordering constraint count mismatch');
  170. }
  171. } catch (\Exception $exception) {
  172. $this->fail('An unexpected Exception has been raised.' . $exception->getMessage());
  173. }
  174. }
  175. /**
  176. * test skiptoken sub-values where type does not match with
  177. * corrosponding type of orderby path
  178. */
  179. public function testSkipTokenTypeInCompatability()
  180. {
  181. try {
  182. $northWindMetadata = CreateNorthWindMetadata3::Create();
  183. $configuration = new DataServiceConfiguration($northWindMetadata);
  184. $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
  185. $metaQueryProverWrapper = new MetadataQueryProviderWrapper(
  186. $northWindMetadata, //IDataServiceMetadataProvider implementation
  187. null, //IDataServiceQueryProvider implementation (set to null)
  188. $configuration, //Service configuuration
  189. false
  190. );
  191. $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Orders');
  192. $resourceType = $resourceSetWrapper->getResourceType();
  193. $orderBy = 'ShipName asc, Price';
  194. //Note: library will add prim key as last sort key
  195. $orderBy .= ', OrderID';
  196. $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper);
  197. //ShipName is String, but in skiptoken uses datetime
  198. $skipToken = "datetime'1996-07-12T03%3A58%3A58', 22.00, 1234";
  199. //do decoding so token become "datetime'1996-07-12T03:58:58', 22.00, 1234";
  200. $skipToken = urldecode($skipToken);
  201. $thrownException = false;
  202. try {
  203. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  204. } catch (ODataException $odataException) {
  205. $thrownException = true;
  206. $this->assertStringStartsWith('The skiptoken value \'datetime\'1996-07-12T03:58:58\', 22.00, 1234\' contain a value of type \'Edm.DateTime\' at position 0 which is not compatible with the type \'Edm.String\' of corrosponding orderby constraint', $odataException->getMessage());
  207. }
  208. if (!$thrownException) {
  209. $this->fail('An expected ODataException for type mismatch (datetime and string) ');
  210. }
  211. //Price is Double, but in skiptoken uses true
  212. $skipToken = "'ANS', true, 1234";
  213. $skipToken = urldecode($skipToken);
  214. $thrownException = false;
  215. try {
  216. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  217. } catch (ODataException $odataException) {
  218. $thrownException = true;
  219. $this->assertStringStartsWith('The skiptoken value \'\'ANS\', true, 1234\' contain a value of type \'Edm.Boolean\' at position 1 which is not compatible with the type \'Edm.Double\' of corrosponding orderby constraint', $odataException->getMessage());
  220. }
  221. if (!$thrownException) {
  222. $this->fail('An expected ODataException for type mismatch (boolean and double) ');
  223. }
  224. //null is allowed in skiptoken and compactable with all types
  225. $skipToken = "null, null, null";
  226. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  227. } catch (\Exception $exception) {
  228. $this->fail('An unexpected Exception has been raised.' . $exception->getMessage());
  229. }
  230. }
  231. /**
  232. * Test the initialzation of orderbyinfo's dummy object from the skiptoken value.
  233. * The orderby parser will create the dummy object, using the orderby path,
  234. * we will do a negative testing on GetKeyObject, by explicitly unsetting property
  235. * set by orderby parser
  236. */
  237. public function testInitializationOfKeyObject1()
  238. {
  239. try {
  240. $northWindMetadata = CreateNorthWindMetadata3::Create();
  241. $configuration = new DataServiceConfiguration($northWindMetadata);
  242. $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
  243. $metaQueryProverWrapper = new MetadataQueryProviderWrapper(
  244. $northWindMetadata, //IDataServiceMetadataProvider implementation
  245. null, //IDataServiceQueryProvider implementation (set to null)
  246. $configuration, //Service configuuration
  247. false
  248. );
  249. $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Order_Details');
  250. $resourceType = $resourceSetWrapper->getResourceType();
  251. $orderBy = 'Order/Customer/Rating';
  252. //Note: library will add primery key as last sort key
  253. $orderBy .= ', ProductID, OrderID';
  254. $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper);
  255. $skipToken = "12, 1234, 4567";
  256. $dummyObject = $internalOrderByInfo->getDummyObject();
  257. //we will remove Customer object createdby orderby parser, so that getKeyObject function will
  258. //fail to acees the property 'Rating', since parent ($dummyObject->Order->Customer) is null
  259. $this->assertTrue(!is_null($dummyObject));
  260. $this->assertTrue(!is_null($dummyObject->Order));
  261. $this->assertTrue(!is_null($dummyObject->Order->Customer));
  262. $this->assertTrue(is_null($dummyObject->Order->Customer->Rating));
  263. $dummyObject->Order->Customer = null;
  264. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  265. $thrownException = false;
  266. try {
  267. $o = $internalSkipTokenInfo->getKeyObject();
  268. } catch (ODataException $odataException) {
  269. $thrownException = true;
  270. $this->assertStringStartsWith('internalSkipTokenInfo failed to access or initialize the property Rating', $odataException->getMessage());
  271. }
  272. if (!$thrownException) {
  273. $this->fail('An expected ODataException for failure of ReflectionProperty on dummy object');
  274. }
  275. } catch (\Exception $exception) {
  276. $this->fail('An unexpected Exception has been raised.' . $exception->getMessage());
  277. }
  278. //test with null values
  279. //test with string value
  280. //test with other values, double, guid, int, datetime
  281. }
  282. /**
  283. * Test the initialzation of orderbyinfo's dummy object from the skiptoken value.
  284. * 1. The string properties in the key object should be utf8 decoded.
  285. * 2. The lexer will consider all token text as string, but when the we populate the
  286. * dummy object with these values, it should be converted to appropriate type
  287. *
  288. */
  289. public function testInitializationOfKeyObject2()
  290. {
  291. try {
  292. $northWindMetadata = CreateNorthWindMetadata3::Create();
  293. $configuration = new DataServiceConfiguration($northWindMetadata);
  294. $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
  295. $metaQueryProverWrapper = new MetadataQueryProviderWrapper(
  296. $northWindMetadata, //IDataServiceMetadataProvider implementation
  297. null, //IDataServiceQueryProvider implementation (set to null)
  298. $configuration, //Service configuuration
  299. false
  300. );
  301. $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Orders');
  302. $resourceType = $resourceSetWrapper->getResourceType();
  303. $orderBy = 'ShipName asc, Price';
  304. //Note: library will add prim key as last sort key
  305. $orderBy .= ', OrderID';
  306. $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper);
  307. $skipToken = "'Antonio%20Moreno%20Taquer%C3%ADa',22.001,10365";
  308. //urldecode convert the skip token to - 'Antonio Moreno Taquería',22.000,10365
  309. $skipToken = urldecode($skipToken);
  310. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  311. //The getKeyObject should do utf8 encoding on Antonio Moreno Taquería
  312. $keyObject = $internalSkipTokenInfo->getKeyObject();
  313. $this->assertTrue(!is_null($keyObject->ShipName));
  314. $shipName = (urldecode('Antonio%20Moreno%20Taquer%C3%ADa'));
  315. $this->assertEquals($shipName, $keyObject->ShipName);
  316. $this->assertTrue(!is_null($keyObject->Price));
  317. $this->assertTrue(is_float($keyObject->Price));
  318. $this->assertTrue(!is_null($keyObject->OrderID));
  319. $this->assertTrue(is_int($keyObject->OrderID));
  320. } catch (\Exception $exception) {
  321. $this->fail('An unexpected Exception has been raised.' . $exception->getMessage());
  322. }
  323. //test with null values
  324. //test with string value
  325. //test with other values, double, guid, int, datetime
  326. }
  327. /**
  328. * Test the initialzation of orderbyinfo's dummy object from the skiptoken value.
  329. * 1. Complex navigation can be also used in the skiptoken
  330. * 2. The lexer will consider all token text as string, but when the we populate the
  331. * dummy object with these values, it should be converted to appropriate type
  332. *
  333. */
  334. public function testInitializationOfKeyObject3()
  335. {
  336. try {
  337. $northWindMetadata = CreateNorthWindMetadata3::Create();
  338. $configuration = new DataServiceConfiguration($northWindMetadata);
  339. $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
  340. $metaQueryProverWrapper = new MetadataQueryProviderWrapper(
  341. $northWindMetadata, //IDataServiceMetadataProvider implementation
  342. null, //IDataServiceQueryProvider implementation (set to null)
  343. $configuration, //Service configuuration
  344. false
  345. );
  346. $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Customers');
  347. $resourceType = $resourceSetWrapper->getResourceType();
  348. $orderBy = 'Address/IsValid';
  349. //Note: library will add primery key as last sort key
  350. $orderBy .= ',CustomerID';
  351. $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper);
  352. $skipToken = "true, 'ALFKI'";
  353. $dummyObject = $internalOrderByInfo->getDummyObject();
  354. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  355. $keyObject = $internalSkipTokenInfo->getKeyObject();
  356. $this->assertTrue(!is_null($keyObject));
  357. $this->assertTrue(!is_null($keyObject->Address));
  358. $this->assertTrue(!is_null($keyObject->Address->IsValid));
  359. $this->assertTrue($keyObject->Address->IsValid);
  360. } catch (\Exception $exception) {
  361. $this->fail('An unexpected Exception has been raised.' . $exception->getMessage());
  362. }
  363. //test with other values, double, guid, int, datetime
  364. }
  365. /**
  366. * test the creation of nextlink from an object.
  367. * Test whether the buildNextPageLink function set skiptoken sub value as null when
  368. * it found one of the ancestor of corrosponding ordering key property(ies) as null.
  369. */
  370. public function testCreationOfNextLink1()
  371. {
  372. try {
  373. $northWindMetadata = CreateNorthWindMetadata3::Create();
  374. $configuration = new DataServiceConfiguration($northWindMetadata);
  375. $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
  376. $metaQueryProverWrapper = new MetadataQueryProviderWrapper(
  377. $northWindMetadata, //IDataServiceMetadataProvider implementation
  378. null, //IDataServiceQueryProvider implementation (set to null)
  379. $configuration, //Service configuuration
  380. false
  381. );
  382. $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Customers');
  383. $resourceType = $resourceSetWrapper->getResourceType();
  384. $orderBy = 'Address/Address2/IsPrimary';
  385. //Note: library will add primery key as last sort key
  386. $orderBy .= ',CustomerID';
  387. $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper);
  388. $skipToken = "true, 'ALFKI'";
  389. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  390. //Here the Address2 property is null, the sort key property IsPrimary is a property of Address2
  391. //so should emit null
  392. $lastObject = new Customer2();
  393. $lastObject->CustomerID = 'ALFKI';
  394. $lastObject->Address = new Address4();
  395. $lastObject->Address->Address2 = null;
  396. $nextLink = $internalSkipTokenInfo->buildNextPageLink($lastObject);
  397. $this->assertTrue(!is_null($nextLink));
  398. $this->assertEquals($nextLink, "null, 'ALFKI'");
  399. $lastObject = null;
  400. $thrownException = false;
  401. try {
  402. $internalSkipTokenInfo->buildNextPageLink($lastObject);
  403. } catch (ODataException $odataException) {
  404. $thrownException = true;
  405. $this->assertStringStartsWith('internalSkipTokenInfo failed to access or initialize the property Address', $odataException->getMessage());
  406. }
  407. if (!$thrownException) {
  408. $this->fail('An expected ODataException for failure of ReflectionProperty on dummy object while building next link');
  409. }
  410. } catch (\Exception $exception) {
  411. $this->fail('An unexpected Exception has been raised.' . $exception->getMessage());
  412. }
  413. }
  414. /**
  415. * test the creation of nextlink from an object.
  416. * Test building of link with string sub-value
  417. */
  418. public function testCreationOfNextLink2()
  419. {
  420. try {
  421. $northWindMetadata = CreateNorthWindMetadata3::Create();
  422. $configuration = new DataServiceConfiguration($northWindMetadata);
  423. $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
  424. $metaQueryProverWrapper = new MetadataQueryProviderWrapper(
  425. $northWindMetadata, //IDataServiceMetadataProvider implementation
  426. null, //IDataServiceQueryProvider implementation (set to null)
  427. $configuration, //Service configuuration
  428. false
  429. );
  430. $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Orders');
  431. $resourceType = $resourceSetWrapper->getResourceType();
  432. $orderBy = 'ShipName asc, Price';
  433. //Note: library will add prim key as last sort key
  434. $orderBy .= ', OrderID';
  435. $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper);
  436. $skipToken = "'ABY',22.000,10365";
  437. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  438. $lastObject = new Order2();
  439. //The string that is fetched from DB can be in utf8 format, so we are building
  440. //such a string with utf8_decode
  441. $lastObject->ShipName = utf8_decode(urldecode('Antonio%20Moreno%20Taquer%C3%ADa'));
  442. $lastObject->Price = 23.56;
  443. $lastObject->OrderID = 3456;
  444. $nextLink = $internalSkipTokenInfo->buildNextPageLink($lastObject);
  445. $this->assertTrue(!is_null($nextLink));
  446. $thrownException = false;
  447. $nextLink = $internalSkipTokenInfo->buildNextPageLink($lastObject);
  448. $this->assertEquals($nextLink, "'Antonio+Moreno+Taquer%C3%ADa', 23.56D, 3456");
  449. } catch (\Exception $exception) {
  450. $this->fail('An unexpected Exception has been raised.' . $exception->getMessage());
  451. }
  452. }
  453. /**
  454. * test the creation of nextlink from an object.
  455. * Test building of link with datetime sub-value
  456. */
  457. public function testCreationOfNextLink3()
  458. {
  459. try {
  460. $northWindMetadata = CreateNorthWindMetadata3::Create();
  461. $configuration = new DataServiceConfiguration($northWindMetadata);
  462. $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
  463. $metaQueryProverWrapper = new MetadataQueryProviderWrapper(
  464. $northWindMetadata, //IDataServiceMetadataProvider implementation
  465. null, //IDataServiceQueryProvider implementation (set to null)
  466. $configuration, //Service configuuration
  467. false
  468. );
  469. $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Orders');
  470. $resourceType = $resourceSetWrapper->getResourceType();
  471. $orderBy = 'OrderDate';
  472. //Note: library will add prim key as last sort key
  473. $orderBy .= ', OrderID';
  474. $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper);
  475. $skipToken = "null,10365";
  476. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  477. $lastObject = new Order2();
  478. $lastObject->OrderDate = '1996-07-12T00:00:00';
  479. $lastObject->OrderID = 3456;
  480. $nextLink = $internalSkipTokenInfo->buildNextPageLink($lastObject);
  481. $this->assertTrue(!is_null($nextLink));
  482. $nextLink = $internalSkipTokenInfo->buildNextPageLink($lastObject);
  483. $this->assertEquals($nextLink, "datetime'1996-07-12T00%3A00%3A00', 3456");
  484. } catch (\Exception $exception) {
  485. $this->fail('An unexpected Exception has been raised.' . $exception->getMessage());
  486. }
  487. }
  488. /**
  489. * test the creation of nextlink from an object.
  490. * Test building of link with guid sub-value
  491. */
  492. public function testCreationOfNextLink4()
  493. {
  494. try {
  495. $northWindMetadata = CreateNorthWindMetadata3::Create();
  496. $configuration = new DataServiceConfiguration($northWindMetadata);
  497. $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL);
  498. $metaQueryProverWrapper = new MetadataQueryProviderWrapper(
  499. $northWindMetadata, //IDataServiceMetadataProvider implementation
  500. null, //IDataServiceQueryProvider implementation (set to null)
  501. $configuration, //Service configuuration
  502. false
  503. );
  504. $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Customers');
  505. $resourceType = $resourceSetWrapper->getResourceType();
  506. $orderBy = 'CustomerID, CustomerGuid';
  507. $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper);
  508. $skipToken = "null, guid'05b242e752eb46bd8f0e6568b72cd9a5'";
  509. $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken);
  510. $keyObject = $internalSkipTokenInfo->getKeyObject();
  511. $lastObject = new Customer2();
  512. $lastObject->CustomerID = 'ABC';
  513. $lastObject->CustomerGuid = '{05b242e7-52eb-46bd-8f0e-6568b72cd9a5}';
  514. $nextLink = $internalSkipTokenInfo->buildNextPageLink($lastObject);
  515. $this->assertEquals($nextLink, "'ABC', guid'%7B05b242e7-52eb-46bd-8f0e-6568b72cd9a5%7D'");
  516. } catch (\Exception $exception) {
  517. $this->fail('An unexpected Exception has been raised.' . $exception->getMessage());
  518. }
  519. }
  520. protected function tearDown()
  521. {
  522. }
  523. }
  524. ?>