<?php

require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'course') . '/tests/CourseTestCase.test';

/**
 * Tests for conditional event-based access to course objects.
 */
class CourseObjectAccessConditionalTestCase extends CourseTestCase {

  public static function getInfo() {
    // Note that getInfo() strings are not translated with t().
    return array(
      'name' => 'Course object conditional access',
      'description' => 'Ensure that the Course object conditional access plugin functions properly.',
      'group' => 'Course',
    );
  }

  /**
   * Test the time based trigger for object access.
   */
  function testTimeAfterStart() {
    global $user;
    $courseNode = $this->createCourseNode();
    $this->createCourseObject($courseNode);
    $this->createCourseObject($courseNode);
    $course = course_get_course($courseNode);

    // Set up a course object that should appear 5 minutes after the first
    // object is started.
    $co = $course->getObjects();
    $co1 = $co[0];
    $co2 = $co[1];

    $set = array();
    $set['plugins']['access']['conditional'] = array(
      'conditional_type' => 'started',
      'conditional_time' => 300,
      'conditional_object' => $co1->getId(),
      'conditional_hidden' => 0,
    );
    $hidden['plugins']['access']['conditional']['conditional_hidden'] = 1;
    $co2->addOptions($set);

    course_enroll($courseNode, $user);
    $this->assertTrue($co1->access('take'), 'Check that user can access first (depended on) object.');
    // Mark first object as complete.
    $co1->getFulfillment()->setComplete(1);
    $this->assertFalse($co2->access('take'), 'Check that user still cannot access second (dependent) object, even though first is complete.');

    // Check visibility.
    $this->assertTrue($co2->access('see'), 'Check that user can still see pending course object.');
    $co2->addOptions($hidden);
    $this->assertFalse($co2->access('see'), 'Check that user cannot still see pending course object when hidden is checked.');

    // Set the completion of this object to more than 5 minutes ago.
    $co1->getFulfillment()->setOption('date_started', REQUEST_TIME - 301);
    $this->assertTrue($co2->access('take'), 'Check that user can access second course object after time has elapsed.');
  }

  /**
   * Test the completion based trigger for object access.
   */
  function testTimeAfterCompletion() {
    global $user;
    $courseNode = $this->createCourseNode();
    $this->createCourseObject($courseNode);
    $this->createCourseObject($courseNode);
    $course = course_get_course($courseNode);

    // Set up a course object that should appear 5 minutes after the first
    // object is completed.
    $co = $course->getObjects();
    $co1 = $co[0];
    $co2 = $co[1];

    $set = array();
    $set['plugins']['access']['conditional'] = array(
      'conditional_type' => 'completed',
      'conditional_time' => 300,
      'conditional_object' => $co1->getId(),
      'conditional_hidden' => 0,
    );
    $hidden['plugins']['access']['conditional']['conditional_hidden'] = 1;
    $co2->addOptions($set);

    course_enroll($courseNode, $user);
    $this->assertTrue($co1->access('take'), 'Check that user can access first (depended on) object.');
    // Mark first object as complete.
    $co1->getFulfillment()->setComplete(1);
    $this->assertFalse($co2->access('take'), 'Check that user still cannot access second (dependent) object, even though first is complete.');

    // Check visibility.
    $this->assertTrue($co2->access('see'), 'Check that user can still see pending course object.');
    $co2->addOptions($hidden);
    $this->assertFalse($co2->access('see'), 'Check that user cannot still see pending course object when hidden is checked.');

    // Set the completion of this object to more than 5 minutes ago.
    $co1->getFulfillment()->setOption('date_completed', REQUEST_TIME - 301);
    $this->assertTrue($co2->access('take'), 'Check that user can access second course object after time has elapsed.');
  }

}
