Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   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 core_course;
  18  
  19  use context_user;
  20  use context_course;
  21  use ReflectionMethod;
  22  use cache_definition;
  23  use core_course\cache\course_image;
  24  
  25  /**
  26   * Functional test for class course_image
  27   *
  28   * @package    core
  29   * @subpackage course
  30   * @author     Dmitrii Metelkin <dmitriim@catalyst-au.net>
  31   * @copyright  2021 Catalyst IT
  32   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  class course_image_cache_test extends \advanced_testcase {
  35  
  36      /**
  37       * Initial setup.
  38       */
  39      protected function setUp(): void {
  40          global $CFG;
  41  
  42          parent::setUp();
  43          $this->resetAfterTest();
  44          $this->setAdminUser();
  45  
  46          // Allow multiple overview files.
  47          $CFG->courseoverviewfileslimit = 3;
  48      }
  49  
  50      /**
  51       * Helper method to create a draft area for current user and fills it with fake files
  52       *
  53       * @param array $files array of files that need to be added to filearea, filename => filecontents
  54       * @return int draftid for the filearea
  55       */
  56      protected function fill_draft_area(array $files): int {
  57          global $USER;
  58  
  59          $draftid = file_get_unused_draft_itemid();
  60          foreach ($files as $filename => $filecontents) {
  61              // Add actual file there.
  62              $filerecord = [
  63                  'component' => 'user',
  64                  'filearea' => 'draft',
  65                  'contextid' => context_user::instance($USER->id)->id, 'itemid' => $draftid,
  66                  'filename' => $filename, 'filepath' => '/'
  67              ];
  68              $fs = get_file_storage();
  69              $fs->create_file_from_string($filerecord, $filecontents);
  70          }
  71          return $draftid;
  72      }
  73  
  74      /**
  75       * A helper method to generate expected file URL.
  76       *
  77       * @param \stdClass $course Course object.
  78       * @param string $filename File name.
  79       * @return string
  80       */
  81      protected function build_expected_course_image_url(\stdClass $course, string $filename): string {
  82          $contextid = context_course::instance($course->id)->id;
  83          return 'https://www.example.com/moodle/pluginfile.php/' . $contextid. '/course/overviewfiles/' . $filename;
  84      }
  85  
  86      /**
  87       * Test exception if try to get an image for non existing course.
  88       */
  89      public function test_getting_data_if_course_is_not_exist() {
  90          $this->expectException('dml_missing_record_exception');
  91          $this->expectExceptionMessageMatches("/Can't find data record in database table course./");
  92          $this->assertFalse(\cache::make('core', 'course_image')->get(999));
  93      }
  94  
  95      /**
  96       * Test get_image_url_from_overview_files when no summary files in the course.
  97       */
  98      public function test_get_image_url_from_overview_files_return_null_if_no_summary_files_in_the_course() {
  99          $method = new ReflectionMethod(course_image::class, 'get_image_url_from_overview_files');
 100          $cache = course_image::get_instance_for_cache(new cache_definition());
 101          $method->setAccessible(true);
 102  
 103          // Create course without files.
 104          $course = $this->getDataGenerator()->create_course();
 105          $this->assertNull($method->invokeArgs($cache, [$course]));
 106      }
 107  
 108      /**
 109       * Test get_image_url_from_overview_files when no summary images in the course.
 110       */
 111      public function test_get_image_url_from_overview_files_returns_null_if_no_summary_images_in_the_course() {
 112          $method = new ReflectionMethod(course_image::class, 'get_image_url_from_overview_files');
 113          $cache = course_image::get_instance_for_cache(new cache_definition());
 114          $method->setAccessible(true);
 115  
 116          // Create course without image files.
 117          $draftid2 = $this->fill_draft_area(['filename2.zip' => 'Test file contents2']);
 118          $course2 = $this->getDataGenerator()->create_course(['overviewfiles_filemanager' => $draftid2]);
 119          $this->assertNull($method->invokeArgs($cache, [$course2]));
 120      }
 121  
 122      /**
 123       * Test get_image_url_from_overview_files when no summary images in the course.
 124       */
 125      public function test_get_image_url_from_overview_files_returns_url_if_there_is_a_summary_image() {
 126          $method = new ReflectionMethod(course_image::class, 'get_image_url_from_overview_files');
 127          $cache = course_image::get_instance_for_cache(new cache_definition());
 128          $method->setAccessible(true);
 129  
 130          // Create course without one image.
 131          $draftid1 = $this->fill_draft_area(['filename1.jpg' => file_get_contents(__DIR__ . '/fixtures/image.jpg')]);
 132          $course1 = $this->getDataGenerator()->create_course(['overviewfiles_filemanager' => $draftid1]);
 133          $expected = $this->build_expected_course_image_url($course1, 'filename1.jpg');
 134          $this->assertEquals($expected, $method->invokeArgs($cache, [$course1]));
 135      }
 136  
 137      /**
 138       * Test get_image_url_from_overview_files when several summary images in the course.
 139       */
 140      public function test_get_image_url_from_overview_files_returns_url_of_the_first_image_if_there_are_many_summary_images() {
 141          $method = new ReflectionMethod(course_image::class, 'get_image_url_from_overview_files');
 142          $cache = course_image::get_instance_for_cache(new cache_definition());
 143          $method->setAccessible(true);
 144  
 145          // Create course with two image files.
 146          $draftid1 = $this->fill_draft_area([
 147              'filename1.jpg' => file_get_contents(__DIR__ . '/fixtures/image.jpg'),
 148              'filename2.jpg' => file_get_contents(__DIR__ . '/fixtures/image.jpg'),
 149          ]);
 150          $course1 = $this->getDataGenerator()->create_course(['overviewfiles_filemanager' => $draftid1]);
 151  
 152          $expected = $this->build_expected_course_image_url($course1, 'filename1.jpg');
 153          $this->assertEquals($expected, $method->invokeArgs($cache, [$course1]));
 154      }
 155  
 156      /**
 157       * Test get_image_url_from_overview_files when several summary files in the course.
 158       */
 159      public function test_get_image_url_from_overview_files_returns_url_of_the_first_image_if_there_are_many_summary_files() {
 160          $method = new ReflectionMethod(course_image::class, 'get_image_url_from_overview_files');
 161          $cache = course_image::get_instance_for_cache(new cache_definition());
 162          $method->setAccessible(true);
 163  
 164          // Create course with two image files and one zip file.
 165          $draftid1 = $this->fill_draft_area([
 166              'filename1.zip' => 'Test file contents2',
 167              'filename2.jpg' => file_get_contents(__DIR__ . '/fixtures/image.jpg'),
 168              'filename3.jpg' => file_get_contents(__DIR__ . '/fixtures/image.jpg'),
 169          ]);
 170          $course1 = $this->getDataGenerator()->create_course(['overviewfiles_filemanager' => $draftid1]);
 171  
 172          $expected = $this->build_expected_course_image_url($course1, 'filename2.jpg');
 173          $this->assertEquals($expected, $method->invokeArgs($cache, [$course1]));
 174      }
 175  
 176  }