diff --git a/php/libraries/NDB_Client.class.inc b/php/libraries/NDB_Client.class.inc index ccc9a757ec6..23497978126 100644 --- a/php/libraries/NDB_Client.class.inc +++ b/php/libraries/NDB_Client.class.inc @@ -65,10 +65,11 @@ class NDB_Client $DBSettings['host'], true ); + // Now make sure the factory reference is the same as the + // singleton reference + $factory->setDatabase($DB); } - // Now make sure the factory reference is the same as the - // singleton reference $DB = $factory->database(); // add extra include paths. This must be done diff --git a/php/libraries/NDB_Factory.class.inc b/php/libraries/NDB_Factory.class.inc index f408a9a90d6..c65759e4980 100644 --- a/php/libraries/NDB_Factory.class.inc +++ b/php/libraries/NDB_Factory.class.inc @@ -4,8 +4,7 @@ * are usually singletons. Instead of directly calling class::singleton staticly, * this factory should be used so that a mock class can be subbed in for testing. * - * If the Factory is in testing mode (setTesting(true) was called), a mock will - * be returned. Otherwise, the normal NDB_ prefixed object will be returned. + * Mocks are injected using the setDatabase/setConfig/etc methods. * * PHP Version 7 * @@ -25,11 +24,6 @@ use \LORIS\StudyEntities\Candidate\CandID; * @author Dave MacFarlane * @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 * @link https://www.github.com/aces/Loris/ - * - * Phan currently has bad support for PHPUnit's Mock objects which is - * creating false positive with the below rule. - * - * @phan-file-suppress PhanUndeclaredClassMethod */ class NDB_Factory { @@ -43,9 +37,6 @@ class NDB_Factory private static $_timepoints = []; private $_baseURL = ""; - var $Testing; // Whether or not Mock objects should be returned instead of - // real ones - // /** * Settings object @@ -55,18 +46,6 @@ class NDB_Factory */ private static $_settings = null; - /** - * Sets whether the factory should return real objects or testing objects - * - * @param boolean $val Whether testing should be enabled - * - * @return void - */ - function setTesting(bool $val): void - { - $this->Testing = $val; - } - /** * Returns a single factory object. This must be used instead of being * constructed directly so that the testing suite and Loris code are @@ -117,34 +96,14 @@ class NDB_Factory */ function config(?string $configfile = '../project/config.xml'): \NDB_Config { - if (self::$config !== null) { - // The below suppression is necessary to satisfy phan. It flags an - // error here because the function is declared to return - // NDB_Config and phan doesn't understand MockNDB_Config (as it is - // generated dynamically by PHPUnit). - // We know this will always return \NDB_Config since this is guaranteed - // by the return type of the function. - // - // @phan-suppress-next-line PhanTypeMismatchReturn - return self::$config; - } - if ($this->Testing) { - $config = new MockNDB_Config(); - $configfile = '../test/config.xml'; - } else { - $config = NDB_Config::singleton($configfile); + $config = self::$config; + if ($config !== null) { + return $config; } - self::$config = $config; + $config = NDB_Config::singleton($configfile); - // The below suppression is necessary to satisfy phan. It flags an - // error here because the function is declared to return - // NDB_Config and phan doesn't understand MockNDB_Config (as it is - // generated dynamically by PHPUnit). - // We know this will always return \NDB_Config since this is guaranteed - // by the return type of the function. - // - // @phan-suppress-next-line PhanTypeMismatchReturn + self::$config = $config; return $config; } @@ -169,22 +128,11 @@ class NDB_Factory */ function user(): \User { - if (self::$_user !== null) { - // The below suppression is necessary to satisfy phan. It flags an - // error here because the function is declared to return - // User and phan doesn't understand MockUser (as it is - // generated dynamically by PHPUnit). - // We know this will always return \User since this is guaranteed - // by the return type of the function. - // @phan-suppress-next-line PhanTypeMismatchReturn - return self::$_user; - } - if ($this->Testing) { - Mock::generate("User"); - $user = new MockUser(); - } else { - $user = \User::singleton(); + $user = self::$_user; + if ($user !== null) { + return $user; } + $user = \User::singleton(); self::$_user = $user; return $user; } @@ -210,21 +158,11 @@ class NDB_Factory */ function database(): \Database { - $db_ref = null; - if ($this->Testing) { - $db_ref = &self::$testdb; - if ($db_ref !== null) { - return $db_ref; - } - //self::$testdb = Mock::generate("Database"); - self::$testdb = new MockDatabase(); - } else { - $db_ref = &self::$db; - if ($db_ref !== null) { - return $db_ref; - } - self::$db = Database::singleton(); + $db_ref = &self::$db; + if ($db_ref !== null) { + return $db_ref; } + $config = $this->config(); $dbc = $config->getSetting('database'); // This check was added to satisfy phan, our static analysis tool. @@ -235,13 +173,16 @@ class NDB_Factory 'Could not configure database for LORIS' ); } - $db_ref->connect( + + $db_ref = \Database::singleton( $dbc['database'], $dbc['username'], $dbc['password'], $dbc['host'], true ); + + self::$db = $db_ref; return $db_ref; } @@ -339,29 +280,16 @@ class NDB_Factory if (!empty(self::$_couchdb[$database])) { return self::$_couchdb[$database]; } - if ($this->Testing) { - Mock::generatePartial( - 'CouchDB', - 'MockCouchDBWrap', - /* mock out the functions that make HTTP requests */ - [ - '_getRelativeURL', - '_postRelativeURL', - '_postURL', - '_getURL', - ] - ); - self::$_couchdb[$database] = new MockCouchDBWrap(); - } else { - self::$_couchdb[$database] = CouchDB::getInstance( - $database, - $host, - $port, - $user, - $password - ); - } - return self::$_couchdb[$database]; + + $couch = CouchDB::getInstance( + $database, + $host, + $port, + $user, + $password + ); + self::$_couchdb[$database] = $couch; + return $couch; } /** @@ -419,15 +347,7 @@ class NDB_Factory */ public function project(string $projectName): \Project { - $project = null; - - if ($this->Testing) { - $project = new MockProject($projectName); - } else { - $project = \Project::singleton($projectName); - } - - return $project; + return \Project::singleton($projectName); } /** @@ -443,11 +363,7 @@ class NDB_Factory if (isset(self::$_candidates[$key])) { return self::$_candidates[$key]; } - if ($this->Testing) { - self::$_candidates[$key] = new MockCandidate($CandID); - } else { - self::$_candidates[$key] = Candidate::singleton($CandID); - } + self::$_candidates[$key] = Candidate::singleton($CandID); return self::$_candidates[$key]; } @@ -465,15 +381,9 @@ class NDB_Factory if (isset(self::$_timepoints[(string) $sessionID])) { return self::$_timepoints[(string) $sessionID]; } - if ($this->Testing) { - self::$_timepoints[(string) $sessionID] = new MockTimepoint( - $sessionID - ); - } else { - self::$_timepoints[(string) $sessionID] = \TimePoint::singleton( - $sessionID - ); - } + self::$_timepoints[(string) $sessionID] = \TimePoint::singleton( + $sessionID + ); return self::$_timepoints[(string) $sessionID]; } } diff --git a/php/libraries/Utility.class.inc b/php/libraries/Utility.class.inc index 11b51d46d4c..29761309e2b 100644 --- a/php/libraries/Utility.class.inc +++ b/php/libraries/Utility.class.inc @@ -851,8 +851,10 @@ class Utility "Input must be a valid date/time string: $e" ); } + + $factory = \NDB_Factory::singleton(); return $dt->format( - \NDB_Config::singleton()->getSetting('dateDisplayFormat') + $factory->config()->getSetting('dateDisplayFormat') ?? DateTime::ATOM ); } diff --git a/test/integrationtests/LorisIntegrationTest.class.inc b/test/integrationtests/LorisIntegrationTest.class.inc index e03eb7ec481..401b8abb70e 100755 --- a/test/integrationtests/LorisIntegrationTest.class.inc +++ b/test/integrationtests/LorisIntegrationTest.class.inc @@ -64,19 +64,22 @@ abstract class LorisIntegrationTest extends TestCase // Set up database wrapper and config $this->factory = NDB_Factory::singleton(); $this->factory->reset(); - $this->factory->setTesting(false); $this->config = $this->factory->Config(CONFIG_XML); $database = $this->config->getSetting('database'); - $this->DB = Database::singleton( + $this->DB = Database::singleton( $database['database'], $database['username'], $database['password'], $database['host'], 1 ); + + $this->factory->setDatabase($this->DB); + $this->factory->setConfig($this->config); + $this->url = getenv('DOCKER_WEB_SERVER'); $password = new \Password($this->validPassword); diff --git a/test/unittests/CandidateTest.php b/test/unittests/CandidateTest.php index 1a3d9b86c2f..1b93d6c35fb 100644 --- a/test/unittests/CandidateTest.php +++ b/test/unittests/CandidateTest.php @@ -148,6 +148,7 @@ protected function setUp(): void $this->_configMock = $this->getMockBuilder('NDB_Config')->getMock(); $this->_dbMock = $this->getMockBuilder('Database')->getMock(); $this->_factory = NDB_Factory::singleton(); + $this->_factory->setConfig($this->_configMock); $this->_factory->setDatabase($this->_dbMock); @@ -1311,7 +1312,6 @@ private function _setUpMockDB() { $this->_factoryForDB = NDB_Factory::singleton(); $this->_factoryForDB->reset(); - $this->_factoryForDB->setTesting(false); $this->_config = $this->_factoryForDB->Config(CONFIG_XML); $database = $this->_config->getSetting('database'); $this->_DB = Database::singleton( @@ -1321,5 +1321,8 @@ private function _setUpMockDB() $database['host'], 1 ); + + $this->_factoryForDB->setDatabase($this->_DB); + $this->_factoryForDB->setConfig($this->_config); } } diff --git a/test/unittests/Database_Test.php b/test/unittests/Database_Test.php index e8869c33fb2..edef89e0bf5 100644 --- a/test/unittests/Database_Test.php +++ b/test/unittests/Database_Test.php @@ -86,7 +86,6 @@ protected function setUp(): void { $this->factory = NDB_Factory::singleton(); $this->factory->reset(); - $this->factory->setTesting(false); $this->config = $this->factory->Config(CONFIG_XML); $database = $this->config->getSetting('database'); $this->DB = Database::singleton( @@ -96,6 +95,9 @@ protected function setUp(): void $database['host'], 1 ); + + $this->factory->setDatabase($this->DB); + $this->factory->setConfig($this->config); } /** diff --git a/test/unittests/NDB_BVL_Instrument_LINST_ToJSON_Test.php b/test/unittests/NDB_BVL_Instrument_LINST_ToJSON_Test.php index 04c80e9d87e..afabb9faccb 100644 --- a/test/unittests/NDB_BVL_Instrument_LINST_ToJSON_Test.php +++ b/test/unittests/NDB_BVL_Instrument_LINST_ToJSON_Test.php @@ -50,7 +50,6 @@ function setUp(): void ]; $factory = \NDB_Factory::singleton(); - $factory->setTesting(true); $mockdb = $this->getMockBuilder("\Database")->getMock(); $mockconfig = $this->getMockBuilder("\NDB_Config")->getMock(); diff --git a/test/unittests/NDB_BVL_Instrument_Test.php b/test/unittests/NDB_BVL_Instrument_Test.php index a3147891dcb..1f0c5eeadec 100644 --- a/test/unittests/NDB_BVL_Instrument_Test.php +++ b/test/unittests/NDB_BVL_Instrument_Test.php @@ -65,14 +65,12 @@ function setUp(): void ]; $this->_factory = \NDB_Factory::singleton(); - $this->_factory->setTesting(true); $this->_mockDB = $this->getMockBuilder("\Database")->getMock(); $this->_mockConfig = $this->getMockBuilder("\NDB_Config")->getMock(); - \NDB_Factory::$db = $this->_mockDB; - \NDB_Factory::$testdb = $this->_mockDB; - \NDB_Factory::$config = $this->_mockConfig; + $this->_factory->setDatabase($this->_mockDB); + $this->_factory->setConfig($this->_mockConfig); $this->quickForm = new \LorisForm(); @@ -1986,7 +1984,7 @@ private function _setUpMockDB() { $this->_factoryForDB = \NDB_Factory::singleton(); $this->_factoryForDB->reset(); - $this->_factoryForDB->setTesting(false); + $this->_config = $this->_factoryForDB->Config(CONFIG_XML); $database = $this->_config->getSetting('database'); $this->_DB = \Database::singleton( @@ -1996,6 +1994,9 @@ private function _setUpMockDB() $database['host'], 1 ); + + $this->_factoryForDB->setDatabase($this->_DB); + $this->_factoryForDB->setConfig($this->_config); } } diff --git a/test/unittests/NDB_Factory_Test.php b/test/unittests/NDB_Factory_Test.php index f16c94fc4ee..0596eb2e412 100644 --- a/test/unittests/NDB_Factory_Test.php +++ b/test/unittests/NDB_Factory_Test.php @@ -35,26 +35,30 @@ class NDB_Factory_Test extends TestCase protected function setUp(): void { parent::setUp(); - $this->_factory = \NDB_Factory::singleton(); - $this->_config = \NDB_Config::singleton(); - $database = $this->_config->getSetting('database'); - $this->_DB = Database::singleton( + $this->_factory = NDB_Factory::singleton(); + $this->_factory->reset(); + + $this->_config = $this->_factory->Config(CONFIG_XML); + $database = $this->_config->getSetting('database'); + $this->_DB = Database::singleton( $database['database'], $database['username'], $database['password'], $database['host'], true ); + + $this->_factory->setDatabase($this->_DB); + $this->_factory->setConfig($this->_config); } /** * Test that the singleton function returns a new NDB_Factory object and - * that the reset and setTesting functions properly set the properties of + * that the reset function properly set the properties of * the object * * @covers NDB_Factory::singleton * @covers NDB_Factory::reset - * @covers NDB_Factory::setTesting * @return void */ function testSetUp() @@ -64,8 +68,6 @@ function testSetUp() $this->assertNull(\NDB_Factory::$testdb); $this->assertNull(\NDB_Factory::$db); $this->assertNull(\NDB_Factory::$config); - $this->_factory->setTesting(true); - $this->assertTrue($this->_factory->Testing); } /** @@ -76,7 +78,6 @@ function testSetUp() */ function testConfig() { - $this->_factory->setTesting(false); $this->_factory->config(); $this->assertEquals( NDB_Config::singleton('../project/config.xml'), @@ -106,7 +107,6 @@ function testSetConfig() */ function testUser() { - $this->_factory->setTesting(false); $this->assertEquals( \User::singleton(), $this->_factory->user() @@ -136,7 +136,6 @@ function testSetUser() */ function testDatabase() { - $this->_factory->setTesting(false); $this->assertEquals($this->_DB, $this->_factory->database()); } @@ -176,7 +175,6 @@ function testCouchDBThrowsException() */ function testCouchDB() { - $this->_factory->setTesting(false); $this->assertEquals( CouchDB::getInstance("db", "host", 1, "user", "pass"), $this->_factory->couchDB("db", "host", 1, "user", "pass") @@ -236,6 +234,12 @@ function testProject() */ function testCandidate() { + $mockdb = $this->getMockBuilder("\Database")->getMock(); + $this->_factory->setDatabase($mockdb); + $mockdb->expects($this->any()) + ->method('pselectRow') + ->willReturn(['DCCID'=>'300001']); + $candID = new CandID("300001"); $this->assertEquals( Candidate::singleton($candID), @@ -252,10 +256,18 @@ function testCandidate() */ function testTimepoint() { + $mockdb = $this->getMockBuilder("\Database")->getMock(); + $mockconfig = $this->getMockBuilder("\NDB_Config")->getMock(); + $this->_factory->setConfig($mockconfig); + $this->_factory->setDatabase($mockdb); + $mockdb->expects($this->any()) + ->method('pselectRow') + ->willReturn(['1']); + $sessionID = new \SessionID("1"); $this->assertEquals( \TimePoint::singleton($sessionID), $this->_factory->timepoint($sessionID) ); } -} \ No newline at end of file +} diff --git a/test/unittests/SinglePointLoginTest.php b/test/unittests/SinglePointLoginTest.php index b7ca86d05d0..04d6df033b1 100644 --- a/test/unittests/SinglePointLoginTest.php +++ b/test/unittests/SinglePointLoginTest.php @@ -34,8 +34,7 @@ class SinglePointLoginTest extends TestCase */ protected function setUp(): void { - $Factory = NDB_Factory::singleton(); - $Factory->setTesting(true); + $Factory = NDB_Factory::singleton(); $mockdb = $this->getMockBuilder("\Database")->getMock(); $mockconfig = $this->getMockBuilder("\NDB_Config")->getMock(); diff --git a/test/unittests/UserTest.php b/test/unittests/UserTest.php index 61744282156..5091714ad6c 100644 --- a/test/unittests/UserTest.php +++ b/test/unittests/UserTest.php @@ -262,7 +262,6 @@ protected function setUp(): void parent::setUp(); $this->_factory = \NDB_Factory::singleton(); $this->_factory->reset(); - $this->_factory->setTesting(false); $this->_configMock = $this->_factory->Config(CONFIG_XML); $database = $this->_configMock->getSetting('database'); $this->_dbMock = \Database::singleton( diff --git a/test/unittests/UtilityTest.php b/test/unittests/UtilityTest.php index 9d91ba89fb4..56cfafc0962 100644 --- a/test/unittests/UtilityTest.php +++ b/test/unittests/UtilityTest.php @@ -1136,6 +1136,13 @@ public function testRandomString() public function testToDateDisplayFormat() { $this->_setMockDB(); + + $config = $this->getMockBuilder("\NDB_Config")->getMock(); + $config->expects($this->any()) + ->method('getSetting') + ->willReturn('Y-m-d H:i:s'); + $this->_mockFactory->setConfig($config); + $date = "2000-01-01"; $this->assertEquals( "2000-01-01 00:00:00", @@ -1216,7 +1223,6 @@ private function _setMockDB() { $this->_mockFactory = \NDB_Factory::singleton(); $this->_mockFactory->reset(); - $this->_mockFactory->setTesting(false); $this->_mockConfig = $this->_mockFactory->Config(CONFIG_XML); $database = $this->_mockConfig->getSetting('database'); $this->_mockDB = \Database::singleton( @@ -1226,5 +1232,8 @@ private function _setMockDB() $database['host'], true ); + + $this->_mockFactory->setDatabase($this->_mockDB); + $this->_mockFactory->setConfig($this->_mockConfig); } } diff --git a/test/unittests/VisitTest.php b/test/unittests/VisitTest.php index 442b491eed5..bea9b852a8e 100644 --- a/test/unittests/VisitTest.php +++ b/test/unittests/VisitTest.php @@ -50,7 +50,6 @@ protected function setUp(): void { $this->factory = NDB_Factory::singleton(); $this->factory->reset(); - $this->factory->setTesting(false); $this->config = $this->factory->Config(CONFIG_XML); $database = $this->config->getSetting('database'); $this->DB = Database::singleton(