You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

api_repo_lfs_locks_test.go 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. package integrations
  5. import (
  6. "fmt"
  7. "net/http"
  8. "testing"
  9. "time"
  10. "code.gitea.io/gitea/models"
  11. "code.gitea.io/gitea/models/unittest"
  12. user_model "code.gitea.io/gitea/models/user"
  13. "code.gitea.io/gitea/modules/lfs"
  14. "code.gitea.io/gitea/modules/setting"
  15. api "code.gitea.io/gitea/modules/structs"
  16. "github.com/stretchr/testify/assert"
  17. )
  18. func TestAPILFSLocksNotStarted(t *testing.T) {
  19. defer prepareTestEnv(t)()
  20. setting.LFS.StartServer = false
  21. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
  22. repo := unittest.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
  23. req := NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks", user.Name, repo.Name)
  24. MakeRequest(t, req, http.StatusNotFound)
  25. req = NewRequestf(t, "POST", "/%s/%s.git/info/lfs/locks", user.Name, repo.Name)
  26. MakeRequest(t, req, http.StatusNotFound)
  27. req = NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks/verify", user.Name, repo.Name)
  28. MakeRequest(t, req, http.StatusNotFound)
  29. req = NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks/10/unlock", user.Name, repo.Name)
  30. MakeRequest(t, req, http.StatusNotFound)
  31. }
  32. func TestAPILFSLocksNotLogin(t *testing.T) {
  33. defer prepareTestEnv(t)()
  34. setting.LFS.StartServer = true
  35. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
  36. repo := unittest.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
  37. req := NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks", user.Name, repo.Name)
  38. req.Header.Set("Accept", lfs.MediaType)
  39. resp := MakeRequest(t, req, http.StatusUnauthorized)
  40. var lfsLockError api.LFSLockError
  41. DecodeJSON(t, resp, &lfsLockError)
  42. assert.Equal(t, "You must have pull access to list locks", lfsLockError.Message)
  43. }
  44. func TestAPILFSLocksLogged(t *testing.T) {
  45. defer prepareTestEnv(t)()
  46. setting.LFS.StartServer = true
  47. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) //in org 3
  48. user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) //in org 3
  49. repo1 := unittest.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
  50. repo3 := unittest.AssertExistsAndLoadBean(t, &models.Repository{ID: 3}).(*models.Repository) // own by org 3
  51. tests := []struct {
  52. user *user_model.User
  53. repo *models.Repository
  54. path string
  55. httpResult int
  56. addTime []int
  57. }{
  58. {user: user2, repo: repo1, path: "foo/bar.zip", httpResult: http.StatusCreated, addTime: []int{0}},
  59. {user: user2, repo: repo1, path: "path/test", httpResult: http.StatusCreated, addTime: []int{0}},
  60. {user: user2, repo: repo1, path: "path/test", httpResult: http.StatusConflict},
  61. {user: user2, repo: repo1, path: "Foo/BaR.zip", httpResult: http.StatusConflict},
  62. {user: user2, repo: repo1, path: "Foo/Test/../subFOlder/../Relative/../BaR.zip", httpResult: http.StatusConflict},
  63. {user: user4, repo: repo1, path: "FoO/BaR.zip", httpResult: http.StatusUnauthorized},
  64. {user: user4, repo: repo1, path: "path/test-user4", httpResult: http.StatusUnauthorized},
  65. {user: user2, repo: repo1, path: "patH/Test-user4", httpResult: http.StatusCreated, addTime: []int{0}},
  66. {user: user2, repo: repo1, path: "some/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/long/path", httpResult: http.StatusCreated, addTime: []int{0}},
  67. {user: user2, repo: repo3, path: "test/foo/bar.zip", httpResult: http.StatusCreated, addTime: []int{1, 2}},
  68. {user: user4, repo: repo3, path: "test/foo/bar.zip", httpResult: http.StatusConflict},
  69. {user: user4, repo: repo3, path: "test/foo/bar.bin", httpResult: http.StatusCreated, addTime: []int{1, 2}},
  70. }
  71. resultsTests := []struct {
  72. user *user_model.User
  73. repo *models.Repository
  74. totalCount int
  75. oursCount int
  76. theirsCount int
  77. locksOwners []*user_model.User
  78. locksTimes []time.Time
  79. }{
  80. {user: user2, repo: repo1, totalCount: 4, oursCount: 4, theirsCount: 0, locksOwners: []*user_model.User{user2, user2, user2, user2}, locksTimes: []time.Time{}},
  81. {user: user2, repo: repo3, totalCount: 2, oursCount: 1, theirsCount: 1, locksOwners: []*user_model.User{user2, user4}, locksTimes: []time.Time{}},
  82. {user: user4, repo: repo3, totalCount: 2, oursCount: 1, theirsCount: 1, locksOwners: []*user_model.User{user2, user4}, locksTimes: []time.Time{}},
  83. }
  84. deleteTests := []struct {
  85. user *user_model.User
  86. repo *models.Repository
  87. lockID string
  88. }{}
  89. //create locks
  90. for _, test := range tests {
  91. session := loginUser(t, test.user.Name)
  92. req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s.git/info/lfs/locks", test.repo.FullName()), map[string]string{"path": test.path})
  93. req.Header.Set("Accept", lfs.MediaType)
  94. req.Header.Set("Content-Type", lfs.MediaType)
  95. resp := session.MakeRequest(t, req, test.httpResult)
  96. if len(test.addTime) > 0 {
  97. var lfsLock api.LFSLockResponse
  98. DecodeJSON(t, resp, &lfsLock)
  99. assert.EqualValues(t, lfsLock.Lock.LockedAt.Format(time.RFC3339), lfsLock.Lock.LockedAt.Format(time.RFC3339Nano)) //locked at should be rounded to second
  100. for _, id := range test.addTime {
  101. resultsTests[id].locksTimes = append(resultsTests[id].locksTimes, time.Now())
  102. }
  103. }
  104. }
  105. //check creation
  106. for _, test := range resultsTests {
  107. session := loginUser(t, test.user.Name)
  108. req := NewRequestf(t, "GET", "/%s.git/info/lfs/locks", test.repo.FullName())
  109. req.Header.Set("Accept", lfs.MediaType)
  110. resp := session.MakeRequest(t, req, http.StatusOK)
  111. var lfsLocks api.LFSLockList
  112. DecodeJSON(t, resp, &lfsLocks)
  113. assert.Len(t, lfsLocks.Locks, test.totalCount)
  114. for i, lock := range lfsLocks.Locks {
  115. assert.EqualValues(t, test.locksOwners[i].DisplayName(), lock.Owner.Name)
  116. assert.WithinDuration(t, test.locksTimes[i], lock.LockedAt, 10*time.Second)
  117. assert.EqualValues(t, lock.LockedAt.Format(time.RFC3339), lock.LockedAt.Format(time.RFC3339Nano)) //locked at should be rounded to second
  118. }
  119. req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s.git/info/lfs/locks/verify", test.repo.FullName()), map[string]string{})
  120. req.Header.Set("Accept", lfs.MediaType)
  121. req.Header.Set("Content-Type", lfs.MediaType)
  122. resp = session.MakeRequest(t, req, http.StatusOK)
  123. var lfsLocksVerify api.LFSLockListVerify
  124. DecodeJSON(t, resp, &lfsLocksVerify)
  125. assert.Len(t, lfsLocksVerify.Ours, test.oursCount)
  126. assert.Len(t, lfsLocksVerify.Theirs, test.theirsCount)
  127. for _, lock := range lfsLocksVerify.Ours {
  128. assert.EqualValues(t, test.user.DisplayName(), lock.Owner.Name)
  129. deleteTests = append(deleteTests, struct {
  130. user *user_model.User
  131. repo *models.Repository
  132. lockID string
  133. }{test.user, test.repo, lock.ID})
  134. }
  135. for _, lock := range lfsLocksVerify.Theirs {
  136. assert.NotEqual(t, test.user.DisplayName(), lock.Owner.Name)
  137. }
  138. }
  139. //remove all locks
  140. for _, test := range deleteTests {
  141. session := loginUser(t, test.user.Name)
  142. req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s.git/info/lfs/locks/%s/unlock", test.repo.FullName(), test.lockID), map[string]string{})
  143. req.Header.Set("Accept", lfs.MediaType)
  144. req.Header.Set("Content-Type", lfs.MediaType)
  145. resp := session.MakeRequest(t, req, http.StatusOK)
  146. var lfsLockRep api.LFSLockResponse
  147. DecodeJSON(t, resp, &lfsLockRep)
  148. assert.Equal(t, test.lockID, lfsLockRep.Lock.ID)
  149. assert.Equal(t, test.user.DisplayName(), lfsLockRep.Lock.Owner.Name)
  150. }
  151. // check that we don't have any lock
  152. for _, test := range resultsTests {
  153. session := loginUser(t, test.user.Name)
  154. req := NewRequestf(t, "GET", "/%s.git/info/lfs/locks", test.repo.FullName())
  155. req.Header.Set("Accept", lfs.MediaType)
  156. resp := session.MakeRequest(t, req, http.StatusOK)
  157. var lfsLocks api.LFSLockList
  158. DecodeJSON(t, resp, &lfsLocks)
  159. assert.Len(t, lfsLocks.Locks, 0)
  160. }
  161. }