From d48b3342f73eea3beee51742279595b89eef5ccf Mon Sep 17 00:00:00 2001 From: Luann Moreira Date: Tue, 7 Nov 2023 13:14:26 -0300 Subject: [PATCH] refactor(ui): refactored profile settings to vue 3 composition api This commit is aimed to refactor the profile settings to Vue 3 Composition Api and create unitary tests for it's functions and store methods. --- ui/src/components/Setting/SettingProfile.vue | 399 ++++++++---------- .../components/Setting/SettingProfile.spec.ts | 214 ++++++++++ .../__snapshots__/SettingProfile.spec.ts.snap | 306 ++++++++++++++ 3 files changed, 707 insertions(+), 212 deletions(-) create mode 100644 ui/tests/components/Setting/SettingProfile.spec.ts create mode 100644 ui/tests/components/Setting/__snapshots__/SettingProfile.spec.ts.snap diff --git a/ui/src/components/Setting/SettingProfile.vue b/ui/src/components/Setting/SettingProfile.vue index 6eb11ad6cd1..26e9e647a1a 100644 --- a/ui/src/components/Setting/SettingProfile.vue +++ b/ui/src/components/Setting/SettingProfile.vue @@ -3,7 +3,7 @@ - +

Account

@@ -13,17 +13,18 @@ Change Data
- + Cancel - Save + Save
@@ -64,7 +65,7 @@ - +

Password

@@ -75,17 +76,19 @@ v-if="!editPasswordStatus" color="primary" @click="editPasswordStatus = !editPasswordStatus" + data-test="change-password-btn" > Change Password
- + Cancel Save @@ -141,9 +144,9 @@ - diff --git a/ui/tests/components/Setting/SettingProfile.spec.ts b/ui/tests/components/Setting/SettingProfile.spec.ts new file mode 100644 index 00000000000..3ab20674f05 --- /dev/null +++ b/ui/tests/components/Setting/SettingProfile.spec.ts @@ -0,0 +1,214 @@ +import { createVuetify } from "vuetify"; +import { flushPromises, mount, VueWrapper } from "@vue/test-utils"; +import { beforeEach, afterEach, describe, expect, it, vi } from "vitest"; +import MockAdapter from "axios-mock-adapter"; +import { nextTick } from "vue"; +import SettingProfile from "@/components/Setting/SettingProfile.vue"; +import { namespacesApi, usersApi } from "@/api/http"; +import { store, key } from "@/store"; +import { router } from "@/router"; +import { envVariables } from "@/envVariables"; +import { SnackbarPlugin } from "@/plugins/snackbar"; + +type SettingProfileWrapper = VueWrapper>; + +describe("Settings Namespace", () => { + let wrapper: SettingProfileWrapper; + + const vuetify = createVuetify(); + + let mockNamespace: MockAdapter; + + let mockUser: MockAdapter; + + const members = [ + { + id: "xxxxxxxx", + username: "test", + role: "owner", + }, + ]; + + const namespaceData = { + name: "test", + owner: "test", + tenant_id: "fake-tenant-data", + members, + settings: { + session_record: true, + }, + max_devices: 3, + devices_count: 3, + created_at: "", + }; + + const authData = { + status: "", + token: "", + user: "test", + name: "test", + tenant: "fake-tenant-data", + email: "test@test.com", + id: "xxxxxxxx", + role: "owner", + }; + + const session = true; + + beforeEach(async () => { + vi.useFakeTimers(); + localStorage.setItem("tenant", "fake-tenant-data"); + envVariables.isCloud = true; + + mockNamespace = new MockAdapter(namespacesApi.getAxios()); + mockUser = new MockAdapter(usersApi.getAxios()); + + mockNamespace.onGet("http://localhost:3000/api/namespaces/fake-tenant-data").reply(200, namespaceData); + mockUser.onGet("http://localhost:3000/api/users/security").reply(200, session); + + store.commit("auth/authSuccess", authData); + store.commit("namespaces/setNamespace", namespaceData); + store.commit("security/setSecurity", session); + + wrapper = mount(SettingProfile, { + global: { + plugins: [[store, key], vuetify, router, SnackbarPlugin], + config: { + errorHandler: () => { /* ignore global error handler */ }, + }, + }, + }); + }); + + afterEach(() => { + wrapper.unmount(); + }); + + it("Is a Vue instance", () => { + expect(wrapper.vm).toBeTruthy(); + }); + + it("Renders the component", () => { + expect(wrapper.html()).toMatchSnapshot(); + }); + + it("Data is defined", () => { + expect(wrapper.vm.$data).toBeDefined(); + }); + + it("Renders components", async () => { + expect(wrapper.find('[data-test="account-header"]').exists()); + expect(wrapper.find('[data-test="change-data-btn"]').exists()); + expect(wrapper.find('[data-test="cancel-btn"]').exists()); + expect(wrapper.find('[data-test="update-user-btn"]').exists()); + expect(wrapper.find('[data-test="name-text"]').exists()); + expect(wrapper.find('[data-test="username-text"]').exists()); + expect(wrapper.find('[data-test="email-text"]').exists()); + expect(wrapper.find('[data-test="password-header"]').exists()); + expect(wrapper.find('[data-test="change-password-btn"]').exists()); + expect(wrapper.find('[data-test="cancel-password-btn"]').exists()); + expect(wrapper.find('[data-test="update-password-btn"]').exists()); + expect(wrapper.find('[data-test="password-text"]').exists()); + expect(wrapper.find('[data-test="newPassword-text"]').exists()); + expect(wrapper.find('[data-test="confirmNewPassword-text"]').exists()); + }); + + it("Successfully changes user data", async () => { + const changeUserData = { + email: "test@test.com", + name: "test", + username: "test", + id: "xxxxxxxx", + }; + + await wrapper.findComponent('[data-test="change-data-btn"]').trigger("click"); + + mockUser.onPatch("http://localhost:3000/api/users/xxxxxxxx/data").reply(200); + + const changeDataSpy = vi.spyOn(store, "dispatch"); + await wrapper.findComponent('[data-test="update-user-btn"]').trigger("click"); + + vi.runOnlyPendingTimers(); + + await nextTick(); + await flushPromises(); + expect(changeDataSpy).toHaveBeenCalledWith("users/patchData", changeUserData); + expect(changeDataSpy).toHaveBeenCalledWith("auth/changeUserData", changeUserData); + }); + + it("Successfully changes user password", async () => { + const changePasswordData = { + currentPassword: "test", + newPassword: "test123", + id: "xxxxxxxx", + }; + + await wrapper.findComponent('[data-test="change-password-btn"]').trigger("click"); + + mockUser.onPatch("http://localhost:3000/api/users/xxxxxxxx/password").reply(200); + + const changePasswordSpy = vi.spyOn(store, "dispatch"); + await wrapper.findComponent('[data-test="password-text"]').setValue("test"); + await wrapper.findComponent('[data-test="newPassword-text"]').setValue("test123"); + await wrapper.findComponent('[data-test="confirmNewPassword-text"]').setValue("test123"); + + await wrapper.findComponent('[data-test="update-password-btn"]').trigger("click"); + + vi.runOnlyPendingTimers(); + + await nextTick(); + await flushPromises(); + expect(changePasswordSpy).toHaveBeenCalledWith("users/patchPassword", changePasswordData); + }); + + it("Fails changes user data", async () => { + const changeUserData = { + email: "test@test.com", + name: "test", + username: "test", + id: "xxxxxxxx", + }; + + mockUser.onPatch("http://localhost:3000/api/users/xxxxxxxx/data").reply(401); + + const changeDataSpy = vi.spyOn(store, "dispatch"); + await wrapper.findComponent('[data-test="change-data-btn"]').trigger("click"); + + await wrapper.findComponent('[data-test="update-user-btn"]').trigger("click"); + + vi.runOnlyPendingTimers(); + + await nextTick(); + await flushPromises(); + expect(changeDataSpy).toHaveBeenCalledWith("users/patchData", changeUserData); + await flushPromises(); + expect(changeDataSpy).toHaveBeenCalledWith("snackbar/showSnackbarErrorDefault"); + }); + + it("Fails changes user password", async () => { + const changePasswordData = { + currentPassword: "test", + newPassword: "test123", + id: "xxxxxxxx", + }; + + await wrapper.findComponent('[data-test="change-password-btn"]').trigger("click"); + + mockUser.onPatch("http://localhost:3000/api/users/xxxxxxxx/password").reply(401); + + const changePasswordSpy = vi.spyOn(store, "dispatch"); + await wrapper.findComponent('[data-test="password-text"]').setValue("test"); + await wrapper.findComponent('[data-test="newPassword-text"]').setValue("test123"); + await wrapper.findComponent('[data-test="confirmNewPassword-text"]').setValue("test123"); + + await wrapper.findComponent('[data-test="update-password-btn"]').trigger("click"); + + vi.runOnlyPendingTimers(); + + await nextTick(); + await flushPromises(); + expect(changePasswordSpy).toHaveBeenCalledWith("users/patchPassword", changePasswordData); + await flushPromises(); + expect(changePasswordSpy).toHaveBeenCalledWith("snackbar/showSnackbarErrorDefault"); + }); +}); diff --git a/ui/tests/components/Setting/__snapshots__/SettingProfile.spec.ts.snap b/ui/tests/components/Setting/__snapshots__/SettingProfile.spec.ts.snap new file mode 100644 index 00000000000..da68bb0e1fa --- /dev/null +++ b/ui/tests/components/Setting/__snapshots__/SettingProfile.spec.ts.snap @@ -0,0 +1,306 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Settings Namespace > Renders the component 1`] = ` +"
+
+
+
+
+

Account

+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+
+ +
+ + + +
+ + +
+ +
+
+
+ +
+ + + + +
+
+
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+
+ +
+ + + +
+ + +
+ +
+
+
+ +
+ + + + +
+
+
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+
+ +
+ + + +
+ + +
+ +
+
+
+ +
+ + + + +
+
+
+
+
+
+
+

Password

+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+
+ +
+ + + +
+ + +
+ +
+
+
+
+ +
+
+ + + + +
+
+
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+
+ +
+ + + +
+ + +
+ +
+
+
+
+ +
+
+ + + + +
+
+
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+
+ +
+ + + +
+ + +
+ +
+
+
+
+ +
+
+ + + + +
+
+
+
+
+
" +`;