Skip to content

Commit

Permalink
MDL-42400 generator: module generators call add_moduleinfo instead of…
Browse files Browse the repository at this point in the history
… direct inserts
  • Loading branch information
marinaglancy committed Oct 26, 2013
1 parent b4b7587 commit 7fbe33f
Show file tree
Hide file tree
Showing 18 changed files with 194 additions and 409 deletions.
4 changes: 3 additions & 1 deletion badges/tests/badgeslib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ protected function setUp() {

unset_config('noemailever');

$CFG->enablecompletion = true;

$user = $this->getDataGenerator()->create_user();

$fordb = new stdClass();
Expand All @@ -69,7 +71,7 @@ protected function setUp() {
$this->badgeid = $DB->insert_record('badge', $fordb, true);

// Create a course with activity and auto completion tracking.
$this->course = $this->getDataGenerator()->create_course();
$this->course = $this->getDataGenerator()->create_course(array('enablecompletion' => true));
$this->user = $this->getDataGenerator()->create_user();
$studentrole = $DB->get_record('role', array('shortname' => 'student'));
$this->assertNotEmpty($studentrole);
Expand Down
3 changes: 2 additions & 1 deletion course/modlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ function add_moduleinfo($moduleinfo, $course, $mform = null) {
print_error('cannotaddcoursemodule');
}

if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true)) {
if (plugin_supports('mod', $moduleinfo->modulename, FEATURE_MOD_INTRO, true) &&
isset($moduleinfo->introeditor)) {
$introeditor = $moduleinfo->introeditor;
unset($moduleinfo->introeditor);
$moduleinfo->intro = $introeditor['text'];
Expand Down
143 changes: 138 additions & 5 deletions lib/testing/generator/module_generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ public function get_modulename() {

/**
* Create course module and link it to course
*
* Since 2.6 it is recommended to use function add_moduleinfo() to create a module.
*
* @deprecated since 2.6
* @see testing_module_generator::create_instance()
*
* @param integer $courseid
* @param array $options section, visible
* @return integer $cm instance id
Expand Down Expand Up @@ -110,6 +116,12 @@ protected function precreate_course_module($courseid, array $options) {

/**
* Called after *_add_instance()
*
* Since 2.6 it is recommended to use function add_moduleinfo() to create a module.
*
* @deprecated since 2.6
* @see testing_module_generator::create_instance()
*
* @param int $id
* @param int $cmid
* @return stdClass module instance
Expand All @@ -130,12 +142,133 @@ protected function post_add_instance($id, $cmid) {
}

/**
* Create a test module
* @param array|stdClass $record
* @param array $options
* @return stdClass activity record
* Merges together arguments $record and $options and fills default module
* fields that are shared by all module types
*
* @param object|array $record fields (different from defaults) for this module
* @param null|array $options for backward-compatibility this may include fields from course_modules
* table. They are merged into $record
* @throws coding_exception if $record->course is not specified
*/
abstract public function create_instance($record = null, array $options = null);
protected function prepare_moduleinfo_record($record, $options) {
global $DB;
// Make sure we don't modify the original object.
$moduleinfo = (object)(array)$record;

if (empty($moduleinfo->course)) {
throw new coding_exception('module generator requires $record->course');
}

$moduleinfo->modulename = $this->get_modulename();
$moduleinfo->module = $DB->get_field('modules', 'id', array('name' => $moduleinfo->modulename));

// Allow idnumber to be set as either $options['idnumber'] or $moduleinfo->cmidnumber or $moduleinfo->idnumber.
// The actual field name is 'idnumber' but add_moduleinfo() expects 'cmidnumber'.
if (isset($options['idnumber'])) {
$moduleinfo->cmidnumber = $options['idnumber'];
} else if (!isset($moduleinfo->cmidnumber) && isset($moduleinfo->idnumber)) {
$moduleinfo->cmidnumber = $moduleinfo->idnumber;
}

// These are the fields from table 'course_modules' in 2.6 when the second
// argument $options is being deprecated.
// List excludes fields: instance (does not exist yet), course, module and idnumber (set above)
$easymergefields = array('section', 'added', 'score', 'indent',
'visible', 'visibleold', 'groupmode', 'groupingid', 'groupmembersonly',
'completion', 'completiongradeitemnumber', 'completionview', 'completionexpected',
'availablefrom', 'availableuntil', 'showavailability', 'showdescription');
foreach ($easymergefields as $key) {
if (isset($options[$key])) {
$moduleinfo->$key = $options[$key];
}
}

// Set default values. Note that visibleold and completiongradeitemnumber are not used when creating a module.
$defaults = array(
'section' => 0,
'visible' => 1,
'cmidnumber' => '',
'groupmode' => 0,
'groupingid' => 0,
'groupmembersonly' => 0,
'showavailability' => 0,
'availablefrom' => 0,
'availableuntil' => 0,
'completion' => 0,
'completionview' => 0,
'completionexpected' => 0,
'conditiongradegroup' => array(),
'conditionfieldgroup' => array(),
'conditioncompletiongroup' => array()
);
foreach ($defaults as $key => $value) {
if (!isset($moduleinfo->$key)) {
$moduleinfo->$key = $value;
}
}

return $moduleinfo;
}

/**
* Creates an instance of the module for testing purposes.
*
* Module type will be taken from the class name. Each module type may overwrite
* this function to add other default values used by it.
*
* @param array|stdClass $record data for module being generated. Requires 'course' key
* (an id or the full object). Also can have any fields from add module form.
* @param null|array $options general options for course module. Since 2.6 it is
* possible to omit this argument by merging options into $record
* @return stdClass record from module-defined table with additional field
* cmid (corresponding id in course_modules table)
*/
public function create_instance($record = null, array $options = null) {
global $CFG, $DB;
require_once($CFG->dirroot.'/course/modlib.php');

$this->instancecount++;

// Merge options into record and add default values.
$record = $this->prepare_moduleinfo_record($record, $options);

// Retrieve the course record.
if (!empty($record->course->id)) {
$course = $record->course;
$record->course = $record->course->id;
} else {
$course = get_course($record->course);
}

// Fill the name and intro with default values (if missing).
if (empty($record->name)) {
$record->name = get_string('pluginname', $this->get_modulename()).' '.$this->instancecount;
}
if (empty($record->introeditor) && empty($record->intro)) {
$record->intro = 'Test '.$this->get_modulename().' ' . $this->instancecount;
}
if (empty($record->introeditor) && empty($record->introformat)) {
$record->introformat = FORMAT_MOODLE;
}

// Before Moodle 2.6 it was possible to create a module with completion tracking when
// it is not setup for course and/or site-wide. Display debugging message so it is
// easier to trace an error in unittests.
if ($record->completion && empty($CFG->enablecompletion)) {
debugging('Did you forget to set $CFG->enablecompletion before generating module with completion tracking?', DEBUG_DEVELOPER);
}
if ($record->completion && empty($course->enablecompletion)) {
debugging('Did you forget to enable completion tracking for the course before generating module with completion tracking?', DEBUG_DEVELOPER);
}

// Add the module to the course.
$moduleinfo = add_moduleinfo($record, $course, $mform = null);

// Prepare object to return with additional field cmid.
$instance = $DB->get_record($this->get_modulename(), array('id' => $moduleinfo->instance), '*', MUST_EXIST);
$instance->cmid = $moduleinfo->coursemodule;
return $instance;
}
}

/**
Expand Down
24 changes: 18 additions & 6 deletions lib/tests/completionlib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,11 @@ protected function setup_data() {

$this->resetAfterTest();

// Enable completion before creating modules, otherwise the completion data is not written in DB.
$CFG->enablecompletion = true;

// Create a course with activities.
$this->course = $this->getDataGenerator()->create_course();
$this->course = $this->getDataGenerator()->create_course(array('enablecompletion' => true));
$this->user = $this->getDataGenerator()->create_user();
$studentrole = $DB->get_record('role', array('shortname' => 'student'));
$this->assertNotEmpty($studentrole);
Expand Down Expand Up @@ -718,10 +721,14 @@ public function test_internal_get_grade_state() {
}

public function test_get_activities() {
global $CFG;
$this->resetAfterTest();

// Enable completion before creating modules, otherwise the completion data is not written in DB.
$CFG->enablecompletion = true;

// Create a course with mixed auto completion data.
$course = $this->getDataGenerator()->create_course();
$course = $this->getDataGenerator()->create_course(array('enablecompletion' => true));
$completionauto = array('completion' => COMPLETION_TRACKING_AUTOMATIC);
$completionmanual = array('completion' => COMPLETION_TRACKING_MANUAL);
$completionnone = array('completion' => COMPLETION_TRACKING_NONE);
Expand All @@ -734,7 +741,7 @@ public function test_get_activities() {
$data2 = $this->getDataGenerator()->create_module('data', array('course' => $course->id), $completionnone);

// Create data in another course to make sure it's not considered.
$course2 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course(array('enablecompletion' => true));
$c2forum = $this->getDataGenerator()->create_module('forum', array('course' => $course2->id), $completionauto);
$c2page = $this->getDataGenerator()->create_module('page', array('course' => $course2->id), $completionmanual);
$c2data = $this->getDataGenerator()->create_module('data', array('course' => $course2->id), $completionnone);
Expand All @@ -755,11 +762,15 @@ public function test_get_activities() {
}

public function test_has_activities() {
global $CFG;
$this->resetAfterTest();

// Enable completion before creating modules, otherwise the completion data is not written in DB.
$CFG->enablecompletion = true;

// Create a course with mixed auto completion data.
$course = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course();
$course = $this->getDataGenerator()->create_course(array('enablecompletion' => true));
$course2 = $this->getDataGenerator()->create_course(array('enablecompletion' => true));
$completionauto = array('completion' => COMPLETION_TRACKING_AUTOMATIC);
$completionnone = array('completion' => COMPLETION_TRACKING_NONE);
$c1forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id), $completionauto);
Expand All @@ -776,9 +787,10 @@ public function test_has_activities() {
* Test course module completion update event.
*/
public function test_course_module_completion_updated_event() {
global $USER;
global $USER, $CFG;

$this->setup_data();

$this->setAdminUser();

$completionauto = array('completion' => COMPLETION_TRACKING_AUTOMATIC);
Expand Down
7 changes: 7 additions & 0 deletions lib/tests/modinfolib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public function test_section_info_properties() {
foreach ($conditionsfield as $conditionfield) {
$ci->add_user_field_condition($conditionfield->fieldname, $conditionfield->operator, $conditionfield->value);
}
// Direct calls to condition_info_section methods do not reset the course cache. Do it manually.
rebuild_course_cache($course->id, true);

// Create and enrol a student.
$studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
Expand Down Expand Up @@ -164,6 +166,8 @@ public function test_cm_info_properties() {
foreach ($conditionsfield as $conditionfield) {
$ci->add_user_field_condition($conditionfield->fieldname, $conditionfield->operator, $conditionfield->value);
}
// Direct access to condition_info functions does not reset course cache, do it manually.
rebuild_course_cache($course->id, true);

// Retrieve all related records from DB.
$assigndb = $DB->get_record('assign', array('id' => $assign->id));
Expand Down Expand Up @@ -542,6 +546,9 @@ public function test_is_user_access_restricted_by_conditional_access() {

$this->resetAfterTest();

// Enable conditional availability before creating modules, otherwise the condition data is not written in DB.
$CFG->enableavailability = true;

// Create a course.
$course = $this->getDataGenerator()->create_course();
// 1. Create an activity that is currently unavailable and hidden entirely (for students).
Expand Down
26 changes: 1 addition & 25 deletions mod/assign/tests/generator/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,10 @@
*/
class mod_assign_generator extends testing_module_generator {

/**
* Create new assign module instance
* @param array|stdClass $record
* @param array $options (mostly course_module properties)
* @return stdClass activity record with extra cmid field
*/
public function create_instance($record = null, array $options = null) {
global $CFG;
require_once("$CFG->dirroot/mod/assign/lib.php");

$this->instancecount++;
$i = $this->instancecount;

$record = (object)(array)$record;
$options = (array)$options;

if (empty($record->course)) {
throw new coding_exception('module generator requires $record->course');
}

$defaultsettings = array(
'name' => get_string('pluginname', 'assign').' '.$i,
'intro' => 'Test assign ' . $i,
'introformat' => FORMAT_MOODLE,
'alwaysshowdescription' => 1,
'submissiondrafts' => 1,
'requiresubmissionstatement' => 0,
Expand All @@ -63,7 +43,6 @@ public function create_instance($record = null, array $options = null) {
'requireallteammemberssubmit' => 0,
'teamsubmissiongroupingid' => 0,
'blindmarking' => 0,
'cmidnumber' => '',
'attemptreopenmethod' => 'none',
'maxattempts' => -1,
'markingworkflow' => 0,
Expand All @@ -76,9 +55,6 @@ public function create_instance($record = null, array $options = null) {
}
}

$record->coursemodule = $this->precreate_course_module($record->course, $options);
$id = assign_add_instance($record, null);
rebuild_course_cache($record->course, true);
return $this->post_add_instance($id, $record->coursemodule);
return parent::create_instance($record, (array)$options);
}
}
34 changes: 1 addition & 33 deletions mod/assignment/tests/generator/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,9 @@
*/
class mod_assignment_generator extends testing_module_generator {

/**
* Create new assignment module instance
* @param array|stdClass $record
* @param array $options (mostly course_module properties)
* @return stdClass activity record with extra cmid field
*/
public function create_instance($record = null, array $options = null) {
global $CFG;
require_once("$CFG->dirroot/mod/assignment/locallib.php");

$this->instancecount++;
$i = $this->instancecount;

$record = (object)(array)$record;
$options = (array)$options;

if (empty($record->course)) {
throw new coding_exception('module generator requires $record->course');
}
if (!isset($record->name)) {
$record->name = get_string('pluginname', 'assignment').' '.$i;
}
if (!isset($record->intro)) {
$record->intro = 'Test assignment '.$i;
}
if (!isset($record->introformat)) {
$record->introformat = FORMAT_MOODLE;
}
if (!isset($record->assignmenttype)) {
$record->assignmenttype = 'upload';
}
Expand All @@ -73,14 +48,7 @@ public function create_instance($record = null, array $options = null) {
if (!isset($record->timedue)) {
$record->timedue = 0;
}
if (isset($options['idnumber'])) {
$record->cmidnumber = $options['idnumber'];
} else {
$record->cmidnumber = '';
}

$record->coursemodule = $this->precreate_course_module($record->course, $options);
$id = assignment_add_instance($record, null);
return $this->post_add_instance($id, $record->coursemodule);
return parent::create_instance($record, (array)$options);
}
}
Loading

0 comments on commit 7fbe33f

Please sign in to comment.