3 * Copyright (C) 2009-2022 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.ce.task.projectanalysis.step;
22 import java.util.Arrays;
23 import java.util.Date;
24 import java.util.List;
25 import org.junit.After;
26 import org.junit.Before;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.junit.rules.TemporaryFolder;
30 import org.mockito.ArgumentCaptor;
31 import org.sonar.api.rule.RuleKey;
32 import org.sonar.api.rules.RuleType;
33 import org.sonar.api.utils.System2;
34 import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule;
35 import org.sonar.ce.task.projectanalysis.issue.AdHocRuleCreator;
36 import org.sonar.ce.task.projectanalysis.issue.ProtoIssueCache;
37 import org.sonar.ce.task.projectanalysis.issue.RuleRepositoryImpl;
38 import org.sonar.ce.task.projectanalysis.issue.UpdateConflictResolver;
39 import org.sonar.ce.task.projectanalysis.period.Period;
40 import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule;
41 import org.sonar.ce.task.projectanalysis.util.cache.DiskCache;
42 import org.sonar.ce.task.step.ComputationStep;
43 import org.sonar.ce.task.step.TestComputationStepContext;
44 import org.sonar.core.issue.DefaultIssue;
45 import org.sonar.core.issue.DefaultIssueComment;
46 import org.sonar.core.issue.FieldDiffs;
47 import org.sonar.core.util.UuidFactoryImpl;
48 import org.sonar.db.DbClient;
49 import org.sonar.db.DbSession;
50 import org.sonar.db.DbTester;
51 import org.sonar.db.component.ComponentDto;
52 import org.sonar.db.issue.IssueChangeDto;
53 import org.sonar.db.issue.IssueDto;
54 import org.sonar.db.issue.IssueMapper;
55 import org.sonar.db.newcodeperiod.NewCodePeriodType;
56 import org.sonar.db.rule.RuleDefinitionDto;
57 import org.sonar.db.rule.RuleTesting;
58 import org.sonar.scanner.protocol.output.ScannerReport;
59 import org.sonar.server.issue.IssueStorage;
61 import static java.util.Collections.singletonList;
62 import static org.assertj.core.api.Assertions.assertThat;
63 import static org.assertj.core.data.MapEntry.entry;
64 import static org.mockito.ArgumentMatchers.any;
65 import static org.mockito.ArgumentMatchers.eq;
66 import static org.mockito.Mockito.mock;
67 import static org.mockito.Mockito.verify;
68 import static org.mockito.Mockito.when;
69 import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
70 import static org.sonar.api.issue.Issue.STATUS_CLOSED;
71 import static org.sonar.api.issue.Issue.STATUS_OPEN;
72 import static org.sonar.api.rule.Severity.BLOCKER;
73 import static org.sonar.db.component.ComponentTesting.newFileDto;
74 import static org.sonar.db.issue.IssueTesting.newCodeReferenceIssue;
76 public class PersistIssuesStepTest extends BaseStepTest {
78 private static final long NOW = 1_400_000_000_000L;
81 public TemporaryFolder temp = new TemporaryFolder();
83 public DbTester db = DbTester.create(System2.INSTANCE);
85 public BatchReportReaderRule reportReader = new BatchReportReaderRule();
87 public PeriodHolderRule periodHolder = new PeriodHolderRule();
89 private System2 system2 = mock(System2.class);
90 private DbSession session = db.getSession();
91 private DbClient dbClient = db.getDbClient();
92 private UpdateConflictResolver conflictResolver = mock(UpdateConflictResolver.class);
93 private ProtoIssueCache protoIssueCache;
94 private ComputationStep underTest;
96 private AdHocRuleCreator adHocRuleCreator = mock(AdHocRuleCreator.class);
99 protected ComputationStep step() {
104 public void setup() throws Exception {
105 periodHolder.setPeriod(new Period(NewCodePeriodType.NUMBER_OF_DAYS.name(), "10", 1000L));
107 protoIssueCache = new ProtoIssueCache(temp.newFile(), System2.INSTANCE);
108 reportReader.setMetadata(ScannerReport.Metadata.getDefaultInstance());
110 underTest = new PersistIssuesStep(dbClient, system2, conflictResolver, new RuleRepositoryImpl(adHocRuleCreator, dbClient), periodHolder,
111 protoIssueCache, new IssueStorage(), UuidFactoryImpl.INSTANCE);
115 public void tearDown() {
120 public void insert_copied_issue() {
121 RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
122 db.rules().insert(rule);
123 ComponentDto project = db.components().insertPrivateProject();
124 ComponentDto file = db.components().insertComponent(newFileDto(project, null));
125 when(system2.now()).thenReturn(NOW);
126 String issueKey = "ISSUE-1";
128 protoIssueCache.newAppender().append(new DefaultIssue()
130 .setType(RuleType.CODE_SMELL)
131 .setRuleKey(rule.getKey())
132 .setComponentUuid(file.uuid())
133 .setComponentKey(file.getKey())
134 .setProjectUuid(project.uuid())
135 .setProjectKey(project.getKey())
136 .setSeverity(BLOCKER)
137 .setStatus(STATUS_OPEN)
138 .setTags(singletonList("test"))
141 .setType(RuleType.BUG)
142 .setCreationDate(new Date(NOW))
144 .addComment(new DefaultIssueComment()
146 .setIssueKey(issueKey)
147 .setUserUuid("john_uuid")
148 .setMarkdownText("Some text")
149 .setCreatedAt(new Date(NOW))
150 .setUpdatedAt(new Date(NOW))
154 .setIssueKey(issueKey)
155 .setUserUuid("john_uuid")
156 .setDiff("technicalDebt", null, 1L)
157 .setCreationDate(new Date(NOW))))
160 TestComputationStepContext context = new TestComputationStepContext();
161 underTest.execute(context);
163 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
165 assertThat(result.getKey()).isEqualTo(issueKey);
166 assertThat(result.getRuleKey()).isEqualTo(rule.getKey());
167 assertThat(result.getComponentUuid()).isEqualTo(file.uuid());
168 assertThat(result.getProjectUuid()).isEqualTo(project.uuid());
169 assertThat(result.getSeverity()).isEqualTo(BLOCKER);
170 assertThat(result.getStatus()).isEqualTo(STATUS_OPEN);
171 assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant());
172 assertThat(result.getTags()).containsExactlyInAnyOrder("test");
173 assertThat(result.isNewCodeReferenceIssue()).isFalse();
175 List<IssueChangeDto> changes = dbClient.issueChangeDao().selectByIssueKeys(session, Arrays.asList(issueKey));
176 assertThat(changes).extracting(IssueChangeDto::getChangeType).containsExactly(IssueChangeDto.TYPE_COMMENT, IssueChangeDto.TYPE_FIELD_CHANGE);
177 assertThat(context.getStatistics().getAll()).contains(
178 entry("inserts", "1"), entry("updates", "0"), entry("merged", "0"));
182 public void insert_copied_issue_with_minimal_info() {
183 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
185 RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
186 db.rules().insert(rule);
187 ComponentDto project = db.components().insertPrivateProject();
188 ComponentDto file = db.components().insertComponent(newFileDto(project, null));
189 when(system2.now()).thenReturn(NOW);
190 String issueKey = "ISSUE-2";
192 protoIssueCache.newAppender().append(new DefaultIssue()
194 .setType(RuleType.CODE_SMELL)
195 .setRuleKey(rule.getKey())
196 .setComponentUuid(file.uuid())
197 .setComponentKey(file.getKey())
198 .setProjectUuid(project.uuid())
199 .setProjectKey(project.getKey())
200 .setSeverity(BLOCKER)
201 .setStatus(STATUS_OPEN)
204 .setType(RuleType.BUG)
205 .setCreationDate(new Date(NOW))
209 TestComputationStepContext context = new TestComputationStepContext();
210 underTest.execute(context);
212 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
213 assertThat(result.getKey()).isEqualTo(issueKey);
214 assertThat(result.getRuleKey()).isEqualTo(rule.getKey());
215 assertThat(result.getComponentUuid()).isEqualTo(file.uuid());
216 assertThat(result.getProjectUuid()).isEqualTo(project.uuid());
217 assertThat(result.getSeverity()).isEqualTo(BLOCKER);
218 assertThat(result.getStatus()).isEqualTo(STATUS_OPEN);
219 assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant());
220 assertThat(result.getTags()).isEmpty();
221 assertThat(result.isNewCodeReferenceIssue()).isFalse();
223 assertThat(dbClient.issueChangeDao().selectByIssueKeys(session, Arrays.asList(issueKey))).isEmpty();
224 assertThat(context.getStatistics().getAll()).contains(
225 entry("inserts", "1"), entry("updates", "0"), entry("merged", "0"));
229 public void insert_merged_issue() {
230 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
231 RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
232 db.rules().insert(rule);
233 ComponentDto project = db.components().insertPrivateProject();
234 ComponentDto file = db.components().insertComponent(newFileDto(project, null));
235 when(system2.now()).thenReturn(NOW);
236 String issueKey = "ISSUE-3";
238 protoIssueCache.newAppender().append(new DefaultIssue()
240 .setType(RuleType.CODE_SMELL)
241 .setRuleKey(rule.getKey())
242 .setComponentUuid(file.uuid())
243 .setComponentKey(file.getKey())
244 .setProjectUuid(project.uuid())
245 .setProjectKey(project.getKey())
246 .setSeverity(BLOCKER)
247 .setStatus(STATUS_OPEN)
249 .setIsOnChangedLine(true)
251 .setType(RuleType.BUG)
252 .setCreationDate(new Date(NOW))
254 .addComment(new DefaultIssueComment()
256 .setIssueKey(issueKey)
257 .setUserUuid("john_uuid")
258 .setMarkdownText("Some text")
259 .setUpdatedAt(new Date(NOW))
260 .setCreatedAt(new Date(NOW))
262 .setCurrentChange(new FieldDiffs()
263 .setIssueKey(issueKey)
264 .setUserUuid("john_uuid")
265 .setDiff("technicalDebt", null, 1L)
266 .setCreationDate(new Date(NOW))))
269 TestComputationStepContext context = new TestComputationStepContext();
270 underTest.execute(context);
272 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
273 assertThat(result.getKey()).isEqualTo(issueKey);
274 assertThat(result.getRuleKey()).isEqualTo(rule.getKey());
275 assertThat(result.getComponentUuid()).isEqualTo(file.uuid());
276 assertThat(result.getProjectUuid()).isEqualTo(project.uuid());
277 assertThat(result.getSeverity()).isEqualTo(BLOCKER);
278 assertThat(result.getStatus()).isEqualTo(STATUS_OPEN);
279 assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant());
280 assertThat(result.isNewCodeReferenceIssue()).isTrue();
282 List<IssueChangeDto> changes = dbClient.issueChangeDao().selectByIssueKeys(session, Arrays.asList(issueKey));
283 assertThat(changes).extracting(IssueChangeDto::getChangeType).containsExactly(IssueChangeDto.TYPE_COMMENT, IssueChangeDto.TYPE_FIELD_CHANGE);
284 assertThat(context.getStatistics().getAll()).contains(
285 entry("inserts", "1"), entry("updates", "0"), entry("merged", "0"));
289 public void update_conflicting_issue() {
290 RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
291 db.rules().insert(rule);
292 ComponentDto project = db.components().insertPrivateProject();
293 ComponentDto file = db.components().insertComponent(newFileDto(project, null));
294 IssueDto issue = db.issues().insert(rule, project, file,
295 i -> i.setStatus(STATUS_OPEN)
297 .setCreatedAt(NOW - 1_000_000_000L)
298 // simulate the issue has been updated after the analysis ran
299 .setUpdatedAt(NOW + 1_000_000_000L));
300 issue = dbClient.issueDao().selectByKey(db.getSession(), issue.getKey()).get();
301 DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender();
302 when(system2.now()).thenReturn(NOW);
304 DefaultIssue defaultIssue = issue.toDefaultIssue()
305 .setStatus(STATUS_CLOSED)
306 .setResolution(RESOLUTION_FIXED)
310 issueCacheAppender.append(defaultIssue).close();
312 TestComputationStepContext context = new TestComputationStepContext();
313 underTest.execute(context);
315 ArgumentCaptor<IssueDto> issueDtoCaptor = ArgumentCaptor.forClass(IssueDto.class);
316 verify(conflictResolver).resolve(eq(defaultIssue), issueDtoCaptor.capture(), any(IssueMapper.class));
317 assertThat(issueDtoCaptor.getValue().getKey()).isEqualTo(issue.getKey());
318 assertThat(context.getStatistics().getAll()).contains(
319 entry("inserts", "0"), entry("updates", "1"), entry("merged", "1"));
323 public void insert_new_issue() {
324 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
325 RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
326 db.rules().insert(rule);
327 ComponentDto project = db.components().insertPrivateProject();
328 ComponentDto file = db.components().insertComponent(newFileDto(project, null));
330 String issueKey = "ISSUE-4";
332 protoIssueCache.newAppender().append(new DefaultIssue()
334 .setType(RuleType.CODE_SMELL)
335 .setRuleKey(rule.getKey())
336 .setComponentUuid(file.uuid())
337 .setComponentKey(file.getKey())
338 .setProjectUuid(project.uuid())
339 .setProjectKey(project.getKey())
340 .setSeverity(BLOCKER)
341 .setStatus(STATUS_OPEN)
342 .setCreationDate(new Date(NOW))
344 .setIsOnChangedLine(true)
345 .setType(RuleType.BUG)).close();
347 TestComputationStepContext context = new TestComputationStepContext();
348 underTest.execute(context);
350 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
351 assertThat(result.getKey()).isEqualTo(issueKey);
352 assertThat(result.getRuleKey()).isEqualTo(rule.getKey());
353 assertThat(result.getComponentUuid()).isEqualTo(file.uuid());
354 assertThat(result.getProjectUuid()).isEqualTo(project.uuid());
355 assertThat(result.getSeverity()).isEqualTo(BLOCKER);
356 assertThat(result.getStatus()).isEqualTo(STATUS_OPEN);
357 assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant());
358 assertThat(context.getStatistics().getAll()).contains(
359 entry("inserts", "1"), entry("updates", "0"), entry("merged", "0"));
360 assertThat(result.isNewCodeReferenceIssue()).isTrue();
364 public void close_issue() {
365 ComponentDto project = db.components().insertPrivateProject();
366 ComponentDto file = db.components().insertComponent(newFileDto(project));
367 RuleDefinitionDto rule = db.rules().insert();
368 IssueDto issue = db.issues().insert(rule, project, file,
369 i -> i.setStatus(STATUS_OPEN)
371 .setCreatedAt(NOW - 1_000_000_000L)
372 .setUpdatedAt(NOW - 1_000_000_000L));
373 DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender();
375 issueCacheAppender.append(
376 issue.toDefaultIssue()
377 .setStatus(STATUS_CLOSED)
378 .setResolution(RESOLUTION_FIXED)
384 TestComputationStepContext context = new TestComputationStepContext();
385 underTest.execute(context);
387 IssueDto issueReloaded = db.getDbClient().issueDao().selectByKey(db.getSession(), issue.getKey()).get();
388 assertThat(issueReloaded.getStatus()).isEqualTo(STATUS_CLOSED);
389 assertThat(issueReloaded.getResolution()).isEqualTo(RESOLUTION_FIXED);
390 assertThat(context.getStatistics().getAll()).contains(
391 entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));
395 public void handle_no_longer_new_issue() {
396 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
397 RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
398 db.rules().insert(rule);
399 ComponentDto project = db.components().insertPrivateProject();
400 ComponentDto file = db.components().insertComponent(newFileDto(project, null));
401 when(system2.now()).thenReturn(NOW);
402 String issueKey = "ISSUE-5";
404 DefaultIssue defaultIssue = new DefaultIssue()
406 .setType(RuleType.CODE_SMELL)
407 .setRuleKey(rule.getKey())
408 .setComponentUuid(file.uuid())
409 .setComponentKey(file.getKey())
410 .setProjectUuid(project.uuid())
411 .setProjectKey(project.getKey())
412 .setSeverity(BLOCKER)
413 .setStatus(STATUS_OPEN)
415 .setIsOnChangedLine(true)
416 .setIsNewCodeReferenceIssue(true)
417 .setIsNoLongerNewCodeReferenceIssue(false)
419 .setType(RuleType.BUG)
420 .setCreationDate(new Date(NOW))
423 IssueDto issueDto = IssueDto.toDtoForComputationInsert(defaultIssue, rule.getUuid(), NOW);
424 dbClient.issueDao().insert(session, issueDto);
425 dbClient.issueDao().insertAsNewCodeOnReferenceBranch(session, newCodeReferenceIssue(issueDto));
428 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
429 assertThat(result.isNewCodeReferenceIssue()).isTrue();
431 protoIssueCache.newAppender().append(defaultIssue.setNew(false)
432 .setIsOnChangedLine(false)
433 .setIsNewCodeReferenceIssue(false)
434 .setIsNoLongerNewCodeReferenceIssue(true))
437 TestComputationStepContext context = new TestComputationStepContext();
438 underTest.execute(context);
440 assertThat(context.getStatistics().getAll()).contains(
441 entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));
443 result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
444 assertThat(result.isNewCodeReferenceIssue()).isFalse();
448 public void handle_existing_new_code_issue_migration() {
449 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
450 RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
451 db.rules().insert(rule);
452 ComponentDto project = db.components().insertPrivateProject();
453 ComponentDto file = db.components().insertComponent(newFileDto(project, null));
454 when(system2.now()).thenReturn(NOW);
455 String issueKey = "ISSUE-6";
457 DefaultIssue defaultIssue = new DefaultIssue()
459 .setType(RuleType.CODE_SMELL)
460 .setRuleKey(rule.getKey())
461 .setComponentUuid(file.uuid())
462 .setComponentKey(file.getKey())
463 .setProjectUuid(project.uuid())
464 .setProjectKey(project.getKey())
465 .setSeverity(BLOCKER)
466 .setStatus(STATUS_OPEN)
469 .setType(RuleType.BUG)
470 .setCreationDate(new Date(NOW))
473 IssueDto issueDto = IssueDto.toDtoForComputationInsert(defaultIssue, rule.getUuid(), NOW);
474 dbClient.issueDao().insert(session, issueDto);
477 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
478 assertThat(result.isNewCodeReferenceIssue()).isFalse();
480 protoIssueCache.newAppender().append(defaultIssue.setNew(false)
481 .setIsOnChangedLine(true)
482 .setIsNewCodeReferenceIssue(false)
483 .setIsNoLongerNewCodeReferenceIssue(false))
486 TestComputationStepContext context = new TestComputationStepContext();
487 underTest.execute(context);
489 assertThat(context.getStatistics().getAll()).contains(
490 entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));
492 result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
493 assertThat(result.isNewCodeReferenceIssue()).isTrue();
497 public void handle_existing_without_need_for_new_code_issue_migration() {
498 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
499 RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
500 db.rules().insert(rule);
501 ComponentDto project = db.components().insertPrivateProject();
502 ComponentDto file = db.components().insertComponent(newFileDto(project, null));
503 when(system2.now()).thenReturn(NOW);
504 String issueKey = "ISSUE-7";
506 DefaultIssue defaultIssue = new DefaultIssue()
508 .setType(RuleType.CODE_SMELL)
509 .setRuleKey(rule.getKey())
510 .setComponentUuid(file.uuid())
511 .setComponentKey(file.getKey())
512 .setProjectUuid(project.uuid())
513 .setProjectKey(project.getKey())
514 .setSeverity(BLOCKER)
515 .setStatus(STATUS_OPEN)
517 .setIsOnChangedLine(true)
518 .setIsNewCodeReferenceIssue(true)
519 .setIsNoLongerNewCodeReferenceIssue(false)
521 .setType(RuleType.BUG)
522 .setCreationDate(new Date(NOW))
525 IssueDto issueDto = IssueDto.toDtoForComputationInsert(defaultIssue, rule.getUuid(), NOW);
526 dbClient.issueDao().insert(session, issueDto);
527 dbClient.issueDao().insertAsNewCodeOnReferenceBranch(session, newCodeReferenceIssue(issueDto));
530 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
531 assertThat(result.isNewCodeReferenceIssue()).isTrue();
533 protoIssueCache.newAppender().append(defaultIssue.setNew(false)
534 .setIsOnChangedLine(false)
535 .setIsNewCodeReferenceIssue(true)
536 .setIsOnChangedLine(true)
537 .setIsNoLongerNewCodeReferenceIssue(false))
540 TestComputationStepContext context = new TestComputationStepContext();
541 underTest.execute(context);
543 assertThat(context.getStatistics().getAll()).contains(
544 entry("inserts", "0"), entry("updates", "0"), entry("merged", "0"));
546 result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
547 assertThat(result.isNewCodeReferenceIssue()).isTrue();
551 public void add_comment() {
552 ComponentDto project = db.components().insertPrivateProject();
553 ComponentDto file = db.components().insertComponent(newFileDto(project));
554 RuleDefinitionDto rule = db.rules().insert();
555 IssueDto issue = db.issues().insert(rule, project, file,
556 i -> i.setStatus(STATUS_OPEN)
558 .setCreatedAt(NOW - 1_000_000_000L)
559 .setUpdatedAt(NOW - 1_000_000_000L));
560 DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender();
562 issueCacheAppender.append(
563 issue.toDefaultIssue()
564 .setStatus(STATUS_CLOSED)
565 .setResolution(RESOLUTION_FIXED)
569 .addComment(new DefaultIssueComment()
571 .setIssueKey(issue.getKey())
572 .setUserUuid("john_uuid")
573 .setMarkdownText("Some text")
574 .setCreatedAt(new Date(NOW))
575 .setUpdatedAt(new Date(NOW))
579 TestComputationStepContext context = new TestComputationStepContext();
580 underTest.execute(context);
582 IssueChangeDto issueChangeDto = db.getDbClient().issueChangeDao().selectByIssueKeys(db.getSession(), singletonList(issue.getKey())).get(0);
583 assertThat(issueChangeDto)
584 .extracting(IssueChangeDto::getChangeType, IssueChangeDto::getUserUuid, IssueChangeDto::getChangeData, IssueChangeDto::getIssueKey,
585 IssueChangeDto::getIssueChangeCreationDate)
586 .containsOnly(IssueChangeDto.TYPE_COMMENT, "john_uuid", "Some text", issue.getKey(), NOW);
587 assertThat(context.getStatistics().getAll()).contains(
588 entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));
592 public void add_change() {
593 ComponentDto project = db.components().insertPrivateProject();
594 ComponentDto file = db.components().insertComponent(newFileDto(project));
595 RuleDefinitionDto rule = db.rules().insert();
596 IssueDto issue = db.issues().insert(rule, project, file,
597 i -> i.setStatus(STATUS_OPEN)
599 .setCreatedAt(NOW - 1_000_000_000L)
600 .setUpdatedAt(NOW - 1_000_000_000L));
601 DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender();
603 issueCacheAppender.append(
604 issue.toDefaultIssue()
605 .setStatus(STATUS_CLOSED)
606 .setResolution(RESOLUTION_FIXED)
610 .setIsOnChangedLine(false)
611 .setIsNewCodeReferenceIssue(false)
612 .setCurrentChange(new FieldDiffs()
613 .setIssueKey("ISSUE")
614 .setUserUuid("john_uuid")
615 .setDiff("technicalDebt", null, 1L)
616 .setCreationDate(new Date(NOW))))
619 TestComputationStepContext context = new TestComputationStepContext();
620 underTest.execute(context);
622 IssueChangeDto issueChangeDto = db.getDbClient().issueChangeDao().selectByIssueKeys(db.getSession(), singletonList(issue.getKey())).get(0);
623 assertThat(issueChangeDto)
624 .extracting(IssueChangeDto::getChangeType, IssueChangeDto::getUserUuid, IssueChangeDto::getChangeData, IssueChangeDto::getIssueKey,
625 IssueChangeDto::getIssueChangeCreationDate)
626 .containsOnly(IssueChangeDto.TYPE_FIELD_CHANGE, "john_uuid", "technicalDebt=1", issue.getKey(), NOW);
627 assertThat(context.getStatistics().getAll()).contains(
628 entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));