Пример #1
0
func TestStackErrorString(t *testing.T) {
	t.Parallel()

	h := newHarness(t)
	defer h.Stop()

	err := stackerr.New("error")

	h.env.ErrorStack = false
	errStr := errorString(h.env, err)

	ensure.DeepEqual(t, errStr, "error")

	h.env.ErrorStack = true
	errStr = errorString(h.env, err)

	ensure.StringContains(t, errStr, "error")
	ensure.StringContains(t, errStr, ".go")

	err = stackerr.Wrap(&parse.Error{Message: "message", Code: 1})
	h.env.ErrorStack = false
	errStr = errorString(h.env, err)

	ensure.DeepEqual(t, errStr, "message")

	h.env.ErrorStack = true
	errStr = errorString(h.env, err)

	ensure.StringContains(t, errStr, `parse: api error with code=1 and message="message`)
	ensure.StringContains(t, errStr, ".go")
}
Пример #2
0
func TestMultiErrorString(t *testing.T) {
	t.Parallel()

	h := newHarness(t)
	defer h.Stop()

	err := errgroup.MultiError(
		[]error{
			stackerr.New("error"),
			stackerr.Wrap(&parse.Error{Message: "message", Code: 1}),
		},
	)

	h.env.ErrorStack = false
	errStr := errorString(h.env, err)

	ensure.DeepEqual(t, errStr, "multiple errors: error | message")

	h.env.ErrorStack = true
	errStr = errorString(h.env, err)

	ensure.StringContains(t, errStr, "multiple errors")
	ensure.StringContains(t, errStr, `parse: api error with code=1 and message="message"`)
	ensure.StringContains(t, errStr, ".go")
}
Пример #3
0
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)
}
Пример #4
0
func TestEnvCmd(t *testing.T) {
	t.Parallel()
	stdout, stderr := testRunCmd(t, "hostctl env", 0, nil, nil)
	ensure.StringContains(t, stdout.String(), "HOSTCTL_PROVIDER=")
	ensure.StringContains(t, stdout.String(), "HOSTCTL_NAMESPACE=")
	ensure.DeepEqual(t, stderr.String(), "")
}
Пример #5
0
func TestHostctlCmd(t *testing.T) {
	t.Parallel()
	stdout, stderr := testRunCmd(t, "hostctl", 0, nil, nil)
	ensure.StringContains(t, stdout.String(), Hostctl.Short)
	ensure.StringContains(t, stdout.String(), "Usage:")
	ensure.StringContains(t, stdout.String(), "Available Commands:")
	ensure.StringContains(t, stdout.String(), "Flags:")
	ensure.DeepEqual(t, stderr.String(), "")
}
Пример #6
0
func TestPageTabURL(t *testing.T) {
	t.Parallel()
	env, _ := fromValues(t, url.Values{})
	pageTabURL := env.PageTabURL("/")
	ensure.StringContains(t, pageTabURL,
		"http://www.facebook.com/pages/Rell-Page-for-Tabs/141929622497380")
	ensure.StringContains(t, pageTabURL, fmt.Sprintf("app_%d", defaultFacebookAppID))
	ensure.StringContains(t, pageTabURL, "app_data=Lw%3D%3D")
}
Пример #7
0
func TestErrorStringWithStack(t *testing.T) {
	t.Parallel()
	h := newHarness(t)
	defer h.Stop()
	h.env.ErrorStack = true
	const message = "hello world"
	actual := errorString(h.env, stackerr.New(message))
	ensure.StringContains(t, actual, message)
	ensure.StringContains(t, actual, ".go")
}
Пример #8
0
func TestCanvasURL(t *testing.T) {
	t.Parallel()
	env, _ := fromValues(t, url.Values{})
	canvasURL := env.CanvasURL("/")
	ensure.StringContains(t, canvasURL,
		fmt.Sprintf("https://apps.facebook.com/%s/", defaultAppNS))
}
Пример #9
0
func TestCanvasURLBeta(t *testing.T) {
	t.Parallel()
	env, _ := fromValues(t, url.Values{"server": []string{"beta"}})
	canvasURL := env.CanvasURL("/")
	ensure.StringContains(t, canvasURL,
		fmt.Sprintf("https://apps.beta.facebook.com/%s/?server=beta", defaultAppNS))
}
Пример #10
0
func TestPageTabURLBeta(t *testing.T) {
	t.Parallel()
	env, _ := fromValues(t, url.Values{"server": []string{"beta"}})
	pageTabURL := env.PageTabURL("/")
	ensure.StringContains(t, pageTabURL,
		"http://www.beta.facebook.com/pages/Rell-Page-for-Tabs/141929622497380")
}
Пример #11
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")
}
Пример #12
0
func TestErrorStringWithoutStack(t *testing.T) {
	t.Parallel()
	h := NewHarness(t)
	defer h.Stop()
	h.Env.ErrorStack = false
	const message = "hello world"
	actual := ErrorString(h.Env, stackerr.New(message))
	ensure.StringContains(t, actual, message)
	ensure.StringDoesNotContain(t, actual, ".go")
}
Пример #13
0
func TestMultiLineStringContains(t *testing.T) {
	var c capture
	ensure.StringContains(&c, "foo\nbaz", "bar")
	c.Equal(t, `ensure_test.go:245: expected substring was not found:
EXPECTED SUBSTRING:
bar
ACTUAL:
foo
baz`)
}
Пример #14
0
func TestSelectNewAppNoCode(t *testing.T) {
	t.Parallel()
	h, _ := parsecli.NewAppHarness(t)
	defer h.Stop()

	h.Env.In = ioutil.NopCloser(strings.NewReader("email\npassword\n"))
	n := &newCmd{noCode: true, parseAppName: "A"}
	ensure.Nil(t, n.run(h.Env))
	ensure.StringContains(t, h.Out.String(), "Successfully selected")
}
Пример #15
0
func TestGetCloudCodeDir(t *testing.T) {
	t.Parallel()
	h := parsecli.NewHarness(t)
	h.MakeEmptyRoot()
	defer h.Stop()

	n := &newCmd{}
	h.Env.In = ioutil.NopCloser(strings.NewReader("\n"))
	name, err := n.getCloudCodeDir(h.Env, "myapp", true)
	ensure.Nil(t, err)
	ensure.StringContains(t, h.Out.String(), "Now it's time to set up some Cloud Code")
	ensure.DeepEqual(t, name, "myapp")

	h.Out.Reset()
	h.Env.In = ioutil.NopCloser(strings.NewReader("otherApp\n"))
	name, err = n.getCloudCodeDir(h.Env, "myapp", true)
	ensure.Nil(t, err)
	ensure.StringContains(t, h.Out.String(), "Now it's time to set up some Cloud Code")
	ensure.DeepEqual(t, name, "otherApp")

	_, err = os.Create(filepath.Join(h.Env.Root, "otherApp"))
	ensure.Nil(t, err)
	h.Out.Reset()
	h.Env.In = ioutil.NopCloser(strings.NewReader("otherApp\n"))
	name, err = n.getCloudCodeDir(h.Env, "myapp", true)
	ensure.Err(t, err, regexp.MustCompile("already exists"))
	ensure.StringContains(t, h.Out.String(), "Now it's time to set up some Cloud Code")

	ensure.Nil(t, os.MkdirAll(filepath.Join(h.Env.Root, "myapp", "config"), 0755))
	_, err = os.Create(filepath.Join(h.Env.Root, "myapp", "config", "global.json"))
	ensure.Nil(t, err)
	h.Out.Reset()
	h.Env.In = ioutil.NopCloser(strings.NewReader("\n"))
	name, err = n.getCloudCodeDir(h.Env, "myapp", true)
	ensure.Err(t, err, regexp.MustCompile("you already have Cloud Code"))
	ensure.Nil(t, os.Remove(filepath.Join(h.Env.Root, "myapp", "config", "global.json")))

	h.Out.Reset()
	h.Env.In = ioutil.NopCloser(strings.NewReader("\n"))
	name, err = n.getCloudCodeDir(h.Env, "myapp", false)
	ensure.Nil(t, err)
	ensure.StringContains(t, h.Out.String(), "folder where we can download the latest")
}
Пример #16
0
func TestRunListCmd(t *testing.T) {
	t.Parallel()

	h, _ := newAppHarness(t)
	defer h.Stop()

	l := &listCmd{}
	h.env.In = ioutil.NopCloser(strings.NewReader("email\npassword\n"))
	ensure.Nil(t, l.run(h.env, []string{"A"}))
	ensure.StringContains(t, h.Out.String(), `Properties of the app "A"`)
}
Пример #17
0
func TestRunNoArgsWithArg(t *testing.T) {
	t.Parallel()
	h := newHarness(t)
	defer h.Stop()
	h.env.Exit = func(i int) { panic(exitCode(i)) }
	func() {
		defer ensure.PanicDeepEqual(t, exitCode(1))
		r := runNoArgs(h.env, nil)
		r(noOpCmd(), []string{"foo"})
	}()
	ensure.StringContains(t, h.Err.String(), "unexpected arguments")
}
Пример #18
0
func TestCreateNewAppNameTaken(t *testing.T) {
	t.Parallel()

	h, _ := NewAppHarness(t)
	defer h.Stop()

	a := defaultApps

	h.Env.In = ioutil.NopCloser(strings.NewReader("A\nD"))
	_, err := a.CreateApp(h.Env, "", 0)
	ensure.Nil(t, err)
	ensure.StringContains(t, h.Err.String(), "already created an app")
}
Пример #19
0
func TestRunNoArgsFuncError(t *testing.T) {
	t.Parallel()
	const message = "hello world"
	h := newHarness(t)
	defer h.Stop()
	h.env.Exit = func(i int) { panic(exitCode(i)) }
	func() {
		defer ensure.PanicDeepEqual(t, exitCode(1))
		r := runNoArgs(h.env, func(*env) error { return errors.New(message) })
		r(noOpCmd(), nil)
	}()
	ensure.StringContains(t, h.Err.String(), message)
}
Пример #20
0
func TestRunWithAppNotFound(t *testing.T) {
	t.Parallel()
	h := newHarness(t)
	defer h.Stop()
	c := legacyConfig{Applications: map[string]*parseAppConfig{"a": {}}}
	h.makeWithConfig(jsonStr(t, c))
	h.env.Exit = func(i int) { panic(exitCode(i)) }
	func() {
		defer ensure.PanicDeepEqual(t, exitCode(1))
		r := runWithClient(h.env, nil)
		r(noOpCmd(), []string{"b"})
	}()
	ensure.StringContains(t, h.Err.String(), `App "b" wasn't found`)
}
Пример #21
0
func TestComplex(t *testing.T) {
	t.Parallel()
	values := url.Values{}
	values.Add("status", "1")
	values.Add("server", "beta")
	values.Add("locale", "en_PI")
	expected := &rellenv.Env{
		Status: true,
		Env:    "beta",
	}
	env, _ := fromValues(t, values)
	ensure.Subset(t, env, expected)
	ensure.StringContains(t, env.SdkURL(), "en_PI")
}
Пример #22
0
func TestRunWithAppMultipleArgs(t *testing.T) {
	t.Parallel()
	h := newHarness(t)
	defer h.Stop()
	h.env.Exit = func(i int) { panic(exitCode(i)) }
	func() {
		defer ensure.PanicDeepEqual(t, exitCode(1))
		r := runWithClient(h.env, nil)
		r(noOpCmd(), []string{"foo", "bar"})
	}()
	ensure.StringContains(
		t,
		h.Err.String(),
		"only an optional app name is expected",
	)
}
Пример #23
0
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")
}
Пример #24
0
func TestRunWithAppNonProjectDir(t *testing.T) {
	t.Parallel()
	h := newHarness(t)
	defer h.Stop()
	h.makeEmptyRoot()
	h.env.Exit = func(i int) { panic(exitCode(i)) }
	func() {
		defer ensure.PanicDeepEqual(t, exitCode(1))
		r := runWithClient(h.env, nil)
		r(noOpCmd(), nil)
	}()
	ensure.StringContains(
		t,
		h.Err.String(),
		"Command must be run inside a Parse project.",
	)
}
Пример #25
0
func TestCloudCodeHelpMessage(t *testing.T) {
	t.Parallel()
	h := parsecli.NewHarness(t)
	defer h.Stop()

	n := &newCmd{}
	msg := n.cloudCodeHelpMessage(h.Env, &parsecli.App{ApplicationID: "a", MasterKey: "m"})
	ensure.StringContains(t,
		msg,
		fmt.Sprintf(
			`Your Cloud Code has been created at %s.

This includes a "Hello world" cloud function, so once you deploy,
you can test that it works, with`,
			h.Env.Root,
		),
	)
}
Пример #26
0
func TestContDeployConfigErr(t *testing.T) {
	t.Parallel()

	h := createParseProject(t)
	defer h.Stop()

	ensure.Nil(t,
		ioutil.WriteFile(
			filepath.Join(h.env.Root, legacyConfigFile),
			[]byte("}"),
			0600,
		),
	)
	h.env.Type = legacy

	deployer := deployFunc(func(parseVersion string,
		prevDeplInfo *deployInfo,
		forDevelop bool,
		e *env) (*deployInfo, error) {
		return &deployInfo{}, nil
	})

	done := make(chan struct{})
	go func() {
		h.Clock.Add(5 * time.Second)
		close(done)
	}()

	first := make(chan struct{})
	(&developCmd{}).contDeploy(h.env, deployer, first, done)
	_, opened := <-first
	ensure.False(t, opened)

	ensure.StringContains(
		t,
		h.Err.String(),
		fmt.Sprintf(
			`Config malformed.
Please fix your config file in %s and try again.
`,
			filepath.Join(h.env.Root, legacyConfigFile),
		),
	)
}
Пример #27
0
func TestRunWithAppError(t *testing.T) {
	t.Parallel()
	h := newHarness(t)
	defer h.Stop()
	const appName = "a"
	c := &parseConfig{
		Applications: map[string]*parseAppConfig{
			appName: {ApplicationID: "id", MasterKey: "token"},
		},
	}
	h.makeWithConfig(jsonStr(t, c))
	h.env.Exit = func(i int) { panic(exitCode(i)) }
	const message = "hello world"
	func() {
		defer ensure.PanicDeepEqual(t, exitCode(1))
		r := runWithClient(h.env, func(e *env, c *context) error {
			ensure.NotNil(t, c)
			return errors.New(message)
		})
		r(noOpCmd(), []string{"a"})
	}()
	ensure.StringContains(t, h.Err.String(), message)
}
Пример #28
0
func TestConfigureAccountKey(t *testing.T) {
	t.Parallel()

	h := parsecli.NewTokenHarness(t)
	defer h.Stop()

	c := configureCmd{login: parsecli.Login{TokenReader: strings.NewReader("")}}

	h.Env.In = ioutil.NopCloser(strings.NewReader("token\n"))
	ensure.Nil(t, c.accountKey(h.Env))
	ensure.StringContains(
		t,
		h.Out.String(),
		`
Input your account key or press ENTER to generate a new one.
`)

	h.Env.In = ioutil.NopCloser(strings.NewReader("invalid\n"))
	ensure.Err(t, c.accountKey(h.Env), regexp.MustCompile("is not valid"))
	ensure.DeepEqual(t,
		h.Err.String(),
		"Could not store credentials. Please try again.\n\n",
	)

	h.Env.Server = "http://api.parse.com/1/"
	c.tokenReader = strings.NewReader(
		`machine api.parse.com#email
			login default
			password token2
		`,
	)
	h.Err.Reset()
	h.Env.In = ioutil.NopCloser(strings.NewReader("token\n"))
	ensure.Nil(t, c.accountKey(h.Env))
	ensure.DeepEqual(t, h.Err.String(),
		`Note: this operation will overwrite the account key:
 "*oken"
for email: "email"
`)

	h.Env.Server = "http://api.parse.com/1/"
	c.tokenReader = strings.NewReader(
		`machine api.parse.com#email
			login default
			password token2
		`,
	)
	c.isDefault = true
	h.Err.Reset()
	h.Env.In = ioutil.NopCloser(strings.NewReader("token\n"))
	ensure.Nil(t, c.accountKey(h.Env))
	ensure.DeepEqual(t, h.Err.String(), "")

	h.Env.Server = "http://api.parse.com/1/"
	c.tokenReader = strings.NewReader(
		`machine api.parse.com
			login default
			password token2
		`,
	)
	c.isDefault = true
	h.Err.Reset()
	h.Env.In = ioutil.NopCloser(strings.NewReader("token\n"))
	ensure.Nil(t, c.accountKey(h.Env))
	ensure.DeepEqual(t, h.Err.String(), "Note: this operation will overwrite the default account key\n")

	h.Env.Server = "http://api.parse.com/1/"
	c.tokenReader = strings.NewReader(
		`machine api.parse.com
			login default
			password token2
		`,
	)
	h.Err.Reset()
	c.isDefault = false
	h.Env.In = ioutil.NopCloser(strings.NewReader("token\n"))
	ensure.Nil(t, c.accountKey(h.Env))
	ensure.DeepEqual(t, h.Err.String(), "")
}
Пример #29
0
func TestGetRandomAppName(t *testing.T) {
	app := &parsecli.App{Name: "test app", ApplicationID: "123456789"}
	name := getRandomAppName(app)
	ensure.StringContains(t, name, "testapp")
}
Пример #30
0
func TestErrorCases(t *testing.T) {
	cases := []struct {
		Request    *http.Request
		Body       interface{}
		Error      string
		StatusCode int
		Transport  http.RoundTripper
	}{
		{
			Request: &http.Request{
				Method: "GET",
				URL: &url.URL{
					Scheme: "https",
					Host:   "api.parse.com",
					Path:   "/1/classes/Foo/Bar",
				},
			},
			Error:      `parse: api error with code=101 and message="object not found for get"`,
			StatusCode: http.StatusNotFound,
			Transport: transportFunc(func(r *http.Request) (*http.Response, error) {
				j := jsonB(t, parse.Error{
					Code:    101,
					Message: "object not found for get",
				})
				return &http.Response{
					StatusCode: http.StatusNotFound,
					Status:     "404 Not Found",
					Body:       ioutil.NopCloser(bytes.NewReader(j)),
				}, nil
			}),
		},
		{
			Request: &http.Request{
				Method: "GET",
				URL: &url.URL{
					Scheme: "https",
					Host:   "api.parse.com",
					Path:   "/1/classes/Foo/Bar",
				},
			},
			Body:  map[int]int{},
			Error: "unsupported type: map[int]int",
			Transport: transportFunc(func(r *http.Request) (*http.Response, error) {
				panic("not reached")
			}),
		},
		{
			Request: &http.Request{
				Method: "GET",
				URL:    &url.URL{Path: "/"},
			},
			Error:      `error with status=404 and body="<html>`,
			StatusCode: 404,
			Transport: transportFunc(func(r *http.Request) (*http.Response, error) {
				return &http.Response{
					StatusCode: http.StatusNotFound,
					Status:     "404 Not Found",
					Body:       ioutil.NopCloser(strings.NewReader("<html>")),
				}, nil
			}),
		},
	}

	t.Parallel()
	for _, ec := range cases {
		c := &parse.Client{
			Credentials: defaultRestAPIKey,
		}
		if !realTransport {
			c.Transport = ec.Transport
		}
		res, err := c.Do(ec.Request, ec.Body, nil)
		ensure.NotNil(t, err)
		ensure.StringContains(t, err.Error(), ec.Error, ec)
		if ec.StatusCode != 0 {
			ensure.False(t, res == nil, ec)
			ensure.DeepEqual(t, res.StatusCode, ec.StatusCode, ec)
		}
	}
}