From a0153daca413e55b9bfd86483624cac82e8b9eaf Mon Sep 17 00:00:00 2001 From: Fayaz Ahmed Date: Tue, 13 Aug 2024 13:02:36 +0530 Subject: [PATCH] refactor: useRouteHelper to useReplaceRoute --- app/javascript/widget/App.vue | 4 +- .../widget/components/ChatFooter.vue | 4 +- .../widget/components/ChatHeader.vue | 4 +- .../widget/components/PreChat/Form.vue | 4 +- ...{useRouterHelper.js => useReplaceRoute.js} | 15 +++-- .../mixins/specs/useRouteReplace.spec.js | 51 ++++++++++++++++ .../mixins/specs/useRouterHelper.spec.js | 59 ------------------- app/javascript/widget/views/Home.vue | 4 +- app/javascript/widget/views/PreChatForm.vue | 4 +- 9 files changed, 70 insertions(+), 79 deletions(-) rename app/javascript/widget/composables/{useRouterHelper.js => useReplaceRoute.js} (69%) create mode 100644 app/javascript/widget/mixins/specs/useRouteReplace.spec.js delete mode 100644 app/javascript/widget/mixins/specs/useRouterHelper.spec.js diff --git a/app/javascript/widget/App.vue b/app/javascript/widget/App.vue index 892046f37..22b7954da 100755 --- a/app/javascript/widget/App.vue +++ b/app/javascript/widget/App.vue @@ -8,7 +8,7 @@ import availabilityMixin from 'widget/mixins/availability'; import { getLocale } from './helpers/urlParamsHelper'; import { isEmptyObject } from 'widget/helpers/utils'; import Spinner from 'shared/components/Spinner.vue'; -import { useRouterHelper } from 'widget/composables/useRouterHelper'; +import { useReplaceRoute } from 'widget/composables/useReplaceRoute'; import { getExtraSpaceToScroll, loadedEventConfig, @@ -29,7 +29,7 @@ export default { }, mixins: [availabilityMixin, configMixin, darkModeMixin], setup() { - const { replaceRoute } = useRouterHelper(); + const replaceRoute = useReplaceRoute(); return { replaceRoute }; }, data() { diff --git a/app/javascript/widget/components/ChatFooter.vue b/app/javascript/widget/components/ChatFooter.vue index 20401dbf8..07774d76e 100755 --- a/app/javascript/widget/components/ChatFooter.vue +++ b/app/javascript/widget/components/ChatFooter.vue @@ -6,7 +6,7 @@ import FooterReplyTo from 'widget/components/FooterReplyTo.vue'; import ChatInputWrap from 'widget/components/ChatInputWrap.vue'; import { BUS_EVENTS } from 'shared/constants/busEvents'; import { sendEmailTranscript } from 'widget/api/conversation'; -import { useRouterHelper } from 'widget/composables/useRouterHelper'; +import { useReplaceRoute } from 'widget/composables/useReplaceRoute'; import { IFrameHelper } from '../helpers/utils'; import { CHATWOOT_ON_START_CONVERSATION } from '../constants/sdkEvents'; @@ -17,7 +17,7 @@ export default { FooterReplyTo, }, setup() { - const { replaceRoute } = useRouterHelper(); + const replaceRoute = useReplaceRoute(); return { replaceRoute }; }, data() { diff --git a/app/javascript/widget/components/ChatHeader.vue b/app/javascript/widget/components/ChatHeader.vue index 1bff57648..69753e9ca 100644 --- a/app/javascript/widget/components/ChatHeader.vue +++ b/app/javascript/widget/components/ChatHeader.vue @@ -3,7 +3,7 @@ import availabilityMixin from 'widget/mixins/availability'; import nextAvailabilityTime from 'widget/mixins/nextAvailabilityTime'; import FluentIcon from 'shared/components/FluentIcon/Index.vue'; import HeaderActions from './HeaderActions.vue'; -import { useRouterHelper } from 'widget/composables/useRouterHelper'; +import { useReplaceRoute } from 'widget/composables/useReplaceRoute'; import darkMixin from 'widget/mixins/darkModeMixin.js'; export default { @@ -36,7 +36,7 @@ export default { }, }, setup() { - const { replaceRoute } = useRouterHelper(); + const replaceRoute = useReplaceRoute(); return { replaceRoute }; }, computed: { diff --git a/app/javascript/widget/components/PreChat/Form.vue b/app/javascript/widget/components/PreChat/Form.vue index 3a0e5e6f4..fafb56de4 100644 --- a/app/javascript/widget/components/PreChat/Form.vue +++ b/app/javascript/widget/components/PreChat/Form.vue @@ -6,7 +6,7 @@ import { getContrastingTextColor } from '@chatwoot/utils'; import { isEmptyObject } from 'widget/helpers/utils'; import { getRegexp } from 'shared/helpers/Validators'; import messageFormatterMixin from 'shared/mixins/messageFormatterMixin'; -import { useRouterHelper } from 'widget/composables/useRouterHelper'; +import { useReplaceRoute } from 'widget/composables/useReplaceRoute'; import darkModeMixin from 'widget/mixins/darkModeMixin'; import configMixin from 'widget/mixins/configMixin'; @@ -23,7 +23,7 @@ export default { }, }, setup() { - const { replaceRoute } = useRouterHelper(); + const replaceRoute = useReplaceRoute(); return { replaceRoute }; }, data() { diff --git a/app/javascript/widget/composables/useRouterHelper.js b/app/javascript/widget/composables/useReplaceRoute.js similarity index 69% rename from app/javascript/widget/composables/useRouterHelper.js rename to app/javascript/widget/composables/useReplaceRoute.js index eaa2d0220..af044b806 100644 --- a/app/javascript/widget/composables/useRouterHelper.js +++ b/app/javascript/widget/composables/useReplaceRoute.js @@ -1,26 +1,25 @@ import { useRouter, useRoute } from 'dashboard/composables/route'; /** - * Composable for handling router-related operations. - * @returns {Object} An object containing methods for router manipulation. + * Composable for replacing the current route with a new one if it's different. + * @returns {Function} A function that replaces the current route. */ -export function useRouterHelper() { +export const useReplaceRoute = () => { const router = useRouter(); const route = useRoute(); + /** * Replaces the current route with a new one if it's different. * @param {string} name - The name of the route to replace with. * @param {Object} params - The params to pass to the new route. * @returns {Promise|undefined} A promise that resolves when the navigation is complete, or undefined if no navigation occurs. */ - const replaceRoute = async (name, params = {}) => { + return (name, params = {}) => { if (route.name !== name) { return router.replace({ name, params }); } return undefined; }; +}; - return { - replaceRoute, - }; -} +export default useReplaceRoute; diff --git a/app/javascript/widget/mixins/specs/useRouteReplace.spec.js b/app/javascript/widget/mixins/specs/useRouteReplace.spec.js new file mode 100644 index 000000000..34c7ca598 --- /dev/null +++ b/app/javascript/widget/mixins/specs/useRouteReplace.spec.js @@ -0,0 +1,51 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { useReplaceRoute } from 'widget/composables/useReplaceRoute'; + +const mockReplace = vi.fn(); +const mockRoute = { name: 'initialRoute' }; + +vi.mock('dashboard/composables/route', () => ({ + useRouter: () => ({ + replace: mockReplace, + }), + useRoute: () => mockRoute, +})); + +describe('useReplaceRoute', () => { + let replaceRoute; + + beforeEach(() => { + vi.clearAllMocks(); + mockRoute.name = 'initialRoute'; + replaceRoute = useReplaceRoute(); + }); + + it('should replace route when current route is different', async () => { + mockReplace.mockResolvedValue(undefined); + + await replaceRoute('newRoute', { id: 1 }); + + expect(mockReplace).toHaveBeenCalledWith({ + name: 'newRoute', + params: { id: 1 }, + }); + }); + + it('should not replace route when current route is the same', async () => { + mockRoute.name = 'sameRoute'; + + const result = await replaceRoute('sameRoute'); + + expect(mockReplace).not.toHaveBeenCalled(); + expect(result).toBeUndefined(); + }); + + it('should handle router replace rejection', async () => { + const error = new Error('Navigation aborted'); + mockReplace.mockRejectedValue(error); + + await expect(replaceRoute('newRoute')).rejects.toThrow( + 'Navigation aborted' + ); + }); +}); diff --git a/app/javascript/widget/mixins/specs/useRouterHelper.spec.js b/app/javascript/widget/mixins/specs/useRouterHelper.spec.js deleted file mode 100644 index 6a2247f72..000000000 --- a/app/javascript/widget/mixins/specs/useRouterHelper.spec.js +++ /dev/null @@ -1,59 +0,0 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { useRouterHelper } from '../../composables/useRouterHelper'; - -const mockRouter = { - currentRoute: { name: 'initialRoute' }, - replace: vi.fn(), -}; - -vi.mock('../../composables/useRouterHelper', () => ({ - useRouterHelper: () => ({ - replaceRoute: async (name, params = {}) => { - if (mockRouter.currentRoute.name !== name) { - return mockRouter.replace({ name, params }); - } - return undefined; - }, - }), -})); - -describe('useRouterHelper', () => { - let routerHelper; - - beforeEach(() => { - vi.resetAllMocks(); - mockRouter.currentRoute = { name: 'initialRoute' }; - routerHelper = useRouterHelper(); - }); - - describe('replaceRoute', () => { - it('should replace route when current route is different', async () => { - mockRouter.replace.mockResolvedValue(undefined); - - await routerHelper.replaceRoute('newRoute', { id: 1 }); - - expect(mockRouter.replace).toHaveBeenCalledWith({ - name: 'newRoute', - params: { id: 1 }, - }); - }); - - it('should not replace route when current route is the same', async () => { - mockRouter.currentRoute.name = 'sameRoute'; - - const result = await routerHelper.replaceRoute('sameRoute'); - - expect(mockRouter.replace).not.toHaveBeenCalled(); - expect(result).toBeUndefined(); - }); - - it('should handle router replace rejection', async () => { - const error = new Error('Navigation aborted'); - mockRouter.replace.mockRejectedValue(error); - - await expect(routerHelper.replaceRoute('newRoute')).rejects.toThrow( - 'Navigation aborted' - ); - }); - }); -}); diff --git a/app/javascript/widget/views/Home.vue b/app/javascript/widget/views/Home.vue index 60e4449cc..f4615270b 100755 --- a/app/javascript/widget/views/Home.vue +++ b/app/javascript/widget/views/Home.vue @@ -5,7 +5,7 @@ import ArticleCardSkeletonLoader from 'widget/components/ArticleCardSkeletonLoad import { mapGetters } from 'vuex'; import darkModeMixin from 'widget/mixins/darkModeMixin'; -import { useRouterHelper } from 'widget/composables/useRouterHelper'; +import { useReplaceRoute } from 'widget/composables/useReplaceRoute'; import configMixin from 'widget/mixins/configMixin'; export default { @@ -17,7 +17,7 @@ export default { }, mixins: [configMixin, darkModeMixin], setup() { - const { replaceRoute } = useRouterHelper(); + const replaceRoute = useReplaceRoute(); return { replaceRoute }; }, computed: { diff --git a/app/javascript/widget/views/PreChatForm.vue b/app/javascript/widget/views/PreChatForm.vue index 43417e8c3..393214b07 100644 --- a/app/javascript/widget/views/PreChatForm.vue +++ b/app/javascript/widget/views/PreChatForm.vue @@ -1,7 +1,7 @@