diff --git a/server/jest.config.json b/server/jest.config.json index 121f06f93..50aae600e 100644 --- a/server/jest.config.json +++ b/server/jest.config.json @@ -3,7 +3,8 @@ "moduleFileExtensions": [ "js", "json", - "ts" + "ts", + "tsx" ], "rootDir": "./", "testRegex": ".*\\.spec\\.ts$", diff --git a/src/components/Collaborative/Components/Source/EditorAddSources.tsx b/src/components/Collaborative/Components/Source/EditorAddSources.tsx index 33e87b93f..67c8f69dd 100644 --- a/src/components/Collaborative/Components/Source/EditorAddSources.tsx +++ b/src/components/Collaborative/Components/Source/EditorAddSources.tsx @@ -5,7 +5,7 @@ import SourceDialog from "../LinkToolBar/Dialog/SourceDialog"; import { VisualEditorContext } from "../../VisualEditorProvider"; import { useTranslation } from "next-i18next"; import AddIcon from '@mui/icons-material/Add'; -import { URL_PATTERN } from "../../hooks/useFloatingLinkState"; +import { URL_PATTERN } from "../../../../utils/ValidateFloatingLink"; import { HTTP_PROTOCOL_REGEX } from "../LinkToolBar/FloatingLinkToolbar"; import { useCommands } from "@remirror/react"; import { Node } from "@remirror/pm/model"; diff --git a/src/components/Collaborative/hooks/useFloatingLinkState.spec.ts b/src/components/Collaborative/hooks/useFloatingLinkState.spec.ts new file mode 100644 index 000000000..1e56a46fb --- /dev/null +++ b/src/components/Collaborative/hooks/useFloatingLinkState.spec.ts @@ -0,0 +1,30 @@ +import { validateFloatingLink } from "../../../utils/ValidateFloatingLink"; + +describe("URL Validation Tests", () => { + const validUrls = [ + "https://example.com", + "https://example.br", + "https://example.org", + "https://example.net", + "https://example.edu", + "https://example.gov", + "https://example.mil", + "https://example.co", + "https://example.info", + "https://example.io", + "https://example.biz", + "https://example.us", + "https://example.uk", + "ftp://example.com", + "http://example.co", + "https://subdomain.example.org" + ]; + + const mockT = jest.fn().mockReturnValue("URL inválida"); + + validUrls.forEach((url) => { + it(`should accept the URL: ${url}`, () => { + expect(() => validateFloatingLink(url, mockT)).not.toThrow(); + }); + }); +}); diff --git a/src/components/Collaborative/hooks/useFloatingLinkState.tsx b/src/components/Collaborative/hooks/useFloatingLinkState.tsx index 47d37eaf2..6001ee671 100644 --- a/src/components/Collaborative/hooks/useFloatingLinkState.tsx +++ b/src/components/Collaborative/hooks/useFloatingLinkState.tsx @@ -14,16 +14,12 @@ import { useCurrentSelection, useUpdateReason, } from "@remirror/react"; -import { useTranslation } from "next-i18next"; import { VisualEditorContext } from "../VisualEditorProvider"; import useLinkShortcut from "./useLinkShortcut"; import { uniqueId } from "remirror"; - -export const URL_PATTERN = - /^(ftp|http|https):\/\/[^ "]+\.(br|com|org|net|edu|gov|mil|co|info|io|biz|us|uk)(\/|\?|#|$)/; +import { validateFloatingLink } from "../../../utils/ValidateFloatingLink"; function useFloatingLinkState() { - const { t } = useTranslation(); const { editorSources, setEditorSources } = useContext(VisualEditorContext); const [error, setError] = useState(null); @@ -54,13 +50,6 @@ function useFloatingLinkState() { useEffect(() => setHref(url), [url]); - const validateFloatingLink = useCallback(() => { - // TODO: use a library or service that maintains a comprehensive list of valid TLDs - if (!URL_PATTERN.test(href)) { - throw new Error(t("sourceForm:errorMessageValidURL")); - } - }, [href, t]); - const updateFloatingLink = useCallback( (id) => { const range = linkShortcut ?? undefined; diff --git a/src/components/Form/FormField.ts b/src/components/Form/FormField.ts index 650f83d51..979e5f5f1 100644 --- a/src/components/Form/FormField.ts +++ b/src/components/Form/FormField.ts @@ -3,7 +3,7 @@ import { RegisterOptions } from "react-hook-form"; import { EditorParser } from "../../../lib/editor-parser"; import { ReviewTaskMachineContextReviewData } from "../../../server/review-task/dto/create-review-task.dto"; import { Roles } from "../../types/enums"; -import { URL_PATTERN } from "../Collaborative/hooks/useFloatingLinkState"; +import { URL_PATTERN } from "../../utils/ValidateFloatingLink"; export type FormField = { fieldName: string; diff --git a/src/utils/ValidateFloatingLink.ts b/src/utils/ValidateFloatingLink.ts new file mode 100644 index 000000000..cd2925364 --- /dev/null +++ b/src/utils/ValidateFloatingLink.ts @@ -0,0 +1,9 @@ + +export const URL_PATTERN = + /^(ftp|http|https):\/\/[^ "]+\.[a-zA-Z]{2,}(\/|\?|#|$)/; + +export const validateFloatingLink = (href?: string, t?: (key: string) => string) => { + if (!URL_PATTERN.test(href)) { + throw new Error(t("sourceForm:errorMessageValidURL")); + } +};