public function testKeyDescriptorValidation() { $northWindMetadata = NorthWindMetadata::Create(); $orderDetailsResourceType = $northWindMetadata->resolveResourceType('Order_Details'); $this->assertFalse(is_null($orderDetailsResourceType)); $keyDescriptor = null; //Test with a valid named value key predicate $keyPredicate = 'ProductID=11, OrderID=2546'; $validPredicateSyntax = KeyDescriptor::tryParseKeysFromKeyPredicate($keyPredicate, $keyDescriptor); $this->assertTrue($validPredicateSyntax); $this->assertFalse(is_null($keyDescriptor)); $keyDescriptor->validate('Order_Details(ProductID=11, OrderID=2546)', $orderDetailsResourceType); $validatedNamedValues = $keyDescriptor->getValidatedNamedValues(); $this->assertTrue(array_key_exists('ProductID', $validatedNamedValues)); $this->assertTrue(array_key_exists('OrderID', $validatedNamedValues)); $productVal = $validatedNamedValues['ProductID']; $orderVal = $validatedNamedValues['OrderID']; $this->assertEquals($productVal[0], 11); $this->assertEquals($orderVal[0], 2546); $keyDescriptor = null; //Test with a valid positional value key predicate $keyPredicate = '11, 2546'; $validPredicateSyntax = KeyDescriptor::tryParseKeysFromKeyPredicate($keyPredicate, $keyDescriptor); $this->assertTrue($validPredicateSyntax); $this->assertFalse(is_null($keyDescriptor)); $keyDescriptor->validate('Order_Details(11, 2546)', $orderDetailsResourceType); $validatedNamedValues = $keyDescriptor->getValidatedNamedValues(); $this->assertEquals(count($validatedNamedValues), 2); $this->assertTrue(array_key_exists('ProductID', $validatedNamedValues)); $this->assertTrue(array_key_exists('OrderID', $validatedNamedValues)); $productVal = $validatedNamedValues['ProductID']; $orderVal = $validatedNamedValues['OrderID']; $this->assertEquals($productVal[0], 11); $this->assertEquals($orderVal[0], 2546); //Test for key count $keyDescriptor = null; $keyPredicate = 'ProductID=11'; $validPredicateSyntax = KeyDescriptor::tryParseKeysFromKeyPredicate($keyPredicate, $keyDescriptor); try { $keyDescriptor->validate('Order_Details(ProductID=11)', $orderDetailsResourceType); $this->fail('An expected ODataException for predicate key count has not been thrown'); } catch (ODataException $exception) { $this->assertStringEndsWith(' expect 2 keys but 1 provided', $exception->getMessage()); } //test for missing key $keyDescriptor = null; $keyPredicate = 'ProductID=11, OrderID1=2546'; $validPredicateSyntax = KeyDescriptor::tryParseKeysFromKeyPredicate($keyPredicate, $keyDescriptor); try { $keyDescriptor->validate('Order_Details(ProductID=11, OrderID1=2546)', $orderDetailsResourceType); $this->fail('An expected ODataException for missing of keys in the predicate has not been thrown'); } catch (ODataException $exception) { $this->assertStringEndsWith('The key predicate expect the keys \'ProductID, OrderID\'', $exception->getMessage()); } //test for key type $keyDescriptor = null; $keyPredicate = 'ProductID=11.12, OrderID=2546'; $validPredicateSyntax = KeyDescriptor::tryParseKeysFromKeyPredicate($keyPredicate, $keyDescriptor); try { $keyDescriptor->validate('Order_Details(ProductID=11.12, OrderID=2546)', $orderDetailsResourceType); $this->fail('An expected ODataException for type incompactibility has not been thrown'); } catch (ODataException $exception) { $this->assertStringEndsWith('The value of key property \'ProductID\' should be of type Edm.Int32, given Edm.Double', $exception->getMessage()); } //test for key type $keyDescriptor = null; $keyPredicate = '11, \'ABCD\''; $validPredicateSyntax = KeyDescriptor::tryParseKeysFromKeyPredicate($keyPredicate, $keyDescriptor); try { $keyDescriptor->validate('Order_Details(11, \'ABCD\')', $orderDetailsResourceType); $this->fail('An expected ODataException for type incompactibility has not been thrown'); } catch (ODataException $exception) { $this->assertStringEndsWith('The value of key property \'OrderID\' at position 1 should be of type Edm.Int32, given Edm.String', $exception->getMessage()); } }
/** * Creates an instance of KeyDescriptor by parsing a key predicate, also * validates the KeyDescriptor * * @param string $segment The uri segment in the form identifier * (keyPredicate) * @param ResourceType $resourceType The Resource type whose keys need to * be parsed * @param string $keyPredicate The key predicate to parse and generate * KeyDescriptor for * * @return KeyDescriptor Describes the key values in the $keyPredicate * * @throws ODataException Exception if any error occurs while parsing and * validating the key predicate */ private function _createKeyDescriptor($segment, ResourceType $resourceType, $keyPredicate) { /** * @var KeyDescriptor $keyDescriptor */ $keyDescriptor = null; if (!KeyDescriptor::tryParseKeysFromKeyPredicate($keyPredicate, $keyDescriptor)) { throw ODataException::createSyntaxError(Messages::syntaxError()); } // Note: Currently WCF Data Service does not support multiple // 'Positional values' so Order_Details(10248, 11) is not valid if (!$keyDescriptor->isEmpty() && !$keyDescriptor->areNamedValues() && $keyDescriptor->valueCount() > 1) { throw ODataException::createSyntaxError(Messages::segmentParserKeysMustBeNamed($segment)); } $keyDescriptor->validate($segment, $resourceType); return $keyDescriptor; }