diff --git a/build/testdata/npm/project6/node_modules/dummy-file b/build/testdata/npm/project6/node_modules/dummy-file new file mode 100644 index 00000000..e69de29b diff --git a/build/testdata/npm/project6/package-lock_test.json b/build/testdata/npm/project6/package-lock_test.json new file mode 100644 index 00000000..28c7bf77 --- /dev/null +++ b/build/testdata/npm/project6/package-lock_test.json @@ -0,0 +1,36 @@ +{ + "name": "project6", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "project6", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "lightweight": "^0.1.0", + "minimist": "^0.1.0", + "underscore": "^1.13.6" + } + }, + "node_modules/lightweight": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lightweight/-/lightweight-0.1.0.tgz", + "integrity": "sha512-10pYSQA9EJqZZnXDR0urhg8Z0Y1XnRfi41ZFj3ZFTKJ5PjRq82HzT7LKlPyxewy3w2WA2POfi3jQQn7Y53oPcQ==", + "bin": { + "lwt": "bin/lwt.js" + } + }, + "node_modules/minimist": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz", + "integrity": "sha512-wR5Ipl99t0mTGwLjQJnBjrP/O7zBbLZqvA3aw32DmLx+nXHfWctUjzDjnDx09pX1Po86WFQazF9xUzfMea3Cnw==" + }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + } + } +} diff --git a/build/testdata/npm/project6/package.json b/build/testdata/npm/project6/package.json new file mode 100644 index 00000000..9a4a6cbb --- /dev/null +++ b/build/testdata/npm/project6/package.json @@ -0,0 +1,17 @@ +{ + "name": "npm_test2", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "lightweight": "^0.1.0", + "minimist": "^0.1.0", + "underscore": "^1.13.6", + "cors.js": "0.0.1-security" + } +} diff --git a/build/utils/npm_test.go b/build/utils/npm_test.go index 83178e28..7727f8c2 100644 --- a/build/utils/npm_test.go +++ b/build/utils/npm_test.go @@ -1,10 +1,14 @@ package utils import ( + "github.com/jfrog/build-info-go/entities" + "github.com/stretchr/testify/require" "os" "path/filepath" "reflect" + "sort" "testing" + "time" testdatautils "github.com/jfrog/build-info-go/build/testdata" "github.com/jfrog/build-info-go/utils" @@ -198,6 +202,79 @@ func TestDependencyWithNoIntegrity(t *testing.T) { assert.Greaterf(t, len(dependencies), 0, "Error: dependencies are not found!") } +// This test case check that CalculateNpmDependenciesList ignore node_modules and update package-lock.json when needed, +// this according to the params 'IgnoreNodeModules' and 'OverWritePackageLock'. +func TestDependencyPackageLockOnly(t *testing.T) { + path, err := filepath.Abs(filepath.Join("..", "testdata/npm/project6")) + assert.NoError(t, err) + data, err := os.ReadFile(filepath.Join(path, "package-lock_test.json")) + require.NoError(t, err) + info, err := os.Stat(filepath.Join(path, "package-lock_test.json")) + require.NoError(t, err) + os.WriteFile(filepath.Join(path, "package-lock.json"), data, info.Mode().Perm()) + defer func() { + assert.NoError(t, os.Remove(filepath.Join(path, "package-lock.json"))) + assert.NoError(t, os.Remove(filepath.Join(path, "node_modules", ".package-lock.json"))) + }() + // sleep so the package.json modified time will be bigger than the package-lock.json, this make sure it will recalculate lock file. + time.Sleep(time.Millisecond * 5) + require.NoError(t, os.Chtimes(filepath.Join(path, "package.json"), time.Now(), time.Now())) + + // Calculate dependencies. + dependencies, err := CalculateNpmDependenciesList("npm", path, "jfrogtest", + NpmTreeDepListParam{Args: []string{}, IgnoreNodeModules: true, OverWritePackageLock: true}, true, logger) + assert.NoError(t, err) + expectedDeps := []entities.Dependency{{ + Id: "underscore:1.13.6", + Scopes: []string{"prod"}, + RequestedBy: [][]string{{"jfrogtest"}}, + Checksum: entities.Checksum{ + Sha1: "04786a1f589dc6c09f761fc5f45b89e935136441", + Md5: "945e1ea169a281c296b82ad2dd5466f6", + Sha256: "aef5a43ac7f903136a93e75a274e3a7b50de1a92277e1666457cabf62eeb0140", + }, + }, + { + Id: "cors.js:0.0.1-security", + Scopes: []string{"prod"}, + RequestedBy: [][]string{{"jfrogtest"}}, + Checksum: entities.Checksum{ + Sha1: "a1304531e44d11f4406b424b8377c3f3f1d3a934", + Md5: "f798d8a0d5e59e0d1b10a8fdc7660df0", + Sha256: "e2352450325dba7f38c45ec43ca77eab2cdba66fdb232061045e7039ada1da7e", + }, + }, + { + Id: "lightweight:0.1.0", + Scopes: []string{"prod"}, + RequestedBy: [][]string{{"jfrogtest"}}, + Checksum: entities.Checksum{ + Sha1: "5e154f8080f0e07a3a28950a5e5ee563df625ed3", + Md5: "8a0ac99046e2c9c962aee498633eccc3", + Sha256: "4119c009fa51fba45331235f00908ab77f2a402ee37e47dfc2dd8d422faa160f", + }, + }, + { + Id: "minimist:0.1.0", + Type: "", + Scopes: []string{"prod"}, + RequestedBy: [][]string{{"jfrogtest"}}, + Checksum: entities.Checksum{ + Sha1: "99df657a52574c21c9057497df742790b2b4c0de", + Md5: "0c9e3002c2af447fcf831fe3f751b2d8", + Sha256: "d8d08725641599bd538ef91f6e77109fec81f74aecaa994d568d61b44d06df6d", + }, + }, + } + sort.Slice(expectedDeps, func(i, j int) bool { + return expectedDeps[i].Id > expectedDeps[j].Id + }) + sort.Slice(dependencies, func(i, j int) bool { + return dependencies[i].Id > dependencies[j].Id + }) + assert.Equal(t, expectedDeps, dependencies) +} + // A project built differently for each operating system. func TestDependenciesTreeDifferentBetweenOKs(t *testing.T) { npmVersion, _, err := GetNpmVersionAndExecPath(logger)