Пример #1
0
func TestHubInsert(t *testing.T) {
	// setup database
	db := testhelpers.SetupDB(t)

	// insert new user
	u := &data.User{
		Username:          "******",
		Email:             "*****@*****.**",
		EncryptedPassword: "******",
	}
	if err := u.Insert(db); err != nil {
		t.Error("Failed to insert user to db: %v", u)
	}

	h := &data.Hub{
		Slug:   "earthworm",
		UserID: 1,
	}
	if err := h.Insert(db); err != nil {
		t.Error("Failed to insert h to db: %v", h)
	}

	// check if returned values are scanned back to the struct
	if h.ID == 0 {
		t.Error("ID must be set")
	}

	if h.CreatedAt == nil {
		t.Error("CreatedAt must be set")
	}

	if h.UpdatedAt == nil {
		t.Error("UpdatedAt must be set")
	}

	// check if adding existing hub violates unique constraint
	h2 := &data.Hub{
		Slug:   "earthworm",
		UserID: 1,
	}
	err := h2.Insert(db)

	if err == nil {
		t.Error("Insert should return an error")
	}
	e, ok := err.(*data.Error)
	if !ok {
		t.Error("Returned error must be of type `data.Error`")
	}
	if e.Code != "unique_violation" {
		t.Error("Error code must be 'unique violation' but received %s", e.Code)
	}
	if e.Desc != "hub exists" {
		t.Error("Error desc must be 'hub exists' but received %s", e.Desc)
	}

	db.Close()
}
Пример #2
0
func TestHubDelete(t *testing.T) {
	// setup database
	db := testhelpers.SetupDB(t)

	// insert new user
	u := &data.User{
		Username:          "******",
		Email:             "*****@*****.**",
		EncryptedPassword: "******",
	}
	if err := u.Insert(db); err != nil {
		t.Error("Failed to insert user to db: %v", u)
	}

	h := &data.Hub{
		Slug:   "earthworm",
		UserID: 1,
	}
	if err := h.Insert(db); err != nil {
		t.Error("Failed to insert h to db: %v", h)
	}

	h1 := &data.Hub{
		Slug: "earthworm",
	}
	if err := h1.Delete(db); err != nil {
		t.Error("Failed to get hubs with hub: earthworm")
	}
	if h1.Slug != h.Slug {
		t.Error("Unexpected user record returned: %v", h1)
	}

	// check if returned values from Delete are scanned back to the struct
	if h1.ID == 0 {
		t.Error("ID must be set")
	}

	if h1.CreatedAt == nil {
		t.Error("CreatedAt must be set")
	}

	if h1.UpdatedAt == nil {
		t.Error("UpdatedAt must be set")
	}

	// query for a non-existing hub
	h2 := &data.Hub{
		Slug: "snail",
	}
	err := h2.Delete(db)
	if err == nil {
		t.Error("Delete should return an error")
	}

	//TODO: Add a test case of other errors (eg: db already closed)
	db.Close()
}
Пример #3
0
func TestHubGet(t *testing.T) {
	// setup database
	db := testhelpers.SetupDB(t)

	// insert new user
	u := &data.User{
		Username:          "******",
		Email:             "*****@*****.**",
		EncryptedPassword: "******",
	}
	if err := u.Insert(db); err != nil {
		t.Error("Failed to insert user to db: %v", u)
	}

	// insert new hub
	h := &data.Hub{
		Slug:   "earthworm",
		UserID: 1,
	}
	if err := h.Insert(db); err != nil {
		t.Error("Failed to insert h to db: %v", h)
	}

	// query for the inserted hub by hub
	h1 := &data.Hub{}
	if err := h1.Get(db, "earthworm"); err != nil {
		t.Error("Failed to get hubs with hub: earthworm")
	}
	if h1.UserID != h.UserID {
		t.Error("Unexpected user record returned: %v", h1)
	}

	// query for a non-existing hub
	h2 := &data.Hub{}
	err := h2.Get(db, "snail")
	if err == nil {
		t.Error("Get should return an error")
	}
	e, ok := err.(*data.Error)
	if !ok {
		t.Error("Returned error must be of type `data.Error`")
	}
	if e.Code != "record_not_found" {
		t.Error("Error code must be 'record_not_found' but received %s", e.Code)
	}
	if e.Desc != "hub not found" {
		t.Error("Error desc must be 'hub not found' but received %s", e.Desc)
	}

	//TODO: Add a test case of other errors (eg: db already closed)
	db.Close()
}
Пример #4
0
func TestTokenGet(t *testing.T) {
	// setup database
	db := testhelpers.SetupDB(t)

	// insert new user
	u := &data.User{
		Username:          "******",
		Email:             "*****@*****.**",
		EncryptedPassword: "******",
	}
	if err := u.Insert(db); err != nil {
		t.Error("Failed to insert user to db: %v", u)
	}

	// insert a new token for the user
	tok := &data.Token{
		UserID:    u.ID,
		ExpiresIn: (30 * 24 * time.Hour).Nanoseconds(),
	}
	if err := tok.Insert(db); err != nil {
		t.Error("Failed to insert token to db: %v", u)
	}

	// query for the inserted token
	tok1 := &data.Token{}
	if err := tok1.Get(db, tok.ID); err != nil {
		t.Error("Failed to find token for id: ", tok.ID)
	}
	if tok1.ID != tok.ID {
		t.Error("Unexpected token returned: %v", tok1)
	}

	// query for a non-existing token
	tok2 := &data.Token{}
	err := tok2.Get(db, 9999)
	if err == nil {
		t.Error("Get should return an error")
	}
	e, ok := err.(*data.Error)
	if !ok {
		t.Error("Returned error must be of type `data.Error`")
	}
	if e.Code != "record_not_found" {
		t.Error("Error code must be 'record_not_found' but received %s", e.Code)
	}
	if e.Desc != "token not found" {
		t.Error("Error desc must be 'token not found' but received %s", e.Desc)
	}

	// TODO: Add a test case of other errors (eg: db already closed)
	db.Close()
}
Пример #5
0
func TestGetByLogin(t *testing.T) {
	// setup database
	db := testhelpers.SetupDB(t)

	// insert new user
	u := &data.User{
		Username:          "******",
		Email:             "*****@*****.**",
		EncryptedPassword: "******",
	}
	if err := u.Insert(db); err != nil {
		t.Error("Failed to insert user to db: %v", u)
	}

	// query for the inserted user by username
	u1 := &data.User{}
	if err := u1.GetByLogin(db, "chucknorris"); err != nil {
		t.Error("Failed to get user with username: chucknorris")
	}
	if u1.ID != u.ID {
		t.Error("Unexpected user record returned: %v", u1)
	}

	// query for the inserted user by email
	u2 := &data.User{}
	if err := u2.GetByLogin(db, "*****@*****.**"); err != nil {
		t.Error("Failed to get user with email: [email protected]")
	}
	if u2.ID != u.ID {
		t.Error("Unexpected user record returned: %v", u2)
	}

	// query for a non-existing user
	u3 := &data.User{}
	err := u3.GetByLogin(db, "jackiechan")
	e, ok := err.(*data.Error)
	if !ok {
		t.Error("Returned error must be of type `data.Error`")
	}
	if e.Code != "record_not_found" {
		t.Error("Error code must be 'record_not_found' but received %s", e.Code)
	}
	if e.Desc != "user not found" {
		t.Error("Error desc must be 'user not found' but received %s", e.Desc)
	}

	// TODO: Add a test case of other errors (eg: db already closed)
	db.Close()
}
Пример #6
0
func TestTokenInsert(t *testing.T) {
	// setup database
	db := testhelpers.SetupDB(t)

	// insert new user
	u := &data.User{
		Username:          "******",
		Email:             "*****@*****.**",
		EncryptedPassword: "******",
	}
	if err := u.Insert(db); err != nil {
		t.Error("Failed to insert user to db: %v", u)
	}

	// insert a new token for the user
	tok := &data.Token{
		UserID:    u.ID,
		ExpiresIn: (30 * 24 * time.Hour).Nanoseconds(),
	}
	if err := tok.Insert(db); err != nil {
		t.Error("Failed to insert token to db: %v", u)
	}

	// check if returned values are scanned back to the struct
	if tok.ID == 0 {
		t.Error("ID must be set")
	}

	if tok.CreatedAt == nil {
		t.Error("CreatedAt must be set")
	}

	// RevokedAt should be nil
	if tok.RevokedAt != nil {
		t.Error("RevokedAt must be nil")
	}

	// insert a token for non-existing user
	tok2 := &data.Token{
		UserID:    9999,
		ExpiresIn: (30 * 24 * time.Hour).Nanoseconds(),
	}
	if err := tok2.Insert(db); err == nil {
		t.Error("Token insert must fail if user does not exist")
	}

	db.Close()
}
Пример #7
0
func TestAddHub(t *testing.T) {
	// setup DB
	db := testhelpers.SetupDB(t)
	defer db.Close()

	// setup server
	ts, err := setupServerHub(db, []byte("secret"))
	if err != nil {
		t.Fatal(err)
	}
	defer ts.Close()

	// create a user
	u := &data.User{
		Username: "******",
		Email:    "*****@*****.**",
	}
	if err := u.EncryptPassword("password"); err != nil {
		t.Fatal(err)
	}
	if err = u.Insert(db); err != nil {
		t.Fatal(err)
	}

	// create a token for the user
	tok := data.Token{
		UserID:    u.ID,
		ExpiresIn: (30 * 24 * time.Hour).Nanoseconds(), // 30 days
	}
	if err := tok.Insert(db); err != nil {
		t.Fatal(err)
	}

	// get the encoded JSON Web Token
	jwt, err := tok.EncodeJWT([]byte("secret"))
	if err != nil {
		t.Fatal(err)
	}

	hub := data.Hub{
		Slug:   "1234",
		UserID: u.ID,
	}
	if err := hub.Insert(db); err != nil {
		t.Fatal(err)
	}

	type testCase struct {
		path       string
		statusCode int
		body       string
	}

	// test when valid params are provided
	spath := "?slug=abcd&access_token=" + jwt
	res, err := http.Get(ts.URL + "/api/v0/hub" + spath)
	if err != nil {
		t.Fatal(err)
	}
	if res.StatusCode != http.StatusOK {
		t.Errorf("%s - Expected status code %v, Got %v", spath, http.StatusOK, res.StatusCode)
	}
	b, err := ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		t.Fatal(err)
	}
	h := data.Hub{}
	if err := json.Unmarshal(b, &h); err != nil {
		t.Errorf("%s - Expected response body to be %+v, Got %s", spath, h, b)
	}

	tCases := []testCase{
		// when slug param is missing
		{"?access_token=" + jwt, http.StatusBadRequest, `{"error":"invalid_request","error_description":"slug required"}`},

		// when access_token param is missing
		{"?slug=abcd", http.StatusUnauthorized, `{"error":"invalid_token","error_description":"no token present in request"}`},

		// when trying to add existing hub
		{"?slug=1234&access_token=" + jwt, http.StatusBadRequest, `{"error":"unique_violation","error_description":"hub exists"}`},
	}
	for _, tc := range tCases {
		res, err := http.Get(ts.URL + "/api/v0/hub" + tc.path)
		if err != nil {
			t.Fatal(err)
		}
		if res.StatusCode != tc.statusCode {
			t.Errorf("%s - Expected status code %v, Got %v", tc.path, tc.statusCode, res.StatusCode)
		}
		b, err := ioutil.ReadAll(res.Body)
		res.Body.Close()
		if err != nil {
			t.Fatal(err)
		}

		if body := string(b); body != tc.body {
			t.Errorf("%s - Expected response body to be %v, Got %v", tc.path, tc.body, body)
		}
	}
}
Пример #8
0
func TestShowHub(t *testing.T) {
	// setup DB
	db := testhelpers.SetupDB(t)
	defer db.Close()

	// setup server
	ts, err := setupServerHub(db, []byte("secret"))
	if err != nil {
		t.Fatal(err)
	}
	defer ts.Close()

	// create a user
	u := &data.User{
		Username: "******",
		Email:    "*****@*****.**",
	}
	if err := u.EncryptPassword("password"); err != nil {
		t.Fatal(err)
	}
	if err = u.Insert(db); err != nil {
		t.Fatal(err)
	}

	// create a token for the user
	tok := data.Token{
		UserID:    u.ID,
		ExpiresIn: (30 * 24 * time.Hour).Nanoseconds(), // 30 days
	}
	if err := tok.Insert(db); err != nil {
		t.Fatal(err)
	}

	// get the encoded JSON Web Token
	jwt, err := tok.EncodeJWT([]byte("secret"))
	if err != nil {
		t.Fatal(err)
	}

	hub := data.Hub{
		Slug:   "abcd",
		UserID: u.ID,
	}
	if err := hub.Insert(db); err != nil {
		t.Fatal(err)
	}

	type testCase struct {
		path       string
		statusCode int
		body       string
	}

	tCases := []testCase{
		// when valid params are provided
		{"?access_token=" + jwt, http.StatusOK, `{"hub":["abcd"]}`},

		// when access_token param is missing
		{"?" + jwt, http.StatusUnauthorized, `{"error":"invalid_token","error_description":"no token present in request"}`},
	}
	for _, tc := range tCases {
		res, err := http.Post(ts.URL+"/api/v0/hub"+tc.path, "", nil)
		if err != nil {
			t.Fatal(err)
		}
		if res.StatusCode != tc.statusCode {
			t.Errorf("%s - Expected status code %v, Got %v", tc.path, tc.statusCode, res.StatusCode)
		}
		b, err := ioutil.ReadAll(res.Body)
		res.Body.Close()
		if err != nil {
			t.Fatal(err)
		}

		if body := string(b); body != tc.body {
			t.Errorf("%s - Expected response body to be %v, Got %v", tc.path, tc.body, body)
		}
	}
}
Пример #9
0
func TestAuthToken(t *testing.T) {
	// setup DB
	db := testhelpers.SetupDB(t)
	defer db.Close()

	// setup server
	ts, err := setupServer(db, []byte("secret"))
	if err != nil {
		t.Fatal(err)
	}
	defer ts.Close()

	// create a user
	u := &data.User{
		Username: "******",
		Email:    "*****@*****.**",
	}
	if err := u.EncryptPassword("password"); err != nil {
		t.Fatal(err)
	}
	if err = u.Insert(db); err != nil {
		t.Fatal(err)
	}

	// create a token for the user
	tok := data.Token{
		UserID:    u.ID,
		ExpiresIn: (30 * 24 * time.Hour).Nanoseconds(), // 30 days
	}
	if err := tok.Insert(db); err != nil {
		t.Fatal(err)
	}

	// get the encoded JSON Web Token
	jwt, err := tok.EncodeJWT([]byte("secret"))
	if err != nil {
		t.Fatal(err)
	}

	type testCase struct {
		path       string
		statusCode int
		body       string
	}

	tCases := []testCase{
		// when access token not provided
		{"hub", http.StatusUnauthorized, `{"error":"invalid_token","error_description":"no token present in request"}`},

		// when access token is invalid
		{"hub?access_token=invalid", http.StatusUnauthorized, `{"error":"invalid_token","error_description":"token contains an invalid number of segments"}`},

		// // when access token is not properly scoped
		// // fixme currently valid scopes are ["user", "hub", "app"]
		// {"admin?access_token=" + jwt, http.statusforbidden, `{"error":"invalid_scope","error_description":"token is not valid for this scope"}`},

		// when a valid token is provided
		{"hub?access_token=" + jwt, http.StatusOK, `{"status":"ok"}`},

		// when access token is revoked
		// TODO
	}
	for _, tc := range tCases {
		res, err := http.Get(ts.URL + path.Join("/api/v0", tc.path))
		if err != nil {
			t.Fatal(err)
		}
		if res.StatusCode != tc.statusCode {
			t.Errorf("%s - Expected status code %v, Got %v", tc.path, tc.statusCode, res.StatusCode)
		}
		b, err := ioutil.ReadAll(res.Body)
		res.Body.Close()
		if err != nil {
			t.Fatal(err)
		}
		if body := string(b); body != tc.body {
			t.Errorf("%s - Expected response body to be %v, Got %v", tc.path, tc.body, body)
		}
	}
}
Пример #10
0
func TestUserToken(t *testing.T) {
	// setup DB
	db := testhelpers.SetupDB(t)
	defer db.Close()

	// setup server
	ts, err := setupServerUser(db, []byte("secret"))
	if err != nil {
		t.Fatal(err)
	}
	defer ts.Close()

	// create a user
	u := &data.User{
		Username: "******",
		Email:    "*****@*****.**",
	}
	if err := u.EncryptPassword("password"); err != nil {
		t.Fatal(err)
	}
	if err = u.Insert(db); err != nil {
		t.Fatal(err)
	}

	tok := data.Token{
		UserID:    u.ID,
		ExpiresIn: (30 * 24 * time.Hour).Nanoseconds(), // 30 days
	}
	if err := tok.Insert(db); err != nil {
		t.Fatal(err)
	}

	//	// get the encoded JSON Web Token
	//	jwt, err := tok.EncodeJWT([]byte("secret"))
	//	if err != nil {
	//		t.Fatal(err)
	//	}

	type testCase struct {
		path       string
		statusCode int
		body       string
	}

	tCases := []testCase{
		// when valid params are provided
		// FIXME: find out why signature in jwt is different from response
		//		{"?grant_type=password&login=foo&password=password", http.StatusOK, `{"access_token":` + jwt + `","token_type":"bearer","expires_in":"720h0m0s"}`},

		// when grant_type param is invalid/missing
		{"?login=foo&password=password", http.StatusBadRequest, `{"error":"unsupported_grant_type","error_description":"supports only password grant type"}`},

		// when login param is missing
		{"?grant_type=password&password=password", http.StatusBadRequest, `{"error":"invalid_request","error_description":"login required"}`},

		// when password param is missing
		{"?grant_type=password&login=foo", http.StatusBadRequest, `{"error":"invalid_request","error_description":"password required"}`},

		// when password value is incorrect
		{"?grant_type=password&login=foo&password=abcd", http.StatusBadRequest, `{"error":"invalid_grant","error_description":"failed to authenticate user"}`},

		// when login value is incorrect
		{"?grant_type=password&login=bar&password=password", http.StatusBadRequest, `{"error":"invalid_grant","error_description":"user not found"}`},
	}

	for _, tc := range tCases {
		res, err := http.Post(ts.URL+"/oauth/token"+tc.path, "", nil)
		if err != nil {
			t.Fatal(err)
		}
		if res.StatusCode != tc.statusCode {
			t.Errorf("%s - Expected status code %v, Got %v", tc.path, tc.statusCode, res.StatusCode)
		}
		b, err := ioutil.ReadAll(res.Body)
		res.Body.Close()
		if err != nil {
			t.Fatal(err)
		}

		if body := string(b); body != tc.body {
			t.Errorf("%s - Expected response body to be %v, Got %v", tc.path, tc.body, body)
		}
	}
}
Пример #11
0
func TestSignup(t *testing.T) {
	// setup DB
	db := testhelpers.SetupDB(t)
	defer db.Close()

	// setup server
	ts, err := setupServerUser(db, []byte("secret"))
	if err != nil {
		t.Fatal(err)
	}
	defer ts.Close()

	type testCase struct {
		path       string
		statusCode int
		body       string
	}

	// test when valid params are provided
	spath := "?username=foo&[email protected]&password=password"
	res, err := http.Post(ts.URL+"/signup"+spath, "", nil)
	if err != nil {
		t.Fatal(err)
	}
	if res.StatusCode != http.StatusCreated {
		t.Errorf("%s - Expected status code %v, Got %v", spath, http.StatusCreated, res.StatusCode)
	}
	b, err := ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		t.Fatal(err)
	}
	u := data.User{}
	if err := json.Unmarshal(b, &u); err != nil {
		t.Errorf("%s - Expected response body to be %+v, Got %s", spath, u, b)
	}

	//test when invalid params are provided
	tCases := []testCase{
		// when username param is missing
		{"[email protected]&password=password", http.StatusBadRequest, `{"error":"username_required","error_description":"username required"}`},

		// when email param is missing
		{"?username=foo&password=password", http.StatusBadRequest, `{"error":"email_required","error_description":"email required"}`},

		// when password param is missing
		{"?username=foo&[email protected]", http.StatusBadRequest, `{"error":"password_required","error_description":"password required"}`},
	}

	for _, tc := range tCases {
		res, err := http.Post(ts.URL+"/signup"+tc.path, "", nil)
		if err != nil {
			t.Fatal(err)
		}
		if res.StatusCode != tc.statusCode {
			t.Errorf("%s - Expected status code %v, Got %v", tc.path, tc.statusCode, res.StatusCode)
		}
		b, err := ioutil.ReadAll(res.Body)
		res.Body.Close()
		if err != nil {
			t.Fatal(err)
		}

		if body := string(b); body != tc.body {
			t.Errorf("%s - Expected response body to be %v, Got %v", tc.path, tc.body, body)
		}
	}
}