Proyectos de Subversion Moodle

Rev

Rev 11 | | 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
 * Unit tests for WS in tags
19
 *
20
 * @package core_tag
21
 * @category test
22
 * @copyright 2015 Marina Glancy
23
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
namespace core_tag\external;
27
 
28
use externallib_advanced_testcase;
29
use core_external\external_api;
30
 
31
defined('MOODLE_INTERNAL') || die();
32
 
33
global $CFG;
34
 
35
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
36
 
1441 ariadna 37
final class external_test extends externallib_advanced_testcase {
1 efrain 38
    /**
39
     * Test update_categories
40
     */
11 efrain 41
    public function test_update_tags(): void {
1 efrain 42
        global $DB;
43
        $this->resetAfterTest();
44
        $context = \context_system::instance();
45
 
46
        $originaltag = array(
47
            'isstandard' => 0,
48
            'flag' => 1,
49
            'rawname' => 'test',
50
            'description' => 'desc'
51
        );
52
        $tag = $this->getDataGenerator()->create_tag($originaltag);
53
 
54
        $updatetag = array(
55
            'id' => $tag->id,
56
            'description' => 'Trying to change tag description',
57
            'rawname' => 'Trying to change tag name',
58
            'flag' => 0,
59
            'isstandard' => 1,
60
        );
61
        $gettag = array(
62
            'id' => $tag->id,
63
        );
64
 
65
        // User without any caps can not change anything about a tag but can request [partial] tag data.
66
        $this->setUser($this->getDataGenerator()->create_user());
67
        $result = \core_tag_external::update_tags(array($updatetag));
68
        $result = external_api::clean_returnvalue(\core_tag_external::update_tags_returns(), $result);
69
        $this->assertEquals($tag->id, $result['warnings'][0]['item']);
70
        $this->assertEquals('nothingtoupdate', $result['warnings'][0]['warningcode']);
71
        $this->assertEquals($originaltag['rawname'], $DB->get_field('tag', 'rawname',
72
            array('id' => $tag->id)));
73
        $this->assertEquals($originaltag['description'], $DB->get_field('tag', 'description',
74
            array('id' => $tag->id)));
75
 
76
        $result = \core_tag_external::get_tags(array($gettag));
77
        $result = external_api::clean_returnvalue(\core_tag_external::get_tags_returns(), $result);
78
        $this->assertEquals($originaltag['rawname'], $result['tags'][0]['rawname']);
79
        $this->assertEquals($originaltag['description'], $result['tags'][0]['description']);
80
        $this->assertNotEmpty($result['tags'][0]['viewurl']);
81
        $this->assertArrayNotHasKey('changetypeurl', $result['tags'][0]);
82
        $this->assertArrayNotHasKey('changeflagurl', $result['tags'][0]);
83
        $this->assertArrayNotHasKey('flag', $result['tags'][0]);
84
        $this->assertArrayNotHasKey('official', $result['tags'][0]);
85
        $this->assertArrayNotHasKey('isstandard', $result['tags'][0]);
86
 
87
        // User with editing only capability can change description but not the tag name.
88
        $roleid = $this->assignUserCapability('moodle/tag:edit', $context->id);
89
        $result = \core_tag_external::update_tags(array($updatetag));
90
        $result = external_api::clean_returnvalue(\core_tag_external::update_tags_returns(), $result);
91
        $this->assertEmpty($result['warnings']);
92
 
93
        $result = \core_tag_external::get_tags(array($gettag));
94
        $result = external_api::clean_returnvalue(\core_tag_external::get_tags_returns(), $result);
95
        $this->assertEquals($updatetag['id'], $result['tags'][0]['id']);
96
        $this->assertEquals($updatetag['description'], $result['tags'][0]['description']);
97
        $this->assertEquals($originaltag['rawname'], $result['tags'][0]['rawname']);
98
        $this->assertArrayNotHasKey('flag', $result['tags'][0]); // 'Flag' is not available unless 'moodle/tag:manage' cap exists.
99
        $this->assertEquals(0, $result['tags'][0]['official']);
100
        $this->assertEquals(0, $result['tags'][0]['isstandard']);
101
        $this->assertEquals($originaltag['rawname'], $DB->get_field('tag', 'rawname',
102
                array('id' => $tag->id)));
103
        $this->assertEquals($updatetag['description'], $DB->get_field('tag', 'description',
104
                array('id' => $tag->id)));
105
 
106
        // User with editing and manage cap can also change the tag name,
107
        // make it standard and reset flag.
108
        assign_capability('moodle/tag:manage', CAP_ALLOW, $roleid, $context->id);
109
        $this->assertTrue(has_capability('moodle/tag:manage', $context));
110
        $result = \core_tag_external::update_tags(array($updatetag));
111
        $result = external_api::clean_returnvalue(\core_tag_external::update_tags_returns(), $result);
112
        $this->assertEmpty($result['warnings']);
113
 
114
        $result = \core_tag_external::get_tags(array($gettag));
115
        $result = external_api::clean_returnvalue(\core_tag_external::get_tags_returns(), $result);
116
        $this->assertEquals($updatetag['id'], $result['tags'][0]['id']);
117
        $this->assertEquals($updatetag['rawname'], $result['tags'][0]['rawname']);
118
        $this->assertEquals(\core_text::strtolower($updatetag['rawname']), $result['tags'][0]['name']);
119
        $this->assertEquals($updatetag['flag'], $result['tags'][0]['flag']);
120
        $this->assertEquals($updatetag['isstandard'], $result['tags'][0]['official']);
121
        $this->assertEquals($updatetag['isstandard'], $result['tags'][0]['isstandard']);
122
        $this->assertEquals($updatetag['rawname'], $DB->get_field('tag', 'rawname',
123
                array('id' => $tag->id)));
124
        $this->assertEquals(1, $DB->get_field('tag', 'isstandard', array('id' => $tag->id)));
125
 
126
        // Updating and getting non-existing tag.
127
        $nonexistingtag = array(
128
            'id' => 123,
129
            'description' => 'test'
130
        );
131
        $getnonexistingtag = array(
132
            'id' => 123,
133
        );
134
        $result = \core_tag_external::update_tags(array($nonexistingtag));
135
        $result = external_api::clean_returnvalue(\core_tag_external::update_tags_returns(), $result);
136
        $this->assertEquals(123, $result['warnings'][0]['item']);
137
        $this->assertEquals('tagnotfound', $result['warnings'][0]['warningcode']);
138
 
139
        $result = \core_tag_external::get_tags(array($getnonexistingtag));
140
        $result = external_api::clean_returnvalue(\core_tag_external::get_tags_returns(), $result);
141
        $this->assertEmpty($result['tags']);
142
        $this->assertEquals(123, $result['warnings'][0]['item']);
143
        $this->assertEquals('tagnotfound', $result['warnings'][0]['warningcode']);
144
 
145
        // Attempt to update a tag to the name that is reserved.
146
        $anothertag = $this->getDataGenerator()->create_tag(array('rawname' => 'Mytag'));
147
        $updatetag2 = array('id' => $tag->id, 'rawname' => 'MYTAG');
148
        $result = \core_tag_external::update_tags(array($updatetag2));
149
        $result = external_api::clean_returnvalue(\core_tag_external::update_tags_returns(), $result);
150
        $this->assertEquals($tag->id, $result['warnings'][0]['item']);
151
        $this->assertEquals('namesalreadybeeingused', $result['warnings'][0]['warningcode']);
152
    }
153
 
154
    /**
155
     * Test update_inplace_editable()
156
     */
11 efrain 157
    public function test_update_inplace_editable(): void {
1 efrain 158
        global $CFG, $DB, $PAGE;
159
        require_once($CFG->dirroot . '/lib/external/externallib.php');
160
 
161
        $this->resetAfterTest(true);
162
        $tag = $this->getDataGenerator()->create_tag();
163
        $this->setUser($this->getDataGenerator()->create_user());
164
 
165
        // Call service for core_tag component without necessary permissions.
166
        try {
167
            \core_external::update_inplace_editable('core_tag', 'tagname', $tag->id, 'new tag name');
168
            $this->fail('Exception expected');
169
        } catch (\moodle_exception $e) {
170
            $this->assertEquals('Sorry, but you do not currently have permissions to do that (Manage all tags).',
171
                    $e->getMessage());
172
        }
173
 
174
        // Change to admin user and make sure that tag name can be updated using web service update_inplace_editable().
175
        $this->setAdminUser();
176
        $res = \core_external::update_inplace_editable('core_tag', 'tagname', $tag->id, 'New tag name');
177
        $res = external_api::clean_returnvalue(\core_external::update_inplace_editable_returns(), $res);
178
        $this->assertEquals('New tag name', $res['value']);
179
        $this->assertEquals('New tag name', $DB->get_field('tag', 'rawname', array('id' => $tag->id)));
180
 
181
        // Call callback core_tag_inplace_editable() directly.
182
        $tmpl = component_callback('core_tag', 'inplace_editable', array('tagname', $tag->id, 'Rename me again'));
183
        $this->assertInstanceOf('core\output\inplace_editable', $tmpl);
184
        $res = $tmpl->export_for_template($PAGE->get_renderer('core'));
185
        $this->assertEquals('Rename me again', $res['value']);
186
        $this->assertEquals('Rename me again', $DB->get_field('tag', 'rawname', array('id' => $tag->id)));
187
    }
188
 
189
    /**
190
     * Test get_tagindex_per_area.
191
     */
11 efrain 192
    public function test_get_tagindex_per_area(): void {
1 efrain 193
        global $USER;
194
        $this->resetAfterTest(true);
195
 
196
        // Create tags for two user profiles and one course.
197
        $this->setAdminUser();
198
        $context = \context_user::instance($USER->id);
199
        \core_tag_tag::set_item_tags('core', 'user', $USER->id, $context, array('test'));
200
 
201
        $this->setUser($this->getDataGenerator()->create_user());
202
        $context = \context_user::instance($USER->id);
203
        \core_tag_tag::set_item_tags('core', 'user', $USER->id, $context, array('test'));
204
 
205
        $course = $this->getDataGenerator()->create_course();
206
        $context = \context_course::instance($course->id);
207
        \core_tag_tag::set_item_tags('core', 'course', $course->id, $context, array('test'));
208
 
209
        $tag = \core_tag_tag::get_by_name(0, 'test');
210
 
211
        // First, search by id.
212
        $result = \core_tag_external::get_tagindex_per_area(array('id' => $tag->id));
213
        $result = external_api::clean_returnvalue(\core_tag_external::get_tagindex_per_area_returns(), $result);
214
        $this->assertCount(2, $result); // Two different areas: course and user.
215
        $this->assertEquals($tag->id, $result[0]['tagid']);
216
        $this->assertEquals('course', $result[0]['itemtype']);
217
        $this->assertEquals($tag->id, $result[1]['tagid']);
218
        $this->assertEquals('user', $result[1]['itemtype']);
219
 
220
        // Now, search by name.
221
        $result = \core_tag_external::get_tagindex_per_area(array('tag' => 'test'));
222
        $result = external_api::clean_returnvalue(\core_tag_external::get_tagindex_per_area_returns(), $result);
223
        $this->assertCount(2, $result); // Two different areas: course and user.
224
        $this->assertEquals($tag->id, $result[0]['tagid']);
225
        $this->assertEquals('course', $result[0]['itemtype']);
226
        $this->assertEquals($tag->id, $result[1]['tagid']);
227
        $this->assertEquals('user', $result[1]['itemtype']);
228
 
229
        // Filter by tag area.
230
        $result = \core_tag_external::get_tagindex_per_area(array('tag' => 'test', 'ta' => $result[0]['ta']));
231
        $result = external_api::clean_returnvalue(\core_tag_external::get_tagindex_per_area_returns(), $result);
232
        $this->assertCount(1, $result); // Just the given area.
233
        $this->assertEquals($tag->id, $result[0]['tagid']);
234
        $this->assertEquals('course', $result[0]['itemtype']);
235
 
236
        // Now, search by tag collection (use default).
237
        $result = \core_tag_external::get_tagindex_per_area(array('id' => $tag->id, 'tc' => 1));
238
        $result = external_api::clean_returnvalue(\core_tag_external::get_tagindex_per_area_returns(), $result);
239
        $this->assertCount(2, $result); // Two different areas: course and user.
240
    }
241
 
242
    /**
243
     * Test get_tag_areas.
244
     */
11 efrain 245
    public function test_get_tag_areas(): void {
1 efrain 246
        global $DB;
247
        $this->resetAfterTest(true);
248
 
249
        $this->setAdminUser();
250
        $result = \core_tag_external::get_tag_areas();
251
        $result = external_api::clean_returnvalue(\core_tag_external::get_tag_areas_returns(), $result);
252
        $areas = $DB->get_records('tag_area');
253
        $this->assertCount(count($areas), $result['areas']);
254
        foreach ($result['areas'] as $area) {
255
            $this->assertEquals($areas[$area['id']]->component, $area['component']);
256
            $this->assertEquals($areas[$area['id']]->itemtype, $area['itemtype']);
257
        }
258
    }
259
 
260
    /**
261
     * Test get_tag_collections.
262
     */
11 efrain 263
    public function test_get_tag_collections(): void {
1 efrain 264
        global $DB;
265
        $this->resetAfterTest(true);
266
 
267
        // Create new tag collection.
268
        $data = (object) array('name' => 'new tag coll');
269
        \core_tag_collection::create($data);
270
 
271
        $this->setAdminUser();
272
        $result = \core_tag_external::get_tag_collections();
273
        $result = external_api::clean_returnvalue(\core_tag_external::get_tag_collections_returns(), $result);
274
 
275
        $collections = $DB->get_records('tag_coll');
276
        $this->assertCount(count($collections), $result['collections']);
277
        foreach ($result['collections'] as $collection) {
278
            $this->assertEquals($collections[$collection['id']]->component, $collection['component']);
279
            $this->assertEquals($collections[$collection['id']]->name, $collection['name']);
280
        }
281
    }
282
 
283
    /**
284
     * Test get_tag_cloud.
285
     */
11 efrain 286
    public function test_get_tag_cloud(): void {
1 efrain 287
        global $USER, $DB;
288
        $this->resetAfterTest(true);
289
 
290
        // Create tags for two user profiles, a post and one course.
291
        $this->setAdminUser();
292
        $context = \context_user::instance($USER->id);
293
        \core_tag_tag::set_item_tags('core', 'user', $USER->id, $context, array('Cats', 'Dogs'));
294
 
295
        $this->setUser($this->getDataGenerator()->create_user());
296
        $context = \context_user::instance($USER->id);
297
        \core_tag_tag::set_item_tags('core', 'user', $USER->id, $context, array('Mice'));
298
 
299
        $course = $this->getDataGenerator()->create_course();
300
        $coursecontext = \context_course::instance($course->id);
301
        \core_tag_tag::set_item_tags('core', 'course', $course->id, $coursecontext, array('Cats'));
302
 
303
        $post = new \stdClass();
304
        $post->userid = $USER->id;
305
        $post->content = 'test post content text';
306
        $post->id = $DB->insert_record('post', $post);
307
        $context = \context_system::instance();
308
        \core_tag_tag::set_item_tags('core', 'post', $post->id, $context, array('Horses', 'Cats'));
309
 
310
        // First, retrieve complete cloud.
311
        $result = \core_tag_external::get_tag_cloud();
312
        $result = external_api::clean_returnvalue(\core_tag_external::get_tag_cloud_returns(), $result);
313
        $this->assertCount(4, $result['tags']); // Four different tags: Cats, Dogs, Mice, Horses.
314
        $this->assertEquals(4, $result['tagscount']);
315
        $this->assertEquals(4, $result['totalcount']);
316
 
317
        foreach ($result['tags'] as $tag) {
318
            if ($tag['name'] == 'Cats') {
319
                $this->assertEquals(3, $tag['count']);
320
            } else {
321
                $this->assertEquals(1, $tag['count']);
322
            }
323
        }
324
 
325
        // Test filter by collection, pagination and sorting.
326
        $defaultcoll = \core_tag_collection::get_default();
327
        $result = \core_tag_external::get_tag_cloud($defaultcoll, false, 2, 'count');
328
        $result = external_api::clean_returnvalue(\core_tag_external::get_tag_cloud_returns(), $result);
329
        $this->assertCount(2, $result['tags']); // Only two tags.
330
        $this->assertEquals(2, $result['tagscount']);
331
        $this->assertEquals(4, $result['totalcount']);
332
        $this->assertEquals('Dogs', $result['tags'][0]['name']); // Lower count first.
333
 
334
        // Test search.
335
        $result = \core_tag_external::get_tag_cloud(0, false, 150, 'name', 'Mice');
336
        $result = external_api::clean_returnvalue(\core_tag_external::get_tag_cloud_returns(), $result);
337
        $this->assertCount(1, $result['tags']); // Only the searched tags.
338
        $this->assertEquals(1, $result['tagscount']);
339
        $this->assertEquals(1, $result['totalcount']); // When searching, the total is always for the search.
340
        $this->assertEquals('Mice', $result['tags'][0]['name']);
341
 
342
        $result = \core_tag_external::get_tag_cloud(0, false, 150, 'name', 'Conejo');
343
        $result = external_api::clean_returnvalue(\core_tag_external::get_tag_cloud_returns(), $result);
344
        $this->assertCount(0, $result['tags']); // Nothing found.
345
        $this->assertEquals(0, $result['tagscount']);
346
        $this->assertEquals(0, $result['totalcount']); // When searching, the total is always for the search.
347
 
348
        // Test standard filtering.
349
        $micetag = \core_tag_tag::get_by_name($defaultcoll, 'Mice', '*');
350
        $micetag->update(array('isstandard' => 1));
351
 
352
        $result = \core_tag_external::get_tag_cloud(0, true);
353
        $result = external_api::clean_returnvalue(\core_tag_external::get_tag_cloud_returns(), $result);
354
        $this->assertCount(1, $result['tags']);
355
        $this->assertEquals(1, $result['tagscount']);
356
        $this->assertEquals(1, $result['totalcount']); // When searching, the total is always for the search.
357
        $this->assertEquals('Mice', $result['tags'][0]['name']);
358
 
359
        // Test course context filtering.
360
        $result = \core_tag_external::get_tag_cloud(0, false, 150, 'name', '', 0, $coursecontext->id);
361
        $result = external_api::clean_returnvalue(\core_tag_external::get_tag_cloud_returns(), $result);
362
        $this->assertCount(1, $result['tags']);
363
        $this->assertEquals(1, $result['tagscount']);
364
        $this->assertEquals(1, $result['totalcount']); // When searching, the total is always for the search.
365
        $this->assertEquals('Cats', $result['tags'][0]['name']);
366
 
367
        // Complete system context.
368
        $result = \core_tag_external::get_tag_cloud(0, false, 150, 'name', '', 0, \context_system::instance()->id);
369
        $result = external_api::clean_returnvalue(\core_tag_external::get_tag_cloud_returns(), $result);
370
        $this->assertCount(4, $result['tags']);
371
        $this->assertEquals(4, $result['tagscount']);
372
 
373
        // Just system context - avoid children.
374
        $result = \core_tag_external::get_tag_cloud(0, false, 150, 'name', '', 0, \context_system::instance()->id, 0);
375
        $result = external_api::clean_returnvalue(\core_tag_external::get_tag_cloud_returns(), $result);
376
        $this->assertCount(2, $result['tags']);
377
        $this->assertEquals(2, $result['tagscount']); // Horses and Cats.
378
        $this->assertEquals('Cats', $result['tags'][0]['name']);
379
        $this->assertEquals('Horses', $result['tags'][1]['name']);
380
    }
381
}