// Path: product-catalog-context/src/main/java/se/citerus/cqrs/bookstore/productcatalog/api/ProductDto.java
// public class ProductDto extends TransportObject {
// 
//   @NotEmpty
//   @Pattern(regexp = ID_PATTERN)
//   public String productId;
// 
//   @Valid
//   public BookDto book;
// 
//   @Min(0)
//   public long price;
// 
//   @NotEmpty
//   @Pattern(regexp = ID_PATTERN)
//   public String publisherContractId;
// 
// }
// 
// Path: product-catalog-context/src/main/java/se/citerus/cqrs/bookstore/productcatalog/api/ProductDtoFactory.java
// public class ProductDtoFactory {
// 
//   public static ProductDto fromProduct(Product product) {
//     return toProduct(product, toBook(product.book));
//   }
// 
//   private static ProductDto toProduct(Product product, BookDto bookDto) {
//     ProductDto productDto = new ProductDto();
//     productDto.productId = product.productId;
//     productDto.price = product.price;
//     productDto.publisherContractId = product.publisherContractId;
//     productDto.book = bookDto;
//     return productDto;
//   }
// 
//   private static BookDto toBook(Book book) {
//     BookDto bookDto = new BookDto();
//     bookDto.bookId = book.bookId;
//     bookDto.isbn = book.isbn;
//     bookDto.title = book.title;
//     bookDto.description = book.description;
//     return bookDto;
//   }
// 
// }
// 
// Path: product-catalog-context/src/main/java/se/citerus/cqrs/bookstore/productcatalog/domain/Book.java
// public class Book extends ValueObject {
// 
//   public final String bookId;
//   public final String isbn;
//   public final String title;
//   public final String description;
// 
//   public Book(String bookId, String isbn, String title, String description) {
//     this.bookId = bookId;
//     this.isbn = isbn;
//     this.title = title;
//     this.description = description;
//   }
// 
// }
// 
// Path: product-catalog-context/src/main/java/se/citerus/cqrs/bookstore/productcatalog/domain/Product.java
// public class Product extends ValueObject {
// 
//   public final String productId;
//   public final Book book;
//   public final long price;
//   public final String publisherContractId;
// 
//   public Product(String productId, Book book, long price, String publisherContractId) {
//     this.productId = productId;
//     this.book = book;
//     this.price = price;
//     this.publisherContractId = publisherContractId;
//   }
// 
// }
// 
// Path: product-catalog-context/src/main/java/se/citerus/cqrs/bookstore/productcatalog/domain/ProductRepository.java
// public interface ProductRepository {
// 
//   Collection<Product> getProducts();
// 
//   Product getProduct(String productId);
// 
//   void save(Product product);
// 
// }


import io.dropwizard.testing.junit.ResourceTestRule;
import org.junit.After;
import org.junit.ClassRule;
import org.junit.Test;
import se.citerus.cqrs.bookstore.productcatalog.api.ProductDto;
import se.citerus.cqrs.bookstore.productcatalog.api.ProductDtoFactory;
import se.citerus.cqrs.bookstore.productcatalog.domain.Book;
import se.citerus.cqrs.bookstore.productcatalog.domain.Product;
import se.citerus.cqrs.bookstore.productcatalog.domain.ProductRepository;
import javax.ws.rs.core.GenericType;
import java.util.Collection;
import java.util.UUID;
import static java.util.Arrays.asList;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.*;
package se.citerus.cqrs.bookstore.productcatalog.resource;




public class ProductResourceTest {

  private static final String PRODUCT_RESOURCE = "/products";
  private static final GenericType<Collection<ProductDto>> PRODUCTS_COLLECTION_TYPE =
      new GenericType<Collection<ProductDto>>() {
      };

  private static ProductRepository productRepository = mock(ProductRepository.class);

  @ClassRule
  public static final ResourceTestRule resources = ResourceTestRule.builder()
      .addResource(new ProductResource(productRepository))
      .build();

  @After
  public void tearDown() throws Exception {
    reset(productRepository);
  }

  @Test
  public void getProductsRequest() {
    Book book = new Book(UUID.randomUUID().toString(), "1234567890", "Book Title", "");
    Product product = new Product(UUID.randomUUID().toString(), book, 1000L, null);
    when(productRepository.getProducts()).thenReturn(asList(product));

    Collection<ProductDto> products = resources.client()
        .target(PRODUCT_RESOURCE)
        .request(APPLICATION_JSON_TYPE)
        .get(PRODUCTS_COLLECTION_TYPE);

    assertThat(products, hasItem(ProductDtoFactory.fromProduct(product)));
  }

  @Test
  public void getProductRequest() {

    String bookId = UUID.randomUUID().toString();
// Path: product-catalog-context/src/main/java/se/citerus/cqrs/bookstore/productcatalog/api/ProductDto.java
// public class ProductDto extends TransportObject {
// 
//   @NotEmpty
//   @Pattern(regexp = ID_PATTERN)
//   public String productId;
// 
//   @Valid
//   public BookDto book;
// 
//   @Min(0)
//   public long price;
// 
//   @NotEmpty
//   @Pattern(regexp = ID_PATTERN)
//   public String publisherContractId;
// 
// }
// 
// Path: product-catalog-context/src/main/java/se/citerus/cqrs/bookstore/productcatalog/api/ProductDtoFactory.java
// public class ProductDtoFactory {
// 
//   public static ProductDto fromProduct(Product product) {
//     return toProduct(product, toBook(product.book));
//   }
// 
//   private static ProductDto toProduct(Product product, BookDto bookDto) {
//     ProductDto productDto = new ProductDto();
//     productDto.productId = product.productId;
//     productDto.price = product.price;
//     productDto.publisherContractId = product.publisherContractId;
//     productDto.book = bookDto;
//     return productDto;
//   }
// 
//   private static BookDto toBook(Book book) {
//     BookDto bookDto = new BookDto();
//     bookDto.bookId = book.bookId;
//     bookDto.isbn = book.isbn;
//     bookDto.title = book.title;
//     bookDto.description = book.description;
//     return bookDto;
//   }
// 
// }
// 
// Path: product-catalog-context/src/main/java/se/citerus/cqrs/bookstore/productcatalog/domain/Book.java
// public class Book extends ValueObject {
// 
//   public final String bookId;
//   public final String isbn;
//   public final String title;
//   public final String description;
// 
//   public Book(String bookId, String isbn, String title, String description) {
//     this.bookId = bookId;
//     this.isbn = isbn;
//     this.title = title;
//     this.description = description;
//   }
// 
// }
// 
// Path: product-catalog-context/src/main/java/se/citerus/cqrs/bookstore/productcatalog/domain/Product.java
// public class Product extends ValueObject {
// 
//   public final String productId;
//   public final Book book;
//   public final long price;
//   public final String publisherContractId;
// 
//   public Product(String productId, Book book, long price, String publisherContractId) {
//     this.productId = productId;
//     this.book = book;
//     this.price = price;
//     this.publisherContractId = publisherContractId;
//   }
// 
// }
// 
// Path: product-catalog-context/src/main/java/se/citerus/cqrs/bookstore/productcatalog/domain/ProductRepository.java
// public interface ProductRepository {
// 
//   Collection<Product> getProducts();
// 
//   Product getProduct(String productId);
// 
//   void save(Product product);
// 
// }


// Path: product-catalog-context/src/test/java/se/citerus/cqrs/bookstore/productcatalog/resource/ProductResourceTest.java
import io.dropwizard.testing.junit.ResourceTestRule;
import org.junit.After;
import org.junit.ClassRule;
import org.junit.Test;
import se.citerus.cqrs.bookstore.productcatalog.api.ProductDto;
import se.citerus.cqrs.bookstore.productcatalog.api.ProductDtoFactory;
import se.citerus.cqrs.bookstore.productcatalog.domain.Book;
import se.citerus.cqrs.bookstore.productcatalog.domain.Product;
import se.citerus.cqrs.bookstore.productcatalog.domain.ProductRepository;
import javax.ws.rs.core.GenericType;
import java.util.Collection;
import java.util.UUID;
import static java.util.Arrays.asList;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.*;

package se.citerus.cqrs.bookstore.productcatalog.resource;




public class ProductResourceTest {

  private static final String PRODUCT_RESOURCE = "/products";
  private static final GenericType<Collection<ProductDto>> PRODUCTS_COLLECTION_TYPE =
      new GenericType<Collection<ProductDto>>() {
      };

  private static ProductRepository productRepository = mock(ProductRepository.class);

  @ClassRule
  public static final ResourceTestRule resources = ResourceTestRule.builder()
      .addResource(new ProductResource(productRepository))
      .build();

  @After
  public void tearDown() throws Exception {
    reset(productRepository);
  }

  @Test
  public void getProductsRequest() {
    Book book = new Book(UUID.randomUUID().toString(), "1234567890", "Book Title", "");
    Product product = new Product(UUID.randomUUID().toString(), book, 1000L, null);
    when(productRepository.getProducts()).thenReturn(asList(product));

    Collection<ProductDto> products = resources.client()
        .target(PRODUCT_RESOURCE)
        .request(APPLICATION_JSON_TYPE)
        .get(PRODUCTS_COLLECTION_TYPE);

    assertThat(products, hasItem(ProductDtoFactory.fromProduct(product)));
  }

  @Test
  public void getProductRequest() {

    String bookId = UUID.randomUUID().toString();
    Book book = new Book(bookId, "1234567890", "Book Title", "");