@Test
  public void reactivate_disabled_custom_rules() {
    Rule templateRule = index.getByKey(RuleKey.of("xoo", "template1"));

    // Create custom rule
    RuleKey customRuleKey =
        tester
            .get(RuleCreator.class)
            .create(
                NewRule.createForCustomRule("CUSTOM_RULE", templateRule.key())
                    .setName("My custom")
                    .setHtmlDescription("Some description")
                    .setSeverity(Severity.MAJOR)
                    .setStatus(RuleStatus.READY));
    dbSession.commit();
    dbSession.clearCache();
    assertThat(index.getByKey(customRuleKey).status()).isEqualTo(RuleStatus.READY);

    // Restart without template rule
    rulesDefinition.includeTemplate1 = false;
    tester.get(Platform.class).executeStartupTasks();
    dbSession.clearCache();

    // Verify custom rule is removed
    assertThat(index.getByKey(customRuleKey).status()).isEqualTo(RuleStatus.REMOVED);

    // Restart with template rule
    rulesDefinition.includeTemplate1 = true;
    tester.get(Platform.class).executeStartupTasks();
    dbSession.clearCache();

    // Verify custom rule is reactivate
    assertThat(index.getByKey(customRuleKey).status()).isEqualTo(RuleStatus.READY);
  }
  @Test
  public void not_update_custom_rule_from_template_if_no_change() throws Exception {
    Rule templateRule = index.getByKey(RuleKey.of("xoo", "template1"));

    // Create custom rule
    RuleKey customRuleKey =
        tester
            .get(RuleCreator.class)
            .create(
                NewRule.createForCustomRule("CUSTOM_RULE", templateRule.key())
                    .setName("My custom")
                    .setHtmlDescription("Some description")
                    .setSeverity(Severity.MAJOR)
                    .setStatus(RuleStatus.READY)
                    .setParameters(ImmutableMap.of("format", "txt")));
    dbSession.commit();
    dbSession.clearCache();

    // Store updated at date
    Date updatedAt = index.getByKey(customRuleKey).updatedAt();

    // Re-execute startup tasks
    tester.get(Platform.class).executeStartupTasks();

    // Verify custom rule has not been updated
    Rule customRuleReloaded = index.getByKey(customRuleKey);
    assertThat(customRuleReloaded.updatedAt()).isEqualTo(updatedAt);
  }
  @Test
  public void update_custom_rule_from_template() throws Exception {
    Rule templateRule = index.getByKey(RuleKey.of("xoo", "template1"));

    // Create custom rule
    RuleKey customRuleKey =
        tester
            .get(RuleCreator.class)
            .create(
                NewRule.createForCustomRule("CUSTOM_RULE", templateRule.key())
                    .setName("My custom")
                    .setHtmlDescription("Some description")
                    .setSeverity(Severity.MAJOR)
                    .setStatus(RuleStatus.READY)
                    .setParameters(ImmutableMap.of("format", "txt")));

    // Update custom rule
    RuleDto customRuleDto = db.ruleDao().getByKey(dbSession, customRuleKey);
    db.ruleDao()
        .update(
            dbSession,
            customRuleDto
                .setLanguage("other language")
                .setConfigKey("other config key")
                .setDefaultSubCharacteristicId(45)
                .setDefaultRemediationFunction("LINEAR_OFFSET")
                .setDefaultRemediationCoefficient("1h")
                .setDefaultRemediationOffset("5min")
                .setEffortToFixDescription("effort to fix desc"));
    dbSession.commit();
    dbSession.clearCache();

    // Re-execute startup tasks
    tester.get(Platform.class).executeStartupTasks();

    // Verify custom rule has been restore from the template
    Rule customRule = index.getByKey(customRuleKey);
    assertThat(customRule.language()).isEqualTo("xoo");
    assertThat(customRule.internalKey()).isNull();
    assertThat(customRule.debtSubCharacteristicKey()).isNull();
    assertThat(customRule.debtRemediationFunction()).isNull();
  }
  @Test
  public void not_update_custom_rule_params_from_template() throws Exception {
    Rule templateRule = index.getByKey(RuleKey.of("xoo", "template1"));

    // Create custom rule
    RuleKey customRuleKey =
        tester
            .get(RuleCreator.class)
            .create(
                NewRule.createForCustomRule("CUSTOM_RULE", templateRule.key())
                    .setName("My custom")
                    .setHtmlDescription("Some description")
                    .setSeverity(Severity.MAJOR)
                    .setStatus(RuleStatus.READY)
                    .setParameters(ImmutableMap.of("format", "txt")));
    dbSession.commit();
    dbSession.clearCache();

    // Update custom rule param name
    RuleDto customRuleDto = db.ruleDao().getByKey(dbSession, customRuleKey);
    RuleParamDto customRuleParamDto =
        db.ruleDao().findRuleParamsByRuleKey(dbSession, customRuleKey).get(0);
    db.ruleDao().removeRuleParam(dbSession, customRuleDto, customRuleParamDto);
    db.ruleDao().addRuleParam(dbSession, customRuleDto, customRuleParamDto.setName("format2"));
    dbSession.commit();
    dbSession.clearCache();

    // Verify param has been updated
    Rule customRule = index.getByKey(customRuleKey);
    assertThat(customRule.params()).hasSize(1);
    assertThat(customRule.params().get(0).key()).isEqualTo("format2");

    // Re-execute startup tasks
    tester.get(Platform.class).executeStartupTasks();

    // Verify custom rule param has not been changed!
    Rule customRuleReloaded = index.getByKey(customRuleKey);
    assertThat(customRuleReloaded.params().get(0).key()).isEqualTo("format2");
  }
  @Test
  public void remove_end_user_tags_that_are_declared_as_system() {
    verifyRulesInDb();

    Rule rule = index.getByKey(RuleTesting.XOO_X1);
    assertThat(rule.systemTags()).contains("tag1");
    assertThat(rule.tags()).isEmpty();

    // Add a user tag
    tester
        .get(RuleUpdater.class)
        .update(
            RuleUpdate.createForPluginRule(rule.key()).setTags(newHashSet("user-tag")),
            UserSession.get());
    dbSession.clearCache();

    // Verify tags
    Rule ruleUpdated = index.getByKey(RuleTesting.XOO_X1);
    assertThat(ruleUpdated.systemTags()).contains("tag1");
    assertThat(ruleUpdated.tags()).contains("user-tag");

    // The plugin X1 will be updated
    rulesDefinition.includeX1 = false;
    rulesDefinition.includeX1bis = true;
    tester.get(Platform.class).executeStartupTasks();
    dbSession.clearCache();

    // User tag should become a system tag
    RuleDto ruleDtoReloaded = db.ruleDao().getByKey(dbSession, RuleTesting.XOO_X1);
    assertThat(ruleDtoReloaded.getSystemTags()).contains("tag1", "tag2", "user-tag");
    assertThat(ruleDtoReloaded.getTags()).isEmpty();

    // User tag should become a system tag
    Rule ruleReloaded = index.getByKey(RuleTesting.XOO_X1);
    assertThat(ruleReloaded.systemTags()).contains("tag1", "tag2", "user-tag");
    assertThat(ruleReloaded.tags()).isEmpty();
  }