diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 4bf9282a..8b0516ee 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -16,10 +16,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'temurin' cache: maven - name: Build with Maven diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index 7cef4c14..c81a0859 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -4,17 +4,17 @@ on: push: branches: [ main ] pull_request: - branches: [ main ] + branches: [ feature/* ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'temurin' cache: maven - name: Analyze with SonarCloud diff --git a/README.md b/README.md index a25e2a6d..25fdbbf3 100644 --- a/README.md +++ b/README.md @@ -216,13 +216,40 @@ Dependency-Track, so this has no default to allow for blank values. **Note:** If the parent cannot be found on the Dependency-Track server, the BOM upload will not be attempted in order to prevent a project being incorrectly created or updated the server. -| Property | Required | Default Value | Example Values | -|-------------------|----------|------------------------|---------------------------| -| bomLocation | false | target/bom.xml | target/custom-bom.xml | -| updateProjectInfo | false | false | false | -| updateParent | false | false | true | -| parentName | false | ${project.parent.name} | my-name-override | -| parentVersion | false | | ${project.parent.version} | +| Property | Required | Default Value | Example Values | +|----------------------|----------|------------------------|---------------------------| +| bomLocation | false | target/bom.xml | target/custom-bom.xml | +| updateProjectInfo | false | false | false | +| updateParent | false | false | true | +| parentName | false | ${project.parent.name} | my-name-override | +| parentVersion | false | | ${project.parent.version} | +| isLatest | false | false | true | +| projectTags[].name | false | false | tag1 | + +The `isLatest` option sets the flag on the project to indicate that it is the latest version. + +The `projectTags` option allows for tags to be added to a project. This adds project tags only, and doesn't reconcile +the tags on the remote server, so if they are removed from the list or modified, they will need to be removed or +modified on the server to reflect the new state. + +Example: + +```xml + + upload-bom + verify + + upload-bom + + + true + true + + tag1 + + + +``` ### Get Project Findings After a BOM upload, the best way to determine if there are any vulnerabilities is to use the `findings` goal which is diff --git a/pom.xml b/pom.xml index 76bc9fe6..2fa650c5 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ io.github.pmckeown dependency-track-maven-plugin - 1.7.1 + 1.7.2-SNAPSHOT maven-plugin Dependency Track Maven Plugin @@ -65,8 +65,8 @@ UTF-8 - 1.8 - 1.8 + 17 + 17 3.9.5 @@ -80,17 +80,17 @@ com.konghq unirest-objectmapper-jackson - 3.14.2 + 3.14.5 com.fasterxml.jackson.core jackson-core - 2.15.2 + 2.17.2 com.fasterxml.jackson.core jackson-databind - 2.14.2 + 2.17.2 org.apache.commons @@ -163,7 +163,7 @@ org.cyclonedx cyclonedx-core-java - 7.3.2 + 9.0.4 @@ -507,6 +507,10 @@ true + true + + dog-food + diff --git a/src/main/java/io/github/pmckeown/dependencytrack/ResourceConstants.java b/src/main/java/io/github/pmckeown/dependencytrack/ResourceConstants.java index 723a67a5..f0929946 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/ResourceConstants.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/ResourceConstants.java @@ -9,7 +9,7 @@ public final class ResourceConstants { public static final String V1_BOM = "/api/v1/bom"; public static final String V1_BOM_TOKEN_UUID = "/api/v1/bom/token/{uuid}"; - public static final String V1_PROJECT = "/api/v1/project?limit=1000000&offset=0"; + public static final String V1_PROJECT_LOOKUP = "/api/v1/project/lookup"; public static final String V1_PROJECT_UUID = "/api/v1/project/{uuid}"; public static final String V1_FINDING_PROJECT_UUID = "/api/v1/finding/project/{uuid}"; public static final String V1_METRICS_PROJECT_UUID_CURRENT = "/api/v1/metrics/project/{uuid}/current"; diff --git a/src/main/java/io/github/pmckeown/dependencytrack/bom/BomParser.java b/src/main/java/io/github/pmckeown/dependencytrack/bom/BomParser.java index c39e3736..b1dc2ca6 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/bom/BomParser.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/bom/BomParser.java @@ -4,14 +4,14 @@ import io.github.pmckeown.util.Logger; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.BOMInputStream; -import org.cyclonedx.BomParserFactory; + import org.cyclonedx.model.Bom; import org.cyclonedx.model.Component; +import org.cyclonedx.parsers.BomParserFactory; import javax.inject.Inject; import javax.inject.Singleton; import java.io.File; -import java.io.FileInputStream; import java.util.Optional; /** @@ -41,11 +41,11 @@ public BomParser(Logger logger) { */ public Optional getProjectInfo(File bomFile) { if (!bomFile.canRead()) { + logger.warn("Can not read bom {}", bomFile); return Optional.empty(); } Bom bom; - try { - BOMInputStream bis = new BOMInputStream(new FileInputStream(bomFile), false); + try (BOMInputStream bis = BOMInputStream.builder().setFile(bomFile).setInclude(false).get()) { byte[] bytes = IOUtils.toByteArray(bis); bom = BomParserFactory.createParser(bytes).parse(bytes); } catch (Exception ex) { diff --git a/src/main/java/io/github/pmckeown/dependencytrack/project/Project.java b/src/main/java/io/github/pmckeown/dependencytrack/project/Project.java index ec50b013..cb3f0639 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/project/Project.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/project/Project.java @@ -4,6 +4,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.github.pmckeown.dependencytrack.Item; import io.github.pmckeown.dependencytrack.metrics.Metrics; + +import java.util.List; + import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -16,14 +19,22 @@ public class Project extends Item { private String name; private String version; private Metrics metrics; + private boolean isLatest; + private List tags; @JsonCreator - public Project(@JsonProperty("uuid") String uuid, @JsonProperty("name") String name, - @JsonProperty("version") String version, @JsonProperty("metrics") Metrics metrics) { + public Project(@JsonProperty("uuid") String uuid, + @JsonProperty("name") String name, + @JsonProperty("version") String version, + @JsonProperty("metrics") Metrics metrics, + @JsonProperty("isLatest") boolean isLatest, + @JsonProperty("tags") List tags) { super(uuid); this.name = name; this.version = version; this.metrics = metrics; + this.isLatest = isLatest; + this.tags = tags; } public String getName() { @@ -38,6 +49,14 @@ public Metrics getMetrics() { return metrics; } + public boolean isLatest() { + return isLatest; + } + + public List getTags() { + return tags; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); diff --git a/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectAction.java b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectAction.java index 3519dad1..a4dc875b 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectAction.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectAction.java @@ -6,13 +6,16 @@ import io.github.pmckeown.dependencytrack.bom.BomParser; import io.github.pmckeown.util.Logger; import kong.unirest.UnirestException; -import org.apache.commons.lang3.StringUtils; import javax.inject.Inject; import javax.inject.Singleton; import java.io.File; +import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; import static java.lang.String.format; @@ -33,21 +36,15 @@ public ProjectAction(ProjectClient projectClient, BomParser bomParser, Logger lo public Project getProject(String projectName, String projectVersion) throws DependencyTrackException { try { - Response> response = projectClient.getProjects(); + Response response = projectClient.getProject(projectName, projectVersion); if (response.isSuccess()) { - Optional> body = response.getBody(); + Optional body = response.getBody(); if (body.isPresent()) { - Optional project = findProject(body.get(), projectName, projectVersion); - - if (project.isPresent()) { - return project.get(); - } else { - throw new DependencyTrackException( - format("Requested project not found: %s-%s", projectName, projectVersion)); - } + return body.get(); } else { - throw new DependencyTrackException("No projects found on server."); + throw new DependencyTrackException( + format("Requested project not found: %s-%s", projectName, projectVersion)); } } else { logger.error("Failed to list projects with error from server: " + response.getStatusText()); @@ -59,17 +56,33 @@ public Project getProject(String projectName, String projectVersion) throws Depe } public boolean updateProject(Project project, UpdateRequest updateReq) throws DependencyTrackException { + return updateProject(project, updateReq, Collections.emptySet()); + } + + public boolean updateProject(Project project, UpdateRequest updateReq, Set projectTags) throws DependencyTrackException { ProjectInfo info = null; if (updateReq.hasBomLocation()) { logger.info("Project info will be updated"); Optional optInfo = bomParser.getProjectInfo(new File(updateReq.getBomLocation())); if (optInfo.isPresent()) { info = optInfo.get(); + info.setIsLatest(Boolean.valueOf(project.isLatest())); } else { logger.warn("Could not create ProjectInfo from bom at location: %s", updateReq.getBomLocation()); return false; } } + if (projectTags != null && !projectTags.isEmpty()) { + if (info == null) { + info = new ProjectInfo(); + } + if (project.getTags() != null && !project.getTags().isEmpty()) { + logger.info("Merging Project Tags"); + info.setTags(mergeTags(project.getTags(), projectTags)); + } else { + info.setTags(projectTags.stream().map(ProjectTag::new).collect(Collectors.toList())); + } + } if (updateReq.hasParent()) { logger.info("Project parent will be updated"); @@ -115,10 +128,19 @@ boolean deleteProject(Project project) throws DependencyTrackException { } } - private Optional findProject(List projects, String projectName, String projectVersion) { - // The project version may be null from the Dependency-Track server - return projects.stream() - .filter(project -> projectName.equals(project.getName()) && StringUtils.equals(projectVersion, project.getVersion())) - .findFirst(); + private List mergeTags(List existingTags, Set mavenTags) { + List projectTags = new LinkedList<>(existingTags); + for (String mavenTag : mavenTags) { + boolean exists = false; + for (ProjectTag projectTag : projectTags) { + if (projectTag.getName().equals(mavenTag)) { + exists = true; + } + } + if (!exists) { + projectTags.add(new ProjectTag(mavenTag)); + } + } + return projectTags; } } diff --git a/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectClient.java b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectClient.java index 46e9ddf1..711c92c5 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectClient.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectClient.java @@ -8,11 +8,10 @@ import javax.inject.Inject; import javax.inject.Singleton; -import java.util.List; import java.util.Optional; -import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT; import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT_UUID; +import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT_LOOKUP; import static kong.unirest.Unirest.*; /** @@ -32,18 +31,19 @@ public ProjectClient(CommonConfig commonConfig) { this.commonConfig = commonConfig; } - public Response> getProjects() { - HttpResponse> httpResponse = get(commonConfig.getDependencyTrackBaseUrl() + V1_PROJECT) - .header(X_API_KEY, commonConfig.getApiKey()) - .asObject(new GenericType>(){}); - - Optional> body; + public Response getProject(String projectName, String projectVersion) { + HttpResponse httpResponse = get(commonConfig.getDependencyTrackBaseUrl() + V1_PROJECT_LOOKUP) + .queryString("name", projectName) + .queryString("version", projectVersion) + .header(X_API_KEY, commonConfig.getApiKey()) + .asObject(new GenericType() { + }); + Optional body; if (httpResponse.isSuccess()) { body = Optional.of(httpResponse.getBody()); } else { body = Optional.empty(); } - return new Response<>(httpResponse.getStatus(), httpResponse.getStatusText(), httpResponse.isSuccess(), body); } diff --git a/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectInfo.java b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectInfo.java index b36a0280..6285fb2f 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectInfo.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectInfo.java @@ -1,6 +1,9 @@ package io.github.pmckeown.dependencytrack.project; import io.github.pmckeown.dependencytrack.Item; + +import java.util.List; + import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -18,7 +21,9 @@ public class ProjectInfo { private String purl; private String cpe; private String swidTagId; + private Boolean isLatest; private Item parent; + private List tags; public String getAuthor() { return author; @@ -92,6 +97,22 @@ public void setParent(Item parent) { this.parent = parent; } + public Boolean getIsLatest() { + return isLatest; + } + + public void setIsLatest(Boolean isLatest) { + this.isLatest = isLatest; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); diff --git a/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectTag.java b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectTag.java new file mode 100644 index 00000000..8312bae1 --- /dev/null +++ b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectTag.java @@ -0,0 +1,43 @@ +package io.github.pmckeown.dependencytrack.project; + +import java.util.Objects; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ProjectTag { + + private final String name; + + public ProjectTag(@JsonProperty("name") String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public int hashCode() { + return Objects.hash(name); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ProjectTag other = (ProjectTag) obj; + return Objects.equals(name, other.name); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} \ No newline at end of file diff --git a/src/main/java/io/github/pmckeown/dependencytrack/score/ScoreAction.java b/src/main/java/io/github/pmckeown/dependencytrack/score/ScoreAction.java index 43c4c7f5..b77a3940 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/score/ScoreAction.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/score/ScoreAction.java @@ -11,7 +11,6 @@ import javax.inject.Inject; import javax.inject.Singleton; -import java.util.List; import java.util.Optional; import static io.github.pmckeown.dependencytrack.Constants.DELIMITER; @@ -41,9 +40,9 @@ public ScoreAction(ProjectClient projectClient, MetricsAction metricsAction, Com Integer determineScore(Integer inheritedRiskScoreThreshold) throws DependencyTrackException { try { - Response> response = projectClient.getProjects(); + Response response = projectClient.getProject(commonConfig.getProjectName(), commonConfig.getProjectVersion()); - Optional> body = response.getBody(); + Optional body = response.getBody(); if (response.isSuccess() && body.isPresent()) { return generateResult(body.get(), inheritedRiskScoreThreshold); } else { @@ -55,25 +54,13 @@ Integer determineScore(Integer inheritedRiskScoreThreshold) throws DependencyTra } } - private Integer generateResult(List projects, Integer inheritedRiskScoreThreshold) + private Integer generateResult(Project project, Integer inheritedRiskScoreThreshold) throws DependencyTrackException { - logger.debug(projects.toString()); - logger.debug("Found %s projects", projects.size()); + Metrics metrics = getMetricsFromProject(project); - Optional projectOptional = findCurrentProject(projects); - if (projectOptional.isPresent()) { - Project project = projectOptional.get(); + printInheritedRiskScore(project, metrics.getInheritedRiskScore(), inheritedRiskScoreThreshold); - Metrics metrics = getMetricsFromProject(project); - - printInheritedRiskScore(project, metrics.getInheritedRiskScore(), inheritedRiskScoreThreshold); - - return metrics.getInheritedRiskScore(); - - } else { - throw new DependencyTrackException(format("Failed to find project on server: Project: %s, Version: %s", - commonConfig.getProjectName(), commonConfig.getProjectVersion())); - } + return metrics.getInheritedRiskScore(); } private Metrics getMetricsFromProject(Project project) throws DependencyTrackException { @@ -102,18 +89,4 @@ private void printInheritedRiskScore(Project project, int inheritedRiskScore, In } logger.info(DELIMITER); } - - private Optional findCurrentProject(List projects) { - logger.debug("Searching for project using Name: [%s] and Version [%s]", - commonConfig.getProjectName(), commonConfig.getProjectVersion()); - - // Output each project when debug is enabled - projects.forEach(project -> logger.debug(project.toString())); - - return projects.stream() - .parallel() - .filter(project -> project.getName().equals(commonConfig.getProjectName())) - .filter(project -> project.getVersion().equals(commonConfig.getProjectVersion())) - .findFirst(); - } } diff --git a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomAction.java b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomAction.java index b32c248f..3e9e2438 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomAction.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomAction.java @@ -8,7 +8,12 @@ import javax.inject.Inject; import javax.inject.Singleton; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Collections; import java.util.Optional; +import java.util.Set; /** * Handles uploading BOMs @@ -35,17 +40,23 @@ public UploadBomAction(BomClient bomClient, BomEncoder bomEncoder, Poller projectTags) throws DependencyTrackException { logger.info("Project Name: %s", commonConfig.getProjectName()); logger.info("Project Version: %s", commonConfig.getProjectVersion()); + logger.info("Project Tags: %s", StringUtils.join(projectTags, ",")); logger.info("%s", commonConfig.getPollingConfig()); + Optional encodedBomOptional = bomEncoder.encodeBom(bomLocation, logger); if (!encodedBomOptional.isPresent()) { logger.error("No bom.xml could be located at: %s", bomLocation); return false; } - Optional uploadBomResponse = doUpload(encodedBomOptional.get()); + Optional uploadBomResponse = doUpload(encodedBomOptional.get(), isLatest, projectTags); if (commonConfig.getPollingConfig().isEnabled() && uploadBomResponse.isPresent()) { try { @@ -74,11 +85,16 @@ private void pollUntilBomIsProcessed(UploadBomResponse uploadBomResponse) { }); } - private Optional doUpload(String encodedBom) throws DependencyTrackException { + private Optional doUpload(String encodedBom, boolean isLatest, Set projectTags) throws DependencyTrackException { try { - Response response = bomClient.uploadBom(new UploadBomRequest( - commonConfig.getProjectName(), commonConfig.getProjectVersion(), true, encodedBom)); - + Response response = bomClient.uploadBom( + new UploadBomRequest(commonConfig.getProjectName(), + commonConfig.getProjectVersion(), + true, + encodedBom, + isLatest, + projectTags)); + if (response.isSuccess()) { logger.info("BOM uploaded to Dependency Track server"); return response.getBody(); diff --git a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojo.java b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojo.java index f48e33d3..956d4801 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojo.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojo.java @@ -16,6 +16,8 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; +import java.util.Set; + import javax.inject.Inject; /** @@ -53,6 +55,12 @@ public class UploadBomMojo extends AbstractDependencyTrackMojo { @Parameter(property = "dependency-track.parentVersion") private String parentVersion; + @Parameter(property = "dependency-track.isLatest", defaultValue = "false") + private boolean isLatest; + + @Parameter(property = "dependency-track.projectTags") + private Set projectTags; + private final UploadBomAction uploadBomAction; private final MetricsAction metricsAction; @@ -73,7 +81,7 @@ public void performAction() throws MojoExecutionException, MojoFailureException logger.info("Update Project Parent : %s", updateParent); try { - if (!uploadBomAction.upload(getBomLocation())) { + if (!uploadBomAction.upload(getBomLocation(), isLatest, projectTags)) { handleFailure("Bom upload failed"); } Project project = projectAction.getProject(projectName, projectVersion); @@ -86,7 +94,7 @@ public void performAction() throws MojoExecutionException, MojoFailureException updateReq.withParent(getProjectParent(parentName, parentVersion)); } if (updateProjectInfo || updateParent) { - boolean projectUpdated = projectAction.updateProject(project, updateReq); + boolean projectUpdated = projectAction.updateProject(project, updateReq, projectTags); if (!projectUpdated) { logger.error("Failed to update project info"); throw new DependencyTrackException("Failed to update project info"); @@ -151,4 +159,11 @@ void setParentVersion(String parentVersion) { this.parentVersion = parentVersion; } + void setLatest(boolean isLatest) { + this.isLatest = isLatest; + } + + void setProjectTags(Set projectTags) { + this.projectTags = projectTags; + } } diff --git a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomRequest.java b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomRequest.java index 436d20c0..fb7b16a9 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomRequest.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomRequest.java @@ -1,8 +1,14 @@ package io.github.pmckeown.dependencytrack.upload; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; +import io.github.pmckeown.dependencytrack.project.ProjectTag; + /** * Encapsulates the request payload for uploading a BOM * @@ -10,16 +16,24 @@ */ public class UploadBomRequest { - private String projectName; - private String projectVersion; - private boolean autoCreate; - private String base64EncodedBom; + private final String projectName; + private final String projectVersion; + private final boolean autoCreate; + private final String base64EncodedBom; + private final boolean isLatest; + private final List projectTags; - UploadBomRequest(String projectName, String projectVersion, boolean autoCreate, String base64EncodedBom) { + UploadBomRequest(String projectName, String projectVersion, boolean autoCreate, String base64EncodedBom, boolean isLatest, Set projectTags) { this.projectName = projectName; this.projectVersion = projectVersion; this.autoCreate = autoCreate; this.base64EncodedBom = base64EncodedBom; + this.isLatest = isLatest; + if (projectTags == null) { + this.projectTags = null; + } else { + this.projectTags = projectTags.stream().map(ProjectTag::new).collect(Collectors.toList()); + } } public String getProjectName() { @@ -34,10 +48,24 @@ public boolean isAutoCreate() { return autoCreate; } + /** + * TODO: Change method name to IsisLatest, when switching to post upload request + * + * @return + */ + public boolean isIsLatestProjectVersion() { + return isLatest; + } + public String getBom() { return base64EncodedBom; } + public List getProjectTags() { + return projectTags; + } + + @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/ObjectMapperFactoryTest.java b/src/test/java/io/github/pmckeown/dependencytrack/ObjectMapperFactoryTest.java index e9da3b71..0ba83f01 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/ObjectMapperFactoryTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/ObjectMapperFactoryTest.java @@ -8,6 +8,7 @@ import org.junit.Test; import java.io.File; +import java.nio.charset.StandardCharsets; import java.util.List; import static org.junit.Assert.assertNotNull; @@ -19,7 +20,7 @@ public void thatUnknownPropertiesAreIgnoredWhenDeserializingJson() throws Except JacksonObjectMapper om = new JacksonObjectMapper(ObjectMapperFactory.relaxedObjectMapper()); List projects = om.readValue(IOUtils.toString(FileUtils.openInputStream( - new File("src/test/resources/__files/api/v1/project/get-all-projects.json"))), + new File("src/test/resources/__files/api/v1/project/get-all-projects.json")), StandardCharsets.UTF_8), new GenericType>(){}); assertNotNull(projects); diff --git a/src/test/java/io/github/pmckeown/dependencytrack/TestResourceConstants.java b/src/test/java/io/github/pmckeown/dependencytrack/TestResourceConstants.java index 1f0a6aba..6fb54dea 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/TestResourceConstants.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/TestResourceConstants.java @@ -4,8 +4,7 @@ public class TestResourceConstants { public static final String V1_METRICS_PROJECT_CURRENT = "/api/v1/metrics/project/(.*)/current"; public static final String V1_METRICS_PROJECT_REFRESH = "/api/v1/metrics/project/(.*)/refresh"; - public static final String V1_PROJECT_UUID = "/api/v1/project/(.*)"; - public static final String V1_PROJECT_WITH_ONE_MILLION_LIMIT = "/api/v1/project?limit=1000000&offset=0"; + public static final String V1_PROJECT_UUID = "/api/v1/project/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"; public static final String V1_BOM_TOKEN_UUID = "/api/v1/bom/token/(.*)"; public static final String V1_FINDING_PROJECT_UUID = "/api/v1/finding/project/(.*)"; public static final String V1_POLICY_VIOLATION_PROJECT_UUID = "/api/v1/violation/project/(.*)"; diff --git a/src/test/java/io/github/pmckeown/dependencytrack/finding/FindingsMojoIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/finding/FindingsMojoIntegrationTest.java index fc4f65c7..60e9156e 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/finding/FindingsMojoIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/finding/FindingsMojoIntegrationTest.java @@ -12,12 +12,12 @@ import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.ok; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static com.github.tomakehurst.wiremock.http.Fault.RANDOM_DATA_THEN_CLOSE; import static io.github.pmckeown.TestMojoLoader.loadFindingsMojo; -import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT; +import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT_LOOKUP; import static io.github.pmckeown.dependencytrack.TestResourceConstants.V1_FINDING_PROJECT_UUID; import static io.github.pmckeown.dependencytrack.TestUtils.asJson; import static io.github.pmckeown.dependencytrack.finding.AnalysisBuilder.anAnalysis; @@ -27,9 +27,6 @@ import static io.github.pmckeown.dependencytrack.finding.Severity.LOW; import static io.github.pmckeown.dependencytrack.finding.Severity.UNASSIGNED; import static io.github.pmckeown.dependencytrack.finding.VulnerabilityBuilder.aVulnerability; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; public class FindingsMojoIntegrationTest extends AbstractDependencyTrackMojoTest { @@ -47,8 +44,8 @@ public void setup() throws Exception { @Test public void thatFindingMojoCanRetrieveFindingsAndPrintThem() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlPathMatching(V1_FINDING_PROJECT_UUID)).willReturn( aResponse().withBody(asJson( aListOfFindings() @@ -60,45 +57,41 @@ public void thatFindingMojoCanRetrieveFindingsAndPrintThem() throws Exception { findingsMojo.execute(); - verify(exactly(1), getRequestedFor(urlEqualTo(V1_PROJECT))); + verify(exactly(1), getRequestedFor(urlPathEqualTo(V1_PROJECT_LOOKUP))); verify(exactly(1), getRequestedFor(urlPathMatching(V1_FINDING_PROJECT_UUID))); } @Test public void thatWhenNoFindingsAreFoundTheMojoDoesNotFail() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlPathMatching(V1_FINDING_PROJECT_UUID)).willReturn(ok())); try { findingsMojo.execute(); - verify(exactly(1), getRequestedFor(urlEqualTo(V1_PROJECT))); + verify(exactly(1), getRequestedFor(urlPathEqualTo(V1_PROJECT_LOOKUP))); verify(exactly(1), getRequestedFor(urlPathMatching(V1_FINDING_PROJECT_UUID))); } catch (Exception ex) { fail("No exception expected"); } } - @Test + @Test(expected = MojoExecutionException.class) public void thatWhenExceptionOccursWhileGettingFindingsAndFailOnErrorIsTrueTheMojoErrors() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlPathMatching(V1_FINDING_PROJECT_UUID)).willReturn(aResponse().withFault(RANDOM_DATA_THEN_CLOSE))); findingsMojo.setFailOnError(true); - try { - findingsMojo.execute(); - fail("Exception expected"); - } catch (Exception ex) { - assertThat(ex, is(instanceOf(MojoExecutionException.class))); - } + findingsMojo.execute(); + fail("Exception expected"); } - @Test + @Test(expected = MojoFailureException.class) public void thatBuildFailsWhenFindingsNumberBreachesDefinedThresholds() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlPathMatching(V1_FINDING_PROJECT_UUID)).willReturn( aResponse().withBody(asJson( aListOfFindings() @@ -110,18 +103,14 @@ public void thatBuildFailsWhenFindingsNumberBreachesDefinedThresholds() throws E findingsMojo.setFindingThresholds(new FindingThresholds(0, 0, 0, 0, 0)); - try { - findingsMojo.execute(); - fail("Exception expected"); - } catch (Exception ex) { - assertThat(ex, is(instanceOf(MojoFailureException.class))); - } + findingsMojo.execute(); + fail("Exception expected"); } @Test public void thatBuildDoesNotFailWhenOnlyUnassignedFindingExists() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlPathMatching(V1_FINDING_PROJECT_UUID)).willReturn( aResponse().withBody(asJson( aListOfFindings() @@ -142,8 +131,8 @@ public void thatBuildDoesNotFailWhenOnlyUnassignedFindingExists() throws Excepti @Test public void thatFindingsIsSkippedWhenSkipIsTrue() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlPathMatching(V1_FINDING_PROJECT_UUID)).willReturn( aResponse().withBody(asJson( aListOfFindings() @@ -157,7 +146,7 @@ public void thatFindingsIsSkippedWhenSkipIsTrue() throws Exception { findingsMojo.execute(); - verify(exactly(0), getRequestedFor(urlEqualTo(V1_PROJECT))); + verify(exactly(0), getRequestedFor(urlPathEqualTo(V1_PROJECT_LOOKUP))); verify(exactly(0), getRequestedFor(urlPathMatching(V1_FINDING_PROJECT_UUID))); } } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojoIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojoIntegrationTest.java index 9f77d110..5856b533 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojoIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojoIntegrationTest.java @@ -4,6 +4,8 @@ import io.github.pmckeown.dependencytrack.AbstractDependencyTrackMojoTest; import io.github.pmckeown.dependencytrack.PollingConfig; import io.github.pmckeown.dependencytrack.ResourceConstants; +import io.github.pmckeown.dependencytrack.project.ProjectBuilder; + import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.junit.Before; @@ -14,19 +16,14 @@ import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static io.github.pmckeown.TestMojoLoader.loadMetricsMojo; -import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT; +import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT_LOOKUP; import static io.github.pmckeown.dependencytrack.TestResourceConstants.V1_METRICS_PROJECT_CURRENT; import static io.github.pmckeown.dependencytrack.TestUtils.asJson; import static io.github.pmckeown.dependencytrack.metrics.MetricsBuilder.aMetrics; -import static io.github.pmckeown.dependencytrack.project.ProjectBuilder.aProject; -import static io.github.pmckeown.dependencytrack.project.ProjectListBuilder.aListOfProjects; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; public class MetricsMojoIntegrationTest extends AbstractDependencyTrackMojoTest { @@ -42,21 +39,21 @@ public void setup() throws Exception { @Test public void thatMetricsCanBeRetrievedForCurrentProject() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); metricsMojo.setProjectName("testName"); metricsMojo.setProjectVersion("99.99"); metricsMojo.execute(); - verify(exactly(1), getRequestedFor(urlEqualTo(ResourceConstants.V1_PROJECT))); + verify(exactly(1), getRequestedFor(urlPathEqualTo(V1_PROJECT_LOOKUP))); } @Test public void thatWhenMetricsAreNotInProjectTheyAreRetrievedExplicitly() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/noMetrics.json"))); stubFor(get(urlPathMatching(V1_METRICS_PROJECT_CURRENT)).willReturn( aResponse().withBodyFile("api/v1/metrics/project/project-metrics.json"))); @@ -66,61 +63,52 @@ public void thatWhenMetricsAreNotInProjectTheyAreRetrievedExplicitly() throws Ex metricsMojo.execute(); - verify(exactly(1), getRequestedFor(urlEqualTo(V1_PROJECT))); + verify(exactly(1), getRequestedFor(urlPathEqualTo(V1_PROJECT_LOOKUP))); verify(exactly(1), getRequestedFor(urlPathMatching(V1_METRICS_PROJECT_CURRENT))); } - @Test + @Test(expected = MojoExecutionException.class) public void thatExceptionIsThrownWhenMetricsCannotBeRetrievedForCurrentProject() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/noMetrics.json"))); stubFor(get(urlPathMatching(V1_METRICS_PROJECT_CURRENT)).willReturn( aResponse().withFault(Fault.MALFORMED_RESPONSE_CHUNK))); metricsMojo.setProjectName("noMetrics"); metricsMojo.setProjectVersion("1.0.0"); metricsMojo.setPollingConfig(new PollingConfig(false, 1, 1)); - - try { - metricsMojo.execute(); - } catch (Exception ex) { - assertThat(ex, is(instanceOf(MojoExecutionException.class))); - } + metricsMojo.setFailOnError(true); + metricsMojo.execute(); } - @Test + @Test(expected = MojoFailureException.class) public void thatAnyCriticalIssuesPresentCanFailTheBuild() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( aResponse().withBody(asJson( - aListOfProjects() - .withProject(aProject() - .withUuid("1234") - .withName("test-project") - .withVersion("1.2.3") - .withMetrics( - aMetrics() - .withCritical(101) - .withHigh(201) - .withMedium(301) - .withLow(401) - .withUnassigned(501))) + ProjectBuilder.aProject() + .withUuid("1234") + .withName("test-project") + .withVersion("1.2.3") + .withMetrics( + aMetrics() + .withCritical(101) + .withHigh(201) + .withMedium(301) + .withLow(401) + .withUnassigned(501)) .build())))); metricsMojo.setProjectName("test-project"); metricsMojo.setProjectVersion("1.2.3"); metricsMojo.setMetricsThresholds(new MetricsThresholds(100, 200, 300, 400, 500)); - try { - metricsMojo.execute(); - fail("MojoFailureException expected"); - } catch (Exception ex) { - assertThat(ex, is(instanceOf(MojoFailureException.class))); - } + metricsMojo.execute(); + fail("MojoFailureException expected"); } @Test public void thatTheMetricsIsSkippedWhenSkipIsTrue() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); metricsMojo.setSkip("true"); metricsMojo.setProjectName("testName"); @@ -128,6 +116,6 @@ public void thatTheMetricsIsSkippedWhenSkipIsTrue() throws Exception { metricsMojo.execute(); - verify(exactly(0), getRequestedFor(urlEqualTo(V1_PROJECT))); + verify(exactly(0), getRequestedFor(urlPathEqualTo(V1_PROJECT_LOOKUP))); } } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/policyviolation/PolicyViolationsMojoIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/policyviolation/PolicyViolationsMojoIntegrationTest.java index 1a28e7c5..18cad777 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/policyviolation/PolicyViolationsMojoIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/policyviolation/PolicyViolationsMojoIntegrationTest.java @@ -11,13 +11,13 @@ import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static com.github.tomakehurst.wiremock.http.Fault.RANDOM_DATA_THEN_CLOSE; import static io.github.pmckeown.TestMojoLoader.loadPolicyMojo; -import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT; +import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT_LOOKUP; import static io.github.pmckeown.dependencytrack.TestResourceConstants.V1_POLICY_VIOLATION_PROJECT_UUID; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; @@ -39,8 +39,8 @@ public void setup() throws Exception { @Test public void thatPolicyMojoCanRetrievePolicyViolationWarningsAndNotFailIfFailOnWarnFalse() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlMatching(V1_POLICY_VIOLATION_PROJECT_UUID)).willReturn( aResponse().withBodyFile("api/v1/violation/project/policy-violation-warnings.json"))); policyMojo.setFailOnWarn(false); @@ -51,8 +51,8 @@ public void thatPolicyMojoCanRetrievePolicyViolationWarningsAndNotFailIfFailOnWa @Test public void thatPolicyMojoCanRetrievePolicyViolationWarningsAndFailIfFailOnWarnTrue() { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlMatching(V1_POLICY_VIOLATION_PROJECT_UUID)).willReturn( aResponse().withBodyFile("api/v1/violation/project/policy-violation-warnings.json"))); policyMojo.setFailOnWarn(true); @@ -69,8 +69,8 @@ public void thatPolicyMojoCanRetrievePolicyViolationWarningsAndFailIfFailOnWarnT @Test public void thatPolicyMojoCanRetrievePolicyViolationFailuresAndFailIfFailOnWarnFalse() { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlMatching(V1_POLICY_VIOLATION_PROJECT_UUID)).willReturn( aResponse().withBodyFile("api/v1/violation/project/policy-violation-failures.json"))); policyMojo.setFailOnWarn(false); @@ -87,8 +87,8 @@ public void thatPolicyMojoCanRetrievePolicyViolationFailuresAndFailIfFailOnWarnF @Test public void thatPolicyMojoCanRetrievePolicyViolationFailuresAndFailIfFailOnWarnTrue() { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlMatching(V1_POLICY_VIOLATION_PROJECT_UUID)).willReturn( aResponse().withBodyFile("api/v1/violation/project/policy-violation-failures.json"))); policyMojo.setFailOnWarn(true); @@ -105,8 +105,8 @@ public void thatPolicyMojoCanRetrievePolicyViolationFailuresAndFailIfFailOnWarnT @Test public void thatWhenExceptionOccursWhileGettingFindingsAndFailOnErrorIsTrueTheMojoErrors() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlPathMatching(V1_POLICY_VIOLATION_PROJECT_UUID)) .willReturn(aResponse().withFault(RANDOM_DATA_THEN_CLOSE))); @@ -122,8 +122,8 @@ public void thatWhenExceptionOccursWhileGettingFindingsAndFailOnErrorIsTrueTheMo @Test public void thatWhenExceptionOccursWhileGettingFindingsAndFailOnErrorIsFalseTheMojoSucceeds() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(get(urlPathMatching(V1_POLICY_VIOLATION_PROJECT_UUID)) .willReturn(aResponse().withFault(RANDOM_DATA_THEN_CLOSE))); @@ -142,7 +142,7 @@ public void thatPolicyViolationsIsSkippedWhenSkipIsTrue() throws Exception { policyMojo.execute(); - verify(exactly(0), getRequestedFor(urlEqualTo(V1_PROJECT))); + verify(exactly(0), getRequestedFor(urlPathEqualTo(V1_PROJECT_LOOKUP))); verify(exactly(0), getRequestedFor(urlPathMatching(V1_POLICY_VIOLATION_PROJECT_UUID))); } } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/project/DeleteProjectMojoIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/project/DeleteProjectMojoIntegrationTest.java index ec8769c8..30a09753 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/project/DeleteProjectMojoIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/project/DeleteProjectMojoIntegrationTest.java @@ -13,11 +13,11 @@ import static com.github.tomakehurst.wiremock.client.WireMock.exactly; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static io.github.pmckeown.TestMojoLoader.loadDeleteProjectMojo; -import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT; +import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT_LOOKUP; import static io.github.pmckeown.dependencytrack.TestResourceConstants.V1_PROJECT_UUID; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; @@ -39,8 +39,8 @@ public void setup() throws Exception { @Test public void thatAProjectCanBeDeleted() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/dependency-track-3.6.json"))); stubFor(delete(urlPathMatching(V1_PROJECT_UUID)).willReturn( aResponse().withStatus(200))); @@ -51,8 +51,8 @@ public void thatAProjectCanBeDeleted() throws Exception { @Test public void thatWhenProjectDeletionFailedAndFailOnErrorFalseThenMojoSucceeds() { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/dependency-track-3.6.json"))); stubFor(delete(urlPathMatching(V1_PROJECT_UUID)).willReturn( aResponse().withStatus(500))); @@ -65,26 +65,21 @@ public void thatWhenProjectDeletionFailedAndFailOnErrorFalseThenMojoSucceeds() { } } - @Test - public void thatWhenProjectDeletionFailedAndFailOnErrorTrueThenMojoFailureExceptionIsThrown() { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + @Test(expected = MojoFailureException.class) + public void thatWhenProjectDeletionFailedAndFailOnErrorTrueThenMojoFailureExceptionIsThrown() throws MojoExecutionException, MojoFailureException { + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(delete(urlPathMatching(V1_PROJECT_UUID)).willReturn( aResponse().withStatus(500))); deleteProjectMojo.setFailOnError(true); - try { - deleteProjectMojo.execute(); - } catch (Exception ex) { - assertThat(ex, is(instanceOf(MojoFailureException.class))); - } + deleteProjectMojo.execute(); } @Test public void thatWhenProjectIsNotFoundDeletionIsNotAttempted() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn(aResponse())); deleteProjectMojo.setProjectName("unknown"); deleteProjectMojo.setProjectVersion("1.2.3-SNAPSHOT"); @@ -99,8 +94,8 @@ public void thatWhenProjectIsNotFoundDeletionIsNotAttempted() throws Exception { @Test public void thatWhenProjectDeleteErrorsAndFailOnErrorTrueThenMojoExecutionExceptionIsThrown() { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(delete(urlPathMatching(V1_PROJECT_UUID)).willReturn( aResponse().withFault(Fault.RANDOM_DATA_THEN_CLOSE))); @@ -115,8 +110,8 @@ public void thatWhenProjectDeleteErrorsAndFailOnErrorTrueThenMojoExecutionExcept @Test public void thatWhenProjectDeleteErrorsAndFailOnErrorFalseThenMojoSucceeds() { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(delete(urlPathMatching(V1_PROJECT_UUID)).willReturn( aResponse().withFault(Fault.RANDOM_DATA_THEN_CLOSE))); @@ -131,8 +126,8 @@ public void thatWhenProjectDeleteErrorsAndFailOnErrorFalseThenMojoSucceeds() { @Test public void thatDeleteIsSkippedWhenSkipIsTrue() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/testName-project.json"))); stubFor(delete(urlPathMatching(V1_PROJECT_UUID)).willReturn( aResponse().withStatus(200))); diff --git a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectActionTest.java b/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectActionTest.java index bb946718..7ff715cd 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectActionTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectActionTest.java @@ -12,9 +12,12 @@ import org.mockito.junit.MockitoJUnitRunner; import java.io.File; -import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Optional; +import java.util.Set; import static io.github.pmckeown.dependencytrack.ResponseBuilder.aSuccessResponse; import static org.hamcrest.CoreMatchers.equalTo; @@ -55,7 +58,7 @@ public class ProjectActionTest { @Test public void thatProjectCanBeRetrievedByNameAndVersion() throws Exception { - doReturn(aSuccessResponse().withBody(aProjectList()).build()).when(projectClient).getProjects(); + doReturn(aSuccessResponse().withBody(project2()).build()).when(projectClient).getProject(anyString(), anyString()); Project project = projectAction.getProject(PROJECT_NAME_2, PROJECT_VERSION_2); @@ -65,7 +68,7 @@ public void thatProjectCanBeRetrievedByNameAndVersion() throws Exception { @Test public void thatExceptionIsThrownWhenConnectionFails() { - doThrow(UnirestException.class).when(projectClient).getProjects(); + doThrow(UnirestException.class).when(projectClient).getProject(anyString(), anyString()); try { projectAction.getProject(PROJECT_NAME_2, PROJECT_VERSION_2); @@ -74,20 +77,16 @@ public void thatExceptionIsThrownWhenConnectionFails() { } } - @Test - public void thatANotFoundResponseResultsInAnException() { - doReturn(aNotFoundResponse()).when(projectClient).getProjects(); + @Test(expected = DependencyTrackException.class) + public void thatANotFoundResponseResultsInAnException() throws DependencyTrackException { + doReturn(aNotFoundResponse()).when(projectClient).getProject(anyString(), anyString()); - try { - projectAction.getProject(PROJECT_NAME_2, PROJECT_VERSION_2); - } catch (Exception ex) { - assertThat(ex, is(instanceOf(DependencyTrackException.class))); - } + projectAction.getProject(PROJECT_NAME_2, PROJECT_VERSION_2); } @Test public void thatNoProjectsAreFoundAnExceptionIsThrown() { - doReturn(aSuccessResponse().build()).when(projectClient).getProjects(); + doReturn(aSuccessResponse().build()).when(projectClient).getProject(anyString(), anyString()); try { projectAction.getProject(PROJECT_NAME_2, PROJECT_VERSION_2); @@ -96,15 +95,11 @@ public void thatNoProjectsAreFoundAnExceptionIsThrown() { } } - @Test - public void thatRequestedProjectCannotBeFoundAnExceptionIsThrown() { - doReturn(aSuccessResponse().withBody(aProjectList()).build()).when(projectClient).getProjects(); + @Test(expected = DependencyTrackException.class) + public void thatRequestedProjectCannotBeFoundAnExceptionIsThrown() throws DependencyTrackException { + doReturn(aSuccessResponse().build()).when(projectClient).getProject(anyString(), anyString()); - try { - projectAction.getProject("missing-project", "unknown-version"); - } catch (Exception ex) { - assertThat(ex, is(instanceOf(DependencyTrackException.class))); - } + projectAction.getProject("missing-project", "unknown-version"); } @Test @@ -171,20 +166,71 @@ public void thatWhenUpdateProjectParentErrorsAnExceptionIsThrown() { } } + @Test + public void thatWhenProjectBomAndIsLatestTrueIsProvidedNoExceptionIsReturned() throws Exception { + doReturn(Optional.of(new ProjectInfo())).when(bomParser).getProjectInfo(any(File.class)); + doReturn(aSuccessResponse().build()).when(projectClient).patchProject(anyString(), any(ProjectInfo.class)); + + UpdateRequest updateReq = new UpdateRequest(); + updateReq.withBomLocation(String.valueOf(new File(BomParser.class.getResource("bom.xml").getPath()))); + assertTrue(projectAction.updateProject(project3(), updateReq)); + } + + @Test + public void thatWhenProjectBomAndIsLatestFalseIsProvidedNoExceptionIsReturned() throws Exception { + doReturn(Optional.of(new ProjectInfo())).when(bomParser).getProjectInfo(any(File.class)); + doReturn(aSuccessResponse().build()).when(projectClient).patchProject(anyString(), any(ProjectInfo.class)); + + UpdateRequest updateReq = new UpdateRequest(); + updateReq.withBomLocation(String.valueOf(new File(BomParser.class.getResource("bom.xml").getPath()))); + assertTrue(projectAction.updateProject(project1(), updateReq)); + } + + @Test + public void thatProjectTagsAreUpdated() throws Exception { + doReturn(aSuccessResponse().build()).when(projectClient).patchProject(anyString(), any(ProjectInfo.class)); + + Set tags = new HashSet<>(); + tags.add("Backend"); + tags.add("Team-1"); + + List existingProjectTags = Collections.emptyList(); + UpdateRequest updateReq = new UpdateRequest(); + assertTrue(projectAction.updateProject(projectWithTags(existingProjectTags), updateReq, tags)); + } + + @Test + public void thatProjectTagsAreUpdatedAndMerged() throws Exception { + doReturn(aSuccessResponse().build()).when(projectClient).patchProject(anyString(), any(ProjectInfo.class)); + + Set tags = new HashSet<>(); + tags.add("Backend"); + tags.add("Team-1"); + + List existingProjectTags = new LinkedList<>(); + existingProjectTags.add(new ProjectTag("Frontend")); + UpdateRequest updateReq = new UpdateRequest(); + assertTrue(projectAction.updateProject(projectWithTags(existingProjectTags), updateReq, tags)); + } + private Response aNotFoundResponse() { return new Response(404, "Not Found", false); } private Project project1() { - return new Project(UUID_2, PROJECT_NAME_2, PROJECT_VERSION_2, null); + return new Project(UUID_2, PROJECT_NAME_2, PROJECT_VERSION_2, null, false, Collections.emptyList()); } private Project project2() { - return new Project(UUID_2, PROJECT_NAME_2, PROJECT_VERSION_2, null); + return new Project(UUID_2, PROJECT_NAME_2, PROJECT_VERSION_2, null, false, Collections.emptyList()); + } + + private Project project3() { + return new Project(UUID_2, PROJECT_NAME_2, PROJECT_VERSION_2, null, true, Collections.emptyList()); } - private List aProjectList() { - return Arrays.asList(project1(), project2()); + private Project projectWithTags(List tags) { + return new Project(UUID_2, PROJECT_NAME_2, PROJECT_VERSION_2, null, false, tags); } } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectBuilder.java b/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectBuilder.java index 7ea68a02..17cd0957 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectBuilder.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectBuilder.java @@ -3,7 +3,10 @@ import io.github.pmckeown.dependencytrack.metrics.Metrics; import io.github.pmckeown.dependencytrack.metrics.MetricsBuilder; +import java.util.List; +import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; public class ProjectBuilder { @@ -11,6 +14,8 @@ public class ProjectBuilder { private String name = "test-project"; private String version = "2.0.0"; private Metrics metrics; + private boolean isLatest; + private List tags; public static ProjectBuilder aProject() { return new ProjectBuilder(); @@ -36,7 +41,17 @@ public ProjectBuilder withMetrics(MetricsBuilder metricsBuilder) { return this; } + public ProjectBuilder withIsLatest(boolean isLatest) { + this.isLatest = isLatest; + return this; + } + + public ProjectBuilder withTags(Set tags) { + this.tags = tags.stream().map(ProjectTag::new).collect(Collectors.toList()); + return this; + } + public Project build() { - return new Project(uuid, name, version, metrics); + return new Project(uuid, name, version, metrics, isLatest, tags); } } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectClientIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectClientIntegrationTest.java index d7ec1bcc..fa0f9330 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectClientIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectClientIntegrationTest.java @@ -7,78 +7,81 @@ import org.junit.Before; import org.junit.Test; -import java.util.Collections; -import java.util.List; - import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.exactly; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.patch; +import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.patchRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static io.github.pmckeown.dependencytrack.TestResourceConstants.V1_PROJECT_UUID; -import static io.github.pmckeown.dependencytrack.TestResourceConstants.V1_PROJECT_WITH_ONE_MILLION_LIMIT; +import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT_LOOKUP; import static io.github.pmckeown.dependencytrack.project.ProjectInfoBuilder.aProjectInfo; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.MatcherAssert.assertThat; public class ProjectClientIntegrationTest extends AbstractDependencyTrackMojoTest { - private static final int COUNT_ALL_PROJECTS = 9; - - private ProjectClient projectClient; - - @Before - public void setUp() { - CommonConfig commonConfig = new CommonConfig(); - commonConfig.setDependencyTrackBaseUrl("http://localhost:" + wireMockRule.port()); - projectClient = new ProjectClient(commonConfig); - } - - @Test - public void thatCallingDependencyTrackWithAHighResponseLimitReturnsAllProjects() { - - stubFor(get(urlEqualTo(V1_PROJECT_WITH_ONE_MILLION_LIMIT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); - - List projects = projectClient.getProjects().getBody().orElse(Collections.emptyList()); - - verify(exactly(1), getRequestedFor(urlEqualTo(V1_PROJECT_WITH_ONE_MILLION_LIMIT))); - assertThat(projects.size(), is(COUNT_ALL_PROJECTS)); - } - - @Test - public void thatProjectInfoUpdateReturnsSuccessWhenServerReturnsSuccess() { - stubFor(patch(urlPathMatching(V1_PROJECT_UUID)).willReturn( - aResponse().withStatus(HttpStatus.OK))); - - Response response = projectClient.patchProject("1234", aProjectInfo().build()); - assertThat(response.isSuccess(), is(equalTo(true))); - verify(exactly(1), patchRequestedFor(urlPathMatching(V1_PROJECT_UUID))); - } - - @Test - public void thatProjectInfoUpdateReturnsSuccessWhenServerReturnsNotModified() { - stubFor(patch(urlPathMatching(V1_PROJECT_UUID)).willReturn( - aResponse().withStatus(HttpStatus.NOT_MODIFIED))); - - Response response = projectClient.patchProject("1234", aProjectInfo().build()); - assertThat(response.isSuccess(), is(equalTo(true))); - verify(exactly(1), patchRequestedFor(urlPathMatching(V1_PROJECT_UUID))); - } - - @Test - public void thatProjectInfoUpdateReturnsFailedWhenServerReturnsTeapot() { - stubFor(patch(urlPathMatching(V1_PROJECT_UUID)).willReturn( - aResponse().withStatus(HttpStatus.IM_A_TEAPOT))); - - Response response = projectClient.patchProject("1234", aProjectInfo().build()); - assertThat(response.isSuccess(), is(equalTo(false))); - verify(exactly(1), patchRequestedFor(urlPathMatching(V1_PROJECT_UUID))); - } + private ProjectClient projectClient; + + @Before + public void setUp() { + CommonConfig commonConfig = new CommonConfig(); + commonConfig.setDependencyTrackBaseUrl("http://localhost:" + wireMockRule.port()); + projectClient = new ProjectClient(commonConfig); + } + + @Test + public void thatProjectInfoUpdateReturnsSuccessWhenServerReturnsSuccess() { + stubFor(patch(urlPathMatching(V1_PROJECT_UUID)).willReturn( + aResponse().withStatus(HttpStatus.OK))); + + Response response = projectClient.patchProject("3b2fa278-6380-4430-b646-a353107e9fbe", aProjectInfo().build()); + assertThat(response.isSuccess(), is(equalTo(true))); + verify(exactly(1), patchRequestedFor(urlPathMatching(V1_PROJECT_UUID))); + } + + @Test + public void thatProjectParsingWorks() { + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse() + .withStatus(HttpStatus.OK) + .withBodyFile("api/v1/project/tags-project.json"))); + + Response response = projectClient.getProject("doesn't matter", "doesn't matter"); + assertThat(response.isSuccess(), is(equalTo(true))); + assertThat(response.getBody().isPresent(), is(equalTo(true))); + Project project = response.getBody().get(); + assertThat(project.getTags(), hasItems(new ProjectTag("backend"), new ProjectTag("Team-1"))); + assertThat(project.getName(), is("tags-project")); + assertThat(project.getVersion(), is("4.6.10")); + assertThat(project.getUuid(), is("8c8fcbd1-b569-4e98-849f-884afef20a2a")); + + verify(exactly(1), getRequestedFor(urlPathMatching(V1_PROJECT_LOOKUP))); + } + + @Test + public void thatProjectInfoUpdateReturnsSuccessWhenServerReturnsNotModified() { + stubFor(patch(urlPathMatching(V1_PROJECT_UUID)).willReturn( + aResponse().withStatus(HttpStatus.NOT_MODIFIED))); + + Response response = projectClient.patchProject("3b2fa278-6380-4430-b646-a353107e9fbe", aProjectInfo().build()); + assertThat(response.isSuccess(), is(equalTo(true))); + verify(exactly(1), patchRequestedFor(urlPathMatching(V1_PROJECT_UUID))); + } + + @Test + public void thatProjectInfoUpdateReturnsFailedWhenServerReturnsTeapot() { + stubFor(patch(urlPathMatching(V1_PROJECT_UUID)).willReturn( + aResponse().withStatus(HttpStatus.IM_A_TEAPOT))); + + Response response = projectClient.patchProject("3b2fa278-6380-4430-b646-a353107e9fbe", aProjectInfo().build()); + assertThat(response.isSuccess(), is(equalTo(false))); + verify(exactly(1), patchRequestedFor(urlPathMatching(V1_PROJECT_UUID))); + } } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectListBuilder.java b/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectListBuilder.java deleted file mode 100644 index 79fbd8f2..00000000 --- a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectListBuilder.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.pmckeown.dependencytrack.project; - -import java.util.ArrayList; -import java.util.List; - -public class ProjectListBuilder { - - private List projects = new ArrayList<>(); - - public static ProjectListBuilder aListOfProjects() { - return new ProjectListBuilder(); - } - - public ProjectListBuilder withProject(ProjectBuilder projectBuilder) { - this.projects.add(projectBuilder.build()); - return this; - } - - public List build() { - return this.projects; - } -} diff --git a/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreActionTest.java b/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreActionTest.java index 75eaecf9..2389caf1 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreActionTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreActionTest.java @@ -8,6 +8,7 @@ import io.github.pmckeown.dependencytrack.project.ProjectClient; import io.github.pmckeown.util.Logger; import kong.unirest.UnirestException; + import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; @@ -17,13 +18,12 @@ import static io.github.pmckeown.dependencytrack.metrics.MetricsBuilder.aMetrics; import static io.github.pmckeown.dependencytrack.project.ProjectBuilder.aProject; import static io.github.pmckeown.dependencytrack.ResponseBuilder.aSuccessResponse; -import static java.util.Collections.singletonList; import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; @@ -34,8 +34,6 @@ public class ScoreActionTest { private static final Integer INHERITED_RISK_SCORE_THRESHOLD = 3; - private static final String PROJECT_VERSION = "projectVersion"; - private static final String PROJECT_NAME = "projectName"; @InjectMocks private ScoreAction scoreAction; @@ -52,52 +50,30 @@ public class ScoreActionTest { @Mock private Logger logger; - @Test - public void thatWhenAnExceptionOccursGettingProjectsThenAnExceptionIsThrown() { - doThrow(UnirestException.class).when(projectClient).getProjects(); - - try { - scoreAction.determineScore(INHERITED_RISK_SCORE_THRESHOLD); - fail("Exception expected"); - } catch (DependencyTrackException ex) { - assertThat(ex, is(instanceOf(DependencyTrackException.class))); - } - } + @Test(expected = DependencyTrackException.class) + public void thatWhenAnExceptionOccursGettingProjectsThenAnExceptionIsThrown() throws DependencyTrackException { + doReturn("ProjectName").when(commonConfig).getProjectName(); + doReturn("ProjectVersion").when(commonConfig).getProjectVersion(); + doThrow(UnirestException.class).when(projectClient).getProject(anyString(), anyString()); - @Test - public void thatWhenNoProjectsAreFoundThenAnExceptionIsThrown() { - doReturn(new Response(404, "Not Found", false)).when(projectClient).getProjects(); - - try { - scoreAction.determineScore(INHERITED_RISK_SCORE_THRESHOLD); - fail("Exception expected"); - } catch (DependencyTrackException ex) { - assertThat(ex, is(instanceOf(DependencyTrackException.class))); - } + scoreAction.determineScore(INHERITED_RISK_SCORE_THRESHOLD); + fail("Exception expected"); } - @Test - public void thatWhenCurrentProjectsIsNotFoundInListThenAnExceptionIsThrown() { - doReturn(aSuccessResponse().withBody( - singletonList( - aProject().withMetrics(aMetrics().withInheritedRiskScore(100)).build() - )).build()).when(projectClient).getProjects(); - doReturn("unknown-project").when(commonConfig).getProjectName(); - doReturn("1.2.3").when(commonConfig).getProjectVersion(); - - try { - scoreAction.determineScore(INHERITED_RISK_SCORE_THRESHOLD); - fail("Exception expected"); - } catch (DependencyTrackException ex) { - assertThat(ex, is(instanceOf(DependencyTrackException.class))); - } + @Test(expected = DependencyTrackException.class) + public void thatWhenNoProjectsAreFoundThenAnExceptionIsThrown() throws DependencyTrackException { + doReturn("ProjectName").when(commonConfig).getProjectName(); + doReturn("ProjectVersion").when(commonConfig).getProjectVersion(); + doReturn(new Response(404, "Not Found", false)).when(projectClient).getProject(anyString(), anyString()); + + scoreAction.determineScore(INHERITED_RISK_SCORE_THRESHOLD); + fail("Exception expected"); } @Test public void thatWhenTheCurrentProjectHasMetricsInItThenTheScoreIsReturned() throws Exception { Project project = aProject().withMetrics(aMetrics().withInheritedRiskScore(100)).build(); - doReturn(aSuccessResponse().withBody( - singletonList(project)).build()).when(projectClient).getProjects(); + doReturn(aSuccessResponse().withBody(project).build()).when(projectClient).getProject(anyString(), anyString()); doReturn(project.getName()).when(commonConfig).getProjectName(); doReturn(project.getVersion()).when(commonConfig).getProjectVersion(); @@ -110,8 +86,7 @@ public void thatWhenTheCurrentProjectHasMetricsInItThenTheScoreIsReturned() thro @Test public void thatWhenTheCurrentProjectHasNoMetricsInItTheyAreRequestedAndThenTheScoreIsReturned() throws Exception { Project project = aProject().build(); - doReturn(aSuccessResponse().withBody( - singletonList(project)).build()).when(projectClient).getProjects(); + doReturn(aSuccessResponse().withBody(project).build()).when(projectClient).getProject(anyString(), anyString()); doReturn(aMetrics().withInheritedRiskScore(100).build()).when(metricsAction).getMetrics( any(Project.class)); doReturn(project.getName()).when(commonConfig).getProjectName(); @@ -126,8 +101,7 @@ public void thatWhenTheCurrentProjectHasNoMetricsInItTheyAreRequestedAndThenTheS @Test public void thatWhenTheCurrentProjectScoreIsZeroThenTheScoreIsReturned() throws Exception { Project project = aProject().build(); - doReturn(aSuccessResponse().withBody( - singletonList(project)).build()).when(projectClient).getProjects(); + doReturn(aSuccessResponse().withBody(project).build()).when(projectClient).getProject(anyString(), anyString()); doReturn(aMetrics().withInheritedRiskScore(0).build()).when(metricsAction).getMetrics( any(Project.class)); doReturn(project.getName()).when(commonConfig).getProjectName(); diff --git a/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreMojoIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreMojoIntegrationTest.java index a2c4d9e1..7ef29fa9 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreMojoIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreMojoIntegrationTest.java @@ -8,7 +8,7 @@ import static com.github.tomakehurst.wiremock.client.WireMock.*; import static io.github.pmckeown.TestMojoLoader.loadScoreMojo; -import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT; +import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT_LOOKUP; import static io.github.pmckeown.dependencytrack.TestResourceConstants.V1_METRICS_PROJECT_CURRENT; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; @@ -29,19 +29,19 @@ public void setup() throws Exception { @Test public void thatAllProjectsCanBeRetrieved() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/dependency-track-3.6.json"))); scoreMojo.execute(); - verify(exactly(1), getRequestedFor(urlEqualTo(V1_PROJECT))); + verify(exactly(1), getRequestedFor(urlPathEqualTo(V1_PROJECT_LOOKUP))); } @Test public void thatARiskScoreHigherThanTheThresholdCausesBuildToFailEvenWithFailOnErrorFalse() throws Exception { // The current project score in the JSON file is 3 - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/dependency-track-3.6.json"))); scoreMojo.setInheritedRiskScoreThreshold(1); scoreMojo.setFailOnError(false); @@ -57,8 +57,8 @@ public void thatARiskScoreHigherThanTheThresholdCausesBuildToFailEvenWithFailOnE @Test public void thatARiskScoreEqualToTheThresholdDoesNothing() throws Exception { // The current project score in the JSON file is 3 - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/dependency-track-3.6.json"))); scoreMojo.setInheritedRiskScoreThreshold(3); @@ -72,8 +72,8 @@ public void thatARiskScoreEqualToTheThresholdDoesNothing() throws Exception { @Test public void thatFailureToGetARiskScoreEqualThrowsAnException() throws Exception { // The current project score in the JSON file is 3 - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/dependency-track-3.6.json"))); scoreMojo.setInheritedRiskScoreThreshold(3); @@ -87,8 +87,8 @@ public void thatFailureToGetARiskScoreEqualThrowsAnException() throws Exception @Test public void thatARiskScoreLowerThanTheThresholdDoesNothing() throws Exception { // The current project score in the JSON file is 3 - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/dependency-track-3.6.json"))); scoreMojo.setInheritedRiskScoreThreshold(999); @@ -102,8 +102,8 @@ public void thatARiskScoreLowerThanTheThresholdDoesNothing() throws Exception { @Test public void thatWhenNoMetricsHaveBeenCalculatedThenTheMetricsAreRetrieved() throws Exception { // The current project score in the JSON file is 3 - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/noMetrics.json"))); stubFor(get(urlPathMatching(V1_METRICS_PROJECT_CURRENT)).willReturn( aResponse().withBodyFile("api/v1/metrics/project/project-metrics.json"))); @@ -117,8 +117,8 @@ public void thatWhenNoMetricsHaveBeenCalculatedThenTheMetricsAreRetrieved() thro @Test public void thatWhenNoMetricsHaveBeenTheTheCallIsRetriedTheCorrectNumberOfTimes() throws Exception { // The current project score in the JSON file is 3 - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( + aResponse().withBodyFile("api/v1/project/noMetrics.json"))); stubFor(get(urlPathMatching(V1_METRICS_PROJECT_CURRENT)).willReturn( aResponse().withStatus(404).withBody("The project could not be found."))); @@ -139,7 +139,7 @@ public void thatWhenNoMetricsHaveBeenTheTheCallIsRetriedTheCorrectNumberOfTimes( @Test public void thatWhenFailOnErrorIsFalseAFailureFromToDependencyTrackDoesNotFailTheBuild() { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn(notFound())); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn(notFound())); try { scoreMojo.setFailOnError(false); @@ -148,12 +148,12 @@ public void thatWhenFailOnErrorIsFalseAFailureFromToDependencyTrackDoesNotFailTh fail("No exception expected"); } - verify(exactly(1), getRequestedFor(urlEqualTo(V1_PROJECT))); + verify(exactly(1), getRequestedFor(urlPathEqualTo(V1_PROJECT_LOOKUP))); } @Test public void thatWhenFailOnErrorIsTrueAFailureFromToDependencyTrackDoesFailTheBuild() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn(notFound())); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn(notFound())); try { scoreMojo.setFailOnError(true); @@ -200,6 +200,6 @@ public void thatTheScoreIsSkippedWhenSkipIsTrue() throws Exception { scoreMojo.execute(); - verify(exactly(0), getRequestedFor(urlEqualTo(V1_PROJECT))); + verify(exactly(0), getRequestedFor(urlPathEqualTo(V1_PROJECT_LOOKUP))); } } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/upload/BomClientIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/upload/BomClientIntegrationTest.java index b5fe3360..7672dea6 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/upload/BomClientIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/upload/BomClientIntegrationTest.java @@ -31,12 +31,14 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; +import java.util.Collections; + public class BomClientIntegrationTest extends AbstractDependencyTrackIntegrationTest { private static final String BASE_64_ENCODED_BOM = "blah"; private BomClient client; - + @Before public void setup() { client = new BomClient(getCommonConfig()); @@ -119,6 +121,6 @@ public void thatWhenAnErrorOccursWhileQueryingTheAUnirestExceptionIsThrown() { */ private UploadBomRequest aBom() { - return new UploadBomRequest(PROJECT_NAME, PROJECT_VERSION, false, BASE_64_ENCODED_BOM); + return new UploadBomRequest(PROJECT_NAME, PROJECT_VERSION, false, BASE_64_ENCODED_BOM, false, Collections.emptySet()); } } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoIntegrationTest.java index f7259362..12a14011 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoIntegrationTest.java @@ -13,12 +13,14 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.HashSet; import java.util.Optional; +import java.util.Set; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static io.github.pmckeown.TestMojoLoader.loadUploadBomMojo; import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_BOM; -import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT; +import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT_LOOKUP; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -42,8 +44,6 @@ public void setup() { @Test public void thatBomCanBeUploadedSuccessfully() throws Exception { - stubFor(get(urlPathMatching(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); stubFor(put(urlEqualTo(ResourceConstants.V1_BOM)).willReturn(ok())); uploadBomMojo(BOM_LOCATION).execute(); @@ -53,8 +53,6 @@ public void thatBomCanBeUploadedSuccessfully() throws Exception { @Test public void thatWhenFailOnErrorIsFalseAFailureFromToDependencyTrackDoesNotFailTheBuild() { - stubFor(get(urlPathMatching(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); stubFor(put(urlEqualTo(ResourceConstants.V1_BOM)).willReturn(notFound())); try { @@ -127,8 +125,6 @@ public void thatWhenFailOnErrorIsTrueAFailureToConnectToDependencyTrackDoesFailT @Test public void thatProjectNameCanBeProvided() throws Exception { - stubFor(get(urlPathMatching(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); stubFor(put(urlEqualTo(V1_BOM)).willReturn(ok())); UploadBomMojo uploadBomMojo = uploadBomMojo(BOM_LOCATION); @@ -142,8 +138,6 @@ public void thatProjectNameCanBeProvided() throws Exception { @Test public void thatProjectNameDefaultsToArtifactId() throws Exception { - stubFor(get(urlPathMatching(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); stubFor(put(urlEqualTo(V1_BOM)).willReturn(ok())); UploadBomMojo uploadBomMojo = uploadBomMojo(BOM_LOCATION); @@ -156,8 +150,6 @@ public void thatProjectNameDefaultsToArtifactId() throws Exception { @Test public void thatProjectVersionCanBeProvided() throws Exception { - stubFor(get(urlPathMatching(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); stubFor(put(urlEqualTo(V1_BOM)).willReturn(ok())); @@ -170,10 +162,39 @@ public void thatProjectVersionCanBeProvided() throws Exception { matchingJsonPath("$.projectVersion", equalTo("99.99.99-RELEASE")))); } + @Test + public void thatProjectIsLatestCanBeProvided() throws Exception { + stubFor(put(urlEqualTo(V1_BOM)).willReturn(ok())); + + + UploadBomMojo uploadBomMojo = uploadBomMojo(BOM_LOCATION); + uploadBomMojo.setLatest(true); + uploadBomMojo.execute(); + + verify(exactly(1), putRequestedFor(urlEqualTo(V1_BOM)) + .withRequestBody( + matchingJsonPath("$.isLatestProjectVersion", equalTo("true")))); + } + + @Test + public void thatProjectTagsCanBeProvided() throws Exception { + stubFor(put(urlEqualTo(V1_BOM)).willReturn(ok())); + + UploadBomMojo uploadBomMojo = uploadBomMojo(BOM_LOCATION); + uploadBomMojo.setLatest(true); + Set tags = new HashSet<>(); + tags.add("Backend"); + tags.add("Team-1"); + uploadBomMojo.setProjectTags(tags); + uploadBomMojo.execute(); + + verify(exactly(1), putRequestedFor(urlEqualTo(V1_BOM)) + .withRequestBody( + matchingJsonPath("$.projectTags", equalToJson("[{\"name\":\"Backend\"},{\"name\":\"Team-1\"}]")))); + } + @Test public void thatProjectVersionDefaultsToPomVersion() throws Exception { - stubFor(get(urlPathMatching(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); stubFor(put(urlEqualTo(V1_BOM)).willReturn(ok())); UploadBomMojo uploadBomMojo = uploadBomMojo(BOM_LOCATION); @@ -186,8 +207,6 @@ public void thatProjectVersionDefaultsToPomVersion() throws Exception { @Test public void thatTheUploadIsSkippedWhenSkipIsTrue() throws Exception { - stubFor(get(urlPathMatching(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); stubFor(put(urlEqualTo(ResourceConstants.V1_BOM)).willReturn(ok())); UploadBomMojo uploadBomMojo = uploadBomMojo("target/test-classes/projects/skip/bom.xml"); @@ -208,8 +227,12 @@ public void thatSslVerifyDefaultsToTrue() throws Exception { @Test public void thatProjectParentNameAndVersionCanBeProvided() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)) + .withQueryParam("name", equalTo("test-parent")) + .willReturn(aResponse().withBodyFile("api/v1/project/test-parent.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).atPriority(1) + .withQueryParam("name", equalTo("test-project")) + .willReturn(aResponse().withBodyFile("api/v1/project/test-project.json"))); stubFor(get(urlPathMatching(TestResourceConstants.V1_PROJECT_UUID)).willReturn(ok())); stubFor(patch(urlPathMatching(TestResourceConstants.V1_PROJECT_UUID)).willReturn(ok())); stubFor(get(urlPathMatching(TestResourceConstants.V1_BOM_TOKEN_UUID)).willReturn(ok())); @@ -232,8 +255,8 @@ public void thatProjectParentNameAndVersionCanBeProvided() throws Exception { @Test public void thatProjectParentNameAndVersionCanBeIgnored() throws Exception { - stubFor(get(urlEqualTo(V1_PROJECT)).willReturn( - aResponse().withBodyFile("api/v1/project/get-all-projects.json"))); + stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)) + .willReturn(aResponse().withBodyFile("api/v1/project/test-project.json"))); stubFor(get(urlPathMatching(TestResourceConstants.V1_PROJECT_UUID)).willReturn(ok())); stubFor(patch(urlPathMatching(TestResourceConstants.V1_PROJECT_UUID)).willReturn(ok())); stubFor(get(urlPathMatching(TestResourceConstants.V1_BOM_TOKEN_UUID)).willReturn(ok())); @@ -248,7 +271,7 @@ public void thatProjectParentNameAndVersionCanBeIgnored() throws Exception { uploadBomMojo.setFailOnError(true); uploadBomMojo.execute(); - verify(exactly(1), getRequestedFor(urlEqualTo(V1_PROJECT))); + verify(exactly(1), getRequestedFor(urlPathEqualTo(V1_PROJECT_LOOKUP))); } /* diff --git a/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoTest.java b/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoTest.java index 620e66e4..09811b8d 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoTest.java @@ -16,12 +16,16 @@ import org.mockito.junit.MockitoJUnitRunner; import java.io.File; +import java.util.Collections; +import java.util.Set; import static io.github.pmckeown.dependencytrack.project.ProjectBuilder.aProject; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anySet; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; @@ -63,16 +67,20 @@ public void setup() { @Test public void thatTheBomLocationIsDefaultedWhenNotSupplied() throws Exception { ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(String.class); + ArgumentCaptor argumentCaptor2 = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor> argumentCaptor3 = ArgumentCaptor.forClass(Set.class); doReturn(new File(".")).when(project).getBasedir(); doReturn(aProject().build()).when(projectAction).getProject(PROJECT_NAME, PROJECT_VERSION); - doReturn(true).when(uploadBomAction).upload(anyString()); + doReturn(true).when(uploadBomAction).upload(anyString(), anyBoolean(), anySet()); uploadBomMojo.setProjectName(PROJECT_NAME); uploadBomMojo.setProjectVersion(PROJECT_VERSION); + uploadBomMojo.setProjectTags(Collections.emptySet()); uploadBomMojo.execute(); - verify(uploadBomAction).upload(argumentCaptor.capture()); + verify(uploadBomAction).upload(argumentCaptor.capture(), argumentCaptor2.capture(), argumentCaptor3.capture()); assertThat(argumentCaptor.getValue(), is(equalTo("./target/bom.xml"))); + assertThat(argumentCaptor2.getValue(), is(equalTo(false))); } @Test @@ -137,7 +145,7 @@ public void thatUnirestIsConfiguredWithSslVerifyOffWhenAsked() throws Exception @Test public void thatWhenUpdateParentFailsTheLoggerIsCalledAndBuildFails() throws Exception { - doReturn(true).when(uploadBomAction).upload(anyString()); + doReturn(true).when(uploadBomAction).upload(anyString(), anyBoolean(), anySet()); doReturn(aProject().withName("project-parent").withVersion("1.2.3").build()) .when(projectAction).getProject("project-parent", "1.2.3"); @@ -145,6 +153,7 @@ public void thatWhenUpdateParentFailsTheLoggerIsCalledAndBuildFails() throws Exc uploadBomMojo.setParentVersion("1.2.3"); uploadBomMojo.setUpdateParent(true); uploadBomMojo.setFailOnError(true); + uploadBomMojo.setProjectTags(Collections.emptySet()); try { uploadBomMojo.performAction(); @@ -157,16 +166,18 @@ public void thatWhenUpdateParentFailsTheLoggerIsCalledAndBuildFails() throws Exc @Test public void thatUpdateParentFailsWhenParentNameIsNull() throws Exception { - doReturn(true).when(uploadBomAction).upload(anyString()); + doReturn(true).when(uploadBomAction).upload(anyString(), anyBoolean(), anySet()); uploadBomMojo.setParentName(null); uploadBomMojo.setParentVersion(null); uploadBomMojo.setUpdateParent(true); uploadBomMojo.setFailOnError(true); + uploadBomMojo.setProjectTags(Collections.emptySet()); try { uploadBomMojo.performAction(); } catch (Exception ex) { + ex.printStackTrace(); assertThat(ex, instanceOf(MojoExecutionException.class)); } diff --git a/src/test/resources/__files/api/v1/project/dependency-track-3.6.json b/src/test/resources/__files/api/v1/project/dependency-track-3.6.json new file mode 100644 index 00000000..3dd0d811 --- /dev/null +++ b/src/test/resources/__files/api/v1/project/dependency-track-3.6.json @@ -0,0 +1,23 @@ +{ + "name": "dependency-track", + "version": "3.6.0-SNAPSHOT", + "uuid": "21ea26f5-f835-488e-bd72-a4f22516fbfe", + "lastBomImport": 1562480255118, + "metrics": { + "critical": 0, + "high": 0, + "medium": 1, + "low": 0, + "unassigned": 0, + "vulnerabilities": 1, + "vulnerableComponents": 1, + "components": 151, + "suppressed": 0, + "findingsTotal": 1, + "findingsAudited": 0, + "findingsUnaudited": 1, + "inheritedRiskScore": 3, + "firstOccurrence": 1562135708949, + "lastOccurrence": 1562482715111 + } +} diff --git a/src/test/resources/__files/api/v1/project/noMetrics.json b/src/test/resources/__files/api/v1/project/noMetrics.json new file mode 100644 index 00000000..6e5cbd5f --- /dev/null +++ b/src/test/resources/__files/api/v1/project/noMetrics.json @@ -0,0 +1,6 @@ +{ + "name": "noMetrics", + "version": "1.0.0", + "uuid": "8977c66f-b310-45b5-bb6a-e63e9eb7c4ce", + "lastBomImport": 1562225389158 +} diff --git a/src/test/resources/__files/api/v1/project/tags-project.json b/src/test/resources/__files/api/v1/project/tags-project.json new file mode 100644 index 00000000..2c50a054 --- /dev/null +++ b/src/test/resources/__files/api/v1/project/tags-project.json @@ -0,0 +1,16 @@ +{ + "name": "tags-project", + "version": "4.6.10", + "classifier": "APPLICATION", + "uuid": "8c8fcbd1-b569-4e98-849f-884afef20a2a", + "tags": [ + { + "name": "backend" + }, + { + "name": "Team-1" + } + ], + "active": true, + "isLatest": true +} \ No newline at end of file diff --git a/src/test/resources/__files/api/v1/project/test-parent.json b/src/test/resources/__files/api/v1/project/test-parent.json new file mode 100644 index 00000000..12ede75f --- /dev/null +++ b/src/test/resources/__files/api/v1/project/test-parent.json @@ -0,0 +1,7 @@ + +{ + "name": "test-parent", + "version": "1.0.0-SNAPSHOT", + "uuid": "8977c66f-b310-aced-face-e63e9eb7c4cf", + "lastBomImport": 1562225389159 +} diff --git a/src/test/resources/__files/api/v1/project/test-project.json b/src/test/resources/__files/api/v1/project/test-project.json new file mode 100644 index 00000000..c2b09424 --- /dev/null +++ b/src/test/resources/__files/api/v1/project/test-project.json @@ -0,0 +1,7 @@ +{ + "name": "test-project", + "version": "0.0.1-SNAPSHOT", + "uuid": "8977c66f-b310-fade-abba-e63e9eb7c4cf", + "lastBomImport": 1562225389160 +} + diff --git a/src/test/resources/__files/api/v1/project/testName-project.json b/src/test/resources/__files/api/v1/project/testName-project.json new file mode 100644 index 00000000..595fbdb4 --- /dev/null +++ b/src/test/resources/__files/api/v1/project/testName-project.json @@ -0,0 +1,23 @@ +{ + "name": "testName", + "version": "99.99", + "uuid": "8977c66f-b310-45b5-bb6a-e63e9eb7c4cf", + "lastBomImport": 1562225389157, + "metrics": { + "critical": 0, + "high": 0, + "medium": 1, + "low": 0, + "unassigned": 0, + "vulnerabilities": 1, + "vulnerableComponents": 1, + "components": 151, + "suppressed": 0, + "findingsTotal": 1, + "findingsAudited": 0, + "findingsUnaudited": 1, + "inheritedRiskScore": 3, + "firstOccurrence": 1562223476643, + "lastOccurrence": 1562482716510 + } +} \ No newline at end of file