package com.bellini.recipecatalog.test.service.book;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;

import java.util.Collections;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;

import com.bellini.recipecatalog.dao.v1.book.BookRepository;
import com.bellini.recipecatalog.exception.book.DuplicateBookException;
import com.bellini.recipecatalog.model.v1.Book;
import com.bellini.recipecatalog.service.v1.book.BookService;

@SpringBootTest
@RunWith(SpringRunner.class)
public class BookServiceTest {

    private static final String DUMMY_BOOK_TITLE = "Da Noi";

    @Autowired
    private BookService bookSrv;

    @MockBean
    private BookRepository bookRepo;

    @Test(expected = DuplicateBookException.class)
    public void create_shouldThrowExceptionWhenDuplicate() {
        when(bookRepo.findByTitleIgnoreCase(ArgumentMatchers.eq(DUMMY_BOOK_TITLE))).thenReturn(Collections.singleton(new Book()));
        bookSrv.create(dummyBook());
        // verify method calls
        verify(bookRepo).findByTitleIgnoreCase(ArgumentMatchers.eq(DUMMY_BOOK_TITLE));
        verify(bookRepo, never()).save(ArgumentMatchers.any(Book.class));
    }

    @Test
    public void create_shouldInvokeStorageWhenNotDuplicate() {
        when(bookRepo.findByTitleIgnoreCase(ArgumentMatchers.eq(DUMMY_BOOK_TITLE))).thenReturn(Collections.emptyList());
        final Book mock = dummyBook();
        when(bookRepo.save(mock)).thenReturn(mock);
        Book stored = bookSrv.create(mock);
        // verify method calls
        verify(bookRepo).findByTitleIgnoreCase(ArgumentMatchers.eq(DUMMY_BOOK_TITLE));
        verify(bookRepo).save(mock);
        assertEquals(mock, stored);
    }

    private Book dummyBook() {
        Book mock = new Book();
        mock.setTitle(DUMMY_BOOK_TITLE);
        return mock;
    }
}

@@ -122,17 +122,203 @@
 ito.
-Mockito.*
+ArgumentMatchers.any;%0Aimport static org.mockito.ArgumentMatchers.anyLong;%0Aimport static org.mockito.Mockito.never;%0Aimport static org.mockito.Mockito.verify;%0Aimport static org.mockito.Mockito.when
 ;%0A%0Ai
@@ -345,16 +345,43 @@
 ections;
+%0Aimport java.util.Optional;
 %0A%0Aimport
@@ -846,16 +846,90 @@
 eption;%0A
+import com.bellini.recipecatalog.exception.book.NotExistingBookException;%0A
 import c
@@ -1168,16 +1168,79 @@
 Da Noi%22;
+%0A    private static final String DUMMY_BOOK_TITLE_2 = %22Da noi%22;
 %0A%0A    @A
@@ -2444,16 +2444,16 @@
 TITLE);%0A
-
         
@@ -2470,11 +2470,1655 @@
 k;%0A    %7D
+%0A%0A    @Test(expected = DuplicateBookException.class)%0A    public void update_shouldThrowExceptionWhenDuplicateTitle() %7B%0A        when(bookRepo.findByTitleIgnoreCase(DUMMY_BOOK_TITLE_2)).thenReturn(Collections.singleton(dummyBookUpdateExisting()));%0A        final Book mock = dummyBookUpdate();%0A        bookSrv.update(2L, mock);%0A        verify(bookRepo, never()).findById(anyLong());%0A        verify(bookRepo, never()).save(anyLong(), any(Book.class));%0A    %7D%0A%0A    @Test(expected = NotExistingBookException.class)%0A    public void update_shouldThrowExceptionWhenBookIdDoesNotExists() %7B%0A        when(bookRepo.findByTitleIgnoreCase(DUMMY_BOOK_TITLE_2)).thenReturn(Collections.emptyList());%0A        when(bookRepo.findById(2L)).thenReturn(Optional.empty());%0A        final Book mock = dummyBookUpdate();%0A        bookSrv.update(2L, mock);%0A        verify(bookRepo, never()).save(anyLong(), any(Book.class));%0A    %7D%0A%0A    @Test%0A    public void update_shouldCallRepositoryWhenDataAreCorrect() %7B%0A        when(bookRepo.findByTitleIgnoreCase(DUMMY_BOOK_TITLE_2)).thenReturn(Collections.emptyList());%0A        when(bookRepo.findById(2L)).thenReturn(Optional.of(dummyBookUpdateExisting()));%0A        final Book mock = dummyBookUpdate();%0A        bookSrv.update(2L, mock);%0A        verify(bookRepo).save(anyLong(), any(Book.class));%0A    %7D%0A%0A    private Book dummyBookUpdate() %7B%0A        Book book = new Book();%0A        book.setId(2L);%0A        book.setTitle(DUMMY_BOOK_TITLE_2);%0A        return book;%0A    %7D%0A%0A    private Book dummyBookUpdateExisting() %7B%0A        Book book = new Book();%0A        book.setId(1L);%0A        book.setTitle(DUMMY_BOOK_TITLE);%0A        return book;%0A    %7D
 %0A%7D%0A

Test methods for update book