func TestReadTriggerParams(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() h.Env.In = ioutil.NopCloser(strings.NewReader("\n")) _, err := readTriggerName(h.Env, nil) ensure.Err(t, err, regexp.MustCompile("Class name cannot be empty")) h.Env.In = ioutil.NopCloser(strings.NewReader("foo\n")) _, err = readTriggerName(h.Env, nil) ensure.Err(t, err, regexp.MustCompile("Trigger name cannot be empty")) h.Env.In = ioutil.NopCloser(strings.NewReader("foo\nbeforeSave")) hook, err := readTriggerName(h.Env, nil) ensure.Nil(t, err) ensure.DeepEqual(t, *hook, triggerHook{ClassName: "foo", TriggerName: "beforeSave"}) h.Env.In = ioutil.NopCloser(strings.NewReader("foo\nbeforeSave\napi.example.com/foo/beforeSave\n")) hook, err = readTriggerParams(h.Env, nil) ensure.Nil(t, err) ensure.DeepEqual(t, *hook, triggerHook{ ClassName: "foo", TriggerName: "beforeSave", URL: "https://api.example.com/foo/beforeSave", }) }
func TestShouldCreateNewApp(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() n := &newCmd{} h.Env.In = ioutil.NopCloser(strings.NewReader("new")) decision, err := n.promptCreateNewApp(h.Env, false) ensure.Nil(t, err) ensure.DeepEqual(t, decision, "new") h.Env.In = ioutil.NopCloser(strings.NewReader("existing")) decision, err = n.promptCreateNewApp(h.Env, false) ensure.Nil(t, err) ensure.DeepEqual(t, decision, "existing") h.Env.In = ioutil.NopCloser(strings.NewReader("other")) _, err = n.promptCreateNewApp(h.Env, false) ensure.Err(t, err, regexp.MustCompile("are the only valid options")) decision, err = n.promptCreateNewApp(h.Env, true) ensure.Nil(t, err) ensure.DeepEqual(t, decision, "existing") n.createNewApp = true decision, err = n.promptCreateNewApp(h.Env, true) ensure.Nil(t, err) ensure.DeepEqual(t, decision, "new") }
func TestSetupAndConfigure(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) h.MakeEmptyRoot() defer h.Stop() n := &newCmd{} h.Env.Type = parsecli.ParseFormat h.Env.In = ioutil.NopCloser(strings.NewReader("\n")) code, err := n.setupSample(h.Env, "myapp", &parsecli.ParseAppConfig{ApplicationID: "a"}, true, false) ensure.Nil(t, err) ensure.True(t, code) type jsSDKVersion struct { JS []string `json:"js"` } ht := parsecli.TransportFunc(func(r *http.Request) (*http.Response, error) { ensure.DeepEqual(t, r.URL.Path, "/1/jsVersions") rows := jsSDKVersion{JS: []string{"1.5.0", "1.6.0"}} return &http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser(strings.NewReader(jsonStr(t, rows))), }, nil }) h.Env.ParseAPIClient = &parsecli.ParseAPIClient{APIClient: &parse.Client{Transport: ht}} err = n.configureSample( &addCmd{MakeDefault: true}, "yolo", (&parsecli.ParseAppConfig{ApplicationID: "a"}).WithInternalMasterKey("m"), nil, h.Env, ) ensure.Nil(t, err) }
func TestMakeNewRelease(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() var d deployCmd info := deployInfo{ ReleaseName: "v2", ParseVersion: "latest", Checksums: deployFileData{ Cloud: map[string]string{"main.js": "4ece160cc8e5e828ee718e7367cf5d37"}, Public: map[string]string{"index.html": "9e2354a0ebac5852bc674026137c8612"}, }, Versions: deployFileData{ Cloud: map[string]string{"main.js": "f2"}, Public: map[string]string{"index.html": "f2"}, }, } ht := parsecli.TransportFunc(func(r *http.Request) (*http.Response, error) { ensure.DeepEqual(t, r.URL.Path, "/1/deploy") return &http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser(strings.NewReader(jsonStr(t, &info))), }, nil }) h.Env.ParseAPIClient = &parsecli.ParseAPIClient{APIClient: &parse.Client{Transport: ht}} res, err := d.makeNewRelease(&deployInfo{}, h.Env) ensure.Nil(t, err) ensure.DeepEqual(t, info, res) }
func TestGetPrevDeplInfo(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() var d deployCmd info := &deployInfo{ ReleaseName: "v1", ParseVersion: "latest", Checksums: deployFileData{ Cloud: map[string]string{"main.js": "d41d8cd98f00b204e9800998ecf8427e"}, Public: map[string]string{"index.html": "d41d8cd98f00b204e9800998ecf8427e"}, }, Versions: deployFileData{ Cloud: map[string]string{"main.js": "f1"}, Public: map[string]string{"index.html": "f1"}, }, } ht := parsecli.TransportFunc(func(r *http.Request) (*http.Response, error) { ensure.DeepEqual(t, r.URL.Path, "/1/deploy") return &http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser(strings.NewReader(jsonStr(t, info))), }, nil }) h.Env.ParseAPIClient = &parsecli.ParseAPIClient{APIClient: &parse.Client{Transport: ht}} res, err := d.getPrevDeplInfo(h.Env) ensure.Nil(t, err) ensure.DeepEqual(t, res, info) }
func TestGenericGetSourceFiles(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) h.MakeEmptyRoot() defer h.Stop() ensure.Nil(t, os.Mkdir(filepath.Join(h.Env.Root, "src"), 0755)) for _, name := range []string{"index.html"} { file, err := os.Create(filepath.Join(h.Env.Root, "src", name)) ensure.Nil(t, err) ensure.Nil(t, file.Close()) } ensure.Nil(t, os.Symlink(filepath.Join(h.Env.Root, "src"), filepath.Join(h.Env.Root, "public"))) var d deployCmd files, ignored, err := d.getSourceFiles( filepath.Join(h.Env.Root, "public"), map[string]struct{}{".html": {}}, h.Env, ) ensure.Nil(t, err) ensure.DeepEqual(t, files, []string{filepath.Join(h.Env.Root, "public", "index.html")}) ensure.DeepEqual(t, len(ignored), 0) }
func TestLatestVersion(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() ht := parsecli.TransportFunc(func(r *http.Request) (*http.Response, error) { ensure.DeepEqual(t, r.URL.Path, "/1/supported") return &http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser( jsonpipe.Encode( map[string]string{"version": "2.0.2"}, ), ), }, nil }) h.Env.ParseAPIClient = &parsecli.ParseAPIClient{APIClient: &parse.Client{Transport: ht}} u := new(updateCmd) latestVersion, err := u.latestVersion(h.Env) ensure.Nil(t, err) ensure.DeepEqual(t, latestVersion, "2.0.2") downloadURL, err := u.getDownloadURL(h.Env) ensure.StringContains(t, downloadURL, "https://github.com/ParsePlatform/parse-cli/releases/download/release_2.0.2") }
func TestProjectType(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() h.MakeEmptyRoot() ensure.Nil(t, parsecli.CloneSampleCloudCode(h.Env, false)) c := &configureCmd{} err := c.projectType(h.Env, []string{"1", "2"}) ensure.Err(t, err, regexp.MustCompile("only an optional project type argument is expected")) h.Env.In = ioutil.NopCloser(strings.NewReader("invalid\n")) err = c.projectType(h.Env, nil) ensure.StringContains(t, h.Err.String(), "Invalid selection. Please enter a number") ensure.Err(t, err, regexp.MustCompile("Could not make a selection. Please try again.")) h.Err.Reset() h.Out.Reset() h.Env.In = ioutil.NopCloser(strings.NewReader("0\n")) err = c.projectType(h.Env, nil) ensure.StringContains(t, h.Err.String(), "Please enter a number between 1 and") ensure.Err(t, err, regexp.MustCompile("Could not make a selection. Please try again.")) h.Err.Reset() h.Out.Reset() h.Env.In = ioutil.NopCloser(strings.NewReader("1\n")) err = c.projectType(h.Env, nil) ensure.StringContains(t, h.Out.String(), "Successfully set project type to: parse") ensure.Nil(t, err) }
func TestLogInvalidLevel(t *testing.T) { t.Parallel() l := logsCmd{} h := parsecli.NewHarness(t) defer h.Stop() err := l.run(h.Env, nil) ensure.Err(t, err, regexp.MustCompile(`invalid level: ""`)) }
func TestFindAAPT(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() aapts := findAAPT("Resources") ensure.DeepEqual(t, aapts[:], []string{filepath.Join("Resources", "build_tools", "aapt")}) }
func TestPrintListOneAppNoDefaultKey(t *testing.T) { t.Parallel() conf := &parsecli.ParseConfig{Applications: map[string]*parsecli.ParseAppConfig{"first": {}}} h := parsecli.NewHarness(t) defer h.Stop() conf.PrettyPrintApps(h.Env) ensure.DeepEqual(t, h.Out.String(), "The following apps are associated with Cloud Code in the current directory:\n first\n") }
func TestRunSymbolsCmd(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() s := &symbolsCmd{} ensure.Err(t, s.run(h.Env, nil), regexp.MustCompile("Please specify path")) }
func TestVersion(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() var c versionCmd err := c.run(h.Env) ensure.Nil(t, err) ensure.DeepEqual(t, h.Out.String(), parsecli.Version+"\n") ensure.DeepEqual(t, h.Err.String(), "") }
func TestBase64MD5OfFileNoFile(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() h.MakeEmptyRoot() testFile := filepath.Join(h.Env.Root, "test") _, err := base64MD5OfFile(testFile) ensure.NotNil(t, err) }
func TestUpgradeLegacyNoOp(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() var m migrateCmd c := &parsecli.ParseConfig{ProjectConfig: &parsecli.ProjectConfig{Type: parsecli.ParseFormat}} _, err := m.upgradeLegacy(h.Env, c) ensure.Err(t, err, regexp.MustCompile("Already using the preferred config format.")) }
func newJsSdkHarnessError(t testing.TB) *parsecli.Harness { h := parsecli.NewHarness(t) ht := parsecli.TransportFunc(func(r *http.Request) (*http.Response, error) { ensure.DeepEqual(t, r.URL.Path, "/1/jsVersions") return &http.Response{ StatusCode: http.StatusExpectationFailed, Body: ioutil.NopCloser(strings.NewReader(`{"error":"something is wrong"}`)), }, nil }) h.Env.ParseAPIClient = &parsecli.ParseAPIClient{APIClient: &parse.Client{Transport: ht}} return h }
func newDefaultCmdHarness(t testing.TB) (*parsecli.Harness, *defaultCmd, *parsecli.ParseConfig) { h := parsecli.NewHarness(t) h.MakeEmptyRoot() ensure.Nil(t, parsecli.CloneSampleCloudCode(h.Env, true)) config := newDefaultParseConfig(t, h) h.Out.Reset() d := &defaultCmd{} return h, d, config }
func newJsSdkHarness(t testing.TB) *parsecli.Harness { h := parsecli.NewHarness(t) ht := parsecli.TransportFunc(func(r *http.Request) (*http.Response, error) { ensure.DeepEqual(t, r.URL.Path, "/1/jsVersions") rows := jsSDKVersion{JS: []string{"1.2.8", "1.2.9", "1.2.10", "1.2.11", "0.2.0"}} return &http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser(strings.NewReader(jsonStr(t, rows))), }, nil }) h.Env.ParseAPIClient = &parsecli.ParseAPIClient{APIClient: &parse.Client{Transport: ht}} return h }
func TestUploadFiles(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() h.MakeEmptyRoot() createRandomFiles(t, h) names := []string{"a", "b"} ht := parsecli.TransportFunc(func(r *http.Request) (*http.Response, error) { switch filepath.Base(r.URL.Path) { case names[0]: ensure.NotNil(t, r.Header) ensure.DeepEqual(t, r.Header.Get("Key"), "Value") ensure.DeepEqual(t, r.Header.Get("Content-Type"), "application/octet-stream") ensure.DeepEqual(t, r.Header.Get("Content-MD5"), "4JnleFGzGppuArF6N50EWg==") return &http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser(strings.NewReader(`{"status":"success"}`)), }, nil case names[1]: ensure.NotNil(t, r.Header) ensure.DeepEqual(t, r.Header.Get("Key"), "Value") ensure.DeepEqual(t, r.Header.Get("Content-Type"), "application/octet-stream") ensure.DeepEqual(t, r.Header.Get("Content-MD5"), "Fv43qsp6mnGCJlC00VkOcA==") return &http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser(strings.NewReader(`{"status":"success"}`)), }, nil default: return &http.Response{ StatusCode: http.StatusInternalServerError, Body: ioutil.NopCloser(strings.NewReader(`{"error":"something is wrong"}`)), }, nil } }) h.Env.ParseAPIClient = &parsecli.ParseAPIClient{APIClient: &parse.Client{Transport: ht}} var filenames []string for _, name := range names { filenames = append(filenames, filepath.Join(h.Env.Root, name)) } ensure.Nil(t, uploadSymbolFiles(filenames[:], map[string]string{"Key": "Value"}, true, h.Env)) for _, filename := range filenames { _, err := os.Lstat(filename) ensure.NotNil(t, err) ensure.True(t, os.IsNotExist(err)) } }
func TestPrepareSymbolsFolder(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() h.MakeEmptyRoot() createRandomFiles(t, h) var i iosSymbolUploader ensure.Nil(t, i.prepareSymbolsFolder(h.Env.Root, h.Env)) files, err := readDirNames(h.Env.Root) ensure.Nil(t, err) ensure.DeepEqual(t, len(files), 0) }
func TestUploadFileNoFile(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() var d deployCmd _, err := d.uploadFile("cloud/master.js", "", h.Env, nil) switch runtime.GOOS { case "windows": ensure.Err(t, err, regexp.MustCompile(`The system cannot find the path specified.`)) default: ensure.Err(t, err, regexp.MustCompile(`no such file or directory`)) } }
func TestBase64MD5OfFile(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() h.MakeEmptyRoot() testFile := filepath.Join(h.Env.Root, "test") ensure.Nil(t, ioutil.WriteFile(testFile, []byte(`A test string`), 0755)) val, err := base64MD5OfFile(testFile) ensure.Nil(t, err) ensure.DeepEqual(t, val, "mc5NvcbbGrh2RDETriS4Fg==") }
func TestParseBaseURL(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() c := &Hooks{} c.BaseURL = "http://hello" ensure.Err(t, c.parseBaseURL(h.Env), regexp.MustCompile("valid https url")) c.BaseURL = "https://hello" ensure.Nil(t, c.parseBaseURL(h.Env)) ensure.DeepEqual(t, c.baseWebhookURL.String(), c.BaseURL) }
func TestDeployRetries(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() info := &struct { ReleaseName string `json:"releaseName,omitempty"` Description string `json:"description,omitempty"` ParseVersion string `json:"parseVersion,omitempty"` Checksums map[string]string `json:"checksums,omitempty"` Versions map[string]string `json:"userFiles,omitempty"` }{ ReleaseName: "v1", ParseVersion: "latest", Checksums: map[string]string{"main.js": "d41d8cd98f00b204e9800998ecf8427e"}, Versions: map[string]string{"main.js": "f1"}, } ht := parsecli.TransportFunc(func(r *http.Request) (*http.Response, error) { ensure.DeepEqual(t, r.URL.Path, "/1/deploy") return &http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser(strings.NewReader(jsonStr(t, info))), }, nil }) h.Env.ParseAPIClient = &parsecli.ParseAPIClient{APIClient: &parse.Client{Transport: ht}} d := &deployCmd{Retries: 1} ctx := parsecli.Context{Config: defaultParseConfig} ctx.Config.GetProjectConfig().Parse.JSSDK = "latest" ensure.Err(t, d.run(h.Env, &ctx), regexp.MustCompile("no such file or directory")) ensure.DeepEqual(t, h.Err.String(), "") h.Err.Reset() d.Retries = 2 ensure.Err(t, d.run(h.Env, &ctx), regexp.MustCompile("no such file or directory")) ensure.DeepEqual( t, h.Err.String(), "Deploy failed with error:\nlstat cloud: no such file or directory\nWill retry in 0 seconds.\n\n", ) h.Err.Reset() d.Retries = 5 ensure.Err(t, d.run(h.Env, &ctx), regexp.MustCompile("no such file or directory")) errStr := "Deploy failed with error:\nlstat cloud: no such file or directory\nWill retry in 0 seconds.\n\n" errStr += strings.Repeat("Sorry, deploy failed again with same error.\nWill retry in 0 seconds.\n\n", 3) ensure.DeepEqual(t, h.Err.String(), errStr) }
func TestReadDirNames(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() h.MakeEmptyRoot() createRandomFiles(t, h) files, err := readDirNames(h.Env.Root) sort.Strings(files) ensure.DeepEqual(t, len(files), 2) ensure.DeepEqual(t, files[:], []string{ filepath.Join(h.Env.Root, "a"), filepath.Join(h.Env.Root, "b"), }) ensure.Nil(t, err) }
func TestRunMigrateCmd(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) h.MakeEmptyRoot() defer h.Stop() n := &newCmd{} h.Env.Type = parsecli.ParseFormat h.Env.In = ioutil.NopCloser(strings.NewReader("\n")) _, err := n.setupSample(h.Env, "yolo", &parsecli.ParseAppConfig{ ApplicationID: "yolo-id", MasterKey: "yoda", }, false, false, ) ensure.Nil(t, err) m := &migrateCmd{} err = m.run(h.Env) ensure.Err(t, err, regexp.MustCompile("Already using the preferred config format")) ensure.Nil(t, os.Remove(filepath.Join(h.Env.Root, parsecli.ParseLocal))) ensure.Nil(t, os.Remove(filepath.Join(h.Env.Root, parsecli.ParseProject))) ensure.Nil(t, os.MkdirAll(filepath.Join(h.Env.Root, parsecli.ConfigDir), 0755)) ensure.Nil(t, ioutil.WriteFile( filepath.Join(h.Env.Root, parsecli.LegacyConfigFile), []byte(`{ "applications": { "yolo": { "applicationId": "yolo-id", "masterKey": "yoda" } } }`), 0600, ), ) ensure.Nil(t, m.run(h.Env)) ensure.StringContains(t, h.Out.String(), "Successfully migrated") }
func TestUpgradeLegacy(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() m := migrateCmd{retainMaster: false} c := &parsecli.ParseConfig{ Applications: map[string]*parsecli.ParseAppConfig{ "app": {ApplicationID: "a", MasterKey: "m"}, }, ProjectConfig: &parsecli.ProjectConfig{Type: parsecli.LegacyParseFormat}, } config, err := m.upgradeLegacy(h.Env, c) ensure.Nil(t, err) ensure.DeepEqual(t, config.Applications["app"].MasterKey, "") }
func TestGetPrevDeplInfoError(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() var d deployCmd ht := parsecli.TransportFunc(func(r *http.Request) (*http.Response, error) { ensure.DeepEqual(t, r.URL.Path, "/1/deploy") return &http.Response{ StatusCode: http.StatusExpectationFailed, Body: ioutil.NopCloser(strings.NewReader(`{"error": "something is wrong"}`)), }, nil }) h.Env.ParseAPIClient = &parsecli.ParseAPIClient{APIClient: &parse.Client{Transport: ht}} _, err := d.getPrevDeplInfo(h.Env) ensure.Err(t, err, regexp.MustCompile("something is wrong")) }
func TestSetVersionNoneSelected(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() c := &parsecli.Context{Config: defaultParseConfig} var j jsSDKCmd c.Config.GetProjectConfig().Parse.JSSDK = "1.2.1" ensure.Nil(t, j.getVersion(h.Env, c)) ensure.DeepEqual(t, "Current JavaScript SDK version is 1.2.1\n", h.Out.String()) c.Config.GetProjectConfig().Parse.JSSDK = "" ensure.Err(t, j.getVersion(h.Env, c), regexp.MustCompile("JavaScript SDK version not set for this project.")) }
func TestCurlCommand(t *testing.T) { t.Parallel() h := parsecli.NewHarness(t) defer h.Stop() n := &newCmd{} command := n.curlCommand(h.Env, &parsecli.App{ApplicationID: "AppID", RestKey: "RestKey"}) ensure.DeepEqual(t, command, `curl -X POST \ -H "X-Parse-Application-Id: AppID" \ -H "X-Parse-REST-API-Key: RestKey" \ -H "Content-Type: application/json" \ -d '{}' \ https://api.parse.com/1/functions/hello `) }