func TestDeleteHook(t *testing.T) { t.Parallel() h := newHarness(t) defer h.Stop() c := &configureCmd{} _, _, err := c.deleteHook(h.env, nil, "delete") ensure.Err(t, err, regexp.MustCompile("invalid format")) _, _, err = c.deleteHook(h.env, nil, "invalid", "1") ensure.Err(t, err, regexp.MustCompile("invalid format")) _, _, err = c.deleteHook(h.env, nil, "delete", "1", "2") ensure.Err(t, err, regexp.MustCompile("invalid trigger name")) var hooksOps []*hookOperation _, ops, err := c.deleteHook(h.env, hooksOps, "delete", "call") ensure.Nil(t, err) ensure.DeepEqual(t, ops[len(ops)-1].method, "DELETE") ensure.DeepEqual( t, *ops[len(ops)-1].function, functionHook{FunctionName: "call"}, ) _, ops, err = c.deleteHook(h.env, hooksOps, "delete", "_User", "beforeSave") ensure.Nil(t, err) ensure.DeepEqual(t, ops[len(ops)-1].method, "DELETE") ensure.DeepEqual( t, *ops[len(ops)-1].trigger, triggerHook{ClassName: "_User", TriggerName: "beforeSave"}, ) }
func TestReadTriggerParams(t *testing.T) { t.Parallel() h := newHarness(t) defer h.Stop() h.env.In = ioutil.NopCloser(strings.NewReader("\n")) _, err := readTriggerName(h.env) ensure.Err(t, err, regexp.MustCompile("Class name cannot be empty")) h.env.In = ioutil.NopCloser(strings.NewReader("foo\n")) _, err = readTriggerName(h.env) 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) 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) ensure.Nil(t, err) ensure.DeepEqual(t, *hook, triggerHook{ ClassName: "foo", TriggerName: "beforeSave", URL: "https://api.example.com/foo/beforeSave", }) }
func TestParserEmail(t *testing.T) { t.Parallel() h := parsecli.NewTokenHarness(t) h.MakeEmptyRoot() defer h.Stop() ensure.Nil(t, parsecli.CreateConfigWithContent(filepath.Join(h.Env.Root, parsecli.ParseLocal), "{}")) ensure.Nil(t, parsecli.CreateConfigWithContent( filepath.Join(h.Env.Root, parsecli.ParseProject), `{"project_type": 1}`, ), ) var c configureCmd ensure.Nil(t, c.parserEmail(h.Env, []string{"email2"})) ensure.DeepEqual( t, h.Out.String(), `Successfully configured email for current project to: "email2" `, ) ensure.Err(t, c.parserEmail(h.Env, nil), regexp.MustCompile("Invalid args:")) ensure.Err(t, c.parserEmail(h.Env, []string{"a", "b"}), regexp.MustCompile("Invalid args:")) }
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 TestDeployRetries(t *testing.T) { t.Parallel() h := 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 := 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 = &ParseAPIClient{apiClient: &parse.Client{Transport: ht}} d := &deployCmd{Retries: 1} ctx := 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 TestUploadFileNoFile(t *testing.T) { t.Parallel() h := 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 TestSetVersionInvalid(t *testing.T) { t.Parallel() h, c := newJsSdkHarnessWithConfig(t) defer h.Stop() j := jsSDKCmd{newVersion: "1.2.12"} ensure.Err(t, j.setVersion(h.env, c), regexp.MustCompile("Invalid SDK version selected")) }
func TestSecondUnixListenInherited(t *testing.T) { var n Net tmpfile, err := ioutil.TempFile("", "TestSecondUnixListenInherited-") ensure.Nil(t, err) ensure.Nil(t, tmpfile.Close()) ensure.Nil(t, os.Remove(tmpfile.Name())) defer os.Remove(tmpfile.Name()) l1, err := net.Listen("unix", tmpfile.Name()) ensure.Nil(t, err) file, err := l1.(*net.UnixListener).File() ensure.Nil(t, err) n.fdStart = dup(t, int(file.Fd())) ensure.Nil(t, file.Close()) os.Setenv(envCountKey, "1") ensure.Nil(t, n.inherit()) ensure.DeepEqual(t, len(n.inherited), 1) l2, err := n.Listen("unix", tmpfile.Name()) ensure.Nil(t, err) ensure.DeepEqual(t, len(n.active), 1) ensure.DeepEqual(t, n.inherited[0], nil) _, err = n.Listen("unix", tmpfile.Name()) ensure.Err(t, err, regexp.MustCompile("bind: address already in use$")) ensure.Nil(t, l1.Close()) ensure.Nil(t, l2.Close()) }
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 TestConfigureAcessToken(t *testing.T) { t.Parallel() h, _ := newAppHarness(t) defer h.Stop() c := configureCmd{login: login{tokenReader: strings.NewReader("")}} h.env.In = ioutil.NopCloser(strings.NewReader("token\n")) ensure.Nil(t, c.accountKey(h.env)) ensure.DeepEqual( t, h.Out.String(), ` Input your account key or press enter to generate a new one. Account Key: Successfully stored credentials. `) h.env.In = ioutil.NopCloser(strings.NewReader("email\ninvalid\n")) ensure.Err(t, c.accountKey(h.env), regexp.MustCompile("Please try again")) ensure.DeepEqual(t, h.Err.String(), `Sorry, the account key you provided is not valid. Please follow instructions at https://www.parse.com/account_keys to generate a new account key. `, ) }
func TestConfigureAcessToken(t *testing.T) { t.Parallel() h, _ := newAppHarness(t) defer h.Stop() c := configureCmd{login: login{tokenReader: strings.NewReader("")}} h.env.In = ioutil.NopCloser(strings.NewReader("n\ntoken\n")) ensure.Nil(t, c.accessToken(h.env)) ensure.DeepEqual(t, h.Out.String(), `Please enter an access token if you already generated it. If you do not have an access token or would like to generate a new one, please type: "y" to open the browser or "n" to continue: Access Token: Successfully stored credentials. `, ) h.env.In = ioutil.NopCloser(strings.NewReader("n\nemail\ninvalid\n")) ensure.Err(t, c.accessToken(h.env), regexp.MustCompile("Please try again")) ensure.DeepEqual(t, h.Err.String(), `Sorry, the access token you provided is not valid. Please follow instructions at https://www.parse.com/account_keys to generate a new access token. `, ) }
func TestGetHostFromURL(t *testing.T) { urlStr := "https://api.parse.com/1/" host, err := getHostFromURL(urlStr, "") ensure.Nil(t, err) ensure.DeepEqual(t, host, "api.parse.com") urlStr = "https://api.parse.com/1/" host, err = getHostFromURL(urlStr, "*****@*****.**") ensure.Nil(t, err) ensure.DeepEqual(t, host, "api.parse.com#[email protected]") urlStr = "https://api.example.com:8080/1/" host, err = getHostFromURL(urlStr, "") ensure.Nil(t, err) ensure.DeepEqual(t, host, "api.example.com") urlStr = "https://api.example.com:8080/1/" host, err = getHostFromURL(urlStr, "*****@*****.**") ensure.Nil(t, err) ensure.DeepEqual(t, host, "api.example.com#[email protected]") urlStr = "api.example.com:8080:90" host, err = getHostFromURL(urlStr, "") ensure.Err(t, err, regexp.MustCompile("not a valid url")) }
func TestLogin(t *testing.T) { t.Parallel() h, _ := newAppHarness(t) defer h.Stop() l := &loginCmd{tokenReader: strings.NewReader("")} h.env.In = ioutil.NopCloser(strings.NewReader("n\nemail\ntoken\n")) ensure.Nil(t, l.run(h.env)) ensure.DeepEqual(t, h.Out.String(), `Please enter the email id you used to register with Parse and an account key if you already generated it. If you do not have an account key or would like to generate a new one, please type: "y" to open the browser or "n" to continue: Email: Account Key: Successfully stored credentials. `) h.env.In = ioutil.NopCloser(strings.NewReader("n\nemail\ninvalid\n")) ensure.Err(t, l.run(h.env), regexp.MustCompile("Please try again")) ensure.DeepEqual(t, h.Err.String(), `Sorry, we do not have a user with this email and account key. Please follow instructions at https://www.parse.com/account/keys to generate a new account key. `) }
func TestConfigAddAliasBadLink(t *testing.T) { t.Parallel() const name = "foo" const link = "bar" c := parseConfig{} ensure.Err(t, c.addAlias(name, link), regexp.MustCompile("wasn't found")) }
func TestConfigAppDefaultNotFound(t *testing.T) { t.Parallel() c := parseConfig{Applications: map[string]*parseAppConfig{}} ac, err := c.app(defaultKey) ensure.True(t, ac == nil) ensure.Err(t, err, regexp.MustCompile("No default app configured")) }
func TestCheckExistingWithoutDesiredBinds(t *testing.T) { const imageID = "ii1" const imageName = "in1" container := &Container{ containerConfig: &dockerclient.ContainerConfig{ Image: imageName, }, hostConfig: &dockerclient.HostConfig{ Binds: []string{"a:b"}, }, } client := &mockClient{ listImages: func() ([]*dockerclient.Image, error) { return []*dockerclient.Image{ { RepoTags: []string{imageName}, Id: imageID, }, }, nil }, } ci := &dockerclient.ContainerInfo{ Image: imageID, Id: "y", Config: &dockerclient.ContainerConfig{}, } ok, err := container.checkExisting(client, ci) ensure.Err(t, err, regexp.MustCompile("but desired volumes are")) ensure.False(t, ok) }
func TestServerAbort(t *testing.T) { t.Parallel() for _, code := range []int{200, 500} { server := httptest.NewServer( http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Length", "4000") w.WriteHeader(code) w.Write(bytes.Repeat([]byte("a"), 3000)) }, ), ) u, err := url.Parse(server.URL) ensure.Nil(t, err) c := &fbapi.Client{ BaseURL: u, } _, err = c.Do(&http.Request{Method: "GET"}, nil) ensure.NotNil(t, err) ensure.Err(t, err, regexp.MustCompile("(invalid character|EOF)")) server.CloseClientConnections() server.Close() } }
func TestInvalidFlagValue(t *testing.T) { const name = "TestInvalidFlagValue" s := flag.NewFlagSet(name, flag.PanicOnError) s.Int("bar", 0, "") os.Setenv(named(name, "bar"), "a") ensure.Err(t, flagenv.ParseSet(name, s), regexp.MustCompile(`failed to set flag "bar" with value "a"`)) }
func TestConfigAppNotFound(t *testing.T) { t.Parallel() const name = "foo" c := parseConfig{Applications: map[string]*parseAppConfig{}} ac, err := c.app(name) ensure.True(t, ac == nil) ensure.Err(t, err, regexp.MustCompile(`App "foo" wasn't found`)) }
func TestConfigAddAliasDupe(t *testing.T) { t.Parallel() const name = "foo" const link = "bar" c := parseConfig{Applications: map[string]*parseAppConfig{link: {}}} ensure.Nil(t, c.addAlias(name, link)) ensure.Err(t, c.addAlias(name, link), regexp.MustCompile("has already been added")) }
func TestGetAllJSVersionsError(t *testing.T) { t.Parallel() h := newJsSdkHarnessError(t) defer h.Stop() j := jsSDKCmd{} _, err := j.getAllJSSdks(h.env) ensure.Err(t, err, regexp.MustCompile(`something is wrong`)) }
func TestGenerateEjsExists(t *testing.T) { t.Parallel() h, g := newGenerateCmdHarness(t, expressEjs) defer h.Stop() g.run(h.Env) ensure.Err(t, g.run(h.Env), regexp.MustCompile("Please remove the above existing files and try again.")) }
func TestCredentiasModifyError(t *testing.T) { t.Parallel() c := parse.Client{ Credentials: parse.RestAPIKey{}, } _, err := c.Do(&http.Request{}, nil, nil) ensure.Err(t, err, regexp.MustCompile("empty ApplicationID")) }
func TestEmptySessionTokenInSessionToken(t *testing.T) { t.Parallel() st := parse.SessionToken{ ApplicationID: defaultApplicationID, RestAPIKey: "rk", } ensure.Err(t, st.Modify(nil), regexp.MustCompile("empty SessionToken")) }
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 TestConfigGlobalEmpty(t *testing.T) { t.Parallel() dir := makeDirWithConfig(t, "") defer os.RemoveAll(dir) c, err := configFromDir(dir) ensure.True(t, c == nil) ensure.Err(t, err, regexp.MustCompile("is not valid JSON")) }
func TestMissingCredentials(t *testing.T) { t.Parallel() var c parse.Client req := http.Request{Method: "GET", URL: &url.URL{Path: "classes/Foo/Bar"}} _, err := c.Do(&req, nil, nil) ensure.NotNil(t, err) ensure.Err(t, err, regexp.MustCompile(`parse: api error with message="unauthorized"`)) }
func TestConfigMissing(t *testing.T) { t.Parallel() dir, err := ioutil.TempDir("", "parse-cli-config-") ensure.Nil(t, err) defer os.RemoveAll(dir) c, err := configFromDir(dir) ensure.True(t, c == nil) ensure.Err(t, err, regexp.MustCompile("Command must be run in a directory containing a Parse project.")) }
func TestRunSymbolsCmd(t *testing.T) { t.Parallel() h := newHarness(t) defer h.Stop() s := &symbolsCmd{} ensure.Err(t, s.run(h.env, nil), regexp.MustCompile("Please specify path")) }
func TestNewRequestAfterStop(t *testing.T) { t.Parallel() const count = 10000 hello := []byte("hello") finOkHandler := make(chan struct{}) unblockOkHandler := make(chan struct{}) okHandler := func(w http.ResponseWriter, r *http.Request) { defer close(finOkHandler) w.WriteHeader(200) const diff = 500 for i := 0; i < count-diff; i++ { w.Write(hello) } <-unblockOkHandler for i := 0; i < diff; i++ { w.Write(hello) } } listener, err := net.Listen("tcp", "127.0.0.1:0") listener, onClose := NewOnCloseListener(listener) ensure.Nil(t, err) server := &http.Server{Handler: http.HandlerFunc(okHandler)} transport := &http.Transport{} client := &http.Client{Transport: transport} down := &httpdown.HTTP{} s := down.Serve(server, listener) res, err := client.Get(fmt.Sprintf("http://%s/", listener.Addr().String())) ensure.Nil(t, err) finStop := make(chan struct{}) go func() { defer close(finStop) ensure.Nil(t, s.Stop()) }() // Wait until the listener is closed. <-onClose // Now the next request should not be able to connect as the listener is // now closed. _, err = client.Get(fmt.Sprintf("http://%s/", listener.Addr().String())) // We should just get "connection refused" here, but sometimes, very rarely, // we get a "connection reset" instead. Unclear why this happens. ensure.Err(t, err, regexp.MustCompile("(connection refused|connection reset by peer)$")) // Unblock the handler and ensure we finish writing the rest of the body // successfully. close(unblockOkHandler) actualBody, err := ioutil.ReadAll(res.Body) ensure.Nil(t, err) ensure.DeepEqual(t, actualBody, bytes.Repeat(hello, count)) ensure.Nil(t, res.Body.Close()) <-finOkHandler <-finStop }