Skip to content

Commit cc57d51

Browse files
committed
tests(api): create tests for project and column handlers
1 parent a825ba0 commit cc57d51

File tree

12 files changed

+965
-13
lines changed

12 files changed

+965
-13
lines changed

models/fixtures/project.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,47 @@
6969
type: 2
7070
created_unix: 1688973000
7171
updated_unix: 1688973000
72+
73+
- id: 7
74+
title: project in archived repository
75+
owner_id: 0
76+
repo_id: 51
77+
is_closed: false
78+
creator_id: 30
79+
board_type: 1
80+
type: 2
81+
created_unix: 1688973000
82+
updated_unix: 1688973000
83+
84+
- id: 8
85+
title: project1 belongs to org3
86+
owner_id: 3
87+
repo_id: 0
88+
is_closed: true
89+
creator_id: 3
90+
board_type: 1
91+
type: 2
92+
created_unix: 1688973000
93+
updated_unix: 1688973000
94+
95+
- id: 9
96+
title: project2 belongs to org3
97+
owner_id: 3
98+
repo_id: 0
99+
is_closed: false
100+
creator_id: 3
101+
board_type: 1
102+
type: 2
103+
created_unix: 1688973000
104+
updated_unix: 1688973000
105+
106+
- id: 10
107+
title: project2 on repo1
108+
owner_id: 0
109+
repo_id: 1
110+
is_closed: false
111+
creator_id: 2
112+
board_type: 1
113+
type: 2
114+
created_unix: 1688973010
115+
updated_unix: 1688973010

models/fixtures/project_issue.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@
2121
issue_id: 5
2222
project_id: 1
2323
project_board_id: 3
24+
25+
-
26+
id: 5
27+
issue_id: 5
28+
project_id: 1
29+
project_board_id: 1

routers/api/v1/org/project.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ func CreateProject(ctx *context.APIContext) {
4747
// "$ref": "#/responses/error"
4848
// "422":
4949
// "$ref": "#/responses/validationError"
50-
// "423":
51-
// "$ref": "#/responses/repoArchivedError"
5250

5351
form := web.GetForm(ctx).(*api.CreateProjectOption)
5452

@@ -98,8 +96,6 @@ func GetProjects(ctx *context.APIContext) {
9896
// "$ref": "#/responses/forbidden"
9997
// "404":
10098
// "$ref": "#/responses/notFound"
101-
// "423":
102-
// "$ref": "#/responses/repoArchivedError"
10399

104100
listOptions := utils.GetListOptions(ctx)
105101
sortType := ctx.FormTrim("sort")

routers/api/v1/project/project.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func GetProject(ctx *context.APIContext) {
4949
return
5050
}
5151

52-
issuesMap, err := issues_model.LoadIssuesFromColumnList(ctx, columns)
52+
issuesMap, err := issues_model.LoadIssuesFromColumnList(ctx, columns, &issues_model.IssuesOptions{})
5353
if err != nil {
5454
ctx.ServerError("LoadIssuesOfColumns", err)
5555
return

routers/api/v1/project/project_column.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"code.gitea.io/gitea/modules/web"
1515
"code.gitea.io/gitea/services/context"
1616
"code.gitea.io/gitea/services/convert"
17+
project_service "code.gitea.io/gitea/services/projects"
1718
)
1819

1920
// GetProjectColumn returns a project column
@@ -416,7 +417,7 @@ func MoveIssues(ctx *context.APIContext) {
416417
}
417418
}
418419

419-
if err = project_model.MoveIssuesOnProjectColumn(ctx, column, sortedIssueIDs); err != nil {
420+
if err = project_service.MoveIssuesOnProjectColumn(ctx, ctx.Doer, column, sortedIssueIDs); err != nil {
420421
ctx.ServerError("MoveIssuesOnProjectColumn", err)
421422
return
422423
}

routers/api/v1/repo/project.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,11 @@ func CreateProject(ctx *context.APIContext) {
143143
ctx.JSON(http.StatusCreated, convert.ToProject(ctx, project))
144144
}
145145

146-
// UpdateIssueProject change an issue's project to another project in a repository
146+
// UpdateIssueProject moves issues from a project to another in a repository
147147
func UpdateIssueProject(ctx *context.APIContext) {
148148
// swagger:operation PUT /repos/{owner}/{reponame}/projects/{type} project repoUpdateIssueProject
149149
// ---
150-
// summary: Change an issue's project
150+
// summary: Moves issues from a project to another in a repository
151151
// consumes:
152152
// - application/json
153153
// parameters:
@@ -202,7 +202,7 @@ func UpdateIssueProject(ctx *context.APIContext) {
202202
return
203203
}
204204
if _, err := issues.LoadRepositories(ctx); err != nil {
205-
ctx.ServerError("LoadProjects", err)
205+
ctx.ServerError("LoadRepositories", err)
206206
return
207207
}
208208

routers/api/v1/user/project.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ func CreateProject(ctx *context.APIContext) {
4242
// "$ref": "#/responses/error"
4343
// "422":
4444
// "$ref": "#/responses/validationError"
45-
// "423":
46-
// "$ref": "#/responses/repoArchivedError"
4745

4846
form := web.GetForm(ctx).(*api.CreateProjectOption)
4947

@@ -93,8 +91,6 @@ func GetProjects(ctx *context.APIContext) {
9391
// "$ref": "#/responses/forbidden"
9492
// "404":
9593
// "$ref": "#/responses/notFound"
96-
// "423":
97-
// "$ref": "#/responses/repoArchivedError"
9894

9995
listOptions := utils.GetListOptions(ctx)
10096
sortType := ctx.FormTrim("sort")
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
// Copyright 2017 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package integration
5+
6+
import (
7+
"fmt"
8+
"net/http"
9+
"testing"
10+
11+
auth_model "code.gitea.io/gitea/models/auth"
12+
"code.gitea.io/gitea/models/unittest"
13+
user_model "code.gitea.io/gitea/models/user"
14+
api "code.gitea.io/gitea/modules/structs"
15+
"code.gitea.io/gitea/tests"
16+
"github.com/stretchr/testify/assert"
17+
)
18+
19+
func TestAPICreateOrgProject(t *testing.T) {
20+
createOrgProjectSuccessTestCases := []struct {
21+
testName string
22+
orgName string
23+
ctxUserID int64
24+
doerID int64
25+
title string
26+
content string
27+
templateType uint8
28+
cardType uint8
29+
}{
30+
{
31+
testName: "site admin create project successfully",
32+
ctxUserID: 3,
33+
doerID: 1,
34+
title: "site-admin",
35+
content: "project_description",
36+
templateType: 1,
37+
cardType: 2,
38+
},
39+
{
40+
testName: "org owner create project successfully",
41+
ctxUserID: 3,
42+
doerID: 2,
43+
title: "org-owner",
44+
content: "project_description",
45+
templateType: 1,
46+
cardType: 2,
47+
},
48+
{
49+
testName: "member create project successfully with write access",
50+
ctxUserID: 3,
51+
doerID: 4,
52+
title: "member-with-write-access",
53+
content: "project_description",
54+
templateType: 1,
55+
cardType: 2,
56+
},
57+
}
58+
59+
createOrgProjectFailTestCases := []struct {
60+
testName string
61+
orgName string
62+
ctxUserID int64
63+
doerID int64
64+
title string
65+
expectedStatus int
66+
}{
67+
{
68+
testName: "user is not in organization",
69+
orgName: "org3",
70+
ctxUserID: 3,
71+
doerID: 5,
72+
title: "user-not-in-org",
73+
expectedStatus: http.StatusForbidden,
74+
},
75+
{
76+
testName: "user is member but not sufficient access",
77+
orgName: "org17",
78+
ctxUserID: 17,
79+
doerID: 20,
80+
title: "member-not-sufficient-access",
81+
expectedStatus: http.StatusForbidden,
82+
},
83+
{
84+
testName: "project not created as title is empty",
85+
orgName: "org3",
86+
ctxUserID: 3,
87+
doerID: 2,
88+
title: "",
89+
expectedStatus: http.StatusUnprocessableEntity,
90+
},
91+
{
92+
testName: "project not created as title is too long",
93+
orgName: "org3",
94+
ctxUserID: 3,
95+
doerID: 2,
96+
title: "This is a very long title that will exceed the maximum allowed size of 100 characters. It keeps going beyond the limit.",
97+
expectedStatus: http.StatusUnprocessableEntity,
98+
},
99+
}
100+
101+
defer tests.PrepareTestEnv(t)()
102+
103+
for _, tt := range createOrgProjectFailTestCases {
104+
t.Run(tt.testName, func(t *testing.T) {
105+
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: tt.doerID})
106+
session := loginUser(t, user.Name)
107+
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin, auth_model.AccessTokenScopeWriteOrganization)
108+
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/projects", tt.orgName), &api.CreateProjectOption{
109+
Title: tt.title,
110+
}).AddTokenAuth(token)
111+
MakeRequest(t, req, tt.expectedStatus)
112+
})
113+
}
114+
115+
for _, tt := range createOrgProjectSuccessTestCases {
116+
t.Run(tt.testName, func(t *testing.T) {
117+
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: tt.doerID})
118+
session := loginUser(t, user.Name)
119+
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin, auth_model.AccessTokenScopeWriteOrganization)
120+
req := NewRequestWithJSON(t, "POST", "/api/v1/orgs/org3/projects", &api.CreateProjectOption{
121+
Title: tt.title,
122+
Content: tt.content,
123+
TemplateType: tt.templateType,
124+
CardType: tt.cardType,
125+
}).AddTokenAuth(token)
126+
resp := MakeRequest(t, req, http.StatusCreated)
127+
var apiProject api.Project
128+
DecodeJSON(t, resp, &apiProject)
129+
assert.Equal(t, tt.title, apiProject.Title)
130+
assert.Equal(t, tt.content, apiProject.Description)
131+
assert.Equal(t, tt.templateType, apiProject.TemplateType)
132+
assert.Equal(t, tt.cardType, apiProject.CardType)
133+
assert.Equal(t, tt.ctxUserID, apiProject.OwnerID)
134+
assert.Equal(t, tt.doerID, apiProject.CreatorID)
135+
})
136+
}
137+
}
138+
139+
func TestAPIGetOrgProjects(t *testing.T) {
140+
141+
defer tests.PrepareTestEnv(t)()
142+
143+
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
144+
session := loginUser(t, user.Name)
145+
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadAdmin, auth_model.AccessTokenScopeReadOrganization)
146+
147+
expectedProjects := []*api.Project{
148+
{
149+
Title: "project1 belongs to org3",
150+
OwnerID: 3,
151+
IsClosed: true,
152+
CreatorID: 3,
153+
TemplateType: 1,
154+
CardType: 2,
155+
},
156+
{
157+
Title: "project2 belongs to org3",
158+
OwnerID: 3,
159+
IsClosed: false,
160+
CreatorID: 3,
161+
TemplateType: 1,
162+
CardType: 2,
163+
},
164+
}
165+
166+
t.Run("failed to get projects org not found", func(t *testing.T) {
167+
req := NewRequest(t, "GET", "/api/v1/orgs/org90/projects").AddTokenAuth(token)
168+
MakeRequest(t, req, http.StatusNotFound)
169+
})
170+
t.Run("get projects successfully", func(t *testing.T) {
171+
req := NewRequest(t, "GET", "/api/v1/orgs/org3/projects").AddTokenAuth(token)
172+
resp := MakeRequest(t, req, http.StatusOK)
173+
var apiProjects []*api.Project
174+
DecodeJSON(t, resp, &apiProjects)
175+
assert.Equal(t, len(expectedProjects), len(apiProjects))
176+
for i, expectedProject := range expectedProjects {
177+
assert.Equal(t, expectedProject.Title, apiProjects[i].Title)
178+
assert.Equal(t, expectedProject.OwnerID, apiProjects[i].OwnerID)
179+
assert.Equal(t, expectedProject.IsClosed, apiProjects[i].IsClosed)
180+
assert.Equal(t, expectedProject.CreatorID, apiProjects[i].CreatorID)
181+
assert.Equal(t, expectedProject.TemplateType, apiProjects[i].TemplateType)
182+
assert.Equal(t, expectedProject.CardType, apiProjects[i].CardType)
183+
}
184+
})
185+
}

0 commit comments

Comments
 (0)