1// Copyright 2019 The Gitea Authors. All rights reserved.
2// SPDX-License-Identifier: MIT
3
4package issue
5
6import (
7 "testing"
8
9 activities_model "forgejo.org/models/activities"
10 "forgejo.org/models/db"
11 issues_model "forgejo.org/models/issues"
12 repo_model "forgejo.org/models/repo"
13 "forgejo.org/models/unittest"
14 user_model "forgejo.org/models/user"
15 "forgejo.org/modules/repository"
16 "forgejo.org/modules/setting"
17
18 "github.com/stretchr/testify/require"
19)
20
21func TestUpdateIssuesCommit(t *testing.T) {
22 require.NoError(t, unittest.PrepareTestDatabase())
23 pushCommits := []*repository.PushCommit{
24 {
25 Sha1: "abcdef1",
26 CommitterEmail: "user2@example.com",
27 CommitterName: "User Two",
28 AuthorEmail: "user4@example.com",
29 AuthorName: "User Four",
30 Message: "start working on #FST-1, #1",
31 },
32 {
33 Sha1: "abcdef2",
34 CommitterEmail: "user2@example.com",
35 CommitterName: "User Two",
36 AuthorEmail: "user2@example.com",
37 AuthorName: "User Two",
38 Message: "a plain message",
39 },
40 {
41 Sha1: "abcdef2",
42 CommitterEmail: "user2@example.com",
43 CommitterName: "User Two",
44 AuthorEmail: "user2@example.com",
45 AuthorName: "User Two",
46 Message: "close #2",
47 },
48 }
49
50 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
51 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
52 repo.Owner = user
53
54 commentBean := &issues_model.Comment{
55 Type: issues_model.CommentTypeCommitRef,
56 CommitSHA: "abcdef1",
57 PosterID: user.ID,
58 IssueID: 1,
59 }
60 issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4}
61
62 unittest.AssertNotExistsBean(t, commentBean)
63 unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
64 require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
65 unittest.AssertExistsAndLoadBean(t, commentBean)
66 unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
67 unittest.CheckConsistencyFor(t, &activities_model.Action{})
68
69 // Test that push to a non-default branch closes no issue.
70 pushCommits = []*repository.PushCommit{
71 {
72 Sha1: "abcdef1",
73 CommitterEmail: "user2@example.com",
74 CommitterName: "User Two",
75 AuthorEmail: "user4@example.com",
76 AuthorName: "User Four",
77 Message: "close #1",
78 },
79 }
80 repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
81 commentBean = &issues_model.Comment{
82 Type: issues_model.CommentTypeCommitRef,
83 CommitSHA: "abcdef1",
84 PosterID: user.ID,
85 IssueID: 6,
86 }
87 issueBean = &issues_model.Issue{RepoID: repo.ID, Index: 1}
88
89 unittest.AssertNotExistsBean(t, commentBean)
90 unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1")
91 require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, "non-existing-branch"))
92 unittest.AssertExistsAndLoadBean(t, commentBean)
93 unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
94 unittest.CheckConsistencyFor(t, &activities_model.Action{})
95
96 pushCommits = []*repository.PushCommit{
97 {
98 Sha1: "abcdef3",
99 CommitterEmail: "user2@example.com",
100 CommitterName: "User Two",
101 AuthorEmail: "user2@example.com",
102 AuthorName: "User Two",
103 Message: "close " + setting.AppURL + repo.FullName() + "/pulls/1",
104 },
105 }
106 repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
107 commentBean = &issues_model.Comment{
108 Type: issues_model.CommentTypeCommitRef,
109 CommitSHA: "abcdef3",
110 PosterID: user.ID,
111 IssueID: 6,
112 }
113 issueBean = &issues_model.Issue{RepoID: repo.ID, Index: 1}
114
115 unittest.AssertNotExistsBean(t, commentBean)
116 unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1")
117 require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
118 unittest.AssertExistsAndLoadBean(t, commentBean)
119 unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
120 unittest.CheckConsistencyFor(t, &activities_model.Action{})
121}
122
123func TestUpdateIssuesCommit_Colon(t *testing.T) {
124 require.NoError(t, unittest.PrepareTestDatabase())
125 pushCommits := []*repository.PushCommit{
126 {
127 Sha1: "abcdef2",
128 CommitterEmail: "user2@example.com",
129 CommitterName: "User Two",
130 AuthorEmail: "user2@example.com",
131 AuthorName: "User Two",
132 Message: "close: #2",
133 },
134 }
135
136 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
137 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
138 repo.Owner = user
139
140 issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4}
141
142 unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
143 require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
144 unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
145 unittest.CheckConsistencyFor(t, &activities_model.Action{})
146}
147
148func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
149 require.NoError(t, unittest.PrepareTestDatabase())
150 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
151
152 // Test that push to a non-default branch closes an issue.
153 pushCommits := []*repository.PushCommit{
154 {
155 Sha1: "abcdef1",
156 CommitterEmail: "user2@example.com",
157 CommitterName: "User Two",
158 AuthorEmail: "user4@example.com",
159 AuthorName: "User Four",
160 Message: "close #2",
161 },
162 }
163
164 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
165 commentBean := &issues_model.Comment{
166 Type: issues_model.CommentTypeCommitRef,
167 CommitSHA: "abcdef1",
168 PosterID: user.ID,
169 IssueID: 7,
170 }
171
172 issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 2, ID: 7}
173
174 unittest.AssertNotExistsBean(t, commentBean)
175 unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
176 require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, "non-existing-branch"))
177 unittest.AssertExistsAndLoadBean(t, commentBean)
178 unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
179 unittest.CheckConsistencyFor(t, &activities_model.Action{})
180}
181
182func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) {
183 require.NoError(t, unittest.PrepareTestDatabase())
184 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
185
186 // Test that a push to default branch closes issue in another repo
187 // If the user also has push permissions to that repo
188 pushCommits := []*repository.PushCommit{
189 {
190 Sha1: "abcdef1",
191 CommitterEmail: "user2@example.com",
192 CommitterName: "User Two",
193 AuthorEmail: "user2@example.com",
194 AuthorName: "User Two",
195 Message: "close user2/repo1#1",
196 },
197 }
198
199 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
200 commentBean := &issues_model.Comment{
201 Type: issues_model.CommentTypeCommitRef,
202 CommitSHA: "abcdef1",
203 PosterID: user.ID,
204 IssueID: 1,
205 }
206
207 issueBean := &issues_model.Issue{RepoID: 1, Index: 1, ID: 1}
208
209 unittest.AssertNotExistsBean(t, commentBean)
210 unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
211 require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
212 unittest.AssertExistsAndLoadBean(t, commentBean)
213 unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
214 unittest.CheckConsistencyFor(t, &activities_model.Action{})
215}
216
217func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) {
218 require.NoError(t, unittest.PrepareTestDatabase())
219 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
220
221 // Test that a push to default branch closes issue in another repo
222 // If the user also has push permissions to that repo
223 pushCommits := []*repository.PushCommit{
224 {
225 Sha1: "abcdef1",
226 CommitterEmail: "user2@example.com",
227 CommitterName: "User Two",
228 AuthorEmail: "user2@example.com",
229 AuthorName: "User Two",
230 Message: "close " + setting.AppURL + "user2/repo1/issues/1",
231 },
232 }
233
234 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
235 commentBean := &issues_model.Comment{
236 Type: issues_model.CommentTypeCommitRef,
237 CommitSHA: "abcdef1",
238 PosterID: user.ID,
239 IssueID: 1,
240 }
241
242 issueBean := &issues_model.Issue{RepoID: 1, Index: 1, ID: 1}
243
244 unittest.AssertNotExistsBean(t, commentBean)
245 unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
246 require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
247 unittest.AssertExistsAndLoadBean(t, commentBean)
248 unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
249 unittest.CheckConsistencyFor(t, &activities_model.Action{})
250}
251
252func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
253 require.NoError(t, unittest.PrepareTestDatabase())
254 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10})
255
256 // Test that a push with close reference *can not* close issue
257 // If the committer doesn't have push rights in that repo
258 pushCommits := []*repository.PushCommit{
259 {
260 Sha1: "abcdef3",
261 CommitterEmail: "user10@example.com",
262 CommitterName: "User Ten",
263 AuthorEmail: "user10@example.com",
264 AuthorName: "User Ten",
265 Message: "close org3/repo3#1",
266 },
267 {
268 Sha1: "abcdef4",
269 CommitterEmail: "user10@example.com",
270 CommitterName: "User Ten",
271 AuthorEmail: "user10@example.com",
272 AuthorName: "User Ten",
273 Message: "close " + setting.AppURL + "org3/repo3/issues/1",
274 },
275 }
276
277 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 6})
278 commentBean := &issues_model.Comment{
279 Type: issues_model.CommentTypeCommitRef,
280 CommitSHA: "abcdef3",
281 PosterID: user.ID,
282 IssueID: 6,
283 }
284 commentBean2 := &issues_model.Comment{
285 Type: issues_model.CommentTypeCommitRef,
286 CommitSHA: "abcdef4",
287 PosterID: user.ID,
288 IssueID: 6,
289 }
290
291 issueBean := &issues_model.Issue{RepoID: 3, Index: 1, ID: 6}
292
293 unittest.AssertNotExistsBean(t, commentBean)
294 unittest.AssertNotExistsBean(t, commentBean2)
295 unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
296 require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
297 unittest.AssertNotExistsBean(t, commentBean)
298 unittest.AssertNotExistsBean(t, commentBean2)
299 unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
300 unittest.CheckConsistencyFor(t, &activities_model.Action{})
301}