diff --git a/superset/assets/javascripts/SqlLab/components/TabStatusIcon.jsx b/superset/assets/javascripts/SqlLab/components/TabStatusIcon.jsx
new file mode 100644
index 0000000000000..33f86469d9a03
--- /dev/null
+++ b/superset/assets/javascripts/SqlLab/components/TabStatusIcon.jsx
@@ -0,0 +1,42 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const propTypes = {
+ onClose: PropTypes.func.isRequired,
+ tabState: PropTypes.string.isRequired,
+};
+
+class TabStatusIcon extends React.Component {
+ constructor(props) {
+ super(props);
+ this.onMouseOver = this.onMouseOver.bind(this);
+ this.onMouseOut = this.onMouseOut.bind(this);
+
+ this.state = { isHovered: false };
+ }
+
+ onMouseOver() {
+ this.setState({ isHovered: true });
+ }
+
+ onMouseOut() {
+ this.setState({ isHovered: false });
+ }
+
+ render() {
+ return (
+
+
+ {this.state.isHovered ? '×' : null}
+
+
+ );
+ }
+}
+
+TabStatusIcon.propTypes = propTypes;
+export default TabStatusIcon;
diff --git a/superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx b/superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx
index c890b5bf6efe6..b9acc160d5330 100644
--- a/superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx
+++ b/superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx
@@ -10,6 +10,7 @@ import SqlEditor from './SqlEditor';
import CopyQueryTabUrl from './CopyQueryTabUrl';
import { areArraysShallowEqual } from '../../reduxUtils';
import { t } from '../../locales';
+import TabStatusIcon from './TabStatusIcon';
const propTypes = {
actions: PropTypes.object.isRequired,
@@ -160,7 +161,7 @@ class TabbedSqlEditors extends React.PureComponent {
const tabTitle = (
-
{qe.title} {' '}
+
{qe.title} {' '}
);
+ return { wrapper, onClose };
+}
+
+describe('TabStatusIcon', () => {
+ it('renders a circle without an x when hovered', () => {
+ const { wrapper } = setup();
+ expect(wrapper.find('div.circle')).to.have.length(1);
+ expect(wrapper.text()).to.equal('');
+ });
+
+ it('renders a circle with an x when hovered', () => {
+ const { wrapper } = setup();
+ wrapper.simulate('mouseOver');
+ expect(wrapper.find('div.circle')).to.have.length(1);
+ expect(wrapper.text()).to.equal('×');
+ });
+
+ it('calls onClose from props when clicked', () => {
+ const { wrapper, onClose } = setup();
+ wrapper.simulate('click');
+ // eslint-disable-next-line no-unused-expressions
+ expect(onClose.calledOnce).to.be.true;
+ });
+});