Skip to content

Commit

Permalink
new phpunit test_rule_on_freeplace_on_intervals() (#467)
Browse files Browse the repository at this point in the history
  • Loading branch information
semteacher committed Dec 14, 2024
1 parent 1f1acd8 commit b3c1d8a
Showing 1 changed file with 199 additions and 3 deletions.
202 changes: 199 additions & 3 deletions tests/booking_rules/rules_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -1070,8 +1070,6 @@ public function test_rule_on_freeplaceagain(array $bdata): void {
booking_rules::$rules = [];
}



/**
* Test rule on option being completed for user.
*
Expand Down Expand Up @@ -1226,7 +1224,7 @@ public function test_rule_on_option_completion(array $bdata): void {
* @dataProvider booking_common_settings_provider
*/
public function test_booking_rules_customform_delete_data(array $bdata): void {

singleton_service::destroy_instance();

// Setup test data.
Expand Down Expand Up @@ -1401,6 +1399,204 @@ public function test_booking_rules_customform_delete_data(array $bdata): void {
booking_rules::$rules = [];
}

/**
* Test rules for "option free to bookagain" and "notification in intervals" events.
*
* @covers \condition\alreadybooked::is_available
* @covers \condition\onwaitinglist::is_available
* @covers \mod_booking\event\bookingoption_freetobookagain
* @covers \mod_booking\event\bookingoptionwaitinglist_booked
* @covers \mod_booking\booking_rules\rules\rule_react_on_event
* @covers \mod_booking\booking_rules\actions\send_mail
* @covers \mod_booking\booking_rules\conditions\select_teacher_in_bo
* @covers \mod_booking\booking_rules\conditions\select_student_in_bo
*
* @param array $bdata
* @throws \coding_exception
* @throws \dml_exception
*
* @dataProvider booking_common_settings_provider
*/
public function test_rule_on_freeplace_on_intervals(array $bdata): void {
global $DB, $CFG;

$bdata['cancancelbook'] = 1;

// Create course.
$course1 = $this->getDataGenerator()->create_course(['enablecompletion' => 1]);

// Create users.
$student1 = $this->getDataGenerator()->create_user();
$student2 = $this->getDataGenerator()->create_user();
$student3 = $this->getDataGenerator()->create_user();
$teacher1 = $this->getDataGenerator()->create_user();

$bdata['course'] = $course1->id;
$bdata['bookingmanager'] = $teacher1->username;

$booking1 = $this->getDataGenerator()->create_module('booking', $bdata);

$this->setAdminUser();

$this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
$this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
$this->getDataGenerator()->enrol_user($student3->id, $course1->id, 'student');
$this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');

/** @var mod_booking_generator $plugingenerator */
$plugingenerator = self::getDataGenerator()->get_plugin_generator('mod_booking');

// Create booking rule 1 - "bookingoption_freetobookagain" with delays.
$boevent1 = '"boevent":"\\\\mod_booking\\\\event\\\\bookingoption_freetobookagain"';
$ruledata1 = [
'name' => 'intervlqs',
'conditionname' => 'select_student_in_bo',
'contextid' => 1,
'conditiondata' => '{"borole":"smallerthan1"}',
'actionname' => 'send_mail_interval',
'actiondata' => '{"interval":1,"subject":"freeplacedelaysubj","template":"freeplacedelaymsg","templateformat":"1"}',
'rulename' => 'rule_react_on_event',
'ruledata' => '{' . $boevent1 . ',"aftercompletion":0,"cancelrules":[],"condition":"2"}',
];
$rule1 = $plugingenerator->create_rule($ruledata1);

// Create booking rule 2 - "bookingoption_freetobookagain".
$boevent2 = '"boevent":"\\\\mod_booking\\\\event\\\\bookingoption_freetobookagain"';
$ruledata2 = [
'name' => 'override',
'conditionname' => 'select_student_in_bo',
'contextid' => 1,
'conditiondata' => '{"borole":"1"}',
'actionname' => 'send_mail',
'actiondata' => '{"subject":"freeplacesubj","template":"freeplacemsg","templateformat":"1"}',
'rulename' => 'rule_react_on_event',
'ruledata' => '{' . $boevent2 . ',"aftercompletion":"","condition":"0"}',
];
$rule2 = $plugingenerator->create_rule($ruledata2);

// Create booking option 1.
$record = new stdClass();
$record->bookingid = $booking1->id;
$record->text = 'football';
$record->chooseorcreatecourse = 1; // Connected existing course.
$record->courseid = $course1->id;
$record->maxanswers = 1;
$record->maxoverbooking = 3; // Enable waitinglist.
$record->waitforconfirmation = 1; // Do not force waitinglist.
$record->description = 'Will start in 2050';
$record->optiondateid_1 = "0";
$record->daystonotify_1 = "0";
$record->coursestarttime_1 = strtotime('20 June 2050 15:00');
$record->courseendtime_1 = strtotime('20 July 2050 14:00');
$record->teachersforoption = $teacher1->username;
$option1 = $plugingenerator->create_option($record);
singleton_service::destroy_booking_option_singleton($option1->id);

$settings = singleton_service::get_instance_of_booking_option_settings($option1->id);
$boinfo = new bo_info($settings);
$option = singleton_service::get_instance_of_booking_option($settings->cmid, $settings->id);

// Create a booking option answer - book student2.
$this->setUser($student2);
singleton_service::destroy_user($student2->id);
$result = booking_bookit::bookit('option', $settings->id, $student2->id);
list($id, $isavailable, $description) = $boinfo->is_available($settings->id, $student2->id, true);
$this->assertEquals(MOD_BOOKING_BO_COND_ONWAITINGLIST, $id);

// Confirm booking as admin.
$this->setAdminUser();
$option->user_submit_response($student2, 0, 0, 0, MOD_BOOKING_VERIFIED);
list($id, $isavailable, $description) = $boinfo->is_available($settings->id, $student2->id, true);
$this->assertEquals(MOD_BOOKING_BO_COND_ALREADYBOOKED, $id);

// Book the student1 via waitinglist.
$this->setUser($student1);
singleton_service::destroy_user($student1->id);
$result = booking_bookit::bookit('option', $settings->id, $student1->id);
list($id, $isavailable, $description) = $boinfo->is_available($settings->id, $student1->id, true);
$this->assertEquals(MOD_BOOKING_BO_COND_ONWAITINGLIST, $id);

// Book the student3 via waitinglist.
$this->setUser($student3);
singleton_service::destroy_user($student3->id);
$result = booking_bookit::bookit('option', $settings->id, $student3->id);
list($id, $isavailable, $description) = $boinfo->is_available($settings->id, $student3->id, true);
$this->assertEquals(MOD_BOOKING_BO_COND_ONWAITINGLIST, $id);

// Now take student 2 from the list, for a place to free up.
$this->setUser($student2);
$option->user_delete_response($student2->id);
singleton_service::destroy_booking_option_singleton($option1->id);
singleton_service::destroy_booking_answers($option1->id);

// Execute tasks, get messages and validate it.
$this->setAdminUser();

// Get all scheduled task messages.
$tasks = \core\task\manager::get_adhoc_tasks('\mod_booking\task\send_mail_by_rule_adhoc');

$this->assertCount(4, $tasks);
// Validate task messages. Might be free order.
foreach ($tasks as $key => $task) {
$customdata = $task->get_custom_data();
if (strpos($customdata->customsubject, "freeplacesubj") !== false) {
// Validate 2 task messages on the bookingoption_freetobookagain event.
$this->assertEquals("freeplacesubj", $customdata->customsubject);
$this->assertEquals("freeplacemsg", $customdata->custommessage);
$this->assertContains($customdata->userid, [$student1->id, $student3->id]);
$this->assertStringContainsString($boevent2, $customdata->rulejson);
$this->assertStringContainsString($ruledata2['conditiondata'], $customdata->rulejson);
$this->assertStringContainsString($ruledata2['actiondata'], $customdata->rulejson);
$this->assertContains($task->get_userid(), [$student1->id, $student3->id]);
$rulejson = json_decode($customdata->rulejson);
$this->assertEmpty($rulejson->datafromevent->relateduserid);
$this->assertEquals($student2->id, $rulejson->datafromevent->userid);
} else {
// Validate 2 task messages on the bookingoption_freetobookagain with delay event.
$this->assertEquals("freeplacedelaysubj", $customdata->customsubject);
$this->assertEquals("freeplacedelaymsg", $customdata->custommessage);
$this->assertContains($customdata->userid, [$student1->id, $student3->id]);
$this->assertStringContainsString($boevent1, $customdata->rulejson);
$this->assertStringContainsString($ruledata1['conditiondata'], $customdata->rulejson);
$this->assertStringContainsString($ruledata1['actiondata'], $customdata->rulejson);
$this->assertContains($task->get_userid(), [$student1->id, $student3->id]);
$rulejson = json_decode($customdata->rulejson);
$this->assertEmpty($rulejson->datafromevent->relateduserid);
$this->assertEquals($student2->id, $rulejson->datafromevent->userid);
}
}

// Run adhock tasks.
$sink = $this->redirectMessages();
$tasks = \core\task\manager::get_adhoc_tasks('\mod_booking\task\send_mail_by_rule_adhoc');
ob_start();
$this->runAdhocTasks();
$messages = $sink->get_messages();
$res = ob_get_clean();
$sink->close();

$this->assertCount(3, $messages);
// Validate ACTUAL task messages. Might be free order.
foreach ($messages as $key => $message) {
if (strpos($message->subject, "freeplacesubj") !== false) {
// Validate 2 task messages on the bookingoption_freetobookagain event.
$this->assertEquals("freeplacesubj", $message->subject);
$this->assertEquals("freeplacemsg", $message->fullmessage);
$this->assertContains($message->useridto, [$student1->id, $student3->id]);
} else {
// Validate 1 task messages on the bookingoption_freetobookagain with delay event.
$this->assertEquals("freeplacedelaysubj", $message->subject);
$this->assertEquals("freeplacedelaymsg", $message->fullmessage);
$this->assertEquals($student1->id, $message->useridto);
}
}
// Mandatory to solve potential cache issues.
singleton_service::destroy_instance();
// Mandatory to deal with static variable in the booking_rules.
rules_info::$rulestoexecute = [];
booking_rules::$rules = [];
}

/**
* Data provider for condition_bookingpolicy_test
*
Expand Down

0 comments on commit b3c1d8a

Please sign in to comment.