1616 */
1717package org .sonar .plugins .csharp ;
1818
19+ import org .junit .jupiter .api .BeforeAll ;
1920import org .junit .jupiter .api .Test ;
2021import org .sonar .api .SonarEdition ;
2122import org .sonar .api .SonarQubeSide ;
2223import org .sonar .api .SonarRuntime ;
2324import org .sonar .api .internal .SonarRuntimeImpl ;
24- import org .sonar .api .rule .RuleStatus ;
25- import org .sonar .api .rules .RuleType ;
26- import org .sonar .api .server .debt .DebtRemediationFunction ;
27- import org .sonar .api .server .rule .RuleParamType ;
2825import org .sonar .api .server .rule .RulesDefinition ;
29- import org .sonar .api .server .rule .RulesDefinition .Context ;
30- import org .sonar .api .server .rule .RulesDefinition .Rule ;
3126import org .sonar .api .utils .Version ;
3227import org .sonarsource .dotnet .shared .plugins .DotNetRulesDefinition ;
3328import org .sonarsource .dotnet .shared .plugins .RoslynRules ;
3429
3530import static org .assertj .core .api .Assertions .assertThat ;
3631
3732class CSharpRulesDefinitionTest {
38- private static final String SECURITY_HOTSPOT_RULE_KEY = "S4502" ;
39- private static final String VULNERABILITY_RULE_KEY = "S2115" ;
40- private static final String NO_TAGS_RULE_KEY = "S1048" ;
41- private static final String SINGLE_PARAM_RULE_KEY = "S1200" ;
42- private static final String MULTI_PARAM_RULE_KEY = "S110" ;
43-
33+ private static final RulesDefinition .Context CONTEXT = new RulesDefinition .Context ();
4434 private static final SonarRuntime SONAR_RUNTIME = SonarRuntimeImpl .forSonarQube (Version .create (10 , 10 ), SonarQubeSide .SCANNER ,
4535 SonarEdition .COMMUNITY );
4636 private static final RoslynRules ROSLYN_RULES = new RoslynRules (CSharpPlugin .METADATA );
4737
38+ private static RulesDefinition .Repository ruleRepo ;
4839
49- @ Test
50- void test () {
51- Context context = new Context ();
52- assertThat (context .repositories ()).isEmpty ();
53-
54- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
55- definition .define (context );
56-
57- assertThat (context .repositories ()).hasSize (1 );
58- assertThat (context .repository ("csharpsquid" ).rules ()).isNotEmpty ();
59-
60- Rule s100 = context .repository ("csharpsquid" ).rule ("S100" );
61- assertThat (s100 .name ()).isEqualTo ("Methods and properties should be named in PascalCase" );
62- assertThat (s100 .type ()).isEqualTo (RuleType .CODE_SMELL );
63- assertThat (s100 .status ()).isEqualTo (RuleStatus .READY );
64- assertThat (s100 .severity ()).isEqualTo ("MINOR" );
65- assertThat (s100 .debtRemediationFunction ().type ()).isEqualTo (DebtRemediationFunction .Type .CONSTANT_ISSUE );
66- assertThat (s100 .debtRemediationFunction ().baseEffort ()).isEqualTo ("5min" );
67- assertThat (s100 .params ()).isEmpty ();
68- assertThat (s100 .tags ()).hasSize (1 ).containsExactly ("convention" );
69- }
70-
71- @ Test
72- void test_symbolic_execution_rules_are_not_defined () {
73- RulesDefinition .Context context = new RulesDefinition .Context ();
74- assertThat (context .repositories ()).isEmpty ();
75-
76- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
77- definition .define (context );
78-
79- assertThat (context .repositories ()).hasSize (1 );
80-
81- assertThat (context .repository ("csharpsquid" ).rule ("S2259" )).isNull ();
82- }
83-
84- @ Test
85- void test_security_hotspot () {
40+ @ BeforeAll
41+ static void setupContext () {
8642 DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
87- RulesDefinition .Context context = new RulesDefinition .Context ();
88- definition .define (context );
89- RulesDefinition .Repository repository = context .repository ("csharpsquid" );
90-
91- RulesDefinition .Rule hardcodedCredentialsRule = repository .rule (SECURITY_HOTSPOT_RULE_KEY );
92- assertThat (hardcodedCredentialsRule .type ()).isEqualTo (RuleType .SECURITY_HOTSPOT );
93- assertThat (hardcodedCredentialsRule .activatedByDefault ()).isTrue ();
43+ definition .define (CONTEXT );
44+ ruleRepo = CONTEXT .repository ("csharpsquid" );
9445 }
9546
9647 @ Test
97- void test_security_hotspot_has_correct_type_and_security_standards () {
98- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
99- RulesDefinition .Context context = new RulesDefinition .Context ();
100- definition .define (context );
101- RulesDefinition .Repository repository = context .repository ("csharpsquid" );
102-
103- RulesDefinition .Rule rule = repository .rule (SECURITY_HOTSPOT_RULE_KEY );
104- assertThat (rule .type ()).isEqualTo (RuleType .SECURITY_HOTSPOT );
105- assertThat (rule .securityStandards ()).containsExactlyInAnyOrder (
106- "cwe:352" ,
107- "owaspTop10:a6" ,
108- "owaspTop10-2021:a1" ,
109- "pciDss-3.2:6.5.9" ,
110- "pciDss-4.0:6.2.4" ,
111- "owaspAsvs-4.0:13.2.3" ,
112- "owaspAsvs-4.0:4.2.2" ,
113- "stig-ASD_V5R3:V-222603" );
48+ void rules_areDefined () {
49+ assertThat (CONTEXT .repositories ()).hasSize (1 );
50+ RulesDefinition .Rule s100 = ruleRepo .rule ("S100" );
51+ assertThat (s100 ).isNotNull ();
52+ assertThat (s100 .name ()).isEqualTo ("Methods and properties should be named in PascalCase" );
11453 }
11554
11655 @ Test
117- void test_security_standards_with_vulnerability () {
118- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
119- RulesDefinition .Context context = new RulesDefinition .Context ();
120- definition .define (context );
121- RulesDefinition .Repository repository = context .repository ("csharpsquid" );
122-
123- RulesDefinition .Rule rule = repository .rule (VULNERABILITY_RULE_KEY );
124- assertThat (rule .type ()).isEqualTo (RuleType .VULNERABILITY );
125- assertThat (rule .securityStandards ()).containsExactlyInAnyOrder (
126- "cwe:521" ,
127- "owaspAsvs-4.0:9.2.2" ,
128- "owaspAsvs-4.0:9.2.3" ,
129- "owaspTop10:a2" ,
130- "owaspTop10:a3" ,
131- "owaspTop10-2021:a7" ,
132- "pciDss-3.2:6.5.10" ,
133- "pciDss-4.0:6.2.4" );
56+ void symbolicExecutionRules_areNotDefined () {
57+ assertThat (CONTEXT .repositories ()).hasSize (1 );
58+ assertThat (ruleRepo .rule ("S2259" )).isNull ();
13459 }
13560
13661 @ Test
137- void test_all_rules_have_metadata_set () {
138- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
139- RulesDefinition .Context context = new RulesDefinition .Context ();
140- definition .define (context );
141- RulesDefinition .Repository repository = context .repository ("csharpsquid" );
142-
143- for (RulesDefinition .Rule rule : repository .rules ()) {
62+ void allRules_haveMetadata () {
63+ for (RulesDefinition .Rule rule : ruleRepo .rules ()) {
14464 assertThat (rule .name ()).isNotEmpty ();
14565 assertThat (rule .type ()).isNotNull ();
14666 assertThat (rule .status ()).isNotNull ();
@@ -149,92 +69,9 @@ void test_all_rules_have_metadata_set() {
14969 }
15070
15171 @ Test
152- void test_all_rules_have_htmldescription () {
153- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
154- RulesDefinition .Context context = new RulesDefinition .Context ();
155- definition .define (context );
156- RulesDefinition .Repository repository = context .repository ("csharpsquid" );
157-
158- for (RulesDefinition .Rule rule : repository .rules ()) {
72+ void allRules_haveHtmlDescription () {
73+ for (RulesDefinition .Rule rule : ruleRepo .rules ()) {
15974 assertThat (rule .htmlDescription ()).isNotEmpty ().hasSizeGreaterThan (100 );
16075 }
16176 }
162-
163- @ Test
164- void test_tags_are_set () {
165- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
166- RulesDefinition .Context context = new RulesDefinition .Context ();
167- definition .define (context );
168- RulesDefinition .Rule rule = context .repository ("csharpsquid" ).rule (SECURITY_HOTSPOT_RULE_KEY );
169-
170- assertThat (rule .tags ()).containsExactly ("cwe" );
171- }
172-
173- @ Test
174- void test_tags_are_empty () {
175- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
176- RulesDefinition .Context context = new RulesDefinition .Context ();
177- definition .define (context );
178- RulesDefinition .Rule rule = context .repository ("csharpsquid" ).rule (NO_TAGS_RULE_KEY );
179-
180- assertThat (rule .tags ()).isEmpty ();
181- }
182-
183- @ Test
184- void test_remediation_is_set () {
185- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
186- RulesDefinition .Context context = new RulesDefinition .Context ();
187- definition .define (context );
188- RulesDefinition .Repository repository = context .repository ("csharpsquid" );
189-
190- // We don't have rule with Linear to assert. That path is tested in AbstractRulesDefinition.test_remediation_is_set_linear()
191- assertThat (repository .rule ("S100" ).debtRemediationFunction ()).hasToString ("DebtRemediationFunction{type=CONSTANT_ISSUE, gap " +
192- "multiplier=null, base effort=5min}" );
193- assertThat (repository .rule ("S110" ).debtRemediationFunction ()).hasToString ("DebtRemediationFunction{type=LINEAR_OFFSET, gap " +
194- "multiplier=30min, base effort=4h}" );
195- }
196-
197- @ Test
198- void test_no_params () {
199- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
200- RulesDefinition .Context context = new RulesDefinition .Context ();
201- definition .define (context );
202- RulesDefinition .Rule rule = context .repository ("csharpsquid" ).rule (SECURITY_HOTSPOT_RULE_KEY );
203-
204- assertThat (rule .params ()).isEmpty ();
205- }
206-
207- @ Test
208- void test_single_params () {
209- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
210- RulesDefinition .Context context = new RulesDefinition .Context ();
211- definition .define (context );
212- RulesDefinition .Rule rule = context .repository ("csharpsquid" ).rule (SINGLE_PARAM_RULE_KEY );
213-
214- assertThat (rule .params ()).hasSize (1 );
215- assertParam (rule .params ().get (0 ), "max" , RuleParamType .INTEGER , "30" , "Maximum number of types a single type is allowed to depend " +
216- "upon" );
217- }
218-
219- @ Test
220- void test_multiple_params () {
221- DotNetRulesDefinition definition = new DotNetRulesDefinition (CSharpPlugin .METADATA , SONAR_RUNTIME , ROSLYN_RULES );
222- RulesDefinition .Context context = new RulesDefinition .Context ();
223- definition .define (context );
224- RulesDefinition .Rule rule = context .repository ("csharpsquid" ).rule (MULTI_PARAM_RULE_KEY );
225-
226- assertThat (rule .params ()).hasSize (2 );
227- assertParam (rule .params ().get (0 ), "max" , RuleParamType .INTEGER , "5" , "Maximum depth of the inheritance tree. (Number)" );
228- assertParam (rule .params ().get (1 ), "filteredClasses" , RuleParamType .STRING , null ,
229- "Comma-separated list of classes or records to be filtered out of the count of inheritance. Depth counting will stop when a " +
230- "filtered class or record is reached. For example: System.Windows.Controls.UserControl, System.Windows.*. (String)" );
231- }
232-
233- private static void assertParam (RulesDefinition .Param param , String expectedKey , RuleParamType expectedType ,
234- String expectedDefaultValue , String expectedDescription ) {
235- assertThat (param .key ()).isEqualTo (expectedKey );
236- assertThat (param .type ()).isEqualTo (expectedType );
237- assertThat (param .defaultValue ()).isEqualTo (expectedDefaultValue );
238- assertThat (param .description ()).isEqualTo (expectedDescription );
239- }
24077}
0 commit comments