]> source.dussan.org Git - sonarqube.git/blob
a3b66907a9b7ec0748ad5ca1832f16b34c4d2cc8
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
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.
10  *
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.
15  *
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.
19  */
20 package org.sonar.ce.task.projectanalysis.step;
21
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;
60
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;
75
76 public class PersistIssuesStepTest extends BaseStepTest {
77
78   private static final long NOW = 1_400_000_000_000L;
79
80   @Rule
81   public TemporaryFolder temp = new TemporaryFolder();
82   @Rule
83   public DbTester db = DbTester.create(System2.INSTANCE);
84   @Rule
85   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
86   @Rule
87   public PeriodHolderRule periodHolder = new PeriodHolderRule();
88
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;
95
96   private AdHocRuleCreator adHocRuleCreator = mock(AdHocRuleCreator.class);
97
98   @Override
99   protected ComputationStep step() {
100     return underTest;
101   }
102
103   @Before
104   public void setup() throws Exception {
105     periodHolder.setPeriod(new Period(NewCodePeriodType.NUMBER_OF_DAYS.name(), "10", 1000L));
106
107     protoIssueCache = new ProtoIssueCache(temp.newFile(), System2.INSTANCE);
108     reportReader.setMetadata(ScannerReport.Metadata.getDefaultInstance());
109
110     underTest = new PersistIssuesStep(dbClient, system2, conflictResolver, new RuleRepositoryImpl(adHocRuleCreator, dbClient), periodHolder,
111       protoIssueCache, new IssueStorage(), UuidFactoryImpl.INSTANCE);
112   }
113
114   @After
115   public void tearDown() {
116     session.close();
117   }
118
119   @Test
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";
127
128     protoIssueCache.newAppender().append(new DefaultIssue()
129         .setKey(issueKey)
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"))
139         .setNew(false)
140         .setCopied(true)
141         .setType(RuleType.BUG)
142         .setCreationDate(new Date(NOW))
143         .setSelectedAt(NOW)
144         .addComment(new DefaultIssueComment()
145           .setKey("COMMENT")
146           .setIssueKey(issueKey)
147           .setUserUuid("john_uuid")
148           .setMarkdownText("Some text")
149           .setCreatedAt(new Date(NOW))
150           .setUpdatedAt(new Date(NOW))
151           .setNew(true))
152         .setCurrentChange(
153           new FieldDiffs()
154             .setIssueKey(issueKey)
155             .setUserUuid("john_uuid")
156             .setDiff("technicalDebt", null, 1L)
157             .setCreationDate(new Date(NOW))))
158       .close();
159
160     TestComputationStepContext context = new TestComputationStepContext();
161     underTest.execute(context);
162
163     IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
164
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();
174
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"));
179   }
180
181   @Test
182   public void insert_copied_issue_with_minimal_info() {
183     periodHolder.setPeriod(new Period(NewCodePeriodType.REFERENCE_BRANCH.name(), "master", null));
184
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";
191
192     protoIssueCache.newAppender().append(new DefaultIssue()
193         .setKey(issueKey)
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)
202         .setNew(false)
203         .setCopied(true)
204         .setType(RuleType.BUG)
205         .setCreationDate(new Date(NOW))
206         .setSelectedAt(NOW))
207       .close();
208
209     TestComputationStepContext context = new TestComputationStepContext();
210     underTest.execute(context);
211
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();
222
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"));
226   }
227
228   @Test
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";
237
238     protoIssueCache.newAppender().append(new DefaultIssue()
239         .setKey(issueKey)
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)
248         .setNew(true)
249         .setIsOnChangedLine(true)
250         .setCopied(true)
251         .setType(RuleType.BUG)
252         .setCreationDate(new Date(NOW))
253         .setSelectedAt(NOW)
254         .addComment(new DefaultIssueComment()
255           .setKey("COMMENT")
256           .setIssueKey(issueKey)
257           .setUserUuid("john_uuid")
258           .setMarkdownText("Some text")
259           .setUpdatedAt(new Date(NOW))
260           .setCreatedAt(new Date(NOW))
261           .setNew(true))
262         .setCurrentChange(new FieldDiffs()
263           .setIssueKey(issueKey)
264           .setUserUuid("john_uuid")
265           .setDiff("technicalDebt", null, 1L)
266           .setCreationDate(new Date(NOW))))
267       .close();
268
269     TestComputationStepContext context = new TestComputationStepContext();
270     underTest.execute(context);
271
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();
281
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"));
286   }
287
288   @Test
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)
296         .setResolution(null)
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);
303
304     DefaultIssue defaultIssue = issue.toDefaultIssue()
305       .setStatus(STATUS_CLOSED)
306       .setResolution(RESOLUTION_FIXED)
307       .setSelectedAt(NOW)
308       .setNew(false)
309       .setChanged(true);
310     issueCacheAppender.append(defaultIssue).close();
311
312     TestComputationStepContext context = new TestComputationStepContext();
313     underTest.execute(context);
314
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"));
320   }
321
322   @Test
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));
329     session.commit();
330     String issueKey = "ISSUE-4";
331
332     protoIssueCache.newAppender().append(new DefaultIssue()
333       .setKey(issueKey)
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))
343       .setNew(true)
344       .setIsOnChangedLine(true)
345       .setType(RuleType.BUG)).close();
346
347     TestComputationStepContext context = new TestComputationStepContext();
348     underTest.execute(context);
349
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();
361   }
362
363   @Test
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)
370         .setResolution(null)
371         .setCreatedAt(NOW - 1_000_000_000L)
372         .setUpdatedAt(NOW - 1_000_000_000L));
373     DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender();
374
375     issueCacheAppender.append(
376         issue.toDefaultIssue()
377           .setStatus(STATUS_CLOSED)
378           .setResolution(RESOLUTION_FIXED)
379           .setSelectedAt(NOW)
380           .setNew(false)
381           .setChanged(true))
382       .close();
383
384     TestComputationStepContext context = new TestComputationStepContext();
385     underTest.execute(context);
386
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"));
392   }
393
394   @Test
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";
403
404     DefaultIssue defaultIssue = new DefaultIssue()
405       .setKey(issueKey)
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)
414       .setNew(true)
415       .setIsOnChangedLine(true)
416       .setIsNewCodeReferenceIssue(true)
417       .setIsNoLongerNewCodeReferenceIssue(false)
418       .setCopied(false)
419       .setType(RuleType.BUG)
420       .setCreationDate(new Date(NOW))
421       .setSelectedAt(NOW);
422
423     IssueDto issueDto = IssueDto.toDtoForComputationInsert(defaultIssue, rule.getUuid(), NOW);
424     dbClient.issueDao().insert(session, issueDto);
425     dbClient.issueDao().insertAsNewCodeOnReferenceBranch(session, newCodeReferenceIssue(issueDto));
426     session.commit();
427
428     IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
429     assertThat(result.isNewCodeReferenceIssue()).isTrue();
430
431     protoIssueCache.newAppender().append(defaultIssue.setNew(false)
432         .setIsOnChangedLine(false)
433         .setIsNewCodeReferenceIssue(false)
434         .setIsNoLongerNewCodeReferenceIssue(true))
435       .close();
436
437     TestComputationStepContext context = new TestComputationStepContext();
438     underTest.execute(context);
439
440     assertThat(context.getStatistics().getAll()).contains(
441       entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));
442
443     result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
444     assertThat(result.isNewCodeReferenceIssue()).isFalse();
445   }
446
447   @Test
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";
456
457     DefaultIssue defaultIssue = new DefaultIssue()
458       .setKey(issueKey)
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)
467       .setNew(true)
468       .setCopied(false)
469       .setType(RuleType.BUG)
470       .setCreationDate(new Date(NOW))
471       .setSelectedAt(NOW);
472
473     IssueDto issueDto = IssueDto.toDtoForComputationInsert(defaultIssue, rule.getUuid(), NOW);
474     dbClient.issueDao().insert(session, issueDto);
475     session.commit();
476
477     IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
478     assertThat(result.isNewCodeReferenceIssue()).isFalse();
479
480     protoIssueCache.newAppender().append(defaultIssue.setNew(false)
481         .setIsOnChangedLine(true)
482         .setIsNewCodeReferenceIssue(false)
483         .setIsNoLongerNewCodeReferenceIssue(false))
484       .close();
485
486     TestComputationStepContext context = new TestComputationStepContext();
487     underTest.execute(context);
488
489     assertThat(context.getStatistics().getAll()).contains(
490       entry("inserts", "0"), entry("updates", "1"), entry("merged", "0"));
491
492     result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
493     assertThat(result.isNewCodeReferenceIssue()).isTrue();
494   }
495
496   @Test
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";
505
506     DefaultIssue defaultIssue = new DefaultIssue()
507       .setKey(issueKey)
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)
516       .setNew(true)
517       .setIsOnChangedLine(true)
518       .setIsNewCodeReferenceIssue(true)
519       .setIsNoLongerNewCodeReferenceIssue(false)
520       .setCopied(false)
521       .setType(RuleType.BUG)
522       .setCreationDate(new Date(NOW))
523       .setSelectedAt(NOW);
524
525     IssueDto issueDto = IssueDto.toDtoForComputationInsert(defaultIssue, rule.getUuid(), NOW);
526     dbClient.issueDao().insert(session, issueDto);
527     dbClient.issueDao().insertAsNewCodeOnReferenceBranch(session, newCodeReferenceIssue(issueDto));
528     session.commit();
529
530     IssueDto result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
531     assertThat(result.isNewCodeReferenceIssue()).isTrue();
532
533     protoIssueCache.newAppender().append(defaultIssue.setNew(false)
534         .setIsOnChangedLine(false)
535         .setIsNewCodeReferenceIssue(true)
536         .setIsOnChangedLine(true)
537         .setIsNoLongerNewCodeReferenceIssue(false))
538       .close();
539
540     TestComputationStepContext context = new TestComputationStepContext();
541     underTest.execute(context);
542
543     assertThat(context.getStatistics().getAll()).contains(
544       entry("inserts", "0"), entry("updates", "0"), entry("merged", "0"));
545
546     result = dbClient.issueDao().selectOrFailByKey(session, issueKey);
547     assertThat(result.isNewCodeReferenceIssue()).isTrue();
548   }
549
550   @Test
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)
557         .setResolution(null)
558         .setCreatedAt(NOW - 1_000_000_000L)
559         .setUpdatedAt(NOW - 1_000_000_000L));
560     DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender();
561
562     issueCacheAppender.append(
563         issue.toDefaultIssue()
564           .setStatus(STATUS_CLOSED)
565           .setResolution(RESOLUTION_FIXED)
566           .setSelectedAt(NOW)
567           .setNew(false)
568           .setChanged(true)
569           .addComment(new DefaultIssueComment()
570             .setKey("COMMENT")
571             .setIssueKey(issue.getKey())
572             .setUserUuid("john_uuid")
573             .setMarkdownText("Some text")
574             .setCreatedAt(new Date(NOW))
575             .setUpdatedAt(new Date(NOW))
576             .setNew(true)))
577       .close();
578
579     TestComputationStepContext context = new TestComputationStepContext();
580     underTest.execute(context);
581
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"));
589   }
590
591   @Test
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)
598         .setResolution(null)
599         .setCreatedAt(NOW - 1_000_000_000L)
600         .setUpdatedAt(NOW - 1_000_000_000L));
601     DiskCache.CacheAppender issueCacheAppender = protoIssueCache.newAppender();
602
603     issueCacheAppender.append(
604         issue.toDefaultIssue()
605           .setStatus(STATUS_CLOSED)
606           .setResolution(RESOLUTION_FIXED)
607           .setSelectedAt(NOW)
608           .setNew(false)
609           .setChanged(true)
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))))
617       .close();
618
619     TestComputationStepContext context = new TestComputationStepContext();
620     underTest.execute(context);
621
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"));
629   }
630
631 }