Initial implementation of the Kolab_Config package.
authorGunnar Wrobel <p@rdus.de>
Mon, 28 Jun 2010 07:05:00 +0000 (09:05 +0200)
committerGunnar Wrobel <p@rdus.de>
Mon, 28 Jun 2010 07:05:00 +0000 (09:05 +0200)
12 files changed:
framework/Kolab_Config/lib/Horde/Kolab/Config.php [new file with mode: 0644]
framework/Kolab_Config/lib/Horde/Kolab/Config/Exception.php [new file with mode: 0644]
framework/Kolab_Config/package.xml
framework/Kolab_Config/test/Horde/Kolab/Config/AllTests.php
framework/Kolab_Config/test/Horde/Kolab/Config/Autoload.php
framework/Kolab_Config/test/Horde/Kolab/Config/ConfigStoryTestCase.php [new file with mode: 0644]
framework/Kolab_Config/test/Horde/Kolab/Config/Integration/ConfigTest.php
framework/Kolab_Config/test/Horde/Kolab/Config/conf.php.dist [new file with mode: 0644]
framework/Kolab_Config/test/Horde/Kolab/Config/fixture/empty/no_config_file [new file with mode: 0644]
framework/Kolab_Config/test/Horde/Kolab/Config/fixture/global/globals.conf [new file with mode: 0644]
framework/Kolab_Config/test/Horde/Kolab/Config/fixture/local/kolab.conf [new file with mode: 0644]
framework/Kolab_Config/test/Horde/Kolab/Config/fixture/local/kolab.globals [new file with mode: 0644]

diff --git a/framework/Kolab_Config/lib/Horde/Kolab/Config.php b/framework/Kolab_Config/lib/Horde/Kolab/Config.php
new file mode 100644 (file)
index 0000000..85c75fb
--- /dev/null
@@ -0,0 +1,214 @@
+<?php
+/**
+ * The Kolab Server configuration handler.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Config
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Config
+ */
+
+/**
+ * The Kolab Server configuration handler.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Config
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Config
+ */
+class Horde_Kolab_Config
+implements ArrayAccess
+{
+    /**
+     * The path to the directory holding the configuration files.
+     *
+     * @var string
+     */
+    private $_directory;
+
+    /**
+     * Name of the global configuration file.
+     *
+     * @var string
+     */
+    private $_global;
+
+    /**
+     * Name of the local configuration file.
+     *
+     * @var string
+     */
+    private $_local;
+
+    /**
+     * The configuration data.
+     *
+     * @var array
+     */
+    private $_data;
+
+    /**
+     * Constructor.
+     *
+     * @param string $directory The path to the directory holding the
+     *                          configuration files.
+     * @param string $global    Name of the global configuration file.
+     * @param string $local     Name of the local configuration file.
+     */
+    public function __construct(
+        $directory = '@kolab_server_dir@/etc/kolab',
+        $global = 'kolab.globals',
+        $local = 'kolab.conf'
+    ) {
+        if ($directory === '@kolab_server_dir@/etc/kolab') {
+            $this->_directory = '/kolab/etc/kolab';
+        } else {            
+            $this->_directory = realpath($directory);
+        }
+        $this->_global    = $global;
+        $this->_local     = $local;
+    }
+
+    /**
+     * Read the configuration files.
+     *
+     * @return NULL
+     */
+    public function read()
+    {
+        if (!file_exists($this->_getGlobalConfigFilePath())
+            && !file_exists($this->_getLocalConfigFilePath())) {
+            throw new Horde_Kolab_Config_Exception(
+                'No configuration files found in ' . $this->_directory . '.'
+            );
+        }
+
+        if (file_exists($this->_getGlobalConfigFilePath())) {
+            $this->_loadConfigurationFile(
+                $this->_getGlobalConfigFilePath()
+            );
+        }
+
+        if (file_exists($this->_getLocalConfigFilePath())) {
+            $this->_loadConfigurationFile(
+                $this->_getLocalConfigFilePath()
+            );
+        }
+    }
+
+    private function _loadConfigurationFile($path)
+    {
+        if ($this->_data === null) {
+            $this->_data = array();
+        }
+
+        $fh = fopen($path, 'r');
+
+        while (!feof($fh)) {
+            $line = trim(fgets($fh));
+            if ($line && preg_match('/^([^:#]+):(.*)/', $line, $matches)) {
+                $this->_data[trim($matches[1])] = trim($matches[2]);
+            }
+        }
+        fclose($fh);
+    }
+
+    /**
+     * Return the path to the global configuration file.
+     *
+     * @return NULL
+     */
+    private function _getGlobalConfigFilePath()
+    {
+        return $this->_directory . DIRECTORY_SEPARATOR . $this->_global;
+    }
+
+    /**
+     * Return the path to the local configuration file.
+     *
+     * @return NULL
+     */
+    private function _getLocalConfigFilePath()
+    {
+        return $this->_directory . DIRECTORY_SEPARATOR . $this->_local;
+    }
+
+    /**
+     * Initialize this object if this has not happened yet.
+     *
+     * @return NULL
+     */
+    private function _init()
+    {
+        if ($this->_data === null) {
+            $this->read();
+        }
+    }
+
+    /**
+     * Return the value for the given array key.
+     *
+     * @param string $key The key.
+     *
+     * @return mixed The value for the given key.
+     */
+    public function offsetGet($key)
+    {
+        if (!$this->offsetExists($key)) {
+            throw new Horde_Kolab_Config_Exception(
+                'Parameter "' . $key . '" has no value!'
+            );
+        }
+        return $this->_data[$key];
+    }
+
+    /**
+     * Does the requested array value exist in the configuration?
+     *
+     * @param string $key The key.
+     *
+     * @return boolean True if the configuration value exists.
+     */
+    public function offsetExists($key)
+    {
+        $this->_init();
+        if (!is_string($key) || empty($key)) {
+            throw new InvalidArgumentException(
+                'The key must be a non-empty string!'
+            );
+        }
+        return isset($this->_data[$key]);
+    }
+
+    /**
+     * Set the given key to the provided value.
+     *
+     * @param string $key   The key.
+     * @param mixed  $value The value that should be stored.
+     *
+     * @return NULL
+     */
+    public function offsetSet($key, $value)
+    {
+    }
+
+    /**
+     * Delete the value identified by the given key.
+     *
+     * @param string $key The key.
+     *
+     * @return NULL
+     */
+    public function offsetUnset($key)
+    {
+    }
+}
\ No newline at end of file
diff --git a/framework/Kolab_Config/lib/Horde/Kolab/Config/Exception.php b/framework/Kolab_Config/lib/Horde/Kolab/Config/Exception.php
new file mode 100644 (file)
index 0000000..8847f4d
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This class provides the standard error class for the Kolab_Config package.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Config
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Config
+ */
+
+/**
+ * This class provides the standard error class for the Kolab_Config package.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Config
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Config
+ */
+class Horde_Kolab_Config_Exception
+extends Exception
+{
+}
index 408f332..4ca3861 100644 (file)
@@ -25,7 +25,7 @@
   <active>yes</active>
  </lead>
  <date>2010-06-27</date>
- <time>11:39:36</time>
+ <time>18:56:35</time>
  <version>
   <release>0.1.0</release>
   <api>0.1.0</api>
  </notes>
  <contents>
   <dir baseinstalldir="/" name="/">
+   <dir name="lib">
+    <dir name="Horde">
+     <dir name="Kolab">
+      <dir name="Config">
+       <file name="Exception.php" role="php" />
+      </dir> <!-- /lib/Horde/Kolab/Config -->
+      <file name="Config.php" role="php" />
+     </dir> <!-- /lib/Horde/Kolab -->
+    </dir> <!-- /lib/Horde -->
+   </dir> <!-- /lib -->
    <dir name="test">
     <dir name="Horde">
      <dir name="Kolab">
       <dir name="Config">
+       <dir name="fixture">
+        <dir name="empty">
+         <file name="no_config_file" role="test" />
+        </dir> <!-- /test/Horde/Kolab/Config/fixture/empty -->
+       </dir> <!-- /test/Horde/Kolab/Config/fixture -->
        <dir name="Integration">
         <file name="ConfigTest.php" role="test" />
-       </dir> <!-- //test/Horde/Kolab/Config/Integration -->
+       </dir> <!-- /test/Horde/Kolab/Config/Integration -->
        <file name="AllTests.php" role="test" />
        <file name="Autoload.php" role="test" />
+       <file name="ConfigStoryTestCase.php" role="test" />
        <file name="phpunit.xml" role="test" />
-      </dir> <!-- //test/Horde/Kolab/Config -->
-     </dir> <!-- //test/Horde/Kolab -->
-    </dir> <!-- //test/Horde -->
-   </dir> <!-- //test -->
+      </dir> <!-- /test/Horde/Kolab/Config -->
+     </dir> <!-- /test/Horde/Kolab -->
+    </dir> <!-- /test/Horde -->
+   </dir> <!-- /test -->
   </dir> <!-- / -->
  </contents>
  <dependencies>
  </dependencies>
  <phprelease>
   <filelist>
+   <install as="Horde/Kolab/Config.php" name="lib/Horde/Kolab/Config.php" />
+   <install as="Horde/Kolab/Config/Exception.php" name="lib/Horde/Kolab/Config/Exception.php" />
    <install as="Horde/Kolab/Config/AllTests.php" name="test/Horde/Kolab/Config/AllTests.php" />
    <install as="Horde/Kolab/Config/Autoload.php" name="test/Horde/Kolab/Config/Autoload.php" />
+   <install as="Horde/Kolab/Config/ConfigStoryTestCase.php" name="test/Horde/Kolab/Config/ConfigStoryTestCase.php" />
    <install as="Horde/Kolab/Config/phpunit.xml" name="test/Horde/Kolab/Config/phpunit.xml" />
+   <install as="Horde/Kolab/Config/fixture/empty/no_config_file" name="test/Horde/Kolab/Config/fixture/empty/no_config_file" />
    <install as="Horde/Kolab/Config/Integration/ConfigTest.php" name="test/Horde/Kolab/Config/Integration/ConfigTest.php" />
   </filelist>
  </phprelease>
index 231c1b8..92c8225 100644 (file)
@@ -41,6 +41,53 @@ require_once 'Horde/Test/AllTests.php';
  */
 class Horde_Kolab_Config_AllTests extends Horde_Test_AllTests
 {
+    /**
+     * Main entry point for running the suite.
+     */
+    public static function main($package = null, $file = null)
+    {
+        if ($package) {
+            self::$_package = $package;
+        }
+        if ($file) {
+            self::$_file = $file;
+        }
+
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    /**
+     * Collect the unit tests of this directory into a new suite.
+     *
+     * @return PHPUnit_Framework_TestSuite The test suite.
+     */
+    public static function suite()
+    {
+        return self::detectTestFixture(Horde_Test_AllTests::suite());
+    }
+
+    /**
+     * Detect if test configuration is available for the server integration
+     * tests.
+     *
+     * @param PHPUnit_Framework_TestSuite $suite The current test suite.
+     */
+    public static function detectTestFixture(PHPUnit_Framework_TestSuite $suite)
+    {
+        $config = getenv('KOLAB_CONFIG_TEST_CONFIG');
+        if ($config === false) {
+            $config = dirname(__FILE__) . '/conf.php';
+        }
+        if (file_exists($config)) {
+            require $config;
+            if (isset($conf['kolab']['config']['test'])) {
+                $fixture = new stdClass;
+                $fixture->conf = $conf['kolab']['config']['test'];
+                $suite->setSharedFixture($fixture);
+            }
+        }
+        return $suite;
+    }
 }
 
 Horde_Kolab_Config_AllTests::init('Horde_Kolab_Config', __FILE__);
index a82afda..0e91eaa 100644 (file)
@@ -1,15 +1,20 @@
-
 <?php
 /**
  * Setup autoloading for the tests.
  *
  * PHP version 5
  *
- * @category Kolab
- * @package  Kolab_Config
- * @author   Gunnar Wrobel <wrobel@pardus.de>
- * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link     http://pear.horde.org/index.php?package=Kolab_Config
+ * Copyright 2009-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category   Kolab
+ * @package    Kolab_Config
+ * @subpackage UnitTests
+ * @author     Gunnar Wrobel <wrobel@pardus.de>
+ * @license    http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link       http://pear.horde.org/index.php?package=Kolab_Config
  */
 
 if (!spl_autoload_functions()) {
@@ -27,3 +32,7 @@ if (!spl_autoload_functions()) {
 
 /** Catch strict standards */
 error_reporting(E_ALL | E_STRICT);
+
+
+/** Load the basic test definition */
+require_once dirname(__FILE__) . '/ConfigStoryTestCase.php';
diff --git a/framework/Kolab_Config/test/Horde/Kolab/Config/ConfigStoryTestCase.php b/framework/Kolab_Config/test/Horde/Kolab/Config/ConfigStoryTestCase.php
new file mode 100644 (file)
index 0000000..6fc7150
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Base for session testing.
+ *
+ * PHP version 5
+ *
+ * @category   Kolab
+ * @package    Kolab_Config
+ * @subpackage UnitTests
+ * @author     Gunnar Wrobel <wrobel@pardus.de>
+ * @license    http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link       http://pear.horde.org/index.php?package=Kolab_Config
+ */
+
+/**
+ * Base for session testing.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category   Kolab
+ * @package    Kolab_Config
+ * @subpackage UnitTests
+ * @author     Gunnar Wrobel <wrobel@pardus.de>
+ * @license    http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link       http://pear.horde.org/index.php?package=Kolab_Config
+ */
+class Horde_Kolab_Config_ConfigStoryTestCase
+extends PHPUnit_Extensions_Story_TestCase
+{
+    /**
+     * Handle a "given" step.
+     *
+     * @param array  &$world    Joined "world" of variables.
+     * @param string $action    The description of the step.
+     * @param array  $arguments Additional arguments to the step.
+     *
+     * @return mixed The outcome of the step.
+     */
+    public function runGiven(&$world, $action, $arguments)
+    {
+        switch($action) {
+        case 'that no Kolab server configuration file can be found':
+            $world['config'] = new Horde_Kolab_Config(
+                dirname(__FILE__) . '/fixture/empty'
+            );
+            break;
+        case 'that a global configuration file was specified as a combination of a directory path and a file name':
+            $world['config'] = new Horde_Kolab_Config(
+                dirname(__FILE__) . '/fixture/global',
+                'globals.conf'
+            );
+            break;
+        case 'that the location of the configuration files were specified with a directory path':
+            $world['config'] = new Horde_Kolab_Config(
+                dirname(__FILE__) . '/fixture/local'
+            );
+            break;
+        default:
+            return $this->notImplemented($action);
+        }
+    }
+
+    /**
+     * Handle a "when" step.
+     *
+     * @param array  &$world    Joined "world" of variables.
+     * @param string $action    The description of the step.
+     * @param array  $arguments Additional arguments to the step.
+     *
+     * @return mixed The outcome of the step.
+     */
+    public function runWhen(&$world, $action, $arguments)
+    {
+        switch($action) {
+        case 'reading the configuration':
+            try {
+                $world['config']->read();
+            } catch (Horde_Kolab_Config_Exception $e) {
+                $world['result'] = $e;
+            }
+            break;
+        case 'reading the parameter':
+            try {
+                $world['result'] = $world['config'][$arguments[0]];
+            } catch (Exception $e) {
+                $world['result'] = $e;
+            }
+            break;
+        default:
+            return $this->notImplemented($action);
+        }
+    }
+
+    /**
+     * Handle a "then" step.
+     *
+     * @param array  &$world    Joined "world" of variables.
+     * @param string $action    The description of the step.
+     * @param array  $arguments Additional arguments to the step.
+     *
+     * @return mixed The outcome of the step.
+     */
+    public function runThen(&$world, $action, $arguments)
+    {
+        switch($action) {
+        case 'the Config Object will throw an exception of type':
+            $this->assertType(
+                $arguments[0], $world['result']
+            );
+            break;
+        case 'the exception has the message':
+            $this->assertEquals(
+                $arguments[0], $world['result']->getMessage()
+            );
+            break;
+        case 'the result will be':
+            if ($world['result'] instanceOf Exception) {
+                $this->assertEquals(
+                    '', $world['result']->getMessage()
+                );
+            } else {
+                $this->assertEquals($arguments[0], $world['result']);
+            }
+            break;
+        default:
+            return $this->notImplemented($action);
+        }
+    }
+
+}
\ No newline at end of file
index a57e334..01d81b1 100644 (file)
@@ -4,11 +4,12 @@
  *
  * PHP version 5
  *
- * @category Kolab
- * @package  Kolab_Config
- * @author   Gunnar Wrobel <wrobel@pardus.de>
- * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link     http://pear.horde.org/index.php?package=Kolab_Config
+ * @category   Kolab
+ * @package    Kolab_Config
+ * @subpackage UnitTests
+ * @author     Gunnar Wrobel <wrobel@pardus.de>
+ * @license    http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link       http://pear.horde.org/index.php?package=Kolab_Config
  */
 
 /**
 require_once dirname(__FILE__) . '/../Autoload.php';
 
 /**
- * Test the Kolab session handler base implementation.
+ * Test the Kolab configuration handler.
  *
- * Copyright 2009-2010 The Horde Project (http://www.horde.org/)
+ * Copyright 2010 Klarälvdalens Datakonsult AB
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  *
- * @category Kolab
- * @package  Kolab_Config
- * @author   Gunnar Wrobel <wrobel@pardus.de>
- * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link     http://pear.horde.org/index.php?package=Kolab_Config
+ * @category   Kolab
+ * @package    Kolab_Config
+ * @subpackage UnitTests
+ * @author     Gunnar Wrobel <wrobel@pardus.de>
+ * @license    http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link       http://pear.horde.org/index.php?package=Kolab_Config
  */
 class Horde_Kolab_Config_Integration_ConfigTest
-extends PHPUnit_Framework_TestCase
+extends Horde_Kolab_Config_ConfigStoryTestCase
 {
+    /**
+     * @scenario
+     */
+    public function aMissingGlobalConfigurationFileThrowsAnException()
+    {
+        $this->given('that no Kolab server configuration file can be found')
+            ->when('reading the configuration')
+            ->then('the Config Object will throw an exception of type', 'Horde_Kolab_Config_Exception')
+            ->and('the exception has the message',
+                  'No configuration files found in '
+                  . realpath(dirname(__FILE__) . '/../fixture/empty') . '.'
+            );
+    }
+
+    /**
+     * @scenario
+     */
+    public function theNameOfTheGlobalConfigurationDirectoryAndFileCanBeSpecified()
+    {
+        $this->given('that a global configuration file was specified as a combination of a directory path and a file name')
+            ->when('reading the parameter', 'global')
+            ->then('the result will be', 'global');
+    }
+
+    /**
+     * @scenario
+     */
+    public function theNameOfTheConfigurationDirectoryCanBeSpecified()
+    {
+        $this->given('that the location of the configuration files were specified with a directory path')
+            ->when('reading the parameter', 'local')
+            ->then('the result will be', 'local');
+    }
+
+    /**
+     * @scenario
+     */
+    public function readingAConfigurationYieldsTheGlobalConfigurationValueIfTheLocalOneIsMissing()
+    {
+        $this->given('that the location of the configuration files were specified with a directory path')
+            ->when('reading the parameter', 'only_global')
+            ->then('the result will be', 'global');
+    }
+
+    /**
+     * @scenario
+     */
+    public function readingAConfigurationYieldsTheLocalConfigurationValueIfItIsSetInBothConfigurationFiles()
+    {
+        $this->given('that the location of the configuration files were specified with a directory path')
+            ->when('reading the parameter', 'both')
+            ->then('the result will be', 'local');
+    }
+
+    /**
+     * @scenario
+     */
+    public function readingAConfigurationWithAnInvalidKeyThrowsAnException()
+    {
+        $this->given('that the location of the configuration files were specified with a directory path')
+            ->when('reading the parameter', array())
+            ->then('the Config Object will throw an exception of type', 'InvalidArgumentException')
+            ->and(
+                'the exception has the message',
+                'The key must be a non-empty string!'
+            );
+    }
 
-    public function testSomething()
+    /**
+     * @scenario
+     */
+    public function tryingToReadAMissingConfigurationValueThrowsAnException()
     {
+        $this->given('that the location of the configuration files were specified with a directory path')
+            ->when('reading the parameter', 'unknown')
+            ->then('the Config Object will throw an exception of type', 'Horde_Kolab_Config_Exception')
+            ->and(
+                'the exception has the message',
+                'Parameter "unknown" has no value!'
+            );
     }
 }
\ No newline at end of file
diff --git a/framework/Kolab_Config/test/Horde/Kolab/Config/conf.php.dist b/framework/Kolab_Config/test/Horde/Kolab/Config/conf.php.dist
new file mode 100644 (file)
index 0000000..16efc53
--- /dev/null
@@ -0,0 +1,2 @@
+<?php
+$conf['kolab']['config']['directory'] = '/kolab/etc/kolab';
diff --git a/framework/Kolab_Config/test/Horde/Kolab/Config/fixture/empty/no_config_file b/framework/Kolab_Config/test/Horde/Kolab/Config/fixture/empty/no_config_file
new file mode 100644 (file)
index 0000000..c6cac69
--- /dev/null
@@ -0,0 +1 @@
+empty
diff --git a/framework/Kolab_Config/test/Horde/Kolab/Config/fixture/global/globals.conf b/framework/Kolab_Config/test/Horde/Kolab/Config/fixture/global/globals.conf
new file mode 100644 (file)
index 0000000..c34878b
--- /dev/null
@@ -0,0 +1 @@
+global: global
diff --git a/framework/Kolab_Config/test/Horde/Kolab/Config/fixture/local/kolab.conf b/framework/Kolab_Config/test/Horde/Kolab/Config/fixture/local/kolab.conf
new file mode 100644 (file)
index 0000000..eed3e11
--- /dev/null
@@ -0,0 +1,2 @@
+local: local
+both: local
diff --git a/framework/Kolab_Config/test/Horde/Kolab/Config/fixture/local/kolab.globals b/framework/Kolab_Config/test/Horde/Kolab/Config/fixture/local/kolab.globals
new file mode 100644 (file)
index 0000000..49df0be
--- /dev/null
@@ -0,0 +1,3 @@
+local: global
+only_global: global
+both: global