132 lines
6.8 KiB
Go
132 lines
6.8 KiB
Go
package app
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/DATA-DOG/go-sqlmock"
|
|
)
|
|
|
|
func TestWebBranchCreateFromExistingAndEmpty(t *testing.T) {
|
|
requireGitForApp(t)
|
|
s, mock, cleanup := newMockServer(t)
|
|
defer cleanup()
|
|
user := User{ID: 1, Email: "alice@example.com", Username: "alice"}
|
|
repo := Repository{ID: 10, OwnerUserID: user.ID, Owner: "alice", Name: "demo", Visibility: "public", DefaultBranch: "main"}
|
|
bare := s.repoPath(repo.Owner, repo.Name)
|
|
if err := os.MkdirAll(filepath.Dir(bare), 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
seedRepoWithFeatureBranch(t, bare)
|
|
|
|
rr := httptest.NewRecorder()
|
|
s.ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/login", nil))
|
|
csrf := csrfFromResponse(t, rr)
|
|
|
|
expectLoadRepo(mock, "alice", "demo", repo)
|
|
expectBearerUser(mock, "tok", user)
|
|
rr = httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet, "/alice/demo/branches", nil)
|
|
req.AddCookie(&http.Cookie{Name: webAuthCookie, Value: "tok"})
|
|
s.ServeHTTP(rr, req)
|
|
if rr.Code != http.StatusOK || !strings.Contains(rr.Body.String(), "Branches for alice/demo") || !strings.Contains(rr.Body.String(), "New branch") || !strings.Contains(rr.Body.String(), "delete") {
|
|
t.Fatalf("branches page status=%d body=%s", rr.Code, rr.Body.String())
|
|
}
|
|
|
|
expectLoadRepo(mock, "alice", "demo", repo)
|
|
expectBearerUser(mock, "tok", user)
|
|
rr = httptest.NewRecorder()
|
|
req = httptest.NewRequest(http.MethodPost, "/alice/demo/branches", strings.NewReader("_csrf="+csrf.Value+"&name=copy&from=main"))
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
req.AddCookie(csrf)
|
|
req.AddCookie(&http.Cookie{Name: webAuthCookie, Value: "tok"})
|
|
s.ServeHTTP(rr, req)
|
|
if rr.Code != http.StatusSeeOther || rr.Header().Get("Location") != "/alice/demo/branches" || !gitBranchExists(bare, "copy") {
|
|
t.Fatalf("copy branch status=%d location=%q exists=%v body=%s", rr.Code, rr.Header().Get("Location"), gitBranchExists(bare, "copy"), rr.Body.String())
|
|
}
|
|
|
|
expectLoadRepo(mock, "alice", "demo", repo)
|
|
expectBearerUser(mock, "tok", user)
|
|
rr = httptest.NewRecorder()
|
|
req = httptest.NewRequest(http.MethodPost, "/alice/demo/branches", strings.NewReader("_csrf="+csrf.Value+"&name=empty"))
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
req.AddCookie(csrf)
|
|
req.AddCookie(&http.Cookie{Name: webAuthCookie, Value: "tok"})
|
|
s.ServeHTTP(rr, req)
|
|
if rr.Code != http.StatusSeeOther || rr.Header().Get("Location") != "/alice/demo/branches" || !gitBranchExists(bare, "empty") {
|
|
t.Fatalf("empty branch status=%d location=%q exists=%v body=%s", rr.Code, rr.Header().Get("Location"), gitBranchExists(bare, "empty"), rr.Body.String())
|
|
}
|
|
|
|
expectLoadRepo(mock, "alice", "demo", repo)
|
|
expectBearerUser(mock, "tok", user)
|
|
rr = httptest.NewRecorder()
|
|
req = httptest.NewRequest(http.MethodPost, "/alice/demo/branches/delete", strings.NewReader("_csrf="+csrf.Value+"&name=copy"))
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
req.AddCookie(csrf)
|
|
req.AddCookie(&http.Cookie{Name: webAuthCookie, Value: "tok"})
|
|
s.ServeHTTP(rr, req)
|
|
if rr.Code != http.StatusSeeOther || rr.Header().Get("Location") != "/alice/demo/branches" || gitBranchExists(bare, "copy") {
|
|
t.Fatalf("delete branch status=%d location=%q exists=%v body=%s", rr.Code, rr.Header().Get("Location"), gitBranchExists(bare, "copy"), rr.Body.String())
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestWebPRPagesCommentsAndProfile(t *testing.T) {
|
|
s, mock, cleanup := newMockServer(t)
|
|
defer cleanup()
|
|
now := time.Now().UTC()
|
|
user := User{ID: 1, Email: "alice@example.com", Username: "alice"}
|
|
repo := Repository{ID: 10, OwnerUserID: user.ID, Owner: "alice", Name: "demo", Visibility: "public", Description: "desc", DefaultBranch: "main", CreatedAt: now, UpdatedAt: now}
|
|
pr := PullRequest{ID: 30, Number: 2, TargetRepositoryID: repo.ID, SourceRepositoryID: repo.ID, AuthorUserID: user.ID, Author: "alice", SourceOwner: "alice", SourceRepo: "demo", SourceBranch: "feature", TargetOwner: "alice", TargetRepo: "demo", TargetBranch: "main", Title: "Fix", Description: "desc", Status: "open", CreatedAt: now, UpdatedAt: now}
|
|
|
|
mock.ExpectQuery("SELECT id, email, username, is_admin FROM users WHERE username").WithArgs("alice").WillReturnRows(sqlmock.NewRows([]string{"id", "email", "username", "is_admin"}).AddRow(user.ID, user.Email, user.Username, user.IsAdmin))
|
|
mock.ExpectQuery("FROM repositories r JOIN users u").WithArgs("alice").WillReturnRows(repoRows(repo))
|
|
rr := httptest.NewRecorder()
|
|
s.ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/alice", nil))
|
|
if rr.Code != http.StatusOK || !strings.Contains(rr.Body.String(), "Public repositories") || !strings.Contains(rr.Body.String(), "alice/demo") {
|
|
t.Fatalf("profile status=%d body=%s", rr.Code, rr.Body.String())
|
|
}
|
|
csrf := csrfFromResponse(t, rr)
|
|
|
|
expectLoadRepo(mock, "alice", "demo", repo)
|
|
mock.ExpectQuery("FROM pull_requests pr").WithArgs(repo.ID).WillReturnRows(prRows(pr))
|
|
rr = httptest.NewRecorder()
|
|
s.ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/alice/demo/pulls", nil))
|
|
if rr.Code != http.StatusOK || !strings.Contains(rr.Body.String(), "Fix") || !strings.Contains(rr.Body.String(), "alice/demo:feature") {
|
|
t.Fatalf("PR list status=%d body=%s", rr.Code, rr.Body.String())
|
|
}
|
|
|
|
expectLoadRepo(mock, "alice", "demo", repo)
|
|
mock.ExpectQuery("FROM pull_requests pr").WithArgs(repo.ID, pr.Number).WillReturnRows(prRows(pr))
|
|
mock.ExpectQuery("SELECT c.id, u.username").WithArgs(pr.ID).WillReturnRows(sqlmock.NewRows([]string{"id", "username", "body", "created_at", "updated_at"}).AddRow(int64(1), "alice", "hello", now, now))
|
|
rr = httptest.NewRecorder()
|
|
s.ServeHTTP(rr, httptest.NewRequest(http.MethodGet, "/alice/demo/pulls/2", nil))
|
|
if rr.Code != http.StatusOK || !strings.Contains(rr.Body.String(), "#2 Fix") || !strings.Contains(rr.Body.String(), "hello") {
|
|
t.Fatalf("PR view status=%d body=%s", rr.Code, rr.Body.String())
|
|
}
|
|
|
|
expectBearerUser(mock, "tok", user)
|
|
expectLoadRepo(mock, "alice", "demo", repo)
|
|
mock.ExpectQuery("FROM pull_requests pr").WithArgs(repo.ID, pr.Number).WillReturnRows(prRows(pr))
|
|
mock.ExpectExec("INSERT INTO pull_request_comments").WithArgs(pr.ID, user.ID, "new comment").WillReturnResult(sqlmock.NewResult(5, 1))
|
|
rr = httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodPost, "/alice/demo/pulls/2/comments", strings.NewReader("_csrf="+csrf.Value+"&body=new+comment"))
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
req.AddCookie(csrf)
|
|
req.AddCookie(&http.Cookie{Name: webAuthCookie, Value: "tok"})
|
|
s.ServeHTTP(rr, req)
|
|
if rr.Code != http.StatusSeeOther || rr.Header().Get("Location") != "/alice/demo/pulls/2" {
|
|
t.Fatalf("comment status=%d location=%q body=%s", rr.Code, rr.Header().Get("Location"), rr.Body.String())
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|