Skip to content

Commit

Permalink
Merge pull request #276 from ZeeCoder/feature/protected-env-params
Browse files Browse the repository at this point in the history
Added the possibility of 'protected' env parameters. (+test).
  • Loading branch information
Anton Medvedev committed May 22, 2015
2 parents f5a1828 + 78a2681 commit 9842ccf
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 3 deletions.
49 changes: 48 additions & 1 deletion src/Server/Environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@ class Environment
* @var \Deployer\Type\DotArray
*/
private $values = null;


/**
* Values represented by their keys here are protected, and cannot be
* changed by calling the `set` method.
* @var array
*/
private $protectedNames = [];

/**
* Constructor
*/
Expand All @@ -40,9 +47,49 @@ public function __construct()
*/
public function set($name, $value)
{
$this->checkIfNameIsProtected($name);
$this->values[$name] = $value;
}

/**
* @param string $name
* @param bool|int|string|array $value
*/
public function setAsProtected($name, $value)
{
$this->set($name, $value);
$this->protectedNames[] = $name;
}

/**
* Checks whether the given name was registered as protected, or if there is
* a protected parameter which would be overwritten.
* @param string $name
* @throws \RuntimeException if the value already exists and is protected.
* @throws \RuntimeException if there's a protected parameter which would
* be overwritten.
*/
private function checkIfNameIsProtected($name)
{
$nameArray = strpos($name, '.') !== false ? explode('.', $name) : [$name];

// Checks every level for protection
foreach ($nameArray as $subName) {
$dotName = !isset($dotName) ? $subName : "$dotName.$subName";
if (in_array($dotName, $this->protectedNames)) {
throw new \RuntimeException("The parameter `$name` cannot be set, because " . ($name === $dotName ? "it's" : "`$dotName` is" ) . " protected.");
}
}

// Even if not one of $name's levels is protected, protected env params
// under it could still exist, so let's check for those too.
foreach ($this->protectedNames as $protectedName) {
if (strpos($protectedName, $name) !== false) {
throw new \RuntimeException("The parameter `$name` could not be set, because a protected parameter named `$protectedName` already exists.");
}
}
}

/**
* @param string $name
* @param bool|int|string|array $default
Expand Down
77 changes: 75 additions & 2 deletions test/src/Server/EnvironmentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Deployer\Server;

class EnvironmentTest extends \PHPUnit_Framework_TestCase
Expand All @@ -30,7 +30,7 @@ public function testEnvironment()
$env->set('string', 'value');
$env->set('array', [1, 'two']);
$env->set('parse', 'is {{int}}');

$this->assertEquals(42, $env->get('int'));
$this->assertEquals('value', $env->get('string'));
$this->assertEquals([1, 'two'], $env->get('array'));
Expand All @@ -39,10 +39,83 @@ public function testEnvironment()
$this->assertEquals('default', Environment::getDefault('default'));
$this->assertEquals('callback', $env->get('callback'));
$this->assertEquals('is 42', $env->get('parse'));

$env->set('int', 11);
$this->assertEquals('is 11', $env->get('parse'));

$this->setExpectedException('RuntimeException', 'Environment parameter `so` does not exists.');
$env->get('so');
}

/**
* Protected env parameters cannot be changed.
* @expectedException \RuntimeException
* @expectedExceptionMessage The parameter `protected` cannot be set, because it's protected.
*/
public function testProtection()
{
$env = new Environment();
$env->setAsProtected('protected', 'value');
$env->set('protected', 'value');
}

/**
* Elements of a protected env array parameter cannot be changed by the dot
* notation.
* @expectedException \RuntimeException
* @expectedExceptionMessage The parameter `protected.protected_key` cannot be set, because `protected` is protected.
*/
public function testProtectionWithDots()
{
$env = new Environment();
$env->setAsProtected('protected', [
'protected_key' => 'value',
]);
$env->set('protected.protected_key', 'some-other-value');
}

/**
* @expectedException \RuntimeException
* @expectedExceptionMessage The parameter `not_protected.protected` cannot be set, because it's protected.
*/
public function testSubArrayProtection()
{
$env = new Environment();
$env->set('not_protected', []);
$env->setAsProtected('not_protected.protected', 'value');
$env->set('not_protected.protected', 'value');
}

/**
* @expectedException \RuntimeException
* @expectedExceptionMessage The parameter `not_protected.protected.under_protection` cannot be set, because `not_protected.protected` is protected.
*/
public function testUpperArrayProtection()
{
$env = new Environment();
$env->set('not_protected', []);
$env->setAsProtected('not_protected.protected', [
'under_protection' => 'value',
]);

// Since the `under_protection` key is under the protected
// `not_protected.protected` parameter, the following operation is not
// allowed.
$env->set('not_protected.protected.under_protection', 'value');
}

/**
* @expectedException \RuntimeException
* @expectedExceptionMessage The parameter `not_protected` could not be set, because a protected parameter named `not_protected.protected` already exists.
*/
public function testContainingProtectedParam()
{
$env = new Environment();
$env->set('not_protected', []);
$env->setAsProtected('not_protected.protected', 'value');

// Since `not_protected.protected` is a protected parameter, overwriting
// the whole `not_protected` parameter is not allowed.
$env->setAsProtected('not_protected', 'value');
}
}

0 comments on commit 9842ccf

Please sign in to comment.