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