@Test
  public void testSaveProduct() {
    // setup product
    Product product = new Product();
    product.setDescription("Spring Framework Guru Shirt");
    product.setPrice(new BigDecimal("18.95"));
    product.setProductId("1234");

    // save product, verify has ID value after save
    assertNull(product.getId()); // null before save
    productRepository.save(product);
    assertNotNull(product.getId()); // not null after save

    // fetch from DB
    Product fetchedProduct = productRepository.findOne(product.getId());

    // should not be null
    assertNotNull(fetchedProduct);

    // should equal
    assertEquals(product.getId(), fetchedProduct.getId());
    assertEquals(product.getDescription(), fetchedProduct.getDescription());

    // update description and save
    fetchedProduct.setDescription("New Description");
    productRepository.save(fetchedProduct);

    // get from DB, should be updated
    Product fetchedUpdatedProduct = productRepository.findOne(fetchedProduct.getId());
    assertEquals(fetchedProduct.getDescription(), fetchedUpdatedProduct.getDescription());

    // verify count of products in DB
    long productCount = productRepository.count();
    assertEquals(productCount, 1);

    // get all products, list should only have one
    Iterable<Product> products = productRepository.findAll();

    int count = 0;

    for (Product p : products) {
      count++;
    }

    assertEquals(count, 1);
  }
  @Test
  public void testFindByIsNull() {
    ProductBean beanWithoutName = createProductBean("5", 3, true, "product");
    beanWithoutName.setName(null);
    repo.save(beanWithoutName);

    List<ProductBean> found = repo.findByNameIsNull();
    Assert.assertEquals(1, found.size());
    Assert.assertEquals(beanWithoutName.getId(), found.get(0).getId());
  }
 @Before
 public void setUp() {
   repo.deleteAll();
   repo.save(
       Arrays.asList(
           POPULAR_AVAILABLE_PRODUCT,
           UNPOPULAR_AVAILABLE_PRODUCT,
           UNAVAILABLE_PRODUCT,
           NAMED_PRODUCT));
 }
  @Test
  public void testWithDefTypeLucene() {
    final ProductBean anotherProductBean = createProductBean("5", 3, true, "an other product");
    repo.save(anotherProductBean);

    List<ProductBean> found =
        repo.findByNameIn(Arrays.asList(NAMED_PRODUCT.getName(), anotherProductBean.getName()));
    Assert.assertEquals(2, found.size());

    Assert.assertThat(found, Matchers.containsInAnyOrder(anotherProductBean, NAMED_PRODUCT));
  }
  @Test
  public void testFindByIsNotNull() {
    ProductBean beanWithoutName = createProductBean("5", 3, true, "product");
    beanWithoutName.setName(null);
    repo.save(beanWithoutName);

    List<ProductBean> found = repo.findByNameIsNotNull();
    Assert.assertEquals(4, found.size());
    for (ProductBean foundBean : found) {
      Assert.assertFalse(beanWithoutName.getId().equals(foundBean.getId()));
    }
  }
  @Test
  public void testFindByNear() {
    ProductBean locatedInBuffalow = createProductBean("100", 5, true);
    locatedInBuffalow.setLocation("45.17614,-93.87341");

    ProductBean locatedInNYC = createProductBean("200", 5, true);
    locatedInNYC.setLocation("40.7143,-74.006");

    repo.save(Arrays.asList(locatedInBuffalow, locatedInNYC));

    List<ProductBean> found =
        repo.findByLocationNear(new GeoLocation(45.15, -93.85), new Distance(5));
    Assert.assertEquals(1, found.size());
    Assert.assertEquals(locatedInBuffalow.getId(), found.get(0).getId());
  }
  @Test
  public void testFindByAfter() {
    repo.deleteAll();
    ProductBean modifiedMid2012 = createProductBean("2012", 5, true);
    modifiedMid2012.setLastModified(new DateTime(2012, 6, 1, 0, 0, 0, DateTimeZone.UTC).toDate());

    ProductBean modifiedMid2011 = createProductBean("2011", 5, true);
    modifiedMid2011.setLastModified(new DateTime(2011, 6, 1, 0, 0, 0, DateTimeZone.UTC).toDate());

    repo.save(Arrays.asList(modifiedMid2012, modifiedMid2011));
    List<ProductBean> found =
        repo.findByLastModifiedAfter(new DateTime(2012, 1, 1, 0, 0, 0, DateTimeZone.UTC).toDate());
    Assert.assertEquals(1, found.size());
    Assert.assertEquals(modifiedMid2012.getId(), found.get(0).getId());
  }
  @Test
  public void testWithBoost() {
    repo.deleteAll();
    ProductBean beanWithName = createProductBean("1", 5, true, "stackoverflow");
    beanWithName.setTitle(Arrays.asList("indexoutofbounds"));

    ProductBean beanWithTitle = createProductBean("2", 5, true, "indexoutofbounds");
    beanWithTitle.setTitle(Arrays.asList("stackoverflow"));

    repo.save(Arrays.asList(beanWithName, beanWithTitle));

    List<ProductBean> found =
        repo.findByNameStartsWithOrTitleStartsWith("indexoutofbounds", "indexoutofbounds");
    Assert.assertEquals(2, found.size());
    Assert.assertEquals(beanWithTitle.getId(), found.get(0).getId());
    Assert.assertEquals(beanWithName.getId(), found.get(1).getId());
  }
  @Test
  public void testFindWithSortDesc() {
    repo.deleteAll();

    List<ProductBean> values = new ArrayList<ProductBean>();
    for (int i = 0; i < 10; i++) {
      values.add(createProductBean(Integer.toString(i), i, true));
    }
    repo.save(values);

    List<ProductBean> found = repo.findByAvailableTrueOrderByPopularityDesc();

    ProductBean prev = found.get(0);
    for (int i = 1; i < found.size(); i++) {
      ProductBean cur = found.get(i);
      Assert.assertTrue(Long.valueOf(cur.getPopularity()) < Long.valueOf(prev.getPopularity()));
      prev = cur;
    }
  }
  @Test
  public void testFindWithSortDescInPageableForNamedQuery() {
    repo.deleteAll();

    List<ProductBean> values = new ArrayList<ProductBean>();
    for (int i = 0; i < 10; i++) {
      values.add(createProductBean(Integer.toString(i), i, true));
    }
    repo.save(values);

    Page<ProductBean> found =
        repo.findByAvailableWithSort(
            true, new PageRequest(0, 30, new Sort(Direction.DESC, "popularity")));

    ProductBean prev = found.getContent().get(0);
    for (int i = 1; i < found.getContent().size(); i++) {
      ProductBean cur = found.getContent().get(i);
      Assert.assertTrue(Long.valueOf(cur.getPopularity()) < Long.valueOf(prev.getPopularity()));
      prev = cur;
    }
  }