From 31dcacad1b955fdd57f0e8af124e38d136e80599 Mon Sep 17 00:00:00 2001
From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date: Fri, 19 Aug 2016 14:26:08 +0100
Subject: [PATCH] Issue #2740983 by VitalyM, alexpott: Configuration system
 doesn't allow importing a single item from a non-default collection

---
 .../config/src/StorageReplaceDataWrapper.php  |  9 +-
 .../Tests/ConfigSingleImportExportTest.php    |  5 +-
 .../Storage/StorageReplaceDataWrapperTest.php | 93 +++++++++++++++++++
 3 files changed, 103 insertions(+), 4 deletions(-)
 create mode 100644 core/tests/Drupal/KernelTests/Core/Config/Storage/StorageReplaceDataWrapperTest.php

diff --git a/core/modules/config/src/StorageReplaceDataWrapper.php b/core/modules/config/src/StorageReplaceDataWrapper.php
index 58b3b492b3ea..91c3a7cfcc17 100644
--- a/core/modules/config/src/StorageReplaceDataWrapper.php
+++ b/core/modules/config/src/StorageReplaceDataWrapper.php
@@ -44,6 +44,7 @@ class StorageReplaceDataWrapper implements StorageInterface {
   public function __construct(StorageInterface $storage, $collection = StorageInterface::DEFAULT_COLLECTION) {
     $this->storage = $storage;
     $this->collection = $collection;
+    $this->replacementData[$collection] = [];
   }
 
   /**
@@ -104,7 +105,7 @@ public function rename($name, $new_name) {
       $this->replacementData[$this->collection][$new_name] = $this->replacementData[$this->collection][$name];
       unset($this->replacementData[$this->collection][$name]);
     }
-    return $this->rename($name, $new_name);
+    return $this->storage->rename($name, $new_name);
   }
 
   /**
@@ -164,8 +165,10 @@ public function deleteAll($prefix = '') {
    * {@inheritdoc}
    */
   public function createCollection($collection) {
-    $this->collection = $collection;
-    return $this->storage->createCollection($collection);
+    return new static(
+      $this->storage->createCollection($collection),
+      $collection
+    );
   }
 
   /**
diff --git a/core/modules/config/src/Tests/ConfigSingleImportExportTest.php b/core/modules/config/src/Tests/ConfigSingleImportExportTest.php
index a5b838627fa7..53f6164cc6bd 100644
--- a/core/modules/config/src/Tests/ConfigSingleImportExportTest.php
+++ b/core/modules/config/src/Tests/ConfigSingleImportExportTest.php
@@ -20,7 +20,10 @@ class ConfigSingleImportExportTest extends WebTestBase {
   public static $modules = [
     'block',
     'config',
-    'config_test'
+    'config_test',
+    // Adding language module makes it possible to involve non-default
+    // (language.xx) collections in import/export operations.
+    'language',
   ];
 
   protected function setUp() {
diff --git a/core/tests/Drupal/KernelTests/Core/Config/Storage/StorageReplaceDataWrapperTest.php b/core/tests/Drupal/KernelTests/Core/Config/Storage/StorageReplaceDataWrapperTest.php
new file mode 100644
index 000000000000..84b4f564c326
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Config/Storage/StorageReplaceDataWrapperTest.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Config\Storage;
+
+use Drupal\config\StorageReplaceDataWrapper;
+use Drupal\Core\Config\StorageInterface;
+
+/**
+ * Tests StorageReplaceDataWrapper operations.
+ *
+ * @group config
+ */
+class StorageReplaceDataWrapperTest extends ConfigStorageTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->storage = new StorageReplaceDataWrapper($this->container->get('config.storage'));
+    // ::listAll() verifications require other configuration data to exist.
+    $this->storage->write('system.performance', array());
+    $this->storage->replaceData('system.performance', array('foo' => 'bar'));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function read($name) {
+    return $this->storage->read($name);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function insert($name, $data) {
+    $this->storage->write($name, $data);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function update($name, $data) {
+    $this->storage->write($name, $data);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function delete($name) {
+    $this->storage->delete($name);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function testInvalidStorage() {
+    // No-op as this test does not make sense.
+  }
+
+  /**
+   * Tests if new collections created correctly.
+   *
+   * @param string $collection
+   *   The collection name.
+   *
+   * @dataProvider providerCollections
+   */
+  public function testCreateCollection($collection) {
+    $initial_collection_name = $this->storage->getCollectionName();
+
+    // Create new storage with given collection and check it is set correctly.
+    $new_storage = $this->storage->createCollection($collection);
+    $this->assertSame($collection, $new_storage->getCollectionName());
+
+    // Check collection not changed in the current storage instance.
+    $this->assertSame($initial_collection_name, $this->storage->getCollectionName());
+  }
+
+  /**
+   * Data provider for testing different collections.
+   *
+   * @return array
+   *   Returns an array of collection names.
+   */
+  public function providerCollections() {
+    return [
+      [StorageInterface::DEFAULT_COLLECTION],
+      ['foo.bar'],
+    ];
+  }
+
+}
-- 
GitLab