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.issue;
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;
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;
67 @RunWith(DataProviderRunner.class)
68 public class TrackerRawInputFactoryTest {
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; ";
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";
80 public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(PROJECT);
82 public BatchReportReaderRule reportReader = new BatchReportReaderRule();
84 public ActiveRulesHolderRule activeRulesHolder = new ActiveRulesHolderRule();
86 public RuleRepositoryRule ruleRepository = new RuleRepositoryRule();
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();
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);
99 public void before() {
100 when(sourceLinesHash.getLineHashesMatchingDBVersion(FILE)).thenReturn(Collections.singletonList("line"));
101 when(issueFilter.accept(any(), eq(FILE))).thenReturn(true);
105 public void load_source_hash_sequences() {
106 Input<DefaultIssue> input = underTest.create(FILE);
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();
113 assertThat(input.getBlockHashSequence()).isNotNull();
117 public void load_source_hash_sequences_only_on_files() {
118 Input<DefaultIssue> input = underTest.create(PROJECT);
120 assertThat(input.getLineHashSequence()).isNotNull();
121 assertThat(input.getBlockHashSequence()).isNotNull();
125 public void load_issues_from_report() {
126 RuleKey ruleKey = RuleKey.of("java", "S001");
127 markRuleAsActive(ruleKey);
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)
137 .setQuickFixAvailable(true)
139 reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
140 Input<DefaultIssue> input = underTest.create(FILE);
142 Collection<DefaultIssue> issues = input.getIssues();
143 assertThat(issues).hasSize(1);
144 DefaultIssue issue = Iterators.getOnlyElement(issues.iterator());
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();
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);
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();
170 public void load_issues_from_report_with_locations() {
171 RuleKey ruleKey = RuleKey.of("java", "S001");
172 markRuleAsActive(ruleKey);
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()))
190 reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
191 Input<DefaultIssue> input = underTest.create(FILE);
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);
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);
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);
209 assertThat(locations.getFlow(2).hasDescription()).isFalse();
210 assertThat(locations.getFlow(2).hasType()).isFalse();
211 assertThat(locations.getFlow(2).getLocationList()).hasSize(1);
215 public void load_issues_from_report_with_rule_description_context_key() {
216 RuleKey ruleKey = RuleKey.of("java", "S001");
217 markRuleAsActive(ruleKey);
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)
226 reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
227 Input<DefaultIssue> input = underTest.create(FILE);
229 Collection<DefaultIssue> issues = input.getIssues();
232 .extracting(DefaultIssue::getRuleDescriptionContextKey)
233 .containsOnly(Optional.of(TEST_CONTEXT_KEY));
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())
246 reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
247 Input<DefaultIssue> input = underTest.create(FILE);
249 Collection<DefaultIssue> issues = input.getIssues();
250 assertThat(issues).hasSize(1);
251 DefaultIssue issue = Iterators.getOnlyElement(issues.iterator());
253 // fields set by analysis report
254 assertThat(issue.ruleKey()).isEqualTo(ruleKey);
256 // fields set by compute engine
257 assertInitializedIssue(issue);
258 assertThat(issue.message()).isEqualTo("Rule 1");
263 public void load_issues_from_report_missing_secondary_location_component() {
264 RuleKey ruleKey = RuleKey.of("java", "S001");
265 markRuleAsActive(ruleKey);
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)
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)))
289 reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
290 Input<DefaultIssue> input = underTest.create(FILE);
292 Collection<DefaultIssue> issues = input.getIssues();
293 assertThat(issues).hasSize(1);
294 DefaultIssue issue = Iterators.getOnlyElement(issues.iterator());
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);
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")
314 .setSeverity(Constants.Severity.BLOCKER)
317 .addFlow(ScannerReport.Flow.newBuilder().setType(FlowType.DATA).addLocation(ScannerReport.IssueLocation.newBuilder().build()).build())
319 reportReader.putExternalIssues(FILE.getReportAttributes().getRef(), asList(reportIssue));
320 Input<DefaultIssue> input = underTest.create(FILE);
322 Collection<DefaultIssue> issues = input.getIssues();
323 assertThat(issues).hasSize(1);
324 DefaultIssue issue = Iterators.getOnlyElement(issues.iterator());
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");
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);
340 assertThat(issue.type()).isEqualTo(expectedRuleType);
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);
347 // fields set by compute engine
348 assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2));
349 assertThat(issue.tags()).isEmpty();
350 assertInitializedExternalIssue(issue, expectedStatus);
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}
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")
371 .setSeverity(Constants.Severity.BLOCKER)
374 reportReader.putExternalIssues(FILE.getReportAttributes().getRef(), asList(reportIssue));
375 Input<DefaultIssue> input = underTest.create(FILE);
377 Collection<DefaultIssue> issues = input.getIssues();
378 assertThat(issues).hasSize(1);
379 DefaultIssue issue = Iterators.getOnlyElement(issues.iterator());
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);
389 // fields set by compute engine
390 assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2));
391 assertThat(issue.tags()).isEmpty();
392 assertInitializedExternalIssue(issue, expectedStatus);
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)
406 reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
407 Input<DefaultIssue> input = underTest.create(FILE);
409 Collection<DefaultIssue> issues = input.getIssues();
410 assertThat(issues).isEmpty();
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)
426 reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
427 Input<DefaultIssue> input = underTest.create(FILE);
429 Collection<DefaultIssue> issues = input.getIssues();
430 assertThat(issues).isEmpty();
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)
443 reportReader.putIssues(FILE.getReportAttributes().getRef(), singletonList(reportIssue));
445 Input<DefaultIssue> input = underTest.create(FILE);
447 assertThat(input.getIssues()).isEmpty();
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()
456 .setMessage("not enough coverage")
458 when(commonRuleEngine.process(FILE)).thenReturn(singletonList(ceIssue));
460 Input<DefaultIssue> input = underTest.create(FILE);
462 assertThat(input.getIssues()).containsOnly(ceIssue);
463 assertInitializedIssue(input.getIssues().iterator().next());
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()
473 .setMessage("not enough coverage")
475 when(commonRuleEngine.process(FILE)).thenReturn(singletonList(ceIssue));
477 Input<DefaultIssue> input = underTest.create(FILE);
479 assertThat(input.getIssues()).isEmpty();
482 private ScannerReport.TextRange newTextRange(int issueOnLine) {
483 return ScannerReport.TextRange.newBuilder()
484 .setStartLine(issueOnLine)
485 .setEndLine(issueOnLine)
487 .setEndOffset(EXAMPLE_LINE_OF_CODE_FORMAT.length() - 1)
491 private void assertInitializedIssue(DefaultIssue issue) {
492 assertInitializedExternalIssue(issue, STATUS_OPEN);
493 assertThat(issue.effort()).isNull();
494 assertThat(issue.effortInMinutes()).isNull();
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();
507 private void markRuleAsActive(RuleKey ruleKey) {
508 activeRulesHolder.put(new ActiveRule(ruleKey, Severity.CRITICAL, emptyMap(), 1_000L, null, "qp1"));
511 private void registerRule(RuleKey ruleKey, String name) {
512 DumbRule dumbRule = new DumbRule(ruleKey);
513 dumbRule.setName(name);
514 ruleRepository.add(dumbRule);