// 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) } }
// 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) }
// 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) }
// 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) }
// 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) }
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) }
// 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) } }
// 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() } }
// 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) }
// 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 }
// 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) }
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) }
// 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) }
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) }
// 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.") }) }) }) }
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) }) }) }) }