From c5306847a93e0f62bfdc9ce0c3fc27c53f58a714 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Fri, 10 Jun 2022 16:31:10 -0400 Subject: [PATCH] Decompose big UserPreferences for reuse. Refactor because I want to reuse configuration via bootstrap vue modal in user preferences pattern for selecting object store default preferences. ``` pytest lib/galaxy_test/selenium/test_personal_information.py::DeleteCurrentAccountTestCase ``` --- .../src/components/User/UserDeletion.test.js | 27 ++++ client/src/components/User/UserDeletion.vue | 117 ++++++++++++++++++ .../src/components/User/UserPreferences.vue | 100 +++------------ client/src/components/User/user-styles.scss | 6 + 4 files changed, 165 insertions(+), 85 deletions(-) create mode 100644 client/src/components/User/UserDeletion.test.js create mode 100644 client/src/components/User/UserDeletion.vue create mode 100644 client/src/components/User/user-styles.scss diff --git a/client/src/components/User/UserDeletion.test.js b/client/src/components/User/UserDeletion.test.js new file mode 100644 index 000000000000..909fa4de06f4 --- /dev/null +++ b/client/src/components/User/UserDeletion.test.js @@ -0,0 +1,27 @@ +import { mount } from "@vue/test-utils"; +import { getLocalVue } from "jest/helpers"; +import UserDeletion from "./UserDeletion"; + +const localVue = getLocalVue(true); + +const TEST_USER_ID = "myTestUserId"; +const TEST_EMAIL = `${TEST_USER_ID}@test.com`; +const TEST_ROOT = "/"; + +function mountComponent() { + const wrapper = mount(UserDeletion, { + propsData: { userId: TEST_USER_ID, root: TEST_ROOT, email: TEST_EMAIL }, + localVue, + }); + return wrapper; +} + +import { ROOT_COMPONENT } from "utils/navigation"; + +describe("UserDeletion.vue", () => { + it("contains a localized link", async () => { + const wrapper = mountComponent(); + const el = await wrapper.find(ROOT_COMPONENT.preferences.delete_account.selector); + expect(el.text()).toBeLocalizationOf("Delete Account"); + }); +}); diff --git a/client/src/components/User/UserDeletion.vue b/client/src/components/User/UserDeletion.vue new file mode 100644 index 000000000000..a485e3329b28 --- /dev/null +++ b/client/src/components/User/UserDeletion.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/client/src/components/User/UserPreferences.vue b/client/src/components/User/UserPreferences.vue index 7a6f03e37de8..cbb8f2e20ea0 100644 --- a/client/src/components/User/UserPreferences.vue +++ b/client/src/components/User/UserPreferences.vue @@ -33,41 +33,12 @@ - - -
- Delete Account -
Delete your account on this Galaxy server.
- -

- {{ deleteError }} - - This action cannot be undone. Your account will be permanently deleted, along with the - data contained in it. - -

- - - - - -
-
-
+ +

{{ titleYouAreUsing }} {{ diskUsage }} {{ titleOfDiskSpace }} @@ -91,7 +62,9 @@ import axios from "axios"; import QueryStringParsing from "utils/query-string-parsing"; import { getUserPreferencesModel } from "components/User/UserPreferencesModel"; import ConfigProvider from "components/providers/ConfigProvider"; -import { userLogoutAll, userLogoutClient } from "layout/menu"; +import { userLogoutAll } from "layout/menu"; +import UserDeletion from "./UserDeletion"; + import "@fortawesome/fontawesome-svg-core"; Vue.use(BootstrapVue); @@ -99,6 +72,7 @@ Vue.use(BootstrapVue); export default { components: { ConfigProvider, + UserDeletion, }, props: { userId: { @@ -115,12 +89,9 @@ export default { email: "", diskUsage: "", quotaUsageString: "", - baseUrl: `${getAppRoot()}user`, + root: getAppRoot(), messageVariant: null, message: null, - name: "", - nameState: null, - deleteError: "", submittedNames: [], titleYouAreUsing: _l("You are using"), titleOfDiskSpace: _l("of disk space in this Galaxy instance."), @@ -130,6 +101,9 @@ export default { }; }, computed: { + baseUrl() { + return `${this.root}user`; + }, activeLinks() { const activeLinks = {}; const UserPreferencesModel = getUserPreferencesModel(); @@ -156,9 +130,6 @@ export default { return activeLinks; }, - showDeleteError() { - return this.deleteError !== ""; - }, }, created() { const message = QueryStringParsing.get("message"); @@ -237,50 +208,9 @@ export default { }, }); }, - checkFormValidity() { - const valid = this.$refs.form.checkValidity(); - this.nameState = valid; - return valid; - }, - resetModal() { - this.name = ""; - this.nameState = null; - }, - handleOk(bvModalEvt) { - // Prevent modal from closing - bvModalEvt.preventDefault(); - // Trigger submit handler - this.handleSubmit(); - }, - async handleSubmit() { - if (!this.checkFormValidity()) { - return false; - } - if (this.email === this.name) { - this.nameState = true; - try { - await axios.delete(`${getAppRoot()}api/users/${this.userId}`); - } catch (e) { - if (e.response.status === 403) { - this.deleteError = - "User deletion must be configured on this instance in order to allow user self-deletion. Please contact an administrator for assistance."; - return false; - } - } - userLogoutClient(); - } else { - this.nameState = false; - return false; - } - }, }, }; diff --git a/client/src/components/User/user-styles.scss b/client/src/components/User/user-styles.scss new file mode 100644 index 000000000000..fdd6f29a6055 --- /dev/null +++ b/client/src/components/User/user-styles.scss @@ -0,0 +1,6 @@ +.pref-content { + width: calc(100% - 3rem); +} +.pref-icon { + width: 3rem; +}