<?php

  class TestProjectScheduler extends AngieModelTestCase {
    
    private $monday;
    
    private $tuesday;
    
    private $wednesday;
    
    private $thursday;
    
    private $friday;
    
    private $logged_user;
    
    private $active_project;
    
    private $active_milestone;
    
    private $active_task;
    
    function setUp() {
      parent::setUp();
      
      $this->monday = new DateValue('2012-03-19');
      $this->tuesday = new DateValue('2012-03-20');
      $this->wednesday = new DateValue('2012-03-21');
      $this->thursday = new DateValue('2012-03-22');
      $this->friday = new DateValue('2012-03-23');
      
      $this->logged_user = new User(1);
      
      $this->second_user = new User();
      $this->second_user->setAttributes(array(
        'email' => 'second-user@test.com', 
        'company_id' => 1, 
        'password' => 'test', 
        'role_id' => 1, 
      ));
      $this->second_user->setState(STATE_VISIBLE);
      $this->second_user->save();
      
      $this->active_project = new Project();
      $this->active_project->setAttributes(array(
        'name' => 'Test Project', 
        'leader_id' => 1, 
        'company_id' => 1, 
      ));
      $this->active_project->save();
      
      $this->active_milestone = new Milestone();
      $this->active_milestone->setAttributes(array(
        'name' => 'Test Subject', 
      ));
      $this->active_milestone->setProject($this->active_project);
      $this->active_milestone->setCreatedBy($this->logged_user);
      $this->active_milestone->setStartOn($this->monday);
      $this->active_milestone->setDueOn($this->monday);
      $this->active_milestone->setState(STATE_VISIBLE);
      $this->active_milestone->save();
      
      $this->active_task = new Task();
      $this->active_task->setName('Test task');
      $this->active_task->setProject($this->active_project);
      $this->active_task->setMilestone($this->active_milestone);
      $this->active_task->setCreatedBy($this->logged_user);
      $this->active_task->setDueOn($this->tuesday);
      $this->active_task->setState(STATE_VISIBLE);
      $this->active_task->setVisibility(VISIBILITY_NORMAL);
      $this->active_task->save();
      
      $subtask = $this->active_task->subtasks()->newSubtask();
      
      $subtask->setAttributes(array(
        'body' => 'Subtask text', 
      ));
      $subtask->setCreatedBy($this->logged_user);
      $subtask->setDueOn($this->wednesday);
      $subtask->setState(STATE_VISIBLE);
      $subtask->save();
    } // setUp
    
    function testInitialization() {
      $this->assertEqual($this->monday->toMySQL(), '2012-03-19', 'Monday is properly set');
      $this->assertEqual($this->tuesday->toMySQL(), '2012-03-20', 'Tuesday is properly set');
      $this->assertEqual($this->wednesday->toMySQL(), '2012-03-21', 'Wednesday is properly set');
      $this->assertEqual($this->thursday->toMySQL(), '2012-03-22', 'Thursday is properly set');
      $this->assertEqual($this->friday->toMySQL(), '2012-03-23', 'Friday is properly set');
      
      $this->assertTrue($this->logged_user->isLoaded(), 'Logged user loaded');
      $this->assertTrue($this->active_project->isLoaded(), 'Active project is created');
      
      $this->assertTrue($this->active_milestone->isLoaded(), 'Test milestone is created');
      $this->assertEqual(ApplicationObjects::getRememberedContext($this->active_milestone), ApplicationObjects::getContext($this->active_project) . '/milestones/' . $this->active_milestone->getId(), 'Test milestone context is OK');
      $this->assertEqual($this->active_milestone->getStartOn()->toMySQL(), $this->monday->toMySQL(), 'Milestone start date is set');
      $this->assertEqual($this->active_milestone->getDueOn()->toMySQL(), $this->monday->toMySQL(), 'Milestone due date is set');
      
      $this->assertTrue($this->active_task->isLoaded(), 'Test task is created');
      $this->assertEqual(ApplicationObjects::getRememberedContext($this->active_task), ApplicationObjects::getContext($this->active_project) . '/tasks/normal/' . $this->active_task->getId(), 'Test task context is OK');
      $this->assertEqual($this->active_task->getMilestoneId(), $this->active_milestone->getId(), 'Task milestone is set');
      $this->assertEqual($this->active_task->getDueOn()->toMySQL(), $this->tuesday->toMySQL(), 'Task due date is set');
      
      $this->assertEqual($this->active_task->subtasks()->count($this->logged_user, false), 1, 'Subtask is created');
      $this->assertIsA($this->active_task->subtasks()->get($this->logged_user)->getRowAt(0), 'Subtask', 'First row is subtak');
      $this->assertEqual($this->active_task->subtasks()->get($this->logged_user)->getRowAt(0)->getDueOn()->toMySQL(), $this->wednesday->toMySQL(), 'Subtask due date is set');
    } // testInitialization
  
    function testRescheduleTaskWithSubtasks() {
      ProjectScheduler::rescheduleProjectObject($this->active_task, $this->wednesday, true, true);
      
      $this->assertEqual($this->active_task->getDueOn()->toMySQL(), $this->wednesday->toMySQL(), 'Task has been rescheduled');
      $this->assertEqual($this->active_task->subtasks()->get($this->logged_user)->getRowAt(0)->getDueOn()->toMySQL(), $this->thursday->toMySQL(), 'Subtask has been rescheduled');
    } // testRescheduleTaskWithSubtasks
    
    function testRescheduleOnlyTask() {
      ProjectScheduler::rescheduleProjectObject($this->active_task, $this->wednesday, false, true);
      
      $this->assertEqual($this->active_task->getDueOn()->toMySQL(), $this->wednesday->toMySQL(), 'Task has been rescheduled');
      $this->assertEqual($this->active_task->subtasks()->get($this->logged_user)->getRowAt(0)->getDueOn()->toMySQL(), $this->wednesday->toMySQL(), 'Subtask has been rescheduled');
    } // testRescheduleOnlyTask
    
    function testRescheduleMilestone() {
      ProjectScheduler::rescheduleMilestone($this->active_milestone, $this->tuesday, $this->tuesday, true, true);
      
      $this->assertEqual($this->active_milestone->getStartOn()->toMySQL(), $this->tuesday->toMySQL(), 'Milestone start date has been moved');
      $this->assertEqual($this->active_milestone->getDueOn()->toMySQL(), $this->tuesday->toMySQL(), 'Milestone due date has been moved');
      
      $this->active_task = Tasks::findById($this->active_task->getId()); // Reload
      
      $this->assertEqual($this->active_task->getDueOn()->toMySQL(), $this->wednesday->toMySQL(), 'Task has been rescheduled');
      $this->assertEqual($this->active_task->subtasks()->get($this->logged_user)->getRowAt(0)->getDueOn()->toMySQL(), $this->wednesday->toMySQL(), 'Subtask has been rescheduled');
    } // testRescheduleMilestone
    
    function testRescheduleProject() {
      $this->assertEqual($this->active_milestone->getStartOn()->toMySQL(), $this->active_milestone->getDueOn()->toMySQL(), 'Single day milestone');
      
      ProjectScheduler::rescheduleProject($this->active_project, $this->monday, $this->tuesday, true);
      
      $this->active_milestone = Milestones::findById($this->active_milestone->getId()); // Reload
      
      $this->assertEqual($this->active_milestone->getStartOn()->toMySQL(), $this->tuesday->toMySQL(), 'Milestone start date has been moved');
      $this->assertEqual($this->active_milestone->getDueOn()->toMySQL(), $this->tuesday->toMySQL(), 'Milestone due date has been moved');
      
      $this->active_task = Tasks::findById($this->active_task->getId()); // Reload
      
      $this->assertEqual($this->active_task->getDueOn()->toMySQL(), $this->wednesday->toMySQL(), 'Task has been rescheduled');
      $this->assertEqual($this->active_task->subtasks()->get($this->logged_user)->getRowAt(0)->getDueOn()->toMySQL(), $this->wednesday->toMySQL(), 'Subtask has been rescheduled');
    } // testRescheduleProject
    
  }