github.com/2lambda123/git-lfs@v2.5.2+incompatible/locking/api_test.go (about) 1 package locking 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "net/http/httptest" 8 "os" 9 "path/filepath" 10 "strings" 11 "testing" 12 13 "github.com/git-lfs/git-lfs/git" 14 "github.com/git-lfs/git-lfs/lfsapi" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 "github.com/xeipuuv/gojsonschema" 18 ) 19 20 func TestAPILock(t *testing.T) { 21 require.NotNil(t, createReqSchema) 22 require.NotNil(t, createResSchema) 23 24 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 25 if r.URL.Path != "/api/locks" { 26 w.WriteHeader(404) 27 return 28 } 29 30 assert.Equal(t, "POST", r.Method) 31 assert.Equal(t, lfsapi.MediaType, r.Header.Get("Accept")) 32 assert.Equal(t, lfsapi.MediaType, r.Header.Get("Content-Type")) 33 assert.Equal(t, "53", r.Header.Get("Content-Length")) 34 35 reqLoader, body := gojsonschema.NewReaderLoader(r.Body) 36 lockReq := &lockRequest{} 37 err := json.NewDecoder(body).Decode(lockReq) 38 r.Body.Close() 39 assert.Nil(t, err) 40 assert.Equal(t, "refs/heads/master", lockReq.Ref.Name) 41 assert.Equal(t, "request", lockReq.Path) 42 assertSchema(t, createReqSchema, reqLoader) 43 44 w.Header().Set("Content-Type", "application/json") 45 resLoader, resWriter := gojsonschema.NewWriterLoader(w) 46 err = json.NewEncoder(resWriter).Encode(&lockResponse{ 47 Lock: &Lock{ 48 Id: "1", 49 Path: "response", 50 }, 51 }) 52 assert.Nil(t, err) 53 assertSchema(t, createResSchema, resLoader) 54 })) 55 defer srv.Close() 56 57 c, err := lfsapi.NewClient(lfsapi.NewContext(nil, nil, map[string]string{ 58 "lfs.url": srv.URL + "/api", 59 })) 60 require.Nil(t, err) 61 62 lc := &lockClient{Client: c} 63 lockRes, res, err := lc.Lock("", &lockRequest{Path: "request", Ref: &lockRef{Name: "refs/heads/master"}}) 64 require.Nil(t, err) 65 assert.Equal(t, 200, res.StatusCode) 66 assert.Equal(t, "1", lockRes.Lock.Id) 67 assert.Equal(t, "response", lockRes.Lock.Path) 68 } 69 70 func TestAPIUnlock(t *testing.T) { 71 require.NotNil(t, delReqSchema) 72 require.NotNil(t, createResSchema) 73 74 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 75 if r.URL.Path != "/api/locks/123/unlock" { 76 w.WriteHeader(404) 77 return 78 } 79 80 assert.Equal(t, "POST", r.Method) 81 assert.Equal(t, lfsapi.MediaType, r.Header.Get("Accept")) 82 assert.Equal(t, lfsapi.MediaType, r.Header.Get("Content-Type")) 83 84 reqLoader, body := gojsonschema.NewReaderLoader(r.Body) 85 unlockReq := &unlockRequest{} 86 err := json.NewDecoder(body).Decode(unlockReq) 87 r.Body.Close() 88 assert.Nil(t, err) 89 assert.True(t, unlockReq.Force) 90 assertSchema(t, delReqSchema, reqLoader) 91 92 w.Header().Set("Content-Type", "application/json") 93 resLoader, resWriter := gojsonschema.NewWriterLoader(w) 94 err = json.NewEncoder(resWriter).Encode(&unlockResponse{ 95 Lock: &Lock{ 96 Id: "123", 97 Path: "response", 98 }, 99 }) 100 assert.Nil(t, err) 101 assertSchema(t, createResSchema, resLoader) 102 })) 103 defer srv.Close() 104 105 c, err := lfsapi.NewClient(lfsapi.NewContext(nil, nil, map[string]string{ 106 "lfs.url": srv.URL + "/api", 107 })) 108 require.Nil(t, err) 109 110 lc := &lockClient{Client: c} 111 unlockRes, res, err := lc.Unlock(&git.Ref{ 112 Name: "master", 113 Sha: "6161616161616161616161616161616161616161", 114 Type: git.RefTypeLocalBranch, 115 }, "", "123", true) 116 require.Nil(t, err) 117 assert.Equal(t, 200, res.StatusCode) 118 assert.Equal(t, "123", unlockRes.Lock.Id) 119 assert.Equal(t, "response", unlockRes.Lock.Path) 120 } 121 122 func TestAPISearch(t *testing.T) { 123 require.NotNil(t, listResSchema) 124 125 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 126 if r.URL.Path != "/api/locks" { 127 w.WriteHeader(404) 128 return 129 } 130 131 assert.Equal(t, "GET", r.Method) 132 assert.Equal(t, lfsapi.MediaType, r.Header.Get("Accept")) 133 assert.Equal(t, "", r.Header.Get("Content-Type")) 134 135 q := r.URL.Query() 136 assert.Equal(t, "A", q.Get("a")) 137 assert.Equal(t, "cursor", q.Get("cursor")) 138 assert.Equal(t, "5", q.Get("limit")) 139 140 w.Header().Set("Content-Type", "application/json") 141 resLoader, resWriter := gojsonschema.NewWriterLoader(w) 142 err := json.NewEncoder(resWriter).Encode(&lockList{ 143 Locks: []Lock{ 144 {Id: "1"}, 145 {Id: "2"}, 146 }, 147 }) 148 assert.Nil(t, err) 149 assertSchema(t, listResSchema, resLoader) 150 })) 151 defer srv.Close() 152 153 c, err := lfsapi.NewClient(lfsapi.NewContext(nil, nil, map[string]string{ 154 "lfs.url": srv.URL + "/api", 155 })) 156 require.Nil(t, err) 157 158 lc := &lockClient{Client: c} 159 locks, res, err := lc.Search("", &lockSearchRequest{ 160 Filters: []lockFilter{ 161 {Property: "a", Value: "A"}, 162 }, 163 Cursor: "cursor", 164 Limit: 5, 165 }) 166 require.Nil(t, err) 167 assert.Equal(t, 200, res.StatusCode) 168 assert.Equal(t, 2, len(locks.Locks)) 169 assert.Equal(t, "1", locks.Locks[0].Id) 170 assert.Equal(t, "2", locks.Locks[1].Id) 171 } 172 173 func TestAPIVerifiableLocks(t *testing.T) { 174 require.NotNil(t, verifyResSchema) 175 176 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 177 if r.URL.Path != "/api/locks/verify" { 178 w.WriteHeader(404) 179 return 180 } 181 182 assert.Equal(t, "POST", r.Method) 183 assert.Equal(t, lfsapi.MediaType, r.Header.Get("Accept")) 184 assert.Equal(t, lfsapi.MediaType, r.Header.Get("Content-Type")) 185 186 body := lockVerifiableRequest{} 187 if assert.Nil(t, json.NewDecoder(r.Body).Decode(&body)) { 188 assert.Equal(t, "cursor", body.Cursor) 189 assert.Equal(t, 5, body.Limit) 190 } 191 192 w.Header().Set("Content-Type", "application/json") 193 resLoader, resWriter := gojsonschema.NewWriterLoader(w) 194 err := json.NewEncoder(resWriter).Encode(&lockVerifiableList{ 195 Ours: []Lock{ 196 {Id: "1"}, 197 {Id: "2"}, 198 }, 199 Theirs: []Lock{ 200 {Id: "3"}, 201 }, 202 }) 203 assert.Nil(t, err) 204 assertSchema(t, verifyResSchema, resLoader) 205 })) 206 defer srv.Close() 207 208 c, err := lfsapi.NewClient(lfsapi.NewContext(nil, nil, map[string]string{ 209 "lfs.url": srv.URL + "/api", 210 })) 211 require.Nil(t, err) 212 213 lc := &lockClient{Client: c} 214 locks, res, err := lc.SearchVerifiable("", &lockVerifiableRequest{ 215 Cursor: "cursor", 216 Limit: 5, 217 }) 218 require.Nil(t, err) 219 assert.Equal(t, 200, res.StatusCode) 220 assert.Equal(t, 2, len(locks.Ours)) 221 assert.Equal(t, "1", locks.Ours[0].Id) 222 assert.Equal(t, "2", locks.Ours[1].Id) 223 assert.Equal(t, 1, len(locks.Theirs)) 224 assert.Equal(t, "3", locks.Theirs[0].Id) 225 } 226 227 var ( 228 createReqSchema *sourcedSchema 229 createResSchema *sourcedSchema 230 delReqSchema *sourcedSchema 231 listResSchema *sourcedSchema 232 verifyResSchema *sourcedSchema 233 ) 234 235 func init() { 236 wd, err := os.Getwd() 237 if err != nil { 238 fmt.Println("getwd error:", err) 239 return 240 } 241 242 createReqSchema = getSchema(wd, "schemas/http-lock-create-request-schema.json") 243 createResSchema = getSchema(wd, "schemas/http-lock-create-response-schema.json") 244 delReqSchema = getSchema(wd, "schemas/http-lock-delete-request-schema.json") 245 listResSchema = getSchema(wd, "schemas/http-lock-list-response-schema.json") 246 verifyResSchema = getSchema(wd, "schemas/http-lock-verify-response-schema.json") 247 } 248 249 type sourcedSchema struct { 250 Source string 251 *gojsonschema.Schema 252 } 253 254 func getSchema(wd, relpath string) *sourcedSchema { 255 abspath := filepath.ToSlash(filepath.Join(wd, relpath)) 256 s, err := gojsonschema.NewSchema(gojsonschema.NewReferenceLoader(fmt.Sprintf("file:///%s", abspath))) 257 if err != nil { 258 fmt.Printf("schema load error for %q: %+v\n", relpath, err) 259 } 260 return &sourcedSchema{Source: relpath, Schema: s} 261 } 262 263 func assertSchema(t *testing.T, schema *sourcedSchema, dataLoader gojsonschema.JSONLoader) { 264 res, err := schema.Validate(dataLoader) 265 if assert.Nil(t, err) { 266 if res.Valid() { 267 return 268 } 269 270 resErrors := res.Errors() 271 valErrors := make([]string, 0, len(resErrors)) 272 for _, resErr := range resErrors { 273 valErrors = append(valErrors, resErr.String()) 274 } 275 t.Errorf("Schema: %s\n%s", schema.Source, strings.Join(valErrors, "\n")) 276 } 277 }