Merge branch 'MDL-63135-master' of git://github.com/rezaies/moodle
authorDavid Monllao <davidm@moodle.com>
Wed, 19 Sep 2018 11:12:40 +0000 (13:12 +0200)
committerDavid Monllao <davidm@moodle.com>
Wed, 19 Sep 2018 11:12:40 +0000 (13:12 +0200)
1  2 
mod/choice/tests/lib_test.php

@@@ -162,6 -162,47 +162,47 @@@ class mod_choice_lib_testcase extends e
          choice_user_submit_response($optionids2[0], $choice1, $USER->id, $course, $cm);
      }
  
+     /**
+      * Test choice_get_user_response
+      * @return void
+      */
+     public function test_choice_get_user_response() {
+         $this->resetAfterTest();
+         $this->setAdminUser();
+         // Setup test data.
+         $course = $this->getDataGenerator()->create_course();
+         $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id));
+         $cm = get_coursemodule_from_instance('choice', $choice->id);
+         $choicewithoptions = choice_get_choice($choice->id);
+         $optionids = array_keys($choicewithoptions->option);
+         choice_user_submit_response($optionids[0], $choice, $student->id, $course, $cm);
+         $responses = choice_get_user_response($choice, $student->id);
+         $this->assertCount(1, $responses);
+         $response = array_shift($responses);
+         $this->assertEquals($optionids[0], $response->optionid);
+         // Multiple responses.
+         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id, 'allowmultiple' => 1));
+         $cm = get_coursemodule_from_instance('choice', $choice->id);
+         $choicewithoptions = choice_get_choice($choice->id);
+         $optionids = array_keys($choicewithoptions->option);
+         // Submit a response with the options reversed.
+         $selections = $optionids;
+         rsort($selections);
+         choice_user_submit_response($selections, $choice, $student->id, $course, $cm);
+         $responses = choice_get_user_response($choice, $student->id);
+         $this->assertCount(count($optionids), $responses);
+         foreach ($responses as $resp) {
+             $this->assertEquals(array_shift($optionids), $resp->optionid);
+         }
+     }
      /**
       * Test choice_get_my_response
       * @return void
          $this->assertEquals('expired', array_keys($warnings)[0]);
      }
  
+     /*
+      * The choice's event should not be shown to a user when the user cannot view the choice activity at all.
+      */
+     public function test_choice_core_calendar_provide_event_action_in_hidden_section() {
+         global $CFG;
+         $this->resetAfterTest();
+         $this->setAdminUser();
+         // Create a course.
+         $course = $this->getDataGenerator()->create_course();
+         // Create a student.
+         $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+         // Create a choice.
+         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id,
+                 'timeopen' => time() - DAYSECS, 'timeclose' => time() + DAYSECS));
+         // Create a calendar event.
+         $event = $this->create_action_event($course->id, $choice->id, CHOICE_EVENT_TYPE_OPEN);
+         // Set sections 0 as hidden.
+         set_section_visible($course->id, 0, 0);
+         // Now, log out.
+         $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
+         $this->setUser();
+         // Create an action factory.
+         $factory = new \core_calendar\action_factory();
+         // Decorate action event for the student.
+         $actionevent = mod_choice_core_calendar_provide_event_action($event, $factory, $student->id);
+         // Confirm the event is not shown at all.
+         $this->assertNull($actionevent);
+     }
+     /*
+      * The choice's event should not be shown to a user who does not have permission to view the choice.
+      */
+     public function test_choice_core_calendar_provide_event_action_for_non_user() {
+         global $CFG;
+         $this->resetAfterTest();
+         $this->setAdminUser();
+         // Create a course.
+         $course = $this->getDataGenerator()->create_course();
+         // Create a choice.
+         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id,
+                 'timeopen' => time() - DAYSECS, 'timeclose' => time() + DAYSECS));
+         // Create a calendar event.
+         $event = $this->create_action_event($course->id, $choice->id, CHOICE_EVENT_TYPE_OPEN);
+         // Now, log out.
+         $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
+         $this->setUser();
+         // Create an action factory.
+         $factory = new \core_calendar\action_factory();
+         // Decorate action event.
+         $actionevent = mod_choice_core_calendar_provide_event_action($event, $factory);
+         // Confirm the event is not shown at all.
+         $this->assertNull($actionevent);
+     }
      public function test_choice_core_calendar_provide_event_action_open() {
          $this->resetAfterTest();
  
          $this->assertTrue($actionevent->is_actionable());
      }
  
+     public function test_choice_core_calendar_provide_event_action_open_for_user() {
+         $this->resetAfterTest();
+         $this->setAdminUser();
+         // Create a course.
+         $course = $this->getDataGenerator()->create_course();
+         // Create a student.
+         $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+         // Create a choice.
+         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id,
+             'timeopen' => time() - DAYSECS, 'timeclose' => time() + DAYSECS));
+         // Create a calendar event.
+         $event = $this->create_action_event($course->id, $choice->id, CHOICE_EVENT_TYPE_OPEN);
+         // Create an action factory.
+         $factory = new \core_calendar\action_factory();
+         // Decorate action event for the student.
+         $actionevent = mod_choice_core_calendar_provide_event_action($event, $factory, $student->id);
+         // Confirm the event was decorated.
+         $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
+         $this->assertEquals(get_string('viewchoices', 'choice'), $actionevent->get_name());
+         $this->assertInstanceOf('moodle_url', $actionevent->get_url());
+         $this->assertEquals(1, $actionevent->get_item_count());
+         $this->assertTrue($actionevent->is_actionable());
+     }
      /**
       * An event should not have an action if the user has already submitted a response
       * to the choice activity.
       */
      public function test_choice_core_calendar_provide_event_action_already_submitted() {
-         global $DB;
          $this->resetAfterTest();
  
          $this->setAdminUser();
  
          // Create a course.
          $course = $this->getDataGenerator()->create_course();
-         // Create user.
-         $student = $this->getDataGenerator()->create_user();
-         $studentrole = $DB->get_record('role', array('shortname' => 'student'));
-         $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id, 'manual');
+         // Create a student.
+         $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
  
          // Create a choice.
          $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id,
              'timeopen' => time() - DAYSECS, 'timeclose' => time() + DAYSECS));
-         $context = context_module::instance($choice->cmid);
          $cm = get_coursemodule_from_instance('choice', $choice->id);
  
          $choicewithoptions = choice_get_choice($choice->id);
          $this->assertNull($action);
      }
  
+     /**
+      * An event should not have an action if the user has already submitted a response
+      * to the choice activity.
+      */
+     public function test_choice_core_calendar_provide_event_action_already_submitted_for_user() {
+         $this->resetAfterTest();
+         $this->setAdminUser();
+         // Create a course.
+         $course = $this->getDataGenerator()->create_course();
+         // Create a student.
+         $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+         // Create a choice.
+         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id,
+             'timeopen' => time() - DAYSECS, 'timeclose' => time() + DAYSECS));
+         $cm = get_coursemodule_from_instance('choice', $choice->id);
+         $choicewithoptions = choice_get_choice($choice->id);
+         $optionids = array_keys($choicewithoptions->option);
+         choice_user_submit_response($optionids[0], $choice, $student->id, $course, $cm);
+         // Create a calendar event.
+         $event = $this->create_action_event($course->id, $choice->id, CHOICE_EVENT_TYPE_OPEN);
+         // Create an action factory.
+         $factory = new \core_calendar\action_factory();
+         // Decorate action event for the student.
+         $action = mod_choice_core_calendar_provide_event_action($event, $factory, $student->id);
+         // Confirm no action was returned if the user has already submitted the
+         // choice activity.
+         $this->assertNull($action);
+     }
      public function test_choice_core_calendar_provide_event_action_closed() {
          $this->resetAfterTest();
  
          $this->assertNull($action);
      }
  
+     public function test_choice_core_calendar_provide_event_action_closed_for_user() {
+         $this->resetAfterTest();
+         $this->setAdminUser();
+         // Create a course.
+         $course = $this->getDataGenerator()->create_course();
+         // Create a student.
+         $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+         $timeclose = time() - DAYSECS;
+         // Create a choice.
+         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id,
+             'timeclose' => $timeclose));
+         // Create a calendar event.
+         $event = $this->create_action_event($course->id, $choice->id, CHOICE_EVENT_TYPE_OPEN, $timeclose - 1);
+         // Create an action factory.
+         $factory = new \core_calendar\action_factory();
+         // Decorate action event for the student.
+         $action = mod_choice_core_calendar_provide_event_action($event, $factory, $student->id);
+         // Confirm not action was provided for a closed activity.
+         $this->assertNull($action);
+     }
      public function test_choice_core_calendar_provide_event_action_open_in_future() {
          $this->resetAfterTest();
  
          $this->assertFalse($actionevent->is_actionable());
      }
  
+     public function test_choice_core_calendar_provide_event_action_open_in_future_for_user() {
+         global $CFG;
+         $this->resetAfterTest();
+         $this->setAdminUser();
+         // Create a course.
+         $course = $this->getDataGenerator()->create_course();
+         // Create a student.
+         $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+         $timeopen = time() + DAYSECS;
+         $timeclose = $timeopen + DAYSECS;
+         // Create a choice.
+         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id,
+             'timeopen' => $timeopen, 'timeclose' => $timeclose));
+         // Create a calendar event.
+         $event = $this->create_action_event($course->id, $choice->id, CHOICE_EVENT_TYPE_OPEN, $timeopen);
+         // Now, log out.
+         $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
+         $this->setUser();
+         // Create an action factory.
+         $factory = new \core_calendar\action_factory();
+         // Decorate action event for the student.
+         $actionevent = mod_choice_core_calendar_provide_event_action($event, $factory, $student->id);
+         // Confirm the event was decorated.
+         $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
+         $this->assertEquals(get_string('viewchoices', 'choice'), $actionevent->get_name());
+         $this->assertInstanceOf('moodle_url', $actionevent->get_url());
+         $this->assertEquals(1, $actionevent->get_item_count());
+         $this->assertFalse($actionevent->is_actionable());
+     }
      public function test_choice_core_calendar_provide_event_action_no_time_specified() {
          $this->resetAfterTest();
  
          $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
          $this->assertEquals(get_string('viewchoices', 'choice'), $actionevent->get_name());
          $this->assertInstanceOf('moodle_url', $actionevent->get_url());
+         $this->assertEquals(1, $actionevent->get_item_count());
+         $this->assertTrue($actionevent->is_actionable());
+     }
+     public function test_choice_core_calendar_provide_event_action_no_time_specified_for_user() {
+         global $CFG;
+         $this->resetAfterTest();
+         $this->setAdminUser();
+         // Create a course.
+         $course = $this->getDataGenerator()->create_course();
+         // Create a student.
+         $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
+         // Create a choice.
+         $choice = $this->getDataGenerator()->create_module('choice', array('course' => $course->id));
+         // Create a calendar event.
+         $event = $this->create_action_event($course->id, $choice->id, CHOICE_EVENT_TYPE_OPEN);
+         // Now, log out.
+         $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
+         $this->setUser();
+         // Create an action factory.
+         $factory = new \core_calendar\action_factory();
+         // Decorate action event for the student.
+         $actionevent = mod_choice_core_calendar_provide_event_action($event, $factory, $student->id);
+         // Confirm the event was decorated.
+         $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
+         $this->assertEquals(get_string('viewchoices', 'choice'), $actionevent->get_name());
+         $this->assertInstanceOf('moodle_url', $actionevent->get_url());
          $this->assertEquals(1, $actionevent->get_item_count());
          $this->assertTrue($actionevent->is_actionable());
      }
          $this->expectException('moodle_exception');
          choice_user_submit_response($optionids[1], $choicewithoptions, $user2->id, $course, $cm);
      }
 +
 +    /**
 +     * A user who does not have capabilities to add events to the calendar should be able to create an choice.
 +     */
 +    public function test_creation_with_no_calendar_capabilities() {
 +        $this->resetAfterTest();
 +        $course = self::getDataGenerator()->create_course();
 +        $context = context_course::instance($course->id);
 +        $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher');
 +        $roleid = self::getDataGenerator()->create_role();
 +        self::getDataGenerator()->role_assign($roleid, $user->id, $context->id);
 +        assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true);
 +        $generator = self::getDataGenerator()->get_plugin_generator('mod_choice');
 +        // Create an instance as a user without the calendar capabilities.
 +        $this->setUser($user);
 +        $time = time();
 +        $params = array(
 +            'course' => $course->id,
 +            'timeopen' => $time + 200,
 +            'timeclose' => $time + 500,
 +        );
 +        $generator->create_instance($params);
 +    }
  }