Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
automatic_updates-3408937
Manage
Activity
Members
Labels
Plan
Custom issue tracker
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Issue forks
automatic_updates-3408937
Commits
c47bac33
Commit
c47bac33
authored
1 year ago
by
Kunal Sachdev
Committed by
Adam G-H
1 year ago
Browse files
Options
Downloads
Patches
Plain Diff
Issue
#3354325
by phenaproxima, kunal.sachdev, Wim Leers: Consolidate UpdateErrorTest
parent
ff67d004
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
tests/src/Functional/UpdateErrorTest.php
+53
-90
53 additions, 90 deletions
tests/src/Functional/UpdateErrorTest.php
with
53 additions
and
90 deletions
tests/src/Functional/UpdateErrorTest.php
+
53
−
90
View file @
c47bac33
...
...
@@ -11,6 +11,7 @@ use Drupal\package_manager\Event\PostRequireEvent;
use
Drupal\package_manager
\Event\PreApplyEvent
;
use
Drupal\package_manager
\Event\PreCreateEvent
;
use
Drupal\package_manager
\Event\PreDestroyEvent
;
use
Drupal\package_manager
\Event\PreOperationStageEvent
;
use
Drupal\package_manager
\Event\PreRequireEvent
;
use
Drupal\package_manager
\Event\StatusCheckEvent
;
use
Drupal\package_manager
\ValidationResult
;
...
...
@@ -39,37 +40,10 @@ class UpdateErrorTest extends UpdaterFormTestBase {
->
save
();
}
/**
* Tests that the update stage is destroyed if an error occurs during require.
*/
public
function
testStageDestroyedOnError
():
void
{
$session
=
$this
->
getSession
();
$assert_session
=
$this
->
assertSession
();
$page
=
$session
->
getPage
();
$this
->
mockActiveCoreVersion
(
'9.8.0'
);
$this
->
checkForUpdates
();
$this
->
drupalGet
(
'/admin/modules/update'
);
$error
=
new
\Exception
(
'Some Exception'
);
TestSubscriber1
::
setException
(
$error
,
PostRequireEvent
::
class
);
$assert_session
->
pageTextNotContains
(
static
::
$errorsExplanation
);
$assert_session
->
pageTextNotContains
(
static
::
$warningsExplanation
);
$page
->
pressButton
(
'Update to 9.8.1'
);
$this
->
checkForMetaRefresh
();
$this
->
assertUpdateStagedTimes
(
1
);
$assert_session
->
pageTextContainsOnce
(
'An error has occurred.'
);
$page
->
clickLink
(
'the error page'
);
$assert_session
->
addressEquals
(
'/admin/modules/update'
);
$assert_session
->
pageTextNotContains
(
'Cannot begin an update because another Composer operation is currently in progress.'
);
$assert_session
->
buttonNotExists
(
'Delete existing update'
);
$assert_session
->
pageTextContains
(
'Some Exception'
);
$assert_session
->
buttonExists
(
'Update'
);
}
/**
* Tests that update cannot be completed via the UI if a status check fails.
*/
public
function
test
NoContinueOnError
():
void
{
public
function
test
StatusCheckErrorPreventsUpdate
():
void
{
$session
=
$this
->
getSession
();
$assert_session
=
$this
->
assertSession
();
$page
=
$session
->
getPage
();
...
...
@@ -103,9 +77,9 @@ class UpdateErrorTest extends UpdaterFormTestBase {
}
/**
* Tests
handling
of errors and warnings during
the update process
.
* Tests
the display
of errors and warnings during
status check
.
*/
public
function
test
UpdateErrors
():
void
{
public
function
test
StatusCheckErrorDisplay
():
void
{
$session
=
$this
->
getSession
();
$assert_session
=
$this
->
assertSession
();
$page
=
$session
->
getPage
();
...
...
@@ -148,53 +122,33 @@ class UpdateErrorTest extends UpdaterFormTestBase {
$assert_session
->
pageTextNotContains
(
static
::
$warningsExplanation
);
$assert_session
->
pageTextNotContains
(
$cached_message
);
TestSubscriber1
::
setTestResult
(
NULL
,
StatusCheckEvent
::
class
);
// Make the validator throw an exception during pre-create.
$error
=
new
\Exception
(
'The update exploded.'
);
TestSubscriber1
::
setException
(
$error
,
PreCreateEvent
::
class
);
$session
->
reload
();
$assert_session
->
pageTextNotContains
(
static
::
$errorsExplanation
);
$assert_session
->
pageTextNotContains
(
static
::
$warningsExplanation
);
$assert_session
->
pageTextNotContains
(
$cached_message
);
$page
->
pressButton
(
'Update to 9.8.1'
);
$this
->
checkForMetaRefresh
();
$this
->
assertUpdateStagedTimes
(
0
);
$assert_session
->
pageTextContainsOnce
(
'An error has occurred.'
);
$page
->
clickLink
(
'the error page'
);
// We should see the exception message, but not the validation result's
// messages or summary, because exceptions thrown directly by event
// subscribers are wrapped in simple exceptions and re-thrown.
$assert_session
->
pageTextContainsOnce
(
$error
->
getMessage
());
$assert_session
->
pageTextNotContains
((
string
)
$expected_results
[
0
]
->
messages
[
0
]);
$assert_session
->
pageTextNotContains
(
$expected_results
[
0
]
->
summary
);
$assert_session
->
pageTextNotContains
(
$cached_message
);
// Since the error occurred during pre-create, there should be no existing
// update to delete.
$assert_session
->
buttonNotExists
(
'Delete existing update'
);
// If a validator flags an error, but doesn't throw, the update should still
// be halted.
TestSubscriber1
::
setTestResult
(
$expected_results
,
PreCreateEvent
::
class
);
$page
->
pressButton
(
'Update to 9.8.1'
);
$this
->
checkForMetaRefresh
();
$this
->
assertUpdateStagedTimes
(
0
);
$assert_session
->
pageTextContainsOnce
(
'An error has occurred.'
);
$page
->
clickLink
(
'the error page'
);
$this
->
assertStatusMessageContainsResult
(
$expected_results
[
0
]);
$assert_session
->
pageTextNotContains
(
$cached_message
);
}
/**
* Tests handling of exceptions
thrown
by event subscribers.
* Tests handling of exceptions
and errors raised
by event subscribers.
*
* @param string $event
* The event that should throw an exception.
* The event that should cause a problem.
* @param string $stopped_by
* Either 'exception' to throw an exception on the given event, or
* 'validation error' to flag a validation error instead.
*
* @dataProvider provider
ExceptionFrom
EventSubscriber
* @dataProvider provider
UpdateStoppedBy
EventSubscriber
*/
public
function
testExceptionFromEventSubscriber
(
string
$event
):
void
{
$exception
=
new
\Exception
(
'Bad news bears!'
);
TestSubscriber
::
setException
(
$exception
,
$event
);
public
function
testUpdateStoppedByEventSubscriber
(
string
$event
,
string
$stopped_by
):
void
{
$expected_message
=
'Bad news bears!'
;
if
(
$stopped_by
===
'validation error'
)
{
$result
=
ValidationResult
::
createError
([
// @codingStandardsIgnoreLine
t
(
$expected_message
),
]);
TestSubscriber
::
setTestResult
([
$result
],
$event
);
}
else
{
$this
->
assertSame
(
'exception'
,
$stopped_by
);
TestSubscriber
::
setException
(
new
\Exception
(
$expected_message
),
$event
);
}
// Only simulate a staged update if we're going to get far enough that the
// stage directory will be created.
...
...
@@ -213,7 +167,16 @@ class UpdateErrorTest extends UpdaterFormTestBase {
// StatusCheckEvent runs very early, before we can even start the update.
// If it raises the error we're expecting, we're done.
if
(
$event
===
StatusCheckEvent
::
class
)
{
$assert_session
->
statusMessageContains
(
$exception
->
getMessage
(),
'error'
);
// If we are flagging a validation error, we should see an explanatory
// message. If we're throwing an exception, we shouldn't.
if
(
$stopped_by
===
'validation error'
)
{
$assert_session
->
statusMessageContains
(
static
::
$errorsExplanation
,
'error'
);
}
else
{
$assert_session
->
pageTextNotContains
(
static
::
$errorsExplanation
);
}
$assert_session
->
pageTextNotContains
(
static
::
$warningsExplanation
);
$assert_session
->
statusMessageContains
(
$expected_message
,
'error'
);
// We shouldn't be able to start the update.
$assert_session
->
buttonNotExists
(
'Update to 9.8.1'
);
return
;
...
...
@@ -228,40 +191,31 @@ class UpdateErrorTest extends UpdaterFormTestBase {
// We should see the exception's backtrace.
$assert_session
->
responseContains
(
'<pre class="backtrace">'
);
$page
->
clickLink
(
'the error page'
);
$assert_session
->
statusMessageContains
(
$ex
ception
->
getM
essage
()
,
'error'
);
$assert_session
->
statusMessageContains
(
$ex
pected_m
essage
,
'error'
);
// We should be on the start page.
$assert_session
->
addressEquals
(
'/admin/modules/update'
);
// If we failed during post-create, the stage is not destroyed, so we
// should not be able to start the update anew without destroying the
// stage first. In all other cases, the stage should have been destroyed
// and we should be able to try again.
//
(or never created at all)
and we should be able to try again.
// @todo Delete the existing update on behalf of the user in
// https://drupal.org/i/3346644.
if
(
$event
===
PostCreateEvent
::
class
)
{
$assert_session
->
pageTextContains
(
'Cannot begin an update because another Composer operation is currently in progress.'
);
$assert_session
->
buttonNotExists
(
'Update to 9.8.1'
);
$assert_session
->
buttonExists
(
'Delete existing update'
);
}
else
{
$assert_session
->
pageTextNotContains
(
'Cannot begin an update because another Composer operation is currently in progress.'
);
$assert_session
->
buttonExists
(
'Update to 9.8.1'
);
$assert_session
->
buttonNotExists
(
'Delete existing update'
);
}
return
;
}
// We should now be ready to finish the update.
..
// We should now be ready to finish the update.
$this
->
assertStringContainsString
(
'/admin/automatic-update-ready/'
,
$session
->
getCurrentUrl
());
// ...but if we set it up to fail on PostRequireEvent, and we see the error
// message from that, we're done.
// @todo In https://drupal.org/i/3346644, ensure that PostRequireEvent
// behaves the same way as PreCreateEvent, PostCreateEvent, and
// PreRequireEvent.
if
(
$event
===
PostRequireEvent
::
class
)
{
$assert_session
->
statusMessageContains
(
$exception
->
getMessage
(),
'error'
);
$assert_session
->
buttonNotExists
(
'Continue'
);
return
;
}
// Ensure that we are expecting a failure from an event that is dispatched
// during the second phase (apply and destroy) of the update.
$this
->
assertContains
(
$event
,
[
...
...
@@ -282,7 +236,7 @@ class UpdateErrorTest extends UpdaterFormTestBase {
// We should be back on the "ready to update" page, and the exception
// message should be visible.
$this
->
assertStringContainsString
(
'/admin/automatic-update-ready/'
,
$session
->
getCurrentUrl
());
$assert_session
->
statusMessageContains
(
$ex
ception
->
getM
essage
()
,
'error'
);
$assert_session
->
statusMessageContains
(
$ex
pected_m
essage
,
'error'
);
return
;
}
...
...
@@ -292,7 +246,7 @@ class UpdateErrorTest extends UpdaterFormTestBase {
// We should have been forwarded to the main update page, and the exception
// message should be visible.
$assert_session
->
addressEquals
(
'/admin/reports/updates'
);
$assert_session
->
statusMessageContains
(
$ex
ception
->
getM
essage
()
,
'error'
);
$assert_session
->
statusMessageContains
(
$ex
pected_m
essage
,
'error'
);
// If the exception was thrown during PreDestroyEvent, the stage was not
// destroyed, so pretend there's another available update, and ensure that
...
...
@@ -321,12 +275,12 @@ class UpdateErrorTest extends UpdaterFormTestBase {
}
/**
* Data provider for ::test
ExceptionFrom
EventSubscriber().
* Data provider for ::test
UpdateStoppedBy
EventSubscriber().
*
* @return array[]
* The test cases.
*/
public
function
provider
ExceptionFrom
EventSubscriber
():
array
{
public
function
provider
UpdateStoppedBy
EventSubscriber
():
array
{
$events
=
[
StatusCheckEvent
::
class
,
PreCreateEvent
::
class
,
...
...
@@ -338,7 +292,16 @@ class UpdateErrorTest extends UpdaterFormTestBase {
PreDestroyEvent
::
class
,
PostDestroyEvent
::
class
,
];
return
array_combine
(
$events
,
array_map
(
fn
(
$event
)
=>
[
$event
],
$events
));
$data
=
[];
foreach
(
$events
as
$event
)
{
$data
[
"exception from
$event
"
]
=
[
$event
,
'exception'
];
// Only the pre-operation events support flagging validation errors.
if
(
is_subclass_of
(
$event
,
PreOperationStageEvent
::
class
))
{
$data
[
"validation error from
$event
"
]
=
[
$event
,
'validation error'
];
}
}
return
$data
;
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment