Skip to content

Commit

Permalink
Only display dashboards with write permissions in add to dashboard me…
Browse files Browse the repository at this point in the history
…nu (Graylog2#4505)

* Add tests for issue

* Only display dashboards with write access in menu

* Update current user permissions with the initial state

* Make writableDashboards consistent with dashboards

This store is using ImmutableJS to store the dashboards state, and it
should do the same with the writableDashboards

* Fix eslint errors on test
  • Loading branch information
edmundoa authored and kmerz committed Jan 24, 2018
1 parent bf72a0f commit 9f11d8f
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const AddToDashboardMenu = React.createClass({
_renderDashboardMenu() {
let dashboards = Immutable.List();

this.state.dashboards
this.state.writableDashboards
.sortBy(dashboard => dashboard.title)
.forEach((dashboard) => {
dashboards = dashboards.push(
Expand Down Expand Up @@ -181,10 +181,10 @@ const AddToDashboardMenu = React.createClass({
},
render() {
let addToDashboardMenu;
if (this.state.dashboards === undefined) {
if (this.state.writableDashboards === undefined) {
addToDashboardMenu = this._renderLoadingDashboardsMenu();
} else {
addToDashboardMenu = (!this.props.hidden && (this.state.dashboards.size > 0 ? this._renderDashboardMenu() : this._renderNoDashboardsMenu()));
addToDashboardMenu = (!this.props.hidden && (this.state.writableDashboards.size > 0 ? this._renderDashboardMenu() : this._renderNoDashboardsMenu()));
}

const { appendMenus, children } = this.props;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import 'jquery-ui/ui/version';
import 'jquery-ui/ui/effect';
import 'jquery-ui/ui/plugin';
import 'jquery-ui/ui/widget';
import 'jquery-ui/ui/widgets/mouse';
import React from 'react';
import Immutable from 'immutable';
import { mount } from 'enzyme';
import PermissionsMixin from 'util/PermissionsMixin';
import AddToDashboardMenu from './AddToDashboardMenu';

describe('<AddToDashboardMenu />', () => {
const exampleProps = {
widgetType: 'SEARCH_RESULT_CHART',
title: 'Add to dashboard',
permissions: [],
};

const allDashboards = Immutable.List([
{ id: '1', title: 'One' },
{ id: '2', title: 'Two' },
{ id: '3', title: 'Three' },
]).sortBy(dashboard => dashboard.title);

const filterDashboards = (dashboards, permissions) => ({
// Emulate API behaviour by filtering out dashboards the user cannot read
dashboards: dashboards.filter(dashboard => PermissionsMixin.isPermitted(permissions, `dashboards:read:${dashboard.id}`)),
writableDashboards: dashboards.filter(dashboard => PermissionsMixin.isPermitted(permissions, `dashboards:edit:${dashboard.id}`)),
});

describe('admin users', () => {
let wrapper;
const permissions = ['*'];
beforeEach(() => {
wrapper = mount(<AddToDashboardMenu
widgetType={exampleProps.widgetType}
title={exampleProps.title}
permissions={permissions} />);
});

it('should see all dashboards', () => {
const { dashboards, writableDashboards } = filterDashboards(allDashboards, permissions);
wrapper.setState({ dashboards: dashboards, writableDashboards: writableDashboards });
wrapper.find('.dropdown-menu').find('MenuItem').forEach((node, idx) => {
expect(node.prop('children')).toEqual(writableDashboards.get(idx).title);
});
});

it('should see an option to create a new dashboard when there are none', () => {
const { dashboards, writableDashboards } = filterDashboards(Immutable.List(), permissions);
wrapper.setState({ dashboards: dashboards, writableDashboards: writableDashboards });
expect(wrapper.find('.dropdown-menu').find('MenuItem').prop('children')).toEqual('No dashboards, create one?');
});
});

describe('reader users', () => {
describe('without dashboards:create permissions', () => {
let wrapper;
const permissions = ['dashboards:read:1', 'dashboards:read:2', 'dashboards:edit:2', 'dashboards:read:3'];
beforeEach(() => {
wrapper = mount(<AddToDashboardMenu
widgetType={exampleProps.widgetType}
title={exampleProps.title}
permissions={permissions} />);
});

it('should only see the dashboards that can edit', () => {
const { dashboards, writableDashboards } = filterDashboards(allDashboards, permissions);
wrapper.setState({ dashboards: dashboards, writableDashboards: writableDashboards });
expect(wrapper.find('.dropdown-menu').find('MenuItem').length).toEqual(1);
expect(wrapper.find('.dropdown-menu').find('MenuItem').prop('children')).toEqual('Two');
});

it('should NOT see an option to create a new dashboard when there are none', () => {
const { dashboards, writableDashboards } = filterDashboards(Immutable.List(), permissions);
wrapper.setState({ dashboards: dashboards, writableDashboards: writableDashboards });
expect(wrapper.find('.dropdown-menu').find('MenuItem').prop('children')).not.toEqual('No dashboards, create one?');
expect(wrapper.find('.dropdown-menu').find('MenuItem').prop('children')).toEqual('No dashboards available');
});
});

describe('with dashboards:create permissions', () => {
let wrapper;
const permissions = ['dashboards:create', 'dashboards:read:1', 'dashboards:read:2', 'dashboards:edit:2', 'dashboards:read:3'];
beforeEach(() => {
wrapper = mount(<AddToDashboardMenu
widgetType={exampleProps.widgetType}
title={exampleProps.title}
permissions={permissions} />);
});

it('should only see the dashboards that can edit', () => {
const { dashboards, writableDashboards } = filterDashboards(allDashboards, permissions);
wrapper.setState({ dashboards: dashboards, writableDashboards: writableDashboards });
expect(wrapper.find('.dropdown-menu').find('MenuItem').length).toEqual(1);
expect(wrapper.find('.dropdown-menu').find('MenuItem').prop('children')).toEqual('Two');
});

it('should see an option to create a new dashboard when there are none', () => {
const { dashboards, writableDashboards } = filterDashboards(Immutable.List(), permissions);
wrapper.setState({ dashboards: dashboards, writableDashboards: writableDashboards });
expect(wrapper.find('.dropdown-menu').find('MenuItem').prop('children')).toEqual('No dashboards, create one?');
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default Reflux.createStore({
permissions: [],

init() {
this.listenTo(CurrentUserStore, this.currentUserUpdated);
this.listenTo(CurrentUserStore, this.currentUserUpdated, this.currentUserUpdated);
DashboardsActions.list();
},

Expand Down Expand Up @@ -115,7 +115,7 @@ export default Reflux.createStore({
},

getWritableDashboardList(dashboards, permissions) {
return dashboards.toArray().filter(dashboard => PermissionsMixin.isPermitted(permissions, `dashboards:edit:${dashboard.id}`));
return dashboards.filter(dashboard => PermissionsMixin.isPermitted(permissions, `dashboards:edit:${dashboard.id}`));
},

update(dashboard) {
Expand Down

0 comments on commit 9f11d8f

Please sign in to comment.