]> source.dussan.org Git - sonarqube.git/blob
6aaba0058f91ab6a8345bd3e23ad6641924e0560
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2023 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.issue;
21
22 import com.google.common.collect.Iterators;
23 import com.tngtech.java.junit.dataprovider.DataProvider;
24 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
25 import com.tngtech.java.junit.dataprovider.UseDataProvider;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Optional;
29 import org.junit.Before;
30 import org.junit.Rule;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.sonar.api.rule.RuleKey;
34 import org.sonar.api.rule.Severity;
35 import org.sonar.api.rules.RuleType;
36 import org.sonar.api.utils.Duration;
37 import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule;
38 import org.sonar.ce.task.projectanalysis.component.Component;
39 import org.sonar.ce.task.projectanalysis.component.ReportComponent;
40 import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
41 import org.sonar.ce.task.projectanalysis.issue.commonrule.CommonRuleEngine;
42 import org.sonar.ce.task.projectanalysis.issue.filter.IssueFilter;
43 import org.sonar.ce.task.projectanalysis.qualityprofile.ActiveRule;
44 import org.sonar.ce.task.projectanalysis.qualityprofile.ActiveRulesHolderRule;
45 import org.sonar.ce.task.projectanalysis.source.SourceLinesHashRepository;
46 import org.sonar.core.issue.DefaultIssue;
47 import org.sonar.core.issue.tracking.Input;
48 import org.sonar.db.protobuf.DbIssues;
49 import org.sonar.scanner.protocol.Constants;
50 import org.sonar.scanner.protocol.output.ScannerReport;
51 import org.sonar.scanner.protocol.output.ScannerReport.FlowType;
52 import org.sonar.scanner.protocol.output.ScannerReport.IssueType;
53 import org.sonar.server.rule.CommonRuleKeys;
54
55 import static java.util.Arrays.asList;
56 import static java.util.Collections.emptyMap;
57 import static java.util.Collections.singletonList;
58 import static org.assertj.core.api.Assertions.assertThat;
59 import static org.mockito.ArgumentMatchers.any;
60 import static org.mockito.ArgumentMatchers.eq;
61 import static org.mockito.Mockito.mock;
62 import static org.mockito.Mockito.when;
63 import static org.sonar.api.issue.Issue.STATUS_OPEN;
64 import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW;
65 import static org.sonar.scanner.protocol.output.ScannerReport.MessageFormattingType.CODE;
66
67 @RunWith(DataProviderRunner.class)
68 public class TrackerRawInputFactoryTest {
69
70   private static final String FILE_UUID = "fake_uuid";
71   private static final String ANOTHER_FILE_UUID = "another_fake_uuid";
72   private static final String EXAMPLE_LINE_OF_CODE_FORMAT = "int example = line + of + code + %d; ";
73
74   private static final int FILE_REF = 2;
75   private static final int NOT_IN_REPORT_FILE_REF = 3;
76   private static final int ANOTHER_FILE_REF = 4;
77   private static final String TEST_CONTEXT_KEY = "test_context_key";
78
79   @Rule
80   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(PROJECT);
81   @Rule
82   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
83   @Rule
84   public ActiveRulesHolderRule activeRulesHolder = new ActiveRulesHolderRule();
85   @Rule
86   public RuleRepositoryRule ruleRepository = new RuleRepositoryRule();
87
88   private static final ReportComponent FILE = ReportComponent.builder(Component.Type.FILE, FILE_REF).setUuid(FILE_UUID).build();
89   private static final ReportComponent ANOTHER_FILE = ReportComponent.builder(Component.Type.FILE, ANOTHER_FILE_REF).setUuid(ANOTHER_FILE_UUID).build();
90   private static final ReportComponent PROJECT = ReportComponent.builder(Component.Type.PROJECT, 1).addChildren(FILE, ANOTHER_FILE).build();
91
92   private final SourceLinesHashRepository sourceLinesHash = mock(SourceLinesHashRepository.class);
93   private final CommonRuleEngine commonRuleEngine = mock(CommonRuleEngine.class);
94   private final IssueFilter issueFilter = mock(IssueFilter.class);
95   private final TrackerRawInputFactory underTest = new TrackerRawInputFactory(treeRootHolder, reportReader, sourceLinesHash,
96     commonRuleEngine, issueFilter, ruleRepository, activeRulesHolder);
97
98   @Before
99   public void before() {
100     when(sourceLinesHash.getLineHashesMatchingDBVersion(FILE)).thenReturn(Collections.singletonList("line"));
101     when(issueFilter.accept(any(), eq(FILE))).thenReturn(true);
102   }
103
104   @Test
105   public void load_source_hash_sequences() {
106     Input<DefaultIssue> input = underTest.create(FILE);
107
108     assertThat(input.getLineHashSequence()).isNotNull();
109     assertThat(input.getLineHashSequence().getHashForLine(1)).isEqualTo("line");
110     assertThat(input.getLineHashSequence().getHashForLine(2)).isEmpty();
111     assertThat(input.getLineHashSequence().getHashForLine(3)).isEmpty();
112
113     assertThat(input.getBlockHashSequence()).isNotNull();
114   }
115
116   @Test
117   public void load_source_hash_sequences_only_on_files() {
118     Input<DefaultIssue> input = underTest.create(PROJECT);
119
120     assertThat(input.getLineHashSequence()).isNotNull();
121     assertThat(input.getBlockHashSequence()).isNotNull();
122   }
123
124   @Test
125   public void load_issues_from_report() {
126     RuleKey ruleKey = RuleKey.of("java", "S001");
127     markRuleAsActive(ruleKey);
128
129     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
130       .setTextRange(newTextRange(2))
131       .setMsg("the message")
132       .addMsgFormatting(ScannerReport.MessageFormatting.newBuilder().setStart(0).setEnd(3).setType(CODE).build())
133       .setRuleRepository(ruleKey.repository())
134       .setRuleKey(ruleKey.rule())
135       .setSeverity(Constants.Severity.BLOCKER)
136       .setGap(3.14)
137       .setQuickFixAvailable(true)
138       .build();
139     reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
140     Input<DefaultIssue> input = underTest.create(FILE);
141
142     Collection<DefaultIssue> issues = input.getIssues();
143     assertThat(issues).hasSize(1);
144     DefaultIssue issue = Iterators.getOnlyElement(issues.iterator());
145
146     // fields set by analysis report
147     assertThat(issue.ruleKey()).isEqualTo(ruleKey);
148     assertThat(issue.severity()).isEqualTo(Severity.BLOCKER);
149     assertThat(issue.line()).isEqualTo(2);
150     assertThat(issue.gap()).isEqualTo(3.14);
151     assertThat(issue.message()).isEqualTo("the message");
152     assertThat(issue.isQuickFixAvailable()).isTrue();
153
154     // Check message formatting
155     DbIssues.MessageFormattings messageFormattings = Iterators.getOnlyElement(issues.iterator()).getMessageFormattings();
156     assertThat(messageFormattings.getMessageFormattingCount()).isEqualTo(1);
157     assertThat(messageFormattings.getMessageFormatting(0).getStart()).isZero();
158     assertThat(messageFormattings.getMessageFormatting(0).getEnd()).isEqualTo(3);
159     assertThat(messageFormattings.getMessageFormatting(0).getType()).isEqualTo(DbIssues.MessageFormattingType.CODE);
160
161     // fields set by compute engine
162     assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2));
163     assertThat(issue.tags()).isEmpty();
164     assertInitializedIssue(issue);
165     assertThat(issue.effort()).isNull();
166     assertThat(issue.getRuleDescriptionContextKey()).isEmpty();
167   }
168
169   @Test
170   public void load_issues_from_report_with_locations() {
171     RuleKey ruleKey = RuleKey.of("java", "S001");
172     markRuleAsActive(ruleKey);
173
174     ScannerReport.MessageFormatting messageFormatting = ScannerReport.MessageFormatting.newBuilder().setStart(0).setEnd(4).setType(CODE).build();
175     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
176       .setMsg("the message")
177       .setRuleRepository(ruleKey.repository())
178       .setRuleKey(ruleKey.rule())
179       .addFlow(ScannerReport.Flow.newBuilder()
180         .setType(FlowType.DATA)
181         .setDescription("flow1")
182         .addLocation(ScannerReport.IssueLocation.newBuilder().setMsg("loc1").addMsgFormatting(messageFormatting).setComponentRef(1).build())
183         .addLocation(ScannerReport.IssueLocation.newBuilder().setMsg("loc2").setComponentRef(1).build()))
184       .addFlow(ScannerReport.Flow.newBuilder()
185         .setType(FlowType.EXECUTION)
186         .addLocation(ScannerReport.IssueLocation.newBuilder().setTextRange(newTextRange(2)).setComponentRef(1).build()))
187       .addFlow(ScannerReport.Flow.newBuilder()
188         .addLocation(ScannerReport.IssueLocation.newBuilder().setTextRange(newTextRange(2)).setComponentRef(1).build()))
189       .build();
190     reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
191     Input<DefaultIssue> input = underTest.create(FILE);
192
193     Collection<DefaultIssue> issues = input.getIssues();
194     DbIssues.Locations locations = Iterators.getOnlyElement(issues.iterator()).getLocations();
195     assertThat(locations.getFlowCount()).isEqualTo(3);
196     assertThat(locations.getFlow(0).getDescription()).isEqualTo("flow1");
197     assertThat(locations.getFlow(0).getType()).isEqualTo(DbIssues.FlowType.DATA);
198     assertThat(locations.getFlow(0).getLocationList()).hasSize(2);
199
200     assertThat(locations.getFlow(0).getLocation(0).getMsg()).isEqualTo("loc1");
201     assertThat(locations.getFlow(0).getLocation(0).getMsgFormattingCount()).isEqualTo(1);
202     assertThat(locations.getFlow(0).getLocation(0).getMsgFormatting(0)).extracting(m -> m.getStart(), m -> m.getEnd(), m -> m.getType())
203       .containsExactly(0, 4, DbIssues.MessageFormattingType.CODE);
204
205     assertThat(locations.getFlow(1).hasDescription()).isFalse();
206     assertThat(locations.getFlow(1).getType()).isEqualTo(DbIssues.FlowType.EXECUTION);
207     assertThat(locations.getFlow(1).getLocationList()).hasSize(1);
208
209     assertThat(locations.getFlow(2).hasDescription()).isFalse();
210     assertThat(locations.getFlow(2).hasType()).isFalse();
211     assertThat(locations.getFlow(2).getLocationList()).hasSize(1);
212   }
213
214   @Test
215   public void load_issues_from_report_with_rule_description_context_key() {
216     RuleKey ruleKey = RuleKey.of("java", "S001");
217     markRuleAsActive(ruleKey);
218
219     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
220       .setTextRange(newTextRange(2))
221       .setMsg("the message")
222       .setRuleRepository(ruleKey.repository())
223       .setRuleKey(ruleKey.rule())
224       .setRuleDescriptionContextKey(TEST_CONTEXT_KEY)
225       .build();
226     reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
227     Input<DefaultIssue> input = underTest.create(FILE);
228
229     Collection<DefaultIssue> issues = input.getIssues();
230     assertThat(issues)
231       .hasSize(1)
232       .extracting(DefaultIssue::getRuleDescriptionContextKey)
233       .containsOnly(Optional.of(TEST_CONTEXT_KEY));
234   }
235
236   @Test
237   public void set_rule_name_as_message_when_issue_message_from_report_is_empty() {
238     RuleKey ruleKey = RuleKey.of("java", "S001");
239     markRuleAsActive(ruleKey);
240     registerRule(ruleKey, "Rule 1");
241     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
242       .setRuleRepository(ruleKey.repository())
243       .setRuleKey(ruleKey.rule())
244       .setMsg("")
245       .build();
246     reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
247     Input<DefaultIssue> input = underTest.create(FILE);
248
249     Collection<DefaultIssue> issues = input.getIssues();
250     assertThat(issues).hasSize(1);
251     DefaultIssue issue = Iterators.getOnlyElement(issues.iterator());
252
253     // fields set by analysis report
254     assertThat(issue.ruleKey()).isEqualTo(ruleKey);
255
256     // fields set by compute engine
257     assertInitializedIssue(issue);
258     assertThat(issue.message()).isEqualTo("Rule 1");
259   }
260
261   // SONAR-10781
262   @Test
263   public void load_issues_from_report_missing_secondary_location_component() {
264     RuleKey ruleKey = RuleKey.of("java", "S001");
265     markRuleAsActive(ruleKey);
266
267     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
268       .setTextRange(newTextRange(2))
269       .setMsg("the message")
270       .setRuleRepository(ruleKey.repository())
271       .setRuleKey(ruleKey.rule())
272       .setSeverity(Constants.Severity.BLOCKER)
273       .setGap(3.14)
274       .addFlow(ScannerReport.Flow.newBuilder()
275         .addLocation(ScannerReport.IssueLocation.newBuilder()
276           .setComponentRef(FILE_REF)
277           .setMsg("Secondary location in same file")
278           .setTextRange(newTextRange(2)))
279         .addLocation(ScannerReport.IssueLocation.newBuilder()
280           .setComponentRef(NOT_IN_REPORT_FILE_REF)
281           .setMsg("Secondary location in a missing file")
282           .setTextRange(newTextRange(3)))
283         .addLocation(ScannerReport.IssueLocation.newBuilder()
284           .setComponentRef(ANOTHER_FILE_REF)
285           .setMsg("Secondary location in another file")
286           .setTextRange(newTextRange(3)))
287         .build())
288       .build();
289     reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
290     Input<DefaultIssue> input = underTest.create(FILE);
291
292     Collection<DefaultIssue> issues = input.getIssues();
293     assertThat(issues).hasSize(1);
294     DefaultIssue issue = Iterators.getOnlyElement(issues.iterator());
295
296     DbIssues.Locations locations = issue.getLocations();
297     // fields set by analysis report
298     assertThat(locations.getFlowList()).hasSize(1);
299     assertThat(locations.getFlow(0).getLocationList()).hasSize(2);
300     // Not component id if location is in the same file
301     assertThat(locations.getFlow(0).getLocation(0).getComponentId()).isEmpty();
302     assertThat(locations.getFlow(0).getLocation(1).getComponentId()).isEqualTo(ANOTHER_FILE_UUID);
303   }
304
305   @Test
306   @UseDataProvider("ruleTypeAndStatusByIssueType")
307   public void load_external_issues_from_report(IssueType issueType, RuleType expectedRuleType, String expectedStatus) {
308     ScannerReport.ExternalIssue reportIssue = ScannerReport.ExternalIssue.newBuilder()
309       .setTextRange(newTextRange(2))
310       .setMsg("the message")
311       .addMsgFormatting(ScannerReport.MessageFormatting.newBuilder().setStart(0).setEnd(3).build())
312       .setEngineId("eslint")
313       .setRuleId("S001")
314       .setSeverity(Constants.Severity.BLOCKER)
315       .setEffort(20L)
316       .setType(issueType)
317       .addFlow(ScannerReport.Flow.newBuilder().setType(FlowType.DATA).addLocation(ScannerReport.IssueLocation.newBuilder().build()).build())
318       .build();
319     reportReader.putExternalIssues(FILE.getReportAttributes().getRef(), asList(reportIssue));
320     Input<DefaultIssue> input = underTest.create(FILE);
321
322     Collection<DefaultIssue> issues = input.getIssues();
323     assertThat(issues).hasSize(1);
324     DefaultIssue issue = Iterators.getOnlyElement(issues.iterator());
325
326     // fields set by analysis report
327     assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("external_eslint", "S001"));
328     assertThat(issue.severity()).isEqualTo(Severity.BLOCKER);
329     assertThat(issue.line()).isEqualTo(2);
330     assertThat(issue.effort()).isEqualTo(Duration.create(20L));
331     assertThat(issue.message()).isEqualTo("the message");
332
333     // Check message formatting
334     DbIssues.MessageFormattings messageFormattings = Iterators.getOnlyElement(issues.iterator()).getMessageFormattings();
335     assertThat(messageFormattings.getMessageFormattingCount()).isEqualTo(1);
336     assertThat(messageFormattings.getMessageFormatting(0).getStart()).isZero();
337     assertThat(messageFormattings.getMessageFormatting(0).getEnd()).isEqualTo(3);
338     assertThat(messageFormattings.getMessageFormatting(0).getType()).isEqualTo(DbIssues.MessageFormattingType.CODE);
339
340     assertThat(issue.type()).isEqualTo(expectedRuleType);
341
342     DbIssues.Locations locations = Iterators.getOnlyElement(issues.iterator()).getLocations();
343     assertThat(locations.getFlowCount()).isEqualTo(1);
344     assertThat(locations.getFlow(0).getType()).isEqualTo(DbIssues.FlowType.DATA);
345     assertThat(locations.getFlow(0).getLocationList()).hasSize(1);
346
347     // fields set by compute engine
348     assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2));
349     assertThat(issue.tags()).isEmpty();
350     assertInitializedExternalIssue(issue, expectedStatus);
351   }
352
353   @DataProvider
354   public static Object[][] ruleTypeAndStatusByIssueType() {
355     return new Object[][] {
356       {IssueType.CODE_SMELL, RuleType.CODE_SMELL, STATUS_OPEN},
357       {IssueType.BUG, RuleType.BUG, STATUS_OPEN},
358       {IssueType.VULNERABILITY, RuleType.VULNERABILITY, STATUS_OPEN},
359       {IssueType.SECURITY_HOTSPOT, RuleType.SECURITY_HOTSPOT, STATUS_TO_REVIEW}
360     };
361   }
362
363   @Test
364   @UseDataProvider("ruleTypeAndStatusByIssueType")
365   public void load_external_issues_from_report_with_default_effort(IssueType issueType, RuleType expectedRuleType, String expectedStatus) {
366     ScannerReport.ExternalIssue reportIssue = ScannerReport.ExternalIssue.newBuilder()
367       .setTextRange(newTextRange(2))
368       .setMsg("the message")
369       .setEngineId("eslint")
370       .setRuleId("S001")
371       .setSeverity(Constants.Severity.BLOCKER)
372       .setType(issueType)
373       .build();
374     reportReader.putExternalIssues(FILE.getReportAttributes().getRef(), asList(reportIssue));
375     Input<DefaultIssue> input = underTest.create(FILE);
376
377     Collection<DefaultIssue> issues = input.getIssues();
378     assertThat(issues).hasSize(1);
379     DefaultIssue issue = Iterators.getOnlyElement(issues.iterator());
380
381     // fields set by analysis report
382     assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("external_eslint", "S001"));
383     assertThat(issue.severity()).isEqualTo(Severity.BLOCKER);
384     assertThat(issue.line()).isEqualTo(2);
385     assertThat(issue.effort()).isEqualTo(Duration.create(0L));
386     assertThat(issue.message()).isEqualTo("the message");
387     assertThat(issue.type()).isEqualTo(expectedRuleType);
388
389     // fields set by compute engine
390     assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2));
391     assertThat(issue.tags()).isEmpty();
392     assertInitializedExternalIssue(issue, expectedStatus);
393   }
394
395   @Test
396   public void excludes_issues_on_inactive_rules() {
397     RuleKey ruleKey = RuleKey.of("java", "S001");
398     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
399       .setTextRange(newTextRange(2))
400       .setMsg("the message")
401       .setRuleRepository(ruleKey.repository())
402       .setRuleKey(ruleKey.rule())
403       .setSeverity(Constants.Severity.BLOCKER)
404       .setGap(3.14)
405       .build();
406     reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
407     Input<DefaultIssue> input = underTest.create(FILE);
408
409     Collection<DefaultIssue> issues = input.getIssues();
410     assertThat(issues).isEmpty();
411   }
412
413   @Test
414   public void filter_excludes_issues_from_report() {
415     RuleKey ruleKey = RuleKey.of("java", "S001");
416     markRuleAsActive(ruleKey);
417     when(issueFilter.accept(any(), eq(FILE))).thenReturn(false);
418     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
419       .setTextRange(newTextRange(2))
420       .setMsg("the message")
421       .setRuleRepository(ruleKey.repository())
422       .setRuleKey(ruleKey.rule())
423       .setSeverity(Constants.Severity.BLOCKER)
424       .setGap(3.14)
425       .build();
426     reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
427     Input<DefaultIssue> input = underTest.create(FILE);
428
429     Collection<DefaultIssue> issues = input.getIssues();
430     assertThat(issues).isEmpty();
431   }
432
433   @Test
434   public void exclude_issues_on_common_rules() {
435     RuleKey ruleKey = RuleKey.of(CommonRuleKeys.commonRepositoryForLang("java"), "S001");
436     markRuleAsActive(ruleKey);
437     ScannerReport.Issue reportIssue = ScannerReport.Issue.newBuilder()
438       .setMsg("the message")
439       .setRuleRepository(ruleKey.repository())
440       .setRuleKey(ruleKey.rule())
441       .setSeverity(Constants.Severity.BLOCKER)
442       .build();
443     reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
444
445     Input<DefaultIssue> input = underTest.create(FILE);
446
447     assertThat(input.getIssues()).isEmpty();
448   }
449
450   @Test
451   public void load_issues_of_compute_engine_common_rules() {
452     RuleKey ruleKey = RuleKey.of(CommonRuleKeys.commonRepositoryForLang("java"), "InsufficientCoverage");
453     markRuleAsActive(ruleKey);
454     DefaultIssue ceIssue = new DefaultIssue()
455       .setRuleKey(ruleKey)
456       .setMessage("not enough coverage")
457       .setGap(10.0);
458     when(commonRuleEngine.process(FILE)).thenReturn(singletonList(ceIssue));
459
460     Input<DefaultIssue> input = underTest.create(FILE);
461
462     assertThat(input.getIssues()).containsOnly(ceIssue);
463     assertInitializedIssue(input.getIssues().iterator().next());
464   }
465
466   @Test
467   public void filter_exclude_issues_on_common_rule() {
468     RuleKey ruleKey = RuleKey.of(CommonRuleKeys.commonRepositoryForLang("java"), "InsufficientCoverage");
469     markRuleAsActive(ruleKey);
470     when(issueFilter.accept(any(), eq(FILE))).thenReturn(false);
471     DefaultIssue ceIssue = new DefaultIssue()
472       .setRuleKey(ruleKey)
473       .setMessage("not enough coverage")
474       .setGap(10.0);
475     when(commonRuleEngine.process(FILE)).thenReturn(singletonList(ceIssue));
476
477     Input<DefaultIssue> input = underTest.create(FILE);
478
479     assertThat(input.getIssues()).isEmpty();
480   }
481
482   private ScannerReport.TextRange newTextRange(int issueOnLine) {
483     return ScannerReport.TextRange.newBuilder()
484       .setStartLine(issueOnLine)
485       .setEndLine(issueOnLine)
486       .setStartOffset(0)
487       .setEndOffset(EXAMPLE_LINE_OF_CODE_FORMAT.length() - 1)
488       .build();
489   }
490
491   private void assertInitializedIssue(DefaultIssue issue) {
492     assertInitializedExternalIssue(issue, STATUS_OPEN);
493     assertThat(issue.effort()).isNull();
494     assertThat(issue.effortInMinutes()).isNull();
495   }
496
497   private void assertInitializedExternalIssue(DefaultIssue issue, String expectedStatus) {
498     assertThat(issue.projectKey()).isEqualTo(PROJECT.getKey());
499     assertThat(issue.componentKey()).isEqualTo(FILE.getKey());
500     assertThat(issue.componentUuid()).isEqualTo(FILE.getUuid());
501     assertThat(issue.resolution()).isNull();
502     assertThat(issue.status()).isEqualTo(expectedStatus);
503     assertThat(issue.key()).isNull();
504     assertThat(issue.authorLogin()).isNull();
505   }
506
507   private void markRuleAsActive(RuleKey ruleKey) {
508     activeRulesHolder.put(new ActiveRule(ruleKey, Severity.CRITICAL, emptyMap(), 1_000L, null, "qp1"));
509   }
510
511   private void registerRule(RuleKey ruleKey, String name) {
512     DumbRule dumbRule = new DumbRule(ruleKey);
513     dumbRule.setName(name);
514     ruleRepository.add(dumbRule);
515   }
516 }