[8.x] Fix bug where columns would be guarded while filling Eloquent models during unit tests #39880
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Versions
laravel/framework: v8.74.0 (affects versions in 6.x and up)
PHP: 7.4.21
Description
#33777 introduces a change that caches Eloquent model database table columns in memory to determine whether they should be guardable attributes or not.
This change does not consider whether or not a database connection is available. If it is unavailable, an empty list of columns will be cached for that model, resulting in subsequent tests that do have a database connection treating all columns as unfillable.
Example to reproduce
Create a unit test, and an integration test:
When you run these tests individually, the unit test fails, and the integration test passes:
When you run them in the same test suite, they both fail. This is because the unit test run caches the empty list of columns in memory:
(The error is because my environment has
name
as a non-nullable column in my table).Proposal
This pull request proposes that we do not cache the column list when it is empty. This means that when running tests that don't have access to a database, it won't interfere with the rest of a suite where tests may in future have access to a database.
With this patch both of these tests pass:
I realise this change was made to address some security issues (https://blog.laravel.com/security-release-laravel-61834-7232, https://blog.laravel.com/security-release-laravel-61835-7240).
My workaround for now is to put
Model::unguard()
inTestCase::setUp()
, however I thought I'd propose a fix here as well.