From b9c639d6c23139cbf31890c116ef8cc7368ba0c8 Mon Sep 17 00:00:00 2001 From: nicolasconnault Date: Tue, 16 Sep 2008 12:19:43 +0000 Subject: [PATCH] MDL-16483 Refactored install/upgrade code into lib/adminlib. Created an intermediate MoodleUnitTestCase class that overrides simpletest's constructor, destructor and setup/teardown methods. All moodle unit tests must extend this class. --- admin/index.php | 447 +---------------- admin/report/simpletest/index.php | 78 +++ course/simpletest/testcourselib.php | 2 +- grade/simpletest/testreportlib.php | 2 +- lang/en_utf8/simpletest.php | 6 +- lib/adminlib.php | 461 ++++++++++++++++++ lib/ddl/simpletest/testddl.php | 2 +- lib/dml/adodb_moodle_database.php | 11 +- lib/dml/moodle_database.php | 2 +- lib/dml/simpletest/dbspecific.php | 2 +- lib/dml/simpletest/testdml.php | 2 +- lib/dml/sqlite3_pdo_moodle_database.php | 13 +- lib/simpletest/fixtures/gradetest.php | 2 +- lib/simpletest/portfolio_testclass.php | 2 +- lib/simpletest/slowtestcode.php | 18 +- lib/simpletest/testaccesslib.php | 2 +- lib/simpletest/testajaxlib.php | 46 +- lib/simpletest/testbackuplib.php | 4 +- lib/simpletest/testcode.php | 10 +- lib/simpletest/testcompletionlib.php | 236 ++++----- lib/simpletest/testeventslib.php | 2 +- lib/simpletest/testmathslib.php | 4 +- lib/simpletest/testmoodlelib.php | 44 +- lib/simpletest/testportfolioaddbutton.php | 2 +- lib/simpletest/testweblib.php | 18 +- lib/simpletestlib.php | 44 +- mod/data/simpletest/testpreset.php | 10 +- mod/forum/simpletest/testmodforumlib.php | 2 +- mod/quiz/simpletest/testaccessrules.php | 12 +- .../numerical/simpletest/testquestiontype.php | 12 +- .../simpletest/testquestiontype.php | 8 +- 31 files changed, 825 insertions(+), 681 deletions(-) diff --git a/admin/index.php b/admin/index.php index 496b709a09..db460af23d 100644 --- a/admin/index.php +++ b/admin/index.php @@ -83,447 +83,8 @@ print_error('withoutversion', 'debug'); // without version, stop } -/// Check if the main tables have been installed yet or not. - if (!$tables = $DB->get_tables() ) { // No tables yet at all. - $maintables = false; - - } else { // Check for missing main tables - $maintables = true; - $mtables = array('config', 'course', 'groupings'); // some tables used in 1.9 and 2.0, preferable something from the start and end of install.xml - foreach ($mtables as $mtable) { - if (!in_array($mtable, $tables)) { - $maintables = false; - break; - } - } - } - unset($mtables); - unset($tables); - - if (!$maintables) { - /// hide errors from headers in case debug enabled in config.php - $origdebug = $CFG->debug; - $CFG->debug = DEBUG_MINIMAL; - error_reporting($CFG->debug); - if (empty($agreelicense)) { - $strlicense = get_string('license'); - $navigation = build_navigation(array(array('name'=>$strlicense, 'link'=>null, 'type'=>'misc'))); - print_header($strlicense, $strlicense, $navigation, "", "", false, " ", " "); - print_heading("Moodle - Modular Object-Oriented Dynamic Learning Environment"); - print_heading(get_string('copyrightnotice')); - print_box(text_to_html(get_string('gpl')), 'copyrightnotice'); - echo "
"; - notice_yesno(get_string('doyouagree'), "index.php?agreelicense=1", - "http://docs.moodle.org/en/License"); - print_footer('none'); - exit; - } - if (empty($confirmrelease)) { - $strcurrentrelease = get_string("currentrelease"); - $navigation = build_navigation(array(array('name'=>$strcurrentrelease, 'link'=>null, 'type'=>'misc'))); - print_header($strcurrentrelease, $strcurrentrelease, $navigation, "", "", false, " ", " "); - print_heading("Moodle $release"); - print_box(get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/en/Release_Notes'), 'generalbox boxaligncenter boxwidthwide'); - echo '
'; - echo ''; - echo ''; - echo '
'; - echo '
'; - echo '

'; - echo '
'; - print_footer('none'); - die; - } - - $strdatabasesetup = get_string("databasesetup"); - $strdatabasesuccess = get_string("databasesuccess"); - $navigation = build_navigation(array(array('name'=>$strdatabasesetup, 'link'=>null, 'type'=>'misc'))); - print_header($strdatabasesetup, $strdatabasesetup, $navigation, - "", upgrade_get_javascript(), false, " ", " "); - /// return to original debugging level - $CFG->debug = $origdebug; - error_reporting($CFG->debug); - upgrade_log_start(); - $DB->set_debug(true); - - if (!$DB->setup_is_unicodedb()) { - if (!$DB->change_db_encoding()) { - // If could not convert successfully, throw error, and prevent installation - print_error('unicoderequired', 'admin'); - } - } - - $DB->get_manager()->install_from_xmldb_file("$CFG->libdir/db/install.xml"); - - /// Continue with the instalation - - // Install the roles system. - moodle_install_roles(); - - // Install core event handlers - events_update_definition(); - - // Install core message providers - message_update_providers(); - message_update_providers('message'); - - /// This is used to handle any settings that must exist in $CFG but which do not exist in - /// admin_get_root()/$ADMIN as admin_setting objects (there are some exceptions). - apply_default_exception_settings(array('auth' => 'email', - 'auth_pop3mailbox' => 'INBOX', - 'enrol' => 'manual', - 'enrol_plugins_enabled' => 'manual', - 'style' => 'default', - 'template' => 'default', - 'theme' => 'standardwhite', - 'filter_multilang_converted' => 1)); - - // store main version - if (!set_config('version', $version)) { - print_error('cannotupdateversion', 'debug'); - } - - // Write default settings unconditionally (i.e. even if a setting is already set, overwrite it) - // (this should only have any effect during initial install). - admin_apply_default_settings(NULL, true); - - notify($strdatabasesuccess, 'notifysuccess'); - - /// do not show certificates in log ;-) - $DB->set_debug(false); - - // hack - set up mnet - require_once $CFG->dirroot.'/mnet/lib.php'; - - print_continue('index.php'); - print_footer('none'); - - die; - } - - -/// Check version of Moodle code on disk compared with database -/// and upgrade if possible. - - $stradministration = get_string('administration'); - - if (empty($CFG->version)) { - print_error('missingconfigversion', 'debug'); - } - - if ($version > $CFG->version) { // upgrade - - require_once($CFG->libdir.'/db/upgrade.php'); // Defines upgrades - require_once($CFG->libdir.'/db/upgradelib.php'); // Upgrade-related functions - - $a->oldversion = "$CFG->release ($CFG->version)"; - $a->newversion = "$release ($version)"; - $strdatabasechecking = get_string("databasechecking", "", $a); + upgrade_db($version, $release); - // hide errors from headers in case debug is enabled - $origdebug = $CFG->debug; - $CFG->debug = DEBUG_MINIMAL; - error_reporting($CFG->debug); - $CFG->xmlstrictheaders = false; - - // logo ut in case we are upgrading from pre 1.9 version in order to prevent - // weird session/role problems caused by incorrect data in USER and SESSION - if ($CFG->version < 2007101500) { - require_logout(); - } - - if (empty($confirmupgrade)) { - $navigation = build_navigation(array(array('name'=>$strdatabasechecking, 'link'=>null, 'type'=>'misc'))); - print_header($strdatabasechecking, $stradministration, $navigation, - "", "", false, " ", " "); - - notice_yesno(get_string('upgradesure', 'admin', $a->newversion), 'index.php?confirmupgrade=1', 'index.php'); - print_footer('none'); - exit; - - } else if (empty($confirmrelease)){ - $strcurrentrelease = get_string("currentrelease"); - $navigation = build_navigation(array(array('name'=>$strcurrentrelease, 'link'=>null, 'type'=>'misc'))); - print_header($strcurrentrelease, $strcurrentrelease, $navigation, "", "", false, " ", " "); - print_heading("Moodle $release"); - print_box(get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/en/Release_Notes')); - - require_once($CFG->libdir.'/environmentlib.php'); - print_heading(get_string('environment', 'admin')); - if (!check_moodle_environment($release, $environment_results, true)) { - print_box_start('generalbox', 'notice'); // MDL-8330 - print_string('langpackwillbeupdated', 'admin'); - print_box_end(); - notice_yesno(get_string('environmenterrorupgrade', 'admin'), - 'index.php?confirmupgrade=1&confirmrelease=1', 'index.php'); - } else { - notify(get_string('environmentok', 'admin'), 'notifysuccess'); - print_box_start('generalbox', 'notice'); // MDL-8330 - print_string('langpackwillbeupdated', 'admin'); - print_box_end(); - echo '
'; - echo ''; - echo ''; - echo '
'; - echo '
'; - echo '

'; - echo '
'; - } - - print_footer('none'); - die; - } elseif (empty($confirmplugins)) { - $strplugincheck = get_string('plugincheck'); - $navigation = build_navigation(array(array('name'=>$strplugincheck, 'link'=>null, 'type'=>'misc'))); - print_header($strplugincheck, $strplugincheck, $navigation, "", "", false, " ", " "); - print_heading($strplugincheck); - print_box_start('generalbox', 'notice'); // MDL-8330 - print_string('pluginchecknotice'); - print_box_end(); - print_plugin_tables(); - echo "
"; - echo '
'; - print_single_button('index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1), get_string('reload'), 'get'); - echo '

'; - echo '
'; - echo ''; - echo ''; - echo ''; - echo '
'; - echo '
'; - echo '

'; - echo '
'; - print_footer('none'); - die(); - - } else { - - $strdatabasesuccess = get_string("databasesuccess"); - $navigation = build_navigation(array(array('name'=>$strdatabasesuccess, 'link'=>null, 'type'=>'misc'))); - print_header($strdatabasechecking, $stradministration, $navigation, - "", upgrade_get_javascript(), false, " ", " "); - - /// return to original debugging level - $CFG->debug = $origdebug; - error_reporting($CFG->debug); - upgrade_log_start(); - - /// Upgrade current language pack if we can - upgrade_language_pack(); - - print_heading($strdatabasechecking); - $DB->set_debug(true); - /// Launch the old main upgrade (if exists) - $status = true; - if (function_exists('main_upgrade')) { - $status = main_upgrade($CFG->version); - } - /// If succesful and exists launch the new main upgrade (XMLDB), called xmldb_main_upgrade - if ($status && function_exists('xmldb_main_upgrade')) { - $status = xmldb_main_upgrade($CFG->version); - } - $DB->set_debug(false); - /// If successful, continue upgrading roles and setting everything properly - if ($status) { - if (!update_capabilities()) { - print_error('cannotupgradecapabilities', 'debug'); - } - - // Update core events - events_update_definition(); - - // Update core message providers - message_update_providers(); - message_update_providers('message'); - - if (set_config("version", $version)) { - remove_dir($CFG->dataroot . '/cache', true); // flush cache - notify($strdatabasesuccess, "green"); - print_continue("upgradesettings.php"); - print_footer('none'); - exit; - } else { - print_error('cannotupdateversion', 'debug'); - } - /// Main upgrade not success - } else { - notify('Main Upgrade failed! See lib/db/upgrade.php'); - print_continue('index.php?confirmupgrade=1&confirmrelease=1&confirmplugincheck=1'); - print_footer('none'); - die; - } - upgrade_log_finish(); - } - } else if ($version < $CFG->version) { - upgrade_log_start(); - notify("WARNING!!! The code you are using is OLDER than the version that made these databases!"); - upgrade_log_finish(); - } - -/// Updated human-readable release version if necessary - - if ($release <> $CFG->release) { // Update the release version - if (!set_config("release", $release)) { - print_error("cannotupdaterelease", 'debug'); - } - } - - // Turn off xmlstrictheaders during upgrade. - $origxmlstrictheaders = !empty($CFG->xmlstrictheaders); - $CFG->xmlstrictheaders = false; - -/// Find and check all main modules and load them up or upgrade them if necessary -/// first old *.php update and then the new upgrade.php script - upgrade_activity_modules("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards - -/// Check all questiontype plugins and upgrade if necessary -/// first old *.php update and then the new upgrade.php script -/// It is important that this is done AFTER the quiz module has been upgraded - upgrade_plugins('qtype', 'question/type', "$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards - -/// Upgrade backup/restore system if necessary -/// first old *.php update and then the new upgrade.php script - require_once("$CFG->dirroot/backup/lib.php"); - upgrade_backup_db("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards - -/// Upgrade blocks system if necessary -/// first old *.php update and then the new upgrade.php script - require_once("$CFG->dirroot/lib/blocklib.php"); - upgrade_blocks_db("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards - -/// Check all blocks and load (or upgrade them if necessary) -/// first old *.php update and then the new upgrade.php script - upgrade_blocks_plugins("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards - -/// Check all enrolment plugins and upgrade if necessary -/// first old *.php update and then the new upgrade.php script - upgrade_plugins('enrol', 'enrol', "$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards - -/// Check all auth plugins and upgrade if necessary - upgrade_plugins('auth','auth',"$CFG->wwwroot/$CFG->admin/index.php"); - -/// Check all course formats and upgrade if necessary - upgrade_plugins('format','course/format',"$CFG->wwwroot/$CFG->admin/index.php"); - -/// Check for local database customisations -/// first old *.php update and then the new upgrade.php script - require_once("$CFG->dirroot/lib/locallib.php"); - upgrade_local_db("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards - -/// Check for changes to RPC functions - require_once("$CFG->dirroot/$CFG->admin/mnet/adminlib.php"); - upgrade_RPC_functions("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards - -/// Upgrade all plugins for gradebook - upgrade_plugins('gradeexport', 'grade/export', "$CFG->wwwroot/$CFG->admin/index.php"); - upgrade_plugins('gradeimport', 'grade/import', "$CFG->wwwroot/$CFG->admin/index.php"); - upgrade_plugins('gradereport', 'grade/report', "$CFG->wwwroot/$CFG->admin/index.php"); - -/// Check all message output plugins and upgrade if necessary - upgrade_plugins('message','message/output',"$CFG->wwwroot/$CFG->admin/index.php"); - -/// Check all admin report plugins and upgrade if necessary - upgrade_plugins('report', $CFG->admin.'/report', "$CFG->wwwroot/$CFG->admin/index.php"); - -/// Check all quiz report plugins and upgrade if necessary - upgrade_plugins('quizreport', 'mod/quiz/report', "$CFG->wwwroot/$CFG->admin/index.php"); - -/// Check all portfolio plugins and upgrade if necessary - upgrade_plugins('portfolio', 'portfolio/type', "$CFG->wwwroot/$CFG->admin/index.php"); - -/// Check all progress tracker plugins and upgrade if necessary - upgrade_plugins('trackerexport', 'tracker/export', "$CFG->wwwroot/$CFG->admin/index.php"); - upgrade_plugins('trackerimport', 'tracker/import', "$CFG->wwwroot/$CFG->admin/index.php"); - upgrade_plugins('trackerreport', 'tracker/report', "$CFG->wwwroot/$CFG->admin/index.php"); - -/// just make sure upgrade logging is properly terminated - upgrade_log_finish(); - - unset($SESSION->installautopilot); - - // Turn xmlstrictheaders back on now. - $CFG->xmlstrictheaders = $origxmlstrictheaders; - -/// Set up the blank site - to be customized later at the end of install. - if (! $site = get_site()) { - // We are about to create the site "course" - require_once($CFG->libdir.'/blocklib.php'); - - $newsite = new object(); - $newsite->fullname = ""; - $newsite->shortname = ""; - $newsite->summary = NULL; - $newsite->newsitems = 3; - $newsite->numsections = 0; - $newsite->category = 0; - $newsite->format = 'site'; // Only for this course - $newsite->teacher = get_string("defaultcourseteacher"); - $newsite->teachers = get_string("defaultcourseteachers"); - $newsite->student = get_string("defaultcoursestudent"); - $newsite->students = get_string("defaultcoursestudents"); - $newsite->timemodified = time(); - - if (!$newid = $DB->insert_record('course', $newsite)) { - print_error('cannotsetupsite', 'error'); - } - // make sure course context exists - get_context_instance(CONTEXT_COURSE, $newid); - - // Site created, add blocks for it - $page = page_create_object(PAGE_COURSE_VIEW, $newid); - blocks_repopulate_page($page); // Return value not checked because you can always edit later - - // create default course category - $cat = get_course_category(); - - redirect('index.php'); - } - - // initialise default blocks on admin and site page if needed - if (empty($CFG->adminblocks_initialised)) { - require_once("$CFG->dirroot/$CFG->admin/pagelib.php"); - require_once($CFG->libdir.'/blocklib.php'); - page_map_class(PAGE_ADMIN, 'page_admin'); - $page = page_create_object(PAGE_ADMIN, 0); // there must be some id number - blocks_repopulate_page($page); - - //add admin_tree block to site if not already present - if ($admintree = $DB->get_record('block', array('name'=>'admin_tree'))) { - $page = page_create_object(PAGE_COURSE_VIEW, SITEID); - $pageblocks=blocks_get_by_page($page); - blocks_execute_action($page, $pageblocks, 'add', (int)$admintree->id, false, false); - if ($admintreeinstance = $DB->get_record('block_instance', array('pagetype'=>$page->type, 'pageid'=>SITEID, 'blockid'=>$admintree->id))) { - $pageblocks=blocks_get_by_page($page); - blocks_execute_action($page, $pageblocks, 'moveleft', $admintreeinstance, false, false); - } - } - - set_config('adminblocks_initialised', 1); - } - -/// Define the unique site ID code if it isn't already - if (empty($CFG->siteidentifier)) { // Unique site identification code - set_config('siteidentifier', random_string(32).$_SERVER['HTTP_HOST']); - } - -/// ugly hack - if mnet is not initialised include the mnet lib, it adds needed mnet records and configures config options -/// we should not do such crazy stuff in lib functions!!! - if (empty($CFG->mnet_localhost_id)) { - require_once $CFG->dirroot.'/mnet/lib.php'; - } - -/// Check if the guest user exists. If not, create one. - if (!$DB->record_exists('user', array('username'=>'guest'))) { - if (! $guest = create_guest_record()) { - notify("Could not create guest user record !!!"); - } - } - -/// Set up the admin user - if (empty($CFG->rolesactive)) { - build_context_path(); // just in case - should not be needed - create_admin_user(); - } /// Check for valid admin user - no guest autologin require_login(0, false); @@ -550,9 +111,9 @@ /// setup critical warnings before printing admin tree block $insecuredataroot = is_dataroot_insecure(true); - $register_globals_enabled = ini_get_bool('register_globals'); + $register_globals_enabled = ini_get_bool('register_globals'); - $SESSION->admin_critical_warning = ($register_globals_enabled || $insecuredataroot==INSECURE_DATAROOT_ERROR); + $SESSION->admin_critical_warning = ($register_globals_enabled || $insecuredataroot==INSECURE_DATAROOT_ERROR); $adminroot =& admin_get_root(); @@ -586,7 +147,7 @@ print_box(get_string('datarootsecuritywarning', 'admin', $CFG->dataroot), 'generalbox adminwarning'); } else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) { print_box(get_string('datarootsecurityerror', 'admin', $CFG->dataroot), 'generalbox adminerror'); - + } if (defined('WARN_DISPLAY_ERRORS_ENABLED')) { diff --git a/admin/report/simpletest/index.php b/admin/report/simpletest/index.php index ed5189b675..bd1b080dff 100644 --- a/admin/report/simpletest/index.php +++ b/admin/report/simpletest/index.php @@ -27,6 +27,8 @@ $showpasses = optional_param('showpasses', false, PARAM_BOOL); $showsearch = optional_param('showsearch', false, PARAM_BOOL); $rundbtests = optional_param('rundbtests', false, PARAM_BOOL); $thorough = optional_param('thorough', false, PARAM_BOOL); +$addconfigprefix = optional_param('addconfigprefix', false, PARAM_RAW); +$setuptesttables = optional_param('setuptesttables', false, PARAM_BOOL); global $UNITTEST; $UNITTEST = new object(); @@ -36,6 +38,82 @@ admin_externalpage_setup('reportsimpletest'); $strtitle = get_string('unittests', $langfile); admin_externalpage_print_header(); +$baseurl = $CFG->wwwroot . '/admin/report/simpletest/index.php'; + +// Add unittest prefix to config.php if needed +if ($addconfigprefix && !isset($CFG->unittest_prefix)) { + // Open config file, search for $CFG->prefix and append a new line under it + $handle = fopen($CFG->dirroot.'/config.php', 'r+'); + + $new_file = ''; + + while (!feof($handle)) { + $line = fgets($handle, 4096); + $prefix_line = null; + + if (preg_match('/CFG\-\>prefix/', $line, $matches)) { + $prefix_line = "\$CFG->unittest_prefix = '$addconfigprefix';\n"; + } + + $new_file .= $line; + $new_file .= $prefix_line; + } + + fclose($handle); + $handle = fopen($CFG->dirroot.'/config.php', 'w'); + fwrite($handle, $new_file); + fclose($handle); + $CFG->unittest_prefix = $addconfigprefix; +} + +if (empty($CFG->unittest_prefix)) { + // TODO replace error with proper admin dialog + print_box_start('generalbox', 'notice'); + echo '

'.get_string("prefixnotset", 'simpletest').'

'; + echo '
+ + + + + + +
+
'; + print_box_end(); + admin_externalpage_print_footer(); + exit(); +} + +$test_tables = $DB->get_tables($CFG->unittest_prefix); +$real_tables = $DB->get_tables(); + +// Build test tables if requested and needed +if ($setuptesttables) { + $version = null; + $release = null; + include("$CFG->dirroot/version.php"); // defines $version and $release + + $real_db = clone($DB); + $DB = moodle_database::get_driver_instance($CFG->dbtype, $CFG->dblibrary); + $DB->connect($CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->dbpersist, $CFG->unittest_prefix); + + // Drop all tables first if they exist + $manager = $DB->get_manager(); + foreach ($test_tables as $table) { + $manager->drop_table($table); + } + + upgrade_db($version, $release, true); + $DB = $real_db; +} + +if (empty($test_tables['config'])) { + // TODO replace error with proper admin dialog + notice_yesno(get_string('tablesnotsetup', 'simpletest'), $baseurl . '?setuptesttables=1', $baseurl); + admin_externalpage_print_footer(); + exit(); +} + if (!is_null($path)) { // Create the group of tests. $test = new AutoGroupTest($showsearch, $thorough); diff --git a/course/simpletest/testcourselib.php b/course/simpletest/testcourselib.php index a62b6d3674..0aa916688a 100755 --- a/course/simpletest/testcourselib.php +++ b/course/simpletest/testcourselib.php @@ -39,7 +39,7 @@ require_once($CFG->dirroot . '/course/lib.php'); global $DB; Mock::generate(get_class($DB), 'mockDB'); -class courselib_test extends UnitTestCase { +class courselib_test extends MoodleUnitTestCase { var $realDB; function setUp() { diff --git a/grade/simpletest/testreportlib.php b/grade/simpletest/testreportlib.php index 34c4186158..6d9df6e85e 100644 --- a/grade/simpletest/testreportlib.php +++ b/grade/simpletest/testreportlib.php @@ -40,7 +40,7 @@ require_once($CFG->dirroot.'/grade/report/lib.php'); /** * @TODO create a set of mock objects to simulate the database operations. We don't want to connect to any real sql server. */ -class gradereportlib_test extends UnitTestCase { +class gradereportlib_test extends MoodleUnitTestCase { var $courseid = 1; var $context = null; var $report = null; diff --git a/lang/en_utf8/simpletest.php b/lang/en_utf8/simpletest.php index 69d7d53d26..27a15097d1 100644 --- a/lang/en_utf8/simpletest.php +++ b/lang/en_utf8/simpletest.php @@ -1,8 +1,9 @@ -run}/{$a->total} test cases complete: {$a->passes} passes, {$a->fails} fails and {$a->exceptions} exceptions.'; +$string['tablesnotsetup'] = 'Unit test tables are not yet built. Do you want to build them now?.'; $string['thorough'] = 'Run a thorough test (may be slow).'; $string['uncaughtexception'] = 'Uncaught exception [{$a->getMessage()}] in [{$a->getFile()}:{$a->getLine()}] TESTS ABORTED.'; $string['unittests'] = 'Unit tests'; diff --git a/lib/adminlib.php b/lib/adminlib.php index c92fdcb06e..ba5a745041 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -22,6 +22,467 @@ $upgradelogbuffer = ''; define('INSECURE_DATAROOT_WARNING', 1); define('INSECURE_DATAROOT_ERROR', 2); +/** + * Central function for upgrading the DB + * + * @param string $version + * @param string $release + * @param bool $unittest If true, bypasses a bunch of confirmation screens + */ +function upgrade_db($version, $release, $unittest=false) { + global $CFG, $DB, $SESSION; + + $confirmupgrade = optional_param('confirmupgrade', $unittest, PARAM_BOOL); + $confirmrelease = optional_param('confirmrelease', $unittest, PARAM_BOOL); + $confirmplugins = optional_param('confirmplugincheck', $unittest, PARAM_BOOL); + $agreelicense = optional_param('agreelicense', $unittest, PARAM_BOOL); + $autopilot = optional_param('autopilot', $unittest, PARAM_BOOL); + $setuptesttables= optional_param('setuptesttables', $unittest, PARAM_BOOL); + + /// Check if the main tables have been installed yet or not. + if (!$tables = $DB->get_tables() ) { // No tables yet at all. + $maintables = false; + + } else { // Check for missing main tables + $maintables = true; + $mtables = array('config', 'course', 'groupings'); // some tables used in 1.9 and 2.0, preferable something from the start and end of install.xml + foreach ($mtables as $mtable) { + if (!in_array($mtable, $tables)) { + $maintables = false; + break; + } + } + } + unset($mtables); + unset($tables); + + if (!$maintables) { + /// hide errors from headers in case debug enabled in config.php + $origdebug = $CFG->debug; + $CFG->debug = DEBUG_MINIMAL; + error_reporting($CFG->debug); + if (empty($agreelicense)) { + $strlicense = get_string('license'); + $navigation = build_navigation(array(array('name'=>$strlicense, 'link'=>null, 'type'=>'misc'))); + print_header($strlicense, $strlicense, $navigation, "", "", false, " ", " "); + print_heading("Moodle - Modular Object-Oriented Dynamic Learning Environment"); + print_heading(get_string('copyrightnotice')); + print_box(text_to_html(get_string('gpl')), 'copyrightnotice'); + echo "
"; + notice_yesno(get_string('doyouagree'), "index.php?agreelicense=1", + "http://docs.moodle.org/en/License"); + print_footer('none'); + exit; + } + if (empty($confirmrelease)) { + $strcurrentrelease = get_string("currentrelease"); + $navigation = build_navigation(array(array('name'=>$strcurrentrelease, 'link'=>null, 'type'=>'misc'))); + print_header($strcurrentrelease, $strcurrentrelease, $navigation, "", "", false, " ", " "); + print_heading("Moodle $release"); + print_box(get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/en/Release_Notes'), 'generalbox boxaligncenter boxwidthwide'); + echo '
'; + echo ''; + echo ''; + echo '
'; + echo '
'; + echo '

'; + echo '
'; + print_footer('none'); + die; + } + + $strdatabasesetup = get_string("databasesetup"); + $strdatabasesuccess = get_string("databasesuccess"); + $navigation = build_navigation(array(array('name'=>$strdatabasesetup, 'link'=>null, 'type'=>'misc'))); + print_header($strdatabasesetup, $strdatabasesetup, $navigation, + "", upgrade_get_javascript(), false, " ", " "); + /// return to original debugging level + $CFG->debug = $origdebug; + error_reporting($CFG->debug); + upgrade_log_start(); + $DB->set_debug(true); + + if (!$DB->setup_is_unicodedb()) { + if (!$DB->change_db_encoding()) { + // If could not convert successfully, throw error, and prevent installation + print_error('unicoderequired', 'admin'); + } + } + + $DB->get_manager()->install_from_xmldb_file("$CFG->libdir/db/install.xml"); + + /// Continue with the instalation + + // Install the roles system. + moodle_install_roles(); + + // Install core event handlers + events_update_definition(); + + // Install core message providers + message_update_providers(); + message_update_providers('message'); + + /// This is used to handle any settings that must exist in $CFG but which do not exist in + /// admin_get_root()/$ADMIN as admin_setting objects (there are some exceptions). + apply_default_exception_settings(array('auth' => 'email', + 'auth_pop3mailbox' => 'INBOX', + 'enrol' => 'manual', + 'enrol_plugins_enabled' => 'manual', + 'style' => 'default', + 'template' => 'default', + 'theme' => 'standardwhite', + 'filter_multilang_converted' => 1)); + + // store main version + if (!set_config('version', $version)) { + print_error('cannotupdateversion', 'debug'); + } + + // Write default settings unconditionally (i.e. even if a setting is already set, overwrite it) + // (this should only have any effect during initial install). + admin_apply_default_settings(NULL, true); + + notify($strdatabasesuccess, 'notifysuccess'); + + /// do not show certificates in log ;-) + $DB->set_debug(false); + + // hack - set up mnet + require_once $CFG->dirroot.'/mnet/lib.php'; + + print_continue('index.php'); + print_footer('none'); + + die; + } + + +/// Check version of Moodle code on disk compared with database +/// and upgrade if possible. + + $stradministration = get_string('administration'); + + if (empty($CFG->version)) { + print_error('missingconfigversion', 'debug'); + } + + if ($version > $CFG->version) { // upgrade + + require_once($CFG->libdir.'/db/upgrade.php'); // Defines upgrades + require_once($CFG->libdir.'/db/upgradelib.php'); // Upgrade-related functions + + $a->oldversion = "$CFG->release ($CFG->version)"; + $a->newversion = "$release ($version)"; + $strdatabasechecking = get_string("databasechecking", "", $a); + + // hide errors from headers in case debug is enabled + $origdebug = $CFG->debug; + $CFG->debug = DEBUG_MINIMAL; + error_reporting($CFG->debug); + $CFG->xmlstrictheaders = false; + + // logo ut in case we are upgrading from pre 1.9 version in order to prevent + // weird session/role problems caused by incorrect data in USER and SESSION + if ($CFG->version < 2007101500) { + require_logout(); + } + + if (empty($confirmupgrade)) { + $navigation = build_navigation(array(array('name'=>$strdatabasechecking, 'link'=>null, 'type'=>'misc'))); + print_header($strdatabasechecking, $stradministration, $navigation, + "", "", false, " ", " "); + + notice_yesno(get_string('upgradesure', 'admin', $a->newversion), 'index.php?confirmupgrade=1', 'index.php'); + print_footer('none'); + exit; + + } else if (empty($confirmrelease)){ + $strcurrentrelease = get_string("currentrelease"); + $navigation = build_navigation(array(array('name'=>$strcurrentrelease, 'link'=>null, 'type'=>'misc'))); + print_header($strcurrentrelease, $strcurrentrelease, $navigation, "", "", false, " ", " "); + print_heading("Moodle $release"); + print_box(get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/en/Release_Notes')); + + require_once($CFG->libdir.'/environmentlib.php'); + print_heading(get_string('environment', 'admin')); + if (!check_moodle_environment($release, $environment_results, true)) { + print_box_start('generalbox', 'notice'); // MDL-8330 + print_string('langpackwillbeupdated', 'admin'); + print_box_end(); + notice_yesno(get_string('environmenterrorupgrade', 'admin'), + 'index.php?confirmupgrade=1&confirmrelease=1', 'index.php'); + } else { + notify(get_string('environmentok', 'admin'), 'notifysuccess'); + print_box_start('generalbox', 'notice'); // MDL-8330 + print_string('langpackwillbeupdated', 'admin'); + print_box_end(); + echo '
'; + echo ''; + echo ''; + echo '
'; + echo '
'; + echo '

'; + echo '
'; + } + + print_footer('none'); + die; + } elseif (empty($confirmplugins)) { + $strplugincheck = get_string('plugincheck'); + $navigation = build_navigation(array(array('name'=>$strplugincheck, 'link'=>null, 'type'=>'misc'))); + print_header($strplugincheck, $strplugincheck, $navigation, "", "", false, " ", " "); + print_heading($strplugincheck); + print_box_start('generalbox', 'notice'); // MDL-8330 + print_string('pluginchecknotice'); + print_box_end(); + print_plugin_tables(); + echo "
"; + echo '
'; + print_single_button('index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1), get_string('reload'), 'get'); + echo '

'; + echo '
'; + echo ''; + echo ''; + echo ''; + echo '
'; + echo '
'; + echo '

'; + echo '
'; + print_footer('none'); + die(); + + } else { + + $strdatabasesuccess = get_string("databasesuccess"); + $navigation = build_navigation(array(array('name'=>$strdatabasesuccess, 'link'=>null, 'type'=>'misc'))); + print_header($strdatabasechecking, $stradministration, $navigation, + "", upgrade_get_javascript(), false, " ", " "); + + /// return to original debugging level + $CFG->debug = $origdebug; + error_reporting($CFG->debug); + upgrade_log_start(); + + /// Upgrade current language pack if we can + upgrade_language_pack(); + + print_heading($strdatabasechecking); + $DB->set_debug(true); + /// Launch the old main upgrade (if exists) + $status = true; + if (function_exists('main_upgrade')) { + $status = main_upgrade($CFG->version); + } + /// If succesful and exists launch the new main upgrade (XMLDB), called xmldb_main_upgrade + if ($status && function_exists('xmldb_main_upgrade')) { + $status = xmldb_main_upgrade($CFG->version); + } + $DB->set_debug(false); + /// If successful, continue upgrading roles and setting everything properly + if ($status) { + if (!update_capabilities()) { + print_error('cannotupgradecapabilities', 'debug'); + } + + // Update core events + events_update_definition(); + + // Update core message providers + message_update_providers(); + message_update_providers('message'); + + if (set_config("version", $version)) { + remove_dir($CFG->dataroot . '/cache', true); // flush cache + notify($strdatabasesuccess, "green"); + print_continue("upgradesettings.php"); + print_footer('none'); + exit; + } else { + print_error('cannotupdateversion', 'debug'); + } + /// Main upgrade not success + } else { + notify('Main Upgrade failed! See lib/db/upgrade.php'); + print_continue('index.php?confirmupgrade=1&confirmrelease=1&confirmplugincheck=1'); + print_footer('none'); + die; + } + upgrade_log_finish(); + } + } else if ($version < $CFG->version) { + upgrade_log_start(); + notify("WARNING!!! The code you are using is OLDER than the version that made these databases!"); + upgrade_log_finish(); + } + +/// Updated human-readable release version if necessary + + if ($release <> $CFG->release) { // Update the release version + if (!set_config("release", $release)) { + print_error("cannotupdaterelease", 'debug'); + } + } + + // Turn off xmlstrictheaders during upgrade. + $origxmlstrictheaders = !empty($CFG->xmlstrictheaders); + $CFG->xmlstrictheaders = false; + +/// Find and check all main modules and load them up or upgrade them if necessary +/// first old *.php update and then the new upgrade.php script + upgrade_activity_modules("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards + +/// Check all questiontype plugins and upgrade if necessary +/// first old *.php update and then the new upgrade.php script +/// It is important that this is done AFTER the quiz module has been upgraded + upgrade_plugins('qtype', 'question/type', "$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards + +/// Upgrade backup/restore system if necessary +/// first old *.php update and then the new upgrade.php script + require_once("$CFG->dirroot/backup/lib.php"); + upgrade_backup_db("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards + +/// Upgrade blocks system if necessary +/// first old *.php update and then the new upgrade.php script + require_once("$CFG->dirroot/lib/blocklib.php"); + upgrade_blocks_db("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards + +/// Check all blocks and load (or upgrade them if necessary) +/// first old *.php update and then the new upgrade.php script + upgrade_blocks_plugins("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards + +/// Check all enrolment plugins and upgrade if necessary +/// first old *.php update and then the new upgrade.php script + upgrade_plugins('enrol', 'enrol', "$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards + +/// Check all auth plugins and upgrade if necessary + upgrade_plugins('auth','auth',"$CFG->wwwroot/$CFG->admin/index.php"); + +/// Check all course formats and upgrade if necessary + upgrade_plugins('format','course/format',"$CFG->wwwroot/$CFG->admin/index.php"); + +/// Check for local database customisations +/// first old *.php update and then the new upgrade.php script + require_once("$CFG->dirroot/lib/locallib.php"); + upgrade_local_db("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards + +/// Check for changes to RPC functions + require_once("$CFG->dirroot/$CFG->admin/mnet/adminlib.php"); + upgrade_RPC_functions("$CFG->wwwroot/$CFG->admin/index.php"); // Return here afterwards + +/// Upgrade all plugins for gradebook + upgrade_plugins('gradeexport', 'grade/export', "$CFG->wwwroot/$CFG->admin/index.php"); + upgrade_plugins('gradeimport', 'grade/import', "$CFG->wwwroot/$CFG->admin/index.php"); + upgrade_plugins('gradereport', 'grade/report', "$CFG->wwwroot/$CFG->admin/index.php"); + +/// Check all message output plugins and upgrade if necessary + upgrade_plugins('message','message/output',"$CFG->wwwroot/$CFG->admin/index.php"); + +/// Check all admin report plugins and upgrade if necessary + upgrade_plugins('report', $CFG->admin.'/report', "$CFG->wwwroot/$CFG->admin/index.php"); + +/// Check all quiz report plugins and upgrade if necessary + upgrade_plugins('quizreport', 'mod/quiz/report', "$CFG->wwwroot/$CFG->admin/index.php"); + +/// Check all portfolio plugins and upgrade if necessary + upgrade_plugins('portfolio', 'portfolio/type', "$CFG->wwwroot/$CFG->admin/index.php"); + +/// Check all progress tracker plugins and upgrade if necessary + upgrade_plugins('trackerexport', 'tracker/export', "$CFG->wwwroot/$CFG->admin/index.php"); + upgrade_plugins('trackerimport', 'tracker/import', "$CFG->wwwroot/$CFG->admin/index.php"); + upgrade_plugins('trackerreport', 'tracker/report', "$CFG->wwwroot/$CFG->admin/index.php"); + +/// just make sure upgrade logging is properly terminated + upgrade_log_finish(); + + unset($SESSION->installautopilot); + + // Turn xmlstrictheaders back on now. + $CFG->xmlstrictheaders = $origxmlstrictheaders; + +/// Set up the blank site - to be customized later at the end of install. + if (! $site = get_site()) { + // We are about to create the site "course" + require_once($CFG->libdir.'/blocklib.php'); + + $newsite = new object(); + $newsite->fullname = ""; + $newsite->shortname = ""; + $newsite->summary = NULL; + $newsite->newsitems = 3; + $newsite->numsections = 0; + $newsite->category = 0; + $newsite->format = 'site'; // Only for this course + $newsite->teacher = get_string("defaultcourseteacher"); + $newsite->teachers = get_string("defaultcourseteachers"); + $newsite->student = get_string("defaultcoursestudent"); + $newsite->students = get_string("defaultcoursestudents"); + $newsite->timemodified = time(); + + if (!$newid = $DB->insert_record('course', $newsite)) { + print_error('cannotsetupsite', 'error'); + } + // make sure course context exists + get_context_instance(CONTEXT_COURSE, $newid); + + // Site created, add blocks for it + $page = page_create_object(PAGE_COURSE_VIEW, $newid); + blocks_repopulate_page($page); // Return value not checked because you can always edit later + + // create default course category + $cat = get_course_category(); + + redirect('index.php'); + } + + // initialise default blocks on admin and site page if needed + if (empty($CFG->adminblocks_initialised)) { + require_once("$CFG->dirroot/$CFG->admin/pagelib.php"); + require_once($CFG->libdir.'/blocklib.php'); + page_map_class(PAGE_ADMIN, 'page_admin'); + $page = page_create_object(PAGE_ADMIN, 0); // there must be some id number + blocks_repopulate_page($page); + + //add admin_tree block to site if not already present + if ($admintree = $DB->get_record('block', array('name'=>'admin_tree'))) { + $page = page_create_object(PAGE_COURSE_VIEW, SITEID); + $pageblocks=blocks_get_by_page($page); + blocks_execute_action($page, $pageblocks, 'add', (int)$admintree->id, false, false); + if ($admintreeinstance = $DB->get_record('block_instance', array('pagetype'=>$page->type, 'pageid'=>SITEID, 'blockid'=>$admintree->id))) { + $pageblocks=blocks_get_by_page($page); + blocks_execute_action($page, $pageblocks, 'moveleft', $admintreeinstance, false, false); + } + } + + set_config('adminblocks_initialised', 1); + } + +/// Define the unique site ID code if it isn't already + if (empty($CFG->siteidentifier)) { // Unique site identification code + set_config('siteidentifier', random_string(32).$_SERVER['HTTP_HOST']); + } + +/// ugly hack - if mnet is not initialised include the mnet lib, it adds needed mnet records and configures config options +/// we should not do such crazy stuff in lib functions!!! + if (empty($CFG->mnet_localhost_id)) { + require_once $CFG->dirroot.'/mnet/lib.php'; + } + +/// Check if the guest user exists. If not, create one. + if (!$DB->record_exists('user', array('username'=>'guest'))) { + if (! $guest = create_guest_record()) { + notify("Could not create guest user record !!!"); + } + } + +/// Set up the admin user + if (empty($CFG->rolesactive)) { + build_context_path(); // just in case - should not be needed + create_admin_user(); + } + +} + /** * Upgrade savepoint, marks end of each upgrade block. * It stores new main version, resets upgrade timeout diff --git a/lib/ddl/simpletest/testddl.php b/lib/ddl/simpletest/testddl.php index 462379c81f..da8f28caf6 100755 --- a/lib/ddl/simpletest/testddl.php +++ b/lib/ddl/simpletest/testddl.php @@ -11,7 +11,7 @@ if (!defined('MOODLE_INTERNAL')) { require_once($CFG->libdir . '/adminlib.php'); -class ddl_test extends UnitTestCase { +class ddl_test extends MoodleUnitTestCase { private $tables = array(); private $tdb; diff --git a/lib/dml/adodb_moodle_database.php b/lib/dml/adodb_moodle_database.php index e07e933676..5b9a67ecfe 100644 --- a/lib/dml/adodb_moodle_database.php +++ b/lib/dml/adodb_moodle_database.php @@ -93,13 +93,18 @@ abstract class adodb_moodle_database extends moodle_database { * Return tables in database WITHOUT current prefix * @return array of table names in lowercase and without prefix */ - public function get_tables() { + public function get_tables($prefix=null) { $metatables = $this->adodb->MetaTables(); $tables = array(); + + if (is_null($prefix)) { + $prefix = $this->prefix; + } + foreach ($metatables as $table) { $table = strtolower($table); - if (empty($this->prefix) || strpos($table, $this->prefix) === 0) { - $tablename = substr($table, strlen($this->prefix)); + if (empty($prefix) || strpos($table, $prefix) === 0) { + $tablename = substr($table, strlen($prefix)); $tables[$tablename] = $tablename; } } diff --git a/lib/dml/moodle_database.php b/lib/dml/moodle_database.php index 8539eba448..f2b17338c8 100644 --- a/lib/dml/moodle_database.php +++ b/lib/dml/moodle_database.php @@ -438,7 +438,7 @@ abstract class moodle_database { * Return tables in database WITHOUT current prefix * @return array of table names in lowercase and without prefix */ - public abstract function get_tables(); + public abstract function get_tables($prefix=null); /** * Return table indexes - everything lowercased diff --git a/lib/dml/simpletest/dbspecific.php b/lib/dml/simpletest/dbspecific.php index e403d44705..a3fe7d2e9b 100644 --- a/lib/dml/simpletest/dbspecific.php +++ b/lib/dml/simpletest/dbspecific.php @@ -1,6 +1,6 @@ prefix; + } + $sql = 'SELECT name FROM sqlite_master WHERE type="table" UNION ALL SELECT name FROM sqlite_temp_master WHERE type="table" ORDER BY name'; if ($this->debug) { $this->debug_query($sql); @@ -118,8 +123,8 @@ class sqlite3_pdo_moodle_database extends pdo_moodle_database { foreach ($rstables as $table) { $table = $table['name']; $table = strtolower($table); - if (empty($this->prefix) || strpos($table, $this->prefix) === 0) { - $table = substr($table, strlen($this->prefix)); + if (empty($prefix) || strpos($table, $prefix) === 0) { + $table = substr($table, strlen($prefix)); $tables[$table] = $table; } } @@ -351,4 +356,4 @@ class sqlite3_pdo_moodle_database extends pdo_moodle_database { $value = (int)$this->get_field_sql('SELECT MAX(id) FROM {'.$table.'}'); return $this->change_database_structure("UPDATE sqlite_sequence SET seq=$value WHERE name='$this->prefix$table'"); } -} \ No newline at end of file +} diff --git a/lib/simpletest/fixtures/gradetest.php b/lib/simpletest/fixtures/gradetest.php index 380d42e22a..06f75d3476 100644 --- a/lib/simpletest/fixtures/gradetest.php +++ b/lib/simpletest/fixtures/gradetest.php @@ -49,7 +49,7 @@ Mock::generate('grade_outcome', 'mock_grade_outcome'); * category1 => array(category2 => array(grade_item1, grade_item2), category3 => array(grade_item3)) * 3 users for 3 grade_items */ -class grade_test extends UnitTestCase { +class grade_test extends MoodleUnitTestCase { /** * Each database table receives a number of test entries. These are saved as diff --git a/lib/simpletest/portfolio_testclass.php b/lib/simpletest/portfolio_testclass.php index d25a18ecae..1b4f1d3958 100644 --- a/lib/simpletest/portfolio_testclass.php +++ b/lib/simpletest/portfolio_testclass.php @@ -187,7 +187,7 @@ foreach ($portfolio_plugins as $plugin) { require_once($CFG->libdir . '/portfoliolib.php'); require_once($CFG->dirroot . '/admin/generator.php'); -class portfoliolib_test extends UnitTestCase { +class portfoliolib_test extends MoodleUnitTestCase { public $tables = array(); function setUp() { diff --git a/lib/simpletest/slowtestcode.php b/lib/simpletest/slowtestcode.php index 0a5e8bb4bd..1c2faa3b7a 100644 --- a/lib/simpletest/slowtestcode.php +++ b/lib/simpletest/slowtestcode.php @@ -12,19 +12,19 @@ if (!defined('MOODLE_INTERNAL')) { die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page } -class slow_code_test extends UnitTestCase { +class slow_code_test extends MoodleUnitTestCase { var $php_code_extensions = array('php', 'html', 'php\.inc'); var $ignore_folders = array(); var $phppath; - + function prepend_dirroot($string) { global $CFG; return $CFG->dirroot . $string; } - + function test_php_syntax() { global $CFG; - + // See if we can run php from the command line: $this->phppath = 'php'; if (!shell_exec($this->phppath . ' -v')) { @@ -32,12 +32,12 @@ class slow_code_test extends UnitTestCase { $this->fail('Cannot test PHP syntax because PHP is not on the path.'); return; } - + $regexp = '/\.(' . implode('|', $this->php_code_extensions) . ')$/'; $ignore = array_map(array($this, 'prepend_dirroot'), $this->ignore_folders); - recurseFolders($CFG->dirroot, array($this, 'syntax_check_file'), $regexp, false, $ignore); + recurseFolders($CFG->dirroot, array($this, 'syntax_check_file'), $regexp, false, $ignore); } - + var $dotcount = 0; function syntax_check_file($filepath) { // If you don't print something for each test, then for some reason the @@ -45,7 +45,7 @@ class slow_code_test extends UnitTestCase { // Printing a space does not seem to be good enough. echo '.'; if (++$this->dotcount % 100 == 0) { - echo '
'; + echo '
'; } flush(); $output = shell_exec($this->phppath . ' -d max_execution_time=5 -d short_open_tag= -l ' . escapeshellarg($filepath)); @@ -55,4 +55,4 @@ class slow_code_test extends UnitTestCase { // "File $filepath contains a tab character."); } } -?> \ No newline at end of file +?> diff --git a/lib/simpletest/testaccesslib.php b/lib/simpletest/testaccesslib.php index db04a70ba5..7dff8f5282 100644 --- a/lib/simpletest/testaccesslib.php +++ b/lib/simpletest/testaccesslib.php @@ -12,7 +12,7 @@ if (!defined('MOODLE_INTERNAL')) { die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page } -class accesslib_test extends UnitTestCase { +class accesslib_test extends MoodleUnitTestCase { function setUp() { } diff --git a/lib/simpletest/testajaxlib.php b/lib/simpletest/testajaxlib.php index 611220c8ec..16ef0b20e4 100644 --- a/lib/simpletest/testajaxlib.php +++ b/lib/simpletest/testajaxlib.php @@ -39,14 +39,14 @@ if (!defined('MOODLE_INTERNAL')) { require_once($CFG->libdir . '/moodlelib.php'); require_once($CFG->libdir . '/ajax/ajaxlib.php'); -class ajaxlib_test extends UnitTestCase { - +class ajaxlib_test extends MoodleUnitTestCase { + var $user_agents = array( 'MSIE' => array( '5.5' => array('Windows 2000' => 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)'), '6.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'), '7.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)') - ), + ), 'Firefox' => array( '1.0.6' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6'), '1.5' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5'), @@ -64,14 +64,14 @@ class ajaxlib_test extends UnitTestCase { 'Debian Linux' => 'Opera/9.01 (X11; Linux i686; U; en)') ) ); - + function setUp() { } function tearDown() { } - /** + /** * Uses the array of user agents to test ajax_lib::ajaxenabled */ function test_ajaxenabled() @@ -79,60 +79,60 @@ class ajaxlib_test extends UnitTestCase { global $CFG, $USER; $CFG->enableajax = true; $USER->ajax = true; - + // Should be true $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP']; $this->assertTrue(ajaxenabled()); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['1.5']['Windows XP']; $this->assertTrue(ajaxenabled()); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X']; $this->assertTrue(ajaxenabled()); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP']; $this->assertTrue(ajaxenabled()); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['6.0']['Windows XP SP2']; $this->assertTrue(ajaxenabled()); - + // Should be false $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['1.0.6']['Windows XP']; - $this->assertFalse(ajaxenabled()); - + $this->assertFalse(ajaxenabled()); + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['312']['Mac OS X']; $this->assertFalse(ajaxenabled()); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['8.51']['Windows XP']; $this->assertFalse(ajaxenabled()); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['5.5']['Windows 2000']; $this->assertFalse(ajaxenabled()); - + // Test array of tested browsers $tested_browsers = array('MSIE' => 6.0, 'Gecko' => 20061111); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP']; $this->assertTrue(ajaxenabled($tested_browsers)); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['7.0']['Windows XP SP2']; $this->assertTrue(ajaxenabled($tested_browsers)); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X']; $this->assertFalse(ajaxenabled($tested_browsers)); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP']; $this->assertFalse(ajaxenabled($tested_browsers)); - + $tested_browsers = array('Safari' => 412, 'Opera' => 9.0); $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP']; $this->assertFalse(ajaxenabled($tested_browsers)); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['7.0']['Windows XP SP2']; $this->assertFalse(ajaxenabled($tested_browsers)); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X']; $this->assertTrue(ajaxenabled($tested_browsers)); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP']; $this->assertTrue(ajaxenabled($tested_browsers)); } diff --git a/lib/simpletest/testbackuplib.php b/lib/simpletest/testbackuplib.php index f6f8d8fbfb..1a0da5427b 100644 --- a/lib/simpletest/testbackuplib.php +++ b/lib/simpletest/testbackuplib.php @@ -39,10 +39,10 @@ require_once($CFG->dirroot . '/backup/backuplib.php'); Mock::generate('ADODB_mysql'); Mock::generate('ADORecordSet_mysql'); -class backuplib_test extends UnitTestCase { +class backuplib_test extends MoodleUnitTestCase { var $real_db; var $real_dataroot; - var $rs; + var $rs; var $firstcolumn; var $testfiles = array(); var $userbasedir; diff --git a/lib/simpletest/testcode.php b/lib/simpletest/testcode.php index a39147c9cf..9cd30563d4 100644 --- a/lib/simpletest/testcode.php +++ b/lib/simpletest/testcode.php @@ -12,13 +12,13 @@ if (!defined('MOODLE_INTERNAL')) { die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page } -class code_test extends UnitTestCase { +class code_test extends MoodleUnitTestCase { var $allok = array(); - + var $badstrings; var $extensions_to_ignore = array('exe', 'gif', 'ico', 'jpg', 'png', 'ttf'); var $ignore_folders = array(); - + function test_dnc() { global $CFG; $regexp = '/\.(' . implode('|', $this->extensions_to_ignore) . ')$/'; @@ -35,7 +35,7 @@ class code_test extends UnitTestCase { } } } - + function search_file_for_dnc($filepath) { $content = file_get_contents($filepath); foreach ($this->badstrings as $description => $badstring) { @@ -47,4 +47,4 @@ class code_test extends UnitTestCase { } } } -?> \ No newline at end of file +?> diff --git a/lib/simpletest/testcompletionlib.php b/lib/simpletest/testcompletionlib.php index df9157b04f..227d470a68 100644 --- a/lib/simpletest/testcompletionlib.php +++ b/lib/simpletest/testcompletionlib.php @@ -14,40 +14,40 @@ Mock::generatePartial('completion_info','completion_cutdown2', array('is_enabled','get_data','internal_get_state','internal_set_data')); Mock::generatePartial('completion_info','completion_cutdown3', array('internal_get_grade_state')); - + class fake_recordset implements Iterator { var $closed; var $values,$index; - + function fake_recordset($values) { $this->values=$values; $this->index=0; } - + function current() { return $this->values[$this->index]; } - + function key() { return $this->values[$this->index]; } - + function next() { $this->index++; } - + function rewind() { $this->index=0; } - + function valid() { return count($this->values) > $this->index; } - + function close() { $closed=true; } - + function was_closed() { return $closed; } @@ -59,14 +59,14 @@ class fake_recordset implements Iterator { */ class TimeModifiedExpectation extends SimpleExpectation { private $otherfields; - + /** * @param array $otherfields Array key=>value of required object fields */ function TimeModifiedExpectation($otherfields) { $this->otherfields=$otherfields; } - + function test($thing) { $thingfields=(array)$thing; foreach($this->otherfields as $key=>$value) { @@ -77,19 +77,19 @@ class TimeModifiedExpectation extends SimpleExpectation { return false; } } - + $timedifference=time()-$thing->timemodified; return ($timedifference < 2 && $timedifference>=0); } - + function testMessage($thing) { return "Object does not match fields/time requirement"; } } -class completionlib_test extends UnitTestCase { +class completionlib_test extends MoodleUnitTestCase { var $realdb,$realcfg,$realsession,$realuser; - + function setUp() { global $DB,$CFG,$SESSION,$USER; $this->realdb=$DB; @@ -120,7 +120,7 @@ class completionlib_test extends UnitTestCase { $CFG->enablecompletion=COMPLETION_ENABLED; $this->assertEqual(COMPLETION_ENABLED,completion_info::is_enabled_for_site()); - // Course + // Course $course=new stdClass; $c=new completion_info($course); $course->enablecompletion=COMPLETION_DISABLED; @@ -144,26 +144,26 @@ class completionlib_test extends UnitTestCase { $cm->completion=COMPLETION_TRACKING_AUTOMATIC; $this->assertEqual(COMPLETION_TRACKING_AUTOMATIC,$c->is_enabled($cm)); } - + function test_update_state() { $c=new completion_cutdown2(); $c->__construct((object)array('id'=>42)); $cm=(object)array('id'=>13,'course'=>42); - + // Not enabled, should do nothing $c->expectAt(0,'is_enabled',array($cm)); $c->setReturnValueAt(0,'is_enabled',false); $c->update_state($cm); - + // Enabled, but current state is same as possible result, do nothing $current=(object)array('completionstate'=>COMPLETION_COMPLETE); $c->expectAt(1,'is_enabled',array($cm)); $c->setReturnValueAt(1,'is_enabled',true); - + $c->expectAt(0,'get_data',array($cm,false,0)); $c->setReturnValueAt(0,'get_data',$current); $c->update_state($cm,COMPLETION_COMPLETE); - + // Enabled, but current state is a specific one and new state is just // omplete, so do nothing $current->completionstate=COMPLETION_COMPLETE_PASS; @@ -172,7 +172,7 @@ class completionlib_test extends UnitTestCase { $c->expectAt(1,'get_data',array($cm,false,0)); $c->setReturnValueAt(1,'get_data',$current); $c->update_state($cm,COMPLETION_COMPLETE); - + // Manual, change state (no change) $cm->completion=COMPLETION_TRACKING_MANUAL; $current->completionstate=COMPLETION_COMPLETE; @@ -181,16 +181,16 @@ class completionlib_test extends UnitTestCase { $c->expectAt(2,'get_data',array($cm,false,0)); $c->setReturnValueAt(2,'get_data',$current); $c->update_state($cm,COMPLETION_COMPLETE); - + // Manual, change state (change) $c->expectAt(4,'is_enabled',array($cm)); $c->setReturnValueAt(4,'is_enabled',true); $c->expectAt(3,'get_data',array($cm,false,0)); $c->setReturnValueAt(3,'get_data',$current); $c->expectAt(0,'internal_set_data',array($cm, - new TimeModifiedExpectation(array('completionstate'=>COMPLETION_INCOMPLETE)))); + new TimeModifiedExpectation(array('completionstate'=>COMPLETION_INCOMPLETE)))); $c->update_state($cm,COMPLETION_INCOMPLETE); - + // Auto, change state $cm->completion=COMPLETION_TRACKING_AUTOMATIC; $c->expectAt(5,'is_enabled',array($cm)); @@ -200,62 +200,62 @@ class completionlib_test extends UnitTestCase { $c->expectAt(0,'internal_get_state',array($cm,0,$current)); $c->setReturnValueAt(0,'internal_get_state',COMPLETION_COMPLETE_PASS); $c->expectAt(1,'internal_set_data',array($cm, - new TimeModifiedExpectation(array('completionstate'=>COMPLETION_COMPLETE_PASS)))); + new TimeModifiedExpectation(array('completionstate'=>COMPLETION_COMPLETE_PASS)))); $c->update_state($cm,COMPLETION_COMPLETE_PASS); $c->tally(); } - + function test_internal_get_state() { global $DB; - + $c=new completion_cutdown3(); $c->__construct((object)array('id'=>42)); $cm=(object)array('id'=>13,'course'=>42,'completiongradeitemnumber'=>null); - + // If view is required, but they haven't viewed it yet $cm->completionview=COMPLETION_VIEW_REQUIRED; - $current=(object)array('viewed'=>COMPLETION_NOT_VIEWED); + $current=(object)array('viewed'=>COMPLETION_NOT_VIEWED); $this->assertEqual(COMPLETION_INCOMPLETE,$c->internal_get_state($cm,123,$current)); - + // OK set view not required $cm->completionview=COMPLETION_VIEW_NOT_REQUIRED; - + // Test not getting module name $cm->modname='label'; $this->assertEqual(COMPLETION_COMPLETE,$c->internal_get_state($cm,123,$current)); - + // Test getting module name $cm->module=13; unset($cm->modname); $DB->expectOnce('get_field',array('modules','name',array('id'=>13))); - $DB->setReturnValue('get_field','label'); + $DB->setReturnValue('get_field','label'); $this->assertEqual(COMPLETION_COMPLETE,$c->internal_get_state($cm,123,$current)); - + // Note: This function is not fully tested (including kind of the main // part) because: // * the grade_item/grade_grade calls are static and can't be mocked - // * the plugin_supports call is static and can't be mocked - + // * the plugin_supports call is static and can't be mocked + $DB->tally(); $c->tally(); } - + function test_set_module_viewed() { $c=new completion_cutdown(); $c->__construct((object)array('id'=>42)); $cm=(object)array('id'=>13,'course'=>42); - - // Not tracking completion, should do nothing + + // Not tracking completion, should do nothing $cm->completionview=COMPLETION_VIEW_NOT_REQUIRED; $c->set_module_viewed($cm); - + // Tracking completion but completion is disabled, should do nothing $cm->completionview=COMPLETION_VIEW_REQUIRED; $c->expectAt(0,'is_enabled',array($cm)); $c->setReturnValueAt(0,'is_enabled',false); $c->set_module_viewed($cm); - + // Now it's enabled, we expect it to get data. If data already has // viewed, still do nothing $c->expectAt(1,'is_enabled',array($cm)); @@ -264,7 +264,7 @@ class completionlib_test extends UnitTestCase { $hasviewed=(object)array('viewed'=>COMPLETION_VIEWED); $c->setReturnValueAt(0,'get_data',$hasviewed); $c->set_module_viewed($cm); - + // OK finally one that hasn't been viewed, now it should set it viewed // and update state $c->expectAt(2,'is_enabled',array($cm)); @@ -275,14 +275,14 @@ class completionlib_test extends UnitTestCase { $c->expectOnce('internal_set_data',array($cm,$hasviewed)); $c->expectOnce('update_state',array($cm,COMPLETION_COMPLETE,1337)); $c->set_module_viewed($cm,1337); - + $c->tally(); } - + function test_count_user_data() { global $DB; $cm=(object)array('id'=>42); - $DB->setReturnValue('get_field_sql',666); + $DB->setReturnValue('get_field_sql',666); $DB->expectOnce('get_field_sql',array(new IgnoreWhitespaceExpectation("SELECT COUNT(1) FROM @@ -291,10 +291,10 @@ WHERE coursemoduleid=? AND completionstate<>0"),array(42))); $c=new completion_info(null); $this->assertEqual(666,$c->count_user_data($cm)); - + $DB->tally(); } - + function test_delete_all_state() { global $DB,$SESSION; $course=(object)array('id'=>13); @@ -303,8 +303,8 @@ WHERE // Check it works ok without data in session $DB->expectAt(0,'delete_records', array('course_modules_completion',array('coursemoduleid'=>42))); - $c->delete_all_state($cm); - + $c->delete_all_state($cm); + // Build up a session to check it deletes the right bits from it // (and not other bits) $SESSION->completioncache=array(); @@ -318,17 +318,17 @@ WHERE $c->delete_all_state($cm); $this->assertEqual(array(13=>array(43=>'foo'),14=>array(42=>'foo')), $SESSION->completioncache); - + $DB->tally(); } - + function test_reset_all_state() { global $DB; $c=new completion_cutdown(); $c->__construct((object)array('id'=>42)); - + $cm=(object)array('id'=>13,'course'=>42); - + $DB->setReturnValue('get_recordset',new fake_recordset(array( (object)array('id'=>1,'userid'=>100), (object)array('id'=>2,'userid'=>101), @@ -341,23 +341,23 @@ WHERE (object)array('id'=>100,'firstname'=>'Woot','lastname'=>'Plugh'), (object)array('id'=>201,'firstname'=>'Vroom','lastname'=>'Xyzzy'), )); - + $c->expectAt(0,'update_state',array($cm,COMPLETION_UNKNOWN,100)); $c->expectAt(1,'update_state',array($cm,COMPLETION_UNKNOWN,101)); $c->expectAt(2,'update_state',array($cm,COMPLETION_UNKNOWN,201)); - + $c->reset_all_state($cm); - + $DB->tally(); $c->tally(); } - + function test_get_data() { global $DB,$SESSION; - - $c=new completion_info((object)array('id'=>42)); + + $c=new completion_info((object)array('id'=>42)); $cm=(object)array('id'=>13,'course'=>42); - + // 1. Not current user, record exists $sillyrecord=(object)array('frog'=>'kermit'); $DB->expectAt(0,'get_record',array('course_modules_completion', @@ -366,7 +366,7 @@ WHERE $result=$c->get_data($cm,false,123); $this->assertEqual($sillyrecord,$result); $this->assertTrue(empty($SESSION->completioncache)); - + // 2. Not current user, default record, wholecourse (ignored) $DB->expectAt(1,'get_record',array('course_modules_completion', array('coursemoduleid'=>13,'userid'=>123))); @@ -376,7 +376,7 @@ WHERE 'id'=>'0','coursemoduleid'=>13,'userid'=>123,'completionstate'=>0, 'viewed'=>0,'timemodified'=>0),$result); $this->assertTrue(empty($SESSION->completioncache)); - + // 3. Current user, single record, not from cache $DB->expectAt(2,'get_record',array('course_modules_completion', array('coursemoduleid'=>13,'userid'=>314159))); @@ -384,71 +384,71 @@ WHERE $result=$c->get_data($cm); $this->assertEqual($sillyrecord,$result); $this->assertEqual($sillyrecord,$SESSION->completioncache[42][13]); - // When checking time(), allow for second overlaps + // When checking time(), allow for second overlaps $this->assertTrue(time()-$SESSION->completioncache[42]['updated']<2); - - // 4. Current user, 'whole course', but from cache + + // 4. Current user, 'whole course', but from cache $result=$c->get_data($cm,true); $this->assertEqual($sillyrecord,$result); - + // 5. Current user, single record, cache expired $SESSION->completioncache[42]['updated']=37; // Quite a long time ago $now=time(); $SESSION->completioncache[17]['updated']=$now; - $SESSION->completioncache[39]['updated']=72; // Also a long time ago + $SESSION->completioncache[39]['updated']=72; // Also a long time ago $DB->expectAt(3,'get_record',array('course_modules_completion', array('coursemoduleid'=>13,'userid'=>314159))); $DB->setReturnValueAt(3,'get_record',$sillyrecord); $result=$c->get_data($cm,false); $this->assertEqual($sillyrecord,$result); - // Check that updated value is right, then fudge it to make next compare + // Check that updated value is right, then fudge it to make next compare // work $this->assertTrue(time()-$SESSION->completioncache[42]['updated']<2); $SESSION->completioncache[42]['updated']=$now; // Check things got expired from cache $this->assertEqual(array(42=>array(13=>$sillyrecord,'updated'=>$now), 17=>array('updated'=>$now)),$SESSION->completioncache); - + // 6. Current user, 'whole course' and record not in cache unset($SESSION->completioncache); - + // Scenario: Completion data exists for one CMid $basicrecord=(object)array('coursemoduleid'=>13); $DB->setReturnValueAt(0,'get_records_sql',array( 1=>$basicrecord - )); + )); $DB->expectAt(0,'get_records_sql',array(new IgnoreWhitespaceExpectation(" SELECT cmc.* FROM {course_modules} cm INNER JOIN {course_modules_completion} cmc ON cmc.coursemoduleid=cm.id -WHERE +WHERE cm.course=? AND cmc.userid=?"),array(42,314159))); // There are two CMids in total, the one we had data for and another one $modinfo->cms=array((object)array('id'=>13),(object)array('id'=>14)); $result=$c->get_data($cm,true,0,$modinfo); - + // Check result $this->assertEqual($basicrecord,$result); - + // Check the cache contents $this->assertTrue(time()-$SESSION->completioncache[42]['updated']<2); $SESSION->completioncache[42]['updated']=$now; $this->assertEqual(array(42=>array(13=>$basicrecord,14=>(object)array( 'id'=>'0','coursemoduleid'=>14,'userid'=>314159,'completionstate'=>0, 'viewed'=>0,'timemodified'=>0),'updated'=>$now)),$SESSION->completioncache); - + $DB->tally(); } - + function test_internal_set_data() { global $DB,$SESSION; - + $cm=(object)array('course'=>42,'id'=>13); - $c=new completion_info((object)array('id'=>42)); - + $c=new completion_info((object)array('id'=>42)); + // 1) Test with new data $data=(object)array('id'=>0,'userid'=>314159); $DB->setReturnValueAt(0,'insert_record',4); @@ -456,29 +456,29 @@ WHERE $c->internal_set_data($cm,$data); $this->assertEqual(4,$data->id); $this->assertEqual(array(42=>array(13=>$data)),$SESSION->completioncache); - + // 2) Test with existing data and for different user (not cached) unset($SESSION->completioncache); $d2=(object)array('id'=>7,'userid'=>17); $DB->expectAt(0,'update_record',array('course_modules_completion',$d2)); $c->internal_set_data($cm,$d2); $this->assertFalse(isset($SESSION->completioncache)); - + $DB->tally(); } - + function test_get_activities() { global $DB; - + $c=new completion_info((object)array('id'=>42)); - + // Try with no activities $DB->expectAt(0,'get_records_select',array('course_modules', 'course=42 AND completion<>'.COMPLETION_TRACKING_NONE)); $DB->setReturnValueAt(0,'get_records_select',array()); $result=$c->get_activities(); $this->assertEqual(array(),$result); - + // Try with an activity (need to fake up modinfo for it as well) $DB->expectAt(1,'get_records_select',array('course_modules', 'course=42 AND completion<>'.COMPLETION_TRACKING_NONE)); @@ -490,20 +490,20 @@ WHERE $modinfo->cms[13]=(object)array('modname'=>'frog','name'=>'kermit'); $result=$c->get_activities($modinfo); $this->assertEqual(array(13=>(object)array('id'=>13,'modname'=>'frog','name'=>'kermit')),$result); - - $DB->tally(); + + $DB->tally(); } - - // internal_get_tracked_users() cannot easily be tested because it uses + + // internal_get_tracked_users() cannot easily be tested because it uses // get_role_users, so skipping that - + function test_get_progress_all() { global $DB; - + $c=new completion_cutdown(); $c->__construct((object)array('id'=>42)); - - // 1) Basic usage + + // 1) Basic usage $c->expectAt(0,'internal_get_tracked_users',array(false,0)); $c->setReturnValueAt(0,'internal_get_tracked_users',array( (object)array('id'=>100,'firstname'=>'Woot','lastname'=>'Plugh'), @@ -531,10 +531,10 @@ WHERE 201 => (object)array('id'=>201,'firstname'=>'Vroom','lastname'=>'Xyzzy', 'progress'=>array(14=>$progress2)), ),$c->get_progress_all(false)); - + // 2) With more than 1,000 results $c->expectAt(1,'internal_get_tracked_users',array(true,3)); - + $tracked=array(); $ids=array(); $progress=array(); @@ -545,7 +545,7 @@ WHERE $progress[]=(object)array('userid'=>$i,'coursemoduleid'=>14); } $c->setReturnValueAt(1,'internal_get_tracked_users',$tracked); - + $DB->expectAt(1,'get_in_or_equal',array(array_slice($ids,0,1000))); $DB->setReturnValueAt(1,'get_in_or_equal',array(' IN whatever',array())); $DB->expectAt(1,'get_recordset_sql',array(new IgnoreWhitespaceExpectation(" @@ -568,50 +568,50 @@ FROM WHERE cm.course=? AND cmc.userid IN whatever2"),array(42))); $DB->setReturnValueAt(2,'get_recordset_sql',new fake_recordset(array_slice($progress,1000))); - + $result=$c->get_progress_all(true,3); - + $resultok=true; $resultok = $resultok && ($ids==array_keys($result)); foreach($result as $userid => $data) { $resultok = $resultok && $data->firstname=='frog'; $resultok = $resultok && $data->lastname==$userid; - $resultok = $resultok && $data->id==$userid; + $resultok = $resultok && $data->id==$userid; $cms=$data->progress; $resultok= $resultok && (array(13,14)==array_keys($cms)); $resultok= $resultok && ((object)array('userid'=>$userid,'coursemoduleid'=>13)==$cms[13]); - $resultok= $resultok && ((object)array('userid'=>$userid,'coursemoduleid'=>14)==$cms[14]); + $resultok= $resultok && ((object)array('userid'=>$userid,'coursemoduleid'=>14)==$cms[14]); } $this->assertTrue($resultok); - - $DB->tally(); + + $DB->tally(); $c->tally(); } - + function test_inform_grade_changed() { $c=new completion_cutdown(); $c->__construct((object)array('id'=>42)); - + $cm=(object)array('course'=>42,'id'=>13,'completiongradeitemnumber'=>null); $item=(object)array('itemnumber'=>3); $grade=(object)array('userid'=>31337); - + // Not enabled (should do nothing) $c->setReturnValueAt(0,'is_enabled',false); $c->expectAt(0,'is_enabled',array($cm)); $c->inform_grade_changed($cm,$item,$grade,false); - + // Enabled but still no grade completion required, should still do nothing $c->setReturnValueAt(1,'is_enabled',true); $c->expectAt(1,'is_enabled',array($cm)); $c->inform_grade_changed($cm,$item,$grade,false); - + // Enabled and completion required but item number is wrong, does nothing $cm->completiongradeitemnumber=7; $c->setReturnValueAt(2,'is_enabled',true); $c->expectAt(2,'is_enabled',array($cm)); $c->inform_grade_changed($cm,$item,$grade,false); - + // Enabled and completion required and item number right. It is supposed // to call update_state with the new potential state being obtained from // internal_get_grade_state. @@ -622,49 +622,49 @@ WHERE $c->setReturnValueAt(0,'internal_get_grade_state',COMPLETION_COMPLETE_PASS); $c->expectAt(0,'update_state',array($cm,COMPLETION_COMPLETE_PASS,31337)); $c->inform_grade_changed($cm,$item,$grade,false); - + // Same as above but marked deleted. It is supposed to call update_state // with new potential state being COMPLETION_INCOMPLETE $c->setReturnValueAt(4,'is_enabled',false); $c->expectAt(4,'is_enabled',array($cm)); $c->expectAt(1,'update_state',array($cm,COMPLETION_INCOMPLETE,31337)); $c->inform_grade_changed($cm,$item,$grade,false); - + $c->tally(); } function test_internal_get_grade_state() { $item=new stdClass; $grade=new stdClass; - + $item->gradepass=4; $item->hidden=0; $grade->rawgrade=4.0; $grade->finalgrade=null; - + // Grade has pass mark and is not hidden, user passes $this->assertEqual( COMPLETION_COMPLETE_PASS, completion_info::internal_get_grade_state($item,$grade)); - + // Same but user fails $grade->rawgrade=3.9; $this->assertEqual( COMPLETION_COMPLETE_FAIL, completion_info::internal_get_grade_state($item,$grade)); - + // User fails on raw grade but passes on final $grade->finalgrade=4.0; $this->assertEqual( COMPLETION_COMPLETE_PASS, completion_info::internal_get_grade_state($item,$grade)); - + // Item is hidden $item->hidden=1; $this->assertEqual( COMPLETION_COMPLETE, completion_info::internal_get_grade_state($item,$grade)); - + // Item isn't hidden but has no pass mark $item->hidden=0; $item->gradepass=0; @@ -673,4 +673,4 @@ WHERE completion_info::internal_get_grade_state($item,$grade)); } } -?> \ No newline at end of file +?> diff --git a/lib/simpletest/testeventslib.php b/lib/simpletest/testeventslib.php index 177eebe189..5eddc25e14 100755 --- a/lib/simpletest/testeventslib.php +++ b/lib/simpletest/testeventslib.php @@ -74,7 +74,7 @@ class sample_handler_class { } } -class eventslib_test extends UnitTestCase { +class eventslib_test extends MoodleUnitTestCase { private $realdb; /** * Create temporary entries in the database for these tests. diff --git a/lib/simpletest/testmathslib.php b/lib/simpletest/testmathslib.php index 071490dc57..e15932bd9e 100755 --- a/lib/simpletest/testmathslib.php +++ b/lib/simpletest/testmathslib.php @@ -12,7 +12,7 @@ require_once($CFG->libdir . '/mathslib.php'); * @author Petr Skoda (skodak) * @version $Id$ */ -class mathsslib_test extends UnitTestCase { +class mathsslib_test extends MoodleUnitTestCase { /** * Tests the basic formula evaluation @@ -76,4 +76,4 @@ class mathsslib_test extends UnitTestCase { } -?> \ No newline at end of file +?> diff --git a/lib/simpletest/testmoodlelib.php b/lib/simpletest/testmoodlelib.php index bdeb7cda5f..26e755e2ef 100644 --- a/lib/simpletest/testmoodlelib.php +++ b/lib/simpletest/testmoodlelib.php @@ -39,14 +39,14 @@ if (!defined('MOODLE_INTERNAL')) { require_once($CFG->libdir . '/moodlelib.php'); -class moodlelib_test extends UnitTestCase { - +class moodlelib_test extends MoodleUnitTestCase { + var $user_agents = array( 'MSIE' => array( '5.5' => array('Windows 2000' => 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)'), '6.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'), '7.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)') - ), + ), 'Firefox' => array( '1.0.6' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6'), '1.5' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5'), @@ -64,7 +64,7 @@ class moodlelib_test extends UnitTestCase { 'Debian Linux' => 'Opera/9.01 (X11; Linux i686; U; en)') ) ); - + function setUp() { } @@ -103,45 +103,45 @@ class moodlelib_test extends UnitTestCase { $this->assertFalse(address_in_subnet(' 2.3.234.1 ', ' 123.121.234.1 , 1.1.1.1/16,2.2.,3.3.3.3-6 ')); $this->assertFalse(address_in_subnet(' 3.3.3.7 ', ' 123.121.234.1 , 1.1.1.1/16,2.2.,3.3.3.3-6 ')); } - + /** - * Modifies $_SERVER['HTTP_USER_AGENT'] manually to check if check_browser_version + * Modifies $_SERVER['HTTP_USER_AGENT'] manually to check if check_browser_version * works as expected. */ function test_check_browser_version() { global $CFG; - - $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X']; + + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X']; $this->assertTrue(check_browser_version('Safari', '312')); $this->assertFalse(check_browser_version('Safari', '500')); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP']; $this->assertTrue(check_browser_version('Opera', '8.0')); $this->assertFalse(check_browser_version('Opera', '10.0')); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['6.0']['Windows XP SP2']; $this->assertTrue(check_browser_version('MSIE', '5.0')); $this->assertFalse(check_browser_version('MSIE', '7.0')); - + $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP']; $this->assertTrue(check_browser_version('Firefox', '1.5')); - $this->assertFalse(check_browser_version('Firefox', '3.0')); + $this->assertFalse(check_browser_version('Firefox', '3.0')); } - + function test_optional_param() { - $_POST['username'] = 'post_user'; + $_POST['username'] = 'post_user'; $_GET['username'] = 'get_user'; $this->assertEqual(optional_param('username', 'default_user'), 'post_user'); - + unset($_POST['username']); $this->assertEqual(optional_param('username', 'default_user'), 'get_user'); - + unset($_GET['username']); $this->assertEqual(optional_param('username', 'default_user'), 'default_user'); } - + /** * Used by {@link optional_param()} and {@link required_param()} to * clean the variables and/or cast to specific types, based on @@ -176,12 +176,12 @@ class moodlelib_test extends UnitTestCase { { global $CFG; // Test unknown parameter type - + // Test Raw param - $this->assertEqual(clean_param('#()*#,9789\'".,<42897>assertEqual(clean_param('#()*#,9789\'".,<42897>assertEqual(clean_param('#()*#,9789\'".,<42897>assertEqual(clean_param('#()*#,9789\'".,<42897>assertFalse(make_user_directory('string', true)); $this->assertFalse(make_user_directory(false, true)); $this->assertFalse(make_user_directory(true, true)); - + } } diff --git a/lib/simpletest/testportfolioaddbutton.php b/lib/simpletest/testportfolioaddbutton.php index 3b0c5517c8..4a46de96cd 100644 --- a/lib/simpletest/testportfolioaddbutton.php +++ b/lib/simpletest/testportfolioaddbutton.php @@ -37,7 +37,7 @@ if (!defined('MOODLE_INTERNAL')) { require_once($CFG->libdir . '/portfoliolib.php'); -class portfoliolibaddbutton_test extends UnitTestCase { +class portfoliolibaddbutton_test extends MoodleMoodleUnitTestCase { function setUp() { global $DB, $CFG; diff --git a/lib/simpletest/testweblib.php b/lib/simpletest/testweblib.php index aa704daaef..708b58e974 100644 --- a/lib/simpletest/testweblib.php +++ b/lib/simpletest/testweblib.php @@ -12,7 +12,7 @@ if (!defined('MOODLE_INTERNAL')) { die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page } -class web_test extends UnitTestCase { +class web_test extends MoodleUnitTestCase { function setUp() { } @@ -22,25 +22,25 @@ class web_test extends UnitTestCase { function test_format_string() { // Ampersands - $this->assertEqual(format_string("& &&&&& &&"), "& &&&&& &&"); + $this->assertEqual(format_string("& &&&&& &&"), "& &&&&& &&"); $this->assertEqual(format_string("ANother & &&&&& Category"), "ANother & &&&&& Category"); $this->assertEqual(format_string("ANother & &&&&& Category", true), "ANother & &&&&& Category"); $this->assertEqual(format_string("Nick's Test Site & Other things", true), "Nick's Test Site & Other things"); - + // String entities $this->assertEqual(format_string("""), """); - + // Digital entities $this->assertEqual(format_string("&11234;"), "&11234;"); - + // Unicode entities $this->assertEqual(format_string("ᅻ"), "ᅻ"); - } - + } + function test_s() { - $this->assertEqual(s("This Breaks \" Strict"), "This Breaks " Strict"); + $this->assertEqual(s("This Breaks \" Strict"), "This Breaks " Strict"); } - + function test_format_text_email() { $this->assertEqual('This is a test', format_text_email('

This is a test

',FORMAT_HTML)); diff --git a/lib/simpletestlib.php b/lib/simpletestlib.php index 823b7d46bf..9a1b6e0d14 100644 --- a/lib/simpletestlib.php +++ b/lib/simpletestlib.php @@ -1,9 +1,9 @@ libdir . '/simpletestlib/mock_objects.php'); /** * Recursively visit all the files in the source tree. Calls the callback - * function with the pathname of each file found. - * - * @param $path the folder to start searching from. + * function with the pathname of each file found. + * + * @param $path the folder to start searching from. * @param $callback the function to call with the name of each file found. * @param $fileregexp a regexp used to filter the search (optional). - * @param $exclude If true, pathnames that match the regexp will be ingored. If false, + * @param $exclude If true, pathnames that match the regexp will be ingored. If false, * only files that match the regexp will be included. (default false). * @param array $ignorefolders will not go into any of these folders (optional). - */ + */ function recurseFolders($path, $callback, $fileregexp = '/.*/', $exclude = false, $ignorefolders = array()) { $files = scandir($path); @@ -149,4 +149,34 @@ class CheckSpecifiedFieldsExpectation extends SimpleExpectation { } } +class MoodleUnitTestCase extends UnitTestCase { + public function __construct($label = false) { + parent::UnitTestCase($label); + global $CFG, $DB; + + if (empty($CFG->unittest_prefix)) { + print_error("prefixnotset", 'simpletest'); + } + + if (!$DB->table_exists('user')) { + print_error('tablesnotsetup', 'simpletest'); + } + } + + public function setUp() { + parent::setUp(); + } + + public function tearDown() { + parent::tearDown(); + } + + /** + * This will execute once all the tests have been run. It should delete the text file holding info about database contents prior to the tests + */ + public function __destruct() { + + } +} + ?> diff --git a/mod/data/simpletest/testpreset.php b/mod/data/simpletest/testpreset.php index e7160a0368..dd6cb95838 100644 --- a/mod/data/simpletest/testpreset.php +++ b/mod/data/simpletest/testpreset.php @@ -37,8 +37,8 @@ if (!defined('MOODLE_INTERNAL')) { require_once($CFG->dirroot . '/mod/data/preset_class.php'); -class data_preset_test extends UnitTestCase { - +class data_preset_test extends MoodleUnitTestCase { + function setUp() { } @@ -47,15 +47,15 @@ class data_preset_test extends UnitTestCase { function test_address_in_subnet() { } - + /** - * Modifies $_SERVER['HTTP_USER_AGENT'] manually to check if check_browser_version + * Modifies $_SERVER['HTTP_USER_AGENT'] manually to check if check_browser_version * works as expected. */ function test_check_browser_version() { } - + function test_optional_param() { } diff --git a/mod/forum/simpletest/testmodforumlib.php b/mod/forum/simpletest/testmodforumlib.php index 7f490383ba..b08ec912ed 100644 --- a/mod/forum/simpletest/testmodforumlib.php +++ b/mod/forum/simpletest/testmodforumlib.php @@ -39,7 +39,7 @@ if (!defined('MOODLE_INTERNAL')) { require_once($CFG->dirroot . '/mod/forum/lib.php'); -class modforumlib_test extends UnitTestCase { +class modforumlib_test extends MoodleUnitTestCase { function setUp() { } diff --git a/mod/quiz/simpletest/testaccessrules.php b/mod/quiz/simpletest/testaccessrules.php index efe3cf75c3..8ec7647c16 100644 --- a/mod/quiz/simpletest/testaccessrules.php +++ b/mod/quiz/simpletest/testaccessrules.php @@ -14,7 +14,7 @@ if (!defined('MOODLE_INTERNAL')) { require_once($CFG->dirroot . '/mod/quiz/locallib.php'); -class simple_rules_test extends UnitTestCase { +class simple_rules_test extends MoodleUnitTestCase { function test_num_attempts_access_rule() { $quiz = new stdClass; $quiz->attempts = 3; @@ -77,7 +77,7 @@ class simple_rules_test extends UnitTestCase { } } -class open_close_date_access_rule_test extends UnitTestCase { +class open_close_date_access_rule_test extends MoodleUnitTestCase { function test_no_dates() { $quiz = new stdClass; $quiz->timeopen = 0; @@ -187,7 +187,7 @@ class open_close_date_access_rule_test extends UnitTestCase { } } -class inter_attempt_delay_access_rule_test extends UnitTestCase { +class inter_attempt_delay_access_rule_test extends MoodleUnitTestCase { function test_just_first_delay() { $quiz = new stdClass; $quiz->attempts = 3; @@ -329,7 +329,7 @@ class inter_attempt_delay_access_rule_test extends UnitTestCase { } } -class password_access_rule_test extends UnitTestCase { +class password_access_rule_test extends MoodleUnitTestCase { function test_password_access_rule() { $quiz = new stdClass; $quiz->password = 'frog'; @@ -379,7 +379,7 @@ class password_access_rule_test extends UnitTestCase { } } -class securewindow_access_rule_test extends UnitTestCase { +class securewindow_access_rule_test extends MoodleUnitTestCase { // Nothing very testable in this class, just test that it obeys the general access rule contact. function test_securewindow_access_rule() { @@ -396,7 +396,7 @@ class securewindow_access_rule_test extends UnitTestCase { } } -class quiz_access_manager_test extends UnitTestCase { +class quiz_access_manager_test extends MoodleUnitTestCase { // TODO } ?> diff --git a/question/type/numerical/simpletest/testquestiontype.php b/question/type/numerical/simpletest/testquestiontype.php index 72731af5fe..a9da903c9e 100644 --- a/question/type/numerical/simpletest/testquestiontype.php +++ b/question/type/numerical/simpletest/testquestiontype.php @@ -14,16 +14,16 @@ if (!defined('MOODLE_INTERNAL')) { require_once($CFG->dirroot . '/question/type/numerical/questiontype.php'); -class question_numerical_qtype_test extends UnitTestCase { - var $tolerance = 0.00000001; +class question_numerical_qtype_test extends MoodleUnitTestCase { + var $tolerance = 0.00000001; var $qtype; - + function setUp() { $this->qtype = new question_numerical_qtype(); } - + function tearDown() { - $this->qtype = null; + $this->qtype = null; } function test_name() { @@ -129,7 +129,7 @@ class question_numerical_qtype_test extends UnitTestCase { (object) array('unit' => 'mm', 'multiplier' => 1000), (object) array('unit' => 'inch', 'multiplier' => 1.0/0.0254) ); - + $this->assertWithinMargin($this->qtype->apply_unit('1', $units), 1, $this->tolerance); $this->assertWithinMargin($this->qtype->apply_unit('1.0', $units), 1, $this->tolerance); $this->assertWithinMargin($this->qtype->apply_unit('-1e0', $units), -1, $this->tolerance); diff --git a/question/type/shortanswer/simpletest/testquestiontype.php b/question/type/shortanswer/simpletest/testquestiontype.php index 00cffdc99f..3f7e9630f2 100644 --- a/question/type/shortanswer/simpletest/testquestiontype.php +++ b/question/type/shortanswer/simpletest/testquestiontype.php @@ -14,15 +14,15 @@ if (!defined('MOODLE_INTERNAL')) { require_once($CFG->dirroot . '/question/type/questiontype.php'); -class question_shortanswer_qtype_test extends UnitTestCase { +class question_shortanswer_qtype_test extends MoodleUnitTestCase { var $qtype; - + function setUp() { $this->qtype = new question_shortanswer_qtype(); } - + function tearDown() { - $this->qtype = null; + $this->qtype = null; } function test_name() { -- 2.39.5