Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
MM-17023: Plugin Marketplace (#924)
Browse files Browse the repository at this point in the history
* MM-17152 - Added support for plugins marketplace endpoint (#912)

* Added support for plugins marketplace endpoint

* Added markeplace plugin status constanst

* Fixed field used in installed selector

* Updated marketplace route to use base getPluginRoute

* Changed state to use new InstalledVersion property to filter installed plugins

* Added action to handle error when getting plugins for the marketplace

* MM-18139 - Add signature_url to install_from_url api (#917)

* MM-18139 - Add signature_url param when invoking install_from_url api

* Using plugin_download_url, signature_download_url instead

* MM-17550 Added support for search term in get marketplace plugins (#920)

* Added support for plugins marketplace endpoint

* Added markeplace plugin status constanst

* Fixed field used in installed selector

* Updated marketplace route to use base getPluginRoute

* Changed state to use new InstalledVersion property to filter installed plugins

* Added action to handle error when getting plugins for the marketplace

* Added support for search in marketplace plugins api

* PR Feedback and no results case handling

* Moved default value of filter at the time adding params to the url

* MM-18103 - Added telemetry events for plugin marketplace (#922)

* Added marketplace  diagnostics events to whitelist
'

* Added search event to whitelist

* Revert "MM-18139 - Add signature_url param when invoking install… (#921)

This reverts commit 79816fb7db2185d29fc6a2679b0811aed05eb4d1.

* MM-18475 - Converge on snake_case responses from the marketplace (#923)

* PR Feedback

* Removing error handling from redux
  • Loading branch information
lieut-data authored and marianunez committed Sep 17, 2019
1 parent 1fdd692 commit 9800f16
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/action_types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import RoleTypes from './roles';
import SchemeTypes from './schemes';
import GroupTypes from './groups';
import BotTypes from './bots';
import PluginTypes from './plugins';

export {
ErrorTypes,
Expand All @@ -42,4 +43,5 @@ export {
SchemeTypes,
GroupTypes,
BotTypes,
PluginTypes,
};
8 changes: 8 additions & 0 deletions src/action_types/plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import keyMirror from 'utils/key_mirror';

export default keyMirror({
RECEIVED_MARKETPLACE_PLUGINS: null,
});
19 changes: 19 additions & 0 deletions src/actions/plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {Client4} from 'client';
import {bindClientFunc} from './helpers';

import {PluginTypes} from 'action_types';

export function getMarketplacePlugins(filter) {
return bindClientFunc({
clientFunc: Client4.getMarketplacePlugins,
onSuccess: PluginTypes.RECEIVED_MARKETPLACE_PLUGINS,
onFailure: PluginTypes.GET_MARKETPLACE_PLUGINS_FAILURE,
params: [
filter,
],
});
}

40 changes: 40 additions & 0 deletions src/actions/plugins.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import assert from 'assert';
import nock from 'nock';

import * as PluginActions from 'actions/plugins';
import {Client4} from 'client';

import TestHelper from 'test/test_helper';
import configureStore from 'test/test_store';

describe('Actions.Plugins', () => {
let store;
beforeAll(async () => {
await TestHelper.initBasic(Client4);
});

beforeEach(async () => {
store = await configureStore();
});

afterAll(async () => {
await TestHelper.tearDown();
});

it('loadMarketplacePlugins', async () => {
const marketplacePlugins = [TestHelper.fakeMarketplacePlugin(), TestHelper.fakeMarketplacePlugin()];
nock(Client4.getPluginsMarketplaceRoute()).
get('').
query(true).
reply(200, marketplacePlugins);

await store.dispatch(PluginActions.getMarketplacePlugins());

const state = store.getState();
const marketplacePluginsResult = state.entities.plugins.marketplacePlugins;
assert.equal(marketplacePlugins.length, Object.values(marketplacePluginsResult).length);
});
});
16 changes: 16 additions & 0 deletions src/client/client4.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@ export default class Client4 {
return `${this.getPluginsRoute()}/${pluginId}`;
}

getPluginsMarketplaceRoute() {
return `${this.getPluginsRoute()}/marketplace`;
}

getRolesRoute() {
return `${this.getBaseRoute()}/roles`;
}
Expand Down Expand Up @@ -2650,6 +2654,13 @@ export default class Client4 {
);
};

getMarketplacePlugins = async (filter) => {
return this.doFetch(
`${this.getPluginsMarketplaceRoute()}${buildQueryString({filter: filter || ''})}`,
{method: 'get'}
);
}

getPluginStatuses = async () => {
return this.doFetch(
`${this.getPluginsRoute()}/statuses`,
Expand Down Expand Up @@ -2928,6 +2939,11 @@ export default class Client4 {
'api_interactive_messages_button_clicked',
'api_interactive_messages_menu_selected',
'api_interactive_messages_dialog_submitted',
'ui_marketplace_download',
'ui_marketplace_configure',
'ui_marketplace_opened',
'ui_marketplace_closed',
'ui_marketplace_search',
].includes(event)) {
return;
}
Expand Down
2 changes: 2 additions & 0 deletions src/reducers/entities/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import roles from './roles';
import schemes from './schemes';
import groups from './groups';
import bots from './bots';
import plugins from './plugins';

export default combineReducers({
general,
Expand All @@ -43,4 +44,5 @@ export default combineReducers({
schemes,
groups,
bots,
plugins,
});
19 changes: 19 additions & 0 deletions src/reducers/entities/plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {combineReducers} from 'redux';
import {PluginTypes} from 'action_types';

function marketplacePlugins(state = [], action) {
switch (action.type) {
case PluginTypes.RECEIVED_MARKETPLACE_PLUGINS: {
return action.data ? action.data : [];
}
default:
return state;
}
}

export default combineReducers({
marketplacePlugins,
});
15 changes: 15 additions & 0 deletions src/selectors/entities/plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {createSelector} from 'reselect';

export function getMarketplacePlugins(state) {
return state.entities.plugins.marketplacePlugins;
}

export const getMarketplaceInstalledPlugins = createSelector(
getMarketplacePlugins,
(plugins) => {
return Object.values(plugins).filter((p) => p.installed_version !== '');
}
);
16 changes: 16 additions & 0 deletions test/test_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,22 @@ class TestHelper {
};
};

fakeMarketplacePlugin = () => {
return {
homepage_url: 'http:https://myplugin.com',
download_url: 'http:https://github.myplugin.tar.gz',
download_signature_url: 'http:https://github.myplugin.tar.gz.asc',
manifest:
{
id: 'com.mattermost.fake-plugin',
name: 'Fake Plugin',
description: 'This plugin is for Redux testing purposes',
version: '0.1.0',
min_server_version: '5.12.0',
},
};
}

fakeChannel = (teamId) => {
const name = this.generateId();

Expand Down

0 comments on commit 9800f16

Please sign in to comment.