-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Form] Fixed edge case where empty data may not be a string and throws TransformationFailedException #13598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… it throws a TransformationFailedException with message: 'Expected a string.'.
After investigating more on how I hit this corner case, I have more information. |
Definitely needs tests |
Also see #5939 |
@Tobion I completely understand that quoted value leads to proper response. That's what I'm using internally in address this issue. |
In any case, this cannot be accepted without tests |
@guilhermeblanco Any chance you can add some tests? |
@fabpot I need to remember the situation that I hit it, but yes, I can add tests for this. =) |
Thank you for submitting this PR @guilhermeblanco! This is a duplicate of #12470. The underlying problem here is #4715, which can't be fixed without breaking BC. Every other solution is unfortunately a hack. I recommend that you use a custom model transformer that sets your default value instead until #4715 is fixed. |
@webmozart Yes, it is a duplicate. However, can you explain me how does this solution qualify as a BC break? |
Reopened after talking to @guilhermeblanco in person. This solution makes sense. Could you please rebase this on 2.3 and add tests? |
@guilhermeblanco Any news on this one? |
@fabpot should be able to do it in the next few days. =) |
@guilhermeblanco Sorry for being pushy, but we try hard to merge/close old PRs. Any chance you can have a look at this one? |
@fabpot I've spent a substantial amount of hours trying to recreate this scenario on both SimpleFormTest and CompoundFormTest without success. |
I've tried to add tests in Here's what I've tried : public function testSubmitNull()
{
$form = $this->factory->create('integer');
$form->submit(null);
$this->assertNull($form->getData());
$this->assertNull($form->getViewData());
}
public function testSubmitNullWithEmptyData()
{
$form = $this->factory->create('integer', null, array(
'empty_data' => 1,
));
$form->submit(null);
$this->assertSame(1, $form->getData());
$this->assertSame('1', $form->getViewData());
}
public function testSubmitNullWithEmptyDataWhenNested()
{
$form = $this->factory->create('form')
->add('age', 'integer', array(
'empty_data' => 1,
));
$form->submit(null);
$this->assertSame(1, $form->get('age')->getData());
$this->assertSame('1', $form->get('age')->getViewData());
} |
@HeahDude IntegerTypeTest requires the intl extension (have a look at the setUp() method). |
@jakzal thanks, will take another look though. |
@jakzal, I've checked and I have intl installed, but tests are skipped even with my global phpunit. Any lead ? |
@HeahDude if I remember correctly it needs to be installed in a specific version. You'll need to look into the code that makes the check. |
@HeahDude PHPUnit tells you why a test was skipped if you pass the #14260 proposes to upgrade to ICU 55.1, which would solve your problem. Would you like to work on that ticket? |
IIUC, the change is good but we don't know (yet) how to write good unit tests to avoid regressions, is that correct? |
@fabpot correct. Patch addresses nicely the problem in the known scenario: 2 integer fields with empty_data as integer values and submitting only one of the values (thus requiring the second to use the empty_data). |
Understood. So, instead of waiting for tests, and because this is a bug fix that is waiting here for so long, I propose to merge this as is for now. ping @symfony/deciders |
@fabpot I'll talk to @guilhermeblanco and try to create some tests. If we don't, chances are that this gets refactored away again when optimizing the |
@guilhermeblanco, is the form compound in your scenario ? I think it may be either not relevant or some cause of this problem. |
I'm fine to have this merged - as long as we don't have any BC concerns. If this introduces an edge-case behavior change, I'm not clear what that change is - I'd like to see the before/after code in an UPGRADE file. I want to avoid this causing upgrade issues - it sounds like something that would be quite hard to track down. |
I took @guilhermeblanco's commit and the tests suggested by @HeahDude (with a minor change where the view data are not expected to be |
Nice job! I would suggest: // CheckBoxTypeTest.php
public function testSubmitNullWithEmptyDataTrueWhenNested()
{
$form = $this->factory->create('form')
->add('agree', 'checkbox', array(
'empty_data' => true,
));
$form->submit(null);
$this->assertTrue($form->get('agree')->getData());
$this->assertSame('1', $form->get('agree')->getViewData());
$view = $form->get('agree')->createView();
$this->assertTrue($view->vars['checked']);
}
public function testSubmitNullWithEmptyDataFalseWhenNested()
{
$form = $this->factory->create('form')
->add('agree', 'checkbox', array(
'empty_data' => false,
));
$form->submit(null);
$this->assertFalse($form->get('agree')->getData());
$this->assertEmpty($form->get('agree')->getViewData());
$view = $form->get('agree')->createView();
$this->assertFalse($view->vars['checked']);
} And I confirm those tests fail without the fix. |
@HeahDude Thanks, test added. |
Closed for the reasons discussed in #18047. |
I just can't recreate this error, by any means.
I somehow have a form with an integer type which happens to submit "null" as
viewData
(somehow) and it reusesempty_data
option. Now my field was configured like:And since the assignment of
viewData
is theempty_data
, one of the normalizers (while callingviewToNorm()
) throws aTransformationFailedException
with the following message:Expected a string.