@Test
  public void search_by_profile() throws InterruptedException {
    QualityProfileDto qualityProfileDto1 = QProfileTesting.newXooP1();
    QualityProfileDto qualityProfileDto2 = QProfileTesting.newXooP2();
    db.qualityProfileDao().insert(dbSession, qualityProfileDto1, qualityProfileDto2);

    RuleDto rule1 = RuleTesting.newXooX1();
    RuleDto rule2 = RuleTesting.newXooX2();
    RuleDto rule3 = RuleTesting.newXooX3();
    dao.insert(dbSession, rule1, rule2, rule3);

    db.activeRuleDao()
        .insert(
            dbSession,
            ActiveRuleDto.createFor(qualityProfileDto1, rule1).setSeverity("BLOCKER"),
            ActiveRuleDto.createFor(qualityProfileDto2, rule1).setSeverity("BLOCKER"),
            ActiveRuleDto.createFor(qualityProfileDto1, rule2).setSeverity("BLOCKER"));
    dbSession.commit();
    dbSession.clearCache();

    // 1. get all active rules.
    Result<Rule> result = index.search(new RuleQuery().setActivation(true), new QueryContext());
    assertThat(result.getHits()).hasSize(2);

    // 2. get all inactive rules.
    result = index.search(new RuleQuery().setActivation(false), new QueryContext());
    assertThat(result.getHits()).hasSize(1);
    assertThat(result.getHits().get(0).name()).isEqualTo(rule3.getName());

    // 3. get all rules not active on profile
    index.search(
        new RuleQuery().setActivation(false).setQProfileKey(qualityProfileDto2.getKey()),
        new QueryContext());
    // TODO
    assertThat(result.getHits()).hasSize(1);

    // 4. get all active rules on profile
    result =
        index.search(
            new RuleQuery().setActivation(true).setQProfileKey(qualityProfileDto2.getKey()),
            new QueryContext());
    assertThat(result.getHits()).hasSize(1);
    assertThat(result.getHits().get(0).name()).isEqualTo(rule1.getName());
  }
  private ActiveRuleDto persist(
      ActiveRuleChange change, RuleActivatorContext context, DbSession dbSession) {
    ActiveRuleDao dao = db.activeRuleDao();
    ActiveRuleDto activeRule = null;
    if (change.getType() == ActiveRuleChange.Type.ACTIVATED) {
      activeRule = ActiveRuleDto.createFor(context.profile(), context.rule());
      activeRule.setSeverity(change.getSeverity());
      if (change.getInheritance() != null) {
        activeRule.setInheritance(change.getInheritance().name());
      }
      dao.insert(dbSession, activeRule);
      for (Map.Entry<String, String> param : change.getParameters().entrySet()) {
        if (param.getValue() != null) {
          ActiveRuleParamDto paramDto =
              ActiveRuleParamDto.createFor(context.ruleParamsByKeys().get(param.getKey()));
          paramDto.setValue(param.getValue());
          dao.addParam(dbSession, activeRule, paramDto);
        }
      }

    } else if (change.getType() == ActiveRuleChange.Type.DEACTIVATED) {
      dao.deleteByKey(dbSession, change.getKey());

    } else if (change.getType() == ActiveRuleChange.Type.UPDATED) {
      activeRule = context.activeRule();
      activeRule.setSeverity(change.getSeverity());
      if (change.getInheritance() != null) {
        activeRule.setInheritance(change.getInheritance().name());
      }
      dao.update(dbSession, activeRule);

      for (Map.Entry<String, String> param : change.getParameters().entrySet()) {
        ActiveRuleParamDto activeRuleParamDto = context.activeRuleParamsAsMap().get(param.getKey());
        if (activeRuleParamDto == null) {
          // did not exist
          if (param.getValue() != null) {
            activeRuleParamDto =
                ActiveRuleParamDto.createFor(context.ruleParamsByKeys().get(param.getKey()));
            activeRuleParamDto.setValue(param.getValue());
            dao.addParam(dbSession, activeRule, activeRuleParamDto);
          }
        } else {
          if (param.getValue() != null) {
            activeRuleParamDto.setValue(param.getValue());
            dao.updateParam(dbSession, activeRule, activeRuleParamDto);
          } else {
            dao.deleteParam(dbSession, activeRule, activeRuleParamDto);
          }
        }
      }
    }

    return activeRule;
  }
  @Test
  public void search_by_profile_and_inheritance() throws InterruptedException {
    QualityProfileDto qualityProfileDto1 = QProfileTesting.newXooP1();
    QualityProfileDto qualityProfileDto2 =
        QProfileTesting.newXooP2().setParentKee(QProfileTesting.XOO_P1_KEY);
    db.qualityProfileDao().insert(dbSession, qualityProfileDto1, qualityProfileDto2);

    RuleDto rule1 = RuleTesting.newDto(RuleKey.of("xoo", "S001"));
    RuleDto rule2 = RuleTesting.newDto(RuleKey.of("xoo", "S002"));
    RuleDto rule3 = RuleTesting.newDto(RuleKey.of("xoo", "S003"));
    RuleDto rule4 = RuleTesting.newDto(RuleKey.of("xoo", "S004"));
    dao.insert(dbSession, rule1, rule2, rule3, rule4);

    db.activeRuleDao()
        .insert(
            dbSession,
            ActiveRuleDto.createFor(qualityProfileDto1, rule1).setSeverity("BLOCKER"),
            ActiveRuleDto.createFor(qualityProfileDto1, rule2).setSeverity("BLOCKER"),
            ActiveRuleDto.createFor(qualityProfileDto1, rule3).setSeverity("BLOCKER"),
            ActiveRuleDto.createFor(qualityProfileDto2, rule1)
                .setSeverity("MINOR")
                .setInheritance(ActiveRule.Inheritance.INHERITED.name()),
            ActiveRuleDto.createFor(qualityProfileDto2, rule2)
                .setSeverity("BLOCKER")
                .setInheritance(ActiveRule.Inheritance.OVERRIDES.name()),
            ActiveRuleDto.createFor(qualityProfileDto2, rule3)
                .setSeverity("BLOCKER")
                .setInheritance(ActiveRule.Inheritance.INHERITED.name()));

    dbSession.commit();

    // 0. get all rules
    Result<Rule> result = index.search(new RuleQuery(), new QueryContext());
    assertThat(result.getHits()).hasSize(4);

    // 1. get all active rules
    result = index.search(new RuleQuery().setActivation(true), new QueryContext());
    assertThat(result.getHits()).hasSize(3);

    // 2. get all inactive rules.
    result = index.search(new RuleQuery().setActivation(false), new QueryContext());
    assertThat(result.getHits()).hasSize(1);
    assertThat(result.getHits().get(0).name()).isEqualTo(rule4.getName());

    // 3. get Inherited Rules on profile1
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto1.getKey())
                .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.INHERITED.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(0);

    // 4. get Inherited Rules on profile2
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto2.getKey())
                .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.INHERITED.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(2);

    // 5. get Overridden Rules on profile1
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto1.getKey())
                .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.OVERRIDES.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(0);

    // 6. get Overridden Rules on profile2
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto2.getKey())
                .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.OVERRIDES.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(1);

    // 7. get Inherited AND Overridden Rules on profile1
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto1.getKey())
                .setInheritance(
                    ImmutableSet.of(
                        ActiveRule.Inheritance.INHERITED.name(),
                        ActiveRule.Inheritance.OVERRIDES.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(0);

    // 8. get Inherited AND Overridden Rules on profile2
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto2.getKey())
                .setInheritance(
                    ImmutableSet.of(
                        ActiveRule.Inheritance.INHERITED.name(),
                        ActiveRule.Inheritance.OVERRIDES.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(3);
  }