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