-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Implement routes * move to api/sdk and create model * Implement add + list * List return 200 empty list no 404 * Add verify lfs lock api * Add delete and start implementing auth control * Revert to code.gitea.io/sdk/gitea vendor * Apply needed check for all lfs locks route * Add simple tests * fix lint * Improve tests * Add delete test + fix * Add lfs ascii header * Various fixes from review + remove useless code + add more corner case testing * Remove repo link since only id is needed. Save a little of memory and cpu time. * Improve tests * Use TEXT column format for path + test * fix mispell * Use NewRequestWithJSON for POST tests * Clean path * Improve DB format * Revert uniquess repoid+path * (Re)-setup uniqueness + max path length * Fixed TEXT in place of VARCHAR * Settle back to maximum VARCHAR(3072) * Let place for repoid in key * Let place for repoid in key * Let place for repoid in key * Revert back
- Loading branch information
Showing
9 changed files
with
638 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
// 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 integrations | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"testing" | ||
"time" | ||
|
||
"code.gitea.io/gitea/models" | ||
"code.gitea.io/gitea/modules/setting" | ||
api "code.gitea.io/sdk/gitea" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestAPILFSLocksNotStarted(t *testing.T) { | ||
prepareTestEnv(t) | ||
setting.LFS.StartServer = false | ||
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) | ||
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) | ||
|
||
req := NewRequestf(t, "GET", "/%s/%s/info/lfs/locks", user.Name, repo.Name) | ||
MakeRequest(t, req, http.StatusNotFound) | ||
req = NewRequestf(t, "POST", "/%s/%s/info/lfs/locks", user.Name, repo.Name) | ||
MakeRequest(t, req, http.StatusNotFound) | ||
req = NewRequestf(t, "GET", "/%s/%s/info/lfs/locks/verify", user.Name, repo.Name) | ||
MakeRequest(t, req, http.StatusNotFound) | ||
req = NewRequestf(t, "GET", "/%s/%s/info/lfs/locks/10/unlock", user.Name, repo.Name) | ||
MakeRequest(t, req, http.StatusNotFound) | ||
} | ||
|
||
func TestAPILFSLocksNotLogin(t *testing.T) { | ||
prepareTestEnv(t) | ||
setting.LFS.StartServer = true | ||
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) | ||
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) | ||
|
||
req := NewRequestf(t, "GET", "/%s/%s/info/lfs/locks", user.Name, repo.Name) | ||
req.Header.Set("Accept", "application/vnd.git-lfs+json") | ||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json") | ||
resp := MakeRequest(t, req, http.StatusForbidden) | ||
var lfsLockError api.LFSLockError | ||
DecodeJSON(t, resp, &lfsLockError) | ||
assert.Equal(t, "You must have pull access to list locks : User undefined doesn't have rigth to list for lfs lock [rid: 1]", lfsLockError.Message) | ||
} | ||
|
||
func TestAPILFSLocksLogged(t *testing.T) { | ||
prepareTestEnv(t) | ||
setting.LFS.StartServer = true | ||
user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) //in org 3 | ||
user4 := models.AssertExistsAndLoadBean(t, &models.User{ID: 4}).(*models.User) //in org 3 | ||
|
||
repo1 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) | ||
repo3 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 3}).(*models.Repository) // own by org 3 | ||
|
||
tests := []struct { | ||
user *models.User | ||
repo *models.Repository | ||
path string | ||
httpResult int | ||
addTime []int | ||
}{ | ||
{user: user2, repo: repo1, path: "foo/bar.zip", httpResult: http.StatusCreated, addTime: []int{0}}, | ||
{user: user2, repo: repo1, path: "path/test", httpResult: http.StatusCreated, addTime: []int{0}}, | ||
{user: user2, repo: repo1, path: "path/test", httpResult: http.StatusConflict}, | ||
{user: user2, repo: repo1, path: "Foo/BaR.zip", httpResult: http.StatusConflict}, | ||
{user: user2, repo: repo1, path: "Foo/Test/../subFOlder/../Relative/../BaR.zip", httpResult: http.StatusConflict}, | ||
{user: user4, repo: repo1, path: "FoO/BaR.zip", httpResult: http.StatusForbidden}, | ||
{user: user4, repo: repo1, path: "path/test-user4", httpResult: http.StatusForbidden}, | ||
{user: user2, repo: repo1, path: "patH/Test-user4", httpResult: http.StatusCreated, addTime: []int{0}}, | ||
{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}}, | ||
|
||
{user: user2, repo: repo3, path: "test/foo/bar.zip", httpResult: http.StatusCreated, addTime: []int{1, 2}}, | ||
{user: user4, repo: repo3, path: "test/foo/bar.zip", httpResult: http.StatusConflict}, | ||
{user: user4, repo: repo3, path: "test/foo/bar.bin", httpResult: http.StatusCreated, addTime: []int{1, 2}}, | ||
} | ||
|
||
resultsTests := []struct { | ||
user *models.User | ||
repo *models.Repository | ||
totalCount int | ||
oursCount int | ||
theirsCount int | ||
locksOwners []*models.User | ||
locksTimes []time.Time | ||
}{ | ||
{user: user2, repo: repo1, totalCount: 4, oursCount: 4, theirsCount: 0, locksOwners: []*models.User{user2, user2, user2, user2}, locksTimes: []time.Time{}}, | ||
{user: user2, repo: repo3, totalCount: 2, oursCount: 1, theirsCount: 1, locksOwners: []*models.User{user2, user4}, locksTimes: []time.Time{}}, | ||
{user: user4, repo: repo3, totalCount: 2, oursCount: 1, theirsCount: 1, locksOwners: []*models.User{user2, user4}, locksTimes: []time.Time{}}, | ||
} | ||
|
||
deleteTests := []struct { | ||
user *models.User | ||
repo *models.Repository | ||
lockID string | ||
}{} | ||
|
||
//create locks | ||
for _, test := range tests { | ||
session := loginUser(t, test.user.Name) | ||
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s/info/lfs/locks", test.repo.FullName()), map[string]string{"path": test.path}) | ||
req.Header.Set("Accept", "application/vnd.git-lfs+json") | ||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json") | ||
session.MakeRequest(t, req, test.httpResult) | ||
if len(test.addTime) > 0 { | ||
for _, id := range test.addTime { | ||
resultsTests[id].locksTimes = append(resultsTests[id].locksTimes, time.Now()) | ||
} | ||
} | ||
} | ||
|
||
//check creation | ||
for _, test := range resultsTests { | ||
session := loginUser(t, test.user.Name) | ||
req := NewRequestf(t, "GET", "/%s/info/lfs/locks", test.repo.FullName()) | ||
req.Header.Set("Accept", "application/vnd.git-lfs+json") | ||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json") | ||
resp := session.MakeRequest(t, req, http.StatusOK) | ||
var lfsLocks api.LFSLockList | ||
DecodeJSON(t, resp, &lfsLocks) | ||
assert.Len(t, lfsLocks.Locks, test.totalCount) | ||
for i, lock := range lfsLocks.Locks { | ||
assert.EqualValues(t, test.locksOwners[i].DisplayName(), lock.Owner.Name) | ||
assert.WithinDuration(t, test.locksTimes[i], lock.LockedAt, 1*time.Second) | ||
} | ||
|
||
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s/info/lfs/locks/verify", test.repo.FullName()), map[string]string{}) | ||
req.Header.Set("Accept", "application/vnd.git-lfs+json") | ||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json") | ||
resp = session.MakeRequest(t, req, http.StatusOK) | ||
var lfsLocksVerify api.LFSLockListVerify | ||
DecodeJSON(t, resp, &lfsLocksVerify) | ||
assert.Len(t, lfsLocksVerify.Ours, test.oursCount) | ||
assert.Len(t, lfsLocksVerify.Theirs, test.theirsCount) | ||
for _, lock := range lfsLocksVerify.Ours { | ||
assert.EqualValues(t, test.user.DisplayName(), lock.Owner.Name) | ||
deleteTests = append(deleteTests, struct { | ||
user *models.User | ||
repo *models.Repository | ||
lockID string | ||
}{test.user, test.repo, lock.ID}) | ||
} | ||
for _, lock := range lfsLocksVerify.Theirs { | ||
assert.NotEqual(t, test.user.DisplayName(), lock.Owner.Name) | ||
} | ||
} | ||
|
||
//remove all locks | ||
for _, test := range deleteTests { | ||
session := loginUser(t, test.user.Name) | ||
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s/info/lfs/locks/%s/unlock", test.repo.FullName(), test.lockID), map[string]string{}) | ||
req.Header.Set("Accept", "application/vnd.git-lfs+json") | ||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json") | ||
resp := session.MakeRequest(t, req, http.StatusOK) | ||
var lfsLockRep api.LFSLockResponse | ||
DecodeJSON(t, resp, &lfsLockRep) | ||
assert.Equal(t, test.lockID, lfsLockRep.Lock.ID) | ||
assert.Equal(t, test.user.DisplayName(), lfsLockRep.Lock.Owner.Name) | ||
} | ||
|
||
// check that we don't have any lock | ||
for _, test := range resultsTests { | ||
session := loginUser(t, test.user.Name) | ||
req := NewRequestf(t, "GET", "/%s/info/lfs/locks", test.repo.FullName()) | ||
req.Header.Set("Accept", "application/vnd.git-lfs+json") | ||
req.Header.Set("Content-Type", "application/vnd.git-lfs+json") | ||
resp := session.MakeRequest(t, req, http.StatusOK) | ||
var lfsLocks api.LFSLockList | ||
DecodeJSON(t, resp, &lfsLocks) | ||
assert.Len(t, lfsLocks.Locks, 0) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.