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
namespace enrol_imsenterprise;
18
 
19
use enrol_imsenterprise_plugin;
20
use enrol_imsenterprise\task\cron_task;
21
 
22
defined('MOODLE_INTERNAL') || die();
23
 
24
global $CFG;
25
require_once($CFG->dirroot . '/enrol/imsenterprise/locallib.php');
26
require_once($CFG->dirroot . '/enrol/imsenterprise/lib.php');
27
 
28
/**
29
 * IMS Enterprise test case
30
 *
31
 * @package    enrol_imsenterprise
32
 * @category   test
33
 * @copyright  2012 David Monllaó
34
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35
 */
36
class imsenterprise_test extends \advanced_testcase {
37
 
38
    /**
39
     * @var $imsplugin enrol_imsenterprise_plugin IMS plugin instance.
40
     */
41
    public $imsplugin;
42
 
43
    /**
44
     * Setup required for all tests.
45
     */
46
    protected function setUp(): void {
47
        $this->resetAfterTest(true);
48
        $this->imsplugin = enrol_get_plugin('imsenterprise');
49
        $this->set_test_config();
50
    }
51
 
52
    /**
53
     * With an empty IMS enterprise file
54
     */
11 efrain 55
    public function test_emptyfile(): void {
1 efrain 56
        global $DB;
57
 
58
        $prevncourses = $DB->count_records('course');
59
        $prevnusers = $DB->count_records('user');
60
 
61
        $this->set_xml_file(false, false);
62
        $this->imsplugin->cron();
63
 
64
        $this->assertEquals($prevncourses, $DB->count_records('course'));
65
        $this->assertEquals($prevnusers, $DB->count_records('user'));
66
    }
67
 
68
    /**
69
     * Existing users are not created again
70
     */
11 efrain 71
    public function test_users_existing(): void {
1 efrain 72
        global $DB;
73
 
74
        $user1 = $this->getDataGenerator()->create_user();
75
        $user2 = $this->getDataGenerator()->create_user();
76
 
77
        $prevnusers = $DB->count_records('user');
78
 
79
        $users = array($user1, $user2);
80
        $this->set_xml_file($users);
81
        $this->imsplugin->cron();
82
 
83
        $this->assertEquals($prevnusers, $DB->count_records('user'));
84
    }
85
 
86
    /**
87
     * Add new users
88
     */
11 efrain 89
    public function test_users_add(): void {
1 efrain 90
        global $DB;
91
 
92
        $prevnusers = $DB->count_records('user');
93
 
94
        $user1 = new \stdClass();
95
        $user1->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
96
        $user1->username = 'u1';
97
        $user1->email = 'u1@example.com';
98
        $user1->firstname = 'U';
99
        $user1->lastname = '1';
100
 
101
        $users = array($user1);
102
        $this->set_xml_file($users);
103
        $this->imsplugin->cron();
104
 
105
        $this->assertEquals(($prevnusers + 1), $DB->count_records('user'));
106
    }
107
 
108
    /**
109
     * Add new users and set an auth type
110
     */
11 efrain 111
    public function test_users_add_with_auth(): void {
1 efrain 112
        global $DB;
113
 
114
        $prevnusers = $DB->count_records('user');
115
 
116
        $user2 = new \stdClass();
117
        $user2->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
118
        $user2->username = 'u2';
119
        $user2->auth = 'cas';
120
        $user2->email = 'u2@u2.org';
121
        $user2->firstname = 'U';
122
        $user2->lastname = '2';
123
 
124
        $users = array($user2);
125
        $this->set_xml_file($users);
126
        $this->imsplugin->cron();
127
 
128
        $dbuser = $DB->get_record('user', array('username' => $user2->username));
129
        // TODO: MDL-15863 this needs more work due to multiauth changes, use first auth for now.
130
        $dbauth = explode(',', $dbuser->auth);
131
        $dbauth = reset($dbauth);
132
 
133
        $this->assertEquals(($prevnusers + 1), $DB->count_records('user'));
134
        $this->assertEquals($dbauth, $user2->auth);
135
    }
136
 
137
 
138
    /**
139
     * Update user
140
     */
11 efrain 141
    public function test_user_update(): void {
1 efrain 142
        global $DB;
143
 
144
        $user = $this->getDataGenerator()->create_user(array('idnumber' => 'test-update-user'));
145
        $imsuser = new \stdClass();
146
        $imsuser->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_UPDATE;
147
        // THIS SHOULD WORK, surely?: $imsuser->username = $user->username;
148
        // But this is required...
149
        $imsuser->username = $user->idnumber;
150
        $imsuser->email = 'u3@u3.org';
151
        $imsuser->firstname = 'U';
152
        $imsuser->lastname = '3';
153
 
154
        $this->set_xml_file(array($imsuser));
155
        $this->imsplugin->cron();
156
        $dbuser = $DB->get_record('user', array('id' => $user->id), '*', MUST_EXIST);
157
        $this->assertEquals($imsuser->email, $dbuser->email);
158
        $this->assertEquals($imsuser->firstname, $dbuser->firstname);
159
        $this->assertEquals($imsuser->lastname, $dbuser->lastname);
160
    }
161
 
11 efrain 162
    public function test_user_update_disabled(): void {
1 efrain 163
        global $DB;
164
 
165
        $this->imsplugin->set_config('imsupdateusers', false);
166
 
167
        $user = $this->getDataGenerator()->create_user(array('idnumber' => 'test-update-user'));
168
        $imsuser = new \stdClass();
169
        $imsuser->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_UPDATE;
170
        // THIS SHOULD WORK, surely?: $imsuser->username = $user->username;
171
        // But this is required...
172
        $imsuser->username = $user->idnumber;
173
        $imsuser->email = 'u3@u3.org';
174
        $imsuser->firstname = 'U';
175
        $imsuser->lastname = '3';
176
 
177
        $this->set_xml_file(array($imsuser));
178
        $this->imsplugin->cron();
179
 
180
        // Verify no changes have been made.
181
        $dbuser = $DB->get_record('user', array('id' => $user->id), '*', MUST_EXIST);
182
        $this->assertEquals($user->email, $dbuser->email);
183
        $this->assertEquals($user->firstname, $dbuser->firstname);
184
        $this->assertEquals($user->lastname, $dbuser->lastname);
185
    }
186
 
187
    /**
188
     * Delete user
189
     */
11 efrain 190
    public function test_user_delete(): void {
1 efrain 191
        global $DB;
192
 
193
        $this->imsplugin->set_config('imsdeleteusers', true);
194
        $user = $this->getDataGenerator()->create_user(array('idnumber' => 'test-update-user'));
195
 
196
        $imsuser = new \stdClass();
197
        $imsuser->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_DELETE;
198
        $imsuser->username = $user->username;
199
        $imsuser->firstname = $user->firstname;
200
        $imsuser->lastname = $user->lastname;
201
        $imsuser->email = $user->email;
202
        $this->set_xml_file(array($imsuser));
203
 
204
        $this->imsplugin->cron();
205
        $this->assertEquals(1, $DB->get_field('user', 'deleted', array('id' => $user->id), MUST_EXIST));
206
    }
207
 
208
    /**
209
     * Delete user disabled
210
     */
11 efrain 211
    public function test_user_delete_disabled(): void {
1 efrain 212
        global $DB;
213
 
214
        $this->imsplugin->set_config('imsdeleteusers', false);
215
        $user = $this->getDataGenerator()->create_user(array('idnumber' => 'test-update-user'));
216
 
217
        $imsuser = new \stdClass();
218
        $imsuser->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_DELETE;
219
        $imsuser->username = $user->username;
220
        $imsuser->firstname = $user->firstname;
221
        $imsuser->lastname = $user->lastname;
222
        $imsuser->email = $user->email;
223
        $this->set_xml_file(array($imsuser));
224
 
225
        $this->imsplugin->cron();
226
        $this->assertEquals(0, $DB->get_field('user', 'deleted', array('id' => $user->id), MUST_EXIST));
227
    }
228
 
229
    /**
230
     * Existing courses are not created again
231
     */
11 efrain 232
    public function test_courses_existing(): void {
1 efrain 233
        global $DB;
234
 
235
        $course1 = $this->getDataGenerator()->create_course(array('idnumber' => 'id1'));
236
        $course2 = $this->getDataGenerator()->create_course(array('idnumber' => 'id2'));
237
 
238
        // Default mapping according to default course attributes - IMS description tags mapping.
239
        $course1->imsshort = $course1->fullname;
240
        $course2->imsshort = $course2->fullname;
241
        unset($course1->category);
242
        unset($course2->category);
243
 
244
        $prevncourses = $DB->count_records('course');
245
 
246
        $courses = array($course1, $course2);
247
        $this->set_xml_file(false, $courses);
248
        $this->imsplugin->cron();
249
 
250
        $this->assertEquals($prevncourses, $DB->count_records('course'));
251
    }
252
 
253
    /**
254
     * Add new courses
255
     */
11 efrain 256
    public function test_courses_add(): void {
1 efrain 257
        global $DB;
258
 
259
        $prevncourses = $DB->count_records('course');
260
 
261
        $course1 = new \stdClass();
262
        $course1->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
263
        $course1->idnumber = 'id1';
264
        $course1->imsshort = 'id1';
265
        $course1->category[] = 'DEFAULT CATNAME';
266
 
267
        $course2 = new \stdClass();
268
        $course2->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
269
        $course2->idnumber = 'id2';
270
        $course2->imsshort = 'id2';
271
        $course2->category[] = 'DEFAULT CATNAME';
272
 
273
        $courses = array($course1, $course2);
274
        $this->set_xml_file(false, $courses);
275
        $this->imsplugin->cron();
276
 
277
        $this->assertEquals(($prevncourses + 2), $DB->count_records('course'));
278
        $this->assertTrue($DB->record_exists('course', array('idnumber' => $course1->idnumber)));
279
        $this->assertTrue($DB->record_exists('course', array('idnumber' => $course2->idnumber)));
280
    }
281
 
282
    /**
283
     * Verify that courses are not created when createnewcourses
284
     * option is diabled.
285
     */
11 efrain 286
    public function test_courses_add_createnewcourses_disabled(): void {
1 efrain 287
        global $DB;
288
 
289
        $this->imsplugin->set_config('createnewcourses', false);
290
        $prevncourses = $DB->count_records('course');
291
 
292
        $course1 = new \stdClass();
293
        $course1->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
294
        $course1->idnumber = 'id1';
295
        $course1->imsshort = 'id1';
296
        $course1->category[] = 'DEFAULT CATNAME';
297
 
298
        $course2 = new \stdClass();
299
        $course2->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
300
        $course2->idnumber = 'id2';
301
        $course2->imsshort = 'id2';
302
        $course2->category[] = 'DEFAULT CATNAME';
303
 
304
        $courses = array($course1, $course2);
305
        $this->set_xml_file(false, $courses);
306
        $this->imsplugin->cron();
307
 
308
        $courses = array($course1, $course2);
309
        $this->set_xml_file(false, $courses);
310
        $this->imsplugin->cron();
311
 
312
        // Verify the courses have not ben creased.
313
        $this->assertEquals($prevncourses , $DB->count_records('course'));
314
        $this->assertFalse($DB->record_exists('course', array('idnumber' => $course1->idnumber)));
315
        $this->assertFalse($DB->record_exists('course', array('idnumber' => $course2->idnumber)));
316
    }
317
 
318
    /**
319
     * Test adding a course with no idnumber.
320
     */
11 efrain 321
    public function test_courses_no_idnumber(): void {
1 efrain 322
        global $DB;
323
 
324
        $prevncourses = $DB->count_records('course');
325
 
326
        $course1 = new \stdClass();
327
        $course1->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
328
        $course1->idnumber = '';
329
        $course1->imsshort = 'id1';
330
        $course1->category[] = 'DEFAULT CATNAME';
331
 
332
        $this->set_xml_file(false, array($course1));
333
        $this->imsplugin->cron();
334
 
335
        // Verify no action.
336
        $this->assertEquals($prevncourses, $DB->count_records('course'));
337
    }
338
 
339
    /**
340
     * Add new course with the truncateidnumber setting.
341
     */
11 efrain 342
    public function test_courses_add_truncate_idnumber(): void {
1 efrain 343
        global $DB;
344
 
345
        $truncatelength = 4;
346
 
347
        $this->imsplugin->set_config('truncatecoursecodes', $truncatelength);
348
        $prevncourses = $DB->count_records('course');
349
 
350
        $course1 = new \stdClass();
351
        $course1->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
352
        $course1->idnumber = '123456789';
353
        $course1->imsshort = 'id1';
354
        $course1->category[] = 'DEFAULT CATNAME';
355
 
356
        $this->set_xml_file(false, array($course1));
357
        $this->imsplugin->cron();
358
 
359
        // Verify the new course has been added.
360
        $this->assertEquals(($prevncourses + 1), $DB->count_records('course'));
361
 
362
        $truncatedidnumber = substr($course1->idnumber, 0, $truncatelength);
363
 
364
        $this->assertTrue($DB->record_exists('course', array('idnumber' => $truncatedidnumber)));
365
    }
366
 
367
    /**
368
     * Add new course without a category.
369
     */
11 efrain 370
    public function test_course_add_default_category(): void {
1 efrain 371
        global $DB;
372
 
373
        $this->imsplugin->set_config('createnewcategories', false);
374
 
375
        // Delete the default category, to ensure the plugin handles this gracefully.
376
        $defaultcat = \core_course_category::get_default();
377
        $defaultcat->delete_full(false);
378
 
379
        // Create an course with the IMS plugin without a category.
380
        $course1 = new \stdClass();
381
        $course1->idnumber = 'id1';
382
        $course1->imsshort = 'id1';
383
        $course1->category[] = '';
384
        $this->set_xml_file(false, array($course1));
385
        $this->imsplugin->cron();
386
 
387
        // Check the course has been created.
388
        $dbcourse = $DB->get_record('course', array('idnumber' => $course1->idnumber), '*', MUST_EXIST);
389
        // Check that it belongs to a category which exists.
390
        $this->assertTrue($DB->record_exists('course_categories', array('id' => $dbcourse->category)));
391
    }
392
 
393
    /**
394
     * Course attributes mapping to IMS enterprise group description tags
395
     */
11 efrain 396
    public function test_courses_attrmapping(): void {
1 efrain 397
        global $DB;
398
 
399
        // Setting a all = coursecode (idnumber) mapping.
400
        $this->imsplugin->set_config('imscoursemapshortname', 'coursecode');
401
        $this->imsplugin->set_config('imscoursemapfullname', 'coursecode');
402
        $this->imsplugin->set_config('imscoursemapsummary', 'coursecode');
403
 
404
        $course1 = new \stdClass();
405
        $course1->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
406
        $course1->idnumber = 'id1';
407
        $course1->imsshort = 'description_short1';
408
        $course1->imslong = 'description_long';
409
        $course1->imsfull = 'description_full';
410
        $course1->category[] = 'DEFAULT CATNAME';
411
 
412
        $this->set_xml_file(false, array($course1));
413
        $this->imsplugin->cron();
414
 
415
        $dbcourse = $DB->get_record('course', array('idnumber' => $course1->idnumber));
416
        $this->assertFalse(!$dbcourse);
417
        $this->assertEquals($dbcourse->shortname, $course1->idnumber);
418
        $this->assertEquals($dbcourse->fullname, $course1->idnumber);
419
        $this->assertEquals($dbcourse->summary, $course1->idnumber);
420
 
421
        // Setting a mapping using all the description tags.
422
        $this->imsplugin->set_config('imscoursemapshortname', 'short');
423
        $this->imsplugin->set_config('imscoursemapfullname', 'long');
424
        $this->imsplugin->set_config('imscoursemapsummary', 'full');
425
 
426
        $course2 = new \stdClass();
427
        $course2->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
428
        $course2->idnumber = 'id2';
429
        $course2->imsshort = 'description_short2';
430
        $course2->imslong = 'description_long';
431
        $course2->imsfull = 'description_full';
432
        $course2->category[] = 'DEFAULT CATNAME';
433
 
434
        $this->set_xml_file(false, array($course2));
435
        $this->imsplugin->cron();
436
 
437
        $dbcourse = $DB->get_record('course', array('idnumber' => $course2->idnumber));
438
        $this->assertFalse(!$dbcourse);
439
        $this->assertEquals($dbcourse->shortname, $course2->imsshort);
440
        $this->assertEquals($dbcourse->fullname, $course2->imslong);
441
        $this->assertEquals($dbcourse->summary, $course2->imsfull);
442
 
443
        // Setting a mapping where the specified description tags doesn't exist in the XML file (must delegate into idnumber).
444
        $this->imsplugin->set_config('imscoursemapshortname', 'short');
445
        $this->imsplugin->set_config('imscoursemapfullname', 'long');
446
        $this->imsplugin->set_config('imscoursemapsummary', 'full');
447
 
448
        $course3 = new \stdClass();
449
        $course3->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
450
        $course3->idnumber = 'id3';
451
        $course3->imsshort = 'description_short3';
452
        $course3->category[] = 'DEFAULT CATNAME';
453
 
454
        $this->set_xml_file(false, array($course3));
455
        $this->imsplugin->cron();
456
 
457
        $dbcourse = $DB->get_record('course', array('idnumber' => $course3->idnumber));
458
        $this->assertFalse(!$dbcourse);
459
        $this->assertEquals($dbcourse->shortname, $course3->imsshort);
460
        $this->assertEquals($dbcourse->fullname, $course3->idnumber);
461
        $this->assertEquals($dbcourse->summary, $course3->idnumber);
462
 
463
    }
464
 
465
    /**
466
     * Course updates
467
     */
11 efrain 468
    public function test_course_update(): void {
1 efrain 469
        global $DB;
470
 
471
        $course4 = new \stdClass();
472
        $course4->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
473
        $course4->idnumber = 'id4';
474
        $course4->imsshort = 'id4';
475
        $course4->imsfull = 'id4';
476
        $course4->category[] = 'DEFAULT CATNAME';
477
 
478
        $this->set_xml_file(false, array($course4));
479
        $this->imsplugin->cron();
480
 
481
        $course4u = $DB->get_record('course', array('idnumber' => $course4->idnumber));
482
 
483
        $course4u->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_UPDATE;
484
        $course4u->imsshort = 'description_short_updated';
485
        $course4u->imsfull = 'description_full_updated';
486
        unset($course4u->category);
487
 
488
        $this->set_xml_file(false, array($course4u));
489
        $this->imsplugin->cron();
490
 
491
        $dbcourse = $DB->get_record('course', array('idnumber' => $course4->idnumber));
492
        $this->assertFalse(!$dbcourse);
493
        $this->assertEquals($dbcourse->shortname, $course4u->imsshort);
494
        $this->assertEquals($dbcourse->fullname, $course4u->imsfull);
495
    }
496
 
497
    /**
498
     * Course delete. Make it hidden.
499
     */
11 efrain 500
    public function test_course_delete(): void {
1 efrain 501
        global $DB;
502
 
503
        $course8 = new \stdClass();
504
        $course8->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
505
        $course8->idnumber = 'id8';
506
        $course8->imsshort = 'id8';
507
        $course8->imsfull = 'id8';
508
        $course8->category[] = 'DEFAULT CATNAME';
509
 
510
        $this->set_xml_file(false, array($course8));
511
        $this->imsplugin->cron();
512
 
513
        $course8d = $DB->get_record('course', array('idnumber' => $course8->idnumber));
514
        $this->assertEquals($course8d->visible, 1);
515
 
516
        $course8d->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_DELETE;
517
        unset($course8d->category);
518
 
519
        $this->set_xml_file(false, array($course8d));
520
        $this->imsplugin->cron();
521
 
522
        $dbcourse = $DB->get_record('course', array('idnumber' => $course8d->idnumber));
523
        $this->assertFalse(!$dbcourse);
524
        $this->assertEquals($dbcourse->visible, 0);
525
    }
526
 
527
 
528
    /**
529
     * Nested categories with name during course creation
530
     */
11 efrain 531
    public function test_nested_categories(): void {
1 efrain 532
        global $DB;
533
 
534
        $this->imsplugin->set_config('nestedcategories', true);
535
 
536
        $topcat = 'DEFAULT CATNAME';
537
        $subcat = 'DEFAULT SUB CATNAME';
538
 
539
        $course5 = new \stdClass();
540
        $course5->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
541
        $course5->idnumber = 'id5';
542
        $course5->imsshort = 'description_short';
543
        $course5->imslong = 'description_long';
544
        $course5->imsfull = 'description_full';
545
        $course5->category = array();
546
        $course5->category[] = $topcat;
547
        $course5->category[] = $subcat;
548
 
549
        $this->set_xml_file(false, array($course5));
550
        $this->imsplugin->cron();
551
 
552
        $parentcatid = $DB->get_field('course_categories', 'id', array('name' => $topcat));
553
        $subcatid = $DB->get_field('course_categories', 'id', array('name' => $subcat, 'parent' => $parentcatid));
554
 
555
        $this->assertTrue(isset($subcatid));
556
        $this->assertTrue($subcatid > 0);
557
 
558
        $topcat = 'DEFAULT CATNAME';
559
        $subcat = 'DEFAULT SUB CATNAME TEST2';
560
 
561
        $course6 = new \stdClass();
562
        $course6->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
563
        $course6->idnumber = 'id6';
564
        $course6->imsshort = 'description_short';
565
        $course6->imslong = 'description_long';
566
        $course6->imsfull = 'description_full';
567
        $course6->category = array();
568
        $course6->category[] = $topcat;
569
        $course6->category[] = $subcat;
570
 
571
        $this->set_xml_file(false, array($course6));
572
        $this->imsplugin->cron();
573
 
574
        $parentcatid = $DB->get_field('course_categories', 'id', array('name' => $topcat));
575
        $subcatid = $DB->get_field('course_categories', 'id', array('name' => $subcat, 'parent' => $parentcatid));
576
 
577
        $this->assertTrue(isset($subcatid));
578
        $this->assertTrue($subcatid > 0);
579
    }
580
 
581
 
582
    /**
583
     * Test that duplicate nested categories with name are not created
584
     */
11 efrain 585
    public function test_nested_categories_for_dups(): void {
1 efrain 586
        global $DB;
587
 
588
        $this->imsplugin->set_config('nestedcategories', true);
589
 
590
        $topcat = 'DEFAULT CATNAME';
591
        $subcat = 'DEFAULT SUB CATNAME DUPTEST';
592
 
593
        $course7 = new \stdClass();
594
        $course7->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
595
        $course7->idnumber = 'id7';
596
        $course7->imsshort = 'description_short';
597
        $course7->imslong = 'description_long';
598
        $course7->imsfull = 'description_full';
599
        $course7->category[] = $topcat;
600
        $course7->category[] = $subcat;
601
 
602
        $this->set_xml_file(false, array($course7));
603
        $this->imsplugin->cron();
604
 
605
        $prevncategories = $DB->count_records('course_categories');
606
 
607
        $course8 = new \stdClass();
608
        $course8->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
609
        $course8->idnumber = 'id8';
610
        $course8->imsshort = 'description_short';
611
        $course8->imslong = 'description_long';
612
        $course8->imsfull = 'description_full';
613
        $course8->category[] = $topcat;
614
        $course8->category[] = $subcat;
615
 
616
        $this->set_xml_file(false, array($course8));
617
        $this->imsplugin->cron();
618
 
619
        $this->assertEquals($prevncategories, $DB->count_records('course_categories'));
620
    }
621
 
622
    /**
623
     * Nested categories with idnumber during course creation
624
     */
11 efrain 625
    public function test_nested_categories_idnumber(): void {
1 efrain 626
        global $DB;
627
 
628
        $this->imsplugin->set_config('nestedcategories', true);
629
        $this->imsplugin->set_config('categoryidnumber', true);
630
        $this->imsplugin->set_config('categoryseparator', '|');
631
 
632
        $catsep = trim($this->imsplugin->get_config('categoryseparator'));
633
 
634
        $topcatname = 'DEFAULT CATNAME';
635
        $subcatname = 'DEFAULT SUB CATNAME';
636
        $topcatidnumber = '01';
637
        $subcatidnumber = '0101';
638
 
639
        $topcat = $topcatname.$catsep.$topcatidnumber;
640
        $subcat = $subcatname.$catsep.$subcatidnumber;
641
 
642
        $course1 = new \stdClass();
643
        $course1->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
644
        $course1->idnumber = 'id5';
645
        $course1->imsshort = 'description_short';
646
        $course1->imslong = 'description_long';
647
        $course1->imsfull = 'description_full';
648
        $course1->category[] = $topcat;
649
        $course1->category[] = $subcat;
650
 
651
        $this->set_xml_file(false, array($course1));
652
        $this->imsplugin->cron();
653
 
654
        $parentcatid = $DB->get_field('course_categories', 'id', array('idnumber' => $topcatidnumber));
655
        $subcatid = $DB->get_field('course_categories', 'id', array('idnumber' => $subcatidnumber, 'parent' => $parentcatid));
656
 
657
        $this->assertTrue(isset($subcatid));
658
        $this->assertTrue($subcatid > 0);
659
 
660
        // Change the category separator character.
661
        $this->imsplugin->set_config('categoryseparator', ':');
662
 
663
        $catsep = trim($this->imsplugin->get_config('categoryseparator'));
664
 
665
        $topcatname = 'DEFAULT CATNAME';
666
        $subcatname = 'DEFAULT SUB CATNAME TEST2';
667
        $topcatidnumber = '01';
668
        $subcatidnumber = '0102';
669
 
670
        $topcat = $topcatname.$catsep.$topcatidnumber;
671
        $subcat = $subcatname.$catsep.$subcatidnumber;
672
 
673
        $course2 = new \stdClass();
674
        $course2->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
675
        $course2->idnumber = 'id6';
676
        $course2->imsshort = 'description_short';
677
        $course2->imslong = 'description_long';
678
        $course2->imsfull = 'description_full';
679
        $course2->category[] = $topcat;
680
        $course2->category[] = $subcat;
681
 
682
        $this->set_xml_file(false, array($course2));
683
        $this->imsplugin->cron();
684
 
685
        $parentcatid = $DB->get_field('course_categories', 'id', array('idnumber' => $topcatidnumber));
686
        $subcatid = $DB->get_field('course_categories', 'id', array('idnumber' => $subcatidnumber, 'parent' => $parentcatid));
687
 
688
        $this->assertTrue(isset($subcatid));
689
        $this->assertTrue($subcatid > 0);
690
    }
691
 
692
    /**
693
     * Test that duplicate nested categories with idnumber are not created
694
     */
11 efrain 695
    public function test_nested_categories_idnumber_for_dups(): void {
1 efrain 696
        global $DB;
697
 
698
        $this->imsplugin->set_config('nestedcategories', true);
699
        $this->imsplugin->set_config('categoryidnumber', true);
700
        $this->imsplugin->set_config('categoryseparator', '|');
701
 
702
        $catsep = trim($this->imsplugin->get_config('categoryseparator'));
703
 
704
        $topcatname = 'DEFAULT CATNAME';
705
        $subcatname = 'DEFAULT SUB CATNAME';
706
        $topcatidnumber = '01';
707
        $subcatidnumber = '0101';
708
 
709
        $topcat = $topcatname.$catsep.$topcatidnumber;
710
        $subcat = $subcatname.$catsep.$subcatidnumber;
711
 
712
        $course1 = new \stdClass();
713
        $course1->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
714
        $course1->idnumber = 'id1';
715
        $course1->imsshort = 'description_short';
716
        $course1->imslong = 'description_long';
717
        $course1->imsfull = 'description_full';
718
        $course1->category[] = $topcat;
719
        $course1->category[] = $subcat;
720
 
721
        $this->set_xml_file(false, array($course1));
722
        $this->imsplugin->cron();
723
 
724
        $prevncategories = $DB->count_records('course_categories');
725
 
726
        $course2 = new \stdClass();
727
        $course2->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
728
        $course2->idnumber = 'id2';
729
        $course2->imsshort = 'description_short';
730
        $course2->imslong = 'description_long';
731
        $course2->imsfull = 'description_full';
732
        $course2->category[] = $topcat;
733
        $course2->category[] = $subcat;
734
 
735
        $this->set_xml_file(false, array($course2));
736
        $this->imsplugin->cron();
737
 
738
        $this->assertEquals($prevncategories, $DB->count_records('course_categories'));
739
    }
740
 
741
    /**
742
     * Test that nested categories with idnumber is not created if name is missing
743
     */
11 efrain 744
    public function test_categories_idnumber_missing_name(): void {
1 efrain 745
        global $DB, $CFG;
746
 
747
        $this->imsplugin->set_config('nestedcategories', true);
748
        $this->imsplugin->set_config('categoryidnumber', true);
749
        $this->imsplugin->set_config('categoryseparator', '|');
750
        $catsep = trim($this->imsplugin->get_config('categoryseparator'));
751
 
752
        $topcatname = 'DEFAULT CATNAME';
753
        $subcatname = '';
754
        $topcatidnumber = '01';
755
        $subcatidnumber = '0101';
756
 
757
        $topcat = $topcatname.$catsep.$topcatidnumber;
758
        $subcat = $subcatname.$catsep.$subcatidnumber;
759
 
760
        $course1 = new \stdClass();
761
        $course1->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
762
        $course1->idnumber = 'id1';
763
        $course1->imsshort = 'description_short';
764
        $course1->imslong = 'description_long';
765
        $course1->imsfull = 'description_full';
766
        $course1->category[] = $topcat;
767
        $course1->category[] = $subcat;
768
 
769
        $this->set_xml_file(false, array($course1));
770
        $this->imsplugin->cron();
771
 
772
        // Check all categories except the last subcategory was created.
773
        $parentcatid = $DB->get_field('course_categories', 'id', array('idnumber' => $topcatidnumber));
774
        $this->assertTrue((boolean)$parentcatid);
775
        $subcatid = $DB->get_field('course_categories', 'id', array('idnumber' => $subcatidnumber, 'parent' => $parentcatid));
776
        $this->assertFalse((boolean)$subcatid);
777
 
778
        // Check course was put in default category.
779
        $defaultcat = \core_course_category::get_default();
780
        $dbcourse = $DB->get_record('course', array('idnumber' => $course1->idnumber), '*', MUST_EXIST);
781
        $this->assertEquals($dbcourse->category, $defaultcat->id);
782
 
783
    }
784
 
785
    /**
786
     * Create category with name (nested categories not activated).
787
     */
11 efrain 788
    public function test_create_category_name_no_nested(): void {
1 efrain 789
        global $DB;
790
 
791
        $course = new \stdClass();
792
        $course->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
793
        $course->idnumber = 'id';
794
        $course->imsshort = 'description_short';
795
        $course->imslong = 'description_long';
796
        $course->imsfull = 'description_full';
797
        $course->category[] = 'CATNAME';
798
 
799
        $this->set_xml_file(false, array($course));
800
        $this->imsplugin->cron();
801
 
802
        $dbcat = $DB->get_record('course_categories', array('name' => $course->category[0]));
803
        $this->assertFalse(!$dbcat);
804
        $this->assertEquals($dbcat->parent, 0);
805
 
806
        $dbcourse = $DB->get_record('course', array('idnumber' => $course->idnumber));
807
        $this->assertFalse(!$dbcourse);
808
        $this->assertEquals($dbcourse->category, $dbcat->id);
809
 
810
    }
811
 
812
    /**
813
     * Find a category with name (nested categories not activated).
814
     */
11 efrain 815
    public function test_find_category_name_no_nested(): void {
1 efrain 816
        global $DB;
817
 
818
        $cattop = $this->getDataGenerator()->create_category(array('name' => 'CAT-TOP'));
819
        $catsub = $this->getDataGenerator()->create_category(array('name' => 'CAT-SUB', 'parent' => $cattop->id));
820
        $prevcats = $DB->count_records('course_categories');
821
 
822
        $course = new \stdClass();
823
        $course->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
824
        $course->idnumber = 'id';
825
        $course->imsshort = 'description_short';
826
        $course->imslong = 'description_long';
827
        $course->imsfull = 'description_full';
828
        $course->category[] = 'CAT-SUB';
829
 
830
        $this->set_xml_file(false, array($course));
831
        $this->imsplugin->cron();
832
 
833
        $newcats = $DB->count_records('course_categories');
834
 
835
        // Check that no new category was not created.
836
        $this->assertEquals($prevcats, $newcats);
837
 
838
        // Check course is associated to CAT-SUB.
839
        $dbcourse = $DB->get_record('course', array('idnumber' => $course->idnumber));
840
        $this->assertFalse(!$dbcourse);
841
        $this->assertEquals($dbcourse->category, $catsub->id);
842
 
843
    }
844
 
845
    /**
846
     * Create category with idnumber (nested categories not activated).
847
     */
11 efrain 848
    public function test_create_category_idnumber_no_nested(): void {
1 efrain 849
        global $DB;
850
 
851
        $this->imsplugin->set_config('categoryidnumber', true);
852
        $this->imsplugin->set_config('categoryseparator', '|');
853
        $catsep = trim($this->imsplugin->get_config('categoryseparator'));
854
 
855
        $course = new \stdClass();
856
        $course->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
857
        $course->idnumber = 'id';
858
        $course->imsshort = 'description_short';
859
        $course->imslong = 'description_long';
860
        $course->imsfull = 'description_full';
861
        $course->category[] = 'CATNAME'. $catsep .  'CATIDNUMBER';
862
 
863
        $this->set_xml_file(false, array($course));
864
        $this->imsplugin->cron();
865
 
866
        $dbcat = $DB->get_record('course_categories', array('idnumber' => 'CATIDNUMBER'));
867
        $this->assertFalse(!$dbcat);
868
        $this->assertEquals($dbcat->parent, 0);
869
        $this->assertEquals($dbcat->name, 'CATNAME');
870
 
871
        $dbcourse = $DB->get_record('course', array('idnumber' => $course->idnumber));
872
        $this->assertFalse(!$dbcourse);
873
        $this->assertEquals($dbcourse->category, $dbcat->id);
874
 
875
    }
876
 
877
    /**
878
     * Find a category with idnumber (nested categories not activated).
879
     */
11 efrain 880
    public function test_find_category_idnumber_no_nested(): void {
1 efrain 881
        global $DB;
882
 
883
        $this->imsplugin->set_config('categoryidnumber', true);
884
        $this->imsplugin->set_config('categoryseparator', '|');
885
        $catsep = trim($this->imsplugin->get_config('categoryseparator'));
886
 
887
        $topcatname = 'CAT-TOP';
888
        $subcatname = 'CAT-SUB';
889
        $topcatidnumber = 'ID-TOP';
890
        $subcatidnumber = 'ID-SUB';
891
 
892
        $cattop = $this->getDataGenerator()->create_category(array('name' => $topcatname, 'idnumber' => $topcatidnumber));
893
        $catsub = $this->getDataGenerator()->create_category(array('name' => $subcatname, 'idnumber' => $subcatidnumber,
894
                'parent' => $cattop->id));
895
        $prevcats = $DB->count_records('course_categories');
896
 
897
        $course = new \stdClass();
898
        $course->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
899
        $course->idnumber = 'id';
900
        $course->imsshort = 'description_short';
901
        $course->imslong = 'description_long';
902
        $course->imsfull = 'description_full';
903
        $course->category[] = $subcatname . $catsep . $subcatidnumber;
904
 
905
        $this->set_xml_file(false, array($course));
906
        $this->imsplugin->cron();
907
 
908
        $newcats = $DB->count_records('course_categories');
909
 
910
        // Check that no new category was not created.
911
        $this->assertEquals($prevcats, $newcats);
912
 
913
        $dbcourse = $DB->get_record('course', array('idnumber' => $course->idnumber));
914
        $this->assertFalse(!$dbcourse);
915
        $this->assertEquals($dbcourse->category, $catsub->id);
916
 
917
    }
918
 
919
    /**
920
     * Test that category with idnumber is not created if name is missing (nested categories not activated).
921
     */
11 efrain 922
    public function test_category_idnumber_missing_name_no_nested(): void {
1 efrain 923
        global $DB;
924
 
925
        $this->imsplugin->set_config('categoryidnumber', true);
926
        $this->imsplugin->set_config('categoryseparator', '|');
927
        $catsep = trim($this->imsplugin->get_config('categoryseparator'));
928
 
929
        $catidnumber = '01';
930
 
931
        $course = new \stdClass();
932
        $course->recstatus = enrol_imsenterprise_plugin::IMSENTERPRISE_ADD;
933
        $course->idnumber = 'id1';
934
        $course->imsshort = 'description_short';
935
        $course->imslong = 'description_long';
936
        $course->imsfull = 'description_full';
937
        $course->category[] = '' . $catsep . $catidnumber;
938
 
939
        $this->set_xml_file(false, array($course));
940
        $this->imsplugin->cron();
941
 
942
        // Check category was not created.
943
        $catid = $DB->get_record('course_categories', array('idnumber' => $catidnumber));
944
        $this->assertFalse($catid);
945
 
946
        // Check course was put in default category.
947
        $defaultcat = \core_course_category::get_default();
948
        $dbcourse = $DB->get_record('course', array('idnumber' => $course->idnumber), '*', MUST_EXIST);
949
        $this->assertEquals($dbcourse->category, $defaultcat->id);
950
 
951
    }
952
 
953
    /**
954
     * Sets the plugin configuration for testing
955
     */
956
    public function set_test_config() {
957
        $this->imsplugin->set_config('mailadmins', false);
958
        $this->imsplugin->set_config('prev_path', '');
959
        $this->imsplugin->set_config('createnewusers', true);
960
        $this->imsplugin->set_config('imsupdateusers', true);
961
        $this->imsplugin->set_config('createnewcourses', true);
962
        $this->imsplugin->set_config('updatecourses', true);
963
        $this->imsplugin->set_config('createnewcategories', true);
964
        $this->imsplugin->set_config('categoryseparator', '');
965
        $this->imsplugin->set_config('categoryidnumber', false);
966
        $this->imsplugin->set_config('nestedcategories', false);
967
    }
968
 
969
    /**
970
     * Creates an IMS enterprise XML file and adds it's path to config settings.
971
     *
972
     * @param bool|array $users false or array of users stdClass
973
     * @param bool|array $courses false or of courses stdClass
974
     */
975
    public function set_xml_file($users = false, $courses = false) {
976
 
977
        $xmlcontent = '<enterprise>';
978
 
979
        // Users.
980
        if (!empty($users)) {
981
            foreach ($users as $user) {
982
                $xmlcontent .= '
983
  <person';
984
 
985
                // Optional recstatus (1=add, 2=update, 3=delete).
986
                if (!empty($user->recstatus)) {
987
                    $xmlcontent .= ' recstatus="'.$user->recstatus.'"';
988
                }
989
 
990
                $xmlcontent .= '>
991
    <sourcedid>
992
      <source>TestSource</source>
993
      <id>'.$user->username.'</id>
994
    </sourcedid>
995
    <userid';
996
 
997
                // Optional authentication type.
998
                if (!empty($user->auth)) {
999
                    $xmlcontent .= ' authenticationtype="'.$user->auth.'"';
1000
                }
1001
 
1002
                $xmlcontent .= '>'.$user->username.'</userid>
1003
    <name>
1004
      <fn>'.$user->firstname.' '.$user->lastname.'</fn>
1005
      <n>
1006
        <family>'.$user->lastname.'</family>
1007
        <given>'.$user->firstname.'</given>
1008
      </n>
1009
    </name>
1010
    <email>'.$user->email.'</email>
1011
  </person>';
1012
            }
1013
        }
1014
 
1015
        // Courses.
1016
        // Mapping based on default course attributes - IMS group tags mapping.
1017
        if (!empty($courses)) {
1018
            foreach ($courses as $course) {
1019
 
1020
                $xmlcontent .= '
1021
  <group';
1022
 
1023
                // Optional recstatus (1=add, 2=update, 3=delete).
1024
                if (!empty($course->recstatus)) {
1025
                    $xmlcontent .= ' recstatus="'.$course->recstatus.'"';
1026
                }
1027
 
1028
                $xmlcontent .= '>
1029
    <sourcedid>
1030
      <source>TestSource</source>
1031
      <id>'.$course->idnumber.'</id>
1032
    </sourcedid>
1033
    <description>';
1034
 
1035
                // Optional to test course attributes mappings.
1036
                if (!empty($course->imsshort)) {
1037
                    $xmlcontent .= '
1038
      <short>'.$course->imsshort.'</short>';
1039
                }
1040
 
1041
                // Optional to test course attributes mappings.
1042
                if (!empty($course->imslong)) {
1043
                    $xmlcontent .= '
1044
      <long>'.$course->imslong.'</long>';
1045
                }
1046
 
1047
                // Optional to test course attributes mappings.
1048
                if (!empty($course->imsfull)) {
1049
                    $xmlcontent .= '
1050
      <full>'.$course->imsfull.'</full>';
1051
                }
1052
 
1053
                // The orgunit tag value is used by moodle as category name.
1054
                $xmlcontent .= '
1055
    </description>
1056
    <org>';
1057
                // Optional category name.
1058
                if (isset($course->category) && !empty($course->category)) {
1059
                    foreach ($course->category as $category) {
1060
                        $xmlcontent .= '
1061
      <orgunit>'.$category.'</orgunit>';
1062
                    }
1063
                }
1064
 
1065
                $xmlcontent .= '
1066
    </org>
1067
  </group>';
1068
            }
1069
        }
1070
 
1071
        $xmlcontent .= '
1072
</enterprise>';
1073
 
1074
        // Creating the XML file.
1075
        $filename = 'ims_' . rand(1000, 9999) . '.xml';
1076
        $tmpdir = make_temp_directory('enrol_imsenterprise');
1077
        $xmlfilepath = $tmpdir . '/' . $filename;
1078
        file_put_contents($xmlfilepath, $xmlcontent);
1079
 
1080
        // Setting the file path in CFG.
1081
        $this->imsplugin->set_config('imsfilelocation', $xmlfilepath);
1082
    }
1083
 
1084
    /**
1085
     * IMS Enterprise enrolment task test.
1086
     */
11 efrain 1087
    public function test_imsenterprise_cron_task(): void {
1 efrain 1088
        global $DB;
1089
        $prevnusers = $DB->count_records('user');
1090
 
1091
        $user1 = new \stdClass();
1092
        $user1->username = 'u1';
1093
        $user1->email = 'u1@example.com';
1094
        $user1->firstname = 'U';
1095
        $user1->lastname = '1';
1096
 
1097
        $users = array($user1);
1098
        $this->set_xml_file($users);
1099
 
1100
        $task = new cron_task();
1101
        $task->execute();
1102
 
1103
        $this->assertEquals(($prevnusers + 1), $DB->count_records('user'));
1104
    }
1105
}