├── .github └── workflows │ └── tests.yaml ├── .gitignore ├── .php-cs-fixer.dist.php ├── CHANGELOG.md ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── phpstan.neon ├── phpunit.xml.dist ├── src └── Mcfedr │ └── JsonFormBundle │ ├── Controller │ ├── JsonController.php │ └── JsonControllerTrait.php │ ├── DependencyInjection │ └── McfedrJsonFormExtension.php │ ├── EventListener │ └── ExceptionListener.php │ ├── Exception │ ├── InvalidFormHttpException.php │ ├── InvalidJsonHttpException.php │ ├── JsonHttpException.php │ └── MissingFormHttpException.php │ ├── McfedrJsonFormBundle.php │ └── Resources │ └── config │ └── services.yml └── tests ├── Mcfedr └── JsonFormBundle │ ├── Controller │ └── TestController.php │ ├── Tests │ └── Controller │ │ ├── JsonControllerCheckboxTest.php │ │ ├── JsonControllerTest.php │ │ └── TestControllerTest.php │ └── Type │ └── TestType.php ├── TestKernel.php ├── bootstrap.php ├── config_test.yml ├── console ├── console_application_loader.php └── routing.yml /.github/workflows/tests.yaml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | 6 | jobs: 7 | tests: 8 | runs-on: ubuntu-18.04 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | version: 13 | - php: '8.0' 14 | symfony: '5.4' 15 | - php: '8.0' 16 | symfony: '6.0' 17 | name: PHP ${{ matrix.version.php }} Symfony ${{ matrix.version.symfony }} 18 | steps: 19 | - uses: actions/checkout@v2 20 | - uses: shivammathur/setup-php@v2 21 | with: 22 | php-version: ${{ matrix.version.php }} 23 | tools: phpunit-bridge, flex 24 | extensions: pdo_sqlite, redis 25 | coverage: none 26 | - run: | 27 | composer config extra.symfony.require ${{ matrix.version.symfony }} 28 | composer update 29 | - run: vendor/bin/php-cs-fixer fix --dry-run --diff 30 | - run: tests/console cache:clear 31 | - run: vendor/bin/phpstan analyse 32 | - run: vendor/bin/phpunit 33 | env: 34 | SYMFONY_DEPRECATIONS_HELPER: 'disabled=1' 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | /tests/cache/ 3 | /tests/logs/ 4 | /var 5 | /.phpunit.result.cache 6 | /.php-cs-fixer.cache 7 | -------------------------------------------------------------------------------- /.php-cs-fixer.dist.php: -------------------------------------------------------------------------------- 1 | in(['src', 'tests']); 5 | 6 | return (new PhpCsFixer\Config()) 7 | ->setRules([ 8 | '@PhpCsFixer' => true, 9 | '@PhpCsFixer:risky' => true, 10 | '@DoctrineAnnotation' => true, 11 | '@PHP71Migration' => true, 12 | '@PHP71Migration:risky' => true, 13 | 'array_syntax' => ['syntax' => 'short'], 14 | 'declare_strict_types' => true, 15 | 'list_syntax' => ['syntax' => 'short'], 16 | 'mb_str_functions' => true, 17 | 'no_superfluous_phpdoc_tags' => true, 18 | 'ordered_imports' => true, 19 | 'phpdoc_to_return_type' => true, 20 | 'yoda_style' => false, 21 | 'php_unit_strict' => false, 22 | 'php_unit_test_class_requires_covers' => false, 23 | ]) 24 | ->setRiskyAllowed(true) 25 | ->setFinder($finder); 26 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 4.7.0 2 | 3 | - Drop Symfony 3.x 4 | - Add Symfony 5.x 5 | - Undeprecate the JsonController 6 | 7 | ## 4.6.0 8 | - Drop support for php less than 7.2 9 | - Add strict_types 10 | - Upgrade phpunit 11 | - Add phpstan 12 | 13 | ## 4.5.0 14 | - Fix use of getParameter in JsonControllerTrait 15 | - Deprecate JsonController 16 | 17 | ## 4.4.0 18 | - Change to using FormInterface instead of Form 19 | 20 | ## 4.3.0 21 | - Don't log json errors, ends up double logging because the resulting http exception is still logged 22 | 23 | ## 4.2.0 24 | - Add a better top level message by combining all the inner messages 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 mcfedr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Json Form helper 2 | 3 | Simply use the `JsonControllerTrait` and then use forms as you would normally, 4 | but they now expect to receive JSON. 5 | 6 | [![Latest Stable Version](https://poser.pugx.org/mcfedr/json-form/v/stable.png)](https://packagist.org/packages/mcfedr/json-form) 7 | [![License](https://poser.pugx.org/mcfedr/json-form/license.png)](https://packagist.org/packages/mcfedr/json-form) 8 | [![Build Status](https://travis-ci.org/mcfedr/json-form.svg?branch=master)](https://travis-ci.org/mcfedr/json-form) 9 | 10 | ## Install 11 | 12 | ### Composer 13 | 14 | ```bash 15 | php composer.phar require mcfedr/json-form 16 | ``` 17 | 18 | ### AppKernel 19 | 20 | Include the bundle in your AppKernel 21 | 22 | ```php 23 | public function registerBundles() 24 | { 25 | $bundles = array( 26 | ... 27 | new Mcfedr\JsonFormBundle\McfedrJsonFormBundle() 28 | ``` 29 | 30 | ## JSON 31 | 32 | The expected JSON will be just like that form values that would be sent. 33 | 34 | Suppose you have the following form type 35 | 36 | ```php 37 | class AccountType extends AbstractType 38 | { 39 | public function buildForm(FormBuilderInterface $builder, array $options) 40 | { 41 | $builder 42 | ->add('name'); 43 | } 44 | 45 | public function getBlockPrefix() 46 | { 47 | return 'account'; 48 | } 49 | } 50 | ``` 51 | 52 | Then the JSON should be 53 | 54 | ```json 55 | { 56 | "account": { 57 | "name": "Fred" 58 | } 59 | } 60 | ``` 61 | 62 | ## Example 63 | 64 | ```php 65 | class AccountController extends AbstractController 66 | use JsonControllerTrait; 67 | 68 | /** 69 | * @Route("/accounts", methods={"POST"}) 70 | */ 71 | public function accountCreateAction(Request $request, $uuid) { 72 | $account = new Account(); 73 | $form = $this->createJsonForm(AccountType::class, $account); 74 | $this->handleJsonForm($form, $request); 75 | 76 | $em = $this->getDoctrine()->getManager(); 77 | $em->persist($account); 78 | $em->flush(); 79 | 80 | return $this->json([ 81 | 'account' => $account 82 | ]); 83 | } 84 | } 85 | ``` 86 | 87 | For Symfony 3.x you will need to extend `Controller` because the trait needs 88 | access to `getParameter` method. 89 | 90 | ## Contributing 91 | 92 | To run the tests 93 | 94 | ```bash 95 | ./vendor/bin/php-cs-fixer fix 96 | ./vendor/bin/phpunit 97 | ./vendor/bin/phpstan analyse 98 | ``` 99 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mcfedr/json-form", 3 | "description": "A couple of helper files for handling json with symfony forms", 4 | "keywords": ["json", "forms", "symfony"], 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Fred Cox", 9 | "email": "mcfedr@gmail.com" 10 | } 11 | ], 12 | "type": "symfony-bundle", 13 | "minimum-stability": "stable", 14 | "autoload": { 15 | "psr-4": { "Mcfedr\\JsonFormBundle\\": "src/Mcfedr/JsonFormBundle" } 16 | }, 17 | "autoload-dev": { 18 | "psr-4": { "Mcfedr\\JsonFormBundle\\": "tests/Mcfedr/JsonFormBundle" }, 19 | "classmap": ["tests/TestKernel.php"] 20 | }, 21 | "require": { 22 | "php": ">=8.0", 23 | "symfony/framework-bundle": "^5.0|^6.0", 24 | "sensio/framework-extra-bundle": "^5.0|^6.0", 25 | "symfony/form": "^5.0|^6.0", 26 | "symfony/validator": "^5.0|^6.0", 27 | "psr/container": "^1.0" 28 | }, 29 | "require-dev": { 30 | "phpunit/phpunit": "^9", 31 | "symfony/monolog-bundle": "^3.0|^4.0", 32 | "friendsofphp/php-cs-fixer": "^2.0|^3.0", 33 | "symfony/browser-kit": "^5.0|^6.0", 34 | "phpstan/phpstan-phpunit": "^0.12", 35 | "phpstan/phpstan-symfony": "^0.12", 36 | "phpstan/phpstan-doctrine": "^0.12", 37 | "symfony/phpunit-bridge": "^5.0|^6.0", 38 | "symfony/yaml": "^5.0|^6.0" 39 | }, 40 | "config": { 41 | "allow-plugins": { 42 | "composer/package-versions-deprecated": true 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | includes: 2 | - vendor/phpstan/phpstan-phpunit/extension.neon 3 | # - vendor/phpstan/phpstan-symfony/extension.neon 4 | - vendor/phpstan/phpstan-doctrine/extension.neon 5 | parameters: 6 | # symfony: 7 | # container_xml_path: %rootDir%/../../../var/cache/test/testsTestKernelTestDebugContainer.xml 8 | # console_application_loader: %rootDir%/../../../tests/console_application_loader.php 9 | level: 1 10 | paths: 11 | - src/ 12 | - tests/ 13 | excludes_analyse: 14 | - tests/cache/ 15 | ignoreErrors: 16 | - 17 | message: '#Class Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder does not have a constructor and must be instantiated without any parameters#' 18 | path: %rootDir%/../../../src/Mcfedr/QueueManagerBundle/DependencyInjection/Configuration.php 19 | reportUnmatchedIgnoredErrors: false 20 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | src 7 | 8 | 9 | src/*/*Bundle/Resources 10 | 11 | 12 | 13 | 14 | tests/*/*Bundle/Tests 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Mcfedr/JsonFormBundle/Controller/JsonController.php: -------------------------------------------------------------------------------- 1 | checkCsrf($options); 30 | 31 | return $this->container->get('form.factory')->create($type, $data, $options); 32 | } 33 | 34 | /** 35 | * @param null|mixed $data 36 | * 37 | * @throws \Psr\Container\ContainerExceptionInterface 38 | * @throws \Psr\Container\NotFoundExceptionInterface 39 | */ 40 | public function createJsonFormBuilder($data = null, array $options = []): FormBuilderInterface 41 | { 42 | $this->checkCsrf($options); 43 | 44 | return $this->container->get('form.factory')->createBuilder(FormType::class, $data, $options); 45 | } 46 | 47 | /** 48 | * @param callable $preValidation callback to be called before the form is validated 49 | * 50 | * @throws \Mcfedr\JsonFormBundle\Exception\InvalidFormHttpException 51 | * @throws \Mcfedr\JsonFormBundle\Exception\MissingFormHttpException 52 | * @throws \Mcfedr\JsonFormBundle\Exception\InvalidJsonHttpException 53 | */ 54 | protected function handleJsonForm(FormInterface $form, Request $request, callable $preValidation = null): void 55 | { 56 | $bodyJson = $request->getContent(); 57 | if (!($body = json_decode($bodyJson, true))) { 58 | throw new InvalidJsonHttpException(); 59 | } 60 | 61 | if (!isset($body[$form->getName()])) { 62 | throw new MissingFormHttpException($form); 63 | } 64 | 65 | $form->submit($body[$form->getName()]); 66 | 67 | if ($preValidation) { 68 | $preValidation(); 69 | } 70 | 71 | if (!$form->isValid()) { 72 | throw new InvalidFormHttpException($form); 73 | } 74 | } 75 | 76 | private function checkCsrf(array &$options): void 77 | { 78 | if (!\array_key_exists('csrf_protection', $options) && $this->jsonControllerGetParameter('form.type_extension.csrf.enabled')) { 79 | $options['csrf_protection'] = false; 80 | } 81 | } 82 | 83 | /** 84 | * @throws \Psr\Container\ContainerExceptionInterface 85 | * @throws \Psr\Container\NotFoundExceptionInterface 86 | */ 87 | private function jsonControllerGetParameter(string $name): mixed 88 | { 89 | // If the controller isn't registered as a service, the container will 90 | // be the full Container, as was default in 3.0 91 | if ($this->container->has('parameter_bag')) { 92 | return $this->container->get('parameter_bag')->get($name); 93 | } 94 | if (method_exists($this->container, 'getParameter')) { 95 | return $this->container->getParameter($name); 96 | } 97 | if (method_exists($this, 'getParameter')) { 98 | return $this->getParameter($name); 99 | } 100 | 101 | throw new \LogicException('Cannot get parameters'); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/Mcfedr/JsonFormBundle/DependencyInjection/McfedrJsonFormExtension.php: -------------------------------------------------------------------------------- 1 | load('services.yml'); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Mcfedr/JsonFormBundle/EventListener/ExceptionListener.php: -------------------------------------------------------------------------------- 1 | getThrowable(); 16 | 17 | if ($exception instanceof JsonHttpException) { 18 | $errorData = [ 19 | 'error' => [ 20 | 'code' => $exception->getStatusCode(), 21 | 'message' => $exception->getMessage(), 22 | ], 23 | ]; 24 | if (($data = $exception->getData())) { 25 | $errorData['error']['info'] = $data; 26 | } 27 | $response = new JsonResponse($errorData); 28 | $event->setResponse($response); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Mcfedr/JsonFormBundle/Exception/InvalidFormHttpException.php: -------------------------------------------------------------------------------- 1 | getAllErrors($form); 17 | parent::__construct(400, implode(' ', $this->simpleError($data)), $data); 18 | } 19 | 20 | public function simpleError(array $errors): array 21 | { 22 | $iterator = new RecursiveArrayIterator($errors); 23 | $recursive = new RecursiveIteratorIterator( 24 | $iterator, 25 | RecursiveIteratorIterator::SELF_FIRST 26 | ); 27 | $err = []; 28 | foreach ($recursive as $key => $value) { 29 | if ('errors' === $key && \count($value) > 0) { 30 | foreach ($value as $error) { 31 | $err[] = $error['message']; 32 | } 33 | } 34 | } 35 | 36 | return $err; 37 | } 38 | 39 | /** 40 | * @return ?\Symfony\Component\Form\FormError[] 41 | */ 42 | protected function getAllErrors(FormInterface $form): ?array 43 | { 44 | $errors = $form->getErrors(); 45 | $children = $form->all(); 46 | if (!\count($errors) && !\count($children)) { 47 | return null; 48 | } 49 | 50 | $section = [ 51 | 'field' => $form->getName(), 52 | ]; 53 | 54 | if (\count($errors)) { 55 | $section['errors'] = array_map( 56 | function (FormError $error) { 57 | return [ 58 | 'message' => $error->getMessage(), 59 | 'parameters' => $error->getMessageParameters(), 60 | ]; 61 | }, 62 | iterator_to_array($form->getErrors()) 63 | ); 64 | } 65 | 66 | if (\count($children)) { 67 | $section['children'] = array_values( 68 | array_filter( 69 | array_map( 70 | function (FormInterface $field) { 71 | return $this->getAllErrors($field); 72 | }, 73 | $form->all() 74 | ) 75 | ) 76 | ); 77 | 78 | if (!\count($errors) && !\count($section['children'])) { 79 | return null; 80 | } 81 | } 82 | 83 | return $section; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Mcfedr/JsonFormBundle/Exception/InvalidJsonHttpException.php: -------------------------------------------------------------------------------- 1 | setData($data); 26 | } 27 | 28 | public function getData() 29 | { 30 | return $this->data; 31 | } 32 | 33 | public function setData($data): void 34 | { 35 | $this->data = $data; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Mcfedr/JsonFormBundle/Exception/MissingFormHttpException.php: -------------------------------------------------------------------------------- 1 | getName()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Mcfedr/JsonFormBundle/McfedrJsonFormBundle.php: -------------------------------------------------------------------------------- 1 | createJsonForm(TestType::class); 32 | $this->handleJsonForm($form, $request); 33 | 34 | return new JsonResponse($form->getData()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Mcfedr/JsonFormBundle/Tests/Controller/JsonControllerCheckboxTest.php: -------------------------------------------------------------------------------- 1 | controller = $this->getMockBuilder(JsonController::class)->disableOriginalConstructor()->getMock(); 35 | $validator = Validation::createValidator(); 36 | $this->form = Forms::createFormFactoryBuilder() 37 | ->addExtension(new ValidatorExtension($validator)) 38 | ->getFormFactory() 39 | ->createBuilder() 40 | ->add('one', CheckboxType::class) 41 | ->getForm() 42 | ; 43 | } 44 | 45 | public function testHandleTrue(): void 46 | { 47 | $request = new Request([], [], [], [], [], [], json_encode([ 48 | 'form' => [ 49 | 'one' => true, 50 | ], 51 | ])); 52 | 53 | $this->invokeMethod($this->controller, 'handleJsonForm', [$this->form, $request]); 54 | 55 | static::assertEquals($this->form->getData()['one'], true); 56 | } 57 | 58 | public function testHandleFalse(): void 59 | { 60 | $request = new Request([], [], [], [], [], [], json_encode([ 61 | 'form' => [ 62 | 'one' => false, 63 | ], 64 | ])); 65 | 66 | $this->invokeMethod($this->controller, 'handleJsonForm', [$this->form, $request]); 67 | 68 | static::assertEquals($this->form->getData()['one'], false); 69 | } 70 | 71 | /** 72 | * Call protected/private method of a class. 73 | * 74 | * @param object $object instantiated object that we will run method on 75 | * @param string $methodName Method name to call 76 | * @param array $parameters array of parameters to pass into method 77 | * 78 | * @return mixed method return 79 | */ 80 | private function invokeMethod($object, $methodName, array $parameters = []): mixed 81 | { 82 | $reflection = new \ReflectionClass(\get_class($object)); 83 | $method = $reflection->getMethod($methodName); 84 | $method->setAccessible(true); 85 | 86 | return $method->invokeArgs($object, $parameters); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /tests/Mcfedr/JsonFormBundle/Tests/Controller/JsonControllerTest.php: -------------------------------------------------------------------------------- 1 | controller = $this->getMockBuilder(JsonController::class)->disableOriginalConstructor()->getMock(); 38 | $validator = Validation::createValidator(); 39 | $this->form = Forms::createFormFactoryBuilder() 40 | ->addExtension(new ValidatorExtension($validator)) 41 | ->getFormFactory() 42 | ->createBuilder() 43 | ->add('one', ChoiceType::class, [ 44 | 'choices' => ['value' => 'value'], 45 | ]) 46 | ->getForm() 47 | ; 48 | } 49 | 50 | public function testHandleJsonForm(): void 51 | { 52 | $request = new Request([], [], [], [], [], [], json_encode([ 53 | 'form' => [ 54 | 'one' => 'value', 55 | ], 56 | ])); 57 | 58 | $this->invokeMethod($this->controller, 'handleJsonForm', [$this->form, $request]); 59 | 60 | static::assertEquals($this->form->getData()['one'], 'value'); 61 | } 62 | 63 | public function testHandleJsonFormInvalid(): void 64 | { 65 | $this->expectException(InvalidJsonHttpException::class); 66 | $request = new Request([], [], [], [], [], [], 'some non json text'); 67 | 68 | $this->invokeMethod($this->controller, 'handleJsonForm', [$this->form, $request]); 69 | } 70 | 71 | public function testHandleJsonFormMissing(): void 72 | { 73 | $this->expectException(MissingFormHttpException::class); 74 | $request = new Request([], [], [], [], [], [], json_encode(['wrong' => 'data'])); 75 | 76 | $this->invokeMethod($this->controller, 'handleJsonForm', [$this->form, $request]); 77 | } 78 | 79 | public function testHandleJsonFormInvalidData(): void 80 | { 81 | $this->expectException(InvalidFormHttpException::class); 82 | $request = new Request([], [], [], [], [], [], json_encode([ 83 | 'form' => [ 84 | 'one' => 'other', 85 | ], 86 | ])); 87 | 88 | $this->invokeMethod($this->controller, 'handleJsonForm', [$this->form, $request]); 89 | } 90 | 91 | /** 92 | * Call protected/private method of a class. 93 | * 94 | * @param object $object instantiated object that we will run method on 95 | * @param string $methodName Method name to call 96 | * @param array $parameters array of parameters to pass into method 97 | * 98 | * @return mixed method return 99 | */ 100 | private function invokeMethod($object, $methodName, array $parameters = []): mixed 101 | { 102 | $reflection = new \ReflectionClass(\get_class($object)); 103 | $method = $reflection->getMethod($methodName); 104 | $method->setAccessible(true); 105 | 106 | return $method->invokeArgs($object, $parameters); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /tests/Mcfedr/JsonFormBundle/Tests/Controller/TestControllerTest.php: -------------------------------------------------------------------------------- 1 | request('GET', '/invalid'); 24 | 25 | static::assertEquals(400, $client->getResponse()->getStatusCode()); 26 | static::assertEquals('application/json', $client->getResponse()->headers->get('content-type')); 27 | 28 | $data = json_decode($client->getResponse()->getContent(), true); 29 | 30 | static::assertIsArray($data); 31 | static::assertCount(1, $data); 32 | static::assertIsArray($data['error']); 33 | static::assertCount(2, $data['error']); 34 | static::assertEquals(400, $data['error']['code']); 35 | static::assertEquals('Invalid JSON', $data['error']['message']); 36 | } 37 | 38 | public function testFormAction(): void 39 | { 40 | $client = static::createClient(); 41 | $client->request('POST', '/form', [], [], [], json_encode([ 42 | 'form' => [ 43 | 'one' => 'value', 44 | 'two' => false, 45 | ], 46 | ])); 47 | 48 | static::assertEquals(200, $client->getResponse()->getStatusCode()); 49 | } 50 | 51 | public function testFormActionCheckbox(): void 52 | { 53 | $client = static::createClient(); 54 | $client->request('POST', '/form', [], [], [], json_encode([ 55 | 'form' => [ 56 | 'one' => 'value', 57 | ], 58 | ])); 59 | $data = json_decode($client->getResponse()->getContent(), true); 60 | static::assertFalse($data['two']); 61 | 62 | static::ensureKernelShutdown(); 63 | $client = static::createClient(); 64 | $client->request('POST', '/form', [], [], [], json_encode([ 65 | 'form' => [ 66 | 'one' => 'value', 67 | 'two' => true, 68 | ], 69 | ])); 70 | $data = json_decode($client->getResponse()->getContent(), true); 71 | static::assertTrue($data['two']); 72 | 73 | static::ensureKernelShutdown(); 74 | $client = static::createClient(); 75 | $client->request('POST', '/form', [], [], [], json_encode([ 76 | 'form' => [ 77 | 'one' => 'value', 78 | 'two' => false, 79 | ], 80 | ])); 81 | $data = json_decode($client->getResponse()->getContent(), true); 82 | static::assertFalse($data['two']); 83 | } 84 | 85 | public function testFormInvalidAction(): void 86 | { 87 | $client = static::createClient(); 88 | $client->request('POST', '/form', [], [], [], json_encode([ 89 | 'form' => [ 90 | 'one' => 'value', 91 | 'two' => true, 92 | 'three' => 'value', 93 | 'number' => 'string', 94 | ], 95 | ])); 96 | 97 | static::assertEquals(400, $client->getResponse()->getStatusCode()); 98 | static::assertEquals('application/json', $client->getResponse()->headers->get('content-type')); 99 | 100 | $data = json_decode($client->getResponse()->getContent(), true); 101 | 102 | static::assertIsArray($data); 103 | static::assertCount(1, $data); 104 | static::assertIsArray($data['error']); 105 | static::assertCount(3, $data['error']); 106 | static::assertEquals(400, $data['error']['code']); 107 | static::assertEquals('This form should not contain extra fields. Please enter a number.', $data['error']['message']); 108 | static::assertIsArray($data['error']['info']); 109 | } 110 | 111 | public function testFormErrorMessageAction(): void 112 | { 113 | $client = static::createClient(); 114 | $client->request('POST', '/form', [], [], [], json_encode([ 115 | 'form' => [ 116 | 'one' => 'value', 117 | 'two' => true, 118 | 'email' => 'test', 119 | ], 120 | ])); 121 | 122 | static::assertEquals(400, $client->getResponse()->getStatusCode()); 123 | static::assertEquals('application/json', $client->getResponse()->headers->get('content-type')); 124 | 125 | $data = json_decode($client->getResponse()->getContent(), true); 126 | 127 | static::assertIsArray($data); 128 | static::assertCount(1, $data); 129 | static::assertIsArray($data['error']); 130 | static::assertCount(3, $data['error']); 131 | static::assertEquals(400, $data['error']['code']); 132 | static::assertEquals('This value is not a valid email address.', $data['error']['message']); 133 | static::assertIsArray($data['error']['info']); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /tests/Mcfedr/JsonFormBundle/Type/TestType.php: -------------------------------------------------------------------------------- 1 | add('one', ChoiceType::class, [ 21 | 'choices' => ['value' => 'value'], 22 | ]) 23 | ->add('two', CheckboxType::class) 24 | ->add('number', NumberType::class, ['invalid_message' => 'Please enter a number.']) 25 | ->add('email', EmailType::class, [ 26 | 'constraints' => new Email(), 27 | ]) 28 | ; 29 | } 30 | 31 | /** 32 | * Returns the name of this type. 33 | * 34 | * @return string The name of this type 35 | */ 36 | public function getBlockPrefix(): string 37 | { 38 | return 'form'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/TestKernel.php: -------------------------------------------------------------------------------- 1 | load(__DIR__.'/config_test.yml'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | run($input); 22 | -------------------------------------------------------------------------------- /tests/console_application_loader.php: -------------------------------------------------------------------------------- 1 |