github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/javascript/parse_package_json_test.go (about) 1 package javascript 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 9 "github.com/anchore/syft/syft/file" 10 "github.com/anchore/syft/syft/pkg" 11 "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" 12 ) 13 14 func TestParsePackageJSON(t *testing.T) { 15 ctx := context.TODO() 16 tests := []struct { 17 Fixture string 18 ExpectedPkg pkg.Package 19 }{ 20 { 21 Fixture: "test-fixtures/pkg-json/package.json", 22 ExpectedPkg: pkg.Package{ 23 Name: "npm", 24 Version: "6.14.6", 25 PURL: "pkg:npm/npm@6.14.6", 26 Type: pkg.NpmPkg, 27 Language: pkg.JavaScript, 28 Licenses: pkg.NewLicenseSet( 29 pkg.NewLicenseFromLocationsWithContext(ctx, "Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package.json")), 30 ), 31 Metadata: pkg.NpmPackage{ 32 Name: "npm", 33 Version: "6.14.6", 34 Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", 35 Homepage: "https://docs.npmjs.com/", 36 URL: "https://github.com/npm/cli", 37 Description: "a package manager for JavaScript", 38 }, 39 }, 40 }, 41 { 42 Fixture: "test-fixtures/pkg-json/package-license-object.json", 43 ExpectedPkg: pkg.Package{ 44 Name: "npm", 45 Version: "6.14.6", 46 PURL: "pkg:npm/npm@6.14.6", 47 Type: pkg.NpmPkg, 48 Language: pkg.JavaScript, 49 Licenses: pkg.NewLicenseSet( 50 pkg.NewLicenseFromLocationsWithContext(ctx, "ISC", file.NewLocation("test-fixtures/pkg-json/package-license-object.json")), 51 ), 52 Metadata: pkg.NpmPackage{ 53 Name: "npm", 54 Version: "6.14.6", 55 Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", 56 Homepage: "https://docs.npmjs.com/", 57 URL: "https://github.com/npm/cli", 58 Description: "a package manager for JavaScript", 59 }, 60 }, 61 }, 62 { 63 Fixture: "test-fixtures/pkg-json/package-license-objects.json", 64 ExpectedPkg: pkg.Package{ 65 Name: "npm", 66 Version: "6.14.6", 67 PURL: "pkg:npm/npm@6.14.6", 68 Type: pkg.NpmPkg, 69 Licenses: pkg.NewLicenseSet( 70 pkg.NewLicenseFromLocationsWithContext(ctx, "MIT", file.NewLocation("test-fixtures/pkg-json/package-license-objects.json")), 71 pkg.NewLicenseFromLocationsWithContext(ctx, "Apache-2.0", file.NewLocation("test-fixtures/pkg-json/package-license-objects.json")), 72 ), 73 Language: pkg.JavaScript, 74 Metadata: pkg.NpmPackage{ 75 Name: "npm", 76 Version: "6.14.6", 77 Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", 78 Homepage: "https://docs.npmjs.com/", 79 URL: "https://github.com/npm/cli", 80 Description: "a package manager for JavaScript", 81 }, 82 }, 83 }, 84 { 85 Fixture: "test-fixtures/pkg-json/package-malformed-license.json", 86 ExpectedPkg: pkg.Package{ 87 Name: "npm", 88 Version: "6.14.6", 89 PURL: "pkg:npm/npm@6.14.6", 90 Type: pkg.NpmPkg, 91 Language: pkg.JavaScript, 92 Metadata: pkg.NpmPackage{ 93 Name: "npm", 94 Version: "6.14.6", 95 Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", 96 Homepage: "https://docs.npmjs.com/", 97 URL: "https://github.com/npm/cli", 98 Description: "a package manager for JavaScript", 99 }, 100 }, 101 }, 102 { 103 Fixture: "test-fixtures/pkg-json/package-no-license.json", 104 ExpectedPkg: pkg.Package{ 105 Name: "npm", 106 Version: "6.14.6", 107 PURL: "pkg:npm/npm@6.14.6", 108 Type: pkg.NpmPkg, 109 Language: pkg.JavaScript, 110 Metadata: pkg.NpmPackage{ 111 Name: "npm", 112 Version: "6.14.6", 113 Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", 114 Homepage: "https://docs.npmjs.com/", 115 URL: "https://github.com/npm/cli", 116 Description: "a package manager for JavaScript", 117 }, 118 }, 119 }, 120 { 121 Fixture: "test-fixtures/pkg-json/package-nested-author.json", 122 ExpectedPkg: pkg.Package{ 123 Name: "npm", 124 Version: "6.14.6", 125 PURL: "pkg:npm/npm@6.14.6", 126 Type: pkg.NpmPkg, 127 Licenses: pkg.NewLicenseSet( 128 pkg.NewLicenseFromLocationsWithContext(ctx, "Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-nested-author.json")), 129 ), 130 Language: pkg.JavaScript, 131 Metadata: pkg.NpmPackage{ 132 Name: "npm", 133 Version: "6.14.6", 134 Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", 135 Homepage: "https://docs.npmjs.com/", 136 URL: "https://github.com/npm/cli", 137 Description: "a package manager for JavaScript", 138 }, 139 }, 140 }, 141 { 142 Fixture: "test-fixtures/pkg-json/package-repo-string.json", 143 ExpectedPkg: pkg.Package{ 144 Name: "function-bind", 145 Version: "1.1.1", 146 PURL: "pkg:npm/function-bind@1.1.1", 147 Type: pkg.NpmPkg, 148 Licenses: pkg.NewLicenseSet( 149 pkg.NewLicenseFromLocationsWithContext(ctx, "MIT", file.NewLocation("test-fixtures/pkg-json/package-repo-string.json")), 150 ), 151 Language: pkg.JavaScript, 152 Metadata: pkg.NpmPackage{ 153 Name: "function-bind", 154 Version: "1.1.1", 155 Author: "Raynos <raynos2@gmail.com>, Raynos, Jordan Harband (https://github.com/ljharb)", 156 Homepage: "https://github.com/Raynos/function-bind", 157 URL: "git://github.com/Raynos/function-bind.git", 158 Description: "Implementation of Function.prototype.bind", 159 }, 160 }, 161 }, 162 { 163 Fixture: "test-fixtures/pkg-json/package-private.json", 164 ExpectedPkg: pkg.Package{ 165 Name: "npm", 166 Version: "6.14.6", 167 PURL: "pkg:npm/npm@6.14.6", 168 Type: pkg.NpmPkg, 169 Licenses: pkg.NewLicenseSet( 170 pkg.NewLicenseFromLocationsWithContext(ctx, "Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-private.json")), 171 ), 172 Language: pkg.JavaScript, 173 Metadata: pkg.NpmPackage{ 174 Name: "npm", 175 Version: "6.14.6", 176 Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", 177 Homepage: "https://docs.npmjs.com/", 178 URL: "https://github.com/npm/cli", 179 Private: true, 180 Description: "a package manager for JavaScript", 181 }, 182 }, 183 }, 184 { 185 Fixture: "test-fixtures/pkg-json/package-author-non-standard.json", 186 ExpectedPkg: pkg.Package{ 187 Name: "npm", 188 Version: "6.14.6", 189 PURL: "pkg:npm/npm@6.14.6", 190 Type: pkg.NpmPkg, 191 Licenses: pkg.NewLicenseSet( 192 pkg.NewLicenseFromLocationsWithContext(ctx, "Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-author-non-standard.json")), 193 ), 194 Language: pkg.JavaScript, 195 Metadata: pkg.NpmPackage{ 196 Name: "npm", 197 Version: "6.14.6", 198 Author: "npm Inc. (https://www.npmjs.com/)", 199 Homepage: "https://docs.npmjs.com/", 200 URL: "https://github.com/npm/cli", 201 Description: "a package manager for JavaScript", 202 }, 203 }, 204 }, 205 { 206 Fixture: "test-fixtures/pkg-json/package-authors-array.json", 207 ExpectedPkg: pkg.Package{ 208 Name: "npm", 209 Version: "6.14.6", 210 PURL: "pkg:npm/npm@6.14.6", 211 Type: pkg.NpmPkg, 212 Licenses: pkg.NewLicenseSet( 213 pkg.NewLicenseFromLocationsWithContext(ctx, "Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-authors-array.json")), 214 ), 215 Language: pkg.JavaScript, 216 Metadata: pkg.NpmPackage{ 217 Name: "npm", 218 Version: "6.14.6", 219 Author: "Harry Potter <hp@hogwards.com> (http://youknowwho.com/), John Smith <j.smith@something.com> (http://awebsite.com/)", 220 Homepage: "https://docs.npmjs.com/", 221 URL: "https://github.com/npm/cli", 222 Description: "a package manager for JavaScript", 223 }, 224 }, 225 }, 226 { 227 Fixture: "test-fixtures/pkg-json/package-authors-objects.json", 228 ExpectedPkg: pkg.Package{ 229 Name: "npm", 230 Version: "6.14.6", 231 PURL: "pkg:npm/npm@6.14.6", 232 Type: pkg.NpmPkg, 233 Licenses: pkg.NewLicenseSet( 234 pkg.NewLicenseFromLocationsWithContext(ctx, "Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-authors-objects.json")), 235 ), 236 Language: pkg.JavaScript, 237 Metadata: pkg.NpmPackage{ 238 Name: "npm", 239 Version: "6.14.6", 240 Author: "Harry Potter <hp@hogwards.com> (http://youknowwho.com/), John Smith <j.smith@something.com> (http://awebsite.com/)", 241 Homepage: "https://docs.npmjs.com/", 242 URL: "https://github.com/npm/cli", 243 Description: "a package manager for JavaScript", 244 }, 245 }, 246 }, 247 { 248 Fixture: "test-fixtures/pkg-json/package-both-author-and-authors.json", 249 ExpectedPkg: pkg.Package{ 250 Name: "npm", 251 Version: "6.14.6", 252 PURL: "pkg:npm/npm@6.14.6", 253 Type: pkg.NpmPkg, 254 Licenses: pkg.NewLicenseSet( 255 pkg.NewLicenseFromLocationsWithContext(ctx, "Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-both-author-and-authors.json")), 256 ), 257 Language: pkg.JavaScript, 258 Metadata: pkg.NpmPackage{ 259 Name: "npm", 260 Version: "6.14.6", 261 Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me), Harry Potter <hp@hogwards.com> (http://youknowwho.com/), John Smith <j.smith@something.com> (http://awebsite.com/)", 262 Homepage: "https://docs.npmjs.com/", 263 URL: "https://github.com/npm/cli", 264 Description: "a package manager for JavaScript", 265 }, 266 }, 267 }, 268 { 269 Fixture: "test-fixtures/pkg-json/package-contributors.json", 270 ExpectedPkg: pkg.Package{ 271 Name: "npm", 272 Version: "6.14.6", 273 PURL: "pkg:npm/npm@6.14.6", 274 Type: pkg.NpmPkg, 275 Licenses: pkg.NewLicenseSet( 276 pkg.NewLicenseFromLocationsWithContext(ctx, "Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-contributors.json")), 277 ), 278 Language: pkg.JavaScript, 279 Metadata: pkg.NpmPackage{ 280 Name: "npm", 281 Version: "6.14.6", 282 Author: "Alice Contributor <alice@example.com>, Bob Helper <bob@example.com>", 283 Homepage: "https://docs.npmjs.com/", 284 URL: "https://github.com/npm/cli", 285 Description: "a package manager for JavaScript", 286 }, 287 }, 288 }, 289 { 290 Fixture: "test-fixtures/pkg-json/package-maintainers.json", 291 ExpectedPkg: pkg.Package{ 292 Name: "npm", 293 Version: "6.14.6", 294 PURL: "pkg:npm/npm@6.14.6", 295 Type: pkg.NpmPkg, 296 Licenses: pkg.NewLicenseSet( 297 pkg.NewLicenseFromLocationsWithContext(ctx, "Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-maintainers.json")), 298 ), 299 Language: pkg.JavaScript, 300 Metadata: pkg.NpmPackage{ 301 Name: "npm", 302 Version: "6.14.6", 303 Author: "Charlie Maintainer <charlie@example.com>, Diana Keeper <diana@example.com>", 304 Homepage: "https://docs.npmjs.com/", 305 URL: "https://github.com/npm/cli", 306 Description: "a package manager for JavaScript", 307 }, 308 }, 309 }, 310 { 311 Fixture: "test-fixtures/pkg-json/package-all-author-fields.json", 312 ExpectedPkg: pkg.Package{ 313 Name: "npm", 314 Version: "6.14.6", 315 PURL: "pkg:npm/npm@6.14.6", 316 Type: pkg.NpmPkg, 317 Licenses: pkg.NewLicenseSet( 318 pkg.NewLicenseFromLocationsWithContext(ctx, "Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-all-author-fields.json")), 319 ), 320 Language: pkg.JavaScript, 321 Metadata: pkg.NpmPackage{ 322 Name: "npm", 323 Version: "6.14.6", 324 Author: "Main Author <main@example.com>, Second Author <second@example.com>, Contrib One <contrib1@example.com>, Maintainer One <maintain1@example.com>", 325 Homepage: "https://docs.npmjs.com/", 326 URL: "https://github.com/npm/cli", 327 Description: "a package manager for JavaScript", 328 }, 329 }, 330 }, 331 } 332 333 for _, test := range tests { 334 t.Run(test.Fixture, func(t *testing.T) { 335 test.ExpectedPkg.Locations.Add(file.NewLocation(test.Fixture)) 336 pkgtest.TestFileParser(t, test.Fixture, parsePackageJSON, []pkg.Package{test.ExpectedPkg}, nil) 337 }) 338 } 339 } 340 341 func Test_corruptPackageJSON(t *testing.T) { 342 pkgtest.NewCatalogTester(). 343 FromFile(t, "test-fixtures/corrupt/package.json"). 344 WithError(). 345 TestParser(t, parsePackageJSON) 346 } 347 348 func TestParsePackageJSON_Partial(t *testing.T) { // see https://github.com/anchore/syft/issues/311 349 const fixtureFile = "test-fixtures/pkg-json/package-partial.json" 350 351 // raise package.json files as packages with any information we find, these will be filtered out 352 // according to compliance rules later 353 expectedPkgs := []pkg.Package{ 354 { 355 Language: pkg.JavaScript, 356 Type: pkg.NpmPkg, 357 PURL: packageURL("", ""), 358 Metadata: pkg.NpmPackage{}, 359 Locations: file.NewLocationSet(file.NewLocation(fixtureFile)), 360 }, 361 } 362 pkgtest.TestFileParser(t, fixtureFile, parsePackageJSON, expectedPkgs, nil) 363 } 364 365 func Test_pathContainsNodeModulesDirectory(t *testing.T) { 366 tests := []struct { 367 path string 368 expected bool 369 }{ 370 // positive 371 { 372 path: "something/node_modules/package", 373 expected: true, 374 }, 375 { 376 path: "node_modules/package", 377 expected: true, 378 }, 379 { 380 path: "something/node_modules", 381 expected: true, 382 }, 383 { 384 path: "\\something\\node_modules\\", 385 expected: true, 386 }, 387 { 388 path: "\\something\\node_modules", 389 expected: true, 390 }, 391 // negative 392 { 393 path: "something/node_bogus_modules", 394 expected: false, 395 }, 396 { 397 path: "something/node_modules_bogus", 398 expected: false, 399 }, 400 { 401 path: "something/node_bogus_modules/package", 402 expected: false, 403 }, 404 } 405 for _, test := range tests { 406 t.Run(test.path, func(t *testing.T) { 407 assert.Equal(t, test.expected, pathContainsNodeModulesDirectory(test.path)) 408 }) 409 } 410 }