Add roles implementation of sources store
Minimal test coverage of Update/Delete/Add methods was done since they do not involve any filtering. The filtering for them should have happened at the API level.pull/10616/head
parent
8ded387a81
commit
9ee3b431db
|
@ -0,0 +1,31 @@
|
|||
package roles
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type contextKey string
|
||||
|
||||
// ContextKey is the key used to specify the
|
||||
// role via context
|
||||
const ContextKey = contextKey("role")
|
||||
|
||||
func validRole(ctx context.Context) error {
|
||||
// prevents panic in case of nil context
|
||||
if ctx == nil {
|
||||
return fmt.Errorf("expect non nil context")
|
||||
}
|
||||
role, ok := ctx.Value(ContextKey).(string)
|
||||
// should never happen
|
||||
if !ok {
|
||||
return fmt.Errorf("expected role key to be a string")
|
||||
}
|
||||
switch role {
|
||||
// TODO(desa): make real roles
|
||||
case "member", "viewer", "editor", "admin":
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("expected role key to be set")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package roles
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/influxdata/chronograf"
|
||||
)
|
||||
|
||||
// ensure that SourcesStore implements chronograf.SourceStore
|
||||
var _ chronograf.SourcesStore = &SourcesStore{}
|
||||
|
||||
// SourcesStore facade on a SourceStore that filters sources
|
||||
// by role.
|
||||
type SourcesStore struct {
|
||||
store chronograf.SourcesStore
|
||||
role string
|
||||
}
|
||||
|
||||
// NewSourcesStore creates a new SourcesStore from an existing
|
||||
// chronograf.SourceStore and an role string
|
||||
func NewSourcesStore(s chronograf.SourcesStore, role string) *SourcesStore {
|
||||
return &SourcesStore{
|
||||
store: s,
|
||||
role: role,
|
||||
}
|
||||
}
|
||||
|
||||
// All retrieves all sources from the underlying SourceStore and filters them
|
||||
// by role.
|
||||
func (s *SourcesStore) All(ctx context.Context) ([]chronograf.Source, error) {
|
||||
err := validRole(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ds, err := s.store.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// This filters sources without allocating
|
||||
// https://github.com/golang/go/wiki/SliceTricks#filtering-without-allocating
|
||||
sources := ds[:0]
|
||||
for _, d := range ds {
|
||||
if hasAuthorizedRole(d.Role, s.role) {
|
||||
sources = append(sources, d)
|
||||
}
|
||||
}
|
||||
|
||||
return sources, nil
|
||||
}
|
||||
|
||||
// Add creates a new Source in the SourcesStore with source.Role set to be the
|
||||
// role from the source store.
|
||||
func (s *SourcesStore) Add(ctx context.Context, d chronograf.Source) (chronograf.Source, error) {
|
||||
err := validRole(ctx)
|
||||
if err != nil {
|
||||
return chronograf.Source{}, err
|
||||
}
|
||||
|
||||
return s.store.Add(ctx, d)
|
||||
}
|
||||
|
||||
// Delete the source from SourcesStore
|
||||
func (s *SourcesStore) Delete(ctx context.Context, d chronograf.Source) error {
|
||||
err := validRole(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d, err = s.store.Get(ctx, d.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.store.Delete(ctx, d)
|
||||
}
|
||||
|
||||
// Get returns a Source if the id exists and belongs to the role that is set.
|
||||
func (s *SourcesStore) Get(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
err := validRole(ctx)
|
||||
if err != nil {
|
||||
return chronograf.Source{}, err
|
||||
}
|
||||
|
||||
d, err := s.store.Get(ctx, id)
|
||||
if err != nil {
|
||||
return chronograf.Source{}, err
|
||||
}
|
||||
|
||||
if !hasAuthorizedRole(d.Role, s.role) {
|
||||
return chronograf.Source{}, chronograf.ErrSourceNotFound
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Update the source in SourcesStore.
|
||||
func (s *SourcesStore) Update(ctx context.Context, d chronograf.Source) error {
|
||||
err := validRole(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = s.store.Get(ctx, d.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.store.Update(ctx, d)
|
||||
}
|
||||
|
||||
func hasAuthorizedRole(sourceRole, providedRole string) bool {
|
||||
// TODO(desa): make real roles
|
||||
switch sourceRole {
|
||||
case "viewer":
|
||||
switch providedRole {
|
||||
case "viewer", "editor", "admin":
|
||||
return true
|
||||
}
|
||||
case "editor":
|
||||
switch providedRole {
|
||||
case "editor", "admin":
|
||||
return true
|
||||
}
|
||||
case "admin":
|
||||
switch providedRole {
|
||||
case "admin":
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,489 @@
|
|||
package roles
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/mocks"
|
||||
)
|
||||
|
||||
func TestSources_Get(t *testing.T) {
|
||||
type fields struct {
|
||||
SourcesStore chronograf.SourcesStore
|
||||
}
|
||||
type args struct {
|
||||
role string
|
||||
id int
|
||||
}
|
||||
type wants struct {
|
||||
source chronograf.Source
|
||||
err bool
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "Get viewer source as viewer",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "viewer",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get viewer source as editor",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "editor",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get viewer source as admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "admin",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor source as editor",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "editor",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor source as admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "admin",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor source as viewer - want error",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "viewer",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get admin source as admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "admin",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get admin source as viewer - want error",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "viewer",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get admin source as editor - want error",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "editor",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get source bad context",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "random role",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
store := NewSourcesStore(tt.fields.SourcesStore, tt.args.role)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if tt.args.role != "" {
|
||||
ctx = context.WithValue(ctx, ContextKey, tt.args.role)
|
||||
}
|
||||
|
||||
source, err := store.Get(ctx, tt.args.id)
|
||||
if (err != nil) != tt.wants.err {
|
||||
t.Errorf("%q. Store.Sources().Get() error = %v, wantErr %v", tt.name, err, tt.wants.err)
|
||||
return
|
||||
}
|
||||
if diff := cmp.Diff(source, tt.wants.source); diff != "" {
|
||||
t.Errorf("%q. Store.Sources().Get():\n-got/+want\ndiff %s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSources_All(t *testing.T) {
|
||||
type fields struct {
|
||||
SourcesStore chronograf.SourcesStore
|
||||
}
|
||||
type args struct {
|
||||
role string
|
||||
}
|
||||
type wants struct {
|
||||
sources []chronograf.Source
|
||||
err bool
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "Get viewer sources as viewer",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Source, error) {
|
||||
return []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "viewer",
|
||||
},
|
||||
wants: wants{
|
||||
sources: []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor sources as editor",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Source, error) {
|
||||
return []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "editor",
|
||||
},
|
||||
wants: wants{
|
||||
sources: []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get admin sources as admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Source, error) {
|
||||
return []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "admin",
|
||||
},
|
||||
wants: wants{
|
||||
sources: []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
store := NewSourcesStore(tt.fields.SourcesStore, tt.args.role)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if tt.args.role != "" {
|
||||
ctx = context.WithValue(ctx, ContextKey, tt.args.role)
|
||||
}
|
||||
|
||||
sources, err := store.All(ctx)
|
||||
if (err != nil) != tt.wants.err {
|
||||
t.Errorf("%q. Store.Sources().Get() error = %v, wantErr %v", tt.name, err, tt.wants.err)
|
||||
return
|
||||
}
|
||||
if diff := cmp.Diff(sources, tt.wants.sources); diff != "" {
|
||||
t.Errorf("%q. Store.Sources().Get():\n-got/+want\ndiff %s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/noop"
|
||||
"github.com/influxdata/chronograf/organizations"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
// hasOrganizationContext retrieves organization specified on context
|
||||
|
@ -26,6 +27,27 @@ func hasOrganizationContext(ctx context.Context) (string, bool) {
|
|||
return orgID, true
|
||||
}
|
||||
|
||||
// hasRoleContext retrieves organization specified on context
|
||||
// under the organizations.ContextKey
|
||||
func hasRoleContext(ctx context.Context) (string, bool) {
|
||||
// prevents panic in case of nil context
|
||||
if ctx == nil {
|
||||
return "", false
|
||||
}
|
||||
role, ok := ctx.Value(roles.ContextKey).(string)
|
||||
// should never happen
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
switch role {
|
||||
// TODO(desa): make real roles
|
||||
case "member", "viewer", "editor", "admin":
|
||||
return role, true
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
type superAdminKey string
|
||||
|
||||
// SuperAdminKey is the context key for retrieving is the context
|
||||
|
@ -75,7 +97,10 @@ type Store struct {
|
|||
// and a organization.SourcesStore otherwise.
|
||||
func (s *Store) Sources(ctx context.Context) chronograf.SourcesStore {
|
||||
if org, ok := hasOrganizationContext(ctx); ok {
|
||||
return organizations.NewSourcesStore(s.SourcesStore, org)
|
||||
store := organizations.NewSourcesStore(s.SourcesStore, org)
|
||||
if role, ok := hasRoleContext(ctx); ok {
|
||||
return roles.NewSourcesStore(store, role)
|
||||
}
|
||||
}
|
||||
|
||||
return &noop.SourcesStore{}
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/mocks"
|
||||
"github.com/influxdata/chronograf/organizations"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
func TestStore_SourcesGet(t *testing.T) {
|
||||
type fields struct {
|
||||
SourcesStore chronograf.SourcesStore
|
||||
}
|
||||
type args struct {
|
||||
superAdmin bool
|
||||
organization string
|
||||
role string
|
||||
id int
|
||||
}
|
||||
type wants struct {
|
||||
source chronograf.Source
|
||||
err bool
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "Get user as super admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
superAdmin: true,
|
||||
organization: "0",
|
||||
role: "viewer",
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get user as super admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
superAdmin: true,
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get user as super admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
superAdmin: true,
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
store := &Store{
|
||||
SourcesStore: tt.fields.SourcesStore,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if tt.args.superAdmin {
|
||||
ctx = context.WithValue(ctx, SuperAdminKey, true)
|
||||
}
|
||||
|
||||
if tt.args.organization != "" {
|
||||
ctx = context.WithValue(ctx, organizations.ContextKey, tt.args.organization)
|
||||
}
|
||||
|
||||
if tt.args.role != "" {
|
||||
ctx = context.WithValue(ctx, roles.ContextKey, tt.args.role)
|
||||
}
|
||||
|
||||
source, err := store.Sources(ctx).Get(ctx, tt.args.id)
|
||||
if (err != nil) != tt.wants.err {
|
||||
t.Errorf("%q. Store.Sources().Get() error = %v, wantErr %v", tt.name, err, tt.wants.err)
|
||||
return
|
||||
}
|
||||
if diff := cmp.Diff(source, tt.wants.source); diff != "" {
|
||||
t.Errorf("%q. Store.Sources().Get():\n-got/+want\ndiff %s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue