diff --git a/app/javascript/widget/App.vue b/app/javascript/widget/App.vue index 892046f37..df8c42d5f 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..15f232bcf 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..de10dd50f 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..6ed6cd264 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/specs/useReplaceRoute.spec.js b/app/javascript/widget/composables/specs/useReplaceRoute.spec.js new file mode 100644 index 000000000..8714b9922 --- /dev/null +++ b/app/javascript/widget/composables/specs/useReplaceRoute.spec.js @@ -0,0 +1,51 @@ +import { describe, it, expect, vi } from 'vitest'; +import { useReplaceRoute } from '../useReplaceRoute'; + +vi.mock('dashboard/composables/route', () => ({ + useRouter: vi.fn(), + useRoute: vi.fn(), +})); + +import { useRouter, useRoute } from 'dashboard/composables/route'; + +describe('useReplaceRoute', () => { + const mockReplace = vi.fn(); + const mockRouter = { replace: mockReplace }; + + beforeEach(() => { + vi.clearAllMocks(); + useRouter.mockReturnValue(mockRouter); + }); + + it('should replace route when current route is different', () => { + useRoute.mockReturnValue({ name: 'currentRoute' }); + const replaceRoute = useReplaceRoute(); + + replaceRoute('newRoute', { id: 1 }); + + expect(mockReplace).toHaveBeenCalledWith({ + name: 'newRoute', + params: { id: 1 }, + }); + }); + + it('should not replace route when current route is the same', () => { + useRoute.mockReturnValue({ name: 'sameRoute' }); + const replaceRoute = useReplaceRoute(); + + const result = replaceRoute('sameRoute'); + + expect(mockReplace).not.toHaveBeenCalled(); + expect(result).toBeUndefined(); + }); + + it('should return the result of router.replace when replacing route', () => { + useRoute.mockReturnValue({ name: 'currentRoute' }); + mockReplace.mockReturnValue('replacementResult'); + const replaceRoute = useReplaceRoute(); + + const result = replaceRoute('newRoute'); + + expect(result).toBe('replacementResult'); + }); +}); diff --git a/app/javascript/widget/composables/specs/useRouterHelper.spec.js b/app/javascript/widget/composables/specs/useRouterHelper.spec.js deleted file mode 100644 index d2f20d258..000000000 --- a/app/javascript/widget/composables/specs/useRouterHelper.spec.js +++ /dev/null @@ -1,59 +0,0 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { useRouterHelper } from '../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/composables/useReplaceRoute.js b/app/javascript/widget/composables/useReplaceRoute.js new file mode 100644 index 000000000..367bd69d4 --- /dev/null +++ b/app/javascript/widget/composables/useReplaceRoute.js @@ -0,0 +1,21 @@ +import { useRouter, useRoute } from 'dashboard/composables/route'; + +/** + * Composable for replacing 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 {Function} A function that replaces the route when called. + */ +export const useReplaceRoute = () => { + const router = useRouter(); + const route = useRoute(); + + return (name, params = {}) => { + if (route.name !== name) { + return router.replace({ name, params }); + } + return undefined; + }; +}; + +export default useReplaceRoute; diff --git a/app/javascript/widget/composables/useRouterHelper.js b/app/javascript/widget/composables/useRouterHelper.js deleted file mode 100644 index eaa2d0220..000000000 --- a/app/javascript/widget/composables/useRouterHelper.js +++ /dev/null @@ -1,26 +0,0 @@ -import { useRouter, useRoute } from 'dashboard/composables/route'; - -/** - * Composable for handling router-related operations. - * @returns {Object} An object containing methods for router manipulation. - */ -export function useRouterHelper() { - 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 = {}) => { - if (route.name !== name) { - return router.replace({ name, params }); - } - return undefined; - }; - - return { - replaceRoute, - }; -} diff --git a/app/javascript/widget/views/Home.vue b/app/javascript/widget/views/Home.vue index 60e4449cc..1d17e406c 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..afee565e5 100644 --- a/app/javascript/widget/views/PreChatForm.vue +++ b/app/javascript/widget/views/PreChatForm.vue @@ -1,7 +1,7 @@