diff --git a/src/InvalidFieldTypeException.php b/src/InvalidFieldTypeException.php new file mode 100644 index 0000000..d807046 --- /dev/null +++ b/src/InvalidFieldTypeException.php @@ -0,0 +1,66 @@ +field = $field; + $this->expectedType = $expectedType; + $this->operation = $operation; + } + + /** + * @return string + */ + public function getField() + { + return $this->field; + } + + /** + * @return string + */ + public function getExpectedType() + { + return $this->expectedType; + } + + /** + * @return OpPath|object + */ + public function getOperation() + { + return $this->operation; + } +} diff --git a/src/JsonPatch.php b/src/JsonPatch.php index 5b07e2c..1b2d239 100644 --- a/src/JsonPatch.php +++ b/src/JsonPatch.php @@ -59,7 +59,6 @@ public static function import(array $data) if (is_array($operation)) { $operation = (object)$operation; } - if (!is_object($operation)) { throw new Exception('Invalid patch operation - should be a JSON object'); } @@ -71,6 +70,13 @@ public static function import(array $data) throw new MissingFieldException('path', $operation); } + if (!is_string($operation->op)) { + throw new InvalidFieldTypeException('op', 'string', $operation); + } + if (!is_string($operation->path)) { + throw new InvalidFieldTypeException('path', 'string', $operation); + } + $op = null; switch ($operation->op) { case Add::OP: @@ -104,6 +110,8 @@ public static function import(array $data) } elseif ($op instanceof OpPathFrom) { if (!isset($operation->from)) { throw new MissingFieldException('from', $operation); + } elseif (!is_string($operation->from)) { + throw new InvalidFieldTypeException('from', 'string', $operation); } $op->from = $operation->from; } diff --git a/tests/src/JsonPatchTest.php b/tests/src/JsonPatchTest.php index e15c910..fa4ac7b 100644 --- a/tests/src/JsonPatchTest.php +++ b/tests/src/JsonPatchTest.php @@ -3,6 +3,7 @@ namespace Swaggest\JsonDiff\Tests; use Swaggest\JsonDiff\Exception; +use Swaggest\JsonDiff\InvalidFieldTypeException; use Swaggest\JsonDiff\JsonDiff; use Swaggest\JsonDiff\JsonPatch; use Swaggest\JsonDiff\JsonPatch\OpPath; @@ -110,6 +111,52 @@ public function testInvalidOp() } } + /** + * @dataProvider provideInvalidFieldType + * + * @param object $operation + * @param string $expectedMessage + * @param string $expectedField + * @param string $expectedType + */ + public function testInvalidFieldType($operation, $expectedMessage, $expectedField, $expectedType) + { + try { + JsonPatch::import(array($operation)); + $this->fail('Expected exception was not thrown'); + } catch (Exception $exception) { + $this->assertInstanceOf(InvalidFieldTypeException::class, $exception); + $this->assertSame($expectedMessage, $exception->getMessage()); + $this->assertSame($expectedField, $exception->getField()); + $this->assertSame($expectedType, $exception->getExpectedType()); + $this->assertSame($operation, $exception->getOperation()); + } + } + + public function provideInvalidFieldType() + { + return [ + '"op" invalid type' => [ + (object)array('op' => array('foo' => 'bar'), 'path' => '/123', 'value' => 'test'), + 'Invalid field type - "op" should be of type: string', + 'op', + 'string' + ], + '"path" invalid type' => [ + (object)array('op' => 'add', 'path' => array('foo' => 'bar'), 'value' => 'test'), + 'Invalid field type - "path" should be of type: string', + 'path', + 'string' + ], + '"from" invalid type' => [ + (object)array('op' => 'move', 'path' => '/123', 'from' => array('foo' => 'bar')), + 'Invalid field type - "from" should be of type: string', + 'from', + 'string' + ] + ]; + } + public function testMissingFrom() { $this->setExpectedException(get_class(new Exception()), 'Missing "from" in operation data');