github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/gosbom/pkg/cataloger/java/parse_pom_xml_test.go (about) 1 package java 2 3 import ( 4 "os" 5 "testing" 6 7 "github.com/nextlinux/gosbom/gosbom/file" 8 "github.com/nextlinux/gosbom/gosbom/pkg" 9 "github.com/nextlinux/gosbom/gosbom/pkg/cataloger/internal/pkgtest" 10 "github.com/stretchr/testify/assert" 11 "github.com/vifraa/gopom" 12 ) 13 14 func Test_parserPomXML(t *testing.T) { 15 tests := []struct { 16 input string 17 expected []pkg.Package 18 }{ 19 { 20 input: "test-fixtures/pom/pom.xml", 21 expected: []pkg.Package{ 22 { 23 Name: "joda-time", 24 Version: "2.9.2", 25 PURL: "pkg:maven/com.joda/joda-time@2.9.2", 26 Language: pkg.Java, 27 Type: pkg.JavaPkg, 28 MetadataType: pkg.JavaMetadataType, 29 Metadata: pkg.JavaMetadata{ 30 PomProperties: &pkg.PomProperties{ 31 GroupID: "com.joda", 32 ArtifactID: "joda-time", 33 }, 34 }, 35 }, 36 { 37 Name: "junit", 38 Version: "4.12", 39 PURL: "pkg:maven/junit/junit@4.12", 40 Language: pkg.Java, 41 Type: pkg.JavaPkg, 42 MetadataType: pkg.JavaMetadataType, 43 Metadata: pkg.JavaMetadata{ 44 PomProperties: &pkg.PomProperties{ 45 GroupID: "junit", 46 ArtifactID: "junit", 47 Scope: "test", 48 }, 49 }, 50 }, 51 }, 52 }, 53 } 54 55 for _, test := range tests { 56 t.Run(test.input, func(t *testing.T) { 57 for i := range test.expected { 58 test.expected[i].Locations.Add(file.NewLocation(test.input)) 59 } 60 pkgtest.TestFileParser(t, test.input, parserPomXML, test.expected, nil) 61 }) 62 } 63 } 64 65 func Test_parseCommonsTextPomXMLProject(t *testing.T) { 66 tests := []struct { 67 input string 68 expected []pkg.Package 69 }{ 70 { 71 input: "test-fixtures/pom/commons-text.pom.xml", 72 expected: []pkg.Package{ 73 { 74 Name: "commons-lang3", 75 Version: "3.12.0", 76 PURL: "pkg:maven/org.apache.commons/commons-lang3@3.12.0", 77 Language: pkg.Java, 78 Type: pkg.JavaPkg, 79 MetadataType: pkg.JavaMetadataType, 80 Metadata: pkg.JavaMetadata{ 81 PomProperties: &pkg.PomProperties{ 82 GroupID: "org.apache.commons", 83 ArtifactID: "commons-lang3", 84 }, 85 }, 86 }, 87 { 88 Name: "junit-jupiter", 89 Version: "", 90 PURL: "pkg:maven/org.junit.jupiter/junit-jupiter", 91 Language: pkg.Java, 92 Type: pkg.JavaPkg, 93 MetadataType: pkg.JavaMetadataType, 94 Metadata: pkg.JavaMetadata{ 95 PomProperties: &pkg.PomProperties{ 96 GroupID: "org.junit.jupiter", 97 ArtifactID: "junit-jupiter", 98 Scope: "test", 99 }, 100 }, 101 }, 102 { 103 Name: "assertj-core", 104 Version: "3.23.1", 105 PURL: "pkg:maven/org.assertj/assertj-core@3.23.1", 106 Language: pkg.Java, 107 Type: pkg.JavaPkg, 108 MetadataType: pkg.JavaMetadataType, 109 Metadata: pkg.JavaMetadata{ 110 PomProperties: &pkg.PomProperties{ 111 GroupID: "org.assertj", 112 ArtifactID: "assertj-core", 113 Scope: "test", 114 }, 115 }, 116 }, 117 { 118 Name: "commons-io", 119 Version: "2.11.0", 120 PURL: "pkg:maven/commons-io/commons-io@2.11.0", 121 Language: pkg.Java, 122 Type: pkg.JavaPkg, 123 MetadataType: pkg.JavaMetadataType, 124 Metadata: pkg.JavaMetadata{ 125 PomProperties: &pkg.PomProperties{ 126 GroupID: "commons-io", 127 ArtifactID: "commons-io", 128 Scope: "test", 129 }, 130 }, 131 }, 132 { 133 Name: "mockito-inline", 134 Version: "4.8.0", 135 PURL: "pkg:maven/org.mockito/mockito-inline@4.8.0", 136 Language: pkg.Java, 137 Type: pkg.JavaPkg, 138 MetadataType: pkg.JavaMetadataType, 139 Metadata: pkg.JavaMetadata{ 140 PomProperties: &pkg.PomProperties{ 141 GroupID: "org.mockito", 142 ArtifactID: "mockito-inline", 143 Scope: "test", 144 }, 145 }, 146 }, 147 { 148 Name: "js", 149 Version: "22.0.0.2", 150 PURL: "pkg:maven/org.graalvm.js/js@22.0.0.2", 151 Language: pkg.Java, 152 Type: pkg.JavaPkg, 153 MetadataType: pkg.JavaMetadataType, 154 Metadata: pkg.JavaMetadata{ 155 PomProperties: &pkg.PomProperties{ 156 GroupID: "org.graalvm.js", 157 ArtifactID: "js", 158 Scope: "test", 159 }, 160 }, 161 }, 162 { 163 Name: "js-scriptengine", 164 Version: "22.0.0.2", 165 PURL: "pkg:maven/org.graalvm.js/js-scriptengine@22.0.0.2", 166 Language: pkg.Java, 167 Type: pkg.JavaPkg, 168 MetadataType: pkg.JavaMetadataType, 169 Metadata: pkg.JavaMetadata{ 170 PomProperties: &pkg.PomProperties{ 171 GroupID: "org.graalvm.js", 172 ArtifactID: "js-scriptengine", 173 Scope: "test", 174 }, 175 }, 176 }, 177 { 178 Name: "commons-rng-simple", 179 Version: "1.4", 180 PURL: "pkg:maven/org.apache.commons/commons-rng-simple@1.4", 181 Language: pkg.Java, 182 Type: pkg.JavaPkg, 183 MetadataType: pkg.JavaMetadataType, 184 Metadata: pkg.JavaMetadata{ 185 PomProperties: &pkg.PomProperties{ 186 GroupID: "org.apache.commons", 187 ArtifactID: "commons-rng-simple", 188 Scope: "test", 189 }, 190 }, 191 }, 192 { 193 Name: "jmh-core", 194 Version: "1.35", 195 PURL: "pkg:maven/org.openjdk.jmh/jmh-core@1.35", 196 Language: pkg.Java, 197 Type: pkg.JavaPkg, 198 MetadataType: pkg.JavaMetadataType, 199 Metadata: pkg.JavaMetadata{ 200 PomProperties: &pkg.PomProperties{ 201 GroupID: "org.openjdk.jmh", 202 ArtifactID: "jmh-core", 203 Scope: "test", 204 }, 205 }, 206 }, 207 { 208 Name: "jmh-generator-annprocess", 209 Version: "1.35", 210 PURL: "pkg:maven/org.openjdk.jmh/jmh-generator-annprocess@1.35", 211 Language: pkg.Java, 212 Type: pkg.JavaPkg, 213 MetadataType: pkg.JavaMetadataType, 214 Metadata: pkg.JavaMetadata{ 215 PomProperties: &pkg.PomProperties{ 216 GroupID: "org.openjdk.jmh", 217 ArtifactID: "jmh-generator-annprocess", 218 Scope: "test", 219 }, 220 }, 221 }, 222 }, 223 }, 224 } 225 226 for _, test := range tests { 227 t.Run(test.input, func(t *testing.T) { 228 for i := range test.expected { 229 test.expected[i].Locations.Add(file.NewLocation(test.input)) 230 } 231 pkgtest.TestFileParser(t, test.input, parserPomXML, test.expected, nil) 232 }) 233 } 234 } 235 236 func Test_parsePomXMLProject(t *testing.T) { 237 tests := []struct { 238 expected pkg.PomProject 239 }{ 240 { 241 expected: pkg.PomProject{ 242 Path: "test-fixtures/pom/commons-codec.pom.xml", 243 Parent: &pkg.PomParent{ 244 GroupID: "org.apache.commons", 245 ArtifactID: "commons-parent", 246 Version: "42", 247 }, 248 GroupID: "commons-codec", 249 ArtifactID: "commons-codec", 250 Version: "1.11", 251 Name: "Apache Commons Codec", 252 Description: "The Apache Commons Codec package contains simple encoder and decoders for various formats such as Base64 and Hexadecimal. In addition to these widely used encoders and decoders, the codec package also maintains a collection of phonetic encoding utilities.", 253 URL: "http://commons.apache.org/proper/commons-codec/", 254 }, 255 }, 256 } 257 258 for _, test := range tests { 259 t.Run(test.expected.Path, func(t *testing.T) { 260 fixture, err := os.Open(test.expected.Path) 261 assert.NoError(t, err) 262 263 actual, err := parsePomXMLProject(fixture.Name(), fixture) 264 assert.NoError(t, err) 265 266 assert.Equal(t, &test.expected, actual) 267 }) 268 } 269 } 270 271 func Test_pomParent(t *testing.T) { 272 tests := []struct { 273 name string 274 input gopom.Parent 275 expected *pkg.PomParent 276 }{ 277 { 278 name: "only group ID", 279 input: gopom.Parent{ 280 GroupID: "org.something", 281 }, 282 expected: &pkg.PomParent{ 283 GroupID: "org.something", 284 }, 285 }, 286 { 287 name: "only artifact ID", 288 input: gopom.Parent{ 289 ArtifactID: "something", 290 }, 291 expected: &pkg.PomParent{ 292 ArtifactID: "something", 293 }, 294 }, 295 { 296 name: "only Version", 297 input: gopom.Parent{ 298 Version: "something", 299 }, 300 expected: &pkg.PomParent{ 301 Version: "something", 302 }, 303 }, 304 { 305 name: "empty", 306 input: gopom.Parent{}, 307 expected: nil, 308 }, 309 { 310 name: "unused field", 311 input: gopom.Parent{ 312 RelativePath: "something", 313 }, 314 expected: nil, 315 }, 316 } 317 318 for _, test := range tests { 319 t.Run(test.name, func(t *testing.T) { 320 assert.Equal(t, test.expected, pomParent(gopom.Project{}, test.input)) 321 }) 322 } 323 } 324 325 func Test_cleanDescription(t *testing.T) { 326 tests := []struct { 327 name string 328 input string 329 expected string 330 }{ 331 { 332 name: "indent + multiline", 333 input: ` The Apache Commons Codec package contains simple encoder and decoders for 334 various formats such as Base64 and Hexadecimal. In addition to these 335 widely used encoders and decoders, the codec package also maintains a 336 collection of phonetic encoding utilities.`, 337 expected: "The Apache Commons Codec package contains simple encoder and decoders for various formats such as Base64 and Hexadecimal. In addition to these widely used encoders and decoders, the codec package also maintains a collection of phonetic encoding utilities.", 338 }, 339 } 340 341 for _, test := range tests { 342 t.Run(test.name, func(t *testing.T) { 343 assert.Equal(t, test.expected, cleanDescription(test.input)) 344 }) 345 } 346 } 347 348 func Test_resolveProperty(t *testing.T) { 349 tests := []struct { 350 name string 351 property string 352 pom gopom.Project 353 expected string 354 }{ 355 { 356 name: "property", 357 property: "${version.number}", 358 pom: gopom.Project{ 359 Properties: gopom.Properties{ 360 Entries: map[string]string{ 361 "version.number": "12.5.0", 362 }, 363 }, 364 }, 365 expected: "12.5.0", 366 }, 367 { 368 name: "groupId", 369 property: "${project.groupId}", 370 pom: gopom.Project{ 371 GroupID: "org.some.group", 372 }, 373 expected: "org.some.group", 374 }, 375 { 376 name: "parent groupId", 377 property: "${project.parent.groupId}", 378 pom: gopom.Project{ 379 Parent: gopom.Parent{ 380 GroupID: "org.some.parent", 381 }, 382 }, 383 expected: "org.some.parent", 384 }, 385 } 386 387 for _, test := range tests { 388 t.Run(test.name, func(t *testing.T) { 389 resolved := resolveProperty(test.pom, test.property) 390 assert.Equal(t, test.expected, resolved) 391 }) 392 } 393 }