1// Copyright 2017 The Gitea Authors. All rights reserved.
2// Use of this source code is governed by a MIT-style
3// license that can be found in the LICENSE file.
4
5package integrations
6
7import (
8	"net/http"
9	"net/http/httptest"
10	"net/url"
11	"path"
12	"testing"
13
14	"github.com/stretchr/testify/assert"
15)
16
17func TestCreateFile(t *testing.T) {
18	onGiteaRun(t, func(t *testing.T, u *url.URL) {
19		session := loginUser(t, "user2")
20
21		// Request editor page
22		req := NewRequest(t, "GET", "/user2/repo1/_new/master/")
23		resp := session.MakeRequest(t, req, http.StatusOK)
24
25		doc := NewHTMLParser(t, resp.Body)
26		lastCommit := doc.GetInputValueByName("last_commit")
27		assert.NotEmpty(t, lastCommit)
28
29		// Save new file to master branch
30		req = NewRequestWithValues(t, "POST", "/user2/repo1/_new/master/", map[string]string{
31			"_csrf":         doc.GetCSRF(),
32			"last_commit":   lastCommit,
33			"tree_path":     "test.txt",
34			"content":       "Content",
35			"commit_choice": "direct",
36		})
37		session.MakeRequest(t, req, http.StatusFound)
38	})
39}
40
41func TestCreateFileOnProtectedBranch(t *testing.T) {
42	onGiteaRun(t, func(t *testing.T, u *url.URL) {
43		session := loginUser(t, "user2")
44
45		csrf := GetCSRF(t, session, "/user2/repo1/settings/branches")
46		// Change master branch to protected
47		req := NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/master", map[string]string{
48			"_csrf":     csrf,
49			"protected": "on",
50		})
51		session.MakeRequest(t, req, http.StatusFound)
52		// Check if master branch has been locked successfully
53		flashCookie := session.GetCookie("macaron_flash")
54		assert.NotNil(t, flashCookie)
55		assert.EqualValues(t, "success%3DBranch%2Bprotection%2Bfor%2Bbranch%2B%2527master%2527%2Bhas%2Bbeen%2Bupdated.", flashCookie.Value)
56
57		// Request editor page
58		req = NewRequest(t, "GET", "/user2/repo1/_new/master/")
59		resp := session.MakeRequest(t, req, http.StatusOK)
60
61		doc := NewHTMLParser(t, resp.Body)
62		lastCommit := doc.GetInputValueByName("last_commit")
63		assert.NotEmpty(t, lastCommit)
64
65		// Save new file to master branch
66		req = NewRequestWithValues(t, "POST", "/user2/repo1/_new/master/", map[string]string{
67			"_csrf":         doc.GetCSRF(),
68			"last_commit":   lastCommit,
69			"tree_path":     "test.txt",
70			"content":       "Content",
71			"commit_choice": "direct",
72		})
73
74		resp = session.MakeRequest(t, req, http.StatusOK)
75		// Check body for error message
76		assert.Contains(t, resp.Body.String(), "Cannot commit to protected branch 'master'.")
77
78		// remove the protected branch
79		csrf = GetCSRF(t, session, "/user2/repo1/settings/branches")
80		// Change master branch to protected
81		req = NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/master", map[string]string{
82			"_csrf":     csrf,
83			"protected": "off",
84		})
85		resp = session.MakeRequest(t, req, http.StatusFound)
86		// Check if master branch has been locked successfully
87		flashCookie = session.GetCookie("macaron_flash")
88		assert.NotNil(t, flashCookie)
89		assert.EqualValues(t, "success%3DBranch%2Bprotection%2Bfor%2Bbranch%2B%2527master%2527%2Bhas%2Bbeen%2Bdisabled.", flashCookie.Value)
90	})
91}
92
93func testEditFile(t *testing.T, session *TestSession, user, repo, branch, filePath, newContent string) *httptest.ResponseRecorder {
94	// Get to the 'edit this file' page
95	req := NewRequest(t, "GET", path.Join(user, repo, "_edit", branch, filePath))
96	resp := session.MakeRequest(t, req, http.StatusOK)
97
98	htmlDoc := NewHTMLParser(t, resp.Body)
99	lastCommit := htmlDoc.GetInputValueByName("last_commit")
100	assert.NotEmpty(t, lastCommit)
101
102	// Submit the edits
103	req = NewRequestWithValues(t, "POST", path.Join(user, repo, "_edit", branch, filePath),
104		map[string]string{
105			"_csrf":         htmlDoc.GetCSRF(),
106			"last_commit":   lastCommit,
107			"tree_path":     filePath,
108			"content":       newContent,
109			"commit_choice": "direct",
110		},
111	)
112	resp = session.MakeRequest(t, req, http.StatusFound)
113
114	// Verify the change
115	req = NewRequest(t, "GET", path.Join(user, repo, "raw/branch", branch, filePath))
116	resp = session.MakeRequest(t, req, http.StatusOK)
117	assert.EqualValues(t, newContent, resp.Body.String())
118
119	return resp
120}
121
122func testEditFileToNewBranch(t *testing.T, session *TestSession, user, repo, branch, targetBranch, filePath, newContent string) *httptest.ResponseRecorder {
123
124	// Get to the 'edit this file' page
125	req := NewRequest(t, "GET", path.Join(user, repo, "_edit", branch, filePath))
126	resp := session.MakeRequest(t, req, http.StatusOK)
127
128	htmlDoc := NewHTMLParser(t, resp.Body)
129	lastCommit := htmlDoc.GetInputValueByName("last_commit")
130	assert.NotEmpty(t, lastCommit)
131
132	// Submit the edits
133	req = NewRequestWithValues(t, "POST", path.Join(user, repo, "_edit", branch, filePath),
134		map[string]string{
135			"_csrf":           htmlDoc.GetCSRF(),
136			"last_commit":     lastCommit,
137			"tree_path":       filePath,
138			"content":         newContent,
139			"commit_choice":   "commit-to-new-branch",
140			"new_branch_name": targetBranch,
141		},
142	)
143	resp = session.MakeRequest(t, req, http.StatusFound)
144
145	// Verify the change
146	req = NewRequest(t, "GET", path.Join(user, repo, "raw/branch", targetBranch, filePath))
147	resp = session.MakeRequest(t, req, http.StatusOK)
148	assert.EqualValues(t, newContent, resp.Body.String())
149
150	return resp
151}
152
153func TestEditFile(t *testing.T) {
154	onGiteaRun(t, func(t *testing.T, u *url.URL) {
155		session := loginUser(t, "user2")
156		testEditFile(t, session, "user2", "repo1", "master", "README.md", "Hello, World (Edited)\n")
157	})
158}
159
160func TestEditFileToNewBranch(t *testing.T) {
161	onGiteaRun(t, func(t *testing.T, u *url.URL) {
162		session := loginUser(t, "user2")
163		testEditFileToNewBranch(t, session, "user2", "repo1", "master", "feature/test", "README.md", "Hello, World (Edited)\n")
164	})
165}
166