From 43051bad905f9004acbb2c3e46598c6defd1befa Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Thu, 13 Sep 2018 18:10:23 +0800 Subject: [PATCH] Finish button of BS update --- .../assets/src/components/admin/Update.vue | 113 ++++++++++++++++++ resources/assets/src/components/route.js | 5 + resources/assets/src/js/admin/update.js | 110 ----------------- .../tests/components/admin/Update.test.js | 55 +++++++++ resources/lang/en/front-end.yml | 6 +- resources/lang/zh_CN/front-end.yml | 6 +- resources/views/admin/update.blade.php | 8 +- 7 files changed, 188 insertions(+), 115 deletions(-) create mode 100644 resources/assets/src/components/admin/Update.vue delete mode 100644 resources/assets/src/js/admin/update.js create mode 100644 resources/assets/tests/components/admin/Update.test.js diff --git a/resources/assets/src/components/admin/Update.vue b/resources/assets/src/components/admin/Update.vue new file mode 100644 index 00000000..68348eb5 --- /dev/null +++ b/resources/assets/src/components/admin/Update.vue @@ -0,0 +1,113 @@ + + + diff --git a/resources/assets/src/components/route.js b/resources/assets/src/components/route.js index 4636feeb..f288b8c4 100644 --- a/resources/assets/src/components/route.js +++ b/resources/assets/src/components/route.js @@ -44,6 +44,11 @@ export default [ component: () => import('./admin/Market'), el: '.content' }, + { + path: 'admin/update', + component: () => import('./admin/Update'), + el: '#update-button' + }, { path: 'auth/login', component: () => import('./auth/Login'), diff --git a/resources/assets/src/js/admin/update.js b/resources/assets/src/js/admin/update.js deleted file mode 100644 index e24837d0..00000000 --- a/resources/assets/src/js/admin/update.js +++ /dev/null @@ -1,110 +0,0 @@ -'use strict'; - -async function downloadUpdates() { - console.log('Prepare trno download'); - - try { - const preparation = await fetch({ - url: url('admin/update/download?action=prepare-download'), - type: 'GET', - dataType: 'json', - beforeSend: function() { - $('#update-button').html( - ' ' + trans('admin.preparing') - ).prop('disabled', 'disabled'); - } - }); - console.log(preparation); - - const { file_size: fileSize } = preparation; - - $('#file-size').html(fileSize); - - $('#modal-start-download').modal({ - 'backdrop': 'static', - 'keyboard': false - }); - - console.log('Start downloading'); - - // Downloading progress polling - const interval_id = setInterval(progressPolling(fileSize), 300); - - const download = await fetch({ - url: url('admin/update/download?action=start-download'), - type: 'POST', - dataType: 'json' - }); - - clearInterval(interval_id); - - console.log('Downloading finished'); - console.log(download); - - $('.modal-title').html(' ' + trans('admin.extracting')); - $('.modal-body').append(`

${trans('admin.downloadCompleted')}

`); - - console.log('Start extracting'); - - const extract = await fetch({ - url: url('admin/update/download?action=extract'), - type: 'POST', - dataType: 'json' - }); - - console.log('Package extracted and files are covered'); - $('#modal-start-download').modal('toggle'); - - swal({ - type: 'success', - html: extract.msg - }).then(function () { - window.location = url('/'); - }, function () { - window.location = url('/'); - }); - } catch (error) { - showAjaxError(error); - } -} - -function progressPolling(fileSize) { - return async () => { - try { - const { size } = await fetch({ - url: url('admin/update/download?action=get-file-size'), - type: 'GET' - }); - - const progress = (size / fileSize * 100).toFixed(2); - - $('#imported-progress').html(progress); - $('.progress-bar') - .css('width', progress + '%') - .attr('aria-valuenow', progress); - } catch (error) { - // No need to show error if failed to get size - } - }; -} - -async function checkForUpdates() { - try { - const data = await fetch({ url: url('admin/update/check') }); - if (data.available === true) { - const dom = `v${data.latest}`; - - $(`[href="${url('admin/update')}"]`).append(dom); - } - } catch (error) { - // - } -} - -if (process.env.NODE_ENV === 'test') { - module.exports = { - checkForUpdates, - progressPolling, - downloadUpdates, - }; -} diff --git a/resources/assets/tests/components/admin/Update.test.js b/resources/assets/tests/components/admin/Update.test.js new file mode 100644 index 00000000..8c4f5052 --- /dev/null +++ b/resources/assets/tests/components/admin/Update.test.js @@ -0,0 +1,55 @@ +import Vue from 'vue'; +import { mount } from '@vue/test-utils'; +import { flushPromises } from '../../utils'; +import Update from '@/components/admin/Update.vue'; +import '@/js/notify'; + +jest.mock('@/js/notify'); + +afterEach(() => { + window.blessing.extra = { canUpdate: true }; +}); + +test('button should be disabled if update is unavailable', () => { + window.blessing.extra = { canUpdate: false }; + const wrapper = mount(Update); + expect(wrapper.find('.btn').attributes('disabled')).toBe('disabled'); +}); + +test('perform update', async () => { + window.$ = jest.fn(() => ({ + modal() {} + })); + Vue.prototype.$http.post + .mockResolvedValueOnce({ errno: 1 }) + .mockResolvedValue({}); + Vue.prototype.$http.get + .mockResolvedValue({ total: 2048, downloaded: 2048 }); + const wrapper = mount(Update); + const button = wrapper.find('.btn'); + + button.trigger('click'); + await flushPromises(); + expect(window.$).not.toBeCalled(); + expect(Vue.prototype.$http.post).toBeCalledWith( + '/admin/update/download', + { action: 'prepare-download' } + ); + + button.trigger('click'); + jest.runOnlyPendingTimers(); + await flushPromises(); + expect(window.$).toBeCalled(); + expect(Vue.prototype.$http.get).toBeCalledWith( + '/admin/update/download', + { action: 'get-progress' } + ); + expect(Vue.prototype.$http.post).toBeCalledWith( + '/admin/update/download', + { action: 'start-download' } + ); + expect(Vue.prototype.$http.post).toBeCalledWith( + '/admin/update/download', + { action: 'extract' } + ); +}); diff --git a/resources/lang/en/front-end.yml b/resources/lang/en/front-end.yml index c430cb4f..db0022e2 100644 --- a/resources/lang/en/front-end.yml +++ b/resources/lang/en/front-end.yml @@ -291,9 +291,11 @@ admin: may be not compatible with the current version of Blessing Skin, and enabling it may cause unexpected problems. Do you really want to enable the plugin? + updateButton: Update Now + updateSize: "Size of package:" preparing: Preparing - downloadCompleted: Update package download completed. - extracting: Extracting update package.. + downloading: Downloading update package... + updateCompleted: Update completed. change-color: title: Change theme color success: Theme color updated. diff --git a/resources/lang/zh_CN/front-end.yml b/resources/lang/zh_CN/front-end.yml index fd209b74..6d170621 100644 --- a/resources/lang/zh_CN/front-end.yml +++ b/resources/lang/zh_CN/front-end.yml @@ -285,9 +285,11 @@ admin: noDependenciesNotice: >- 此插件没有声明任何依赖关系,这代表它有可能并不兼容此版本的 Blessing Skin,请将此插件升级至可能的最新版本。强行启用可能导致无法预料的后果。你确定要启用此插件吗? + updateButton: 马上升级 + updateSize: 更新包大小: preparing: 正在准备 - downloadCompleted: 更新包下载完成 - extracting: 正在解压更新包 + downloading: 正在下载更新包 + updateCompleted: 更新完成 change-color: title: 更改配色 success: 修改配色成功 diff --git a/resources/views/admin/update.blade.php b/resources/views/admin/update.blade.php index 655cf1e7..be1694a6 100644 --- a/resources/views/admin/update.blade.php +++ b/resources/views/admin/update.blade.php @@ -94,7 +94,7 @@ @endif @@ -132,4 +132,10 @@ + + @endsection