Problem/Motivation
Testing out #3390193: Add a drupalGet() method to KernelTestBase on navigation.module
Steps to reproduce
Proposed resolution
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|
Issue fork drupal-3519393
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3519393-drupalget-navigation
changes, plain diff MR !11847
Comments
Comment #4
catchComment #5
joachim commentedRebased, and cherry-picked the MR from #3582228: add $options and $headers parameters to HttpKernelUiHelperTrait::drupalGet() that we need here.
One test is failing.
I suspect the problem is here:
In a Kernel test, will this install the blocks & whatever as was happening in the Browser test?
Comment #6
joachim commentedHmm so supposedly ModuleInstaller will do a full install.
But stepping in the debugger shows that after these lines:
the config table has these rows only:
Comment #7
mstrelan commentedComment #8
joachim commentedAh, I was barking up the wrong tree.
navigation_test_block module has no default config -- it has an implementation of hook_navigation_defaults().
However I don't understand how this is meant to work. In navigation module we have this hook_modules_installed(), which isn't going to look at navigation_test_block module, only the modules which are getting installed:
And AFAICT, hook_navigation_defaults() isn't invoked anywhere else.
How was this working in a Functional test?
EDIT: well, the Functional test is failing for me too ???
Comment #9
plopescHi, which is the problematic test? If I'm not mistaken, it was not mentioned above.
I can assume it's NavigationDefaultBlockDefinitionTest from your last comment, but I'm not 100% sure. That test is working well locally for me in main branch.
Regarding the mentioned hook, it was introduced in #3491081: Allow other modules to include their own Navigation blocks during installation and it is being used by Dashboard module. I'm unaware of other usages, tbh.
I'm happy to help here if you could provide your specific needs.
Comment #10
joachim commentedThe failing test is NavigationDefaultBlockDefinitionTest.php --filter=testNavigationDefaultBeforeNavigation. How is it working for you on the MR?
Comment #11
mstrelan commentedThe functional test works for me, but not the kernel test. This is consistent with the comment I made 12 months ago. Specifically from the CR I linked:
I can get hook_page_top to fire for navigation module if I add the following after installing navigation:
But then the final assertion to find
.toolbar-button--icon--test-blockwas failing. I fixed this by removing the unnecessary call to$this->installConfig(['navigation']);that actually overwrites thenavigation.block_layoutconfig that was set inhook_modules_installed.There are merge conflicts and build fails, but that should at least get the test passing.
Comment #12
joachim commentedI don't understand this comment:
> // Refresh the mink session so we don't have a stale container.
The service container? How does clearing $mink affect that?
We should document that this needs to be done on HttpKernelUiHelperTrait.
> removing the unnecessary call to $this->installConfig(['navigation']);
I'm confused by this too! I thought that in kernel tests, we had to install config manually as it's not done by module installation?
Comment #13
joachim commentedThe broken test is because of this:
What's the reason for doing this in each drupalGet()? We might potentially want to test caching.
Comment #14
mstrelan commentedNot sure exactly, it's something in getDefaultDriverInstance. If this is something that needs to happen a lot I thought maybe we should have a helper for installing modules rather than telling people they need to do this.
AFK now and don't remember specifically but see my earlier commentary on the MR.
Comment #15
mstrelan commentedIn this case the config is set by hook_modules_installed and installing the module config happens after, wiping out the changes from the hook.
Comment #16
joachim commentedIf I remove the call to refreshVariables() inside drupalGet(), it turns out that a call to refreshVariables() is only needed in one place in the test, in testNavigationDefaultAfterNavigation():
but doing it this way round, which to me seems more logical as it's after the installation of a new module, breaks the test:
I don't know why, and this doesn't smell good.
Comment #17
mstrelan commentedInterestingly you can also do
$this->mink = NULL;instead of$this->refreshVariables();in the same way you describe in #16. It seems that something called from drupalGet is caching the old container and refreshing mink or calling refreshVariables is what resets it.Comment #18
joachim commentedThanks for figuring that out -- it really helps!
The problem is in fact that inside $http_kernel, there is an instance of KernelPreHandle which itself has an instance of DrupalKernel, and that has an instance of the container.
And rather than $this->mink = NULL, we can call initMink(), which is more elegant, and it means I can document it on that method.
Comment #19
joachim commentedComment #20
joachim commentedShould the addition of query string etc support to drupalGet() go in a preliminary helper issue, so that backporting the test utilities is easier?Oops, that is already done: #3582228: add $options and $headers parameters to HttpKernelUiHelperTrait::drupalGet().Apart from that, this is ready I think. @mstrelan could you move the MR from draft state?
Comment #21
smustgrave commentedShouldn't this be postponed on #3582228: add $options and $headers parameters to HttpKernelUiHelperTrait::drupalGet()?
Comment #22
mstrelan commentedYes, but we can still review the other changes here. In particular it would be good to have more feedback on
$this->initMink();. I also wanted to point out we have\Drupal\Tests\ApiRequestTrait::makeApiRequestwhich calls$this->refreshVariables();which might give us some hints to understand why it might be needed.Comment #23
joachim commentedCalling initMink() is needed because the Mink browser has an instance of the HTTP Kernel service, which itself contains (deep down) a reference to the container.
Therefore, if you do something such as installing a module which requires the container to be rebuilt, you need to re-do the setup of the Mink browser, so there is a fresh version of the container deep in there. I documented this on initMink() -- does it need further documentation in the list of restrictions on drupalGet() (or its trait, I forget which) maybe?
Calling refreshVariables() before each drupalGet() is something for tests to do. If we do it inside drupalGet() then caching won't ever work.
Comment #24
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #25
mstrelan commentedRebased on main. Added a todo comment to eventually remove the initMink. I tested that the solution would work here, but let's save that discussion for the other issue for those willing to look at it.
Comment #26
dcam commentedThe changes in the MR are consistent with other Functional-to-Kernel test conversions that I've done recently. They look good to me.
The use of
initMink()is covered in the discussion above, particularly #23.I think that adding the return typehint for
refreshVariables()is probably out of scope since we're no longer using it inHttpKernelUiHelperTrait. But I don't think there's a reason to roll it back, so I'm not going to set the issue to Needs Work for that. I'm just noting it.And just to be certain, I checked the GitLab CI Kernel test logs to make certain that the tests are running. Both of them are listed in the results.
Comment #27
catchThis needs a rebase for the phpstan baseline, when I tried to do that locally, I then got:
Which suggests it might need more than that.
Comment #28
catchIgnore #27, I was on 11.x by mistake.
Committed/pushed to main, thanks!