Skip to content

Commit

Permalink
feat(validate): Parameters to methods will Validate automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
dustmop committed Mar 15, 2021
1 parent 45f104c commit 7bb1515
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 6 deletions.
6 changes: 0 additions & 6 deletions lib/access.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ func (accessImpl) CreateAuthToken(scp scope, p *CreateAuthTokenParams) (string,
grantee *profile.Profile
err error
)
// TODO(b5): it'd be great if dispatch checked if input params implemented
// a "validator" interface & auto-called validate *before* dispatching.
// would save an HTTP call in RPC-style contexts.
if err = p.Validate(); err != nil {
return "", err
}

if p.GranteeProfileID != "" {
id, err := profile.IDB58Decode(p.GranteeProfileID)
Expand Down
17 changes: 17 additions & 0 deletions lib/access_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,20 @@ func TestAccessCreateAuthToken(t *testing.T) {
t.Fatal(err)
}
}

func TestAccessValidationFailure(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
inst, cleanup := NewMemTestInstance(ctx, t)
defer cleanup()

p := &CreateAuthTokenParams{}
_, err := inst.Access().CreateAuthToken(ctx, p)
if err == nil {
t.Fatal("expected err but did not get one")
}
expectErr := "either grantee username or profile is required"
if err.Error() != expectErr {
t.Errorf("error mismatch, expect: %s, got: %s", expectErr, err)
}
}
14 changes: 14 additions & 0 deletions lib/dispatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ func (inst *Instance) Dispatch(ctx context.Context, method string, param interfa
return nil, nil, fmt.Errorf("instance is nil, cannot dispatch")
}

// If the input parameters has a Validate method, call it
if validator, ok := param.(ParamValidator); ok {
err = validator.Validate()
if err != nil {
return nil, nil, err
}
}

// If the http rpc layer is engaged, use it to dispatch methods
// This happens when another process is running `qri connect`
if inst.http != nil {
Expand Down Expand Up @@ -150,6 +158,12 @@ func (inst *Instance) Dispatch(ctx context.Context, method string, param interfa
return nil, nil, fmt.Errorf("method %q not found", method)
}

// ParamValidator may be implemented by method parameter structs, and if so
// then Dispatch will validate the parameters are okay before calling anything
type ParamValidator interface {
Validate() error
}

// NewInputParam takes a method name that has been registered, and constructs
// an instance of that input parameter
func (inst *Instance) NewInputParam(method string) interface{} {
Expand Down
1 change: 1 addition & 0 deletions lib/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func (m *RenderMethods) RenderViz(ctx context.Context, p *RenderParams) ([]byte,
return bres.Bytes(), nil
}

// TODO(dustmop): Remove this once scope is used here, Dispatch will call Validate
if err := p.Validate(); err != nil {
return nil, err
}
Expand Down
19 changes: 19 additions & 0 deletions lib/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,22 @@ func TestRenderReadme(t *testing.T) {
t.Errorf("expected RenderReadme with both ref & dataset to error")
}
}

func TestRenderValidationFailure(t *testing.T) {
runner := newRenderTestRunner(t, "render_readme")
defer runner.Delete()

params := RenderParams{
Ref: "peer/my_dataset",
Dataset: &dataset.Dataset{},
Format: "html",
}
_, err := runner.RenderMethods.RenderReadme(runner.Context, &params)
if err == nil {
t.Fatal("expected err but did not get one")
}
expectErr := "cannot provide both a reference and a dataset to render"
if err.Error() != expectErr {
t.Errorf("error mismatch, expect: %s, got: %s", expectErr, err)
}
}
15 changes: 15 additions & 0 deletions lib/transform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,18 @@ def transform(ds,ctx):
t.Errorf("result mismatch. (-want +got):\n%s", diff)
}
}

func TestApplyTransformValidationFailure(t *testing.T) {
tr := newTestRunner(t)
defer tr.Delete()

params := ApplyParams{}
_, err := tr.Instance.Transform().Apply(tr.Ctx, &params)
if err == nil {
t.Fatal("expected err but did not get one")
}
expectErr := "one or both of Reference, Transform are required"
if err.Error() != expectErr {
t.Errorf("error mismatch, expect: %s, got: %s", expectErr, err)
}
}

0 comments on commit 7bb1515

Please sign in to comment.