@Test
  public void testProductFullConstructor() {
    Product prod = new Product("cp_test-label", "variant", owner, "version", "arch", "", "SVC");
    productCurator.create(prod);

    productCurator.find(prod.getUuid());
  }
  @Test
  public void testRemoveProductContent() {
    Product p = createTestProduct();
    Content content =
        new Content(
            this.owner,
            "test-content",
            "test-content",
            "test-content",
            "yum",
            "us",
            "here",
            "here",
            "test-arch");
    p.addContent(content);
    contentCurator.create(content);
    productCurator.create(p);

    p = productCurator.find(p.getUuid());
    assertEquals(1, p.getProductContent().size());

    productCurator.removeProductContent(p, content);
    p = productCurator.find(p.getUuid());
    assertEquals(0, p.getProductContent().size());
  }
 @Test
 public void testProductAttributeUpdateSuccessZeroInt() {
   Product original = createTestProduct();
   productCurator.create(original);
   assertTrue(original.getUuid() != null);
   original.addAttribute(new ProductAttribute("product.pos_count", "0"));
   productCurator.createOrUpdate(original);
 }
 @Test(expected = BadRequestException.class)
 public void testProductAttributeUpdateFailPosLong() {
   Product original = createTestProduct();
   productCurator.create(original);
   assertTrue(original.getUuid() != null);
   original.addAttribute(new ProductAttribute("product.long_pos_count", "-23"));
   productCurator.createOrUpdate(original);
 }
 @Test(expected = BadRequestException.class)
 public void testProductAttributeUpdateFailNumberBool() {
   Product original = createTestProduct();
   productCurator.create(original);
   assertTrue(original.getUuid() != null);
   original.addAttribute(new ProductAttribute("product.bool_val_num", "6"));
   productCurator.createOrUpdate(original);
 }
  @Test(expected = PersistenceException.class)
  public void labelUnique() {

    Product prod = new Product("label1", "name", owner);
    Product prod2 = new Product("label1", "name2", owner);
    productCurator.create(prod);

    productCurator.create(prod2);
  }
  @Test
  public void testDependentProducts() {
    Product prod = new Product("test-label", "test-product-name", owner);
    HashSet<String> dependentProductIds = new HashSet<String>();
    dependentProductIds.add("ProductX");
    prod.setDependentProductIds(dependentProductIds);
    productCurator.create(prod);

    Product lookedUp = productCurator.find(prod.getUuid());
    assertThat(lookedUp.getDependentProductIds(), hasItem("ProductX"));
  }
  @Test
  public void nameNonUnique() {

    Product prod = new Product("label1", "name", owner);
    productCurator.create(prod);

    Product prod2 = new Product("label2", "name", owner);
    productCurator.create(prod2);

    assertEquals(prod.getName(), prod2.getName());
    assertFalse(prod.getUuid().equals(prod2.getUuid()));
  }
 @Test
 public void testProductAttributeValidationSuccessUpdate() {
   Product original = createTestProduct();
   productCurator.create(original);
   assertTrue(original.getUuid() != null);
   original.setAttribute("product.count", "134");
   original.setAttribute("product.pos_count", "333");
   original.setAttribute(
       "product.long_multiplier", (new Long(Integer.MAX_VALUE * 100)).toString());
   original.setAttribute("product.long_pos_count", "10");
   original.setAttribute("product.bool_val_str", "false");
   original.setAttribute("product.bool_val_num", "1");
   productCurator.createOrUpdate(original);
 }
  @Test
  public void testInitialUpdate() {
    Product prod = new Product("test-label", "test-product-name", owner);
    productCurator.create(prod);

    assertNotNull(prod.getUpdated());
  }
  @Before
  public void setUp() {
    owner = new Owner("test-owner", "Test Owner");
    owner = ownerCurator.create(owner);

    e = new Environment("env1", "Env 1", owner);
    envCurator.create(e);

    p = TestUtil.createProduct(owner);
    c =
        new Content(
            this.owner,
            "testcontent",
            "contentId1",
            "testcontent",
            "yum",
            "red hat",
            "http://example.com",
            "http://example.com/gpg.key",
            "test-arch");
    contentCurator.create(c);
    p.addContent(c);
    productCurator.create(p);

    envContent = new EnvironmentContent(e, c, true);
    envContent = envContentCurator.create(envContent);
  }
  @Before
  public void setUp() {
    config.setProperty(ConfigProperties.INTEGER_ATTRIBUTES, "product.count, product.multiplier");
    config.setProperty(ConfigProperties.NON_NEG_INTEGER_ATTRIBUTES, "product.pos_count");
    config.setProperty(
        ConfigProperties.LONG_ATTRIBUTES, "product.long_count, product.long_multiplier");
    config.setProperty(ConfigProperties.NON_NEG_LONG_ATTRIBUTES, "product.long_pos_count");
    config.setProperty(
        ConfigProperties.BOOLEAN_ATTRIBUTES, "product.bool_val_str, product.bool_val_num");

    this.owner = createOwner();
    ownerCurator.create(owner);

    product = TestUtil.createProduct(owner);
    productCurator.create(product);

    providedProduct = TestUtil.createProduct(owner);
    productCurator.create(providedProduct);

    Set<Product> providedProducts = new HashSet<Product>();
    providedProducts.add(providedProduct);

    derivedProduct = TestUtil.createProduct(owner);
    productCurator.create(derivedProduct);

    derivedProvidedProduct = TestUtil.createProduct(owner);
    productCurator.create(derivedProvidedProduct);

    Set<Product> derivedProvidedProducts = new HashSet<Product>();
    derivedProvidedProducts.add(derivedProvidedProduct);

    pool =
        new Pool(
            owner,
            product,
            providedProducts,
            16L,
            TestUtil.createDate(2006, 10, 21),
            TestUtil.createDate(2020, 1, 1),
            "1",
            "2",
            "3");

    pool.setDerivedProduct(derivedProduct);
    pool.setDerivedProvidedProducts(derivedProvidedProducts);
    poolCurator.create(pool);
  }
  @Test
  public void testSaveOrUpdateProductNoDuplicateProdContent() {
    Product p = createTestProduct();
    Content content =
        new Content(
            this.owner,
            "best-content",
            "best-content",
            "best-content",
            "yum",
            "us",
            "here",
            "here",
            "test-arch");

    p.addContent(content);
    contentCurator.create(content);
    productCurator.createOrUpdate(p);

    // Technically the same product:
    Product p2 = createTestProduct();

    // The content isn't quite the same. We just care about matching
    // product ids with content ids
    Content contentUpdate =
        new Content(
            this.owner,
            "best-content",
            "best-content",
            "best-content",
            "yum",
            "us",
            "here",
            "differnet",
            "test-arch");

    contentUpdate.setUuid(content.getUuid());

    p2.addContent(contentUpdate);
    productCurator.createOrUpdate(p2);

    Product result = productCurator.find(p.getUuid());
    assertEquals(1, result.getProductContent().size());
  }
  @Test
  @SuppressWarnings("unchecked")
  public void normalCreate() {

    Product prod = new Product("cptest-label", "My Product", owner);
    productCurator.create(prod);

    List<Product> results =
        entityManager().createQuery("select p from Product as p").getResultList();
    assertEquals(5, results.size());
  }
  @Test
  public void listByIds() {
    List<Product> products = new ArrayList<Product>();
    List<String> pids = new ArrayList<String>();
    for (int i = 0; i < 5; i++) {
      Product p = TestUtil.createProduct(owner);
      productCurator.create(p);
      products.add(p);
      pids.add(p.getId());
    }

    // ok get first 3 items to lookup
    List<Product> returned = productCurator.listAllByIds(owner, pids.subList(0, 3));
    assertEquals(3, returned.size());

    // verify the first 3 were actually returned, and only those 3.
    assertTrue(returned.contains(products.get(0)));
    assertTrue(returned.contains(products.get(1)));
    assertTrue(returned.contains(products.get(2)));
    assertFalse(returned.contains(products.get(3)));
    assertFalse(returned.contains(products.get(4)));
  }
  @Test
  public void testGetProductIdFromContentUuid() {
    Product p = createTestProduct();
    Content content =
        new Content(
            this.owner,
            "best-content",
            "best-content",
            "best-content",
            "yum",
            "us",
            "here",
            "here",
            "test-arch");
    p.addContent(content);
    contentCurator.create(content);
    productCurator.create(p);

    List<String> contentUuids = new LinkedList<String>();
    contentUuids.add(content.getUuid());
    List<Product> products = productCurator.getProductsWithContent(contentUuids);
    assertEquals(1, products.size());
    assertEquals(p, products.get(0));
  }
  @Test
  public void testWithSimpleJsonAttribute() throws Exception {
    Map<String, String> data = new HashMap<String, String>();
    data.put("a", "1");
    data.put("b", "2");
    ObjectMapper mapper = new ObjectMapper();
    String jsonData = mapper.writeValueAsString(data);

    Product prod = new Product("cptest-label", "My Product", owner);
    ProductAttribute a = new ProductAttribute("content_sets", jsonData);
    prod.addAttribute(a);
    productCurator.create(prod);
    attributeCurator.create(a);

    Product lookedUp = productCurator.find(prod.getUuid());
    assertEquals(jsonData, lookedUp.getAttribute("content_sets").getValue());

    data =
        mapper.readValue(
            lookedUp.getAttribute("content_sets").getValue(),
            new TypeReference<Map<String, String>>() {});
    assertEquals("1", data.get("a"));
    assertEquals("2", data.get("b"));
  }
  @Test
  public void testJsonListOfHashes() throws Exception {
    List<Map<String, String>> data = new LinkedList<Map<String, String>>();
    Map<String, String> contentSet1 = new HashMap<String, String>();
    contentSet1.put("name", "cs1");
    contentSet1.put("url", "url");

    Map<String, String> contentSet2 = new HashMap<String, String>();
    contentSet2.put("name", "cs2");
    contentSet2.put("url", "url2");

    data.add(contentSet1);
    data.add(contentSet2);

    ObjectMapper mapper = new ObjectMapper();
    String jsonData = mapper.writeValueAsString(data);

    Product prod = new Product("cptest-label", "My Product", owner);
    ProductAttribute a = new ProductAttribute("content_sets", jsonData);
    prod.addAttribute(a);
    productCurator.create(prod);
    attributeCurator.create(a);

    Product lookedUp = productCurator.find(prod.getUuid());
    assertEquals(jsonData, lookedUp.getAttribute("content_sets").getValue());

    data =
        mapper.readValue(
            lookedUp.getAttribute("content_sets").getValue(),
            new TypeReference<List<Map<String, String>>>() {});
    Map<String, String> cs1 = data.get(0);
    assertEquals("cs1", cs1.get("name"));

    Map<String, String> cs2 = data.get(1);
    assertEquals("cs2", cs2.get("name"));
  }
  /** Test whether the product updation date is updated when merging. */
  @Test
  public void testSubsequentUpdate() {
    Product prod = new Product("test-label", "test-product-name", owner);
    productCurator.create(prod);

    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.MONTH, -2);
    prod.setUpdated(calendar.getTime());

    long updated = prod.getUpdated().getTime();

    prod.setName("test-changed-name");
    prod = this.productCurator.merge(prod);
    assertTrue(prod.getUpdated().getTime() > updated);
  }
  @Test
  public void testUpdateProduct() {
    Product original = createTestProduct();
    productCurator.create(original);
    // Will have same ID, but we'll modify other data:
    Product modified = createTestProduct();
    String newName = "new name";
    modified.setName(newName);

    // Hack up the attributes, keep a1, skip a2, modify a3, add a4:
    Set<ProductAttribute> newAttributes = new HashSet<ProductAttribute>();
    newAttributes.add(modified.getAttribute("a1"));
    ProductAttribute a3 = modified.getAttribute("a3");
    a3.setValue("a3-modified");
    a3.setProduct(modified);
    newAttributes.add(a3);
    ProductAttribute a4 = new ProductAttribute("a4", "a4");
    a4.setProduct(modified);
    newAttributes.add(a4);
    modified.setAttributes(newAttributes);

    int initialAttrCount = attributeCurator.listAll().size();
    productCurator.createOrUpdate(modified);

    Product lookedUp = productCurator.lookupById(owner, original.getId());
    assertEquals(newName, lookedUp.getName());
    assertEquals(3, lookedUp.getAttributes().size());
    assertEquals("a1", lookedUp.getAttributeValue("a1"));
    assertEquals("a3-modified", lookedUp.getAttributeValue("a3"));
    assertEquals("a4", lookedUp.getAttributeValue("a4"));

    // TODO: test content merging

    // Old attributes should get cleaned up:
    assertEquals(initialAttrCount, attributeCurator.listAll().size());
  }
 @Test
 public void ensureDerivedProvidedProductHasSubscription() {
   assertTrue(productCurator.productHasSubscriptions(derivedProvidedProduct));
 }
  @Test(expected = PersistenceException.class)
  public void nameRequired() {

    Product prod = new Product("someproductlabel", null, owner);
    productCurator.create(prod);
  }
 @Test
 public void ensureProductHasSubscription() {
   assertTrue(productCurator.productHasSubscriptions(product));
 }
  @Test(expected = ConstraintViolationException.class)
  public void labelRequired() {

    Product prod = new Product(null, "My Product Name", owner);
    productCurator.create(prod);
  }
 @Test
 public void testProductAttributeCreationSuccessZeroInt() {
   Product original = createTestProduct();
   original.addAttribute(new ProductAttribute("product.pos_count", "0"));
   productCurator.create(original);
 }
 @Test(expected = BadRequestException.class)
 public void testProductAttributeCreationFailNumberBool() {
   Product original = createTestProduct();
   original.addAttribute(new ProductAttribute("product.bool_val_num", "2"));
   productCurator.create(original);
 }
 @Test(expected = BadRequestException.class)
 public void testProductAttributeCreationFailBadPosLong() {
   Product original = createTestProduct();
   original.addAttribute(new ProductAttribute("product.long_pos_count", "-1"));
   productCurator.create(original);
 }
 @Test
 public void ensureDoesNotHaveSubscription() {
   Product doesNotHave = TestUtil.createProduct(owner);
   productCurator.create(doesNotHave);
   assertFalse(productCurator.productHasSubscriptions(doesNotHave));
 }
 @Test(expected = BadRequestException.class)
 public void testProductAttributeCreationFailBadLong() {
   Product original = createTestProduct();
   original.addAttribute(new ProductAttribute("product.long_multiplier", "ZZ"));
   productCurator.create(original);
 }
 @Test
 public void testSubstringConfigList() {
   Product original = createTestProduct();
   original.addAttribute(new ProductAttribute("product.pos", "-5"));
   productCurator.create(original);
 }