From 85ff5bf356b62a5ad8428ceb0ecd1389d0340074 Mon Sep 17 00:00:00 2001
From: Jaime Perez Crespo <jaime.perez@uninett.no>
Date: Tue, 2 Feb 2016 14:33:36 +0100
Subject: [PATCH] Make it possible to pre-load a configuration array into
 SimpleSAML_Configuration for subsequent calls to getInstance() to use it.
 This opens up for unit-testing code that calls
 SimpleSAML_Configuration::getInstance().

---
 lib/SimpleSAML/Configuration.php           | 21 ++++++++++-----
 tests/lib/SimpleSAML/ConfigurationTest.php | 31 ++++++++++++++++++++++
 2 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/lib/SimpleSAML/Configuration.php b/lib/SimpleSAML/Configuration.php
index a559aa52d..2a52bf11c 100644
--- a/lib/SimpleSAML/Configuration.php
+++ b/lib/SimpleSAML/Configuration.php
@@ -214,15 +214,22 @@ class SimpleSAML_Configuration
      *
      * @param array  $config The configuration array.
      * @param string $location The location which will be given when an error occurs. Optional.
+     * @param string|null $instance The name of this instance. If specified, the configuration will be loaded and an
+     * instance with that name will be kept for it to be retrieved later with getInstance($instance). If null, the
+     * configuration will not be kept for later use. Defaults to null.
      *
      * @return SimpleSAML_Configuration The configuration object.
      */
-    public static function loadFromArray($config, $location = '[ARRAY]')
+    public static function loadFromArray($config, $location = '[ARRAY]', $instance = null)
     {
         assert('is_array($config)');
         assert('is_string($location)');
 
-        return new SimpleSAML_Configuration($config, $location);
+        $c = new SimpleSAML_Configuration($config, $location);
+        if ($instance !== null) {
+            self::$instance[$instance] = $c;
+        }
+        return $c;
     }
 
 
@@ -245,14 +252,16 @@ class SimpleSAML_Configuration
     {
         assert('is_string($instancename)');
 
+        // check if the instance exists already
+        if (array_key_exists($instancename, self::$instance)) {
+            return self::$instance[$instancename];
+        }
+
         if ($instancename === 'simplesaml') {
             return self::getConfig();
         }
 
-        if (!array_key_exists($instancename, self::$instance)) {
-            throw new Exception('Configuration with name '.$instancename.' is not initialized.');
-        }
-        return self::$instance[$instancename];
+        throw new Exception('Configuration with name '.$instancename.' is not initialized.');
     }
 
 
diff --git a/tests/lib/SimpleSAML/ConfigurationTest.php b/tests/lib/SimpleSAML/ConfigurationTest.php
index 8fb8aa854..548f2a966 100644
--- a/tests/lib/SimpleSAML/ConfigurationTest.php
+++ b/tests/lib/SimpleSAML/ConfigurationTest.php
@@ -522,4 +522,35 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase
         $c->getLocalizedString('opt');
     }
 
+
+    /**
+     * Test that the default instance fails to load even if we previously loaded another instance.
+     * @expectedException Exception
+     */
+    public function testLoadDefaultInstance()
+    {
+        SimpleSAML_Configuration::loadFromArray(array('key' => 'value'), '', 'dummy');
+        $c = SimpleSAML_Configuration::getInstance();
+        var_dump($c);
+    }
+
+
+    /**
+     * Test that Configuration objects can be initialized from an array.
+     *
+     * ATTENTION: this test must be kept the last.
+     */
+    public function testLoadInstanceFromArray()
+    {
+        $c = array(
+            'key' => 'value'
+        );
+        // test loading a custom instance
+        SimpleSAML_Configuration::loadFromArray($c, '', 'dummy');
+        $this->assertEquals('value', SimpleSAML_Configuration::getInstance('dummy')->getValue('key', null));
+
+        // test loading the default instance
+        SimpleSAML_Configuration::loadFromArray($c, '', 'simplesaml');
+        $this->assertEquals('value', SimpleSAML_Configuration::getInstance()->getValue('key', null));
+    }
 }
-- 
GitLab