PageRenderTime 41ms CodeModel.GetById 5ms app.highlight 23ms RepoModel.GetById 2ms app.codeStats 1ms

/OData Producer for PHP/Tests/UriProcessor/UriProcessorTest.php

#
PHP | 2461 lines | 1975 code | 149 blank | 337 comment | 134 complexity | 5840980579cbdb4b484766a33ca79aa8 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1<?php
  2/**
  3 * Mainly test UriProcessor, but also do some partial test for DataService class.
  4 */
  5use ODataProducer\UriProcessor\QueryProcessor\ExpandProjectionParser\ProjectionNode;
  6use ODataProducer\UriProcessor\QueryProcessor\ExpandProjectionParser\ExpandedProjectionNode;
  7use ODataProducer\UriProcessor\QueryProcessor\ExpandProjectionParser\RootProjectionNode;
  8use ODataProducer\UriProcessor\QueryProcessor\AnonymousFunction;
  9use ODataProducer\UriProcessor\QueryProcessor\OrderByParser\OrderBySubPathSegment;
 10use ODataProducer\UriProcessor\QueryProcessor\OrderByParser\OrderByPathSegment;
 11use ODataProducer\UriProcessor\QueryProcessor\SkipTokenParser\InternalSkipTokenInfo;
 12use ODataProducer\UriProcessor\QueryProcessor\SkipTokenParser\SkipTokenInfo;
 13use ODataProducer\UriProcessor\QueryProcessor\ExpressionParser\InternalFilterInfo;
 14use ODataProducer\UriProcessor\QueryProcessor\OrderByParser\InternalOrderByInfo;
 15use ODataProducer\UriProcessor\RequestCountOption;
 16use ODataProducer\Configuration\DataServiceProtocolVersion;
 17use ODataProducer\UriProcessor\ResourcePathProcessor\SegmentParser\RequestTargetKind;
 18use ODataProducer\UriProcessor\ResourcePathProcessor\SegmentParser\RequestTargetSource;
 19use ODataProducer\Providers\Metadata\Type\Int32;
 20use ODataProducer\Providers\Metadata\Type\DateTime;
 21use ODataProducer\Common\Url;
 22use ODataProducer\Common\Version;
 23use ODataProducer\Common\ODataException;
 24require_once 'PHPUnit\Framework\Assert.php';
 25require_once 'PHPUnit\Framework\Test.php';
 26require_once 'PHPUnit\Framework\SelfDescribing.php';
 27require_once 'PHPUnit\Framework\TestCase.php';
 28require_once 'PHPUnit\Framework\TestSuite.php';
 29require_once 'ODataProducer\Common\ClassAutoLoader.php';
 30require_once (dirname(__FILE__) . "\.\..\Resources\NorthWindMetadata.php");
 31require_once (dirname(__FILE__) . "\.\..\Resources\NorthWindDataServiceV1.php");
 32require_once (dirname(__FILE__) . "\.\..\Resources\NorthWindDataService.php");
 33require_once (dirname(__FILE__) . "\.\..\Resources\NorthWindDataServiceV3.php");
 34require_once (dirname(__FILE__) . "\.\..\Resources\DataServiceHost2.php");
 35ODataProducer\Common\ClassAutoLoader::register();
 36class TestUriProcessor extends PHPUnit_Framework_TestCase
 37{
 38    protected function setUp()
 39    {
 40    }
 41
 42    /**
 43     * The request uri should be based on the service uri specified in the configuration.
 44     */
 45    /**public function testRequestUriWithInvalidBaseUri()
 46    {
 47        try {
 48            $hostInfo = array('AbsoluteRequestUri' => 
 49                                    new Url('http://localhost:8083/NorthWindDataService.svc'), 
 50				      		  'AbsoluteServiceUri' => 
 51                                    new Url('http://localhost:8083/XX/NorthWindDataService.svc'),
 52				  		      'QueryString' => 
 53                                    null);
 54            $host = new DataServiceHost2($hostInfo);
 55            $dataService = new NorthWindDataService2();
 56            $dataService->setHost($host);
 57            $exceptionThrown = false;
 58            try {
 59                $dataService->handleRequest();
 60            } catch (ODataException $odataException) {
 61                $exceptionThrown = true;
 62                $this->assertStringStartsWith("The URI 'http://localhost:8083/NorthWindDataService.svc' is not ", $odataException->getMessage());
 63            }
 64
 65            if (!$exceptionThrown) {
 66                $this->fail('An expected ODataException for invalid base uri in the request uri has not been thrown');
 67            }
 68                        
 69        } catch (\Exception $exception) {
 70            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
 71        }
 72        
 73        
 74    }**/
 75
 76    /**
 77     * Test with request uri where RequestTargetKind is NONE. RequestTargetKind will be
 78     * NONE for service directory, metadata and batch.
 79     */
 80    public function testUriProcessorWithRequestUriOfNoneTargetSourceKind()
 81    {
 82        try {
 83            //Request for service directory
 84            $hostInfo = array('AbsoluteRequestUri' => 
 85                                    new Url('http://localhost:8083/NorthWindDataService.svc'), 
 86				      		  'AbsoluteServiceUri' => 
 87                                    new Url('http://localhost:8083/NorthWindDataService.svc'),
 88				  		      'QueryString' => 
 89                                    null);
 90            $host = new DataServiceHost2($hostInfo);
 91            $dataService = new NorthWindDataService2();
 92            $dataService->setHost($host);
 93            $exceptionThrown = false;           
 94            $uriProcessor = $dataService->handleRequest();
 95            $requestDescripton = $uriProcessor->getRequestDescription();
 96            $this->assertEquals($requestDescripton->getTargetSource(), RequestTargetSource::NONE);
 97            $this->assertEquals($requestDescripton->getTargetKind(), RequestTargetKind::SERVICE_DIRECTORY);
 98            // Context is a singleton class reset it
 99            $host->getWebOperationContext()->resetWebContextInternal();
100            
101            //Request for metadata
102            $hostInfo = array('AbsoluteRequestUri' => 
103                                    new Url('http://localhost:8083/NorthWindDataService.svc/$metadata'), 
104				      		  'AbsoluteServiceUri' => 
105                                    new Url('http://localhost:8083/NorthWindDataService.svc'),
106				  		      'QueryString' => 
107                                    null);
108                                    
109            $host = new DataServiceHost2($hostInfo);
110            $dataService = new NorthWindDataService2();
111            $dataService->setHost($host);
112            $exceptionThrown = false;   
113            $requestDescripton = $uriProcessor = null;        
114            $uriProcessor = $dataService->handleRequest();
115            $requestDescripton = $uriProcessor->getRequestDescription();            
116            $this->assertEquals($requestDescripton->getTargetSource(), RequestTargetSource::NONE);
117            $this->assertEquals($requestDescripton->getTargetKind(), RequestTargetKind::METADATA);
118            // Context is a singleton class reset it
119            $host->getWebOperationContext()->resetWebContextInternal();
120            
121            //Request for batch
122            $hostInfo = array('AbsoluteRequestUri' => 
123                                    new Url('http://localhost:8083/NorthWindDataService.svc/$batch'), 
124				      		  'AbsoluteServiceUri' => 
125                                    new Url('http://localhost:8083/NorthWindDataService.svc'),
126				  		      'QueryString' => 
127                                    null);
128            $host = new DataServiceHost2($hostInfo);
129            $dataService = new NorthWindDataService2();
130            $dataService->setHost($host);
131            $exceptionThrown = false;           
132            $uriProcessor = $dataService->handleRequest();
133            $requestDescripton = $uriProcessor->getRequestDescription();
134            $this->assertEquals($requestDescripton->getTargetSource(), RequestTargetSource::NONE);
135            $this->assertEquals($requestDescripton->getTargetKind(), RequestTargetKind::BATCH);
136            // Context is a singleton class reset it
137            $host->getWebOperationContext()->resetWebContextInternal();
138        } catch (\Exception $exception) {
139            if ($host != null) {
140                $host->getWebOperationContext()->resetWebContextInternal();
141            }
142            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
143        } 
144    }
145
146    /**
147     * Test request uri for row count ($count)     
148     * DataServiceVersion and MaxDataServiceVersion should be >= 2.0 for $count
149     */
150    public function testUriProcessorForCountRequest1()
151    {
152        try {
153            //Test $count with DataServiceVersion < 2.0
154            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers/$count'), 
155			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
156				      'QueryString' => null,
157                  	  'DataServiceVersion' => new Version(1, 0),
158                  	  'MaxDataServiceVersion' => new Version(2, 0));
159
160            $host = new DataServiceHost2($hostInfo);
161            $dataService = new NorthWindDataService2();
162            $dataService->setHost($host);
163            $exceptionThrown = false;
164            try {
165                $uriProcessor = $dataService->handleRequest();                
166            } catch (ODataException $odataException) {                
167                $exceptionThrown = true;                
168                $this->assertStringStartsWith("Request version '1.0' is not supported for the request payload. The only supported version is '2.0", $odataException->getMessage());
169            }
170
171            if (!$exceptionThrown) {
172                $this->fail('An expected ODataException for failure of capability negoitation over DataServiceVersion has not been thrown');
173            }
174
175            // Context is a singleton class reset it
176            $host->getWebOperationContext()->resetWebContextInternal();
177            //Test $count with MaxDataServiceVersion < 2.0
178            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers/$count'), 
179			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
180				      'QueryString' => null,
181                  	  'DataServiceVersion' => new Version(2, 0),
182                  	  'MaxDataServiceVersion' => new Version(1, 0));
183            
184            $host = new DataServiceHost2($hostInfo);
185            $dataService = new NorthWindDataService2();
186            $dataService->setHost($host);
187            $exceptionThrown = false;
188            try {
189                $uriProcessor = $dataService->handleRequest();
190            } catch (ODataException $odataException) {
191                $exceptionThrown = true;
192                $this->assertStringStartsWith("Request version '1.0' is not supported for the request payload. The only supported version is '2.0", $odataException->getMessage());
193            }
194
195            if (!$exceptionThrown) {
196                $this->fail('An expected ODataException for failure of capability negoitation over MaxDataServiceVersion has not been thrown');
197            }
198            $host->getWebOperationContext()->resetWebContextInternal();
199        } catch (\Exception $exception) {
200            if ($host != null) {
201                $host->getWebOperationContext()->resetWebContextInternal();
202            }
203            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());            
204        }
205    }
206
207    /**
208     * Test request uri for row count ($count)     
209     * $count is a version 2 feature so service devloper should use protocol version 2.0
210     */
211    public function testUriProcessorForCountRequest2()
212    {
213        try {            
214            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers/$count'), 
215			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
216				      'QueryString' => null,
217                  	  'DataServiceVersion' => new Version(2, 0),
218                  	  'MaxDataServiceVersion' => new Version(2, 0));
219
220            $host = new DataServiceHost2($hostInfo);
221            $dataService = new NorthWindDataServiceV1();                
222            $dataService->setHost($host);
223            $exceptionThrown = false;
224            try {
225                $uriProcessor = $dataService->handleRequest();
226            } catch (ODataException $odataException) {
227                $exceptionThrown = true;                
228                $this->assertStringStartsWith("The response requires that version 2.0 of the protocol be used, but the MaxProtocolVersion of the data service is set to 1.0", $odataException->getMessage());
229            }
230
231            if (!$exceptionThrown) {
232                $this->fail('An expected ODataException for failure of capability negoitation due to V1 configuration has not been thrown');
233            }
234            $host->getWebOperationContext()->resetWebContextInternal();
235        } catch (\Exception $exception) {
236            if ($host != null) {
237                $host->getWebOperationContext()->resetWebContextInternal();
238            }
239            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
240        }
241    }
242
243    /**
244     * Test request uri for row count ($count)     
245     * 
246     * Suppose $top option is absent, still
247     * RequestDescription::topCount will be set if the resource targetted by the
248     * uri has paging enabled, if RequestDescription::topCount 
249     * is set then internal orderby info will be generated. But if the request 
250     * is for raw count for a resource collection then paging is not applicable
251     * for that, so topCount will be null and internal orderby info will not be 
252     * generated.
253     */
254    public function testUriProcessorForCountRequest3()
255    {
256        try {            
257            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers/$count'), 
258			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
259				      'QueryString' => null,
260                  	  'DataServiceVersion' => new Version(2, 0),
261                  	  'MaxDataServiceVersion' => new Version(2, 0));
262
263            $host = new DataServiceHost2($hostInfo);
264            $dataService = new NorthWindDataService2();                   
265            $dataService->setHost($host);
266            $exceptionThrown = false;            
267            $uriProcessor = $dataService->handleRequest();
268            $requestDescription = $uriProcessor->getRequestDescription();
269            $this->assertTrue(!is_null($requestDescription));
270            $this->assertTrue(is_null($requestDescription->getInternalOrderByInfo()));
271            $host->getWebOperationContext()->resetWebContextInternal();
272            
273        } catch (\Exception $exception) {            
274            if ($host != null) {
275                $host->getWebOperationContext()->resetWebContextInternal();
276            }
277            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
278        }
279    }
280
281    /**
282     * Test request uri for row count ($count)     
283     * 
284     * $orderby option can be applied to a $count request.
285     */
286    public function testUriProcessorForCountRequest4()
287    {
288        try {            
289            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers/$count'), 
290			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
291				      'QueryString' => '$orderby=Country',
292                  	  'DataServiceVersion' => new Version(2, 0),
293                  	  'MaxDataServiceVersion' => new Version(2, 0));
294
295            $host = new DataServiceHost2($hostInfo);
296            $dataService = new NorthWindDataService2();                   
297            $dataService->setHost($host);
298            $exceptionThrown = false;            
299            $uriProcessor = $dataService->handleRequest();
300            $requestDescription = $uriProcessor->getRequestDescription();
301            $this->assertTrue(!is_null($requestDescription));
302            $internalOrderByInfo = $requestDescription->getInternalOrderByInfo();
303            $this->assertTrue(!is_null($internalOrderByInfo));
304            $object = $internalOrderByInfo->getDummyObject();
305            $this->assertTrue(!is_null($object));
306            $this->assertTrue($object instanceof Customer2);
307            $host->getWebOperationContext()->resetWebContextInternal();
308            
309        } catch (\Exception $exception) {
310            if ($host != null) {
311                $host->getWebOperationContext()->resetWebContextInternal();
312            }
313            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
314        }
315    }
316
317    /**
318     * Test request uri for row count ($count)     
319     * 
320     * $skip and $top options can be applied to $count request, this cause
321     * processor to generate internalorderinfo.
322     */
323    public function testUriProcessorForCountRequest5()
324    {
325        try {            
326            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers/$count'), 
327			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
328				      'QueryString' => '$skip=2&$top=4',
329                  	  'DataServiceVersion' => new Version(2, 0),
330                  	  'MaxDataServiceVersion' => new Version(2, 0));
331
332            $host = new DataServiceHost2($hostInfo);
333            $dataService = new NorthWindDataService2();                   
334            $dataService->setHost($host);
335            $exceptionThrown = false;            
336            $uriProcessor = $dataService->handleRequest();
337            $requestDescription = $uriProcessor->getRequestDescription();
338            $this->assertTrue(!is_null($requestDescription));
339            $this->assertEquals($requestDescription->getTopCount(), 4);
340            $this->assertEquals($requestDescription->getSkipCount(), 2);
341            $internalOrderByInfo = $requestDescription->getInternalOrderByInfo();
342            $this->assertTrue(!is_null($internalOrderByInfo));
343            $object = $internalOrderByInfo->getDummyObject();
344            $this->assertTrue(!is_null($object));
345            $this->assertTrue($object instanceof Customer2);
346            $host->getWebOperationContext()->resetWebContextInternal();
347        } catch (\Exception $exception) {
348            if ($host != null) {
349                $host->getWebOperationContext()->resetWebContextInternal();
350            }
351            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
352        }
353    }
354
355    /**
356     * Test request uri for row count ($count)     
357     * 
358     * $skip and/or $top options along with $orderby option cause internalOrderInfo
359     * to include sorter functions using keys + paths in the $orderby clause
360     */
361    public function testUriProcessorForCountRequest6()
362    {
363        try {            
364            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers/$count'), 
365			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
366				      'QueryString' => '$skip=2&$top=4&$orderby=Country',
367                  	  'DataServiceVersion' => new Version(2, 0),
368                  	  'MaxDataServiceVersion' => new Version(2, 0));
369
370            $host = new DataServiceHost2($hostInfo);
371            $dataService = new NorthWindDataService2();                   
372            $dataService->setHost($host);
373            $exceptionThrown = false;            
374            $uriProcessor = $dataService->handleRequest();
375            $requestDescription = $uriProcessor->getRequestDescription();
376            $this->assertTrue(!is_null($requestDescription));
377            $this->assertEquals($requestDescription->getTopCount(), 4);
378            $this->assertEquals($requestDescription->getSkipCount(), 2);
379            $internalOrderByInfo = $requestDescription->getInternalOrderByInfo();
380            $this->assertTrue(!is_null($internalOrderByInfo));
381            $object = $internalOrderByInfo->getDummyObject();
382            $this->assertTrue(!is_null($object));
383            $this->assertTrue($object instanceof Customer2);
384            $pathSegments = $internalOrderByInfo->getOrderByPathSegments();
385            $this->assertTrue(!is_null($pathSegments));
386            $this->assertTrue(is_array($pathSegments));
387            $this->assertEquals(count($pathSegments), 3);
388            $this->assertTrue($pathSegments[0] instanceof OrderByPathSegment);
389            $subPathSegments = $pathSegments[0]->getSubPathSegments();
390            $this->assertTrue(!is_null($subPathSegments));
391            $this->assertTrue(is_array($subPathSegments));
392            $this->assertEquals(count($subPathSegments), 1);
393            $this->assertTrue($subPathSegments[0] instanceof OrderBySubPathSegment);
394            $this->assertEquals($subPathSegments[0]->getName(), 'Country');
395            
396            $this->assertTrue($pathSegments[1] instanceof OrderByPathSegment);
397            $subPathSegments = $pathSegments[1]->getSubPathSegments();
398            $this->assertTrue(!is_null($subPathSegments));
399            $this->assertTrue(is_array($subPathSegments));
400            $this->assertEquals(count($subPathSegments), 1);
401            $this->assertTrue($subPathSegments[0] instanceof OrderBySubPathSegment);
402            $this->assertEquals($subPathSegments[0]->getName(), 'CustomerID');
403            
404            $this->assertTrue($pathSegments[2] instanceof OrderByPathSegment);
405            $subPathSegments = $pathSegments[2]->getSubPathSegments();
406            $this->assertTrue(!is_null($subPathSegments));
407            $this->assertTrue(is_array($subPathSegments));
408            $this->assertEquals(count($subPathSegments), 1);
409            $this->assertTrue($subPathSegments[0] instanceof OrderBySubPathSegment);
410            $this->assertEquals($subPathSegments[0]->getName(), 'CustomerGuid');
411            $host->getWebOperationContext()->resetWebContextInternal();
412        } catch (\Exception $exception) {
413            if ($host != null) {
414                $host->getWebOperationContext()->resetWebContextInternal();
415            }
416            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
417        }
418    }
419
420    /**
421     * Test request uri for row count ($count)     
422     * $skiptoken is not applicable for $count request, as it requires
423     * paging and paging is not applicable for $count request
424     */
425    public function testUriProcessorForCountRequest7()
426    {
427        try {            
428            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers/$count'), 
429			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
430				      'QueryString' => '$top=1&$skiptoken=\'ALFKI\',guid\'05b242e752eb46bd8f0e6568b72cd9a5\'',
431                  	  'DataServiceVersion' => new Version(2, 0),
432                  	  'MaxDataServiceVersion' => new Version(2, 0));
433
434            $host = new DataServiceHost2($hostInfo);
435            $dataService = new NorthWindDataService2();
436            $dataService->setHost($host);
437            $exceptionThrown = false;
438            try {
439                $uriProcessor = $dataService->handleRequest();
440            } catch (ODataException $odataException) {
441                $exceptionThrown = true;
442                $this->assertStringStartsWith("Query option \$skiptoken cannot be applied to the requested resource", $odataException->getMessage());
443            }
444
445            if (!$exceptionThrown) {
446                $this->fail('An expected ODataException for applying $skiptoken on $count has not been thrown');
447            }
448
449            $host->getWebOperationContext()->resetWebContextInternal();
450        } catch (\Exception $exception) {
451            if ($host != null) {
452                $host->getWebOperationContext()->resetWebContextInternal();
453            }
454            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
455        }
456    }
457
458    /**
459     * Test request uri for row count ($count)     
460     * 
461     * $filter is applicable for $count segment.
462     */
463    public function testUriProcessorForCountRequest8()
464    {
465        try {            
466            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers/$count'), 
467			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
468				      'QueryString' => '$filter=Country eq \'USA\'',
469                  	  'DataServiceVersion' => new Version(2, 0),
470                  	  'MaxDataServiceVersion' => new Version(2, 0));
471
472            $host = new DataServiceHost2($hostInfo);
473            $dataService = new NorthWindDataService2();                   
474            $dataService->setHost($host);                  
475            $uriProcessor = $dataService->handleRequest();
476            $requestDescription = $uriProcessor->getRequestDescription();
477            $this->assertTrue(!is_null($requestDescription));
478            $internalFilterInfo = $requestDescription->getInternalFilterInfo();
479            $this->assertTrue(!is_null($internalFilterInfo));
480            $filterInfo = $internalFilterInfo->getFilterInfo();
481            $this->assertTrue(!is_null($filterInfo));
482            $this->assertTrue(is_null($filterInfo->getNavigationPropertiesUsed()));
483            $filterFunction = $internalFilterInfo->getFilterFunction();
484            $this->assertTrue(!is_null($filterFunction));
485            $this->assertTrue($filterFunction instanceof  AnonymousFunction);
486            $host->getWebOperationContext()->resetWebContextInternal();
487        } catch (\Exception $exception) {
488            if ($host != null) {
489                $host->getWebOperationContext()->resetWebContextInternal();
490            }
491            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
492        }
493    }
494
495    /**
496     * Test request uri for row count ($count)     
497     * 
498     * $select and $expand options are applicable for $count segment.
499     * but when we do query execution we will ignore them.
500     */
501    public function testUriProcessorForCountRequest9()
502    {
503        try {            
504            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers/$count'), 
505			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
506				      'QueryString' => '$select=Country&$expand=Orders',
507                  	  'DataServiceVersion' => new Version(2, 0),
508                  	  'MaxDataServiceVersion' => new Version(2, 0));
509
510            $host = new DataServiceHost2($hostInfo);
511            $dataService = new NorthWindDataService2();                   
512            $dataService->setHost($host);                  
513            $uriProcessor = $dataService->handleRequest();
514            $requestDescription = $uriProcessor->getRequestDescription();
515            $this->assertTrue(!is_null($requestDescription));
516            $projectionTreeRoot = $requestDescription->getRootProjectionNode();
517            $this->assertTrue(!is_null($projectionTreeRoot));
518            $this->assertTrue($projectionTreeRoot instanceof RootProjectionNode);
519            //There will be one child node for 'Country', 'Orders' wont be included
520            //as its not selected
521            $childNodes = $projectionTreeRoot->getChildNodes();
522            $this->assertTrue(!is_null($childNodes));
523            $this->assertTrue(is_array($childNodes));
524            $this->assertEquals(count($childNodes), 1);
525            $this->assertTrue(array_key_exists('Country', $childNodes));
526            $this->assertTrue($childNodes['Country'] instanceof ProjectionNode);
527            $host->getWebOperationContext()->resetWebContextInternal();
528        } catch (\Exception $exception) {
529            if ($host != null) {
530                $host->getWebOperationContext()->resetWebContextInternal();
531            }
532            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
533        }
534    }
535
536    /**
537     * Test request uri for row count ($count)     
538     * $count with $inlinecount not allowed
539     */
540    public function testUriProcessorForCountWithInline()
541    {
542        try {            
543            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers/$count'), 
544			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
545				      'QueryString' => '$inlinecount=allpages',
546                  	  'DataServiceVersion' => new Version(2, 0),
547                  	  'MaxDataServiceVersion' => new Version(2, 0));
548
549            $host = new DataServiceHost2($hostInfo);
550            $dataService = new NorthWindDataService2();
551            $dataService->setHost($host);
552            $exceptionThrown = false;
553            try {
554                $uriProcessor = $dataService->handleRequest();
555            } catch (ODataException $odataException) {
556                $exceptionThrown = true;
557                $this->assertStringStartsWith("\$inlinecount cannot be applied to the resource segment \$count", $odataException->getMessage());
558            }
559
560            if (!$exceptionThrown) {
561                $this->fail('An expected ODataException for applying $skiptoken on $count has not been thrown');
562            }
563            $host->getWebOperationContext()->resetWebContextInternal();
564        } catch (\Exception $exception) {
565            if ($host != null) {
566                $host->getWebOperationContext()->resetWebContextInternal();
567            }
568            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
569        }
570    }
571
572    /**
573     * If paging is enabled for a resource set, then the uri 
574     * processor should generate orderinfo irrespective of
575     * whether $top or $orderby is specified or not.
576     * 
577     * Request DataServiceVersion => 1.0
578     * Request MaxDataServiceVersion => 2.0
579     */
580    public function testUriProcessorForResourcePageInfo1()
581    {
582        try {
583            //Test for generation of orderinfo for resource set
584            //with request DataServiceVersion 1.0
585            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers'), 
586			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
587				      'QueryString' => null,
588                  	  'DataServiceVersion' => new Version(1, 0),
589                  	  'MaxDataServiceVersion' => new Version(2, 0));
590
591            $host = new DataServiceHost2($hostInfo);
592            $dataService = new NorthWindDataService2();
593            $dataService->setHost($host);
594            $uriProcessor = $dataService->handleRequest();
595            $requestDescription = $uriProcessor->getRequestDescription();
596            $this->assertTrue(!is_null($requestDescription));
597            //Page size is 5, so take count is 5
598            $this->assertEquals($requestDescription->getTopCount(), 5);
599            
600            //order info is required for pagination
601            $internalOrderByInfo = $requestDescription->getInternalOrderByInfo();
602            $this->assertTrue(!is_null($internalOrderByInfo));
603            $pathSegments = $internalOrderByInfo->getOrderByPathSegments();
604            $this->assertTrue(!is_null($pathSegments));
605            $this->assertTrue(is_array($pathSegments));
606            //Customer has two keys
607            $this->assertEquals(count($pathSegments), 2);
608            $this->assertTrue($pathSegments[0] instanceof OrderByPathSegment);
609            $subPathSegments = $pathSegments[0]->getSubPathSegments();
610            $this->assertTrue(!is_null($subPathSegments));
611            $this->assertTrue(is_array($subPathSegments));
612            $this->assertEquals(count($subPathSegments), 1);
613            $this->assertTrue($subPathSegments[0] instanceof OrderBySubPathSegment);
614            $this->assertEquals($subPathSegments[0]->getName(), 'CustomerID');
615            
616            $this->assertTrue($pathSegments[1] instanceof OrderByPathSegment);
617            $subPathSegments = $pathSegments[1]->getSubPathSegments();
618            $this->assertTrue(!is_null($subPathSegments));
619            $this->assertTrue(is_array($subPathSegments));
620            $this->assertEquals(count($subPathSegments), 1);
621            $this->assertTrue($subPathSegments[0] instanceof OrderBySubPathSegment);
622            $this->assertEquals($subPathSegments[0]->getName(), 'CustomerGuid');
623            $host->getWebOperationContext()->resetWebContextInternal();
624        } catch (\Exception $exception) {
625            if ($host != null) {
626                $host->getWebOperationContext()->resetWebContextInternal();
627            }
628            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
629        }
630    }
631
632    /**
633     * If paging is enabled for a resource set, then the uri 
634     * processor should generate orderinfo irrespective of
635     * whether $top or $orderby is specified or not.
636     * 
637     * Request DataServiceVersion => 1.0
638     * Request MaxDataServiceVersion => 1.0
639     * 
640     * This will fail as paging requires version 2.0 or above
641     */
642    public function testUriProcessorForResourcePageInfo2()
643    {
644        try {
645            //Test for generation of orderinfo for resource set
646            //with request DataServiceVersion 1.0
647            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Customers'), 
648			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
649				      'QueryString' => null,
650                  	  'DataServiceVersion' => new Version(1, 0),
651                  	  'MaxDataServiceVersion' => new Version(1, 0));
652
653            $host = new DataServiceHost2($hostInfo);
654            $dataService = new NorthWindDataService2();
655            $dataService->setHost($host);
656            $exceptionThrown = false;
657            try {
658                $uriProcessor = $dataService->handleRequest();
659            } catch (ODataException $odataException) {
660                $exceptionThrown = true;                
661                $this->assertStringStartsWith("Request version '1.0' is not supported for the request payload. The only supported version is '2.0'", $odataException->getMessage());
662            }
663
664            if (!$exceptionThrown) {
665                $this->fail('An expected ODataException due to capability negotiation has not been thrown (paged result but client\'s max supportedd version is 1.0)');
666            }
667            $host->getWebOperationContext()->resetWebContextInternal();    
668        } catch (\Exception $exception) {
669            if ($host != null) {
670                $host->getWebOperationContext()->resetWebContextInternal();
671            }
672            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
673        }
674    }
675
676    /**
677     * Paging is enabled only for resource set, so with resource set
678     * reference there will not be any paginginfo.
679     */
680    public function testUriProcessorForResourcePageInfo3()
681    {
682        try {
683            //Test for generation of orderinfo for resource set
684            //with request DataServiceVersion 1.0
685            $hostInfo = array('AbsoluteRequestUri' => new Url('http://localhost:8083/NorthWindDataService.svc/Orders(123)'), 
686			    	  'AbsoluteServiceUri' => new Url('http://localhost:8083/NorthWindDataService.svc'),
687				      'QueryString' => null,
688                  	  'DataServiceVersion' => new Version(1, 0),
689                  	  'MaxDataServiceVersion' => new Version(2, 0));
690
691            $host = new DataServiceHost2($hostInfo);
692            $dataService = new NorthWindDataService2();
693            $dataService->setHost($host);
694            $uriProcessor = $dataService->handleRequest();
695            $requestDescription = $uriProcessor->getRequestDescription();
696            $this->assertTrue(!is_null($requestDescription));
697            //Page is not appliable for single resouce
698            $this->assertEquals($requestDescription->getTopCount(), null);            
699            //order info wont be generated as resource is not applicable for pagination
700            $internalOrderByInfo = $requestDescription->getInternalOrderByInfo();
701            $this->assertTrue(is_null($internalOrderByInfo));
702            $host->getWebOperationContext()->resetWebContextInternal();
703        } catch (\Exception $exception) {
704            if ($host != null) {
705                $host->getWebOperationContext()->resetWebContextInternal();
706            }
707            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
708        }
709    }
710
711    /**
712     * If paging is enabled for a resource set, then $link request for that resource set
713     * will also paged
714     * e.g. http://host/service.svc/Customers('A')/$links/Orders
715     * here if paging is enabled for Orders then prcoessor must generate orderbyinfo for
716     * this.     
717     */
718    public function testUriProcessorForResourcePageInfo4()
719    {
720        try {
721            //Test for generation of orderinfo for resource set in $links query
722            $baseUri = 'http://localhost:8083/NorthWindDataService.svc/';
723            $resourcePath = 'Customers(CustomerID=\'ALFKI\', CustomerGuid=guid\'05b242e752eb46bd8f0e6568b72cd9a5\')/$links/Orders';
724            $hostInfo = array('AbsoluteRequestUri' => new Url($baseUri . $resourcePath),                                
725			    	  			'AbsoluteServiceUri' => new Url($baseUri),
726				      			'QueryString' => null,
727                  	  			'DataServiceVersion' => new Version(1, 0),
728                  	  			'MaxDataServiceVersion' => new Version(2, 0));
729
730            $host = new DataServiceHost2($hostInfo);
731            $dataService = new NorthWindDataService2();
732            $dataService->setHost($host);
733            $uriProcessor = $dataService->handleRequest();
734            $requestDescription = $uriProcessor->getRequestDescription();
735            $this->assertTrue(!is_null($requestDescription));
736            //Page size is 5, so take count is 5
737            $this->assertEquals($requestDescription->getTopCount(), 5);            
738            //order info is required for pagination
739            $internalOrderByInfo = $requestDescription->getInternalOrderByInfo();
740            $this->assertTrue(!is_null($internalOrderByInfo));
741            $pathSegments = $internalOrderByInfo->getOrderByPathSegments();
742            $this->assertTrue(!is_null($pathSegments));
743            $this->assertTrue(is_array($pathSegments));
744            //Order has one key
745            $this->assertEquals(count($pathSegments), 1);
746            $this->assertTrue($pathSegments[0] instanceof OrderByPathSegment);
747            $subPathSegments = $pathSegments[0]->getSubPathSegments();
748            $this->assertTrue(!is_null($subPathSegments));
749            $this->assertTrue(is_array($subPathSegments));
750            $this->assertEquals(count($subPathSegments), 1);
751            $this->assertTrue($subPathSegments[0] instanceof OrderBySubPathSegment);
752            $this->assertEquals($subPathSegments[0]->getName(), 'OrderID');
753            $host->getWebOperationContext()->resetWebContextInternal();
754        } catch (\Exception $exception) {
755            if ($host != null) {
756                $host->getWebOperationContext()->resetWebContextInternal();
757            }
758            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
759        }
760    }
761
762    /**
763     * $orderby option can be applied to $links resource set
764     */
765    public function testUriProcessorForLinksResourceSet1()
766    {
767        try {
768            $baseUri = 'http://localhost:8083/NorthWindDataService.svc/';
769            $resourcePath = 'Customers(CustomerID=\'ALFKI\', CustomerGuid=guid\'05b242e752eb46bd8f0e6568b72cd9a5\')/$links/Orders';
770            $hostInfo = array('AbsoluteRequestUri' => new Url($baseUri . $resourcePath),                                
771			    	  			'AbsoluteServiceUri' => new Url($baseUri),
772				      			'QueryString' => '$orderby=ShipName asc, OrderDate desc',
773                  	  			'DataServiceVersion' => new Version(2, 0),
774                  	  			'MaxDataServiceVersion' => new Version(2, 0));
775
776            $host = new DataServiceHost2($hostInfo);
777            $dataService = new NorthWindDataService2();
778            $dataService->setHost($host);
779            $uriProcessor = $dataService->handleRequest();
780            $requestDescription = $uriProcessor->getRequestDescription();
781            $this->assertTrue(!is_null($requestDescription));
782             $this->assertEquals($requestDescription->isSingleResult(), false); 
783            //Page size is 5, so take count is 5 means you will get only 5 links for a request
784            $this->assertEquals($requestDescription->getTopCount(), 5); 
785            //Paging requires ordering, the result should be ordered like
786            //Note: additional ordering constraint
787            //
788            //SELECT links(d.orderID) FROM Customers JOIN Orders WHERE CustomerID='ALFKI' AND 
789            //CustomerGuid=guid'05b242e752eb46bd8f0e6568b72cd9a5' ORDER BY
790            //d.ShipName ASC, d.OrderDate DESC, d.OrderID ASC
791
792            $internalOrderByInfo = $requestDescription->getInternalOrderByInfo();
793            $this->assertTrue(!is_null($internalOrderByInfo));
794            $pathSegments = $internalOrderByInfo->getOrderByPathSegments();
795            $this->assertTrue(!is_null($pathSegments));
796            $this->assertTrue(is_array($pathSegments));            
797            $this->assertEquals(count($pathSegments), 3);
798            $this->assertTrue($pathSegments[0] instanceof OrderByPathSegment);
799            $subPathSegments = $pathSegments[0]->getSubPathSegments();
800            $this->assertTrue($pathSegments[0]->isAscending());
801            $this->assertTrue(!is_null($subPathSegments));
802            $this->assertTrue(is_array($subPathSegments));
803            $this->assertEquals(count($subPathSegments), 1);
804            $this->assertTrue($subPathSegments[0] instanceof OrderBySubPathSegment);
805            $this->assertEquals($subPathSegments[0]->getName(), 'ShipName');
806            $this->assertTrue($pathSegments[1] instanceof OrderByPathSegment);
807            $this->assertFalse($pathSegments[1]->isAscending());
808            $subPathSegments = $pathSegments[1]->getSubPathSegments();
809            $this->assertTrue(!is_null($subPathSegments));
810            $this->assertTrue(is_array($subPathSegments));
811            $this->assertEquals(count($subPathSegments), 1);
812            $this->assertTrue($subPathSegments[0] instanceof OrderBySubPathSegment);
813            $this->assertEquals($subPathSegments[0]->getName(), 'OrderDate');
814            $this->assertTrue($pathSegments[2] instanceof OrderByPathSegment);
815            $this->assertTrue($pathSegments[2]->isAscending());
816            $subPathSegments = $pathSegments[2]->getSubPathSegments();
817            $this->assertTrue(!is_null($subPathSegments));
818            $this->assertTrue(is_array($subPathSegments));
819            $this->assertEquals(count($subPathSegments), 1);
820            $this->assertTrue($subPathSegments[0] instanceof OrderBySubPathSegment);
821            $this->assertEquals($subPathSegments[0]->getName(), 'OrderID');
822            $host->getWebOperationContext()->resetWebContextInternal();
823        } catch (\Exception $exception) {
824            if ($host != null) {
825                $host->getWebOperationContext()->resetWebContextInternal();
826            }
827            $this->fail('An unexpected Exception has been raised' . $exception->getMessage());
828        }
829    }
830
831    /**
832     * $skiptoken option can be applied to $links resource set
833     */
834    public function testUriProcessorForLinksResourceSet2()
835    {
836        try {
837            //Test with skiptoken that corrosponds to default ordering key
838            $baseUri = 'http://localhost:8083/NorthWindDataService.svc/';
839            $resourcePath = 'Customers(CustomerID=\'ALFKI\', CustomerGuid=guid\'05b242e752eb46bd8f0e6568b72cd9a5\')/$links/Orders';
840            $hostInfo = array('AbsoluteRequestUri' => new Url($baseUri . $resourcePath),                                
841			    	  			'AbsoluteServiceUri' => new Url($baseUri),
842				      			'QueryString' => '$skiptoken=123',
843                  	  			'DataServiceVersion' => new Version(2, 0),
844                  	  			'MaxDataServiceVersion' => new Version(2, 0));
845            
846            $host = new DataServiceHost2($hostInfo);
847            $dataService = new NorthWindDataService2();
848            $dataService->setHost($host);
849            $uriProcessor = $dataService->handleRequest();
850            $requestDescription = $uriProcessor->getRequestDescription();
851            $this->assertTrue(!is_null($requestDescription));
852             $this->assertEquals($requestDescription->isSingleResult(), false); 
853            //Page size is 5, so take count is 5 means you will get only 5 links for a request
854            $this->assertEquals($requestDescription->getTopCount(), 5); 
855            //paging requires ordering
856            $internalOrderByInfo = $requestDescription->getInternalOrderByInfo();
857            $this->assertTrue(!is_null($internalOrderByInfo));
858            $pathSegments = $internalOrderByInfo->getOrderByPathSegments();
859            $this->assertTrue(!is_null($pathSegments));
860            $this->assertTrue(is_array($pathSegments));            
861            $this->assertEquals(count($pathSegments), 1);
862            $this->assertTrue($pathSegments[0] instanceof OrderByPathSegment);
863            $subPathSegments = $pathSegments[0]->getSubPathSegments();
864            $this->assertTrue($pathSegments[0]->isAscending());
865            $this->assertTrue(!is_null($subPathSegments));
866            $this->assertTrue(is_array($subPathSegments));
867            $this->assertEquals(count($subPathSegments), 1);
868            $this->assertTrue($subPathSegments[0] instanceof OrderBySubPathSegment);
869            $this->assertEquals($subPathSegments[0]->getName(), 'OrderID');
870            //check the skiptoken details
871            $internalSkiptokenInfo = $requestDescription->getInternalSkipTokenInfo();
872            $this->assertTrue(!is_null($internalSkiptokenInfo));
873            $this->assertTrue($internalSkiptokenInfo instanceof InternalSkipTokenInfo);
874            $skipTokenInfo = $internalSkiptokenInfo->getSkipTokenInfo();
875            $this->assertTrue(!is_null($skipTokenInfo));
876            $this->assertTrue($skipTokenInfo instanceof SkipTokenInfo);
877            $orderByValuesInSkipToken = $skipTokenInfo->getOrderByKeysInToken();
878            $this->assertTrue(!is_null($orderByValuesInSkipToken));
879            $this->assertTrue(is_array($orderByValuesInSkipToken));
880            $this->assertEquals(count($orderByValuesInSkipToken), 1);
881            $this->assertTrue(!is_null($orderByValuesInSkipToken[0]));
882            $this->assertTrue(is_array($orderByValuesInSkipToken[0]));
883            $this->assertEquals(count($orderByValuesInSkipToken[0]), 2);
884            $this->assertEquals($orderByValuesInSkipToken[0][0], 123);
885            $this->assertTrue(is_object($orderByValuesInSkipToken[0][1]));
886            $this->assertTrue($orderByValuesInSkipToken[0][1] instanceof Int32);
887            $host->getWebOperationContext()->resetWebContextInternal();
888            
889            //Test with skiptoken that corrosponds to explict ordering keys
890            $baseUri = 'http://localhost:8083/NorthWindDataService.svc/';
891            $resourcePath = 'Customers(CustomerID=\'ALFKI\', CustomerGuid=guid\'05b242e752eb46bd8f0e6568b72cd9a5\')/$links/Orders';
892            $hostInfo = array('AbsoluteRequestUri' => new Url($baseUri . $resourcePath),                                
893			    	  			'AbsoluteServiceUri' => new Url($baseUri),
894				      			'QueryString' => '$orderby=OrderID asc, OrderDate desc&$skiptoken=123, datetime\'2000-11-11\'',
895                  	  			'DataServiceVersion' => new Version(2, 0),
896                  	  			'MaxDataServiceVersion' => new Version(2, 0));
897            $host = new DataServiceHost2($hostInfo);
898            $dataService = new NorthWindDataService2();
899            $dataService->setHost($host);
900            $uriProcessor = $dataService->handleRequest();
901            $requestDescription = $uriProcessor->getRequestDescription();
902            $this->assertTrue(!is_null($requestDescription));
903             $this->assertEquals($requestDescription->isSingleResult(), false); 
904            //Page size is 5, so take count is 5 means you will get only 5 links for a request
905            $this->assertEquals($requestDescription->getTopCount(), 5); 
906            //paging requires ordering
907            $internalOrderByInfo = $requestDescription->getInternalOrderByInfo();
908            $this->assertTrue(!is_null($internalOrderByInfo));
909            $pathSegments = $internalOrderByInfo->getOrderByPathSegments();
910            $this->assertTrue(!is_null($pathSegments));
911            $this->assertTrue(is_array($pathSegments));
912            $this->assertEquals(count($pathSegments), 2);
913            $this->assertTrue($pathSegments[0] instanceof OrderByPathSegment);
914            $subPathSegments = $pathSegments[0]->getSubPathSegments();
915            $this->assertTrue($pathSegments[0]->isAscending());
916            $this->assertTrue(!is_null($subPathSegments));
917            $this->assertTrue(is_array($subPathSegments));
918            $this->assertEquals(count($subPathSegments), 1);
919            $this->assertTrue($subPathSegments[0

Large files files are truncated, but you can click here to view the full file