2017-11-28 15:58:37 -05:00
// Copyright 2017 The Gitea Authors. All rights reserved.
2022-11-27 13:20:29 -05:00
// SPDX-License-Identifier: MIT
2017-11-28 15:58:37 -05:00
2022-09-02 15:18:23 -04:00
package integration
2017-11-28 15:58:37 -05:00
import (
"fmt"
"net/http"
"testing"
"time"
2021-12-09 20:27:50 -05:00
repo_model "code.gitea.io/gitea/models/repo"
2021-11-16 03:53:21 -05:00
"code.gitea.io/gitea/models/unittest"
2021-11-24 04:49:20 -05:00
user_model "code.gitea.io/gitea/models/user"
2021-06-05 19:59:27 -04:00
"code.gitea.io/gitea/modules/lfs"
2017-11-28 15:58:37 -05:00
"code.gitea.io/gitea/modules/setting"
2019-05-11 06:21:34 -04:00
api "code.gitea.io/gitea/modules/structs"
2022-09-02 15:18:23 -04:00
"code.gitea.io/gitea/tests"
2017-11-28 15:58:37 -05:00
"github.com/stretchr/testify/assert"
)
func TestAPILFSLocksNotStarted ( t * testing . T ) {
2022-09-02 15:18:23 -04:00
defer tests . PrepareTestEnv ( t ) ( )
2017-11-28 15:58:37 -05:00
setting . LFS . StartServer = false
2022-08-15 22:22:25 -04:00
user := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 2 } )
repo := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : 1 } )
2017-11-28 15:58:37 -05:00
2017-11-28 18:35:23 -05:00
req := NewRequestf ( t , "GET" , "/%s/%s.git/info/lfs/locks" , user . Name , repo . Name )
2017-11-28 15:58:37 -05:00
MakeRequest ( t , req , http . StatusNotFound )
2017-11-28 18:35:23 -05:00
req = NewRequestf ( t , "POST" , "/%s/%s.git/info/lfs/locks" , user . Name , repo . Name )
2017-11-28 15:58:37 -05:00
MakeRequest ( t , req , http . StatusNotFound )
2017-11-28 18:35:23 -05:00
req = NewRequestf ( t , "GET" , "/%s/%s.git/info/lfs/locks/verify" , user . Name , repo . Name )
2017-11-28 15:58:37 -05:00
MakeRequest ( t , req , http . StatusNotFound )
2017-11-28 18:35:23 -05:00
req = NewRequestf ( t , "GET" , "/%s/%s.git/info/lfs/locks/10/unlock" , user . Name , repo . Name )
2017-11-28 15:58:37 -05:00
MakeRequest ( t , req , http . StatusNotFound )
}
func TestAPILFSLocksNotLogin ( t * testing . T ) {
2022-09-02 15:18:23 -04:00
defer tests . PrepareTestEnv ( t ) ( )
2017-11-28 15:58:37 -05:00
setting . LFS . StartServer = true
2022-08-15 22:22:25 -04:00
user := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 2 } )
repo := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : 1 } )
2017-11-28 15:58:37 -05:00
2017-11-28 18:35:23 -05:00
req := NewRequestf ( t , "GET" , "/%s/%s.git/info/lfs/locks" , user . Name , repo . Name )
2021-06-05 19:59:27 -04:00
req . Header . Set ( "Accept" , lfs . MediaType )
2018-01-27 11:48:15 -05:00
resp := MakeRequest ( t , req , http . StatusUnauthorized )
2017-11-28 15:58:37 -05:00
var lfsLockError api . LFSLockError
DecodeJSON ( t , resp , & lfsLockError )
2021-05-15 11:32:09 -04:00
assert . Equal ( t , "You must have pull access to list locks" , lfsLockError . Message )
2017-11-28 15:58:37 -05:00
}
func TestAPILFSLocksLogged ( t * testing . T ) {
2022-09-02 15:18:23 -04:00
defer tests . PrepareTestEnv ( t ) ( )
2017-11-28 15:58:37 -05:00
setting . LFS . StartServer = true
2022-08-15 22:22:25 -04:00
user2 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 2 } ) // in org 3
user4 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 4 } ) // in org 3
2017-11-28 15:58:37 -05:00
2022-08-15 22:22:25 -04:00
repo1 := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : 1 } )
repo3 := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : 3 } ) // own by org 3
2017-11-28 15:58:37 -05:00
tests := [ ] struct {
2021-11-24 04:49:20 -05:00
user * user_model . User
2021-12-09 20:27:50 -05:00
repo * repo_model . Repository
2017-11-28 15:58:37 -05:00
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 } ,
2018-01-27 11:48:15 -05:00
{ user : user4 , repo : repo1 , path : "FoO/BaR.zip" , httpResult : http . StatusUnauthorized } ,
{ user : user4 , repo : repo1 , path : "path/test-user4" , httpResult : http . StatusUnauthorized } ,
2017-11-28 15:58:37 -05:00
{ 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 {
2021-11-24 04:49:20 -05:00
user * user_model . User
2021-12-09 20:27:50 -05:00
repo * repo_model . Repository
2017-11-28 15:58:37 -05:00
totalCount int
oursCount int
theirsCount int
2021-11-24 04:49:20 -05:00
locksOwners [ ] * user_model . User
2017-11-28 15:58:37 -05:00
locksTimes [ ] time . Time
} {
2021-11-24 04:49:20 -05:00
{ user : user2 , repo : repo1 , totalCount : 4 , oursCount : 4 , theirsCount : 0 , locksOwners : [ ] * user_model . User { user2 , user2 , user2 , user2 } , locksTimes : [ ] time . Time { } } ,
{ user : user2 , repo : repo3 , totalCount : 2 , oursCount : 1 , theirsCount : 1 , locksOwners : [ ] * user_model . User { user2 , user4 } , locksTimes : [ ] time . Time { } } ,
{ user : user4 , repo : repo3 , totalCount : 2 , oursCount : 1 , theirsCount : 1 , locksOwners : [ ] * user_model . User { user2 , user4 } , locksTimes : [ ] time . Time { } } ,
2017-11-28 15:58:37 -05:00
}
deleteTests := [ ] struct {
2021-11-24 04:49:20 -05:00
user * user_model . User
2021-12-09 20:27:50 -05:00
repo * repo_model . Repository
2017-11-28 15:58:37 -05:00
lockID string
} { }
2022-01-20 12:46:10 -05:00
// create locks
2017-11-28 15:58:37 -05:00
for _ , test := range tests {
session := loginUser ( t , test . user . Name )
2017-11-28 18:35:23 -05:00
req := NewRequestWithJSON ( t , "POST" , fmt . Sprintf ( "/%s.git/info/lfs/locks" , test . repo . FullName ( ) ) , map [ string ] string { "path" : test . path } )
2024-06-11 18:22:28 -04:00
req . Header . Set ( "Accept" , lfs . AcceptHeader )
2021-06-05 19:59:27 -04:00
req . Header . Set ( "Content-Type" , lfs . MediaType )
2019-08-15 06:53:28 -04:00
resp := session . MakeRequest ( t , req , test . httpResult )
2017-11-28 15:58:37 -05:00
if len ( test . addTime ) > 0 {
2019-08-15 06:53:28 -04:00
var lfsLock api . LFSLockResponse
DecodeJSON ( t , resp , & lfsLock )
2022-10-11 21:03:15 -04:00
assert . Equal ( t , test . user . Name , lfsLock . Lock . Owner . Name )
2022-01-20 12:46:10 -05:00
assert . EqualValues ( t , lfsLock . Lock . LockedAt . Format ( time . RFC3339 ) , lfsLock . Lock . LockedAt . Format ( time . RFC3339Nano ) ) // locked at should be rounded to second
2017-11-28 15:58:37 -05:00
for _ , id := range test . addTime {
resultsTests [ id ] . locksTimes = append ( resultsTests [ id ] . locksTimes , time . Now ( ) )
}
}
}
2022-01-20 12:46:10 -05:00
// check creation
2017-11-28 15:58:37 -05:00
for _ , test := range resultsTests {
session := loginUser ( t , test . user . Name )
2017-11-28 18:35:23 -05:00
req := NewRequestf ( t , "GET" , "/%s.git/info/lfs/locks" , test . repo . FullName ( ) )
2024-06-11 18:22:28 -04:00
req . Header . Set ( "Accept" , lfs . AcceptHeader )
2017-11-28 15:58:37 -05:00
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 {
2022-10-11 21:03:15 -04:00
assert . EqualValues ( t , test . locksOwners [ i ] . Name , lock . Owner . Name )
2019-10-03 03:56:26 -04:00
assert . WithinDuration ( t , test . locksTimes [ i ] , lock . LockedAt , 10 * time . Second )
2022-01-20 12:46:10 -05:00
assert . EqualValues ( t , lock . LockedAt . Format ( time . RFC3339 ) , lock . LockedAt . Format ( time . RFC3339Nano ) ) // locked at should be rounded to second
2017-11-28 15:58:37 -05:00
}
2017-11-28 18:35:23 -05:00
req = NewRequestWithJSON ( t , "POST" , fmt . Sprintf ( "/%s.git/info/lfs/locks/verify" , test . repo . FullName ( ) ) , map [ string ] string { } )
2024-06-11 18:22:28 -04:00
req . Header . Set ( "Accept" , lfs . AcceptHeader )
2021-06-05 19:59:27 -04:00
req . Header . Set ( "Content-Type" , lfs . MediaType )
2017-11-28 15:58:37 -05:00
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 {
2022-10-11 21:03:15 -04:00
assert . EqualValues ( t , test . user . Name , lock . Owner . Name )
2017-11-28 15:58:37 -05:00
deleteTests = append ( deleteTests , struct {
2021-11-24 04:49:20 -05:00
user * user_model . User
2021-12-09 20:27:50 -05:00
repo * repo_model . Repository
2017-11-28 15:58:37 -05:00
lockID string
} { test . user , test . repo , lock . ID } )
}
for _ , lock := range lfsLocksVerify . Theirs {
assert . NotEqual ( t , test . user . DisplayName ( ) , lock . Owner . Name )
}
}
2022-01-20 12:46:10 -05:00
// remove all locks
2017-11-28 15:58:37 -05:00
for _ , test := range deleteTests {
session := loginUser ( t , test . user . Name )
2017-11-28 18:35:23 -05:00
req := NewRequestWithJSON ( t , "POST" , fmt . Sprintf ( "/%s.git/info/lfs/locks/%s/unlock" , test . repo . FullName ( ) , test . lockID ) , map [ string ] string { } )
2024-06-11 18:22:28 -04:00
req . Header . Set ( "Accept" , lfs . AcceptHeader )
2021-06-05 19:59:27 -04:00
req . Header . Set ( "Content-Type" , lfs . MediaType )
2017-11-28 15:58:37 -05:00
resp := session . MakeRequest ( t , req , http . StatusOK )
var lfsLockRep api . LFSLockResponse
DecodeJSON ( t , resp , & lfsLockRep )
assert . Equal ( t , test . lockID , lfsLockRep . Lock . ID )
2022-10-11 21:03:15 -04:00
assert . Equal ( t , test . user . Name , lfsLockRep . Lock . Owner . Name )
2017-11-28 15:58:37 -05:00
}
// check that we don't have any lock
for _ , test := range resultsTests {
session := loginUser ( t , test . user . Name )
2017-11-28 18:35:23 -05:00
req := NewRequestf ( t , "GET" , "/%s.git/info/lfs/locks" , test . repo . FullName ( ) )
2024-06-11 18:22:28 -04:00
req . Header . Set ( "Accept" , lfs . AcceptHeader )
2017-11-28 15:58:37 -05:00
resp := session . MakeRequest ( t , req , http . StatusOK )
var lfsLocks api . LFSLockList
DecodeJSON ( t , resp , & lfsLocks )
2024-07-30 15:41:10 -04:00
assert . Empty ( t , lfsLocks . Locks )
2017-11-28 15:58:37 -05:00
}
}