This is an automated email from the ASF dual-hosted git repository. sjaranowski pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven-project-info-reports-plugin.git
The following commit(s) were added to refs/heads/master by this push: new e51cef8 [MPIR-478] Allow to save avatars images for team report during project build e51cef8 is described below commit e51cef80148c7fc79d53325275589f9f41702ca8 Author: Slawomir Jaranowski <s.jaranow...@gmail.com> AuthorDate: Thu Feb 20 22:49:37 2025 +0100 [MPIR-478] Allow to save avatars images for team report during project build --- pom.xml | 4 +- src/it/team-local-avatars/pom.xml | 82 ++++++++++ .../team-local-avatars/verify.groovy} | 18 +-- .../maven/report/projectinfo/TeamReport.java | 179 +++++++++++++-------- .../projectinfo/avatars/AvatarsProvider.java | 59 +++++++ .../projectinfo/avatars/GravatarProvider.java | 156 ++++++++++++++++++ .../report/projectinfo/avatars/default-avatar.jpg | Bin 0 -> 129 bytes .../maven/report/projectinfo/TeamReportTest.java | 3 + .../projectinfo/avatars/GravatarProviderTest.java | 92 +++++++++++ .../maven/report/projectinfo/stubs/TeamStub.java | 15 ++ 10 files changed, 524 insertions(+), 84 deletions(-) diff --git a/pom.xml b/pom.xml index 3f3732e..cd81f6e 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ under the License. </parent> <artifactId>maven-project-info-reports-plugin</artifactId> - <version>3.8.1-SNAPSHOT</version> + <version>3.9.0-SNAPSHOT</version> <packaging>maven-plugin</packaging> <name>Apache Maven Project Info Reports Plugin</name> @@ -123,7 +123,7 @@ under the License. <sitePluginVersion>3.21.0</sitePluginVersion> <fluidoSkinVersion>2.0.1</fluidoSkinVersion> <checkstyle.violation.ignore>ParameterNumber,MethodLength</checkstyle.violation.ignore> - <project.build.outputTimestamp>2024-10-18T09:42:43Z</project.build.outputTimestamp> + <project.build.outputTimestamp>2025-02-19T22:31:07Z</project.build.outputTimestamp> </properties> <dependencies> diff --git a/src/it/team-local-avatars/pom.xml b/src/it/team-local-avatars/pom.xml new file mode 100644 index 0000000..3b068eb --- /dev/null +++ b/src/it/team-local-avatars/pom.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.maven.plugins.project-info-reports</groupId> + <artifactId>team-local-avatars</artifactId> + <version>1.0-SNAPSHOT</version> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + </properties> + + <developers> + <developer> + <id>one-id</id> + <name>one-name</name> + <email>sjaranow...@apache.org</email> + </developer> + <developer> + <id>two-id</id> + <name>two-name</name> + </developer> + <developer> + <id>three-id</id> + <name>three-name</name> + <email>ema...@ecample.com</email> + </developer> + </developers> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-site-plugin</artifactId> + <version>@sitePluginVersion@</version> + </plugin> + </plugins> + </build> + + <reporting> + <excludeDefaults>true</excludeDefaults> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-project-info-reports-plugin</artifactId> + <version>@project.version@</version> + <configuration> + <externalAvatarImages>false</externalAvatarImages> + </configuration> + <reportSets> + <reportSet> + <reports> + <report>team</report> + </reports> + </reportSet> + </reportSets> + </plugin> + </plugins> + </reporting> +</project> diff --git a/src/test/java/org/apache/maven/report/projectinfo/stubs/TeamStub.java b/src/it/team-local-avatars/verify.groovy similarity index 64% copy from src/test/java/org/apache/maven/report/projectinfo/stubs/TeamStub.java copy to src/it/team-local-avatars/verify.groovy index 63d0e7b..aabeac8 100644 --- a/src/test/java/org/apache/maven/report/projectinfo/stubs/TeamStub.java +++ b/src/it/team-local-avatars/verify.groovy @@ -16,15 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.maven.report.projectinfo.stubs; -/** - * @author <a href="mailto:vincent.sive...@gmail.com">Vincent Siveton</a> - * @version $Id$ - */ -public class TeamStub extends ProjectInfoProjectStub { - @Override - protected String getPOM() { - return "team-plugin-config.xml"; - } -} +def team = new File( basedir, 'target/site/team.html' ).text + +assert team.count('<figure><img src="avatars/90cc13b765c79d2d55ca64388ea2bc5f.jpg" /></figure>') == 1 +assert team.count('<figure><img src="avatars/00000000000000000000000000000000.jpg" /></figure>') == 2 + +assert new File(basedir, 'target/site/avatars/90cc13b765c79d2d55ca64388ea2bc5f.jpg').exists() +assert new File(basedir, 'target/site/avatars/00000000000000000000000000000000.jpg').exists() diff --git a/src/main/java/org/apache/maven/report/projectinfo/TeamReport.java b/src/main/java/org/apache/maven/report/projectinfo/TeamReport.java index 5fb6bda..3b93a1c 100644 --- a/src/main/java/org/apache/maven/report/projectinfo/TeamReport.java +++ b/src/main/java/org/apache/maven/report/projectinfo/TeamReport.java @@ -20,9 +20,9 @@ package org.apache.maven.report.projectinfo; import javax.inject.Inject; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; +import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -32,10 +32,11 @@ import java.util.Properties; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.model.Contributor; import org.apache.maven.model.Developer; -import org.apache.maven.model.Model; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuilder; +import org.apache.maven.report.projectinfo.avatars.AvatarsProvider; import org.apache.maven.reporting.MavenReportException; import org.apache.maven.repository.RepositorySystem; import org.codehaus.plexus.i18n.I18N; @@ -52,19 +53,51 @@ public class TeamReport extends AbstractProjectInfoReport { /** * Shows avatar images for team members that have a) properties/picUrl set b) An avatar at gravatar.com for their * email address - * <p/> - * Future versions of this plugin may implement different strategies for resolving avatar images, possibly - * using different providers. - *<p> - *<strong>Note</strong>: This property will be renamed to {@code tteam.showAvatarImages} in 3.0. + * * @since 2.6 */ @Parameter(property = "teamlist.showAvatarImages", defaultValue = "true") private boolean showAvatarImages; + /** + * Indicate if URL should be used for avatar images. + * <p> + * If set to <code>false</code> images will be downloaded and attached to report during build. + * Local path will be used for images. + * + * @since 3.9.0 + */ + @Parameter(property = "teamlist.externalAvatarImages", defaultValue = "true") + private boolean externalAvatarImages; + + /** + * Base URL for avatar provider. + * + * @since 3.9.0 + */ + @Parameter(property = "teamlist.avatarBaseUrl", defaultValue = "https://www.gravatar.com/avatar/") + private String avatarBaseUrl; + + /** + * Provider name for avatar images. + * <p> + * Report has one implementation for gravatar.com. Users can provide other by implementing {@link AvatarsProvider}. + * + * @since 3.9.0 + */ + @Parameter(property = "teamlist.avatarProviderName", defaultValue = "gravatar") + private String avatarProviderName; + + private final Map<String, AvatarsProvider> avatarsProviders; + @Inject - public TeamReport(RepositorySystem repositorySystem, I18N i18n, ProjectBuilder projectBuilder) { + public TeamReport( + RepositorySystem repositorySystem, + I18N i18n, + ProjectBuilder projectBuilder, + Map<String, AvatarsProvider> avatarsProviders) { super(repositorySystem, i18n, projectBuilder); + this.avatarsProviders = avatarsProviders; } // ---------------------------------------------------------------------- @@ -83,10 +116,55 @@ public class TeamReport extends AbstractProjectInfoReport { } @Override - public void executeReport(Locale locale) { - ProjectTeamRenderer r = - new ProjectTeamRenderer(getSink(), project.getModel(), getI18N(locale), locale, showAvatarImages); - r.render(); + public void executeReport(Locale locale) throws MavenReportException { + + Map<Contributor, String> avatarImages = prepareAvatars(); + + ProjectTeamRenderer renderer = + new ProjectTeamRenderer(getSink(), project, getI18N(locale), locale, showAvatarImages, avatarImages); + renderer.render(); + } + + private Map<Contributor, String> prepareAvatars() throws MavenReportException { + + if (!showAvatarImages) { + return Collections.emptyMap(); + } + + AvatarsProvider avatarsProvider = avatarsProviders.get(avatarProviderName); + if (avatarsProvider == null) { + throw new MavenReportException("No AvatarsProvider found for name " + avatarProviderName); + } + avatarsProvider.setBaseUrl(avatarBaseUrl); + avatarsProvider.setOutputDirectory(getReportOutputDirectory()); + + Map<Contributor, String> result = new HashMap<>(); + try { + prepareContributorAvatars(result, avatarsProvider, project.getDevelopers()); + prepareContributorAvatars(result, avatarsProvider, project.getContributors()); + } catch (IOException e) { + throw new MavenReportException("Unable to load avatar images", e); + } + return result; + } + + private void prepareContributorAvatars( + Map<Contributor, String> avatarImages, + AvatarsProvider avatarsProvider, + List<? extends Contributor> contributors) + throws IOException { + + for (Contributor contributor : contributors) { + + String picSource = contributor.getProperties().getProperty("picUrl"); + if (picSource == null || picSource.isEmpty()) { + picSource = externalAvatarImages + ? avatarsProvider.getAvatarUrl(contributor.getEmail()) + : avatarsProvider.getLocalAvatarPath(contributor.getEmail()); + } + + avatarImages.put(contributor, picSource); + } } /** @@ -130,24 +208,24 @@ public class TeamReport extends AbstractProjectInfoReport { private static final String ID = "id"; - private final Model model; + private final MavenProject mavenProject; private final boolean showAvatarImages; - private final String protocol; + private final Map<Contributor, String> avatarImages; - ProjectTeamRenderer(Sink sink, Model model, I18N i18n, Locale locale, boolean showAvatarImages) { + ProjectTeamRenderer( + Sink sink, + MavenProject mavenProject, + I18N i18n, + Locale locale, + boolean showAvatarImages, + Map<Contributor, String> avatarImages) { super(sink, i18n, locale); - this.model = model; + this.mavenProject = mavenProject; this.showAvatarImages = showAvatarImages; - - // prepare protocol for gravatar - if (model.getUrl() != null && model.getUrl().startsWith("https://")) { - this.protocol = "https"; - } else { - this.protocol = "http"; - } + this.avatarImages = avatarImages; } @Override @@ -164,11 +242,11 @@ public class TeamReport extends AbstractProjectInfoReport { paragraph(getI18nString("intro.description2")); // Developer section - List<Developer> developers = model.getDevelopers(); + List<Developer> developers = mavenProject.getDevelopers(); startSection(getI18nString("developers.title")); - if (isEmpty(developers)) { + if (developers.isEmpty()) { paragraph(getI18nString("nodeveloper")); } else { paragraph(getI18nString("developers.intro")); @@ -191,11 +269,11 @@ public class TeamReport extends AbstractProjectInfoReport { endSection(); // contributors section - List<Contributor> contributors = model.getContributors(); + List<Contributor> contributors = mavenProject.getContributors(); startSection(getI18nString("contributors.title")); - if (isEmpty(contributors)) { + if (contributors.isEmpty()) { paragraph(getI18nString("nocontributor")); } else { paragraph(getI18nString("contributors.intro")); @@ -223,17 +301,9 @@ public class TeamReport extends AbstractProjectInfoReport { sink.tableRow(); if (headersMap.get(IMAGE) == Boolean.TRUE && showAvatarImages) { - Properties properties = member.getProperties(); - String picUrl = properties.getProperty("picUrl"); - if (picUrl == null || picUrl.isEmpty()) { - picUrl = getGravatarUrl(member.getEmail()); - } - if (picUrl == null || picUrl.isEmpty()) { - picUrl = getSpacerGravatarUrl(); - } sink.tableCell(); sink.figure(); - sink.figureGraphics(picUrl); + sink.figureGraphics(avatarImages.get(member)); sink.figure_(); sink.tableCell_(); } @@ -288,35 +358,6 @@ public class TeamReport extends AbstractProjectInfoReport { sink.tableRow_(); } - private static final String AVATAR_SIZE = "s=60"; - - private String getSpacerGravatarUrl() { - return protocol + "://www.gravatar.com/avatar/00000000000000000000000000000000?d=blank&f=y&" + AVATAR_SIZE; - } - - private String getGravatarUrl(String email) { - if (email == null) { - return null; - } - email = StringUtils.trim(email); - email = email.toLowerCase(); - MessageDigest md; - try { - md = MessageDigest.getInstance("MD5"); - md.update(email.getBytes()); - byte[] byteData = md.digest(); - StringBuilder sb = new StringBuilder(); - final int lowerEightBitsOnly = 0xff; - for (byte aByteData : byteData) { - sb.append(Integer.toString((aByteData & lowerEightBitsOnly) + 0x100, 16) - .substring(1)); - } - return protocol + "://www.gravatar.com/avatar/" + sb.toString() + "?d=mm&" + AVATAR_SIZE; - } catch (NoSuchAlgorithmException e) { - return null; - } - } - private String[] getRequiredContrHeaderArray(Map<String, Boolean> requiredHeaders) { List<String> requiredArray = new ArrayList<>(); String image = getI18nString("contributors.image"); @@ -461,7 +502,7 @@ public class TeamReport extends AbstractProjectInfoReport { if (StringUtils.isNotEmpty(unit.getOrganizationUrl())) { requiredHeaders.put(ORGANIZATION_URL, Boolean.TRUE); } - if (!isEmpty(unit.getRoles())) { + if (!unit.getRoles().isEmpty()) { requiredHeaders.put(ROLES, Boolean.TRUE); } if (StringUtils.isNotEmpty(unit.getTimezone())) { @@ -494,9 +535,5 @@ public class TeamReport extends AbstractProjectInfoReport { sink.tableCell_(); } - - private static boolean isEmpty(List<?> list) { - return (list == null) || list.isEmpty(); - } } } diff --git a/src/main/java/org/apache/maven/report/projectinfo/avatars/AvatarsProvider.java b/src/main/java/org/apache/maven/report/projectinfo/avatars/AvatarsProvider.java new file mode 100644 index 0000000..c9c9975 --- /dev/null +++ b/src/main/java/org/apache/maven/report/projectinfo/avatars/AvatarsProvider.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.report.projectinfo.avatars; + +import java.io.File; +import java.io.IOException; + +/** + * Avatar provider API. + */ +public interface AvatarsProvider { + + /** + * Set a base URL for provider + * + * @param baseUrl for provider + */ + void setBaseUrl(String baseUrl); + + /** + * Set site output directory. Used to store avatar images in project. + * + * @param outputDirectory a site output directory + */ + void setOutputDirectory(File outputDirectory); + + /** + * Return a URL for avatar image. + * + * @param email email address for gravatar image + * @return a URL for avatar image + */ + String getAvatarUrl(String email); + + /** + * Return a local path to downloaded avatar image. + * + * @param email email address for gravatar image + * @return a local avatar path + * @throws IOException if problem with image downloading + */ + String getLocalAvatarPath(String email) throws IOException; +} diff --git a/src/main/java/org/apache/maven/report/projectinfo/avatars/GravatarProvider.java b/src/main/java/org/apache/maven/report/projectinfo/avatars/GravatarProvider.java new file mode 100644 index 0000000..d3b5405 --- /dev/null +++ b/src/main/java/org/apache/maven/report/projectinfo/avatars/GravatarProvider.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.report.projectinfo.avatars; + +import javax.inject.Named; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Locale; + +import org.codehaus.plexus.util.IOUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provider for user avatar from gravatar.com + * <p> + * <a href="https://docs.gravatar.com/api/avatars/images/">Gravatar API</a> + */ +@Named("gravatar") +class GravatarProvider implements AvatarsProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(GravatarProvider.class); + + private static final String AVATAR_SIZE = "s=60"; + + private static final String AVATAR_DIRECTORY = "avatars"; + + private static final String AVATAR_DEFAULT_FILE_NAME = "00000000000000000000000000000000.jpg"; + + private String baseUrl = "https://www.gravatar.com/avatar/"; + + private Path outputDirectory; + + @Override + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/"; + } + + @Override + public void setOutputDirectory(File outputDirectory) { + this.outputDirectory = outputDirectory.toPath(); + } + + public String getAvatarUrl(String email) { + return getAvatarUrl(email, "blank"); + } + + private String getAvatarUrl(String email, String defaultAvatar) { + if (email == null || email.isEmpty()) { + return getSpacerGravatarUrl(); + } + + try { + email = email.trim().toLowerCase(Locale.ROOT); + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(email.getBytes()); + byte[] byteData = md.digest(); + StringBuilder sb = new StringBuilder(); + final int lowerEightBitsOnly = 0xff; + for (byte aByteData : byteData) { + sb.append(Integer.toString((aByteData & lowerEightBitsOnly) + 0x100, 16) + .substring(1)); + } + return baseUrl + sb + ".jpg?d=" + defaultAvatar + "&" + AVATAR_SIZE; + } catch (NoSuchAlgorithmException e) { + LOGGER.warn("Error while getting MD5 hash, use default image: {}", e.getMessage()); + return getSpacerGravatarUrl(); + } + } + + @Override + public String getLocalAvatarPath(String email) throws IOException { + // use 404 http status for not existing avatars + String avatarUrl = getAvatarUrl(email, "404"); + try { + URL url = new URI(avatarUrl).toURL(); + Path name = Paths.get(url.getPath()).getFileName(); + if (AVATAR_DEFAULT_FILE_NAME.equals(name.toString())) { + copyDefault(); + } else { + copyUrl(url, outputDirectory.resolve(AVATAR_DIRECTORY).resolve(name)); + } + return AVATAR_DIRECTORY + "/" + name; + } catch (URISyntaxException | IOException e) { + if (e instanceof FileNotFoundException) { + LOGGER.debug( + "Error while getting external avatar url for: {}, use default image: {}:{}", + email, + e.getClass().getName(), + e.getMessage()); + } else { + LOGGER.warn( + "Error while getting external avatar url for: {}, use default image: {}:{}", + email, + e.getClass().getName(), + e.getMessage()); + } + copyDefault(); + return AVATAR_DIRECTORY + "/" + AVATAR_DEFAULT_FILE_NAME; + } + } + + private String getSpacerGravatarUrl() { + return baseUrl + AVATAR_DEFAULT_FILE_NAME + "?d=blank&f=y&" + AVATAR_SIZE; + } + + private void copyUrl(URL url, Path outputPath) throws IOException { + if (!Files.exists(outputPath)) { + Files.createDirectories(outputPath.getParent()); + try (InputStream in = url.openStream(); + OutputStream out = Files.newOutputStream(outputPath)) { + LOGGER.debug("Copying URL {} to {}", url, outputPath); + IOUtil.copy(in, out); + } + } + } + + private void copyDefault() throws IOException { + Path outputPath = outputDirectory.resolve(AVATAR_DIRECTORY).resolve(AVATAR_DEFAULT_FILE_NAME); + if (!Files.exists(outputPath)) { + Files.createDirectories(outputPath.getParent()); + try (InputStream in = getClass().getResourceAsStream("default-avatar.jpg"); + OutputStream out = Files.newOutputStream(outputPath)) { + IOUtil.copy(in, out); + } + } + } +} diff --git a/src/main/resources/org/apache/maven/report/projectinfo/avatars/default-avatar.jpg b/src/main/resources/org/apache/maven/report/projectinfo/avatars/default-avatar.jpg new file mode 100644 index 0000000..a32c67d Binary files /dev/null and b/src/main/resources/org/apache/maven/report/projectinfo/avatars/default-avatar.jpg differ diff --git a/src/test/java/org/apache/maven/report/projectinfo/TeamReportTest.java b/src/test/java/org/apache/maven/report/projectinfo/TeamReportTest.java index e9d9340..409ea0d 100644 --- a/src/test/java/org/apache/maven/report/projectinfo/TeamReportTest.java +++ b/src/test/java/org/apache/maven/report/projectinfo/TeamReportTest.java @@ -50,6 +50,9 @@ public class TeamReportTest extends AbstractProjectInfoTestCase { File pluginXmlFile = new File(getBasedir(), "src/test/resources/plugin-configs/" + "team-plugin-config.xml"); AbstractProjectInfoReport mojo = createReportMojo(getGoal(), pluginXmlFile); setVariableValueToObject(mojo, "showAvatarImages", Boolean.TRUE); + setVariableValueToObject(mojo, "externalAvatarImages", Boolean.TRUE); + setVariableValueToObject(mojo, "avatarProviderName", "gravatar"); + setVariableValueToObject(mojo, "avatarBaseUrl", "https://www.gravatar.com/avatar/"); generateReport(mojo, pluginXmlFile); assertTrue("Test html generated", getGeneratedReport("team.html").exists()); diff --git a/src/test/java/org/apache/maven/report/projectinfo/avatars/GravatarProviderTest.java b/src/test/java/org/apache/maven/report/projectinfo/avatars/GravatarProviderTest.java new file mode 100644 index 0000000..f3c91b4 --- /dev/null +++ b/src/test/java/org/apache/maven/report/projectinfo/avatars/GravatarProviderTest.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.report.projectinfo.avatars; + +import java.io.File; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class GravatarProviderTest { + + @Rule + public TemporaryFolder tmpFolder = new TemporaryFolder(); + + @Test + public void urlShouldBeCorrect() { + GravatarProvider gravatarProvider = new GravatarProvider(); + gravatarProvider.setBaseUrl("https://www.gravatar.com/avatar"); + String externalAvatarUrl = gravatarProvider.getAvatarUrl("em...@example.com"); + + assertEquals( + "https://www.gravatar.com/avatar/5658ffccee7f0ebfda2b226238b1eb6e.jpg?d=blank&s=60", externalAvatarUrl); + } + + @Test + public void urlForEmptyEmailShouldBeCorrect() { + GravatarProvider gravatarProvider = new GravatarProvider(); + gravatarProvider.setBaseUrl("https://www.gravatar.com/avatar"); + + String externalAvatarUrl = gravatarProvider.getAvatarUrl(null); + + assertEquals( + "https://www.gravatar.com/avatar/00000000000000000000000000000000.jpg?d=blank&f=y&s=60", + externalAvatarUrl); + + externalAvatarUrl = gravatarProvider.getAvatarUrl(""); + + assertEquals( + "https://www.gravatar.com/avatar/00000000000000000000000000000000.jpg?d=blank&f=y&s=60", + externalAvatarUrl); + } + + @Test + public void localAvatarPathShouldBeCorrect() throws Exception { + GravatarProvider gravatarProvider = new GravatarProvider(); + gravatarProvider.setBaseUrl("https://www.gravatar.com/avatar"); + gravatarProvider.setOutputDirectory(tmpFolder.getRoot()); + String localAvatarUrl = gravatarProvider.getLocalAvatarPath("sjaranow...@apache.org"); + assertEquals("avatars/90cc13b765c79d2d55ca64388ea2bc5f.jpg", localAvatarUrl); + assertTrue(new File(tmpFolder.getRoot(), "avatars/90cc13b765c79d2d55ca64388ea2bc5f.jpg").exists()); + } + + @Test + public void localAvatarPathShouldHaveDefaultForNotExisting() throws Exception { + GravatarProvider gravatarProvider = new GravatarProvider(); + gravatarProvider.setBaseUrl("https://www.gravatar.com/avatar"); + gravatarProvider.setOutputDirectory(tmpFolder.getRoot()); + String localAvatarUrl = gravatarProvider.getLocalAvatarPath("t...@example.com"); + assertEquals("avatars/00000000000000000000000000000000.jpg", localAvatarUrl); + assertTrue(new File(tmpFolder.getRoot(), "avatars/00000000000000000000000000000000.jpg").exists()); + } + + @Test + public void localAvatarPathShouldBeCorrectForDefault() throws Exception { + GravatarProvider gravatarProvider = new GravatarProvider(); + gravatarProvider.setBaseUrl("https://www.gravatar.com/avatar"); + gravatarProvider.setOutputDirectory(tmpFolder.getRoot()); + String localAvatarUrl = gravatarProvider.getLocalAvatarPath(null); + assertEquals("avatars/00000000000000000000000000000000.jpg", localAvatarUrl); + assertTrue(new File(tmpFolder.getRoot(), "avatars/00000000000000000000000000000000.jpg").exists()); + } +} diff --git a/src/test/java/org/apache/maven/report/projectinfo/stubs/TeamStub.java b/src/test/java/org/apache/maven/report/projectinfo/stubs/TeamStub.java index 63d0e7b..bc41f1a 100644 --- a/src/test/java/org/apache/maven/report/projectinfo/stubs/TeamStub.java +++ b/src/test/java/org/apache/maven/report/projectinfo/stubs/TeamStub.java @@ -18,6 +18,11 @@ */ package org.apache.maven.report.projectinfo.stubs; +import java.util.List; + +import org.apache.maven.model.Contributor; +import org.apache.maven.model.Developer; + /** * @author <a href="mailto:vincent.sive...@gmail.com">Vincent Siveton</a> * @version $Id$ @@ -27,4 +32,14 @@ public class TeamStub extends ProjectInfoProjectStub { protected String getPOM() { return "team-plugin-config.xml"; } + + @Override + public List<Contributor> getContributors() { + return getModel().getContributors(); + } + + @Override + public List<Developer> getDevelopers() { + return getModel().getDevelopers(); + } }