github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/syft/pkg/cataloger/javascript/parse_package_lock_test.go (about) 1 package javascript 2 3 import ( 4 "testing" 5 6 "github.com/anchore/syft/syft/artifact" 7 "github.com/anchore/syft/syft/file" 8 "github.com/anchore/syft/syft/pkg" 9 "github.com/lineaje-labs/syft/syft/pkg/cataloger/internal/pkgtest" 10 ) 11 12 func TestParsePackageLock(t *testing.T) { 13 var expectedRelationships []artifact.Relationship 14 expectedPkgs := []pkg.Package{ 15 { 16 Name: "@actions/core", 17 Version: "1.6.0", 18 PURL: "pkg:npm/%40actions/core@1.6.0", 19 Language: pkg.JavaScript, 20 Type: pkg.NpmPkg, 21 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", Integrity: "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw=="}, 22 }, 23 { 24 Name: "ansi-regex", 25 Version: "3.0.0", 26 PURL: "pkg:npm/ansi-regex@3.0.0", 27 Language: pkg.JavaScript, 28 Type: pkg.NpmPkg, 29 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", Integrity: "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="}, 30 }, 31 { 32 Name: "cowsay", 33 Version: "1.4.0", 34 PURL: "pkg:npm/cowsay@1.4.0", 35 Language: pkg.JavaScript, 36 Type: pkg.NpmPkg, 37 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/cowsay/-/cowsay-1.4.0.tgz", Integrity: "sha512-rdg5k5PsHFVJheO/pmE3aDg2rUDDTfPJau6yYkZYlHFktUz+UxbE+IgnUAEyyCyv4noL5ltxXD0gZzmHPCy/9g=="}, 38 }, 39 { 40 Name: "get-stdin", 41 Version: "5.0.1", 42 PURL: "pkg:npm/get-stdin@5.0.1", 43 Language: pkg.JavaScript, 44 Type: pkg.NpmPkg, 45 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", Integrity: "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g="}, 46 }, 47 { 48 Name: "is-fullwidth-code-point", 49 Version: "2.0.0", 50 PURL: "pkg:npm/is-fullwidth-code-point@2.0.0", 51 Language: pkg.JavaScript, 52 Type: pkg.NpmPkg, 53 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", Integrity: "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="}, 54 }, 55 { 56 Name: "minimist", 57 Version: "0.0.10", 58 PURL: "pkg:npm/minimist@0.0.10", 59 Language: pkg.JavaScript, 60 Type: pkg.NpmPkg, 61 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", Integrity: "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="}, 62 }, 63 { 64 Name: "optimist", 65 Version: "0.6.1", 66 PURL: "pkg:npm/optimist@0.6.1", 67 Language: pkg.JavaScript, 68 Type: pkg.NpmPkg, 69 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", Integrity: "sha1-2j6nRob6IaGaERwybpDrFaAZZoY="}, 70 }, 71 { 72 Name: "string-width", 73 Version: "2.1.1", 74 PURL: "pkg:npm/string-width@2.1.1", 75 Language: pkg.JavaScript, 76 Type: pkg.NpmPkg, 77 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", Integrity: "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw=="}, 78 }, 79 { 80 Name: "strip-ansi", 81 Version: "4.0.0", 82 PURL: "pkg:npm/strip-ansi@4.0.0", 83 Language: pkg.JavaScript, 84 Type: pkg.NpmPkg, 85 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", Integrity: "sha1-qEeQIusaw2iocTibY1JixQXuNo8="}, 86 }, 87 { 88 Name: "strip-eof", 89 Version: "1.0.0", 90 PURL: "pkg:npm/strip-eof@1.0.0", 91 Language: pkg.JavaScript, 92 Type: pkg.NpmPkg, 93 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", Integrity: "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="}, 94 }, 95 { 96 Name: "wordwrap", 97 Version: "0.0.3", 98 PURL: "pkg:npm/wordwrap@0.0.3", 99 Language: pkg.JavaScript, 100 Type: pkg.NpmPkg, 101 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", Integrity: "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="}, 102 }, 103 } 104 fixture := "test-fixtures/pkg-lock/package-lock.json" 105 for i := range expectedPkgs { 106 expectedPkgs[i].Locations.Add(file.NewLocation(fixture)) 107 } 108 109 pkgtest.TestFileParser(t, fixture, parsePackageLock, expectedPkgs, expectedRelationships) 110 } 111 112 func TestParsePackageLockV2(t *testing.T) { 113 fixture := "test-fixtures/pkg-lock/package-lock-2.json" 114 var expectedRelationships []artifact.Relationship 115 expectedPkgs := []pkg.Package{ 116 { 117 Name: "npm", 118 Version: "6.14.6", 119 Language: pkg.JavaScript, 120 Type: pkg.NpmPkg, 121 PURL: "pkg:npm/npm@6.14.6", 122 Metadata: pkg.NpmPackageLockEntry{}, 123 }, 124 { 125 Name: "@types/prop-types", 126 Version: "15.7.5", 127 PURL: "pkg:npm/%40types/prop-types@15.7.5", 128 Language: pkg.JavaScript, 129 Type: pkg.NpmPkg, 130 Licenses: pkg.NewLicenseSet( 131 pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), 132 ), 133 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", Integrity: "sha1-XxnSuFqY6VWANvajysyIGUIPBc8="}, 134 }, 135 { 136 Name: "@types/react", 137 Version: "18.0.17", 138 PURL: "pkg:npm/%40types/react@18.0.17", 139 Language: pkg.JavaScript, 140 Type: pkg.NpmPkg, 141 Licenses: pkg.NewLicenseSet( 142 pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), 143 ), 144 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/react/-/react-18.0.17.tgz", Integrity: "sha1-RYPZwyLWfv5LOak10iPtzHBQzPQ="}, 145 }, 146 { 147 Name: "@types/scheduler", 148 Version: "0.16.2", 149 PURL: "pkg:npm/%40types/scheduler@0.16.2", 150 Language: pkg.JavaScript, 151 Type: pkg.NpmPkg, 152 Licenses: pkg.NewLicenseSet( 153 pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), 154 ), 155 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", Integrity: "sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk="}, 156 }, 157 { 158 Name: "csstype", 159 Version: "3.1.0", 160 PURL: "pkg:npm/csstype@3.1.0", 161 Language: pkg.JavaScript, 162 Type: pkg.NpmPkg, 163 Licenses: pkg.NewLicenseSet( 164 pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), 165 ), 166 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", Integrity: "sha1-TdysNxjXh8+d8NG30VAzklyPKfI="}, 167 }, 168 } 169 for i := range expectedPkgs { 170 expectedPkgs[i].Locations.Add(file.NewLocation(fixture)) 171 } 172 pkgtest.TestFileParser(t, fixture, parsePackageLock, expectedPkgs, expectedRelationships) 173 } 174 175 func TestParsePackageLockV3(t *testing.T) { 176 fixture := "test-fixtures/pkg-lock/package-lock-3.json" 177 var expectedRelationships []artifact.Relationship 178 expectedPkgs := []pkg.Package{ 179 { 180 Name: "lock-v3-fixture", 181 Version: "1.0.0", 182 Language: pkg.JavaScript, 183 Type: pkg.NpmPkg, 184 PURL: "pkg:npm/lock-v3-fixture@1.0.0", 185 Metadata: pkg.NpmPackageLockEntry{}, 186 }, 187 { 188 Name: "@types/prop-types", 189 Version: "15.7.5", 190 Language: pkg.JavaScript, 191 Type: pkg.NpmPkg, 192 PURL: "pkg:npm/%40types/prop-types@15.7.5", 193 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", Integrity: "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="}, 194 }, 195 { 196 Name: "@types/react", 197 Version: "18.0.20", 198 Language: pkg.JavaScript, 199 Type: pkg.NpmPkg, 200 PURL: "pkg:npm/%40types/react@18.0.20", 201 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/react/-/react-18.0.20.tgz", Integrity: "sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA=="}, 202 }, 203 { 204 Name: "@types/scheduler", 205 Version: "0.16.2", 206 Language: pkg.JavaScript, 207 Type: pkg.NpmPkg, 208 PURL: "pkg:npm/%40types/scheduler@0.16.2", 209 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", Integrity: "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="}, 210 }, 211 { 212 Name: "csstype", 213 Version: "3.1.1", 214 Language: pkg.JavaScript, 215 Type: pkg.NpmPkg, 216 PURL: "pkg:npm/csstype@3.1.1", 217 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", Integrity: "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="}, 218 }, 219 } 220 for i := range expectedPkgs { 221 expectedPkgs[i].Locations.Add(file.NewLocation(fixture)) 222 } 223 pkgtest.TestFileParser(t, fixture, parsePackageLock, expectedPkgs, expectedRelationships) 224 } 225 226 func TestParsePackageLockAlias(t *testing.T) { 227 var expectedRelationships []artifact.Relationship 228 commonPkgs := []pkg.Package{ 229 { 230 Name: "case", 231 Version: "1.6.2", 232 PURL: "pkg:npm/case@1.6.2", 233 Language: pkg.JavaScript, 234 Type: pkg.NpmPkg, 235 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/case/-/case-1.6.2.tgz", Integrity: "sha512-ll380ZRoraT7mUK2G92UbH+FJVD5AwdVIAYk9xhV1tauh0carDgYByUD1HhjCWsWgxrfQvCeHvtfj7IYR6TKeg=="}, 236 }, 237 { 238 Name: "case", 239 Version: "1.6.3", 240 PURL: "pkg:npm/case@1.6.3", 241 Language: pkg.JavaScript, 242 Type: pkg.NpmPkg, 243 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/case/-/case-1.6.3.tgz", Integrity: "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ=="}, 244 }, 245 { 246 Name: "@bundled-es-modules/chai", 247 Version: "4.2.2", 248 PURL: "pkg:npm/%40bundled-es-modules/chai@4.2.2", 249 Language: pkg.JavaScript, 250 Type: pkg.NpmPkg, 251 Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@bundled-es-modules/chai/-/chai-4.2.2.tgz", Integrity: "sha512-iGmVYw2/zJCoqyKTtWEYCtFmMyi8WmACQKtky0lpNyEKWX0YIOpKWGD7saMXL+tPpllss0otilxV0SLwyi3Ytg=="}, 252 }, 253 } 254 255 packageLockV1 := "test-fixtures/pkg-lock/alias-package-lock-1.json" 256 packageLockV2 := "test-fixtures/pkg-lock/alias-package-lock-2.json" 257 packageLocks := []string{packageLockV1, packageLockV2} 258 259 v2Pkg := pkg.Package{ 260 Name: "alias-check", 261 Version: "1.0.0", 262 PURL: "pkg:npm/alias-check@1.0.0", 263 Language: pkg.JavaScript, 264 Type: pkg.NpmPkg, 265 Licenses: pkg.NewLicenseSet( 266 pkg.NewLicenseFromLocations("ISC", file.NewLocation(packageLockV2)), 267 ), 268 Metadata: pkg.NpmPackageLockEntry{}, 269 } 270 271 for _, pl := range packageLocks { 272 expected := make([]pkg.Package, len(commonPkgs)) 273 copy(expected, commonPkgs) 274 275 if pl == packageLockV2 { 276 expected = append(expected, v2Pkg) 277 } 278 279 for i := range expected { 280 expected[i].Locations.Add(file.NewLocation(pl)) 281 } 282 pkgtest.TestFileParser(t, pl, parsePackageLock, expected, expectedRelationships) 283 } 284 } 285 286 func TestParsePackageLockLicenseWithArray(t *testing.T) { 287 fixture := "test-fixtures/pkg-lock/array-license-package-lock.json" 288 var expectedRelationships []artifact.Relationship 289 expectedPkgs := []pkg.Package{ 290 { 291 Name: "tmp", 292 Version: "1.0.0", 293 Language: pkg.JavaScript, 294 Type: pkg.NpmPkg, 295 Licenses: pkg.NewLicenseSet( 296 pkg.NewLicenseFromLocations("ISC", file.NewLocation(fixture)), 297 ), 298 PURL: "pkg:npm/tmp@1.0.0", 299 Metadata: pkg.NpmPackageLockEntry{}, 300 }, 301 { 302 Name: "pause-stream", 303 Version: "0.0.11", 304 Language: pkg.JavaScript, 305 Type: pkg.NpmPkg, 306 307 Licenses: pkg.NewLicenseSet( 308 pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), 309 pkg.NewLicenseFromLocations("Apache2", file.NewLocation(fixture)), 310 ), 311 PURL: "pkg:npm/pause-stream@0.0.11", 312 Metadata: pkg.NpmPackageLockEntry{}, 313 }, 314 { 315 Name: "through", 316 Version: "2.3.8", 317 Language: pkg.JavaScript, 318 Type: pkg.NpmPkg, 319 Licenses: pkg.NewLicenseSet( 320 pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), 321 ), 322 PURL: "pkg:npm/through@2.3.8", 323 Metadata: pkg.NpmPackageLockEntry{}, 324 }, 325 } 326 for i := range expectedPkgs { 327 expectedPkgs[i].Locations.Add(file.NewLocation(fixture)) 328 } 329 pkgtest.TestFileParser(t, fixture, parsePackageLock, expectedPkgs, expectedRelationships) 330 }