diff --git a/resources/assets/src/js/__tests__/admin.test.js b/resources/assets/src/js/__tests__/admin.test.js
index 84f6a5eb..7a5cb7c1 100644
--- a/resources/assets/src/js/__tests__/admin.test.js
+++ b/resources/assets/src/js/__tests__/admin.test.js
@@ -566,6 +566,124 @@ describe('tests for "plugins" module', () => {
});
});
+describe('tests for "market" module', () => {
+ const modulePath = '../admin/market';
+
+ // TODO: test initializing market table
+
+ it('install a plugin', async () => {
+ const fetch = jest.fn()
+ .mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }))
+ .mockReturnValueOnce(Promise.resolve({ errno: 1, msg: 'failed' }))
+ .mockReturnValueOnce(Promise.reject());
+ const url = jest.fn(path => path);
+ const swal = jest.fn();
+ const toastr = {
+ success: jest.fn(),
+ warning: jest.fn()
+ };
+ const trans = jest.fn(key => key);
+ const reloadTable = jest.fn();
+ const showAjaxError = jest.fn();
+ window.trans = trans;
+ window.fetch = fetch;
+ window.url = url;
+ window.swal = swal;
+ window.toastr = toastr;
+ window.showAjaxError = showAjaxError;
+ $.marketTable = {
+ ajax: {
+ reload: reloadTable
+ }
+ };
+ document.body.innerHTML = `
+
+ `;
+
+ const installPlugin = require(modulePath).installPlugin;
+
+ await installPlugin('foo-bar');
+ expect(fetch).toBeCalledWith({
+ type: 'POST',
+ url: 'admin/plugins/market/download',
+ dataType: 'json',
+ data: { name: 'foo-bar' },
+ beforeSend: expect.any(Function)
+ });
+ expect(swal).not.toBeCalledWith({ type: 'warning' });
+ expect(toastr.success).toBeCalledWith('success');
+ expect(reloadTable).toBeCalledWith(null, false);
+
+ await installPlugin('foo-bar');
+ expect(swal).toBeCalledWith({ type: 'warning', html: 'failed' });
+
+ await installPlugin('foo-bar');
+ expect(showAjaxError).toBeCalled();
+ });
+
+ it('update a plugin', async () => {
+ const fetch = jest.fn()
+ .mockReturnValueOnce(Promise.resolve({ errno: 0, msg: 'success' }));
+ const getPluginRowData = jest.fn()
+ .mockReturnValueOnce({ installed: false })
+ .mockReturnValue({
+ title: 'Foo Bar',
+ version: '5.1.4',
+ installed: '1.1.4'
+ });
+ const url = jest.fn(path => path);
+ const swal = jest.fn()
+ .mockReturnValueOnce(Promise.resolve())
+ .mockReturnValueOnce(Promise.reject())
+ .mockReturnValueOnce(Promise.resolve());
+ const toastr = {
+ success: jest.fn(),
+ warning: jest.fn()
+ };
+ const trans = jest.fn(key => key);
+ const reloadTable = jest.fn();
+ const showAjaxError = jest.fn();
+ window.trans = trans;
+ window.fetch = fetch;
+ window.url = url;
+ window.swal = swal;
+ window.toastr = toastr;
+ window.showAjaxError = showAjaxError;
+ $.marketTable = {
+ ajax: {
+ reload: reloadTable
+ },
+ row: () => ({
+ data: getPluginRowData
+ })
+ };
+ document.body.innerHTML = `
+
+ `;
+
+ const updatePlugin = require(modulePath).updatePlugin;
+
+ await updatePlugin('foo-bar');
+ expect(swal).toBeCalledWith({ type: 'warning', html: 'not installed' });
+ expect(fetch).not.toBeCalled();
+
+ await updatePlugin('foo-bar');
+ expect(swal).toBeCalledWith({ type: 'warning', text: 'admin.confirmUpdate', showCancelButton: true });
+ expect(fetch).not.toBeCalled();
+
+ await updatePlugin('foo-bar');
+ expect(fetch).toBeCalledWith({
+ type: 'POST',
+ url: 'admin/plugins/market/download',
+ dataType: 'json',
+ data: { name: 'foo-bar' },
+ beforeSend: expect.any(Function)
+ });
+ expect(toastr.success).toBeCalledWith('success');
+ expect(reloadTable).toBeCalledWith(null, false);
+ });
+});
+
describe('tests for "update" module', () => {
const modulePath = '../admin/update';
diff --git a/resources/assets/src/js/admin/market.js b/resources/assets/src/js/admin/market.js
index 1b1c6f49..ed157f91 100644
--- a/resources/assets/src/js/admin/market.js
+++ b/resources/assets/src/js/admin/market.js
@@ -130,14 +130,18 @@ async function updatePlugin(name) {
const data = $.marketTable.row(`#plugin-${name}`).data();
if (data.installed === false) {
- swal({ type: 'warning', html: 'not installed' });
+ return swal({ type: 'warning', html: 'not installed' });
}
- await swal({
- text: trans('admin.confirmUpdate', { plugin: data.title, old: data.installed, new: data.version }),
- type: 'warning',
- showCancelButton: true
- });
+ try {
+ await swal({
+ text: trans('admin.confirmUpdate', { plugin: data.title, old: data.installed, new: data.version }),
+ type: 'warning',
+ showCancelButton: true
+ });
+ } catch (error) {
+ return;
+ }
installPlugin(name, {
beforeSend: () => {
diff --git a/tests/MarketControllerTest.php b/tests/MarketControllerTest.php
new file mode 100644
index 00000000..471f9d5f
--- /dev/null
+++ b/tests/MarketControllerTest.php
@@ -0,0 +1,59 @@
+actAs('admin');
+ }
+
+ public function testShowMarket()
+ {
+ $this->visit('/admin/plugins/market')
+ ->see(trans('general.plugin-market'));
+ }
+
+ public function testDownload()
+ {
+ // Try to download a non-existent plugin
+ $this->post('/admin/plugins/market/download', [
+ 'name' => 'non-existent-plugin'
+ ])->seeJson([
+ 'errno' => 1,
+ 'msg' => trans('admin.plugins.market.non-existent', ['plugin' => 'non-existent-plugin'])
+ ]);
+
+ // Download and extract plugin
+ $this->post('/admin/plugins/market/download', [
+ 'name' => 'hello-dolly'
+ ])->seeJson([
+ 'errno' => 0,
+ 'msg' => trans('admin.plugins.market.install-success')
+ ]);
+ $this->assertTrue(is_dir(base_path('plugins/hello-dolly')));
+ $this->assertFileNotExists(base_path('plugins/hello-dolly_v1.0.0.zip'));
+ }
+
+ public function testGetMarketData()
+ {
+ $this->post('/admin/plugins/market-data')
+ ->seeJsonStructure([
+ 'data' => [[
+ 'name',
+ 'title',
+ 'version',
+ 'installed',
+ 'description',
+ 'author',
+ 'dist',
+ 'enabled',
+ 'dependencies'
+ ]]
+ ]);
+
+ // Get plugins info without an valid certificate
+ config(['secure.certificates' => '']);
+ $this->setExpectedException('Error')->post('/admin/plugins/market-data');
+ }
+}