mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 17:05:18 +00:00
Query Manage Page: Role based views (#843)
* Removes create new query button from only observers * Renders CTA ManageQueriesPage side panel * Renders Observer can run column for non observers * Fixes integration tests: ManageQueriesPage and SidePanel UI co-authored by: @gillespi314 Integration tests co-authored by: @ghernandez345
This commit is contained in:
parent
0395020b6f
commit
a6e921c7b8
@ -15,11 +15,11 @@ class KolideAce extends Component {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
error: PropTypes.string,
|
error: PropTypes.string,
|
||||||
fontSize: PropTypes.number,
|
fontSize: PropTypes.number,
|
||||||
handleSubmit: PropTypes.func.isRequired,
|
handleSubmit: PropTypes.func,
|
||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func,
|
||||||
onLoad: PropTypes.func.isRequired,
|
onLoad: PropTypes.func,
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
readOnly: PropTypes.bool,
|
readOnly: PropTypes.bool,
|
||||||
showGutter: PropTypes.bool,
|
showGutter: PropTypes.bool,
|
||||||
|
@ -19,6 +19,7 @@ class QueriesList extends Component {
|
|||||||
onDblClickQuery: PropTypes.func,
|
onDblClickQuery: PropTypes.func,
|
||||||
queries: PropTypes.arrayOf(queryInterface).isRequired,
|
queries: PropTypes.arrayOf(queryInterface).isRequired,
|
||||||
selectedQuery: queryInterface,
|
selectedQuery: queryInterface,
|
||||||
|
isOnlyObserver: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@ -96,6 +97,7 @@ class QueriesList extends Component {
|
|||||||
onDblClickQuery,
|
onDblClickQuery,
|
||||||
queries,
|
queries,
|
||||||
selectedQuery,
|
selectedQuery,
|
||||||
|
isOnlyObserver,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { allQueriesChecked } = this.state;
|
const { allQueriesChecked } = this.state;
|
||||||
const { renderHelpText, handleCheckAll, handleCheckQuery } = this;
|
const { renderHelpText, handleCheckAll, handleCheckQuery } = this;
|
||||||
@ -103,7 +105,6 @@ class QueriesList extends Component {
|
|||||||
const wrapperClassName = classnames(`${baseClass}__table`, {
|
const wrapperClassName = classnames(`${baseClass}__table`, {
|
||||||
[`${baseClass}__table--query-selected`]: size(checkedQueryIDs),
|
[`${baseClass}__table--query-selected`]: size(checkedQueryIDs),
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={baseClass}>
|
<div className={baseClass}>
|
||||||
<table className={wrapperClassName}>
|
<table className={wrapperClassName}>
|
||||||
@ -118,6 +119,11 @@ class QueriesList extends Component {
|
|||||||
</th>
|
</th>
|
||||||
<th>Query name</th>
|
<th>Query name</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
|
{isOnlyObserver ? null : (
|
||||||
|
<th className={`${baseClass}__observers-can-run`}>
|
||||||
|
Observers can run
|
||||||
|
</th>
|
||||||
|
)}
|
||||||
<th className={`${baseClass}__author-name`}>Author</th>
|
<th className={`${baseClass}__author-name`}>Author</th>
|
||||||
<th>Last modified</th>
|
<th>Last modified</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -134,6 +140,7 @@ class QueriesList extends Component {
|
|||||||
onSelect={onSelectQuery}
|
onSelect={onSelectQuery}
|
||||||
onDoubleClick={onDblClickQuery}
|
onDoubleClick={onDblClickQuery}
|
||||||
query={query}
|
query={query}
|
||||||
|
isOnlyObserver={isOnlyObserver}
|
||||||
selected={
|
selected={
|
||||||
allQueriesChecked || selectedQuery.id === query.id
|
allQueriesChecked || selectedQuery.id === query.id
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ class QueriesListRow extends Component {
|
|||||||
onDoubleClick: PropTypes.func,
|
onDoubleClick: PropTypes.func,
|
||||||
query: queryInterface.isRequired,
|
query: queryInterface.isRequired,
|
||||||
selected: PropTypes.bool,
|
selected: PropTypes.bool,
|
||||||
|
isOnlyObserver: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps) {
|
shouldComponentUpdate(nextProps) {
|
||||||
@ -47,7 +48,7 @@ class QueriesListRow extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { checked, query, selected } = this.props;
|
const { checked, query, selected, isOnlyObserver } = this.props;
|
||||||
const { onCheck, onSelect, onDblClick } = this;
|
const { onCheck, onSelect, onDblClick } = this;
|
||||||
const {
|
const {
|
||||||
author_name: authorName,
|
author_name: authorName,
|
||||||
@ -55,6 +56,7 @@ class QueriesListRow extends Component {
|
|||||||
name,
|
name,
|
||||||
updated_at: updatedAt,
|
updated_at: updatedAt,
|
||||||
description,
|
description,
|
||||||
|
observer_can_run,
|
||||||
} = query;
|
} = query;
|
||||||
const lastModifiedDate = moment(updatedAt).format("MM/DD/YY");
|
const lastModifiedDate = moment(updatedAt).format("MM/DD/YY");
|
||||||
const rowClassName = classnames(baseClass, {
|
const rowClassName = classnames(baseClass, {
|
||||||
@ -76,6 +78,11 @@ class QueriesListRow extends Component {
|
|||||||
</td>
|
</td>
|
||||||
<td className={`${baseClass}__name`}>{name}</td>
|
<td className={`${baseClass}__name`}>{name}</td>
|
||||||
<td className={`${baseClass}__description`}>{description}</td>
|
<td className={`${baseClass}__description`}>{description}</td>
|
||||||
|
{isOnlyObserver ? null : (
|
||||||
|
<td className={`${baseClass}__observers-can-run`}>
|
||||||
|
{observer_can_run.toString()}
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
<td className={`${baseClass}__author-name`}>{authorName}</td>
|
<td className={`${baseClass}__author-name`}>{authorName}</td>
|
||||||
<td>{lastModifiedDate}</td>
|
<td>{lastModifiedDate}</td>
|
||||||
</ClickableTableRow>
|
</ClickableTableRow>
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
max-width: 280px;
|
max-width: 280px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__observers-can-run {
|
||||||
|
max-width: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,11 @@ import React, { Component } from "react";
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { Link } from "react-router";
|
import { Link } from "react-router";
|
||||||
|
|
||||||
|
import permissionUtils from "utilities/permissions";
|
||||||
import Button from "components/buttons/Button";
|
import Button from "components/buttons/Button";
|
||||||
import KolideAce from "components/KolideAce";
|
import KolideAce from "components/KolideAce";
|
||||||
import queryInterface from "interfaces/query";
|
import queryInterface from "interfaces/query";
|
||||||
|
import userInterface from "interfaces/user";
|
||||||
import SecondarySidePanelContainer from "components/side_panels/SecondarySidePanelContainer";
|
import SecondarySidePanelContainer from "components/side_panels/SecondarySidePanelContainer";
|
||||||
|
|
||||||
const baseClass = "query-details-side-panel";
|
const baseClass = "query-details-side-panel";
|
||||||
@ -13,6 +15,7 @@ class QueryDetailsSidePanel extends Component {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
onEditQuery: PropTypes.func.isRequired,
|
onEditQuery: PropTypes.func.isRequired,
|
||||||
query: queryInterface.isRequired,
|
query: queryInterface.isRequired,
|
||||||
|
currentUser: userInterface,
|
||||||
};
|
};
|
||||||
|
|
||||||
handleEditQueryClick = (evt) => {
|
handleEditQueryClick = (evt) => {
|
||||||
@ -57,9 +60,27 @@ class QueryDetailsSidePanel extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { query } = this.props;
|
const { query, currentUser } = this.props;
|
||||||
const { handleEditQueryClick, renderPacks } = this;
|
const { handleEditQueryClick, renderPacks } = this;
|
||||||
const { description, name, query: queryText } = query;
|
const { description, name, query: queryText, observer_can_run } = query;
|
||||||
|
|
||||||
|
const renderCTA = () => {
|
||||||
|
if (
|
||||||
|
permissionUtils.isGlobalAdmin(currentUser) ||
|
||||||
|
permissionUtils.isGlobalMaintainer(currentUser)
|
||||||
|
) {
|
||||||
|
return "Edit or run query";
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
permissionUtils.isAnyTeamMaintainer(currentUser) ||
|
||||||
|
(permissionUtils.isOnlyObserver(currentUser) && observer_can_run)
|
||||||
|
) {
|
||||||
|
return "Run query";
|
||||||
|
}
|
||||||
|
if (permissionUtils.isOnlyObserver(currentUser) && !observer_can_run) {
|
||||||
|
return "Show query";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SecondarySidePanelContainer className={baseClass}>
|
<SecondarySidePanelContainer className={baseClass}>
|
||||||
@ -81,8 +102,8 @@ class QueryDetailsSidePanel extends Component {
|
|||||||
</p>
|
</p>
|
||||||
<p className={`${baseClass}__label`}>Packs</p>
|
<p className={`${baseClass}__label`}>Packs</p>
|
||||||
{renderPacks()}
|
{renderPacks()}
|
||||||
<Button onClick={handleEditQueryClick} variant="inverse">
|
<Button onClick={handleEditQueryClick} variant="brand">
|
||||||
Edit or run query
|
{renderCTA(currentUser)}
|
||||||
</Button>
|
</Button>
|
||||||
</SecondarySidePanelContainer>
|
</SecondarySidePanelContainer>
|
||||||
);
|
);
|
||||||
|
@ -3,12 +3,16 @@ import { mount } from "enzyme";
|
|||||||
import { noop } from "lodash";
|
import { noop } from "lodash";
|
||||||
|
|
||||||
import QueryDetailsSidePanel from "components/side_panels/QueryDetailsSidePanel";
|
import QueryDetailsSidePanel from "components/side_panels/QueryDetailsSidePanel";
|
||||||
import { queryStub } from "test/stubs";
|
import { queryStub, userStub } from "test/stubs";
|
||||||
|
|
||||||
describe("QueryDetailsSidePanel - component", () => {
|
describe("QueryDetailsSidePanel - component", () => {
|
||||||
it("renders", () => {
|
it("renders", () => {
|
||||||
const component = mount(
|
const component = mount(
|
||||||
<QueryDetailsSidePanel onEditQuery={noop} query={queryStub} />
|
<QueryDetailsSidePanel
|
||||||
|
onEditQuery={noop}
|
||||||
|
query={queryStub}
|
||||||
|
currentUser={userStub}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(component.length).toEqual(1);
|
expect(component.length).toEqual(1);
|
||||||
@ -16,7 +20,11 @@ describe("QueryDetailsSidePanel - component", () => {
|
|||||||
|
|
||||||
it("renders a read-only Kolide Ace component with the query text", () => {
|
it("renders a read-only Kolide Ace component with the query text", () => {
|
||||||
const component = mount(
|
const component = mount(
|
||||||
<QueryDetailsSidePanel onEditQuery={noop} query={queryStub} />
|
<QueryDetailsSidePanel
|
||||||
|
onEditQuery={noop}
|
||||||
|
query={queryStub}
|
||||||
|
currentUser={userStub}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
const aceEditor = component.find("KolideAce");
|
const aceEditor = component.find("KolideAce");
|
||||||
|
|
||||||
@ -28,7 +36,11 @@ describe("QueryDetailsSidePanel - component", () => {
|
|||||||
it("calls the onEditQuery prop when Edit/Run Query is clicked", () => {
|
it("calls the onEditQuery prop when Edit/Run Query is clicked", () => {
|
||||||
const spy = jest.fn();
|
const spy = jest.fn();
|
||||||
const component = mount(
|
const component = mount(
|
||||||
<QueryDetailsSidePanel onEditQuery={spy} query={queryStub} />
|
<QueryDetailsSidePanel
|
||||||
|
onEditQuery={spy}
|
||||||
|
query={queryStub}
|
||||||
|
currentUser={userStub}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
const button = component.find("Button");
|
const button = component.find("Button");
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ export default PropTypes.shape({
|
|||||||
id: PropTypes.number,
|
id: PropTypes.number,
|
||||||
interval: PropTypes.number,
|
interval: PropTypes.number,
|
||||||
last_excuted: PropTypes.string,
|
last_excuted: PropTypes.string,
|
||||||
|
observer_can_run: PropTypes.bool,
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface IQuery {
|
export interface IQuery {
|
||||||
@ -16,4 +17,5 @@ export interface IQuery {
|
|||||||
id: number;
|
id: number;
|
||||||
interval: number;
|
interval: number;
|
||||||
last_excuted: string;
|
last_excuted: string;
|
||||||
|
observer_can_run: boolean;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import { filter, get, includes, pull } from "lodash";
|
|||||||
import { push } from "react-router-redux";
|
import { push } from "react-router-redux";
|
||||||
|
|
||||||
import Button from "components/buttons/Button";
|
import Button from "components/buttons/Button";
|
||||||
|
import permissionUtils from "utilities/permissions";
|
||||||
import entityGetter from "redux/utilities/entityGetter";
|
import entityGetter from "redux/utilities/entityGetter";
|
||||||
import InputField from "components/forms/fields/InputField";
|
import InputField from "components/forms/fields/InputField";
|
||||||
import Modal from "components/modals/Modal";
|
import Modal from "components/modals/Modal";
|
||||||
@ -15,6 +16,7 @@ import QueryDetailsSidePanel from "components/side_panels/QueryDetailsSidePanel"
|
|||||||
import QueriesList from "components/queries/QueriesList";
|
import QueriesList from "components/queries/QueriesList";
|
||||||
import queryActions from "redux/nodes/entities/queries/actions";
|
import queryActions from "redux/nodes/entities/queries/actions";
|
||||||
import queryInterface from "interfaces/query";
|
import queryInterface from "interfaces/query";
|
||||||
|
import userInterface from "interfaces/user";
|
||||||
import { renderFlash } from "redux/nodes/notifications/actions";
|
import { renderFlash } from "redux/nodes/notifications/actions";
|
||||||
|
|
||||||
const baseClass = "manage-queries-page";
|
const baseClass = "manage-queries-page";
|
||||||
@ -25,6 +27,7 @@ export class ManageQueriesPage extends Component {
|
|||||||
loadingQueries: PropTypes.bool.isRequired,
|
loadingQueries: PropTypes.bool.isRequired,
|
||||||
queries: PropTypes.arrayOf(queryInterface),
|
queries: PropTypes.arrayOf(queryInterface),
|
||||||
selectedQuery: queryInterface,
|
selectedQuery: queryInterface,
|
||||||
|
currentUser: userInterface,
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@ -183,6 +186,8 @@ export class ManageQueriesPage extends Component {
|
|||||||
|
|
||||||
renderCTAs = () => {
|
renderCTAs = () => {
|
||||||
const { goToNewQueryPage, onToggleModal } = this;
|
const { goToNewQueryPage, onToggleModal } = this;
|
||||||
|
const { currentUser } = this.props;
|
||||||
|
|
||||||
const btnClass = `${baseClass}__delete-queries-btn`;
|
const btnClass = `${baseClass}__delete-queries-btn`;
|
||||||
const checkedQueryCount = this.state.checkedQueryIDs.length;
|
const checkedQueryCount = this.state.checkedQueryIDs.length;
|
||||||
|
|
||||||
@ -201,11 +206,14 @@ export class ManageQueriesPage extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
// Render option to create new query only for maintainers and admin
|
||||||
<Button variant="brand" onClick={goToNewQueryPage}>
|
if (!permissionUtils.isOnlyObserver(currentUser)) {
|
||||||
Create new query
|
return (
|
||||||
</Button>
|
<Button variant="brand" onClick={goToNewQueryPage}>
|
||||||
);
|
Create new query
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
renderModal = () => {
|
renderModal = () => {
|
||||||
@ -233,7 +241,7 @@ export class ManageQueriesPage extends Component {
|
|||||||
|
|
||||||
renderSidePanel = () => {
|
renderSidePanel = () => {
|
||||||
const { goToEditQueryPage } = this;
|
const { goToEditQueryPage } = this;
|
||||||
const { selectedQuery } = this.props;
|
const { selectedQuery, currentUser } = this.props;
|
||||||
|
|
||||||
if (!selectedQuery) {
|
if (!selectedQuery) {
|
||||||
// FIXME: Render QueryDetailsSidePanel when Fritz has completed the mock
|
// FIXME: Render QueryDetailsSidePanel when Fritz has completed the mock
|
||||||
@ -251,6 +259,7 @@ export class ManageQueriesPage extends Component {
|
|||||||
<QueryDetailsSidePanel
|
<QueryDetailsSidePanel
|
||||||
onEditQuery={goToEditQueryPage}
|
onEditQuery={goToEditQueryPage}
|
||||||
query={selectedQuery}
|
query={selectedQuery}
|
||||||
|
currentUser={currentUser}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -268,12 +277,18 @@ export class ManageQueriesPage extends Component {
|
|||||||
renderModal,
|
renderModal,
|
||||||
renderSidePanel,
|
renderSidePanel,
|
||||||
} = this;
|
} = this;
|
||||||
const { loadingQueries, queries: allQueries, selectedQuery } = this.props;
|
const {
|
||||||
|
loadingQueries,
|
||||||
|
queries: allQueries,
|
||||||
|
selectedQuery,
|
||||||
|
currentUser,
|
||||||
|
} = this.props;
|
||||||
const queries = getQueries();
|
const queries = getQueries();
|
||||||
const queriesCount = queries.length;
|
const queriesCount = queries.length;
|
||||||
const queriesTotalDisplay =
|
const queriesTotalDisplay =
|
||||||
queriesCount === 1 ? "1 query" : `${queriesCount} queries`;
|
queriesCount === 1 ? "1 query" : `${queriesCount} queries`;
|
||||||
const isQueriesAvailable = allQueries.length > 0;
|
const isQueriesAvailable = allQueries.length > 0;
|
||||||
|
const isOnlyObserver = permissionUtils.isOnlyObserver(currentUser);
|
||||||
|
|
||||||
if (loadingQueries) {
|
if (loadingQueries) {
|
||||||
return false;
|
return false;
|
||||||
@ -307,6 +322,7 @@ export class ManageQueriesPage extends Component {
|
|||||||
onDblClickQuery={onDblClickQuery}
|
onDblClickQuery={onDblClickQuery}
|
||||||
queries={queries}
|
queries={queries}
|
||||||
selectedQuery={selectedQuery}
|
selectedQuery={selectedQuery}
|
||||||
|
isOnlyObserver={isOnlyObserver}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{renderSidePanel()}
|
{renderSidePanel()}
|
||||||
@ -323,8 +339,9 @@ const mapStateToProps = (state, { location }) => {
|
|||||||
const selectedQuery =
|
const selectedQuery =
|
||||||
selectedQueryID && queryEntities.findBy({ id: selectedQueryID });
|
selectedQueryID && queryEntities.findBy({ id: selectedQueryID });
|
||||||
const { loading: loadingQueries } = state.entities.queries;
|
const { loading: loadingQueries } = state.entities.queries;
|
||||||
|
const currentUser = state.auth.user;
|
||||||
|
|
||||||
return { loadingQueries, queries, selectedQuery };
|
return { loadingQueries, queries, selectedQuery, currentUser };
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps)(ManageQueriesPage);
|
export default connect(mapStateToProps)(ManageQueriesPage);
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
reduxMockStore,
|
reduxMockStore,
|
||||||
} from "test/helpers";
|
} from "test/helpers";
|
||||||
import queryActions from "redux/nodes/entities/queries/actions";
|
import queryActions from "redux/nodes/entities/queries/actions";
|
||||||
import { queryStub } from "test/stubs";
|
import { queryStub, userStub } from "test/stubs";
|
||||||
|
|
||||||
const store = {
|
const store = {
|
||||||
entities: {
|
entities: {
|
||||||
@ -27,6 +27,9 @@ const store = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
auth: {
|
||||||
|
user: userStub,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
describe("ManageQueriesPage - component", () => {
|
describe("ManageQueriesPage - component", () => {
|
||||||
@ -40,6 +43,7 @@ describe("ManageQueriesPage - component", () => {
|
|||||||
it("does not render if queries are loading", () => {
|
it("does not render if queries are loading", () => {
|
||||||
const loadingQueriesStore = {
|
const loadingQueriesStore = {
|
||||||
entities: { queries: { loading: true, data: {} } },
|
entities: { queries: { loading: true, data: {} } },
|
||||||
|
auth: { user: userStub },
|
||||||
};
|
};
|
||||||
const Component = connectedComponent(ConnectedManageQueriesPage, {
|
const Component = connectedComponent(ConnectedManageQueriesPage, {
|
||||||
mockStore: reduxMockStore(loadingQueriesStore),
|
mockStore: reduxMockStore(loadingQueriesStore),
|
||||||
@ -50,6 +54,7 @@ describe("ManageQueriesPage - component", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("renders a QueriesList component", () => {
|
it("renders a QueriesList component", () => {
|
||||||
|
console.log(store);
|
||||||
const Component = connectedComponent(ConnectedManageQueriesPage, {
|
const Component = connectedComponent(ConnectedManageQueriesPage, {
|
||||||
mockStore: reduxMockStore(store),
|
mockStore: reduxMockStore(store),
|
||||||
});
|
});
|
||||||
@ -76,6 +81,7 @@ describe("ManageQueriesPage - component", () => {
|
|||||||
dispatch: () => Promise.resolve(),
|
dispatch: () => Promise.resolve(),
|
||||||
loadingQueries: false,
|
loadingQueries: false,
|
||||||
queries: [queryStub],
|
queries: [queryStub],
|
||||||
|
currentUser: userStub,
|
||||||
};
|
};
|
||||||
const page = mount(<ManageQueriesPage {...props} />);
|
const page = mount(<ManageQueriesPage {...props} />);
|
||||||
|
|
||||||
@ -97,6 +103,7 @@ describe("ManageQueriesPage - component", () => {
|
|||||||
dispatch: () => Promise.reject(),
|
dispatch: () => Promise.reject(),
|
||||||
loadingQueries: false,
|
loadingQueries: false,
|
||||||
queries: [queryStub],
|
queries: [queryStub],
|
||||||
|
currentUser: userStub,
|
||||||
};
|
};
|
||||||
const page = mount(<ManageQueriesPage {...props} />);
|
const page = mount(<ManageQueriesPage {...props} />);
|
||||||
|
|
||||||
@ -128,7 +135,9 @@ describe("ManageQueriesPage - component", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("updates checkedQueryIDs in state when the check all queries Checkbox is toggled", () => {
|
it("updates checkedQueryIDs in state when the check all queries Checkbox is toggled", () => {
|
||||||
const page = mount(<ManageQueriesPage queries={[queryStub]} />);
|
const page = mount(
|
||||||
|
<ManageQueriesPage queries={[queryStub]} currentUser={userStub} />
|
||||||
|
);
|
||||||
const selectAllQueries = page.find({ name: "check-all-queries" });
|
const selectAllQueries = page.find({ name: "check-all-queries" });
|
||||||
|
|
||||||
expect(page.state("checkedQueryIDs")).toEqual([]);
|
expect(page.state("checkedQueryIDs")).toEqual([]);
|
||||||
@ -143,7 +152,9 @@ describe("ManageQueriesPage - component", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("updates checkedQueryIDs in state when a query row Checkbox is toggled", () => {
|
it("updates checkedQueryIDs in state when a query row Checkbox is toggled", () => {
|
||||||
const page = mount(<ManageQueriesPage queries={[queryStub]} />);
|
const page = mount(
|
||||||
|
<ManageQueriesPage queries={[queryStub]} currentUser={userStub} />
|
||||||
|
);
|
||||||
const queryCheckbox = page.find({ name: `query-checkbox-${queryStub.id}` });
|
const queryCheckbox = page.find({ name: `query-checkbox-${queryStub.id}` });
|
||||||
|
|
||||||
expect(page.state("checkedQueryIDs")).toEqual([]);
|
expect(page.state("checkedQueryIDs")).toEqual([]);
|
||||||
@ -207,7 +218,9 @@ describe("ManageQueriesPage - component", () => {
|
|||||||
const queries = [queryStub, { ...queryStub, id: 101, name: "alpha query" }];
|
const queries = [queryStub, { ...queryStub, id: 101, name: "alpha query" }];
|
||||||
|
|
||||||
it("displays the delete action button when a query is checked", () => {
|
it("displays the delete action button when a query is checked", () => {
|
||||||
const page = mount(<ManageQueriesPage queries={queries} />);
|
const page = mount(
|
||||||
|
<ManageQueriesPage queries={queries} currentUser={userStub} />
|
||||||
|
);
|
||||||
const checkAllQueries = page.find({ name: "check-all-queries" });
|
const checkAllQueries = page.find({ name: "check-all-queries" });
|
||||||
|
|
||||||
checkAllQueries.hostNodes().simulate("change");
|
checkAllQueries.hostNodes().simulate("change");
|
||||||
|
@ -137,6 +137,7 @@ export const queryStub = {
|
|||||||
snapshot: false,
|
snapshot: false,
|
||||||
updated_at: "2016-10-17T07:06:00Z",
|
updated_at: "2016-10-17T07:06:00Z",
|
||||||
version: "",
|
version: "",
|
||||||
|
observer_can_run: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const scheduledQueryStub = {
|
export const scheduledQueryStub = {
|
||||||
|
Loading…
Reference in New Issue
Block a user