浏览代码

test and some refactoring

Peter Holmberg 7 年之前
父节点
当前提交
026588cbf1

+ 45 - 0
public/app/features/org/OrgDetailsPage.test.tsx

@@ -0,0 +1,45 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import { OrgDetailsPage, Props } from './OrgDetailsPage';
+import { NavModel, Organization, OrganizationPreferences } from '../../types';
+
+const setup = (propOverrides?: object) => {
+  const props: Props = {
+    preferences: {} as OrganizationPreferences,
+    organization: {} as Organization,
+    navModel: {} as NavModel,
+    loadOrganization: jest.fn(),
+    loadOrganizationPreferences: jest.fn(),
+    loadStarredDashboards: jest.fn(),
+    setOrganizationName: jest.fn(),
+    updateOrganization: jest.fn(),
+  };
+
+  Object.assign(props, propOverrides);
+
+  return shallow(<OrgDetailsPage {...props} />);
+};
+
+describe('Render', () => {
+  it('should render component', () => {
+    const wrapper = setup();
+
+    expect(wrapper).toMatchSnapshot();
+  });
+
+  it('should render organization and preferences', () => {
+    const wrapper = setup({
+      organization: {
+        name: 'Cool org',
+        id: 1,
+      },
+      preferences: {
+        homeDashboardId: 1,
+        theme: 'Default',
+        timezone: 'Default',
+      },
+    });
+
+    expect(wrapper).toMatchSnapshot();
+  });
+});

+ 3 - 40
public/app/features/org/OrgDetailsPage.tsx

@@ -9,30 +9,21 @@ import {
   loadOrganization,
   loadOrganizationPreferences,
   setOrganizationName,
-  setOrganizationTheme,
-  setOrganizationHomeDashboard,
-  setOrganizationTimezone,
   updateOrganization,
-  updateOrganizationPreferences,
 } from './state/actions';
 import { loadStarredDashboards } from '../dashboard/state/actions';
-import { DashboardAcl, NavModel, Organization, OrganizationPreferences, StoreState } from 'app/types';
+import { NavModel, Organization, OrganizationPreferences, StoreState } from 'app/types';
 import { getNavModel } from '../../core/selectors/navModel';
 
 export interface Props {
   navModel: NavModel;
   organization: Organization;
   preferences: OrganizationPreferences;
-  starredDashboards: DashboardAcl[];
   loadOrganization: typeof loadOrganization;
   loadOrganizationPreferences: typeof loadOrganizationPreferences;
   loadStarredDashboards: typeof loadStarredDashboards;
   setOrganizationName: typeof setOrganizationName;
-  setOrganizationHomeDashboard: typeof setOrganizationHomeDashboard;
-  setOrganizationTheme: typeof setOrganizationTheme;
-  setOrganizationTimezone: typeof setOrganizationTimezone;
   updateOrganization: typeof updateOrganization;
-  updateOrganizationPreferences: typeof updateOrganizationPreferences;
 }
 
 export class OrgDetailsPage extends PureComponent<Props> {
@@ -50,24 +41,8 @@ export class OrgDetailsPage extends PureComponent<Props> {
     this.props.updateOrganization();
   };
 
-  onSubmitPreferences = () => {
-    this.props.updateOrganizationPreferences();
-  };
-
-  onThemeChange = theme => {
-    this.props.setOrganizationTheme(theme);
-  };
-
-  onHomeDashboardChange = dashboardId => {
-    this.props.setOrganizationHomeDashboard(dashboardId);
-  };
-
-  onTimeZoneChange = timeZone => {
-    this.props.setOrganizationTimezone(timeZone);
-  };
-
   render() {
-    const { navModel, organization, preferences, starredDashboards } = this.props;
+    const { navModel, organization, preferences } = this.props;
 
     return (
       <div>
@@ -82,14 +57,7 @@ export class OrgDetailsPage extends PureComponent<Props> {
                 onSubmit={this.onUpdateOrganization}
                 orgName={organization.name}
               />
-              <OrgPreferences
-                preferences={preferences}
-                starredDashboards={starredDashboards}
-                onDashboardChange={dashboardId => this.onHomeDashboardChange(dashboardId)}
-                onThemeChange={theme => this.onThemeChange(theme)}
-                onTimeZoneChange={timeZone => this.onTimeZoneChange(timeZone)}
-                onSubmit={this.onSubmitPreferences}
-              />
+              <OrgPreferences />
             </div>
           )}
         </div>
@@ -103,7 +71,6 @@ function mapStateToProps(state: StoreState) {
     navModel: getNavModel(state.navIndex, 'org-settings'),
     organization: state.organization.organization,
     preferences: state.organization.preferences,
-    starredDashboards: state.organization.starredDashboards,
   };
 }
 
@@ -112,11 +79,7 @@ const mapDispatchToProps = {
   loadOrganizationPreferences,
   loadStarredDashboards,
   setOrganizationName,
-  setOrganizationTheme,
-  setOrganizationHomeDashboard,
-  setOrganizationTimezone,
   updateOrganization,
-  updateOrganizationPreferences,
 };
 
 export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(OrgDetailsPage));

+ 28 - 0
public/app/features/org/OrgPreferences.test.tsx

@@ -0,0 +1,28 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import { OrgPreferences, Props } from './OrgPreferences';
+
+const setup = () => {
+  const props: Props = {
+    preferences: {
+      homeDashboardId: 1,
+      timezone: 'UTC',
+      theme: 'Default',
+    },
+    starredDashboards: [{ id: 1, name: 'Standard dashboard' }],
+    setOrganizationTimezone: jest.fn(),
+    setOrganizationTheme: jest.fn(),
+    setOrganizationHomeDashboard: jest.fn(),
+    updateOrganizationPreferences: jest.fn(),
+  };
+
+  return shallow(<OrgPreferences {...props} />);
+};
+
+describe('Render', () => {
+  it('should render component', () => {
+    const wrapper = setup();
+
+    expect(wrapper).toMatchSnapshot();
+  });
+});

+ 105 - 80
public/app/features/org/OrgPreferences.tsx

@@ -1,92 +1,117 @@
-import React, { SFC } from 'react';
+import React, { PureComponent } from 'react';
+import { connect } from 'react-redux';
 import Tooltip from '../../core/components/Tooltip/Tooltip';
 import SimplePicker from '../../core/components/Picker/SimplePicker';
 import { DashboardAcl, OrganizationPreferences } from 'app/types';
+import {
+  setOrganizationHomeDashboard,
+  setOrganizationTheme,
+  setOrganizationTimezone,
+  updateOrganizationPreferences,
+} from './state/actions';
 
-interface Props {
+export interface Props {
   preferences: OrganizationPreferences;
   starredDashboards: DashboardAcl[];
-  onDashboardChange: (dashboardId: number) => void;
-  onTimeZoneChange: (timeZone: string) => void;
-  onThemeChange: (theme: string) => void;
-  onSubmit: () => void;
+  setOrganizationHomeDashboard: typeof setOrganizationHomeDashboard;
+  setOrganizationTheme: typeof setOrganizationTheme;
+  setOrganizationTimezone: typeof setOrganizationTimezone;
+  updateOrganizationPreferences: typeof updateOrganizationPreferences;
 }
 
-const OrgPreferences: SFC<Props> = ({
-  preferences,
-  starredDashboards,
-  onDashboardChange,
-  onSubmit,
-  onTimeZoneChange,
-  onThemeChange,
-}) => {
-  const themes = [{ value: '', text: 'Default' }, { value: 'dark', text: 'Dark' }, { value: 'light', text: 'Light' }];
+const themes = [{ value: '', text: 'Default' }, { value: 'dark', text: 'Dark' }, { value: 'light', text: 'Light' }];
 
-  const timezones = [
-    { value: '', text: 'Default' },
-    { value: 'browser', text: 'Local browser time' },
-    { value: 'utc', text: 'UTC' },
-  ];
+const timezones = [
+  { value: '', text: 'Default' },
+  { value: 'browser', text: 'Local browser time' },
+  { value: 'utc', text: 'UTC' },
+];
 
-  return (
-    <form
-      className="section gf-form-group"
-      onSubmit={event => {
-        event.preventDefault();
-        onSubmit();
-      }}
-    >
-      <h3 className="page-heading">Preferences</h3>
-      <div className="gf-form">
-        <span className="gf-form-label width-11">UI Theme</span>
-        <SimplePicker
-          defaultValue={themes.find(theme => theme.value === preferences.theme)}
-          options={themes}
-          getOptionValue={i => i.value}
-          getOptionLabel={i => i.text}
-          onSelected={theme => onThemeChange(theme.value)}
-          width={20}
-        />
-      </div>
-      <div className="gf-form">
-        <span className="gf-form-label width-11">
-          Home Dashboard
-          <Tooltip
-            className="gf-form-help-icon gf-form-help-icon--right-normal"
-            placement="right"
-            content="Not finding dashboard you want? Star it first, then it should appear in this select box."
-          >
-            <i className="fa fa-info-circle" />
-          </Tooltip>
-        </span>
-        <SimplePicker
-          defaultValue={starredDashboards.find(dashboard => dashboard.id === preferences.homeDashboardId)}
-          getOptionValue={i => i.id}
-          getOptionLabel={i => i.title}
-          onSelected={(dashboard: DashboardAcl) => onDashboardChange(dashboard.id)}
-          options={starredDashboards}
-          placeholder="Chose default dashboard"
-          width={20}
-        />
-      </div>
-      <div className="gf-form">
-        <label className="gf-form-label width-11">Timezone</label>
-        <SimplePicker
-          defaultValue={timezones.find(timezone => timezone.value === preferences.timezone)}
-          getOptionValue={i => i.value}
-          getOptionLabel={i => i.text}
-          onSelected={timezone => onTimeZoneChange(timezone.value)}
-          options={timezones}
-          width={20}
-        />
-      </div>
-      <div className="gf-form-button-row">
-        <button type="submit" className="btn btn-success">
-          Save
-        </button>
-      </div>
-    </form>
-  );
+export class OrgPreferences extends PureComponent<Props> {
+  onSubmitForm = event => {
+    event.preventDefault();
+    this.props.updateOrganizationPreferences();
+  };
+
+  render() {
+    const {
+      preferences,
+      starredDashboards,
+      setOrganizationHomeDashboard,
+      setOrganizationTimezone,
+      setOrganizationTheme,
+    } = this.props;
+
+    starredDashboards.unshift({ id: 0, title: 'Default' });
+
+    return (
+      <form className="section gf-form-group" onSubmit={this.onSubmitForm}>
+        <h3 className="page-heading">Preferences</h3>
+        <div className="gf-form">
+          <span className="gf-form-label width-11">UI Theme</span>
+          <SimplePicker
+            defaultValue={themes.find(theme => theme.value === preferences.theme)}
+            options={themes}
+            getOptionValue={i => i.value}
+            getOptionLabel={i => i.text}
+            onSelected={theme => setOrganizationTheme(theme.value)}
+            width={20}
+          />
+        </div>
+        <div className="gf-form">
+          <span className="gf-form-label width-11">
+            Home Dashboard
+            <Tooltip
+              className="gf-form-help-icon gf-form-help-icon--right-normal"
+              placement="right"
+              content="Not finding dashboard you want? Star it first, then it should appear in this select box."
+            >
+              <i className="fa fa-info-circle" />
+            </Tooltip>
+          </span>
+          <SimplePicker
+            defaultValue={starredDashboards.find(dashboard => dashboard.id === preferences.homeDashboardId)}
+            getOptionValue={i => i.id}
+            getOptionLabel={i => i.title}
+            onSelected={(dashboard: DashboardAcl) => setOrganizationHomeDashboard(dashboard.id)}
+            options={starredDashboards}
+            placeholder="Chose default dashboard"
+            width={20}
+          />
+        </div>
+        <div className="gf-form">
+          <label className="gf-form-label width-11">Timezone</label>
+          <SimplePicker
+            defaultValue={timezones.find(timezone => timezone.value === preferences.timezone)}
+            getOptionValue={i => i.value}
+            getOptionLabel={i => i.text}
+            onSelected={timezone => setOrganizationTimezone(timezone.value)}
+            options={timezones}
+            width={20}
+          />
+        </div>
+        <div className="gf-form-button-row">
+          <button type="submit" className="btn btn-success">
+            Save
+          </button>
+        </div>
+      </form>
+    );
+  }
+}
+
+function mapStateToProps(state) {
+  return {
+    preferences: state.organization.preferences,
+    starredDashboards: state.organization.starredDashboards,
+  };
+}
+
+const mapDispatchToProps = {
+  setOrganizationHomeDashboard,
+  setOrganizationTimezone,
+  setOrganizationTheme,
+  updateOrganizationPreferences,
 };
 
-export default OrgPreferences;
+export default connect(mapStateToProps, mapDispatchToProps)(OrgPreferences);

+ 21 - 0
public/app/features/org/OrgProfile.test.tsx

@@ -0,0 +1,21 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import OrgProfile, { Props } from './OrgProfile';
+
+const setup = () => {
+  const props: Props = {
+    orgName: 'Main org',
+    onSubmit: jest.fn(),
+    onOrgNameChange: jest.fn(),
+  };
+
+  return shallow(<OrgProfile {...props} />);
+};
+
+describe('Render', () => {
+  it('should render component', () => {
+    const wrapper = setup();
+
+    expect(wrapper).toMatchSnapshot();
+  });
+});

+ 1 - 1
public/app/features/org/OrgProfile.tsx

@@ -1,6 +1,6 @@
 import React, { SFC } from 'react';
 
-interface Props {
+export interface Props {
   orgName: string;
   onSubmit: () => void;
   onOrgNameChange: (orgName: string) => void;

+ 36 - 0
public/app/features/org/__snapshots__/OrgDetailsPage.test.tsx.snap

@@ -0,0 +1,36 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Render should render component 1`] = `
+<div>
+  <PageHeader
+    model={Object {}}
+  />
+  <div
+    className="page-container page-body"
+  >
+    <PageLoader
+      pageName="Organization"
+    />
+  </div>
+</div>
+`;
+
+exports[`Render should render organization and preferences 1`] = `
+<div>
+  <PageHeader
+    model={Object {}}
+  />
+  <div
+    className="page-container page-body"
+  >
+    <div>
+      <OrgProfile
+        onOrgNameChange={[Function]}
+        onSubmit={[Function]}
+        orgName="Cool org"
+      />
+      <Connect(OrgPreferences) />
+    </div>
+  </div>
+</div>
+`;

+ 125 - 0
public/app/features/org/__snapshots__/OrgPreferences.test.tsx.snap

@@ -0,0 +1,125 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Render should render component 1`] = `
+<form
+  className="section gf-form-group"
+  onSubmit={[Function]}
+>
+  <h3
+    className="page-heading"
+  >
+    Preferences
+  </h3>
+  <div
+    className="gf-form"
+  >
+    <span
+      className="gf-form-label width-11"
+    >
+      UI Theme
+    </span>
+    <SimplePicker
+      getOptionLabel={[Function]}
+      getOptionValue={[Function]}
+      onSelected={[Function]}
+      options={
+        Array [
+          Object {
+            "text": "Default",
+            "value": "",
+          },
+          Object {
+            "text": "Dark",
+            "value": "dark",
+          },
+          Object {
+            "text": "Light",
+            "value": "light",
+          },
+        ]
+      }
+      width={20}
+    />
+  </div>
+  <div
+    className="gf-form"
+  >
+    <span
+      className="gf-form-label width-11"
+    >
+      Home Dashboard
+      <class_1
+        className="gf-form-help-icon gf-form-help-icon--right-normal"
+        content="Not finding dashboard you want? Star it first, then it should appear in this select box."
+        placement="right"
+      >
+        <i
+          className="fa fa-info-circle"
+        />
+      </class_1>
+    </span>
+    <SimplePicker
+      defaultValue={
+        Object {
+          "id": 1,
+          "name": "Standard dashboard",
+        }
+      }
+      getOptionLabel={[Function]}
+      getOptionValue={[Function]}
+      onSelected={[Function]}
+      options={
+        Array [
+          Object {
+            "id": 1,
+            "name": "Standard dashboard",
+          },
+        ]
+      }
+      placeholder="Chose default dashboard"
+      width={20}
+    />
+  </div>
+  <div
+    className="gf-form"
+  >
+    <label
+      className="gf-form-label width-11"
+    >
+      Timezone
+    </label>
+    <SimplePicker
+      getOptionLabel={[Function]}
+      getOptionValue={[Function]}
+      onSelected={[Function]}
+      options={
+        Array [
+          Object {
+            "text": "Default",
+            "value": "",
+          },
+          Object {
+            "text": "Local browser time",
+            "value": "browser",
+          },
+          Object {
+            "text": "UTC",
+            "value": "utc",
+          },
+        ]
+      }
+      width={20}
+    />
+  </div>
+  <div
+    className="gf-form-button-row"
+  >
+    <button
+      className="btn btn-success"
+      type="submit"
+    >
+      Save
+    </button>
+  </div>
+</form>
+`;

+ 46 - 0
public/app/features/org/__snapshots__/OrgProfile.test.tsx.snap

@@ -0,0 +1,46 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Render should render component 1`] = `
+<div>
+  <h3
+    className="page-sub-heading"
+  >
+    Organization profile
+  </h3>
+  <form
+    className="gf-form-group"
+    name="orgForm"
+    onSubmit={[Function]}
+  >
+    <div
+      className="gf-form-inline"
+    >
+      <div
+        className="gf-form max-width-28"
+      >
+        <span
+          className="gf-form-label"
+        >
+          Organization name
+        </span>
+        <input
+          className="gf-form-input"
+          onChange={[Function]}
+          type="text"
+          value="Main org"
+        />
+      </div>
+    </div>
+    <div
+      className="gf-form-button-row"
+    >
+      <button
+        className="btn btn-success"
+        type="submit"
+      >
+        Save
+      </button>
+    </div>
+  </form>
+</div>
+`;

+ 1 - 0
public/app/types/acl.ts

@@ -39,6 +39,7 @@ export interface DashboardAcl {
   name?: string;
   inherited?: boolean;
   sortRank?: number;
+  title?: string;
 }
 
 export interface DashboardPermissionInfo {