001package org.apache.maven.plugins.enforcer;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
023import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
024import org.apache.maven.execution.MavenSession;
025import org.apache.maven.model.Dependency;
026import org.apache.maven.plugin.logging.Log;
027import org.apache.maven.project.MavenProject;
028import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
029import org.junit.Before;
030import org.junit.Test;
031
032import static org.junit.Assert.assertTrue;
033import static org.mockito.Mockito.mock;
034import static org.mockito.Mockito.when;
035
036import java.util.Arrays;
037import java.util.Collections;
038import java.util.List;
039
040/**
041 * Check reactorModuleConvergence rule.
042 * 
043 * @author <a href="mailto:khmarbaise@apache.org">Karl Heinz Marbaise</a>
044 */
045public class ReactorModuleConvergenceTest
046{
047    private MavenProject project;
048
049    private MavenSession session;
050
051    private EnforcerRuleHelper helper;
052
053    private ReactorModuleConvergence rule;
054
055    @Before
056    public void before()
057        throws ExpressionEvaluationException
058    {
059        project = mock( MavenProject.class );
060        session = mock( MavenSession.class );
061        helper = mock( EnforcerRuleHelper.class );
062        when( helper.evaluate( "${project}" ) ).thenReturn( project );
063        when( helper.evaluate( "${session}" ) ).thenReturn( session );
064        when( helper.getLog() ).thenReturn( mock( Log.class ) );
065
066        rule = new ReactorModuleConvergence();
067    }
068
069    @Test
070    public void shouldNotFailWithNoProject()
071        throws EnforcerRuleException
072    {
073        when( session.getSortedProjects() ).thenReturn( Collections.<MavenProject> emptyList() );
074
075        rule.execute( helper );
076
077        //intentionally only assertTrue cause we don't expect an exception.
078        assertTrue( true );
079    }
080
081    @Test
082    public void shouldNotFailWithAValidProject()
083        throws EnforcerRuleException, ExpressionEvaluationException
084    {
085        MavenProject mp1 = createProjectParent();
086        MavenProject mp2 = createProjectChild1( mp1 );
087        MavenProject mp3 = createProjectChild2( mp1 );
088
089        List<MavenProject> theList = Arrays.asList( mp1, mp2, mp3 );
090        when( session.getSortedProjects() ).thenReturn( theList );
091
092        rule.execute( helper );
093
094        //intentionally only assertTrue cause we don't expect an exception.
095        assertTrue( true );
096    }
097
098    @Test( expected = EnforcerRuleException.class )
099    public void shouldFailWithWrongVersionInOneChild()
100        throws EnforcerRuleException, ExpressionEvaluationException
101    {
102        MavenProject mp1 = createProjectParent();
103        MavenProject mp2 = createProjectChild1( mp1 );
104        MavenProject mp3 = createProjectChild2WithWrongVersion( mp1 );
105
106        List<MavenProject> theList = Arrays.asList( mp1, mp2, mp3 );
107        when( session.getSortedProjects() ).thenReturn( theList );
108
109        rule.execute( helper );
110
111        //intentionally no assertTrue() cause we expect getting an exception.
112    }
113
114    @Test( expected = EnforcerRuleException.class )
115    public void shouldFailWithWrongParent()
116        throws EnforcerRuleException, ExpressionEvaluationException
117    {
118        MavenProject mp1 = createProjectParent();
119
120        MavenProject wrongParentVerison = mock( MavenProject.class );
121        when( wrongParentVerison.getGroupId() ).thenReturn( "org.apache.enforcer" );
122        when( wrongParentVerison.getArtifactId() ).thenReturn( "m1" );
123        when( wrongParentVerison.getVersion() ).thenReturn( "1.1-SNAPSHOT" );
124        when( wrongParentVerison.getId() ).thenReturn( "org.apache.enforcer:m1:jar:1.1-SNAPSHOT" );
125        when( wrongParentVerison.getDependencies() ).thenReturn( Collections.<Dependency>emptyList() );
126
127        MavenProject mp2 = createProjectChild2( wrongParentVerison );
128        MavenProject mp3 = createProjectChild2( mp1 );
129
130        List<MavenProject> theList = Arrays.asList( mp1, mp2, mp3 );
131        when( session.getSortedProjects() ).thenReturn( theList );
132
133        rule.execute( helper );
134
135        //intentionally no assertTrue() cause we expect getting an exception.
136    }
137
138    @Test
139    public void shouldNotFailWithACompanyParent()
140        throws EnforcerRuleException, ExpressionEvaluationException
141    {
142        MavenProject companyParent = createCompanyParent();
143        MavenProject mp1 = createProjectParent( companyParent );
144
145        MavenProject mp2 = createProjectChild1( mp1 );
146        MavenProject mp3 = createProjectChild2( mp1 );
147
148        List<MavenProject> theList = Arrays.asList( mp1, mp2, mp3 );
149        when( session.getSortedProjects() ).thenReturn( theList );
150
151        rule.execute( helper );
152
153        //intentionally only assertTrue cause we don't expect an exception.
154        assertTrue( true );
155    }
156
157    @Test( expected = EnforcerRuleException.class )
158    public void shouldFailWithMissingParentsInReactory()
159        throws EnforcerRuleException, ExpressionEvaluationException
160    {
161        MavenProject mp1 = createProjectParent();
162        MavenProject mp2 = createProjectChild1( mp1 );
163        MavenProject mp3 = createProjectChild2( null );
164
165        List<MavenProject> theList = Arrays.asList( mp1, mp2, mp3 );
166        when( session.getSortedProjects() ).thenReturn( theList );
167
168        rule.execute( helper );
169
170        //intentionally only assertTrue cause we don't expect an exception.
171        assertTrue( true );
172    }
173
174    @Test( expected = EnforcerRuleException.class )
175    public void shouldFailWithAParentWhichIsNotPartOfTheReactory()
176        throws EnforcerRuleException, ExpressionEvaluationException
177    {
178        MavenProject mp1 = createProjectParent();
179
180        MavenProject wrongParentVerison = mock( MavenProject.class );
181        when( wrongParentVerison.getGroupId() ).thenReturn( "org.apache" );
182        when( wrongParentVerison.getArtifactId() ).thenReturn( "m1" );
183        when( wrongParentVerison.getVersion() ).thenReturn( "1.0-SNAPSHOT" );
184        when( wrongParentVerison.getId() ).thenReturn( "org.apache.enforcer:m1:jar:1.0-SNAPSHOT" );
185        when( wrongParentVerison.getDependencies() ).thenReturn( Collections.<Dependency>emptyList() );
186
187        MavenProject mp2 = createProjectChild2( wrongParentVerison );
188        MavenProject mp3 = createProjectChild2( mp1 );
189
190        List<MavenProject> theList = Arrays.asList( mp1, mp2, mp3 );
191        when( session.getSortedProjects() ).thenReturn( theList );
192
193        rule.execute( helper );
194
195        //intentionally no assertTrue() cause we expect getting an exception.
196    }
197
198    @Test
199    public void shouldNotFailWithDependencyInReactory()
200        throws EnforcerRuleException, ExpressionEvaluationException
201    {
202        MavenProject mp1 = createProjectParent();
203        MavenProject mp2 = createProjectChild1( mp1 );
204
205        Dependency goodDependency = createDependency( "org.junit", "junit", "2.0" );
206        List<Dependency> depListMP2 = Arrays.asList( goodDependency );
207        when( mp2.getDependencies() ).thenReturn( depListMP2 );
208
209        MavenProject mp3 = createProjectChild2( mp1 );
210        Dependency dep1_MP3 = createDependency( "org.apache.commons", "commons-io", "1.0.4" );
211        List<Dependency> depListMP3 = Arrays.asList( dep1_MP3 );
212        when( mp3.getDependencies() ).thenReturn( depListMP3 );
213
214        List<MavenProject> theList = Arrays.asList( mp1, mp2, mp3 );
215        when( session.getSortedProjects() ).thenReturn( theList );
216
217        rule.execute( helper );
218
219        //intentionally no assertTrue() cause we do not expect to get an exception.
220        assertTrue( true );
221    }
222
223    @Test( expected = EnforcerRuleException.class )
224    public void shouldFailWithWrongDependencyInReactor()
225        throws EnforcerRuleException, ExpressionEvaluationException
226    {
227        MavenProject mp1 = createProjectParent();
228        MavenProject mp2 = createProjectChild1( mp1 );
229
230        Dependency goodDependency = createDependency( "org.junit", "junit", "2.0" );
231
232        Dependency wrongDepFromReactor = createDependency( "org.apache.enforcer", "m2", "1.1-SNAPSHOT" );
233        List<Dependency> depList = Arrays.asList( goodDependency, wrongDepFromReactor );
234        when( mp2.getDependencies() ).thenReturn( depList );
235
236        MavenProject mp3 = createProjectChild2( mp1 );
237
238        List<MavenProject> theList = Arrays.asList( mp1, mp2, mp3 );
239        when( session.getSortedProjects() ).thenReturn( theList );
240
241        rule.execute( helper );
242
243        //intentionally no assertTrue() cause we expect getting an exception.
244    }
245
246    /**
247     * This small setup is equivalent to the following situation:
248     * 
249     * <pre>
250     *  &lt;parent&gt;
251     *    &lt;groupId&gt;...&lt;/groupId&gt;
252     *    &lt;artifactId&gt;...&lt;/artifactId&gt;
253     *    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
254     *  &lt;/parent&gt;
255     *  
256     *  &lt;version&gt;1.1-SNAPSHOT&lt;/version&gt;
257     * </pre>
258     * 
259     * @param parent
260     * @return Create MavenProject mock.
261     */
262    private MavenProject createProjectChild2WithWrongVersion( MavenProject parent )
263    {
264        MavenProject mp2 = mock( MavenProject.class );
265        when( mp2.getParent() ).thenReturn( parent );
266        when( mp2.getGroupId() ).thenReturn( "org.apache.enforcer" );
267        when( mp2.getArtifactId() ).thenReturn( "m1" );
268        when( mp2.getVersion() ).thenReturn( "1.1-SNAPSHOT" );
269        when( mp2.getId() ).thenReturn( "org.apache.enforcer:m1:jar:1.1-SNAPSHOT" );
270        when( mp2.getDependencies() ).thenReturn( Collections.<Dependency>emptyList() );
271        return mp2;
272    }
273
274    private MavenProject createProjectChild2( MavenProject parent )
275    {
276        MavenProject mp3 = mock( MavenProject.class );
277        when( mp3.getParent() ).thenReturn( parent );
278        when( mp3.getGroupId() ).thenReturn( "org.apache.enforcer" );
279        when( mp3.getArtifactId() ).thenReturn( "m2" );
280        when( mp3.getVersion() ).thenReturn( "1.0-SNAPSHOT" );
281        when( mp3.getId() ).thenReturn( "org.apache.enforcer:m2:jar:1.0-SNAPSHOT" );
282        when( mp3.getDependencies() ).thenReturn( Collections.<Dependency>emptyList() );
283        return mp3;
284    }
285
286    private MavenProject createProjectChild1( MavenProject parent )
287    {
288        MavenProject mp2 = mock( MavenProject.class );
289        when( mp2.getParent() ).thenReturn( parent );
290        when( mp2.getGroupId() ).thenReturn( "org.apache.enforcer" );
291        when( mp2.getArtifactId() ).thenReturn( "m1" );
292        when( mp2.getVersion() ).thenReturn( "1.0-SNAPSHOT" );
293        when( mp2.getId() ).thenReturn( "org.apache.enforcer:m1:jar:1.0-SNAPSHOT" );
294        when( mp2.getDependencies() ).thenReturn( Collections.<Dependency>emptyList() );
295        return mp2;
296    }
297
298    private MavenProject createCompanyParent()
299    {
300        MavenProject nonReactorParent = mock( MavenProject.class );
301        when( nonReactorParent.getGroupId() ).thenReturn("org.apache.enforcer.parent");
302        when( nonReactorParent.getArtifactId() ).thenReturn("parent");
303        when( nonReactorParent.getVersion() ).thenReturn( "1.1" );
304        when( nonReactorParent.getId() ).thenReturn("org.apache.enforcer.parent:parent:jar:1.1");
305        when( nonReactorParent.getDependencies() ).thenReturn(Collections.<Dependency>emptyList());
306        return nonReactorParent;
307    }
308
309    private MavenProject createProjectParent( MavenProject nonReactorParent )
310    {
311        MavenProject m = createProjectParent();
312        when( m.isExecutionRoot() ).thenReturn( true );
313        when( m.getParent() ).thenReturn( nonReactorParent );
314        return m;
315    }
316
317    private MavenProject createProjectParent()
318    {
319        MavenProject mp1 = mock( MavenProject.class );
320        when( mp1.isExecutionRoot() ).thenReturn( true );
321        when( mp1.getParent() ).thenReturn( null );
322        when( mp1.getGroupId() ).thenReturn( "org.apache.enforcer" );
323        when( mp1.getArtifactId() ).thenReturn( "parent" );
324        when( mp1.getVersion() ).thenReturn( "1.0-SNAPSHOT" );
325        when( mp1.getId() ).thenReturn( "org.apache.enforcer:parent:pom:1.0-SNAPSHOT" );
326        when( mp1.getDependencies() ).thenReturn( Collections.<Dependency>emptyList() );
327        return mp1;
328    }
329
330    private Dependency createDependency( String groupId, String artifactId, String version )
331    {
332        Dependency dep = mock( Dependency.class );
333        when( dep.getGroupId() ).thenReturn( groupId );
334        when( dep.getArtifactId() ).thenReturn( artifactId );
335        when( dep.getVersion() ).thenReturn( version );
336        return dep;
337    }
338}