@Test public void testBlame() throws IOException { File source = new File(baseDir, "src/foo.xoo"); FileUtils.write(source, "sample content"); File scm = new File(baseDir, "src/foo.xoo.scm"); FileUtils.write(scm, "123,julien,2014-12-12\n234,julien,2014-12-24"); DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage(Xoo.KEY); fs.add(inputFile); BlameOutput result = mock(BlameOutput.class); when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile)); new XooBlameCommand().blame(input, result); verify(result) .blameResult( inputFile, Arrays.asList( new BlameLine() .revision("123") .author("julien") .date(DateUtils.parseDate("2014-12-12")), new BlameLine() .revision("234") .author("julien") .date(DateUtils.parseDate("2014-12-24")))); }
public Settings setProperty(String key, @Nullable Date date, boolean includeTime) { if (date == null) { return removeProperty(key); } return setProperty( key, includeTime ? DateUtils.formatDateTime(date) : DateUtils.formatDate(date)); }
@Test public void get_last_snapshot_by_component_uuid() { setupData("get_last_snapshot_by_component_uuid"); SnapshotDto snapshotDto = dao.getLastSnapshotByResourceUuid("ABCD", session); assertThat(snapshotDto.getId()).isEqualTo(1); assertThat(snapshotDto.getPeriodMode(1)).isEqualTo("previous_analysis"); assertThat(snapshotDto.getPeriodModeParameter(1)).isNull(); assertThat(snapshotDto.getPeriodDate(1)).isNull(); assertThat(snapshotDto.getPeriodMode(2)).isEqualTo("days"); assertThat(snapshotDto.getPeriodModeParameter(2)).isEqualTo("30"); assertThat(snapshotDto.getPeriodDate(2)).isEqualTo(DateUtils.parseDate("2011-09-24").getTime()); assertThat(snapshotDto.getPeriodMode(3)).isEqualTo("days"); assertThat(snapshotDto.getPeriodModeParameter(3)).isEqualTo("90"); assertThat(snapshotDto.getPeriodDate(3)).isEqualTo(DateUtils.parseDate("2011-07-26").getTime()); assertThat(snapshotDto.getPeriodMode(4)).isEqualTo("previous_analysis"); assertThat(snapshotDto.getPeriodModeParameter(4)).isNull(); assertThat(snapshotDto.getPeriodDate(4)).isNull(); assertThat(snapshotDto.getPeriodMode(5)).isEqualTo("previous_version"); assertThat(snapshotDto.getPeriodModeParameter(5)).isNull(); assertThat(snapshotDto.getPeriodDate(5)).isNull(); snapshotDto = dao.getLastSnapshotByResourceUuid("EFGH", session); assertThat(snapshotDto.getId()).isEqualTo(2L); snapshotDto = dao.getLastSnapshotByResourceUuid("GHIJ", session); assertThat(snapshotDto.getId()).isEqualTo(3L); assertThat(dao.getLastSnapshotByResourceUuid("UNKNOWN", session)).isNull(); }
private void writeChangelog(Issue issue, JsonWriter json) { json.name("changelog") .beginArray() .beginObject() .prop("creationDate", DateUtils.formatDateTime(issue.creationDate())) .prop("fCreationDate", formatDate(issue.creationDate())) .name("diffs") .beginArray() .value(i18n.message(UserSession.get().locale(), "created", null)) .endArray() .endObject(); IssueChangelog changelog = issueChangelogService.changelog(issue); for (FieldDiffs diffs : changelog.changes()) { String userLogin = diffs.userLogin(); json.beginObject() .prop("userName", userLogin != null ? changelog.user(diffs).name() : null) .prop("creationDate", DateUtils.formatDateTime(diffs.creationDate())) .prop("fCreationDate", formatDate(diffs.creationDate())); json.name("diffs").beginArray(); List<String> diffsFormatted = issueChangelogService.formatDiffs(diffs); for (String diff : diffsFormatted) { json.value(diff); } json.endArray(); json.endObject(); } json.endArray(); }
@Test public void should_keep_changes_made_by_user() throws Exception { DefaultIssue issue = new DefaultIssue() .setKey("ABCDE") .setRuleKey(RuleKey.of("squid", "AvoidCycles")) .setComponentKey("struts:org.apache.struts.Action") .setNew(false); // Before starting scan issue.setAssignee(null); issue.setActionPlanKey("PLAN-1"); issue.setCreationDate(DateUtils.parseDate("2012-01-01")); issue.setUpdateDate(DateUtils.parseDate("2012-02-02")); // Changed by scan issue.setLine(200); issue.setSeverity(Severity.BLOCKER); issue.setManualSeverity(false); issue.setAuthorLogin("simon"); issue.setChecksum("CHECKSUM-ABCDE"); issue.setResolution(null); issue.setStatus(Issue.STATUS_REOPENED); // Issue as seen and changed by end-user IssueDto dbIssue = new IssueDto() .setKee("ABCDE") .setRuleId(10) .setRuleKey("squid", "AvoidCycles") .setComponentUuid("100") .setComponentKey("struts:org.apache.struts.Action") .setLine(10) .setResolution(Issue.RESOLUTION_FALSE_POSITIVE) .setStatus(Issue.STATUS_RESOLVED) .setAssignee("arthur") .setActionPlanKey("PLAN-2") .setSeverity(Severity.MAJOR) .setManualSeverity(false); new UpdateConflictResolver().mergeFields(dbIssue, issue); assertThat(issue.key()).isEqualTo("ABCDE"); assertThat(issue.componentKey()).isEqualTo("struts:org.apache.struts.Action"); // Scan wins on : assertThat(issue.line()).isEqualTo(200); assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); assertThat(issue.manualSeverity()).isFalse(); // User wins on : assertThat(issue.assignee()).isEqualTo("arthur"); assertThat(issue.resolution()).isEqualTo(Issue.RESOLUTION_FALSE_POSITIVE); assertThat(issue.status()).isEqualTo(Issue.STATUS_RESOLVED); assertThat(issue.actionPlanKey()).isEqualTo("PLAN-2"); }
protected void appendFooter(StringBuilder message, Notification notification) { String projectKey = notification.getFieldValue(FIELD_PROJECT_KEY); String dateString = notification.getFieldValue(FIELD_PROJECT_DATE); if (projectKey != null && dateString != null) { Date date = DateUtils.parseDateTime(dateString); String url = String.format( "%s/component_issues?id=%s#createdAt=%s", settings.getServerBaseURL(), encode(projectKey), encode(DateUtils.formatDateTime(date))); message.append("See it in SonarQube: ").append(url).append(NEW_LINE); } }
public Date getDateTime(String key) { String value = getString(key); if (StringUtils.isNotEmpty(value)) { return DateUtils.parseDateTime(value); } return null; }
@Before public void createDao() { session = getMyBatis().openSession(false); system2 = mock(System2.class); when(system2.now()).thenReturn(DateUtils.parseDate("2014-09-03").getTime()); dao = new ResourceDao(getMyBatis(), system2); }
@Test public void should_send_notification_if_issue_change() throws Exception { when(project.getAnalysisDate()).thenReturn(DateUtils.parseDate("2013-05-18")); RuleKey ruleKey = RuleKey.of("squid", "AvoidCycles"); Rule rule = new Rule("squid", "AvoidCycles"); DefaultIssue issue = new DefaultIssue() .setNew(false) .setChanged(true) .setFieldChange(mock(IssueChangeContext.class), "severity", "MINOR", "BLOCKER") .setRuleKey(ruleKey); when(issueCache.all()).thenReturn(Arrays.asList(issue)); when(ruleFinder.findByKey(ruleKey)).thenReturn(rule); SendIssueNotificationsPostJob job = new SendIssueNotificationsPostJob(issueCache, notifications, ruleFinder); job.executeOn(project, sensorContext); verify(notifications) .sendChanges( eq(issue), any(IssueChangeContext.class), eq(rule), any(Component.class), (Component) isNull()); }
@Test public void search_json_example() { ComponentDto jdk7 = insertJdk7(); ComponentDto cLang = insertClang(); dbClient .componentLinkDao() .insert( dbSession, new ComponentLinkDto() .setComponentUuid(jdk7.uuid()) .setHref("http://www.oracle.com") .setType(ComponentLinkDto.TYPE_HOME_PAGE) .setName("Home")); dbClient .componentLinkDao() .insert( dbSession, new ComponentLinkDto() .setComponentUuid(jdk7.uuid()) .setHref("http://download.java.net/openjdk/jdk8/") .setType(ComponentLinkDto.TYPE_SOURCES) .setName("Sources")); long oneTime = DateUtils.parseDateTime("2016-06-10T13:17:53+0000").getTime(); long anotherTime = DateUtils.parseDateTime("2016-06-11T14:25:53+0000").getTime(); SnapshotDto jdk7Snapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(jdk7).setCreatedAt(oneTime)); SnapshotDto cLangSnapshot = dbClient.snapshotDao().insert(dbSession, newAnalysis(cLang).setCreatedAt(anotherTime)); dbClient .measureDao() .insert( dbSession, newMeasureDto(alertStatusMetric, jdk7, jdk7Snapshot).setData(Level.ERROR.name())); dbClient .measureDao() .insert( dbSession, newMeasureDto(alertStatusMetric, cLang, cLangSnapshot).setData(Level.OK.name())); insertUserPermission(UserRole.ADMIN, user.getId(), jdk7.getId()); insertUserPermission(UserRole.ADMIN, user.getId(), cLang.getId()); db.commit(); System.setProperty("user.timezone", "UTC"); String result = ws.newRequest().execute().getInput(); assertJson(result).isSimilarTo(getClass().getResource("search_my_projects-example.json")); }
public void add(String language, String name) { qualityProfiles.add( QualityProfile.newBuilder() .setLanguage(language) .setKey(name) .setName(name) .setRulesUpdatedAt(DateUtils.formatDateTime(new Date(1234567891212L))) .build()); }
@Test public void toDate() throws Exception { assertThat(RubyUtils.toDate(null)).isNull(); assertThat(RubyUtils.toDate("")).isNull(); assertThat(RubyUtils.toDate(" ")).isNull(); assertThat(RubyUtils.toDate("2013-01-18").getDate()).isEqualTo(18); assertThat(RubyUtils.toDate("2013-01-18T15:38:19+0200").getDate()).isEqualTo(18); assertThat(RubyUtils.toDate("2013-01-18T15:38:19+0200").getMinutes()).isEqualTo(38); assertThat(RubyUtils.toDate(DateUtils.parseDate("2013-01-18")).getDate()).isEqualTo(18); }
@Before public void before() { System2 system2 = mock(System2.class); when(system2.now()).thenReturn(DateUtils.parseDate("2011-09-29").getTime()); underTest = new SwitchSnapshotStep( new DbClient(db.database(), db.myBatis(), new SnapshotDao()), treeRootHolder, dbIdsRepository); }
@Test public void should_not_send_notif_if_no_new_issues() throws Exception { when(project.getAnalysisDate()).thenReturn(DateUtils.parseDate("2013-05-18")); when(issueCache.all()).thenReturn(Arrays.asList(new DefaultIssue().setNew(false))); SendIssueNotificationsPostJob job = new SendIssueNotificationsPostJob(issueCache, notifications, ruleFinder); job.executeOn(project, sensorContext); verifyZeroInteractions(notifications); }
private void delete(List<PurgeableSnapshotDto> snapshots, DbSession session) { for (PurgeableSnapshotDto snapshot : snapshots) { LOG.debug( "<- Delete snapshot: {} [{}]", DateUtils.formatDateTime(snapshot.getDate()), snapshot.getSnapshotId()); purgeDao.deleteSnapshots( PurgeSnapshotQuery.create().setRootSnapshotId(snapshot.getSnapshotId()), session); purgeDao.deleteSnapshots( PurgeSnapshotQuery.create().setId(snapshot.getSnapshotId()), session); } }
private void writeIssue(IssueQueryResult result, DefaultIssue issue, JsonWriter json) { Component component = result.component(issue); Component project = result.project(issue); String actionPlanKey = issue.actionPlanKey(); WorkDayDuration technicalDebt = issue.technicalDebt(); Date updateDate = issue.updateDate(); Date closeDate = issue.closeDate(); json.prop("key", issue.key()) .prop("component", issue.componentKey()) .prop("componentLongName", component != null ? component.longName() : null) .prop("componentQualifier", component != null ? component.qualifier() : null) .prop("project", issue.projectKey()) .prop("projectLongName", project != null ? project.longName() : null) .prop("rule", issue.ruleKey().toString()) .prop("ruleName", result.rule(issue).getName()) .prop("line", issue.line()) .prop("message", issue.message()) .prop("resolution", issue.resolution()) .prop("status", issue.status()) .prop("severity", issue.severity()) .prop("author", issue.authorLogin()) .prop("actionPlan", actionPlanKey) .prop( "debt", technicalDebt != null ? technicalDebtFormatter.format(UserSession.get().locale(), technicalDebt) : null) .prop("actionPlanName", actionPlanKey != null ? result.actionPlan(issue).name() : null) .prop("creationDate", DateUtils.formatDateTime(issue.creationDate())) .prop("fCreationDate", formatDate(issue.creationDate())) .prop("updateDate", updateDate != null ? DateUtils.formatDateTime(updateDate) : null) .prop("fUpdateDate", formatDate(updateDate)) .prop("fUpdateAge", formatAgeDate(updateDate)) .prop("closeDate", closeDate != null ? DateUtils.formatDateTime(closeDate) : null) .prop("fCloseDate", formatDate(issue.closeDate())); addUserWithLabel(result, issue.assignee(), "assignee", json); addUserWithLabel(result, issue.reporter(), "reporter", json); }
@Test public void should_update_issues() throws Exception { setupData("should_update_issues"); IssueChangeContext context = IssueChangeContext.createUser(new Date(), "emmerik"); DefaultIssueComment comment = DefaultIssueComment.create("ABCDE", "emmerik", "the comment"); // override generated key comment.setKey("FGHIJ"); Date date = DateUtils.parseDate("2013-05-18"); DefaultIssue issue = new DefaultIssue() .setKey("ABCDE") .setNew(false) .setChanged(true) // updated fields .setLine(5000) .setProjectUuid("CDEF") .setDebt(Duration.create(10L)) .setChecksum("FFFFF") .setAuthorLogin("simon") .setAssignee("loic") .setFieldChange(context, "severity", "INFO", "BLOCKER") .setReporter("emmerik") .setResolution("FIXED") .setStatus("RESOLVED") .setSeverity("BLOCKER") .setAttribute("foo", "bar") .addComment(comment) .setCreationDate(date) .setUpdateDate(date) .setCloseDate(date) // unmodifiable fields .setRuleKey(RuleKey.of("xxx", "unknown")) .setComponentKey("struts:Action") .setProjectKey("struts"); storage.save(issue); checkTables( "should_update_issues", new String[] {"id", "created_at", "updated_at", "issue_change_creation_date"}, "issues", "issue_changes"); }
@CheckForNull private static Long parseDateTimeAsLong(@Nullable String dateAsString) { if (dateAsString == null) { return null; } Date date = parseDateTimeQuietly(dateAsString); if (date == null) { date = parseDateQuietly(dateAsString); checkRequest( date != null, "Date '%s' cannot be parsed as either a date or date+time", dateAsString); date = DateUtils.addDays(date, 1); } return date.getTime(); }
@Test public void shouldCopyDateWhenNotNew() { Violation newViolation = newViolation("message", 1, 50, "checksum"); RuleFailureModel referenceViolation = newReferenceViolation("", 1, 50, "checksum"); Date referenceDate = DateUtils.parseDate("2009-05-18"); referenceViolation.setCreatedAt(referenceDate); assertThat(newViolation.getCreatedAt(), nullValue()); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.<RuleFailureModel>newArrayList(referenceViolation)); assertThat(mapping.size(), is(1)); assertThat(newViolation.getCreatedAt(), is(referenceDate)); assertThat(newViolation.isNew(), is(false)); }
private void writeComments(IssueQueryResult queryResult, Issue issue, JsonWriter json) { json.name("comments").beginArray(); for (IssueComment comment : issue.comments()) { String userLogin = comment.userLogin(); json.beginObject() .prop("key", comment.key()) .prop("userName", userLogin != null ? queryResult.user(userLogin).name() : null) .prop("raw", comment.markdownText()) .prop("html", Markdown.convertToHtml(comment.markdownText())) .prop("createdAt", DateUtils.formatDateTime(comment.createdAt())) .prop("fCreatedAge", formatAgeDate(comment.createdAt())) .prop( "updatable", UserSession.get().isLoggedIn() && UserSession.get().login().equals(comment.userLogin())) .endObject(); } json.endArray(); }
private void writeResponse(JsonWriter json, Result<QProfileActivity> result, Paging paging) { json.beginObject(); json.prop("total", result.getTotal()); json.prop(Param.PAGE, paging.pageIndex()); json.prop(Param.PAGE_SIZE, paging.pageSize()); json.name("events").beginArray(); for (QProfileActivity event : result.getHits()) { json.beginObject() .prop("date", DateUtils.formatDateTime(event.getCreatedAt())) .prop("authorLogin", event.getLogin()) .prop("authorName", event.authorName()) .prop("action", event.getAction()) .prop("ruleKey", event.ruleKey().toString()) .prop("ruleName", event.ruleName()); writeParameters(json, event); json.endObject(); } json.endArray(); json.endObject().close(); }
@Test public void should_insert_new_issues() throws Exception { setupData("should_insert_new_issues"); DefaultIssueComment comment = DefaultIssueComment.create("ABCDE", "emmerik", "the comment"); // override generated key comment.setKey("FGHIJ"); Date date = DateUtils.parseDate("2013-05-18"); DefaultIssue issue = new DefaultIssue() .setKey("ABCDE") .setNew(true) .setRuleKey(RuleKey.of("squid", "AvoidCycle")) .setProjectKey("struts") .setLine(5000) .setDebt(Duration.create(10L)) .setReporter("emmerik") .setResolution("OPEN") .setStatus("OPEN") .setSeverity("BLOCKER") .setAttribute("foo", "bar") .addComment(comment) .setCreationDate(date) .setUpdateDate(date) .setCloseDate(date) .setComponentKey("struts:Action"); storage.save(issue); checkTables( "should_insert_new_issues", new String[] {"id", "created_at", "updated_at", "issue_change_creation_date"}, "issues", "issue_changes"); }
/** TODO this class should use ServerTester instead of mocking db */ @RunWith(MockitoJUnitRunner.class) public class DebtModelOperationsTest { @Rule public UserSessionRule userSessionRule = UserSessionRule.standalone(); @Mock CharacteristicDao dao; @Mock RuleDao ruleDao; @Mock DbClient dbClient; @Mock DbSession session; @Mock System2 system2; @Captor ArgumentCaptor<CharacteristicDto> characteristicCaptor; @Captor ArgumentCaptor<RuleDto> ruleCaptor; Date now = DateUtils.parseDate("2014-03-19"); CharacteristicDto characteristicDto = new CharacteristicDto() .setId(1) .setKey("MEMORY_EFFICIENCY") .setName("Memory use") .setOrder(2) .setEnabled(true); CharacteristicDto subCharacteristicDto = new CharacteristicDto() .setId(2) .setKey("EFFICIENCY") .setName("Efficiency") .setParentId(1) .setEnabled(true); int currentId; DebtModelOperations service; @Before public void setUp() { when(system2.now()).thenReturn(now.getTime()); userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); currentId = 10; // Associate an id when inserting an object to simulate the db id generator doAnswer( new Answer() { public Object answer(InvocationOnMock invocation) { Object[] args = invocation.getArguments(); CharacteristicDto dto = (CharacteristicDto) args[0]; dto.setId(++currentId); return null; } }) .when(dao) .insert(any(CharacteristicDto.class), any(SqlSession.class)); when(dbClient.openSession(false)).thenReturn(session); when(dbClient.ruleDao()).thenReturn(ruleDao); when(dbClient.debtCharacteristicDao()).thenReturn(dao); service = new DebtModelOperations(dbClient, system2, userSessionRule); } @Test public void create_sub_characteristic() { when(dao.selectById(1, session)).thenReturn(characteristicDto); DefaultDebtCharacteristic result = (DefaultDebtCharacteristic) service.create("Compilation name", 1); assertThat(result.id()).isEqualTo(currentId); assertThat(result.key()).isEqualTo("COMPILATION_NAME"); assertThat(result.name()).isEqualTo("Compilation name"); assertThat(result.parentId()).isEqualTo(1); assertThat(result.createdAt()).isEqualTo(now); } @Test public void fail_to_create_sub_characteristic_when_parent_id_is_not_a_root_characteristic() { when(dao.selectById(1, session)).thenReturn(subCharacteristicDto); try { service.create("Compilation", 1); fail(); } catch (BadRequestException e) { assertThat(e.firstError().getKey()) .isEqualTo("A sub characteristic can not have a sub characteristic as parent."); } } @Test public void fail_to_create_sub_characteristic_when_parent_does_not_exists() { when(dao.selectById(1, session)).thenReturn(null); try { service.create("Compilation", 1); fail(); } catch (Exception e) { assertThat(e) .isInstanceOf(NotFoundException.class) .hasMessage("Characteristic with id 1 does not exists."); } } @Test public void fail_to_create_sub_characteristic_when_name_already_used() { when(dao.selectByName("Compilation", session)).thenReturn(new CharacteristicDto()); when(dao.selectById(1, session)).thenReturn(characteristicDto); try { service.create("Compilation", 1); fail(); } catch (BadRequestException e) { assertThat(e.firstError().getKey()).isEqualTo("errors.is_already_used"); assertThat(e.firstError().getParams()[0]).isEqualTo("Compilation"); } } @Test public void fail_to_create_sub_characteristic_when_wrong_permission() { userSessionRule.setGlobalPermissions(GlobalPermissions.DASHBOARD_SHARING); try { service.create("Compilation", 1); fail(); } catch (Exception e) { assertThat(e).isInstanceOf(ForbiddenException.class); } } @Test public void create_characteristic() { when(dao.selectMaxCharacteristicOrder(session)).thenReturn(2); DefaultDebtCharacteristic result = (DefaultDebtCharacteristic) service.create("Portability", null); assertThat(result.id()).isEqualTo(currentId); assertThat(result.key()).isEqualTo("PORTABILITY"); assertThat(result.name()).isEqualTo("Portability"); assertThat(result.order()).isEqualTo(3); assertThat(result.createdAt()).isEqualTo(now); } @Test public void create_first_characteristic() { when(dao.selectMaxCharacteristicOrder(session)).thenReturn(0); DefaultDebtCharacteristic result = (DefaultDebtCharacteristic) service.create("Portability", null); assertThat(result.id()).isEqualTo(currentId); assertThat(result.key()).isEqualTo("PORTABILITY"); assertThat(result.name()).isEqualTo("Portability"); assertThat(result.order()).isEqualTo(1); assertThat(result.createdAt()).isEqualTo(now); } @Test public void rename_characteristic() { when(dao.selectById(10, session)).thenReturn(subCharacteristicDto); DefaultDebtCharacteristic result = (DefaultDebtCharacteristic) service.rename(10, "New Efficiency"); assertThat(result.key()).isEqualTo("EFFICIENCY"); assertThat(result.name()).isEqualTo("New Efficiency"); assertThat(result.updatedAt()).isEqualTo(now); } @Test public void not_rename_characteristic_when_renaming_with_same_name() { when(dao.selectById(10, session)).thenReturn(subCharacteristicDto); service.rename(10, "Efficiency"); verify(dao, never()).update(any(CharacteristicDto.class), eq(session)); } @Test public void fail_to_rename_unknown_characteristic() { when(dao.selectById(10, session)).thenReturn(null); try { service.rename(10, "New Efficiency"); fail(); } catch (Exception e) { assertThat(e) .isInstanceOf(NotFoundException.class) .hasMessage("Characteristic with id 10 does not exists."); } } @Test public void move_up() { when(dao.selectById(10, session)) .thenReturn(new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setOrder(2)); when(dao.selectEnabledRootCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto().setId(2).setKey("PORTABILITY").setOrder(1), new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setOrder(2))); DebtCharacteristic result = service.moveUp(10); verify(dao, times(2)).update(characteristicCaptor.capture(), eq(session)); assertThat(result.order()).isEqualTo(1); assertThat(characteristicCaptor.getAllValues().get(0).getOrder()).isEqualTo(2); assertThat(characteristicCaptor.getAllValues().get(0).getUpdatedAt()).isEqualTo(now); assertThat(characteristicCaptor.getAllValues().get(1).getOrder()).isEqualTo(1); assertThat(characteristicCaptor.getAllValues().get(1).getUpdatedAt()).isEqualTo(now); } @Test public void do_nothing_when_move_up_and_already_on_top() { when(dao.selectById(10, session)) .thenReturn(new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setOrder(1)); when(dao.selectEnabledRootCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setOrder(1), new CharacteristicDto().setId(2).setKey("PORTABILITY").setOrder(2))); service.moveUp(10); verify(dao, never()).update(any(CharacteristicDto.class), eq(session)); } @Test public void move_down() { when(dao.selectById(10, session)) .thenReturn(new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setOrder(2)); when(dao.selectEnabledRootCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setOrder(2), new CharacteristicDto().setId(2).setKey("PORTABILITY").setOrder(3))); DebtCharacteristic result = service.moveDown(10); verify(dao, times(2)).update(characteristicCaptor.capture(), eq(session)); assertThat(result.order()).isEqualTo(3); assertThat(characteristicCaptor.getAllValues().get(0).getOrder()).isEqualTo(2); assertThat(characteristicCaptor.getAllValues().get(0).getUpdatedAt()).isEqualTo(now); assertThat(characteristicCaptor.getAllValues().get(1).getOrder()).isEqualTo(3); assertThat(characteristicCaptor.getAllValues().get(1).getUpdatedAt()).isEqualTo(now); } @Test public void do_nothing_when_move_down_and_already_on_bottom() { when(dao.selectById(10, session)) .thenReturn(new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setOrder(2)); when(dao.selectEnabledRootCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto().setId(2).setKey("PORTABILITY").setOrder(1), new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setOrder(2))); service.moveDown(10); verify(dao, never()).update(any(CharacteristicDto.class), eq(session)); } @Test public void fail_to_move_sub_characteristic() { when(dao.selectById(10, session)) .thenReturn(new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setParentId(1)); when(dao.selectEnabledRootCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setOrder(2), new CharacteristicDto().setId(2).setKey("PORTABILITY").setOrder(3))); try { service.moveDown(10); fail(); } catch (BadRequestException e) { assertThat(e.firstError().getKey()).isEqualTo("Sub characteristics can not be moved."); } verify(dao, never()).update(any(CharacteristicDto.class), eq(session)); } @Test public void fail_to_move_characteristic_with_no_order() { when(dao.selectById(10, session)) .thenReturn(new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setOrder(null)); when(dao.selectEnabledRootCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto().setId(10).setKey("MEMORY_EFFICIENCY").setOrder(2), new CharacteristicDto().setId(2).setKey("PORTABILITY").setOrder(3))); try { service.moveDown(10); fail(); } catch (Exception e) { assertThat(e) .isInstanceOf(IllegalArgumentException.class) .hasMessage("The order of the characteristic 'MEMORY_EFFICIENCY' should not be null"); } verify(dao, never()).update(any(CharacteristicDto.class), eq(session)); } @Test public void delete_sub_characteristic() { DbSession batchSession = mock(DbSession.class); when(dbClient.openSession(true)).thenReturn(batchSession); when(ruleDao.findRulesByDebtSubCharacteristicId(batchSession, 2)) .thenReturn( newArrayList( new RuleDto() .setSubCharacteristicId(2) .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("2h") .setRemediationOffset("5min") .setDefaultSubCharacteristicId(10) .setDefaultRemediationFunction( DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setDefaultRemediationCoefficient("4h") .setDefaultRemediationOffset("15min"))); when(dao.selectById(2, batchSession)).thenReturn(subCharacteristicDto); service.delete(2); verify(ruleDao).update(eq(batchSession), ruleCaptor.capture()); RuleDto ruleDto = ruleCaptor.getValue(); assertThat(ruleDto.getUpdatedAt()).isEqualTo(now); // Overridden debt data are disabled assertThat(ruleDto.getSubCharacteristicId()).isEqualTo(-1); assertThat(ruleDto.getRemediationFunction()).isNull(); assertThat(ruleDto.getRemediationCoefficient()).isNull(); assertThat(ruleDto.getRemediationOffset()).isNull(); // Default debt data should not be touched assertThat(ruleDto.getDefaultSubCharacteristicId()).isEqualTo(10); assertThat(ruleDto.getDefaultRemediationFunction()).isEqualTo("LINEAR_OFFSET"); assertThat(ruleDto.getDefaultRemediationCoefficient()).isEqualTo("4h"); assertThat(ruleDto.getDefaultRemediationOffset()).isEqualTo("15min"); verify(dao).update(characteristicCaptor.capture(), eq(batchSession)); CharacteristicDto characteristicDto = characteristicCaptor.getValue(); // Sub characteristic is disable assertThat(characteristicDto.getId()).isEqualTo(2); assertThat(characteristicDto.isEnabled()).isFalse(); assertThat(characteristicDto.getUpdatedAt()).isEqualTo(now); } @Test public void delete_sub_characteristic_disable_default_rules_debt_if_default_characteristic_is_deleted() { DbSession batchSession = mock(DbSession.class); when(dbClient.openSession(true)).thenReturn(batchSession); when(ruleDao.findRulesByDebtSubCharacteristicId(batchSession, 2)) .thenReturn( newArrayList( new RuleDto() .setSubCharacteristicId(10) .setRemediationFunction("LINEAR_OFFSET") .setRemediationCoefficient("2h") .setRemediationOffset("5min") .setDefaultSubCharacteristicId(2) .setDefaultRemediationFunction("LINEAR_OFFSET") .setDefaultRemediationCoefficient("4h") .setDefaultRemediationOffset("15min"))); when(dao.selectById(2, batchSession)).thenReturn(subCharacteristicDto); service.delete(2); verify(ruleDao).update(eq(batchSession), ruleCaptor.capture()); RuleDto ruleDto = ruleCaptor.getValue(); // Default debt data are disabled assertThat(ruleDto.getDefaultSubCharacteristicId()).isNull(); assertThat(ruleDto.getDefaultRemediationFunction()).isNull(); assertThat(ruleDto.getDefaultRemediationCoefficient()).isNull(); assertThat(ruleDto.getDefaultRemediationOffset()).isNull(); // Overridden debt data should not be touched assertThat(ruleDto.getSubCharacteristicId()).isEqualTo(10); assertThat(ruleDto.getRemediationFunction()).isEqualTo("LINEAR_OFFSET"); assertThat(ruleDto.getRemediationCoefficient()).isEqualTo("2h"); assertThat(ruleDto.getRemediationOffset()).isEqualTo("5min"); verify(dao).update(characteristicCaptor.capture(), eq(batchSession)); CharacteristicDto characteristicDto = characteristicCaptor.getValue(); // Sub characteristic is disable assertThat(characteristicDto.getId()).isEqualTo(2); assertThat(characteristicDto.isEnabled()).isFalse(); assertThat(characteristicDto.getUpdatedAt()).isEqualTo(now); } @Test public void delete_characteristic() { DbSession batchSession = mock(DbSession.class); when(dbClient.openSession(true)).thenReturn(batchSession); when(ruleDao.findRulesByDebtSubCharacteristicId(batchSession, subCharacteristicDto.getId())) .thenReturn( newArrayList( new RuleDto() .setSubCharacteristicId(subCharacteristicDto.getId()) .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("2h") .setRemediationOffset("5min"))); when(dao.selectCharacteristicsByParentId(1, batchSession)) .thenReturn(newArrayList(subCharacteristicDto)); when(dao.selectById(1, batchSession)).thenReturn(characteristicDto); service.delete(1); verify(ruleDao).update(eq(batchSession), ruleCaptor.capture()); verify(dao, times(2)).update(characteristicCaptor.capture(), eq(batchSession)); CharacteristicDto subCharacteristicDto = characteristicCaptor.getAllValues().get(0); CharacteristicDto characteristicDto = characteristicCaptor.getAllValues().get(1); // Sub characteristic is disable assertThat(subCharacteristicDto.getId()).isEqualTo(2); assertThat(subCharacteristicDto.isEnabled()).isFalse(); assertThat(subCharacteristicDto.getUpdatedAt()).isEqualTo(now); // Characteristic is disable assertThat(characteristicDto.getId()).isEqualTo(1); assertThat(characteristicDto.isEnabled()).isFalse(); assertThat(characteristicDto.getUpdatedAt()).isEqualTo(now); } @Test public void not_delete_already_disabled_characteristic() { DbSession batchSession = mock(DbSession.class); when(dbClient.openSession(true)).thenReturn(batchSession); when(dao.selectById(1, batchSession)) .thenReturn( new CharacteristicDto() .setId(1) .setKey("MEMORY_EFFICIENCY") .setName("Memory use") .setOrder(2) .setEnabled(false)); service.delete(1); verify(dao, never()).update(any(CharacteristicDto.class), eq(batchSession)); } }
@Category(DbTests.class) public class RegisterRulesTest { static final Date DATE1 = DateUtils.parseDateTime("2014-01-01T19:10:03+0100"); static final Date DATE2 = DateUtils.parseDateTime("2014-02-01T12:10:03+0100"); static final Date DATE3 = DateUtils.parseDateTime("2014-03-01T12:10:03+0100"); System2 system; @org.junit.Rule public DbTester dbTester = DbTester.create(system); RuleActivator ruleActivator = mock(RuleActivator.class); DbClient dbClient; @Before public void before() { system = mock(System2.class); when(system.now()).thenReturn(DATE1.getTime()); RuleDao ruleDao = new RuleDao(system); ActiveRuleDao activeRuleDao = new ActiveRuleDao(new QualityProfileDao(dbTester.myBatis(), system), ruleDao, system); dbClient = new DbClient( dbTester.database(), dbTester.myBatis(), ruleDao, activeRuleDao, new QualityProfileDao(dbTester.myBatis(), system), new CharacteristicDao(dbTester.myBatis())); } @Test public void insert_new_rules() { execute(new FakeRepositoryV1()); // verify db assertThat(dbClient.ruleDao().selectAll(dbTester.getSession())).hasSize(2); RuleKey ruleKey1 = RuleKey.of("fake", "rule1"); RuleDto rule1 = dbClient.ruleDao().getNullableByKey(dbTester.getSession(), ruleKey1); assertThat(rule1.getName()).isEqualTo("One"); assertThat(rule1.getDescription()).isEqualTo("Description of One"); assertThat(rule1.getSeverityString()).isEqualTo(Severity.BLOCKER); assertThat(rule1.getTags()).isEmpty(); assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag2", "tag3"); assertThat(rule1.getConfigKey()).isEqualTo("config1"); assertThat(rule1.getStatus()).isEqualTo(RuleStatus.BETA); assertThat(rule1.getCreatedAt()).isEqualTo(DATE1); assertThat(rule1.getUpdatedAt()).isEqualTo(DATE1); // TODO check characteristic and remediation function List<RuleParamDto> params = dbClient.ruleDao().selectRuleParamsByRuleKey(dbTester.getSession(), ruleKey1); assertThat(params).hasSize(2); RuleParamDto param = getParam(params, "param1"); assertThat(param.getDescription()).isEqualTo("parameter one"); assertThat(param.getDefaultValue()).isEqualTo("default1"); } @Test public void do_not_update_rules_when_no_changes() { execute(new FakeRepositoryV1()); assertThat(dbClient.ruleDao().selectAll(dbTester.getSession())).hasSize(2); when(system.now()).thenReturn(DATE2.getTime()); execute(new FakeRepositoryV1()); RuleKey ruleKey1 = RuleKey.of("fake", "rule1"); RuleDto rule1 = dbClient.ruleDao().getNullableByKey(dbTester.getSession(), ruleKey1); assertThat(rule1.getCreatedAt()).isEqualTo(DATE1); assertThat(rule1.getUpdatedAt()).isEqualTo(DATE1); } @Test public void update_and_remove_rules_on_changes() { execute(new FakeRepositoryV1()); assertThat(dbClient.ruleDao().selectAll(dbTester.getSession())).hasSize(2); // user adds tags and sets markdown note RuleKey ruleKey1 = RuleKey.of("fake", "rule1"); RuleDto rule1 = dbClient.ruleDao().getNullableByKey(dbTester.getSession(), ruleKey1); rule1.setTags(Sets.newHashSet("usertag1", "usertag2")); rule1.setNoteData("user *note*"); rule1.setNoteUserLogin("marius"); dbClient.ruleDao().update(dbTester.getSession(), rule1); dbTester.getSession().commit(); when(system.now()).thenReturn(DATE2.getTime()); execute(new FakeRepositoryV2()); // rule1 has been updated rule1 = dbClient.ruleDao().getNullableByKey(dbTester.getSession(), ruleKey1); assertThat(rule1.getName()).isEqualTo("One v2"); assertThat(rule1.getDescription()).isEqualTo("Description of One v2"); assertThat(rule1.getSeverityString()).isEqualTo(Severity.INFO); assertThat(rule1.getTags()).containsOnly("usertag1", "usertag2"); assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag4"); assertThat(rule1.getConfigKey()).isEqualTo("config1 v2"); assertThat(rule1.getNoteData()).isEqualTo("user *note*"); assertThat(rule1.getNoteUserLogin()).isEqualTo("marius"); assertThat(rule1.getStatus()).isEqualTo(RuleStatus.READY); assertThat(rule1.getCreatedAt()).isEqualTo(DATE1); assertThat(rule1.getUpdatedAt()).isEqualTo(DATE2); // TODO check characteristic and remediation function List<RuleParamDto> params = dbClient.ruleDao().selectRuleParamsByRuleKey(dbTester.getSession(), ruleKey1); assertThat(params).hasSize(2); RuleParamDto param = getParam(params, "param1"); assertThat(param.getDescription()).isEqualTo("parameter one v2"); assertThat(param.getDefaultValue()).isEqualTo("default1 v2"); // rule2 has been removed -> status set to REMOVED but db row is not deleted RuleDto rule2 = dbClient.ruleDao().getNullableByKey(dbTester.getSession(), RuleKey.of("fake", "rule2")); assertThat(rule2.getStatus()).isEqualTo(RuleStatus.REMOVED); assertThat(rule2.getUpdatedAt()).isEqualTo(DATE2); // rule3 has been created RuleDto rule3 = dbClient.ruleDao().getNullableByKey(dbTester.getSession(), RuleKey.of("fake", "rule3")); assertThat(rule3).isNotNull(); assertThat(rule3.getStatus()).isEqualTo(RuleStatus.READY); } @Test public void do_not_update_already_removed_rules() { execute(new FakeRepositoryV1()); assertThat(dbClient.ruleDao().selectAll(dbTester.getSession())).hasSize(2); RuleDto rule2 = dbClient.ruleDao().getByKey(dbTester.getSession(), RuleKey.of("fake", "rule2")); assertThat(rule2.getStatus()).isEqualTo(RuleStatus.READY); when(system.now()).thenReturn(DATE2.getTime()); execute(new FakeRepositoryV2()); // On MySQL, need to update a rule otherwise rule2 will be seen as READY, but why ??? dbClient .ruleDao() .update( dbTester.getSession(), dbClient.ruleDao().getByKey(dbTester.getSession(), RuleKey.of("fake", "rule1"))); dbTester.getSession().commit(); // rule2 is removed rule2 = dbClient.ruleDao().getNullableByKey(dbTester.getSession(), RuleKey.of("fake", "rule2")); assertThat(rule2.getStatus()).isEqualTo(RuleStatus.REMOVED); when(system.now()).thenReturn(DATE3.getTime()); execute(new FakeRepositoryV2()); dbTester.getSession().commit(); // -> rule2 is still removed, but not update at DATE3 rule2 = dbClient.ruleDao().getNullableByKey(dbTester.getSession(), RuleKey.of("fake", "rule2")); assertThat(rule2.getStatus()).isEqualTo(RuleStatus.REMOVED); assertThat(rule2.getUpdatedAt()).isEqualTo(DATE2); } @Test public void mass_insert() { execute(new BigRepository()); assertThat(dbClient.ruleDao().selectAll(dbTester.getSession())).hasSize(BigRepository.SIZE); assertThat(dbClient.ruleDao().selectAllRuleParams(dbTester.getSession())) .hasSize(BigRepository.SIZE * 20); } @Test public void manage_repository_extensions() { execute(new FindbugsRepository(), new FbContribRepository()); List<RuleDto> rules = dbClient.ruleDao().selectAll(dbTester.getSession()); assertThat(rules).hasSize(2); for (RuleDto rule : rules) { assertThat(rule.getRepositoryKey()).isEqualTo("findbugs"); } } private void execute(RulesDefinition... defs) { RuleDefinitionsLoader loader = new RuleDefinitionsLoader( mock(DeprecatedRulesDefinitionLoader.class), new RuleRepositories(), mock(CommonRuleDefinitionsImpl.class), defs); Languages languages = mock(Languages.class); when(languages.get("java")).thenReturn(mock(Language.class)); RegisterRules task = new RegisterRules(loader, ruleActivator, dbClient, languages); task.start(); // Execute a commit to refresh session state as the task is using its own session dbTester.getSession().commit(); } private RuleParamDto getParam(List<RuleParamDto> params, String key) { for (RuleParamDto param : params) { if (param.getName().equals(key)) { return param; } } return null; } static class FakeRepositoryV1 implements RulesDefinition { @Override public void define(Context context) { NewRepository repo = context.createRepository("fake", "java"); NewRule rule1 = repo.createRule("rule1") .setName("One") .setHtmlDescription("Description of One") .setSeverity(Severity.BLOCKER) .setInternalKey("config1") .setTags("tag1", "tag2", "tag3") .setStatus(RuleStatus.BETA) .setDebtSubCharacteristic("MEMORY_EFFICIENCY") .setEffortToFixDescription("squid.S115.effortToFix"); rule1.setDebtRemediationFunction( rule1.debtRemediationFunctions().linearWithOffset("5d", "10h")); rule1.createParam("param1").setDescription("parameter one").setDefaultValue("default1"); rule1.createParam("param2").setDescription("parameter two").setDefaultValue("default2"); repo.createRule("rule2").setName("Two").setHtmlDescription("Minimal rule"); repo.done(); } } /** FakeRepositoryV1 with some changes */ static class FakeRepositoryV2 implements RulesDefinition { @Override public void define(Context context) { NewRepository repo = context.createRepository("fake", "java"); // almost all the attributes of rule1 are changed NewRule rule1 = repo.createRule("rule1") .setName("One v2") .setHtmlDescription("Description of One v2") .setSeverity(Severity.INFO) .setInternalKey("config1 v2") // tag2 and tag3 removed, tag4 added .setTags("tag1", "tag4") .setStatus(RuleStatus.READY) .setDebtSubCharacteristic("MEMORY_EFFICIENCY") .setEffortToFixDescription("squid.S115.effortToFix.v2"); rule1.setDebtRemediationFunction( rule1.debtRemediationFunctions().linearWithOffset("6d", "2h")); rule1.createParam("param1").setDescription("parameter one v2").setDefaultValue("default1 v2"); rule1.createParam("param2").setDescription("parameter two v2").setDefaultValue("default2 v2"); // rule2 is dropped, rule3 is new repo.createRule("rule3").setName("Three").setHtmlDescription("Rule Three"); repo.done(); } } static class BigRepository implements RulesDefinition { static final int SIZE = 500; @Override public void define(Context context) { NewRepository repo = context.createRepository("big", "java"); for (int i = 0; i < SIZE; i++) { NewRule rule = repo.createRule("rule" + i) .setName("name of " + i) .setHtmlDescription("description of " + i); for (int j = 0; j < 20; j++) { rule.createParam("param" + j); } } repo.done(); } } static class FindbugsRepository implements RulesDefinition { @Override public void define(Context context) { NewRepository repo = context.createRepository("findbugs", "java"); repo.createRule("rule1").setName("Rule One").setHtmlDescription("Description of Rule One"); repo.done(); } } static class FbContribRepository implements RulesDefinition { @Override public void define(Context context) { NewExtendedRepository repo = context.extendRepository("findbugs", "java"); repo.createRule("rule2").setName("Rule Two").setHtmlDescription("Description of Rule Two"); repo.done(); } } }
@Override public void define(WebService.NewController controller) { WebService.NewAction action = controller .createAction("activity") .setDescription( format( "Search for tasks.<br> " + "Requires the system administration permission, " + "or project administration permission if %s is set.<br/>" + "Since 5.5, it's no more possible to specify the page parameter", PARAM_COMPONENT_ID)) .setResponseExample(getClass().getResource("activity-example.json")) .setHandler(this) .setSince("5.2"); action .createParam(PARAM_COMPONENT_ID) .setDescription("Id of the component (project) to filter on") .setExampleValue(Uuids.UUID_EXAMPLE_03); action .createParam(PARAM_COMPONENT_QUERY) .setDescription( format( "Limit search to: <ul>" + "<li>component names that contain the supplied string</li>" + "<li>component keys that are exactly the same as the supplied string</li>" + "</ul>" + "Must not be set together with %s.<br />" + "Deprecated and replaced by '%s'", PARAM_COMPONENT_ID, Param.TEXT_QUERY)) .setExampleValue("Apache") .setDeprecatedSince("5.5"); action .createParam(Param.TEXT_QUERY) .setDescription( format( "Limit search to: <ul>" + "<li>component names that contain the supplied string</li>" + "<li>component keys that are exactly the same as the supplied string</li>" + "<li>task ids that are exactly the same as the supplied string</li>" + "</ul>" + "Must not be set together with %s", PARAM_COMPONENT_ID)) .setExampleValue("Apache") .setSince("5.5"); action .createParam(PARAM_STATUS) .setDescription("Comma separated list of task statuses") .setPossibleValues( ImmutableList.builder() .add(CeActivityDto.Status.values()) .add(CeQueueDto.Status.values()) .build()) .setExampleValue( Joiner.on(",").join(CeQueueDto.Status.IN_PROGRESS, CeActivityDto.Status.SUCCESS)) // activity statuses by default to be backward compatible // queued tasks have been added in 5.5 .setDefaultValue(Joiner.on(",").join(CeActivityDto.Status.values())); action .createParam(PARAM_ONLY_CURRENTS) .setDescription("Filter on the last tasks (only the most recent finished task by project)") .setBooleanPossibleValues() .setDefaultValue("false"); action .createParam(PARAM_TYPE) .setDescription("Task type") .setExampleValue(CeTaskTypes.REPORT) .setPossibleValues(taskTypes); action .createParam(PARAM_MIN_SUBMITTED_AT) .setDescription("Minimum date of task submission (inclusive)") .setExampleValue(DateUtils.formatDateTime(new Date())); action .createParam(PARAM_MAX_EXECUTED_AT) .setDescription("Maximum date of end of task processing (inclusive)") .setExampleValue(DateUtils.formatDateTime(new Date())); action .createParam(Param.PAGE) .setDescription("Deprecated parameter") .setDeprecatedSince("5.5") .setDeprecatedKey("pageIndex"); action.addPageSize(100, MAX_PAGE_SIZE); }
@Nullable public Date getExpirationDate() { return DateUtils.parseDateQuietly(expirationDate); }
private void addDate(@Nullable Date date, String dateKey, JsonWriter json) { if (date != null) { json.prop(dateKey, DateUtils.formatDateTime(date)); } }
public static PurgeableSnapshotDto createSnapshotWithDateTime(long snapshotId, String datetime) { PurgeableSnapshotDto snapshot = new PurgeableSnapshotDto(); snapshot.setSnapshotId(snapshotId); snapshot.setDate(DateUtils.parseDateTime(datetime)); return snapshot; }
public class ViolationTrackingDecoratorTest { private ViolationTrackingDecorator decorator; private Date analysisDate = DateUtils.parseDate("2010-12-25"); @Before public void setUp() throws ParseException { Project project = mock(Project.class); when(project.getAnalysisDate()).thenReturn(analysisDate); decorator = new ViolationTrackingDecorator(project, null, null); } @Test public void permanentIdShouldBeThePrioritaryFieldToCheck() { RuleFailureModel referenceViolation1 = newReferenceViolation("message", 10, 1, "checksum1").setPermanentId(100); RuleFailureModel referenceViolation2 = newReferenceViolation("message", 18, 1, "checksum2").setPermanentId(200); Violation newViolation = newViolation("message", 10, 1, "checksum1"); // exactly the fields of referenceViolation1 newViolation.setPermanentId(200); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation1, referenceViolation2)); assertThat(mapping.get(newViolation), equalTo(referenceViolation2)); // same permanent id assertThat(newViolation.isNew(), is(false)); } @Test public void checksumShouldHaveGreaterPriorityThanLine() { RuleFailureModel referenceViolation1 = newReferenceViolation("message", 1, 50, "checksum1"); RuleFailureModel referenceViolation2 = newReferenceViolation("message", 3, 50, "checksum2"); Violation newViolation1 = newViolation("message", 3, 50, "checksum1"); Violation newViolation2 = newViolation("message", 5, 50, "checksum2"); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation1, newViolation2), Lists.newArrayList(referenceViolation1, referenceViolation2)); assertThat(mapping.get(newViolation1), equalTo(referenceViolation1)); assertThat(newViolation1.isNew(), is(false)); assertThat(mapping.get(newViolation2), equalTo(referenceViolation2)); assertThat(newViolation2.isNew(), is(false)); } /** See SONAR-2928 */ @Test public void sameRuleAndNullLineAndChecksumButDifferentMessages() { Violation newViolation = newViolation("new message", null, 50, "checksum1"); RuleFailureModel referenceViolation = newReferenceViolation("old message", null, 50, "checksum1"); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation)); assertThat(mapping.get(newViolation), equalTo(referenceViolation)); assertThat(newViolation.isNew(), is(false)); } @Test public void sameRuleAndLineAndChecksumButDifferentMessages() { Violation newViolation = newViolation("new message", 1, 50, "checksum1"); RuleFailureModel referenceViolation = newReferenceViolation("old message", 1, 50, "checksum1"); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation)); assertThat(mapping.get(newViolation), equalTo(referenceViolation)); assertThat(newViolation.isNew(), is(false)); } @Test public void sameRuleAndLineMessage() { Violation newViolation = newViolation("message", 1, 50, "checksum1"); RuleFailureModel refernceViolation = newReferenceViolation("message", 1, 50, "checksum2"); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.newArrayList(refernceViolation)); assertThat(mapping.get(newViolation), equalTo(refernceViolation)); assertThat(newViolation.isNew(), is(false)); } @Test public void shouldIgnoreReferenceMeasureWithoutChecksum() { Violation newViolation = newViolation("message", 1, 50, null); RuleFailureModel referenceViolation = newReferenceViolation("message", 1, 51, null); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation)); assertThat(mapping.get(newViolation), is(nullValue())); assertThat(newViolation.isNew(), is(true)); } @Test public void sameRuleAndMessageAndChecksumButDifferentLine() { Violation newViolation = newViolation("message", 1, 50, "checksum1"); RuleFailureModel referenceViolation = newReferenceViolation("message", 2, 50, "checksum1"); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation)); assertThat(mapping.get(newViolation), equalTo(referenceViolation)); assertThat(newViolation.isNew(), is(false)); } /** See https://jira.codehaus.org/browse/SONAR-2812 */ @Test public void sameChecksumAndRuleButDifferentLineAndDifferentMessage() { Violation newViolation = newViolation("new message", 1, 50, "checksum1"); RuleFailureModel referenceViolation = newReferenceViolation("old message", 2, 50, "checksum1"); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation)); assertThat(mapping.get(newViolation), equalTo(referenceViolation)); assertThat(newViolation.isNew(), is(false)); } @Test public void shouldCreateNewViolationWhenSameRuleSameMessageButDifferentLineAndChecksum() { Violation newViolation = newViolation("message", 1, 50, "checksum1"); RuleFailureModel referenceViolation = newReferenceViolation("message", 2, 50, "checksum2"); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation)); assertThat(mapping.get(newViolation), is(nullValue())); assertThat(newViolation.isNew(), is(true)); } @Test public void shouldNotTrackViolationIfDifferentRule() { Violation newViolation = newViolation("message", 1, 50, "checksum1"); RuleFailureModel referenceViolation = newReferenceViolation("message", 1, 51, "checksum1"); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation)); assertThat(mapping.get(newViolation), is(nullValue())); assertThat(newViolation.isNew(), is(true)); } @Test public void shouldCompareViolationsWithDatabaseFormat() { // violation messages are trimmed and can be abbreviated when persisted in database. // Comparing violation messages must use the same format. Violation newViolation = newViolation(" message ", 1, 50, "checksum1"); RuleFailureModel referenceViolation = newReferenceViolation(" message ", 1, 50, "checksum2"); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.newArrayList(referenceViolation)); assertThat(mapping.get(newViolation), equalTo(referenceViolation)); assertThat(newViolation.isNew(), is(false)); } @Test public void shouldSetDateOfNewViolations() { Violation newViolation = newViolation("message", 1, 50, "checksum"); assertThat(newViolation.getCreatedAt(), nullValue()); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Collections.<RuleFailureModel>emptyList()); assertThat(mapping.size(), is(0)); assertThat(newViolation.getCreatedAt(), is(analysisDate)); assertThat(newViolation.isNew(), is(true)); } @Test public void shouldCopyDateWhenNotNew() { Violation newViolation = newViolation("message", 1, 50, "checksum"); RuleFailureModel referenceViolation = newReferenceViolation("", 1, 50, "checksum"); Date referenceDate = DateUtils.parseDate("2009-05-18"); referenceViolation.setCreatedAt(referenceDate); assertThat(newViolation.getCreatedAt(), nullValue()); Map<Violation, RuleFailureModel> mapping = decorator.mapViolations( Lists.newArrayList(newViolation), Lists.<RuleFailureModel>newArrayList(referenceViolation)); assertThat(mapping.size(), is(1)); assertThat(newViolation.getCreatedAt(), is(referenceDate)); assertThat(newViolation.isNew(), is(false)); } private Violation newViolation(String message, Integer lineId, int ruleId) { Rule rule = Rule.create().setKey("rule"); rule.setId(ruleId); return Violation.create(rule, null).setLineId(lineId).setMessage(message); } private Violation newViolation(String message, Integer lineId, int ruleId, String lineChecksum) { return newViolation(message, lineId, ruleId).setChecksum(lineChecksum); } private RuleFailureModel newReferenceViolation( String message, Integer lineId, int ruleId, String lineChecksum) { RuleFailureModel referenceViolation = new RuleFailureModel(); referenceViolation.setId(violationId++); referenceViolation.setLine(lineId); referenceViolation.setMessage(message); referenceViolation.setRuleId(ruleId); referenceViolation.setChecksum(lineChecksum); return referenceViolation; } private int violationId = 0; }
@RunWith(MockitoJUnitRunner.class) public class DebtModelBackupTest { @Rule public UserSessionRule userSessionRule = UserSessionRule.standalone(); @Mock DbClient dbClient; @Mock DbSession session; @Mock DebtModelPluginRepository debtModelPluginRepository; @Mock CharacteristicDao dao; @Mock RuleDao ruleDao; @Mock DebtModelOperations debtModelOperations; @Mock RuleOperations ruleOperations; @Mock DebtCharacteristicsXMLImporter characteristicsXMLImporter; @Mock DebtRulesXMLImporter rulesXMLImporter; @Mock DebtModelXMLExporter debtModelXMLExporter; @Mock RuleDefinitionsLoader defLoader; @Mock System2 system2; @Captor ArgumentCaptor<CharacteristicDto> characteristicCaptor; @Captor ArgumentCaptor<RuleDto> ruleCaptor; @Captor ArgumentCaptor<ArrayList<RuleDebt>> ruleDebtListCaptor; Date oldDate = DateUtils.parseDate("2014-01-01"); Date now = DateUtils.parseDate("2014-03-19"); int currentId; DebtModelBackup debtModelBackup; @Before public void setUp() { userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); when(system2.now()).thenReturn(now.getTime()); currentId = 10; // Associate an id when inserting an object to simulate the db id generator doAnswer( new Answer() { public Object answer(InvocationOnMock invocation) { Object[] args = invocation.getArguments(); CharacteristicDto dto = (CharacteristicDto) args[0]; dto.setId(currentId++); return null; } }) .when(dao) .insert(any(CharacteristicDto.class), any(DbSession.class)); when(dbClient.openSession(false)).thenReturn(session); when(dbClient.ruleDao()).thenReturn(ruleDao); when(dbClient.debtCharacteristicDao()).thenReturn(dao); Reader defaultModelReader = mock(Reader.class); when(debtModelPluginRepository.createReaderForXMLFile("technical-debt")) .thenReturn(defaultModelReader); debtModelBackup = new DebtModelBackup( dbClient, debtModelOperations, ruleOperations, debtModelPluginRepository, characteristicsXMLImporter, rulesXMLImporter, debtModelXMLExporter, defLoader, system2, userSessionRule); } @Test public void backup() { when(dao.selectEnabledCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto() .setId(1) .setKey("PORTABILITY") .setName("Portability updated") .setOrder(2), new CharacteristicDto() .setId(2) .setKey("COMPILER") .setName("Compiler updated") .setParentId(1))); when(ruleDao.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( // Rule with overridden debt values new RuleDto() .setRepositoryKey("squid") .setRuleKey("UselessImportCheck") .setSubCharacteristicId(2) .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("2h") .setRemediationOffset("15min"), // Rule with default debt values new RuleDto() .setRepositoryKey("squid") .setRuleKey("AvoidNPE") .setDefaultSubCharacteristicId(2) .setDefaultRemediationFunction("LINEAR") .setDefaultRemediationCoefficient("2h"))); debtModelBackup.backup(); ArgumentCaptor<DebtModel> debtModelArgument = ArgumentCaptor.forClass(DebtModel.class); verify(debtModelXMLExporter).export(debtModelArgument.capture(), ruleDebtListCaptor.capture()); assertThat(debtModelArgument.getValue().rootCharacteristics()).hasSize(1); assertThat(debtModelArgument.getValue().subCharacteristics("PORTABILITY")).hasSize(1); List<RuleDebt> rules = ruleDebtListCaptor.getValue(); assertThat(rules).hasSize(2); RuleDebt rule = rules.get(0); assertThat(rule.ruleKey().repository()).isEqualTo("squid"); assertThat(rule.ruleKey().rule()).isEqualTo("UselessImportCheck"); assertThat(rule.subCharacteristicKey()).isEqualTo("COMPILER"); assertThat(rule.function()).isEqualTo("LINEAR_OFFSET"); assertThat(rule.coefficient()).isEqualTo("2h"); assertThat(rule.offset()).isEqualTo("15min"); rule = rules.get(1); assertThat(rule.ruleKey().repository()).isEqualTo("squid"); assertThat(rule.ruleKey().rule()).isEqualTo("AvoidNPE"); assertThat(rule.subCharacteristicKey()).isEqualTo("COMPILER"); assertThat(rule.function()).isEqualTo("LINEAR"); assertThat(rule.coefficient()).isEqualTo("2h"); assertThat(rule.offset()).isNull(); } @Test public void backup_with_disabled_rules() { when(dao.selectEnabledCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto() .setId(1) .setKey("PORTABILITY") .setName("Portability updated") .setOrder(2), new CharacteristicDto() .setId(2) .setKey("COMPILER") .setName("Compiler updated") .setParentId(1))); when(ruleDao.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( // Debt disabled new RuleDto() .setRepositoryKey("squid") .setRuleKey("UselessImportCheck") .setSubCharacteristicId(RuleDto.DISABLED_CHARACTERISTIC_ID), // Not debt new RuleDto().setRepositoryKey("squid").setRuleKey("AvoidNPE"))); debtModelBackup.backup(); verify(debtModelXMLExporter).export(any(DebtModel.class), ruleDebtListCaptor.capture()); assertThat(ruleDebtListCaptor.getValue()).isEmpty(); } @Test public void backup_with_rule_having_default_linear_and_overridden_offset() { when(dao.selectEnabledCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto() .setId(1) .setKey("PORTABILITY") .setName("Portability updated") .setOrder(2), new CharacteristicDto() .setId(2) .setKey("COMPILER") .setName("Compiler updated") .setParentId(1))); when(ruleDao.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( // Rule with default debt values : default value is linear (only coefficient is set) // and overridden value is constant per issue (only offset is set) // -> Ony offset should be set new RuleDto() .setRepositoryKey("squid") .setRuleKey("AvoidNPE") .setDefaultSubCharacteristicId(2) .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) .setDefaultRemediationCoefficient("2h") .setSubCharacteristicId(2) .setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.toString()) .setRemediationOffset("15min"))); debtModelBackup.backup(); ArgumentCaptor<DebtModel> debtModelArgument = ArgumentCaptor.forClass(DebtModel.class); verify(debtModelXMLExporter).export(debtModelArgument.capture(), ruleDebtListCaptor.capture()); assertThat(debtModelArgument.getValue().rootCharacteristics()).hasSize(1); assertThat(debtModelArgument.getValue().subCharacteristics("PORTABILITY")).hasSize(1); List<RuleDebt> rules = ruleDebtListCaptor.getValue(); assertThat(rules).hasSize(1); RuleDebt rule = rules.get(0); assertThat(rule.ruleKey().repository()).isEqualTo("squid"); assertThat(rule.ruleKey().rule()).isEqualTo("AvoidNPE"); assertThat(rule.subCharacteristicKey()).isEqualTo("COMPILER"); assertThat(rule.function()).isEqualTo("CONSTANT_ISSUE"); assertThat(rule.offset()).isEqualTo("15min"); assertThat(rule.coefficient()).isNull(); } @Test public void backup_from_language() { when(dao.selectEnabledCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto() .setId(1) .setKey("PORTABILITY") .setName("Portability updated") .setOrder(2), new CharacteristicDto() .setId(2) .setKey("COMPILER") .setName("Compiler updated") .setParentId(1))); when(ruleDao.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( new RuleDto() .setId(1) .setRepositoryKey("squid") .setRuleKey("UselessImportCheck") .setLanguage("java") .setSubCharacteristicId(2) .setRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE.toString()) .setRemediationOffset("15min"), // .setCreatedAt(oldDate).setUpdatedAt(oldDate), // Should be ignored new RuleDto() .setId(2) .setRepositoryKey("checkstyle") .setLanguage("java2") .setSubCharacteristicId(3) .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) .setRemediationCoefficient("2h") // .setCreatedAt(oldDate).setUpdatedAt(oldDate) )); debtModelBackup.backup("java"); verify(debtModelXMLExporter).export(any(DebtModel.class), ruleDebtListCaptor.capture()); List<RuleDebt> rules = ruleDebtListCaptor.getValue(); assertThat(rules).hasSize(1); RuleDebt rule = rules.get(0); assertThat(rule.ruleKey().repository()).isEqualTo("squid"); assertThat(rule.ruleKey().rule()).isEqualTo("UselessImportCheck"); assertThat(rule.subCharacteristicKey()).isEqualTo("COMPILER"); assertThat(rule.function()).isEqualTo("CONSTANT_ISSUE"); assertThat(rule.coefficient()).isNull(); assertThat(rule.offset()).isEqualTo("15min"); } @Test public void create_characteristics_when_restoring_characteristics() { when(dao.selectEnabledCharacteristics(session)) .thenReturn(Collections.<CharacteristicDto>emptyList()); debtModelBackup.restoreCharacteristics( new DebtModel() .addRootCharacteristic( new DefaultDebtCharacteristic() .setKey("PORTABILITY") .setName("Portability") .setOrder(1)) .addSubCharacteristic( new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"), now, session); verify(dao, times(2)).insert(characteristicCaptor.capture(), eq(session)); CharacteristicDto dto1 = characteristicCaptor.getAllValues().get(0); assertThat(dto1.getId()).isEqualTo(10); assertThat(dto1.getKey()).isEqualTo("PORTABILITY"); assertThat(dto1.getName()).isEqualTo("Portability"); assertThat(dto1.getParentId()).isNull(); assertThat(dto1.getOrder()).isEqualTo(1); assertThat(dto1.getCreatedAt()).isEqualTo(now); assertThat(dto1.getUpdatedAt()).isNull(); CharacteristicDto dto2 = characteristicCaptor.getAllValues().get(1); assertThat(dto2.getId()).isEqualTo(11); assertThat(dto2.getKey()).isEqualTo("COMPILER"); assertThat(dto2.getName()).isEqualTo("Compiler"); assertThat(dto2.getParentId()).isEqualTo(10); assertThat(dto2.getOrder()).isNull(); assertThat(dto2.getCreatedAt()).isEqualTo(now); assertThat(dto2.getUpdatedAt()).isNull(); } @Test public void update_characteristics_when_restoring_characteristics() { 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))); debtModelBackup.restoreCharacteristics( new DebtModel() .addRootCharacteristic( new DefaultDebtCharacteristic() .setKey("PORTABILITY") .setName("Portability") .setOrder(1)) .addSubCharacteristic( new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY"), 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.getName()).isEqualTo("Portability"); assertThat(dto1.getParentId()).isNull(); assertThat(dto1.getOrder()).isEqualTo(1); assertThat(dto1.getCreatedAt()).isEqualTo(oldDate); assertThat(dto1.getUpdatedAt()).isEqualTo(now); CharacteristicDto dto2 = characteristicCaptor.getAllValues().get(1); assertThat(dto2.getId()).isEqualTo(2); assertThat(dto2.getKey()).isEqualTo("COMPILER"); assertThat(dto2.getName()).isEqualTo("Compiler"); assertThat(dto2.getParentId()).isEqualTo(1); assertThat(dto2.getOrder()).isNull(); assertThat(dto2.getCreatedAt()).isEqualTo(oldDate); assertThat(dto2.getUpdatedAt()).isEqualTo(now); } @Test public void update_parent_when_restoring_characteristics() { 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"), 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() { CharacteristicDto dto1 = new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability").setOrder(1); CharacteristicDto dto2 = new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler").setParentId(1); when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList(dto1, dto2)); debtModelBackup.restoreCharacteristics(new DebtModel(), now, session); verify(debtModelOperations).delete(dto1, now, session); verify(debtModelOperations).delete(dto2, now, session); } @Test public void reset_model() { 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.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( new RuleDto() .setRepositoryKey("squid") .setRuleKey("NPE") .setDefaultSubCharacteristicId(10) .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) .setDefaultRemediationCoefficient("2h") .setSubCharacteristicId(2) .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("2h") .setRemediationOffset("15min"))); 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); verify(dao, times(2)).update(any(CharacteristicDto.class), eq(session)); verifyNoMoreInteractions(dao); verify(ruleDao).selectEnabledAndNonManual(session); verify(ruleDao).update(eq(session), ruleCaptor.capture()); verifyNoMoreInteractions(ruleDao); 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(); assertThat(rule.getRemediationOffset()).isNull(); assertThat(rule.getUpdatedAt()).isEqualTo(now); } @Test public void reset_model_when_no_default_value() { 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.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( new RuleDto() .setRepositoryKey("squid") .setRuleKey("NPE") .setDefaultSubCharacteristicId(10) .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) .setDefaultRemediationCoefficient("2h") .setSubCharacteristicId(2) .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("2h") .setRemediationOffset("15min"))); 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).selectEnabledAndNonManual(session); verify(ruleDao).update(eq(session), ruleCaptor.capture()); verifyNoMoreInteractions(ruleDao); 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 reset_model_on_custom_rules() { 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.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( // Template rule new RuleDto() .setId(5) .setRepositoryKey("squid") .setRuleKey("XPath") .setSubCharacteristicId(2) .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("2h") .setRemediationOffset("15min"), // Custom rule new RuleDto() .setId(6) .setRepositoryKey("squid") .setRuleKey("XPath_1369910135") .setTemplateId(5) .setSubCharacteristicId(2) .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("2h") .setRemediationOffset("15min"))); RulesDefinition.Context context = new RulesDefinition.Context(); // Template rule RulesDefinition.NewRepository repo = context.createRepository("squid", "java").setName("XPath"); RulesDefinition.NewRule newRule = repo.createRule("XPath") .setName("XPath") .setHtmlDescription("XPath") .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(ruleDao).selectEnabledAndNonManual(session); verify(ruleDao, times(2)).update(eq(session), ruleCaptor.capture()); verifyNoMoreInteractions(ruleDao); verify(session).commit(); RuleDto rule = ruleCaptor.getAllValues().get(1); assertThat(rule.getId()).isEqualTo(6); 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(); assertThat(rule.getRemediationOffset()).isNull(); assertThat(rule.getUpdatedAt()).isEqualTo(now); } @Test public void reset_model_do_not_load_rule_definitions_if_no_rule() { 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.selectEnabledAndNonManual(session)).thenReturn(Collections.<RuleDto>emptyList()); debtModelBackup.reset(); verify(dao).selectEnabledCharacteristics(session); verify(dao, times(2)).update(any(CharacteristicDto.class), eq(session)); verifyNoMoreInteractions(dao); verify(ruleDao).selectEnabledAndNonManual(session); verify(ruleDao, never()).update(eq(session), any(RuleDto.class)); verifyZeroInteractions(defLoader); verify(session).commit(); } @Test public void restore_from_xml() { when(characteristicsXMLImporter.importXML(anyString())) .thenReturn( new DebtModel() .addRootCharacteristic( new DefaultDebtCharacteristic() .setKey("PORTABILITY") .setName("Portability") .setOrder(1)) .addSubCharacteristic( new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY")); CharacteristicDto compiler = new CharacteristicDto() .setId(2) .setKey("COMPILER") .setName("Compiler") .setParentId(1) .setCreatedAt(oldDate); when(dao.selectEnabledCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto() .setId(1) .setKey("PORTABILITY") .setName("Portability") .setOrder(1) .setCreatedAt(oldDate), new CharacteristicDto() .setId(3) .setKey("HARDWARE") .setName("Hardware") .setParentId(1) .setCreatedAt(oldDate), compiler)); when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))) .thenReturn( newArrayList( new RuleDebt() .setRuleKey(RuleKey.of("squid", "UselessImportCheck")) .setSubCharacteristicKey("COMPILER") .setFunction(DebtRemediationFunction.Type.LINEAR.name()) .setCoefficient("2h"))); when(ruleDao.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( new RuleDto() .setId(1) .setRepositoryKey("squid") .setRuleKey("UselessImportCheck") .setDefaultSubCharacteristicId(3) .setDefaultRemediationFunction("LINEAR") .setDefaultRemediationCoefficient("2h") // .setCreatedAt(oldDate).setUpdatedAt(oldDate) )); debtModelBackup.restoreFromXml("<xml/>"); verify(ruleOperations) .updateRule( ruleCaptor.capture(), eq(compiler), eq("LINEAR"), eq("2h"), isNull(String.class), eq(session)); verify(ruleDao).selectEnabledAndNonManual(session); verify(session).commit(); } @Test public void restore_from_xml_disable_rule_debt_when_not_in_xml_and_rule_have_default_debt_values() { when(characteristicsXMLImporter.importXML(anyString())) .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") .setOrder(1) .setCreatedAt(oldDate), new CharacteristicDto() .setId(2) .setKey("COMPILER") .setName("Compiler") .setParentId(1) .setCreatedAt(oldDate))); when(ruleDao.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( new RuleDto() .setId(1) .setRepositoryKey("squid") .setRuleKey("UselessImportCheck") .setDefaultSubCharacteristicId(2) .setDefaultRemediationFunction("LINEAR_OFFSET") .setDefaultRemediationCoefficient("2h") .setDefaultRemediationOffset("15min") // .setCreatedAt(oldDate).setUpdatedAt(oldDate) )); debtModelBackup.restoreFromXml("<xml/>"); verify(ruleOperations) .updateRule( ruleCaptor.capture(), isNull(CharacteristicDto.class), isNull(String.class), isNull(String.class), isNull(String.class), eq(session)); verify(ruleDao).selectEnabledAndNonManual(session); verify(session).commit(); } @Test public void restore_from_xml_and_language() { when(characteristicsXMLImporter.importXML(anyString())) .thenReturn( new DebtModel() .addRootCharacteristic( new DefaultDebtCharacteristic() .setKey("PORTABILITY") .setName("Portability") .setOrder(1)) .addSubCharacteristic( new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY")); CharacteristicDto compiler = new CharacteristicDto() .setId(2) .setKey("COMPILER") .setName("Compiler") .setParentId(1) .setCreatedAt(oldDate); when(dao.selectEnabledCharacteristics(session)) .thenReturn( newArrayList( new CharacteristicDto() .setId(1) .setKey("PORTABILITY") .setName("Portability") .setOrder(1) .setCreatedAt(oldDate), compiler)); when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))) .thenReturn( newArrayList( new RuleDebt() .setRuleKey(RuleKey.of("squid", "UselessImportCheck")) .setSubCharacteristicKey("COMPILER") .setFunction(DebtRemediationFunction.Type.LINEAR.name()) .setCoefficient("2h"))); when(ruleDao.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( new RuleDto() .setId(1) .setRepositoryKey("squid") .setRuleKey("UselessImportCheck") .setLanguage("java") .setDefaultSubCharacteristicId(10) .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) .setDefaultRemediationCoefficient("2h"), // Should be ignored new RuleDto() .setId(2) .setRepositoryKey("checkstyle") .setLanguage("java2") .setSubCharacteristicId(3) .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) .setRemediationCoefficient("2h"))); debtModelBackup.restoreFromXml("<xml/>", "java"); verify(ruleOperations) .updateRule( ruleCaptor.capture(), eq(compiler), eq("LINEAR"), eq("2h"), isNull(String.class), eq(session)); verify(ruleDao).selectEnabledAndNonManual(session); verify(session).commit(); } @Test public void restore_from_xml_and_language_disable_no_more_existing_characteristics() { when(characteristicsXMLImporter.importXML(anyString())) .thenReturn( new DebtModel() .addRootCharacteristic( new DefaultDebtCharacteristic() .setKey("PORTABILITY") .setName("Portability") .setOrder(1))); CharacteristicDto dto1 = new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability").setOrder(1); // No more existing characteristic CharacteristicDto dto2 = new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler").setParentId(1); when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList(dto1, dto2)); debtModelBackup.restoreFromXml("<xml/>", "java"); verify(debtModelOperations).delete(dto2, now, session); verify(session).commit(); } @Test public void restore_from_xml_and_language_with_rule_not_in_xml() { when(characteristicsXMLImporter.importXML(anyString())) .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(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))) .thenReturn(Collections.<RuleDebt>emptyList()); when(ruleDao.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( // Rule does not exits in XML -> debt will be disabled new RuleDto() .setId(1) .setRepositoryKey("squid") .setRuleKey("UselessImportCheck") .setLanguage("java") .setDefaultSubCharacteristicId(2) .setDefaultRemediationFunction("LINEAR") .setDefaultRemediationCoefficient("2h") .setSubCharacteristicId(2) .setRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString()) .setRemediationCoefficient("2h") .setRemediationOffset("15min"))); debtModelBackup.restoreFromXml("<xml/>", "java"); verify(ruleOperations) .updateRule( ruleCaptor.capture(), isNull(CharacteristicDto.class), isNull(String.class), isNull(String.class), isNull(String.class), eq(session)); verify(ruleDao).selectEnabledAndNonManual(session); verify(session).commit(); } @Test public void restore_from_xml_add_warning_message_when_rule_from_xml_is_not_found() { when(characteristicsXMLImporter.importXML(anyString())) .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") .setOrder(1) .setCreatedAt(oldDate), new CharacteristicDto() .setId(2) .setKey("COMPILER") .setName("Compiler") .setParentId(1) .setCreatedAt(oldDate))); when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))) .thenReturn( newArrayList( new RuleDebt() .setRuleKey(RuleKey.of("squid", "UselessImportCheck")) .setSubCharacteristicKey("COMPILER") .setFunction(DebtRemediationFunction.Type.LINEAR.name()) .setCoefficient("2h"))); when(ruleDao.selectEnabledAndNonManual(session)).thenReturn(Collections.<RuleDto>emptyList()); assertThat(debtModelBackup.restoreFromXml("<xml/>").getWarnings()).hasSize(1); verifyZeroInteractions(ruleOperations); verify(ruleDao).selectEnabledAndNonManual(session); verify(session).commit(); } @Test public void restore_from_xml_add_error_message_when_illegal_argument_exception() { when(characteristicsXMLImporter.importXML(anyString())) .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") .setOrder(1) .setCreatedAt(oldDate), new CharacteristicDto() .setId(2) .setKey("COMPILER") .setName("Compiler") .setParentId(1) .setCreatedAt(oldDate))); when(rulesXMLImporter.importXML(anyString(), any(ValidationMessages.class))) .thenReturn( newArrayList( new RuleDebt() .setRuleKey(RuleKey.of("squid", "UselessImportCheck")) .setSubCharacteristicKey("COMPILER") .setFunction(DebtRemediationFunction.Type.LINEAR.name()) .setCoefficient("2h"))); when(ruleDao.selectEnabledAndNonManual(session)) .thenReturn( newArrayList( new RuleDto() .setId(1) .setRepositoryKey("squid") .setRuleKey("UselessImportCheck") .setDefaultSubCharacteristicId(3) .setDefaultRemediationFunction("LINEAR") .setDefaultRemediationCoefficient("2h") // .setCreatedAt(oldDate).setUpdatedAt(oldDate) )); when(ruleOperations.updateRule( any(RuleDto.class), any(CharacteristicDto.class), anyString(), anyString(), anyString(), eq(session))) .thenThrow(IllegalArgumentException.class); assertThat(debtModelBackup.restoreFromXml("<xml/>").getErrors()).hasSize(1); verify(ruleDao).selectEnabledAndNonManual(session); verify(session, never()).commit(); } }