Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/src/batch_remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Examples:
ui.ResolvingNamespaceSuccess(namespace.ID)

ui.SendingBatchChange()
batchChangeName, err := svc.UpsertBatchChange(ctx, spec.Name, namespace.ID)
batchChangeID, batchChangeName, err := svc.UpsertBatchChange(ctx, spec.Name, namespace.ID)
if err != nil {
return err
}
Expand All @@ -93,6 +93,7 @@ Examples:
flags.allowIgnored,
flags.allowUnsupported,
flags.clearCache,
batchChangeID,
)
if err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ require (
github.com/spf13/cobra v1.4.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
github.com/stretchr/objx v0.4.0 // indirect
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonder where that is coming from 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from me using testify's mock package

github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
Expand Down
78 changes: 78 additions & 0 deletions internal/api/mock/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package mock

import (
"context"
"encoding/json"
"io"
"net/http"

"github.com/sourcegraph/src-cli/internal/api"
"github.com/stretchr/testify/mock"
)

type Client struct {
mock.Mock
}

func (m *Client) NewQuery(query string) api.Request {
args := m.Called(query)
return args.Get(0).(api.Request)
}

func (m *Client) NewRequest(query string, vars map[string]interface{}) api.Request {
args := m.Called(query, vars)
return args.Get(0).(api.Request)
}

func (m *Client) NewGzippedRequest(query string, vars map[string]interface{}) api.Request {
args := m.Called(query, vars)
return args.Get(0).(api.Request)
}

func (m *Client) NewGzippedQuery(query string) api.Request {
args := m.Called(query)
return args.Get(0).(api.Request)
}

func (m *Client) NewHTTPRequest(ctx context.Context, method, path string, body io.Reader) (*http.Request, error) {
args := m.Called(ctx, method, path, body)
var obj *http.Request
if args.Get(0) != nil {
obj = args.Get(0).(*http.Request)
}
return obj, args.Error(1)
}

func (m *Client) Do(req *http.Request) (*http.Response, error) {
args := m.Called(req)
var obj *http.Response
if args.Get(0) != nil {
obj = args.Get(0).(*http.Response)
}
return obj, args.Error(1)
}

type Request struct {
mock.Mock
Response string
}

func (r *Request) Do(ctx context.Context, result interface{}) (bool, error) {
args := r.Called(ctx, result)
if r.Response != "" {
if err := json.Unmarshal([]byte(r.Response), result); err != nil {
return false, err
}
}
return args.Bool(0), args.Error(1)
}

func (r *Request) DoRaw(ctx context.Context, result interface{}) (bool, error) {
args := r.Called(ctx, result)
if r.Response != "" {
if err := json.Unmarshal([]byte(r.Response), result); err != nil {
return false, err
}
}
return args.Bool(0), args.Error(1)
}
12 changes: 9 additions & 3 deletions internal/batches/service/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mutation UpsertEmptyBatchChange(
name: $name,
namespace: $namespace
) {
id
name
}
}
Expand All @@ -26,9 +27,10 @@ func (svc *Service) UpsertBatchChange(
ctx context.Context,
name string,
namespaceID string,
) (string, error) {
) (string, string, error) {
var resp struct {
UpsertEmptyBatchChange struct {
ID string `json:"id"`
Name string `json:"name"`
} `json:"upsertEmptyBatchChange"`
}
Expand All @@ -37,10 +39,10 @@ func (svc *Service) UpsertBatchChange(
"name": name,
"namespace": namespaceID,
}).Do(ctx, &resp); err != nil || !ok {
return "", err
return "", "", err
}

return resp.UpsertEmptyBatchChange.Name, nil
return resp.UpsertEmptyBatchChange.ID, resp.UpsertEmptyBatchChange.Name, nil
}

const createBatchSpecFromRawQuery = `
Expand All @@ -50,13 +52,15 @@ mutation CreateBatchSpecFromRaw(
$allowIgnored: Boolean!,
$allowUnsupported: Boolean!,
$noCache: Boolean!,
$batchChange: ID!,
) {
createBatchSpecFromRaw(
batchSpec: $batchSpec,
namespace: $namespace,
allowIgnored: $allowIgnored,
allowUnsupported: $allowUnsupported,
noCache: $noCache,
batchChange: $batchChange,
) {
id
}
Expand All @@ -70,6 +74,7 @@ func (svc *Service) CreateBatchSpecFromRaw(
allowIgnored bool,
allowUnsupported bool,
noCache bool,
batchChange string,
) (string, error) {
var resp struct {
CreateBatchSpecFromRaw struct {
Expand All @@ -83,6 +88,7 @@ func (svc *Service) CreateBatchSpecFromRaw(
"allowIgnored": allowIgnored,
"allowUnsupported": allowUnsupported,
"noCache": noCache,
"batchChange": batchChange,
}).Do(ctx, &resp); err != nil || !ok {
return "", err
}
Expand Down
193 changes: 193 additions & 0 deletions internal/batches/service/remote_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package service_test

import (
"context"
"encoding/json"
"testing"

mockclient "github.com/sourcegraph/src-cli/internal/api/mock"
"github.com/sourcegraph/src-cli/internal/batches/service"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"

"github.com/sourcegraph/sourcegraph/lib/errors"
)

func TestService_UpsertBatchChange(t *testing.T) {
client := new(mockclient.Client)
mockRequest := new(mockclient.Request)
svc := service.New(&service.Opts{Client: client})

tests := []struct {
name string

mockInvokes func()

requestName string
requestNamespaceID string

expectedID string
expectedName string
expectedErr error
}{
{
name: "New Batch Change",
mockInvokes: func() {
client.On("NewRequest", mock.Anything, map[string]interface{}{
"name": "my-change",
"namespace": "my-namespace",
}).
Return(mockRequest, nil).
Once()
mockRequest.On("Do", mock.Anything, mock.Anything).
Run(func(args mock.Arguments) {
json.Unmarshal([]byte(`{"upsertEmptyBatchChange":{"id":"123", "name":"my-change"}}`), &args[1])
}).
Return(true, nil).
Once()
},
requestName: "my-change",
requestNamespaceID: "my-namespace",
expectedID: "123",
expectedName: "my-change",
},
{
name: "Failed to upsert batch change",
mockInvokes: func() {
client.On("NewRequest", mock.Anything, map[string]interface{}{
"name": "my-change",
"namespace": "my-namespace",
}).
Return(mockRequest, nil).
Once()
mockRequest.On("Do", mock.Anything, mock.Anything).
Return(false, errors.New("did not get a good response code")).
Once()
},
requestName: "my-change",
requestNamespaceID: "my-namespace",
expectedErr: errors.New("did not get a good response code"),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if test.mockInvokes != nil {
test.mockInvokes()
}

id, name, err := svc.UpsertBatchChange(context.Background(), test.requestName, test.requestNamespaceID)
assert.Equal(t, test.expectedID, id)
assert.Equal(t, test.expectedName, name)
if test.expectedErr != nil {
assert.Error(t, err)
assert.Equal(t, test.expectedErr.Error(), err.Error())
} else {
assert.NoError(t, err)
}

client.AssertExpectations(t)
})
}
}

func TestService_CreateBatchSpecFromRaw(t *testing.T) {
client := new(mockclient.Client)
mockRequest := new(mockclient.Request)
svc := service.New(&service.Opts{Client: client})

tests := []struct {
name string

mockInvokes func()

requestBatchSpec string
requestNamespaceID string
requestAllowIgnored bool
requestAllowUnsupported bool
requestNoCache bool
requestBatchChange string

expectedID string
expectedErr error
}{
{
name: "Create batch spec",
mockInvokes: func() {
client.On("NewRequest", mock.Anything, map[string]interface{}{
"batchSpec": "abc",
"namespace": "some-namespace",
"allowIgnored": false,
"allowUnsupported": false,
"noCache": false,
"batchChange": "123",
}).
Return(mockRequest, nil).
Once()
mockRequest.On("Do", mock.Anything, mock.Anything).
Run(func(args mock.Arguments) {
json.Unmarshal([]byte(`{"createBatchSpecFromRaw":{"id":"xyz"}}`), &args[1])
}).
Return(true, nil).
Once()
},
requestBatchSpec: "abc",
requestNamespaceID: "some-namespace",
requestAllowIgnored: false,
requestAllowUnsupported: false,
requestNoCache: false,
requestBatchChange: "123",
expectedID: "xyz",
},
{
name: "Failed to create batch spec",
mockInvokes: func() {
client.On("NewRequest", mock.Anything, map[string]interface{}{
"batchSpec": "abc",
"namespace": "some-namespace",
"allowIgnored": false,
"allowUnsupported": false,
"noCache": false,
"batchChange": "123",
}).
Return(mockRequest, nil).
Once()
mockRequest.On("Do", mock.Anything, mock.Anything).
Return(false, errors.New("did not get a good response code")).
Once()
},
requestBatchSpec: "abc",
requestNamespaceID: "some-namespace",
requestAllowIgnored: false,
requestAllowUnsupported: false,
requestNoCache: false,
requestBatchChange: "123",
expectedErr: errors.New("did not get a good response code"),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if test.mockInvokes != nil {
test.mockInvokes()
}

id, err := svc.CreateBatchSpecFromRaw(
context.Background(),
test.requestBatchSpec,
test.requestNamespaceID,
test.requestAllowIgnored,
test.requestAllowUnsupported,
test.requestNoCache,
test.requestBatchChange,
)
assert.Equal(t, test.expectedID, id)
if test.expectedErr != nil {
assert.Error(t, err)
assert.Equal(t, test.expectedErr.Error(), err.Error())
} else {
assert.NoError(t, err)
}

client.AssertExpectations(t)
})
}
}