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