// Path: src/main/java/com/edwise/completespring/assemblers/BookResource.java
// @Getter
// @Setter
// @Accessors(chain = true)
// public class BookResource extends ResourceSupport {
//     private Book book;
// }
// 
// Path: src/main/java/com/edwise/completespring/assemblers/BookResourceAssembler.java
// @Component
// public class BookResourceAssembler extends ResourceAssemblerSupport<Book, BookResource> {
// 
//     public BookResourceAssembler() {
//         super(BookController.class, BookResource.class);
//     }
// 
//     @Override
//     protected BookResource instantiateResource(Book book) {
//         BookResource bookResource = super.instantiateResource(book);
//         bookResource.setBook(book);
// 
//         return bookResource;
//     }
// 
//     public BookResource toResource(Book book) {
//         return createResourceWithId(book.getId(), book);
//     }
// }
// 
// Path: src/main/java/com/edwise/completespring/exceptions/InvalidRequestException.java
// public class InvalidRequestException extends RuntimeException {
// 
//     @Getter
//     private final ErrorInfo errors;
// 
//     public InvalidRequestException(BindingResult bindingResultErrors) {
//         super(bindingResultErrors.toString());
//         this.errors = ErrorInfo.generateErrorInfoFromBindingResult(bindingResultErrors);
//     }
// 
// }
// 
// Path: src/main/java/com/edwise/completespring/exceptions/NotFoundException.java
// public class NotFoundException extends RuntimeException {
// 
//     public NotFoundException(String msg) {
//         super(msg);
//     }
// }
// 
// Path: src/main/java/com/edwise/completespring/services/BookService.java
// public interface BookService extends Service<Book, Long> {
// 
//     List<Book> findByTitle(String title);
// 
//     List<Book> findByReleaseDate(LocalDate releaseDate);
// 
//     Book create(Book book);
// }
// 
// Path: src/test/java/com/edwise/completespring/testutil/BookBuilder.java
// public class BookBuilder {
// 
//     private final Book book;
// 
//     public BookBuilder() {
//         book = new Book();
//     }
// 
//     public BookBuilder id(Long id) {
//         book.setId(id);
//         return this;
//     }
// 
//     public BookBuilder title(String title) {
//         book.setTitle(title);
//         return this;
//     }
// 
//     public BookBuilder authors(List<Author> authors) {
//         book.setAuthors(authors);
//         return this;
//     }
// 
//     public BookBuilder isbn(String isbn) {
//         book.setIsbn(isbn);
//         return this;
//     }
// 
//     public BookBuilder releaseDate(LocalDate releaseDate) {
//         book.setReleaseDate(releaseDate);
//         return this;
//     }
// 
//     public BookBuilder publisher(Publisher publisher) {
//         book.setPublisher(publisher);
//         return this;
//     }
// 
//     public Book build() {
//         return book;
//     }
// }


import com.edwise.completespring.assemblers.BookResource;
import com.edwise.completespring.assemblers.BookResourceAssembler;
import com.edwise.completespring.entities.*;
import com.edwise.completespring.exceptions.InvalidRequestException;
import com.edwise.completespring.exceptions.NotFoundException;
import com.edwise.completespring.services.BookService;
import com.edwise.completespring.testutil.BookBuilder;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.hateoas.Link;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.validation.BindingResult;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.mockito.Mockito.*;

        Throwable thrown = catchThrowable(() -> controller.updateBook(BOOK_ID_TEST1, bookReq, errors));

        assertThat(thrown).isInstanceOf(InvalidRequestException.class);
    }

    @Test
    public void testGet() {
        Book bookReq = new BookBuilder()
                .id(BOOK_ID_TEST1)
                .title(BOOK_TITLE_TEST1)
                .authors(Collections.singletonList(new Author().setName(AUTHOR_NAME_TEST1).setSurname(AUTHOR_SURNAME_TEST1)))
                .isbn(BOOK_ISBN_TEST1)
                .releaseDate(BOOK_RELEASEDATE_TEST1)
                .publisher(new Publisher().setName(PUBLISHER_NAME_TEST1).setCountry(PUBLISHER_COUNTRY_TEST1).setOnline(false))
                .build();
        when(bookService.findOne(BOOK_ID_TEST1)).thenReturn(bookReq);
        when(bookResourceAssembler.toResource(any(Book.class))).thenReturn(new BookResource().setBook(bookReq));

        ResponseEntity<BookResource> result = controller.getBook(BOOK_ID_TEST1);

        assertThat(result.getBody()).isNotNull();
        assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
        verify(bookService, times(ONE_TIME)).findOne(BOOK_ID_TEST1);
        verify(bookResourceAssembler, times(ONE_TIME)).toResource(bookReq);
    }


    @Test
    public void testGetNotFound() {
// Path: src/main/java/com/edwise/completespring/assemblers/BookResource.java
// @Getter
// @Setter
// @Accessors(chain = true)
// public class BookResource extends ResourceSupport {
//     private Book book;
// }
// 
// Path: src/main/java/com/edwise/completespring/assemblers/BookResourceAssembler.java
// @Component
// public class BookResourceAssembler extends ResourceAssemblerSupport<Book, BookResource> {
// 
//     public BookResourceAssembler() {
//         super(BookController.class, BookResource.class);
//     }
// 
//     @Override
//     protected BookResource instantiateResource(Book book) {
//         BookResource bookResource = super.instantiateResource(book);
//         bookResource.setBook(book);
// 
//         return bookResource;
//     }
// 
//     public BookResource toResource(Book book) {
//         return createResourceWithId(book.getId(), book);
//     }
// }
// 
// Path: src/main/java/com/edwise/completespring/exceptions/InvalidRequestException.java
// public class InvalidRequestException extends RuntimeException {
// 
//     @Getter
//     private final ErrorInfo errors;
// 
//     public InvalidRequestException(BindingResult bindingResultErrors) {
//         super(bindingResultErrors.toString());
//         this.errors = ErrorInfo.generateErrorInfoFromBindingResult(bindingResultErrors);
//     }
// 
// }
// 
// Path: src/main/java/com/edwise/completespring/exceptions/NotFoundException.java
// public class NotFoundException extends RuntimeException {
// 
//     public NotFoundException(String msg) {
//         super(msg);
//     }
// }
// 
// Path: src/main/java/com/edwise/completespring/services/BookService.java
// public interface BookService extends Service<Book, Long> {
// 
//     List<Book> findByTitle(String title);
// 
//     List<Book> findByReleaseDate(LocalDate releaseDate);
// 
//     Book create(Book book);
// }
// 
// Path: src/test/java/com/edwise/completespring/testutil/BookBuilder.java
// public class BookBuilder {
// 
//     private final Book book;
// 
//     public BookBuilder() {
//         book = new Book();
//     }
// 
//     public BookBuilder id(Long id) {
//         book.setId(id);
//         return this;
//     }
// 
//     public BookBuilder title(String title) {
//         book.setTitle(title);
//         return this;
//     }
// 
//     public BookBuilder authors(List<Author> authors) {
//         book.setAuthors(authors);
//         return this;
//     }
// 
//     public BookBuilder isbn(String isbn) {
//         book.setIsbn(isbn);
//         return this;
//     }
// 
//     public BookBuilder releaseDate(LocalDate releaseDate) {
//         book.setReleaseDate(releaseDate);
//         return this;
//     }
// 
//     public BookBuilder publisher(Publisher publisher) {
//         book.setPublisher(publisher);
//         return this;
//     }
// 
//     public Book build() {
//         return book;
//     }
// }


// Path: src/test/java/com/edwise/completespring/controllers/BookControllerTest.java
import com.edwise.completespring.assemblers.BookResource;
import com.edwise.completespring.assemblers.BookResourceAssembler;
import com.edwise.completespring.entities.*;
import com.edwise.completespring.exceptions.InvalidRequestException;
import com.edwise.completespring.exceptions.NotFoundException;
import com.edwise.completespring.services.BookService;
import com.edwise.completespring.testutil.BookBuilder;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.hateoas.Link;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.validation.BindingResult;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.mockito.Mockito.*;


        Throwable thrown = catchThrowable(() -> controller.updateBook(BOOK_ID_TEST1, bookReq, errors));

        assertThat(thrown).isInstanceOf(InvalidRequestException.class);
    }

    @Test
    public void testGet() {
        Book bookReq = new BookBuilder()
                .id(BOOK_ID_TEST1)
                .title(BOOK_TITLE_TEST1)
                .authors(Collections.singletonList(new Author().setName(AUTHOR_NAME_TEST1).setSurname(AUTHOR_SURNAME_TEST1)))
                .isbn(BOOK_ISBN_TEST1)
                .releaseDate(BOOK_RELEASEDATE_TEST1)
                .publisher(new Publisher().setName(PUBLISHER_NAME_TEST1).setCountry(PUBLISHER_COUNTRY_TEST1).setOnline(false))
                .build();
        when(bookService.findOne(BOOK_ID_TEST1)).thenReturn(bookReq);
        when(bookResourceAssembler.toResource(any(Book.class))).thenReturn(new BookResource().setBook(bookReq));

        ResponseEntity<BookResource> result = controller.getBook(BOOK_ID_TEST1);

        assertThat(result.getBody()).isNotNull();
        assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
        verify(bookService, times(ONE_TIME)).findOne(BOOK_ID_TEST1);
        verify(bookResourceAssembler, times(ONE_TIME)).toResource(bookReq);
    }


    @Test
    public void testGetNotFound() {
        when(bookService.findOne(BOOK_ID_TEST2)).thenThrow(new NotFoundException("Book not exist"));