import grails.test.*

/**
* Integration tests for TaskService.
*/
class TaskServiceTests extends GroovyTestCase {

    // Data will be saved, not rolled back.
    // Be sure to clean up in tearDown().
    boolean transactional = false

    def taskService
    def dateUtilService

    def taskA
    def taskB
    def taskCount = 0

    // Setup is called before each test.
    protected void setUp() {
        super.setUp()

        // Check environment state.
        assert Task.count() == 0
        assert Entry.count() == 0
        assert TaskModification.count() == 0

        def p = [:]
        def result

        p = [taskGroup:TaskGroup.findByName("Engineering Activites"),
                taskPriority:TaskPriority.get(2),
                taskType:TaskType.get(1),
                leadPerson:Person.get(1),
                description:"TestA",
                comment:"Service test task.",
                targetStartDate: dateUtilService.today,
                targetCompletionDate: dateUtilService.today]

        result = taskService.save(p)
        assert result.error == null
        taskCount++
        taskA = result.taskInstance.refresh()

        p.description = "TestB"
        result = taskService.save(p)
        assert result.error == null
        taskCount++
        taskB = result.taskInstance.refresh()
    }

    // Tear down is called after each test.
    protected void tearDown() {
        super.tearDown()

        taskService.delete(taskA)
        taskService.delete(taskB)

        // Ensure that we leave environment clean.
        assert Task.count() == 0
        assert TaskModification.count() == 0
        assert Entry.count() == 0
    }

    def testSave() {

        // Task are created by setUp().
        assert Task.count() == taskCount

        taskA.refresh()
        assert taskA.taskModifications.size() == 1
        assert taskA.taskModifications.each() {
            it.taskModificationType.id == 1 // Created.
        }

        taskB.refresh()
        assert taskB.taskModifications.size() == 1
        assert taskB.taskModifications.each() {
            it.taskModificationType.id == 1 // Created.
        }

    } // testSave()

    void testComplete() {

        def modificationCount = 0

        taskA.refresh()
        assert taskA.taskStatus ==  TaskStatus.read(1) // Not Started.
        assert taskA.taskModifications.size() == ++modificationCount

        taskService.complete(taskA)
        taskA.refresh()
        assert taskA.taskStatus ==  TaskStatus.read(3) // Complete.
        assert taskA.taskModifications.size() == ++modificationCount

    } // testComplete()

    void testReopen() {

        def entryParams = [:]
        def modificationCount = 0

        taskA.refresh()
        assert taskA.taskStatus ==  TaskStatus.read(1) // Not Started.
        assert taskA.taskModifications.size() == ++modificationCount

        taskService.complete(taskA)
        taskA.refresh()
        assert taskA.taskStatus ==  TaskStatus.read(3) // Complete.
        assert taskA.taskModifications.size() == ++modificationCount

        taskService.reopen(taskA)
        taskA.refresh()
        assert taskA.taskStatus ==  TaskStatus.read(1) // Not Started.
        assert taskA.taskModifications.size() == ++modificationCount

        // Work Done Entry, with zero time booked.
        entryParams = [task: taskA,
                                        entryType: EntryType.read(3),
                                        comment: "Test entry.",
                                        durationHour: 0,
                                        durationMinute: 0]

        assert taskService.saveEntry(entryParams).error == null

        taskService.complete(taskA)
        taskA.refresh()
        assert taskA.taskStatus ==  TaskStatus.read(3) // Complete.
        assert taskA.taskModifications.size() == ++modificationCount

        taskService.reopen(taskA)
        taskA.refresh()
        assert taskA.taskStatus ==  TaskStatus.read(1) // Not Started.
        assert taskA.taskModifications.size() == ++modificationCount

        // Work Done Entry, with time booked.
        entryParams.durationMinute = 1
        assert taskService.saveEntry(entryParams).error == null
        taskA.refresh()
        assert taskA.taskStatus ==  TaskStatus.read(2) // In Progress.
        assert taskA.taskModifications.size() == ++modificationCount

        taskService.complete(taskA)
        taskA.refresh()
        assert taskA.taskStatus ==  TaskStatus.read(3) // Complete.
        assert taskA.taskModifications.size() == ++modificationCount

        taskService.reopen(taskA)
        taskA.refresh()
        assert taskA.taskStatus ==  TaskStatus.read(2) // In Progress.
        assert taskA.taskModifications.size() == ++modificationCount

    } // testReopen()

} // end class