Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Contains the tests for the content_item_service class.
19
 *
20
 * @package    core
21
 * @subpackage course
22
 * @copyright  2020 Jake Dallimore <jrhdallimore@gmail.com>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
namespace core_course;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
use core_course\local\service\content_item_service;
30
use core_course\local\repository\content_item_readonly_repository;
31
 
32
/**
33
 * The tests for the content_item_service class.
34
 *
35
 * @copyright  2020 Jake Dallimore <jrhdallimore@gmail.com>
36
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37
 */
38
class services_content_item_service_test extends \advanced_testcase {
39
 
40
    /**
41
     * Test confirming that content items are returned by the service.
42
     */
11 efrain 43
    public function test_get_content_items_for_user_in_course_basic(): void {
1 efrain 44
        $this->resetAfterTest();
45
 
46
        // Create a user in a course.
47
        $course = $this->getDataGenerator()->create_course();
48
        $user = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
49
 
50
        $cis = new content_item_service(new content_item_readonly_repository());
51
        $contentitems = $cis->get_content_items_for_user_in_course($user, $course);
52
 
53
        foreach ($contentitems as $key => $contentitem) {
54
            $this->assertObjectHasProperty('id', $contentitem);
55
            $this->assertObjectHasProperty('name', $contentitem);
56
            $this->assertObjectHasProperty('title', $contentitem);
57
            $this->assertObjectHasProperty('link', $contentitem);
58
            $this->assertObjectHasProperty('icon', $contentitem);
59
            $this->assertObjectHasProperty('help', $contentitem);
60
            $this->assertObjectHasProperty('archetype', $contentitem);
61
            $this->assertObjectHasProperty('componentname', $contentitem);
62
        }
63
    }
64
 
65
    /**
66
     * Test confirming that access control is performed when asking the service to return content items for a user in a course.
67
     */
11 efrain 68
    public function test_get_content_items_for_user_in_course_permissions(): void {
1 efrain 69
        $this->resetAfterTest();
70
        global $DB;
71
 
72
        // Create a user in a course.
73
        $course = $this->getDataGenerator()->create_course();
74
        $user = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
75
 
76
        // No cap override, so assign should be returned.
77
        $cis = new content_item_service(new content_item_readonly_repository());
78
        $contentitems = $cis->get_content_items_for_user_in_course($user, $course);
79
        $this->assertContains('assign', array_column($contentitems, 'name'));
80
 
81
        // Override the capability 'mod/assign:addinstance' for the 'editing teacher' role.
82
        $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
83
        assign_capability('mod/assign:addinstance', CAP_PROHIBIT, $teacherrole->id, \context_course::instance($course->id));
84
 
85
        $contentitems = $cis->get_content_items_for_user_in_course($user, $course);
86
        $this->assertArrayNotHasKey('assign', $contentitems);
87
    }
88
 
89
    /**
90
     * Test confirming that params can be added to the content item's link.
91
     */
11 efrain 92
    public function test_get_content_item_for_user_in_course_link_params(): void {
1 efrain 93
        $this->resetAfterTest();
94
 
95
        // Create a user in a course.
96
        $course = $this->getDataGenerator()->create_course();
97
        $user = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
98
 
99
        $cis = new content_item_service(new content_item_readonly_repository());
100
        $contentitems = $cis->get_content_items_for_user_in_course($user, $course, ['sr' => 7]);
101
 
102
        foreach ($contentitems as $item) {
103
            $this->assertStringContainsString('sr=7', $item->link);
104
        }
105
    }
106
 
107
    /**
108
     * Test confirming that all content items can be fetched irrespective of permissions.
109
     */
11 efrain 110
    public function test_get_all_content_items(): void {
1 efrain 111
        $this->resetAfterTest();
112
        global $DB;
113
 
114
        // Create a user in a course and set up a site-level LTI tool, configured to display in the activity chooser.
115
        $course = $this->getDataGenerator()->create_course();
116
        $user = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
117
        /** @var \mod_lti_generator $ltigenerator */
118
        $ltigenerator = $this->getDataGenerator()->get_plugin_generator('mod_lti');
119
        $ltigenerator->create_tool_types([
120
            'name' => 'site tool',
121
            'baseurl' => 'http://example.com',
122
            'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER,
123
            'state' => LTI_TOOL_STATE_CONFIGURED
124
        ]);
125
        $cis = new content_item_service(new content_item_readonly_repository());
126
        $this->setUser($user); // This is needed since the underlying lti code needs the global user despite the api accepting user.
127
 
128
        // The call to get_all_content_items() should return the same items as for the course,
129
        // given the user is an editing teacher and can add preconfigured lti instances.
130
        $allcontentitems = $cis->get_all_content_items($user);
131
        $coursecontentitems = $cis->get_content_items_for_user_in_course($user, $course);
132
        $this->assertContains('site tool', array_column($coursecontentitems, 'title'));
133
        $this->assertContains('site tool', array_column($allcontentitems, 'title'));
134
 
135
        // Now removing the cap 'mod/lti:addpreconfiguredinstance', restricting those items returned by the course-specific method.
136
        $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
137
        assign_capability('mod/lti:addpreconfiguredinstance', CAP_PROHIBIT, $teacherrole->id,
138
            \core\context\course::instance($course->id));
139
 
140
        // Verify that all items, including the tool, are still returned by the get_all_content_items() call.
141
        $allcontentitems = $cis->get_all_content_items($user);
142
        $coursecontentitems = $cis->get_content_items_for_user_in_course($user, $course);
143
        $this->assertNotContains('site tool', array_column($coursecontentitems, 'title'));
144
        $this->assertContains('site tool', array_column($allcontentitems, 'title'));
145
    }
146
 
147
    /**
148
     * Test confirming that content items which title match a certain pattern can be fetched irrespective of permissions.
149
     */
11 efrain 150
    public function test_get_content_items_by_name_pattern(): void {
1 efrain 151
        $this->resetAfterTest();
152
 
153
        // Create a user in a course.
154
        $course = $this->getDataGenerator()->create_course();
155
        $user = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
156
 
157
        // Pattern that does exist.
158
        $pattern1 = "assign";
159
        // Pattern that does not exist.
160
        $pattern2 = "random string";
161
 
162
        $cis = new content_item_service(new content_item_readonly_repository());
163
        $matchingcontentitems1 = $cis->get_content_items_by_name_pattern($user, $pattern1);
164
        $matchingcontentitems2 = $cis->get_content_items_by_name_pattern($user, $pattern2);
165
 
166
        // The pattern "assign" should return at least 1 content item (ex. "Assignment").
167
        $this->assertGreaterThanOrEqual(1, count($matchingcontentitems1));
168
        // Verify the pattern "assign" can be found in the title of each returned content item.
169
        foreach ($matchingcontentitems1 as $contentitem) {
170
            $this->assertEquals(1, preg_match("/$pattern1/i", $contentitem->title));
171
        }
172
        // The pattern "random string" should not return any content items.
173
        $this->assertEmpty($matchingcontentitems2);
174
    }
175
 
176
    /**
177
     * Test confirming that a content item can be added to a user's favourites.
178
     */
11 efrain 179
    public function test_add_to_user_favourites(): void {
1 efrain 180
        $this->resetAfterTest();
181
 
182
        // Create a user in a course.
183
        $course = $this->getDataGenerator()->create_course();
184
        $user = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
185
        $cis = new content_item_service(new content_item_readonly_repository());
186
 
187
        // Grab a the assign content item, which we'll favourite for the user.
188
        $items = $cis->get_all_content_items($user);
189
        $assign = $items[array_search('assign', array_column($items, 'name'))];
190
        $contentitem = $cis->add_to_user_favourites($user, 'mod_assign', $assign->id);
191
 
192
        // Verify the exported result is marked as a favourite.
193
        $this->assertEquals('assign', $contentitem->name);
194
        $this->assertTrue($contentitem->favourite);
195
 
196
        // Verify the item is marked as a favourite when returned from the other service methods.
197
        $allitems = $cis->get_all_content_items($user);
198
        $allitemsassign = $allitems[array_search('assign', array_column($allitems, 'name'))];
199
 
200
        $courseitems = $cis->get_content_items_for_user_in_course($user, $course);
201
        $courseitemsassign = $courseitems[array_search('assign', array_column($courseitems, 'name'))];
202
        $this->assertTrue($allitemsassign->favourite);
203
        $this->assertTrue($courseitemsassign->favourite);
204
    }
205
 
206
    /**
207
     * Test verifying that content items can be removed from a user's favourites.
208
     */
11 efrain 209
    public function test_remove_from_user_favourites(): void {
1 efrain 210
        $this->resetAfterTest();
211
 
212
        // Create a user in a course.
213
        $course = $this->getDataGenerator()->create_course();
214
        $user = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
215
        $cis = new content_item_service(new content_item_readonly_repository());
216
 
217
        // Grab a the assign content item, which we'll favourite for the user.
218
        $items = $cis->get_all_content_items($user);
219
        $assign = $items[array_search('assign', array_column($items, 'name'))];
220
        $cis->add_to_user_favourites($user, 'mod_assign', $assign->id);
221
 
222
        // Now, remove the favourite, and verify it.
223
        $contentitem = $cis->remove_from_user_favourites($user, 'mod_assign', $assign->id);
224
 
225
        // Verify the exported result is not marked as a favourite.
226
        $this->assertEquals('assign', $contentitem->name);
227
        $this->assertFalse($contentitem->favourite);
228
 
229
        // Verify the item is not marked as a favourite when returned from the other service methods.
230
        $allitems = $cis->get_all_content_items($user);
231
        $allitemsassign = $allitems[array_search('assign', array_column($allitems, 'name'))];
232
        $courseitems = $cis->get_content_items_for_user_in_course($user, $course);
233
        $courseitemsassign = $courseitems[array_search('assign', array_column($courseitems, 'name'))];
234
        $this->assertFalse($allitemsassign->favourite);
235
        $this->assertFalse($courseitemsassign->favourite);
236
    }
237
 
238
    /**
239
     * Test that toggling a recommendation works as anticipated.
240
     */
11 efrain 241
    public function test_toggle_recommendation(): void {
1 efrain 242
        $this->resetAfterTest();
243
 
244
        // Create a user in a course.
245
        $course = $this->getDataGenerator()->create_course();
246
        $user = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
247
        $cis = new content_item_service(new content_item_readonly_repository());
248
 
249
        // Grab a the assign content item, which we'll recommend for the user.
250
        $items = $cis->get_all_content_items($user);
251
        $assign = $items[array_search('assign', array_column($items, 'name'))];
252
        $result = $cis->toggle_recommendation($assign->componentname, $assign->id);
253
        $this->assertTrue($result);
254
 
255
        $courseitems = $cis->get_all_content_items($user);
256
        $courseitemsassign = $courseitems[array_search('assign', array_column($courseitems, 'name'))];
257
        $this->assertTrue($courseitemsassign->recommended);
258
 
259
        // Let's toggle the recommendation off.
260
        $result = $cis->toggle_recommendation($assign->componentname, $assign->id);
261
        $this->assertFalse($result);
262
 
263
        $courseitems = $cis->get_all_content_items($user);
264
        $courseitemsassign = $courseitems[array_search('assign', array_column($courseitems, 'name'))];
265
        $this->assertFalse($courseitemsassign->recommended);
266
    }
267
}