From b71ccf5074102e3ddd4b7029af7beb13f501f05f Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Mon, 25 Nov 2019 13:11:21 +0000
Subject: [PATCH] Issue #3093879 by amateescu, catch: Ensure that there's no
 active workspace while running database updates

(cherry picked from commit 528ab050de58dbb9ca3d2aa360de9e8b1411a2ab)
---
 .../src/WorkspacesServiceProvider.php         |  11 +++++
 .../drupal-8.6.0-workspaces_installed.php     | Bin 44187 -> 44502 bytes
 .../Negotiator/TestWorkspaceNegotiator.php    |  43 ++++++++++++++++++
 .../workspace_update_test.info.yml            |   8 ++++
 .../workspace_update_test.post_update.php     |  13 ++++++
 .../workspace_update_test.services.yml        |   5 ++
 .../Update/WorkspacesUpdateTest.php           |  31 ++++++++++++-
 7 files changed, 110 insertions(+), 1 deletion(-)
 create mode 100644 core/modules/workspaces/tests/modules/workspace_update_test/src/Negotiator/TestWorkspaceNegotiator.php
 create mode 100644 core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.info.yml
 create mode 100644 core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.post_update.php
 create mode 100644 core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.services.yml

diff --git a/core/modules/workspaces/src/WorkspacesServiceProvider.php b/core/modules/workspaces/src/WorkspacesServiceProvider.php
index 712af5f36858..4df0da6db565 100644
--- a/core/modules/workspaces/src/WorkspacesServiceProvider.php
+++ b/core/modules/workspaces/src/WorkspacesServiceProvider.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\ServiceProviderBase;
+use Drupal\Core\Update\UpdateKernel;
 use Symfony\Component\DependencyInjection\Reference;
 
 /**
@@ -24,6 +25,16 @@ public function alter(ContainerBuilder $container) {
     $container->getDefinition('path_alias.repository')
       ->setClass(WorkspacesAliasRepository::class)
       ->addMethodCall('setWorkspacesManager', [new Reference('workspaces.manager')]);
+
+    // Ensure that there's no active workspace while running database updates by
+    // removing the relevant tag from all workspace negotiator services.
+    if ($container->get('kernel') instanceof UpdateKernel) {
+      foreach ($container->getDefinitions() as $id => $definition) {
+        if ($definition->hasTag('workspace_negotiator')) {
+          $definition->clearTag('workspace_negotiator');
+        }
+      }
+    }
   }
 
 }
diff --git a/core/modules/workspaces/tests/fixtures/update/drupal-8.6.0-workspaces_installed.php b/core/modules/workspaces/tests/fixtures/update/drupal-8.6.0-workspaces_installed.php
index fae7377e9decbc1a4fb8039bb7250d1c7655eb1a..459a7207e77284e754ca3eff07d80176f8f38c8f 100644
GIT binary patch
delta 77
zcmbPzlj+)RrVU(7ll52fPS#`$;)yRUNJ%V7jW0<pE}2}zScNL^k6COpFOxjuBxZRO
KiOmYk)hhvL9~@W!

delta 19
bcmcb1n`!n<rVU(7oB5cP7&oW0<gWw(PP7LD

diff --git a/core/modules/workspaces/tests/modules/workspace_update_test/src/Negotiator/TestWorkspaceNegotiator.php b/core/modules/workspaces/tests/modules/workspace_update_test/src/Negotiator/TestWorkspaceNegotiator.php
new file mode 100644
index 000000000000..72a727bf5e06
--- /dev/null
+++ b/core/modules/workspaces/tests/modules/workspace_update_test/src/Negotiator/TestWorkspaceNegotiator.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Drupal\workspace_update_test\Negotiator;
+
+use Drupal\workspaces\Entity\Workspace;
+use Drupal\workspaces\Negotiator\WorkspaceNegotiatorInterface;
+use Drupal\workspaces\WorkspaceInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Defines a workspace negotiator used for testing.
+ */
+class TestWorkspaceNegotiator implements WorkspaceNegotiatorInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function applies(Request $request) {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getActiveWorkspace(Request $request) {
+    return Workspace::create(['id' => 'test', 'label' => 'Test']);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setActiveWorkspace(WorkspaceInterface $workspace) {
+    // Nothing to do here.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function unsetActiveWorkspace() {
+    // Nothing to do here.
+  }
+
+}
diff --git a/core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.info.yml b/core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.info.yml
new file mode 100644
index 000000000000..9d9b3ed28e62
--- /dev/null
+++ b/core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.info.yml
@@ -0,0 +1,8 @@
+name: 'Workspace Update Test'
+type: module
+description: 'Provides supporting code for testing workspaces during database updates.'
+package: Testing
+version: VERSION
+core: 8.x
+dependencies:
+  - drupal:workspaces
diff --git a/core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.post_update.php b/core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.post_update.php
new file mode 100644
index 000000000000..4bc3295131cf
--- /dev/null
+++ b/core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.post_update.php
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Post update functions for the Workspace Update Test module.
+ */
+
+/**
+ * Checks the active workspace during database updates.
+ */
+function workspace_update_test_post_update_check_active_workspace() {
+  \Drupal::state()->set('workspace_update_test.has_active_workspace', \Drupal::service('workspaces.manager')->hasActiveWorkspace());
+}
diff --git a/core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.services.yml b/core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.services.yml
new file mode 100644
index 000000000000..d2b4a1a9dc7c
--- /dev/null
+++ b/core/modules/workspaces/tests/modules/workspace_update_test/workspace_update_test.services.yml
@@ -0,0 +1,5 @@
+services:
+  workspace_update_test.negotiator.test:
+    class: Drupal\workspace_update_test\Negotiator\TestWorkspaceNegotiator
+    tags:
+      - { name: workspace_negotiator, priority: 0 }
diff --git a/core/modules/workspaces/tests/src/Functional/Update/WorkspacesUpdateTest.php b/core/modules/workspaces/tests/src/Functional/Update/WorkspacesUpdateTest.php
index ca074da74fce..30062be1c7df 100644
--- a/core/modules/workspaces/tests/src/Functional/Update/WorkspacesUpdateTest.php
+++ b/core/modules/workspaces/tests/src/Functional/Update/WorkspacesUpdateTest.php
@@ -18,7 +18,7 @@ class WorkspacesUpdateTest extends UpdatePathTestBase {
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['workspaces'];
+  protected static $modules = ['workspaces', 'workspace_update_test'];
 
   /**
    * {@inheritdoc}
@@ -127,4 +127,33 @@ public function testWorkspaceParentField() {
     $this->assertNull($form_display->getComponent('parent'));
   }
 
+  /**
+   * Tests that there is no active workspace during database updates.
+   */
+  public function testActiveWorkspaceDuringUpdate() {
+    /** @var \Drupal\workspaces\WorkspaceManagerInterface $workspace_manager */
+    $workspace_manager = \Drupal::service('workspaces.manager');
+
+    // Check that we have an active workspace before running the updates.
+    $this->assertTrue($workspace_manager->hasActiveWorkspace());
+    $this->assertEquals('test', $workspace_manager->getActiveWorkspace()->id());
+
+    $this->runUpdates();
+
+    // Check that we didn't have an active workspace while running the updates.
+    // @see workspace_update_test_post_update_check_active_workspace()
+    $this->assertFalse(\Drupal::state()->get('workspace_update_test.has_active_workspace'));
+
+    // Check that we have an active workspace after running the updates.
+    $this->assertTrue($workspace_manager->hasActiveWorkspace());
+    $this->assertEquals('test', $workspace_manager->getActiveWorkspace()->id());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function replaceUser1() {
+    // Do not replace the user from our dump.
+  }
+
 }
-- 
GitLab