parent
							
								
									1e3548b7e7
								
							
						
					
					
						commit
						3803f257fb
					
				
					 5 changed files with 123 additions and 72 deletions
				
			
		
							
								
								
									
										4
									
								
								models/fixtures/follow.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								models/fixtures/follow.yml
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | |||
| - | ||||
|   id: 1 | ||||
|   user_id: 4 | ||||
|   follow_id: 2 | ||||
|  | @ -26,6 +26,7 @@ | |||
|   avatar_email: user2@example.com | ||||
|   num_repos: 2 | ||||
|   num_stars: 2 | ||||
|   num_followers: 1 | ||||
| 
 | ||||
| - | ||||
|   id: 3 | ||||
|  | @ -56,6 +57,7 @@ | |||
|   avatar: avatar4 | ||||
|   avatar_email: user4@example.com | ||||
|   num_repos: 0 | ||||
|   num_following: 1 | ||||
| 
 | ||||
| - | ||||
|   id: 5 | ||||
|  | @ -72,6 +74,7 @@ | |||
|   num_repos: 1 | ||||
|   allow_create_organization: false | ||||
|   is_active: true | ||||
|   num_following: 0 | ||||
| 
 | ||||
| - | ||||
|   id: 6 | ||||
|  |  | |||
|  | @ -1292,78 +1292,6 @@ func SearchUserByName(opts *SearchUserOptions) (users []*User, _ int64, _ error) | |||
| 	return users, count, sess.Find(&users) | ||||
| } | ||||
| 
 | ||||
| // ___________    .__  .__
 | ||||
| // \_   _____/___ |  | |  |   ______  _  __
 | ||||
| //  |    __)/  _ \|  | |  |  /  _ \ \/ \/ /
 | ||||
| //  |     \(  <_> )  |_|  |_(  <_> )     /
 | ||||
| //  \___  / \____/|____/____/\____/ \/\_/
 | ||||
| //      \/
 | ||||
| 
 | ||||
| // Follow represents relations of user and his/her followers.
 | ||||
| type Follow struct { | ||||
| 	ID       int64 `xorm:"pk autoincr"` | ||||
| 	UserID   int64 `xorm:"UNIQUE(follow)"` | ||||
| 	FollowID int64 `xorm:"UNIQUE(follow)"` | ||||
| } | ||||
| 
 | ||||
| // IsFollowing returns true if user is following followID.
 | ||||
| func IsFollowing(userID, followID int64) bool { | ||||
| 	has, _ := x.Get(&Follow{UserID: userID, FollowID: followID}) | ||||
| 	return has | ||||
| } | ||||
| 
 | ||||
| // FollowUser marks someone be another's follower.
 | ||||
| func FollowUser(userID, followID int64) (err error) { | ||||
| 	if userID == followID || IsFollowing(userID, followID) { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	sess := x.NewSession() | ||||
| 	defer sessionRelease(sess) | ||||
| 	if err = sess.Begin(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Insert(&Follow{UserID: userID, FollowID: followID}); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Exec("UPDATE `user` SET num_followers = num_followers + 1 WHERE id = ?", followID); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Exec("UPDATE `user` SET num_following = num_following + 1 WHERE id = ?", userID); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return sess.Commit() | ||||
| } | ||||
| 
 | ||||
| // UnfollowUser unmarks someone as another's follower.
 | ||||
| func UnfollowUser(userID, followID int64) (err error) { | ||||
| 	if userID == followID || !IsFollowing(userID, followID) { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	sess := x.NewSession() | ||||
| 	defer sessionRelease(sess) | ||||
| 	if err = sess.Begin(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Delete(&Follow{UserID: userID, FollowID: followID}); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Exec("UPDATE `user` SET num_followers = num_followers - 1 WHERE id = ?", followID); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Exec("UPDATE `user` SET num_following = num_following - 1 WHERE id = ?", userID); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return sess.Commit() | ||||
| } | ||||
| 
 | ||||
| // GetStarredRepos returns the repos starred by a particular user
 | ||||
| func GetStarredRepos(userID int64, private bool) ([]*Repository, error) { | ||||
| 	sess := x.Where("star.uid=?", userID). | ||||
|  |  | |||
							
								
								
									
										71
									
								
								models/user_follow.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								models/user_follow.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,71 @@ | |||
| // Copyright 2017 The Gitea Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package models | ||||
| 
 | ||||
| // Follow represents relations of user and his/her followers.
 | ||||
| type Follow struct { | ||||
| 	ID       int64 `xorm:"pk autoincr"` | ||||
| 	UserID   int64 `xorm:"UNIQUE(follow)"` | ||||
| 	FollowID int64 `xorm:"UNIQUE(follow)"` | ||||
| } | ||||
| 
 | ||||
| // IsFollowing returns true if user is following followID.
 | ||||
| func IsFollowing(userID, followID int64) bool { | ||||
| 	has, _ := x.Get(&Follow{UserID: userID, FollowID: followID}) | ||||
| 	return has | ||||
| } | ||||
| 
 | ||||
| // FollowUser marks someone be another's follower.
 | ||||
| func FollowUser(userID, followID int64) (err error) { | ||||
| 	if userID == followID || IsFollowing(userID, followID) { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	sess := x.NewSession() | ||||
| 	defer sessionRelease(sess) | ||||
| 	if err = sess.Begin(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Insert(&Follow{UserID: userID, FollowID: followID}); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Exec("UPDATE `user` SET num_followers = num_followers + 1 WHERE id = ?", followID); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Exec("UPDATE `user` SET num_following = num_following + 1 WHERE id = ?", userID); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return sess.Commit() | ||||
| } | ||||
| 
 | ||||
| // UnfollowUser unmarks someone as another's follower.
 | ||||
| func UnfollowUser(userID, followID int64) (err error) { | ||||
| 	if userID == followID || !IsFollowing(userID, followID) { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	sess := x.NewSession() | ||||
| 	defer sessionRelease(sess) | ||||
| 	if err = sess.Begin(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Delete(&Follow{UserID: userID, FollowID: followID}); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Exec("UPDATE `user` SET num_followers = num_followers - 1 WHERE id = ?", followID); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err = sess.Exec("UPDATE `user` SET num_following = num_following - 1 WHERE id = ?", userID); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return sess.Commit() | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										45
									
								
								models/user_follow_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								models/user_follow_test.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | |||
| package models | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestIsFollowing(t *testing.T) { | ||||
| 	assert.NoError(t, PrepareTestDatabase()) | ||||
| 	assert.True(t, IsFollowing(4, 2)) | ||||
| 	assert.False(t, IsFollowing(2, 4)) | ||||
| 	assert.False(t, IsFollowing(5, NonexistentID)) | ||||
| 	assert.False(t, IsFollowing(NonexistentID, 5)) | ||||
| 	assert.False(t, IsFollowing(NonexistentID, NonexistentID)) | ||||
| } | ||||
| 
 | ||||
| func TestFollowUser(t *testing.T) { | ||||
| 	assert.NoError(t, PrepareTestDatabase()) | ||||
| 
 | ||||
| 	testSuccess := func(followerID, followedID int64) { | ||||
| 		assert.NoError(t, FollowUser(followerID, followedID)) | ||||
| 		AssertExistsAndLoadBean(t, &Follow{UserID: followerID, FollowID: followedID}) | ||||
| 	} | ||||
| 	testSuccess(4, 2) | ||||
| 	testSuccess(5, 2) | ||||
| 
 | ||||
| 	assert.NoError(t, FollowUser(2, 2)) | ||||
| 
 | ||||
| 	CheckConsistencyFor(t, &User{}) | ||||
| } | ||||
| 
 | ||||
| func TestUnfollowUser(t *testing.T) { | ||||
| 	assert.NoError(t, PrepareTestDatabase()) | ||||
| 
 | ||||
| 	testSuccess := func(followerID, followedID int64) { | ||||
| 		assert.NoError(t, UnfollowUser(followerID, followedID)) | ||||
| 		AssertNotExistsBean(t, &Follow{UserID: followerID, FollowID: followedID}) | ||||
| 	} | ||||
| 	testSuccess(4, 2) | ||||
| 	testSuccess(5, 2) | ||||
| 	testSuccess(2, 2) | ||||
| 
 | ||||
| 	CheckConsistencyFor(t, &User{}) | ||||
| } | ||||
		Loading…
	
		Reference in a new issue