Peter Holmberg 7 年之前
父節點
當前提交
70c3e1f3bc

+ 30 - 0
public/app/features/plugins/PluginActionBar.test.tsx

@@ -0,0 +1,30 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import { PluginActionBar, Props } from './PluginActionBar';
+
+const setup = (propOverrides?: object) => {
+  const props: Props = {
+    searchQuery: '',
+    layoutMode: 'grid',
+    setLayoutMode: jest.fn(),
+    setPluginsSearchQuery: jest.fn(),
+  };
+
+  Object.assign(props, propOverrides);
+
+  const wrapper = shallow(<PluginActionBar {...props} />);
+  const instance = wrapper.instance() as PluginActionBar;
+
+  return {
+    wrapper,
+    instance,
+  };
+};
+
+describe('Render', () => {
+  it('should render component', () => {
+    const { wrapper } = setup();
+
+    expect(wrapper).toMatchSnapshot();
+  });
+});

+ 24 - 0
public/app/features/plugins/PluginList.test.tsx

@@ -0,0 +1,24 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import PluginList from './PluginList';
+import { getMockPlugins } from './__mocks__/pluginMocks';
+
+const setup = (propOverrides?: object) => {
+  const props = Object.assign(
+    {
+      plugins: getMockPlugins(5),
+      layout: 'grid',
+    },
+    propOverrides
+  );
+
+  return shallow(<PluginList {...props} />);
+};
+
+describe('Render', () => {
+  it('should render component', () => {
+    const wrapper = setup();
+
+    expect(wrapper).toMatchSnapshot();
+  });
+});

+ 33 - 0
public/app/features/plugins/PluginListItem.test.tsx

@@ -0,0 +1,33 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import PluginListItem from './PluginListItem';
+import { getMockPlugin } from './__mocks__/pluginMocks';
+
+const setup = (propOverrides?: object) => {
+  const props = Object.assign(
+    {
+      plugin: getMockPlugin(),
+    },
+    propOverrides
+  );
+
+  return shallow(<PluginListItem {...props} />);
+};
+
+describe('Render', () => {
+  it('should render component', () => {
+    const wrapper = setup();
+
+    expect(wrapper).toMatchSnapshot();
+  });
+
+  it('should render has plugin section', () => {
+    const mockPlugin = getMockPlugin();
+    mockPlugin.hasUpdate = true;
+    const wrapper = setup({
+      plugin: mockPlugin,
+    });
+
+    expect(wrapper).toMatchSnapshot();
+  });
+});

+ 1 - 1
public/app/features/plugins/PluginListPage.tsx

@@ -32,7 +32,7 @@ export class PluginListPage extends PureComponent<Props> {
       <div>
       <div>
         <PageHeader model={navModel} />
         <PageHeader model={navModel} />
         <div className="page-container page-body">
         <div className="page-container page-body">
-          <PluginActionBar searchQuery="" onQueryChange={() => {}} />
+          <PluginActionBar />
           {plugins && <PluginList plugins={plugins} layout={layoutMode} />}
           {plugins && <PluginList plugins={plugins} layout={layoutMode} />}
         </div>
         </div>
       </div>
       </div>

+ 59 - 0
public/app/features/plugins/__mocks__/pluginMocks.ts

@@ -0,0 +1,59 @@
+import { Plugin } from 'app/types';
+
+export const getMockPlugins = (amount: number): Plugin[] => {
+  const plugins = [];
+
+  for (let i = 0; i <= amount; i++) {
+    plugins.push({
+      defaultNavUrl: 'some/url',
+      enabled: false,
+      hasUpdate: false,
+      id: `${i}`,
+      info: {
+        author: {
+          name: 'Grafana Labs',
+          url: 'url/to/GrafanaLabs',
+        },
+        description: 'pretty decent plugin',
+        links: ['one link'],
+        logos: { small: 'small/logo', large: 'large/logo' },
+        screenshots: `screenshot/${i}`,
+        updated: '2018-09-26',
+        version: '1',
+      },
+      latestVersion: `1.${i}`,
+      name: `pretty cool plugin-${i}`,
+      pinned: false,
+      state: '',
+      type: '',
+    });
+  }
+
+  return plugins;
+};
+
+export const getMockPlugin = () => {
+  return {
+    defaultNavUrl: 'some/url',
+    enabled: false,
+    hasUpdate: false,
+    id: '1',
+    info: {
+      author: {
+        name: 'Grafana Labs',
+        url: 'url/to/GrafanaLabs',
+      },
+      description: 'pretty decent plugin',
+      links: ['one link'],
+      logos: { small: 'small/logo', large: 'large/logo' },
+      screenshots: 'screenshot/1',
+      updated: '2018-09-26',
+      version: '1',
+    },
+    latestVersion: '1',
+    name: 'pretty cool plugin 1',
+    pinned: false,
+    state: '',
+    type: '',
+  };
+};

+ 40 - 0
public/app/features/plugins/__snapshots__/PluginActionBar.test.tsx.snap

@@ -0,0 +1,40 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Render should render component 1`] = `
+<div
+  className="page-action-bar"
+>
+  <div
+    className="gf-form gf-form--grow"
+  >
+    <label
+      className="gf-form--has-input-icon"
+    >
+      <input
+        className="gf-form-input width-20"
+        onChange={[Function]}
+        placeholder="Filter by name or type"
+        type="text"
+        value=""
+      />
+      <i
+        className="gf-form-input-icon fa fa-search"
+      />
+    </label>
+    <LayoutSelector
+      mode="grid"
+      onLayoutModeChanged={[Function]}
+    />
+  </div>
+  <div
+    className="page-action-bar__spacer"
+  />
+  <a
+    className="btn btn-success"
+    href="https://grafana.com/plugins?utm_source=grafana_plugin_list"
+    target="_blank"
+  >
+    Find more plugins on Grafana.com
+  </a>
+</div>
+`;

+ 210 - 0
public/app/features/plugins/__snapshots__/PluginList.test.tsx.snap

@@ -0,0 +1,210 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Render should render component 1`] = `
+<section
+  className="card-section card-list-layout-grid"
+>
+  <ol
+    className="card-list"
+  >
+    <PluginListItem
+      key="pretty cool plugin-0-0"
+      plugin={
+        Object {
+          "defaultNavUrl": "some/url",
+          "enabled": false,
+          "hasUpdate": false,
+          "id": "0",
+          "info": Object {
+            "author": Object {
+              "name": "Grafana Labs",
+              "url": "url/to/GrafanaLabs",
+            },
+            "description": "pretty decent plugin",
+            "links": Array [
+              "one link",
+            ],
+            "logos": Object {
+              "large": "large/logo",
+              "small": "small/logo",
+            },
+            "screenshots": "screenshot/0",
+            "updated": "2018-09-26",
+            "version": "1",
+          },
+          "latestVersion": "1.0",
+          "name": "pretty cool plugin-0",
+          "pinned": false,
+          "state": "",
+          "type": "",
+        }
+      }
+    />
+    <PluginListItem
+      key="pretty cool plugin-1-1"
+      plugin={
+        Object {
+          "defaultNavUrl": "some/url",
+          "enabled": false,
+          "hasUpdate": false,
+          "id": "1",
+          "info": Object {
+            "author": Object {
+              "name": "Grafana Labs",
+              "url": "url/to/GrafanaLabs",
+            },
+            "description": "pretty decent plugin",
+            "links": Array [
+              "one link",
+            ],
+            "logos": Object {
+              "large": "large/logo",
+              "small": "small/logo",
+            },
+            "screenshots": "screenshot/1",
+            "updated": "2018-09-26",
+            "version": "1",
+          },
+          "latestVersion": "1.1",
+          "name": "pretty cool plugin-1",
+          "pinned": false,
+          "state": "",
+          "type": "",
+        }
+      }
+    />
+    <PluginListItem
+      key="pretty cool plugin-2-2"
+      plugin={
+        Object {
+          "defaultNavUrl": "some/url",
+          "enabled": false,
+          "hasUpdate": false,
+          "id": "2",
+          "info": Object {
+            "author": Object {
+              "name": "Grafana Labs",
+              "url": "url/to/GrafanaLabs",
+            },
+            "description": "pretty decent plugin",
+            "links": Array [
+              "one link",
+            ],
+            "logos": Object {
+              "large": "large/logo",
+              "small": "small/logo",
+            },
+            "screenshots": "screenshot/2",
+            "updated": "2018-09-26",
+            "version": "1",
+          },
+          "latestVersion": "1.2",
+          "name": "pretty cool plugin-2",
+          "pinned": false,
+          "state": "",
+          "type": "",
+        }
+      }
+    />
+    <PluginListItem
+      key="pretty cool plugin-3-3"
+      plugin={
+        Object {
+          "defaultNavUrl": "some/url",
+          "enabled": false,
+          "hasUpdate": false,
+          "id": "3",
+          "info": Object {
+            "author": Object {
+              "name": "Grafana Labs",
+              "url": "url/to/GrafanaLabs",
+            },
+            "description": "pretty decent plugin",
+            "links": Array [
+              "one link",
+            ],
+            "logos": Object {
+              "large": "large/logo",
+              "small": "small/logo",
+            },
+            "screenshots": "screenshot/3",
+            "updated": "2018-09-26",
+            "version": "1",
+          },
+          "latestVersion": "1.3",
+          "name": "pretty cool plugin-3",
+          "pinned": false,
+          "state": "",
+          "type": "",
+        }
+      }
+    />
+    <PluginListItem
+      key="pretty cool plugin-4-4"
+      plugin={
+        Object {
+          "defaultNavUrl": "some/url",
+          "enabled": false,
+          "hasUpdate": false,
+          "id": "4",
+          "info": Object {
+            "author": Object {
+              "name": "Grafana Labs",
+              "url": "url/to/GrafanaLabs",
+            },
+            "description": "pretty decent plugin",
+            "links": Array [
+              "one link",
+            ],
+            "logos": Object {
+              "large": "large/logo",
+              "small": "small/logo",
+            },
+            "screenshots": "screenshot/4",
+            "updated": "2018-09-26",
+            "version": "1",
+          },
+          "latestVersion": "1.4",
+          "name": "pretty cool plugin-4",
+          "pinned": false,
+          "state": "",
+          "type": "",
+        }
+      }
+    />
+    <PluginListItem
+      key="pretty cool plugin-5-5"
+      plugin={
+        Object {
+          "defaultNavUrl": "some/url",
+          "enabled": false,
+          "hasUpdate": false,
+          "id": "5",
+          "info": Object {
+            "author": Object {
+              "name": "Grafana Labs",
+              "url": "url/to/GrafanaLabs",
+            },
+            "description": "pretty decent plugin",
+            "links": Array [
+              "one link",
+            ],
+            "logos": Object {
+              "large": "large/logo",
+              "small": "small/logo",
+            },
+            "screenshots": "screenshot/5",
+            "updated": "2018-09-26",
+            "version": "1",
+          },
+          "latestVersion": "1.5",
+          "name": "pretty cool plugin-5",
+          "pinned": false,
+          "state": "",
+          "type": "",
+        }
+      }
+    />
+  </ol>
+</section>
+`;

+ 106 - 0
public/app/features/plugins/__snapshots__/PluginListItem.test.tsx.snap

@@ -0,0 +1,106 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Render should render component 1`] = `
+<li
+  className="card-item-wrapper"
+>
+  <a
+    className="card-item"
+    href="plugins/1/edit"
+  >
+    <div
+      className="card-item-header"
+    >
+      <div
+        className="card-item-type"
+      >
+        <i
+          className="icon-gf icon-gf-"
+        />
+      </div>
+    </div>
+    <div
+      className="card-item-body"
+    >
+      <figure
+        className="card-item-figure"
+      >
+        <img
+          src="small/logo"
+        />
+      </figure>
+      <div
+        className="card-item-details"
+      >
+        <div
+          className="card-item-name"
+        >
+          pretty cool plugin 1
+        </div>
+        <div
+          className="card-item-sub-name"
+        >
+          By Grafana Labs
+        </div>
+      </div>
+    </div>
+  </a>
+</li>
+`;
+
+exports[`Render should render has plugin section 1`] = `
+<li
+  className="card-item-wrapper"
+>
+  <a
+    className="card-item"
+    href="plugins/1/edit"
+  >
+    <div
+      className="card-item-header"
+    >
+      <div
+        className="card-item-type"
+      >
+        <i
+          className="icon-gf icon-gf-"
+        />
+      </div>
+      <div
+        className="card-item-notice"
+      >
+        <span
+          bs-tooltip="plugin.latestVersion"
+        >
+          Update available!
+        </span>
+      </div>
+    </div>
+    <div
+      className="card-item-body"
+    >
+      <figure
+        className="card-item-figure"
+      >
+        <img
+          src="small/logo"
+        />
+      </figure>
+      <div
+        className="card-item-details"
+      >
+        <div
+          className="card-item-name"
+        >
+          pretty cool plugin 1
+        </div>
+        <div
+          className="card-item-sub-name"
+        >
+          By Grafana Labs
+        </div>
+      </div>
+    </div>
+  </a>
+</li>
+`;

+ 1 - 4
public/app/features/plugins/__snapshots__/PluginListPage.test.tsx.snap

@@ -8,10 +8,7 @@ exports[`Render should render component 1`] = `
   <div
   <div
     className="page-container page-body"
     className="page-container page-body"
   >
   >
-    <Connect(PluginActionBar)
-      onQueryChange={[Function]}
-      searchQuery=""
-    />
+    <Connect(PluginActionBar) />
     <PluginList
     <PluginList
       layout="grid"
       layout="grid"
       plugins={Array []}
       plugins={Array []}

+ 31 - 0
public/app/features/plugins/state/selectors.test.ts

@@ -0,0 +1,31 @@
+import { getPlugins, getPluginsSearchQuery } from './selectors';
+import { initialState } from './reducers';
+import { getMockPlugins } from '../__mocks__/pluginMocks';
+
+describe('Selectors', () => {
+  const mockState = initialState;
+
+  it('should return search query', () => {
+    mockState.searchQuery = 'test';
+    const query = getPluginsSearchQuery(mockState);
+
+    expect(query).toEqual(mockState.searchQuery);
+  });
+
+  it('should return plugins', () => {
+    mockState.plugins = getMockPlugins(5);
+    mockState.searchQuery = '';
+
+    const plugins = getPlugins(mockState);
+
+    expect(plugins).toEqual(mockState.plugins);
+  });
+
+  it('should filter plugins', () => {
+    mockState.searchQuery = 'plugin-1';
+
+    const plugins = getPlugins(mockState);
+
+    expect(plugins.length).toEqual(1);
+  });
+});

+ 1 - 1
public/app/features/plugins/state/selectors.ts

@@ -2,7 +2,7 @@ export const getPlugins = state => {
   const regex = new RegExp(state.searchQuery, 'i');
   const regex = new RegExp(state.searchQuery, 'i');
 
 
   return state.plugins.filter(item => {
   return state.plugins.filter(item => {
-    return regex.test(item.name);
+    return regex.test(item.name) || regex.test(item.info.author.name) || regex.test(item.info.description);
   });
   });
 };
 };