Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 39 and 311]

   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   * Test for content bank contenttype class.
  19   *
  20   * @package    core_contentbank
  21   * @category   test
  22   * @copyright  2020 Amaia Anabitarte <amaia@moodle.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  namespace core_contentbank;
  27  
  28  use stdClass;
  29  use context_system;
  30  use contenttype_testable\contenttype as contenttype;
  31  
  32  /**
  33   * Test for content bank contenttype class.
  34   *
  35   * @package    core_contentbank
  36   * @category   test
  37   * @copyright  2020 Amaia Anabitarte <amaia@moodle.com>
  38   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   * @coversDefaultClass \core_contentbank\content
  40   *
  41   */
  42  class content_test extends \advanced_testcase {
  43  
  44      /**
  45       * Setup to ensure that fixtures are loaded.
  46       */
  47      public static function setupBeforeClass(): void {
  48          global $CFG;
  49  
  50          require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_contenttype.php');
  51          require_once($CFG->dirroot . '/contentbank/tests/fixtures/testable_content.php');
  52      }
  53  
  54      /**
  55       * Tests for behaviour of get_name().
  56       *
  57       * @covers ::get_name
  58       */
  59      public function test_get_name() {
  60          $this->resetAfterTest();
  61  
  62          // Create content.
  63          $record = new stdClass();
  64          $record->name = 'Test content';
  65          $record->configdata = '';
  66  
  67          $contenttype = new contenttype(context_system::instance());
  68          $content = $contenttype->create_content($record);
  69          $this->assertEquals($record->name, $content->get_name());
  70      }
  71  
  72      /**
  73       * Data provider for test_set_name.
  74       *
  75       * @return  array
  76       */
  77      public function set_name_provider() {
  78          return [
  79              'Standard name' => ['New name', 'New name'],
  80              'Name with digits' => ['Today is 17/04/2017', 'Today is 17/04/2017'],
  81              'Name with symbols' => ['Follow us: @moodle', 'Follow us: @moodle'],
  82              'Name with tags' => ['This is <b>bold</b>', 'This is bold'],
  83              'Long name' => [str_repeat('a', 100), str_repeat('a', 100)],
  84              'Too long name' => [str_repeat('a', 300), str_repeat('a', 255)],
  85              'Empty name' => ['', 'Old name'],
  86              'Blanks only' => ['  ', 'Old name'],
  87          ];
  88      }
  89  
  90      /**
  91       * Tests for 'set_name' behaviour.
  92       *
  93       * @dataProvider    set_name_provider
  94       * @param   string  $newname    The name to set
  95       * @param   string   $expected   The name result
  96       *
  97       * @covers ::set_name
  98       */
  99      public function test_set_name(string $newname, string $expected) {
 100          global $DB;
 101  
 102          $this->resetAfterTest();
 103          $this->setAdminUser();
 104  
 105          $oldname = "Old name";
 106          $context = context_system::instance();
 107  
 108          // Create content.
 109          $record = new stdClass();
 110          $record->name = $oldname;
 111  
 112          $contenttype = new contenttype($context);
 113          $content = $contenttype->create_content($record);
 114          $this->assertEquals($oldname, $content->get_name());
 115  
 116          $content->set_name($newname);
 117          $this->assertEquals($expected, $content->get_name());
 118  
 119          $record = $DB->get_record('contentbank_content', ['id' => $content->get_id()]);
 120          $this->assertEquals($expected, $record->name);
 121      }
 122  
 123      /**
 124       * Tests for behaviour of get_content_type().
 125       *
 126       * @covers ::get_content_type
 127       */
 128      public function test_get_content_type() {
 129          $this->resetAfterTest();
 130  
 131          // Create content.
 132          $record = new stdClass();
 133          $record->name = 'Test content';
 134          $record->configdata = '';
 135  
 136          $contenttype = new contenttype(context_system::instance());
 137          $content = $contenttype->create_content($record);
 138          $this->assertEquals('contenttype_testable', $content->get_content_type());
 139      }
 140  
 141      /**
 142       * Tests for 'configdata' behaviour.
 143       *
 144       * @covers ::set_configdata
 145       */
 146      public function test_configdata_changes() {
 147          $this->resetAfterTest();
 148  
 149          $configdata = "{img: 'icon.svg'}";
 150  
 151          // Create content.
 152          $record = new stdClass();
 153          $record->configdata = $configdata;
 154  
 155          $contenttype = new contenttype(context_system::instance());
 156          $content = $contenttype->create_content($record);
 157          $this->assertEquals($configdata, $content->get_configdata());
 158  
 159          $configdata = "{alt: 'Name'}";
 160          $content->set_configdata($configdata);
 161          $this->assertEquals($configdata, $content->get_configdata());
 162      }
 163  
 164      /**
 165       * Tests for 'set_contextid' behaviour.
 166       *
 167       * @covers ::set_contextid
 168       */
 169      public function test_set_contextid() {
 170          $this->resetAfterTest();
 171          $this->setAdminUser();
 172          $context = context_system::instance();
 173          $course = $this->getDataGenerator()->create_course();
 174          $newcontext = \context_course::instance($course->id);
 175  
 176          // Add some content to the content bank.
 177          $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
 178          $contents = $generator->generate_contentbank_data('contenttype_testable', 3, 0, $context);
 179          $content = reset($contents);
 180  
 181          $oldcontextid = $content->get_contextid();
 182  
 183          $file = $content->get_file();
 184          $this->assertEquals($oldcontextid, $file->get_contextid());
 185          $this->assertEquals($context->id, $oldcontextid);
 186          $this->assertNotEquals($newcontext->id, $oldcontextid);
 187  
 188          $content->set_contextid($newcontext->id);
 189          $file = $content->get_file();
 190  
 191          $this->assertEquals($newcontext->id, $content->get_contextid());
 192          $this->assertEquals($newcontext->id, $file->get_contextid());
 193      }
 194  
 195      /**
 196       * Tests for set_visibility behaviour
 197       *
 198       * @covers ::set_visibility
 199       */
 200      public function test_set_visibility() {
 201          $this->resetAfterTest();
 202          $this->setAdminUser();
 203          $context = context_system::instance();
 204          $oldvisibility = content::VISIBILITY_PUBLIC;
 205          $newvisibility = content::VISIBILITY_UNLISTED;
 206          $illegalvisibility = -1;
 207  
 208          $record = new stdClass();
 209          $record->visibility = $oldvisibility;
 210          $contenttype = new contenttype($context);
 211          $content = $contenttype->create_content($record);
 212  
 213          $this->assertEquals($oldvisibility, $content->get_visibility());
 214  
 215          $content->set_visibility($newvisibility);
 216  
 217          $this->assertEquals($newvisibility, $content->get_visibility());
 218  
 219          $content->set_visibility($illegalvisibility);
 220  
 221          $this->assertEquals($newvisibility, $content->get_visibility());
 222      }
 223  
 224      /**
 225       * Tests for 'import_file' behaviour when replacing a file.
 226       *
 227       * @covers ::import_file
 228       */
 229      public function test_import_file_replace(): void {
 230          global $USER;
 231          $this->resetAfterTest();
 232          $this->setAdminUser();
 233          $context = context_system::instance();
 234  
 235          // Add some content to the content bank.
 236          $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
 237          $contents = $generator->generate_contentbank_data('contenttype_testable', 3, 0, $context);
 238          $content = reset($contents);
 239  
 240          $originalfile = $content->get_file();
 241  
 242          // Create a dummy file.
 243          $filerecord = array(
 244              'contextid' => $context->id,
 245              'component' => 'contentbank',
 246              'filearea' => 'draft',
 247              'itemid' => $content->get_id(),
 248              'filepath' => '/',
 249              'filename' => 'example.txt'
 250          );
 251          $fs = get_file_storage();
 252          $file = $fs->create_file_from_string($filerecord, 'Dummy content ');
 253  
 254          $importedfile = $content->import_file($file);
 255  
 256          $this->assertEquals($originalfile->get_filename(), $importedfile->get_filename());
 257          $this->assertEquals($originalfile->get_filearea(), $importedfile->get_filearea());
 258          $this->assertEquals($originalfile->get_filepath(), $importedfile->get_filepath());
 259          $this->assertEquals($originalfile->get_mimetype(), $importedfile->get_mimetype());
 260  
 261          $this->assertEquals($file->get_userid(), $importedfile->get_userid());
 262          $this->assertEquals($file->get_contenthash(), $importedfile->get_contenthash());
 263      }
 264  
 265      /**
 266       * Tests for 'import_file' behaviour when uploading a new file.
 267       *
 268       * @covers ::import_file
 269       */
 270      public function test_import_file_upload(): void {
 271          global $USER;
 272          $this->resetAfterTest();
 273          $this->setAdminUser();
 274          $context = context_system::instance();
 275  
 276          $type = new contenttype($context);
 277          $record = (object)[
 278              'name' => 'content name',
 279              'usercreated' => $USER->id,
 280          ];
 281          $content = $type->create_content($record);
 282  
 283          // Create a dummy file.
 284          $filerecord = array(
 285              'contextid' => $context->id,
 286              'component' => 'contentbank',
 287              'filearea' => 'draft',
 288              'itemid' => $content->get_id(),
 289              'filepath' => '/',
 290              'filename' => 'example.txt'
 291          );
 292          $fs = get_file_storage();
 293          $file = $fs->create_file_from_string($filerecord, 'Dummy content ');
 294  
 295          $importedfile = $content->import_file($file);
 296  
 297          $this->assertEquals($file->get_filename(), $importedfile->get_filename());
 298          $this->assertEquals($file->get_userid(), $importedfile->get_userid());
 299          $this->assertEquals($file->get_mimetype(), $importedfile->get_mimetype());
 300          $this->assertEquals($file->get_contenthash(), $importedfile->get_contenthash());
 301          $this->assertEquals('public', $importedfile->get_filearea());
 302          $this->assertEquals('/', $importedfile->get_filepath());
 303  
 304          $contentfile = $content->get_file($file);
 305          $this->assertEquals($importedfile->get_id(), $contentfile->get_id());
 306      }
 307  
 308      /**
 309       * Tests for 'get_content_type_instance'
 310       *
 311       * @covers ::get_content_type_instance
 312       */
 313      public function test_get_content_type_instance(): void {
 314          global $USER;
 315          $this->resetAfterTest();
 316          $this->setAdminUser();
 317          $context = context_system::instance();
 318  
 319          $type = new contenttype($context);
 320          $record = (object)[
 321              'name' => 'content name',
 322              'usercreated' => $USER->id,
 323          ];
 324          $content = $type->create_content($record);
 325  
 326          $contenttype = $content->get_content_type_instance();
 327  
 328          $this->assertInstanceOf(get_class($type), $contenttype);
 329      }
 330  
 331      /**
 332       * Tests for 'is_view_allowed'.
 333       *
 334       * @covers ::is_view_allowed
 335       */
 336      public function test_is_view_allowed() {
 337          $this->resetAfterTest();
 338          $this->setAdminUser();
 339          $context = context_system::instance();
 340  
 341          $userauthor = $this->getDataGenerator()->create_user();
 342          $userother = $this->getDataGenerator()->create_user();
 343  
 344          $contenttype = new contenttype($context);
 345  
 346          $unlistedrecord = new stdClass();
 347          $unlistedrecord->visibility = content::VISIBILITY_UNLISTED;
 348          $unlistedrecord->usercreated = $userauthor->id;
 349          $unlistedcontent = $contenttype->create_content($unlistedrecord);
 350  
 351          $publicrecord = new stdClass();
 352          $publicrecord->visibility = content::VISIBILITY_PUBLIC;
 353          $publicrecord->usercreated = $userauthor->id;
 354          $publiccontent = $contenttype->create_content($publicrecord);
 355  
 356          $this->setUser($userother);
 357          $this->assertFalse($unlistedcontent->is_view_allowed());
 358          $this->assertTrue($publiccontent->is_view_allowed());
 359  
 360          $this->setUser($userauthor);
 361          $this->assertTrue($unlistedcontent->is_view_allowed());
 362          $this->assertTrue($publiccontent->is_view_allowed());
 363  
 364          $this->setAdminUser();
 365          $this->assertTrue($unlistedcontent->is_view_allowed());
 366          $this->assertTrue($publiccontent->is_view_allowed());
 367      }
 368  
 369      /**
 370       * Tests for 'get_uses' behaviour.
 371       *
 372       * @covers ::get_uses
 373       */
 374      public function test_get_uses() {
 375          $this->resetAfterTest();
 376          $this->setAdminUser();
 377          $context = context_system::instance();
 378  
 379          // Add some content to the content bank.
 380          $generator = $this->getDataGenerator()->get_plugin_generator('core_contentbank');
 381          $contents = $generator->generate_contentbank_data('contenttype_testable', 3, 0, $context);
 382          $content1 = array_shift($contents);
 383  
 384          // Check content has no references for now.
 385          $this->assertCount(0, $content1->get_uses());
 386  
 387          // Add a link to the previous content.
 388          $cbfile = $content1->get_file();
 389          $cbrecord = array(
 390              'contextid' => $cbfile->get_contextid(),
 391              'component' => $cbfile->get_component(),
 392              'filearea'  => $cbfile->get_filearea(),
 393              'itemid'    => $cbfile->get_itemid(),
 394              'filepath'  => $cbfile->get_filepath(),
 395              'filename'  => $cbfile->get_filename(),
 396          );
 397          $fs = get_file_storage();
 398          $ref = $fs->pack_reference($cbrecord);
 399  
 400          $aliasrecord = new stdClass();
 401          $aliasrecord->contextid = $context->id;
 402          $aliasrecord->component = 'core';
 403          $aliasrecord->filearea = 'phpunit';
 404          $aliasrecord->filepath = '/foo/';
 405          $aliasrecord->filename = 'one.txt';
 406          $aliasrecord->itemid = 0;
 407  
 408          $repos = \repository::get_instances(['type' => 'contentbank']);
 409          $cbrepo = reset($repos);
 410          $this->assertInstanceOf('repository', $cbrepo);
 411  
 412          $alias = $fs->create_file_from_reference($aliasrecord, $cbrepo->id, $ref);
 413  
 414          // Check content now has one reference (the previous alias).
 415          $contentuses1 = $content1->get_uses();
 416          $this->assertCount(1, $contentuses1);
 417          $reffile = reset($contentuses1);
 418          $this->assertEquals($alias, $reffile);
 419  
 420          // Check a different content hasn't any reference.
 421          $content2 = array_shift($contents);
 422          $this->assertCount(0, $content2->get_uses());
 423      }
 424  }