diff --git a/bolt/organizations.go b/bolt/organizations.go index 81dfce09cd..2a98769f38 100644 --- a/bolt/organizations.go +++ b/bolt/organizations.go @@ -168,17 +168,6 @@ func (s *OrganizationsStore) Delete(ctx context.Context, o *chronograf.Organizat } } - layoutsStore := organizations.NewLayoutsStore(s.client.LayoutsStore, org) - layouts, err := layoutsStore.All(ctx) - if err != nil { - return err - } - for _, layout := range layouts { - if err := layoutsStore.Delete(ctx, layout); err != nil { - return err - } - } - dashboardsStore := organizations.NewDashboardsStore(s.client.DashboardsStore, org) dashboards, err := dashboardsStore.All(ctx) if err != nil { diff --git a/organizations/layouts.go b/organizations/layouts.go deleted file mode 100644 index 2f744c1e3c..0000000000 --- a/organizations/layouts.go +++ /dev/null @@ -1,123 +0,0 @@ -package organizations - -import ( - "context" - - "github.com/influxdata/chronograf" -) - -// ensure that LayoutsStore implements chronograf.LayoutStore -var _ chronograf.LayoutsStore = &LayoutsStore{} - -// LayoutsStore facade on a LayoutStore that filters layouts -// by organization. -type LayoutsStore struct { - store chronograf.LayoutsStore - organization string -} - -// NewLayoutsStore creates a new LayoutsStore from an existing -// chronograf.LayoutStore and an organization string -func NewLayoutsStore(s chronograf.LayoutsStore, org string) *LayoutsStore { - return &LayoutsStore{ - store: s, - organization: org, - } -} - -// All retrieves all layouts from the underlying LayoutStore and filters them -// by organization. -func (s *LayoutsStore) All(ctx context.Context) ([]chronograf.Layout, error) { - err := validOrganization(ctx) - if err != nil { - return nil, err - } - - ds, err := s.store.All(ctx) - if err != nil { - return nil, err - } - - // This filters layouts without allocating - // https://github.com/golang/go/wiki/SliceTricks#filtering-without-allocating - layouts := ds[:0] - for _, d := range ds { - if d.Organization == s.organization { - // If the layout belongs to the organization add it to the list - layouts = append(layouts, d) - } - - // Layouts stored in the canned layouts store do not - // have an organization associated with them and as a result - // would be filtered out without this. It may be worth while - // to add a `*` organization to check for instead, since this - // change has implications elsewhere or possibly a Global - // attribute on the layout. - if d.Organization == "" { - layouts = append(layouts, d) - } - } - - return layouts, nil -} - -// Add creates a new Layout in the LayoutsStore with layout.Organization set to be the -// organization from the layout store. -func (s *LayoutsStore) Add(ctx context.Context, d chronograf.Layout) (chronograf.Layout, error) { - err := validOrganization(ctx) - if err != nil { - return chronograf.Layout{}, err - } - - d.Organization = s.organization - return s.store.Add(ctx, d) -} - -// Delete the layout from LayoutsStore -func (s *LayoutsStore) Delete(ctx context.Context, d chronograf.Layout) error { - err := validOrganization(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 Layout if the id exists and belongs to the organization that is set. -func (s *LayoutsStore) Get(ctx context.Context, id string) (chronograf.Layout, error) { - err := validOrganization(ctx) - if err != nil { - return chronograf.Layout{}, err - } - - d, err := s.store.Get(ctx, id) - if err != nil { - return chronograf.Layout{}, err - } - - if d.Organization != s.organization { - return chronograf.Layout{}, chronograf.ErrLayoutNotFound - } - - return d, nil -} - -// Update the layout in LayoutsStore. -func (s *LayoutsStore) Update(ctx context.Context, d chronograf.Layout) error { - err := validOrganization(ctx) - if err != nil { - return err - } - - _, err = s.store.Get(ctx, d.ID) - if err != nil { - return err - } - - return s.store.Update(ctx, d) -} diff --git a/organizations/layouts_test.go b/organizations/layouts_test.go deleted file mode 100644 index 1d182405ac..0000000000 --- a/organizations/layouts_test.go +++ /dev/null @@ -1,376 +0,0 @@ -package organizations_test - -import ( - "context" - "fmt" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" - "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/mocks" - "github.com/influxdata/chronograf/organizations" -) - -// IgnoreFields is used because ID cannot be predicted reliably -// EquateEmpty is used because we want nil slices, arrays, and maps to be equal to the empty map -var layoutCmpOptions = cmp.Options{ - cmpopts.EquateEmpty(), - cmpopts.IgnoreFields(chronograf.Layout{}, "ID"), -} - -func TestLayouts_All(t *testing.T) { - type fields struct { - LayoutsStore chronograf.LayoutsStore - } - type args struct { - organization string - ctx context.Context - } - tests := []struct { - name string - args args - fields fields - want []chronograf.Layout - wantRaw []chronograf.Layout - wantErr bool - }{ - { - name: "No Layouts", - fields: fields{ - LayoutsStore: &mocks.LayoutsStore{ - AllF: func(ctx context.Context) ([]chronograf.Layout, error) { - return nil, fmt.Errorf("No Layouts") - }, - }, - }, - wantErr: true, - }, - { - name: "All Layouts", - fields: fields{ - LayoutsStore: &mocks.LayoutsStore{ - AllF: func(ctx context.Context) ([]chronograf.Layout, error) { - return []chronograf.Layout{ - { - Application: "howdy", - Organization: "1337", - }, - { - Application: "doody", - Organization: "1338", - }, - }, nil - }, - }, - }, - args: args{ - organization: "1337", - ctx: context.Background(), - }, - want: []chronograf.Layout{ - { - Application: "howdy", - Organization: "1337", - }, - }, - }, - { - name: "All Layouts with empty organization", - fields: fields{ - LayoutsStore: &mocks.LayoutsStore{ - AllF: func(ctx context.Context) ([]chronograf.Layout, error) { - return []chronograf.Layout{ - { - Application: "howdy", - Organization: "1337", - }, - { - Application: "doody", - Organization: "1338", - }, - { - Application: "noorg", - Organization: "", - }, - }, nil - }, - }, - }, - args: args{ - organization: "1337", - ctx: context.Background(), - }, - want: []chronograf.Layout{ - { - Application: "howdy", - Organization: "1337", - }, - { - Application: "noorg", - Organization: "", - }, - }, - }, - } - for _, tt := range tests { - s := organizations.NewLayoutsStore(tt.fields.LayoutsStore, tt.args.organization) - tt.args.ctx = context.WithValue(tt.args.ctx, organizations.ContextKey, tt.args.organization) - gots, err := s.All(tt.args.ctx) - if (err != nil) != tt.wantErr { - t.Errorf("%q. LayoutsStore.All() error = %v, wantErr %v", tt.name, err, tt.wantErr) - continue - } - for i, got := range gots { - if diff := cmp.Diff(got, tt.want[i], layoutCmpOptions...); diff != "" { - t.Errorf("%q. LayoutsStore.All():\n-got/+want\ndiff %s", tt.name, diff) - } - } - } -} - -func TestLayouts_Add(t *testing.T) { - type fields struct { - LayoutsStore chronograf.LayoutsStore - } - type args struct { - organization string - ctx context.Context - layout chronograf.Layout - } - tests := []struct { - name string - args args - fields fields - want chronograf.Layout - wantErr bool - }{ - { - name: "Add Layout", - fields: fields{ - LayoutsStore: &mocks.LayoutsStore{ - AddF: func(ctx context.Context, s chronograf.Layout) (chronograf.Layout, error) { - return s, nil - }, - GetF: func(ctx context.Context, id string) (chronograf.Layout, error) { - return chronograf.Layout{ - ID: "1229", - Application: "howdy", - Organization: "1337", - }, nil - }, - }, - }, - args: args{ - organization: "1337", - ctx: context.Background(), - layout: chronograf.Layout{ - ID: "1229", - Application: "howdy", - }, - }, - want: chronograf.Layout{ - Application: "howdy", - Organization: "1337", - }, - }, - } - for _, tt := range tests { - s := organizations.NewLayoutsStore(tt.fields.LayoutsStore, tt.args.organization) - tt.args.ctx = context.WithValue(tt.args.ctx, organizations.ContextKey, tt.args.organization) - d, err := s.Add(tt.args.ctx, tt.args.layout) - if (err != nil) != tt.wantErr { - t.Errorf("%q. LayoutsStore.Add() error = %v, wantErr %v", tt.name, err, tt.wantErr) - continue - } - got, err := s.Get(tt.args.ctx, d.ID) - if diff := cmp.Diff(got, tt.want, layoutCmpOptions...); diff != "" { - t.Errorf("%q. LayoutsStore.Add():\n-got/+want\ndiff %s", tt.name, diff) - } - } -} - -func TestLayouts_Delete(t *testing.T) { - type fields struct { - LayoutsStore chronograf.LayoutsStore - } - type args struct { - organization string - ctx context.Context - layout chronograf.Layout - } - tests := []struct { - name string - fields fields - args args - want []chronograf.Layout - addFirst bool - wantErr bool - }{ - { - name: "Delete layout", - fields: fields{ - LayoutsStore: &mocks.LayoutsStore{ - DeleteF: func(ctx context.Context, s chronograf.Layout) error { - return nil - }, - GetF: func(ctx context.Context, id string) (chronograf.Layout, error) { - return chronograf.Layout{ - ID: "1229", - Application: "howdy", - Organization: "1337", - }, nil - }, - }, - }, - args: args{ - organization: "1337", - ctx: context.Background(), - layout: chronograf.Layout{ - ID: "1229", - Application: "howdy", - Organization: "1337", - }, - }, - addFirst: true, - }, - } - for _, tt := range tests { - s := organizations.NewLayoutsStore(tt.fields.LayoutsStore, tt.args.organization) - tt.args.ctx = context.WithValue(tt.args.ctx, organizations.ContextKey, tt.args.organization) - err := s.Delete(tt.args.ctx, tt.args.layout) - if (err != nil) != tt.wantErr { - t.Errorf("%q. LayoutsStore.All() error = %v, wantErr %v", tt.name, err, tt.wantErr) - continue - } - } -} - -func TestLayouts_Get(t *testing.T) { - type fields struct { - LayoutsStore chronograf.LayoutsStore - } - type args struct { - organization string - ctx context.Context - layout chronograf.Layout - } - tests := []struct { - name string - fields fields - args args - want chronograf.Layout - addFirst bool - wantErr bool - }{ - { - name: "Get Layout", - fields: fields{ - LayoutsStore: &mocks.LayoutsStore{ - GetF: func(ctx context.Context, id string) (chronograf.Layout, error) { - return chronograf.Layout{ - ID: "1229", - Application: "howdy", - Organization: "1337", - }, nil - }, - }, - }, - args: args{ - organization: "1337", - ctx: context.Background(), - layout: chronograf.Layout{ - ID: "1229", - Application: "howdy", - Organization: "1337", - }, - }, - want: chronograf.Layout{ - ID: "1229", - Application: "howdy", - Organization: "1337", - }, - }, - } - for _, tt := range tests { - s := organizations.NewLayoutsStore(tt.fields.LayoutsStore, tt.args.organization) - tt.args.ctx = context.WithValue(tt.args.ctx, organizations.ContextKey, tt.args.organization) - got, err := s.Get(tt.args.ctx, tt.args.layout.ID) - if (err != nil) != tt.wantErr { - t.Errorf("%q. LayoutsStore.Get() error = %v, wantErr %v", tt.name, err, tt.wantErr) - continue - } - if diff := cmp.Diff(got, tt.want, layoutCmpOptions...); diff != "" { - t.Errorf("%q. LayoutsStore.Get():\n-got/+want\ndiff %s", tt.name, diff) - } - } -} - -func TestLayouts_Update(t *testing.T) { - type fields struct { - LayoutsStore chronograf.LayoutsStore - } - type args struct { - organization string - ctx context.Context - layout chronograf.Layout - name string - } - tests := []struct { - name string - fields fields - args args - want chronograf.Layout - addFirst bool - wantErr bool - }{ - { - name: "Update Layout Application", - fields: fields{ - LayoutsStore: &mocks.LayoutsStore{ - UpdateF: func(ctx context.Context, s chronograf.Layout) error { - return nil - }, - GetF: func(ctx context.Context, id string) (chronograf.Layout, error) { - return chronograf.Layout{ - ID: "1229", - Application: "doody", - Organization: "1337", - }, nil - }, - }, - }, - args: args{ - organization: "1337", - ctx: context.Background(), - layout: chronograf.Layout{ - ID: "1229", - Application: "howdy", - Organization: "1337", - }, - name: "doody", - }, - want: chronograf.Layout{ - Application: "doody", - Organization: "1337", - }, - addFirst: true, - }, - } - for _, tt := range tests { - if tt.args.name != "" { - tt.args.layout.Application = tt.args.name - } - s := organizations.NewLayoutsStore(tt.fields.LayoutsStore, tt.args.organization) - tt.args.ctx = context.WithValue(tt.args.ctx, organizations.ContextKey, tt.args.organization) - err := s.Update(tt.args.ctx, tt.args.layout) - if (err != nil) != tt.wantErr { - t.Errorf("%q. LayoutsStore.Update() error = %v, wantErr %v", tt.name, err, tt.wantErr) - continue - } - got, err := s.Get(tt.args.ctx, tt.args.layout.ID) - if diff := cmp.Diff(got, tt.want, layoutCmpOptions...); diff != "" { - t.Errorf("%q. LayoutsStore.Update():\n-got/+want\ndiff %s", tt.name, diff) - } - } -}