From d2c01bbf3df7afffbed6b62baec2b3ec475ac574 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Atte=20Kein=C3=A4nen?= <atte.keinanen@gmail.com>
Date: Wed, 12 Apr 2017 14:46:55 -0700
Subject: [PATCH] Fix dashboards Jest tests and fix ESLint warnings

---
 .../src/metabase/components/EmptyState.jsx    |   2 +-
 .../src/metabase/components/FilterWidget.jsx  |   2 +-
 .../dashboards/components/DashboardList.jsx   |   3 +-
 .../dashboards/components/WhatsADashboard.jsx |  30 ---
 .../dashboards/containers/Dashboards.spec.js  |   6 +-
 .../__snapshots__/Dashboards.spec.js.snap     | 209 +++++++++++++++---
 .../__snapshots__/components.spec.js.snap     |   4 +-
 .../e2e/query_builder/query_builder.spec.js   |   2 -
 package.json                                  |   6 +-
 yarn.lock                                     |   8 +-
 10 files changed, 199 insertions(+), 73 deletions(-)
 delete mode 100644 frontend/src/metabase/dashboards/components/WhatsADashboard.jsx

diff --git a/frontend/src/metabase/components/EmptyState.jsx b/frontend/src/metabase/components/EmptyState.jsx
index eace3e416bb..44fc4dc269c 100644
--- a/frontend/src/metabase/components/EmptyState.jsx
+++ b/frontend/src/metabase/components/EmptyState.jsx
@@ -19,7 +19,7 @@ type EmptyStateProps = {
     action?: string,
     link?: string,
     onActionClick?: () => void,
-    smallDescription: boolean
+    smallDescription?: boolean
 }
 
 const EmptyState = ({title, message, icon, image, imageClassName, action, link, onActionClick, smallDescription = false}: EmptyStateProps) =>
diff --git a/frontend/src/metabase/components/FilterWidget.jsx b/frontend/src/metabase/components/FilterWidget.jsx
index 56991049612..e8d58f7dc76 100644
--- a/frontend/src/metabase/components/FilterWidget.jsx
+++ b/frontend/src/metabase/components/FilterWidget.jsx
@@ -3,7 +3,7 @@
 // An UI element that is normally right-aligned and showing a currently selected filter together with chevron.
 // Clicking the element will trigger a popover showing all available filter options.
 
-import React, { Component, PropTypes } from "react";
+import React, { Component } from "react";
 import Icon from "metabase/components/Icon";
 import PopoverWithTrigger from "./PopoverWithTrigger";
 
diff --git a/frontend/src/metabase/dashboards/components/DashboardList.jsx b/frontend/src/metabase/dashboards/components/DashboardList.jsx
index 2e42d9778c7..f09d617e3b1 100644
--- a/frontend/src/metabase/dashboards/components/DashboardList.jsx
+++ b/frontend/src/metabase/dashboards/components/DashboardList.jsx
@@ -1,6 +1,7 @@
 /* @flow */
 
-import React, {Component, PropTypes} from "react";
+import React, {Component} from "react";
+import PropTypes from "prop-types";
 import {Link} from "react-router";
 import {withState} from "recompose";
 import cx from "classnames";
diff --git a/frontend/src/metabase/dashboards/components/WhatsADashboard.jsx b/frontend/src/metabase/dashboards/components/WhatsADashboard.jsx
deleted file mode 100644
index ca2503a2848..00000000000
--- a/frontend/src/metabase/dashboards/components/WhatsADashboard.jsx
+++ /dev/null
@@ -1,30 +0,0 @@
-/* eslint "react/prop-types": "warn" */
-import React, { Component, PropTypes } from "react";
-
-import RetinaImage from "react-retina-image";
-
-export default class WhatsADashboard extends Component {
-    static propTypes = {
-        button: PropTypes.object
-    };
-    render() {
-        return (
-            <div className="flex flex-column align-center px4">
-                <h2 className="my4 text-brand">
-                    Copy & image missing
-                </h2>
-                <div className="mx4">
-                    <RetinaImage
-                        width={574}
-                        src="/app/img/pulse_empty_illustration.png"
-                        forceOriginalDimensions={false}
-                    />
-                </div>
-                <div className="h3 my3 text-centered text-grey-2 text-bold" style={{maxWidth: "500px"}}>
-                    Copy & image missing
-                </div>
-                {this.props.button}
-            </div>
-        );
-    }
-}
diff --git a/frontend/src/metabase/dashboards/containers/Dashboards.spec.js b/frontend/src/metabase/dashboards/containers/Dashboards.spec.js
index ed294bde383..20f47272da9 100644
--- a/frontend/src/metabase/dashboards/containers/Dashboards.spec.js
+++ b/frontend/src/metabase/dashboards/containers/Dashboards.spec.js
@@ -1,6 +1,5 @@
 import React from 'react';
 import renderer from 'react-test-renderer';
-import {Provider} from 'react-redux';
 
 import {Dashboards} from './Dashboards';
 import {noDashboardsList, twoDashboardsList} from './Dashboards.spec.data';
@@ -19,6 +18,11 @@ function setupDashboards(dashboards) {
         component
     }
 }
+
+// Don't render Ellipsified as Tooltip class that it is using causes trouble
+// (ReactDOM.findDOMNode not supported by react-test-renderer)
+jest.mock('metabase/components/Ellipsified', () => () => null )
+
 describe('Dashboards list view', () => {
     it('should render correctly in loading state', () => {
         const {component} = setupDashboards(null);
diff --git a/frontend/src/metabase/dashboards/containers/__snapshots__/Dashboards.spec.js.snap b/frontend/src/metabase/dashboards/containers/__snapshots__/Dashboards.spec.js.snap
index 6743446dd8c..586999c31f6 100644
--- a/frontend/src/metabase/dashboards/containers/__snapshots__/Dashboards.spec.js.snap
+++ b/frontend/src/metabase/dashboards/containers/__snapshots__/Dashboards.spec.js.snap
@@ -28,50 +28,203 @@ exports[`Dashboards list view should render correctly with two dashboards 1`] =
 <div
   className="relative mx4"
   style={undefined}>
-  <div
-    className="wrapper py4 text-brand text-centered flex-full flex flex-column layout-centered bg-white">
+  <div>
     <div
-      className={undefined}>
+      className="flex align-center pt4 pb1">
       <div
-        className="LoadingSpinner"
+        className="flex align-center">
+        <h2
+          className="mr1">
+          Dashboards
+        </h2>
+      </div>
+      <div
+        className="flex-align-right cursor-pointer text-grey-5 text-brand-hover">
+        <svg
+          className="Icon Icon-add"
+          fill="currentcolor"
+          height={20}
+          name="add"
+          onClick={[Function]}
+          size={20}
+          viewBox="0 0 32 32"
+          width={20}>
+          <path
+            d="M19,13 L19,2 L14,2 L14,13 L2,13 L2,18 L14,18 L14,30 L19,30 L19,18 L30,18 L30,13 L19,13 Z" />
+        </svg>
+      </div>
+    </div>
+    <div
+      className="flex align-center pb1">
+      <div
+        className="searchHeader">
+        <svg
+          className="searchIcon"
+          fill="currentcolor"
+          height={18}
+          name="search"
+          size={18}
+          viewBox="0 0 32 32"
+          width={18}>
+          <path
+            d="M12 0 A12 12 0 0 0 0 12 A12 12 0 0 0 12 24 A12 12 0 0 0 18.5 22.25 L28 32 L32 28 L22.25 18.5 A12 12 0 0 0 24 12 A12 12 0 0 0 12 0 M12 4 A8 8 0 0 1 12 20 A8 8 0 0 1 12 4  " />
+        </svg>
+        <input
+          className="input searchBox"
+          onChange={[Function]}
+          placeholder="Filter this list..."
+          type="text"
+          value="" />
+      </div>
+    </div>
+    <ol
+      className="Grid Grid--guttersXl Grid--full small-Grid--1of2 md-Grid--1of3">
+      <li
+        className="Grid-cell flex-retain-width"
         style={
           Object {
-            "borderWidth": 4,
-            "height": 32,
-            "width": 32,
+            "maxWidth": "550px",
           }
-        } />
-    </div>
-    <h2
-      className="text-normal text-grey-2 mt1">
-      Loading...
-    </h2>
+        }>
+        <a
+          className="flex align-center border-box p2 rounded no-decoration transition-background bg-white"
+          data-metabase-event="Navbar;Dashboards;Open Dashboard;3"
+          onClick={[Function]}
+          onMouseEnter={[Function]}
+          onMouseLeave={[Function]}
+          style={
+            Object {
+              "border": "1px solid rgba(220,225,228,0.50)",
+              "boxShadow": "0 1px 3px 0 rgba(220,220,220,0.50)",
+              "height": "80px",
+            }
+          }>
+          <svg
+            className="pr2 text-grey-1"
+            fill="currentcolor"
+            height={32}
+            name="dashboard"
+            size={32}
+            viewBox="0 0 32 32"
+            width={32}>
+            <path
+              d="M32,29 L32,4 L32,0 L0,0 L0,8 L28,8 L28,28 L4,28 L4,8 L0,8 L0,29.5 L0,32 L32,32 L32,29 Z M7.27272727,18.9090909 L17.4545455,18.9090909 L17.4545455,23.2727273 L7.27272727,23.2727273 L7.27272727,18.9090909 Z M7.27272727,12.0909091 L24.7272727,12.0909091 L24.7272727,16.4545455 L7.27272727,16.4545455 L7.27272727,12.0909091 Z M20.3636364,18.9090909 L24.7272727,18.9090909 L24.7272727,23.2727273 L20.3636364,23.2727273 L20.3636364,18.9090909 Z" />
+          </svg>
+          <div
+            className="flex-full flex-retain-width">
+            <h4
+              className="text-ellipsis text-nowrap overflow-hidden text-brand"
+              style={
+                Object {
+                  "marginBottom": "0.2em",
+                }
+              } />
+            <div
+              className="text-smaller text-uppercase text-bold text-grey-3">
+              Mar 28, 2017
+            </div>
+          </div>
+        </a>
+      </li>
+      <li
+        className="Grid-cell flex-retain-width"
+        style={
+          Object {
+            "maxWidth": "550px",
+          }
+        }>
+        <a
+          className="flex align-center border-box p2 rounded no-decoration transition-background bg-white"
+          data-metabase-event="Navbar;Dashboards;Open Dashboard;7"
+          onClick={[Function]}
+          onMouseEnter={[Function]}
+          onMouseLeave={[Function]}
+          style={
+            Object {
+              "border": "1px solid rgba(220,225,228,0.50)",
+              "boxShadow": "0 1px 3px 0 rgba(220,220,220,0.50)",
+              "height": "80px",
+            }
+          }>
+          <svg
+            className="pr2 text-grey-1"
+            fill="currentcolor"
+            height={32}
+            name="dashboard"
+            size={32}
+            viewBox="0 0 32 32"
+            width={32}>
+            <path
+              d="M32,29 L32,4 L32,0 L0,0 L0,8 L28,8 L28,28 L4,28 L4,8 L0,8 L0,29.5 L0,32 L32,32 L32,29 Z M7.27272727,18.9090909 L17.4545455,18.9090909 L17.4545455,23.2727273 L7.27272727,23.2727273 L7.27272727,18.9090909 Z M7.27272727,12.0909091 L24.7272727,12.0909091 L24.7272727,16.4545455 L7.27272727,16.4545455 L7.27272727,12.0909091 Z M20.3636364,18.9090909 L24.7272727,18.9090909 L24.7272727,23.2727273 L20.3636364,23.2727273 L20.3636364,18.9090909 Z" />
+          </svg>
+          <div
+            className="flex-full flex-retain-width">
+            <h4
+              className="text-ellipsis text-nowrap overflow-hidden text-brand"
+              style={
+                Object {
+                  "marginBottom": "0.2em",
+                }
+              } />
+            <div
+              className="text-smaller text-uppercase text-bold text-grey-3">
+              Apr 4, 2017
+            </div>
+          </div>
+        </a>
+      </li>
+    </ol>
   </div>
 </div>
 `;
 
 exports[`Dashboards list view should render correctly with zero dashboards 1`] = `
 <div
-  className="relative mx4"
+  className="relative mx4 flex-full flex align-center justify-center"
   style={undefined}>
   <div
-    className="wrapper py4 text-brand text-centered flex-full flex flex-column layout-centered bg-white">
+    className="mt2">
     <div
-      className={undefined}>
+      className="text-centered text-brand-light my2"
+      style={
+        Object {
+          "width": "350px",
+        }
+      }>
+      <img
+        alt={
+          <span>
+            Put the charts and graphs you look at 
+            <br />
+            frequently in a single, handy place.
+          </span>
+        }
+        className="mln2"
+        src="/app/img/dashboard_illustration.png"
+        srcSet="/app/img/dashboard_illustration@2x.png 2x"
+        width="300px" />
       <div
-        className="LoadingSpinner"
-        style={
-          Object {
-            "borderWidth": 4,
-            "height": 32,
-            "width": 32,
-          }
-        } />
+        className="flex justify-center">
+        <h2
+          className="text-grey-2 text-normal mt2 mb4"
+          style={
+            Object {
+              "lineHeight": "1.5em",
+            }
+          }>
+          <span>
+            Put the charts and graphs you look at 
+            <br />
+            frequently in a single, handy place.
+          </span>
+        </h2>
+      </div>
+      <a
+        className="Button Button--primary mt4"
+        onClick={[Function]}>
+        Create a dashboard
+      </a>
     </div>
-    <h2
-      className="text-normal text-grey-2 mt1">
-      Loading...
-    </h2>
   </div>
 </div>
 `;
diff --git a/frontend/src/metabase/internal/__snapshots__/components.spec.js.snap b/frontend/src/metabase/internal/__snapshots__/components.spec.js.snap
index 256ce8fadff..047230b9e3e 100644
--- a/frontend/src/metabase/internal/__snapshots__/components.spec.js.snap
+++ b/frontend/src/metabase/internal/__snapshots__/components.spec.js.snap
@@ -379,7 +379,7 @@ exports[`StackedCheckBox should render "on" correctly 1`] = `
 
 exports[`Toggle should render "off" correctly 1`] = `
 <a
-  className="no-decoration "
+  className="toggle no-decoration "
   onClick={null}
   style={
     Object {
@@ -390,7 +390,7 @@ exports[`Toggle should render "off" correctly 1`] = `
 
 exports[`Toggle should render "on" correctly 1`] = `
 <a
-  className="no-decoration undefined "
+  className="toggle no-decoration selected "
   onClick={null}
   style={
     Object {
diff --git a/frontend/test/e2e/query_builder/query_builder.spec.js b/frontend/test/e2e/query_builder/query_builder.spec.js
index 1a14987512d..1e407d4d0e8 100644
--- a/frontend/test/e2e/query_builder/query_builder.spec.js
+++ b/frontend/test/e2e/query_builder/query_builder.spec.js
@@ -1,6 +1,4 @@
-
 import {
-    screenshot,
     describeE2E,
     ensureLoggedIn
 } from "../support/utils";
diff --git a/package.json b/package.json
index 9a167d461b2..7ea0834249d 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,6 @@
     "history": "^4.5.0",
     "humanize-plus": "^1.8.1",
     "icepick": "^1.1.0",
-    "identity-obj-proxy": "^3.0.0",
     "inflection": "^1.7.1",
     "isomorphic-fetch": "^2.2.1",
     "js-cookie": "^2.1.2",
@@ -107,6 +106,7 @@
     "html-webpack-harddisk-plugin": "^0.1.0",
     "html-webpack-plugin": "^2.14.0",
     "husky": "^0.13.2",
+    "identity-obj-proxy": "^3.0.0",
     "image-diff": "^1.6.3",
     "imports-loader": "^0.7.0",
     "jasmine": "^2.4.1",
@@ -133,7 +133,7 @@
     "promise-loader": "^1.0.0",
     "react-addons-test-utils": "^15.4.2",
     "react-hot-loader": "^1.3.0",
-    "react-test-renderer": "^15.4.2",
+    "react-test-renderer": "^15.5.4",
     "sauce-connect-launcher": "^1.1.1",
     "selenium-webdriver": "^2.53.3",
     "style-loader": "^0.13.0",
@@ -175,8 +175,8 @@
   },
   "jest": {
     "moduleNameMapper": {
-      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/frontend/test/__mocks__/fileMock.js",
       "\\.(css|less)$": "identity-obj-proxy",
+      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/frontend/test/__mocks__/fileMock.js",
       "^promise-loader": "<rootDir>/frontend/test/__mocks__/fileMock.js"
     },
     "testPathIgnorePatterns": [
diff --git a/yarn.lock b/yarn.lock
index a7c85378d99..e180920d74f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6405,11 +6405,11 @@ react-sortable@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/react-sortable/-/react-sortable-1.2.0.tgz#5acd7e1910df665408957035acb5f2354519d849"
 
-react-test-renderer@^15.4.2:
-  version "15.4.2"
-  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-15.4.2.tgz#27e1dff5d26d0e830f99614c487622bc831416f3"
+react-test-renderer@^15.5.4:
+  version "15.5.4"
+  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-15.5.4.tgz#d4ebb23f613d685ea8f5390109c2d20fbf7c83bc"
   dependencies:
-    fbjs "^0.8.4"
+    fbjs "^0.8.9"
     object-assign "^4.1.0"
 
 react-textarea-autosize@^4.0.5:
-- 
GitLab