View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.enforcer.rules.dependency;
20  
21  import java.util.Collections;
22  
23  import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
24  import org.apache.maven.enforcer.rules.utils.DependencyNodeBuilder;
25  import org.apache.maven.execution.MavenSession;
26  import org.apache.maven.plugin.testing.ArtifactStubFactory;
27  import org.apache.maven.project.MavenProject;
28  import org.junit.jupiter.api.Test;
29  import org.junit.jupiter.api.extension.ExtendWith;
30  import org.mockito.InjectMocks;
31  import org.mockito.Mock;
32  import org.mockito.junit.jupiter.MockitoExtension;
33  
34  import static org.assertj.core.api.Assertions.assertThatCode;
35  import static org.mockito.ArgumentMatchers.anyList;
36  import static org.mockito.Mockito.when;
37  
38  /**
39   * The Class BannedDependenciesTest.
40   *
41   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
42   */
43  @ExtendWith(MockitoExtension.class)
44  class BannedDependenciesTest {
45  
46      private static final ArtifactStubFactory ARTIFACT_STUB_FACTORY = new ArtifactStubFactory();
47  
48      @Mock
49      private MavenProject project;
50  
51      @Mock
52      private MavenSession session;
53  
54      @Mock
55      private ResolverUtil resolverUtil;
56  
57      @InjectMocks
58      private BannedDependencies rule;
59  
60      @Test
61      void excludesDoNotUseTransitiveDependenciesNullSafe() throws Exception {
62          when(session.getCurrentProject()).thenReturn(project);
63          when(project.getDependencyArtifacts()).thenReturn(ARTIFACT_STUB_FACTORY.getTypedArtifacts());
64  
65          rule.setSearchTransitive(false);
66          rule.setExcludes(Collections.singletonList("g:b:*:*:compile:*"));
67  
68          assertThatCode(rule::execute)
69                  .isInstanceOf(EnforcerRuleException.class)
70                  .hasMessageContaining("g:b:jar:1.0 <--- banned via the exclude/include list");
71      }
72  
73      @Test
74      void excludesDoNotUseTransitiveDependencies() throws Exception {
75          when(session.getCurrentProject()).thenReturn(project);
76          when(project.getDependencyArtifacts()).thenReturn(ARTIFACT_STUB_FACTORY.getScopedArtifacts());
77  
78          rule.setSearchTransitive(false);
79          rule.setExcludes(Collections.singletonList("*"));
80  
81          assertThatCode(rule::execute)
82                  .isInstanceOf(EnforcerRuleException.class)
83                  .hasMessageContaining("g:runtime:jar:1.0 <--- banned via the exclude/include list")
84                  .hasMessageContaining("g:compile:jar:1.0 <--- banned via the exclude/include list")
85                  .hasMessageContaining("g:provided:jar:1.0 <--- banned via the exclude/include list")
86                  .hasMessageContaining("g:test:jar:1.0 <--- banned via the exclude/include list")
87                  .hasMessageContaining("g:system:jar:1.0 <--- banned via the exclude/include list");
88      }
89  
90      @Test
91      void excludesAndIncludesDoNotUseTransitiveDependencies() throws Exception {
92          when(session.getCurrentProject()).thenReturn(project);
93          when(project.getDependencyArtifacts()).thenReturn(ARTIFACT_STUB_FACTORY.getScopedArtifacts());
94  
95          rule.setSearchTransitive(false);
96          rule.setExcludes(Collections.singletonList("*"));
97          rule.setIncludes(Collections.singletonList("g:compile"));
98  
99          assertThatCode(rule::execute)
100                 .isInstanceOf(EnforcerRuleException.class)
101                 .hasMessageContaining("g:runtime:jar:1.0 <--- banned via the exclude/include list")
102                 .hasMessageContaining("g:provided:jar:1.0 <--- banned via the exclude/include list")
103                 .hasMessageContaining("g:test:jar:1.0 <--- banned via the exclude/include list")
104                 .hasMessageContaining("g:system:jar:1.0 <--- banned via the exclude/include list")
105                 .hasMessageNotContaining("g:compile:jar:1.0");
106     }
107 
108     @Test
109     void excludesUseTransitiveDependencies() throws Exception {
110 
111         when(resolverUtil.resolveTransitiveDependenciesVerbose(anyList()))
112                 .thenReturn(new DependencyNodeBuilder()
113                         .withType(DependencyNodeBuilder.Type.POM)
114                         .withChildNode(new DependencyNodeBuilder()
115                                 .withArtifactId("childA")
116                                 .withVersion("1.0.0")
117                                 .withChildNode(new DependencyNodeBuilder()
118                                         .withType(DependencyNodeBuilder.Type.WAR)
119                                         .withArtifactId("childAA")
120                                         .withVersion("1.0.0-SNAPSHOT")
121                                         .build())
122                                 .withChildNode(new DependencyNodeBuilder()
123                                         .withType(DependencyNodeBuilder.Type.WAR)
124                                         .withArtifactId("childAB")
125                                         .withVersion("1.0.0-SNAPSHOT")
126                                         .build())
127                                 .build())
128                         .build());
129 
130         rule.setSearchTransitive(true);
131         rule.setExcludes(Collections.singletonList("*:*:*:war"));
132 
133         assertThatCode(rule::execute)
134                 .isInstanceOf(EnforcerRuleException.class)
135                 .hasMessageContaining(
136                         "default-group:childAA:war:classifier:1.0.0-SNAPSHOT <--- banned via the exclude/include list")
137                 .hasMessageContaining(
138                         "default-group:childAB:war:classifier:1.0.0-SNAPSHOT <--- banned via the exclude/include list");
139     }
140 
141     @Test
142     void excludesAndIncludesUseTransitiveDependencies() throws Exception {
143 
144         when(resolverUtil.resolveTransitiveDependenciesVerbose(anyList()))
145                 .thenReturn(new DependencyNodeBuilder()
146                         .withType(DependencyNodeBuilder.Type.POM)
147                         .withChildNode(new DependencyNodeBuilder()
148                                 .withArtifactId("childA")
149                                 .withVersion("1.0.0")
150                                 .withChildNode(new DependencyNodeBuilder()
151                                         .withType(DependencyNodeBuilder.Type.WAR)
152                                         .withArtifactId("childAA")
153                                         .withVersion("1.0.0-SNAPSHOT")
154                                         .build())
155                                 .withChildNode(new DependencyNodeBuilder()
156                                         .withType(DependencyNodeBuilder.Type.WAR)
157                                         .withArtifactId("childAB")
158                                         .withVersion("1.0.0-SNAPSHOT")
159                                         .build())
160                                 .build())
161                         .build());
162 
163         rule.setSearchTransitive(true);
164         rule.setExcludes(Collections.singletonList("*:*:*:war"));
165         rule.setIncludes(Collections.singletonList("*:childAB:*:war"));
166 
167         assertThatCode(rule::execute)
168                 .isInstanceOf(EnforcerRuleException.class)
169                 .hasMessageContaining(
170                         "default-group:childAA:war:classifier:1.0.0-SNAPSHOT <--- banned via the exclude/include list")
171                 .hasMessageNotContaining("childAB");
172     }
173 
174     @Test
175     void invalidExcludeFormat() throws Exception {
176         rule.setSearchTransitive(false);
177         rule.setExcludes(Collections.singletonList("::::::::::"));
178 
179         assertThatCode(rule::execute).isInstanceOf(IllegalArgumentException.class);
180     }
181 
182     @Test
183     void invalidIncludeFormat() throws Exception {
184         rule.setSearchTransitive(false);
185         rule.setExcludes(Collections.singletonList("*"));
186         rule.setIncludes(Collections.singletonList("*:*:x:x:x:x:x:x:x:x:"));
187 
188         assertThatCode(rule::execute).isInstanceOf(IllegalArgumentException.class);
189     }
190 }