/*
 * 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.c.commands.CreateBasicTask;
import org.spine3.examples.todolist.c.commands.CreateDraft;
import org.spine3.examples.todolist.c.commands.DeleteTask;
import org.spine3.examples.todolist.c.events.TaskDraftCreated;
import org.spine3.examples.todolist.c.failures.CannotCreateDraft;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.spine3.examples.todolist.TaskStatus.DRAFT;
import static org.spine3.examples.todolist.testdata.TestTaskCommandFactory.DESCRIPTION;
import static org.spine3.examples.todolist.testdata.TestTaskCommandFactory.createDraftInstance;
import static org.spine3.examples.todolist.testdata.TestTaskCommandFactory.createTaskInstance;
import static org.spine3.examples.todolist.testdata.TestTaskCommandFactory.deleteTaskInstance;

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

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

    @Test
    @DisplayName("produce TaskDraftCreated event")
    public void produceEvent() {
        final CreateDraft createDraftCmd = createDraftInstance(taskId);

        final List<? extends Message> messageList =
                aggregate.dispatchForTest(createDraftCmd, commandContext);
        assertEquals(1, messageList.size());
        assertEquals(TaskDraftCreated.class, messageList.get(0)
                                                        .getClass());

        final TaskDraftCreated taskDraftCreated = (TaskDraftCreated) messageList.get(0);
        assertEquals(taskId, taskDraftCreated.getId());
    }

    @Test
    @DisplayName("create the draft")
    public void createDraft() {
        final CreateDraft createDraftCmd = createDraftInstance(taskId);
        aggregate.dispatchForTest(createDraftCmd, commandContext);
        final TaskDefinition state = aggregate.getState();

        assertEquals(taskId, state.getId());
        assertEquals(DRAFT, state.getTaskStatus());
    }

    @Test
    @DisplayName("throw CannotCreateDraft failure upon an attempt to create draft with deleted task ID")
    public void notCreateDraft() {
        final CreateBasicTask createTaskCmd = createTaskInstance(taskId, DESCRIPTION);
        aggregate.dispatchForTest(createTaskCmd, commandContext);

        final DeleteTask deleteTaskCmd = deleteTaskInstance(taskId);
        aggregate.dispatchForTest(deleteTaskCmd, commandContext);

        try {
            final CreateDraft createDraftCmd = createDraftInstance(taskId);
            aggregate.dispatchForTest(createDraftCmd, commandContext);
        } catch (IllegalStateException ex) {
            final Throwable cause = ex.getCause();
            final CannotCreateDraft failure = (CannotCreateDraft) cause;
            final TaskId actualId = failure.getFailureMessage()
                                           .getCreateDraftFailed()
                                           .getFailureDetails()
                                           .getTaskId();
            assertEquals(taskId, actualId);
        }
    }
}

@@ -1072,16 +1072,58 @@
 ition;%0A%0A
+import com.google.common.base.Throwables;%0A
 import c
@@ -1150,16 +1150,16 @@
 essage;%0A
-
 import o
@@ -1762,16 +1762,77 @@
 Equals;%0A
+import static org.junit.jupiter.api.Assertions.assertThrows;%0A
 import s
@@ -2606,31 +2606,24 @@
 event%22)%0A    
-public 
 void produce
@@ -3211,31 +3211,24 @@
 draft%22)%0A    
-public 
 void createD
@@ -3604,16 +3604,33 @@
 re upon 
+%22 +%0A            %22
 an attem
@@ -3675,23 +3675,16 @@
 D%22)%0A    
-public 
 void not
@@ -3993,26 +3993,8 @@
 );%0A%0A
-        try %7B%0A    
     
@@ -4073,53 +4073,219 @@
     
-    aggregate.dispatchForTest(createDraftCmd,
+final Throwable t = assertThrows(Throwable.class,%0A                                         () -%3E aggregate.dispatchForTest(createDraftCmd,%0A                                                                        
  com
@@ -4300,59 +4300,11 @@
 ext)
+)
 ;%0A
-        %7D catch (IllegalStateException ex) %7B%0A    
     
@@ -4335,27 +4335,36 @@
 e = 
-ex.ge
+Throwables.getRoo
 tCause(
+t
 );%0A
-    
     
@@ -4428,20 +4428,16 @@
  cause;%0A
-    
         
@@ -4523,28 +4523,24 @@
             
-    
 .getCreateDr
@@ -4586,28 +4586,24 @@
             
-    
 .getFailureD
@@ -4646,28 +4646,24 @@
             
- 
-   
 .getTaskId()
@@ -4664,20 +4664,16 @@
 skId();%0A
-    
         
@@ -4708,18 +4708,8 @@
 d);%0A
-        %7D%0A
     

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