Merge branch 'MDL-73654-master' of https://github.com/HuongNV13/moodle

This commit is contained in:
Jun Pataleta 2022-05-31 13:34:35 +08:00
commit f0b6e8ecd8
3 changed files with 142 additions and 28 deletions

View File

@ -8,25 +8,27 @@ Feature: The timeline block allows users to search for upcoming activities
| username | firstname | lastname | email | idnumber |
| student1 | Student | 1 | student1@example.com | S1 |
And the following "courses" exist:
| fullname | shortname | category | startdate | enddate |
| Course 1 | C1 | 0 | ##1 month ago## | ##15 days ago## |
| Course 2 | C2 | 0 | ##yesterday## | ##tomorrow## |
| Course 3 | C3 | 0 | ##first day of next month## | ##last day of next month## |
| Course 4 | C4 | 0 | ##1 month ago## | ##tomorrow## |
| Course 5 | C5 | 0 | ##first day of last month## | ##last day of next month## |
| fullname | shortname | category | startdate | enddate |
| Course 1 | C1 | 0 | ##1 month ago## | ##15 days ago## |
| Course 2 | C2 | 0 | ##yesterday## | ##tomorrow## |
| Course 3 | C3 | 0 | ##first day of next month## | ##last day of next month## |
| Course 4 | C4 | 0 | ##1 month ago## | ##tomorrow## |
| Course 5 | C5 | 0 | ##first day of last month## | ##last day of next month## |
| Course with advanced name | C6 | 0 | ##first day of last month## | ##last day of next month## |
And the following "activities" exist:
| activity | course | idnumber | name | intro | timeopen | timeclose |
| choice | C2 | choice1 | Test choice 1 | Test choice description | ##yesterday## | ##tomorrow## |
| choice | C1 | choice2 | Test choice 2 | Test choice description | ##first day of +5 months## | ##last day of +5 months## |
| choice | C3 | choice3 | Test choice 3 | Test choice description | ##first day of +5 months## | ##last day of +10 months## |
| choice | C2 | choice4 | Test choice 4 | Test choice description | ##first day of +5 months## | ##last day of +15 months## |
| choice | C1 | choice5 | Test choice 5 | Test choice description | ##first day of +5 months## | ##last day of +20 months## |
| choice | C3 | choice6 | Test choice 6 | Test choice description | ##first day of +5 months## | ##last day of +25 months## |
| choice | C4 | choice7 | Test choice 7 | Test choice description | ##first day of +5 months## | ##last day of +5 months## |
| choice | C5 | choice8 | Test choice 8 | Test choice description | ##first day of +5 months## | ##last day of +10 months## |
| feedback | C2 | feedback1 | Test feedback 1 | Test feedback description | ##yesterday## | ##tomorrow## |
| feedback | C1 | feedback2 | Test feedback 2 | Test feedback description | ##first day of +5 months## | ##last day of +5 months## |
| feedback | C3 | feedback3 | Test feedback 3 | Test feedback description | ##first day of +5 months## | ##last day of +10 months## |
| activity | course | idnumber | name | intro | timeopen | timeclose | duedate |
| choice | C2 | choice1 | Test choice 1 | Test choice description | ##yesterday## | ##tomorrow## | |
| choice | C1 | choice2 | Test choice 2 | Test choice description | ##first day of +5 months## | ##last day of +5 months## | |
| choice | C3 | choice3 | Test choice 3 | Test choice description | ##first day of +5 months## | ##last day of +10 months## | |
| choice | C2 | choice4 | Test choice 4 | Test choice description | ##first day of +5 months## | ##last day of +15 months## | |
| choice | C1 | choice5 | Test choice 5 | Test choice description | ##first day of +5 months## | ##last day of +20 months## | |
| choice | C3 | choice6 | Test choice 6 | Test choice description | ##first day of +5 months## | ##last day of +25 months## | |
| choice | C4 | choice7 | Test choice 7 | Test choice description | ##first day of +5 months## | ##last day of +5 months## | |
| choice | C5 | choice8 | Test choice 8 | Test choice description | ##first day of +5 months## | ##last day of +10 months## | |
| feedback | C2 | feedback1 | Test feedback 1 | Test feedback description | ##yesterday## | ##tomorrow## | |
| feedback | C1 | feedback2 | Test feedback 2 | Test feedback description | ##first day of +5 months## | ##last day of +5 months## | |
| feedback | C3 | feedback3 | Test feedback 3 | Test feedback description | ##first day of +5 months## | ##last day of +10 months## | |
| assign | C6 | assign1 | Assign with advanced name | Test assign description | ##yesterday## | | ##tomorrow## |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
@ -34,6 +36,7 @@ Feature: The timeline block allows users to search for upcoming activities
| student1 | C3 | student |
| student1 | C4 | student |
| student1 | C5 | student |
| student1 | C6 | student |
Scenario: The search should return no events if I enter the wrong value
Given I log in as "student1"
@ -56,6 +59,13 @@ Feature: The timeline block allows users to search for upcoming activities
And I should not see "Test feedback 1" in the "Timeline" "block"
And I should not see "Test feedback 3" in the "Timeline" "block"
Scenario: Search for Course name - Advanced
Given I log in as "student1"
And I click on "Filter timeline by date" "button" in the "Timeline" "block"
And I click on "All" "link" in the "Timeline" "block"
When I set the field "Search" in the "Timeline" "block" to "Course advanced"
Then I should see "Assign with advanced name" in the "Timeline" "block"
Scenario: Search for Activity name
Given I log in as "student1"
And I click on "Filter timeline by date" "button" in the "Timeline" "block"
@ -72,6 +82,13 @@ Feature: The timeline block allows users to search for upcoming activities
And I should not see "Test feedback 2" in the "Timeline" "block"
And I should not see "Test feedback 3" in the "Timeline" "block"
Scenario: Search for Activity name - Advanced
Given I log in as "student1"
And I click on "Filter timeline by date" "button" in the "Timeline" "block"
And I click on "All" "link" in the "Timeline" "block"
When I set the field "Search" in the "Timeline" "block" to "Assign advanced"
Then I should see "Assign with advanced name" in the "Timeline" "block"
Scenario: Search for Activity type
Given I log in as "student1"
And I click on "Filter timeline by date" "button" in the "Timeline" "block"

View File

@ -415,13 +415,18 @@ class event_vault implements event_vault_interface {
return null;
}
// Course searching.
$whereconditions[] = $DB->sql_like('c.fullname', ':cfullname', false);
$params['cfullname'] = '%' . $DB->sql_like_escape($searchvalue) . '%';
$parts = preg_split('/\s+/', $searchvalue);
$wherecoursenameconditions = [];
$whereactivitynameconditions = [];
foreach ($parts as $index => $part) {
// Course name searching.
$wherecoursenameconditions[] = $DB->sql_like('c.fullname', ':cfullname' . $index, false);
$params['cfullname'. $index] = '%' . $DB->sql_like_escape($part) . '%';
// Activity name searching.
$whereconditions[] = $DB->sql_like('e.name', ':eventname', false);
$params['eventname'] = '%' . $DB->sql_like_escape($searchvalue) . '%';
// Activity name searching.
$whereactivitynameconditions[] = $DB->sql_like('e.name', ':eventname' . $index, false);
$params['eventname'. $index] = '%' . $DB->sql_like_escape($part) . '%';
}
// Activity type searching.
$whereconditions[] = $DB->sql_like('e.modulename', ':modulename', false);
@ -440,7 +445,11 @@ class event_vault implements event_vault_interface {
$params += $inparams;
}
$whereclause = '(' . implode(' OR ', $whereconditions) . ')';
$whereclause = '(';
$whereclause .= implode(' OR ', $whereconditions);
$whereclause .= ' OR (' . implode(' AND ', $wherecoursenameconditions) . ')';
$whereclause .= ' OR (' . implode(' AND ', $whereactivitynameconditions) . ')';
$whereclause .= ')';
return ['where' => $whereclause, 'params' => $params];
}

View File

@ -28,6 +28,7 @@ require_once(__DIR__ . '/helpers.php');
* @package core_calendar
* @copyright 2017 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @coversDefaultClass \core_calendar\local\api
*/
class local_api_test extends \advanced_testcase {
@ -286,6 +287,7 @@ class local_api_test extends \advanced_testcase {
/**
* Test get_calendar_action_events_by_timesort with search feature.
* @covers ::get_action_events_by_timesort
*/
public function test_get_calendar_action_events_by_timesort_with_search() {
// Generate data.
@ -317,6 +319,7 @@ class local_api_test extends \advanced_testcase {
$event6 = create_event(array_merge($params, ['name' => 'Event 6', 'timesort' => 6]));
$event7 = create_event(array_merge($params, ['name' => 'Event 7', 'timesort' => 7]));
$event8 = create_event(array_merge($params, ['name' => 'Event 8', 'timesort' => 8]));
$event9 = create_event(array_merge($params, ['name' => 'Assign with advanced name', 'timesort' => 9]));
$this->setUser($user);
@ -325,13 +328,25 @@ class local_api_test extends \advanced_testcase {
$this->assertEmpty($result);
// Search for event name called 'Event 1'.
$result = \core_calendar\local\api::get_action_events_by_timesort(0, 8, null, 20, false, null, 'Event 1');
$result = \core_calendar\local\api::get_action_events_by_timesort(0, 10, null, 20, false, null, 'Event 1');
$this->assertCount(1, $result);
$this->assertEquals('Event 1', $result[0]->get_name());
// Search for event name called 'Assign with advanced name'.
$result = \core_calendar\local\api::get_action_events_by_timesort(
0, 10, null, 20, false, null, 'Assign with advanced name');
$this->assertCount(1, $result);
$this->assertEquals('Assign with advanced name', $result[0]->get_name());
// Search for event name contains 'Assign advanced'.
$result = \core_calendar\local\api::get_action_events_by_timesort(
0, 10, null, 20, false, null, 'Assign advanced');
$this->assertCount(1, $result);
$this->assertEquals('Assign with advanced name', $result[0]->get_name());
// Search for activity type called 'assign'.
$result = \core_calendar\local\api::get_action_events_by_timesort(0, 8, null, 20, false, null, 'assign');
$this->assertCount(8, $result);
$result = \core_calendar\local\api::get_action_events_by_timesort(0, 10, null, 20, false, null, 'assign');
$this->assertCount(9, $result);
$this->assertEquals('Event 1', $result[0]->get_name());
$this->assertEquals('Event 2', $result[1]->get_name());
$this->assertEquals('Event 3', $result[2]->get_name());
@ -340,6 +355,7 @@ class local_api_test extends \advanced_testcase {
$this->assertEquals('Event 6', $result[5]->get_name());
$this->assertEquals('Event 7', $result[6]->get_name());
$this->assertEquals('Event 8', $result[7]->get_name());
$this->assertEquals('Assign with advanced name', $result[8]->get_name());
}
/**
@ -696,6 +712,78 @@ class local_api_test extends \advanced_testcase {
$this->assertEquals('Event 6', $result[$course3->id][0]->get_name());
}
/**
* Test get_action_events_by_courses with search feature.
* @covers ::get_action_events_by_courses
*/
public function test_get_action_events_by_courses_with_search() {
// Generate data.
$user = $this->getDataGenerator()->create_user();
$course1 = $this->getDataGenerator()->create_course(['fullname' => 'Course with advanced name']);
$course2 = $this->getDataGenerator()->create_course(['fullname' => 'Another name']);
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
$moduleinstance1 = $generator->create_instance(['course' => $course1->id]);
$moduleinstance2 = $generator->create_instance(['course' => $course2->id]);
$this->getDataGenerator()->enrol_user($user->id, $course1->id);
$this->getDataGenerator()->enrol_user($user->id, $course2->id);
$this->resetAfterTest(true);
$this->setUser($user);
$params = [
'type' => CALENDAR_EVENT_TYPE_ACTION,
'modulename' => 'assign',
'instance' => $moduleinstance1->id,
'userid' => $user->id,
'courseid' => $course1->id,
'eventtype' => 'user',
'repeats' => 0,
'timestart' => 1,
];
$event1 = create_event(array_merge($params, ['name' => 'Event 1', 'timesort' => 1]));
$event2 = create_event(array_merge($params, ['name' => 'Event 2', 'timesort' => 2]));
$params['courseid'] = $course2->id;
$params['instance'] = $moduleinstance2->id;
$event3 = create_event(array_merge($params, ['name' => 'Event 3', 'timesort' => 3]));
$event4 = create_event(array_merge($params, ['name' => 'Event 4', 'timesort' => 4]));
$event5 = create_event(array_merge($params, ['name' => 'Event 5', 'timesort' => 5]));
// No result found for fake search.
$result = \core_calendar\local\api::get_action_events_by_courses(
[$course1, $course2], 1, null, '6', 'Fake search');
$this->assertEmpty($result[$course1->id]);
$this->assertEmpty($result[$course2->id]);
// Search for course name called 'Course with advanced name'.
$result = \core_calendar\local\api::get_action_events_by_courses(
[$course1, $course2], 1, null, '6', 'Course with advanced name');
$this->assertNotEmpty($result[$course1->id]);
$this->assertEmpty($result[$course2->id]);
$this->assertEquals('Event 1', $result[$course1->id][0]->get_name());
$this->assertEquals('Event 2', $result[$course1->id][1]->get_name());
// Search for course name contains 'Course advanced'.
$result = \core_calendar\local\api::get_action_events_by_courses(
[$course1, $course2], 1, null, '6', 'Course advanced');
$this->assertNotEmpty($result[$course1->id]);
$this->assertEmpty($result[$course2->id]);
$this->assertEquals('Event 1', $result[$course1->id][0]->get_name());
$this->assertEquals('Event 2', $result[$course1->id][1]->get_name());
// Search for course name contains 'name'.
$result = \core_calendar\local\api::get_action_events_by_courses(
[$course1, $course2], 1, null, '6', 'name');
$this->assertNotEmpty($result[$course1->id]);
$this->assertNotEmpty($result[$course2->id]);
$this->assertEquals('Event 1', $result[$course1->id][0]->get_name());
$this->assertEquals('Event 2', $result[$course1->id][1]->get_name());
$this->assertEquals('Event 3', $result[$course2->id][0]->get_name());
$this->assertEquals('Event 4', $result[$course2->id][1]->get_name());
$this->assertEquals('Event 5', $result[$course2->id][2]->get_name());
}
/**
* Test that the get_legacy_events() function only returns activity events that are enabled.
*/