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  }