// Path: src/main/java/org/javiermf/features/Application.java
// @SpringBootApplication
// public class Application {
// 
//     public static void main(String[] args) throws Exception {
//         SpringApplication.run(Application.class, args);
//     }
// 
// }
// 
// Path: src/main/java/org/javiermf/features/daos/ProductsConfigurationsDAO.java
// @Repository
// public class ProductsConfigurationsDAO {
// 
//     @PersistenceContext
//     private EntityManager entityManager;
// 
//     QProductConfiguration qProductConfiguration = QProductConfiguration.productConfiguration;
//     QProduct qProduct = QProduct.product;
// 
//     public List<ProductConfiguration> findByProductName(String productName) {
// 
// 
//         JPAQuery query = new JPAQuery(entityManager);
//         query.from(qProductConfiguration)
//                 .innerJoin(qProductConfiguration.product, qProduct)
//                 .where(qProduct.name.eq(productName));
//         return query.list(qProductConfiguration);
//     }
// 
//     public ProductConfiguration findByNameAndProductName(String productName, String configurationName) {
//         QProduct qProduct = QProduct.product;
// 
// 
//         JPAQuery query = new JPAQuery(entityManager);
//         query.from(qProductConfiguration)
//                 .innerJoin(qProductConfiguration.product, qProduct)
//                 .where(qProduct.name.eq(productName)
//                         .and(qProductConfiguration.name.eq(configurationName)));
//         return query.singleResult(qProductConfiguration);
//     }
// 
//     @Transactional
//     public void deleteConfigurationsForProduct(String productName) {
//         for (ProductConfiguration productConfiguration : findByProductName(productName)) {
//             entityManager.remove(productConfiguration);
//         }
// 
//     }
// 
//     public List<ProductConfiguration> findConfigurationsWithFeatureActive(Feature feature) {
//         JPAQuery query = new JPAQuery(entityManager);
//         query.from(qProductConfiguration)
//                 .where(qProductConfiguration.activedFeatures.contains(feature));
// 
//         return query.list(qProductConfiguration);
//     }
// 
//     @Transactional
//     public void insert(ProductConfiguration configuration) {
//         entityManager.persist(configuration);
// 
//     }
// 
//     @Transactional
//     public void deleteConfigurationForProduct(String productName, String configurationName) {
//         ProductConfiguration configuration = findByNameAndProductName(productName, configurationName);
//         entityManager.remove(configuration);
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/models/ProductConfiguration.java
// @Entity
// public class ProductConfiguration {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     Boolean valid = true;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @ManyToMany(fetch = FetchType.EAGER)
//     Set<Feature> activedFeatures = new HashSet<Feature>();
// 
//     public Set<Feature> getActivedFeatures() {
//         return activedFeatures;
//     }
// 
//     public Set<String> availableFeatures() {
//         return collectFeatureNames(product.getProductFeatures());
//     }
// 
//     private Set<String> collectFeatureNames(Set<Feature> featuresSet) {
//         Set<String> features = new HashSet<String>();
//         for (Feature feature : featuresSet) {
//             features.add(feature.name);
//         }
// 
//         return features;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Set<String> activedFeatures() {
//         return collectFeatureNames(activedFeatures);
//     }
// 
//     public Boolean isValid() {
//         return valid;
//     }
// 
//     public void setValid(Boolean valid) {
//         this.valid = valid;
//     }
// 
//     public void active(Feature feature) {
//         activedFeatures.add(feature);
// 
//     }
// 
//     public void deactive(Feature feature) {
//         activedFeatures.remove(feature);
//     }
// 
//     public void active(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         active(feature);
//     }
// 
//     public void deactive(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         deactive(feature);
//     }
// 
//     public boolean hasActiveFeature(String featureName) {
//         return activedFeatures().contains(featureName);
//     }
// }


import org.apache.http.HttpStatus;
import org.javiermf.features.Application;
import org.javiermf.features.daos.ProductsConfigurationsDAO;
import org.javiermf.features.models.ProductConfiguration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static com.jayway.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.util.MatcherAssertionErrors.assertThat;
package org.javiermf.features.services.rest;



@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
// Path: src/main/java/org/javiermf/features/Application.java
// @SpringBootApplication
// public class Application {
// 
//     public static void main(String[] args) throws Exception {
//         SpringApplication.run(Application.class, args);
//     }
// 
// }
// 
// Path: src/main/java/org/javiermf/features/daos/ProductsConfigurationsDAO.java
// @Repository
// public class ProductsConfigurationsDAO {
// 
//     @PersistenceContext
//     private EntityManager entityManager;
// 
//     QProductConfiguration qProductConfiguration = QProductConfiguration.productConfiguration;
//     QProduct qProduct = QProduct.product;
// 
//     public List<ProductConfiguration> findByProductName(String productName) {
// 
// 
//         JPAQuery query = new JPAQuery(entityManager);
//         query.from(qProductConfiguration)
//                 .innerJoin(qProductConfiguration.product, qProduct)
//                 .where(qProduct.name.eq(productName));
//         return query.list(qProductConfiguration);
//     }
// 
//     public ProductConfiguration findByNameAndProductName(String productName, String configurationName) {
//         QProduct qProduct = QProduct.product;
// 
// 
//         JPAQuery query = new JPAQuery(entityManager);
//         query.from(qProductConfiguration)
//                 .innerJoin(qProductConfiguration.product, qProduct)
//                 .where(qProduct.name.eq(productName)
//                         .and(qProductConfiguration.name.eq(configurationName)));
//         return query.singleResult(qProductConfiguration);
//     }
// 
//     @Transactional
//     public void deleteConfigurationsForProduct(String productName) {
//         for (ProductConfiguration productConfiguration : findByProductName(productName)) {
//             entityManager.remove(productConfiguration);
//         }
// 
//     }
// 
//     public List<ProductConfiguration> findConfigurationsWithFeatureActive(Feature feature) {
//         JPAQuery query = new JPAQuery(entityManager);
//         query.from(qProductConfiguration)
//                 .where(qProductConfiguration.activedFeatures.contains(feature));
// 
//         return query.list(qProductConfiguration);
//     }
// 
//     @Transactional
//     public void insert(ProductConfiguration configuration) {
//         entityManager.persist(configuration);
// 
//     }
// 
//     @Transactional
//     public void deleteConfigurationForProduct(String productName, String configurationName) {
//         ProductConfiguration configuration = findByNameAndProductName(productName, configurationName);
//         entityManager.remove(configuration);
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/models/ProductConfiguration.java
// @Entity
// public class ProductConfiguration {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     Boolean valid = true;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @ManyToMany(fetch = FetchType.EAGER)
//     Set<Feature> activedFeatures = new HashSet<Feature>();
// 
//     public Set<Feature> getActivedFeatures() {
//         return activedFeatures;
//     }
// 
//     public Set<String> availableFeatures() {
//         return collectFeatureNames(product.getProductFeatures());
//     }
// 
//     private Set<String> collectFeatureNames(Set<Feature> featuresSet) {
//         Set<String> features = new HashSet<String>();
//         for (Feature feature : featuresSet) {
//             features.add(feature.name);
//         }
// 
//         return features;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Set<String> activedFeatures() {
//         return collectFeatureNames(activedFeatures);
//     }
// 
//     public Boolean isValid() {
//         return valid;
//     }
// 
//     public void setValid(Boolean valid) {
//         this.valid = valid;
//     }
// 
//     public void active(Feature feature) {
//         activedFeatures.add(feature);
// 
//     }
// 
//     public void deactive(Feature feature) {
//         activedFeatures.remove(feature);
//     }
// 
//     public void active(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         active(feature);
//     }
// 
//     public void deactive(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         deactive(feature);
//     }
// 
//     public boolean hasActiveFeature(String featureName) {
//         return activedFeatures().contains(featureName);
//     }
// }


// Path: src/test/java/org/javiermf/features/services/rest/ConstraintRequiresIntegrationTests.java
import org.apache.http.HttpStatus;
import org.javiermf.features.Application;
import org.javiermf.features.daos.ProductsConfigurationsDAO;
import org.javiermf.features.models.ProductConfiguration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static com.jayway.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.util.MatcherAssertionErrors.assertThat;

package org.javiermf.features.services.rest;



@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@Sql({"/empty-db.sql", "/data-test.sql"})