From bd30579923501d8fa2ecded41b98d8b71339d1a4 Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Mon, 27 Jul 2026 14:17:47 +0200 Subject: [PATCH] refactor(settings): move setttings path normalization utility to a separate file Moved the normalizePagePath utility from the settings page composable to a separate utility file and restructured tests accordingly. --- .../__tests__/useSettingsPage.test.js | 65 +++---------------- .../settings/composables/useSettingsPage.js | 14 +--- .../utils/__tests__/settingsPage.test.js | 63 ++++++++++++++++++ src/features/settings/utils/settingsPage.js | 31 +++++++++ 4 files changed, 106 insertions(+), 67 deletions(-) create mode 100644 src/features/settings/utils/__tests__/settingsPage.test.js create mode 100644 src/features/settings/utils/settingsPage.js diff --git a/src/features/settings/composables/__tests__/useSettingsPage.test.js b/src/features/settings/composables/__tests__/useSettingsPage.test.js index 89fb3f3..f54401d 100644 --- a/src/features/settings/composables/__tests__/useSettingsPage.test.js +++ b/src/features/settings/composables/__tests__/useSettingsPage.test.js @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { normalizePagePath, useSettingsPage } from '../useSettingsPage.js'; +import { useSettingsPage } from '../useSettingsPage.js'; import { describe, expect, test, vi } from 'vitest'; const pushRoute = vi.fn(); @@ -25,60 +25,15 @@ vi.mock('vue-router', () => ({ })); describe('useSettingsPage', () => { - describe('normalizePagePath', () => { - test.for([ - { path: 'a.b.c', expected: ['a', 'b', 'c'] }, - { path: 'a', expected: ['a'] }, - { path: 'a.b', expected: ['a', 'b'] }, - { path: 'a..b', expected: ['a', 'b'] }, - { path: '.a.b', expected: ['a', 'b'] }, - { path: '..a.b', expected: ['a', 'b'] }, - { path: '.a.b.', expected: ['a', 'b'] }, - { path: '..a.b..', expected: ['a', 'b'] }, - { path: 'a.b.', expected: ['a', 'b'] }, - { path: 'a.b..', expected: ['a', 'b'] }, - { path: '.a.b..', expected: ['a', 'b'] }, - { path: '..a.b.', expected: ['a', 'b'] }, - { path: '.a..b', expected: ['a', 'b'] }, - { path: '..a..b', expected: ['a', 'b'] }, - { path: '.a..b.', expected: ['a', 'b'] }, - { path: '..a..b..', expected: ['a', 'b'] }, - { path: 'a..b.', expected: ['a', 'b'] }, - { path: 'a..b..', expected: ['a', 'b'] }, - { path: '.a..b..', expected: ['a', 'b'] }, - { path: '..a..b.', expected: ['a', 'b'] }, - { path: '..a.....b.c..d....', expected: ['a', 'b', 'c', 'd'] }, - { path: 'a.b.c/', expected: ['a', 'b', 'c'] }, - { path: 'a.#b.c', expected: ['a', 'b', 'c'] }, - { path: 'a.#b.c/', expected: ['a', 'b', 'c'] }, - { path: 'a1.#b.c/', expected: ['a1', 'b', 'c'] }, - { path: 'a-1.#b.c/', expected: ['a-1', 'b', 'c'] }, - { path: 'a-1.b@.c', expected: ['a-1', 'b', 'c'] }, - { path: '....@a/#...)!&§[b.#§c..d....', expected: ['a', 'b', 'c', 'd'] }, - { path: '....@a/#...)!&§[b.#§c..dä....', expected: ['a', 'b', 'c', 'd'] }, - { path: '..,...~..@a/#.+..)!&§[b.#§c..dä..)..', expected: ['a', 'b', 'c', 'd'] }, - { path: 'a.@.b', expected: ['a', 'b'] }, - { path: 1, expected: [] }, - { path: false, expected: [] }, - { path: true, expected: [] }, - { path: null, expected: [] }, - { path: undefined, expected: [] } - ])('normalizes path correctly', async ({ path, expected }) => { - expect(normalizePagePath(path)).toStrictEqual(expected); - }); - }); - - describe('useSettingsPage', () => { - describe('goToSettingsPage', () => { - test('pushes correct route', async () => { - const { goToSettingsPage } = useSettingsPage(); - await goToSettingsPage('..a.b...c.d..e......'); - expect(pushRoute).toHaveBeenCalledWith({ - name: 'settings', - params: { - rest: ['a', 'b', 'c', 'd', 'e'] - } - }); + describe('goToSettingsPage', () => { + test('pushes correct route', async () => { + const { goToSettingsPage } = useSettingsPage(); + await goToSettingsPage('..a.b...c.d..e......'); + expect(pushRoute).toHaveBeenCalledWith({ + name: 'settings', + params: { + rest: ['a', 'b', 'c', 'd', 'e'] + } }); }); }); diff --git a/src/features/settings/composables/useSettingsPage.js b/src/features/settings/composables/useSettingsPage.js index 4dbf8e1..eea8ac1 100644 --- a/src/features/settings/composables/useSettingsPage.js +++ b/src/features/settings/composables/useSettingsPage.js @@ -14,19 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { getSettingsPagePathSegments } from '../utils/settingsPage'; import { useRouter } from 'vue-router'; -export const normalizePagePath = function normalizePagePath (path) { - if (typeof path !== 'string') return []; - return path - .replace(/^\.+|\.+$/g, '') - .split('.') - .map( - (segment) => segment.replace(/[^a-zA-Z0-9-]/g, '') - ) - .filter(Boolean); -}; - export const useSettingsPage = function useSettingsPage () { const router = useRouter(); @@ -34,7 +24,7 @@ export const useSettingsPage = function useSettingsPage () { return router.push({ name: 'settings', params: { - rest: normalizePagePath(pagePath) + rest: getSettingsPagePathSegments(pagePath) } }); }; diff --git a/src/features/settings/utils/__tests__/settingsPage.test.js b/src/features/settings/utils/__tests__/settingsPage.test.js new file mode 100644 index 0000000..29ea74d --- /dev/null +++ b/src/features/settings/utils/__tests__/settingsPage.test.js @@ -0,0 +1,63 @@ +/* +Copyright 2026 Seekra + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { getSettingsPagePathSegments } from '../settingsPage.js'; +import { describe, expect, test } from 'vitest'; + +describe('settingsPage', () => { + describe('getSettingsPagePathSegments', () => { + test.for([ + { path: 'a.b.c', expected: ['a', 'b', 'c'] }, + { path: 'a', expected: ['a'] }, + { path: 'a.b', expected: ['a', 'b'] }, + { path: 'a..b', expected: ['a', 'b'] }, + { path: '.a.b', expected: ['a', 'b'] }, + { path: '..a.b', expected: ['a', 'b'] }, + { path: '.a.b.', expected: ['a', 'b'] }, + { path: '..a.b..', expected: ['a', 'b'] }, + { path: 'a.b.', expected: ['a', 'b'] }, + { path: 'a.b..', expected: ['a', 'b'] }, + { path: '.a.b..', expected: ['a', 'b'] }, + { path: '..a.b.', expected: ['a', 'b'] }, + { path: '.a..b', expected: ['a', 'b'] }, + { path: '..a..b', expected: ['a', 'b'] }, + { path: '.a..b.', expected: ['a', 'b'] }, + { path: '..a..b..', expected: ['a', 'b'] }, + { path: 'a..b.', expected: ['a', 'b'] }, + { path: 'a..b..', expected: ['a', 'b'] }, + { path: '.a..b..', expected: ['a', 'b'] }, + { path: '..a..b.', expected: ['a', 'b'] }, + { path: '..a.....b.c..d....', expected: ['a', 'b', 'c', 'd'] }, + { path: 'a.b.c/', expected: ['a', 'b', 'c'] }, + { path: 'a.#b.c', expected: ['a', 'b', 'c'] }, + { path: 'a.#b.c/', expected: ['a', 'b', 'c'] }, + { path: 'a1.#b.c/', expected: ['a1', 'b', 'c'] }, + { path: 'a-1.#b.c/', expected: ['a-1', 'b', 'c'] }, + { path: 'a-1.b@.c', expected: ['a-1', 'b', 'c'] }, + { path: '....@a/#...)!&§[b.#§c..d....', expected: ['a', 'b', 'c', 'd'] }, + { path: '....@a/#...)!&§[b.#§c..dä....', expected: ['a', 'b', 'c', 'd'] }, + { path: '..,...~..@a/#.+..)!&§[b.#§c..dä..)..', expected: ['a', 'b', 'c', 'd'] }, + { path: 'a.@.b', expected: ['a', 'b'] }, + { path: 1, expected: [] }, + { path: false, expected: [] }, + { path: true, expected: [] }, + { path: null, expected: [] }, + { path: undefined, expected: [] } + ])('returns $expected', async ({ path, expected }) => { + expect(getSettingsPagePathSegments(path)).toStrictEqual(expected); + }); + }) +}) \ No newline at end of file diff --git a/src/features/settings/utils/settingsPage.js b/src/features/settings/utils/settingsPage.js new file mode 100644 index 0000000..2f1cb1a --- /dev/null +++ b/src/features/settings/utils/settingsPage.js @@ -0,0 +1,31 @@ +/* +Copyright 2026 Seekra + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** + * Extracts the segments of a settings page path and normalizes each segment. + * @param {string} path - The settings page path. + * @returns {Array} The settings page path segments. + */ +export const getSettingsPagePathSegments = function getSettingsPagePathSegments (path) { + if (typeof path !== 'string') return []; + return path + .replace(/^\.+|\.+$/g, '') + .split('.') + .map( + (segment) => segment.replace(/[^a-zA-Z0-9-]/g, '') + ) + .filter(Boolean); +}; \ No newline at end of file