Skip to content

Commit f8b6f63

Browse files
authored
Tests for Restricting user to use yarn v4 (#2866)
1 parent 8d5750c commit f8b6f63

File tree

10 files changed

+1135
-7
lines changed

10 files changed

+1135
-7
lines changed

.github/workflows/npmTests.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,6 @@ jobs:
4141
RTLIC: ${{ secrets.RTLIC }}
4242

4343
- name: Run npm tests
44+
env:
45+
YARN_IGNORE_NODE: 1
4446
run: go test -v github.com/jfrog/jfrog-cli --timeout 0 --test.npm

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,8 @@ require (
189189
sigs.k8s.io/yaml v1.4.0 // indirect
190190
)
191191

192-
replace github.com/jfrog/jfrog-cli-artifactory => github.com/jfrog/jfrog-cli-artifactory v0.1.13-0.20250219071539-9bcf054e67db
192+
replace github.com/jfrog/jfrog-cli-artifactory => github.com/jfrog/jfrog-cli-artifactory v0.1.13-0.20250221101554-05889536ad05
193193

194-
replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250221065317-8f044fe71fea
194+
replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250221100045-5b6a23a37852
195195

196196
replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20250221062042-87cb5136765e

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,10 @@ github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s=
185185
github.com/jfrog/gofrog v1.7.6/go.mod h1:ntr1txqNOZtHplmaNd7rS4f8jpA5Apx8em70oYEe7+4=
186186
github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY=
187187
github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w=
188-
github.com/jfrog/jfrog-cli-artifactory v0.1.13-0.20250219071539-9bcf054e67db h1:I9ywkE/lXJ/1S/0h2jjEWiqIKzWiJszE0VrjoGsorLk=
189-
github.com/jfrog/jfrog-cli-artifactory v0.1.13-0.20250219071539-9bcf054e67db/go.mod h1:EzlrSRtRoEipL+8axXHfgoUgXEoHZMVA6cElS2xK1w8=
190-
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250221065317-8f044fe71fea h1:ahP9eFJOw5K3AehHytj1H9nPGpswYfb3paTTwcBtwHg=
191-
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250221065317-8f044fe71fea/go.mod h1:VAVY5umw94aXf+yGzKCoEqijeUjIUNv+ikJUeQkd9tw=
188+
github.com/jfrog/jfrog-cli-artifactory v0.1.13-0.20250221101554-05889536ad05 h1:UV9W1ZImGWLks4+w+zg9hMtySvEIU+WxO73lsO6NIyY=
189+
github.com/jfrog/jfrog-cli-artifactory v0.1.13-0.20250221101554-05889536ad05/go.mod h1:223EqxDx7Ogrj7zJZkKAoFuQJStC5qtPXjwsf+r6d/A=
190+
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250221100045-5b6a23a37852 h1:tz6j/XO+BDoemr2LvQHN16ZHEG6dHT+79A+O+AvxXfk=
191+
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250221100045-5b6a23a37852/go.mod h1:VAVY5umw94aXf+yGzKCoEqijeUjIUNv+ikJUeQkd9tw=
192192
github.com/jfrog/jfrog-cli-platform-services v1.7.0 h1:u0AOyG4JX3VT7xhEeA9gDpBgW8tYILONpQURtzR3FkI=
193193
github.com/jfrog/jfrog-cli-platform-services v1.7.0/go.mod h1:u3lMRG7XC8MeUy/OPkHkZnsgCMIi0br4sjk2/W1Pm8I=
194194
github.com/jfrog/jfrog-cli-security v1.15.0 h1:TYNIID231X/AivYtptDCF25JyH8qTQht6ISHRfwejL8=

npm_test.go

Lines changed: 175 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
77
"github.com/jfrog/jfrog-client-go/http/httpclient"
88
"github.com/stretchr/testify/require"
9+
"gopkg.in/yaml.v2"
910
"net/http"
1011
"os"
1112
"os/exec"
@@ -669,7 +670,7 @@ func TestYarn(t *testing.T) {
669670
testDataTarget := filepath.Join(tempDirPath, tests.Out, "yarn")
670671
assert.NoError(t, biutils.CopyDir(testDataSource, testDataTarget, true, nil))
671672

672-
yarnProjectPath := filepath.Join(testDataTarget, "yarnproject")
673+
yarnProjectPath := filepath.Join(testDataTarget, "yarnprojectV2")
673674
assert.NoError(t, createConfigFileForTest([]string{yarnProjectPath}, tests.NpmRemoteRepo, "", t, project.Yarn, false))
674675

675676
wd, err := os.Getwd()
@@ -714,6 +715,169 @@ func TestYarn(t *testing.T) {
714715
inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, tests.YarnBuildName, artHttpDetails)
715716
}
716717

718+
func TestYarnSetVersion(t *testing.T) {
719+
initNpmTest(t)
720+
defer cleanNpmTest(t)
721+
722+
// Temporarily change the cache folder to a temporary folder - to make sure the cache is clean and dependencies will be downloaded from Artifactory
723+
tempDirPath, createTempDirCallback := coretests.CreateTempDirWithCallbackAndAssert(t)
724+
defer createTempDirCallback()
725+
726+
testDataSource := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "yarn")
727+
testDataTarget := filepath.Join(tempDirPath, tests.Out, "yarn")
728+
assert.NoError(t, biutils.CopyDir(testDataSource, testDataTarget, true, nil))
729+
730+
yarnProjectPath := filepath.Join(testDataTarget, "yarnprojectV2")
731+
assert.NoError(t, createConfigFileForTest([]string{yarnProjectPath}, tests.NpmRemoteRepo, "", t, project.Yarn, false))
732+
733+
wd, err := os.Getwd()
734+
assert.NoError(t, err, "Failed to get current dir")
735+
chdirCallback := clientTestUtils.ChangeDirWithCallback(t, wd, yarnProjectPath)
736+
defer chdirCallback()
737+
cleanUpYarnGlobalFolder := clientTestUtils.SetEnvWithCallbackAndAssert(t, "YARN_GLOBAL_FOLDER", tempDirPath)
738+
defer cleanUpYarnGlobalFolder()
739+
740+
// Add "localhost" to http whitelist
741+
yarnExecPath, err := exec.LookPath("yarn")
742+
assert.NoError(t, err)
743+
// Get original http white list config
744+
origWhitelist, err := yarn.ConfigGet("unsafeHttpWhitelist", yarnExecPath, true)
745+
assert.NoError(t, err)
746+
assert.NoError(t, yarn.ConfigSet("unsafeHttpWhitelist", "[\"localhost\"]", yarnExecPath, true))
747+
defer func() {
748+
// Restore original whitelist config
749+
assert.NoError(t, yarn.ConfigSet("unsafeHttpWhitelist", origWhitelist, yarnExecPath, true))
750+
}()
751+
752+
jfrogCli := coretests.NewJfrogCli(execMain, "jfrog", "")
753+
err = jfrogCli.Exec("yarn", "set", "version", "3.2.1")
754+
assert.NoError(t, err)
755+
modifyExistingYarnRc(t, "3.2.1")
756+
}
757+
758+
func TestYarnUpgradeToV4(t *testing.T) {
759+
initNpmTest(t)
760+
defer cleanNpmTest(t)
761+
762+
// Temporarily change the cache folder to a temporary folder - to make sure the cache is clean and dependencies will be downloaded from Artifactory
763+
tempDirPath, createTempDirCallback := coretests.CreateTempDirWithCallbackAndAssert(t)
764+
defer createTempDirCallback()
765+
766+
testDataSource := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "yarn")
767+
testDataTarget := filepath.Join(tempDirPath, tests.Out, "yarn")
768+
assert.NoError(t, biutils.CopyDir(testDataSource, testDataTarget, true, nil))
769+
770+
yarnProjectPath := filepath.Join(testDataTarget, "yarnprojectV2")
771+
assert.NoError(t, createConfigFileForTest([]string{yarnProjectPath}, tests.NpmRemoteRepo, "", t, project.Yarn, false))
772+
773+
wd, err := os.Getwd()
774+
assert.NoError(t, err, "Failed to get current dir")
775+
chdirCallback := clientTestUtils.ChangeDirWithCallback(t, wd, yarnProjectPath)
776+
defer chdirCallback()
777+
cleanUpYarnGlobalFolder := clientTestUtils.SetEnvWithCallbackAndAssert(t, "YARN_GLOBAL_FOLDER", tempDirPath)
778+
defer cleanUpYarnGlobalFolder()
779+
780+
// Add "localhost" to http whitelist
781+
yarnExecPath, err := exec.LookPath("yarn")
782+
assert.NoError(t, err)
783+
// Get original http white list config
784+
origWhitelist, err := yarn.ConfigGet("unsafeHttpWhitelist", yarnExecPath, true)
785+
assert.NoError(t, err)
786+
assert.NoError(t, yarn.ConfigSet("unsafeHttpWhitelist", "[\"localhost\"]", yarnExecPath, true))
787+
defer func() {
788+
// Restore original whitelist config
789+
assert.NoError(t, yarn.ConfigSet("unsafeHttpWhitelist", origWhitelist, yarnExecPath, true))
790+
}()
791+
792+
jfrogCli := coretests.NewJfrogCli(execMain, "jfrog", "")
793+
err = jfrogCli.Exec("yarn", "set", "version", "4.0.1")
794+
assert.Error(t, err)
795+
}
796+
797+
func TestYarnInV4(t *testing.T) {
798+
initNpmTest(t)
799+
defer cleanNpmTest(t)
800+
801+
// Temporarily change the cache folder to a temporary folder - to make sure the cache is clean and dependencies will be downloaded from Artifactory
802+
tempDirPath, createTempDirCallback := coretests.CreateTempDirWithCallbackAndAssert(t)
803+
defer createTempDirCallback()
804+
805+
testDataSource := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "yarn")
806+
testDataTarget := filepath.Join(tempDirPath, tests.Out, "yarn")
807+
assert.NoError(t, biutils.CopyDir(testDataSource, testDataTarget, true, nil))
808+
809+
wd, err := os.Getwd()
810+
assert.NoError(t, err, "Failed to get current dir")
811+
812+
yarnProjectPath := filepath.Join(testDataTarget, "yarnprojectV4")
813+
assert.NoError(t, createConfigFileForTest([]string{yarnProjectPath}, tests.NpmRemoteRepo, "", t, project.Yarn, false))
814+
chdirCallback := clientTestUtils.ChangeDirWithCallback(t, wd, yarnProjectPath)
815+
defer chdirCallback()
816+
cleanUpYarnGlobalFolder := clientTestUtils.SetEnvWithCallbackAndAssert(t, "YARN_GLOBAL_FOLDER", tempDirPath)
817+
defer cleanUpYarnGlobalFolder()
818+
819+
jfrogCli := coretests.NewJfrogCli(execMain, "jfrog", "")
820+
err = jfrogCli.Exec("yarn", "install")
821+
assert.Error(t, err)
822+
}
823+
824+
func TestYarnChangeVersionInV4(t *testing.T) {
825+
initNpmTest(t)
826+
defer cleanNpmTest(t)
827+
828+
// Temporarily change the cache folder to a temporary folder - to make sure the cache is clean and dependencies will be downloaded from Artifactory
829+
tempDirPath, createTempDirCallback := coretests.CreateTempDirWithCallbackAndAssert(t)
830+
defer createTempDirCallback()
831+
832+
testDataSource := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "yarn")
833+
testDataTarget := filepath.Join(tempDirPath, tests.Out, "yarn")
834+
assert.NoError(t, biutils.CopyDir(testDataSource, testDataTarget, true, nil))
835+
836+
yarnProjectPath := filepath.Join(testDataTarget, "yarnprojectV4")
837+
assert.NoError(t, createConfigFileForTest([]string{yarnProjectPath}, tests.NpmRemoteRepo, "", t, project.Yarn, false))
838+
839+
wd, err := os.Getwd()
840+
assert.NoError(t, err, "Failed to get current dir")
841+
chdirCallback := clientTestUtils.ChangeDirWithCallback(t, wd, yarnProjectPath)
842+
defer chdirCallback()
843+
cleanUpYarnGlobalFolder := clientTestUtils.SetEnvWithCallbackAndAssert(t, "YARN_GLOBAL_FOLDER", tempDirPath)
844+
defer cleanUpYarnGlobalFolder()
845+
846+
// Add "localhost" to http whitelist
847+
yarnExecPath, err := exec.LookPath("yarn")
848+
assert.NoError(t, err)
849+
850+
yarnrcPath := ".yarnrc.yml"
851+
data, err := os.ReadFile(yarnrcPath)
852+
assert.NoError(t, err)
853+
// Parse YAML
854+
var config = make(map[string]any)
855+
err = yaml.Unmarshal(data, &config)
856+
if err != nil {
857+
assert.NoError(t, err)
858+
}
859+
config["unsafeHttpWhitelist"] = []string{"localhost"}
860+
updatedYamlData, err := yaml.Marshal(&config)
861+
assert.NoError(t, err)
862+
err = os.WriteFile(yarnrcPath, updatedYamlData, 0644)
863+
assert.NoError(t, err)
864+
865+
assert.NoError(t, err)
866+
defer func() {
867+
// Restore original whitelist config
868+
assert.NoError(t, yarn.ConfigSet("unsafeHttpWhitelist", "[]", yarnExecPath, true))
869+
}()
870+
871+
jfrogCli := coretests.NewJfrogCli(execMain, "jfrog", "")
872+
873+
err = jfrogCli.Exec("yarn", "set", "version", "3.2.1")
874+
assert.NoError(t, err)
875+
modifyExistingYarnRc(t, "3.2.1")
876+
877+
err = jfrogCli.Exec("yarn", "--version")
878+
assert.NoError(t, err)
879+
}
880+
717881
// Checks if the expected dependencies match the actual dependencies. Only the dependencies' IDs and scopes (not more than one scope) are compared.
718882
func equalDependenciesSlices(t *testing.T, expectedDependencies []expectedDependency, actualDependencies []buildinfo.Dependency) {
719883
assert.Equal(t, len(expectedDependencies), len(actualDependencies))
@@ -733,6 +897,16 @@ func equalDependenciesSlices(t *testing.T, expectedDependencies []expectedDepend
733897
}
734898
}
735899

900+
func modifyExistingYarnRc(t *testing.T, version string) {
901+
yarnConfig := make(map[string]any)
902+
yarnRcPath := ".yarnrc.yml"
903+
yarnConfig["yarnPath"] = ".yarn/releases/yarn-" + version + ".cjs"
904+
updatedYamlData, err := yaml.Marshal(&yarnConfig)
905+
assert.NoError(t, err)
906+
err = os.WriteFile(yarnRcPath, updatedYamlData, 0644)
907+
assert.NoError(t, err)
908+
}
909+
736910
func isNpm7(npmVersion *version.Version) bool {
737911
return npmVersion.Compare("7.0.0") <= 0
738912
}

0 commit comments

Comments
 (0)