Skip to content
Snippets Groups Projects
Commit dc4934f7 authored by Atte Keinänen's avatar Atte Keinänen
Browse files

Add experimental React+Redux Jest test

parent 446129ef
No related branches found
No related tags found
No related merge requests found
/* @flow */
import React, {PropTypes} from "react";
import {Link} from "react-router";
import cx from "classnames";
/*
* EmptyState is a component that can
* 1) introduce a new section of Metabase to a user, and encourages the user to take an action
* 2) indicate an empty result after an user-triggered search/query
* 2) indicate an empty result after a user-triggered search/query
*/
......
......@@ -19,7 +19,7 @@ type DashboardListItemType = {
const enhance = withState('hover', 'setHover', false)
const DashboardListItem = enhance(({dashboard, hover, setHover}: DashboardListItemType) =>
<li key={dashboard.id} className="Grid-cell flex-retain-width">
<li className="Grid-cell flex-retain-width">
<Link to={Urls.dashboard(dashboard.id)}
data-metabase-event={"Navbar;Dashboards;Open Dashboard;" + dashboard.id}
className="flex align-center border-box p2 bg-white bg-brand-hover rounded hover-parent hover--display no-decoration"
......@@ -54,9 +54,10 @@ export default class DashboardList extends Component {
render() {
const {dashboards} = this.props;
console.log('daash:', dashboards)
return (
<ol className="Grid Grid--guttersXl Grid--1of2 large-Grid--1of3">
{ dashboards.map(dash => <DashboardListItem dashboard={dash}/>)}
{ dashboards.map(dash => <DashboardListItem key={dash.id} dashboard={dash}/>)}
</ol>
);
}
......
import reducers from 'metabase/reducers-main';
import { combineReducers, createStore, applyMiddleware} from 'redux'
import thunk from "redux-thunk";
import promise from "redux-promise";
import logger from "redux-logger";
const createTestStore = (initialState) =>
createStore(combineReducers(reducers), initialState, applyMiddleware(thunk, promise, logger()))
export const noDashboardsStore = createTestStore({dashboards: {dashboardListing: []}});
// Dumped from redux state tree 4/10/17
export const twoDashboardsStore = createTestStore({
dashboards: {
dashboardListing: [
{
description: 'For seeing the usual response times, feedback topics, our response rate, how often customers are directed to our knowledge base instead of providing a customized response',
creator: {
email: 'atte@metabase.com',
first_name: 'Atte',
last_login: '2017-04-10T23:56:12.562Z',
is_qbnewb: false,
is_superuser: false,
id: 1,
last_name: 'Keinänen',
date_joined: '2017-03-17T03:37:27.396Z',
common_name: 'Atte Keinänen'
},
enable_embedding: false,
show_in_getting_started: false,
name: 'Customer Feedback Analysis',
caveats: null,
creator_id: 1,
updated_at: '2017-04-05T00:23:20.991Z',
made_public_by_id: null,
embedding_params: null,
id: 3,
parameters: [
{
name: 'Date Range',
slug: 'date_range',
id: 'fc68dfa5',
type: 'date/range',
'default': '2017-03-07~2017-03-14'
}
],
created_at: '2017-03-28T23:24:16.891Z',
public_uuid: null,
points_of_interest: null
},
{
description: 'For seeing our progress over time, and if there are bottlenecks in our product development process',
creator: {
email: 'atte@metabase.com',
first_name: 'Atte',
last_login: '2017-04-10T23:56:12.562Z',
is_qbnewb: false,
is_superuser: false,
id: 1,
last_name: 'Keinänen',
date_joined: '2017-03-17T03:37:27.396Z',
common_name: 'Atte Keinänen'
},
enable_embedding: false,
show_in_getting_started: false,
name: 'Kanban Breakdown Chart',
caveats: null,
creator_id: 1,
updated_at: '2017-04-04T20:41:50.616Z',
made_public_by_id: null,
embedding_params: null,
id: 7,
parameters: [],
created_at: '2017-04-04T20:39:01.263Z',
public_uuid: null,
points_of_interest: null
}
]
}
});
import React from 'react';
import renderer from 'react-test-renderer';
import {Provider} from 'react-redux';
import Dashboards from './Dashboards';
import {noDashboardsStore, twoDashboardsStore} from './Dashboards.spec.data';
describe('Dashboards list view', () => {
it('should render correctly without dashboards', () => {
const tree = renderer.create(
<Provider store={noDashboardsStore}>
<Dashboards />
</Provider>).toJSON();
console.log(tree);
expect(tree).toMatchSnapshot()
})
it('should render correctly with two dashboards', () => {
const tree = renderer.create(
<Provider store={twoDashboardsStore}>
<Dashboards />
</Provider>).toJSON();
console.log(tree);
expect(tree).toMatchSnapshot()
})
})
\ No newline at end of file
exports[`Dashboards list view should render correctly with two dashboards 1`] = `
<div
className="relative mx4"
style={undefined}>
<div>
<div
className="flex align-center pt4 pb1">
<div
className="flex align-center">
<h2
className="mr1">
Dashboards
</h2>
</div>
<svg
className="flex-align-right px4 cursor-pointer text-grey-5 text-brand-hover"
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
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--1of2 large-Grid--1of3">
<li
className="Grid-cell flex-retain-width">
<a
className="flex align-center border-box p2 bg-white bg-brand-hover rounded hover-parent hover--display no-decoration"
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",
}
}>
Customer Feedback Analysis
</h4>
<div
className="text-small text-uppercase text-bold text-grey-3">
Mar 28, 2017
</div>
</div>
</a>
</li>
<li
className="Grid-cell flex-retain-width">
<a
className="flex align-center border-box p2 bg-white bg-brand-hover rounded hover-parent hover--display no-decoration"
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",
}
}>
Kanban Breakdown Chart
</h4>
<div
className="text-small text-uppercase text-bold text-grey-3">
Apr 4, 2017
</div>
</div>
</a>
</li>
</ol>
</div>
</div>
`;
exports[`Dashboards list view should render correctly without dashboards 1`] = `
<div
className="relative mx4 flex-full flex align-center justify-center"
style={undefined}>
<div
className="mt2">
<div
className="text-centered text-brand-light my2">
<img
alt={
<div>
Put the charts and graphs you look at
<br />
frequently in a single, handy place.
</div>
}
className="mln2"
height="250px"
src="/app/img/dashboard_illustration.png"
srcSet="/app/img/dashboard_illustration@2x.png 2x" />
<div
className="flex justify-center">
<div>
Put the charts and graphs you look at
<br />
frequently in a single, handy place.
</div>
}
</div>
<a
className="Button Button--primary mt3"
onClick={[Function]}>
Create a dashboard
</a>
</div>
</div>
</div>
`;
import d3 from "d3";
import inflection from "inflection";
import moment from "moment";
import Humanize from "humanize";
import Humanize from "humanize-plus";
import React from "react";
import ExternalLink from "metabase/components/ExternalLink.jsx";
......
module.exports = 'test-file-stub';
\ No newline at end of file
module.exports = {};
\ No newline at end of file
......@@ -23,6 +23,7 @@
"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",
......@@ -173,11 +174,19 @@
]
},
"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",
"^promise-loader": "<rootDir>/frontend/test/__mocks__/fileMock.js"
},
"testPathIgnorePatterns": [
"<rootDir>/frontend/test/"
],
"modulePaths": [
"<rootDir>/frontend/src"
],
"setupFiles": [
"<rootDir>/frontend/test/metabase-bootstrap.js"
]
}
}
......@@ -3603,6 +3603,10 @@ har-validator@~2.0.6:
is-my-json-valid "^2.12.4"
pinkie-promise "^2.0.0"
harmony-reflect@^1.4.6:
version "1.5.1"
resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.5.1.tgz#b54ca617b00cc8aef559bbb17b3d85431dc7e329"
has-ansi@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e"
......@@ -3833,6 +3837,12 @@ icss-replace-symbols@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.0.2.tgz#cb0b6054eb3af6edc9ab1d62d01933e2d4c8bfa5"
identity-obj-proxy@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14"
dependencies:
harmony-reflect "^1.4.6"
ieee754@^1.1.4:
version "1.1.8"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment