Skip to content

Commit 6eeadb2

Browse files
lunnylafriks
authored andcommitted
Hide unactive on explore users and some refactors (#2741)
* hide unactive on explore users and some refactors * fix test for removed Organizations * fix test for removed Organizations * fix imports * fix logic bug * refactor the toConds * Rename TestOrganizations to TestSearchUsers and add tests for users * fix other tests * fix other tests * fix watchers tests * fix comments and remove unused code
1 parent 0390030 commit 6eeadb2

File tree

15 files changed

+142
-150
lines changed

15 files changed

+142
-150
lines changed

models/fixtures/issue_watch.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
-
22
id: 1
3-
user_id: 1
3+
user_id: 9
44
issue_id: 1
55
is_watching: true
66
created_unix: 946684800

models/fixtures/user.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
avatar: avatar1
1414
avatar_email: [email protected]
1515
num_repos: 0
16+
is_active: true
1617

1718
-
1819
id: 2
@@ -62,6 +63,7 @@
6263
avatar_email: [email protected]
6364
num_repos: 0
6465
num_following: 1
66+
is_active: true
6567

6668
-
6769
id: 5

models/fixtures/watch.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010

1111
-
1212
id: 3
13-
user_id: 10
13+
user_id: 9
1414
repo_id: 1

models/issue_watch_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func TestCreateOrUpdateIssueWatch(t *testing.T) {
2525
func TestGetIssueWatch(t *testing.T) {
2626
assert.NoError(t, PrepareTestDatabase())
2727

28-
_, exists, err := GetIssueWatch(1, 1)
28+
_, exists, err := GetIssueWatch(9, 1)
2929
assert.Equal(t, true, exists)
3030
assert.NoError(t, err)
3131

models/notification_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@ func TestCreateOrUpdateIssueNotifications(t *testing.T) {
1616

1717
assert.NoError(t, CreateOrUpdateIssueNotifications(issue, 2))
1818

19-
// Two watchers are inactive, thus only notification for user 10 is created
20-
notf := AssertExistsAndLoadBean(t, &Notification{UserID: 10, IssueID: issue.ID}).(*Notification)
19+
// User 9 is inactive, thus notifications for user 1 and 4 are created
20+
notf := AssertExistsAndLoadBean(t, &Notification{UserID: 1, IssueID: issue.ID}).(*Notification)
2121
assert.Equal(t, NotificationStatusUnread, notf.Status)
2222
CheckConsistencyFor(t, &Issue{ID: issue.ID})
23+
24+
notf = AssertExistsAndLoadBean(t, &Notification{UserID: 4, IssueID: issue.ID}).(*Notification)
25+
assert.Equal(t, NotificationStatusUnread, notf.Status)
2326
}
2427

2528
func TestNotificationsForUser(t *testing.T) {

models/org.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -201,23 +201,6 @@ func CountOrganizations() int64 {
201201
return count
202202
}
203203

204-
// Organizations returns number of organizations in given page.
205-
func Organizations(opts *SearchUserOptions) ([]*User, error) {
206-
orgs := make([]*User, 0, opts.PageSize)
207-
208-
if len(opts.OrderBy) == 0 {
209-
opts.OrderBy = "name ASC"
210-
}
211-
212-
sess := x.
213-
Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).
214-
Where("type=1")
215-
216-
return orgs, sess.
217-
OrderBy(opts.OrderBy).
218-
Find(&orgs)
219-
}
220-
221204
// DeleteOrganization completely and permanently deletes everything of organization.
222205
func DeleteOrganization(org *User) (err error) {
223206
sess := x.NewSession()

models/org_test.go

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -237,27 +237,6 @@ func TestCountOrganizations(t *testing.T) {
237237
assert.Equal(t, expected, CountOrganizations())
238238
}
239239

240-
func TestOrganizations(t *testing.T) {
241-
assert.NoError(t, PrepareTestDatabase())
242-
testSuccess := func(opts *SearchUserOptions, expectedOrgIDs []int64) {
243-
orgs, err := Organizations(opts)
244-
assert.NoError(t, err)
245-
if assert.Len(t, orgs, len(expectedOrgIDs)) {
246-
for i, expectedOrgID := range expectedOrgIDs {
247-
assert.EqualValues(t, expectedOrgID, orgs[i].ID)
248-
}
249-
}
250-
}
251-
testSuccess(&SearchUserOptions{OrderBy: "id ASC", Page: 1, PageSize: 2},
252-
[]int64{3, 6})
253-
254-
testSuccess(&SearchUserOptions{OrderBy: "id ASC", Page: 2, PageSize: 2},
255-
[]int64{7, 17})
256-
257-
testSuccess(&SearchUserOptions{Page: 3, PageSize: 2},
258-
[]int64{})
259-
}
260-
261240
func TestDeleteOrganization(t *testing.T) {
262241
assert.NoError(t, PrepareTestDatabase())
263242
org := AssertExistsAndLoadBean(t, &User{ID: 6}).(*User)

models/repo_watch_test.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ func TestGetWatchers(t *testing.T) {
4040
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
4141
watches, err := GetWatchers(repo.ID)
4242
assert.NoError(t, err)
43-
// Two watchers are inactive, thus minus 2
44-
assert.Len(t, watches, repo.NumWatches-2)
43+
// One watchers are inactive, thus minus 1
44+
assert.Len(t, watches, repo.NumWatches-1)
4545
for _, watch := range watches {
4646
assert.EqualValues(t, repo.ID, watch.RepoID)
4747
}
@@ -62,7 +62,7 @@ func TestRepository_GetWatchers(t *testing.T) {
6262
AssertExistsAndLoadBean(t, &Watch{UserID: watcher.ID, RepoID: repo.ID})
6363
}
6464

65-
repo = AssertExistsAndLoadBean(t, &Repository{ID: 10}).(*Repository)
65+
repo = AssertExistsAndLoadBean(t, &Repository{ID: 9}).(*Repository)
6666
watchers, err = repo.GetWatchers(1)
6767
assert.NoError(t, err)
6868
assert.Len(t, watchers, 0)
@@ -78,7 +78,7 @@ func TestNotifyWatchers(t *testing.T) {
7878
}
7979
assert.NoError(t, NotifyWatchers(action))
8080

81-
// Two watchers are inactive, thus action is only created for user 8, 10
81+
// One watchers are inactive, thus action is only created for user 8, 1, 4
8282
AssertExistsAndLoadBean(t, &Action{
8383
ActUserID: action.ActUserID,
8484
UserID: 8,
@@ -87,7 +87,13 @@ func TestNotifyWatchers(t *testing.T) {
8787
})
8888
AssertExistsAndLoadBean(t, &Action{
8989
ActUserID: action.ActUserID,
90-
UserID: 10,
90+
UserID: 1,
91+
RepoID: action.RepoID,
92+
OpType: action.OpType,
93+
})
94+
AssertExistsAndLoadBean(t, &Action{
95+
ActUserID: action.ActUserID,
96+
UserID: 4,
9197
RepoID: action.RepoID,
9298
OpType: action.OpType,
9399
})

models/user.go

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
"code.gitea.io/gitea/modules/base"
3737
"code.gitea.io/gitea/modules/log"
3838
"code.gitea.io/gitea/modules/setting"
39+
"code.gitea.io/gitea/modules/util"
3940
)
4041

4142
// UserType defines the user type
@@ -729,22 +730,6 @@ func CountUsers() int64 {
729730
return countUsers(x)
730731
}
731732

732-
// Users returns number of users in given page.
733-
func Users(opts *SearchUserOptions) ([]*User, error) {
734-
if len(opts.OrderBy) == 0 {
735-
opts.OrderBy = "name ASC"
736-
}
737-
738-
users := make([]*User, 0, opts.PageSize)
739-
sess := x.
740-
Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).
741-
Where("type=0")
742-
743-
return users, sess.
744-
OrderBy(opts.OrderBy).
745-
Find(&users)
746-
}
747-
748733
// get user by verify code
749734
func getVerifyUser(code string) (user *User) {
750735
if len(code) <= base.TimeLimitCodeLength {
@@ -1284,45 +1269,50 @@ type SearchUserOptions struct {
12841269
OrderBy string
12851270
Page int
12861271
PageSize int // Can be smaller than or equal to setting.UI.ExplorePagingNum
1272+
IsActive util.OptionalBool
12871273
}
12881274

1289-
// SearchUserByName takes keyword and part of user name to search,
1290-
// it returns results in given range and number of total results.
1291-
func SearchUserByName(opts *SearchUserOptions) (users []*User, _ int64, _ error) {
1292-
if len(opts.Keyword) == 0 {
1293-
return users, 0, nil
1275+
func (opts *SearchUserOptions) toConds() builder.Cond {
1276+
var cond builder.Cond = builder.Eq{"type": opts.Type}
1277+
if len(opts.Keyword) > 0 {
1278+
lowerKeyword := strings.ToLower(opts.Keyword)
1279+
cond = cond.And(builder.Or(
1280+
builder.Like{"lower_name", lowerKeyword},
1281+
builder.Like{"LOWER(full_name)", lowerKeyword},
1282+
))
12941283
}
1295-
opts.Keyword = strings.ToLower(opts.Keyword)
12961284

1297-
if opts.PageSize <= 0 || opts.PageSize > setting.UI.ExplorePagingNum {
1298-
opts.PageSize = setting.UI.ExplorePagingNum
1299-
}
1300-
if opts.Page <= 0 {
1301-
opts.Page = 1
1285+
if !opts.IsActive.IsNone() {
1286+
cond = cond.And(builder.Eq{"is_active": opts.IsActive.IsTrue()})
13021287
}
13031288

1304-
users = make([]*User, 0, opts.PageSize)
1305-
1306-
// Append conditions
1307-
cond := builder.And(
1308-
builder.Eq{"type": opts.Type},
1309-
builder.Or(
1310-
builder.Like{"lower_name", opts.Keyword},
1311-
builder.Like{"LOWER(full_name)", opts.Keyword},
1312-
),
1313-
)
1289+
return cond
1290+
}
13141291

1292+
// SearchUsers takes options i.e. keyword and part of user name to search,
1293+
// it returns results in given range and number of total results.
1294+
func SearchUsers(opts *SearchUserOptions) (users []*User, _ int64, _ error) {
1295+
cond := opts.toConds()
13151296
count, err := x.Where(cond).Count(new(User))
13161297
if err != nil {
13171298
return nil, 0, fmt.Errorf("Count: %v", err)
13181299
}
13191300

1320-
sess := x.Where(cond).
1321-
Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
1322-
if len(opts.OrderBy) > 0 {
1323-
sess.OrderBy(opts.OrderBy)
1301+
if opts.PageSize <= 0 || opts.PageSize > setting.UI.ExplorePagingNum {
1302+
opts.PageSize = setting.UI.ExplorePagingNum
1303+
}
1304+
if opts.Page <= 0 {
1305+
opts.Page = 1
13241306
}
1325-
return users, count, sess.Find(&users)
1307+
if len(opts.OrderBy) == 0 {
1308+
opts.OrderBy = "name ASC"
1309+
}
1310+
1311+
users = make([]*User, 0, opts.PageSize)
1312+
return users, count, x.Where(cond).
1313+
Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).
1314+
OrderBy(opts.OrderBy).
1315+
Find(&users)
13261316
}
13271317

13281318
// GetStarredRepos returns the repos starred by a particular user

models/user_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"testing"
99

1010
"code.gitea.io/gitea/modules/setting"
11+
"code.gitea.io/gitea/modules/util"
1112

1213
"github.com/stretchr/testify/assert"
1314
)
@@ -38,6 +39,56 @@ func TestCanCreateOrganization(t *testing.T) {
3839
assert.False(t, user.CanCreateOrganization())
3940
}
4041

42+
func TestSearchUsers(t *testing.T) {
43+
assert.NoError(t, PrepareTestDatabase())
44+
testSuccess := func(opts *SearchUserOptions, expectedUserOrOrgIDs []int64) {
45+
users, _, err := SearchUsers(opts)
46+
assert.NoError(t, err)
47+
if assert.Len(t, users, len(expectedUserOrOrgIDs)) {
48+
for i, expectedID := range expectedUserOrOrgIDs {
49+
assert.EqualValues(t, expectedID, users[i].ID)
50+
}
51+
}
52+
}
53+
54+
// test orgs
55+
testOrgSuccess := func(opts *SearchUserOptions, expectedOrgIDs []int64) {
56+
opts.Type = UserTypeOrganization
57+
testSuccess(opts, expectedOrgIDs)
58+
}
59+
60+
testOrgSuccess(&SearchUserOptions{OrderBy: "id ASC", Page: 1, PageSize: 2},
61+
[]int64{3, 6})
62+
63+
testOrgSuccess(&SearchUserOptions{OrderBy: "id ASC", Page: 2, PageSize: 2},
64+
[]int64{7, 17})
65+
66+
testOrgSuccess(&SearchUserOptions{Page: 3, PageSize: 2},
67+
[]int64{})
68+
69+
// test users
70+
testUserSuccess := func(opts *SearchUserOptions, expectedUserIDs []int64) {
71+
opts.Type = UserTypeIndividual
72+
testSuccess(opts, expectedUserIDs)
73+
}
74+
75+
testUserSuccess(&SearchUserOptions{OrderBy: "id ASC", Page: 1},
76+
[]int64{1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18})
77+
78+
testUserSuccess(&SearchUserOptions{Page: 1, IsActive: util.OptionalBoolFalse},
79+
[]int64{9})
80+
81+
testUserSuccess(&SearchUserOptions{OrderBy: "id ASC", Page: 1, IsActive: util.OptionalBoolTrue},
82+
[]int64{1, 2, 4, 5, 8, 10, 11, 12, 13, 14, 15, 16, 18})
83+
84+
testUserSuccess(&SearchUserOptions{Keyword: "user1", OrderBy: "id ASC", Page: 1, IsActive: util.OptionalBoolTrue},
85+
[]int64{1, 10, 11, 12, 13, 14, 15, 16, 18})
86+
87+
// order by name asc default
88+
testUserSuccess(&SearchUserOptions{Keyword: "user1", Page: 1, IsActive: util.OptionalBoolTrue},
89+
[]int64{1, 10, 11, 12, 13, 14, 15, 16, 18})
90+
}
91+
4192
func TestDeleteUser(t *testing.T) {
4293
test := func(userID int64) {
4394
assert.NoError(t, PrepareTestDatabase())

modules/util/util.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ const (
1616
OptionalBoolFalse
1717
)
1818

19+
// IsTrue return true if equal to OptionalBoolTrue
20+
func (o OptionalBool) IsTrue() bool {
21+
return o == OptionalBoolTrue
22+
}
23+
24+
// IsFalse return true if equal to OptionalBoolFalse
25+
func (o OptionalBool) IsFalse() bool {
26+
return o == OptionalBoolFalse
27+
}
28+
29+
// IsNone return true if equal to OptionalBoolNone
30+
func (o OptionalBool) IsNone() bool {
31+
return o == OptionalBoolNone
32+
}
33+
1934
// OptionalBoolOf get the corresponding OptionalBool of a bool
2035
func OptionalBoolOf(b bool) OptionalBool {
2136
if b {

routers/admin/orgs.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ func Organizations(ctx *context.Context) {
2222
ctx.Data["PageIsAdmin"] = true
2323
ctx.Data["PageIsAdminOrganizations"] = true
2424

25-
routers.RenderUserSearch(ctx, &routers.UserSearchOptions{
25+
routers.RenderUserSearch(ctx, &models.SearchUserOptions{
2626
Type: models.UserTypeOrganization,
27-
Counter: models.CountOrganizations,
28-
Ranger: models.Organizations,
2927
PageSize: setting.UI.Admin.OrgPagingNum,
30-
TplName: tplOrgs,
31-
})
28+
}, tplOrgs)
3229
}

routers/admin/users.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,10 @@ func Users(ctx *context.Context) {
3030
ctx.Data["PageIsAdmin"] = true
3131
ctx.Data["PageIsAdminUsers"] = true
3232

33-
routers.RenderUserSearch(ctx, &routers.UserSearchOptions{
33+
routers.RenderUserSearch(ctx, &models.SearchUserOptions{
3434
Type: models.UserTypeIndividual,
35-
Counter: models.CountUsers,
36-
Ranger: models.Users,
3735
PageSize: setting.UI.Admin.UserPagingNum,
38-
TplName: tplUsers,
39-
})
36+
}, tplUsers)
4037
}
4138

4239
// NewUser render adding a new user page

routers/api/v1/user/user.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func Search(ctx *context.APIContext) {
3535
opts.PageSize = 10
3636
}
3737

38-
users, _, err := models.SearchUserByName(opts)
38+
users, _, err := models.SearchUsers(opts)
3939
if err != nil {
4040
ctx.JSON(500, map[string]interface{}{
4141
"ok": false,

0 commit comments

Comments
 (0)