Skip to content

Commit

Permalink
Adding unit tests for Group actions
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan Nixon authored and anasinnyk committed Jul 31, 2020
1 parent 58c8bd4 commit 11829d4
Show file tree
Hide file tree
Showing 3 changed files with 320 additions and 15 deletions.
270 changes: 270 additions & 0 deletions onepassword/group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
package onepassword

import (
"fmt"
"reflect"
"testing"
)

func TestOnePassClient_ReadGroup(t *testing.T) {
type fields struct {
runCmd func() (string, error)
}
type args struct {
id string
}
tests := []struct {
name string
fields fields
args args
wantExecResults []string
want *Group
wantErr bool
}{
{
name: "success",
fields: fields{
runCmd: func() (string, error) {
return `{ "uuid": "uniq", "name": "foo" }`, nil
},
},
args: args{id: "uniq"},
wantExecResults: []string{"op", "get", "group", "uniq", "--session="},
want: &Group{UUID: "uniq", Name: "foo"},
},
{
name: "bad json",
fields: fields{
runCmd: func() (string, error) {
return `This was supposed to be JSON`, nil
},
},
args: args{id: "uniq"},
wantExecResults: []string{"op", "get", "group", "uniq", "--session="},
wantErr: true,
},
{
name: "error",
fields: fields{
runCmd: func() (string, error) {
return ``, fmt.Errorf("oops")
},
},
args: args{id: "uniq"},
wantExecResults: []string{"op", "get", "group", "uniq", "--session="},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
config := &mockOnePassConfig{
runCmd: tt.fields.runCmd,
}
o := mockOnePassClient(config)

got, err := o.ReadGroup(tt.args.id)
if (err != nil) != tt.wantErr {
t.Errorf("OnePassClient.ReadGroup() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("OnePassClient.ReadGroup() = %v, want %v", got, tt.want)
}
if !reflect.DeepEqual(config.execCommandResults, tt.wantExecResults) {
t.Errorf("OnePassClient.ReadGroup() = %v, want %v", config.execCommandResults, tt.wantExecResults)
}
})
}
}

func TestOnePassClient_CreateGroup(t *testing.T) {
type fields struct {
runCmd func() (string, error)
}
type args struct {
v *Group
}
tests := []struct {
name string
fields fields
args args
wantExecResults []string
want *Group
wantErr bool
}{
{
name: "success",
fields: fields{
runCmd: func() (string, error) {
return `{ "uuid": "uniq", "name": "foo" }`, nil
},
},
args: args{v: &Group{Name: "foo"}},
wantExecResults: []string{"op", "create", "group", "foo", "--session="},
want: &Group{UUID: "uniq", Name: "foo"},
},
{
name: "bad json",
fields: fields{
runCmd: func() (string, error) {
return `This was supposed to be JSON`, nil
},
},
args: args{v: &Group{Name: "foo"}},
wantExecResults: []string{"op", "create", "group", "foo", "--session="},
wantErr: true,
},
{
name: "error",
fields: fields{
runCmd: func() (string, error) {
return ``, fmt.Errorf("oops")
},
},
args: args{v: &Group{Name: "foo"}},
wantExecResults: []string{"op", "create", "group", "foo", "--session="},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
config := &mockOnePassConfig{
runCmd: tt.fields.runCmd,
}
o := mockOnePassClient(config)

got, err := o.CreateGroup(tt.args.v)
if (err != nil) != tt.wantErr {
t.Errorf("OnePassClient.CreateGroup() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("OnePassClient.CreateGroup() = %v, want %v", got, tt.want)
}
if !reflect.DeepEqual(config.execCommandResults, tt.wantExecResults) {
t.Errorf("OnePassClient.CreateGroup() = %v, want %v", config.execCommandResults, tt.wantExecResults)
}
})
}
}

func TestOnePassClient_UpdateGroup(t *testing.T) {
type fields struct {
runCmd func() (string, error)
}
type args struct {
id string
v *Group
}
tests := []struct {
name string
fields fields
args args
wantExecResults []string
want *Group
wantErr bool
}{
{
name: "success",
fields: fields{
runCmd: func() (string, error) {
return `{ "uuid": "uniq", "name": "foo" }`, nil
},
},
args: args{
id: "uniq",
v: &Group{Name: "foo"},
},
wantExecResults: []string{"op", "edit", "group", "uniq", "--name=foo", "--session="},
want: &Group{UUID: "uniq", Name: "foo"},
},
{
name: "error",
fields: fields{
runCmd: func() (string, error) {
return ``, fmt.Errorf("oops")
},
},
args: args{
id: "uniq",
v: &Group{Name: "foo"},
},
wantExecResults: []string{"op", "edit", "group", "uniq", "--name=foo", "--session="},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
config := &mockOnePassConfig{
runCmd: tt.fields.runCmd,
}
o := mockOnePassClient(config)

err := o.UpdateGroup(tt.args.id, tt.args.v)
if (err != nil) != tt.wantErr {
t.Errorf("OnePassClient.UpdateGroup() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(config.execCommandResults, tt.wantExecResults) {
t.Errorf("OnePassClient.UpdateGroup() = %v, want %v", config.execCommandResults, tt.wantExecResults)
}
})
}
}

func TestOnePassClient_DeleteGroup(t *testing.T) {
type fields struct {
runCmd func() (string, error)
}
type args struct {
id string
}
tests := []struct {
name string
fields fields
args args
wantExecResults []string
want *Group
wantErr bool
}{
{
name: "success",
fields: fields{
runCmd: func() (string, error) {
return `{ "uuid": "uniq", "name": "foo" }`, nil
},
},
args: args{id: "uniq"},
wantExecResults: []string{"op", "delete", "group", "uniq", "--session="},
want: &Group{UUID: "uniq", Name: "foo"},
},
{
name: "error",
fields: fields{
runCmd: func() (string, error) {
return ``, fmt.Errorf("oops")
},
},
args: args{id: "uniq"},
wantExecResults: []string{"op", "delete", "group", "uniq", "--session="},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
config := &mockOnePassConfig{
runCmd: tt.fields.runCmd,
}
o := mockOnePassClient(config)

err := o.DeleteGroup(tt.args.id)
if (err != nil) != tt.wantErr {
t.Errorf("OnePassClient.DeleteGroup() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(config.execCommandResults, tt.wantExecResults) {
t.Errorf("OnePassClient.DeleteGroup() = %v, want %v", config.execCommandResults, tt.wantExecResults)
}
})
}
}
32 changes: 17 additions & 15 deletions onepassword/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,14 @@ const opPasswordDelete = "delete"
const opPasswordGet = "get"

type OnePassClient struct {
Password string
Email string
SecretKey string
Subdomain string
PathToOp string
Session string
mutex *sync.Mutex
Password string
Email string
SecretKey string
Subdomain string
PathToOp string
Session string
execCommand func(string, ...string) *exec.Cmd // Can be overridden for mocking purposes
mutex *sync.Mutex
}

type Meta struct {
Expand Down Expand Up @@ -255,13 +256,14 @@ func (m *Meta) NewOnePassClient() (*OnePassClient, error) {
}

op := &OnePassClient{
Email: email,
Password: password,
SecretKey: secretKey,
Subdomain: subdomain,
PathToOp: bin,
Session: session,
mutex: &sync.Mutex{},
Email: email,
Password: password,
SecretKey: secretKey,
Subdomain: subdomain,
PathToOp: bin,
Session: session,
execCommand: exec.Command,
mutex: &sync.Mutex{},
}

if session != "" {
Expand Down Expand Up @@ -298,7 +300,7 @@ func (o *OnePassClient) SignIn() error {
func (o *OnePassClient) runCmd(args ...string) ([]byte, error) {
args = append(args, fmt.Sprintf("--session=%s", strings.Trim(o.Session, "\n")))
o.mutex.Lock()
cmd := exec.Command(o.PathToOp, args...)
cmd := o.execCommand(o.PathToOp, args...)
defer o.mutex.Unlock()
res, err := cmd.CombinedOutput()
if err != nil {
Expand Down
33 changes: 33 additions & 0 deletions onepassword/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package onepassword

import (
"os/exec"
"strings"
"sync"
)

type mockOnePassConfig struct {
runCmd func() (string, error)
execCommandResults []string // Populated when execCommand is executed so you can assert against the args passed in
}

func mockOnePassClient(params *mockOnePassConfig) *OnePassClient {
ret := &OnePassClient{
PathToOp: "op",
mutex: &sync.Mutex{},
}

if params.runCmd != nil {
ret.execCommand = func(binary string, args ...string) *exec.Cmd {
params.execCommandResults = append([]string{binary}, args...)

out, err := params.runCmd()
if err != nil {
return exec.Command("sh", "-c", "echo "+strings.ReplaceAll(err.Error(), `"`, `\"`)+" && false")
}
return exec.Command("sh", "-c", "echo "+strings.ReplaceAll(out, `"`, `\"`))
}
}

return ret
}

0 comments on commit 11829d4

Please sign in to comment.