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

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