/*
 * Copyright 2017, TeamDev Ltd. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.spine3.examples.todolist.c.aggregate.definition;

import com.google.protobuf.Message;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.spine3.examples.todolist.TaskDefinition;
import org.spine3.examples.todolist.TaskId;
import org.spine3.examples.todolist.TaskStatus;
import org.spine3.examples.todolist.c.commands.CreateBasicTask;
import org.spine3.examples.todolist.c.events.TaskCreated;
import org.spine3.examples.todolist.c.failures.CannotCreateTaskWithInappropriateDescription;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.spine3.examples.todolist.testdata.TestTaskCommandFactory.DESCRIPTION;
import static org.spine3.examples.todolist.testdata.TestTaskCommandFactory.createTaskInstance;

/**
 * @author Illia Shepilov
 */
@DisplayName("CreateBasicTask command should be interpreted by TaskDefinitionPart and")
public class CreateBasicTaskTest extends TaskDefinitionCommandTest<CreateBasicTask> {

    @Override
    @BeforeEach
    public void setUp() {
        super.setUp();
    }

    @Test
    @DisplayName("produce TaskCreated event")
    public void produceEvent() {
        final CreateBasicTask createTaskCmd = createTaskInstance(taskId, DESCRIPTION);
        final List<? extends Message> messageList =
                aggregate.dispatchForTest(createTaskCmd, commandContext);

        assertNotNull(aggregate.getState()
                               .getCreated());
        assertNotNull(aggregate.getId());
        assertEquals(1, messageList.size());
        assertEquals(TaskCreated.class, messageList.get(0)
                                                   .getClass());
        final TaskCreated taskCreated = (TaskCreated) messageList.get(0);

        assertEquals(taskId, taskCreated.getId());
        assertEquals(DESCRIPTION, taskCreated.getDetails()
                                             .getDescription());
    }

    @Test
    @DisplayName("create the task")
    public void createTask() {
        final CreateBasicTask createBasicTask = createTaskInstance();
        aggregate.dispatchForTest(createBasicTask, commandContext);

        final TaskDefinition state = aggregate.getState();
        assertEquals(state.getId(), createBasicTask.getId());
        assertEquals(state.getTaskStatus(), TaskStatus.FINALIZED);
    }

    @Test
    @DisplayName("throw CannotCreateTaskWithInappropriateDescription failure " +
            "upon an attempt to create task with too short description")
    public void notCreateTask() {
        final CreateBasicTask createBasicTask = createTaskInstance(taskId, "D");
        try {
            aggregate.dispatchForTest(createBasicTask, commandContext);
        } catch (IllegalStateException ex) {
            final CannotCreateTaskWithInappropriateDescription failure =
                    (CannotCreateTaskWithInappropriateDescription) ex.getCause();
            final TaskId actualId = failure.getFailureMessage()
                                           .getCreateTaskFailed()
                                           .getFailureDetails()
                                           .getTaskId();
            assertEquals(this.taskId, actualId);
        }
    }
}

@@ -1068,24 +1068,66 @@
 efinition;%0A%0A
+import com.google.common.base.Throwables;%0A
 import com.g
@@ -1150,16 +1150,16 @@
 essage;%0A
-
 import o
@@ -1775,16 +1775,77 @@
 otNull;%0A
+import static org.junit.jupiter.api.Assertions.assertThrows;%0A
 import s
@@ -2371,31 +2371,24 @@
 event%22)%0A    
-public 
 void produce
@@ -3215,31 +3215,24 @@
  task%22)%0A    
-public 
 void createT
@@ -3737,31 +3737,24 @@
 ption%22)%0A    
-public 
 void notCrea
@@ -3845,24 +3845,25 @@
 , %22D%22);%0A
+%0A
         
 try %7B%0A  
@@ -3858,68 +3858,220 @@
     
-try %7B%0A            aggregate.dispatchForTest(createBasicTask,
+final Throwable t = assertThrows(Throwable.class,%0A                                         () -%3E aggregate.dispatchForTest(createBasicTask,%0A                                                                        
  com
@@ -4082,16 +4082,17 @@
 Context)
+)
 ;%0A      
@@ -4097,49 +4097,64 @@
     
-%7D catch (IllegalStateException ex) %7B%0A    
+final Throwable rootCause = Throwables.getRootCause(t);%0A
     
@@ -4234,20 +4234,16 @@
         
-    
 (CannotC
@@ -4285,27 +4285,19 @@
 on) 
-ex.ge
+roo
 tCause
-();%0A    
+;%0A
     
@@ -4383,36 +4383,32 @@
                 
- 
-   
 .getCreateTaskFa
@@ -4449,28 +4449,24 @@
             
-    
 .getFailureD
@@ -4509,28 +4509,24 @@
             
- 
-   
 .getTaskId()
@@ -4523,28 +4523,24 @@
 etTaskId();%0A
-    
         asse
@@ -4576,18 +4576,8 @@
 d);%0A
-        %7D%0A
     

Rewrite exception instance checking in `CreateBasicTaskTest` using `assertThrows`