From d57a6fa6b78052419186ea22413db0d55af872f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Wed, 10 Jan 2018 15:29:05 +0200 Subject: [PATCH 01/20] tests restructure --- tests/DummyController.php | 2 +- tests/TestBaseClass.php | 52 +- tests/TestBaseClassView.php | 4 +- tests/TestBaseClassWeb.php | 4 +- tests/TestHelper.php | 7 +- tests/WebTestCase.php | 25 + tests/acceptance/README.md | 7 + .../admin}/AdminViewsTest.php | 20 +- .../admin}/CreateSurveyTest.php | 14 +- .../admin/InstallationControllerTest.php | 147 +++ .../admin}/TemplateConfigurationTest.php | 5 +- .../admin}/TemplateControllerTest.php | 22 +- .../SaveDualScaleAnswerOptionsTest.php | 14 +- .../DateTimeDefaultAnswerExpressionTest.php | 32 +- .../questions/DateTimeForwardBackTest.php | 20 +- .../questions/DateTimeTest.php | 15 +- .../questions/DateTimeValidationTest.php | 19 +- .../MultipleChoiceNextPreviousTest.php | 16 +- .../{ => acceptance}/surveys/AjaxModeTest.php | 4 +- .../surveys}/GroupRandomizationTest.php | 16 +- .../MultipleChoiceWithExpressionTest.php | 4 +- .../surveys/ScreenOutTest.php | 3 +- .../InstallationControllerTest.php | 166 ---- tests/functional/README.md | 6 + .../helpers/CheckDatabaseJsonValuesTest.php | 11 +- .../helpers/ExpressionCoreAux.php | 7 +- .../helpers/ExpressionCoreHelperTest.php | 3 +- .../helpers/UpdateDbHelperTest.php | 3 +- tests/index.html | 15 + tests/resources/README.md | 1 + .../sql/create-mysql.153.sql | 0 .../sql/create-mysql.258.sql | 0 .../sql/create-mysql.315.sql | 0 .../surveys/limesurvey_survey_186734.lss | 0 .../surveys/limesurvey_survey_352985.lss | 0 .../surveys/limesurvey_survey_366446.lss | 0 .../surveys/limesurvey_survey_454287.lss | 0 .../surveys/limesurvey_survey_563168.lss | 0 .../surveys/limesurvey_survey_583999.lss | 0 .../surveys/limesurvey_survey_677328.lss | 0 .../surveys/limesurvey_survey_834477.lss | 0 .../surveys/limesurvey_survey_88881.lss | 0 .../surveys/limesurvey_survey_917744.lss | 0 .../surveys/limesurvey_survey_975622.lss | 0 .../travis/travis-ci-apache | 0 .../travis/travis_setup.sh | 0 .../views/adminBaseViews.php | 0 .../views/adminGeneralSettingsViews.php | 0 .../views/adminParticipantsViews.php | 0 .../views/adminSettingsViews.php | 0 .../views/adminSurveyViews.php | 0 .../views/adminUsersViews.php | 0 tests/staticCalls.php | 144 +++ tests/travis/travis-ci-apache | 25 - tests/unit/ExpressionManagerTest.php | 894 ++++++++++++++++++ tests/unit/README.md | 11 + 56 files changed, 1475 insertions(+), 263 deletions(-) create mode 100644 tests/WebTestCase.php create mode 100644 tests/acceptance/README.md rename tests/{controllers => acceptance/admin}/AdminViewsTest.php (84%) rename tests/{controllers => acceptance/admin}/CreateSurveyTest.php (95%) create mode 100644 tests/acceptance/admin/InstallationControllerTest.php rename tests/{models => acceptance/admin}/TemplateConfigurationTest.php (84%) rename tests/{controllers => acceptance/admin}/TemplateControllerTest.php (72%) rename tests/{controllers => acceptance/admin/questions}/SaveDualScaleAnswerOptionsTest.php (88%) rename tests/{ => acceptance}/questions/DateTimeDefaultAnswerExpressionTest.php (85%) rename tests/{ => acceptance}/questions/DateTimeForwardBackTest.php (81%) rename tests/{ => acceptance}/questions/DateTimeTest.php (91%) rename tests/{ => acceptance}/questions/DateTimeValidationTest.php (83%) rename tests/{ => acceptance}/questions/MultipleChoiceNextPreviousTest.php (82%) rename tests/{ => acceptance}/surveys/AjaxModeTest.php (97%) rename tests/{helpers => acceptance/surveys}/GroupRandomizationTest.php (84%) rename tests/{ => acceptance}/surveys/MultipleChoiceWithExpressionTest.php (96%) rename tests/{ => acceptance}/surveys/ScreenOutTest.php (97%) delete mode 100644 tests/controllers/InstallationControllerTest.php create mode 100644 tests/functional/README.md rename tests/{ => functional}/helpers/CheckDatabaseJsonValuesTest.php (96%) rename tests/{ => functional}/helpers/ExpressionCoreAux.php (97%) rename tests/{ => functional}/helpers/ExpressionCoreHelperTest.php (97%) rename tests/{ => functional}/helpers/UpdateDbHelperTest.php (99%) create mode 100644 tests/index.html create mode 100644 tests/resources/README.md rename tests/{data => resources}/sql/create-mysql.153.sql (100%) rename tests/{data => resources}/sql/create-mysql.258.sql (100%) rename tests/{data => resources}/sql/create-mysql.315.sql (100%) rename tests/{data => resources}/surveys/limesurvey_survey_186734.lss (100%) rename tests/{data => resources}/surveys/limesurvey_survey_352985.lss (100%) rename tests/{data => resources}/surveys/limesurvey_survey_366446.lss (100%) rename tests/{data => resources}/surveys/limesurvey_survey_454287.lss (100%) rename tests/{data => resources}/surveys/limesurvey_survey_563168.lss (100%) rename tests/{data => resources}/surveys/limesurvey_survey_583999.lss (100%) rename tests/{data => resources}/surveys/limesurvey_survey_677328.lss (100%) rename tests/{data => resources}/surveys/limesurvey_survey_834477.lss (100%) rename tests/{data => resources}/surveys/limesurvey_survey_88881.lss (100%) rename tests/{data => resources}/surveys/limesurvey_survey_917744.lss (100%) rename tests/{data => resources}/surveys/limesurvey_survey_975622.lss (100%) rename tests/{data => resources}/travis/travis-ci-apache (100%) rename tests/{data => resources}/travis/travis_setup.sh (100%) rename tests/{data => resources}/views/adminBaseViews.php (100%) rename tests/{data => resources}/views/adminGeneralSettingsViews.php (100%) rename tests/{data => resources}/views/adminParticipantsViews.php (100%) rename tests/{data => resources}/views/adminSettingsViews.php (100%) rename tests/{data => resources}/views/adminSurveyViews.php (100%) rename tests/{data => resources}/views/adminUsersViews.php (100%) create mode 100644 tests/staticCalls.php delete mode 100644 tests/travis/travis-ci-apache create mode 100644 tests/unit/ExpressionManagerTest.php create mode 100644 tests/unit/README.md diff --git a/tests/DummyController.php b/tests/DummyController.php index 5e8081091e7..21a5de9e473 100644 --- a/tests/DummyController.php +++ b/tests/DummyController.php @@ -1,6 +1,6 @@ importAll(); + parent::setUpBeforeClass(); + } + + // the folder getter can be used in @dataProvider methods since the setUpBeforeClass will run after them + + /** + * @return string + */ + public static function getDataFolder(){ + return __DIR__."/resources"; + } + + /** + * @return string + */ + public static function getViewsFolder(){ + return self::getDataFolder().DIRECTORY_SEPARATOR.'views'; + } + + /** + * @return string + */ + public static function getSurveysFolder(){ + return self::getDataFolder().DIRECTORY_SEPARATOR.'surveys'; + } + + /** + * @return string + */ + public static function getTempFolder(){ + return __DIR__."/tmp"; + } + + /** + * @return string + */ + public static function getScreenShotsFolder(){ + return self::getTempFolder().DIRECTORY_SEPARATOR.'screenshots'; } /** diff --git a/tests/TestBaseClassView.php b/tests/TestBaseClassView.php index 447cfa6b41d..fab22f3409f 100644 --- a/tests/TestBaseClassView.php +++ b/tests/TestBaseClassView.php @@ -11,13 +11,13 @@ * See COPYRIGHT.php for copyright notices and details. */ -namespace ls\tests; +namespace LimeSurvey\tests; use Facebook\WebDriver\WebDriverBy; use Facebook\WebDriver\WebDriverExpectedCondition; /** - * @package ls\tests + * @package LimeSurvey\tests */ class TestBaseClassView extends TestBaseClassWeb { diff --git a/tests/TestBaseClassWeb.php b/tests/TestBaseClassWeb.php index 4b04f54dc7f..90e0d518e43 100644 --- a/tests/TestBaseClassWeb.php +++ b/tests/TestBaseClassWeb.php @@ -11,7 +11,7 @@ * See COPYRIGHT.php for copyright notices and details. */ -namespace ls\tests; +namespace LimeSurvey\tests; use Facebook\WebDriver\WebDriver; use Facebook\WebDriver\WebDriverBy; @@ -21,7 +21,7 @@ /** * Class TestBaseClassWeb * this is the base class for functional tests that need browser simulation - * @package ls\tests + * @package LimeSurvey\tests */ class TestBaseClassWeb extends TestBaseClass { diff --git a/tests/TestHelper.php b/tests/TestHelper.php index 7008d64d317..c0b899b4dbc 100644 --- a/tests/TestHelper.php +++ b/tests/TestHelper.php @@ -1,6 +1,6 @@ connection = $connection; // Check SQL file. - $file = __DIR__ . '/data/sql/create-mysql.' . $version . '.sql'; + $file = TestBaseClass::getDataFolder() . '/sql/create-mysql.' . $version . '.sql'; $this->assertFileExists($file, 'SQL file exists: ' . $file); // Run SQL install file. diff --git a/tests/WebTestCase.php b/tests/WebTestCase.php new file mode 100644 index 00000000000..20eb3408e89 --- /dev/null +++ b/tests/WebTestCase.php @@ -0,0 +1,25 @@ +setBrowserUrl(TEST_BASE_URL); + } +} diff --git a/tests/acceptance/README.md b/tests/acceptance/README.md new file mode 100644 index 00000000000..7ad775045b2 --- /dev/null +++ b/tests/acceptance/README.md @@ -0,0 +1,7 @@ +# Acceptance tests +from: +https://stackoverflow.com/questions/4904096/whats-the-difference-between-unit-functional-acceptance-and-integration-test + +> Standard acceptance testing involves performing tests on the full system (e.g. using your web page via a web browser) to see whether the application's functionality satisfies the specification. E.g. "clicking a zoom icon should enlarge the document view by 25%." There is no real continuum of results, just a pass or fail outcome. + +Any test using the Facebook WebDriver should be somewhere here \ No newline at end of file diff --git a/tests/controllers/AdminViewsTest.php b/tests/acceptance/admin/AdminViewsTest.php similarity index 84% rename from tests/controllers/AdminViewsTest.php rename to tests/acceptance/admin/AdminViewsTest.php index 2e167cb3628..3de526d25dc 100644 --- a/tests/controllers/AdminViewsTest.php +++ b/tests/acceptance/admin/AdminViewsTest.php @@ -11,15 +11,15 @@ * See COPYRIGHT.php for copyright notices and details. */ -namespace ls\tests\controllers; +namespace LimeSurvey\tests\acceptance\admin; -use ls\tests\TestBaseClassView; +use LimeSurvey\tests\TestBaseClassView; /** * Class AdminViewsTest * This test loops through all basic admin view pages and cheks if they open withour errors * - * @package ls\tests + * @package LimeSurvey\tests * @group adminviews */ class AdminViewsTest extends TestBaseClassView @@ -27,31 +27,31 @@ class AdminViewsTest extends TestBaseClassView public function addBaseViews() { - return require __DIR__."/../data/views/adminBaseViews.php"; + return require self::getViewsFolder()."/adminBaseViews.php"; } public function addSurveyViews() { - return require __DIR__."/../data/views/adminSurveyViews.php"; + return require self::getViewsFolder()."/adminSurveyViews.php"; } public function addSettingsViews() { - return require __DIR__."/../data/views/adminSettingsViews.php"; + return require self::getViewsFolder()."/adminSettingsViews.php"; } public function addUsersViews() { - return require __DIR__."/../data/views/adminUsersViews.php"; + return require self::getViewsFolder()."/adminUsersViews.php"; } public function addParticipantsViews() { - return require __DIR__."/../data/views/adminParticipantsViews.php"; + return require self::getViewsFolder()."/adminParticipantsViews.php"; } public function addGeneralSettingsViews() { - return require __DIR__."/../data/views/adminGeneralSettingsViews.php"; + return require self::getViewsFolder()."/adminGeneralSettingsViews.php"; } /** @@ -89,7 +89,7 @@ public function testAdminSurveyViews($name, $view) } elseif (empty(self::$surveyId)) { // This situation can happen if we test only one data entry, // using --filter="testAdminSurveyViews#13" (for data entry 13). - $surveyFile = self::$surveysFolder . '/../data/surveys/limesurvey_survey_454287.lss'; + $surveyFile = self::$surveysFolder . '/limesurvey_survey_454287.lss'; self::importSurvey($surveyFile); } diff --git a/tests/controllers/CreateSurveyTest.php b/tests/acceptance/admin/CreateSurveyTest.php similarity index 95% rename from tests/controllers/CreateSurveyTest.php rename to tests/acceptance/admin/CreateSurveyTest.php index c5186412d2c..aa88ae93c63 100644 --- a/tests/controllers/CreateSurveyTest.php +++ b/tests/acceptance/admin/CreateSurveyTest.php @@ -1,6 +1,17 @@ getBasePath() . '/config/config.php'; + $databaseName = 'limesurvey'; + + $username = getenv('ADMINUSERNAME'); + if (!$username) { + $username = 'admin'; + } + $password = getenv('PASSWORD'); + if (!$password) { + $password = 'password'; + } + + $dbuser = getenv('DBUSER'); + if (!$dbuser) { + $dbuser = 'root'; + echo 'Default to database user "root". Use DBUSER=... from command-line to override this.' . PHP_EOL; + } + $dbpwd = getenv('DBPASSWORD'); + if (!$dbpwd) { + $dbpwd = ''; + echo 'Default to empty database password. Use DBPASSWORD=... from command-line to override this.' . PHP_EOL; + } + + if (file_exists($configFile)) { + // Delete possible previous database. + try { + $dbo = \Yii::app()->getDb(); + $dbo->createCommand('DROP DATABASE ' . $databaseName)->execute(); + } catch (\CDbException $ex) { + $msg = $ex->getMessage(); + // Only this error is OK. + self::assertTrue( + strpos($msg, "database doesn't exist") !== false, + 'Could drop database. Error message: ' . $msg + ); + } + + // Remove config.php if present. + $result = unlink($configFile); + $this->assertTrue($result, 'Could unlink config.php'); + } + + // Run installer. + $urlMan = \Yii::app()->urlManager; + $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); + $url = $urlMan->createUrl(''); + + // Installer start page. + self::$webDriver->get($url); + + // Click "Start installation". + $start = self::$webDriver->findElement(WebDriverBy::id('ls-start-installation')); + $start->click(); + + // Accept license. + $accept = self::$webDriver->findElement(WebDriverBy::id('ls-accept-license')); + $accept->click(); + + // Click next at pre-check. + $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); + $next->click(); + + // Fill in database form. + $dbuserInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbuser]"]')); + $dbpwdInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbpwd]"]')); + $dbnameInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbname]"]')); + $dbuserInput->clear()->sendKeys($dbuser); + $dbpwdInput->clear()->sendKeys($dbpwd); + $dbnameInput->sendKeys($databaseName); + + // Click next. + $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); + $next->click(); + + // Click "Create database". + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + + // Click "Populate". + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + + // Fill in admin username/password. + $adminLoginName = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginName]"]')); + $adminLoginPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginPwd]"]')); + $confirmPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[confirmPwd]"]')); + $adminLoginName->clear()->sendKeys($username); + $adminLoginPwd->clear()->sendKeys($password); + $confirmPwd->clear()->sendKeys($password); + + // Confirm optional settings (admin password etc). + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + + // Go to administration. + $button = self::$webDriver->findElement(WebDriverBy::id('ls-administration')); + $button->click(); + + // Reset urlManager to adapt to latest config. + $configFile = \Yii::app()->getBasePath() . '/config/config.php'; + $config = require($configFile); + $urlMan = \Yii::app()->urlManager; + $urlMan->setUrlFormat($config['components']['urlManager']['urlFormat']); + + // Login. + self::adminLogin($username, $password); + + self::$testHelper->connectToOriginalDatabase(); + } +} diff --git a/tests/models/TemplateConfigurationTest.php b/tests/acceptance/admin/TemplateConfigurationTest.php similarity index 84% rename from tests/models/TemplateConfigurationTest.php rename to tests/acceptance/admin/TemplateConfigurationTest.php index f744b8f756f..f63d4721051 100644 --- a/tests/models/TemplateConfigurationTest.php +++ b/tests/acceptance/admin/TemplateConfigurationTest.php @@ -1,6 +1,7 @@ prepareTemplateRendering('default'); + // FIXME + // No PHP notices. $this->assertTrue(true); } diff --git a/tests/controllers/TemplateControllerTest.php b/tests/acceptance/admin/TemplateControllerTest.php similarity index 72% rename from tests/controllers/TemplateControllerTest.php rename to tests/acceptance/admin/TemplateControllerTest.php index 706e9ac3847..927b4392c58 100644 --- a/tests/controllers/TemplateControllerTest.php +++ b/tests/acceptance/admin/TemplateControllerTest.php @@ -1,8 +1,20 @@ templatecopy(); $flashes = \Yii::app()->user->getFlashes(); @@ -57,7 +69,9 @@ public function testCopyTemplate() $this->assertNotEmpty($template); $this->assertEquals($templateName, $template->name); - // Clean up. + + + // Clean up. //TODO tearDown \Template::model()->deleteAll('name = \'foobartest\''); } diff --git a/tests/controllers/SaveDualScaleAnswerOptionsTest.php b/tests/acceptance/admin/questions/SaveDualScaleAnswerOptionsTest.php similarity index 88% rename from tests/controllers/SaveDualScaleAnswerOptionsTest.php rename to tests/acceptance/admin/questions/SaveDualScaleAnswerOptionsTest.php index 6193b1cc952..b74e409470f 100644 --- a/tests/controllers/SaveDualScaleAnswerOptionsTest.php +++ b/tests/acceptance/admin/questions/SaveDualScaleAnswerOptionsTest.php @@ -1,8 +1,20 @@ findByPk(self::$surveyId); list($question, $group, $sgqa) = self::$testHelper->getSgqa('q2', self::$surveyId); @@ -122,7 +138,8 @@ public function testCorrectDefaultAnswerExpression() // Check result from qanda. $qanda = \retrieveAnswers( - $_SESSION['survey_' . self::$surveyId]['fieldarray'][1] // 1 = second question (q2) + $_SESSION['survey_' . self::$surveyId]['fieldarray'][1], // 1 = second question (q2) + self::$surveyId ); $correctDate = date('d/m/Y'); @@ -178,11 +195,12 @@ public function testWrongDefaultAnswerExpression() $_SESSION['survey_' . self::$surveyId]['step'] = 1; // Move one step to run expressions. - $moveResult = \LimeExpressionManager::NavigateForwards(); + $moveResult = LimeExpressionManager::NavigateForwards(); // Check result from qanda. $qanda = \retrieveAnswers( - $_SESSION['survey_' . self::$surveyId]['fieldarray'][2] // 2 = third question (q3) + $_SESSION['survey_' . self::$surveyId]['fieldarray'][2], // 2 = third question (q3) + self::$surveyId ); // NB: Empty value, since default answer expression is not parsed by qanda. diff --git a/tests/questions/DateTimeForwardBackTest.php b/tests/acceptance/questions/DateTimeForwardBackTest.php similarity index 81% rename from tests/questions/DateTimeForwardBackTest.php rename to tests/acceptance/questions/DateTimeForwardBackTest.php index 2dd2b1c5974..67104478432 100644 --- a/tests/questions/DateTimeForwardBackTest.php +++ b/tests/acceptance/questions/DateTimeForwardBackTest.php @@ -1,6 +1,21 @@ assertEquals(false, strpos($qanda[0][1], "value=\"11:00\""), 'No 11:00 value from qanda'); $this->assertNotEquals(false, strpos($qanda[0][1], "value=\"10:00\""), 'One 10:00 value from qanda'); diff --git a/tests/questions/DateTimeTest.php b/tests/acceptance/questions/DateTimeTest.php similarity index 91% rename from tests/questions/DateTimeTest.php rename to tests/acceptance/questions/DateTimeTest.php index 93d99553154..ecc315d9194 100644 --- a/tests/questions/DateTimeTest.php +++ b/tests/acceptance/questions/DateTimeTest.php @@ -1,7 +1,20 @@ session['loginID'] = 1; - $surveyFile = __DIR__ . '/../data/surveys/limesurvey_survey_88881.lss'; + $surveyFile = self::getSurveysFolder() . '/limesurvey_survey_88881.lss'; if (!file_exists($surveyFile)) { echo 'Fatal error: found no survey file'; exit(4); diff --git a/tests/surveys/MultipleChoiceWithExpressionTest.php b/tests/acceptance/surveys/MultipleChoiceWithExpressionTest.php similarity index 96% rename from tests/surveys/MultipleChoiceWithExpressionTest.php rename to tests/acceptance/surveys/MultipleChoiceWithExpressionTest.php index 4d44989d5a9..819a8dcd215 100644 --- a/tests/surveys/MultipleChoiceWithExpressionTest.php +++ b/tests/acceptance/surveys/MultipleChoiceWithExpressionTest.php @@ -1,8 +1,8 @@ getWebDriver(); - self::$domain = getenv('DOMAIN'); - } - - public static function teardownAfterClass() - { - self::$testHelper->connectToOriginalDatabase(); - } - - /** - * - * @throws \CException - */ - public function testBasic() - { - $configFile = \Yii::app()->getBasePath() . '/config/config.php'; - $databaseName = 'limesurvey'; - - $username = getenv('ADMINUSERNAME'); - if (!$username) { - $username = 'admin'; - } - $password = getenv('PASSWORD'); - if (!$password) { - $password = 'password'; - } - - $dbuser = getenv('DBUSER'); - if (!$dbuser) { - $dbuser = 'root'; - echo 'Default to database user "root". Use DBUSER=... from command-line to override this.' . PHP_EOL; - } - $dbpwd = getenv('DBPASSWORD'); - if (!$dbpwd) { - $dbpwd = ''; - echo 'Default to empty database password. Use DBPASSWORD=... from command-line to override this.' . PHP_EOL; - } - - if (file_exists($configFile)) { - // Delete possible previous database. - try { - $dbo = \Yii::app()->getDb(); - $dbo->createCommand('DROP DATABASE ' . $databaseName)->execute(); - } catch (\CDbException $ex) { - $msg = $ex->getMessage(); - // Only this error is OK. - self::assertTrue( - strpos($msg, "database doesn't exist") !== false, - 'Could drop database. Error message: ' . $msg - ); - } - - // Remove config.php if present. - $result = unlink($configFile); - $this->assertTrue($result, 'Could unlink config.php'); - } - - // Run installer. - $urlMan = \Yii::app()->urlManager; - $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); - $url = $urlMan->createUrl(''); - - try { - - // Installer start page. - self::$webDriver->get($url); - - // Click "Start installation". - $start = self::$webDriver->findElement(WebDriverBy::id('ls-start-installation')); - $start->click(); - - // Accept license. - $accept = self::$webDriver->findElement(WebDriverBy::id('ls-accept-license')); - $accept->click(); - - // Click next at pre-check. - $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); - $next->click(); - - // Fill in database form. - $dbuserInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbuser]"]')); - $dbpwdInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbpwd]"]')); - $dbnameInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbname]"]')); - $dbuserInput->clear()->sendKeys($dbuser); - $dbpwdInput->clear()->sendKeys($dbpwd); - $dbnameInput->sendKeys($databaseName); - - // Click next. - $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); - $next->click(); - - // Click "Create database". - $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); - $button->click(); - - // Click "Populate". - $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); - $button->click(); - - // Fill in admin username/password. - $adminLoginName = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginName]"]')); - $adminLoginPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginPwd]"]')); - $confirmPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[confirmPwd]"]')); - $adminLoginName->clear()->sendKeys($username); - $adminLoginPwd->clear()->sendKeys($password); - $confirmPwd->clear()->sendKeys($password); - - // Confirm optional settings (admin password etc). - $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); - $button->click(); - - // Go to administration. - $button = self::$webDriver->findElement(WebDriverBy::id('ls-administration')); - $button->click(); - - // Set debug=2 - /* TODO: Can't write to config.php after installation. - $configFile = \Yii::app()->getBasePath() . '/config/config.php'; - $data = file($configFile); - $data = array_map(function($data) { - return stristr($data, "'debug'=>0") ? "'debug'=>2," : $data; - }, $data); - $output = []; - exec('chmod 777 ' . $configFile, $output); - var_dump($output); - $result = file_put_contents($configFile, implode('', $data)); - $this->assertTrue($result > 0, 'Wrote config'); - */ - - // Reset urlManager to adapt to latest config. - $config = require($configFile); - $urlMan = \Yii::app()->urlManager; - $urlMan->setUrlFormat($config['components']['urlManager']['urlFormat']); - - // Login. - self::adminLogin($username, $password); - } catch (NoSuchElementException $ex) { - self::$testHelper->takeScreenshot(self::$webDriver, (new \ReflectionClass($this))->getShortName() . '_' . __FUNCTION__); - $this->assertFalse( - true, - self::$testHelper->javaTrace($ex) - ); - } - } -} diff --git a/tests/functional/README.md b/tests/functional/README.md new file mode 100644 index 00000000000..0b7c3d8a36a --- /dev/null +++ b/tests/functional/README.md @@ -0,0 +1,6 @@ +# Functional tests + +from: +https://stackoverflow.com/questions/4904096/whats-the-difference-between-unit-functional-acceptance-and-integration-test + +>Functional tests check a particular feature for correctness by comparing the results for a given input against the specification. Functional tests don't concern themselves with intermediate results or side-effects, just the result (they don't care that after doing x, object y has state z). They are written to test part of the specification such as, "calling function Square(x) with the argument of 2 returns 4". diff --git a/tests/helpers/CheckDatabaseJsonValuesTest.php b/tests/functional/helpers/CheckDatabaseJsonValuesTest.php similarity index 96% rename from tests/helpers/CheckDatabaseJsonValuesTest.php rename to tests/functional/helpers/CheckDatabaseJsonValuesTest.php index 56d1e7b94ec..e4941f252f4 100644 --- a/tests/helpers/CheckDatabaseJsonValuesTest.php +++ b/tests/functional/helpers/CheckDatabaseJsonValuesTest.php @@ -1,6 +1,8 @@ + + + +403 Forbidden + + + + + +

Directory access is forbidden.

+ + + + \ No newline at end of file diff --git a/tests/resources/README.md b/tests/resources/README.md new file mode 100644 index 00000000000..23d7ee42c17 --- /dev/null +++ b/tests/resources/README.md @@ -0,0 +1 @@ +# Test resources diff --git a/tests/data/sql/create-mysql.153.sql b/tests/resources/sql/create-mysql.153.sql similarity index 100% rename from tests/data/sql/create-mysql.153.sql rename to tests/resources/sql/create-mysql.153.sql diff --git a/tests/data/sql/create-mysql.258.sql b/tests/resources/sql/create-mysql.258.sql similarity index 100% rename from tests/data/sql/create-mysql.258.sql rename to tests/resources/sql/create-mysql.258.sql diff --git a/tests/data/sql/create-mysql.315.sql b/tests/resources/sql/create-mysql.315.sql similarity index 100% rename from tests/data/sql/create-mysql.315.sql rename to tests/resources/sql/create-mysql.315.sql diff --git a/tests/data/surveys/limesurvey_survey_186734.lss b/tests/resources/surveys/limesurvey_survey_186734.lss similarity index 100% rename from tests/data/surveys/limesurvey_survey_186734.lss rename to tests/resources/surveys/limesurvey_survey_186734.lss diff --git a/tests/data/surveys/limesurvey_survey_352985.lss b/tests/resources/surveys/limesurvey_survey_352985.lss similarity index 100% rename from tests/data/surveys/limesurvey_survey_352985.lss rename to tests/resources/surveys/limesurvey_survey_352985.lss diff --git a/tests/data/surveys/limesurvey_survey_366446.lss b/tests/resources/surveys/limesurvey_survey_366446.lss similarity index 100% rename from tests/data/surveys/limesurvey_survey_366446.lss rename to tests/resources/surveys/limesurvey_survey_366446.lss diff --git a/tests/data/surveys/limesurvey_survey_454287.lss b/tests/resources/surveys/limesurvey_survey_454287.lss similarity index 100% rename from tests/data/surveys/limesurvey_survey_454287.lss rename to tests/resources/surveys/limesurvey_survey_454287.lss diff --git a/tests/data/surveys/limesurvey_survey_563168.lss b/tests/resources/surveys/limesurvey_survey_563168.lss similarity index 100% rename from tests/data/surveys/limesurvey_survey_563168.lss rename to tests/resources/surveys/limesurvey_survey_563168.lss diff --git a/tests/data/surveys/limesurvey_survey_583999.lss b/tests/resources/surveys/limesurvey_survey_583999.lss similarity index 100% rename from tests/data/surveys/limesurvey_survey_583999.lss rename to tests/resources/surveys/limesurvey_survey_583999.lss diff --git a/tests/data/surveys/limesurvey_survey_677328.lss b/tests/resources/surveys/limesurvey_survey_677328.lss similarity index 100% rename from tests/data/surveys/limesurvey_survey_677328.lss rename to tests/resources/surveys/limesurvey_survey_677328.lss diff --git a/tests/data/surveys/limesurvey_survey_834477.lss b/tests/resources/surveys/limesurvey_survey_834477.lss similarity index 100% rename from tests/data/surveys/limesurvey_survey_834477.lss rename to tests/resources/surveys/limesurvey_survey_834477.lss diff --git a/tests/data/surveys/limesurvey_survey_88881.lss b/tests/resources/surveys/limesurvey_survey_88881.lss similarity index 100% rename from tests/data/surveys/limesurvey_survey_88881.lss rename to tests/resources/surveys/limesurvey_survey_88881.lss diff --git a/tests/data/surveys/limesurvey_survey_917744.lss b/tests/resources/surveys/limesurvey_survey_917744.lss similarity index 100% rename from tests/data/surveys/limesurvey_survey_917744.lss rename to tests/resources/surveys/limesurvey_survey_917744.lss diff --git a/tests/data/surveys/limesurvey_survey_975622.lss b/tests/resources/surveys/limesurvey_survey_975622.lss similarity index 100% rename from tests/data/surveys/limesurvey_survey_975622.lss rename to tests/resources/surveys/limesurvey_survey_975622.lss diff --git a/tests/data/travis/travis-ci-apache b/tests/resources/travis/travis-ci-apache similarity index 100% rename from tests/data/travis/travis-ci-apache rename to tests/resources/travis/travis-ci-apache diff --git a/tests/data/travis/travis_setup.sh b/tests/resources/travis/travis_setup.sh similarity index 100% rename from tests/data/travis/travis_setup.sh rename to tests/resources/travis/travis_setup.sh diff --git a/tests/data/views/adminBaseViews.php b/tests/resources/views/adminBaseViews.php similarity index 100% rename from tests/data/views/adminBaseViews.php rename to tests/resources/views/adminBaseViews.php diff --git a/tests/data/views/adminGeneralSettingsViews.php b/tests/resources/views/adminGeneralSettingsViews.php similarity index 100% rename from tests/data/views/adminGeneralSettingsViews.php rename to tests/resources/views/adminGeneralSettingsViews.php diff --git a/tests/data/views/adminParticipantsViews.php b/tests/resources/views/adminParticipantsViews.php similarity index 100% rename from tests/data/views/adminParticipantsViews.php rename to tests/resources/views/adminParticipantsViews.php diff --git a/tests/data/views/adminSettingsViews.php b/tests/resources/views/adminSettingsViews.php similarity index 100% rename from tests/data/views/adminSettingsViews.php rename to tests/resources/views/adminSettingsViews.php diff --git a/tests/data/views/adminSurveyViews.php b/tests/resources/views/adminSurveyViews.php similarity index 100% rename from tests/data/views/adminSurveyViews.php rename to tests/resources/views/adminSurveyViews.php diff --git a/tests/data/views/adminUsersViews.php b/tests/resources/views/adminUsersViews.php similarity index 100% rename from tests/data/views/adminUsersViews.php rename to tests/resources/views/adminUsersViews.php diff --git a/tests/staticCalls.php b/tests/staticCalls.php new file mode 100644 index 00000000000..f4597e7cf92 --- /dev/null +++ b/tests/staticCalls.php @@ -0,0 +1,144 @@ +hasChildren() && !ignore($entry)) { + iterateList($i->getChildren()); + } else { + if (substr($entry, -4, 4) == '.php') { + checkFile($entry); + } + } + } +} + +// Get all static calls in file. +function checkFile($filename) +{ + if ($filename == __FILE__) { + return; + } + $file = file($filename, FILE_IGNORE_NEW_LINES); + $file = array_filter($file, "checkStatic"); + + if (!empty($file)) { + pr($filename); + print_r($file); + } +} + +function checkStatic($line) +{ + $validStatics = array( + 'Yii::', + 'parent::', + 'LimeExpressionManager::', +'Answer::', +'Question::', +'Survey::', +'QuestionGroup::', +'self::', +'PDO::', +'Participants::', +'SurveyLink::', +'ParticipantAttribute::', +'Tokens::', +'UserGroup::', +'Condition::', +'Survey_Common_Action::', +'Quota::', +'SurveyURLParameter::', +'Survey_languagesettings::', +'Permission::', +'SavedControl::', +'QuotaMember::', +'QuotaLanguageSetting::', +'ParticipantAttributeName::', +'User::', +'SurveyLanguageSetting::', +'QuestionAttribute::', +'Assessment::', +'CDbConnection::', +'ParticipantShare::', +'\'{INSERTANS::', +'DefaultValue::', +'CHtml::', +'ExpressionManager::', +'\'::\'', +'LabelSet::', +'SurveyDynamic::', +'PEAR::', +'SettingGlobal::', +'Zend_Http_Client::', +'Zend_XmlRpc_Value::', +'Zend_XmlRpc_Server_Fault::', +'Zend_XmlRpc_Value::', +'Zend_Server_Cache::', +'Zend_XmlRpc_Server_Cache::', +'Label::', +'Assessments::', +'XMLReader::', +'LEM::', +'Question::', +'DateTime::', +'Installer::', +'Session::', +'dataentry::', +'Assessments::', +'Zend_Server_Reflection::', +'Participants::', +'jsonRPCServer::', +'FailedLoginAttempt::', +'survey::', +'tokens::', +'questiongroup::', +'printanswers::', +'imagick::', +':: ', +'Assessments::', +'InstallerConfigForm::', +'Database::', +'UserInGroups::', +'Usergroups::', +'SurveyTimingDynamic::', +'::regClass', +'surveypermission::', +'Template::', +'templates::', +'register::', +'::first', +'::before', +'::after', +'::reg', +'text::', +'httpCache::' + ); + $replacements = array_pad(array(), count($validStatics), ''); + $line = str_replace($validStatics, $replacements, $line); + + return strpos($line, '::') !== false; + +} +function pr($msg) +{ + echo $msg."\n"; +} +?> diff --git a/tests/travis/travis-ci-apache b/tests/travis/travis-ci-apache deleted file mode 100644 index fa2370a815c..00000000000 --- a/tests/travis/travis-ci-apache +++ /dev/null @@ -1,25 +0,0 @@ - - # [...] - - DocumentRoot %TRAVIS_BUILD_DIR% - - - Options FollowSymLinks MultiViews ExecCGI - AllowOverride All - Require all granted - - - # Wire up Apache to use Travis CI's php-fpm. - - AddHandler php7.1-fcgi .php - Action php7.1-fcgi /php7.1-fcgi - Alias /php7.1-fcgi /usr/lib/cgi-bin/php7.1-fcgi - FastCgiExternalServer /usr/lib/cgi-bin/php7.1-fcgi -host 127.0.0.1:9000 -pass-header Authorization - - - Require all granted - - - - # [...] - diff --git a/tests/unit/ExpressionManagerTest.php b/tests/unit/ExpressionManagerTest.php new file mode 100644 index 00000000000..2b0ac1dacee --- /dev/null +++ b/tests/unit/ExpressionManagerTest.php @@ -0,0 +1,894 @@ +em = new ExpressionManager(); + } + +// public function testVariables() +// { +// $vars = array( +// 'one' => array('sgqa'=>'one', 'code'=>1, 'jsName'=>'java_one', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>4), +// 'two' => array('sgqa'=>'two', 'code'=>2, 'jsName'=>'java_two', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>4), +// 'three' => array('sgqa'=>'three', 'code'=>3, 'jsName'=>'java_three', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>4), +// 'four' => array('sgqa'=>'four', 'code'=>4, 'jsName'=>'java_four', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>1), +// 'five' => array('sgqa'=>'five', 'code'=>5, 'jsName'=>'java_five', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>1), +// 'six' => array('sgqa'=>'six', 'code'=>6, 'jsName'=>'java_six', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>1), +// 'seven' => array('sgqa'=>'seven', 'code'=>7, 'jsName'=>'java_seven', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>5), +// 'eight' => array('sgqa'=>'eight', 'code'=>8, 'jsName'=>'java_eight', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>5), +// 'nine' => array('sgqa'=>'nine', 'code'=>9, 'jsName'=>'java_nine', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>5), +// 'ten' => array('sgqa'=>'ten', 'code'=>10, 'jsName'=>'java_ten', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), +// 'half' => array('sgqa'=>'half', 'code'=>.5, 'jsName'=>'java_half', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), +// 'hi' => array('sgqa'=>'hi', 'code'=>'there', 'jsName'=>'java_hi', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), +// 'hello' => array('sgqa'=>'hello', 'code'=>"Tom", 'jsName'=>'java_hello', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), +// 'a' => array('sgqa'=>'a', 'code'=>0, 'jsName'=>'java_a', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), +// 'b' => array('sgqa'=>'b', 'code'=>0, 'jsName'=>'java_b', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), +// 'c' => array('sgqa'=>'c', 'code'=>0, 'jsName'=>'java_c', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), +// 'd' => array('sgqa'=>'d', 'code'=>0, 'jsName'=>'java_d', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), +// 'eleven' => array('sgqa'=>'eleven', 'code'=>11, 'jsName'=>'java_eleven', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), +// 'twelve' => array('sgqa'=>'twelve', 'code'=>12, 'jsName'=>'java_twelve', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), +// // Constants +// 'ASSESSMENT_HEADING' => array('sgqa'=>'ASSESSMENT_HEADING', 'code'=>'"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"', 'jsName'=>'', 'readWrite'=>'N'), +// 'QID' => array('sgqa'=>'QID', 'code'=>'value for {QID}', 'jsName'=>'', 'readWrite'=>'N'), +// 'QUESTIONHELP' => array('sgqa'=>'QUESTIONHELP', 'code'=>'"can single quoted strings" . \'contain nested \'quoted sections\'?', 'jsName'=>'', 'readWrite'=>'N'), +// 'QUESTION_HELP' => array('sgqa'=>'QUESTION_HELP', 'code'=>'Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and <?', 'jsName'=>'', 'readWrite'=>'N'), +// 'NUMBEROFQUESTIONS' => array('sgqa'=>'NUMBEROFQUESTIONS', 'code'=>'value for {NUMBEROFQUESTIONS}', 'jsName'=>'', 'readWrite'=>'N'), +// 'THEREAREXQUESTIONS' => array('sgqa'=>'THEREAREXQUESTIONS', 'code'=>'value for {THEREAREXQUESTIONS}', 'jsName'=>'', 'readWrite'=>'N'), +// 'TOKEN:FIRSTNAME' => array('sgqa'=>'TOKEN:FIRSTNAME', 'code' => 'value for {TOKEN:FIRSTNAME}', 'jsName' => '', 'readWrite' => 'N'), +// 'WELCOME' => array('sgqa'=>'WELCOME', 'code'=>'value for {WELCOME}', 'jsName'=>'', 'readWrite'=>'N'), +// // also include SGQA values and read-only variable attributes +// '12X34X56' => array('sgqa'=>'12X34X56', 'code'=>5, 'jsName'=>'', 'readWrite'=>'N', 'gseq'=>1,'qseq'=>1), +// '12X3X5lab1_ber' => array('sgqa'=>'12X3X5lab1_ber', 'code'=>10, 'jsName'=>'', 'readWrite'=>'N', 'gseq'=>1,'qseq'=>1), +// 'q5pointChoice' => array('sgqa'=>'q5pointChoice', 'code'=> 3, 'jsName'=>'java_q5pointChoice', 'readWrite'=>'N','shown'=>'Father', 'relevance'=>1, 'type'=>'5', 'question'=>'(question for q5pointChoice)', 'qid'=>14,'gseq'=>2,'qseq'=>14), +// 'qArrayNumbers_ls1_min' => array('sgqa'=>'qArrayNumbers_ls1_min', 'code'=> 7, 'jsName'=>'java_qArrayNumbers_ls1_min', 'readWrite'=>'N','shown'=> 'I love LimeSurvey', 'relevance'=>1, 'type'=>'A', 'question'=>'(question for qArrayNumbers)', 'qid'=>6,'gseq'=>2,'qseq'=>6), +// '12X3X5lab1_ber#1' => array('sgqa'=>'12X3X5lab1_ber#1', 'code'=> 15, 'jsName'=>'', 'readWrite'=>'N', 'gseq'=>1,'qseq'=>1), +// 'zero' => array('sgqa'=>'zero', 'code'=>0, 'jsName'=>'java_zero', 'gseq'=>0,'qseq'=>0), +// 'empty' => array('sgqa'=>'empty', 'code'=>'', 'jsName'=>'java_empty', 'gseq'=>0,'qseq'=>0), +// 'BREAKS' => array('sgqa'=>'BREAKS', 'code'=>"1\n2\n3", 'jsName'=>'', 'readWrite'=>'N'), +// ); +// $this->lem->setTempVars($vars); +// +// foreach ($vars as $var => $attributes) +// { +// foreach ($attributes as $key => $val) +// { +// $this->assertEquals($val, $this->lem->GetVarAttribute($var, $key, null, 0, 0), "Failed GetVarAttribute: $var.$key"); +// } +// } +// +// } +// + public function testEvaluator() + { + $booleanExpressions = array( + "1" => true, + "0" => false, + "" => false, + "1 == 1" => true, + "0 == 1" => false, + "1 && 0" => false, + "1 && 1" => true, + "1 || 0" => true, + "0 || 0" => false, + ); + + foreach ($booleanExpressions as $expr => $expected) { + $this->assertEquals($expected, $this->em->ProcessBooleanExpression($expr), "Expression: '$expr'"); + } + } + + public function testFunctions() + { + $functions = array( + 'abs(5)' => 5, + 'abs(-5)' => 5, + 'abs(0)' => 0, + 'acos(0.5)' => acos(0.5), + 'acos(0.1)' => acos(0.1), + + ); + foreach ($functions as $function => $expected) { + $this->assertEquals($expected, $this->em->sProcessStringContainingExpressions('{'.$function.'}')); + } + } + + public function testEscapes() + { + $strings = array( + '\{1+1}' => '{1+1}', + 'x{1+1}' => 'x2', + 'x{1+1\}' => 'x{1+1}', + ); + foreach ($strings as $escaped => $expected) { + $this->assertEquals($expected, $this->em->sProcessStringContainingExpressions($escaped)); + } + } + + public function testJuggling() + { + $equalities = array( + '"1" == 1' => 1, + '"5" + "2"' => 7, + '"1" == 0' => '', // False is an empty string. + '1 == "1"' => 1, + '1 + "2"' => 3, + '"1" + "a"' => '1a', + '1 + "a"' => '1a', + '"05" + "1"' => 6, + '"" + "1" + "2"' => 12 + ); + foreach ($equalities as $expression => $expected) { + $result = $this->em->sProcessStringContainingExpressions('{'.$expression.'}'); + $this->assertEquals($expected, $result); + } + } + public function oldTestEvaluator() + { + + + // Syntax for $tests is + // expectedResult~expression + // if the expected result is an error, use NULL for the expected result + $tests = <<Empty Vs. Empty~"Empty Vs. Empty" +1~'' == '' +0~'' != '' +0~'' > '' +1~'' >= '' +0~'' < '' +1~'' <= '' +1~!'' +~('' and '') +~('' or '') +Empty Vs. Zero~"Empty Vs. Zero" +0~'' == 0 +1~'' != 0 +0~'' > 0 +0~'' >= 0 +0~'' < 0 +0~'' <= 0 +1~!'' +1~!0 +0~('' and 0) +0~('' or 0) +Empty Vs. Constant~"Empty Vs. Constant" +0~'' == 3 +1~'' != 3 +0~'' > 3 +0~'' >= 3 +0~'' < 3 +0~'' <= 3 +1~!'' +0~!3 +0~('' and 3) +1~('' or 3) +Empty Vs. Empty_Var~"Empty Vs. Empty_Var" +1~'' == empty +0~'' != empty +0~'' > empty +1~'' >= empty +0~'' < empty +1~'' <= empty +1~!'' +1~!empty +~('' and empty) +~('' or empty) +Empty_Var Vs. Zero~"Empty_Var Vs. Zero" +0~empty == 0 +1~empty != 0 +0~empty > 0 +0~empty >= 0 +0~empty < 0 +0~empty <= 0 +1~!empty +1~!0 +0~(empty and 0) +0~(empty or 0) +Empty_Var Vs. Zero~"Empty_Var Vs. Zero" +0~empty == zero +1~empty != zero +0~empty > zero +0~empty >= zero +0~empty < zero +0~empty <= zero +1~!empty +1~!zero +0~(empty and zero) +0~(empty or zero) +Empty_Var Vs. Constant~"Empty_Var Vs. Constant" +0~empty == 3 +1~empty != 3 +0~empty > 3 +0~empty >= 3 +0~empty < 3 +0~empty <= 3 +1~!empty +0~!3 +0~(empty and 3) +1~(empty or 3) +Solution: Empty_Var Vs. Zero~"Solution: Empty_Var Vs. Zero" +0~!is_empty(empty) && (empty == 0) +0~!is_empty(five) && (five == 0) +1~!is_empty(zero) && (zero == 0) +0~!is_empty(empty) && (empty > 0) +0~!is_empty(empty) && (empty >= 0) +0~!is_empty(empty) && (empty < 0) +0~!is_empty(empty) && (empty <= 0) +0~!is_empty(empty) && ((empty and 0)) +0~!is_empty(empty) && ((empty or 0)) +Solution: Empty_Var Vs. Zero~"Solution: Empty_Var Vs. Zero" +0~!is_empty(empty) && (empty == zero) +0~!is_empty(five) && (five == zero) +1~!is_empty(zero) && (zero == zero) +0~!is_empty(empty) && (empty > zero) +0~!is_empty(empty) && (empty >= zero) +0~!is_empty(empty) && (empty < zero) +0~!is_empty(empty) && (empty <= zero) +0~!is_empty(empty) && ((empty and zero)) +0~!is_empty(empty) && ((empty or zero)) +Solution: Empty_Var Vs. Constant~"Solution: Empty_Var Vs. Constant" +0~!is_empty(empty) && (empty < 3) +0~!is_empty(empty) && (empty <= 3) +Solution: Empty_Var Vs. Variable~"Solution: Empty_Var Vs. Variable" +0~!is_empty(empty) && (empty < five) +0~!is_empty(empty) && (empty <= five) +Solution: The Hard One is Empty_Var != 0~"Solution: The Hard One is Empty_Var != 0" +1~(empty != 0) +1~!is_empty(empty) && (empty != 0) +1~is_empty(empty) || (empty != 0) +1~is_empty(empty) || (empty != zero) +0~is_empty(zero) || (zero != 0) +1~is_empty(five) || (five != 0) +SETUP~'SETUP' +"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~a=htmlspecialchars(ASSESSMENT_HEADING) +"can single quoted strings" . 'contain nested 'quoted sections'?~b=htmlspecialchars(QUESTIONHELP) +Can strings have embedded <tags> like <html>, or even unbalanced "quotes or entities without terminal semicolons like &amp and &lt?~c=htmlspecialchars(QUESTION_HELP) +Hi there!~d='Hi there!' +FUNCTIONS~'FUNCTIONS' +5~abs(five) +5~abs(-five) +0.2~acos(cos(0.2)) +0~acos(cos(pi()))-pi() +"Can strings contain embedded \\"quoted passages\\" (and parentheses + other characters?)?"~addslashes(a) +"can single quoted strings" . 'contain nested 'quoted sections'?~addslashes(b) +Can strings have embedded <tags> like <html>, or even unbalanced "quotes or entities without terminal semicolons like &amp and &lt?~addslashes(c) +0.2~asin(sin(0.2)) +0.2~atan(tan(0.2)) +0~atan2(0,1) +1~ceil(0.3) +1~ceil(0.7) +0~ceil(-0.3) +0~ceil(-0.7) +10~ceil(9.1) +1~checkdate(1,29,1967) +0~checkdate(2,29,1967) +0.2~cos(acos(0.2)) +5~count(1,2,3,4,5) +0~count() +5~count(one,two,three,four,five) +2~count(a,'',c) +NULL~date('F j, Y, g:i a',time()) +April 5, 2006, 1:02 am~date('F j, Y, g:i a',mktime(1,2,3,4,5,6)) +20~floor(exp(3)) +0~floor(asin(sin(pi()))) +9~floor(9.9) +3~floor(pi()) +January 12, 2012, 5:27 pm~date('F j, Y, g:i a',1326410867) +January 12, 2012, 11:27 pm~gmdate('F j, Y, g:i a',1326410867) +"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~html_entity_decode(a) +"can single quoted strings" . 'contain nested 'quoted sections'?~html_entity_decode(b) +Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and <?~html_entity_decode(c) +"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~htmlentities(a) +"can single quoted strings" . 'contain nested 'quoted sections'?~htmlentities(b) +Can strings have embedded <tags> like <html>, or even unbalanced "quotes or entities without terminal semicolons like &amp and &lt?~htmlentities(c) +1~c==htmlspecialchars(htmlspecialchars_decode(c)) +1~b==htmlspecialchars(htmlspecialchars_decode(b)) +1~a==htmlspecialchars(htmlspecialchars_decode(a)) +"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~htmlspecialchars_decode(a) +"can single quoted strings" . 'contain nested 'quoted sections'?~htmlspecialchars_decode(b) +Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and like , or even unbalanced "quotes or entities without terminal semicolons like & and <?~htmlspecialchars(c) +9~idate('B',1326410867) +0~if('0',1,0) +0~if(0,1,0) +1~if(!0,1,0) +0~if(!(!0),1,0) +1~if('true',1,0) +1~if('false',1,0) +1~if('00',1,0) +0~if('',1,0) +1~if('A',1,0) +0~if(empty,1,0) +4~if(5 > 7,2,4) +1~if(' ',1,0) +there~if((one > two),'hi','there') +64~if((one < two),pow(2,6),pow(6,2)) +H e l l o~implode(' ','H','e','l','l','o') +1|2|3|4|5~implode('|',one,two,three,four,five) +123~join(1,2,3) +123 5~join(one,2,three," ",five) +4~intval('4') +4~intval('100',2) +5~intval(5.7) +0~is_empty(four) +1~is_empty(empty) +1~is_empty('') +0~is_empty(0) +0~is_empty('0') +0~is_empty('false') +0~is_empty('NULL') +0~is_empty(1) +1~is_empty(one==two) +0~!is_empty(one==two) +1~is_float(half) +0~is_float(one) +1~is_float(pi()) +0~is_float(5) +0~is_int(half) +1~is_int(one) +0~is_nan(half) +1~is_nan(WELCOME) +1~is_null(sdfjskdfj) +0~is_null(four) +0~is_numeric(empty) +1~is_numeric('1') +1~is_numeric(four) +0~is_numeric('hi') +1~is_numeric(five) +0~is_numeric(hi) +0~is_string(four) +1~is_string('hi') +1~is_string(hi) +1, 2, 3, 4, 5~list(one,two,three,min(four,five,six),max(three,four,five)) +11, 12~list(eleven,twelve) +0, 1, 3, 5~list(0,one,'',three,'',five) +1~log(exp(1)) +2~log(exp(2)) +I was trimmed ~ltrim(' I was trimmed ') +10~max(5,6,10,-20) +6~max(five,(one + (two * four)- three)) +6~max((one + (two * four)- three)) +212~5 + max(1,(2+3),(4 + (5 + 6)),((7 + 8) + 9),((10 + 11), 12),(13 + (14 * 15) - 16)) +29~five + max(one, (two + three), (four + (five + six)),((seven + eight) + nine),((ten + eleven), twelve),(one + (two * three) - four)) +1024~max(one,(two*three),pow(four,five),six) +2~max(one,two) +5~max(one,two,three,four,five) +-5~min(-5,10,15,12,-3) +1~min(five,four,one,two,three) +1344765967~mktime(5,6,7,8) +1144191723~mktime(1,2,3,4,5,6) +1,000~number_format(1000) +1,000.23~number_format(1000.23) +1,234,567~number_format(1234567) +315~ceil(100*pi()) +1~pi() == pi() * 2 - pi() +4~pow(2,2) +27~pow(3,3) +=~quoted_printable_decode(quoted_printable_encode('=')) +\\$~quotemeta('$') +IGNORE THIS ERROR~rand(3,5) +0~(a=rand())-a +1~regexMatch('/embedded/',c) +1~regexMatch('/^.*embedded.*$/',c) +0~regexMatch('/joe/',c) +1~regexMatch('/(?:dog|cat)food/','catfood stinks') +1~regexMatch('/(?:dog|cat)food/','catfood stinks') +1~regexMatch('/[0-9]{3}-[0-9]{2}-[0-9]{4}/','123-45-6789') +1~regexMatch('/\d{3}-\d{2}-\d{4}/','123-45-6789') +1~regexMatch('/(?:\(\d{3}\))\s*\d{3}-\d{4}/','(212) 555-1212') +0~round(0.2) +1~round(.8) +0.07~0.01 + 0.06 +0.07~round(0.01 + 0.06,10) + I was trimmed~rtrim(' I was trimmed ') +0.2~sin(asin(0.2)) +1~sin(pi()/2) +1~sin(pi()/2) == sin(.5 * pi()) +1~sin(0.5 * pi()) +hello,5~sprintf('%s,%d','hello',5) +2~sqrt(4) +158~round(stddev(4,5,6,7,8)*100) +hello-----~str_pad('hello',10,'-') +hello ~str_pad('hello',10) +hello~str_pad('hello',3) +testtesttest~str_repeat('test',3) +I am awesome~str_replace('You are','I am','You are awesome') +I love LimeSurvey~str_replace('like','love','I like LimeSurvey') +1~0==strcasecmp('Hello','hello') +0~0==strcasecmp('Hello','hi') +1~0==strcmp('Hello','Hello') +0~0==strcmp('Hello','hi') +Hi there!~c=strip_tags(d) +hello~strip_tags('hello') +5~stripos('ABCDEFGHI','f') +hi~stripslashes('\\h\\i') +FGHI~stristr('ABCDEFGHI','fg') +5~strlen('12345') +5~strlen(hi) +0~strpos('ABCDEFGHI','f') +5~strpos('ABCDEFGHI','F') +2~strpos('I like LimeSurvey','like') +54321~strrev('12345') +0~strstr('ABCDEFGHI','fg') +FGHI~strstr('ABCDEFGHI','FG') +hi there!~strtolower(c) +HI THERE!~strtoupper(c) +3600~strtotime("27 Mar 1976 8:20")-strtotime("1976/03/27 7:20") +10~(strtotime("13 Apr 2013")-strtotime("2013-04-03"))/60/60/24 +1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("05 Nov 1985")) +HOURS PASSED SINCE 1970~round(strtotime("now")/60/60) +~"" +1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("11/5/85")) +2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("8/9/10")) +2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("8/9/2010")) +2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("2010/8/9")) +~"" +1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("85-11-5")) +2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("10-8-9")) +2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("9-8-2010")) +2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("2010-8-9")) +~"" +1985-11-05 00:53:20~date("Y-m-d H:i:s",strtotime("85-11-5 0:53:20")) +2010-08-09 00:53:20~date("Y-m-d H:i:s",strtotime("10-8-9 0:53:20")) +2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("9-8-2010 11:12:13")) +2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("2010-8-9 11:12:13")) +~"" +Today 11:11:59~date("Y-m-d H:i:s",strtotime("11.11.59")) +Today 9:08:10~date("Y-m-d H:i:s",strtotime("9.8.10")) +2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("9.8.2010")) +~"" +1985-11-05 00:53:20~date("Y-m-d H:i:s",strtotime("5.11.85 0:53:20")) +2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("9.8.2010 11:12:13")) +~"" +1970-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("70-01-01")) +1999-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("99-01-01")) +2001-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("01-01-01")) +1902-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("1902-01-01")) +~"" +today 2:15:00~date("Y-m-d H:i:s",strtotime("2:15:00")) +Some dates that are not (correctly) parsed:~"Some dates that are not (correctly) parsed:" +1969-01-19 00:00:00~date("Y-m-d H:i:s",strtotime("69-01-19")) +1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("85/11/5")) +1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("5-11-85")) +2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("2010.8.9")) +1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("85.11.5")) +1985-11-05 00:53:20~date("Y-m-d H:i:s",strtotime("85.11.5 0:53:20")) +2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("9.8.10 11:12:13")) +678~substr('1234567890',5,3) +15~sum(1,2,3,4,5) +15~sum(one,two,three,four,five) +0.2~tan(atan(0.2)) +IGNORE THIS ERROR~time() +I was trimmed~trim(' I was trimmed ') +Hi There You~ucwords('hi there you') +EXPRESSIONS~'EXPRESSIONS' +1~!'0' +1~0 eq '0' +0~0 ne '0' +0~0 eq empty +1~0 ne empty +0~0 eq '' +1~0 ne '' +0~'' < 10 +0~0 < empty +1~0 <= empty +0~0 > empty +1~0 >= empty +0~'0' eq empty +1~'0' ne empty +0~'0' < empty +1~'0' <= empty +0~'0' > empty +1~'0' >= empty +1~empty eq empty +0~empty ne empty +0~'' > 0 +0~' ' > 0 +1~!0 +0~!' ' +0~!'A' +0~!1 +0~!'1' +1~!'' +1~!empty +1~'0'==0 +0~'A'>0 +0~'A'<0 +0~'A'==0 +0~'A'>=0 +0~'A'<=0 +0~0>'A' +0~0>='B' +0~0=='C' +0~0<'D' +0~0<='E' +1~0!='F' +1~'A' or 'B' +1~'A' and 'B' +0~'A' eq 'B' +1~'A' ne 'B' +1~'A' < 'B' +1~'A' <= 'B' +0~'A' > 'B' +0~'A' >= 'B' +AB~'A' + 'B' +NAN~'A' - 'B' +NAN~'A' * 'B' +NAN~'A' / 'B' +1~'A' or empty +0~'A' and empty +0~'A' eq empty +1~'A' ne empty +0~'A' < empty +0~'A' <= empty +1~'A' > empty +1~'A' >= empty +A~'A' + empty +NAN~'A' - empty +NAN~'A' * empty +NAN~'A' / empty +0~0 or empty +0~0 and empty +0~0 + empty +0~0 - empty +0~0 * empty +NAN~0 / empty +0~(-1 > 0) +0~zero +~empty +1~five > zero +1~five > empty +1~empty < 16 +1~zero == empty +3~q5pointChoice.code +5~q5pointChoice.type +(question for q5pointChoice)~q5pointChoice.question +1~q5pointChoice.relevance +4~q5pointChoice.NAOK + 1 +NULL~q5pointChoice.bogus +14~q5pointChoice.qid +7~qArrayNumbers_ls1_min.code +1~(one * (two + (three - four) + five) / six) +2.4~(one * two) + (three * four) / (five * six) +50~12X34X56 * 12X3X5lab1_ber +1~c == 'Hi there!' +1~c == "Hi there!" +3~a=three +3~c=a +12~c*=four +15~c+=a +5~c/=a +-1~c-=six +24~one * two * three * four +-4~five - four - three - two +0~two * three - two - two - two +4~two * three - two +105~5 + 1, 7 * 15 +7~7 +15~10 + 5 +24~12 * 2 +10~13 - 3 +3.5~14 / 4 +5~3 + 1 * 2 +1~one +there~hi +6.25~one * two - three / four + five +1~one + hi +1~two > one +1~two gt one +1~three >= two +1~three ge two +0~four < three +0~four lt three +0~four <= three +0~four le three +0~four == three +0~four eq three +1~four != three +0~four ne four +NAN~one * hi +0~a='hello',b='',c=0 +hello~a +0~c +0~one && 0 +0~two and 0 +1~five && 6 +1~seven && eight +1~one or 0 +1~one || 0 +1~(one and 0) || (two and three) +value for {QID}~QID +"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~ASSESSMENT_HEADING +"can single quoted strings" . 'contain nested 'quoted sections'?~QUESTIONHELP +Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and <?~QUESTION_HELP +value for {TOKEN:FIRSTNAME}~TOKEN:FIRSTNAME +value for {THEREAREXQUESTIONS}~THEREAREXQUESTIONS +15~12X3X5lab1_ber#1 +1~three == three +1~three == 3 +11~eleven +144~twelve * twelve +0~!three +8~five + + three +2~five + - three +SYNTAX ERRORS~'SYNTAX ERRORS' +NULL~* +NULL~three + +NULL~four * / seven +NULL~(five - three +NULL~five + three) +NULL~seven + = four +NULL~> +NULL~five > > three +NULL~seven > = four +NULL~seven >= +NULL~three && +NULL~three || +NULL~three + +NULL~three >= +NULL~three += +NULL~three ! +NULL~three * +NULL~five ! three +NULL~(5 + 7) = 8 +NULL~&& four +NULL~min( +NULL~max three, four, five) +NULL~three four +NULL~max(three,four,five) six +NULL~WELCOME='Good morning' +NULL~TOKEN:FIRSTNAME='Tom' +NULL~NUMBEROFQUESTIONS+=3 +NULL~NUMBEROFQUESTIONS*=4 +NULL~NUMBEROFQUESTIONS/=5 +NULL~NUMBEROFQUESTIONS-=6 +NULL~'Tom'='tired' +NULL~max() +NULL~convert_value( 10, 1, '0,5,10,15,20', '0,5,10,15') +100~convert_value( 10, 1, '0,5,10,15,20', '0,50,100,150,200') +NULL~convert_value( 10, 0, '0,5,10,15,20', '0,50,100,150,200') +100~convert_value( 8, 0, '0,5,10,15,20', '0,50,100,150,200') +100~convert_value( 12, 0, '0,5,10,15,20', '0,50,100,150,200') +0~convert_value( 0, 0, '0,5,10,15,20', '0,50,100,150,200') +0~convert_value( -10000, 0, '0,5,10,15,20', '0,50,100,150,200') +NULL~convert_value( -10000, 1, '0,5,10,15,20', '0,50,100,150,200') +200~convert_value( 20, 0, '0,5,10,15,20', '0,50,100,150,200') +200~convert_value( 20, 1, '0,5,10,15,20', '0,50,100,150,200') +200~convert_value( 30, 0, '0,5,10,15,20', '0,50,100,150,200') +NULL~convert_value( 30, 1, '0,5,10,15,20', '0,50,100,150,200') +EOD; + + $atests = explode("\n", $tests); + $atests[] = "1\n2\n3~BREAKS"; + $atests[] = "1
\n2
\n3~nl2br(BREAKS)"; + $atests[] = "hi
\nthere
\nhow
\nare
\nyou?~nl2br('hi\\nthere\\nhow\\nare\\nyou?')"; + $atests[] = "hi
\nthere,
\nuser!~nl2br(implode('\\n','hi','there,','user!'))"; + + $LEM = & LimeExpressionManager::singleton(); + $em = new ExpressionManager(); + $LEM->setTempVars($vars); + + //$LEMsessid = 'survey_' . Yii::app()->getConfig('surveyID'); + $LEMsessid = 'survey_12345'; + // manually set relevance status + $_SESSION[$LEMsessid]['relevanceStatus'] = array(); + foreach ($vars as $var) { + if (isset($var['qseq'])) { + $_SESSION[$LEMsessid]['relevanceStatus'][$var['qseq']] = 1; + } + } + + $allJsVarnamesUsed = array(); + $body = ''; + $body .= ''; + $i = 0; + $javaScript = array(); + foreach ($atests as $test) { + ++$i; + $values = explode("~", $test); + $expectedResult = array_shift($values); + $expr = implode("~", $values); + $resultStatus = 'ok'; + $em->groupSeq = 2; + $em->questionSeq = 3; + $status = $em->RDP_Evaluate($expr); + if ($status) { + $allJsVarnamesUsed = array_merge($allJsVarnamesUsed, $em->GetJsVarsUsed()); + } + $result = $em->GetResult(); + $valToShow = $result; // htmlspecialchars($result,ENT_QUOTES,'UTF-8',false); + $expectedToShow = $expectedResult; // htmlspecialchars($expectedResult,ENT_QUOTES,'UTF-8',false); + $body .= ""; + $body .= "\n"; + if (is_null($result)) { + $valToShow = "NULL"; + } + if ($valToShow != $expectedToShow) { + $resultStatus = 'error'; + } + $body .= "\n"; + $body .= '\n"; + $javaScript[] = $em->GetJavascriptTestforExpression($expectedToShow, $i); + $body .= "\n"; + $varsUsed = $em->GetVarsUsed(); + if (is_array($varsUsed) and count($varsUsed) > 0) { + $varDesc = array(); + foreach ($varsUsed as $v) { + $varDesc[] = $v; + } + $body .= '\n"; + } else { + $body .= "\n"; + } + $jsEqn = $em->GetJavaScriptEquivalentOfExpression(); + if ($jsEqn == '') { + $body .= "\n"; + } else { + $body .= '\n"; + } + $body .= ''; + } + $body .= '
ExpressionPHP ResultExpectedJavaScript ResultVarNamesJavaScript Eqn
".$em->GetPrettyPrintString()."".$valToShow."'.$expectedToShow." '.implode(',
', $varDesc)."
  '.$jsEqn."
'; + $body .= "\n"; + + $allJsVarnamesUsed = array_unique($allJsVarnamesUsed); + asort($allJsVarnamesUsed); + $pre = ''; + $pre .= "

Change some Relevance values to 0 to see how it affects computations

\n"; + $pre .= ''; + $i = 0; + $LEMvarNameAttr = array(); + $LEMalias2varName = array(); + foreach ($allJsVarnamesUsed as $jsVarName) { + ++$i; + $pre .= "\n"; + $LEMalias2varName[] = "'".substr($jsVarName, 5)."':'".$jsVarName."'"; + $LEMalias2varName[] = "'".$jsVarName."':'".$jsVarName."'"; + $attrInfo = "'".$jsVarName."': {'jsName':'".$jsVarName."'"; + + $varInfo = $vars[substr($jsVarName, 5)]; + foreach ($varInfo as $k=>$v) { + if ($k == 'code') { + continue; // will access it from hidden node + } + if ($k == 'shown') { + $k = 'shown'; + $v = htmlspecialchars(preg_replace("/[[:space:]]/", ' ', $v), ENT_QUOTES); + } + if ($k == 'jsName') { + continue; // since already set + } + $attrInfo .= ", '".$k."':'".$v."'"; + + } + $attrInfo .= ",'qid':".$i."}"; + $LEMvarNameAttr[] = $attrInfo; + } + $pre .= "
#JsVarnameStarting ValueRelevance
".$i."".$jsVarName; + foreach ($vars as $k => $v) { + if ($v['jsName'] == $jsVarName) { + $value = $v['code']; + } + } + $pre .= "".$value."\n"; + $pre .= "\n"; + $pre .= "
\n"; + + $pre .= "\n"; + + print $pre; + print $body; + + } + + + /** + * Unit test the asSplitStringOnExpressions() function to ensure that accurately parses out all expressions + * surrounded by curly braces, allowing for strings and escaped curly braces. + */ + + public function oldStringSplitter() + { + $tests = << INSERT61764X1X4),'children','pets')} than you do {if((INSERT61764X1X3 > INSERT61764X1X4),'pets','children')}, do you feel that the {if((INSERT61764X1X3 > INSERT61764X1X4),'pets','children')} are at a disadvantage? +Here is a String that failed to parse prior to fixing the preg_split() command to avoid recursive search of sub-strings: [{((617167X9X3241 == "Y" or 617167X9X3242 == "Y" or 617167X9X3243 == "Y" or 617167X9X3244 == "Y" or 617167X9X3245 == "Y" or 617167X9X3246 == "Y" or 617167X9X3247 == "Y" or 617167X9X3248 == "Y" or 617167X9X3249 == "Y") and (617167X9X3301 == "Y" or 617167X9X3302 == "Y" or 617167X9X3303 == "Y" or 617167X9X3304 == "Y" or 617167X9X3305 == "Y" or 617167X9X3306 == "Y" or 617167X9X3307 == "Y" or 617167X9X3308 == "Y" or 617167X9X3309 == "Y"))}] Here is the question. +EOD; +// Here is a String that failed to parse prior to fixing the preg_split() command to avoid recursive search of sub-strings: [{((617167X9X3241 == "Y" or 617167X9X3242 == "Y" or 617167X9X3243 == "Y" or 617167X9X3244 == "Y" or 617167X9X3245 == "Y" or 617167X9X3246 == "Y" or 617167X9X3247 == "Y" or 617167X9X3248 == "Y" or 617167X9X3249 == "Y") and (617167X9X3301 == "Y" or 617167X9X3302 == "Y" or 617167X9X3303 == "Y" or 617167X9X3304 == "Y" or 617167X9X3305 == "Y" or 617167X9X3306 == "Y" or 617167X9X3307 == "Y" or 617167X9X3308 == "Y" or 617167X9X3309 == "Y"))}] Here is the question. + + $em = new ExpressionManager(); + + $atests = explode("\n", $tests); + array_push($atests, '"hi\nthere\nhow\nare\nyou?\n"'); + + foreach ($atests as $test) { + $tokens = $em->asSplitStringOnExpressions($test); + print ''.$test.'
'; + print ''; + print implode("
\n", explode("\n", print_r($tokens, true))); + print '

'; + } + } + + /** + * Unit test the Tokenizer - Tokenize and generate a HTML-compatible print-out of a comprehensive set of test cases + */ + + public function oldTokenizer() + { + // Comprehensive test cases for tokenizing + $tests = << >= < <= == != gt ge lt le eq ne (target large gents built agile less equal) + Assign: = += -= *= /= + SGQA: 1X6X12 1X6X12ber1 1X6X12ber1_lab1 3583X84X249 12X3X5lab1_ber#1 1X6X12.NAOK 1X6X12ber1.NAOK 1X6X12ber1_lab1.NAOK 3583X84X249.NAOK 12X3X5lab1_ber#1.NAOK + Errors: Apt # 10C; (2 > 0) ? 'hi' : 'there'; array[30]; >>> <<< /* this is not a comment */ // neither is this + Words: q5pointChoice q5pointChoice.bogus q5pointChoice.code q5pointChoice.mandatory q5pointChoice.NAOK q5pointChoice.qid q5pointChoice.question q5pointChoice.relevance q5pointChoice.shown q5pointChoice.type +EOD; + + $em = new ExpressionManager(); + + foreach (explode("\n", $tests) as $test) { + $tokens = array(); //$em->RDP_Tokenize($test); + print ''.$test.'
'; + print ''; + print implode("
\n", explode("\n", print_r($tokens, true))); + print '

'; + } + } + } + +?> diff --git a/tests/unit/README.md b/tests/unit/README.md new file mode 100644 index 00000000000..ff60f5fa178 --- /dev/null +++ b/tests/unit/README.md @@ -0,0 +1,11 @@ +# Unit tests +from: +https://stackoverflow.com/questions/4904096/whats-the-difference-between-unit-functional-acceptance-and-integration-test + > Unit tests should be focussed on one particular feature (e.g., calling the pop method when the stack is empty should throw an InvalidOperationException). Everything it touches should be done in memory; this means that the test code and the code under test shouldn't: + >- Call out into (non-trivial) collaborators + >- Access the network + >- Hit a database + >- Use the file system + >- Spin up a thread + > + >Any kind of dependency that is slow / hard to understand / initialise / manipulate should be stubbed/mocked/whatevered using the appropriate techniques so you can focus on what the unit of code is doing, not what its dependencies do. From c1953c0015a8949552c6129d13d021cf046c8514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Wed, 10 Jan 2018 15:39:23 +0200 Subject: [PATCH 02/20] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fe919e118ba..9beaadb02e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,7 +43,7 @@ before_script: - sudo sed -i -e "s,www-data,travis,g" /etc/apache2/envvars - sudo chown -R travis:travis /var/lib/apache2/fastcgi - ~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm - - sudo cp -f tests/travis/travis-ci-apache /etc/apache2/sites-available/000-default.conf + - sudo cp -f tests/resources/travis/travis-ci-apache /etc/apache2/sites-available/000-default.conf - sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/000-default.conf - sudo service apache2 restart From 268071f76fdb80a2f32fe9367a7b93798f989816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Wed, 10 Jan 2018 16:18:19 +0200 Subject: [PATCH 03/20] don't ignore travis --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8dd96ca468c..ab67056388b 100644 --- a/.gitignore +++ b/.gitignore @@ -109,6 +109,7 @@ third_party/composer/installed\.json !.eslintignore !.eslint.json !.eslintrc.json +!.travis.yml ## ignore Vagrantfile Vagrantfile From a5bd60d7e4ee848353181f95a8e2627af0f87be5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Wed, 10 Jan 2018 16:34:25 +0200 Subject: [PATCH 04/20] ADD suites! --- phpunit.xml | 18 ++++++------------ tests/unit/ExpressionManagerTest.php | 5 ++++- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 94633b631b0..91c99e93aa8 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,19 +1,13 @@ - - tests/questions + + tests/acceptance - - tests/helpers + + tests/functional - - tests/models - - - tests/controllers - - - tests/surveys + + tests/unit diff --git a/tests/unit/ExpressionManagerTest.php b/tests/unit/ExpressionManagerTest.php index 2b0ac1dacee..3c20827cfd0 100644 --- a/tests/unit/ExpressionManagerTest.php +++ b/tests/unit/ExpressionManagerTest.php @@ -1,5 +1,8 @@ Date: Thu, 11 Jan 2018 09:26:29 +0200 Subject: [PATCH 05/20] update tests --- tests/unit/ExpressionManagerTest.php | 897 --------------------------- 1 file changed, 897 deletions(-) delete mode 100644 tests/unit/ExpressionManagerTest.php diff --git a/tests/unit/ExpressionManagerTest.php b/tests/unit/ExpressionManagerTest.php deleted file mode 100644 index 3c20827cfd0..00000000000 --- a/tests/unit/ExpressionManagerTest.php +++ /dev/null @@ -1,897 +0,0 @@ -em = new ExpressionManager(); - } - -// public function testVariables() -// { -// $vars = array( -// 'one' => array('sgqa'=>'one', 'code'=>1, 'jsName'=>'java_one', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>4), -// 'two' => array('sgqa'=>'two', 'code'=>2, 'jsName'=>'java_two', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>4), -// 'three' => array('sgqa'=>'three', 'code'=>3, 'jsName'=>'java_three', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>4), -// 'four' => array('sgqa'=>'four', 'code'=>4, 'jsName'=>'java_four', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>1), -// 'five' => array('sgqa'=>'five', 'code'=>5, 'jsName'=>'java_five', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>1), -// 'six' => array('sgqa'=>'six', 'code'=>6, 'jsName'=>'java_six', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>1), -// 'seven' => array('sgqa'=>'seven', 'code'=>7, 'jsName'=>'java_seven', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>5), -// 'eight' => array('sgqa'=>'eight', 'code'=>8, 'jsName'=>'java_eight', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>5), -// 'nine' => array('sgqa'=>'nine', 'code'=>9, 'jsName'=>'java_nine', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>5), -// 'ten' => array('sgqa'=>'ten', 'code'=>10, 'jsName'=>'java_ten', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), -// 'half' => array('sgqa'=>'half', 'code'=>.5, 'jsName'=>'java_half', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), -// 'hi' => array('sgqa'=>'hi', 'code'=>'there', 'jsName'=>'java_hi', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), -// 'hello' => array('sgqa'=>'hello', 'code'=>"Tom", 'jsName'=>'java_hello', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), -// 'a' => array('sgqa'=>'a', 'code'=>0, 'jsName'=>'java_a', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), -// 'b' => array('sgqa'=>'b', 'code'=>0, 'jsName'=>'java_b', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), -// 'c' => array('sgqa'=>'c', 'code'=>0, 'jsName'=>'java_c', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), -// 'd' => array('sgqa'=>'d', 'code'=>0, 'jsName'=>'java_d', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), -// 'eleven' => array('sgqa'=>'eleven', 'code'=>11, 'jsName'=>'java_eleven', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), -// 'twelve' => array('sgqa'=>'twelve', 'code'=>12, 'jsName'=>'java_twelve', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), -// // Constants -// 'ASSESSMENT_HEADING' => array('sgqa'=>'ASSESSMENT_HEADING', 'code'=>'"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"', 'jsName'=>'', 'readWrite'=>'N'), -// 'QID' => array('sgqa'=>'QID', 'code'=>'value for {QID}', 'jsName'=>'', 'readWrite'=>'N'), -// 'QUESTIONHELP' => array('sgqa'=>'QUESTIONHELP', 'code'=>'"can single quoted strings" . \'contain nested \'quoted sections\'?', 'jsName'=>'', 'readWrite'=>'N'), -// 'QUESTION_HELP' => array('sgqa'=>'QUESTION_HELP', 'code'=>'Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and <?', 'jsName'=>'', 'readWrite'=>'N'), -// 'NUMBEROFQUESTIONS' => array('sgqa'=>'NUMBEROFQUESTIONS', 'code'=>'value for {NUMBEROFQUESTIONS}', 'jsName'=>'', 'readWrite'=>'N'), -// 'THEREAREXQUESTIONS' => array('sgqa'=>'THEREAREXQUESTIONS', 'code'=>'value for {THEREAREXQUESTIONS}', 'jsName'=>'', 'readWrite'=>'N'), -// 'TOKEN:FIRSTNAME' => array('sgqa'=>'TOKEN:FIRSTNAME', 'code' => 'value for {TOKEN:FIRSTNAME}', 'jsName' => '', 'readWrite' => 'N'), -// 'WELCOME' => array('sgqa'=>'WELCOME', 'code'=>'value for {WELCOME}', 'jsName'=>'', 'readWrite'=>'N'), -// // also include SGQA values and read-only variable attributes -// '12X34X56' => array('sgqa'=>'12X34X56', 'code'=>5, 'jsName'=>'', 'readWrite'=>'N', 'gseq'=>1,'qseq'=>1), -// '12X3X5lab1_ber' => array('sgqa'=>'12X3X5lab1_ber', 'code'=>10, 'jsName'=>'', 'readWrite'=>'N', 'gseq'=>1,'qseq'=>1), -// 'q5pointChoice' => array('sgqa'=>'q5pointChoice', 'code'=> 3, 'jsName'=>'java_q5pointChoice', 'readWrite'=>'N','shown'=>'Father', 'relevance'=>1, 'type'=>'5', 'question'=>'(question for q5pointChoice)', 'qid'=>14,'gseq'=>2,'qseq'=>14), -// 'qArrayNumbers_ls1_min' => array('sgqa'=>'qArrayNumbers_ls1_min', 'code'=> 7, 'jsName'=>'java_qArrayNumbers_ls1_min', 'readWrite'=>'N','shown'=> 'I love LimeSurvey', 'relevance'=>1, 'type'=>'A', 'question'=>'(question for qArrayNumbers)', 'qid'=>6,'gseq'=>2,'qseq'=>6), -// '12X3X5lab1_ber#1' => array('sgqa'=>'12X3X5lab1_ber#1', 'code'=> 15, 'jsName'=>'', 'readWrite'=>'N', 'gseq'=>1,'qseq'=>1), -// 'zero' => array('sgqa'=>'zero', 'code'=>0, 'jsName'=>'java_zero', 'gseq'=>0,'qseq'=>0), -// 'empty' => array('sgqa'=>'empty', 'code'=>'', 'jsName'=>'java_empty', 'gseq'=>0,'qseq'=>0), -// 'BREAKS' => array('sgqa'=>'BREAKS', 'code'=>"1\n2\n3", 'jsName'=>'', 'readWrite'=>'N'), -// ); -// $this->lem->setTempVars($vars); -// -// foreach ($vars as $var => $attributes) -// { -// foreach ($attributes as $key => $val) -// { -// $this->assertEquals($val, $this->lem->GetVarAttribute($var, $key, null, 0, 0), "Failed GetVarAttribute: $var.$key"); -// } -// } -// -// } -// - public function testEvaluator() - { - $booleanExpressions = array( - "1" => true, - "0" => false, - "" => false, - "1 == 1" => true, - "0 == 1" => false, - "1 && 0" => false, - "1 && 1" => true, - "1 || 0" => true, - "0 || 0" => false, - ); - - foreach ($booleanExpressions as $expr => $expected) { - $this->assertEquals($expected, $this->em->ProcessBooleanExpression($expr), "Expression: '$expr'"); - } - } - - public function testFunctions() - { - $functions = array( - 'abs(5)' => 5, - 'abs(-5)' => 5, - 'abs(0)' => 0, - 'acos(0.5)' => acos(0.5), - 'acos(0.1)' => acos(0.1), - - ); - foreach ($functions as $function => $expected) { - $this->assertEquals($expected, $this->em->sProcessStringContainingExpressions('{'.$function.'}')); - } - } - - public function testEscapes() - { - $strings = array( - '\{1+1}' => '{1+1}', - 'x{1+1}' => 'x2', - 'x{1+1\}' => 'x{1+1}', - ); - foreach ($strings as $escaped => $expected) { - $this->assertEquals($expected, $this->em->sProcessStringContainingExpressions($escaped)); - } - } - - public function testJuggling() - { - $equalities = array( - '"1" == 1' => 1, - '"5" + "2"' => 7, - '"1" == 0' => '', // False is an empty string. - '1 == "1"' => 1, - '1 + "2"' => 3, - '"1" + "a"' => '1a', - '1 + "a"' => '1a', - '"05" + "1"' => 6, - '"" + "1" + "2"' => 12 - ); - foreach ($equalities as $expression => $expected) { - $result = $this->em->sProcessStringContainingExpressions('{'.$expression.'}'); - $this->assertEquals($expected, $result); - } - } - public function oldTestEvaluator() - { - - - // Syntax for $tests is - // expectedResult~expression - // if the expected result is an error, use NULL for the expected result - $tests = <<Empty Vs. Empty~"Empty Vs. Empty" -1~'' == '' -0~'' != '' -0~'' > '' -1~'' >= '' -0~'' < '' -1~'' <= '' -1~!'' -~('' and '') -~('' or '') -Empty Vs. Zero~"Empty Vs. Zero" -0~'' == 0 -1~'' != 0 -0~'' > 0 -0~'' >= 0 -0~'' < 0 -0~'' <= 0 -1~!'' -1~!0 -0~('' and 0) -0~('' or 0) -Empty Vs. Constant~"Empty Vs. Constant" -0~'' == 3 -1~'' != 3 -0~'' > 3 -0~'' >= 3 -0~'' < 3 -0~'' <= 3 -1~!'' -0~!3 -0~('' and 3) -1~('' or 3) -Empty Vs. Empty_Var~"Empty Vs. Empty_Var" -1~'' == empty -0~'' != empty -0~'' > empty -1~'' >= empty -0~'' < empty -1~'' <= empty -1~!'' -1~!empty -~('' and empty) -~('' or empty) -Empty_Var Vs. Zero~"Empty_Var Vs. Zero" -0~empty == 0 -1~empty != 0 -0~empty > 0 -0~empty >= 0 -0~empty < 0 -0~empty <= 0 -1~!empty -1~!0 -0~(empty and 0) -0~(empty or 0) -Empty_Var Vs. Zero~"Empty_Var Vs. Zero" -0~empty == zero -1~empty != zero -0~empty > zero -0~empty >= zero -0~empty < zero -0~empty <= zero -1~!empty -1~!zero -0~(empty and zero) -0~(empty or zero) -Empty_Var Vs. Constant~"Empty_Var Vs. Constant" -0~empty == 3 -1~empty != 3 -0~empty > 3 -0~empty >= 3 -0~empty < 3 -0~empty <= 3 -1~!empty -0~!3 -0~(empty and 3) -1~(empty or 3) -Solution: Empty_Var Vs. Zero~"Solution: Empty_Var Vs. Zero" -0~!is_empty(empty) && (empty == 0) -0~!is_empty(five) && (five == 0) -1~!is_empty(zero) && (zero == 0) -0~!is_empty(empty) && (empty > 0) -0~!is_empty(empty) && (empty >= 0) -0~!is_empty(empty) && (empty < 0) -0~!is_empty(empty) && (empty <= 0) -0~!is_empty(empty) && ((empty and 0)) -0~!is_empty(empty) && ((empty or 0)) -Solution: Empty_Var Vs. Zero~"Solution: Empty_Var Vs. Zero" -0~!is_empty(empty) && (empty == zero) -0~!is_empty(five) && (five == zero) -1~!is_empty(zero) && (zero == zero) -0~!is_empty(empty) && (empty > zero) -0~!is_empty(empty) && (empty >= zero) -0~!is_empty(empty) && (empty < zero) -0~!is_empty(empty) && (empty <= zero) -0~!is_empty(empty) && ((empty and zero)) -0~!is_empty(empty) && ((empty or zero)) -Solution: Empty_Var Vs. Constant~"Solution: Empty_Var Vs. Constant" -0~!is_empty(empty) && (empty < 3) -0~!is_empty(empty) && (empty <= 3) -Solution: Empty_Var Vs. Variable~"Solution: Empty_Var Vs. Variable" -0~!is_empty(empty) && (empty < five) -0~!is_empty(empty) && (empty <= five) -Solution: The Hard One is Empty_Var != 0~"Solution: The Hard One is Empty_Var != 0" -1~(empty != 0) -1~!is_empty(empty) && (empty != 0) -1~is_empty(empty) || (empty != 0) -1~is_empty(empty) || (empty != zero) -0~is_empty(zero) || (zero != 0) -1~is_empty(five) || (five != 0) -SETUP~'SETUP' -"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~a=htmlspecialchars(ASSESSMENT_HEADING) -"can single quoted strings" . 'contain nested 'quoted sections'?~b=htmlspecialchars(QUESTIONHELP) -Can strings have embedded <tags> like <html>, or even unbalanced "quotes or entities without terminal semicolons like &amp and &lt?~c=htmlspecialchars(QUESTION_HELP) -Hi there!~d='Hi there!' -FUNCTIONS~'FUNCTIONS' -5~abs(five) -5~abs(-five) -0.2~acos(cos(0.2)) -0~acos(cos(pi()))-pi() -"Can strings contain embedded \\"quoted passages\\" (and parentheses + other characters?)?"~addslashes(a) -"can single quoted strings" . 'contain nested 'quoted sections'?~addslashes(b) -Can strings have embedded <tags> like <html>, or even unbalanced "quotes or entities without terminal semicolons like &amp and &lt?~addslashes(c) -0.2~asin(sin(0.2)) -0.2~atan(tan(0.2)) -0~atan2(0,1) -1~ceil(0.3) -1~ceil(0.7) -0~ceil(-0.3) -0~ceil(-0.7) -10~ceil(9.1) -1~checkdate(1,29,1967) -0~checkdate(2,29,1967) -0.2~cos(acos(0.2)) -5~count(1,2,3,4,5) -0~count() -5~count(one,two,three,four,five) -2~count(a,'',c) -NULL~date('F j, Y, g:i a',time()) -April 5, 2006, 1:02 am~date('F j, Y, g:i a',mktime(1,2,3,4,5,6)) -20~floor(exp(3)) -0~floor(asin(sin(pi()))) -9~floor(9.9) -3~floor(pi()) -January 12, 2012, 5:27 pm~date('F j, Y, g:i a',1326410867) -January 12, 2012, 11:27 pm~gmdate('F j, Y, g:i a',1326410867) -"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~html_entity_decode(a) -"can single quoted strings" . 'contain nested 'quoted sections'?~html_entity_decode(b) -Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and <?~html_entity_decode(c) -"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~htmlentities(a) -"can single quoted strings" . 'contain nested 'quoted sections'?~htmlentities(b) -Can strings have embedded <tags> like <html>, or even unbalanced "quotes or entities without terminal semicolons like &amp and &lt?~htmlentities(c) -1~c==htmlspecialchars(htmlspecialchars_decode(c)) -1~b==htmlspecialchars(htmlspecialchars_decode(b)) -1~a==htmlspecialchars(htmlspecialchars_decode(a)) -"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~htmlspecialchars_decode(a) -"can single quoted strings" . 'contain nested 'quoted sections'?~htmlspecialchars_decode(b) -Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and like , or even unbalanced "quotes or entities without terminal semicolons like & and <?~htmlspecialchars(c) -9~idate('B',1326410867) -0~if('0',1,0) -0~if(0,1,0) -1~if(!0,1,0) -0~if(!(!0),1,0) -1~if('true',1,0) -1~if('false',1,0) -1~if('00',1,0) -0~if('',1,0) -1~if('A',1,0) -0~if(empty,1,0) -4~if(5 > 7,2,4) -1~if(' ',1,0) -there~if((one > two),'hi','there') -64~if((one < two),pow(2,6),pow(6,2)) -H e l l o~implode(' ','H','e','l','l','o') -1|2|3|4|5~implode('|',one,two,three,four,five) -123~join(1,2,3) -123 5~join(one,2,three," ",five) -4~intval('4') -4~intval('100',2) -5~intval(5.7) -0~is_empty(four) -1~is_empty(empty) -1~is_empty('') -0~is_empty(0) -0~is_empty('0') -0~is_empty('false') -0~is_empty('NULL') -0~is_empty(1) -1~is_empty(one==two) -0~!is_empty(one==two) -1~is_float(half) -0~is_float(one) -1~is_float(pi()) -0~is_float(5) -0~is_int(half) -1~is_int(one) -0~is_nan(half) -1~is_nan(WELCOME) -1~is_null(sdfjskdfj) -0~is_null(four) -0~is_numeric(empty) -1~is_numeric('1') -1~is_numeric(four) -0~is_numeric('hi') -1~is_numeric(five) -0~is_numeric(hi) -0~is_string(four) -1~is_string('hi') -1~is_string(hi) -1, 2, 3, 4, 5~list(one,two,three,min(four,five,six),max(three,four,five)) -11, 12~list(eleven,twelve) -0, 1, 3, 5~list(0,one,'',three,'',five) -1~log(exp(1)) -2~log(exp(2)) -I was trimmed ~ltrim(' I was trimmed ') -10~max(5,6,10,-20) -6~max(five,(one + (two * four)- three)) -6~max((one + (two * four)- three)) -212~5 + max(1,(2+3),(4 + (5 + 6)),((7 + 8) + 9),((10 + 11), 12),(13 + (14 * 15) - 16)) -29~five + max(one, (two + three), (four + (five + six)),((seven + eight) + nine),((ten + eleven), twelve),(one + (two * three) - four)) -1024~max(one,(two*three),pow(four,five),six) -2~max(one,two) -5~max(one,two,three,four,five) --5~min(-5,10,15,12,-3) -1~min(five,four,one,two,three) -1344765967~mktime(5,6,7,8) -1144191723~mktime(1,2,3,4,5,6) -1,000~number_format(1000) -1,000.23~number_format(1000.23) -1,234,567~number_format(1234567) -315~ceil(100*pi()) -1~pi() == pi() * 2 - pi() -4~pow(2,2) -27~pow(3,3) -=~quoted_printable_decode(quoted_printable_encode('=')) -\\$~quotemeta('$') -IGNORE THIS ERROR~rand(3,5) -0~(a=rand())-a -1~regexMatch('/embedded/',c) -1~regexMatch('/^.*embedded.*$/',c) -0~regexMatch('/joe/',c) -1~regexMatch('/(?:dog|cat)food/','catfood stinks') -1~regexMatch('/(?:dog|cat)food/','catfood stinks') -1~regexMatch('/[0-9]{3}-[0-9]{2}-[0-9]{4}/','123-45-6789') -1~regexMatch('/\d{3}-\d{2}-\d{4}/','123-45-6789') -1~regexMatch('/(?:\(\d{3}\))\s*\d{3}-\d{4}/','(212) 555-1212') -0~round(0.2) -1~round(.8) -0.07~0.01 + 0.06 -0.07~round(0.01 + 0.06,10) - I was trimmed~rtrim(' I was trimmed ') -0.2~sin(asin(0.2)) -1~sin(pi()/2) -1~sin(pi()/2) == sin(.5 * pi()) -1~sin(0.5 * pi()) -hello,5~sprintf('%s,%d','hello',5) -2~sqrt(4) -158~round(stddev(4,5,6,7,8)*100) -hello-----~str_pad('hello',10,'-') -hello ~str_pad('hello',10) -hello~str_pad('hello',3) -testtesttest~str_repeat('test',3) -I am awesome~str_replace('You are','I am','You are awesome') -I love LimeSurvey~str_replace('like','love','I like LimeSurvey') -1~0==strcasecmp('Hello','hello') -0~0==strcasecmp('Hello','hi') -1~0==strcmp('Hello','Hello') -0~0==strcmp('Hello','hi') -Hi there!~c=strip_tags(d) -hello~strip_tags('hello') -5~stripos('ABCDEFGHI','f') -hi~stripslashes('\\h\\i') -FGHI~stristr('ABCDEFGHI','fg') -5~strlen('12345') -5~strlen(hi) -0~strpos('ABCDEFGHI','f') -5~strpos('ABCDEFGHI','F') -2~strpos('I like LimeSurvey','like') -54321~strrev('12345') -0~strstr('ABCDEFGHI','fg') -FGHI~strstr('ABCDEFGHI','FG') -hi there!~strtolower(c) -HI THERE!~strtoupper(c) -3600~strtotime("27 Mar 1976 8:20")-strtotime("1976/03/27 7:20") -10~(strtotime("13 Apr 2013")-strtotime("2013-04-03"))/60/60/24 -1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("05 Nov 1985")) -HOURS PASSED SINCE 1970~round(strtotime("now")/60/60) -~"" -1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("11/5/85")) -2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("8/9/10")) -2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("8/9/2010")) -2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("2010/8/9")) -~"" -1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("85-11-5")) -2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("10-8-9")) -2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("9-8-2010")) -2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("2010-8-9")) -~"" -1985-11-05 00:53:20~date("Y-m-d H:i:s",strtotime("85-11-5 0:53:20")) -2010-08-09 00:53:20~date("Y-m-d H:i:s",strtotime("10-8-9 0:53:20")) -2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("9-8-2010 11:12:13")) -2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("2010-8-9 11:12:13")) -~"" -Today 11:11:59~date("Y-m-d H:i:s",strtotime("11.11.59")) -Today 9:08:10~date("Y-m-d H:i:s",strtotime("9.8.10")) -2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("9.8.2010")) -~"" -1985-11-05 00:53:20~date("Y-m-d H:i:s",strtotime("5.11.85 0:53:20")) -2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("9.8.2010 11:12:13")) -~"" -1970-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("70-01-01")) -1999-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("99-01-01")) -2001-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("01-01-01")) -1902-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("1902-01-01")) -~"" -today 2:15:00~date("Y-m-d H:i:s",strtotime("2:15:00")) -Some dates that are not (correctly) parsed:~"Some dates that are not (correctly) parsed:" -1969-01-19 00:00:00~date("Y-m-d H:i:s",strtotime("69-01-19")) -1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("85/11/5")) -1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("5-11-85")) -2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("2010.8.9")) -1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("85.11.5")) -1985-11-05 00:53:20~date("Y-m-d H:i:s",strtotime("85.11.5 0:53:20")) -2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("9.8.10 11:12:13")) -678~substr('1234567890',5,3) -15~sum(1,2,3,4,5) -15~sum(one,two,three,four,five) -0.2~tan(atan(0.2)) -IGNORE THIS ERROR~time() -I was trimmed~trim(' I was trimmed ') -Hi There You~ucwords('hi there you') -EXPRESSIONS~'EXPRESSIONS' -1~!'0' -1~0 eq '0' -0~0 ne '0' -0~0 eq empty -1~0 ne empty -0~0 eq '' -1~0 ne '' -0~'' < 10 -0~0 < empty -1~0 <= empty -0~0 > empty -1~0 >= empty -0~'0' eq empty -1~'0' ne empty -0~'0' < empty -1~'0' <= empty -0~'0' > empty -1~'0' >= empty -1~empty eq empty -0~empty ne empty -0~'' > 0 -0~' ' > 0 -1~!0 -0~!' ' -0~!'A' -0~!1 -0~!'1' -1~!'' -1~!empty -1~'0'==0 -0~'A'>0 -0~'A'<0 -0~'A'==0 -0~'A'>=0 -0~'A'<=0 -0~0>'A' -0~0>='B' -0~0=='C' -0~0<'D' -0~0<='E' -1~0!='F' -1~'A' or 'B' -1~'A' and 'B' -0~'A' eq 'B' -1~'A' ne 'B' -1~'A' < 'B' -1~'A' <= 'B' -0~'A' > 'B' -0~'A' >= 'B' -AB~'A' + 'B' -NAN~'A' - 'B' -NAN~'A' * 'B' -NAN~'A' / 'B' -1~'A' or empty -0~'A' and empty -0~'A' eq empty -1~'A' ne empty -0~'A' < empty -0~'A' <= empty -1~'A' > empty -1~'A' >= empty -A~'A' + empty -NAN~'A' - empty -NAN~'A' * empty -NAN~'A' / empty -0~0 or empty -0~0 and empty -0~0 + empty -0~0 - empty -0~0 * empty -NAN~0 / empty -0~(-1 > 0) -0~zero -~empty -1~five > zero -1~five > empty -1~empty < 16 -1~zero == empty -3~q5pointChoice.code -5~q5pointChoice.type -(question for q5pointChoice)~q5pointChoice.question -1~q5pointChoice.relevance -4~q5pointChoice.NAOK + 1 -NULL~q5pointChoice.bogus -14~q5pointChoice.qid -7~qArrayNumbers_ls1_min.code -1~(one * (two + (three - four) + five) / six) -2.4~(one * two) + (three * four) / (five * six) -50~12X34X56 * 12X3X5lab1_ber -1~c == 'Hi there!' -1~c == "Hi there!" -3~a=three -3~c=a -12~c*=four -15~c+=a -5~c/=a --1~c-=six -24~one * two * three * four --4~five - four - three - two -0~two * three - two - two - two -4~two * three - two -105~5 + 1, 7 * 15 -7~7 -15~10 + 5 -24~12 * 2 -10~13 - 3 -3.5~14 / 4 -5~3 + 1 * 2 -1~one -there~hi -6.25~one * two - three / four + five -1~one + hi -1~two > one -1~two gt one -1~three >= two -1~three ge two -0~four < three -0~four lt three -0~four <= three -0~four le three -0~four == three -0~four eq three -1~four != three -0~four ne four -NAN~one * hi -0~a='hello',b='',c=0 -hello~a -0~c -0~one && 0 -0~two and 0 -1~five && 6 -1~seven && eight -1~one or 0 -1~one || 0 -1~(one and 0) || (two and three) -value for {QID}~QID -"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~ASSESSMENT_HEADING -"can single quoted strings" . 'contain nested 'quoted sections'?~QUESTIONHELP -Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and <?~QUESTION_HELP -value for {TOKEN:FIRSTNAME}~TOKEN:FIRSTNAME -value for {THEREAREXQUESTIONS}~THEREAREXQUESTIONS -15~12X3X5lab1_ber#1 -1~three == three -1~three == 3 -11~eleven -144~twelve * twelve -0~!three -8~five + + three -2~five + - three -SYNTAX ERRORS~'SYNTAX ERRORS' -NULL~* -NULL~three + -NULL~four * / seven -NULL~(five - three -NULL~five + three) -NULL~seven + = four -NULL~> -NULL~five > > three -NULL~seven > = four -NULL~seven >= -NULL~three && -NULL~three || -NULL~three + -NULL~three >= -NULL~three += -NULL~three ! -NULL~three * -NULL~five ! three -NULL~(5 + 7) = 8 -NULL~&& four -NULL~min( -NULL~max three, four, five) -NULL~three four -NULL~max(three,four,five) six -NULL~WELCOME='Good morning' -NULL~TOKEN:FIRSTNAME='Tom' -NULL~NUMBEROFQUESTIONS+=3 -NULL~NUMBEROFQUESTIONS*=4 -NULL~NUMBEROFQUESTIONS/=5 -NULL~NUMBEROFQUESTIONS-=6 -NULL~'Tom'='tired' -NULL~max() -NULL~convert_value( 10, 1, '0,5,10,15,20', '0,5,10,15') -100~convert_value( 10, 1, '0,5,10,15,20', '0,50,100,150,200') -NULL~convert_value( 10, 0, '0,5,10,15,20', '0,50,100,150,200') -100~convert_value( 8, 0, '0,5,10,15,20', '0,50,100,150,200') -100~convert_value( 12, 0, '0,5,10,15,20', '0,50,100,150,200') -0~convert_value( 0, 0, '0,5,10,15,20', '0,50,100,150,200') -0~convert_value( -10000, 0, '0,5,10,15,20', '0,50,100,150,200') -NULL~convert_value( -10000, 1, '0,5,10,15,20', '0,50,100,150,200') -200~convert_value( 20, 0, '0,5,10,15,20', '0,50,100,150,200') -200~convert_value( 20, 1, '0,5,10,15,20', '0,50,100,150,200') -200~convert_value( 30, 0, '0,5,10,15,20', '0,50,100,150,200') -NULL~convert_value( 30, 1, '0,5,10,15,20', '0,50,100,150,200') -EOD; - - $atests = explode("\n", $tests); - $atests[] = "1\n2\n3~BREAKS"; - $atests[] = "1
\n2
\n3~nl2br(BREAKS)"; - $atests[] = "hi
\nthere
\nhow
\nare
\nyou?~nl2br('hi\\nthere\\nhow\\nare\\nyou?')"; - $atests[] = "hi
\nthere,
\nuser!~nl2br(implode('\\n','hi','there,','user!'))"; - - $LEM = & LimeExpressionManager::singleton(); - $em = new ExpressionManager(); - $LEM->setTempVars($vars); - - //$LEMsessid = 'survey_' . Yii::app()->getConfig('surveyID'); - $LEMsessid = 'survey_12345'; - // manually set relevance status - $_SESSION[$LEMsessid]['relevanceStatus'] = array(); - foreach ($vars as $var) { - if (isset($var['qseq'])) { - $_SESSION[$LEMsessid]['relevanceStatus'][$var['qseq']] = 1; - } - } - - $allJsVarnamesUsed = array(); - $body = ''; - $body .= ''; - $i = 0; - $javaScript = array(); - foreach ($atests as $test) { - ++$i; - $values = explode("~", $test); - $expectedResult = array_shift($values); - $expr = implode("~", $values); - $resultStatus = 'ok'; - $em->groupSeq = 2; - $em->questionSeq = 3; - $status = $em->RDP_Evaluate($expr); - if ($status) { - $allJsVarnamesUsed = array_merge($allJsVarnamesUsed, $em->GetJsVarsUsed()); - } - $result = $em->GetResult(); - $valToShow = $result; // htmlspecialchars($result,ENT_QUOTES,'UTF-8',false); - $expectedToShow = $expectedResult; // htmlspecialchars($expectedResult,ENT_QUOTES,'UTF-8',false); - $body .= ""; - $body .= "\n"; - if (is_null($result)) { - $valToShow = "NULL"; - } - if ($valToShow != $expectedToShow) { - $resultStatus = 'error'; - } - $body .= "\n"; - $body .= '\n"; - $javaScript[] = $em->GetJavascriptTestforExpression($expectedToShow, $i); - $body .= "\n"; - $varsUsed = $em->GetVarsUsed(); - if (is_array($varsUsed) and count($varsUsed) > 0) { - $varDesc = array(); - foreach ($varsUsed as $v) { - $varDesc[] = $v; - } - $body .= '\n"; - } else { - $body .= "\n"; - } - $jsEqn = $em->GetJavaScriptEquivalentOfExpression(); - if ($jsEqn == '') { - $body .= "\n"; - } else { - $body .= '\n"; - } - $body .= ''; - } - $body .= '
ExpressionPHP ResultExpectedJavaScript ResultVarNamesJavaScript Eqn
".$em->GetPrettyPrintString()."".$valToShow."'.$expectedToShow." '.implode(',
', $varDesc)."
  '.$jsEqn."
'; - $body .= "\n"; - - $allJsVarnamesUsed = array_unique($allJsVarnamesUsed); - asort($allJsVarnamesUsed); - $pre = ''; - $pre .= "

Change some Relevance values to 0 to see how it affects computations

\n"; - $pre .= ''; - $i = 0; - $LEMvarNameAttr = array(); - $LEMalias2varName = array(); - foreach ($allJsVarnamesUsed as $jsVarName) { - ++$i; - $pre .= "\n"; - $LEMalias2varName[] = "'".substr($jsVarName, 5)."':'".$jsVarName."'"; - $LEMalias2varName[] = "'".$jsVarName."':'".$jsVarName."'"; - $attrInfo = "'".$jsVarName."': {'jsName':'".$jsVarName."'"; - - $varInfo = $vars[substr($jsVarName, 5)]; - foreach ($varInfo as $k=>$v) { - if ($k == 'code') { - continue; // will access it from hidden node - } - if ($k == 'shown') { - $k = 'shown'; - $v = htmlspecialchars(preg_replace("/[[:space:]]/", ' ', $v), ENT_QUOTES); - } - if ($k == 'jsName') { - continue; // since already set - } - $attrInfo .= ", '".$k."':'".$v."'"; - - } - $attrInfo .= ",'qid':".$i."}"; - $LEMvarNameAttr[] = $attrInfo; - } - $pre .= "
#JsVarnameStarting ValueRelevance
".$i."".$jsVarName; - foreach ($vars as $k => $v) { - if ($v['jsName'] == $jsVarName) { - $value = $v['code']; - } - } - $pre .= "".$value."\n"; - $pre .= "\n"; - $pre .= "
\n"; - - $pre .= "\n"; - - print $pre; - print $body; - - } - - - /** - * Unit test the asSplitStringOnExpressions() function to ensure that accurately parses out all expressions - * surrounded by curly braces, allowing for strings and escaped curly braces. - */ - - public function oldStringSplitter() - { - $tests = << INSERT61764X1X4),'children','pets')} than you do {if((INSERT61764X1X3 > INSERT61764X1X4),'pets','children')}, do you feel that the {if((INSERT61764X1X3 > INSERT61764X1X4),'pets','children')} are at a disadvantage? -Here is a String that failed to parse prior to fixing the preg_split() command to avoid recursive search of sub-strings: [{((617167X9X3241 == "Y" or 617167X9X3242 == "Y" or 617167X9X3243 == "Y" or 617167X9X3244 == "Y" or 617167X9X3245 == "Y" or 617167X9X3246 == "Y" or 617167X9X3247 == "Y" or 617167X9X3248 == "Y" or 617167X9X3249 == "Y") and (617167X9X3301 == "Y" or 617167X9X3302 == "Y" or 617167X9X3303 == "Y" or 617167X9X3304 == "Y" or 617167X9X3305 == "Y" or 617167X9X3306 == "Y" or 617167X9X3307 == "Y" or 617167X9X3308 == "Y" or 617167X9X3309 == "Y"))}] Here is the question. -EOD; -// Here is a String that failed to parse prior to fixing the preg_split() command to avoid recursive search of sub-strings: [{((617167X9X3241 == "Y" or 617167X9X3242 == "Y" or 617167X9X3243 == "Y" or 617167X9X3244 == "Y" or 617167X9X3245 == "Y" or 617167X9X3246 == "Y" or 617167X9X3247 == "Y" or 617167X9X3248 == "Y" or 617167X9X3249 == "Y") and (617167X9X3301 == "Y" or 617167X9X3302 == "Y" or 617167X9X3303 == "Y" or 617167X9X3304 == "Y" or 617167X9X3305 == "Y" or 617167X9X3306 == "Y" or 617167X9X3307 == "Y" or 617167X9X3308 == "Y" or 617167X9X3309 == "Y"))}] Here is the question. - - $em = new ExpressionManager(); - - $atests = explode("\n", $tests); - array_push($atests, '"hi\nthere\nhow\nare\nyou?\n"'); - - foreach ($atests as $test) { - $tokens = $em->asSplitStringOnExpressions($test); - print ''.$test.'
'; - print ''; - print implode("
\n", explode("\n", print_r($tokens, true))); - print '

'; - } - } - - /** - * Unit test the Tokenizer - Tokenize and generate a HTML-compatible print-out of a comprehensive set of test cases - */ - - public function oldTokenizer() - { - // Comprehensive test cases for tokenizing - $tests = << >= < <= == != gt ge lt le eq ne (target large gents built agile less equal) - Assign: = += -= *= /= - SGQA: 1X6X12 1X6X12ber1 1X6X12ber1_lab1 3583X84X249 12X3X5lab1_ber#1 1X6X12.NAOK 1X6X12ber1.NAOK 1X6X12ber1_lab1.NAOK 3583X84X249.NAOK 12X3X5lab1_ber#1.NAOK - Errors: Apt # 10C; (2 > 0) ? 'hi' : 'there'; array[30]; >>> <<< /* this is not a comment */ // neither is this - Words: q5pointChoice q5pointChoice.bogus q5pointChoice.code q5pointChoice.mandatory q5pointChoice.NAOK q5pointChoice.qid q5pointChoice.question q5pointChoice.relevance q5pointChoice.shown q5pointChoice.type -EOD; - - $em = new ExpressionManager(); - - foreach (explode("\n", $tests) as $test) { - $tokens = array(); //$em->RDP_Tokenize($test); - print ''.$test.'
'; - print ''; - print implode("
\n", explode("\n", print_r($tokens, true))); - print '

'; - } - } - } - -?> From 8b814bc5c61a9bfd7fc538564378cc75afa7504b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 10:17:38 +0200 Subject: [PATCH 06/20] update tests --- tests/acceptance/admin/CreateSurveyTest.php | 54 ++------------------- 1 file changed, 4 insertions(+), 50 deletions(-) diff --git a/tests/acceptance/admin/CreateSurveyTest.php b/tests/acceptance/admin/CreateSurveyTest.php index bd96a2feeeb..e48994c98d5 100644 --- a/tests/acceptance/admin/CreateSurveyTest.php +++ b/tests/acceptance/admin/CreateSurveyTest.php @@ -31,7 +31,7 @@ class CreateSurveyTest extends TestBaseClassWeb { /** - * + * */ public static function setupBeforeClass() { @@ -40,26 +40,22 @@ public static function setupBeforeClass() if (!$username) { $username = 'admin'; } - $password = getenv('PASSWORD'); if (!$password) { $password = 'password'; } - // Permission to everything. \Yii::app()->session['loginID'] = 1; - // Browser login. self::adminLogin($username, $password); } /** - * + * */ public static function teardownAfterClass() { parent::tearDownAfterClass(); - // Delete survey. $criteria = new \CDbCriteria; $criteria->compare('correct_relation_defaultlanguage.surveyls_title', 'test survey 1', true, 'AND'); @@ -83,9 +79,7 @@ public function testCreateSurvey() $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); $url = $urlMan->createUrl('admin'); self::$webDriver->get($url); - sleep(1); - // Ignore welcome modal. try { $button = self::$webDriver->wait(1)->until( @@ -99,9 +93,7 @@ public function testCreateSurvey() } catch (TimeOutException $ex) { // Do nothing. } - sleep(1); - // Ignore password warning. try { $button = self::$webDriver->wait(1)->until( @@ -115,10 +107,7 @@ public function testCreateSurvey() } catch (NoSuchElementException $ex) { // Do nothing. } - - sleep(1); - // Click on big "Create survey" button. $link = self::$webDriver->wait(10)->until( WebDriverExpectedCondition::elementToBeClickable( @@ -126,27 +115,20 @@ public function testCreateSurvey() ) ); $link->click(); - // Fill in title. $title = self::$webDriver->findElement(WebDriverBy::id('surveyls_title')); $title->clear()->sendKeys('test survey 1'); - // Click save. $save = self::$webDriver->findElement(WebDriverBy::id('save-form-button')); $save->click(); - sleep(1); - // Remove notification. $save = self::$webDriver->findElement(WebDriverBy::cssSelector('button.close.limebutton')); $save->click(); - sleep(1); - // Go to structure sidebar $selectStructureSidebar = self::$webDriver->findElement(WebDriverBy::id('adminpanel__sidebar--selectorStructureButton')); $selectStructureSidebar->click(); - // Click "Add group". $addgroup = self::$webDriver->wait(10)->until( @@ -155,31 +137,24 @@ public function testCreateSurvey() ) ); $addgroup->click(); - // Fill in group title. $groupname = self::$webDriver->findElement(WebDriverBy::id('group_name_en')); $groupname->clear()->sendKeys('group1'); - sleep(1); - // Click save and add question. $save = self::$webDriver->findElement(WebDriverBy::id('save-and-new-question-button')); $save->click(); sleep(3); - // Add question title. $groupname = self::$webDriver->findElement(WebDriverBy::id('title')); $groupname->clear()->sendKeys('question1'); - // Click save. $save = self::$webDriver->findElement(WebDriverBy::id('save-button')); $save->click(); - sleep(1); - + $selectSettingsSidebar = self::$webDriver->findElement(WebDriverBy::id('adminpanel__sidebar--selectorSettingsButton')); $selectSettingsSidebar->click(); - // Click "Overview". $overview = self::$webDriver->wait(10)->until( WebDriverExpectedCondition::elementToBeClickable( @@ -187,23 +162,17 @@ public function testCreateSurvey() ) ); $overview->click(); - sleep(1); - // Click "Activate survey". $overview = self::$webDriver->findElement(WebDriverBy::id('ls-activate-survey')); $overview->click(); - // Confirm. $overview = self::$webDriver->findElement(WebDriverBy::id('activateSurvey__basicSettings--proceed')); $overview->click(); - // Click "Overview". $overview = self::$webDriver->findElement(WebDriverBy::id('sidemenu_1_1')); $overview->click(); - sleep(1); - // Click "Execute survey". $execute = self::$webDriver->wait(10)->until( WebDriverExpectedCondition::elementToBeClickable( @@ -211,21 +180,16 @@ public function testCreateSurvey() ) ); $execute->click(); - sleep(1); - // Switch to new tab. $windowHandles = self::$webDriver->getWindowHandles(); self::$webDriver->switchTo()->window( end($windowHandles) ); - sleep(1); - // New tab with active survey. $nextButton = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); $nextButton->click(); - // Get questions. $dbo = \Yii::app()->getDb(); $query = 'SELECT sid FROM {{surveys}} ORDER BY datecreated DESC LIMIT 1'; @@ -242,18 +206,14 @@ public function testCreateSurvey() } $this->assertCount(1, $questions, 'We have exactly one question'); $this->assertTrue(isset($questions['question1']), json_encode(array_keys($questions))); - // Enter answer text. $sgqa = $sid . 'X' . $survey->groups[0]->gid . 'X' . $questions['question1']->qid; $question = self::$webDriver->findElement(WebDriverBy::id('answer' . $sgqa)); $question->sendKeys('foo bar'); - sleep(1); - // Click submit. $submitButton = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); $submitButton->click(); - // Check so that we see end page. $completed = self::$webDriver->findElement(WebDriverBy::cssSelector('div.completed-text')); $this->assertEquals( @@ -261,7 +221,6 @@ public function testCreateSurvey() "Thank you!\nYour survey responses have been recorded.", 'I can see completed text' ); - // Check so that response is recorded in database. $query = sprintf( 'SELECT * FROM {{survey_%d}}', @@ -270,13 +229,11 @@ public function testCreateSurvey() $result = $dbo->createCommand($query)->queryAll(); $this->assertCount(1, $result, 'Exactly one response'); $this->assertEquals('foo bar', $result[0][$sgqa], '"foo bar" response'); - // Switch to first window. $windowHandles = self::$webDriver->getWindowHandles(); self::$webDriver->switchTo()->window( reset($windowHandles) ); - // Delete survey. $execute = self::$webDriver->wait(10)->until( WebDriverExpectedCondition::elementToBeClickable( @@ -296,14 +253,11 @@ public function testCreateSurvey() ) ); $execute->click(); - sleep(1); - // Make sure the survey can't be found. $query = 'SELECT sid FROM {{surveys}} WHERE sid = ' . $sid; $sids = $dbo->createCommand($query)->queryAll(); $this->assertCount(0, $sids); - } catch (NoSuchElementException $ex) { // TODO :Duplicated code. self::$testHelper->takeScreenshot(self::$webDriver, __CLASS__ . '_' . __FUNCTION__); @@ -337,4 +291,4 @@ public function testCreateSurvey() ); } } -} +} \ No newline at end of file From d8a9d46f85b54737256db476f5e027dd4c02e59c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 10:26:57 +0200 Subject: [PATCH 07/20] all test files sync to master --- .../admin/InstallationControllerTest.php | 164 +++++------------- .../admin/TemplateConfigurationTest.php | 5 +- .../admin/TemplateControllerTest.php | 15 +- .../SaveDualScaleAnswerOptionsTest.php | 38 +--- .../DateTimeDefaultAnswerExpressionTest.php | 44 +---- .../questions/DateTimeForwardBackTest.php | 17 +- tests/acceptance/questions/DateTimeTest.php | 119 +++++-------- .../questions/DateTimeValidationTest.php | 22 +-- .../MultipleChoiceNextPreviousTest.php | 16 +- tests/acceptance/surveys/AjaxModeTest.php | 16 +- .../surveys/GroupRandomizationTest.php | 27 +-- .../MultipleChoiceWithExpressionTest.php | 10 +- tests/acceptance/surveys/ScreenOutTest.php | 21 +-- .../helpers/CheckDatabaseJsonValuesTest.php | 27 +-- .../functional/helpers/ExpressionCoreAux.php | 21 +-- .../helpers/ExpressionCoreHelperTest.php | 14 +- .../functional/helpers/UpdateDbHelperTest.php | 29 +--- 17 files changed, 143 insertions(+), 462 deletions(-) diff --git a/tests/acceptance/admin/InstallationControllerTest.php b/tests/acceptance/admin/InstallationControllerTest.php index dd7aa15f537..f630b58f6d6 100644 --- a/tests/acceptance/admin/InstallationControllerTest.php +++ b/tests/acceptance/admin/InstallationControllerTest.php @@ -17,131 +17,59 @@ use LimeSurvey\tests\TestBaseClassWeb; /** - * @since 2017-11-24 - * @group inst + * @since 2017-10-15 + * @group tempcontr + * @group template */ -class InstallationControllerTest extends TestBaseClassWeb +class TemplateControllerTest extends TestBaseClass { /** - * + * Test copy a template. + * @group copytemplate */ - public static function setupBeforeClass() + public function testCopyTemplate() { - parent::setUpBeforeClass(); + \Yii::app()->session['loginID'] = 1; + \Yii::import('application.controllers.admin.themes', true); + \Yii::import('application.helpers.globalsettings_helper', true); + // Clean up from last test. + $templateName = 'foobartest'; + \TemplateConfiguration::uninstall($templateName); + \Template::model()->deleteAll('name = \'foobartest\''); + \Permission::model()->deleteAllByAttributes(array('permission' => $templateName,'entity' => 'template')); + // Remove folder from last test. + $newname = 'foobartest'; + $newdirname = \Yii::app()->getConfig('userthemerootdir') . "/" . $newname; + if (file_exists($newdirname)) { + exec('rm -r ' . $newdirname); + } + $config = require(\Yii::app()->getBasePath() . '/config/config-defaults.php'); + // Simulate a POST. + $_POST['newname'] = $newname; + // NB: If default theme is not installed, this test will fail. + $_POST['copydir'] = $config['defaulttheme']; + $_SERVER['SERVER_NAME'] = 'localhost'; + $contr = new \themes(new \ls\tests\DummyController('dummyid')); + $contr->templatecopy(); + $flashes = \Yii::app()->user->getFlashes(); + $this->assertEmpty($flashes, 'No flash messages'); + $template = \Template::model()->find( + sprintf( + 'name = \'%s\'', + $templateName + ) + ); + $this->assertNotEmpty($template); + $this->assertEquals($templateName, $template->name); + // Clean up. + \Template::model()->deleteAll('name = \'foobartest\''); } - /** - * + * @todo Copy template folder that does not exist. */ - public function testBasic() + /* + public function testCopyWrongFolder() { - $configFile = \Yii::app()->getBasePath() . '/config/config.php'; - $databaseName = 'limesurvey'; - - $username = getenv('ADMINUSERNAME'); - if (!$username) { - $username = 'admin'; - } - $password = getenv('PASSWORD'); - if (!$password) { - $password = 'password'; - } - - $dbuser = getenv('DBUSER'); - if (!$dbuser) { - $dbuser = 'root'; - echo 'Default to database user "root". Use DBUSER=... from command-line to override this.' . PHP_EOL; - } - $dbpwd = getenv('DBPASSWORD'); - if (!$dbpwd) { - $dbpwd = ''; - echo 'Default to empty database password. Use DBPASSWORD=... from command-line to override this.' . PHP_EOL; - } - - if (file_exists($configFile)) { - // Delete possible previous database. - try { - $dbo = \Yii::app()->getDb(); - $dbo->createCommand('DROP DATABASE ' . $databaseName)->execute(); - } catch (\CDbException $ex) { - $msg = $ex->getMessage(); - // Only this error is OK. - self::assertTrue( - strpos($msg, "database doesn't exist") !== false, - 'Could drop database. Error message: ' . $msg - ); - } - - // Remove config.php if present. - $result = unlink($configFile); - $this->assertTrue($result, 'Could unlink config.php'); - } - - // Run installer. - $urlMan = \Yii::app()->urlManager; - $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); - $url = $urlMan->createUrl(''); - - // Installer start page. - self::$webDriver->get($url); - - // Click "Start installation". - $start = self::$webDriver->findElement(WebDriverBy::id('ls-start-installation')); - $start->click(); - - // Accept license. - $accept = self::$webDriver->findElement(WebDriverBy::id('ls-accept-license')); - $accept->click(); - - // Click next at pre-check. - $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); - $next->click(); - - // Fill in database form. - $dbuserInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbuser]"]')); - $dbpwdInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbpwd]"]')); - $dbnameInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbname]"]')); - $dbuserInput->clear()->sendKeys($dbuser); - $dbpwdInput->clear()->sendKeys($dbpwd); - $dbnameInput->sendKeys($databaseName); - - // Click next. - $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); - $next->click(); - - // Click "Create database". - $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); - $button->click(); - - // Click "Populate". - $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); - $button->click(); - - // Fill in admin username/password. - $adminLoginName = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginName]"]')); - $adminLoginPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginPwd]"]')); - $confirmPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[confirmPwd]"]')); - $adminLoginName->clear()->sendKeys($username); - $adminLoginPwd->clear()->sendKeys($password); - $confirmPwd->clear()->sendKeys($password); - - // Confirm optional settings (admin password etc). - $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); - $button->click(); - - // Go to administration. - $button = self::$webDriver->findElement(WebDriverBy::id('ls-administration')); - $button->click(); - - // Reset urlManager to adapt to latest config. - $configFile = \Yii::app()->getBasePath() . '/config/config.php'; - $config = require($configFile); - $urlMan = \Yii::app()->urlManager; - $urlMan->setUrlFormat($config['components']['urlManager']['urlFormat']); - - // Login. - self::adminLogin($username, $password); - - self::$testHelper->connectToOriginalDatabase(); } -} + */ +} \ No newline at end of file diff --git a/tests/acceptance/admin/TemplateConfigurationTest.php b/tests/acceptance/admin/TemplateConfigurationTest.php index f63d4721051..b2d33e0b094 100644 --- a/tests/acceptance/admin/TemplateConfigurationTest.php +++ b/tests/acceptance/admin/TemplateConfigurationTest.php @@ -19,10 +19,7 @@ public function testCopyMinimalTemplate() \Yii::import('application.helpers.globalsettings_helper', true); $tempConf = \TemplateConfiguration::getInstanceFromTemplateName('default'); $tempConf->prepareTemplateRendering('default'); - - // FIXME - // No PHP notices. $this->assertTrue(true); } -} +} \ No newline at end of file diff --git a/tests/acceptance/admin/TemplateControllerTest.php b/tests/acceptance/admin/TemplateControllerTest.php index 927b4392c58..55336203c4b 100644 --- a/tests/acceptance/admin/TemplateControllerTest.php +++ b/tests/acceptance/admin/TemplateControllerTest.php @@ -23,7 +23,6 @@ */ class TemplateControllerTest extends TestBaseClass { - /** * Test copy a template. * @group copytemplate @@ -33,33 +32,27 @@ public function testCopyTemplate() \Yii::app()->session['loginID'] = 1; \Yii::import('application.controllers.admin.themes', true); \Yii::import('application.helpers.globalsettings_helper', true); - // Clean up from last test. $templateName = 'foobartest'; \TemplateConfiguration::uninstall($templateName); \Template::model()->deleteAll('name = \'foobartest\''); \Permission::model()->deleteAllByAttributes(array('permission' => $templateName,'entity' => 'template')); - // Remove folder from last test. $newname = 'foobartest'; $newdirname = \Yii::app()->getConfig('userthemerootdir') . "/" . $newname; if (file_exists($newdirname)) { exec('rm -r ' . $newdirname); } - $config = require(\Yii::app()->getBasePath() . '/config/config-defaults.php'); // Simulate a POST. $_POST['newname'] = $newname; // NB: If default theme is not installed, this test will fail. $_POST['copydir'] = $config['defaulttheme']; $_SERVER['SERVER_NAME'] = 'localhost'; - $contr = new \themes(new DummyController('dummyid')); $contr->templatecopy(); - $flashes = \Yii::app()->user->getFlashes(); $this->assertEmpty($flashes, 'No flash messages'); - $template = \Template::model()->find( sprintf( 'name = \'%s\'', @@ -68,13 +61,9 @@ public function testCopyTemplate() ); $this->assertNotEmpty($template); $this->assertEquals($templateName, $template->name); - - - - // Clean up. //TODO tearDown + // Clean up. \Template::model()->deleteAll('name = \'foobartest\''); } - /** * @todo Copy template folder that does not exist. */ @@ -83,4 +72,4 @@ public function testCopyWrongFolder() { } */ -} +} \ No newline at end of file diff --git a/tests/acceptance/admin/questions/SaveDualScaleAnswerOptionsTest.php b/tests/acceptance/admin/questions/SaveDualScaleAnswerOptionsTest.php index b74e409470f..654340d5138 100644 --- a/tests/acceptance/admin/questions/SaveDualScaleAnswerOptionsTest.php +++ b/tests/acceptance/admin/questions/SaveDualScaleAnswerOptionsTest.php @@ -23,34 +23,28 @@ class SaveDualScaleAnswerOptionsTest extends TestBaseClassWeb { /** - * + * */ public static function setupBeforeClass() { parent::setupBeforeClass(); - // Permission to everything. \Yii::app()->session['loginID'] = 1; - $username = getenv('ADMINUSERNAME'); if (!$username) { $username = 'admin'; } - $password = getenv('PASSWORD'); if (!$password) { $password = 'password'; } - // Permission to everything. \Yii::app()->session['loginID'] = 1; - // Browser login. self::adminLogin($username, $password); } - /** - * + * */ public function setup() { @@ -58,9 +52,8 @@ public function setup() $surveyFile = self::$surveysFolder . '/limesurvey_survey_677328.lss'; self::importSurvey($surveyFile); } - /** - * + * */ public function tearDown() { @@ -70,9 +63,8 @@ public function tearDown() self::$testSurvey = null; } } - /** - * + * */ public function testBasic() { @@ -81,7 +73,6 @@ public function testBasic() $this->assertNotEmpty($survey); $this->assertCount(1, $survey->groups, 'Wrong number of groups: ' . count($survey->groups)); $this->assertCount(1, $survey->groups[0]->questions, 'We have exactly one question'); - $urlMan = \Yii::app()->urlManager; $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); $url = $urlMan->createUrl( @@ -93,39 +84,30 @@ public function testBasic() 'qid' => $survey->groups[0]->questions[0]->qid ] ); - self::$webDriver->get($url); - $answer1 = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="answer_en_1_0"]')); $answer1->sendKeys('123'); - $answer2 = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="answer_en_1_1"]')); $answer2->sendKeys('abc'); - $savebutton = self::$webDriver->findElement(WebDriverBy::id('save-button')); $savebutton->click(); - $notif = self::$webDriver->findElement(WebDriverBy::id('notif-container')); $notifText = $notif->getText(); $this->assertContains('Answer options were successfully saved', $notifText); - $answers = \Answer::model()->findAllByAttributes(['qid' => $survey->groups[0]->questions[0]->qid]); $this->assertCount(2, $answers, 'Two answer options saved'); } - /** - * + * */ public function testUsingLinkToEditAnswers() { $surveyFile = self::$surveysFolder . '/limesurvey_survey_677328.lss'; self::importSurvey($surveyFile); - $survey = \Survey::model()->findByPk(self::$surveyId); $this->assertNotEmpty($survey); $this->assertCount(1, $survey->groups, 'Wrong number of groups: ' . count($survey->groups)); $this->assertCount(1, $survey->groups[0]->questions, 'We have exactly one question'); - $urlMan = \Yii::app()->urlManager; $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); $url = $urlMan->createUrl( @@ -137,28 +119,20 @@ public function testUsingLinkToEditAnswers() 'qid' => $survey->groups[0]->questions[0]->qid ] ); - self::$webDriver->get($url); - $button = self::$webDriver->findElement(WebDriverBy::linkText('Edit answer options')); $button->click(); - $answer1 = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="answer_en_1_0"]')); $answer1->sendKeys('123'); - $answer2 = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="answer_en_1_1"]')); $answer2->sendKeys('abc'); - sleep(1); - $savebutton = self::$webDriver->findElement(WebDriverBy::id('save-button')); $savebutton->click(); - $notif = self::$webDriver->findElement(WebDriverBy::id('notif-container')); $notifText = $notif->getText(); $this->assertContains('Answer options were successfully saved', $notifText); - $answers = \Answer::model()->findAllByAttributes(['qid' => $survey->groups[0]->questions[0]->qid]); $this->assertCount(2, $answers, 'Two answer options saved'); } -} +} \ No newline at end of file diff --git a/tests/acceptance/questions/DateTimeDefaultAnswerExpressionTest.php b/tests/acceptance/questions/DateTimeDefaultAnswerExpressionTest.php index 2f78ca38a1f..080a943ba08 100644 --- a/tests/acceptance/questions/DateTimeDefaultAnswerExpressionTest.php +++ b/tests/acceptance/questions/DateTimeDefaultAnswerExpressionTest.php @@ -24,14 +24,12 @@ */ class DateTimeDefaultAnswerExpressionTest extends TestBaseClass { - public static function setUpBeforeClass() { parent::setUpBeforeClass(); $fileName = self::$surveysFolder . '/limesurvey_survey_454287.lss'; self::importSurvey($fileName); } - /** * Test the question with lacking default answer expression, * date('Y-m-d'), will be filled with ' 00:00' to work with @@ -42,11 +40,8 @@ public function testDefaultAnswerExpressionFill() { global $thissurvey; $thissurvey = self::$surveyId; - list($question, $group, $sgqa) = self::$testHelper->getSgqa('G1Q00005', self::$surveyId); - $surveyOptions = self::$testHelper->getSurveyOptions(self::$surveyId); - \Yii::app()->setConfig('surveyID', self::$surveyId); \Yii::app()->setController(new DummyController('dummyid')); buildsurveysession(self::$surveyId); @@ -66,20 +61,15 @@ public function testDefaultAnswerExpressionFill() ], $result ); - // Qanda needs this. $_SESSION['survey_' . self::$surveyId]['maxstep'] = 2; $_SESSION['survey_' . self::$surveyId]['step'] = 1; - // Move one step to run expressions. - $moveResult = LimeExpressionManager::NavigateForwards(); - + $moveResult = \LimeExpressionManager::NavigateForwards(); // Check result from qanda. $qanda = \retrieveAnswers( - $_SESSION['survey_' . self::$surveyId]['fieldarray'][0], - self::$surveyId + $_SESSION['survey_' . self::$surveyId]['fieldarray'][0] ); - $correctDate = date('d/m/Y'); $this->assertNotEquals( false, @@ -92,9 +82,7 @@ public function testDefaultAnswerExpressionFill() ), 'Showing todays date' ); - } - /** * Test full default answer expression, * date('Y-m-d H:i'). @@ -104,11 +92,9 @@ public function testCorrectDefaultAnswerExpression() { global $thissurvey; $thissurvey = self::$surveyId; - + $survey = \Survey::model()->findByPk(self::$surveyId); list($question, $group, $sgqa) = self::$testHelper->getSgqa('q2', self::$surveyId); - $surveyOptions = self::$testHelper->getSurveyOptions(self::$surveyId); - \Yii::app()->setConfig('surveyID', self::$surveyId); \Yii::app()->setController(new DummyController('dummyid')); buildsurveysession(self::$surveyId); @@ -128,22 +114,16 @@ public function testCorrectDefaultAnswerExpression() ], $result ); - // Qanda needs this. $_SESSION['survey_' . self::$surveyId]['maxstep'] = 2; $_SESSION['survey_' . self::$surveyId]['step'] = 1; - // Move one step to run expressions. $moveResult = \LimeExpressionManager::NavigateForwards(); - // Check result from qanda. $qanda = \retrieveAnswers( - $_SESSION['survey_' . self::$surveyId]['fieldarray'][1], // 1 = second question (q2) - self::$surveyId + $_SESSION['survey_' . self::$surveyId]['fieldarray'][1] // 1 = second question (q2) ); - $correctDate = date('d/m/Y'); - $this->assertNotEquals( false, strpos( @@ -156,7 +136,6 @@ public function testCorrectDefaultAnswerExpression() 'Showing todays date' ); } - /** * Test default answer, date format HH:MM, expression * date('HH:ii'). Return empty value. @@ -165,11 +144,8 @@ public function testWrongDefaultAnswerExpression() { global $thissurvey; $thissurvey = self::$surveyId; - list($question, $group, $sgqa) = self::$testHelper->getSgqa('q3', self::$surveyId); - $surveyOptions = self::$testHelper->getSurveyOptions(self::$surveyId); - \Yii::app()->setConfig('surveyID', self::$surveyId); \Yii::app()->setController(new DummyController('dummyid')); buildsurveysession(self::$surveyId); @@ -189,29 +165,23 @@ public function testWrongDefaultAnswerExpression() ], $result ); - // Qanda needs this. $_SESSION['survey_' . self::$surveyId]['maxstep'] = 2; $_SESSION['survey_' . self::$surveyId]['step'] = 1; - // Move one step to run expressions. - $moveResult = LimeExpressionManager::NavigateForwards(); - + $moveResult = \LimeExpressionManager::NavigateForwards(); // Check result from qanda. $qanda = \retrieveAnswers( - $_SESSION['survey_' . self::$surveyId]['fieldarray'][2], // 2 = third question (q3) - self::$surveyId + $_SESSION['survey_' . self::$surveyId]['fieldarray'][2] // 2 = third question (q3) ); - // NB: Empty value, since default answer expression is not parsed by qanda. $this->assertNotEquals( false, strpos($qanda[0][1], "value=\"\""), 'Showing empty date due to wrong expression' ); - // NB: Value below is todays time in format H:i, which can't be // parsed by qanda (expects Y-m-d H:i). //print_r($_SESSION['survey_' . self::$surveyId][$sgqa]); } -} +} \ No newline at end of file diff --git a/tests/acceptance/questions/DateTimeForwardBackTest.php b/tests/acceptance/questions/DateTimeForwardBackTest.php index 67104478432..f33fe2b94b2 100644 --- a/tests/acceptance/questions/DateTimeForwardBackTest.php +++ b/tests/acceptance/questions/DateTimeForwardBackTest.php @@ -24,7 +24,6 @@ */ class DateTimeForwardBackTest extends TestBaseClass { - /** * Import survey in tests/surveys/. */ @@ -33,11 +32,9 @@ public static function setUpBeforeClass() parent::setUpBeforeClass(); $_POST = []; $_SESSION = []; - $surveyFile = self::$surveysFolder.'/limesurvey_survey_917744.lss'; self::importSurvey($surveyFile); } - /** * q1 is hidden question with default answer "now". * @group q01 @@ -47,12 +44,9 @@ public function testQ1() list($question, $group, $sgqa) = self::$testHelper->getSgqa('G1Q00001', self::$surveyId); $surveyMode = 'group'; $LEMdebugLevel = 0; - self::$testHelper->activateSurvey(self::$surveyId); - // Must fetch this AFTER survey is activated. $surveyOptions = self::$testHelper->getSurveyOptions(self::$surveyId); - \Yii::app()->setConfig('surveyID', self::$surveyId); \Yii::app()->setController(new DummyController('dummyid')); \buildsurveysession(self::$surveyId); @@ -70,7 +64,6 @@ public function testQ1() ], $result ); - $qid = $question->qid; $gseq = 0; $_POST['relevance' . $qid] = 1; @@ -82,28 +75,22 @@ public function testQ1() $_POST[$sgqa] = '10:00'; $_SESSION['survey_' . self::$surveyId]['maxstep'] = 2; $_SESSION['survey_' . self::$surveyId]['step'] = 1; - $moveResult = \LimeExpressionManager::NavigateForwards(); $result = \LimeExpressionManager::ProcessCurrentResponses(); $this->assertEquals($result[$sgqa]['value'], '1970-01-01 10:00'); - $moveResult = \LimeExpressionManager::NavigateForwards(); // Result is empty dummy text question. \LimeExpressionManager::ProcessCurrentResponses(); - // Check answer in database. $query = 'SELECT * FROM {{survey_' . self::$surveyId . '}}'; $result = \Yii::app()->db->createCommand($query)->queryAll(); $this->assertEquals($result[0][$sgqa], '1970-01-01 10:00:00', 'Answer in database is 10:00'); - // Check result from qanda. $qanda = \retrieveAnswers( - $_SESSION['survey_' . self::$surveyId]['fieldarray'][0], - self::$surveyId + $_SESSION['survey_' . self::$surveyId]['fieldarray'][0] ); $this->assertEquals(false, strpos($qanda[0][1], "value=\"11:00\""), 'No 11:00 value from qanda'); $this->assertNotEquals(false, strpos($qanda[0][1], "value=\"10:00\""), 'One 10:00 value from qanda'); - self::$testHelper->deactivateSurvey(self::$surveyId); } -} +} \ No newline at end of file diff --git a/tests/acceptance/questions/DateTimeTest.php b/tests/acceptance/questions/DateTimeTest.php index ecc315d9194..5eb7e7cccf0 100644 --- a/tests/acceptance/questions/DateTimeTest.php +++ b/tests/acceptance/questions/DateTimeTest.php @@ -22,80 +22,74 @@ */ class DateTimeTest extends TestBaseClass { - /** * Import survey in tests/surveys/. */ public static function setUpBeforeClass() { parent::setUpBeforeClass(); - $_POST = []; $_SESSION = []; - $surveyFile = self::$surveysFolder.'/limesurvey_survey_975622.lss'; self::importSurvey($surveyFile); - } - /** * "currentQset" in EM. */ protected function getQuestionSetForQ2(\Question $question, \QuestionGroup $group, $sgqa) { $qset = array($question->qid => array + ( + 'info' => array ( - 'info' => array - ( - 'relevance' => '1', - 'grelevance' => '', - 'qid' => $question->qid, - 'qseq' => 1, - 'gseq' => 0, - 'jsResultVar_on' => 'answer' . $sgqa, - 'jsResultVar' => 'java' . $sgqa, - 'type' => 'D', - 'hidden' => false, - 'gid' => $group->gid, - 'mandatory' => 'N', - 'eqn' => '', - 'help' => '', - 'qtext' => '', - 'code' => 'q2', - 'other' => 'N', - 'default' => null, - 'rootVarName' => 'q2', - 'rowdivid' => '', - 'aid' => '', - 'sqid' => '', - ), - 'relevant' => true, + 'relevance' => '1', + 'grelevance' => '', + 'qid' => $question->qid, + 'qseq' => 1, + 'gseq' => 0, + 'jsResultVar_on' => 'answer' . $sgqa, + 'jsResultVar' => 'java' . $sgqa, + 'type' => 'D', 'hidden' => false, - 'relEqn' => '', - 'sgqa' => $sgqa, - 'unansweredSQs' => $sgqa, - 'valid' => true, - 'validEqn' => '', - 'prettyValidEqn' => '', - 'validTip' => '', - 'prettyValidTip' => '', - 'validJS' => '', - 'invalidSQs' => '', - 'relevantSQs' => $sgqa, - 'irrelevantSQs' => '', - 'subQrelEqn' => '', - 'mandViolation' => false, - 'anyUnanswered' => true, - 'mandTip' => '', - 'message' => '', - 'updatedValues' => array(), - 'sumEqn' => '', - 'sumRemainingEqn' => '' - ) + 'gid' => $group->gid, + 'mandatory' => 'N', + 'eqn' => '', + 'help' => '', + 'qtext' => '', + 'code' => 'q2', + 'other' => 'N', + 'default' => null, + 'rootVarName' => 'q2', + 'rowdivid' => '', + 'aid' => '', + 'sqid' => '', + ), + 'relevant' => true, + 'hidden' => false, + 'relEqn' => '', + 'sgqa' => $sgqa, + 'unansweredSQs' => $sgqa, + 'valid' => true, + 'validEqn' => '', + 'prettyValidEqn' => '', + 'validTip' => '', + 'prettyValidTip' => '', + 'validJS' => '', + 'invalidSQs' => '', + 'relevantSQs' => $sgqa, + 'irrelevantSQs' => '', + 'subQrelEqn' => '', + 'mandViolation' => false, + 'anyUnanswered' => true, + 'mandTip' => '', + 'message' => '', + 'updatedValues' => array(), + 'sumEqn' => '', + 'sumRemainingEqn' => '' + ) ); return $qset; } - /** * Test wrong date input and error message. * @group datewronginput @@ -104,14 +98,10 @@ public function testWrongInput() { $contr = new DummyController('dummyid'); \Yii::app()->setController($contr); - list($question, $group, $sgqa) = self::$testHelper->getSgqa('q2', self::$surveyId); - $qset = $this->getQuestionSetForQ2($question, $group, $sgqa); - $em = \LimeExpressionManager::singleton(); $em->setCurrentQset($qset); - $surveyMode = 'group'; $LEMdebugLevel = 0; $surveyOptions = self::$testHelper->getSurveyOptions(self::$surveyId); @@ -122,40 +112,31 @@ public function testWrongInput() false, $LEMdebugLevel ); - $qid = $question->qid; $gseq = 0; $_POST['relevance' . $qid] = 1; $_POST['relevanceG' . $gseq] = 1; $_POST[$sgqa] = 'asd'; - $result = \LimeExpressionManager::ProcessCurrentResponses(); $this->assertNotEmpty($result); $this->assertEquals(1, count($result), 'One question from ProcessCurrentResponses'); $this->assertEquals('INVALID', $result[$sgqa]['value']); - $originalPrefix = \Yii::app()->user->getStateKeyPrefix(); \Yii::app()->user->setStateKeyPrefix('frontend' . self::$surveyId); $flashes = \Yii::app()->user->getFlashes(); - $this->assertNotEmpty($flashes); $this->assertEquals(1, count($flashes), 'One error message'); - \Yii::app()->user->setStateKeyPrefix($originalPrefix); } - /** * Test correct date. */ public function testCorrectDateFormat() { list($question, $group, $sgqa) = self::$testHelper->getSgqa('q2', self::$surveyId); - $qset = $this->getQuestionSetForQ2($question, $group, $sgqa); - $em = \LimeExpressionManager::singleton(); $em->setCurrentQset($qset); - $surveyMode = 'group'; $LEMdebugLevel = 0; $surveyOptions = self::$testHelper->getSurveyOptions(self::$surveyId); @@ -166,27 +147,21 @@ public function testCorrectDateFormat() false, $LEMdebugLevel ); - $qid = $question->qid; $gseq = 0; $_POST['relevance' . $qid] = 1; $_POST['relevanceG' . $gseq] = 1; $_POST[$sgqa] = '23/12/2016'; - $result = \LimeExpressionManager::ProcessCurrentResponses(); $this->assertNotEmpty($result); $this->assertEquals(1, count($result), 'One question from ProcessCurrentResponses'); $this->assertEquals('2016-12-23 00:00', $result[$sgqa]['value']); - $originalPrefix = \Yii::app()->user->getStateKeyPrefix(); \Yii::app()->user->setStateKeyPrefix('frontend' . self::$surveyId); $flashes = \Yii::app()->user->getFlashes(); - $this->assertEmpty($flashes, 'No error message'); - \Yii::app()->user->setStateKeyPrefix($originalPrefix); } - /** * q1 is hidden question with default answer "now". */ @@ -211,4 +186,4 @@ public function testQ1() $result = \LimeExpressionManager::ProcessCurrentResponses(); $this->assertEquals(date('Y-m-d'), $_SESSION['survey_' . self::$surveyId][$sgqa]); } -} +} \ No newline at end of file diff --git a/tests/acceptance/questions/DateTimeValidationTest.php b/tests/acceptance/questions/DateTimeValidationTest.php index 5e36351e532..3606ddb2bda 100644 --- a/tests/acceptance/questions/DateTimeValidationTest.php +++ b/tests/acceptance/questions/DateTimeValidationTest.php @@ -32,14 +32,12 @@ class DateTimeValidationTest extends TestBaseClassWeb public static function setUpBeforeClass() { parent::setUpBeforeClass(); - $surveyFile = self::$surveysFolder.'/limesurvey_survey_834477.lss'; self::importSurvey($surveyFile); self::$testHelper->enablePreview(); } - /** - * + * */ public function testBasic() { @@ -53,9 +51,7 @@ public function testBasic() 'lang' => 'pt' ] ); - self::$webDriver->get($url); - try { $submit = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); } catch (NoSuchElementException $ex) { @@ -68,15 +64,13 @@ public function testBasic() 'Screenshot in ' . $filename . PHP_EOL . $ex->getMessage() ); } - $this->assertNotEmpty($submit); self::$webDriver->wait(5)->until( WebDriverExpectedCondition::elementToBeClickable( - WebDriverBy::id('ls-button-submit') - ) + WebDriverBy::id('ls-button-submit') + ) ); $submit->click(); - // After submit we should see the complete page. try { // Wait max 10 second to find this div. @@ -98,14 +92,14 @@ public function testBasic() ); } catch (TimeOutException $ex) { $body = self::$webDriver->findElement(WebDriverBy::tagName('body')); - var_dump($body->getText()); - $reflect = new \ReflectionClass($this); - //if ($reflect->getShortName() === 'Name') { + var_dump($body->getText()); + $reflect = new \ReflectionClass($this); + //if ($reflect->getShortName() === 'Name') { self::$testHelper->takeScreenshot(self::$webDriver, $reflect->getShortName() . '_' . __FUNCTION__); $this->assertFalse( true, self::$testHelper->javaTrace($ex) ); - } + } } -} +} \ No newline at end of file diff --git a/tests/acceptance/questions/MultipleChoiceNextPreviousTest.php b/tests/acceptance/questions/MultipleChoiceNextPreviousTest.php index 29b00f5ba15..b65e9a5ed1d 100644 --- a/tests/acceptance/questions/MultipleChoiceNextPreviousTest.php +++ b/tests/acceptance/questions/MultipleChoiceNextPreviousTest.php @@ -30,16 +30,14 @@ public static function setUpBeforeClass() { parent::setUpBeforeClass(); } - /** - * + * */ public function testNextPrevious() { // Import survey. $surveyFile = self::$surveysFolder . '/limesurvey_survey_583999.lss'; self::importSurvey($surveyFile); - // Go to preview. $urlMan = \Yii::app()->urlManager; $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); @@ -51,7 +49,6 @@ public function testNextPrevious() 'lang' => 'pt' ] ); - // Get questions. $survey = \Survey::model()->findByPk(self::$surveyId); $questionObjects = $survey->groups[0]->questions; @@ -59,38 +56,29 @@ public function testNextPrevious() foreach ($questionObjects as $q) { $questions[$q->title] = $q; } - try { - self::$webDriver->get($url); - // Click first checkbox. $lis = self::$webDriver->findElements(WebDriverBy::cssSelector('li label')); $this->assertCount(3, $lis); $lis[0]->click(); - // Click next. $submit = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); $submit->click(); - // Click previous.. $prev = self::$webDriver->findElement(WebDriverBy::id('ls-button-previous')); $prev->click(); sleep(1); // TODO: Does not work without this. - // Click next. $submit = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); $submit->click(); - // Click previous.. $prev = self::$webDriver->findElement(WebDriverBy::id('ls-button-previous')); $prev->click(); - // Check value of checkbox. $sgqa = self::$surveyId . 'X' . $survey->groups[0]->gid . 'X' . $questions['q2']->qid; $checkbox = self::$webDriver->findElement(WebDriverBy::id('java' . $sgqa . 'SQ001')); $this->assertEquals('Y', $checkbox->getAttribute('value')); - } catch (NoSuchElementException $ex) { $screenshot = self::$webDriver->takeScreenshot(); $filename = self::$screenshotsFolder.'/MultipleChoiceNextPreviousTest.png'; @@ -102,4 +90,4 @@ public function testNextPrevious() ); } } -} +} \ No newline at end of file diff --git a/tests/acceptance/surveys/AjaxModeTest.php b/tests/acceptance/surveys/AjaxModeTest.php index cf8b3e1971b..6c905997157 100644 --- a/tests/acceptance/surveys/AjaxModeTest.php +++ b/tests/acceptance/surveys/AjaxModeTest.php @@ -17,21 +17,17 @@ class AjaxModeTest extends TestBaseClassWeb public static function setupBeforeClass() { parent::setUpBeforeClass(); - // Import survey. $surveyFile = self::$surveysFolder . '/limesurvey_survey_366446.lss'; self::importSurvey($surveyFile); - // Activate survey. self::$testHelper->activateSurvey(self::$surveyId); } - /** * Test that Ajax mode records answer. */ public function testAjaxModeRecordsAnswer() { - // Get questions. $survey = \Survey::model()->findByPk(self::$surveyId); $questionObjects = $survey->groups[0]->questions; @@ -39,7 +35,6 @@ public function testAjaxModeRecordsAnswer() foreach ($questionObjects as $q) { $questions[$q->title] = $q; } - // Make sure there are no responses in database. $query = sprintf( 'SELECT * FROM {{survey_%d}}', @@ -48,7 +43,6 @@ public function testAjaxModeRecordsAnswer() $db = \Yii::app()->getDb(); $rows = $db->createCommand($query)->queryAll(); $this->assertEmpty($rows, 'No answers'); - // Execute survey. $urlMan = \Yii::app()->urlManager; $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); @@ -60,33 +54,26 @@ public function testAjaxModeRecordsAnswer() 'lang' => 'pt' ] ); - try { // Click welcome page. self::$webDriver->get($url); $nextButton = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); $nextButton->click(); - // Find yes-no radio buttons, click "Yes". $items = self::$webDriver->findElements(WebDriverBy::cssSelector('ul.yesno-button li')); $this->assertCount(3, $items, 'Three radio buttons for yes-no question'); $items[0]->click(); - // Check that EM is reacting. $div = self::$webDriver->findElement(WebDriverBy::cssSelector('div#question' . $questions['q2']->qid)); $this->assertEquals($div->getText(), 'The previous answer was FALSE'); - // Click "No". $items[1]->click(); - // Check EM. $div = self::$webDriver->findElement(WebDriverBy::cssSelector('div#question' . $questions['q2']->qid)); $this->assertEquals($div->getText(), 'The previous answer was TRUE'); - // Click submit. $submitButton = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); $submitButton->click(); - // Check so that we see end page. $completed = self::$webDriver->findElement(WebDriverBy::cssSelector('div.completed-text')); $this->assertEquals( @@ -104,7 +91,6 @@ public function testAjaxModeRecordsAnswer() 'Screenshot in ' .$filename . PHP_EOL . $ex->getMessage() ); } - // Check answer in database. $query = sprintf( 'SELECT * FROM {{survey_%d}}', @@ -116,4 +102,4 @@ public function testAjaxModeRecordsAnswer() $answer = $rows[0][$sgqa]; $this->assertEquals('N', $answer, 'Answer is "N"'); } -} +} \ No newline at end of file diff --git a/tests/acceptance/surveys/GroupRandomizationTest.php b/tests/acceptance/surveys/GroupRandomizationTest.php index f1e405a0a91..c956ff06e50 100644 --- a/tests/acceptance/surveys/GroupRandomizationTest.php +++ b/tests/acceptance/surveys/GroupRandomizationTest.php @@ -27,23 +27,18 @@ class GroupRandomizationTest extends TestBaseClassWeb * @var int */ public static $surveyId = null; - /** */ public static function setupBeforeClass() { parent::setupBeforeClass(); - self::$testHelper->connectToOriginalDatabase(); - \Yii::app()->session['loginID'] = 1; - - $surveyFile = self::getSurveysFolder() . '/limesurvey_survey_88881.lss'; + $surveyFile = __DIR__ . '/../data/surveys/limesurvey_survey_88881.lss'; if (!file_exists($surveyFile)) { echo 'Fatal error: found no survey file'; exit(4); } - $translateLinksFields = false; $newSurveyName = null; try { @@ -59,7 +54,6 @@ public static function setupBeforeClass() 'Could not import survey limesurvey_survey_88881.lss: ' . $ex->getMessage() ); } - if ($result) { self::$surveyId = $result['newsid']; } else { @@ -67,7 +61,6 @@ public static function setupBeforeClass() exit(5); } } - /** * Selenium setup. */ @@ -78,13 +71,11 @@ public function setUp() echo 'Must specify DOMAIN environment variable to run this test, like "DOMAIN=localhost/limesurvey" or "DOMAIN=limesurvey.localhost".'; exit(6); } - //$capabilities = DesiredCapabilities::phantomjs(); //$this->webDriver = RemoteWebDriver::create('http://localhost:4444/', $capabilities); } - /** - * + * */ public static function teardownAfterClass() { @@ -94,7 +85,6 @@ public static function teardownAfterClass() exit(8); } } - /** * Tear down fixture. */ @@ -103,20 +93,16 @@ public function tearDown() // Close Firefox. self::$webDriver->quit(); } - - /** - * + * */ public function testRunSurvey() { self::$testHelper->activateSurvey(self::$surveyId); - $domain = getenv('DOMAIN'); if (empty($domain)) { $domain = ''; } - $urlMan = \Yii::app()->urlManager; $urlMan->setBaseUrl('http://' . $domain . '/index.php'); $url = $urlMan->createUrl( @@ -127,7 +113,6 @@ public function testRunSurvey() 'lang' => 'pt' ) ); - self::$webDriver->get($url); $submit = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); $this->assertNotEmpty($submit); @@ -135,17 +120,13 @@ public function testRunSurvey() WebDriverExpectedCondition::visibilityOf($submit) ); $submit->click(); - $body = self::$webDriver->findElement(WebDriverBy::tagName('body')); $text = $body->getText(); - // There should be no PHP notice. $this->assertTrue(strpos($text, 'PHP notice') === false, $text); - // NB: This is how to take a screenshot, if necessary. //$screenshot = self::$webDriver->takeScreenshot(); //file_put_contents(__DIR__ . '/screenshot.png', $screenshot); - self::$testHelper->deactivateSurvey(self::$surveyId); } -} +} \ No newline at end of file diff --git a/tests/acceptance/surveys/MultipleChoiceWithExpressionTest.php b/tests/acceptance/surveys/MultipleChoiceWithExpressionTest.php index 819a8dcd215..c14cf355869 100644 --- a/tests/acceptance/surveys/MultipleChoiceWithExpressionTest.php +++ b/tests/acceptance/surveys/MultipleChoiceWithExpressionTest.php @@ -11,14 +11,13 @@ class MultipleChoiceWithExpressionTest extends TestBaseClassWeb { /** - * + * */ public function testBasic() { // Import survey. $surveyFile = self::$surveysFolder . '/limesurvey_survey_352985.lss'; self::importSurvey($surveyFile); - // Preview survey. $urlMan = \Yii::app()->urlManager; $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); @@ -30,7 +29,6 @@ public function testBasic() 'lang' => 'pt' ] ); - // Get questions. $survey = \Survey::model()->findByPk(self::$surveyId); $questionObjects = $survey->groups[0]->questions; @@ -43,11 +41,9 @@ public function testBasic() $subquestions[$subq->title] = $subq; } $sgqa = self::$surveyId . 'X' . $survey->groups[0]->gid . 'X' . $questions['Q1']->qid . '123'; // 123 = first subquestion title. - try { // Get first page. self::$webDriver->get($url); - // Click on first multiple choice checkbox. $label = self::$webDriver->findElement( WebDriverBy::cssSelector( @@ -58,13 +54,11 @@ public function testBasic() ) ); $label->click(); - // Check that equation reacts. $equation = self::$webDriver->findElement(WebDriverBy::id('question' . $questions['equation1']->qid)); $equestionText = $equation->getText(); $trues = substr_count($equestionText, 'true'); $this->assertEquals(2, $trues, 'Found two "true"'); - $label->click(); $equestionText = $equation->getText(); $trues = substr_count($equestionText, 'true'); @@ -77,4 +71,4 @@ public function testBasic() ); } } -} +} \ No newline at end of file diff --git a/tests/acceptance/surveys/ScreenOutTest.php b/tests/acceptance/surveys/ScreenOutTest.php index c6435514a48..6512b48e8a6 100644 --- a/tests/acceptance/surveys/ScreenOutTest.php +++ b/tests/acceptance/surveys/ScreenOutTest.php @@ -7,7 +7,7 @@ use LimeSurvey\tests\TestBaseClassWeb; /** - * Test survey when all other questions relevance is 0, due to first + * Test survey when all other questions relevance is 0, due to first * question being yes or no. * @since 2017-11-16 * @group screenout @@ -20,12 +20,10 @@ class ScreenOutTest extends TestBaseClassWeb public static function setUpBeforeClass() { parent::setUpBeforeClass(); - // Import survey. $surveyFile = self::$surveysFolder . '/limesurvey_survey_186734.lss'; self::importSurvey($surveyFile); } - /** * Test answer "No answer" on first question. */ @@ -42,18 +40,14 @@ public function testNoAnswer() 'lang' => 'pt' ] ); - try { self::$webDriver->get($url); - // Click next. $nextButton = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); $nextButton->click(); - // Check that we see completed text. $completed = self::$webDriver->findElement(WebDriverBy::cssSelector('div.completed-text')); $this->assertNotEmpty($completed); - } catch (NoSuchElementException $ex) { $screenshot = self::$webDriver->takeScreenshot(); $filename = self::$screenshotsFolder.'/ScreenOutTest.png'; @@ -65,9 +59,8 @@ public function testNoAnswer() ); } } - /** - * + * */ public function testYes() { @@ -82,7 +75,6 @@ public function testYes() 'lang' => 'pt' ] ); - // Get questions. $survey = \Survey::model()->findByPk(self::$surveyId); $questionObjects = $survey->groups[0]->questions; @@ -90,32 +82,25 @@ public function testYes() foreach ($questionObjects as $q) { $questions[$q->title] = $q; } - try { self::$webDriver->get($url); - //javatbd186734X355X1911Y $answerId = 'javatbd' . self::$surveyId . 'X' . $survey->groups[0]->gid . 'X' . $questions['q1']->qid . 'Y'; $yesButton = self::$webDriver->findElement(WebDriverBy::id($answerId)); $yesButton->click(); - // Click next. $nextButton = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); $nextButton->click(); - // answer186734X355X1912 $question2Id = 'answer' . self::$surveyId . 'X' . $survey->groups[0]->gid . 'X' . $questions['q2']->qid; $question2 = self::$webDriver->findElement(WebDriverBy::id($question2Id)); $this->assertNotEmpty($question2); - // Click next again. $nextButton = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); $nextButton->click(); - // Check that we see completed text. $completed = self::$webDriver->findElement(WebDriverBy::cssSelector('div.completed-text')); $this->assertNotEmpty($completed); - } catch (NoSuchElementException $ex) { $screenshot = self::$webDriver->takeScreenshot(); $filename = self::$screenshotsFolder.'/ScreenOutTest.png'; @@ -127,4 +112,4 @@ public function testYes() ); } } -} +} \ No newline at end of file diff --git a/tests/functional/helpers/CheckDatabaseJsonValuesTest.php b/tests/functional/helpers/CheckDatabaseJsonValuesTest.php index e4941f252f4..10161178361 100644 --- a/tests/functional/helpers/CheckDatabaseJsonValuesTest.php +++ b/tests/functional/helpers/CheckDatabaseJsonValuesTest.php @@ -11,7 +11,13 @@ */ class CheckDatabaseJsonValuesTest extends TestBaseClass { - + /** + * + */ + public static function setupBeforeClass() + { + parent::setupBeforeClass(); + } /** * Tear down fixtures. */ @@ -21,7 +27,6 @@ public static function teardownAfterClass() self::$testHelper->teardownDatabase('__test_update_helper_258'); self::$testHelper->teardownDatabase('__test_update_helper_315'); } - /** * * @throws \CException @@ -29,12 +34,10 @@ public static function teardownAfterClass() public function testCreate() { $db = \Yii::app()->getDb(); - $config = require(\Yii::app()->getBasePath() . '/config/config.php'); $version = require(\Yii::app()->getBasePath() . '/config/version.php'); $connection = self::$testHelper->connectToNewDatabase('__test_check_database_json'); $this->assertNotEmpty($connection, 'Could connect to new database'); - // Get InstallerController. $inst = new \InstallerController('foobar'); $inst->connection = \Yii::app()->db; @@ -43,55 +46,45 @@ public function testCreate() if ($result) { print_r($result); } - // Run upgrade. $result = \db_upgrade_all($version['dbversionnumber']); - // Check JSON. $this->checkMenuEntriesJson($inst->connection); $this->checkTemplateConfigurationJson($inst->connection); - // Connect to old database. $db->setActive(false); \Yii::app()->setComponent('db', $config['components']['db'], false); $db->setActive(true); } - /** - * + * */ public function testUpdateFrom258() { $connection = self::$testHelper->updateDbFromVersion(258); - // Check JSON. $this->checkMenuEntriesJson($connection); $this->checkTemplateConfigurationJson($connection); - $db = \Yii::app()->getDb(); $db->setActive(false); $config = require(\Yii::app()->getBasePath() . '/config/config.php'); \Yii::app()->setComponent('db', $config['components']['db'], false); $db->setActive(true); } - /** */ public function testUpdateFrom315() { $connection = self::$testHelper->updateDbFromVersion(315); - // Check JSON. $this->checkMenuEntriesJson($connection); $this->checkTemplateConfigurationJson($connection); - $db = \Yii::app()->getDb(); $db->setActive(false); $config = require(\Yii::app()->getBasePath() . '/config/config.php'); \Yii::app()->setComponent('db', $config['components']['db'], false); $db->setActive(true); } - /** * @param \CDbConnection $connection * @return void @@ -109,7 +102,6 @@ protected function checkMenuEntriesJson(\CDbConnection $connection) } } } - /** * @param \CDbConnection $connection * @return void @@ -139,8 +131,7 @@ protected function checkTemplateConfigurationJson(\CDbConnection $connection) } else { // Nothing to check. } - } } } -} +} \ No newline at end of file diff --git a/tests/functional/helpers/ExpressionCoreAux.php b/tests/functional/helpers/ExpressionCoreAux.php index 18fb5ebfe61..5b6c1658f70 100644 --- a/tests/functional/helpers/ExpressionCoreAux.php +++ b/tests/functional/helpers/ExpressionCoreAux.php @@ -13,42 +13,35 @@ class ExpressionCoreAux extends TestCase * @var boolean */ public $jsonEncodeEmResult = false; - /** * If true, sets onlynum = 1 in LEMvarNameAttr. * @var int */ public $onlynum = 0; - /** * @var string */ public $expression; - /** * Survey-group-question-answer code, like '123X123X123_1'. * @var string */ public $sgqa; - /** * Question type char. Defaults to 'T' = long free text. * @var string */ public $questionType = 'T'; - /** * Value of question, as in $_SESSION and . * @mixed */ public $value; - /** * Question alias. * @var string */ public $alias = 'test'; - /** * @param string $expression * @param string $sgqa @@ -62,7 +55,6 @@ public function __construct($expression, $sgqa, $questionType, $value) $this->questionType = $questionType; $this->value = $value; } - /** * @return void */ @@ -70,7 +62,6 @@ public function compareExpression() { // Input value 3. $_SESSION['survey_563168'][$this->sgqa] = $this->value; - $em = new \ExpressionManager(); $lem = \LimeExpressionManager::singleton(); $lem->setVariableAndTokenMappingsForExpressionManager('563168'); @@ -83,23 +74,16 @@ public function compareExpression() ] ] ); - $em->RDP_Evaluate($this->expression); - $emResult = $em->GetResult(); - if ($this->jsonEncodeEmResult) { $emResult = json_encode($emResult); } - $errors = $em->RDP_GetErrors(); $this->assertEmpty($errors, print_r($errors, true)); $jsOfExpression = $em->GetJavaScriptEquivalentOfExpression(); - $js = $this->getDummyNodeSetup() . $jsOfExpression; - $nodeOutput = $this->runNode($js); - $this->assertCount(1, $nodeOutput); $this->assertEquals( $emResult, @@ -114,7 +98,6 @@ public function compareExpression() ); } - /** * JS code to setup environment so LEMval() can run. * @return string @@ -126,7 +109,6 @@ public function getDummyNodeSetup() } else { $value = $this->value; } - list($surveyId, $groupId, /* questionId */) = explode('X', $this->sgqa, 3); return << 2, 2 => 'NUMBER' ]; - $dqString = [ 0 => ' ', 1 => 26, 2 => 'DQ_STRING' ]; - $em->RDP_StackPush($number); $em->RDP_StackPush($dqString); - $compare = [ 0 => '>=', 1 => 23, @@ -85,15 +78,12 @@ public function notes() ]; $noErrors = $em->RDP_EvaluateBinary($compare); $this->assertTrue($noErrors); - $result = $em->RDP_StackPop(); - $em->RDP_StackPush($number); $em->RDP_StackPush($dqString); $em->RDP_StackPush($compare); $em->SetJsVarsUsed([]); */ - /* $pageInfo = [ 'qid' => '5377', @@ -110,7 +100,6 @@ public function notes() ]; */ } - /** * @group me */ @@ -126,7 +115,6 @@ public function testNumericalQuestion() $test->compareExpression(); } } - /** * @group me2 */ @@ -141,4 +129,4 @@ public function testShortTextQuestion() $test->compareExpression(); } } -} +} \ No newline at end of file diff --git a/tests/functional/helpers/UpdateDbHelperTest.php b/tests/functional/helpers/UpdateDbHelperTest.php index 322ce1c2d9d..6cc8f0e2834 100644 --- a/tests/functional/helpers/UpdateDbHelperTest.php +++ b/tests/functional/helpers/UpdateDbHelperTest.php @@ -20,7 +20,6 @@ public static function teardownAfterClass() self::$testHelper->teardownDatabase('__test_install_script'); self::$testHelper->teardownDatabase('__test_install_script_compare'); } - /** * Run the database PHP install script. * @group install @@ -29,11 +28,9 @@ public static function teardownAfterClass() public function testInstallPhp() { $db = \Yii::app()->getDb(); - $config = require(\Yii::app()->getBasePath() . '/config/config.php'); $connection = self::$testHelper->connectToNewDatabase('__test_install_script'); $this->assertNotEmpty($connection, 'Could connect to new database'); - // Get InstallerController. $inst = new \InstallerController('foobar'); $inst->connection = \Yii::app()->db; @@ -42,7 +39,6 @@ public function testInstallPhp() if ($result) { print_r($result); } - // Dump database to file. /* $output = array(); @@ -57,13 +53,11 @@ public function testInstallPhp() $this->assertEmpty($output, 'No output from mysqldump'); $this->assertEmpty($result, 'No last line output from mysqldump'); */ - // Connect to old database. $db->setActive(false); \Yii::app()->setComponent('db', $config['components']['db'], false); $db->setActive(true); } - /** * Run db_upgrade_all() from dbversion 258, to make sure * there are no conflicts or syntax errors. @@ -73,10 +67,8 @@ public function testInstallPhp() public function testDbUpgradeFrom258() { self::$testHelper->updateDbFromVersion(258); - $db = \Yii::app()->getDb(); $config = require(\Yii::app()->getBasePath() . '/config/config.php'); - // Dump database to file. /* $output = array(); @@ -91,14 +83,11 @@ public function testDbUpgradeFrom258() $this->assertEmpty($output, 'No output from mysqldump'); $this->assertEmpty($result, 'No last line output from mysqldump'); */ - // Connect to old database. \Yii::app()->setComponent('db', $config['components']['db'], false); $db->setActive(true); - // Database is deleted in teardownAfterClass(). } - /** * @group from315 * @throws \CException @@ -106,15 +95,12 @@ public function testDbUpgradeFrom258() public function testDbUpgradeFrom315() { self::$testHelper->updateDbFromVersion(315); - $db = \Yii::app()->getDb(); $config = require(\Yii::app()->getBasePath() . '/config/config.php'); - // Connect to old database. \Yii::app()->setComponent('db', $config['components']['db'], false); $db->setActive(true); } - /** * Compare database between upgrade and fresh install. * @group dbcompare @@ -125,12 +111,10 @@ public function testCompareUpgradeAndFreshInstall() $connection = self::$testHelper->updateDbFromVersion(258); $upgradeTables = $connection->schema->getTables(); $this->compareAux($upgradeTables, 258); - $connection = self::$testHelper->updateDbFromVersion(315); $upgradeTables = $connection->schema->getTables(); $this->compareAux($upgradeTables, 315); } - /** * @param array $upgradeTables * @return void @@ -139,9 +123,7 @@ public function testCompareUpgradeAndFreshInstall() protected function compareAux(array $upgradeTables, $upgradedFrom) { $config = require(\Yii::app()->getBasePath() . '/config/config.php'); - $dbo = \Yii::app()->getDb(); - /* $config = require(\Yii::app()->getBasePath() . '/config/config.php'); // Get database name. @@ -161,15 +143,12 @@ protected function compareAux(array $upgradeTables, $upgradedFrom) ); $connection->active = true; */ - \Yii::app()->cache->flush(); - self::$testHelper->teardownDatabase('__test_install_script_compare'); $connection = self::$testHelper->connectToNewDatabase('__test_install_script_compare'); $this->assertNotEmpty($connection, 'Could not connect to new database: ' . json_encode($connection)); $connection->schemaCachingDuration = 0; // Deactivate schema caching $connection->schema->refresh(); - // Get InstallerController. $db = \Yii::app()->getDb(); $inst = new \InstallerController('foobar'); @@ -188,10 +167,8 @@ protected function compareAux(array $upgradeTables, $upgradedFrom) } $inst->connection->schema->refresh(); $freshInstallTables = $inst->connection->schema->getTables(); - $this->assertEquals(count($upgradeTables), count($freshInstallTables), 'Same number of tables'); $this->assertEquals(array_keys($upgradeTables), array_keys($freshInstallTables), 'Same number of tables'); - // Loop tables. $upgradeKeys = array_keys($upgradeTables); $freshInstallKeys = array_keys($freshInstallTables); @@ -199,10 +176,8 @@ protected function compareAux(array $upgradeTables, $upgradedFrom) $this->assertEquals($upgradeKeys[$i], $freshInstallKeys[$i]); $upgradeTable = $upgradeTables[$upgradeKeys[$i]]; $freshTable = $freshInstallTables[$freshInstallKeys[$i]]; - $upgradeColumns = $upgradeTable->columns; $freshColumns = $freshTable->columns; - // Loop columns. foreach ($upgradeColumns as $columnName => $upgradeColumn) { $upgradeColumn = (array) $upgradeColumn; @@ -226,7 +201,6 @@ protected function compareAux(array $upgradeTables, $upgradedFrom) } } } - /* Code to dump diff, but nearly useless due to collate difference. $output = array(); exec( @@ -240,10 +214,9 @@ protected function compareAux(array $upgradeTables, $upgradedFrom) $output ); */ - // Connect to old database. $dbo->setActive(false); \Yii::app()->setComponent('db', $config['components']['db'], false); $dbo->setActive(true); } -} +} \ No newline at end of file From 426c9069258f46b9d30a18d583273f666270d334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 10:31:25 +0200 Subject: [PATCH 08/20] test root files sync to master --- tests/DummyController.php | 3 +- tests/TestHelper.php | 42 ++--------- tests/WebTestCase.php | 25 ------- tests/index.html | 15 ---- tests/staticCalls.php | 144 -------------------------------------- 5 files changed, 5 insertions(+), 224 deletions(-) delete mode 100644 tests/WebTestCase.php delete mode 100644 tests/index.html delete mode 100644 tests/staticCalls.php diff --git a/tests/DummyController.php b/tests/DummyController.php index 21a5de9e473..551dda3b505 100644 --- a/tests/DummyController.php +++ b/tests/DummyController.php @@ -8,11 +8,10 @@ class DummyController extends \CController * @var string */ public $sTemplate = 'dummyvalue'; - /** * Do nothing. */ public function redirect($url, $terminate = true, $statusCode = 302) { } -} +} \ No newline at end of file diff --git a/tests/TestHelper.php b/tests/TestHelper.php index c0b899b4dbc..d6d1792b60c 100644 --- a/tests/TestHelper.php +++ b/tests/TestHelper.php @@ -14,7 +14,6 @@ class TestHelper extends TestCase { - /** * Import all helpers etc. * @return void @@ -33,7 +32,6 @@ public function importAll() \Yii::import('application.helpers.SurveyRuntimeHelper', true); \Yii::app()->loadHelper('admin/activate'); } - /** * @param string $title * @param int $surveyId @@ -48,28 +46,22 @@ public function getSgqa($title, $surveyId) 'sid' => $surveyId ] ); - $this->assertNotEmpty($question); - $group = \QuestionGroup::model()->find( 'gid = :gid', [ 'gid' => $question->gid ] ); - $this->assertNotEmpty($group); - $sgqa = sprintf( '%sX%sX%s', $surveyId, $group->gid, $question->qid ); - return [$question, $group, $sgqa]; } - /** * Get survey options for imported survey. * @param int $surveyId @@ -103,7 +95,6 @@ public function getSurveyOptions($surveyId) ); return $surveyOptions; } - /** * @param int $surveyId * @return void @@ -118,11 +109,9 @@ public function activateSurvey($surveyId) $survey->savetimings = ''; $survey->save(); \Survey::model()->resetCache(); // Make sure the saved values will be picked up - $result = \activateSurvey($surveyId); $this->assertEquals(['status' => 'OK', 'pluginFeedback' => null], $result, 'Activate survey is OK'); } - /** * @param int $surveyId * @return void @@ -138,12 +127,11 @@ public function deactivateSurvey($surveyId) $result = $survey->save(); $this->assertTrue($result, 'Survey deactivated'); } - /** * Overwrite the db component with a new * configuration and database. * Before you run this, you might want to save - * the old db config in a variable, so you can + * the old db config in a variable, so you can * reconnect to it after you're done with the new * database. * $config = require(\Yii::app()->getBasePath() . '/config/config.php'); @@ -154,9 +142,7 @@ public function deactivateSurvey($surveyId) public function connectToNewDatabase($databaseName) { $db = \Yii::app()->getDb(); - $config = require(\Yii::app()->getBasePath() . '/config/config.php'); - // Check that we're using MySQL. $conStr = \Yii::app()->db->connectionString; $isMysql = substr($conStr, 0, 5) === 'mysql'; @@ -165,12 +151,10 @@ public function connectToNewDatabase($databaseName) return false; } $this->assertTrue($isMysql, 'This test only works on MySQL'); - // Get database name. preg_match("/dbname=([^;]*)/", $config['components']['db']['connectionString'], $matches); $this->assertEquals(2, count($matches)); $oldDatabase = $matches[1]; - try { $db->createCommand('DROP DATABASE ' . $databaseName)->execute(); } catch (\CDbException $ex) { @@ -178,7 +162,6 @@ public function connectToNewDatabase($databaseName) // Only this error is OK. self::assertTrue(strpos($msg, 'database doesn\'t exist') !== false, 'Could drop database'); } - try { $result = $db->createCommand( sprintf( @@ -192,7 +175,6 @@ public function connectToNewDatabase($databaseName) // This error is OK. $this->assertTrue(strpos($msg, 'database exists') !== false, 'Could create database'); } - // Connect to new database. $db->setActive(false); $newConfig = $config; @@ -207,7 +189,6 @@ public function connectToNewDatabase($databaseName) \Yii::app()->db->schema->refresh(); return \Yii::app()->getDb(); } - /** * @return void */ @@ -220,7 +201,6 @@ public function connectToOriginalDatabase() \Yii::app()->db->schema->getTables(); \Yii::app()->db->schema->refresh(); } - /** * @param int $version * @return \CDbConnection @@ -231,22 +211,17 @@ public function updateDbFromVersion($version, $connection = null) $connection = $this->connectToNewDatabase('__test_update_helper_' . $version); $this->assertNotEmpty($connection, 'Could connect to new database'); } - // Get InstallerController. $inst = new \InstallerController('foobar'); $inst->connection = $connection; - // Check SQL file. - $file = TestBaseClass::getDataFolder() . '/sql/create-mysql.' . $version . '.sql'; + $file = __DIR__ . '/data/sql/create-mysql.' . $version . '.sql'; $this->assertFileExists($file, 'SQL file exists: ' . $file); - // Run SQL install file. $result = $inst->_executeSQLFile($file, 'lime_'); $this->assertEquals([], $result, 'No error messages from _executeSQLFile' . print_r($result, true)); - // Run upgrade. $result = \db_upgrade_all($version); - // Check error messages. $flashes = \Yii::app()->user->getFlashes(); if ($flashes) { @@ -254,10 +229,8 @@ public function updateDbFromVersion($version, $connection = null) } $this->assertEmpty($flashes, 'No flash error messages'); $this->assertTrue($result, 'Upgrade successful'); - return $inst->connection; } - /** * Make sure Selenium can preview surveys without * being logged in. @@ -267,7 +240,6 @@ public function enablePreview() { // Make sure we can preview without being logged in. $setting = \SettingGlobal::model()->findByPk('surveyPreview_require_Auth'); - // Possibly this setting does not exist yet. if (empty($setting)) { $setting = new \SettingGlobal(); @@ -279,7 +251,6 @@ public function enablePreview() $setting->save(); } } - /** * Drop database $databaseName. * Use in teardown methods. @@ -298,7 +269,7 @@ public function teardownDatabase($databaseName, $connection = null) $msg = $ex->getMessage(); // Only this error is OK. self::assertTrue( - // MySQL + // MySQL strpos($msg, 'database doesn\'t exist') !== false || // Postgres strpos($msg, "database \"$databaseName\" does not exist") !== false, @@ -306,7 +277,6 @@ public function teardownDatabase($databaseName, $connection = null) ); } } - /** * Use webdriver to put a screenshot in screenshot folder. * @param WebDriver $webDriver @@ -322,7 +292,6 @@ public function takeScreenshot($webDriver, $name) $result = file_put_contents($filename, $screenshot); $this->assertTrue($result > 0, 'Could not write screenshot to file ' . $filename); } - /** * javaTrace() - provide a Java style exception trace * @@ -374,10 +343,8 @@ public function javaTrace($ex, $seen = null) if ($prev) { $result .= "\n" . jTraceEx($prev, $seen); } - return $result; } - /** * @return WebDriver|null */ @@ -403,7 +370,6 @@ public function getWebDriver() sleep(1); } } while (!$success && $tries < 5); - return $webDriver; } -} +} \ No newline at end of file diff --git a/tests/WebTestCase.php b/tests/WebTestCase.php deleted file mode 100644 index 20eb3408e89..00000000000 --- a/tests/WebTestCase.php +++ /dev/null @@ -1,25 +0,0 @@ -setBrowserUrl(TEST_BASE_URL); - } -} diff --git a/tests/index.html b/tests/index.html deleted file mode 100644 index 233ae63b6c5..00000000000 --- a/tests/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -403 Forbidden - - - - - -

Directory access is forbidden.

- - - - \ No newline at end of file diff --git a/tests/staticCalls.php b/tests/staticCalls.php deleted file mode 100644 index f4597e7cf92..00000000000 --- a/tests/staticCalls.php +++ /dev/null @@ -1,144 +0,0 @@ -hasChildren() && !ignore($entry)) { - iterateList($i->getChildren()); - } else { - if (substr($entry, -4, 4) == '.php') { - checkFile($entry); - } - } - } -} - -// Get all static calls in file. -function checkFile($filename) -{ - if ($filename == __FILE__) { - return; - } - $file = file($filename, FILE_IGNORE_NEW_LINES); - $file = array_filter($file, "checkStatic"); - - if (!empty($file)) { - pr($filename); - print_r($file); - } -} - -function checkStatic($line) -{ - $validStatics = array( - 'Yii::', - 'parent::', - 'LimeExpressionManager::', -'Answer::', -'Question::', -'Survey::', -'QuestionGroup::', -'self::', -'PDO::', -'Participants::', -'SurveyLink::', -'ParticipantAttribute::', -'Tokens::', -'UserGroup::', -'Condition::', -'Survey_Common_Action::', -'Quota::', -'SurveyURLParameter::', -'Survey_languagesettings::', -'Permission::', -'SavedControl::', -'QuotaMember::', -'QuotaLanguageSetting::', -'ParticipantAttributeName::', -'User::', -'SurveyLanguageSetting::', -'QuestionAttribute::', -'Assessment::', -'CDbConnection::', -'ParticipantShare::', -'\'{INSERTANS::', -'DefaultValue::', -'CHtml::', -'ExpressionManager::', -'\'::\'', -'LabelSet::', -'SurveyDynamic::', -'PEAR::', -'SettingGlobal::', -'Zend_Http_Client::', -'Zend_XmlRpc_Value::', -'Zend_XmlRpc_Server_Fault::', -'Zend_XmlRpc_Value::', -'Zend_Server_Cache::', -'Zend_XmlRpc_Server_Cache::', -'Label::', -'Assessments::', -'XMLReader::', -'LEM::', -'Question::', -'DateTime::', -'Installer::', -'Session::', -'dataentry::', -'Assessments::', -'Zend_Server_Reflection::', -'Participants::', -'jsonRPCServer::', -'FailedLoginAttempt::', -'survey::', -'tokens::', -'questiongroup::', -'printanswers::', -'imagick::', -':: ', -'Assessments::', -'InstallerConfigForm::', -'Database::', -'UserInGroups::', -'Usergroups::', -'SurveyTimingDynamic::', -'::regClass', -'surveypermission::', -'Template::', -'templates::', -'register::', -'::first', -'::before', -'::after', -'::reg', -'text::', -'httpCache::' - ); - $replacements = array_pad(array(), count($validStatics), ''); - $line = str_replace($validStatics, $replacements, $line); - - return strpos($line, '::') !== false; - -} -function pr($msg) -{ - echo $msg."\n"; -} -?> From 5dfa1b1cff14fd3952d749948f04d6b2b3fbcac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 10:33:12 +0200 Subject: [PATCH 09/20] fix installationtest --- .../admin/InstallationControllerTest.php | 208 ++++++++++++++---- 1 file changed, 163 insertions(+), 45 deletions(-) diff --git a/tests/acceptance/admin/InstallationControllerTest.php b/tests/acceptance/admin/InstallationControllerTest.php index f630b58f6d6..c3f9b696c5a 100644 --- a/tests/acceptance/admin/InstallationControllerTest.php +++ b/tests/acceptance/admin/InstallationControllerTest.php @@ -13,63 +13,181 @@ namespace LimeSurvey\tests\acceptance\admin; -use Facebook\WebDriver\WebDriverBy; -use LimeSurvey\tests\TestBaseClassWeb; +use LimeSurvey\tests\DummyController; +use LimeSurvey\tests\TestBaseClass; /** - * @since 2017-10-15 - * @group tempcontr - * @group template + * @since 2017-11-24 + * @group inst */ -class TemplateControllerTest extends TestBaseClass +class InstallationControllerTest extends TestBaseClassWeb { /** - * Test copy a template. - * @group copytemplate + * */ - public function testCopyTemplate() + public static function setupBeforeClass() { - \Yii::app()->session['loginID'] = 1; - \Yii::import('application.controllers.admin.themes', true); - \Yii::import('application.helpers.globalsettings_helper', true); - // Clean up from last test. - $templateName = 'foobartest'; - \TemplateConfiguration::uninstall($templateName); - \Template::model()->deleteAll('name = \'foobartest\''); - \Permission::model()->deleteAllByAttributes(array('permission' => $templateName,'entity' => 'template')); - // Remove folder from last test. - $newname = 'foobartest'; - $newdirname = \Yii::app()->getConfig('userthemerootdir') . "/" . $newname; - if (file_exists($newdirname)) { - exec('rm -r ' . $newdirname); + // NB: Does not call parent, because there might not + // be a database (happens if this test is run multiple + // times with failures). + self::$testHelper = new TestHelper(); + self::$webDriver = self::$testHelper->getWebDriver(); + self::$domain = getenv('DOMAIN'); + } + /** + * + */ + public static function teardownAfterClass() + { + $configFile = \Yii::app()->getBasePath() . '/config/config.php'; + if (file_exists($configFile)) { + self::$testHelper->connectToOriginalDatabase(); } - $config = require(\Yii::app()->getBasePath() . '/config/config-defaults.php'); - // Simulate a POST. - $_POST['newname'] = $newname; - // NB: If default theme is not installed, this test will fail. - $_POST['copydir'] = $config['defaulttheme']; - $_SERVER['SERVER_NAME'] = 'localhost'; - $contr = new \themes(new \ls\tests\DummyController('dummyid')); - $contr->templatecopy(); - $flashes = \Yii::app()->user->getFlashes(); - $this->assertEmpty($flashes, 'No flash messages'); - $template = \Template::model()->find( - sprintf( - 'name = \'%s\'', - $templateName - ) - ); - $this->assertNotEmpty($template); - $this->assertEquals($templateName, $template->name); - // Clean up. - \Template::model()->deleteAll('name = \'foobartest\''); } /** - * @todo Copy template folder that does not exist. + * + * @throws \CException */ - /* - public function testCopyWrongFolder() + public function testBasic() { + //$this->checkFolders(); + $configFile = \Yii::app()->getBasePath() . '/config/config.php'; + $databaseName = 'limesurvey'; + $username = getenv('ADMINUSERNAME'); + if (!$username) { + $username = 'admin'; + } + $password = getenv('PASSWORD'); + if (!$password) { + $password = 'password'; + } + $dbuser = getenv('DBUSER'); + if (!$dbuser) { + $dbuser = 'root'; + echo 'Default to database user "root". Use DBUSER=... from command-line to override this.' . PHP_EOL; + } + $dbpwd = getenv('DBPASSWORD'); + if (!$dbpwd) { + $dbpwd = ''; + echo 'Default to empty database password. Use DBPASSWORD=... from command-line to override this.' . PHP_EOL; + } + if (file_exists($configFile)) { + // Delete possible previous database. + try { + $dbo = \Yii::app()->getDb(); + $dbo->createCommand('DROP DATABASE ' . $databaseName)->execute(); + } catch (\CDbException $ex) { + $msg = $ex->getMessage(); + // Only this error is OK. + self::assertTrue( + strpos($msg, "database doesn't exist") !== false, + 'Could drop database. Error message: ' . $msg + ); + } + // Remove config.php if present. + $result = unlink($configFile); + $this->assertTrue($result, 'Could unlink config.php'); + } + // Run installer. + $urlMan = \Yii::app()->urlManager; + $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); + $url = $urlMan->createUrl(''); + try { + // Installer start page. + self::$webDriver->get($url); + // Click "Start installation". + $start = self::$webDriver->findElement(WebDriverBy::id('ls-start-installation')); + $start->click(); + // Accept license. + $accept = self::$webDriver->findElement(WebDriverBy::id('ls-accept-license')); + $accept->click(); + // Click next at pre-check. + $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); + $next->click(); + // Fill in database form. + $dbuserDbType = self::$webDriver->findElement(WebDriverBy::cssSelector('select[name="InstallerConfigForm[dbtype]"] option[value="mysql"]')); + $dbuserInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbuser]"]')); + $dbpwdInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbpwd]"]')); + $dbnameInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbname]"]')); + + $dbuserDbType->click(); + $dbuserInput->clear()->sendKeys($dbuser); + $dbpwdInput->clear()->sendKeys($dbpwd); + $dbnameInput->sendKeys($databaseName); + // Click next. + $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); + $next->click(); + // Click "Create database". + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + // Click "Populate". + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + // Fill in admin username/password. + $adminLoginName = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginName]"]')); + $adminLoginPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginPwd]"]')); + $confirmPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[confirmPwd]"]')); + $adminLoginName->clear()->sendKeys($username); + $adminLoginPwd->clear()->sendKeys($password); + $confirmPwd->clear()->sendKeys($password); + // Confirm optional settings (admin password etc). + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + // Go to administration. + $button = self::$webDriver->findElement(WebDriverBy::id('ls-administration')); + $button->click(); + // Set debug=2 + /* TODO: Can't write to config.php after installation. + $configFile = \Yii::app()->getBasePath() . '/config/config.php'; + $data = file($configFile); + $data = array_map(function($data) { + return stristr($data, "'debug'=>0") ? "'debug'=>2," : $data; + }, $data); + $output = []; + exec('chmod 777 ' . $configFile, $output); + var_dump($output); + $result = file_put_contents($configFile, implode('', $data)); + $this->assertTrue($result > 0, 'Wrote config'); + */ + // Reset urlManager to adapt to latest config. + $config = require($configFile); + $urlMan = \Yii::app()->urlManager; + $urlMan->setUrlFormat($config['components']['urlManager']['urlFormat']); + // Login. + self::adminLogin($username, $password); + } catch (NoSuchElementException $ex) { + self::$testHelper->takeScreenshot(self::$webDriver, (new \ReflectionClass($this))->getShortName() . '_' . __FUNCTION__); + $this->assertFalse( + true, + self::$testHelper->javaTrace($ex) + ); + } } + /** + * Check that upload/tmp folders are writable. + * @todo Does not work. */ + public function checkFolders() + { + $instContr = new \InstallerController('dummyvalue'); + $data = []; + $folder = \Yii::app()->getConfig('tempdir') . '/'; + $tempdirIsWritable = $instContr->checkDirectoryWriteable( + $folder, + $data, + 'tmpdir', + 'tperror', + true + ); + $this->assertTrue($tempdirIsWritable, 'Can write to tmp/'); + $folder = \Yii::app()->getConfig('uploaddir') . '/'; + $uploadIsWritable = $instContr->checkDirectoryWriteable( + $folder, + $data, + 'uploaddir', + 'uerror', + true + ); + $this->assertTrue($uploadIsWritable, 'Can write to upload/'); + } } \ No newline at end of file From 3b0a06a1ca9f834067569b6d09e91a7424f8b33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 10:35:41 +0200 Subject: [PATCH 10/20] fix installationtest 2 --- tests/acceptance/admin/InstallationControllerTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/acceptance/admin/InstallationControllerTest.php b/tests/acceptance/admin/InstallationControllerTest.php index c3f9b696c5a..5e2148a9b47 100644 --- a/tests/acceptance/admin/InstallationControllerTest.php +++ b/tests/acceptance/admin/InstallationControllerTest.php @@ -13,8 +13,7 @@ namespace LimeSurvey\tests\acceptance\admin; -use LimeSurvey\tests\DummyController; -use LimeSurvey\tests\TestBaseClass; +use LimeSurvey\tests\TestBaseClassWeb; /** * @since 2017-11-24 From 32d53d334908b60a6cadb1836f20f44b3152926d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 10:38:14 +0200 Subject: [PATCH 11/20] fix installationtest imports --- tests/acceptance/admin/InstallationControllerTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/acceptance/admin/InstallationControllerTest.php b/tests/acceptance/admin/InstallationControllerTest.php index 5e2148a9b47..c1d7d431736 100644 --- a/tests/acceptance/admin/InstallationControllerTest.php +++ b/tests/acceptance/admin/InstallationControllerTest.php @@ -14,6 +14,9 @@ namespace LimeSurvey\tests\acceptance\admin; use LimeSurvey\tests\TestBaseClassWeb; +use LimeSurvey\tests\TestHelper; +use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\Exception\NoSuchElementException; /** * @since 2017-11-24 From 2dd02fe6242ae616ad4218e4496b4541902145e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 10:45:19 +0200 Subject: [PATCH 12/20] fix paths --- tests/acceptance/surveys/GroupRandomizationTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/acceptance/surveys/GroupRandomizationTest.php b/tests/acceptance/surveys/GroupRandomizationTest.php index c956ff06e50..dc1b574afbe 100644 --- a/tests/acceptance/surveys/GroupRandomizationTest.php +++ b/tests/acceptance/surveys/GroupRandomizationTest.php @@ -34,7 +34,7 @@ public static function setupBeforeClass() parent::setupBeforeClass(); self::$testHelper->connectToOriginalDatabase(); \Yii::app()->session['loginID'] = 1; - $surveyFile = __DIR__ . '/../data/surveys/limesurvey_survey_88881.lss'; + $surveyFile = self::getSurveysFolder().'/limesurvey_survey_88881.lss'; if (!file_exists($surveyFile)) { echo 'Fatal error: found no survey file'; exit(4); From 201d4152d3a9061b50551622aa88a8a7844b606c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 10:53:16 +0200 Subject: [PATCH 13/20] fix paths 2 --- tests/TestHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/TestHelper.php b/tests/TestHelper.php index d6d1792b60c..19b27e9e908 100644 --- a/tests/TestHelper.php +++ b/tests/TestHelper.php @@ -215,7 +215,7 @@ public function updateDbFromVersion($version, $connection = null) $inst = new \InstallerController('foobar'); $inst->connection = $connection; // Check SQL file. - $file = __DIR__ . '/data/sql/create-mysql.' . $version . '.sql'; + $file = TestBaseClass::getDataFolder().'/sql/create-mysql.' . $version . '.sql'; $this->assertFileExists($file, 'SQL file exists: ' . $file); // Run SQL install file. $result = $inst->_executeSQLFile($file, 'lime_'); From e80d2d3f530c2b20809e4f83697f66e8ed5d5c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 11:15:34 +0200 Subject: [PATCH 14/20] resoleve conflict on installationTest --- .../admin/InstallationControllerTest.php | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/tests/acceptance/admin/InstallationControllerTest.php b/tests/acceptance/admin/InstallationControllerTest.php index c1d7d431736..a814c263950 100644 --- a/tests/acceptance/admin/InstallationControllerTest.php +++ b/tests/acceptance/admin/InstallationControllerTest.php @@ -1,22 +1,11 @@ getWebDriver(); self::$domain = getenv('DOMAIN'); } + /** * */ @@ -46,6 +36,7 @@ public static function teardownAfterClass() self::$testHelper->connectToOriginalDatabase(); } } + /** * * @throws \CException @@ -53,8 +44,10 @@ public static function teardownAfterClass() public function testBasic() { //$this->checkFolders(); + $configFile = \Yii::app()->getBasePath() . '/config/config.php'; $databaseName = 'limesurvey'; + $username = getenv('ADMINUSERNAME'); if (!$username) { $username = 'admin'; @@ -63,6 +56,7 @@ public function testBasic() if (!$password) { $password = 'password'; } + $dbuser = getenv('DBUSER'); if (!$dbuser) { $dbuser = 'root'; @@ -73,6 +67,7 @@ public function testBasic() $dbpwd = ''; echo 'Default to empty database password. Use DBPASSWORD=... from command-line to override this.' . PHP_EOL; } + if (file_exists($configFile)) { // Delete possible previous database. try { @@ -86,26 +81,34 @@ public function testBasic() 'Could drop database. Error message: ' . $msg ); } + // Remove config.php if present. $result = unlink($configFile); $this->assertTrue($result, 'Could unlink config.php'); } + // Run installer. $urlMan = \Yii::app()->urlManager; $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); $url = $urlMan->createUrl(''); + try { + // Installer start page. self::$webDriver->get($url); + // Click "Start installation". $start = self::$webDriver->findElement(WebDriverBy::id('ls-start-installation')); $start->click(); + // Accept license. $accept = self::$webDriver->findElement(WebDriverBy::id('ls-accept-license')); $accept->click(); + // Click next at pre-check. $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); $next->click(); + // Fill in database form. $dbuserDbType = self::$webDriver->findElement(WebDriverBy::cssSelector('select[name="InstallerConfigForm[dbtype]"] option[value="mysql"]')); $dbuserInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbuser]"]')); @@ -116,15 +119,19 @@ public function testBasic() $dbuserInput->clear()->sendKeys($dbuser); $dbpwdInput->clear()->sendKeys($dbpwd); $dbnameInput->sendKeys($databaseName); + // Click next. $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); $next->click(); + // Click "Create database". $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); $button->click(); + // Click "Populate". $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); $button->click(); + // Fill in admin username/password. $adminLoginName = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginName]"]')); $adminLoginPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginPwd]"]')); @@ -132,12 +139,15 @@ public function testBasic() $adminLoginName->clear()->sendKeys($username); $adminLoginPwd->clear()->sendKeys($password); $confirmPwd->clear()->sendKeys($password); + // Confirm optional settings (admin password etc). $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); $button->click(); + // Go to administration. $button = self::$webDriver->findElement(WebDriverBy::id('ls-administration')); $button->click(); + // Set debug=2 /* TODO: Can't write to config.php after installation. $configFile = \Yii::app()->getBasePath() . '/config/config.php'; @@ -151,10 +161,12 @@ public function testBasic() $result = file_put_contents($configFile, implode('', $data)); $this->assertTrue($result > 0, 'Wrote config'); */ + // Reset urlManager to adapt to latest config. $config = require($configFile); $urlMan = \Yii::app()->urlManager; $urlMan->setUrlFormat($config['components']['urlManager']['urlFormat']); + // Login. self::adminLogin($username, $password); } catch (NoSuchElementException $ex) { @@ -165,6 +177,7 @@ public function testBasic() ); } } + /** * Check that upload/tmp folders are writable. * @todo Does not work. @@ -182,6 +195,7 @@ public function checkFolders() true ); $this->assertTrue($tempdirIsWritable, 'Can write to tmp/'); + $folder = \Yii::app()->getConfig('uploaddir') . '/'; $uploadIsWritable = $instContr->checkDirectoryWriteable( $folder, @@ -192,4 +206,4 @@ public function checkFolders() ); $this->assertTrue($uploadIsWritable, 'Can write to upload/'); } -} \ No newline at end of file +} From ab69d9625a9796dc52b33edc53b511fc41d77163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 11:25:06 +0200 Subject: [PATCH 15/20] resolve conflict on installationTest huh? --- .../InstallationControllerTest.php | 206 ++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 tests/controllers/InstallationControllerTest.php diff --git a/tests/controllers/InstallationControllerTest.php b/tests/controllers/InstallationControllerTest.php new file mode 100644 index 00000000000..c5ab66179de --- /dev/null +++ b/tests/controllers/InstallationControllerTest.php @@ -0,0 +1,206 @@ +getWebDriver(); + self::$domain = getenv('DOMAIN'); + } + + /** + * + */ + public static function teardownAfterClass() + { + $configFile = \Yii::app()->getBasePath() . '/config/config.php'; + if (file_exists($configFile)) { + self::$testHelper->connectToOriginalDatabase(); + } + } + + /** + * + * @throws \CException + */ + public function testBasic() + { + //$this->checkFolders(); + + $configFile = \Yii::app()->getBasePath() . '/config/config.php'; + $databaseName = 'limesurvey'; + + $username = getenv('ADMINUSERNAME'); + if (!$username) { + $username = 'admin'; + } + $password = getenv('PASSWORD'); + if (!$password) { + $password = 'password'; + } + + $dbuser = getenv('DBUSER'); + if (!$dbuser) { + $dbuser = 'root'; + echo 'Default to database user "root". Use DBUSER=... from command-line to override this.' . PHP_EOL; + } + $dbpwd = getenv('DBPASSWORD'); + if (!$dbpwd) { + $dbpwd = ''; + echo 'Default to empty database password. Use DBPASSWORD=... from command-line to override this.' . PHP_EOL; + } + + if (file_exists($configFile)) { + // Delete possible previous database. + try { + $dbo = \Yii::app()->getDb(); + $dbo->createCommand('DROP DATABASE ' . $databaseName)->execute(); + } catch (\CDbException $ex) { + $msg = $ex->getMessage(); + // Only this error is OK. + self::assertTrue( + strpos($msg, "database doesn't exist") !== false, + 'Could drop database. Error message: ' . $msg + ); + } + + // Remove config.php if present. + $result = unlink($configFile); + $this->assertTrue($result, 'Could unlink config.php'); + } + + // Run installer. + $urlMan = \Yii::app()->urlManager; + $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); + $url = $urlMan->createUrl(''); + + try { + + // Installer start page. + self::$webDriver->get($url); + + // Click "Start installation". + $start = self::$webDriver->findElement(WebDriverBy::id('ls-start-installation')); + $start->click(); + + // Accept license. + $accept = self::$webDriver->findElement(WebDriverBy::id('ls-accept-license')); + $accept->click(); + + // Click next at pre-check. + $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); + $next->click(); + + // Fill in database form. + $dbuserDbType = self::$webDriver->findElement(WebDriverBy::cssSelector('select[name="InstallerConfigForm[dbtype]"] option[value="mysql"]')); + $dbuserInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbuser]"]')); + $dbpwdInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbpwd]"]')); + $dbnameInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbname]"]')); + + $dbuserDbType->click(); + $dbuserInput->clear()->sendKeys($dbuser); + $dbpwdInput->clear()->sendKeys($dbpwd); + $dbnameInput->sendKeys($databaseName); + + // Click next. + $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); + $next->click(); + + // Click "Create database". + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + + // Click "Populate". + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + + // Fill in admin username/password. + $adminLoginName = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginName]"]')); + $adminLoginPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginPwd]"]')); + $confirmPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[confirmPwd]"]')); + $adminLoginName->clear()->sendKeys($username); + $adminLoginPwd->clear()->sendKeys($password); + $confirmPwd->clear()->sendKeys($password); + + // Confirm optional settings (admin password etc). + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + + // Go to administration. + $button = self::$webDriver->findElement(WebDriverBy::id('ls-administration')); + $button->click(); + + // Set debug=2 + /* TODO: Can't write to config.php after installation. + $configFile = \Yii::app()->getBasePath() . '/config/config.php'; + $data = file($configFile); + $data = array_map(function($data) { + return stristr($data, "'debug'=>0") ? "'debug'=>2," : $data; + }, $data); + $output = []; + exec('chmod 777 ' . $configFile, $output); + var_dump($output); + $result = file_put_contents($configFile, implode('', $data)); + $this->assertTrue($result > 0, 'Wrote config'); + */ + + // Reset urlManager to adapt to latest config. + $config = require($configFile); + $urlMan = \Yii::app()->urlManager; + $urlMan->setUrlFormat($config['components']['urlManager']['urlFormat']); + + // Login. + self::adminLogin($username, $password); + } catch (NoSuchElementException $ex) { + self::$testHelper->takeScreenshot(self::$webDriver, (new \ReflectionClass($this))->getShortName() . '_' . __FUNCTION__); + $this->assertFalse( + true, + self::$testHelper->javaTrace($ex) + ); + } + } + + /** + * Check that upload/tmp folders are writable. + * @todo Does not work. + */ + public function checkFolders() + { + $instContr = new \InstallerController('dummyvalue'); + $data = []; + $folder = \Yii::app()->getConfig('tempdir') . '/'; + $tempdirIsWritable = $instContr->checkDirectoryWriteable( + $folder, + $data, + 'tmpdir', + 'tperror', + true + ); + $this->assertTrue($tempdirIsWritable, 'Can write to tmp/'); + + $folder = \Yii::app()->getConfig('uploaddir') . '/'; + $uploadIsWritable = $instContr->checkDirectoryWriteable( + $folder, + $data, + 'uploaddir', + 'uerror', + true + ); + $this->assertTrue($uploadIsWritable, 'Can write to upload/'); + } +} From d46f6a89f985b315c7c24293aa6c6d5022db122c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 11:27:17 +0200 Subject: [PATCH 16/20] resolve conflict on installationTest clean old test --- .../InstallationControllerTest.php | 195 +----------------- 1 file changed, 1 insertion(+), 194 deletions(-) diff --git a/tests/controllers/InstallationControllerTest.php b/tests/controllers/InstallationControllerTest.php index c5ab66179de..5297590513c 100644 --- a/tests/controllers/InstallationControllerTest.php +++ b/tests/controllers/InstallationControllerTest.php @@ -8,199 +8,6 @@ * @since 2017-11-24 * @group inst */ -class InstallationControllerTest extends TestBaseClassWeb +class InstallationControllerTest { - /** - * - */ - public static function setupBeforeClass() - { - // NB: Does not call parent, because there might not - // be a database (happens if this test is run multiple - // times with failures). - self::$testHelper = new TestHelper(); - self::$webDriver = self::$testHelper->getWebDriver(); - self::$domain = getenv('DOMAIN'); - } - - /** - * - */ - public static function teardownAfterClass() - { - $configFile = \Yii::app()->getBasePath() . '/config/config.php'; - if (file_exists($configFile)) { - self::$testHelper->connectToOriginalDatabase(); - } - } - - /** - * - * @throws \CException - */ - public function testBasic() - { - //$this->checkFolders(); - - $configFile = \Yii::app()->getBasePath() . '/config/config.php'; - $databaseName = 'limesurvey'; - - $username = getenv('ADMINUSERNAME'); - if (!$username) { - $username = 'admin'; - } - $password = getenv('PASSWORD'); - if (!$password) { - $password = 'password'; - } - - $dbuser = getenv('DBUSER'); - if (!$dbuser) { - $dbuser = 'root'; - echo 'Default to database user "root". Use DBUSER=... from command-line to override this.' . PHP_EOL; - } - $dbpwd = getenv('DBPASSWORD'); - if (!$dbpwd) { - $dbpwd = ''; - echo 'Default to empty database password. Use DBPASSWORD=... from command-line to override this.' . PHP_EOL; - } - - if (file_exists($configFile)) { - // Delete possible previous database. - try { - $dbo = \Yii::app()->getDb(); - $dbo->createCommand('DROP DATABASE ' . $databaseName)->execute(); - } catch (\CDbException $ex) { - $msg = $ex->getMessage(); - // Only this error is OK. - self::assertTrue( - strpos($msg, "database doesn't exist") !== false, - 'Could drop database. Error message: ' . $msg - ); - } - - // Remove config.php if present. - $result = unlink($configFile); - $this->assertTrue($result, 'Could unlink config.php'); - } - - // Run installer. - $urlMan = \Yii::app()->urlManager; - $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); - $url = $urlMan->createUrl(''); - - try { - - // Installer start page. - self::$webDriver->get($url); - - // Click "Start installation". - $start = self::$webDriver->findElement(WebDriverBy::id('ls-start-installation')); - $start->click(); - - // Accept license. - $accept = self::$webDriver->findElement(WebDriverBy::id('ls-accept-license')); - $accept->click(); - - // Click next at pre-check. - $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); - $next->click(); - - // Fill in database form. - $dbuserDbType = self::$webDriver->findElement(WebDriverBy::cssSelector('select[name="InstallerConfigForm[dbtype]"] option[value="mysql"]')); - $dbuserInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbuser]"]')); - $dbpwdInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbpwd]"]')); - $dbnameInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbname]"]')); - - $dbuserDbType->click(); - $dbuserInput->clear()->sendKeys($dbuser); - $dbpwdInput->clear()->sendKeys($dbpwd); - $dbnameInput->sendKeys($databaseName); - - // Click next. - $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); - $next->click(); - - // Click "Create database". - $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); - $button->click(); - - // Click "Populate". - $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); - $button->click(); - - // Fill in admin username/password. - $adminLoginName = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginName]"]')); - $adminLoginPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginPwd]"]')); - $confirmPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[confirmPwd]"]')); - $adminLoginName->clear()->sendKeys($username); - $adminLoginPwd->clear()->sendKeys($password); - $confirmPwd->clear()->sendKeys($password); - - // Confirm optional settings (admin password etc). - $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); - $button->click(); - - // Go to administration. - $button = self::$webDriver->findElement(WebDriverBy::id('ls-administration')); - $button->click(); - - // Set debug=2 - /* TODO: Can't write to config.php after installation. - $configFile = \Yii::app()->getBasePath() . '/config/config.php'; - $data = file($configFile); - $data = array_map(function($data) { - return stristr($data, "'debug'=>0") ? "'debug'=>2," : $data; - }, $data); - $output = []; - exec('chmod 777 ' . $configFile, $output); - var_dump($output); - $result = file_put_contents($configFile, implode('', $data)); - $this->assertTrue($result > 0, 'Wrote config'); - */ - - // Reset urlManager to adapt to latest config. - $config = require($configFile); - $urlMan = \Yii::app()->urlManager; - $urlMan->setUrlFormat($config['components']['urlManager']['urlFormat']); - - // Login. - self::adminLogin($username, $password); - } catch (NoSuchElementException $ex) { - self::$testHelper->takeScreenshot(self::$webDriver, (new \ReflectionClass($this))->getShortName() . '_' . __FUNCTION__); - $this->assertFalse( - true, - self::$testHelper->javaTrace($ex) - ); - } - } - - /** - * Check that upload/tmp folders are writable. - * @todo Does not work. - */ - public function checkFolders() - { - $instContr = new \InstallerController('dummyvalue'); - $data = []; - $folder = \Yii::app()->getConfig('tempdir') . '/'; - $tempdirIsWritable = $instContr->checkDirectoryWriteable( - $folder, - $data, - 'tmpdir', - 'tperror', - true - ); - $this->assertTrue($tempdirIsWritable, 'Can write to tmp/'); - - $folder = \Yii::app()->getConfig('uploaddir') . '/'; - $uploadIsWritable = $instContr->checkDirectoryWriteable( - $folder, - $data, - 'uploaddir', - 'uerror', - true - ); - $this->assertTrue($uploadIsWritable, 'Can write to upload/'); - } } From 6e454625cd824d51c84df947112acacef95bc04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 11:28:12 +0200 Subject: [PATCH 17/20] resolve conflict on installationTest put back old test --- .../InstallationControllerTest.php | 195 +++++++++++++++++- 1 file changed, 194 insertions(+), 1 deletion(-) diff --git a/tests/controllers/InstallationControllerTest.php b/tests/controllers/InstallationControllerTest.php index 5297590513c..c5ab66179de 100644 --- a/tests/controllers/InstallationControllerTest.php +++ b/tests/controllers/InstallationControllerTest.php @@ -8,6 +8,199 @@ * @since 2017-11-24 * @group inst */ -class InstallationControllerTest +class InstallationControllerTest extends TestBaseClassWeb { + /** + * + */ + public static function setupBeforeClass() + { + // NB: Does not call parent, because there might not + // be a database (happens if this test is run multiple + // times with failures). + self::$testHelper = new TestHelper(); + self::$webDriver = self::$testHelper->getWebDriver(); + self::$domain = getenv('DOMAIN'); + } + + /** + * + */ + public static function teardownAfterClass() + { + $configFile = \Yii::app()->getBasePath() . '/config/config.php'; + if (file_exists($configFile)) { + self::$testHelper->connectToOriginalDatabase(); + } + } + + /** + * + * @throws \CException + */ + public function testBasic() + { + //$this->checkFolders(); + + $configFile = \Yii::app()->getBasePath() . '/config/config.php'; + $databaseName = 'limesurvey'; + + $username = getenv('ADMINUSERNAME'); + if (!$username) { + $username = 'admin'; + } + $password = getenv('PASSWORD'); + if (!$password) { + $password = 'password'; + } + + $dbuser = getenv('DBUSER'); + if (!$dbuser) { + $dbuser = 'root'; + echo 'Default to database user "root". Use DBUSER=... from command-line to override this.' . PHP_EOL; + } + $dbpwd = getenv('DBPASSWORD'); + if (!$dbpwd) { + $dbpwd = ''; + echo 'Default to empty database password. Use DBPASSWORD=... from command-line to override this.' . PHP_EOL; + } + + if (file_exists($configFile)) { + // Delete possible previous database. + try { + $dbo = \Yii::app()->getDb(); + $dbo->createCommand('DROP DATABASE ' . $databaseName)->execute(); + } catch (\CDbException $ex) { + $msg = $ex->getMessage(); + // Only this error is OK. + self::assertTrue( + strpos($msg, "database doesn't exist") !== false, + 'Could drop database. Error message: ' . $msg + ); + } + + // Remove config.php if present. + $result = unlink($configFile); + $this->assertTrue($result, 'Could unlink config.php'); + } + + // Run installer. + $urlMan = \Yii::app()->urlManager; + $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); + $url = $urlMan->createUrl(''); + + try { + + // Installer start page. + self::$webDriver->get($url); + + // Click "Start installation". + $start = self::$webDriver->findElement(WebDriverBy::id('ls-start-installation')); + $start->click(); + + // Accept license. + $accept = self::$webDriver->findElement(WebDriverBy::id('ls-accept-license')); + $accept->click(); + + // Click next at pre-check. + $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); + $next->click(); + + // Fill in database form. + $dbuserDbType = self::$webDriver->findElement(WebDriverBy::cssSelector('select[name="InstallerConfigForm[dbtype]"] option[value="mysql"]')); + $dbuserInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbuser]"]')); + $dbpwdInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbpwd]"]')); + $dbnameInput = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[dbname]"]')); + + $dbuserDbType->click(); + $dbuserInput->clear()->sendKeys($dbuser); + $dbpwdInput->clear()->sendKeys($dbpwd); + $dbnameInput->sendKeys($databaseName); + + // Click next. + $next = self::$webDriver->findElement(WebDriverBy::id('ls-next')); + $next->click(); + + // Click "Create database". + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + + // Click "Populate". + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + + // Fill in admin username/password. + $adminLoginName = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginName]"]')); + $adminLoginPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[adminLoginPwd]"]')); + $confirmPwd = self::$webDriver->findElement(WebDriverBy::cssSelector('input[name="InstallerConfigForm[confirmPwd]"]')); + $adminLoginName->clear()->sendKeys($username); + $adminLoginPwd->clear()->sendKeys($password); + $confirmPwd->clear()->sendKeys($password); + + // Confirm optional settings (admin password etc). + $button = self::$webDriver->findElement(WebDriverBy::cssSelector('input[type="submit"]')); + $button->click(); + + // Go to administration. + $button = self::$webDriver->findElement(WebDriverBy::id('ls-administration')); + $button->click(); + + // Set debug=2 + /* TODO: Can't write to config.php after installation. + $configFile = \Yii::app()->getBasePath() . '/config/config.php'; + $data = file($configFile); + $data = array_map(function($data) { + return stristr($data, "'debug'=>0") ? "'debug'=>2," : $data; + }, $data); + $output = []; + exec('chmod 777 ' . $configFile, $output); + var_dump($output); + $result = file_put_contents($configFile, implode('', $data)); + $this->assertTrue($result > 0, 'Wrote config'); + */ + + // Reset urlManager to adapt to latest config. + $config = require($configFile); + $urlMan = \Yii::app()->urlManager; + $urlMan->setUrlFormat($config['components']['urlManager']['urlFormat']); + + // Login. + self::adminLogin($username, $password); + } catch (NoSuchElementException $ex) { + self::$testHelper->takeScreenshot(self::$webDriver, (new \ReflectionClass($this))->getShortName() . '_' . __FUNCTION__); + $this->assertFalse( + true, + self::$testHelper->javaTrace($ex) + ); + } + } + + /** + * Check that upload/tmp folders are writable. + * @todo Does not work. + */ + public function checkFolders() + { + $instContr = new \InstallerController('dummyvalue'); + $data = []; + $folder = \Yii::app()->getConfig('tempdir') . '/'; + $tempdirIsWritable = $instContr->checkDirectoryWriteable( + $folder, + $data, + 'tmpdir', + 'tperror', + true + ); + $this->assertTrue($tempdirIsWritable, 'Can write to tmp/'); + + $folder = \Yii::app()->getConfig('uploaddir') . '/'; + $uploadIsWritable = $instContr->checkDirectoryWriteable( + $folder, + $data, + 'uploaddir', + 'uerror', + true + ); + $this->assertTrue($uploadIsWritable, 'Can write to upload/'); + } } From a7a00e1de63e94edebbcd745b4077bb096f05f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 11 Jan 2018 11:28:52 +0200 Subject: [PATCH 18/20] resolve conflict on installationTest put back old test --- tests/controllers/InstallationControllerTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/controllers/InstallationControllerTest.php b/tests/controllers/InstallationControllerTest.php index c5ab66179de..452206d37ac 100644 --- a/tests/controllers/InstallationControllerTest.php +++ b/tests/controllers/InstallationControllerTest.php @@ -4,6 +4,9 @@ use Facebook\WebDriver\WebDriverBy; use Facebook\WebDriver\Exception\NoSuchElementException; +use LimeSurvey\tests\TestBaseClassWeb; +use LimeSurvey\tests\TestHelper; + /** * @since 2017-11-24 * @group inst From af3c24cb36bf859109b2d1889fdf17b9b0c88da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Fri, 12 Jan 2018 12:42:08 +0200 Subject: [PATCH 19/20] get ajaxtest from master --- tests/acceptance/surveys/AjaxModeTest.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/acceptance/surveys/AjaxModeTest.php b/tests/acceptance/surveys/AjaxModeTest.php index 6c905997157..2826b416a96 100644 --- a/tests/acceptance/surveys/AjaxModeTest.php +++ b/tests/acceptance/surveys/AjaxModeTest.php @@ -28,6 +28,10 @@ public static function setupBeforeClass() */ public function testAjaxModeRecordsAnswer() { + // TODO: This works when run individually, but not + // as part of the test suit. Screenshot shows it's + // stuck on welcome page. + $this->markTestSkipped(); // Get questions. $survey = \Survey::model()->findByPk(self::$surveyId); $questionObjects = $survey->groups[0]->questions; @@ -59,6 +63,11 @@ public function testAjaxModeRecordsAnswer() self::$webDriver->get($url); $nextButton = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); $nextButton->click(); + sleep(1); + // TODO: Temporary, test fails here (but only on fresh install). + $screenshot = self::$webDriver->takeScreenshot(); + $filename = self::$screenshotsFolder.'/AjaxModeTest.png'; + file_put_contents($filename, $screenshot); // Find yes-no radio buttons, click "Yes". $items = self::$webDriver->findElements(WebDriverBy::cssSelector('ul.yesno-button li')); $this->assertCount(3, $items, 'Three radio buttons for yes-no question'); From 93ba5932b416e47fd29126ea246365bfca579f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Fri, 12 Jan 2018 12:45:34 +0200 Subject: [PATCH 20/20] conflict: AjaxModeTest by old structure (delete after) --- tests/surveys/AjaxModeTest.php | 130 +++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 tests/surveys/AjaxModeTest.php diff --git a/tests/surveys/AjaxModeTest.php b/tests/surveys/AjaxModeTest.php new file mode 100644 index 00000000000..6cba14a6b57 --- /dev/null +++ b/tests/surveys/AjaxModeTest.php @@ -0,0 +1,130 @@ +activateSurvey(self::$surveyId); + } + + /** + * Test that Ajax mode records answer. + */ + public function testAjaxModeRecordsAnswer() + { + // TODO: This works when run individually, but not + // as part of the test suit. Screenshot shows it's + // stuck on welcome page. + $this->markTestSkipped(); + + // Get questions. + $survey = \Survey::model()->findByPk(self::$surveyId); + $questionObjects = $survey->groups[0]->questions; + $questions = []; + foreach ($questionObjects as $q) { + $questions[$q->title] = $q; + } + + // Make sure there are no responses in database. + $query = sprintf( + 'SELECT * FROM {{survey_%d}}', + self::$surveyId + ); + $db = \Yii::app()->getDb(); + $rows = $db->createCommand($query)->queryAll(); + $this->assertEmpty($rows, 'No answers'); + + // Execute survey. + $urlMan = \Yii::app()->urlManager; + $urlMan->setBaseUrl('http://' . self::$domain . '/index.php'); + $url = $urlMan->createUrl( + 'survey/index', + [ + 'sid' => self::$surveyId, + 'newtest' => 'Y', + 'lang' => 'pt' + ] + ); + + try { + // Click welcome page. + self::$webDriver->get($url); + $nextButton = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); + $nextButton->click(); + + sleep(1); + + // TODO: Temporary, test fails here (but only on fresh install). + $screenshot = self::$webDriver->takeScreenshot(); + $filename = self::$screenshotsFolder.'/AjaxModeTest.png'; + file_put_contents($filename, $screenshot); + + // Find yes-no radio buttons, click "Yes". + $items = self::$webDriver->findElements(WebDriverBy::cssSelector('ul.yesno-button li')); + $this->assertCount(3, $items, 'Three radio buttons for yes-no question'); + $items[0]->click(); + + // Check that EM is reacting. + $div = self::$webDriver->findElement(WebDriverBy::cssSelector('div#question' . $questions['q2']->qid)); + $this->assertEquals($div->getText(), 'The previous answer was FALSE'); + + // Click "No". + $items[1]->click(); + + // Check EM. + $div = self::$webDriver->findElement(WebDriverBy::cssSelector('div#question' . $questions['q2']->qid)); + $this->assertEquals($div->getText(), 'The previous answer was TRUE'); + + // Click submit. + $submitButton = self::$webDriver->findElement(WebDriverBy::id('ls-button-submit')); + $submitButton->click(); + + // Check so that we see end page. + $completed = self::$webDriver->findElement(WebDriverBy::cssSelector('div.completed-text')); + $this->assertEquals( + $completed->getText(), + "Thank you!\nYour survey responses have been recorded.", + 'I can see completed text' + ); + } catch (NoSuchElementException $ex) { + $screenshot = self::$webDriver->takeScreenshot(); + $filename = self::$screenshotsFolder.'/AjaxModeTest.png'; + file_put_contents($filename, $screenshot); + $this->assertFalse( + true, + 'Url: ' . $url . PHP_EOL . + 'Screenshot in ' .$filename . PHP_EOL . $ex->getMessage() + ); + } + + // Check answer in database. + $query = sprintf( + 'SELECT * FROM {{survey_%d}}', + self::$surveyId + ); + $rows = $db->createCommand($query)->queryAll(); + $this->assertCount(1, $rows); + $sgqa = self::$surveyId . 'X' . $survey->groups[0]->gid . 'X' . $questions['q1']->qid; + $answer = $rows[0][$sgqa]; + $this->assertEquals('N', $answer, 'Answer is "N"'); + } +}