| Línea 45... |
Línea 45... |
| 45 |
* Tests set up
|
45 |
* Tests set up
|
| 46 |
*/
|
46 |
*/
|
| 47 |
protected function setUp(): void {
|
47 |
protected function setUp(): void {
|
| 48 |
global $CFG;
|
48 |
global $CFG;
|
| 49 |
require_once($CFG->dirroot . '/course/externallib.php');
|
49 |
require_once($CFG->dirroot . '/course/externallib.php');
|
| - |
|
50 |
parent::setUp();
|
| 50 |
}
|
51 |
}
|
| Línea 51... |
Línea 52... |
| 51 |
|
52 |
|
| 52 |
/**
|
53 |
/**
|
| 53 |
* Test create_categories
|
54 |
* Test create_categories
|
| Línea 889... |
Línea 890... |
| 889 |
'shortname' => $datefield->get('shortname'),
|
890 |
'shortname' => $datefield->get('shortname'),
|
| 890 |
'type' => $datefield->get('type'),
|
891 |
'type' => $datefield->get('type'),
|
| 891 |
'value' => userdate(1580389200),
|
892 |
'value' => userdate(1580389200),
|
| 892 |
'valueraw' => 1580389200,
|
893 |
'valueraw' => 1580389200,
|
| 893 |
], reset($course['customfields']));
|
894 |
], reset($course['customfields']));
|
| - |
|
895 |
|
| - |
|
896 |
// Set the multilang filter to apply to strings + reset filer caches.
|
| - |
|
897 |
filter_set_global_state('multilang', TEXTFILTER_ON);
|
| - |
|
898 |
filter_set_applies_to_strings('multilang', true);
|
| - |
|
899 |
\filter_manager::reset_caches();
|
| - |
|
900 |
|
| - |
|
901 |
// Let's create a custom field (number), and test the placeholders/multilang display.
|
| - |
|
902 |
/** @var core_customfield_generator $cfgenerator */
|
| - |
|
903 |
$cfgenerator = $this->getDataGenerator()->get_plugin_generator('core_customfield');
|
| - |
|
904 |
$numberfieldata = [
|
| - |
|
905 |
'categoryid' => $fieldcategory->get('id'),
|
| - |
|
906 |
'name' => 'Price',
|
| - |
|
907 |
'shortname' => 'price',
|
| - |
|
908 |
'type' => 'number',
|
| - |
|
909 |
'configdata' => [
|
| - |
|
910 |
'display' => '{value}',
|
| - |
|
911 |
'decimalplaces' => 2,
|
| - |
|
912 |
],
|
| - |
|
913 |
];
|
| - |
|
914 |
|
| - |
|
915 |
// Create a number custom field with default display template.
|
| - |
|
916 |
$numberfield = $cfgenerator->create_field($numberfieldata);
|
| - |
|
917 |
$cfgenerator->add_instance_data($numberfield, $newcourse->id, 15);
|
| - |
|
918 |
|
| - |
|
919 |
// Create a number custom field with multilang display template.
|
| - |
|
920 |
$numberfieldata['name'] = 'Price (multilang)';
|
| - |
|
921 |
$numberfieldata['shortname'] = 'pricemultilang';
|
| - |
|
922 |
$numberfieldata['configdata']['display'] = '<span lang="en" class="multilang">$ {value}</span>'
|
| - |
|
923 |
. '<span lang="es" class="multilang">€ {value}</span>';
|
| - |
|
924 |
$numberfield1 = $cfgenerator->create_field($numberfieldata);
|
| - |
|
925 |
$cfgenerator->add_instance_data($numberfield1, $newcourse->id, 20);
|
| - |
|
926 |
|
| - |
|
927 |
$courses = external_api::clean_returnvalue(
|
| - |
|
928 |
core_course_external::get_courses_returns(),
|
| - |
|
929 |
core_course_external::get_courses(['ids' => [$newcourse->id]])
|
| - |
|
930 |
);
|
| - |
|
931 |
|
| - |
|
932 |
$course = reset($courses);
|
| - |
|
933 |
$this->assertCount(3, $course['customfields']);
|
| - |
|
934 |
|
| - |
|
935 |
// Assert the received number custom fields display placeholders correctly with multilang filter when applied.
|
| - |
|
936 |
$this->assertEquals('15.00', $course['customfields'][1]['value']);
|
| - |
|
937 |
$this->assertEquals('$ 20.00', $course['customfields'][2]['value']);
|
| 894 |
}
|
938 |
}
|
| Línea 895... |
Línea 939... |
| 895 |
|
939 |
|
| 896 |
/**
|
940 |
/**
|
| 897 |
* Test get_courses without capability
|
941 |
* Test get_courses without capability
|
| Línea 1169... |
Línea 1213... |
| 1169 |
$this->setAdminUser();
|
1213 |
$this->setAdminUser();
|
| 1170 |
$sections = core_course_external::get_course_contents($course->id, array());
|
1214 |
$sections = core_course_external::get_course_contents($course->id, array());
|
| 1171 |
// We need to execute the return values cleaning process to simulate the web service server.
|
1215 |
// We need to execute the return values cleaning process to simulate the web service server.
|
| 1172 |
$sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections);
|
1216 |
$sections = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $sections);
|
| Línea -... |
Línea 1217... |
| - |
|
1217 |
|
| - |
|
1218 |
$this->assertEmpty($sections[0]['component']);
|
| - |
|
1219 |
$this->assertEmpty($sections[0]['itemid']);
|
| 1173 |
|
1220 |
|
| 1174 |
$modinfo = get_fast_modinfo($course);
|
1221 |
$modinfo = get_fast_modinfo($course);
|
| 1175 |
$testexecuted = 0;
|
1222 |
$testexecuted = 0;
|
| 1176 |
foreach ($sections[0]['modules'] as $module) {
|
1223 |
foreach ($sections[0]['modules'] as $module) {
|
| 1177 |
if ($module['id'] == $forumcm->id and $module['modname'] == 'forum') {
|
1224 |
if ($module['id'] == $forumcm->id and $module['modname'] == 'forum') {
|
| Línea 1847... |
Línea 1894... |
| 1847 |
$this->assertDebuggingCalled();
|
1894 |
$this->assertDebuggingCalled();
|
| 1848 |
$result = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $result);
|
1895 |
$result = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $result);
|
| 1849 |
}
|
1896 |
}
|
| Línea 1850... |
Línea 1897... |
| 1850 |
|
1897 |
|
| - |
|
1898 |
/**
|
| - |
|
1899 |
* Test get_course_contents for courses with sub-sections.
|
| - |
|
1900 |
*
|
| - |
|
1901 |
* @covers ::get_course_contents
|
| - |
|
1902 |
*/
|
| - |
|
1903 |
public function test_get_course_contents_subsections(): void {
|
| - |
|
1904 |
global $DB, $PAGE;
|
| - |
|
1905 |
$this->resetAfterTest();
|
| - |
|
1906 |
|
| - |
|
1907 |
list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test();
|
| - |
|
1908 |
|
| - |
|
1909 |
// Add subsection.
|
| - |
|
1910 |
$modsubsection = $this->getDataGenerator()->create_module('subsection', ['course' => $course->id, 'section' => 2]);
|
| - |
|
1911 |
|
| - |
|
1912 |
// This is needed until MDL-76728 is resolved.
|
| - |
|
1913 |
$PAGE->set_url('/course/view.php', ['id' => $course->id]);
|
| - |
|
1914 |
|
| - |
|
1915 |
$result = core_course_external::get_course_contents($course->id);
|
| - |
|
1916 |
$result = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $result);
|
| - |
|
1917 |
|
| - |
|
1918 |
$this->assertCount(5, $result); // We have 4 original sections plus the one created by mod_subsection.
|
| - |
|
1919 |
|
| - |
|
1920 |
foreach ($result as $section) {
|
| - |
|
1921 |
|
| - |
|
1922 |
if ($section['section'] == 5) { // This is the new section created by modsubsection.
|
| - |
|
1923 |
$this->assertEquals('mod_subsection', $section['component']);
|
| - |
|
1924 |
$this->assertEquals($modsubsection->id, $section['itemid']);
|
| - |
|
1925 |
} else {
|
| - |
|
1926 |
$this->assertEmpty($section['component']);
|
| - |
|
1927 |
$this->assertEmpty($section['itemid']);
|
| - |
|
1928 |
}
|
| - |
|
1929 |
|
| - |
|
1930 |
if ($section['section'] == 2) { // This is the section where mod_subsection is.
|
| - |
|
1931 |
foreach ($section['modules'] as $module) {
|
| - |
|
1932 |
if ($module['modname'] == 'subsection') {
|
| - |
|
1933 |
$this->assertNotEmpty($module['customdata']);
|
| - |
|
1934 |
$customdata = json_decode($module['customdata']);
|
| - |
|
1935 |
$lastsection = end($result);
|
| - |
|
1936 |
// Customdata contains the section id of the section created by the module.
|
| - |
|
1937 |
$this->assertEquals($lastsection['id'], $customdata->sectionid);
|
| - |
|
1938 |
}
|
| - |
|
1939 |
}
|
| - |
|
1940 |
}
|
| - |
|
1941 |
}
|
| - |
|
1942 |
}
|
| - |
|
1943 |
|
| 1851 |
/**
|
1944 |
/**
|
| 1852 |
* Test duplicate_course
|
1945 |
* Test duplicate_course
|
| 1853 |
*/
|
1946 |
*/
|
| 1854 |
public function test_duplicate_course(): void {
|
1947 |
public function test_duplicate_course(): void {
|
| Línea 2752... |
Línea 2845... |
| 2752 |
foreach ($result['courses'] as $course) {
|
2845 |
foreach ($result['courses'] as $course) {
|
| 2753 |
$navoptions = new stdClass;
|
2846 |
$navoptions = new stdClass;
|
| 2754 |
foreach ($course['options'] as $option) {
|
2847 |
foreach ($course['options'] as $option) {
|
| 2755 |
$navoptions->{$option['name']} = $option['available'];
|
2848 |
$navoptions->{$option['name']} = $option['available'];
|
| 2756 |
}
|
2849 |
}
|
| 2757 |
$this->assertCount(9, $course['options']);
|
2850 |
$this->assertCount(10, $course['options']);
|
| 2758 |
if ($course['id'] == SITEID) {
|
2851 |
if ($course['id'] == SITEID) {
|
| 2759 |
$this->assertTrue($navoptions->blogs);
|
2852 |
$this->assertTrue($navoptions->blogs);
|
| 2760 |
$this->assertFalse($navoptions->notes);
|
2853 |
$this->assertFalse($navoptions->notes);
|
| 2761 |
$this->assertFalse($navoptions->participants);
|
2854 |
$this->assertFalse($navoptions->participants);
|
| 2762 |
$this->assertTrue($navoptions->badges);
|
2855 |
$this->assertTrue($navoptions->badges);
|
| 2763 |
$this->assertTrue($navoptions->tags);
|
2856 |
$this->assertTrue($navoptions->tags);
|
| 2764 |
$this->assertFalse($navoptions->grades);
|
2857 |
$this->assertFalse($navoptions->grades);
|
| 2765 |
$this->assertFalse($navoptions->search);
|
2858 |
$this->assertFalse($navoptions->search);
|
| 2766 |
$this->assertTrue($navoptions->competencies);
|
2859 |
$this->assertTrue($navoptions->competencies);
|
| 2767 |
$this->assertFalse($navoptions->communication);
|
2860 |
$this->assertFalse($navoptions->communication);
|
| - |
|
2861 |
$this->assertFalse($navoptions->overview);
|
| 2768 |
} else {
|
2862 |
} else {
|
| 2769 |
$this->assertTrue($navoptions->blogs);
|
2863 |
$this->assertTrue($navoptions->blogs);
|
| 2770 |
$this->assertFalse($navoptions->notes);
|
2864 |
$this->assertFalse($navoptions->notes);
|
| 2771 |
$this->assertTrue($navoptions->participants);
|
2865 |
$this->assertTrue($navoptions->participants);
|
| 2772 |
$this->assertFalse($navoptions->badges);
|
2866 |
$this->assertFalse($navoptions->badges);
|
| 2773 |
$this->assertFalse($navoptions->tags);
|
2867 |
$this->assertFalse($navoptions->tags);
|
| 2774 |
$this->assertTrue($navoptions->grades);
|
2868 |
$this->assertTrue($navoptions->grades);
|
| 2775 |
$this->assertFalse($navoptions->search);
|
2869 |
$this->assertFalse($navoptions->search);
|
| 2776 |
$this->assertTrue($navoptions->competencies);
|
2870 |
$this->assertTrue($navoptions->competencies);
|
| 2777 |
$this->assertFalse($navoptions->communication);
|
2871 |
$this->assertFalse($navoptions->communication);
|
| - |
|
2872 |
$this->assertTrue($navoptions->overview);
|
| 2778 |
}
|
2873 |
}
|
| 2779 |
}
|
2874 |
}
|
| 2780 |
}
|
2875 |
}
|
| Línea 2781... |
Línea 2876... |
| 2781 |
|
2876 |
|
| Línea 2855... |
Línea 2950... |
| 2855 |
|
2950 |
|
| Línea 2856... |
Línea 2951... |
| 2856 |
$this->setAdminUser();
|
2951 |
$this->setAdminUser();
|
| 2857 |
|
2952 |
|
| - |
|
2953 |
$category1 = self::getDataGenerator()->create_category(array('name' => 'Cat 1'));
|
| 2858 |
$category1 = self::getDataGenerator()->create_category(array('name' => 'Cat 1'));
|
2954 |
$category2 = self::getDataGenerator()->create_category(array('parent' => $category1->id));
|
| 2859 |
$category2 = self::getDataGenerator()->create_category(array('parent' => $category1->id));
|
2955 |
$numsections = 4;
|
| - |
|
2956 |
$course1 = self::getDataGenerator()->create_course([
|
| - |
|
2957 |
'category' => $category1->id,
|
| - |
|
2958 |
'shortname' => 'c1',
|
| - |
|
2959 |
'format' => 'topics',
|
| Línea 2860... |
Línea 2960... |
| 2860 |
$course1 = self::getDataGenerator()->create_course(
|
2960 |
'numsections' => $numsections,
|
| 2861 |
array('category' => $category1->id, 'shortname' => 'c1', 'format' => 'topics'));
|
2961 |
]);
|
| 2862 |
|
2962 |
|
| 2863 |
$fieldcategory = self::getDataGenerator()->create_custom_field_category(['name' => 'Other fields']);
|
2963 |
$fieldcategory = self::getDataGenerator()->create_custom_field_category(['name' => 'Other fields']);
|
| Línea 2874... |
Línea 2974... |
| 2874 |
'itemid' => $draftid,
|
2974 |
'itemid' => $draftid,
|
| 2875 |
'filename' => 'image.jpg',
|
2975 |
'filename' => 'image.jpg',
|
| 2876 |
'filepath' => '/',
|
2976 |
'filepath' => '/',
|
| 2877 |
];
|
2977 |
];
|
| 2878 |
$fs = get_file_storage();
|
2978 |
$fs = get_file_storage();
|
| 2879 |
$fs->create_file_from_pathname($filerecord, __DIR__ . '/fixtures/image.jpg');
|
2979 |
$fs->create_file_from_pathname($filerecord, self::get_fixture_path('core_course', 'image.jpg'));
|
| 2880 |
$course2 = self::getDataGenerator()->create_course([
|
2980 |
$course2 = self::getDataGenerator()->create_course([
|
| 2881 |
'visible' => 0,
|
2981 |
'visible' => 0,
|
| 2882 |
'category' => $category2->id,
|
2982 |
'category' => $category2->id,
|
| 2883 |
'idnumber' => 'i2',
|
2983 |
'idnumber' => 'i2',
|
| 2884 |
'customfields' => [$customfieldvalue],
|
2984 |
'customfields' => [$customfieldvalue],
|
| Línea 3062... |
Línea 3162... |
| 3062 |
$this->assertCount(0, $result['courses']);
|
3162 |
$this->assertCount(0, $result['courses']);
|
| Línea 3063... |
Línea 3163... |
| 3063 |
|
3163 |
|
| 3064 |
$result = core_course_external::get_courses_by_field('idnumber', 'x');
|
3164 |
$result = core_course_external::get_courses_by_field('idnumber', 'x');
|
| 3065 |
$result = external_api::clean_returnvalue(core_course_external::get_courses_by_field_returns(), $result);
|
3165 |
$result = external_api::clean_returnvalue(core_course_external::get_courses_by_field_returns(), $result);
|
| - |
|
3166 |
$this->assertCount(0, $result['courses']);
|
| - |
|
3167 |
|
| - |
|
3168 |
$existingsections = $DB->get_records('course_sections', ['course' => $course1->id]);
|
| - |
|
3169 |
$this->assertEquals(count($existingsections), $numsections + 1); // Includes generic section.
|
| - |
|
3170 |
|
| - |
|
3171 |
$section = array_shift($existingsections);
|
| - |
|
3172 |
$result = core_course_external::get_courses_by_field('sectionid', $section->id);
|
| - |
|
3173 |
$result = external_api::clean_returnvalue(core_course_external::get_courses_by_field_returns(), $result);
|
| - |
|
3174 |
$this->assertCount(1, $result['courses']);
|
| - |
|
3175 |
$this->assertEquals($course1->id, $result['courses'][0]['id']);
|
| - |
|
3176 |
|
| - |
|
3177 |
// Wrong section.
|
| - |
|
3178 |
$result = core_course_external::get_courses_by_field('sectionid', 1234);
|
| - |
|
3179 |
$result = external_api::clean_returnvalue(core_course_external::get_courses_by_field_returns(), $result);
|
| 3066 |
$this->assertCount(0, $result['courses']);
|
3180 |
$this->assertCount(0, $result['courses']);
|
| Línea 3067... |
Línea 3181... |
| 3067 |
}
|
3181 |
}
|
| 3068 |
|
3182 |
|
| 3069 |
/**
|
3183 |
/**
|
| Línea 3703... |
Línea 3817... |
| 3703 |
}
|
3817 |
}
|
| Línea 3704... |
Línea 3818... |
| 3704 |
|
3818 |
|
| 3705 |
/**
|
3819 |
/**
|
| 3706 |
* Test the get_enrolled_courses_by_timeline_classification function.
|
3820 |
* Test the get_enrolled_courses_by_timeline_classification function.
|
| 3707 |
*
|
3821 |
*
|
| 3708 |
* @dataProvider get_get_enrolled_courses_by_timeline_classification_test_cases()
|
3822 |
* @dataProvider get_get_enrolled_courses_by_timeline_classification_test_cases
|
| 3709 |
* @param array $coursedata Courses to create
|
3823 |
* @param array $coursedata Courses to create
|
| 3710 |
* @param string $classification Timeline classification
|
3824 |
* @param string $classification Timeline classification
|
| 3711 |
* @param int $limit Maximum number of results
|
3825 |
* @param int $limit Maximum number of results
|
| 3712 |
* @param int $offset Offset the unfiltered courses result set by this amount
|
3826 |
* @param int $offset Offset the unfiltered courses result set by this amount
|
| Línea 3848... |
Línea 3962... |
| 3848 |
$teacherroleid = $DB->get_field('role', 'id', array('shortname' => 'editingteacher'));
|
3962 |
$teacherroleid = $DB->get_field('role', 'id', array('shortname' => 'editingteacher'));
|
| 3849 |
$usercontext = context_user::instance($student->id);
|
3963 |
$usercontext = context_user::instance($student->id);
|
| 3850 |
$this->assignUserCapability('moodle/user:viewdetails', $usercontext, $teacherroleid);
|
3964 |
$this->assignUserCapability('moodle/user:viewdetails', $usercontext, $teacherroleid);
|
| Línea 3851... |
Línea 3965... |
| 3851 |
|
3965 |
|
| - |
|
3966 |
// Sorted by course id DESC.
|
| - |
|
3967 |
// User without moodle/user:viewalldetails capability will not be able to see the course details.
|
| - |
|
3968 |
$result = core_course_external::get_recent_courses($student->id);
|
| - |
|
3969 |
$this->assertCount(0, $result);
|
| - |
|
3970 |
|
| - |
|
3971 |
// User with moodle/user:viewalldetails capability will be able to see the course details.
|
| 3852 |
// Sorted by course id DESC.
|
3972 |
$this->assignUserCapability('moodle/user:viewalldetails', $usercontext, $teacherroleid);
|
| 3853 |
$result = core_course_external::get_recent_courses($student->id);
|
3973 |
$result = core_course_external::get_recent_courses($student->id);
|
| 3854 |
$this->assertCount(1, $result);
|
3974 |
$this->assertCount(1, $result);
|
| 3855 |
$this->assertEquals($courses[0]->id, array_shift($result)->id);
|
3975 |
$this->assertEquals($courses[0]->id, array_shift($result)->id);
|
| Línea 3951... |
Línea 4071... |
| 3951 |
]
|
4071 |
]
|
| 3952 |
];
|
4072 |
];
|
| Línea 3953... |
Línea 4073... |
| 3953 |
|
4073 |
|
| 3954 |
$this->assertEquals(2, count($users['users']));
|
4074 |
$this->assertEquals(2, count($users['users']));
|
| - |
|
4075 |
$this->assertEquals($expectedusers, $users);
|
| - |
|
4076 |
|
| - |
|
4077 |
// Prohibit the capability for viewing course participants.
|
| - |
|
4078 |
$this->unassignUserCapability('moodle/course:viewparticipants', null, null, $course1->id);
|
| - |
|
4079 |
$this->expectException(required_capability_exception::class);
|
| - |
|
4080 |
$this->expectExceptionMessage('Sorry, but you do not currently have permissions to do that (View participants)');
|
| 3955 |
$this->assertEquals($expectedusers, $users);
|
4081 |
core_course_external::get_enrolled_users_by_cmid($forum1->cmid);
|
| Línea 3956... |
Línea 4082... |
| 3956 |
}
|
4082 |
}
|
| 3957 |
|
4083 |
|
| 3958 |
/**
|
4084 |
/**
|