mirror of
https://github.com/ysoftdevs/odc-analyzer.git
synced 2026-03-22 17:19:51 +01:00
Fixed bug in filtering by team. If a team has assigned a project with all subprojects and the project has more than one subproject, only one subproject used to be shown when filtering by team.
This is a trivial fix (two/three lines changed), but other additions are in tests.
This commit is contained in:
@@ -20,7 +20,7 @@ sealed trait Filter{
|
|||||||
def descriptionHtml: Html
|
def descriptionHtml: Html
|
||||||
def descriptionText: String
|
def descriptionText: String
|
||||||
}
|
}
|
||||||
private final case class ProjectFilter(project: ReportInfo) extends Filter{
|
final case class ProjectFilter(project: ReportInfo) extends Filter{
|
||||||
override def filters: Boolean = true
|
override def filters: Boolean = true
|
||||||
override def descriptionHtml: Html = views.html.filters.project(project)
|
override def descriptionHtml: Html = views.html.filters.project(project)
|
||||||
override def descriptionText: String = s"project ${friendlyProjectNameString(project)}"
|
override def descriptionText: String = s"project ${friendlyProjectNameString(project)}"
|
||||||
@@ -43,7 +43,7 @@ private final case class ProjectFilter(project: ReportInfo) extends Filter{
|
|||||||
}
|
}
|
||||||
override def selector = Some(s"project:${project.fullId}")
|
override def selector = Some(s"project:${project.fullId}")
|
||||||
}
|
}
|
||||||
private final case class TeamFilter(team: Team) extends Filter{
|
final case class TeamFilter(team: Team) extends Filter{
|
||||||
override def filters: Boolean = true
|
override def filters: Boolean = true
|
||||||
|
|
||||||
private def splitSuccessesAndFailures[T, U](set: Set[Either[T, U]]) = {
|
private def splitSuccessesAndFailures[T, U](set: Set[Either[T, U]]) = {
|
||||||
@@ -64,10 +64,10 @@ private final case class TeamFilter(team: Team) extends Filter{
|
|||||||
val ProjectName = """^(.*): (.*)$""".r
|
val ProjectName = """^(.*): (.*)$""".r
|
||||||
val failedProjectsFriendlyNames = r.failedProjects.failedProjectsSet.map(_.projectName)
|
val failedProjectsFriendlyNames = r.failedProjects.failedProjectsSet.map(_.projectName)
|
||||||
Logger.error("failedProjectsFriendlyNames: "+failedProjectsFriendlyNames)
|
Logger.error("failedProjectsFriendlyNames: "+failedProjectsFriendlyNames)
|
||||||
val rootProjectReports = reportInfoByFriendlyProjectNameMap.map{
|
val rootProjectReports = reportInfoByFriendlyProjectNameMap.toSeq.map{
|
||||||
case (ProjectName(rootProject, _subproject), v) => (rootProject, v)
|
case (ProjectName(rootProject, _subproject), v) => (rootProject, v)
|
||||||
case value @ (rootProject, v) => value
|
case value @ (rootProject, v) => value
|
||||||
}.groupBy(_._1).mapValues(_.values).withDefault(name =>
|
}.groupBy(_._1).mapValues(_.map(_._2)).withDefault(name =>
|
||||||
if(failedProjectsFriendlyNames contains name) Seq()
|
if(failedProjectsFriendlyNames contains name) Seq()
|
||||||
else sys.error("Unknown project: "+name)
|
else sys.error("Unknown project: "+name)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class ProjectsWithReports (val projects: Projects, val reports: Set[String]) {
|
|||||||
|
|
||||||
private def parseUnfriendlyName(unfriendlyName: String, missingProject: String => String): ReportInfo = {
|
private def parseUnfriendlyName(unfriendlyName: String, missingProject: String => String): ReportInfo = {
|
||||||
val (baseName, theRest) = unfriendlyName.span(_ != '/')
|
val (baseName, theRest) = unfriendlyName.span(_ != '/')
|
||||||
val removeLeadingMess = RestMessBeginRegexp.replaceAllIn(_: String, "")
|
val removeLeadingMess = RestMessBeginRegexp.replaceAllIn(_: String, "").dropWhile(_=='/')
|
||||||
val removeTrailingMess = RestMessEndRegexp.replaceAllIn(_: String, "")
|
val removeTrailingMess = RestMessEndRegexp.replaceAllIn(_: String, "")
|
||||||
val removeMess = removeLeadingMess andThen removeTrailingMess
|
val removeMess = removeLeadingMess andThen removeTrailingMess
|
||||||
val subProjectOption = Some(removeMess(theRest)).filter(_ != "")
|
val subProjectOption = Some(removeMess(theRest)).filter(_ != "")
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ libraryDependencies ++= Seq(
|
|||||||
//jdbc,
|
//jdbc,
|
||||||
cache,
|
cache,
|
||||||
ws,
|
ws,
|
||||||
filters
|
filters,
|
||||||
//specs2 % Test
|
specs2 % Test
|
||||||
)
|
)
|
||||||
|
|
||||||
//resolvers += "scalaz-bintray" at https?"http://dl.bintray.com/scalaz/releases"
|
//resolvers += "scalaz-bintray" at https?"http://dl.bintray.com/scalaz/releases"
|
||||||
|
|||||||
26
test/ProjectFilterSpec.scala
Normal file
26
test/ProjectFilterSpec.scala
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import controllers.ProjectFilter
|
||||||
|
import org.specs2.mutable.Specification
|
||||||
|
|
||||||
|
//noinspection ScalaUnnecessaryParentheses
|
||||||
|
class ProjectFilterSpec extends Specification {
|
||||||
|
import factories.ReportsFactory._
|
||||||
|
|
||||||
|
private val f1 = ProjectFilter(res.projectsReportInfo.reportIdToReportInfo("a")) // with subprojects
|
||||||
|
// TODO: filter root
|
||||||
|
// TODO: filter subproject
|
||||||
|
|
||||||
|
private val s1 = f1.subReports(res).get
|
||||||
|
|
||||||
|
"It should have all dependencies for project a and its subprojects" >> {
|
||||||
|
"like a" >> {s1.groupedDependenciesByPlainLibraryIdentifier.keySet should contain(buildFakeIdentifier("a").toLibraryIdentifierOption.get)}
|
||||||
|
"like a/subX" >> {s1.groupedDependenciesByPlainLibraryIdentifier.keySet should contain(buildFakeIdentifier("a/subX").toLibraryIdentifierOption.get)}
|
||||||
|
"like a/subY" >> {s1.groupedDependenciesByPlainLibraryIdentifier.keySet should contain(buildFakeIdentifier("a/subY").toLibraryIdentifierOption.get)}
|
||||||
|
}
|
||||||
|
|
||||||
|
"It should now have other dependencies" >> {
|
||||||
|
"like b" >> {s1.groupedDependenciesByPlainLibraryIdentifier.keySet should not contain(buildFakeIdentifier("b").toLibraryIdentifierOption.get)}
|
||||||
|
"like b/subX" >> {s1.groupedDependenciesByPlainLibraryIdentifier.keySet should not contain(buildFakeIdentifier("b/subX").toLibraryIdentifierOption.get)}
|
||||||
|
"like b/subY" >> {s1.groupedDependenciesByPlainLibraryIdentifier.keySet should not contain(buildFakeIdentifier("b/subY").toLibraryIdentifierOption.get)}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
24
test/ResultsTest.scala
Normal file
24
test/ResultsTest.scala
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import org.specs2.mutable.Specification
|
||||||
|
|
||||||
|
//noinspection ScalaUnnecessaryParentheses
|
||||||
|
class ResultsTest extends Specification {
|
||||||
|
import factories.ReportsFactory._
|
||||||
|
|
||||||
|
"The resultset should" >> {
|
||||||
|
"have dependencies related to project a" >> {
|
||||||
|
"like a" >> {res.groupedDependenciesByPlainLibraryIdentifier.keySet should contain(buildFakeIdentifier("a").toLibraryIdentifierOption.get)}
|
||||||
|
"libe a/subX" >> {res.groupedDependenciesByPlainLibraryIdentifier.keySet should contain(buildFakeIdentifier("a/subX").toLibraryIdentifierOption.get)}
|
||||||
|
"like a/subY" >> {res.groupedDependenciesByPlainLibraryIdentifier.keySet should contain(buildFakeIdentifier("a/subY").toLibraryIdentifierOption.get)}
|
||||||
|
}
|
||||||
|
"have dependencies related to project m" >> {
|
||||||
|
"like m" >> {res.groupedDependenciesByPlainLibraryIdentifier.keySet should contain(buildFakeIdentifier("m").toLibraryIdentifierOption.get)}
|
||||||
|
"libe m/subX" >> {res.groupedDependenciesByPlainLibraryIdentifier.keySet should contain(buildFakeIdentifier("m/subX").toLibraryIdentifierOption.get)}
|
||||||
|
"like m/subY" >> {res.groupedDependenciesByPlainLibraryIdentifier.keySet should contain(buildFakeIdentifier("m/subY").toLibraryIdentifierOption.get)}
|
||||||
|
}
|
||||||
|
"have groupedDependencies" >> {
|
||||||
|
res.groupedDependencies shouldNotEqual null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
116
test/factories/ReportsFactory.scala
Normal file
116
test/factories/ReportsFactory.scala
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
package factories
|
||||||
|
|
||||||
|
import com.github.nscala_time.time.Imports.DateTime
|
||||||
|
import com.ysoft.odc._
|
||||||
|
import controllers.DependencyCheckReportsParser.Result
|
||||||
|
import controllers.{Projects, ProjectsWithReports, ReportInfo, TeamId}
|
||||||
|
import org.apache.commons.codec.digest.DigestUtils
|
||||||
|
|
||||||
|
//noinspection TypeAnnotation
|
||||||
|
object ReportsFactory{
|
||||||
|
|
||||||
|
def buildFlatReport(projectId: String): (String, () => (ReportInfo, Analysis)) = {
|
||||||
|
val thuck = () => { // needs laziness in order to prevent dependency cycle
|
||||||
|
val reportInfo = projectsReportInfo.parseUnfriendlyName(projectId)
|
||||||
|
reportInfo -> Analysis(
|
||||||
|
scanInfo = SerializableXml("<a></a>"),
|
||||||
|
name = projectId,
|
||||||
|
reportDate = DateTime.lastDay,
|
||||||
|
dependencies = Seq(
|
||||||
|
buildDependency(projectId)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
projectId -> thuck
|
||||||
|
}
|
||||||
|
|
||||||
|
def buildDependency(projectId: String) = {
|
||||||
|
val fakeFileContent = projectId
|
||||||
|
Dependency(
|
||||||
|
fileName = s"dep-for-$projectId",
|
||||||
|
filePath = s"dep-for-$projectId",
|
||||||
|
md5 = DigestUtils.md5Hex(fakeFileContent),
|
||||||
|
sha1 = DigestUtils.sha1Hex(fakeFileContent),
|
||||||
|
description = s"Some fake dependency for project $projectId",
|
||||||
|
evidenceCollected = Set(),
|
||||||
|
identifiers = Seq(buildFakeIdentifier(projectId)),
|
||||||
|
suppressedIdentifiers = Seq(),
|
||||||
|
license = "something",
|
||||||
|
vulnerabilities = Seq(),
|
||||||
|
suppressedVulnerabilities = Seq(),
|
||||||
|
relatedDependencies = SerializableXml("<c></c>")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
def buildFakeIdentifier(projectId: String) = {
|
||||||
|
Identifier(s"fake:dep-for-$projectId:1.0-SNAPSHOT", Confidence.High, "", "maven")
|
||||||
|
}
|
||||||
|
|
||||||
|
val pm = Map(
|
||||||
|
"a"->"project a",
|
||||||
|
"b"->"project b",
|
||||||
|
"c"->"project c",
|
||||||
|
"d"->"project d",
|
||||||
|
"e"->"project e",
|
||||||
|
"f"->"project f",
|
||||||
|
"g"->"project g",
|
||||||
|
"h"->"project h",
|
||||||
|
"i"->"project i",
|
||||||
|
"j"->"project j",
|
||||||
|
"k"->"project k",
|
||||||
|
"l"->"project l",
|
||||||
|
"m"->"project m",
|
||||||
|
"n"->"project n",
|
||||||
|
"o"->"project o"
|
||||||
|
)
|
||||||
|
|
||||||
|
val projectToTeams = Map(
|
||||||
|
"project a: *" -> Set("TEAM A"),
|
||||||
|
"project b: subX" -> Set("TEAM A"),
|
||||||
|
"project b: subY" -> Set("TEAM B"),
|
||||||
|
"project b" -> Set("TEAM A"),
|
||||||
|
"project c: *" -> Set("TEAM A"),
|
||||||
|
"project d: *" -> Set("TEAM A"),
|
||||||
|
"project e: *" -> Set("TEAM A"),
|
||||||
|
"project f: *" -> Set("TEAM A"),
|
||||||
|
"project g: *" -> Set("TEAM A"),
|
||||||
|
"project h: *" -> Set("TEAM B"),
|
||||||
|
"project i: *" -> Set("TEAM B"),
|
||||||
|
"project j: *" -> Set("TEAM B"),
|
||||||
|
"project k: *" -> Set("TEAM B"),
|
||||||
|
"project l: *" -> Set("TEAM B"),
|
||||||
|
"project m: *" -> Set("TEAM B"),
|
||||||
|
"project n: *" -> Set("TEAM B"),
|
||||||
|
"project o: *" -> Set("TEAM B")
|
||||||
|
)
|
||||||
|
|
||||||
|
val teamLeaders = Map(TeamId("TEAM A") -> "John Smith", TeamId("TEAM B") -> "Jane")
|
||||||
|
|
||||||
|
val projects = new Projects(
|
||||||
|
projectMap = pm,
|
||||||
|
teamLeaders = teamLeaders,
|
||||||
|
projectToTeams = projectToTeams.mapValues(_.map(TeamId))
|
||||||
|
)
|
||||||
|
|
||||||
|
val bareFlatReportsFactories = pm.keySet.flatMap{ projectId =>
|
||||||
|
Seq(
|
||||||
|
buildFlatReport(projectId),
|
||||||
|
buildFlatReport(projectId+"/subX"),
|
||||||
|
buildFlatReport(projectId+"/subY")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val projectsReportInfo = new ProjectsWithReports(projects, bareFlatReportsFactories.map(_._1))
|
||||||
|
|
||||||
|
val bareFlatReports = bareFlatReportsFactories.map(_._2()).toMap // Prevents forward reference issues
|
||||||
|
|
||||||
|
val res = Result(
|
||||||
|
bareFlatReports = bareFlatReports,
|
||||||
|
bareFailedAnalysises = Map(),
|
||||||
|
projectsReportInfo = projectsReportInfo,
|
||||||
|
failedReportDownloads = Map()
|
||||||
|
)
|
||||||
|
|
||||||
|
val team1 = projects.teamById("TEAM A")
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user