]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5056 When reseting debt model, restore rules from rule definitions in order...
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 2 Apr 2014 14:38:25 +0000 (16:38 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 2 Apr 2014 14:38:34 +0000 (16:38 +0200)
sonar-server/src/main/java/org/sonar/server/debt/DebtModelBackup.java
sonar-server/src/main/java/org/sonar/server/debt/DebtModelOperations.java
sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java
sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java
sonar-server/src/test/java/org/sonar/server/debt/DebtModelOperationsTest.java

index 4cbe40bfdb76fe1feee40ae2d01c0209ae846d96..5ea075a0fc2e6192982d44312607acb5e5f6dc89 100644 (file)
@@ -31,6 +31,7 @@ import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.debt.DebtCharacteristic;
 import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic;
+import org.sonar.api.server.rule.RulesDefinition;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.ValidationMessages;
 import org.sonar.core.permission.GlobalPermissions;
@@ -39,6 +40,7 @@ import org.sonar.core.rule.RuleDao;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.core.technicaldebt.db.CharacteristicDao;
 import org.sonar.core.technicaldebt.db.CharacteristicDto;
+import org.sonar.server.rule.RuleDefinitionsLoader;
 import org.sonar.server.rule.RuleRegistry;
 import org.sonar.server.user.UserSession;
 
@@ -64,19 +66,20 @@ public class DebtModelBackup implements ServerComponent {
   private final DebtRulesXMLImporter rulesXMLImporter;
   private final DebtModelXMLExporter debtModelXMLExporter;
   private final RuleRegistry ruleRegistry;
+  private final RuleDefinitionsLoader defLoader;
   private final System2 system2;
 
   public DebtModelBackup(MyBatis mybatis, CharacteristicDao dao, RuleDao ruleDao, DebtModelOperations debtModelOperations, DebtModelPluginRepository debtModelPluginRepository,
                          DebtCharacteristicsXMLImporter characteristicsXMLImporter, DebtRulesXMLImporter rulesXMLImporter,
-                         DebtModelXMLExporter debtModelXMLExporter, RuleRegistry ruleRegistry) {
-    this(mybatis, dao, ruleDao, debtModelOperations, debtModelPluginRepository, characteristicsXMLImporter, rulesXMLImporter, debtModelXMLExporter, ruleRegistry,
+                         DebtModelXMLExporter debtModelXMLExporter, RuleRegistry ruleRegistry, RuleDefinitionsLoader defLoader) {
+    this(mybatis, dao, ruleDao, debtModelOperations, debtModelPluginRepository, characteristicsXMLImporter, rulesXMLImporter, debtModelXMLExporter, ruleRegistry, defLoader,
       System2.INSTANCE);
   }
 
   @VisibleForTesting
   DebtModelBackup(MyBatis mybatis, CharacteristicDao dao, RuleDao ruleDao, DebtModelOperations debtModelOperations, DebtModelPluginRepository debtModelPluginRepository,
-                  DebtCharacteristicsXMLImporter characteristicsXMLImporter, DebtRulesXMLImporter rulesXMLImporter,DebtModelXMLExporter debtModelXMLExporter,
-                  RuleRegistry ruleRegistry, System2 system2) {
+                  DebtCharacteristicsXMLImporter characteristicsXMLImporter, DebtRulesXMLImporter rulesXMLImporter, DebtModelXMLExporter debtModelXMLExporter,
+                  RuleRegistry ruleRegistry, RuleDefinitionsLoader defLoader, System2 system2) {
     this.mybatis = mybatis;
     this.dao = dao;
     this.ruleDao = ruleDao;
@@ -86,6 +89,7 @@ public class DebtModelBackup implements ServerComponent {
     this.rulesXMLImporter = rulesXMLImporter;
     this.debtModelXMLExporter = debtModelXMLExporter;
     this.ruleRegistry = ruleRegistry;
+    this.defLoader = defLoader;
     this.system2 = system2;
   }
 
@@ -133,18 +137,36 @@ public class DebtModelBackup implements ServerComponent {
    * Reset from provided model
    */
   public void reset() {
-    restoreProvidedModel();
-  }
-
-  private void restoreProvidedModel() {
     checkPermission();
 
     Date updateDate = new Date(system2.now());
     SqlSession session = mybatis.openSession();
     try {
-      restoreCharacteristics(loadModelFromPlugin(DebtModelPluginRepository.DEFAULT_MODEL), true, updateDate, session);
+      // Restore characteristics
+      List<CharacteristicDto> allCharacteristicDtos = restoreCharacteristics(loadModelFromPlugin(DebtModelPluginRepository.DEFAULT_MODEL), true, updateDate, session);
+
+      // Load default rule definitions
+      RulesDefinition.Context context = defLoader.load();
+      List<RulesDefinition.Rule> rules = newArrayList();
+      for (RulesDefinition.Repository repoDef : context.repositories()) {
+        rules.addAll(repoDef.rules());
+      }
+
+      // Restore rules
       List<RuleDto> ruleDtos = rules(null, session);
       for (RuleDto rule : ruleDtos) {
+        // Restore default debt definitions
+        RulesDefinition.Rule ruleDef = ruleDef(rule, rules);
+        String subCharacteristicKey = ruleDef.debtSubCharacteristic();
+        CharacteristicDto subCharacteristicDto = characteristicByKey(subCharacteristicKey, allCharacteristicDtos);
+        DebtRemediationFunction remediationFunction = ruleDef.debtRemediationFunction();
+        boolean hasDebtDefinition = subCharacteristicDto != null && remediationFunction != null;
+        rule.setDefaultSubCharacteristicId(hasDebtDefinition ? subCharacteristicDto.getId() : null);
+        rule.setDefaultRemediationFunction(hasDebtDefinition ? remediationFunction.type().name() : null);
+        rule.setDefaultRemediationCoefficient(hasDebtDefinition ? remediationFunction.coefficient() : null);
+        rule.setDefaultRemediationOffset(hasDebtDefinition ? remediationFunction.offset() : null);
+
+        // Reset overridden debt definitions
         rule.setSubCharacteristicId(null);
         rule.setRemediationFunction(null);
         rule.setRemediationCoefficient(null);
@@ -193,7 +215,7 @@ public class DebtModelBackup implements ServerComponent {
   private void restoreRules(List<CharacteristicDto> allCharacteristicDtos, List<RuleDto> rules, List<RuleDebt> ruleDebts,
                             ValidationMessages validationMessages, Date updateDate, SqlSession session) {
     for (RuleDto rule : rules) {
-      RuleDebt ruleDebt = ruleDebtByRule(rule, ruleDebts);
+      RuleDebt ruleDebt = ruleDebt(rule, ruleDebts);
       if (ruleDebt == null) {
         // rule does not exists in the XML
         disabledOverriddenRuleDebt(rule);
@@ -261,9 +283,11 @@ public class DebtModelBackup implements ServerComponent {
     } else {
       // Update only if modifications
       if (ObjectUtils.notEqual(sourceCharacteristic.getName(), targetCharacteristic.name()) ||
-        ObjectUtils.notEqual(sourceCharacteristic.getOrder(), targetCharacteristic.order())) {
+        ObjectUtils.notEqual(sourceCharacteristic.getOrder(), targetCharacteristic.order()) ||
+        ObjectUtils.notEqual(sourceCharacteristic.getParentId(), parentId)) {
         sourceCharacteristic.setName(targetCharacteristic.name());
         sourceCharacteristic.setOrder(targetCharacteristic.order());
+        sourceCharacteristic.setParentId(parentId);
         sourceCharacteristic.setUpdatedAt(updateDate);
         dao.update(sourceCharacteristic, session);
       }
@@ -311,7 +335,7 @@ public class DebtModelBackup implements ServerComponent {
   }
 
   @CheckForNull
-  private static RuleDebt ruleDebtByRule(final RuleDto rule, List<RuleDebt> ruleDebts) {
+  private static RuleDebt ruleDebt(final RuleDto rule, List<RuleDebt> ruleDebts) {
     if (ruleDebts.isEmpty()) {
       return null;
     }
@@ -323,8 +347,20 @@ public class DebtModelBackup implements ServerComponent {
     }, null);
   }
 
+  private static RulesDefinition.Rule ruleDef(final RuleDto rule, List<RulesDefinition.Rule> rules) {
+    return Iterables.find(rules, new Predicate<RulesDefinition.Rule>() {
+      @Override
+      public boolean apply(@Nullable RulesDefinition.Rule input) {
+        return input != null && rule.getRepositoryKey().equals(input.repository().key()) && rule.getRuleKey().equals(input.key());
+      }
+    });
+  }
+
   @CheckForNull
-  private static CharacteristicDto characteristicByKey(final String key, List<CharacteristicDto> characteristicDtos) {
+  private static CharacteristicDto characteristicByKey(@Nullable final String key, List<CharacteristicDto> characteristicDtos) {
+    if (key == null) {
+      return null;
+    }
     return Iterables.find(characteristicDtos, new Predicate<CharacteristicDto>() {
       @Override
       public boolean apply(@Nullable CharacteristicDto input) {
index 8d703c0adcb1710e6d276a7407993121d763fd10..fb30b883097a5808554c61d63bde81eb0437d53a 100644 (file)
@@ -170,7 +170,7 @@ public class DebtModelOperations implements ServerComponent {
 
   @CheckForNull
   private CharacteristicDto findCharacteristicToSwitchWith(final CharacteristicDto dto, final boolean moveUpOrDown, SqlSession session) {
-    // characteristics should be order by 'order'
+    // characteristics should be sort by 'order'
     List<CharacteristicDto> rootCharacteristics = dao.selectEnabledRootCharacteristics(session);
     int currentPosition = Iterables.indexOf(rootCharacteristics, new Predicate<CharacteristicDto>() {
       @Override
@@ -234,7 +234,7 @@ public class DebtModelOperations implements ServerComponent {
   public void disableRulesDebt(List<RuleDto> ruleDtos, Integer subCharacteristicId, Date updateDate, SqlSession session) {
     for (RuleDto ruleDto : ruleDtos) {
       if (subCharacteristicId.equals(ruleDto.getSubCharacteristicId())) {
-        ruleDto.setSubCharacteristicId(null);
+        ruleDto.setSubCharacteristicId(RuleDto.DISABLED_CHARACTERISTIC_ID);
         ruleDto.setRemediationFunction(null);
         ruleDto.setRemediationCoefficient(null);
         ruleDto.setRemediationOffset(null);
index a97618d7b5baa4c0747d31660b55d24cad4a795b..73e14c715303e365581bca9f958b7ef49efbb2e8 100644 (file)
@@ -257,6 +257,8 @@ class ServerComponents {
     pico.addSingleton(RuleRegistry.class);
     pico.addSingleton(RubyRuleService.class);
     pico.addSingleton(RuleRepositories.class);
+    pico.addSingleton(DeprecatedRulesDefinition.class);
+    pico.addSingleton(RuleDefinitionsLoader.class);
     pico.addSingleton(RulesWs.class);
     pico.addSingleton(RuleShowWsHandler.class);
     pico.addSingleton(RuleSearchWsHandler.class);
@@ -398,8 +400,6 @@ class ServerComponents {
     startupContainer.addSingleton(GwtPublisher.class);
     startupContainer.addSingleton(RegisterMetrics.class);
     startupContainer.addSingleton(RegisterQualityGates.class);
-    startupContainer.addSingleton(DeprecatedRulesDefinition.class);
-    startupContainer.addSingleton(RuleDefinitionsLoader.class);
     startupContainer.addSingleton(RegisterRules.class);
     startupContainer.addSingleton(RegisterQualityProfiles.class);
     startupContainer.addSingleton(JdbcDriverDeployer.class);
index b441f3048e25c8c6ad9c639d8fdd054d848a964b..89db8d2154400bf70a27554c4faee70f0673d2b6 100644 (file)
@@ -259,21 +259,21 @@ public class RegisterRules implements Startable {
       dto.setLanguage(def.repository().language());
       changed = true;
     }
-    CharacteristicDto characteristic = buffer.characteristic(def.debtSubCharacteristic(), def.repository().key(), def.key(), dto.getSubCharacteristicId());
-    changed = mergeDebtDefinitions(def, dto, characteristic) || changed;
+    CharacteristicDto subCharacteristic = buffer.characteristic(def.debtSubCharacteristic(), def.repository().key(), def.key(), dto.getSubCharacteristicId());
+    changed = mergeDebtDefinitions(def, dto, subCharacteristic) || changed;
     if (changed) {
       dto.setUpdatedAt(buffer.now());
     }
     return changed;
   }
 
-  private boolean mergeDebtDefinitions(RulesDefinition.Rule def, RuleDto dto, @Nullable CharacteristicDto characteristic) {
+  private boolean mergeDebtDefinitions(RulesDefinition.Rule def, RuleDto dto, @Nullable CharacteristicDto subCharacteristic) {
     boolean changed = false;
 
-    // Debt definitions are set to null if the characteristic is null or unknown
-    boolean hasCharacteristic = characteristic != null;
+    // Debt definitions are set to null if the sub-characteristic is null or unknown
+    boolean hasCharacteristic = subCharacteristic != null;
     DebtRemediationFunction debtRemediationFunction = hasCharacteristic ? def.debtRemediationFunction() : null;
-    Integer characteristicId = hasCharacteristic ? characteristic.getId() : null;
+    Integer characteristicId = hasCharacteristic ? subCharacteristic.getId() : null;
     String remediationFactor = hasCharacteristic ? debtRemediationFunction.coefficient() : null;
     String remediationOffset = hasCharacteristic ? debtRemediationFunction.offset() : null;
     String effortToFixDescription = hasCharacteristic ? def.effortToFixDescription() : null;
index f6b76645cfb62ebe61984263811aa8f54b1c1abc..50a2915876c9a238cc578d8f61b8d0dd7eb41828 100644 (file)
@@ -31,8 +31,11 @@ import org.mockito.invocation.InvocationOnMock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
 import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rule.Severity;
 import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.server.debt.internal.DefaultDebtCharacteristic;
+import org.sonar.api.server.rule.RulesDefinition;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.ValidationMessages;
@@ -42,6 +45,7 @@ import org.sonar.core.rule.RuleDao;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.core.technicaldebt.db.CharacteristicDao;
 import org.sonar.core.technicaldebt.db.CharacteristicDto;
+import org.sonar.server.rule.RuleDefinitionsLoader;
 import org.sonar.server.rule.RuleRegistry;
 import org.sonar.server.user.MockUserSession;
 
@@ -92,6 +96,9 @@ public class DebtModelBackupTest {
   @Mock
   RuleRegistry ruleRegistry;
 
+  @Mock
+  RuleDefinitionsLoader defLoader;
+
   @Mock
   System2 system2;
 
@@ -134,7 +141,7 @@ public class DebtModelBackupTest {
     when(debtModelPluginRepository.createReaderForXMLFile("technical-debt")).thenReturn(defaultModelReader);
 
     debtModelBackup = new DebtModelBackup(myBatis, dao, ruleDao, debtModelOperations, debtModelPluginRepository, characteristicsXMLImporter, rulesXMLImporter,
-      debtModelXMLExporter, ruleRegistry, system2);
+      debtModelXMLExporter, ruleRegistry, defLoader, system2);
   }
 
   @Test
@@ -271,6 +278,7 @@ public class DebtModelBackupTest {
   @Test
   public void update_characteristics_when_restoring_characteristics() throws Exception {
     when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList(
+      // Order and name have changed
       new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability updated").setOrder(2).setCreatedAt(oldDate).setUpdatedAt(oldDate),
       new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler updated").setParentId(1).setCreatedAt(oldDate).setUpdatedAt(oldDate)
     ));
@@ -305,6 +313,38 @@ public class DebtModelBackupTest {
     assertThat(dto2.getUpdatedAt()).isEqualTo(now);
   }
 
+  @Test
+  public void update_parent_when_restoring_characteristics() throws Exception {
+    when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList(
+      // Parent has changed
+      new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability updated").setParentId(1).setOrder(1).setCreatedAt(oldDate).setUpdatedAt(oldDate),
+      new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler updated").setCreatedAt(oldDate).setUpdatedAt(oldDate)
+    ));
+
+    debtModelBackup.restoreCharacteristics(
+      new DebtModel()
+        .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1))
+        .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"),
+      true,
+      now,
+      session
+    );
+
+    verify(dao, times(2)).update(characteristicCaptor.capture(), eq(session));
+
+    CharacteristicDto dto1 = characteristicCaptor.getAllValues().get(0);
+    assertThat(dto1.getId()).isEqualTo(1);
+    assertThat(dto1.getKey()).isEqualTo("PORTABILITY");
+    assertThat(dto1.getParentId()).isNull();
+    assertThat(dto1.getUpdatedAt()).isEqualTo(now);
+
+    CharacteristicDto dto2 = characteristicCaptor.getAllValues().get(1);
+    assertThat(dto2.getId()).isEqualTo(2);
+    assertThat(dto2.getKey()).isEqualTo("COMPILER");
+    assertThat(dto2.getParentId()).isEqualTo(1);
+    assertThat(dto2.getUpdatedAt()).isEqualTo(now);
+  }
+
   @Test
   public void disable_no_more_existing_characteristics_when_restoring_characteristics() throws Exception {
     CharacteristicDto dto1 = new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability").setOrder(1);
@@ -319,7 +359,7 @@ public class DebtModelBackupTest {
   }
 
   @Test
-  public void reset_from_provided_model() throws Exception {
+  public void reset_model() throws Exception {
     when(characteristicsXMLImporter.importXML(any(Reader.class))).thenReturn(new DebtModel()
       .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1))
       .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"));
@@ -330,10 +370,24 @@ public class DebtModelBackupTest {
     ));
 
     when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList(
-      new RuleDto().setRepositoryKey("squid").setSubCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("15min")
+      new RuleDto().setRepositoryKey("squid").setRuleKey("NPE")
+        .setDefaultSubCharacteristicId(10).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("2h")
+        .setSubCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("15min")
         .setCreatedAt(oldDate).setUpdatedAt(oldDate)
     ));
 
+    RulesDefinition.Context context = new RulesDefinition.Context();
+    RulesDefinition.NewRepository repo = context.createRepository("squid", "java").setName("Squid");
+    RulesDefinition.NewRule newRule = repo.createRule("NPE")
+      .setName("Detect NPE")
+      .setHtmlDescription("Detect <code>java.lang.NullPointerException</code>")
+      .setSeverity(Severity.BLOCKER)
+      .setStatus(RuleStatus.BETA)
+      .setDebtSubCharacteristic("COMPILER");
+    newRule.setDebtRemediationFunction(newRule.debtRemediationFunctions().linearWithOffset("4h", "20min"));
+    repo.done();
+    when(defLoader.load()).thenReturn(context);
+
     debtModelBackup.reset();
 
     verify(dao).selectEnabledCharacteristics(session);
@@ -348,6 +402,13 @@ public class DebtModelBackupTest {
     verify(session).commit();
 
     RuleDto rule = ruleCaptor.getValue();
+
+    assertThat(rule.getDefaultSubCharacteristicId()).isEqualTo(2);
+    assertThat(rule.getDefaultRemediationFunction()).isEqualTo("LINEAR_OFFSET");
+    assertThat(rule.getDefaultRemediationCoefficient()).isEqualTo("4h");
+    assertThat(rule.getDefaultRemediationOffset()).isEqualTo("20min");
+    assertThat(rule.getUpdatedAt()).isEqualTo(now);
+
     assertThat(rule.getSubCharacteristicId()).isNull();
     assertThat(rule.getRemediationFunction()).isNull();
     assertThat(rule.getRemediationCoefficient()).isNull();
@@ -355,6 +416,55 @@ public class DebtModelBackupTest {
     assertThat(rule.getUpdatedAt()).isEqualTo(now);
   }
 
+  @Test
+  public void reset_model_when_no_default_value() throws Exception {
+    when(characteristicsXMLImporter.importXML(any(Reader.class))).thenReturn(new DebtModel()
+      .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1))
+      .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"));
+
+    when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList(
+      new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability updated").setOrder(2).setCreatedAt(oldDate),
+      new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler updated").setParentId(1).setCreatedAt(oldDate)
+    ));
+
+    when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList(
+      new RuleDto().setRepositoryKey("squid").setRuleKey("NPE")
+        .setDefaultSubCharacteristicId(10).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("2h")
+        .setSubCharacteristicId(2).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("15min")
+        .setCreatedAt(oldDate).setUpdatedAt(oldDate)
+    ));
+
+    RulesDefinition.Context context = new RulesDefinition.Context();
+    RulesDefinition.NewRepository repo = context.createRepository("squid", "java").setName("Squid");
+    repo.createRule("NPE")
+      .setName("Detect NPE")
+      .setHtmlDescription("Detect <code>java.lang.NullPointerException</code>")
+      .setSeverity(Severity.BLOCKER)
+      .setStatus(RuleStatus.BETA);
+    repo.done();
+    when(defLoader.load()).thenReturn(context);
+
+    debtModelBackup.reset();
+
+    verify(dao).selectEnabledCharacteristics(session);
+    verify(dao, times(2)).update(any(CharacteristicDto.class), eq(session));
+    verifyNoMoreInteractions(dao);
+
+    verify(ruleDao).selectEnablesAndNonManual(session);
+    verify(ruleDao).update(ruleCaptor.capture(), eq(session));
+    verifyNoMoreInteractions(ruleDao);
+    verify(ruleRegistry).reindex(ruleCaptor.getAllValues(), session);
+
+    verify(session).commit();
+
+    RuleDto rule = ruleCaptor.getValue();
+    assertThat(rule.getDefaultSubCharacteristicId()).isNull();
+    assertThat(rule.getDefaultRemediationFunction()).isNull();
+    assertThat(rule.getDefaultRemediationCoefficient()).isNull();
+    assertThat(rule.getDefaultRemediationOffset()).isNull();
+    assertThat(rule.getUpdatedAt()).isEqualTo(now);
+  }
+
   @Test
   public void restore_from_xml_with_different_characteristic_and_same_function() throws Exception {
     when(characteristicsXMLImporter.importXML(anyString())).thenReturn(new DebtModel()
index 41a8077417ad3ec4857a2046955858e629853a5f..baf1f8bd0603439c67e9151639ec04fa8a58c976 100644 (file)
@@ -363,7 +363,7 @@ public class DebtModelOperationsTest {
     assertThat(ruleDto.getUpdatedAt()).isEqualTo(now);
 
     // Overridden debt data are disabled
-    assertThat(ruleDto.getSubCharacteristicId()).isNull();
+    assertThat(ruleDto.getSubCharacteristicId()).isEqualTo(-1);
     assertThat(ruleDto.getRemediationFunction()).isNull();
     assertThat(ruleDto.getRemediationCoefficient()).isNull();
     assertThat(ruleDto.getRemediationOffset()).isNull();