2016-05-18 21:44:34 +00:00
|
|
|
package api_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
2016-05-20 15:16:40 +00:00
|
|
|
"time"
|
2016-05-18 21:44:34 +00:00
|
|
|
|
|
|
|
"github.com/github/git-lfs/api"
|
2016-05-20 15:16:40 +00:00
|
|
|
"github.com/github/git-lfs/api/schema"
|
2016-05-18 21:44:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var LockService api.LockService
|
|
|
|
|
|
|
|
func TestSuccessfullyObtainingALock(t *testing.T) {
|
api/schema: remove MethodTestCase in favor of AssertSchema()
MethodTestCase had lots of problems, most caused by a good degree of ambiguity
in what we were actually testing.
AssertSchema(), on the other hand, simplifies this problem greatly by correctly
identifying the responsibilities of an *api.RequestSchema. An
*api.RequestSchema is responsible for one thing, and one thing only: to provide
a template for requests to be made against the API, completely regardless of
protocol or implementation.
Most notably, these responsibilities do not include:
- Preforming an HTTP request, or
- reading the response of an http request
So MethodTestCase gets simplified to a simple assert.Equal(). We expect to get
some *api.RequestSchema out, and we expect it to have certain parameters. Now,
all of the API's Service tests are rather simple: create a schema, compare,
rinse and repeat.
The only thing left to do is test the schema of the request and response
payload. This is what I had tried to do with the original MethodTestCase
implementation, but the way the system is desinged, trying to accomplish this
involves integrating with too many unrelated parts. To address this, I plan to
introduce a JSON Schema implementation that compares generated request/reponse
payloads with their ideal types.
2016-05-19 15:52:29 +00:00
|
|
|
got, body := LockService.Lock(new(api.LockRequest))
|
|
|
|
|
2016-05-20 15:51:59 +00:00
|
|
|
AssertRequestSchema(t, &api.RequestSchema{
|
2016-05-25 19:31:12 +00:00
|
|
|
Method: "POST",
|
|
|
|
Path: "/locks",
|
|
|
|
Operation: api.UploadOperation,
|
|
|
|
Body: new(api.LockRequest),
|
|
|
|
Into: body,
|
api/schema: remove MethodTestCase in favor of AssertSchema()
MethodTestCase had lots of problems, most caused by a good degree of ambiguity
in what we were actually testing.
AssertSchema(), on the other hand, simplifies this problem greatly by correctly
identifying the responsibilities of an *api.RequestSchema. An
*api.RequestSchema is responsible for one thing, and one thing only: to provide
a template for requests to be made against the API, completely regardless of
protocol or implementation.
Most notably, these responsibilities do not include:
- Preforming an HTTP request, or
- reading the response of an http request
So MethodTestCase gets simplified to a simple assert.Equal(). We expect to get
some *api.RequestSchema out, and we expect it to have certain parameters. Now,
all of the API's Service tests are rather simple: create a schema, compare,
rinse and repeat.
The only thing left to do is test the schema of the request and response
payload. This is what I had tried to do with the original MethodTestCase
implementation, but the way the system is desinged, trying to accomplish this
involves integrating with too many unrelated parts. To address this, I plan to
introduce a JSON Schema implementation that compares generated request/reponse
payloads with their ideal types.
2016-05-19 15:52:29 +00:00
|
|
|
}, got)
|
2016-05-18 21:44:34 +00:00
|
|
|
}
|
2016-05-20 15:16:40 +00:00
|
|
|
|
2016-05-20 15:49:44 +00:00
|
|
|
func TestLockSearchWithFilters(t *testing.T) {
|
|
|
|
got, body := LockService.Search(&api.LockSearchRequest{
|
|
|
|
Filters: []api.Filter{
|
|
|
|
{"branch", "master"},
|
|
|
|
{"path", "/path/to/file"},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2016-05-20 15:51:59 +00:00
|
|
|
AssertRequestSchema(t, &api.RequestSchema{
|
2016-05-24 15:34:51 +00:00
|
|
|
Method: "GET",
|
2016-05-20 15:49:44 +00:00
|
|
|
Query: map[string]string{
|
|
|
|
"branch": "master",
|
|
|
|
"path": "/path/to/file",
|
|
|
|
},
|
2016-05-25 19:31:12 +00:00
|
|
|
Path: "/locks",
|
|
|
|
Operation: api.UploadOperation,
|
|
|
|
Into: body,
|
2016-05-20 15:49:44 +00:00
|
|
|
}, got)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLockSearchWithNextCursor(t *testing.T) {
|
|
|
|
got, body := LockService.Search(&api.LockSearchRequest{
|
|
|
|
Cursor: "some-lock-id",
|
|
|
|
})
|
|
|
|
|
2016-05-20 15:51:59 +00:00
|
|
|
AssertRequestSchema(t, &api.RequestSchema{
|
2016-05-24 15:34:51 +00:00
|
|
|
Method: "GET",
|
2016-05-20 15:49:44 +00:00
|
|
|
Query: map[string]string{
|
|
|
|
"cursor": "some-lock-id",
|
|
|
|
},
|
2016-05-25 19:31:12 +00:00
|
|
|
Path: "/locks",
|
|
|
|
Operation: api.UploadOperation,
|
|
|
|
Into: body,
|
2016-05-20 15:49:44 +00:00
|
|
|
}, got)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLockSearchWithLimit(t *testing.T) {
|
|
|
|
got, body := LockService.Search(&api.LockSearchRequest{
|
|
|
|
Limit: 20,
|
|
|
|
})
|
|
|
|
|
2016-05-20 15:51:59 +00:00
|
|
|
AssertRequestSchema(t, &api.RequestSchema{
|
2016-05-24 15:34:51 +00:00
|
|
|
Method: "GET",
|
2016-05-20 15:49:44 +00:00
|
|
|
Query: map[string]string{
|
|
|
|
"limit": "20",
|
|
|
|
},
|
2016-05-25 19:31:12 +00:00
|
|
|
Path: "/locks",
|
|
|
|
Operation: api.UploadOperation,
|
|
|
|
Into: body,
|
2016-05-20 15:49:44 +00:00
|
|
|
}, got)
|
|
|
|
}
|
|
|
|
|
2016-05-27 21:42:04 +00:00
|
|
|
func TestUnlockingALock(t *testing.T) {
|
2016-05-27 21:45:02 +00:00
|
|
|
got, body := LockService.Unlock("some-lock-id", true)
|
2016-05-27 21:42:04 +00:00
|
|
|
|
|
|
|
AssertRequestSchema(t, &api.RequestSchema{
|
|
|
|
Method: "POST",
|
|
|
|
Path: "/locks/some-lock-id/unlock",
|
|
|
|
Operation: api.UploadOperation,
|
|
|
|
Body: &api.UnlockRequest{
|
|
|
|
Id: "some-lock-id",
|
|
|
|
Force: true,
|
|
|
|
},
|
|
|
|
Into: body,
|
|
|
|
}, got)
|
|
|
|
}
|
|
|
|
|
2016-05-20 15:16:40 +00:00
|
|
|
func TestLockRequest(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.LockRequestSchema, &api.LockRequest{
|
|
|
|
Path: "/path/to/lock",
|
|
|
|
LatestRemoteCommit: "deadbeef",
|
|
|
|
Committer: api.Committer{
|
|
|
|
Name: "Jane Doe",
|
|
|
|
Email: "jane@example.com",
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLockResponseWithLockedLock(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.LockResponseSchema, &api.LockResponse{
|
|
|
|
Lock: &api.Lock{
|
|
|
|
Id: "some-lock-id",
|
|
|
|
Path: "/lock/path",
|
|
|
|
Committer: api.Committer{
|
|
|
|
Name: "Jane Doe",
|
|
|
|
Email: "jane@example.com",
|
|
|
|
},
|
|
|
|
LockedAt: time.Now(),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLockResponseWithUnlockedLock(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.LockResponseSchema, &api.LockResponse{
|
|
|
|
Lock: &api.Lock{
|
|
|
|
Id: "some-lock-id",
|
|
|
|
Path: "/lock/path",
|
|
|
|
Committer: api.Committer{
|
|
|
|
Name: "Jane Doe",
|
|
|
|
Email: "jane@example.com",
|
|
|
|
},
|
|
|
|
LockedAt: time.Now(),
|
|
|
|
UnlockedAt: time.Now(),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLockResponseWithError(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.LockResponseSchema, &api.LockResponse{
|
|
|
|
Err: "some error",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLockResponseWithCommitNeeded(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.LockResponseSchema, &api.LockResponse{
|
|
|
|
CommitNeeded: "deadbeef",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLockResponseInvalidWithCommitAndError(t *testing.T) {
|
|
|
|
schema.Refute(t, schema.LockResponseSchema, &api.LockResponse{
|
|
|
|
Err: "some error",
|
|
|
|
CommitNeeded: "deadbeef",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-05-27 21:42:04 +00:00
|
|
|
func TestUnlockRequest(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.UnlockRequestSchema, &api.UnlockRequest{
|
|
|
|
Id: "some-lock-id",
|
|
|
|
Force: false,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-05-20 15:16:40 +00:00
|
|
|
func TestUnlockResponseWithLock(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.UnlockResponseSchema, &api.UnlockResponse{
|
|
|
|
Lock: &api.Lock{
|
|
|
|
Id: "some-lock-id",
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUnlockResponseWithError(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.UnlockResponseSchema, &api.UnlockResponse{
|
|
|
|
Err: "some-error",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUnlockResponseDoesNotAllowLockAndError(t *testing.T) {
|
|
|
|
schema.Refute(t, schema.UnlockResponseSchema, &api.UnlockResponse{
|
|
|
|
Lock: &api.Lock{
|
|
|
|
Id: "some-lock-id",
|
|
|
|
},
|
|
|
|
Err: "some-error",
|
|
|
|
})
|
|
|
|
}
|
2016-05-20 16:09:28 +00:00
|
|
|
|
|
|
|
func TestLockListWithLocks(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.LockListSchema, &api.LockList{
|
|
|
|
Locks: []api.Lock{
|
|
|
|
api.Lock{Id: "foo"},
|
|
|
|
api.Lock{Id: "bar"},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLockListWithNoResults(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.LockListSchema, &api.LockList{
|
|
|
|
Locks: []api.Lock{},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLockListWithNextCursor(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.LockListSchema, &api.LockList{
|
|
|
|
Locks: []api.Lock{
|
|
|
|
api.Lock{Id: "foo"},
|
|
|
|
api.Lock{Id: "bar"},
|
|
|
|
},
|
|
|
|
NextCursor: "baz",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLockListWithError(t *testing.T) {
|
|
|
|
schema.Validate(t, schema.LockListSchema, &api.LockList{
|
|
|
|
Err: "some error",
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLockListWithErrorAndLocks(t *testing.T) {
|
|
|
|
schema.Refute(t, schema.LockListSchema, &api.LockList{
|
|
|
|
Locks: []api.Lock{
|
|
|
|
api.Lock{Id: "foo"},
|
|
|
|
api.Lock{Id: "bar"},
|
|
|
|
},
|
|
|
|
Err: "this isn't possible!",
|
|
|
|
})
|
|
|
|
}
|