3 * Copyright (C) 2009-2023 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.issue.impact.Severity;
32 import org.sonar.api.issue.impact.SoftwareQuality;
33 import org.sonar.api.rule.RuleKey;
34 import org.sonar.api.rules.RuleType;
35 import org.sonar.api.utils.System2;
36 import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule;
37 import org.sonar.ce.task.projectanalysis.issue.AdHocRuleCreator;
38 import org.sonar.ce.task.projectanalysis.issue.ProtoIssueCache;
39 import org.sonar.ce.task.projectanalysis.issue.RuleRepositoryImpl;
40 import org.sonar.ce.task.projectanalysis.issue.UpdateConflictResolver;
41 import org.sonar.ce.task.projectanalysis.period.Period;
42 import org.sonar.ce.task.projectanalysis.period.PeriodHolderRule;
43 import org.sonar.ce.task.projectanalysis.util.cache.DiskCache;
44 import org.sonar.ce.task.step.ComputationStep;
45 import org.sonar.ce.task.step.TestComputationStepContext;
46 import org.sonar.core.issue.DefaultIssue;
47 import org.sonar.core.issue.DefaultIssueComment;
48 import org.sonar.core.issue.FieldDiffs;
49 import org.sonar.core.util.UuidFactoryImpl;
50 import org.sonar.db.DbClient;
51 import org.sonar.db.DbSession;
52 import org.sonar.db.DbTester;
53 import org.sonar.db.component.ComponentDto;
54 import org.sonar.db.issue.AnticipatedTransitionDto;
55 import org.sonar.db.issue.IssueChangeDto;
56 import org.sonar.db.issue.IssueDao;
57 import org.sonar.db.issue.IssueDto;
58 import org.sonar.db.newcodeperiod.NewCodePeriodType;
59 import org.sonar.db.rule.RuleDto;
60 import org.sonar.db.rule.RuleTesting;
61 import org.sonar.scanner.protocol.output.ScannerReport;
62 import org.sonar.server.issue.IssueStorage;
64 import static java.util.Collections.singletonList;
65 import static org.assertj.core.api.Assertions.assertThat;
66 import static org.assertj.core.api.Assertions.tuple;
67 import static org.assertj.core.data.MapEntry.entry;
68 import static org.mockito.ArgumentMatchers.any;
69 import static org.mockito.ArgumentMatchers.eq;
70 import static org.mockito.Mockito.mock;
71 import static org.mockito.Mockito.verify;
72 import static org.mockito.Mockito.when;
73 import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
74 import static org.sonar.api.issue.Issue.STATUS_CLOSED;
75 import static org.sonar.api.issue.Issue.STATUS_OPEN;
76 import static org.sonar.api.rule.Severity.BLOCKER;
77 import static org.sonar.db.component.ComponentTesting.newFileDto;
78 import static org.sonar.db.issue.IssueTesting.newCodeReferenceIssue;
80 public class PersistIssuesStepIT extends BaseStepTest {
82 private static final long NOW = 1_400_000_000_000L;
85 public TemporaryFolder temp = new TemporaryFolder();
87 public DbTester db = DbTester.create(System2.INSTANCE);
89 public BatchReportReaderRule reportReader = new BatchReportReaderRule();
91 public PeriodHolderRule periodHolder = new PeriodHolderRule();
93 private System2 system2 = mock(System2.class);
94 private DbSession session = db.getSession();
95 private DbClient dbClient = db.getDbClient();
96 private UpdateConflictResolver conflictResolver = mock(UpdateConflictResolver.class);
97 private ProtoIssueCache protoIssueCache;
98 private ComputationStep underTest;
100 private AdHocRuleCreator adHocRuleCreator = mock(AdHocRuleCreator.class);
103 protected ComputationStep step() {
108 public void setup() throws Exception {
109 periodHolder.setPeriod(new Period(NewCodePeriodType.NUMBER_OF_DAYS.name(), "10", 1000L));
111 protoIssueCache = new ProtoIssueCache(temp.newFile(), System2.INSTANCE);
112 reportReader.setMetadata(ScannerReport.Metadata.getDefaultInstance());
114 underTest = new PersistIssuesStep(dbClient, system2, conflictResolver, new RuleRepositoryImpl(adHocRuleCreator, dbClient), periodHolder,
115 protoIssueCache, new IssueStorage(), UuidFactoryImpl.INSTANCE);
119 public void tearDown() {
124 public void insert_copied_issue() {
125 RuleDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
126 db.rules().insert(rule);
127 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
128 ComponentDto file = db.components().insertComponent(newFileDto(project));
129 when(system2.now()).thenReturn(NOW);
130 String issueKey = "ISSUE-1";
132 protoIssueCache.newAppender().append(new DefaultIssue()
134 .setType(RuleType.CODE_SMELL)
135 .setRuleKey(rule.getKey())
136 .setComponentUuid(file.uuid())
137 .setComponentKey(file.getKey())
138 .setProjectUuid(project.uuid())
139 .setProjectKey(project.getKey())
140 .setSeverity(BLOCKER)
141 .setStatus(STATUS_OPEN)
142 .setTags(singletonList("test"))
145 .setType(RuleType.BUG)
146 .setCreationDate(new Date(NOW))
148 .addComment(new DefaultIssueComment()
150 .setIssueKey(issueKey)
151 .setUserUuid("john_uuid")
152 .setMarkdownText("Some text")
153 .setCreatedAt(new Date(NOW))
154 .setUpdatedAt(new Date(NOW))
158 .setIssueKey(issueKey)
159 .setUserUuid("john_uuid")
160 .setDiff("technicalDebt", null, 1L)
161 .setCreationDate(new Date(NOW))))
164 TestComputationStepContext context = new TestComputationStepContext();
165 underTest.execute(context);
167 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
169 assertThat(result.getKey()).isEqualTo(issueKey);
170 assertThat(result.getRuleKey()).isEqualTo(rule.getKey());
171 assertThat(result.getComponentUuid()).isEqualTo(file.uuid());
172 assertThat(result.getProjectUuid()).isEqualTo(project.uuid());
173 assertThat(result.getSeverity()).isEqualTo(BLOCKER);
174 assertThat(result.getStatus()).isEqualTo(STATUS_OPEN);
175 assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant());
176 assertThat(result.getTags()).containsExactlyInAnyOrder("test");
177 assertThat(result.isNewCodeReferenceIssue()).isFalse();
179 List<IssueChangeDto> changes = dbClient.issueChangeDao().selectByIssueKeys(session, Arrays.asList(issueKey));
180 assertThat(changes).extracting(IssueChangeDto::getChangeType).containsExactly(IssueChangeDto.TYPE_COMMENT, IssueChangeDto.TYPE_FIELD_CHANGE);
181 assertThat(context.getStatistics().getAll()).contains(
182 entry("inserts", "1"), entry("updates", "0"), entry("merged", "0"));
186 public void insert_copied_issue_with_minimal_info() {
187 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
189 RuleDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
190 db.rules().insert(rule);
191 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
192 ComponentDto file = db.components().insertComponent(newFileDto(project));
193 when(system2.now()).thenReturn(NOW);
194 String issueKey = "ISSUE-2";
196 protoIssueCache.newAppender().append(new DefaultIssue()
198 .setType(RuleType.CODE_SMELL)
199 .setRuleKey(rule.getKey())
200 .setComponentUuid(file.uuid())
201 .setComponentKey(file.getKey())
202 .setProjectUuid(project.uuid())
203 .setProjectKey(project.getKey())
204 .setSeverity(BLOCKER)
205 .setStatus(STATUS_OPEN)
208 .setType(RuleType.BUG)
209 .setCreationDate(new Date(NOW))
213 TestComputationStepContext context = new TestComputationStepContext();
214 underTest.execute(context);
216 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
217 assertThat(result.getKey()).isEqualTo(issueKey);
218 assertThat(result.getRuleKey()).isEqualTo(rule.getKey());
219 assertThat(result.getComponentUuid()).isEqualTo(file.uuid());
220 assertThat(result.getProjectUuid()).isEqualTo(project.uuid());
221 assertThat(result.getSeverity()).isEqualTo(BLOCKER);
222 assertThat(result.getStatus()).isEqualTo(STATUS_OPEN);
223 assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant());
224 assertThat(result.getTags()).isEmpty();
225 assertThat(result.isNewCodeReferenceIssue()).isFalse();
227 assertThat(dbClient.issueChangeDao().selectByIssueKeys(session, Arrays.asList(issueKey))).isEmpty();
228 assertThat(context.getStatistics().getAll()).contains(
229 entry("inserts", "1"), entry("updates", "0"), entry("merged", "0"));
233 public void insert_merged_issue() {
234 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
235 RuleDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
236 db.rules().insert(rule);
237 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
238 ComponentDto file = db.components().insertComponent(newFileDto(project));
239 when(system2.now()).thenReturn(NOW);
240 String issueKey = "ISSUE-3";
242 protoIssueCache.newAppender().append(new DefaultIssue()
244 .setType(RuleType.CODE_SMELL)
245 .setRuleKey(rule.getKey())
246 .setComponentUuid(file.uuid())
247 .setComponentKey(file.getKey())
248 .setProjectUuid(project.uuid())
249 .setProjectKey(project.getKey())
250 .setSeverity(BLOCKER)
251 .setStatus(STATUS_OPEN)
253 .setIsOnChangedLine(true)
255 .setType(RuleType.BUG)
256 .setCreationDate(new Date(NOW))
258 .addComment(new DefaultIssueComment()
260 .setIssueKey(issueKey)
261 .setUserUuid("john_uuid")
262 .setMarkdownText("Some text")
263 .setUpdatedAt(new Date(NOW))
264 .setCreatedAt(new Date(NOW))
266 .setCurrentChange(new FieldDiffs()
267 .setIssueKey(issueKey)
268 .setUserUuid("john_uuid")
269 .setDiff("technicalDebt", null, 1L)
270 .setCreationDate(new Date(NOW))))
273 TestComputationStepContext context = new TestComputationStepContext();
274 underTest.execute(context);
276 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
277 assertThat(result.getKey()).isEqualTo(issueKey);
278 assertThat(result.getRuleKey()).isEqualTo(rule.getKey());
279 assertThat(result.getComponentUuid()).isEqualTo(file.uuid());
280 assertThat(result.getProjectUuid()).isEqualTo(project.uuid());
281 assertThat(result.getSeverity()).isEqualTo(BLOCKER);
282 assertThat(result.getStatus()).isEqualTo(STATUS_OPEN);
283 assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant());
284 assertThat(result.isNewCodeReferenceIssue()).isTrue();
286 List<IssueChangeDto> changes = dbClient.issueChangeDao().selectByIssueKeys(session, Arrays.asList(issueKey));
287 assertThat(changes).extracting(IssueChangeDto::getChangeType).containsExactly(IssueChangeDto.TYPE_COMMENT, IssueChangeDto.TYPE_FIELD_CHANGE);
288 assertThat(context.getStatistics().getAll()).contains(
289 entry("inserts", "1"), entry("updates", "0"), entry("merged", "0"));
293 public void update_conflicting_issue() {
294 RuleDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
295 db.rules().insert(rule);
296 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
297 ComponentDto file = db.components().insertComponent(newFileDto(project));
298 IssueDto issue = db.issues().insert(rule, project, file,
299 i -> i.setStatus(STATUS_OPEN)
301 .setCreatedAt(NOW - 1_000_000_000L)
302 // simulate the issue has been updated after the analysis ran
303 .setUpdatedAt(NOW + 1_000_000_000L));
304 issue = dbClient.issueDao().selectByKey(db.getSession(), issue.getKey()).get();
305 DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender();
306 when(system2.now()).thenReturn(NOW);
308 DefaultIssue defaultIssue = issue.toDefaultIssue()
309 .setStatus(STATUS_CLOSED)
310 .setResolution(RESOLUTION_FIXED)
314 issueCacheAppender.append(defaultIssue).close();
316 TestComputationStepContext context = new TestComputationStepContext();
317 underTest.execute(context);
319 ArgumentCaptor<IssueDto> issueDtoCaptor = ArgumentCaptor.forClass(IssueDto.class);
320 verify(conflictResolver).resolve(eq(defaultIssue), issueDtoCaptor.capture(), any(IssueDao.class), any(DbSession.class));
321 assertThat(issueDtoCaptor.getValue().getKey()).isEqualTo(issue.getKey());
322 assertThat(context.getStatistics().getAll()).contains(
323 entry("inserts", "0"), entry("updates", "1"), entry("merged", "1"));
327 public void insert_new_issue() {
328 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
329 RuleDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
330 db.rules().insert(rule);
331 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
332 ComponentDto file = db.components().insertComponent(newFileDto(project));
334 String issueKey = "ISSUE-4";
336 protoIssueCache.newAppender().append(new DefaultIssue()
338 .setType(RuleType.CODE_SMELL)
339 .setRuleKey(rule.getKey())
340 .setComponentUuid(file.uuid())
341 .setComponentKey(file.getKey())
342 .setProjectUuid(project.uuid())
343 .setProjectKey(project.getKey())
344 .setSeverity(BLOCKER)
345 .setStatus(STATUS_OPEN)
346 .setCreationDate(new Date(NOW))
348 .setIsOnChangedLine(true)
349 .addImpact(SoftwareQuality.SECURITY, Severity.MEDIUM)
350 .setType(RuleType.BUG)).close();
352 TestComputationStepContext context = new TestComputationStepContext();
353 underTest.execute(context);
355 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
356 assertThat(result.getKey()).isEqualTo(issueKey);
357 assertThat(result.getRuleKey()).isEqualTo(rule.getKey());
358 assertThat(result.getComponentUuid()).isEqualTo(file.uuid());
359 assertThat(result.getProjectUuid()).isEqualTo(project.uuid());
360 assertThat(result.getSeverity()).isEqualTo(BLOCKER);
361 assertThat(result.getStatus()).isEqualTo(STATUS_OPEN);
362 assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant());
363 assertThat(result.getImpacts()).extracting(i -> i.getSoftwareQuality(), i -> i.getSeverity())
364 .containsExactly(tuple(SoftwareQuality.SECURITY, Severity.MEDIUM));
365 assertThat(context.getStatistics().getAll()).contains(
366 entry("inserts", "1"), entry("updates", "0"), entry("merged", "0"));
367 assertThat(result.isNewCodeReferenceIssue()).isTrue();
371 public void close_issue() {
372 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
373 ComponentDto file = db.components().insertComponent(newFileDto(project));
374 RuleDto rule = db.rules().insert();
375 IssueDto issue = db.issues().insert(rule, project, file,
376 i -> i.setStatus(STATUS_OPEN)
378 .setCreatedAt(NOW - 1_000_000_000L)
379 .setUpdatedAt(NOW - 1_000_000_000L));
380 DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender();
382 issueCacheAppender.append(
383 issue.toDefaultIssue()
384 .setStatus(STATUS_CLOSED)
385 .setResolution(RESOLUTION_FIXED)
391 TestComputationStepContext context = new TestComputationStepContext();
392 underTest.execute(context);
394 IssueDto issueReloaded = db.getDbClient().issueDao().selectByKey(db.getSession(), issue.getKey()).get();
395 assertThat(issueReloaded.getStatus()).isEqualTo(STATUS_CLOSED);
396 assertThat(issueReloaded.getResolution()).isEqualTo(RESOLUTION_FIXED);
397 assertThat(context.getStatistics().getAll()).contains(
398 entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));
402 public void handle_no_longer_new_issue() {
403 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
404 RuleDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
405 db.rules().insert(rule);
406 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
407 ComponentDto file = db.components().insertComponent(newFileDto(project));
408 when(system2.now()).thenReturn(NOW);
409 String issueKey = "ISSUE-5";
411 DefaultIssue defaultIssue = new DefaultIssue()
413 .setType(RuleType.CODE_SMELL)
414 .setRuleKey(rule.getKey())
415 .setComponentUuid(file.uuid())
416 .setComponentKey(file.getKey())
417 .setProjectUuid(project.uuid())
418 .setProjectKey(project.getKey())
419 .setSeverity(BLOCKER)
420 .setStatus(STATUS_OPEN)
422 .setIsOnChangedLine(true)
423 .setIsNewCodeReferenceIssue(true)
424 .setIsNoLongerNewCodeReferenceIssue(false)
426 .setType(RuleType.BUG)
427 .setCreationDate(new Date(NOW))
430 IssueDto issueDto = IssueDto.toDtoForComputationInsert(defaultIssue, rule.getUuid(), NOW);
431 dbClient.issueDao().insert(session, issueDto);
432 dbClient.issueDao().insertAsNewCodeOnReferenceBranch(session, newCodeReferenceIssue(issueDto));
435 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
436 assertThat(result.isNewCodeReferenceIssue()).isTrue();
438 protoIssueCache.newAppender().append(defaultIssue.setNew(false)
439 .setIsOnChangedLine(false)
440 .setIsNewCodeReferenceIssue(false)
441 .setIsNoLongerNewCodeReferenceIssue(true))
444 TestComputationStepContext context = new TestComputationStepContext();
445 underTest.execute(context);
447 assertThat(context.getStatistics().getAll()).contains(
448 entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));
450 result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
451 assertThat(result.isNewCodeReferenceIssue()).isFalse();
455 public void handle_existing_new_code_issue_migration() {
456 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
457 RuleDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
458 db.rules().insert(rule);
459 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
460 ComponentDto file = db.components().insertComponent(newFileDto(project));
461 when(system2.now()).thenReturn(NOW);
462 String issueKey = "ISSUE-6";
464 DefaultIssue defaultIssue = new DefaultIssue()
466 .setType(RuleType.CODE_SMELL)
467 .setRuleKey(rule.getKey())
468 .setComponentUuid(file.uuid())
469 .setComponentKey(file.getKey())
470 .setProjectUuid(project.uuid())
471 .setProjectKey(project.getKey())
472 .setSeverity(BLOCKER)
473 .setStatus(STATUS_OPEN)
476 .setType(RuleType.BUG)
477 .setCreationDate(new Date(NOW))
480 IssueDto issueDto = IssueDto.toDtoForComputationInsert(defaultIssue, rule.getUuid(), NOW);
481 dbClient.issueDao().insert(session, issueDto);
484 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
485 assertThat(result.isNewCodeReferenceIssue()).isFalse();
487 protoIssueCache.newAppender().append(defaultIssue.setNew(false)
488 .setIsOnChangedLine(true)
489 .setIsNewCodeReferenceIssue(false)
490 .setIsNoLongerNewCodeReferenceIssue(false))
493 TestComputationStepContext context = new TestComputationStepContext();
494 underTest.execute(context);
496 assertThat(context.getStatistics().getAll()).contains(
497 entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));
499 result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
500 assertThat(result.isNewCodeReferenceIssue()).isTrue();
504 public void handle_existing_without_need_for_new_code_issue_migration() {
505 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
506 RuleDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
507 db.rules().insert(rule);
508 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
509 ComponentDto file = db.components().insertComponent(newFileDto(project));
510 when(system2.now()).thenReturn(NOW);
511 String issueKey = "ISSUE-7";
513 DefaultIssue defaultIssue = new DefaultIssue()
515 .setType(RuleType.CODE_SMELL)
516 .setRuleKey(rule.getKey())
517 .setComponentUuid(file.uuid())
518 .setComponentKey(file.getKey())
519 .setProjectUuid(project.uuid())
520 .setProjectKey(project.getKey())
521 .setSeverity(BLOCKER)
522 .setStatus(STATUS_OPEN)
524 .setIsOnChangedLine(true)
525 .setIsNewCodeReferenceIssue(true)
526 .setIsNoLongerNewCodeReferenceIssue(false)
528 .setType(RuleType.BUG)
529 .setCreationDate(new Date(NOW))
532 IssueDto issueDto = IssueDto.toDtoForComputationInsert(defaultIssue, rule.getUuid(), NOW);
533 dbClient.issueDao().insert(session, issueDto);
534 dbClient.issueDao().insertAsNewCodeOnReferenceBranch(session, newCodeReferenceIssue(issueDto));
537 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
538 assertThat(result.isNewCodeReferenceIssue()).isTrue();
540 protoIssueCache.newAppender().append(defaultIssue.setNew(false)
541 .setIsOnChangedLine(false)
542 .setIsNewCodeReferenceIssue(true)
543 .setIsOnChangedLine(true)
544 .setIsNoLongerNewCodeReferenceIssue(false))
547 TestComputationStepContext context = new TestComputationStepContext();
548 underTest.execute(context);
550 assertThat(context.getStatistics().getAll()).contains(
551 entry("inserts", "0"), entry("updates", "0"), entry("merged", "0"));
553 result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
554 assertThat(result.isNewCodeReferenceIssue()).isTrue();
558 public void add_comment() {
559 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
560 ComponentDto file = db.components().insertComponent(newFileDto(project));
561 RuleDto rule = db.rules().insert();
562 IssueDto issue = db.issues().insert(rule, project, file,
563 i -> i.setStatus(STATUS_OPEN)
565 .setCreatedAt(NOW - 1_000_000_000L)
566 .setUpdatedAt(NOW - 1_000_000_000L));
567 DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender();
569 issueCacheAppender.append(
570 issue.toDefaultIssue()
571 .setStatus(STATUS_CLOSED)
572 .setResolution(RESOLUTION_FIXED)
576 .addComment(new DefaultIssueComment()
578 .setIssueKey(issue.getKey())
579 .setUserUuid("john_uuid")
580 .setMarkdownText("Some text")
581 .setCreatedAt(new Date(NOW))
582 .setUpdatedAt(new Date(NOW))
586 TestComputationStepContext context = new TestComputationStepContext();
587 underTest.execute(context);
589 IssueChangeDto issueChangeDto = db.getDbClient().issueChangeDao().selectByIssueKeys(db.getSession(), singletonList(issue.getKey())).get(0);
590 assertThat(issueChangeDto)
591 .extracting(IssueChangeDto::getChangeType, IssueChangeDto::getUserUuid, IssueChangeDto::getChangeData, IssueChangeDto::getIssueKey,
592 IssueChangeDto::getIssueChangeCreationDate)
593 .containsOnly(IssueChangeDto.TYPE_COMMENT, "john_uuid", "Some text", issue.getKey(), NOW);
594 assertThat(context.getStatistics().getAll()).contains(
595 entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));
599 public void add_change() {
600 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
601 ComponentDto file = db.components().insertComponent(newFileDto(project));
602 RuleDto rule = db.rules().insert();
603 IssueDto issue = db.issues().insert(rule, project, file,
604 i -> i.setStatus(STATUS_OPEN)
606 .setCreatedAt(NOW - 1_000_000_000L)
607 .setUpdatedAt(NOW - 1_000_000_000L));
608 DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender();
610 issueCacheAppender.append(
611 issue.toDefaultIssue()
612 .setStatus(STATUS_CLOSED)
613 .setResolution(RESOLUTION_FIXED)
617 .setIsOnChangedLine(false)
618 .setIsNewCodeReferenceIssue(false)
619 .setCurrentChange(new FieldDiffs()
620 .setIssueKey("ISSUE")
621 .setUserUuid("john_uuid")
622 .setDiff("technicalDebt", null, 1L)
623 .setCreationDate(new Date(NOW))))
626 TestComputationStepContext context = new TestComputationStepContext();
627 underTest.execute(context);
629 IssueChangeDto issueChangeDto = db.getDbClient().issueChangeDao().selectByIssueKeys(db.getSession(), singletonList(issue.getKey())).get(0);
630 assertThat(issueChangeDto)
631 .extracting(IssueChangeDto::getChangeType, IssueChangeDto::getUserUuid, IssueChangeDto::getChangeData, IssueChangeDto::getIssueKey,
632 IssueChangeDto::getIssueChangeCreationDate)
633 .containsOnly(IssueChangeDto.TYPE_FIELD_CHANGE, "john_uuid", "technicalDebt=1", issue.getKey(), NOW);
634 assertThat(context.getStatistics().getAll()).contains(
635 entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));
639 public void when_anticipatedTransitionIsPresent_ItShouldBeDeleted() {
640 periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
641 RuleDto rule = RuleTesting.newRule(RuleKey.of("xoo", "S01"));
642 db.rules().insert(rule);
643 ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
644 ComponentDto file = db.components().insertComponent(newFileDto(project));
646 String issueKey = "ISSUE-4";
648 DefaultIssue newIssue = new DefaultIssue()
650 .setType(RuleType.CODE_SMELL)
651 .setRuleKey(rule.getKey())
652 .setComponentUuid(file.uuid())
653 .setComponentKey(file.getKey())
654 .setProjectUuid(project.uuid())
655 .setProjectKey(project.getKey())
656 .setSeverity(BLOCKER)
657 .setStatus(STATUS_OPEN)
658 .setCreationDate(new Date(NOW))
660 .setIsOnChangedLine(true)
661 .setType(RuleType.BUG);
663 AnticipatedTransitionDto atDto = db.anticipatedTransitions().createForIssue(newIssue, "test_uuid", file.name());
664 newIssue.setAnticipatedTransitionUuid(atDto.getUuid());
666 var defaultIssueCacheAppender = protoIssueCache.newAppender();
667 defaultIssueCacheAppender.append(newIssue).close();
669 TestComputationStepContext context = new TestComputationStepContext();
670 underTest.execute(context);
672 IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
673 assertThat(result.getKey()).isEqualTo(issueKey);
674 assertThat(result.getRuleKey()).isEqualTo(rule.getKey());
675 assertThat(result.getComponentUuid()).isEqualTo(file.uuid());
676 assertThat(result.getProjectUuid()).isEqualTo(project.uuid());
677 assertThat(result.getSeverity()).isEqualTo(BLOCKER);
678 assertThat(result.getStatus()).isEqualTo(STATUS_OPEN);
679 assertThat(result.getType()).isEqualTo(RuleType.BUG.getDbConstant());
680 assertThat(context.getStatistics().getAll()).contains(
681 entry("inserts", "1"), entry("updates", "0"), entry("merged", "0"));
682 assertThat(result.isNewCodeReferenceIssue()).isTrue();
684 assertThat(db.anticipatedTransitions().selectByProjectUuid(project.uuid())).isEmpty();