aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/marketplace
diff options
context:
space:
mode:
authorWouter Admiraal <wouter.admiraal@sonarsource.com>2020-06-15 13:06:06 +0200
committersonartech <sonartech@sonarsource.com>2020-06-19 20:04:42 +0000
commitb66618cf03868a56c3fee751a82c1de13c674e79 (patch)
treeaba2679c2de36bfd306950219db3049634641c4e /server/sonar-web/src/main/js/apps/marketplace
parent8cbfbbe99dab20d6ecf3477d64888e474dbe6428 (diff)
downloadsonarqube-b66618cf03868a56c3fee751a82c1de13c674e79.tar.gz
sonarqube-b66618cf03868a56c3fee751a82c1de13c674e79.zip
SONAR-13386 Don't show 'plugin will get installed' if it's already installed
Diffstat (limited to 'server/sonar-web/src/main/js/apps/marketplace')
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/App.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/PluginsList.tsx25
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginActions.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginAvailable.tsx18
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLog.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLogButton.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLogItem.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginDescription.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginInstalled.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginOrganization.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginStatus.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdateButton.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdateItem.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdates.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/PluginUrls.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/PluginActions-test.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/PluginAvailable-test.tsx64
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/PluginAvailable-test.tsx.snap546
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/utils.ts14
19 files changed, 665 insertions, 55 deletions
diff --git a/server/sonar-web/src/main/js/apps/marketplace/App.tsx b/server/sonar-web/src/main/js/apps/marketplace/App.tsx
index 6f54f90f4c8..be0278ceb20 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/App.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/App.tsx
@@ -25,13 +25,12 @@ import {
getAvailablePlugins,
getInstalledPlugins,
getInstalledPluginsWithUpdates,
- getPluginUpdates,
- Plugin,
- PluginPendingResult
+ getPluginUpdates
} from '../../api/plugins';
import Suggestions from '../../app/components/embed-docs-modal/Suggestions';
import { Location, Router, withRouter } from '../../components/hoc/withRouter';
import { EditionKey } from '../../types/editions';
+import { PendingPluginResult, Plugin } from '../../types/plugins';
import EditionBoxes from './EditionBoxes';
import Footer from './Footer';
import Header from './Header';
@@ -43,7 +42,7 @@ import { filterPlugins, parseQuery, Query, serializeQuery } from './utils';
interface Props {
currentEdition?: EditionKey;
fetchPendingPlugins: () => void;
- pendingPlugins: PluginPendingResult;
+ pendingPlugins: PendingPluginResult;
location: Location;
router: Pick<Router, 'push'>;
standaloneMode?: boolean;
diff --git a/server/sonar-web/src/main/js/apps/marketplace/PluginsList.tsx b/server/sonar-web/src/main/js/apps/marketplace/PluginsList.tsx
index 8d864fcdf59..4c1933ac587 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/PluginsList.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/PluginsList.tsx
@@ -18,17 +18,22 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { Plugin, PluginPending } from '../../api/plugins';
+import {
+ InstalledPlugin,
+ isAvailablePlugin,
+ isInstalledPlugin,
+ PendingPlugin,
+ Plugin
+} from '../../types/plugins';
import PluginAvailable from './components/PluginAvailable';
import PluginInstalled from './components/PluginInstalled';
-import { isPluginAvailable, isPluginInstalled } from './utils';
interface Props {
plugins: Plugin[];
pending: {
- installing: PluginPending[];
- updating: PluginPending[];
- removing: PluginPending[];
+ installing: PendingPlugin[];
+ updating: PendingPlugin[];
+ removing: PendingPlugin[];
};
readOnly: boolean;
refreshPending: () => void;
@@ -49,9 +54,9 @@ export default class PluginsList extends React.PureComponent<Props> {
return undefined;
};
- renderPlugin = (plugin: Plugin) => {
+ renderPlugin = (plugin: Plugin, installedPlugins: InstalledPlugin[]) => {
const status = this.getPluginStatus(plugin);
- if (isPluginInstalled(plugin)) {
+ if (isInstalledPlugin(plugin)) {
return (
<PluginInstalled
plugin={plugin}
@@ -61,9 +66,10 @@ export default class PluginsList extends React.PureComponent<Props> {
/>
);
}
- if (isPluginAvailable(plugin)) {
+ if (isAvailablePlugin(plugin)) {
return (
<PluginAvailable
+ installedPlugins={installedPlugins}
plugin={plugin}
readOnly={this.props.readOnly}
refreshPending={this.props.refreshPending}
@@ -75,13 +81,14 @@ export default class PluginsList extends React.PureComponent<Props> {
};
render() {
+ const installedPlugins = this.props.plugins.filter(isInstalledPlugin);
return (
<div className="boxed-group boxed-group-inner" id="marketplace-plugins">
<ul>
{this.props.plugins.map(plugin => (
<li className="panel panel-vertical" key={plugin.key}>
<table className="marketplace-plugin-table">
- <tbody>{this.renderPlugin(plugin)}</tbody>
+ <tbody>{this.renderPlugin(plugin, installedPlugins)}</tbody>
</table>
</li>
))}
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginActions.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginActions.tsx
index 57b237d965f..06319354ad5 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginActions.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginActions.tsx
@@ -22,8 +22,8 @@ import { Button } from 'sonar-ui-common/components/controls/buttons';
import Checkbox from 'sonar-ui-common/components/controls/Checkbox';
import CheckIcon from 'sonar-ui-common/components/icons/CheckIcon';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { installPlugin, Plugin, uninstallPlugin, updatePlugin } from '../../../api/plugins';
-import { isPluginAvailable, isPluginInstalled } from '../utils';
+import { installPlugin, uninstallPlugin, updatePlugin } from '../../../api/plugins';
+import { isAvailablePlugin, isInstalledPlugin, Plugin } from '../../../types/plugins';
import PluginUpdateButton from './PluginUpdateButton';
interface Props {
@@ -75,7 +75,7 @@ export default class PluginActions extends React.PureComponent<Props, State> {
return (
<div className="js-actions">
- {isPluginAvailable(plugin) && (
+ {isAvailablePlugin(plugin) && (
<div>
<p className="little-spacer-bottom">
{translate('marketplace.available_under_commercial_license')}
@@ -85,13 +85,13 @@ export default class PluginActions extends React.PureComponent<Props, State> {
</a>
</div>
)}
- {isPluginInstalled(plugin) && (
+ {isInstalledPlugin(plugin) && (
<p>
<CheckIcon className="little-spacer-right" />
{translate('marketplace.installed')}
</p>
)}
- {isPluginInstalled(plugin) && plugin.updates && plugin.updates.length > 0 && (
+ {isInstalledPlugin(plugin) && plugin.updates && plugin.updates.length > 0 && (
<div className="spacer-top">
{plugin.updates.map((update, idx) => (
<PluginUpdateButton
@@ -117,7 +117,7 @@ export default class PluginActions extends React.PureComponent<Props, State> {
const { loading } = this.state;
return (
<div className="js-actions">
- {isPluginAvailable(plugin) && plugin.termsAndConditionsUrl && (
+ {isAvailablePlugin(plugin) && plugin.termsAndConditionsUrl && (
<p className="little-spacer-bottom">
<Checkbox
checked={this.state.acceptTerms}
@@ -138,7 +138,7 @@ export default class PluginActions extends React.PureComponent<Props, State> {
</p>
)}
{loading && <i className="spinner spacer-right little-spacer-top little-spacer-bottom" />}
- {isPluginInstalled(plugin) && (
+ {isInstalledPlugin(plugin) && (
<div className="display-inlin-block">
{plugin.updates &&
plugin.updates.map((update, idx) => (
@@ -157,7 +157,7 @@ export default class PluginActions extends React.PureComponent<Props, State> {
</Button>
</div>
)}
- {isPluginAvailable(plugin) && (
+ {isAvailablePlugin(plugin) && (
<Button
className="js-install"
disabled={loading || (plugin.termsAndConditionsUrl != null && !this.state.acceptTerms)}
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginAvailable.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginAvailable.tsx
index 6b166a46eba..985e4212f9e 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginAvailable.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginAvailable.tsx
@@ -19,7 +19,7 @@
*/
import * as React from 'react';
import { translateWithParameters } from 'sonar-ui-common/helpers/l10n';
-import { PluginAvailable as IPluginAvailable } from '../../../api/plugins';
+import { AvailablePlugin, InstalledPlugin } from '../../../types/plugins';
import PluginChangeLogButton from './PluginChangeLogButton';
import PluginDescription from './PluginDescription';
import PluginLicense from './PluginLicense';
@@ -27,14 +27,17 @@ import PluginOrganization from './PluginOrganization';
import PluginStatus from './PluginStatus';
import PluginUrls from './PluginUrls';
-interface Props {
- plugin: IPluginAvailable;
+export interface PluginAvailableProps {
+ installedPlugins: InstalledPlugin[];
+ plugin: AvailablePlugin;
readOnly: boolean;
refreshPending: () => void;
status?: string;
}
-export default function PluginAvailable({ plugin, readOnly, refreshPending, status }: Props) {
+export default function PluginAvailable(props: PluginAvailableProps) {
+ const { installedPlugins, plugin, readOnly, status } = props;
+ const installedPluginKeys = installedPlugins.map(({ key }) => key);
return (
<tr>
<PluginDescription plugin={plugin} />
@@ -52,7 +55,10 @@ export default function PluginAvailable({ plugin, readOnly, refreshPending, stat
<strong>
{translateWithParameters(
'marketplace.installing_this_plugin_will_also_install_x',
- plugin.update.requires.map(requiredPlugin => requiredPlugin.name).join(', ')
+ plugin.update.requires
+ .filter(({ key }) => !installedPluginKeys.includes(key))
+ .map(requiredPlugin => requiredPlugin.name)
+ .join(', ')
)}
</strong>
</p>
@@ -71,7 +77,7 @@ export default function PluginAvailable({ plugin, readOnly, refreshPending, stat
</td>
{!readOnly && (
- <PluginStatus plugin={plugin} refreshPending={refreshPending} status={status} />
+ <PluginStatus plugin={plugin} refreshPending={props.refreshPending} status={status} />
)}
</tr>
);
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLog.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLog.tsx
index 95fff94e48e..9891560e82d 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLog.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLog.tsx
@@ -19,7 +19,7 @@
*/
import * as React from 'react';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { Release, Update } from '../../../api/plugins';
+import { Release, Update } from '../../../types/plugins';
import PluginChangeLogItem from './PluginChangeLogItem';
export interface Props {
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLogButton.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLogButton.tsx
index 5824380100a..402a4665ed4 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLogButton.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLogButton.tsx
@@ -21,7 +21,7 @@ import * as React from 'react';
import { ButtonLink } from 'sonar-ui-common/components/controls/buttons';
import Dropdown from 'sonar-ui-common/components/controls/Dropdown';
import EllipsisIcon from 'sonar-ui-common/components/icons/EllipsisIcon';
-import { Release, Update } from '../../../api/plugins';
+import { Release, Update } from '../../../types/plugins';
import PluginChangeLog from './PluginChangeLog';
interface Props {
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLogItem.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLogItem.tsx
index 7e0da5e02ee..0e45bc31d72 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLogItem.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginChangeLogItem.tsx
@@ -21,7 +21,7 @@ import * as React from 'react';
import Tooltip from 'sonar-ui-common/components/controls/Tooltip';
import DateFormatter from 'sonar-ui-common/components/intl/DateFormatter';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { Release, Update } from '../../../api/plugins';
+import { Release, Update } from '../../../types/plugins';
interface Props {
release: Release;
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginDescription.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginDescription.tsx
index e964a0a0e71..a099350e7a7 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginDescription.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginDescription.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { Plugin } from '../../../api/plugins';
+import { Plugin } from '../../../types/plugins';
interface Props {
plugin: Plugin;
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginInstalled.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginInstalled.tsx
index 7c3070e9804..e3859f7c25b 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginInstalled.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginInstalled.tsx
@@ -19,7 +19,7 @@
*/
import * as React from 'react';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { PluginInstalled as IPluginInstalled } from '../../../api/plugins';
+import { InstalledPlugin } from '../../../types/plugins';
import PluginDescription from './PluginDescription';
import PluginLicense from './PluginLicense';
import PluginOrganization from './PluginOrganization';
@@ -28,7 +28,7 @@ import PluginUpdates from './PluginUpdates';
import PluginUrls from './PluginUrls';
interface Props {
- plugin: IPluginInstalled;
+ plugin: InstalledPlugin;
readOnly: boolean;
refreshPending: () => void;
status?: string;
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginOrganization.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginOrganization.tsx
index 204fbb5c216..b889cbd82bd 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginOrganization.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginOrganization.tsx
@@ -20,7 +20,7 @@
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { Plugin } from '../../../api/plugins';
+import { Plugin } from '../../../types/plugins';
export interface PluginOrganizationProps {
plugin: Plugin;
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginStatus.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginStatus.tsx
index 41b4ddf0ee7..a7a603336d8 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginStatus.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginStatus.tsx
@@ -19,7 +19,7 @@
*/
import * as React from 'react';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { Plugin } from '../../../api/plugins';
+import { Plugin } from '../../../types/plugins';
import PluginActions from './PluginActions';
interface Props {
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdateButton.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdateButton.tsx
index a7d094504b2..e34e3f37bad 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdateButton.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdateButton.tsx
@@ -20,7 +20,7 @@
import * as React from 'react';
import { Button } from 'sonar-ui-common/components/controls/buttons';
import { translateWithParameters } from 'sonar-ui-common/helpers/l10n';
-import { Update } from '../../../api/plugins';
+import { Update } from '../../../types/plugins';
interface Props {
disabled: boolean;
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdateItem.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdateItem.tsx
index a1e1e36cfcb..f6ef8eff74e 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdateItem.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdateItem.tsx
@@ -20,7 +20,7 @@
import * as React from 'react';
import Tooltip from 'sonar-ui-common/components/controls/Tooltip';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { Release, Update } from '../../../api/plugins';
+import { Release, Update } from '../../../types/plugins';
import PluginChangeLogButton from './PluginChangeLogButton';
interface Props {
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdates.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdates.tsx
index ab76582882a..0d6064d7e33 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdates.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginUpdates.tsx
@@ -19,7 +19,7 @@
*/
import * as React from 'react';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { Update } from '../../../api/plugins';
+import { Update } from '../../../types/plugins';
import PluginUpdateItem from './PluginUpdateItem';
interface Props {
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/PluginUrls.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/PluginUrls.tsx
index 6a13802c3f9..f5e20c2fdc7 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/PluginUrls.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/PluginUrls.tsx
@@ -19,7 +19,7 @@
*/
import * as React from 'react';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { Plugin } from '../../../api/plugins';
+import { Plugin } from '../../../types/plugins';
interface Props {
plugin: Plugin;
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/PluginActions-test.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/PluginActions-test.tsx
index b549e44431c..2d2c245a9fa 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/PluginActions-test.tsx
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/PluginActions-test.tsx
@@ -19,10 +19,10 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { PluginAvailable, PluginInstalled } from '../../../../api/plugins';
+import { AvailablePlugin, InstalledPlugin } from '../../../../types/plugins';
import PluginActions from '../PluginActions';
-const installedPlugin: PluginInstalled = {
+const installedPlugin: InstalledPlugin = {
key: 'foo',
name: 'Foo',
filename: 'foo.zip',
@@ -35,7 +35,7 @@ const installedPlugin: PluginInstalled = {
version: '7.7'
};
-const availablePlugin: PluginAvailable = {
+const availablePlugin: AvailablePlugin = {
key: 'foo',
name: 'Foo',
release: { version: '7.7', date: 'date' },
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/PluginAvailable-test.tsx b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/PluginAvailable-test.tsx
new file mode 100644
index 00000000000..360592ea24c
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/PluginAvailable-test.tsx
@@ -0,0 +1,64 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import {
+ mockAvailablePlugin,
+ mockInstalledPlugin,
+ mockPlugin,
+ mockUpdate
+} from '../../../../helpers/mocks/plugins';
+import PluginAvailable, { PluginAvailableProps } from '../PluginAvailable';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot('default');
+ expect(shallowRender({ readOnly: true })).toMatchSnapshot('read only');
+ expect(
+ shallowRender({
+ plugin: mockAvailablePlugin({
+ update: mockUpdate({ requires: [mockPlugin()] })
+ })
+ })
+ ).toMatchSnapshot('has requirements');
+ const installed = mockInstalledPlugin({ key: 'sonar-bar', name: 'Sonar Bar' });
+ expect(
+ shallowRender({
+ installedPlugins: [installed],
+ plugin: mockAvailablePlugin({
+ update: mockUpdate({
+ requires: [mockPlugin(), installed]
+ })
+ })
+ })
+ ).toMatchSnapshot('has requirements, some of them already met');
+});
+
+function shallowRender(props: Partial<PluginAvailableProps> = {}) {
+ return shallow<PluginAvailableProps>(
+ <PluginAvailable
+ installedPlugins={[]}
+ plugin={mockAvailablePlugin()}
+ readOnly={false}
+ refreshPending={jest.fn()}
+ {...props}
+ />
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/PluginAvailable-test.tsx.snap b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/PluginAvailable-test.tsx.snap
new file mode 100644
index 00000000000..9222f0091d3
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/marketplace/components/__tests__/__snapshots__/PluginAvailable-test.tsx.snap
@@ -0,0 +1,546 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly: default 1`] = `
+<tr>
+ <PluginDescription
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [],
+ "status": "available",
+ },
+ }
+ }
+ />
+ <td
+ className="text-top big-spacer-right"
+ >
+ <ul>
+ <li
+ className="display-flex-row little-spacer-bottom"
+ >
+ <div
+ className="pull-left spacer-right"
+ >
+ <span
+ className="badge badge-success"
+ >
+ 8.2
+ </span>
+ </div>
+ <div>
+ <PluginChangeLogButton
+ release={
+ Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ }
+ }
+ update={
+ Object {
+ "requires": Array [],
+ "status": "available",
+ }
+ }
+ />
+ </div>
+ </li>
+ </ul>
+ </td>
+ <td
+ className="text-top width-20"
+ >
+ <ul>
+ <PluginUrls
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [],
+ "status": "available",
+ },
+ }
+ }
+ />
+ <PluginLicense />
+ <PluginOrganization
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [],
+ "status": "available",
+ },
+ }
+ }
+ />
+ </ul>
+ </td>
+ <PluginStatus
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [],
+ "status": "available",
+ },
+ }
+ }
+ refreshPending={[MockFunction]}
+ />
+</tr>
+`;
+
+exports[`should render correctly: has requirements 1`] = `
+<tr>
+ <PluginDescription
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ },
+ ],
+ "status": "available",
+ },
+ }
+ }
+ />
+ <td
+ className="text-top big-spacer-right"
+ >
+ <ul>
+ <li
+ className="display-flex-row little-spacer-bottom"
+ >
+ <div
+ className="pull-left spacer-right"
+ >
+ <span
+ className="badge badge-success"
+ >
+ 8.2
+ </span>
+ </div>
+ <div>
+ <PluginChangeLogButton
+ release={
+ Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ }
+ }
+ update={
+ Object {
+ "requires": Array [
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ },
+ ],
+ "status": "available",
+ }
+ }
+ />
+ <p
+ className="little-spacer-top"
+ >
+ <strong>
+ marketplace.installing_this_plugin_will_also_install_x.Sonar Foo
+ </strong>
+ </p>
+ </div>
+ </li>
+ </ul>
+ </td>
+ <td
+ className="text-top width-20"
+ >
+ <ul>
+ <PluginUrls
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ },
+ ],
+ "status": "available",
+ },
+ }
+ }
+ />
+ <PluginLicense />
+ <PluginOrganization
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ },
+ ],
+ "status": "available",
+ },
+ }
+ }
+ />
+ </ul>
+ </td>
+ <PluginStatus
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ },
+ ],
+ "status": "available",
+ },
+ }
+ }
+ refreshPending={[MockFunction]}
+ />
+</tr>
+`;
+
+exports[`should render correctly: has requirements, some of them already met 1`] = `
+<tr>
+ <PluginDescription
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ },
+ Object {
+ "filename": "sonar-bar-1.0.jar",
+ "hash": "hash",
+ "implementationBuild": "1.0.0.1234",
+ "key": "sonar-bar",
+ "name": "Sonar Bar",
+ "sonarLintSupported": false,
+ "updatedAt": 100,
+ "version": "1.0",
+ },
+ ],
+ "status": "available",
+ },
+ }
+ }
+ />
+ <td
+ className="text-top big-spacer-right"
+ >
+ <ul>
+ <li
+ className="display-flex-row little-spacer-bottom"
+ >
+ <div
+ className="pull-left spacer-right"
+ >
+ <span
+ className="badge badge-success"
+ >
+ 8.2
+ </span>
+ </div>
+ <div>
+ <PluginChangeLogButton
+ release={
+ Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ }
+ }
+ update={
+ Object {
+ "requires": Array [
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ },
+ Object {
+ "filename": "sonar-bar-1.0.jar",
+ "hash": "hash",
+ "implementationBuild": "1.0.0.1234",
+ "key": "sonar-bar",
+ "name": "Sonar Bar",
+ "sonarLintSupported": false,
+ "updatedAt": 100,
+ "version": "1.0",
+ },
+ ],
+ "status": "available",
+ }
+ }
+ />
+ <p
+ className="little-spacer-top"
+ >
+ <strong>
+ marketplace.installing_this_plugin_will_also_install_x.Sonar Foo
+ </strong>
+ </p>
+ </div>
+ </li>
+ </ul>
+ </td>
+ <td
+ className="text-top width-20"
+ >
+ <ul>
+ <PluginUrls
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ },
+ Object {
+ "filename": "sonar-bar-1.0.jar",
+ "hash": "hash",
+ "implementationBuild": "1.0.0.1234",
+ "key": "sonar-bar",
+ "name": "Sonar Bar",
+ "sonarLintSupported": false,
+ "updatedAt": 100,
+ "version": "1.0",
+ },
+ ],
+ "status": "available",
+ },
+ }
+ }
+ />
+ <PluginLicense />
+ <PluginOrganization
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ },
+ Object {
+ "filename": "sonar-bar-1.0.jar",
+ "hash": "hash",
+ "implementationBuild": "1.0.0.1234",
+ "key": "sonar-bar",
+ "name": "Sonar Bar",
+ "sonarLintSupported": false,
+ "updatedAt": 100,
+ "version": "1.0",
+ },
+ ],
+ "status": "available",
+ },
+ }
+ }
+ />
+ </ul>
+ </td>
+ <PluginStatus
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ },
+ Object {
+ "filename": "sonar-bar-1.0.jar",
+ "hash": "hash",
+ "implementationBuild": "1.0.0.1234",
+ "key": "sonar-bar",
+ "name": "Sonar Bar",
+ "sonarLintSupported": false,
+ "updatedAt": 100,
+ "version": "1.0",
+ },
+ ],
+ "status": "available",
+ },
+ }
+ }
+ refreshPending={[MockFunction]}
+ />
+</tr>
+`;
+
+exports[`should render correctly: read only 1`] = `
+<tr>
+ <PluginDescription
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [],
+ "status": "available",
+ },
+ }
+ }
+ />
+ <td
+ className="text-top big-spacer-right"
+ >
+ <ul>
+ <li
+ className="display-flex-row little-spacer-bottom"
+ >
+ <div
+ className="pull-left spacer-right"
+ >
+ <span
+ className="badge badge-success"
+ >
+ 8.2
+ </span>
+ </div>
+ <div>
+ <PluginChangeLogButton
+ release={
+ Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ }
+ }
+ update={
+ Object {
+ "requires": Array [],
+ "status": "available",
+ }
+ }
+ />
+ </div>
+ </li>
+ </ul>
+ </td>
+ <td
+ className="text-top width-20"
+ >
+ <ul>
+ <PluginUrls
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [],
+ "status": "available",
+ },
+ }
+ }
+ />
+ <PluginLicense />
+ <PluginOrganization
+ plugin={
+ Object {
+ "key": "sonar-foo",
+ "name": "Sonar Foo",
+ "release": Object {
+ "date": "2020-01-01",
+ "version": "8.2",
+ },
+ "update": Object {
+ "requires": Array [],
+ "status": "available",
+ },
+ }
+ }
+ />
+ </ul>
+ </td>
+</tr>
+`;
diff --git a/server/sonar-web/src/main/js/apps/marketplace/utils.ts b/server/sonar-web/src/main/js/apps/marketplace/utils.ts
index 4aa1ad8b878..db6ed4743ee 100644
--- a/server/sonar-web/src/main/js/apps/marketplace/utils.ts
+++ b/server/sonar-web/src/main/js/apps/marketplace/utils.ts
@@ -19,7 +19,7 @@
*/
import { memoize } from 'lodash';
import { cleanQuery, parseAsString, serializeString } from 'sonar-ui-common/helpers/query';
-import { Plugin, PluginAvailable, PluginInstalled, PluginPending } from '../../api/plugins';
+import { Plugin } from '../../types/plugins';
export interface Query {
filter: string;
@@ -43,18 +43,6 @@ export function filterPlugins(plugins: Plugin[], search?: string): Plugin[] {
});
}
-export function isPluginAvailable(plugin: Plugin): plugin is PluginAvailable {
- return (plugin as any).release !== undefined;
-}
-
-export function isPluginInstalled(plugin: Plugin): plugin is PluginInstalled {
- return isPluginPending(plugin) && (plugin as any).updatedAt !== undefined;
-}
-
-export function isPluginPending(plugin: Plugin): plugin is PluginPending {
- return (plugin as any).version !== undefined;
-}
-
export const DEFAULT_FILTER = 'all';
export const parseQuery = memoize(
(urlQuery: T.RawQuery): Query => ({