diff --git a/src/test/java/org/dependencytrack/resources/v1/NotificationPublisherResourceTest.java b/src/test/java/org/dependencytrack/resources/v1/NotificationPublisherResourceTest.java index ede0944fa1..f3f3557d08 100644 --- a/src/test/java/org/dependencytrack/resources/v1/NotificationPublisherResourceTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/NotificationPublisherResourceTest.java @@ -137,6 +137,33 @@ public void createNotificationPublisherTest() { Assert.assertNotNull(json); Assert.assertEquals("Example Publisher", json.getString("name")); Assert.assertFalse(json.getBoolean("defaultPublisher")); + Assert.assertFalse(json.getBoolean("publishScheduled")); + Assert.assertEquals("Publisher description", json.getString("description")); + Assert.assertEquals("template", json.getString("template")); + Assert.assertEquals("application/json", json.getString("templateMimeType")); + Assert.assertTrue(UuidUtil.isValidUUID(json.getString("uuid"))); + Assert.assertEquals(SendMailPublisher.class.getName(), json.getString("publisherClass")); + } + + @Test + public void createNotificationPublisherWithPublishScheduledTest() { + NotificationPublisher publisher = new NotificationPublisher(); + publisher.setName("Example Publisher"); + publisher.setDescription("Publisher description"); + publisher.setTemplate("template"); + publisher.setTemplateMimeType("application/json"); + publisher.setPublisherClass(SendMailPublisher.class.getName()); + publisher.setDefaultPublisher(false); + publisher.setPublishScheduled(true); + Response response = jersey.target(V1_NOTIFICATION_PUBLISHER).request() + .header(X_API_KEY, apiKey) + .put(Entity.entity(publisher, MediaType.APPLICATION_JSON)); + Assert.assertEquals(201, response.getStatus(), 0); + JsonObject json = parseJsonObject(response); + Assert.assertNotNull(json); + Assert.assertEquals("Example Publisher", json.getString("name")); + Assert.assertFalse(json.getBoolean("defaultPublisher")); + Assert.assertTrue(json.getBoolean("publishScheduled")); Assert.assertEquals("Publisher description", json.getString("description")); Assert.assertEquals("template", json.getString("template")); Assert.assertEquals("application/json", json.getString("templateMimeType")); @@ -228,6 +255,32 @@ public void updateNotificationPublisherTest() { Assert.assertNotNull(json); Assert.assertEquals("Updated Publisher name", json.getString("name")); Assert.assertFalse(json.getBoolean("defaultPublisher")); + Assert.assertFalse(json.getBoolean("publishScheduled")); + Assert.assertEquals("Publisher description", json.getString("description")); + Assert.assertEquals("template", json.getString("template")); + Assert.assertEquals("text/html", json.getString("templateMimeType")); + Assert.assertEquals(notificationPublisher.getUuid().toString(), json.getString("uuid")); + Assert.assertEquals(SendMailPublisher.class.getName(), json.getString("publisherClass")); + } + + @Test + public void updateNotificationPublisherToScheduledTest() { + NotificationPublisher notificationPublisher = qm.createNotificationPublisher( + "Example Publisher", "Publisher description", + SendMailPublisher.class, "template", "text/html", + false + ); + notificationPublisher.setName("Updated Publisher name"); + notificationPublisher.setPublishScheduled(true); + Response response = jersey.target(V1_NOTIFICATION_PUBLISHER).request() + .header(X_API_KEY, apiKey) + .post(Entity.entity(notificationPublisher, MediaType.APPLICATION_JSON)); + Assert.assertEquals(200, response.getStatus(), 0); + JsonObject json = parseJsonObject(response); + Assert.assertNotNull(json); + Assert.assertEquals("Updated Publisher name", json.getString("name")); + Assert.assertFalse(json.getBoolean("defaultPublisher")); + Assert.assertTrue(json.getBoolean("publishScheduled")); Assert.assertEquals("Publisher description", json.getString("description")); Assert.assertEquals("template", json.getString("template")); Assert.assertEquals("text/html", json.getString("templateMimeType")); diff --git a/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java b/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java index 9e8db554cc..371d3325f1 100644 --- a/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java @@ -178,6 +178,7 @@ public void updateNotificationRuleInvalidTest() { @Test public void updateNotificationRuleWithTagsTest() { final NotificationPublisher publisher = qm.getNotificationPublisher(DefaultNotificationPublishers.SLACK.getPublisherName()); + publisher.setPublishScheduled(true); final NotificationRule rule = qm.createNotificationRule("Rule 1", NotificationScope.PORTFOLIO, NotificationLevel.INFORMATIONAL, publisher); // Tag the rule with "foo" and "bar". @@ -227,7 +228,7 @@ public void updateNotificationRuleWithTagsTest() { "publisherClass": "${json-unit.any-string}", "templateMimeType": "${json-unit.any-string}", "defaultPublisher": true, - "publishScheduled": false, + "publishScheduled": true, "uuid": "${json-unit.any-string}" }, "uuid": "${json-unit.matches:ruleUuid}" @@ -275,7 +276,7 @@ public void updateNotificationRuleWithTagsTest() { "publisherClass": "${json-unit.any-string}", "templateMimeType": "${json-unit.any-string}", "defaultPublisher": true, - "publishScheduled": false, + "publishScheduled": true, "uuid": "${json-unit.any-string}" }, "uuid": "${json-unit.matches:ruleUuid}" diff --git a/src/test/java/org/dependencytrack/util/NotificationUtilTest.java b/src/test/java/org/dependencytrack/util/NotificationUtilTest.java new file mode 100644 index 0000000000..8e2fdd09f8 --- /dev/null +++ b/src/test/java/org/dependencytrack/util/NotificationUtilTest.java @@ -0,0 +1,149 @@ +package org.dependencytrack.util; + +import java.math.BigDecimal; +import java.util.EnumMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.commons.collections4.map.LinkedMap; +import org.dependencytrack.model.AnalysisState; +import org.dependencytrack.model.Component; +import org.dependencytrack.model.Project; +import org.dependencytrack.model.Severity; +import org.dependencytrack.model.Tag; +import org.dependencytrack.model.Vulnerability; +import org.dependencytrack.model.scheduled.vulnerabilities.VulnerabilityDetails; +import org.dependencytrack.model.scheduled.vulnerabilities.VulnerabilityDetailsInfo; +import org.dependencytrack.model.scheduled.vulnerabilities.VulnerabilityOverview; +import org.dependencytrack.model.scheduled.vulnerabilities.VulnerabilitySummary; +import org.dependencytrack.model.scheduled.vulnerabilities.VulnerabilitySummaryInfo; +import org.dependencytrack.notification.vo.ScheduledNewVulnerabilitiesIdentified; +import org.junit.Test; +import org.junit.Assert; + +import jakarta.json.JsonObject; + +public class NotificationUtilTest { + + @Test + public void toJsonWithScheduledNewVulnerabilitiesIdentified() { + final var project = createProject(); + final var component = createComponent(project); + final var vuln = createVulnerability(); + final Map mapVulnBySev = new EnumMap<>(Severity.class); + final Map mapVulnSummInfos = new LinkedHashMap<>(); + final Map> mapVulnDetailInfos = new LinkedHashMap<>(); + + mapVulnBySev.put(Severity.CRITICAL, 1); + mapVulnSummInfos.put(project, new VulnerabilitySummaryInfo(mapVulnBySev, mapVulnBySev, new LinkedMap<>())); + mapVulnDetailInfos.put(project, List.of(new VulnerabilityDetailsInfo( + component.getUuid().toString(), + component.getName(), + component.getVersion(), + component.getGroup(), + vuln.getSource(), + vuln.getVulnId(), + vuln.getSeverity().name(), + "analyzer", + "http://example.com", + "Thu Jan 01 18:31:06 GMT 1970", // Thu Jan 01 18:31:06 GMT 1970 + AnalysisState.EXPLOITABLE.name(), + false))); + + final ScheduledNewVulnerabilitiesIdentified vo = new ScheduledNewVulnerabilitiesIdentified( + new VulnerabilityOverview(1, 1, mapVulnBySev, 1, 0), + new VulnerabilitySummary(mapVulnSummInfos), + new VulnerabilityDetails(mapVulnDetailInfos) + ); + JsonObject json = NotificationUtil.toJson(vo); + System.out.println(json.toString()); + + Assert.assertEquals(1, json.getJsonObject("overview").getInt("affectedProjectsCount")); + Assert.assertEquals(1, json.getJsonObject("overview").getInt("newVulnerabilitiesCount")); + Assert.assertEquals(1, json.getJsonObject("overview").getInt("affectedComponentsCount")); + Assert.assertEquals(0, json.getJsonObject("overview").getInt("suppressedNewVulnerabilitiesCount")); + Assert.assertEquals(1, json.getJsonObject("overview").getJsonObject("newVulnerabilitiesBySeverity").getInt("CRITICAL")); + Assert.assertEquals(0, json.getJsonObject("overview").getInt("suppressedNewVulnerabilitiesCount")); + + Assert.assertEquals(project.getUuid().toString(), json.getJsonObject("summary").getJsonArray("projectSummaries").getJsonObject(0).getJsonObject("project").getString("uuid")); + Assert.assertEquals(project.getName(), json.getJsonObject("summary").getJsonArray("projectSummaries").getJsonObject(0).getJsonObject("project").getString("name")); + Assert.assertEquals(project.getVersion(), json.getJsonObject("summary").getJsonArray("projectSummaries").getJsonObject(0).getJsonObject("project").getString("version")); + Assert.assertEquals(project.getDescription(), json.getJsonObject("summary").getJsonArray("projectSummaries").getJsonObject(0).getJsonObject("project").getString("description")); + Assert.assertEquals(project.getPurl().toString(), json.getJsonObject("summary").getJsonArray("projectSummaries").getJsonObject(0).getJsonObject("project").getString("purl")); + Assert.assertEquals("tag1,tag2", json.getJsonObject("summary").getJsonArray("projectSummaries").getJsonObject(0).getJsonObject("project").getString("tags")); + Assert.assertEquals(1, json.getJsonObject("summary").getJsonArray("projectSummaries").getJsonObject(0).getJsonObject("summary").getJsonObject("newVulnerabilitiesBySeverity").getInt("CRITICAL")); + Assert.assertEquals(1, json.getJsonObject("summary").getJsonArray("projectSummaries").getJsonObject(0).getJsonObject("summary").getJsonObject("totalProjectVulnerabilitiesBySeverity").getInt("CRITICAL")); + Assert.assertTrue(json.getJsonObject("summary").getJsonArray("projectSummaries").getJsonObject(0).getJsonObject("summary").getJsonObject("suppressedNewVulnerabilitiesBySeverity").isEmpty()); + + Assert.assertEquals(project.getUuid().toString(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonObject("project").getString("uuid")); + Assert.assertEquals(project.getName(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonObject("project").getString("name")); + Assert.assertEquals(project.getVersion(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonObject("project").getString("version")); + Assert.assertEquals(project.getDescription(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonObject("project").getString("description")); + Assert.assertEquals(project.getPurl().toString(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonObject("project").getString("purl")); + Assert.assertEquals("tag1,tag2", json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonObject("project").getString("tags")); + Assert.assertEquals(component.getUuid().toString(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonArray("findings").getJsonObject(0).getString("componentUuid")); + Assert.assertEquals(component.getName(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonArray("findings").getJsonObject(0).getString("componentName")); + Assert.assertEquals(component.getVersion(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonArray("findings").getJsonObject(0).getString("componentVersion")); + Assert.assertEquals(vuln.getSource(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonArray("findings").getJsonObject(0).getString("vulnerabilitySource")); + Assert.assertEquals(vuln.getVulnId(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonArray("findings").getJsonObject(0).getString("vulnerabilityId")); + Assert.assertEquals(vuln.getSeverity().toString(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonArray("findings").getJsonObject(0).getString("vulnerabilitySeverity")); + Assert.assertEquals("analyzer", json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonArray("findings").getJsonObject(0).getString("analyzer")); + Assert.assertEquals("http://example.com", json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonArray("findings").getJsonObject(0).getString("attributionReferenceUrl")); + Assert.assertEquals("Thu Jan 01 18:31:06 GMT 1970", json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonArray("findings").getJsonObject(0).getString("attributedOn")); + Assert.assertEquals(AnalysisState.EXPLOITABLE.name(), json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonArray("findings").getJsonObject(0).getString("analysisState")); + Assert.assertFalse(json.getJsonObject("details").getJsonArray("projectDetails").getJsonObject(0).getJsonArray("findings").getJsonObject(0).getBoolean("suppressed")); + + } + + private static Component createComponent(final Project project) { + final var component = new Component(); + component.setProject(project); + component.setUuid(UUID.fromString("94f87321-a5d1-4c2f-b2fe-95165debebc6")); + component.setName("componentName"); + component.setVersion("componentVersion"); + return component; + } + + private static Project createProject() { + final var projectTag1 = new Tag(); + projectTag1.setName("tag1"); + final var projectTag2 = new Tag(); + projectTag2.setName("tag2"); + + final var project = new Project(); + project.setUuid(UUID.fromString("c9c9539a-e381-4b36-ac52-6a7ab83b2c95")); + project.setName("projectName"); + project.setVersion("projectVersion"); + project.setDescription("projectDescription"); + project.setPurl("pkg:maven/org.acme/projectName@projectVersion"); + project.setTags(List.of(projectTag1, projectTag2)); + return project; + } + + private static Vulnerability createVulnerability() { + final var alias = new org.dependencytrack.model.VulnerabilityAlias(); + alias.setInternalId("INT-001"); + alias.setOsvId("OSV-001"); + + final var vuln = new org.dependencytrack.model.Vulnerability(); + vuln.setUuid(UUID.fromString("bccec5d5-ec21-4958-b3e8-22a7a866a05a")); + vuln.setVulnId("INT-001"); + vuln.setSource(org.dependencytrack.model.Vulnerability.Source.INTERNAL); + vuln.setAliases(List.of(alias)); + vuln.setTitle("vulnerabilityTitle"); + vuln.setSubTitle("vulnerabilitySubTitle"); + vuln.setDescription("vulnerabilityDescription"); + vuln.setRecommendation("vulnerabilityRecommendation"); + vuln.setCvssV2BaseScore(BigDecimal.valueOf(5.5)); + vuln.setCvssV3BaseScore(BigDecimal.valueOf(6.6)); + vuln.setOwaspRRLikelihoodScore(BigDecimal.valueOf(1.1)); + vuln.setOwaspRRTechnicalImpactScore(BigDecimal.valueOf(2.2)); + vuln.setOwaspRRBusinessImpactScore(BigDecimal.valueOf(3.3)); + vuln.setSeverity(Severity.MEDIUM); + vuln.setCwes(List.of(666, 777)); + return vuln; + } +} + diff --git a/src/test/java/org/dependencytrack/util/ScheduledUtilTest.java b/src/test/java/org/dependencytrack/util/ScheduledUtilTest.java new file mode 100644 index 0000000000..5ddb65eb03 --- /dev/null +++ b/src/test/java/org/dependencytrack/util/ScheduledUtilTest.java @@ -0,0 +1,53 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ + +package org.dependencytrack.util; + +import java.time.Instant; +import java.util.Date; + +import org.junit.Assert; +import org.junit.Test; + +public class ScheduledUtilTest { + + @Test + public void getValueOrEmptyIfNullTest() { + Integer object = Integer.valueOf(123); + Assert.assertEquals("123", ScheduledUtil.getValueOrEmptyIfNull(object)); + } + + @Test + public void getValueOrEmptyIfNullWithNullTest() { + Integer object = null; + Assert.assertEquals("", ScheduledUtil.getValueOrEmptyIfNull(object)); + } + + @Test + public void getDateOrUnknownIfNull() { + Date date = Date.from(Instant.now()); + Assert.assertEquals(DateUtil.toISO8601(date), ScheduledUtil.getDateOrUnknownIfNull(date)); + } + + @Test + public void getDateOrUnknownIfNullWithNull() { + Date date = null; + Assert.assertEquals("Unknown", ScheduledUtil.getDateOrUnknownIfNull(date)); + } +} diff --git a/src/test/java/org/dependencytrack/util/ZonedDateTimeUtilTest.java b/src/test/java/org/dependencytrack/util/ZonedDateTimeUtilTest.java new file mode 100644 index 0000000000..cf159a1c99 --- /dev/null +++ b/src/test/java/org/dependencytrack/util/ZonedDateTimeUtilTest.java @@ -0,0 +1,48 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ + + +package org.dependencytrack.util; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +import org.junit.Assert; +import org.junit.Test; + +public class ZonedDateTimeUtilTest { + + @Test + public void toISO8601Test() { + final ZonedDateTime testTime = ZonedDateTime.parse("2024-05-31T13:24:46Z", DateTimeFormatter.ISO_OFFSET_DATE_TIME); + Assert.assertEquals("2024-05-31T13:24:46Z", ZonedDateTimeUtil.toISO8601(testTime)); + } + + @Test + public void fromISO8601Test() { + final ZonedDateTime testTime = ZonedDateTime.parse("2024-05-31T13:24:46Z", DateTimeFormatter.ISO_OFFSET_DATE_TIME); + Assert.assertEquals(testTime, ZonedDateTimeUtil.fromISO8601("2024-05-31T13:24:46Z")); + } + + @Test + public void fromISO8601WithNullTest() { + final ZonedDateTime testTime = null; + Assert.assertEquals(testTime, ZonedDateTimeUtil.fromISO8601(null)); + } +}