Nest and unnest Config and Controller for each test and test suite

This commit is contained in:
Daniel Hensby 2015-03-06 22:37:06 +00:00 committed by Daniel Hensby
parent 38ca214e2b
commit 3ee5b24898
9 changed files with 275 additions and 320 deletions

View File

@ -5,12 +5,12 @@ require_once 'TestRunner.php';
* Test case class for the Sapphire framework. * Test case class for the Sapphire framework.
* Sapphire unit testing is based on PHPUnit, but provides a number of hooks into our data model that make it easier * Sapphire unit testing is based on PHPUnit, but provides a number of hooks into our data model that make it easier
* to work with. * to work with.
* *
* @package framework * @package framework
* @subpackage testing * @subpackage testing
*/ */
class SapphireTest extends PHPUnit_Framework_TestCase { class SapphireTest extends PHPUnit_Framework_TestCase {
/** @config */ /** @config */
private static $dependencies = array( private static $dependencies = array(
'fixtureFactory' => '%$FixtureFactory', 'fixtureFactory' => '%$FixtureFactory',
@ -21,7 +21,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
* If passed as an array, multiple fixture files will be loaded. * If passed as an array, multiple fixture files will be loaded.
* Please note that you won't be able to refer with "=>" notation * Please note that you won't be able to refer with "=>" notation
* between the fixtures, they act independent of each other. * between the fixtures, they act independent of each other.
* *
* @var string|array * @var string|array
*/ */
protected static $fixture_file = null; protected static $fixture_file = null;
@ -30,19 +30,19 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
* @var FixtureFactory * @var FixtureFactory
*/ */
protected $fixtureFactory; protected $fixtureFactory;
/** /**
* @var bool Set whether to include this test in the TestRunner or to skip this. * @var bool Set whether to include this test in the TestRunner or to skip this.
*/ */
protected $skipTest = false; protected $skipTest = false;
/** /**
* @var Boolean If set to TRUE, this will force a test database to be generated * @var Boolean If set to TRUE, this will force a test database to be generated
* in {@link setUp()}. Note that this flag is overruled by the presence of a * in {@link setUp()}. Note that this flag is overruled by the presence of a
* {@link $fixture_file}, which always forces a database build. * {@link $fixture_file}, which always forces a database build.
*/ */
protected $usesDatabase = null; protected $usesDatabase = null;
protected $originalMailer; protected $originalMailer;
protected $originalMemberPasswordValidator; protected $originalMemberPasswordValidator;
protected $originalRequirements; protected $originalRequirements;
@ -50,33 +50,33 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
protected $originalTheme; protected $originalTheme;
protected $originalNestedURLsState; protected $originalNestedURLsState;
protected $originalMemoryLimit; protected $originalMemoryLimit;
protected $mailer; protected $mailer;
/** /**
* Pointer to the manifest that isn't a test manifest * Pointer to the manifest that isn't a test manifest
*/ */
protected static $regular_manifest; protected static $regular_manifest;
/** /**
* @var boolean * @var boolean
*/ */
protected static $is_running_test = false; protected static $is_running_test = false;
protected static $test_class_manifest; protected static $test_class_manifest;
/** /**
* By default, setUp() does not require default records. Pass * By default, setUp() does not require default records. Pass
* class names in here, and the require/augment default records * class names in here, and the require/augment default records
* function will be called on them. * function will be called on them.
*/ */
protected $requireDefaultRecordsFrom = array(); protected $requireDefaultRecordsFrom = array();
/** /**
* A list of extensions that can't be applied during the execution of this run. If they are * A list of extensions that can't be applied during the execution of this run. If they are
* applied, they will be temporarily removed and a database migration called. * applied, they will be temporarily removed and a database migration called.
* *
* The keys of the are the classes that the extensions can't be applied the extensions to, and * The keys of the are the classes that the extensions can't be applied the extensions to, and
* the values are an array of illegal extensions on that class. * the values are an array of illegal extensions on that class.
*/ */
@ -86,10 +86,10 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
/** /**
* A list of extensions that must be applied during the execution of this run. If they are * A list of extensions that must be applied during the execution of this run. If they are
* not applied, they will be temporarily added and a database migration called. * not applied, they will be temporarily added and a database migration called.
* *
* The keys of the are the classes to apply the extensions to, and the values are an array * The keys of the are the classes to apply the extensions to, and the values are an array
* of required extensions on that class. * of required extensions on that class.
* *
* Example: * Example:
* <code> * <code>
* array("MyTreeDataObject" => array("Versioned", "Hierarchy")) * array("MyTreeDataObject" => array("Versioned", "Hierarchy"))
@ -97,35 +97,35 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
*/ */
protected $requiredExtensions = array( protected $requiredExtensions = array(
); );
/** /**
* By default, the test database won't contain any DataObjects that have the interface TestOnly. * By default, the test database won't contain any DataObjects that have the interface TestOnly.
* This variable lets you define additional TestOnly DataObjects to set up for this test. * This variable lets you define additional TestOnly DataObjects to set up for this test.
* Set it to an array of DataObject subclass names. * Set it to an array of DataObject subclass names.
*/ */
protected $extraDataObjects = array(); protected $extraDataObjects = array();
/** /**
* We need to disabling backing up of globals to avoid overriding * We need to disabling backing up of globals to avoid overriding
* the few globals SilverStripe relies on, like $lang for the i18n subsystem. * the few globals SilverStripe relies on, like $lang for the i18n subsystem.
* *
* @see http://sebastian-bergmann.de/archives/797-Global-Variables-and-PHPUnit.html * @see http://sebastian-bergmann.de/archives/797-Global-Variables-and-PHPUnit.html
*/ */
protected $backupGlobals = FALSE; protected $backupGlobals = FALSE;
/** /**
* Helper arrays for illegalExtensions/requiredExtensions code * Helper arrays for illegalExtensions/requiredExtensions code
*/ */
private $extensionsToReapply = array(), $extensionsToRemove = array(); private $extensionsToReapply = array(), $extensionsToRemove = array();
/** /**
* Determines if unit tests are currently run (via {@link TestRunner}). * Determines if unit tests are currently run (via {@link TestRunner}).
* This is used as a cheap replacement for fully mockable state * This is used as a cheap replacement for fully mockable state
* in certain contiditions (e.g. access checks). * in certain contiditions (e.g. access checks).
* Caution: When set to FALSE, certain controllers might bypass * Caution: When set to FALSE, certain controllers might bypass
* access checks, so this is a very security sensitive setting. * access checks, so this is a very security sensitive setting.
* *
* @return boolean * @return boolean
*/ */
public static function is_running_test() { public static function is_running_test() {
@ -133,7 +133,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
} }
public static function set_is_running_test($bool) { public static function set_is_running_test($bool) {
self::$is_running_test = $bool; self::$is_running_test = $bool;
} }
/** /**
@ -161,22 +161,27 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
* @var array $fixtures Array of {@link YamlFixture} instances * @var array $fixtures Array of {@link YamlFixture} instances
* @deprecated 3.1 Use $fixtureFactory instad * @deprecated 3.1 Use $fixtureFactory instad
*/ */
protected $fixtures = array(); protected $fixtures = array();
protected $model; protected $model;
public function setUp() { public function setUp() {
//nest config and injector for each test so they are effectively sandboxed per test
Config::nest();
Injector::nest();
// We cannot run the tests on this abstract class. // We cannot run the tests on this abstract class.
if(get_class($this) == "SapphireTest") $this->skipTest = true; if(get_class($this) == "SapphireTest") $this->skipTest = true;
if($this->skipTest) { if($this->skipTest) {
$this->markTestSkipped(sprintf( $this->markTestSkipped(sprintf(
'Skipping %s ', get_class($this) 'Skipping %s ', get_class($this)
)); ));
return; return;
} }
// Mark test as being run // Mark test as being run
$this->originalIsRunningTest = self::$is_running_test; $this->originalIsRunningTest = self::$is_running_test;
self::$is_running_test = true; self::$is_running_test = true;
@ -185,16 +190,16 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
i18n::set_locale(i18n::default_locale()); i18n::set_locale(i18n::default_locale());
i18n::config()->date_format = null; i18n::config()->date_format = null;
i18n::config()->time_format = null; i18n::config()->time_format = null;
// Set default timezone consistently to avoid NZ-specific dependencies // Set default timezone consistently to avoid NZ-specific dependencies
date_default_timezone_set('UTC'); date_default_timezone_set('UTC');
// Remove password validation // Remove password validation
$this->originalMemberPasswordValidator = Member::password_validator(); $this->originalMemberPasswordValidator = Member::password_validator();
$this->originalRequirements = Requirements::backend(); $this->originalRequirements = Requirements::backend();
Member::set_password_validator(null); Member::set_password_validator(null);
Config::inst()->update('Cookie', 'report_errors', false); Config::inst()->update('Cookie', 'report_errors', false);
if(class_exists('RootURLController')) RootURLController::reset(); if(class_exists('RootURLController')) RootURLController::reset();
if(class_exists('Translatable')) Translatable::reset(); if(class_exists('Translatable')) Translatable::reset();
Versioned::reset(); Versioned::reset();
@ -203,7 +208,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
Hierarchy::reset(); Hierarchy::reset();
if(Controller::has_curr()) Controller::curr()->setSession(Injector::inst()->create('Session', array())); if(Controller::has_curr()) Controller::curr()->setSession(Injector::inst()->create('Session', array()));
Security::$database_is_ready = null; Security::$database_is_ready = null;
$fixtureFile = static::get_fixture_file(); $fixtureFile = static::get_fixture_file();
$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_'; $prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
@ -213,13 +218,13 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
$this->mailer = new TestMailer(); $this->mailer = new TestMailer();
Email::set_mailer($this->mailer); Email::set_mailer($this->mailer);
Config::inst()->remove('Email', 'send_all_emails_to'); Config::inst()->remove('Email', 'send_all_emails_to');
// Todo: this could be a special test model // Todo: this could be a special test model
$this->model = DataModel::inst(); $this->model = DataModel::inst();
// Set up fixture // Set up fixture
if($fixtureFile || $this->usesDatabase || !self::using_temp_db()) { if($fixtureFile || $this->usesDatabase || !self::using_temp_db()) {
if(substr(DB::getConn()->currentDatabase(), 0, strlen($prefix) + 5) if(substr(DB::getConn()->currentDatabase(), 0, strlen($prefix) + 5)
!= strtolower(sprintf('%stmpdb', $prefix))) { != strtolower(sprintf('%stmpdb', $prefix))) {
//echo "Re-creating temp database... "; //echo "Re-creating temp database... ";
@ -228,9 +233,9 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
} }
singleton('DataObject')->flushCache(); singleton('DataObject')->flushCache();
self::empty_temp_db(); self::empty_temp_db();
foreach($this->requireDefaultRecordsFrom as $className) { foreach($this->requireDefaultRecordsFrom as $className) {
$instance = singleton($className); $instance = singleton($className);
if (method_exists($instance, 'requireDefaultRecords')) $instance->requireDefaultRecords(); if (method_exists($instance, 'requireDefaultRecords')) $instance->requireDefaultRecords();
@ -245,14 +250,14 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
foreach($fixtureFiles as $fixtureFilePath) { foreach($fixtureFiles as $fixtureFilePath) {
// Support fixture paths relative to the test class, rather than relative to webroot // Support fixture paths relative to the test class, rather than relative to webroot
// String checking is faster than file_exists() calls. // String checking is faster than file_exists() calls.
$isRelativeToFile = (strpos('/', $fixtureFilePath) === false $isRelativeToFile = (strpos('/', $fixtureFilePath) === false
|| preg_match('/^\.\./', $fixtureFilePath)); || preg_match('/^\.\./', $fixtureFilePath));
if($isRelativeToFile) { if($isRelativeToFile) {
$resolvedPath = realpath($pathForClass . '/' . $fixtureFilePath); $resolvedPath = realpath($pathForClass . '/' . $fixtureFilePath);
if($resolvedPath) $fixtureFilePath = $resolvedPath; if($resolvedPath) $fixtureFilePath = $resolvedPath;
} }
$fixture = Injector::inst()->create('YamlFixture', $fixtureFilePath); $fixture = Injector::inst()->create('YamlFixture', $fixtureFilePath);
$fixture->writeInto($this->getFixtureFactory()); $fixture->writeInto($this->getFixtureFactory());
$this->fixtures[] = $fixture; $this->fixtures[] = $fixture;
@ -262,20 +267,20 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
$i++; $i++;
} }
} }
$this->logInWithPermission("ADMIN"); $this->logInWithPermission("ADMIN");
} }
// Preserve memory settings // Preserve memory settings
$this->originalMemoryLimit = ini_get('memory_limit'); $this->originalMemoryLimit = ini_get('memory_limit');
// turn off template debugging // turn off template debugging
Config::inst()->update('SSViewer', 'source_file_comments', false); Config::inst()->update('SSViewer', 'source_file_comments', false);
// Clear requirements // Clear requirements
Requirements::clear(); Requirements::clear();
} }
/** /**
* Called once per test case ({@link SapphireTest} subclass). * Called once per test case ({@link SapphireTest} subclass).
* This is different to {@link setUp()}, which gets called once * This is different to {@link setUp()}, which gets called once
@ -285,6 +290,10 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
* for tearing down the state again. * for tearing down the state again.
*/ */
public function setUpOnce() { public function setUpOnce() {
//nest config and injector for each suite so they are effectively sandboxed
Config::nest();
Injector::nest();
$isAltered = false; $isAltered = false;
if(!Director::isDev()) { if(!Director::isDev()) {
@ -315,46 +324,34 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
} }
} }
} }
// If we have made changes to the extensions present, then migrate the database schema. // If we have made changes to the extensions present, then migrate the database schema.
if($isAltered || $this->extensionsToReapply || $this->extensionsToRemove || $this->extraDataObjects) { if($isAltered || $this->extensionsToReapply || $this->extensionsToRemove || $this->extraDataObjects) {
if(!self::using_temp_db()) self::create_temp_db(); if(!self::using_temp_db()) self::create_temp_db();
$this->resetDBSchema(true); $this->resetDBSchema(true);
} }
// clear singletons, they're caching old extension info // clear singletons, they're caching old extension info
// which is used in DatabaseAdmin->doBuild() // which is used in DatabaseAdmin->doBuild()
Injector::inst()->unregisterAllObjects(); Injector::inst()->unregisterAllObjects();
// Set default timezone consistently to avoid NZ-specific dependencies // Set default timezone consistently to avoid NZ-specific dependencies
date_default_timezone_set('UTC'); date_default_timezone_set('UTC');
} }
/** /**
* tearDown method that's called once per test class rather once per test method. * tearDown method that's called once per test class rather once per test method.
*/ */
public function tearDownOnce() { public function tearDownOnce() {
// If we have made changes to the extensions present, then migrate the database schema. //unnest injector / config now that the test suite is over
if($this->extensionsToReapply || $this->extensionsToRemove) { // this will reset all the extensions on the object too (see setUpOnce)
// Remove extensions added for testing Injector::unnest();
foreach($this->extensionsToRemove as $class => $extensions) { Config::unnest();
foreach($extensions as $extension) {
$class::remove_extension($extension);
}
}
// Reapply ones removed
foreach($this->extensionsToReapply as $class => $extensions) {
foreach($extensions as $extension) {
$class::add_extension($extension);
}
}
}
if($this->extensionsToReapply || $this->extensionsToRemove || $this->extraDataObjects) { if($this->extensionsToReapply || $this->extensionsToRemove || $this->extraDataObjects) {
$this->resetDBSchema(); $this->resetDBSchema();
} }
} }
/** /**
* @return FixtureFactory * @return FixtureFactory
*/ */
@ -367,10 +364,10 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
$this->fixtureFactory = $factory; $this->fixtureFactory = $factory;
return $this; return $this;
} }
/** /**
* Get the ID of an object from the fixture. * Get the ID of an object from the fixture.
* *
* @param $className The data class, as specified in your fixture file. Parent classes won't work * @param $className The data class, as specified in your fixture file. Parent classes won't work
* @param $identifier The identifier string, as provided in your fixture file * @param $identifier The identifier string, as provided in your fixture file
* @return int * @return int
@ -416,12 +413,12 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
"Couldn't find object '%s' (class: %s)", "Couldn't find object '%s' (class: %s)",
$identifier, $identifier,
$className $className
), E_USER_ERROR); ), E_USER_ERROR);
} }
return $obj; return $obj;
} }
/** /**
* Load a YAML fixture file into the database. * Load a YAML fixture file into the database.
* Once loaded, you can use idFromFixture() and objFromFixture() to get items from the fixture. * Once loaded, you can use idFromFixture() and objFromFixture() to get items from the fixture.
@ -434,19 +431,19 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
$fixture->writeInto($this->getFixtureFactory()); $fixture->writeInto($this->getFixtureFactory());
$this->fixtures[] = $fixture; $this->fixtures[] = $fixture;
} }
/** /**
* Clear all fixtures which were previously loaded through * Clear all fixtures which were previously loaded through
* {@link loadFixture()} * {@link loadFixture()}
*/ */
public function clearFixtures() { public function clearFixtures() {
$this->fixtures = array(); $this->fixtures = array();
$this->getFixtureFactory()->clear(); $this->getFixtureFactory()->clear();
} }
/** /**
* Useful for writing unit tests without hardcoding folder structures. * Useful for writing unit tests without hardcoding folder structures.
* *
* @return String Absolute path to current class. * @return String Absolute path to current class.
*/ */
protected function getCurrentAbsolutePath() { protected function getCurrentAbsolutePath() {
@ -454,7 +451,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
if(!$filename) throw new LogicException("getItemPath returned null for " . get_class($this)); if(!$filename) throw new LogicException("getItemPath returned null for " . get_class($this));
return dirname($filename); return dirname($filename);
} }
/** /**
* @return String File path relative to webroot * @return String File path relative to webroot
*/ */
@ -464,7 +461,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
if(substr($path,0,strlen($base)) == $base) $path = preg_replace('/^\/*/', '', substr($path,strlen($base))); if(substr($path,0,strlen($base)) == $base) $path = preg_replace('/^\/*/', '', substr($path,strlen($base)));
return $path; return $path;
} }
public function tearDown() { public function tearDown() {
// Preserve memory settings // Preserve memory settings
ini_set('memory_limit', ($this->originalMemoryLimit) ? $this->originalMemoryLimit : -1); ini_set('memory_limit', ($this->originalMemoryLimit) ? $this->originalMemoryLimit : -1);
@ -474,16 +471,16 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
Email::set_mailer($this->originalMailer); Email::set_mailer($this->originalMailer);
$this->originalMailer = null; $this->originalMailer = null;
} }
$this->mailer = null; $this->mailer = null;
// Restore password validation // Restore password validation
if($this->originalMemberPasswordValidator) { if($this->originalMemberPasswordValidator) {
Member::set_password_validator($this->originalMemberPasswordValidator); Member::set_password_validator($this->originalMemberPasswordValidator);
} }
// Restore requirements // Restore requirements
if($this->originalRequirements) { if($this->originalRequirements) {
Requirements::set_backend($this->originalRequirements); Requirements::set_backend($this->originalRequirements);
} }
// Mark test as no longer being run - we use originalIsRunningTest to allow for nested SapphireTest calls // Mark test as no longer being run - we use originalIsRunningTest to allow for nested SapphireTest calls
@ -492,15 +489,18 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
// Reset mocked datetime // Reset mocked datetime
SS_Datetime::clear_mock_now(); SS_Datetime::clear_mock_now();
// Stop the redirection that might have been requested in the test. // Stop the redirection that might have been requested in the test.
// Note: Ideally a clean Controller should be created for each test. // Note: Ideally a clean Controller should be created for each test.
// Now all tests executed in a batch share the same controller. // Now all tests executed in a batch share the same controller.
$controller = Controller::has_curr() ? Controller::curr() : null; $controller = Controller::has_curr() ? Controller::curr() : null;
if ( $controller && $controller->response && $controller->response->getHeader('Location') ) { if ( $controller && $controller->response && $controller->response->getHeader('Location') ) {
$controller->response->setStatusCode(200); $controller->response->setStatusCode(200);
$controller->response->removeHeader('Location'); $controller->response->removeHeader('Location');
} }
//unnest injector / config now that tests are over
Injector::unnest();
Config::unnest();
} }
public static function assertContains( public static function assertContains(
@ -547,7 +547,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
public function findEmail($to, $from = null, $subject = null, $content = null) { public function findEmail($to, $from = null, $subject = null, $content = null) {
return $this->mailer->findEmail($to, $from, $subject, $content); return $this->mailer->findEmail($to, $from, $subject, $content);
} }
/** /**
* Assert that the matching email was sent since the last call to clearEmails() * Assert that the matching email was sent since the last call to clearEmails()
* All of the parameters can either be a string, or, if they start with "/", a PREG-compatible regular expression. * All of the parameters can either be a string, or, if they start with "/", a PREG-compatible regular expression.
@ -579,7 +579,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
/** /**
* Assert that the given {@link SS_List} includes DataObjects matching the given key-value * Assert that the given {@link SS_List} includes DataObjects matching the given key-value
* pairs. Each match must correspond to 1 distinct record. * pairs. Each match must correspond to 1 distinct record.
* *
* @param $matches The patterns to match. Each pattern is a map of key-value pairs. You can * @param $matches The patterns to match. Each pattern is a map of key-value pairs. You can
* either pass a single pattern or an array of patterns. * either pass a single pattern or an array of patterns.
* @param $dataObjectSet The {@link SS_List} to test. * @param $dataObjectSet The {@link SS_List} to test.
@ -587,19 +587,19 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
* Examples * Examples
* -------- * --------
* Check that $members includes an entry with Email = sam@example.com: * Check that $members includes an entry with Email = sam@example.com:
* $this->assertDOSContains(array('Email' => '...@example.com'), $members); * $this->assertDOSContains(array('Email' => '...@example.com'), $members);
* *
* Check that $members includes entries with Email = sam@example.com and with * Check that $members includes entries with Email = sam@example.com and with
* Email = ingo@example.com: * Email = ingo@example.com:
* $this->assertDOSContains(array( * $this->assertDOSContains(array(
* array('Email' => '...@example.com'), * array('Email' => '...@example.com'),
* array('Email' => 'i...@example.com'), * array('Email' => 'i...@example.com'),
* ), $members); * ), $members);
*/ */
public function assertDOSContains($matches, $dataObjectSet) { public function assertDOSContains($matches, $dataObjectSet) {
$extracted = array(); $extracted = array();
foreach($dataObjectSet as $item) $extracted[] = $item->toMap(); foreach($dataObjectSet as $item) $extracted[] = $item->toMap();
foreach($matches as $match) { foreach($matches as $match) {
$matched = false; $matched = false;
foreach($extracted as $i => $item) { foreach($extracted as $i => $item) {
@ -615,35 +615,35 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
$this->assertTrue( $this->assertTrue(
$matched, $matched,
"Failed asserting that the SS_List contains an item matching " "Failed asserting that the SS_List contains an item matching "
. var_export($match, true) . "\n\nIn the following SS_List:\n" . var_export($match, true) . "\n\nIn the following SS_List:\n"
. $this->DOSSummaryForMatch($dataObjectSet, $match) . $this->DOSSummaryForMatch($dataObjectSet, $match)
); );
} }
} }
/** /**
* Assert that the given {@link SS_List} includes only DataObjects matching the given * Assert that the given {@link SS_List} includes only DataObjects matching the given
* key-value pairs. Each match must correspond to 1 distinct record. * key-value pairs. Each match must correspond to 1 distinct record.
* *
* @param $matches The patterns to match. Each pattern is a map of key-value pairs. You can * @param $matches The patterns to match. Each pattern is a map of key-value pairs. You can
* either pass a single pattern or an array of patterns. * either pass a single pattern or an array of patterns.
* @param $dataObjectSet The {@link SS_List} to test. * @param $dataObjectSet The {@link SS_List} to test.
* *
* Example * Example
* -------- * --------
* Check that *only* the entries Sam Minnee and Ingo Schommer exist in $members. Order doesn't * Check that *only* the entries Sam Minnee and Ingo Schommer exist in $members. Order doesn't
* matter: * matter:
* $this->assertDOSEquals(array( * $this->assertDOSEquals(array(
* array('FirstName' =>'Sam', 'Surname' => 'Minnee'), * array('FirstName' =>'Sam', 'Surname' => 'Minnee'),
* array('FirstName' => 'Ingo', 'Surname' => 'Schommer'), * array('FirstName' => 'Ingo', 'Surname' => 'Schommer'),
* ), $members); * ), $members);
*/ */
public function assertDOSEquals($matches, $dataObjectSet) { public function assertDOSEquals($matches, $dataObjectSet) {
if(!$dataObjectSet) return false; if(!$dataObjectSet) return false;
$extracted = array(); $extracted = array();
foreach($dataObjectSet as $item) $extracted[] = $item->toMap(); foreach($dataObjectSet as $item) $extracted[] = $item->toMap();
foreach($matches as $match) { foreach($matches as $match) {
$matched = false; $matched = false;
foreach($extracted as $i => $item) { foreach($extracted as $i => $item) {
@ -659,11 +659,11 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
$this->assertTrue( $this->assertTrue(
$matched, $matched,
"Failed asserting that the SS_List contains an item matching " "Failed asserting that the SS_List contains an item matching "
. var_export($match, true) . "\n\nIn the following SS_List:\n" . var_export($match, true) . "\n\nIn the following SS_List:\n"
. $this->DOSSummaryForMatch($dataObjectSet, $match) . $this->DOSSummaryForMatch($dataObjectSet, $match)
); );
} }
// If we have leftovers than the DOS has extra data that shouldn't be there // If we have leftovers than the DOS has extra data that shouldn't be there
$this->assertTrue( $this->assertTrue(
(count($extracted) == 0), (count($extracted) == 0),
@ -671,19 +671,19 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
"Failed asserting that the SS_List contained only the given items, the " "Failed asserting that the SS_List contained only the given items, the "
. "following items were left over:\n" . var_export($extracted, true) . "following items were left over:\n" . var_export($extracted, true)
); );
} }
/** /**
* Assert that the every record in the given {@link SS_List} matches the given key-value * Assert that the every record in the given {@link SS_List} matches the given key-value
* pairs. * pairs.
* *
* @param $match The pattern to match. The pattern is a map of key-value pairs. * @param $match The pattern to match. The pattern is a map of key-value pairs.
* @param $dataObjectSet The {@link SS_List} to test. * @param $dataObjectSet The {@link SS_List} to test.
* *
* Example * Example
* -------- * --------
* Check that every entry in $members has a Status of 'Active': * Check that every entry in $members has a Status of 'Active':
* $this->assertDOSAllMatch(array('Status' => 'Active'), $members); * $this->assertDOSAllMatch(array('Status' => 'Active'), $members);
*/ */
public function assertDOSAllMatch($match, $dataObjectSet) { public function assertDOSAllMatch($match, $dataObjectSet) {
$extracted = array(); $extracted = array();
@ -692,12 +692,12 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
foreach($extracted as $i => $item) { foreach($extracted as $i => $item) {
$this->assertTrue( $this->assertTrue(
$this->dataObjectArrayMatch($item, $match), $this->dataObjectArrayMatch($item, $match),
"Failed asserting that the the following item matched " "Failed asserting that the the following item matched "
. var_export($match, true) . ": " . var_export($item, true) . var_export($match, true) . ": " . var_export($item, true)
); );
} }
} }
/** /**
* Helper function for the DOS matchers * Helper function for the DOS matchers
*/ */
@ -723,17 +723,17 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
public static function using_temp_db() { public static function using_temp_db() {
$dbConn = DB::getConn(); $dbConn = DB::getConn();
$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_'; $prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
return $dbConn && (substr($dbConn->currentDatabase(), 0, strlen($prefix) + 5) return $dbConn && (substr($dbConn->currentDatabase(), 0, strlen($prefix) + 5)
== strtolower(sprintf('%stmpdb', $prefix))); == strtolower(sprintf('%stmpdb', $prefix)));
} }
public static function kill_temp_db() { public static function kill_temp_db() {
// Delete our temporary database // Delete our temporary database
if(self::using_temp_db()) { if(self::using_temp_db()) {
$dbConn = DB::getConn(); $dbConn = DB::getConn();
$dbName = $dbConn->currentDatabase(); $dbName = $dbConn->currentDatabase();
if($dbName && DB::getConn()->databaseExists($dbName)) { if($dbName && DB::getConn()->databaseExists($dbName)) {
// Some DataExtensions keep a static cache of information that needs to // Some DataExtensions keep a static cache of information that needs to
// be reset whenever the database is killed // be reset whenever the database is killed
foreach(ClassInfo::subclassesFor('DataExtension') as $class) { foreach(ClassInfo::subclassesFor('DataExtension') as $class) {
$toCall = array($class, 'on_db_reset'); $toCall = array($class, 'on_db_reset');
@ -745,7 +745,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
} }
} }
} }
/** /**
* Remove all content from the temporary database. * Remove all content from the temporary database.
*/ */
@ -753,8 +753,8 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
if(self::using_temp_db()) { if(self::using_temp_db()) {
$dbadmin = new DatabaseAdmin(); $dbadmin = new DatabaseAdmin();
$dbadmin->clearAllData(); $dbadmin->clearAllData();
// Some DataExtensions keep a static cache of information that needs to // Some DataExtensions keep a static cache of information that needs to
// be reset whenever the database is cleaned out // be reset whenever the database is cleaned out
$classes = array_merge(ClassInfo::subclassesFor('DataExtension'), ClassInfo::subclassesFor('DataObject')); $classes = array_merge(ClassInfo::subclassesFor('DataExtension'), ClassInfo::subclassesFor('DataObject'));
foreach($classes as $class) { foreach($classes as $class) {
@ -763,7 +763,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
} }
} }
} }
public static function create_temp_db() { public static function create_temp_db() {
// Disable PHPUnit error handling // Disable PHPUnit error handling
restore_error_handler(); restore_error_handler();
@ -784,13 +784,13 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
$st = Injector::inst()->create('SapphireTest'); $st = Injector::inst()->create('SapphireTest');
$st->resetDBSchema(); $st->resetDBSchema();
// Reinstate PHPUnit error handling // Reinstate PHPUnit error handling
set_error_handler(array('PHPUnit_Util_ErrorHandler', 'handleError')); set_error_handler(array('PHPUnit_Util_ErrorHandler', 'handleError'));
return $dbname; return $dbname;
} }
public static function delete_all_temp_dbs() { public static function delete_all_temp_dbs() {
$prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_'; $prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_';
foreach(DB::getConn()->allDatabaseNames() as $dbName) { foreach(DB::getConn()->allDatabaseNames() as $dbName) {
@ -805,7 +805,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
} }
} }
} }
/** /**
* Reset the testing database's schema. * Reset the testing database's schema.
* @param $includeExtraDataObjects If true, the extraDataObjects tables will also be included * @param $includeExtraDataObjects If true, the extraDataObjects tables will also be included
@ -846,7 +846,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
singleton('DataObject')->flushCache(); singleton('DataObject')->flushCache();
} }
} }
/** /**
* Create a member and group with the given permission code, and log in with it. * Create a member and group with the given permission code, and log in with it.
* Returns the member ID. * Returns the member ID.
@ -861,23 +861,23 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
$permission->Code = $permCode; $permission->Code = $permCode;
$permission->write(); $permission->write();
$group->Permissions()->add($permission); $group->Permissions()->add($permission);
$member = DataObject::get_one('Member', sprintf('"Email" = \'%s\'', "$permCode@example.org")); $member = DataObject::get_one('Member', sprintf('"Email" = \'%s\'', "$permCode@example.org"));
if(!$member) $member = Injector::inst()->create('Member'); if(!$member) $member = Injector::inst()->create('Member');
$member->FirstName = $permCode; $member->FirstName = $permCode;
$member->Surname = "User"; $member->Surname = "User";
$member->Email = "$permCode@example.org"; $member->Email = "$permCode@example.org";
$member->write(); $member->write();
$group->Members()->add($member); $group->Members()->add($member);
$this->cache_generatedMembers[$permCode] = $member; $this->cache_generatedMembers[$permCode] = $member;
} }
$this->cache_generatedMembers[$permCode]->logIn(); $this->cache_generatedMembers[$permCode]->logIn();
return $this->cache_generatedMembers[$permCode]->ID; return $this->cache_generatedMembers[$permCode]->ID;
} }
/** /**
* Cache for logInWithPermission() * Cache for logInWithPermission()
*/ */

View File

@ -2,7 +2,7 @@
/** /**
* @package framework * @package framework
* @subpackage tests * @subpackage tests
* *
* @todo test Director::alternateBaseFolder() * @todo test Director::alternateBaseFolder()
*/ */
class DirectorTest extends SapphireTest { class DirectorTest extends SapphireTest {
@ -10,27 +10,24 @@ class DirectorTest extends SapphireTest {
protected static $originalRequestURI; protected static $originalRequestURI;
protected $originalProtocolHeaders = array(); protected $originalProtocolHeaders = array();
protected $originalGet = array(); protected $originalGet = array();
protected $originalSession = array(); protected $originalSession = array();
public function setUp() { public function setUp() {
parent::setUp(); parent::setUp();
// Required for testRequestFilterInDirectorTest
Injector::nest();
// Hold the original request URI once so it doesn't get overwritten // Hold the original request URI once so it doesn't get overwritten
if(!self::$originalRequestURI) { if(!self::$originalRequestURI) {
self::$originalRequestURI = $_SERVER['REQUEST_URI']; self::$originalRequestURI = $_SERVER['REQUEST_URI'];
} }
$_SERVER['REQUEST_URI'] = 'http://www.mysite.com'; $_SERVER['REQUEST_URI'] = 'http://www.mysite.com';
$this->originalGet = $_GET; $this->originalGet = $_GET;
$this->originalSession = $_SESSION; $this->originalSession = $_SESSION;
$_SESSION = array(); $_SESSION = array();
Config::inst()->update('Director', 'rules', array( Config::inst()->update('Director', 'rules', array(
'DirectorTestRule/$Action/$ID/$OtherID' => 'DirectorTestRequest_Controller', 'DirectorTestRule/$Action/$ID/$OtherID' => 'DirectorTestRequest_Controller',
'en-nz/$Action/$ID/$OtherID' => array( 'en-nz/$Action/$ID/$OtherID' => array(
@ -49,16 +46,13 @@ class DirectorTest extends SapphireTest {
} }
} }
} }
public function tearDown() { public function tearDown() {
// TODO Remove director rule, currently API doesnt allow this // TODO Remove director rule, currently API doesnt allow this
// Remove base URL override (setting to false reverts to default behaviour)
Config::inst()->update('Director', 'alternate_base_url', false);
$_GET = $this->originalGet; $_GET = $this->originalGet;
$_SESSION = $this->originalSession; $_SESSION = $this->originalSession;
// Reinstate the original REQUEST_URI after it was modified by some tests // Reinstate the original REQUEST_URI after it was modified by some tests
$_SERVER['REQUEST_URI'] = self::$originalRequestURI; $_SERVER['REQUEST_URI'] = self::$originalRequestURI;
@ -67,34 +61,32 @@ class DirectorTest extends SapphireTest {
$_SERVER[$header] = $value; $_SERVER[$header] = $value;
} }
} }
Injector::unnest();
parent::tearDown(); parent::tearDown();
} }
public function testFileExists() { public function testFileExists() {
$tempFileName = 'DirectorTest_testFileExists.tmp'; $tempFileName = 'DirectorTest_testFileExists.tmp';
$tempFilePath = TEMP_FOLDER . '/' . $tempFileName; $tempFilePath = TEMP_FOLDER . '/' . $tempFileName;
// create temp file // create temp file
file_put_contents($tempFilePath, ''); file_put_contents($tempFilePath, '');
$this->assertTrue( $this->assertTrue(
Director::fileExists($tempFilePath), Director::fileExists($tempFilePath),
'File exist check with absolute path' 'File exist check with absolute path'
); );
$this->assertTrue( $this->assertTrue(
Director::fileExists($tempFilePath . '?queryparams=1&foo[bar]=bar'), Director::fileExists($tempFilePath . '?queryparams=1&foo[bar]=bar'),
'File exist check with query params ignored' 'File exist check with query params ignored'
); );
unlink($tempFilePath); unlink($tempFilePath);
} }
public function testAbsoluteURL() { public function testAbsoluteURL() {
$rootURL = Director::protocolAndHost(); $rootURL = Director::protocolAndHost();
$_SERVER['REQUEST_URI'] = "$rootURL/mysite/sub-page/"; $_SERVER['REQUEST_URI'] = "$rootURL/mysite/sub-page/";
Config::inst()->update('Director', 'alternate_base_url', '/mysite/'); Config::inst()->update('Director', 'alternate_base_url', '/mysite/');
@ -116,20 +108,20 @@ class DirectorTest extends SapphireTest {
$this->assertEquals('http://www.mytest.com', Director::absoluteURL('http://www.mytest.com', true)); $this->assertEquals('http://www.mytest.com', Director::absoluteURL('http://www.mytest.com', true));
$this->assertEquals("$rootURL/test", Director::absoluteURL("$rootURL/test")); $this->assertEquals("$rootURL/test", Director::absoluteURL("$rootURL/test"));
$this->assertEquals("$rootURL/test", Director::absoluteURL("$rootURL/test", true)); $this->assertEquals("$rootURL/test", Director::absoluteURL("$rootURL/test", true));
// Test relative to base // Test relative to base
$this->assertEquals("$rootURL/mysite/test", Director::absoluteURL("test", true)); $this->assertEquals("$rootURL/mysite/test", Director::absoluteURL("test", true));
$this->assertEquals("$rootURL/mysite/test/url", Director::absoluteURL("test/url", true)); $this->assertEquals("$rootURL/mysite/test/url", Director::absoluteURL("test/url", true));
$this->assertEquals("$rootURL/root", Director::absoluteURL("/root", true)); $this->assertEquals("$rootURL/root", Director::absoluteURL("/root", true));
$this->assertEquals("$rootURL/root/url", Director::absoluteURL("/root/url", true)); $this->assertEquals("$rootURL/root/url", Director::absoluteURL("/root/url", true));
// Test relative to requested page // Test relative to requested page
$this->assertEquals("$rootURL/mysite/sub-page/test", Director::absoluteURL("test")); $this->assertEquals("$rootURL/mysite/sub-page/test", Director::absoluteURL("test"));
// Legacy behaviour resolves this to $rootURL/mysite/test/url // Legacy behaviour resolves this to $rootURL/mysite/test/url
//$this->assertEquals("$rootURL/mysite/sub-page/test/url", Director::absoluteURL("test/url")); //$this->assertEquals("$rootURL/mysite/sub-page/test/url", Director::absoluteURL("test/url"));
$this->assertEquals("$rootURL/root", Director::absoluteURL("/root")); $this->assertEquals("$rootURL/root", Director::absoluteURL("/root"));
$this->assertEquals("$rootURL/root/url", Director::absoluteURL("/root/url")); $this->assertEquals("$rootURL/root/url", Director::absoluteURL("/root/url"));
// Test that javascript links are not left intact // Test that javascript links are not left intact
$this->assertStringStartsNotWith('javascript', Director::absoluteURL('javascript:alert("attack")')); $this->assertStringStartsNotWith('javascript', Director::absoluteURL('javascript:alert("attack")'));
$this->assertStringStartsNotWith('alert', Director::absoluteURL('javascript:alert("attack")')); $this->assertStringStartsNotWith('alert', Director::absoluteURL('javascript:alert("attack")'));
@ -140,7 +132,7 @@ class DirectorTest extends SapphireTest {
public function testAlternativeBaseURL() { public function testAlternativeBaseURL() {
// Get original protocol and hostname // Get original protocol and hostname
$rootURL = Director::protocolAndHost(); $rootURL = Director::protocolAndHost();
// relative base URLs - you should end them in a / // relative base URLs - you should end them in a /
Config::inst()->update('Director', 'alternate_base_url', '/relativebase/'); Config::inst()->update('Director', 'alternate_base_url', '/relativebase/');
$_SERVER['REQUEST_URI'] = "$rootURL/relativebase/sub-page/"; $_SERVER['REQUEST_URI'] = "$rootURL/relativebase/sub-page/";
@ -180,7 +172,7 @@ class DirectorTest extends SapphireTest {
Director::absoluteURL('subfolder/test') Director::absoluteURL('subfolder/test')
); );
} }
/** /**
* Tests that {@link Director::is_absolute()} works under different environment types * Tests that {@link Director::is_absolute()} works under different environment types
*/ */
@ -196,12 +188,12 @@ class DirectorTest extends SapphireTest {
'folder' => false, 'folder' => false,
'a/c:/' => false 'a/c:/' => false
); );
foreach($expected as $path => $result) { foreach($expected as $path => $result) {
$this->assertEquals(Director::is_absolute($path), $result, "Test result for $path"); $this->assertEquals(Director::is_absolute($path), $result, "Test result for $path");
} }
} }
public function testIsAbsoluteUrl() { public function testIsAbsoluteUrl() {
$this->assertTrue(Director::is_absolute_url('http://test.com/testpage')); $this->assertTrue(Director::is_absolute_url('http://test.com/testpage'));
$this->assertTrue(Director::is_absolute_url('ftp://test.com')); $this->assertTrue(Director::is_absolute_url('ftp://test.com'));
@ -218,7 +210,7 @@ class DirectorTest extends SapphireTest {
$this->assertTrue(Director::is_absolute_url('http:test.com')); $this->assertTrue(Director::is_absolute_url('http:test.com'));
$this->assertTrue(Director::is_absolute_url('//http://test.com')); $this->assertTrue(Director::is_absolute_url('//http://test.com'));
} }
public function testIsRelativeUrl() { public function testIsRelativeUrl() {
$siteUrl = Director::absoluteBaseURL(); $siteUrl = Director::absoluteBaseURL();
$this->assertFalse(Director::is_relative_url('http://test.com')); $this->assertFalse(Director::is_relative_url('http://test.com'));
@ -231,18 +223,18 @@ class DirectorTest extends SapphireTest {
$this->assertTrue(Director::is_relative_url('/relative/?url=http://test.com')); $this->assertTrue(Director::is_relative_url('/relative/?url=http://test.com'));
$this->assertTrue(Director::is_relative_url('/relative/#=http://test.com')); $this->assertTrue(Director::is_relative_url('/relative/#=http://test.com'));
} }
public function testMakeRelative() { public function testMakeRelative() {
$siteUrl = Director::absoluteBaseURL(); $siteUrl = Director::absoluteBaseURL();
$siteUrlNoProtocol = preg_replace('/https?:\/\//', '', $siteUrl); $siteUrlNoProtocol = preg_replace('/https?:\/\//', '', $siteUrl);
$this->assertEquals(Director::makeRelative("$siteUrl"), ''); $this->assertEquals(Director::makeRelative("$siteUrl"), '');
$this->assertEquals(Director::makeRelative("https://$siteUrlNoProtocol"), ''); $this->assertEquals(Director::makeRelative("https://$siteUrlNoProtocol"), '');
$this->assertEquals(Director::makeRelative("http://$siteUrlNoProtocol"), ''); $this->assertEquals(Director::makeRelative("http://$siteUrlNoProtocol"), '');
$this->assertEquals(Director::makeRelative(" $siteUrl/testpage "), 'testpage'); $this->assertEquals(Director::makeRelative(" $siteUrl/testpage "), 'testpage');
$this->assertEquals(Director::makeRelative("$siteUrlNoProtocol/testpage"), 'testpage'); $this->assertEquals(Director::makeRelative("$siteUrlNoProtocol/testpage"), 'testpage');
$this->assertEquals(Director::makeRelative('ftp://test.com'), 'ftp://test.com'); $this->assertEquals(Director::makeRelative('ftp://test.com'), 'ftp://test.com');
$this->assertEquals(Director::makeRelative('http://test.com'), 'http://test.com'); $this->assertEquals(Director::makeRelative('http://test.com'), 'http://test.com');
@ -252,7 +244,7 @@ class DirectorTest extends SapphireTest {
$this->assertEquals("test", Director::makeRelative("https://".$siteUrlNoProtocol."/test")); $this->assertEquals("test", Director::makeRelative("https://".$siteUrlNoProtocol."/test"));
$this->assertEquals("test", Director::makeRelative("http://".$siteUrlNoProtocol."/test")); $this->assertEquals("test", Director::makeRelative("http://".$siteUrlNoProtocol."/test"));
} }
/** /**
* Mostly tested by {@link testIsRelativeUrl()}, * Mostly tested by {@link testIsRelativeUrl()},
* just adding the host name matching aspect here. * just adding the host name matching aspect here.
@ -264,7 +256,7 @@ class DirectorTest extends SapphireTest {
$this->assertFalse(Director::is_site_url("http://test.com?url=" . urlencode(Director::absoluteBaseURL()))); $this->assertFalse(Director::is_site_url("http://test.com?url=" . urlencode(Director::absoluteBaseURL())));
$this->assertFalse(Director::is_site_url("//test.com?url=" . Director::absoluteBaseURL())); $this->assertFalse(Director::is_site_url("//test.com?url=" . Director::absoluteBaseURL()));
} }
/** /**
* Tests isDev, isTest, isLive set from querystring * Tests isDev, isTest, isLive set from querystring
*/ */
@ -274,32 +266,32 @@ class DirectorTest extends SapphireTest {
unset($_SESSION['isLive']); unset($_SESSION['isLive']);
unset($_GET['isTest']); unset($_GET['isTest']);
unset($_GET['isDev']); unset($_GET['isDev']);
// Test isDev=1 // Test isDev=1
$_GET['isDev'] = '1'; $_GET['isDev'] = '1';
$this->assertTrue(Director::isDev()); $this->assertTrue(Director::isDev());
$this->assertFalse(Director::isTest()); $this->assertFalse(Director::isTest());
$this->assertFalse(Director::isLive()); $this->assertFalse(Director::isLive());
// Test persistence // Test persistence
unset($_GET['isDev']); unset($_GET['isDev']);
$this->assertTrue(Director::isDev()); $this->assertTrue(Director::isDev());
$this->assertFalse(Director::isTest()); $this->assertFalse(Director::isTest());
$this->assertFalse(Director::isLive()); $this->assertFalse(Director::isLive());
// Test change to isTest // Test change to isTest
$_GET['isTest'] = '1'; $_GET['isTest'] = '1';
$this->assertFalse(Director::isDev()); $this->assertFalse(Director::isDev());
$this->assertTrue(Director::isTest()); $this->assertTrue(Director::isTest());
$this->assertFalse(Director::isLive()); $this->assertFalse(Director::isLive());
// Test persistence // Test persistence
unset($_GET['isTest']); unset($_GET['isTest']);
$this->assertFalse(Director::isDev()); $this->assertFalse(Director::isDev());
$this->assertTrue(Director::isTest()); $this->assertTrue(Director::isTest());
$this->assertFalse(Director::isLive()); $this->assertFalse(Director::isLive());
} }
public function testResetGlobalsAfterTestRequest() { public function testResetGlobalsAfterTestRequest() {
$_GET = array('somekey' => 'getvalue'); $_GET = array('somekey' => 'getvalue');
$_POST = array('somekey' => 'postvalue'); $_POST = array('somekey' => 'postvalue');
@ -315,7 +307,7 @@ class DirectorTest extends SapphireTest {
$this->assertEquals('cookievalue', $_COOKIE['somekey'], $this->assertEquals('cookievalue', $_COOKIE['somekey'],
'$_COOKIE reset to original value after Director::test()'); '$_COOKIE reset to original value after Director::test()');
} }
public function testTestRequestCarriesGlobals() { public function testTestRequestCarriesGlobals() {
$fixture = array('somekey' => 'sometestvalue'); $fixture = array('somekey' => 'sometestvalue');
foreach(array('get', 'post') as $method) { foreach(array('get', 'post') as $method) {
@ -329,20 +321,20 @@ class DirectorTest extends SapphireTest {
} }
} }
} }
/** /**
* Tests that additional parameters specified in the routing table are * Tests that additional parameters specified in the routing table are
* saved in the request * saved in the request
*/ */
public function testRouteParams() { public function testRouteParams() {
Director::test('en-nz/myaction/myid/myotherid', null, null, null, null, null, null, $request); Director::test('en-nz/myaction/myid/myotherid', null, null, null, null, null, null, $request);
$this->assertEquals( $this->assertEquals(
$request->params(), $request->params(),
array( array(
'Controller' => 'DirectorTestRequest_Controller', 'Controller' => 'DirectorTestRequest_Controller',
'Action' => 'myaction', 'Action' => 'myaction',
'ID' => 'myid', 'ID' => 'myid',
'OtherID' => 'myotherid', 'OtherID' => 'myotherid',
'Locale' => 'en_NZ' 'Locale' => 'en_NZ'
) )
@ -406,7 +398,7 @@ class DirectorTest extends SapphireTest {
'CONTENT_TYPE' => 'text/xml', 'CONTENT_TYPE' => 'text/xml',
'CONTENT_LENGTH' => 10 'CONTENT_LENGTH' => 10
); );
$headers = array( $headers = array(
'Host' => 'host', 'Host' => 'host',
'User-Agent' => 'User Agent', 'User-Agent' => 'User Agent',
@ -416,7 +408,7 @@ class DirectorTest extends SapphireTest {
'Content-Type' => 'text/xml', 'Content-Type' => 'text/xml',
'Content-Length' => '10' 'Content-Length' => '10'
); );
$this->assertEquals($headers, Director::extract_request_headers($request)); $this->assertEquals($headers, Director::extract_request_headers($request));
} }
@ -483,34 +475,34 @@ class DirectorTest extends SapphireTest {
$_SERVER = $origServer; $_SERVER = $origServer;
} }
public function testRequestFilterInDirectorTest() { public function testRequestFilterInDirectorTest() {
$filter = new TestRequestFilter; $filter = new TestRequestFilter;
$processor = new RequestProcessor(array($filter)); $processor = new RequestProcessor(array($filter));
Injector::inst()->registerService($processor, 'RequestProcessor'); Injector::inst()->registerService($processor, 'RequestProcessor');
$response = Director::test('some-dummy-url'); $response = Director::test('some-dummy-url');
$this->assertEquals(1, $filter->preCalls); $this->assertEquals(1, $filter->preCalls);
$this->assertEquals(1, $filter->postCalls); $this->assertEquals(1, $filter->postCalls);
$filter->failPost = true; $filter->failPost = true;
$this->setExpectedException('SS_HTTPResponse_Exception'); $this->setExpectedException('SS_HTTPResponse_Exception');
$response = Director::test('some-dummy-url'); $response = Director::test('some-dummy-url');
$this->assertEquals(2, $filter->preCalls); $this->assertEquals(2, $filter->preCalls);
$this->assertEquals(2, $filter->postCalls); $this->assertEquals(2, $filter->postCalls);
$filter->failPre = true; $filter->failPre = true;
$response = Director::test('some-dummy-url'); $response = Director::test('some-dummy-url');
$this->assertEquals(3, $filter->preCalls); $this->assertEquals(3, $filter->preCalls);
// preCall 'false' will trigger an exception and prevent post call execution // preCall 'false' will trigger an exception and prevent post call execution
$this->assertEquals(2, $filter->postCalls); $this->assertEquals(2, $filter->postCalls);
} }
@ -519,13 +511,13 @@ class DirectorTest extends SapphireTest {
class TestRequestFilter implements RequestFilter, TestOnly { class TestRequestFilter implements RequestFilter, TestOnly {
public $preCalls = 0; public $preCalls = 0;
public $postCalls = 0; public $postCalls = 0;
public $failPre = false; public $failPre = false;
public $failPost = false; public $failPost = false;
public function preRequest(\SS_HTTPRequest $request, \Session $session, \DataModel $model) { public function preRequest(\SS_HTTPRequest $request, \Session $session, \DataModel $model) {
++$this->preCalls; ++$this->preCalls;
if ($this->failPre) { if ($this->failPre) {
return false; return false;
} }
@ -533,7 +525,7 @@ class TestRequestFilter implements RequestFilter, TestOnly {
public function postRequest(\SS_HTTPRequest $request, \SS_HTTPResponse $response, \DataModel $model) { public function postRequest(\SS_HTTPRequest $request, \SS_HTTPResponse $response, \DataModel $model) {
++$this->postCalls; ++$this->postCalls;
if ($this->failPost) { if ($this->failPost) {
return false; return false;
} }

View File

@ -82,23 +82,23 @@ class ConfigTest_TestNest extends Object implements TestOnly {
} }
class ConfigTest extends SapphireTest { class ConfigTest extends SapphireTest {
public function testNest() { public function testNest() {
// Check basic config // Check basic config
$this->assertEquals(3, Config::inst()->get('ConfigTest_TestNest', 'foo')); $this->assertEquals(3, Config::inst()->get('ConfigTest_TestNest', 'foo'));
$this->assertEquals(5, Config::inst()->get('ConfigTest_TestNest', 'bar')); $this->assertEquals(5, Config::inst()->get('ConfigTest_TestNest', 'bar'));
// Test nest copies data // Test nest copies data
Config::nest(); Config::nest();
$this->assertEquals(3, Config::inst()->get('ConfigTest_TestNest', 'foo')); $this->assertEquals(3, Config::inst()->get('ConfigTest_TestNest', 'foo'));
$this->assertEquals(5, Config::inst()->get('ConfigTest_TestNest', 'bar')); $this->assertEquals(5, Config::inst()->get('ConfigTest_TestNest', 'bar'));
// Test nested data can be updated // Test nested data can be updated
Config::inst()->update('ConfigTest_TestNest', 'foo', 4); Config::inst()->update('ConfigTest_TestNest', 'foo', 4);
$this->assertEquals(4, Config::inst()->get('ConfigTest_TestNest', 'foo')); $this->assertEquals(4, Config::inst()->get('ConfigTest_TestNest', 'foo'));
$this->assertEquals(5, Config::inst()->get('ConfigTest_TestNest', 'bar')); $this->assertEquals(5, Config::inst()->get('ConfigTest_TestNest', 'bar'));
// Test unnest restores data // Test unnest restores data
Config::unnest(); Config::unnest();
$this->assertEquals(3, Config::inst()->get('ConfigTest_TestNest', 'foo')); $this->assertEquals(3, Config::inst()->get('ConfigTest_TestNest', 'foo'));
@ -193,8 +193,8 @@ class ConfigTest extends SapphireTest {
Config::inst()->get('ConfigStaticTest_Fourth', 'first', Config::UNINHERITED)); Config::inst()->get('ConfigStaticTest_Fourth', 'first', Config::UNINHERITED));
// Subclasses that don't have the static explicitly defined should allow definition, also // Subclasses that don't have the static explicitly defined should allow definition, also
// This also checks that set can be called after the first uninherited get() // This also checks that set can be called after the first uninherited get()
// call (which can be buggy due to caching) // call (which can be buggy due to caching)
Config::inst()->update('ConfigStaticTest_Fourth', 'first', array('test_4b')); Config::inst()->update('ConfigStaticTest_Fourth', 'first', array('test_4b'));
$this->assertContains('test_4b', Config::inst()->get('ConfigStaticTest_Fourth', 'first', Config::UNINHERITED)); $this->assertContains('test_4b', Config::inst()->get('ConfigStaticTest_Fourth', 'first', Config::UNINHERITED));
} }
@ -227,7 +227,7 @@ class ConfigTest extends SapphireTest {
$result = array('A' => 1, 'B' => 2, 'C' => array('Foo' => 1, 'Bar' => 2), 'D' => 3); $result = array('A' => 1, 'B' => 2, 'C' => array('Foo' => 1, 'Bar' => 2), 'D' => 3);
Config::merge_array_low_into_high($result, array('C' => array('Bar' => 3, 'Baz' => 4))); Config::merge_array_low_into_high($result, array('C' => array('Bar' => 3, 'Baz' => 4)));
$this->assertEquals($result, $this->assertEquals($result,
array('A' => 1, 'B' => 2, 'C' => array('Foo' => 1, 'Bar' => 2, 'Baz' => 4), 'D' => 3)); array('A' => 1, 'B' => 2, 'C' => array('Foo' => 1, 'Bar' => 2, 'Baz' => 4), 'D' => 3));
$result = array('A' => 1, 'B' => 2, 'C' => array('Foo' => 1, 'Bar' => 2), 'D' => 3); $result = array('A' => 1, 'B' => 2, 'C' => array('Foo' => 1, 'Bar' => 2), 'D' => 3);

View File

@ -391,7 +391,7 @@ class ConfigManifestTest extends SapphireTest {
public function testEnvironmentRules() { public function testEnvironmentRules() {
foreach (array('dev', 'test', 'live') as $env) { foreach (array('dev', 'test', 'live') as $env) {
Config::inst()->nest(); Config::nest();
Config::inst()->update('Director', 'environment_type', $env); Config::inst()->update('Director', 'environment_type', $env);
$config = $this->getConfigFixtureValue('Environment'); $config = $this->getConfigFixtureValue('Environment');
@ -403,13 +403,11 @@ class ConfigManifestTest extends SapphireTest {
); );
} }
Config::inst()->unnest(); Config::unnest();
} }
} }
public function testDynamicEnvironmentRules() { public function testDynamicEnvironmentRules() {
Config::inst()->nest();
// First, make sure environment_type is live // First, make sure environment_type is live
Config::inst()->update('Director', 'environment_type', 'live'); Config::inst()->update('Director', 'environment_type', 'live');
$this->assertEquals('live', Config::inst()->get('Director', 'environment_type')); $this->assertEquals('live', Config::inst()->get('Director', 'environment_type'));
@ -423,8 +421,6 @@ class ConfigManifestTest extends SapphireTest {
// And that the dynamic rule was calculated correctly // And that the dynamic rule was calculated correctly
$this->assertEquals('dev', Config::inst()->get('ConfigManifestTest', 'DynamicEnvironment')); $this->assertEquals('dev', Config::inst()->get('ConfigManifestTest', 'DynamicEnvironment'));
Config::inst()->unnest();
} }
public function testMultipleRules() { public function testMultipleRules() {

View File

@ -1,17 +1,17 @@
<?php <?php
/** /**
* Note: the running of this test is handled by the thing it's testing (DevelopmentAdmin controller). * Note: the running of this test is handled by the thing it's testing (DevelopmentAdmin controller).
* *
* @package framework * @package framework
* @package tests * @package tests
*/ */
class DevAdminControllerTest extends FunctionalTest { class DevAdminControllerTest extends FunctionalTest {
public function setUp(){ public function setUp(){
parent::setUp(); parent::setUp();
Config::nest()->update('DevelopmentAdmin', 'registered_controllers', array( Config::inst()->update('DevelopmentAdmin', 'registered_controllers', array(
'x1' => array( 'x1' => array(
'controller' => 'DevAdminControllerTest_Controller1', 'controller' => 'DevAdminControllerTest_Controller1',
'links' => array( 'links' => array(
@ -27,45 +27,40 @@ class DevAdminControllerTest extends FunctionalTest {
) )
)); ));
} }
public function tearDown(){
parent::tearDown();
Config::unnest();
}
public function testGoodRegisteredControllerOutput(){ public function testGoodRegisteredControllerOutput(){
// Check for the controller running from the registered url above // Check for the controller running from the registered url above
// (we use contains rather than equals because sometimes you get Warning: You probably want to define an entry in $_FILE_TO_URL_MAPPING) // (we use contains rather than equals because sometimes you get Warning: You probably want to define an entry in $_FILE_TO_URL_MAPPING)
$this->assertContains(DevAdminControllerTest_Controller1::OK_MSG, $this->getCapture('/dev/x1')); $this->assertContains(DevAdminControllerTest_Controller1::OK_MSG, $this->getCapture('/dev/x1'));
$this->assertContains(DevAdminControllerTest_Controller1::OK_MSG, $this->getCapture('/dev/x1/y1')); $this->assertContains(DevAdminControllerTest_Controller1::OK_MSG, $this->getCapture('/dev/x1/y1'));
} }
public function testGoodRegisteredControllerStatus(){ public function testGoodRegisteredControllerStatus(){
// Check response code is 200/OK // Check response code is 200/OK
$this->assertEquals(false, $this->getAndCheckForError('/dev/x1')); $this->assertEquals(false, $this->getAndCheckForError('/dev/x1'));
$this->assertEquals(false, $this->getAndCheckForError('/dev/x1/y1')); $this->assertEquals(false, $this->getAndCheckForError('/dev/x1/y1'));
// Check response code is 500/ some sort of error // Check response code is 500/ some sort of error
$this->assertEquals(true, $this->getAndCheckForError('/dev/x2')); $this->assertEquals(true, $this->getAndCheckForError('/dev/x2'));
} }
protected function getCapture($url){ protected function getCapture($url){
$this->logInWithPermission('ADMIN'); $this->logInWithPermission('ADMIN');
ob_start(); ob_start();
$this->get($url); $this->get($url);
$r = ob_get_contents(); $r = ob_get_contents();
ob_end_clean(); ob_end_clean();
return $r; return $r;
} }
protected function getAndCheckForError($url){ protected function getAndCheckForError($url){
$this->logInWithPermission('ADMIN'); $this->logInWithPermission('ADMIN');
if(Director::is_cli()){ if(Director::is_cli()){
// when in CLI the admin controller throws exceptions // when in CLI the admin controller throws exceptions
ob_start(); ob_start();
@ -75,10 +70,10 @@ class DevAdminControllerTest extends FunctionalTest {
ob_end_clean(); ob_end_clean();
return true; return true;
} }
ob_end_clean(); ob_end_clean();
return false; return false;
}else{ }else{
// when in http the admin controller sets a response header // when in http the admin controller sets a response header
ob_start(); ob_start();
@ -87,30 +82,30 @@ class DevAdminControllerTest extends FunctionalTest {
return $resp->isError(); return $resp->isError();
} }
} }
} }
class DevAdminControllerTest_Controller1 extends Controller { class DevAdminControllerTest_Controller1 extends Controller {
const OK_MSG = 'DevAdminControllerTest_Controller1 TEST OK'; const OK_MSG = 'DevAdminControllerTest_Controller1 TEST OK';
private static $url_handlers = array( private static $url_handlers = array(
'' => 'index', '' => 'index',
'y1' => 'y1Action' 'y1' => 'y1Action'
); );
private static $allowed_actions = array( private static $allowed_actions = array(
'index', 'index',
'y1Action', 'y1Action',
); );
public function index(){ public function index(){
echo self::OK_MSG; echo self::OK_MSG;
} }
public function y1Action(){ public function y1Action(){
echo self::OK_MSG; echo self::OK_MSG;
} }
} }

View File

@ -5,13 +5,13 @@ class DataObjectSchemaGenerationTest extends SapphireTest {
'DataObjectSchemaGenerationTest_DO', 'DataObjectSchemaGenerationTest_DO',
'DataObjectSchemaGenerationTest_IndexDO' 'DataObjectSchemaGenerationTest_IndexDO'
); );
public function setUpOnce() { public function setUpOnce() {
// enable fulltext option on this table // enable fulltext option on this table
Config::inst()->update('DataObjectSchemaGenerationTest_IndexDO', 'create_table_options', Config::inst()->update('DataObjectSchemaGenerationTest_IndexDO', 'create_table_options',
array('MySQLDatabase' => 'ENGINE=MyISAM')); array('MySQLDatabase' => 'ENGINE=MyISAM'));
parent::setUpOnce(); parent::setUpOnce();
} }
@ -23,7 +23,7 @@ class DataObjectSchemaGenerationTest extends SapphireTest {
DB::quiet(); DB::quiet();
// Table will have been initially created by the $extraDataObjects setting // Table will have been initially created by the $extraDataObjects setting
// Verify that it doesn't need to be recreated // Verify that it doesn't need to be recreated
$db->beginSchemaUpdate(); $db->beginSchemaUpdate();
$obj = new DataObjectSchemaGenerationTest_DO(); $obj = new DataObjectSchemaGenerationTest_DO();
@ -41,9 +41,8 @@ class DataObjectSchemaGenerationTest extends SapphireTest {
DB::quiet(); DB::quiet();
// Table will have been initially created by the $extraDataObjects setting // Table will have been initially created by the $extraDataObjects setting
// Let's insert a new field here // Let's insert a new field here
Config::nest();
Config::inst()->update('DataObjectSchemaGenerationTest_DO', 'db', array( Config::inst()->update('DataObjectSchemaGenerationTest_DO', 'db', array(
'SecretField' => 'Varchar(100)' 'SecretField' => 'Varchar(100)'
)); ));
@ -55,20 +54,17 @@ class DataObjectSchemaGenerationTest extends SapphireTest {
$needsUpdating = $db->doesSchemaNeedUpdating(); $needsUpdating = $db->doesSchemaNeedUpdating();
$db->cancelSchemaUpdate(); $db->cancelSchemaUpdate();
$this->assertTrue($needsUpdating); $this->assertTrue($needsUpdating);
// Restore db configuration
Config::unnest();
} }
/** /**
* Check that indexes on a newly generated class do not subsequently request modification * Check that indexes on a newly generated class do not subsequently request modification
*/ */
public function testIndexesDontRerequestChanges() { public function testIndexesDontRerequestChanges() {
$db = DB::getConn(); $db = DB::getConn();
DB::quiet(); DB::quiet();
// Table will have been initially created by the $extraDataObjects setting // Table will have been initially created by the $extraDataObjects setting
// Verify that it doesn't need to be recreated // Verify that it doesn't need to be recreated
$db->beginSchemaUpdate(); $db->beginSchemaUpdate();
$obj = new DataObjectSchemaGenerationTest_IndexDO(); $obj = new DataObjectSchemaGenerationTest_IndexDO();
@ -76,9 +72,8 @@ class DataObjectSchemaGenerationTest extends SapphireTest {
$needsUpdating = $db->doesSchemaNeedUpdating(); $needsUpdating = $db->doesSchemaNeedUpdating();
$db->cancelSchemaUpdate(); $db->cancelSchemaUpdate();
$this->assertFalse($needsUpdating); $this->assertFalse($needsUpdating);
// Test with alternate index format, although these indexes are the same // Test with alternate index format, although these indexes are the same
Config::nest();
Config::inst()->remove('DataObjectSchemaGenerationTest_IndexDO', 'indexes'); Config::inst()->remove('DataObjectSchemaGenerationTest_IndexDO', 'indexes');
Config::inst()->update('DataObjectSchemaGenerationTest_IndexDO', 'indexes', Config::inst()->update('DataObjectSchemaGenerationTest_IndexDO', 'indexes',
Config::inst()->get('DataObjectSchemaGenerationTest_IndexDO', 'indexes_alt') Config::inst()->get('DataObjectSchemaGenerationTest_IndexDO', 'indexes_alt')
@ -91,22 +86,18 @@ class DataObjectSchemaGenerationTest extends SapphireTest {
$needsUpdating = $db->doesSchemaNeedUpdating(); $needsUpdating = $db->doesSchemaNeedUpdating();
$db->cancelSchemaUpdate(); $db->cancelSchemaUpdate();
$this->assertFalse($needsUpdating); $this->assertFalse($needsUpdating);
// Restore old index format
Config::unnest();
} }
/** /**
* Check that updates to a dataobject's indexes are reflected in DDL * Check that updates to a dataobject's indexes are reflected in DDL
*/ */
public function testIndexesRerequestChanges() { public function testIndexesRerequestChanges() {
$db = DB::getConn(); $db = DB::getConn();
DB::quiet(); DB::quiet();
// Table will have been initially created by the $extraDataObjects setting // Table will have been initially created by the $extraDataObjects setting
// Update the SearchFields index here // Update the SearchFields index here
Config::nest();
Config::inst()->update('DataObjectSchemaGenerationTest_IndexDO', 'indexes', array( Config::inst()->update('DataObjectSchemaGenerationTest_IndexDO', 'indexes', array(
'SearchFields' => array( 'SearchFields' => array(
'value' => 'Title' 'value' => 'Title'
@ -120,17 +111,14 @@ class DataObjectSchemaGenerationTest extends SapphireTest {
$needsUpdating = $db->doesSchemaNeedUpdating(); $needsUpdating = $db->doesSchemaNeedUpdating();
$db->cancelSchemaUpdate(); $db->cancelSchemaUpdate();
$this->assertTrue($needsUpdating); $this->assertTrue($needsUpdating);
// Restore old indexes
Config::unnest();
} }
/** /**
* Tests the generation of the ClassName spec and ensure it's not unnecessarily influenced * Tests the generation of the ClassName spec and ensure it's not unnecessarily influenced
* by the order of classnames of existing records * by the order of classnames of existing records
*/ */
public function testClassNameSpecGeneration() { public function testClassNameSpecGeneration() {
// Test with blank entries // Test with blank entries
DataObject::clear_classname_spec_cache(); DataObject::clear_classname_spec_cache();
$fields = DataObject::database_fields('DataObjectSchemaGenerationTest_DO'); $fields = DataObject::database_fields('DataObjectSchemaGenerationTest_DO');
@ -138,7 +126,7 @@ class DataObjectSchemaGenerationTest extends SapphireTest {
"Enum('DataObjectSchemaGenerationTest_DO, DataObjectSchemaGenerationTest_IndexDO')", "Enum('DataObjectSchemaGenerationTest_DO, DataObjectSchemaGenerationTest_IndexDO')",
$fields['ClassName'] $fields['ClassName']
); );
// Test with instance of subclass // Test with instance of subclass
$item1 = new DataObjectSchemaGenerationTest_IndexDO(); $item1 = new DataObjectSchemaGenerationTest_IndexDO();
$item1->write(); $item1->write();
@ -149,7 +137,7 @@ class DataObjectSchemaGenerationTest extends SapphireTest {
$fields['ClassName'] $fields['ClassName']
); );
$item1->delete(); $item1->delete();
// Test with instance of main class // Test with instance of main class
$item2 = new DataObjectSchemaGenerationTest_DO(); $item2 = new DataObjectSchemaGenerationTest_DO();
$item2->write(); $item2->write();
@ -160,7 +148,7 @@ class DataObjectSchemaGenerationTest extends SapphireTest {
$fields['ClassName'] $fields['ClassName']
); );
$item2->delete(); $item2->delete();
// Test with instances of both classes // Test with instances of both classes
$item1 = new DataObjectSchemaGenerationTest_IndexDO(); $item1 = new DataObjectSchemaGenerationTest_IndexDO();
$item1->write(); $item1->write();
@ -199,7 +187,7 @@ class DataObjectSchemaGenerationTest_IndexDO extends DataObjectSchemaGenerationT
'value' => '"Title","Content"' 'value' => '"Title","Content"'
) )
); );
/** @config */ /** @config */
private static $indexes_alt = array( private static $indexes_alt = array(
'NameIndex' => array( 'NameIndex' => array(
@ -209,4 +197,4 @@ class DataObjectSchemaGenerationTest_IndexDO extends DataObjectSchemaGenerationT
), ),
'SearchFields' => 'fulltext ("Title","Content")' 'SearchFields' => 'fulltext ("Title","Content")'
); );
} }

View File

@ -8,8 +8,9 @@ class MySQLDatabaseTest extends SapphireTest {
protected $extraDataObjects = array( protected $extraDataObjects = array(
'MySQLDatabaseTest_DO', 'MySQLDatabaseTest_DO',
); );
public function setUp() { public function setUp() {
parent::setUp();
if(DB::getConn() instanceof MySQLDatabase) { if(DB::getConn() instanceof MySQLDatabase) {
MySQLDatabaseTest_DO::config()->db = array( MySQLDatabaseTest_DO::config()->db = array(
'MultiEnum1' => 'MultiEnum("A, B, C, D","")', 'MultiEnum1' => 'MultiEnum("A, B, C, D","")',
@ -18,9 +19,8 @@ class MySQLDatabaseTest extends SapphireTest {
); );
} }
$this->markTestSkipped('This test requires the Config API to be immutable'); $this->markTestSkipped('This test requires the Config API to be immutable');
parent::setUp();
} }
/** /**
* Check that once a schema has been generated, then it doesn't need any more updating * Check that once a schema has been generated, then it doesn't need any more updating
*/ */

View File

@ -1,16 +1,6 @@
<?php <?php
class OembedTest extends SapphireTest { class OembedTest extends SapphireTest {
public function setUp() {
parent::setUp();
Config::nest();
}
public function tearDown() {
Config::unnest();
parent::tearDown();
}
public function testGetOembedFromUrl() { public function testGetOembedFromUrl() {
Config::inst()->update('Oembed', 'providers', array( Config::inst()->update('Oembed', 'providers', array(
'http://*.silverstripe.com/watch*'=>'http://www.silverstripe.com/oembed/' 'http://*.silverstripe.com/watch*'=>'http://www.silverstripe.com/oembed/'
@ -35,7 +25,7 @@ class OembedTest extends SapphireTest {
$result = Oembed::get_oembed_from_url('http://www.silverstripe.com/watch12345', false, array('foo'=>'bar')); $result = Oembed::get_oembed_from_url('http://www.silverstripe.com/watch12345', false, array('foo'=>'bar'));
$this->assertTrue($result!=false); $this->assertTrue($result!=false);
$this->assertEquals($result->getOembedURL(), 'http://www.silverstripe.com/oembed/?format=json&url=' $this->assertEquals($result->getOembedURL(), 'http://www.silverstripe.com/oembed/?format=json&url='
. urlencode('http://www.silverstripe.com/watch12345').'&foo=bar', . urlencode('http://www.silverstripe.com/watch12345').'&foo=bar',
'Includes options'); 'Includes options');
// Test magic. // Test magic.

View File

@ -14,46 +14,40 @@ class BasicAuthTest extends FunctionalTest {
parent::setUp(); parent::setUp();
// Fixtures assume Email is the field used to identify the log in identity // Fixtures assume Email is the field used to identify the log in identity
Config::nest();
Member::config()->unique_identifier_field = 'Email'; Member::config()->unique_identifier_field = 'Email';
Member::config()->lock_out_after_incorrect_logins = 10; Member::config()->lock_out_after_incorrect_logins = 10;
} }
public function tearDown() {
Config::unnest();
parent::tearDown();
}
public function testBasicAuthEnabledWithoutLogin() { public function testBasicAuthEnabledWithoutLogin() {
$origUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null; $origUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null;
$origPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null; $origPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null;
unset($_SERVER['PHP_AUTH_USER']); unset($_SERVER['PHP_AUTH_USER']);
unset($_SERVER['PHP_AUTH_PW']); unset($_SERVER['PHP_AUTH_PW']);
$response = Director::test('BasicAuthTest_ControllerSecuredWithPermission'); $response = Director::test('BasicAuthTest_ControllerSecuredWithPermission');
$this->assertEquals(401, $response->getStatusCode()); $this->assertEquals(401, $response->getStatusCode());
$_SERVER['PHP_AUTH_USER'] = $origUser; $_SERVER['PHP_AUTH_USER'] = $origUser;
$_SERVER['PHP_AUTH_PW'] = $origPw; $_SERVER['PHP_AUTH_PW'] = $origPw;
} }
public function testBasicAuthDoesntCallActionOrFurtherInitOnAuthFailure() { public function testBasicAuthDoesntCallActionOrFurtherInitOnAuthFailure() {
$origUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null; $origUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null;
$origPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null; $origPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null;
unset($_SERVER['PHP_AUTH_USER']); unset($_SERVER['PHP_AUTH_USER']);
unset($_SERVER['PHP_AUTH_PW']); unset($_SERVER['PHP_AUTH_PW']);
$response = Director::test('BasicAuthTest_ControllerSecuredWithPermission'); $response = Director::test('BasicAuthTest_ControllerSecuredWithPermission');
$this->assertFalse(BasicAuthTest_ControllerSecuredWithPermission::$index_called); $this->assertFalse(BasicAuthTest_ControllerSecuredWithPermission::$index_called);
$this->assertFalse(BasicAuthTest_ControllerSecuredWithPermission::$post_init_called); $this->assertFalse(BasicAuthTest_ControllerSecuredWithPermission::$post_init_called);
$_SERVER['PHP_AUTH_USER'] = 'user-in-mygroup@test.com'; $_SERVER['PHP_AUTH_USER'] = 'user-in-mygroup@test.com';
$_SERVER['PHP_AUTH_PW'] = 'test'; $_SERVER['PHP_AUTH_PW'] = 'test';
$response = Director::test('BasicAuthTest_ControllerSecuredWithPermission'); $response = Director::test('BasicAuthTest_ControllerSecuredWithPermission');
$this->assertTrue(BasicAuthTest_ControllerSecuredWithPermission::$index_called); $this->assertTrue(BasicAuthTest_ControllerSecuredWithPermission::$index_called);
$this->assertTrue(BasicAuthTest_ControllerSecuredWithPermission::$post_init_called); $this->assertTrue(BasicAuthTest_ControllerSecuredWithPermission::$post_init_called);
$_SERVER['PHP_AUTH_USER'] = $origUser; $_SERVER['PHP_AUTH_USER'] = $origUser;
$_SERVER['PHP_AUTH_PW'] = $origPw; $_SERVER['PHP_AUTH_PW'] = $origPw;
} }
@ -61,45 +55,45 @@ class BasicAuthTest extends FunctionalTest {
public function testBasicAuthEnabledWithPermission() { public function testBasicAuthEnabledWithPermission() {
$origUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null; $origUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null;
$origPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null; $origPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null;
$_SERVER['PHP_AUTH_USER'] = 'user-in-mygroup@test.com'; $_SERVER['PHP_AUTH_USER'] = 'user-in-mygroup@test.com';
$_SERVER['PHP_AUTH_PW'] = 'wrongpassword'; $_SERVER['PHP_AUTH_PW'] = 'wrongpassword';
$response = Director::test('BasicAuthTest_ControllerSecuredWithPermission'); $response = Director::test('BasicAuthTest_ControllerSecuredWithPermission');
$this->assertEquals(401, $response->getStatusCode(), 'Invalid users dont have access'); $this->assertEquals(401, $response->getStatusCode(), 'Invalid users dont have access');
$_SERVER['PHP_AUTH_USER'] = 'user-without-groups@test.com'; $_SERVER['PHP_AUTH_USER'] = 'user-without-groups@test.com';
$_SERVER['PHP_AUTH_PW'] = 'test'; $_SERVER['PHP_AUTH_PW'] = 'test';
$response = Director::test('BasicAuthTest_ControllerSecuredWithPermission'); $response = Director::test('BasicAuthTest_ControllerSecuredWithPermission');
$this->assertEquals(401, $response->getStatusCode(), 'Valid user without required permission has no access'); $this->assertEquals(401, $response->getStatusCode(), 'Valid user without required permission has no access');
$_SERVER['PHP_AUTH_USER'] = 'user-in-mygroup@test.com'; $_SERVER['PHP_AUTH_USER'] = 'user-in-mygroup@test.com';
$_SERVER['PHP_AUTH_PW'] = 'test'; $_SERVER['PHP_AUTH_PW'] = 'test';
$response = Director::test('BasicAuthTest_ControllerSecuredWithPermission'); $response = Director::test('BasicAuthTest_ControllerSecuredWithPermission');
$this->assertEquals(200, $response->getStatusCode(), 'Valid user with required permission has access'); $this->assertEquals(200, $response->getStatusCode(), 'Valid user with required permission has access');
$_SERVER['PHP_AUTH_USER'] = $origUser; $_SERVER['PHP_AUTH_USER'] = $origUser;
$_SERVER['PHP_AUTH_PW'] = $origPw; $_SERVER['PHP_AUTH_PW'] = $origPw;
} }
public function testBasicAuthEnabledWithoutPermission() { public function testBasicAuthEnabledWithoutPermission() {
$origUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null; $origUser = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : null;
$origPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null; $origPw = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : null;
$_SERVER['PHP_AUTH_USER'] = 'user-without-groups@test.com'; $_SERVER['PHP_AUTH_USER'] = 'user-without-groups@test.com';
$_SERVER['PHP_AUTH_PW'] = 'wrongpassword'; $_SERVER['PHP_AUTH_PW'] = 'wrongpassword';
$response = Director::test('BasicAuthTest_ControllerSecuredWithoutPermission'); $response = Director::test('BasicAuthTest_ControllerSecuredWithoutPermission');
$this->assertEquals(401, $response->getStatusCode(), 'Invalid users dont have access'); $this->assertEquals(401, $response->getStatusCode(), 'Invalid users dont have access');
$_SERVER['PHP_AUTH_USER'] = 'user-without-groups@test.com'; $_SERVER['PHP_AUTH_USER'] = 'user-without-groups@test.com';
$_SERVER['PHP_AUTH_PW'] = 'test'; $_SERVER['PHP_AUTH_PW'] = 'test';
$response = Director::test('BasicAuthTest_ControllerSecuredWithoutPermission'); $response = Director::test('BasicAuthTest_ControllerSecuredWithoutPermission');
$this->assertEquals(200, $response->getStatusCode(), 'All valid users have access'); $this->assertEquals(200, $response->getStatusCode(), 'All valid users have access');
$_SERVER['PHP_AUTH_USER'] = 'user-in-mygroup@test.com'; $_SERVER['PHP_AUTH_USER'] = 'user-in-mygroup@test.com';
$_SERVER['PHP_AUTH_PW'] = 'test'; $_SERVER['PHP_AUTH_PW'] = 'test';
$response = Director::test('BasicAuthTest_ControllerSecuredWithoutPermission'); $response = Director::test('BasicAuthTest_ControllerSecuredWithoutPermission');
$this->assertEquals(200, $response->getStatusCode(), 'All valid users have access'); $this->assertEquals(200, $response->getStatusCode(), 'All valid users have access');
$_SERVER['PHP_AUTH_USER'] = $origUser; $_SERVER['PHP_AUTH_USER'] = $origUser;
$_SERVER['PHP_AUTH_PW'] = $origPw; $_SERVER['PHP_AUTH_PW'] = $origPw;
} }
@ -131,23 +125,23 @@ class BasicAuthTest extends FunctionalTest {
} }
class BasicAuthTest_ControllerSecuredWithPermission extends Controller implements TestOnly { class BasicAuthTest_ControllerSecuredWithPermission extends Controller implements TestOnly {
static $post_init_called = false; static $post_init_called = false;
static $index_called = false; static $index_called = false;
protected $template = 'BlankPage'; protected $template = 'BlankPage';
public function init() { public function init() {
self::$post_init_called = false; self::$post_init_called = false;
self::$index_called = false; self::$index_called = false;
BasicAuth::protect_entire_site(true, 'MYCODE'); BasicAuth::protect_entire_site(true, 'MYCODE');
parent::init(); parent::init();
self::$post_init_called = true; self::$post_init_called = true;
} }
public function index() { public function index() {
self::$index_called = true; self::$index_called = true;
} }
@ -164,5 +158,5 @@ class BasicAuthTest_ControllerSecuredWithoutPermission extends Controller implem
BasicAuth::protect_entire_site(true, null); BasicAuth::protect_entire_site(true, null);
parent::init(); parent::init();
} }
} }