Problem/Motivation
The form to install pending updates at /admin/reports/updates/update
(and /admin/modules/update
and /admin/theme/update
) has no notion that some of the available updates are incompatible with your currently installed version of core, and will happily try to download and install them for you. I haven't actually tested what happens, but it seems seriously problematic to leave it as is.
Splitting this off from
#3102724: Improve usability of core compatibility ranges on available updates report
#3096078: Display core compatibility ranges for available module updates
...
For example, with the latest screenshots from #3102724, on a test site setup to believe it's 8.7.10 core, we'd see this:
Compare that with the "Update" page on the same site:
No indication at all that redis 8.x-1.4 (the "Recommended release") won't install on your current version of core (which you still have to manually update, unlike all the contrib updates this form would (try to) install for you...
Proposed resolution
- Harvest some of the compatibility-awareness from #3102724: Improve usability of core compatibility ranges on available updates report and use it on this other page/form, too. YES
- Add similar
Compatible /Not compatible details elements. YES, but to avoid too much noise, only show details for "Not compatible" Disable checkboxes on incompatible updates?NO- Move rows with incompatible releases into another table at the bottom of the page. Either:
Figure out the latest release we could safely upgrade to and call that the recommended release for this form? E.g. given the current scenario from the screenshots, at least the redis 8.x-1.3 release could be installed on that site...- Nah, punt to follow-up: #3115432: Add logic to figure out the latest/recommended release a site could update to with the currently installed version of core
Remaining tasks
Decide what to do:Into what table should incompatible releases be moved? Either existing "Manual updates required" (#10) vs. new "Not compatible" (#14).- Decided: new table.If new, should it be above (#14) or below (#21) core's "Manual updates required"?BelowIf new, do we need a little intro sentence / description? If so, what exactly should it say?No descriptionAny other tweaks / concerns / improvements?None yet
Land #3102724: Improve usability of core compatibility ranges on available updates report so we have the new code we need to make this work.Implement proposed resolution.See #21Add test coverage of new scenarios.Reviews.Figure out how the markup in the new 'Not compatible' table should work so the required changes are both in scope and acceptable to @lauriiiSee #85 and #3121769: Make the table of incompatible releases in UpdateManagerUpdateForm more theme-friendly- RTBC
- Commit
User interface changes
Prototype from patch #21:
API changes
Nothing public. Introduces a new protected
helper method in the UpdateManagerUpdate
form class.
Data model changes
None.
Release notes snippet
The Update Manager provides an 'Update' tab in three locations in the administrative interface (/admin/reports/updates/update
, /admin/modules/update
and /admin/theme/update
). This form allows highly privileged site administrators to install updated versions of contributed modules and themes that have new releases available. Previously, the form had no knowledge of what versions of Drupal core a given update is compatible with, and would try to install incompatible updates. Now, if the recommended version of a given extension is not compatible with the currently installed version of Drupal core, the update will appear in a new "Not compatible" table that shows what versions of core are required for each update.
Comment | File | Size | Author |
---|---|---|---|
#121 | 3113992.120_121.interdiff.txt | 1.13 KB | dww |
#121 | 3113992-121.patch | 19.09 KB | dww |
Comments
Comment #2
dwwAdding screenshot of the problem, and some brainstorming on possible solutions.
Comment #8
dwwWe discussed this on the UX call right this morning. Updates:
Updating proposed resolution accordingly.
Crediting folks from the meeting.
Comment #9
dwwActually, getting this working is going to require code from #3102724: Improve usability of core compatibility ranges on available updates report so I'm calling this postponed for now. We really need to land that one first so we can easily re-use the details element and all the supporting logic.
Comment #10
dwwHere's a very quick proof-of-concept. Requires latest patches from #3102724: Improve usability of core compatibility ranges on available updates report, but given that, this is surprisingly easy to get working. ;)
Comment #11
dwwI'm re-thinking if we actually want
<details>
for this form at all. We're only going to print the message if an update is moved into the 'Manual updates required' table, we presumably always want that message to be seen, and it would save some hassle if we're not trying to use<details>
for it again. Perhaps we should just always show a big warning in that table, "Not compatible. Requires Drupal core: 8.8.0 to 8.8.2" or whatever ?Comment #12
dwwAlso, note that core's 1st column in the table says: "Drupal core (security update)"
So maybe we should re-use the (important thing) pattern and have redis look like this:
Comment #13
dwwNot really up to me, but given the #ux team meeting discussion that we have a UI to badly break your site, seems we need to fix this before 9.0.0-beta1. Tagging for now.
Comment #14
dww#3102724: Improve usability of core compatibility ranges on available updates report has moved on since I posted #10. Here's a new version.
Also, based on a Slack chat in #ux channel, we're now leaning towards a whole separate table for this, instead of lumping it in with "Manual Updates Required".
Comment #15
dwwActually, we're not done yet with "decide what to do", so I uncrossed that off and fleshed it out in the summary with these sub-points:
Re: 3: For now, I vote no. Less words is almost always better UI. But we could easily add it if folks think it's needed.
I'd like to have this patch as close to RTBC as possible when the parent issue lands, so the sooner we can sort out all the "Decide" tasks, the sooner we'll have this ready.
Thanks!
-Derek
Comment #16
dwwFollow-up: #3115432: Add logic to figure out the latest/recommended release a site could update to with the currently installed version of core
Comment #17
klonosYou could re-label the button to something like "Download selected updates". Then also have it so that any incompatible updates either do not have a checkbox next to them, or their checkbox is unticked+locked, or replace the checkbox with a red x. This would allow to keep the updates in a single table, which would simplify the UI.
Other things to consider if this ^^ works:
Comment #18
kualeeRe:2 in #15 if we do stick to having separate table, I reckon having it under core's "Manual updates required" is more logically, as in term of relevance, modules that can be manually updated are far more relevant than those are are incompatible. Taking the order of tables as order of "importance" or "action-ability", it makes a lot more sense for that new table to stick to the bottom. Just my 2cents
Comment #19
mandclu CreditAttribution: mandclu at Northern Commerce commentedFor the cases where some extra explanation might be helpful, could it follow the model of the webform module's interface, where it commonly uses a question mark symbol you can hover over for additional help text? I like this model because experienced users get a nice clean interface, but less experienced users have the additional help text easily accessible.
Comment #20
dwwRe: #17:
- Having disabled checkboxes is almost always a UI WTF.
- Using color could be nice, but it can't be the only indication something is incompatible or it's an accessibility bug.
- I'm not sure that trying to lump everything into a single table would actually improve the UI. It'd make it more complicated in a lot of ways. Separate tables for separate projects in different states means that each table can be processed by the site admin independently. Sadly, the UI can't help you with anything that's not compatible or core itself, so those are basically just here for informational purposes.
Re: #18: Yeah, I agree that the 'Not compatible' table should probably go below the core "Manual updates" table. Sadly, that table is only ever used for core, and only ever has a single row in it. ;) That could potentially be cleaned up in a follow-up (but not here).
Re: #19: Hover / tooltips are usually very hard to make accessible. I'm a big -1 to trying to use that approach here. Honestly, this entire UI is for "less experienced" users. Experienced users are probably using composer to manage their sites, not this UI. So I'd rather not try to "simplify" this for "power users".
Thanks,
-Derek
Comment #21
dwwPatch + screenshot with 'Not compatible' table below 'Manual updates'.
I vote for this, but it's not just up to me. There's a UX team meeting tomorrow morning, and I hope they'll make some final decisions on all this. Stay tuned.
Thanks,
-Derek
Comment #22
dwwp.s. Re: separate tables vs. a single table, I will say that the screenshots demonstrate that either we should have everything in a single table (which I oppose as stated above), or we should consider some CSS to make the widths of the table columns more consistent across tables. As-is, it's pretty jarring and hard to scan. :(
Comment #23
benjifisherSince #3102724: Improve usability of core compatibility ranges on available updates report was committed to 8.9.x and 9.0.x, we can un-postpone this issue. I am setting the status to NW and updating the title.
#8 mentions last week's meeting of the Usability team, and we discussed this issue again at today' meeting. Recordings (on YoiuTube):
We generally agree with the responses in #20 to some of the earlier suggestions. In particular, color and how to present the table description are up to the admin theme, so they are out of scope here.
We like the approach in #21:
I am updating the "Remaining tasks" to match.
In particular, leaving off the description gives us flexibility for future enhancements. For example, we may find that a particular update has a new module or composer dependency that has to be installed. Then we can add appropriate text to the row without further changing the title/description of the table.
I will create a follow-up issue to make the cell widths more consistent.
Comment #24
webchickJust one additional bullet on benji's excellent summary...
The reason "why" for the order shown in #21 is because it's both a) what chronologically makes sense (have to update core in order to not have versions incompatible with core), and b) there might potentially be 5-6 things in that "not compatible" list, and this puts the necessary core update's visibility higher in the list so it doesn't get lost.
Comment #25
kualeeThanks for your work @dww. I reckon we also need a quick summary/description under the table heading to add on to what actions could be taken by the site admin. As you mentioned, this screen is more for less experienced users, so some guidance/explanation here would help/don't send them into panic mode.
#20 I agreed, it definitely needs a follow-up issue to clean up, a table with one row is not very useful, and also taking up a fair bit of space too.
Comment #26
kualeeDidn't mean to change the title and status, my google chrome restarted and was carrying data from pre#23 (???)
Comment #27
dwwRestoring the changes to the summary that were overwritten via #25.
Also doing some additional updates to the summary.
All that remains here is "Add test coverage of new scenarios.", so tagging for 'Needs tests'.
It looks like we have 0 test coverage of this form yet. :(
I wonder if it's desirable to extend the existing tests of the available updates report (that have all the fixtures we care about, etc) to also load this form and ensure the form looks like we want it to. Or perhaps it's better to add entirely new dedicated tests for this? Part of me doesn't want to further complicate the existing tests. The other side doesn't want to incur the cost of re-installing Drupal N more times for Functional tests of this form for N different update scenarios. We're already incurring all the cost of re-installing Drupal and setting up the fixtures -- so it'd be negligible test execution time to load another page in each scenario and run another set of assertions. I'll ping @tedbow about this and get their input before we proceed.
Thanks,
-Derek
Comment #28
dwwAlso removing the screenshot of patch #14 from the summary, since we decided we want the order of tables from #21.
Comment #29
tedbowre #27I think it would make sense to extend
\Drupal\Tests\update\Functional\UpdateContribTest::testCoreCompatibilityMessage()
to handle also checkingadmin/modules/update
. Might be able to leave that method untouched actually and just update\Drupal\Tests\update\Functional\UpdateContribTest::assertCoreCompatibilityMessage()
which it uses.testCoreCompatibilityMessage()
already has test cases for compatible and NOt compatible modules so we just need to loadadmin/modules/update
and make sure they show in the correct table and with the correct message if not compatible.Comment #30
dwwRe: #29 - great, yeah, that's pretty much exactly what I had in mind.
To manage scope, I spun off #3117229: Expand test coverage of Drupal\update\Form\UpdateManagerUpdate for the bigger problem that we have 0 test coverage of this form.
Thanks,
-Derek
Comment #31
tedbowI chatted with @dww and I was going to add the test coverage as described in #29
Comment #32
tedbowAlthough this seem like good change it is out scope for this issue.
If will give a warning for the core project itself because the key is not set. Fixed
Comment #33
dwwExcellent, thanks for the fixes and the test coverage! Removing that tag and updating summary.
Minor nit with the tests... seems unfortunate to sprinkle calls to:
before some (but not all) of the calls to
assertCoreCompatibilityMessage()
.I understand that
refreshUpdateStatus()
already loads that page, so it's a bit wasteful, but it seems better and less error-prone to maintain ifassertCoreCompatibilityMessage()
is doing targeted assertions for different pages that it's responsible to load the pages it's asserting about in all cases. So instead of it assuming you've loaded the right page first, it should just always do thedrupalGet()
it's assuming as context. Like so.Comment #34
dwwSorry, utterly wrong patch + interdiff. :( Try this.
Comment #36
tedbowWhen I added this if here I missed that this actually will remove the existing test coverage for all other types of updates, such as latest version and "also available".
Adding this for just the new parts of the test as the form at
/admin/module/updates
doesn't show all types of updates.Also returning early now if it is not in this list instead.
Comment #37
xjmComment #38
dwwGreat catch in #36 on not blasting the existing test coverage for those other cases. ;)
Glad you agree on #33.
Yeah, #34 was random fail, indeed.
Re: #36:
A few questions, a few nits, a few out-of-scope changes, and one unnecessary page load:
To be really defensive in case we add something else to the outer if(), should this be elseif ($not_compatible) instead?
This was copy/pasted from a code block with a conditional prefix. In this case, the prefix is always the same. Seems we should just insert it directly via #prefix and not have the $prefix variable.
This seems both out of scope and unnecessary. 'closed' just barely fit at 80 chars in the original.
And here.
Maybe it doesn't matter, but the exact same form is available at 3 different paths:
admin/modules/update
admin/theme/update
admin/reports/updates/update
That's a bit of a UI-WTF (and resolving it is of course completely out of scope). But I wonder if it'd be cleaner to have this test pointing at admin/reports/updates/update instead of doing something module-specific...
This one is an unnecessary page load (inside the not_compatible else). We already loaded the right page after the early return.
To keep this moving forward, I'll quickly re-roll to address these. Stay tuned.
Comment #39
dwwChanges for #38:
1. Ignored for now. Probably should stay as-is from #36. TBD.
2. fixed
3. fixed
4. fixed
5. left it using admin/modules/update for now. TBD.
6. fixed
Comment #40
benjifisherThis looks very close. I just have a few requests for making the code a little more readable.
In ProjectCoreCompatibility.php, I see
If this key is set, then the value is already boolean. I think it would be simpler to avoid double negatives and do it this way:
and then use
!$compatible
instead of!$not_compatible
later. Or you could name the variable$is_compatible
, as in the test.Sorry for the nit, but at least it shows that I am reviewing carefully! ;)
The nested conditionals are hard to follow. It would be clearer to structure this as
In order to be DRY, we could refactor the lines that restructure the render array for
table
instead oftableselect
into a helper function. I consider that a down payment on refactoring thebuildForm()
method. With the current patch, that method runs to 252 lines, including 143 in aforeach
loop.If we do this, then I think there is less need for the suggestion in #36.1.
I guess we need this because this method calls
assertCoreCompatibilityMessage()
, and that method now loads a more restricted page.Most of these variables are not used until after the second
drupalGet()
. I suggest starting the function by defining$expected_range_text
, since that is used on both pages. Then skip a line and do the tests on the first page. Then skip a line, define$assertSession
and the locator strings, and test the second page. Consider replacing the several "Confirm ..." comments with a single, longer comment after the empty line. Related: do we often use "Confirm" in such comments? Maybe we can leave it out entirely ("There is no table ...") or replace it with "Assert".Comment #41
dwwThanks, @benjifisher! I'll work on your excellent points...
Comment #42
dwwThis should fix everything in #40, including #36.5. Took a little while since I ran tests locally to confirm UpdateContribTest is still passing after the refactorings and changes.
Comment #43
dwwBah, some newline funkiness crept in. This is better.
Comment #44
tim.plunkettThe feedback in #40 was excellent, and mirrored my own thinking as I reviewed the previous patch. The new if/elseif/else structure is much clearer.
Thanks!
Comment #45
benjifisher(cross post. TL;DR +1 for RTBC)
@dww:
Thanks for those updates. I think this is ready to go.
In addition to reviewing the patch in #43, I did one last manual test: download and extract tarballs for redis-8.x-1.2 and token-8.x-1.5; hack Drupal.php to pretend the version is 8.7.10. My Update form looks a lot like the screenshot in the issue summary.
The refactoring is a step in the right direction. We removed 10 lines from the
foreach
loop that I mentioned in #40. The new helper function (not counting the doc block) is a little less than that. Coincidentally, the net effect compared to HEAD is no change to the number of lines in theforeach
loop; we did add lines tobuildForm()
overall, because of the new block at the end of that function.Comment #46
alexpottThis raised an eyebrow. Since if $recommended_release['core_compatible'] = NULL the $compatible will equal TRUE. This is the opposite of the behaviour in
template_preprocess_update_version()
which does$core_compatible = !empty($version['core_compatible']);
BUT it is the same as the behaviour in core/themes/stable/templates/admin/update-version.html.twig which does{% if version.core_compatible is not defined or version.core_compatible %}
Do we have test coverage when 'core_compatible' is missing?
Comment #47
benjifisher@alexpott:
I think the code you refer to was all added in #3102724: Improve usability of core compatibility ranges on available updates report. I reviewed that issue, but I may have neglected the templates and preprocess functions a bit.
The code we add in this issue does what we want. If the key is not present, we want the default assumption to be that the project is compatible.
The comment I made in #40.1 of this issue also applies to the preprocess function. That is, we should simply have
$core_compatible = $version['core_compatible'];
because of the early exit in the preprocess function:so we never get to the line in question unless
$version['core_compatibility_message']
is set. But in ProjectCoreCompatibility.php (one more line of context than I gave in #40.1) we haveso those two keys are either both set or neither is.
I am not sure what you want to test.
Note the doc block of
update-version.html.twig
:I am pretty sure that we have test coverage of this template for project = Drupal core. But that is out of scope for this issue, so probably that is not what you are looking for.
Comment #48
dww@alexpott re: #46: +1 to @benjifisher's explanation in #47. We could open a follow-up to change
template_preprocess_update_version()
to assume compatible if not otherwise specified, just to be more consistent with the other parts of core. But as explained, it doesn't actually matter there, since we only hit that code if we know we've got real values to work with and it'll never be NULL. /shrugTL;DR: Still RTBC. ;)
Comment #49
xjmReviewing this now.
Comment #50
xjmHiding some files since the IS formatting has made the last patch difficult to locate.
Meanwhile, crediting reviewers for helpful feedback, which turns out to be everyone but me. Were there any participants from the UX meeting in #23 who aren't included from the original credits added for #8?
Comment #52
xjmAdding credit for @worldlinemine based on @benjifisher's summary of who was at the UX meeting. (Thanks Benji!)
Comment #54
xjmOh, and Gábor.
Comment #55
xjmOK, that was a dense little 8 K patch. Note that I haven't read other reviews, #40, or any of the recent discussion yet -- I usually deliberately read the code first after the IS so that I don't bias my own review.
This is one of those "shorter is not always better" situations IMO. The comment also doesn't actually explain what's happening on the following line.
What's happening on the following line, reading out the null coalescing operator in words, is: If a core compatibility flag is set for the recommended release, then set
$compatible
to that; otherwise, set it toTRUE
.Which is... code smell. Null value leads to very un-null Boolean value. "Yeah, having nothing there means it's compatible". For an undocumented magic key in the release data. ("Magic key" is just how things work because all this code dates from ArrayPI days; "undocumented" is perhaps out of scope for this patch.) But, at the least, we need a better inline comment justifying this. And tests for all three of
TRUE
,FALSE
, andNULL
logics.Why're we sticking it in a classless child div? Some divitis up in here.
Uhhh, what is going on with the diff here? As far as I can see, the only change is that the
core
case is being removed. Which... why? And unrelatedly, why is git detecting it as this massive change? Is there a different difference I missed?This is the
coreerr, central change of the patch.There's a missing comma after "tables" here, but this is just being factored into a method from stuff that used to be inline, so that's at best scope-adjacent.
That said, the one-line summary of this method is kinda bizarre. Out of context, it's totally unclear why we would care about or expect tableselects. I think we need to add something that says something like, "The data in the
$foo
array is primarily used byBar::method()
for baz_purpose, so it includes a checkbox element to perform qux_operation."Without having read the whole form builder, I'm guessing baz and qux are "In the main update table, where a site owner can select which updates to install."
Hmm. No data provider. But is that maybe a faux-data-provider?
And why didn't we need to add permissions before? Surely the update status report is restricted?
Instead of defining
$expected_range_text
, I would assertRequires Drupal core: $expected_range
in both cases. It's usually better for assertions to assert static things, except where they're varying with a data provider or parameter (which$expected_range
itself does, but not the "Requires Drupal core:" part), or where they're verbose such that they they make the code harder to read (as with the CSS selectors). In this case, defining the additional variable is actually making the assertion harder to read.So, I would undo the change in the first half of the method, remove the variable declaration, and just repeat
Requires Drupal core:
in the new assertion....And why didn't it do this before?
Okay, this is... kind of weird. We're testing two different pages from within one assertion helper?
The conditional is also not what I typically expect; hoping this is getting called from something with a data provider.
Hmm, hardcoding that there's only one table row makes me wonder about the extent of the test coverage here, and whether there should be more for more combinations.
I like that this assertion is broader: If there were a bug or difference with the core version number and we asserted the whole thing, this could give a false positive.
Next I'm going to read the other reviews/comments. This is probably NW, but reading what others have said first.
Comment #56
xjmOK, read #38 on which seemed to be the most relevant to the current patch.
For #40.1 / #46 / #55.1, two committers have WTFed at the line and asked for more test coverage. So let's fix the inline comment to reference the bit from
ProjectCoreCompatibility
that @benjifisher explained, and probably expand the test coverage.And actually based on #46 / #47 / #48 the situation is kinda worse than the patch alone indicates.
Regarding this in #47:
But why do we want that? We need to justify it (in the inline comment, if not just by refactoring it to be clearer).
#43.3 partly answers #55.7, but not entirely. While it makes sense for the page that lets you download code to the filesystem (or the next thing to it) to have the absolute highest permission restrictions, the admin status report should still have some permission requirement, so I'm still confused there. (It might make more sense once I read the whole test, which I'll do tomorrow.
Next I'm going to read both the test and the form builder with and without the patch applied to get more context for a few of my questions in #55, but that'll have to wait until tomorrow since it's late. Un-assigning for now, and NW for at least #55.1 (inline comment and test coverage, at a minimum, even if we scope refactoring things to followups), .5, and .8, as well as any other points for which someone has a fix.
Comment #57
dww@xjm: Thanks for the careful review.
1. Sure, a better comment is in order.
2. Because we want it on a separate line from the recommended version + release notes link. This whole thing is weird with the inline twig stuff. Completely re-doing it seemed like scope creep. A
<div>
seemed like the simplest, easiest solution.3. It’s now indented 2 chars since it’s now inside the
else
. Core’s removed since that’s now the if():4. 👍
5. Sure, I can write a better comment for this, too.
6. Are you looking at the same patch? ;) None of that changed in this issue. No, that’s not a faux data provider. It’s how all the update module tests work. Here’s the full context:
7. Available updates report is restricted, but the form we’re testing here, that lets you install new PHP code on your site, requires "administer software updates”.
8. /shrug. Ok, personal preference.
9. See #33 and others.
10. See #33 and others.
11. Yes, called from
testCoreCompatibilityMessage()
, which was added elsewhere. Seems like massive scope creep in your review here.12. We’re explicitly testing with a single contrib. See the
$system_info
I posted above in answer to 6. We load both reports multiple times in multiple scenarios to make sure the single contrib is handled properly in each case. Sounds like you’re asking for all of #3117229: Expand test coverage of Drupal\update\Form\UpdateManagerUpdate to be done in here? Yes, this form has 0 test coverage right now. We’re adding test coverage to handle the scope of this issue. Adding extensive coverage of the whole form is exactly what 3117229 is for.13. 👍
Comment #58
dwwRe: #56.3:
Comment #59
xjmThanks @dww.
I think we might need FEFM feedback on the markup for the markup/themeability choice in #55.2; I'll ask about it tomorrow.
Sorry about the confusion for #55.6; I read patches bottom-up so my comments are out of order because Dreditor orders them top-down, not by timestamp. So I first said I hoped there was a data provider because of the if/else, and then looked for it and didn't find it.
#55.8 isn't a personal preference BTW; it's a testing best practice for core. There's a reasonable chance other committers would have given the same feedback.
#33 didn't really clear anything up for me, but hopefully reading the whole test will.
Re: point 11, asking for more test coverage is not scope creep. It's asking for more test coverage. And for point 12, tests are a gate; while we don't have to test the whole form here (the other two tables), we should test the possible scenarios for the part that we are changing, including at least two values and a "one of each" case.
Comment #60
dwwTL;DR re: #55:
Fixed 1, 5 and 8.
Answered everything else in #57 and #58.
Comment #61
dww#60 was a x-post with #59, so I didn't see any of that when I wrote the patch or posted the comment (and why the patch # doesn't match the comment).
#55.11 said:
I answered in #57.11:
You seemed to be reviewing everything near the lines this issue is touching, not the patch itself. That was my concern. You seem to be upset about the test coverage and methodology introduced in #3102724: Improve usability of core compatibility ranges on available updates report, which is why I said it seemed like "massive scope creep in your review". You didn't actually ask for more test coverage for this issue.
#55.12 wasn't very clear about what additional test coverage you're expecting. #59 is clear:
So I'll work on that now.
Comment #62
dwwWow, I started down this path, and it's a huge mess to add this additional test coverage, given the state of the rest of the update test code. All sorts of things assume there's only a single contrib being tested. I'm not going to re-write dozens (hundreds?) of lines of test plumbing for #59.
Opened #3121040: Add Update manager test coverage involving multiple contribs instead.
If you want to block this critical bug fix on that issue, it's your discretion as the release manager.
I think we have sufficient test coverage in here (not to mention all the manual testing I, @benjifisher and others have done) to prove this works as intended. Getting our test plumbing up to snuff is going to take significantly more effort, and I really don't want to see us keep shipping versions of core that have this glaring bug that we've already fixed here. We have #3121040 and #3117229: Expand test coverage of Drupal\update\Form\UpdateManagerUpdate for follow-ups to expand the test coverage.
Comment #63
dwwAfter being away from this for a while, I saw it in a new light. At the risk of derailing this (but in the hopes this approach is more pleasing to @xjm and could be committed in time for 9.0.0-beta1), here's an attempt at better test coverage for this bug. Instead of trying to re-use much of anything, start over with a totally new test class for this form. This basically ignores and invalidates all the patches and most of the reviews since #29. But it should solve #59 and render obsolete or solve #55.6-13.
Pros
Cons
p.s. I should add, although the inline comments don't spell this out, the new test coverage here means we're hitting all 3 cases for #55.1: TRUE (aaa_update_test 8.x-1.2), FALSE (bbb_update_test 8.x-1.2), and NULL treated as TRUE (bbb_update_test 8.x-1.1).
Comment #64
xjmThanks @dww! This looks really promising; will start a review once @tedbow has had a chance to look at it.
Not that I didn't commit #3102724: Improve usability of core compatibility ranges on available updates report, but when the test was added there, it covered the test scenarios that were important for that issue and that page.. However, this test was adding a conditional if/else in the assertion helper, variables checked in assertions, etc., which are warning flags because it can mean we're testing the test (in a way that might give false positives or hide regressions in the future). So either asserting static things, or assuring all the tested cases are covered by a data provider, is usually the best way to go. Plus that weird null coalesce we've talked a lot about; glad to see #63 should provide coverage for it.
Comment #65
tedbowThis comment is slightly wrong but is because of some complications from a few different areas. I just happened to work on some of the related issues.
core_version_requirement
doesn't have to be set in a projects info.yml file for$recommended_release['core_compatible']
to be set.In drupal.org update feeds
core_compatibility
is set basedcore_version_requirement
if it is set but falls back tocore
if it is not.You can see this in the Webform XML feed. Search for
8.x-5.0-rc31
and see that it has 8.x. The info.yml file for that release does not havecore_version_requirements
set. Because in semver(at least composer's version) this means it compatible with all versions of 8.So in
\Drupal\update\ProjectCoreCompatibility::setReleaseMessage()
where weThis will almost always be set. The only case it would not be set is
1) If there was problem fetching the drupal core project's XML but not another project's XML because it we can't determine available versions of core we won't set this. This seems unlikely but of course could happen
2) If an alternative update server was being used. Not likely but possible. see #3120655: Determine if there are other update servers besides updates.drupal.org, if not deprecate the ability to have different servers.
I will review the rest of this after breakfast
Comment #66
tedbowThis is an unrelated change. Though I agree it may be an improvement we should try make as few changes as possible. I looked this patch locally also ignoring whitespace. I know we have this big section in the diff because this switch block is now in indented. So I am aware reverting this change will not make the actually patch file smaller it is a change we don't need to make.
This case is removed regardless of indentation. But nothing related to this has changed to make us have to make this change.
In the patch we are now setting this above via
This if statement was already present just some of the code was refactor and put into
removeCheckboxFromRow()
. We don't need to also move$projects['manual'][$name] = $entry;
here.🤔Maybe the only reason this
case
is removed and the setting changed is that in an earlier version of the patch we did hadThis was because we were adding the incompatible projects into the manual table with core. So in that version of the patch removing the
case
and moving to theif
block made sense. It does not now.We could keep all the assigning to
$projects[*][$name] = $entry;
in the switch statement by doingIt seems like that might be better so it would be easier to all the projects be assigned to the various tables in the
switch
statement.This is all the non-test comments I have. I do like use having a dedicated for this and will look at the test next.
Comment #67
dwwRe: #65: Fair enough. I admit I've lost track of a lot of these complications. I'm glad you remember. ;) You missed another reason: you're looking at core itself (which never defines compatibility with itself). That was part of why the other patches had to treat NULL as TRUE. Here's another stab at a better comment.
Re: #66: In an effort to make this patch easier to review, I think you making it harder to review. ;) That's not the only reason for the re-structured code. There's also the question of injecting the
core_compatibility_message
for the not compatible case. There's also DRY and not making the "smallest possible change" by bloating and complicating the resulting code. The original code was weirdly organized, and made it hard to extend. If we can't reorganize exactly the code we're dealing with in an issue to make the end result easier to read, I don't understand our scoping efforts. The structure we've arrived at after many hours of reviews and writing is in #63. The whole block is this:I believe you're proposing this:
I really don't think that's an improvement, either for the patch size, nor the final result.
But here it is in patch form for consideration.
Comment #68
dwwAnd if we're going that far, we might as well remove
removeCheckboxFromRow()
entirely and do this...Comment #69
dwwAlthough if we do #68, we need this, too...
Comment #70
dwwFor visual comparison, here's the full code block from #69 to compare with the options in #67:
progress? ;) /shrug I still think #63 is clearer than all this, but not up to me.
Comment #71
dwwShould have done this originally, but here's #63 with only the improved comment from patch #67 to address #65.
Comment #72
tedbowExtra blank line
Do we need a todo if the whole purpose of that issue is expand the test coverage?
I think this should be
UpdateFormTest
.UpdateUpdate
is confusingShould be
protected
I think in general we should use an actual
@dataProvider
method when we have to go through this much complexity to avoid a dataProvider.I know we sometimes skip a dataprovider and just have an array of tests cases but when then have to make another
doTest*()
method as well as faux data provider method to make it understandable, I think we should just use@dataProvider
and not worry that the test suite will take a little longer to run.That way we leverage more of PHPUnit and it is easier to understand and maintain for any developers who are new to this class. If we just use a standard dataProvider then it is just that much easier because it is pattern people have seen more.
I searched core I more occurences of
* @see ::methodOnSameClass()
97
than
* @see self::methodOnSameClass()
52
I don't actually know which 1 is more correct. Maybe somebody else does?
I like the expanded number of test case 🎉
Comments can't appear at the end of the line. Should be moved to the line before
I don't actually think we need to assign this and I don't think it makes it more clear.
We use each of these 2x.
Once in an if
if ($num_compatible) {
But since these are arrays I think this function the exact same way
if (compatible) {
The second time is
$assert_session->elementsCount('css', "$compatible_table_locator tbody tr", $num_compatible);
We could just do
$assert_session->elementsCount('css', "$compatible_table_locator tbody tr", count($compatible));
So aren't actually saving a call to
count()
by assigning the variable.I think it is more readable because
$num_compatible
is not as clear as count($compatible).Another reason is because if you are using an IDE invoking help on
$compatible
will give you the help next of @param vs nothing on$num_compatible
because there is not doc text associated with it.I only see "contribs" 1 other place core. Should be "contrib modules"
Comment #73
dwwThanks for reviewing the tests. Re #72:
1. Fixed.
2. Doesn't seem to hurt. The issue is already open. This class is missing a lot of coverage. Might as well say so.
3. I went with UpdateManagerUpdateTest to match UpdateManagerUpdateForm.
4. Fixed.
5. I've seen numerous core patches trying to use a
dataProvider
in a functional test get shot down. It's wickedly expensive and wasteful to re-install Drupal for every scenario, especially if you add lots of them. ;) It's all pretty thoroughly documented, so I trust other folks could add more test cases here without much trouble.6. See #3112830: [policy, no patch] Allow static::methodName() and/or self::methodName() in @see comments when referring to the same class. There's no documented policy and core is inconsistent. I'm trying to fix that. /shrug
7. 👍
8. Fixed.
9. Fixed, good points.
10. Fixed.
Note: due to the rename, interdiff is wildly confused. So here's a raw diff of the 2 patch files. This is built on #71, my preference of the latest implementation patches).
Comment #74
tedbowHere is an interdiff for 71-73.
@dww I putting
in your
~/.gitconfig
will allow it to find the renames. I am positive because I set it up awhile again
Comment #75
dwwHere's a real data provider. As you can see from the patch and interdiff, it doesn't actually save us much in the test class. But it more than doubles the runtime of the test (at least locally):
Faux (#73)
Real (#75)
I vote #73, and work (elsewhere) to make it less expensive to have dataProviders for Functional tests.
Comment #76
tedbow@dww thanks for updates
#73
Missed 1 "contribs" to "contrib modules"
I still think it makes more sense to use real @dataProvider. @dww you did document it well adn I don't think it will be hard to add ongoing test cases. I just think if we use
@dataProvider
we don't need the documentation because we are using standard feature of our testing framework.@xjm mention that FunctionalJavascript test are much slower so not using a dataProvider might make sense in that case.
All that being said I won't block this issue on it.
couple things I missed before
Needs {@inheritdoc}
Needs {@inheritdoc}
I think this should be
@param string[][]
Needs array type hint for
$compatible, $incompatible
. This problem was there on the non-dataprovider version. I just missed itJust saw #75.
@dww thanks for making this version.
To me this much clearer. I just see
@dataProvider
I don't have to know anything else to know the relationship between the 2 methods.In the older version I see "Time: 10.77 seconds"
and the new version I see "Time: 28.87 seconds"
so yes 20 seconds more but seems worth it to me.
Comment #77
dwwRe: #76 thanks @tedbow for continued careful reviews...
1st 1. Fixed.
1st 2. TBD. I'm providing both real and faux versions for continued consideration.
2nd 1. Fixed.
2nd 2. Duplicate
3. Fixed.
4. Fixed.
3rd 1. /shrug Providing an interdiff between both patches here for continued comparison.
3rd 2. /shrug I know every time we add 20 seconds to the test runs, that gets multiplied *a lot* for all of core development, and it costs the DA real cash money. Not my decision. I still vote faux, until that doesn't cost us anything.
p.s. Officially crediting @xjm on this, who's spent far more effort and valuable time on this than many of the folks already credited. ;)
p.p.s. We need another RTBC, so putting that back on the remaining tasks list.
Comment #78
dwwAsked for more input on this topic in Slack, to which @alexpott replied:
So yay, a real dataProvider it is! ;) Hiding faux from the summary. Posting this here so I have a lasting place to point people to who push back against Functional dataProvider patches in the future.
Thanks!
-Derek
Comment #79
benjifisherThanks @dww and @tedbow for all the effort you have put in here. I only have time to make a few suggestions.
First, the change discussed in #66, #67, and following comments. I agree with @dww on this point. In #44 and #45, @tim.plunkett and I reviewed and approved that bit of moving code around. In other words, we both decided that the change was in scope given the changes needed for this issue. I think that is the right standard to apply, not "as few changes as possible".
Second, we can add some comments as part of this issue, but a proper fix for the "code smell" (the term used in #55.1 for the line
$compatible = $recommended_release['core_compatible'] ?? TRUE;
) is outside the scope of this issue. I started to create a follow-up issue to do something about that, but then I realized how hard it will be to fix. Currently,ProjectCoreCompatibility::setReleaseMessage()
is responsible for adding messages to projects that need a compatibility warning. Asking it to add a flag to projects that do not need such a warning seems like the wrong solution.I think the right answer is to have a class that "owns" the update information for all projects and can answer questions like "is version foo of core compatible with version bar of the quux module?" What do you think?
Third and last point: I think the problem we are trying to solve with the
removeCheckboxFromRow()
method (#55.5) is that we have already prepared an array for'#type' => 'tableselect',
and now we are trying to modify it for'#type' => 'table',
. I would rather pass around a simpler data structure until we know whether it will be used fortable
ortableselect
. Is that in scope for this issue? I think not, and if you agree then I am happy to create a follow-up issue for that.Comment #80
dww@benjifisher Thanks for #79:
1) Does that mean you want to RTBC this? ;)
2) Yeah, it is a bit hard to solve that cleanly, given nearly the entire codebase dates from the ArrayPI days of Drupal (thanks @xjm, that's a great term!). Regardless, I think cleaning up that smell properly requires a follow-up, not something we can solve here. Feel free to open it, and we can redesign / rescope it as things evolve. I don't know that a global class that knows everything is necessarily the right answer. A step in the right direction would be #3100110: Convert update_calculate_project_update_status() into a class, but that's not the whole picture. I don't think it's unreasonable for
ProjectCoreCompatibility
to be responsible for setting an is_compatible flag on releases. That's basically what the class is all about, as the name implies. We'd just need to think a little more clearly and carefully about how we want that to work, and if it's worth continuing to make the ArrayPI more beautiful with a yummy aroma, or if it'd be more worthwhile to start converting more of Update Manager into classes. /shrug3) Yes, that'd probably be cleaner. Yes, that also seems like good follow-up material. Given how much angst has been spilled in here over scope creep already, trying to change anything else about this code in this critical bug fix makes me nervous.
Thanks again,
-Derek
Comment #81
dwwUntil #3113798: Remove unused (and generally wrong) <tag> markup from Update module test XML fixtures is done, we might as well not make that problem worse. Fixing a copy/paste propagation of more of the totally bogus
<tag>
values in our fixtures.Comment #82
dwwFixing a bit more bogus (but irrelevant) data in the new fixtures I had missed.
Short of the "divitis" from #55.2, I think this is RTBC. Everything else has been either fixed in the patch or answered in previous comments.
It seems like yucky scope creep to add a whole new twig template for the new table here. I'm happy to add a class to the
<div>
if that's better, but I suspect it's not. I fear if I go changing anything else, it's going to be labeled "nice but out of scope" again. But I know this particular bit of markup isn't easily modified or themed, so that's not great, either.Since this is now in a separate table, we could add a whole new column for this. But that'll make #3116542: Make column widths consistent on the Update form more difficult or impossible.
Really not clear on how this should be done so it's acceptable to everyone.
Tagging for @lauriii's opinion and adding this point to remaining tasks.
Thanks,
-Derek
Both of the fixes in #81 and #82 are needed because the original
bbb_update_test.1_0.xml
file has both errors. I'd fix those, but then I'm *sure* someone would complain it's out of scope.Comment #83
tedbow@benjifisher thanks for the further review.
@dww thanks for the fixes.
We don't need the "administer modules" permission. I just ran the test locally without it and they all pass.
<div>
/template question.Comment #84
MeenakshiG CreditAttribution: MeenakshiG at OpenSense Labs for DrupalFit commentedComment #85
lauriiiGenerally we wouldn't want to add
<div>
elements without at least having an API that would allow adding attributes to it. Given that this issue is critical, I'd say adding the<div>
here is fine. We could consider using a<p>
element, which would feel slightly better solution in the sense that it usually has some default styling. However, this changes the design. I recommend that if we prefer the design as it is, we should move forward with the current solution and ensure we have opened a follow-up for refactoring the render array to use templates.Comment #86
dww@tedbow re: #83: Good catch, thanks for reviewing.
@Meenakshi.g re: #84: Thanks for fixing that point.
@lauriii re: #85: Thanks for weighing in, and for validating the pragmatic path I picked and explained in #57.2. Follow-up it is. ;)
I'll open the follow-up now, and add @todo to the patch to point to it. Stay tuned.
Comment #87
dwwComment #88
dwwWhoops, hit submit before my comment was up. Was trying to say:
Opened #3121769: Make the table of incompatible releases in UpdateManagerUpdateForm more theme-friendly for #85 / #55.2
Also #3121775: Refactor UpdateManagerUpdateForm::buildForm() to make ::removeCheckboxFromRow() unnecessary for #79.3
RTBC?
Thanks!
-Derek
Comment #89
tedbow@dww thanks for sticking with it! RTBC 🎉
Comment #90
xjmReviewing now.
Comment #91
tedbowI chatted with @xjm and @tim.plunkett about this.
Just couple test changes and some nits
We were trying to figure out a way to make the test depend less on 1) the other of the modules in the table and 2) the particular markup.
I have made some changes that do this but don't change the overall structure of the test.
Small typo here; I think it's
core_compatibility
and notcre_compatibility
.compatibility range
Nitpick: "currently-installed" does not need to be hyphenated; "currently" is an adverb.
Comment #92
dww@tedbow: Thanks for posting your review in the form of a new patch. ;) Still hope this lands in time for 8.8.5! I obviously can't RTBC it, and you can't either. Not sure what happens next.
Re: #91:
Comment #94
dwwRestoring the working tests from #87 and ignoring #91.1.
Fixing everything else from #91.
Interdiffs relative to both #87 and #91.
🤞
Thanks,
-Derek
Comment #95
dwwNote on why #91 failed, looking at the interdiff:
This is what broke the tests... these tables have a row for the header in
<thead>
, and then rows for the payload in<tbody>
. The previous, more precise locator is needed unless you want tocount() + 1
to deal with the header row...Same here.
If we insist on going with something like #91, those are the parts that would need to be reverted for the tests to pass.
Comment #96
dwwInitial stab at a release note snippet. Probably too verbose (as usual) but it can be edited down as desired. Not sure we need one at all, but that's up to @xjm...
Cheers,
-Derek
Comment #97
dwwOther summary updates to make it accurate and complete.
Comment #98
xjmThe test changes in #91.1 were based on the fact that the test was too tightly coupled to the specific markup and order of the modules; while there's a bug, it was on the right track. It is not desirable for tests to be coupled to markup any more than is necessary to ensure that we're testing the right thing. So marking NW and assigning to Ted to fix tomorrow. :)
Comment #99
dwwConfirmed this passes locally.
Comment #100
dwwComment typo.
Comment #101
dwwHere's why I think #94 is better than #91/#100. Let's say #3121775: Refactor UpdateManagerUpdateForm::buildForm() to make ::removeCheckboxFromRow() unnecessary introduces a bug where we get mixed up with which column a given thing should go into. See 3113992-101.break-it.do-not-test.patch -- something of a stretch, but it's possible. Seems like exactly the kind of regression we would hope these tests would prevent.
If you apply that to #100 (and tell the bot not to waste cycles running the entire test suite), you get 3113992-101.broken-100.should-fail-will-pass.patch -- which passes all 5 cases in the new test. :( We're no longer testing that the version string we expect is in the column where we expect it.
If you apply that to #94, you get 3113992-101.broken-94.should-fail-will-fail.patch which now fails, since the expected installed version string isn't just present anywhere, it's missing from the column where it should be.
Meanwhile, at #3117229: Expand test coverage of Drupal\update\Form\UpdateManagerUpdate we're going to need to start testing the order of the things in these tables. There's code that puts the security updates at the top:
How do we test this if not by having tests that care about the order of the rows in the tables?
In short, why are we undoing test coverage? Isn't all this "testing the right thing"? I don't understand #98, and it doesn't answer #92.1.
Comment #102
dwwSince the bot's going to be confused about re-testing the #101 patches, also re-uploading #94 as the latest patch...
Comment #104
dwwp.p.s. I'd happily have classes in the table columns (which would make #3116542: Make column widths consistent on the Update form easier) instead of nth-of-type()'ing these, but that'll surely be called out of scope. So I'm doing the best I can given the constraints. ;)
Comment #105
dwwI forgot #94 doesn't have the comment typo fix from #100. This is better.
3113992.94_105.interdiff.txt is identical to 3113992.99_100.interdiff.txt
Comment #106
tedbowIn #46 @alexpott asked if we have test coverage for
$recommended_release['core_compatible']
not being set.In #55.1 @xjm also asked if we had test coverage for the TRUE, FALSE and NULL cases.
I have checked and we do.
aaa_update_test.8.x-1.2.xml has core_compatibility set will evaluate to
$recommended_release['core_compatible'] === TRUE
bbb_update_test.1_2.xml has core_compatibility set will evaluate to
$recommended_release['core_compatible'] === FALSE
bbb_update_test.1_1.xml does not have core_compatibility set and will mean
$recommended_release['core_compatible']
will not be set.While this fixture does not have
core_compatibility
set and will therefore cover the test case of$recommended_release['core_compatible']
not being set this comment doesn't actually explain. Being "compatible with everything" could meancore_compatibility
is not set but it also could mean<core_compatibility>^8</core_compatibility>
Not everything, but all core version we would be testing. an all version of 8.
or
<core_compatibility>*</core_compatibility>
Truely everything. Not a value hopefully people are using but it is value we do use other test modules info files.
So I think unless this is well documented we could easily accidently add either 1 of the values above to
bbb_update_test.1_1.xml
especially in an issue like #3110917: [meta] Fix update XML fixtures bad datain that case all the tests would continue to pass but we would lose test coverage the case where
$recommended_release['core_compatible']
I think we should add a comment in
bbb_update_test.1_1.xml
explicitly sayingcore_compatibility
can not be added to the release there and why.we are now relying on not being set where we weren't before this issue.
Comment #107
tedbowI think @dww's comment in #101 shows there is some possible value to having the assertion that in asserting the particular column order. I am fine with this. This very unlikely to change.
While the order of the modules unlikely change I am less convinced that we need to assert the order all modules in this table.
yes #3117229: Expand test coverage of Drupal\update\Form\UpdateManagerUpdate we will need to assert that security updates are before other updates it does not follow that we to test the exact order of other modules. For all we know we will have separate test method for that assertion anyways.
Nowhere in the update functions involved does it document or guarantee they are returned in specific order.
The order of the projects ultimately comes from our extension list classes which also do not document the order. and their unit/kernel tests don’t explicitly test the order.
We could add back
$incompatible_row = "$incompatible_table_locator tr:contains('$module Update test')";
and get rid of
$i++
logic and leave everything else basically the same.Comment #108
tedbowHere is just a demo of what I was trying to explain in #106.2
If we update the fixtures in this way(not at all unlikely without strict comments) we lose test coverage.
Comment #109
dwwRe: #106:
1. Yeah, exactly like I said at the end of #63 in answer to both #46 and #55:
2. I'm not sure what you're talking about.
bbb_update_test.1_1.xml
is a new fixture for this issue/test. There's no "we are now relying on not being set where we weren't before this issue" since the fixture never existed until now. I'm of course in favor of more comments (almost always!), but I think this is somewhat grasping at straws to find any possible reason to not RTBC this. :/ We could block this (and every other Update manager issue) on fixing #3115435: Make clear why each XML update.module fixture is created the way it is, but that would violate your position in #3100386: Create contrib update module test cases that use semantic versioning that fixing critical bugs is more important than documenting our test fixtures properly. I give up.Re: #107:
1. 👍
2. 🤦♂️ Maybe I should start yet another issue tag "Perfect is the enemy of good". Lord knows I'd set that on my own reviews in many other issues. 😉But still, really? We're going to keep delaying this issue for stuff like this? Assigning to you. Have fun. I'm very burned out on trying to fix this bug.
I think #105 is RTBC and should be in core before any more releases. But if you want to keep polishing the test coverage, knock yourself out.
Comment #110
dwwAdding comments for #106.
If #107.2 blocks this issue, someone else can do that.
Comment #111
tedbow@dww thanks for addressing #106.
Comment looks but will throw an error because the
<?xml version="1.0" encoding="utf-8"?>
need to the first element in an xml file. Just moving that to the top.Assign to @tim.plunkett for review
Comment #112
xjmNice work and thanks for checking #106.1. Can we add a brief column to the data provider documenting that coverage?
@dww, thanks for your reviews and feedback. It's okay to step back on an issue if it's burning you out. Please do let reviewers provide feedback and remember they also care both about landing this critical and ensuring we're not adding other technical debt when we do. And remember that this issue is an allowed change during beta, and actually since there's a regression we'll make an exception here to backport it to a patch release, so this change is not at risk of not getting in. I understand that it can be tough to balance the QA process and covering edgecases under time pressure, but it's okay also for this bug to be fixed and tested in a way that everyone who contributed is confident in it.
Since we do want to backport this to 8.8.x, I queued an 8.8.x test to check that the change does apply there also, and am setting the branch accordingly.
Comment #113
xjmActually setting the branch.
Comment #114
dwwThanks for the encouragement, @xjm. Yes, I understand we're all balancing a lot. I'm finding the differences between what folks are saying and doing in here vs. the arguments being made in #3100386: Create contrib update module test cases that use semantic versioning are creating a lot of cognitive dissonance for me, so I'm struggling to keep my cool. Glad to know this critical bug can be backported to 8.8.x. I'm feeling time pressure because this has been fixed for a month, but it got bogged down in getting the test coverage perfect. I know we want solid test coverage, but this is starting to feel rather absurd.
Re:
Do you mean something more than these comments I already added?
These are comments for
incompatibleUpdatesTableProvider()
(not that the patch file gives you that context on its own). If that's not sufficient, can you clarify what you want?Thanks,
-Derek
Comment #115
tim.plunkettI think those docs are helpful, especially as they reference which fixtures are used.
The last missing piece is something inline at the top of incompatibleUpdatesTableProvider() that explains what the order of the keys means, essentially repeating the @param docs of testIncompatibleUpdatesTable().
For example, see
\Drupal\Tests\layout_builder\Unit\OverridesSectionStorageTest
, specifically howtestExtractEntityFromRoute()
providerTestExtractEntityFromRoute()
have their docs done.Comment #116
dwwRe: #115: I thought that's part of why we wanted a real dataProvider, not the faux provider, since everyone is supposed to understand the relationship between these functions automatically, and will know where to look if they need to better understand the structure of the returned data. In other issues, when I asked for comments about something in multiple places to make each spot easier to understand, core committers like @xjm have said, in effect: "But then there are multiple places we'd have to update if we change anything, and that's not good."
But since I love excessively commented code, here goes nothing. ;) Also fixed every other conceivable nit I could possibly find in the comments, and moved the @dataProvider annotation above the @param annotations to match the linked example of perfect dataProvider documentation.
RTBC? Pretty please with 31 patches on top?
🤞🙏🤞🙏🤞🙏🤞🙏🤞🙏🤞🙏🤞🙏🤞🙏🤞🙏🤞🙏🤞🙏🤞🙏🤞🙏🤞🙏
Comment #117
tim.plunkettIt's beautiful 😭😭😭
@tedbow and @dww I really appreciate both of your work on this. I think this is ready to go!
Comment #118
xjmSorry for being unclear; I am literally asking for the words from #106.1 to be put in inline comments on the specific array items in the data provider that test each of the three logics. That will make it easier to identify the test coverage for that one line, given the brittleness of the behavior that's out of scope to fix for this issue. Something like this...
I am just going off what @tedbow wrote in #106 here and have not validated this myself, so please check that the comments are true and in the right place. If others +1 that this small comment improvement is adding true information then I can still commit this. 🤞Or if it's wrong and someone else fixes it. Sorry for the confusion!
Comment #119
dww#118 clobbers the fixes in #116 to address #115. Re-rolling and putting the comments in the right places.
Comment #120
dwwComment #121
dwwIn Slack, @xjm confirmed:
@tim.plunkett: You owe me a bottle of wine. ;) And a follow-up to remove the duplicate stuff from your linked example in layout_builder. ;)
Comment #122
tedbowJust checke 120 and it documents nicely what I mentioned in #106.1
I prefer the non-duplication of comments like #121 though I know not everybody does.
Looks RTBC to me.
@dww, @tim.plunkett and @xjm thanks for all the work!
Comment #123
xjmThanks all!
Just wanted to point out that Tim's recommendation wasn't wrong at all, and what LB does is completely correct. I was just trying to explain why my interdiff hadn't included the hunk when I was trying to illustrate what I meant. There's precedent for both #120 and #121 in core and I'm happy to commit either one. Since there seems to be a slight majority for #121 and the most critical parts of the docs are covered, I'll commit that one.
Thanks everyone for your perseverance on this. I know it's been a pain.
Committed to 9.1.x down through 8.8.x. Thanks!