Example #1
0
// TestUpdateUser tests the ability to updatee an
// existing User in the database.
func TestUpdateUser(t *testing.T) {
	Setup()
	defer Teardown()

	// get the user we plan to update
	user, err := database.GetUser(1)
	if err != nil {
		t.Error(err)
	}

	// update fields
	user.Email = "*****@*****.**"
	user.Password = "******"

	// update the database
	if err := database.SaveUser(user); err != nil {
		t.Error(err)
	}

	// get the updated user
	updatedUser, err := database.GetUser(1)
	if err != nil {
		t.Error(err)
	}

	// verify the updated fields
	if user.Email != updatedUser.Email {
		t.Errorf("Exepected Email %s, got %s", user.Email, updatedUser.Email)
	}

	if user.Password != updatedUser.Password {
		t.Errorf("Exepected Password %s, got %s", user.Email, updatedUser.Password)
	}
}
Example #2
0
// Repository Settings
func RepoSettingsForm(w http.ResponseWriter, r *http.Request, u *User, repo *Repo) error {

	// get the list of teams
	teams, err := database.ListTeams(u.ID)
	if err != nil {
		return err
	}

	data := struct {
		Repo  *Repo
		User  *User
		Teams []*Team
		Owner *User
		Team  *Team
	}{Repo: repo, User: u, Teams: teams}

	// get the repo owner
	if repo.TeamID > 0 {
		data.Team, err = database.GetTeam(repo.TeamID)
		if err != nil {
			return err
		}
	}

	// get the team owner
	data.Owner, err = database.GetUser(repo.UserID)
	if err != nil {
		return err
	}

	return RenderTemplate(w, "repo_settings.html", &data)
}
Example #3
0
// updateGitHubStatus is a helper function that will send
// the build status to GitHub using the Status API.
// see https://github.com/blog/1227-commit-status-api
func updateGitHubStatus(repo *Repo, commit *Commit) error {

	// convert from drone status to github status
	var message, status string
	switch commit.Status {
	case "Success":
		status = "success"
		message = "The build succeeded on drone.io"
	case "Failure":
		status = "failure"
		message = "The build failed on drone.io"
	case "Pending":
		status = "pending"
		message = "The build is pending on drone.io"
	default:
		status = "error"
		message = "The build errored on drone.io"
	}

	// get the system settings
	settings, _ := database.GetSettings()

	// get the user from the database
	// since we need his / her GitHub token
	user, err := database.GetUser(repo.UserID)
	if err != nil {
		return err
	}

	client := github.New(user.GithubToken)
	return client.Repos.CreateStatus(repo.Owner, repo.Name, status, settings.URL().String(), message, commit.Hash)
}
Example #4
0
// Update a specific Team Member.
func TeamMemberUpdate(w http.ResponseWriter, r *http.Request, u *User) error {
	roleParam := r.FormValue("Role")
	teamParam := r.FormValue(":team")

	// get the team from the database
	team, err := database.GetTeamSlug(teamParam)
	if err != nil {
		return RenderError(w, err, http.StatusNotFound)
	}
	// verify the user is a admin member of the team
	if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
		return fmt.Errorf("Forbidden")
	}

	// get the ID from the URL parameter
	idstr := r.FormValue("id")
	id, err := strconv.Atoi(idstr)
	if err != nil {
		return err
	}

	// get the user from the database
	user, err := database.GetUser(int64(id))
	if err != nil {
		return RenderError(w, err, http.StatusNotFound)
	}

	// add the user to the team
	if err := database.SaveMember(user.ID, team.ID, roleParam); err != nil {
		return RenderError(w, err, http.StatusInternalServerError)
	}

	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Example #5
0
// Return an HTML form for editing a Team Member.
func TeamMemberEdit(w http.ResponseWriter, r *http.Request, u *User) error {
	teamParam := r.FormValue(":team")
	team, err := database.GetTeamSlug(teamParam)
	if err != nil {
		return err
	}
	if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
		return fmt.Errorf("Forbidden")
	}

	// get the ID from the URL parameter
	idstr := r.FormValue("id")
	id, err := strconv.Atoi(idstr)
	if err != nil {
		return err
	}

	user, err := database.GetUser(int64(id))
	if err != nil {
		return err
	}
	member, err := database.GetMember(user.ID, team.ID)
	if err != nil {
		return err
	}
	data := struct {
		User   *User
		Team   *Team
		Member *Member
	}{u, team, member}
	return RenderTemplate(w, "members_edit.html", &data)
}
Example #6
0
func AdminUserUpdate(w http.ResponseWriter, r *http.Request, u *User) error {
	// get the ID from the URL parameter
	idstr := r.FormValue("id")
	id, err := strconv.Atoi(idstr)
	if err != nil {
		return err
	}

	// get the user from the database
	user, err := database.GetUser(int64(id))
	if err != nil {
		return err
	}

	// update if user is administrator or not
	switch r.FormValue("Admin") {
	case "true":
		user.Admin = true
	case "false":
		user.Admin = false
	}

	// saving user
	if err := database.SaveUser(user); err != nil {
		return err
	}

	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Example #7
0
// TestGetUser tests the ability to retrieve a User
// from the database by Unique ID.
func TestGetUser(t *testing.T) {
	Setup()
	defer Teardown()

	u, err := database.GetUser(1)
	if err != nil {
		t.Error(err)
	}

	if u.ID != 1 {
		t.Errorf("Exepected ID %d, got %d", 1, u.ID)
	}

	if u.Password != "$2a$10$b8d63QsTL38vx7lj0HEHfOdbu1PCAg6Gfca74UavkXooIBx9YxopS" {
		t.Errorf("Exepected Password %s, got %s", "$2a$10$b8d63QsTL38vx7lj0HEHfOdbu1PCAg6Gfca74UavkXooIBx9YxopS", u.Password)
	}

	if u.Token != "123" {
		t.Errorf("Exepected Token %s, got %s", "123", u.Token)
	}

	if u.Name != "Brad Rydzewski" {
		t.Errorf("Exepected Name %s, got %s", "Brad Rydzewski", u.Name)
	}

	if u.Email != "*****@*****.**" {
		t.Errorf("Exepected Email %s, got %s", "*****@*****.**", u.Email)
	}

	if u.Gravatar != "8c58a0be77ee441bb8f8595b7f1b4e87" {
		t.Errorf("Exepected Gravatar %s, got %s", "8c58a0be77ee441bb8f8595b7f1b4e87", u.Gravatar)
	}
}
Example #8
0
// Deletes an existing User account.
func TestDeleteUser(t *testing.T) {
	Setup()
	defer Teardown()

	// get the user we plan to update
	if err := database.DeleteUser(1); err != nil {
		t.Error(err)
	}

	// now try to get the user from the database
	_, err := database.GetUser(1)
	if err == nil {
		t.Fail()
	}
}
Example #9
0
// Form to edit a user
func AdminUserEdit(w http.ResponseWriter, r *http.Request, u *User) error {
	idstr := r.FormValue("id")
	id, err := strconv.Atoi(idstr)
	if err != nil {
		return err
	}

	// get the user from the database
	user, err := database.GetUser(int64(id))
	if err != nil {
		return err
	}

	data := struct {
		User     *User
		EditUser *User
	}{u, user}

	return RenderTemplate(w, "admin_users_edit.html", &data)
}
Example #10
0
// Delete a specific Team Member.
func TeamMemberDelete(w http.ResponseWriter, r *http.Request, u *User) error {
	// get the team from the database
	teamParam := r.FormValue(":team")
	team, err := database.GetTeamSlug(teamParam)
	if err != nil {
		return RenderNotFound(w)
	}

	if member, _ := database.IsMemberAdmin(u.ID, team.ID); !member {
		return fmt.Errorf("Forbidden")
	}

	// get the ID from the URL parameter
	idstr := r.FormValue("id")
	id, err := strconv.Atoi(idstr)
	if err != nil {
		return err
	}

	// get the user from the database
	user, err := database.GetUser(int64(id))
	if err != nil {
		return RenderNotFound(w)
	}
	// must be at least 1 member
	members, err := database.ListMembers(team.ID)
	if err != nil {
		return err
	} else if len(members) == 1 {
		return fmt.Errorf("There must be at least 1 member per team")
	}
	// delete the member
	database.DeleteMember(user.ID, team.ID)
	http.Redirect(w, r, fmt.Sprintf("/account/team/%s/members", team.Name), http.StatusSeeOther)
	return nil
}
Example #11
0
// Processes a generic POST-RECEIVE hook and
// attempts to trigger a build.
func Hook(w http.ResponseWriter, r *http.Request) error {

	// if this is a pull request route
	// to a different handler
	if r.Header.Get("X-Github-Event") == "pull_request" {
		PullRequestHook(w, r)
		return nil
	}

	// get the payload of the message
	// this should contain a json representation of the
	// repository and commit details
	payload := r.FormValue("payload")

	// parse the github Hook payload
	hook, err := github.ParseHook([]byte(payload))
	if err != nil {
		println("could not parse hook")
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// make sure this is being triggered because of a commit
	// and not something like a tag deletion or whatever
	if hook.IsTag() || hook.IsGithubPages() ||
		hook.IsHead() == false || hook.IsDeleted() {
		return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
	}

	// get the repo from the URL
	repoId := r.FormValue("id")

	// get the repo from the database, return error if not found
	repo, err := database.GetRepoSlug(repoId)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	// Get the user that owns the repository
	user, err := database.GetUser(repo.UserID)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// Verify that the commit doesn't already exist.
	// We should never build the same commit twice.
	_, err = database.GetCommitHash(hook.Head.Id, repo.ID)
	if err != nil && err != sql.ErrNoRows {
		println("commit already exists")
		return RenderText(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway)
	}

	// we really only need:
	//  * repo owner
	//  * repo name
	//  * repo host (github)
	//  * commit hash
	//  * commit timestamp
	//  * commit branch
	//  * commit message
	//  * commit author
	//  * pull request

	// once we have this data we could just send directly to the queue
	// and let it handle everything else

	commit := &Commit{}
	commit.RepoID = repo.ID
	commit.Branch = hook.Branch()
	commit.Hash = hook.Head.Id
	commit.Status = "Pending"
	commit.Created = time.Now().UTC()

	// extract the author and message from the commit
	// this is kind of experimental, since I don't know
	// what I'm doing here.
	if hook.Head != nil && hook.Head.Author != nil {
		commit.Message = hook.Head.Message
		commit.Timestamp = hook.Head.Timestamp
		commit.SetAuthor(hook.Head.Author.Email)
	} else if hook.Commits != nil && len(hook.Commits) > 0 && hook.Commits[0].Author != nil {
		commit.Message = hook.Commits[0].Message
		commit.Timestamp = hook.Commits[0].Timestamp
		commit.SetAuthor(hook.Commits[0].Author.Email)
	}

	// get the drone.yml file from GitHub
	client := github.New(user.GithubToken)
	content, err := client.Contents.FindRef(repo.Owner, repo.Name, ".drone.yml", commit.Hash)
	if err != nil {
		msg := "No .drone.yml was found in this repository.  You need to add one.\n"
		if err := saveFailedBuild(commit, msg); err != nil {
			return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// decode the content.  Note: Not sure this will ever happen...it basically means a GitHub API issue
	raw, err := content.DecodeContent()
	if err != nil {
		msg := "Could not decode the yaml from GitHub.  Check that your .drone.yml is a valid yaml file.\n"
		if err := saveFailedBuild(commit, msg); err != nil {
			return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// parse the build script
	buildscript, err := script.ParseBuild(raw)
	if err != nil {
		msg := "Could not parse your .drone.yml file.  It needs to be a valid drone yaml file.\n\n" + err.Error() + "\n"
		if err := saveFailedBuild(commit, msg); err != nil {
			return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// save the commit to the database
	if err := database.SaveCommit(commit); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	// save the build to the database
	build := &Build{}
	build.Slug = "1" // TODO
	build.CommitID = commit.ID
	build.Created = time.Now().UTC()
	build.Status = "Pending"
	if err := database.SaveBuild(build); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	// notify websocket that a new build is pending
	//realtime.CommitPending(repo.UserID, repo.TeamID, repo.ID, commit.ID, repo.Private)
	//realtime.BuildPending(repo.UserID, repo.TeamID, repo.ID, commit.ID, build.ID, repo.Private)

	queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build, Script: buildscript}) //Push(repo, commit, build, buildscript)

	// OK!
	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Example #12
0
func PullRequestHook(w http.ResponseWriter, r *http.Request) {

	// get the payload of the message
	// this should contain a json representation of the
	// repository and commit details
	payload := r.FormValue("payload")

	println("GOT PR HOOK")
	println(payload)

	hook, err := github.ParsePullRequestHook([]byte(payload))
	if err != nil {
		RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}

	// ignore these
	if hook.Action != "opened" && hook.Action != "synchronize" {
		RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
		return
	}

	// get the repo from the URL
	repoId := r.FormValue("id")

	// get the repo from the database, return error if not found
	repo, err := database.GetRepoSlug(repoId)
	if err != nil {
		RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}

	// Get the user that owns the repository
	user, err := database.GetUser(repo.UserID)
	if err != nil {
		RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}

	// Verify that the commit doesn't already exist.
	// We should enver build the same commit twice.
	_, err = database.GetCommitHash(hook.PullRequest.Head.Sha, repo.ID)
	if err != nil && err != sql.ErrNoRows {
		RenderText(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway)
		return
	}

	///////////////////////////////////////////////////////

	commit := &Commit{}
	commit.RepoID = repo.ID
	commit.Branch = hook.PullRequest.Head.Ref
	commit.Hash = hook.PullRequest.Head.Sha
	commit.Status = "Pending"
	commit.Created = time.Now().UTC()
	commit.Gravatar = hook.PullRequest.User.GravatarId
	commit.PullRequest = strconv.Itoa(hook.Number)
	commit.Message = hook.PullRequest.Title
	// label := p.PullRequest.Head.Labe

	// get the drone.yml file from GitHub
	client := github.New(user.GithubToken)
	content, err := client.Contents.FindRef(repo.Owner, repo.Name, ".drone.yml", commit.Hash) // TODO should this really be the hash??
	if err != nil {
		println(err.Error())
		RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}

	// decode the content
	raw, err := content.DecodeContent()
	if err != nil {
		RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}

	// parse the build script
	buildscript, err := script.ParseBuild(raw)
	if err != nil {
		// TODO if the YAML is invalid we should create a commit record
		// with an ERROR status so that the user knows why a build wasn't
		// triggered in the system
		RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}

	// save the commit to the database
	if err := database.SaveCommit(commit); err != nil {
		RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}

	// save the build to the database
	build := &Build{}
	build.Slug = "1" // TODO
	build.CommitID = commit.ID
	build.Created = time.Now().UTC()
	build.Status = "Pending"
	if err := database.SaveBuild(build); err != nil {
		RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}

	// notify websocket that a new build is pending
	// TODO we should, for consistency, just put this inside Queue.Add()
	queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build, Script: buildscript})

	// OK!
	RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Example #13
0
// Processes a generic POST-RECEIVE Bitbucket hook and
// attempts to trigger a build.
func (h *BitbucketHandler) Hook(w http.ResponseWriter, r *http.Request) error {
	// get the payload from the request
	payload := r.FormValue("payload")

	// parse the post-commit hook
	hook, err := bitbucket.ParseHook([]byte(payload))
	if err != nil {
		return err
	}

	// get the repo from the URL
	repoId := r.FormValue("id")

	// get the repo from the database, return error if not found
	repo, err := database.GetRepoSlug(repoId)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	// Get the user that owns the repository
	user, err := database.GetUser(repo.UserID)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// Verify that the commit doesn't already exist.
	// We should never build the same commit twice.
	_, err = database.GetCommitHash(hook.Commits[len(hook.Commits)-1].Hash, repo.ID)
	if err != nil && err != sql.ErrNoRows {
		return RenderText(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway)
	}

	commit := &Commit{}
	commit.RepoID = repo.ID
	commit.Branch = hook.Commits[len(hook.Commits)-1].Branch
	commit.Hash = hook.Commits[len(hook.Commits)-1].Hash
	commit.Status = "Pending"
	commit.Created = time.Now().UTC()
	commit.Message = hook.Commits[len(hook.Commits)-1].Message
	commit.Timestamp = time.Now().UTC().String()
	commit.SetAuthor(hook.Commits[len(hook.Commits)-1].Author)

	// get the github settings from the database
	settings := database.SettingsMust()

	// create the Bitbucket client
	client := bitbucket.New(
		settings.BitbucketKey,
		settings.BitbucketSecret,
		user.BitbucketToken,
		user.BitbucketSecret,
	)

	// get the yaml from the database
	raw, err := client.Sources.Find(repo.Owner, repo.Name, commit.Hash, ".drone.yml")
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	// parse the build script
	buildscript, err := script.ParseBuild([]byte(raw.Data), repo.Params)
	if err != nil {
		msg := "Could not parse your .drone.yml file.  It needs to be a valid drone yaml file.\n\n" + err.Error() + "\n"
		if err := saveFailedBuild(commit, msg); err != nil {
			return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// save the commit to the database
	if err := database.SaveCommit(commit); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	// save the build to the database
	build := &Build{}
	build.Slug = "1" // TODO
	build.CommitID = commit.ID
	build.Created = time.Now().UTC()
	build.Status = "Pending"
	if err := database.SaveBuild(build); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	// send the build to the queue
	h.queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build, Script: buildscript})

	// OK!
	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
}
Example #14
0
func (g *GitlabHandler) Hook(w http.ResponseWriter, r *http.Request) error {
	rID := r.FormValue("id")
	repo, err := database.GetRepoSlug(rID)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	user, err := database.GetUser(repo.UserID)
	if err != nil {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	payload, _ := ioutil.ReadAll(r.Body)
	parsed, err := gogitlab.ParseHook(payload)
	if err != nil {
		return err
	}
	if parsed.ObjectKind == "merge_request" {
		fmt.Println(string(payload))
		if err := g.PullRequestHook(parsed, repo, user); err != nil {
			return err
		}
		return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
	}

	if len(parsed.After) == 0 {
		return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
	}

	_, err = database.GetCommitHash(parsed.After, repo.ID)
	if err != nil && err != sql.ErrNoRows {
		fmt.Println("commit already exists")
		return RenderText(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway)
	}

	commit := &Commit{}
	commit.RepoID = repo.ID
	commit.Branch = parsed.Branch()
	commit.Hash = parsed.After
	commit.Status = "Pending"
	commit.Created = time.Now().UTC()

	head := parsed.Head()
	commit.Message = head.Message
	commit.Timestamp = head.Timestamp
	if head.Author != nil {
		commit.SetAuthor(head.Author.Email)
	} else {
		commit.SetAuthor(parsed.UserName)
	}

	// get the github settings from the database
	settings := database.SettingsMust()

	// get the drone.yml file from GitHub
	client := gogitlab.NewGitlab(settings.GitlabApiUrl, g.apiPath, user.GitlabToken)

	buildscript, err := client.RepoRawFile(ns(repo.Owner, repo.Name), commit.Hash, ".drone.yml")
	if err != nil {
		msg := "No .drone.yml was found in this repository.  You need to add one.\n"
		if err := saveFailedBuild(commit, msg); err != nil {
			return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		}
		return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
	}

	// save the commit to the database
	if err := database.SaveCommit(commit); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	// save the build to the database
	build := &Build{}
	build.Slug = "1" // TODO
	build.CommitID = commit.ID
	build.Created = time.Now().UTC()
	build.Status = "Pending"
	build.BuildScript = string(buildscript)
	if err := database.SaveBuild(build); err != nil {
		return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
	}

	g.queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build})

	// OK!
	return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)

}
Example #15
0
// Tests the ability to create GitHub repositories.
func Test_GitHubCreate(t *testing.T) {
	// seed the database with values
	SetupFixtures()
	defer TeardownFixtures()

	// mock request
	req := http.Request{}
	req.Form = url.Values{}

	// get user that will add repositories
	user, _ := database.GetUser(1)
	settings := database.SettingsMust()

	Convey("Given request to setup github repo", t, func() {

		Convey("When repository is public", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "public")
			req.Form.Set("team", "")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)
			repo, _ := database.GetRepoSlug(settings.GitHubDomain + "/example/public")

			Convey("The repository is created", func() {
				So(err, ShouldBeNil)
				So(repo, ShouldNotBeNil)
				So(repo.ID, ShouldNotEqual, 0)
				So(repo.Owner, ShouldEqual, "example")
				So(repo.Name, ShouldEqual, "public")
				So(repo.Host, ShouldEqual, settings.GitHubDomain)
				So(repo.TeamID, ShouldEqual, 0)
				So(repo.UserID, ShouldEqual, user.ID)
				So(repo.Private, ShouldEqual, false)
				So(repo.SCM, ShouldEqual, "git")
			})
			Convey("The repository is public", func() {
				So(repo.Private, ShouldEqual, false)
			})
		})

		Convey("When repository is private", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "private")
			req.Form.Set("team", "")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)
			repo, _ := database.GetRepoSlug(settings.GitHubDomain + "/example/private")

			Convey("The repository is created", func() {
				So(err, ShouldBeNil)
				So(repo, ShouldNotBeNil)
				So(repo.ID, ShouldNotEqual, 0)
			})
			Convey("The repository is private", func() {
				So(repo.Private, ShouldEqual, true)
			})
		})

		Convey("When repository is not found", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "notfound")
			req.Form.Set("team", "")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)

			Convey("The result is an error", func() {
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "Unable to find GitHub repository example/notfound.")
			})

			Convey("The repository is not created", func() {
				_, err := database.GetRepoSlug("example/notfound")
				So(err, ShouldNotBeNil)
				So(err, ShouldEqual, sql.ErrNoRows)
			})
		})

		Convey("When repository hook is not writable", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "hookerr")
			req.Form.Set("team", "")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)

			Convey("The result is an error", func() {
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "Unable to add Hook to your GitHub repository.")
			})

			Convey("The repository is not created", func() {
				_, err := database.GetRepoSlug("example/hookerr")
				So(err, ShouldNotBeNil)
				So(err, ShouldEqual, sql.ErrNoRows)
			})
		})

		Convey("When repository ssh key is not writable", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "keyerr")
			req.Form.Set("team", "")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)

			Convey("The result is an error", func() {
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "Unable to add Public Key to your GitHub repository.")
			})

			Convey("The repository is not created", func() {
				_, err := database.GetRepoSlug("example/keyerr")
				So(err, ShouldNotBeNil)
				So(err, ShouldEqual, sql.ErrNoRows)
			})
		})

		Convey("When a team is provided", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "team")
			req.Form.Set("team", "drone")
			res := httptest.NewRecorder()

			// invoke handler
			err := handler.RepoCreateGithub(res, &req, user)
			team, _ := database.GetTeamSlug("drone")
			repo, _ := database.GetRepoSlug(settings.GitHubDomain + "/example/team")

			Convey("The repository is created", func() {
				So(err, ShouldBeNil)
				So(repo, ShouldNotBeNil)
				So(repo.ID, ShouldNotEqual, 0)
			})

			Convey("The team should be set", func() {
				So(repo.TeamID, ShouldEqual, team.ID)
			})
		})

		Convey("When a team is not found", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "public")
			req.Form.Set("team", "faketeam")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)

			Convey("The result is an error", func() {
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "Unable to find Team faketeam.")
			})
		})

		Convey("When a team is forbidden", func() {
			req.Form.Set("owner", "example")
			req.Form.Set("name", "public")
			req.Form.Set("team", "golang")
			res := httptest.NewRecorder()
			err := handler.RepoCreateGithub(res, &req, user)

			Convey("The result is an error", func() {
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "Invalid permission to access Team golang.")
			})
		})
	})
}
Example #16
0
func TestUserProfilePage(t *testing.T) {
	// seed the database with values
	Setup()
	defer Teardown()

	// dummy request
	req := http.Request{}
	req.Form = url.Values{}

	Convey("User Profile", t, func() {
		SkipConvey("View Profile Information", func() {
			user, _ := database.GetUser(1)
			res := httptest.NewRecorder()
			handler.UserUpdate(res, &req, user)

			Convey("Email Address is correct", func() {

			})
			Convey("User Name is correct", func() {

			})
		})
		Convey("Update Email Address", func() {
			Convey("With a Valid Email Address", func() {
				user, _ := database.GetUser(1)
				req.Form.Set("name", "John Smith")
				req.Form.Set("email", "*****@*****.**")
				res := httptest.NewRecorder()
				handler.UserUpdate(res, &req, user)

				So(res.Code, ShouldEqual, http.StatusOK)
			})
			Convey("With an Invalid Email Address", func() {
				user, _ := database.GetUser(1)
				req.Form.Set("name", "John Smith")
				req.Form.Set("email", "John.Smith")
				res := httptest.NewRecorder()
				handler.UserUpdate(res, &req, user)

				So(res.Code, ShouldEqual, http.StatusBadRequest)
				So(res.Body.String(), ShouldContainSubstring, ErrInvalidEmail.Error())
			})
			Convey("With an Empty Email Address", func() {
				user, _ := database.GetUser(1)
				req.Form.Set("name", "John Smith")
				req.Form.Set("email", "")
				res := httptest.NewRecorder()
				handler.UserUpdate(res, &req, user)

				So(res.Code, ShouldEqual, http.StatusBadRequest)
				So(res.Body.String(), ShouldContainSubstring, ErrInvalidEmail.Error())
			})
			Convey("With a Duplicate Email Address", func() {
				user, _ := database.GetUser(1)
				req.Form.Set("name", "John Smith")
				req.Form.Set("email", "*****@*****.**")
				res := httptest.NewRecorder()
				handler.UserUpdate(res, &req, user)

				So(res.Code, ShouldEqual, http.StatusBadRequest)
			})
		})

		Convey("Update User Name", func() {
			Convey("With a Valid Name", func() {
				user, _ := database.GetUser(1)
				req.Form.Set("name", "John Smith")
				req.Form.Set("email", "*****@*****.**")
				res := httptest.NewRecorder()
				handler.UserUpdate(res, &req, user)

				So(res.Code, ShouldEqual, http.StatusOK)
			})
			Convey("With an Empty Name", func() {
				user, _ := database.GetUser(1)
				req.Form.Set("name", "")
				req.Form.Set("email", "*****@*****.**")
				res := httptest.NewRecorder()
				handler.UserUpdate(res, &req, user)

				So(res.Code, ShouldEqual, http.StatusBadRequest)
				So(res.Body.String(), ShouldContainSubstring, ErrInvalidUserName.Error())
			})
		})

		Convey("Change Password", func() {
			Convey("To a Valid Password", func() {
				user, _ := database.GetUser(1)
				req.Form.Set("password", "password123")
				res := httptest.NewRecorder()
				handler.UserPassUpdate(res, &req, user)

				So(res.Code, ShouldEqual, http.StatusOK)
				So(user.ComparePassword("password123"), ShouldBeNil)
			})
			Convey("To an Invalid Password, too short", func() {
				user, _ := database.GetUser(1)
				req.Form.Set("password", "123")
				res := httptest.NewRecorder()
				handler.UserPassUpdate(res, &req, user)

				So(res.Code, ShouldEqual, http.StatusBadRequest)
			})
		})
		Convey("Delete the Account", func() {
			Convey("Providing an Invalid Password", func() {
				user, _ := database.GetUser(1)
				req.Form.Set("password", "password111")
				res := httptest.NewRecorder()
				handler.UserDelete(res, &req, user)

				So(res.Code, ShouldEqual, http.StatusBadRequest)
			})
			SkipConvey("Providing a Valid Password", func() {
				// TODO Skipping because there are no teampltes
				// loaded which will cause a panic
				user, _ := database.GetUser(2)
				req.Form.Set("password", "password")
				res := httptest.NewRecorder()
				handler.UserDelete(res, &req, user)

				So(res.Code, ShouldEqual, http.StatusOK)
			})
		})
	})
}