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