Closed (fixed)
Project:
Drupal core
Version:
8.2.x-dev
Component:
editor.module
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
5 Jan 2016 at 22:46 UTC
Updated:
2 Aug 2016 at 16:14 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
Matt_five commentedComment #3
Matt_five commentedComment #4
Matt_five commentedHello,
Please find the revised patch and the WebTest.
Since the "EditorSettingsValidationTest.php" cannot be uploaded due to extension restriction, I had renamed to "EditorSettingsValidationTest.txt".
Thanks you.
Comment #6
dawehnerIs this check really needed? A nesting of 3 levels just seems to be too much.
Comment #7
Matt_five commentedReally thank for the review and comment.
Since the system need to accept the situation when both value are Empty.
If the related code was removed, it would not simple identify the case "Empty width - Empty height" as valid input at the beginning.
Comment #8
Matt_five commentedThe patch was updated to include the test file.
Comment #9
Matt_five commentedComment #10
deepshikha.singh commentedComment #11
swarad07Hey Matt_five, the patch does fix the issue.
Can you make sure the code follows drupal standards, for example here the function does not have any comment block.
Comment #12
Matt_five commentedThanks for the review.
Please find the updated patch.
Comment #13
Matt_five commentedComment #14
Matt_five commentedHi,
Would anyone have advise for the issue ?
Comment #15
thpoul commented@Matt_five You should read the Coding Standards set by the Drupal community as the patch does not comply with them. In the meantime you could unassign the issue so somebody else could help move it forward.
Comment #16
thpoul commentedTest only patch. Should fail
Comment #17
thpoul commentedFixed some coding standards issues and changed some checks of the test.
Comment #19
Matt_five commentedThanks thpoul for the review and comment.
Also, I had unassign the issue. Really thanks the advise about assign ownership. Then, I checked https://www.drupal.org/node/2172049 for better understanding for "assigned".
Comment #20
wim leersLooking great! :) This is definitely the right direction.
My remarks are mostly nitpicks, and organization/repetitiveness of the test. Should be easy to fix :)
Thanks so much for pushing this forward!
Nit: Needs to be reduced to a single line. Look elsewhere in core for inspiration on how to do that.
This Should use
$form_state->getValue('width')etc.Nit: s/@name/%name/
This makes this test very very very very slow. This is fine for a first iteration of this test though, because it means less work for you :)
But instead of doing this, either import the
basic_htmltext format + text editor directly, or duplicate them.s/array()/[]/, this is a new class, so let's use the short notation everywhere in this class.
Nit:
Editor::load()Why this assert?
This can be split off into a helper method, this happens multiple times.
This can also be split off to a helper method.
Comment #21
thpoul commented@Matt_five: Glad I could help!
@Wim Leers: Thank you for the review! Not sure how to change that since I initially got inspired from
\Drupal\ckeditor\Plugin\CKEditorPlugin\DrupalImage::validateImageUploadSettings()and\Drupal\ckeditor\Plugin\CKEditorPlugin\StylesCombo::validateStylesValue(). Also I wasn't able to do 2 for some reason. Could you please advice on that?Comment #22
wim leersInterdiff review:
These should still use
$form_state->getValue().Much better! I bet that was ten times faster to run :)
This is confusing. If we'd pass the empty strings explicitly, it wouldn't be confusing.
Same for
setDimensions().Overall patch review:
Not
$this->formator$this->editor, because you don't use them later, and they're not class properties.Just
$formatand$editor.And in fact, not even that. Just
FilterFormat::create([…])->save();:)Let's remove all these comments, none of them add anything meaningful, they're only distracting.
We're not testing 200 vs 400 here. We're always asserting 200. That's not very meaningful. If any response turns out to not be a 200, then all the other assertions will fail anyway. So, let's just remove these assertions and keep it simple, and focus on testing the things that really matter.
Once you've done the previous point, these 4 comments become the *only* comments. That's not by accident: these are the 4 cases you're testing. It's worth explicitly describing those. The rest is just details.
Comment #23
thpoul commentedHopefully this is should almost there :)
Comment #24
wim leersYes! So much better :) Very, very close now. Next one will probably be RTBC.
Why the reference?
And you can simplify this to just:
Why not do
$this->setDimensions('300', '')directly?The expected saved dimensions will not match this anyway, so these variables are useless.
Nit:
setMaxDimensions()s/array()/[]/
This is a helper that combines a bunch of asserts. That should then also have the
assert*prefix.I'd call this
assertSavedMaxDimensions()Omit these messages.
The message will always be displayed, which means you won't actually see what the mismatch is. If you omit the message, you'll get things like "Expected '300' equals '300'." — i.e. useful output.
Comment #25
thpoul commentedThank you for the review! Let see :)
Comment #26
wim leersI wanted to RTBC, but then remembered #20.1 and #21. So, providing the answer you were looking for back then, sorry for forgetting about that in #24.
Suggested alternative:
Nit: s/array()/[]/
Thinking on this again, I think the long-form explanations here are a distraction. They describe the entire behavior that is asserted in the couple of lines that follow.
I'd omit the portions of all of these. Then it's clear what the 4 cases are: they describe the 4 cases you test, not all the detailed consequences.
Nit: these two lines can be combined.
Once those are addressed, I think this patch looks absolutely perfect, and I'll be very confident that if I RTBC it, it will also actually be committed by a core committer :)
Comment #27
thpoul commentedNo worries :D Thank you for reviewing!
Comment #28
wim leersPerfect! :) Funny how the patch size decreased from 8 KB in #17 to <5.5 KB in #27!
Thanks so much!
Comment #29
alexpottI think the drupalPostForm() should have the url and the
setMaxDimensions()should take an argument of the filter format ID. This way we have less code andsetMaxDimensions()has less undeclared dependencies - in order to use it atm you need to do a drupalGet first...Missing a docblock
Asserts are supposed to return a bool which is TRUE on success or FALSE. This method is also missing a doc block.
There is no meaningful message here.
Comment #30
wim leers$this->drupalGet()call intosetMaxDimensions(). No need to make the text format ID a parameter yet at this point.\Drupal\simpletest\WebTestBase::assertUrl(),\Drupal\simpletest\AssertContentTrait::assertTitle(). What matters is that you make an assertion, but that doesn't mean it's boolean. It can be a comparison. I'm very very confused by this statement.Comment #31
wim leersRegarding point 4:
After a lot of comparing with existing
assert*()implementations, I now see what Alex meant.We should assign the result of these two statements to variables (say $a and $b), and then return the result:
return $a && $b;.But I've never realized that until now. I've done it wrong in every test I've ever written. And along with that, 99% of us.
Some of my violations:
\Drupal\ckeditor\Tests\CKEditorTest::assertCKEditorLanguage()\Drupal\big_pipe\Tests\BigPipeTest::assertBigPipeResponseHeadersPresent()Some of our collective violations:
\Drupal\node\Tests\AssertButtonsTrait::assertButtons\Drupal\config\Tests\SchemaCheckTestTrait::assertConfigSchema()Comment #32
wim leersRegarding point 2: I discussed that with Alex Pott on IRC, he pointed out that this is a requirement of the current coding standard. Which is totally fair. I posted #2108785-22: Remove the requirement for doxygen for test methods to hopefully make that coding standard more sensible.
So, I agree with points 1, 2 and 3. Point 4 is IMO very questionable (but easy enough to comply with per #31) and point 5 I still disagree with (though of course I agree having a nicely formatted message that says "Expected width of 55 does not equal the expected width of 60" or "Expected width of 55 equals the expected width of 60" is much nicer, but we don't do that anywhere). Overall I don't understand this extreme nitpicking of tests, I'm very surprised by it.
Comment #33
xjmI'd agree with point 4 (either making the assert method follow the normal pattern or renaming it, and followups to look at the other ones that don't follow the pattern). I can see that point 5 could be interpreted either way.
assertTrue()andassertFalse()have useless assertion messages by default, so it is almost always better to override them (in contrast with likeassertText()where the default assertion message is almost always better than what someone comes up with to replace it).assertEqual()is in between. For the best test debugging the assertion would both show the values that were equal (or not) and what they meant, exactly like the proposed one in #32.This also reminded me of #1601146: Allow custom assertion messages using predefined placeholders again.
Comment #34
thpoul commentedDid the changes according to #29 and #32.
@alexpott: If we want
setMaxDimensions()to take format as an argument, maybeassertSavedMaxDimensions()should do that too. I would do what #30-1 suggested but didn't because of:Comment #35
wim leers#33: Thanks so much for linking to #1601146: Allow custom assertion messages using predefined placeholders, I didn't know about that at all!
Violates 80 cols rule.
We don't ever write
@return void. If nothing is returned, omit@return.You wrote "Expected width" twice. The first one is not the expected width, it's the actual width.
This is not a text editor format, but just a text format.
s/Editor image/associated text editor's image upload/
s/The width/The expected width
s/The height/The expected height/
Comment #36
thpoul commented1. I am not sure how this violates to 80 cols rule.
2. Here are some wrong examples of this practice:
Should I open a new issue to fix these?
Comment #37
thpoul commentedNever mind about 1 I think I understand now.
Comment #38
thpoul commentedComment #40
wim leersAFAICT this addressed all of the feedback in #29 and #35.
Just a few more minor things and then this is ready!
Sets the maximum image dimensions using the UI.
The text format whose associated text editor will be updated.
s/$format/$format_id/
More importantly: remove all the default argument values.
Since we're getting the format ID, we might as well use routes instead of using string concatenation.
Let's do
$this->drupalPostForm(Url::fromRoute('entity.filter_format.edit_form', ['filter_format' => $format_id]), …Remove all the default argument values.
Comment #41
thpoul commentedApplied changes and rerolled for 8.1.x
Comment #42
wim leersThanks!
Comment #43
Matt_five commentedthanks
Comment #45
wim leersLooks like l.d.o was down.
Comment #46
gábor hojtsyYeah I don't think we are testing remote l.d.o download anywhere in the tests, but either way it is not a problem of this patch.
Comment #47
alexpottI've considered the upgrade path. I'm not sure there is anything we can do. We could warn the user that they need to fix them I guess. What happens if only one value is completed?
Comment #48
alexpott@file blocks are now against the coding standard for autoloaded files. Can be fixed on commit if the answer to the upgrade question is that we don't need one.
Comment #49
wim leersNo upgrade path is necessary. I agree there's nothing we can do.
Comment #50
wim leersDid some manual testing.
1. The problem
The configuration for the text editor is used in
EditorImageDialogand is passed tofile_validate_image_resolution(), which is the validation callback ultimately responsible.Its expectation:
It then uses this logic:
2. When walking through it with a debugger using manual testing, what happens?
EditorImageDialogconstructs the string300x, whichfile_validate_image_resolution()parses into$width=300,$height="". It then does$image->getHeight() > $height, which always evaluates to TRUE, so it will always complain.EditorImageDialogconstructs the stringx300, whichfile_validate_image_resolution()parses into$width="",$height=300. It then does$image->getWidth() > $width, which always evaluates to TRUE, so it will always complain.file_validate_image_resolution()works as expected/intended.EditorImageDialogpasses$max_dimensions = 0tofile_validate_image_resolution(), which is also correct, and behaves as expected/intended.Note: #2628656: Max dimensions do not apply to Editor Inline image is the other issue in this area that must land for this functionality to work correctly:
EditorImageDialogboth accesses the wrong keys and constructs that500x500(width x height) string incorrectly… Yes, so much fail on so few lines of code. Clearly we should've had test coverage for this. Fortunately, this issue and #2628656 are now rectifying that!Comment #51
wim leersActually, the code in HEAD is correct…
I manually tested it from an end user's POV with max width 300 and no max height. The end result is a message that says it's been resized to "300x0", but the image was actually resized to 300 pixels wide and the height is calculated automatically: if the max height is 0, it is calculated to retain the same aspect ratio.
So, in fact, this is a valuable feature: you can specify max width or max height, and not care about anything else. Requiring both or neither dimensions would be a feature regression.
So, what actually needs to happen here:
widthandheightcan benullEditorImageDialog:nulland not 0 or something else)Comment #52
wim leersSome parts of the existing test can be reused to address points 4.1 and 4.2. That already provides part of what you need to do 4.3.
I've attached a patch that does point 2, because few people know the Config Schema API well. I'll leave everything else to you, thpoul, if you're up for it. I'll continue mentoring/reviewing you, of course. Sorry for having led you in the wrong direction!
On that note, to be able to points 1 and 3, you actually need max dimensions to be working. So this issue is now effectively blocked on #2628656: Max dimensions do not apply to Editor Inline image.
Comment #53
wim leersOh, actually, most of point 3 can actually be done in #2628656: Max dimensions do not apply to Editor Inline image, the current patch already has the bulk of what is needed! :)
Comment #54
thpoul commentedSwitching to NW since #2628656: Max dimensions do not apply to Editor Inline image is now fixed :)
Comment #55
wim leersIndeed, and YAY!
Updating the IS to reflect which parts were already done in #2628656: Max dimensions do not apply to Editor Inline image.
Comment #56
thpoul commentedRegarding point 1 I think that the problem relies on
file_validate_image_resolution()which takes for granted that there will be provided either both width and height or neither of them. Also the function for some reason asks for the$image->getFileSize()without using it anywhere. I suggest we change the message fromThe image was resized to fit within the maximum allowed dimensions of %dimensions pixels.to something more sophisticated that actually makes sense to the user. Maybe we should let the user know the dimensions of the scaled image and not the maximum allowed ones, maybe both. Suggestions?One more problem I found is that when I tried to upload an image (with max 100px width only set) to replicate the behavior I got the same message twice (see screenshot).
@Wim Leers: Should the test coverage on the same track like the one provided in the previous patches?
Comment #57
wim leers+1
I think letting the user know that it was scaled to fit within the maximum dimensions is simplest and best. If they're sufficiently technically oriented to even care about the actual resized solution, they can inspect the image itself.
The duplicate message problem is a known bug elsewhere in the AJAX system, we don't need to address that here.
Comment #58
thpoul commentedThank you for your review Wim! Hopefully the updated patch is no the right direction and the only thing left todo is to right the relevant tests at
\Drupal\image\Tests\ImageFieldValidateTest::testResolutionComment #59
wim leersThis looks great! Indeed the only remaining task here is updating
\Drupal\image\Tests\ImageFieldValidateTest::testResolution().This fixes points 1 () and points 4.1, 4.2 and 4.3:
In other words: once this patch lands, we have strong, comprehensive test coverage for the image upload maximum dimensions settings, as well as the expected behavior of those settings on uploaded images — awesome!
Here are a few nitpicks:
Nit: s/null/NULL/
This was not being used, nice catch!
Rather than calling
drupal_set_message()from 3 different places, I think it'd be clearer to assign the message to$messagein these 3 places, and then add aat the very end, after those if/else statements.
Comment #60
swarad07Making changes as suggested in #59.
Comment #61
oriol_e9gUltra-minor but sould be
elseifinstead ofelse ifComment #62
wim leers#60 addressed the nits. But we still need this:
Comment #63
thpoul commentedThank you @swarad07 & @oriol_e9g for your input :)
@WimLeers: Hopefully this is close to what we need
Comment #64
thpoul commentedNit spotted :(
Comment #66
wim leersThis looks perfect! :)
Thanks so much, now the configuration of the image upload settings and the
EditorImageDialoghas very solid test coverage — almost completely thanks to you, @thpoul!Nit: These should both be
int[]. Can be fixed on commit.Comment #67
wim leersComment #68
thpoul commentedSome nits :)
Comment #69
wim leersLooks great! :)
Comment #71
thpoul commentedPatch still applies and passes the tests.
Comment #73
gábor hojtsyRandom fail. RTBC as per Wim Leers above.
Comment #74
alexpottGiven this has new strings I think this only can go into 8.2.x.
Committed fbcd924 and pushed to 8.2.x. Thanks!
Comment #77
alexpottComment #78
wim leersAhh, good point! I didn't think of that. Thanks!