diff --git a/src/utils/link/index.test.js b/__tests__/src/utils/link.test.js similarity index 98% rename from src/utils/link/index.test.js rename to __tests__/src/utils/link.test.js index 9234893..e35870e 100644 --- a/src/utils/link/index.test.js +++ b/__tests__/src/utils/link.test.js @@ -1,5 +1,5 @@ +import { getTweetId, isTwitterLink } from '@/utils/link'; import { describe, expect, test } from '@jest/globals'; -import { isTwitterLink, getTweetId } from './index'; describe('isTwitterLink', () => { test('url to user should return true', () => { diff --git a/__tests__/src/utils/newsletter.test.js b/__tests__/src/utils/newsletter.test.js new file mode 100644 index 0000000..cfb31fb --- /dev/null +++ b/__tests__/src/utils/newsletter.test.js @@ -0,0 +1,58 @@ +import { describe, expect, test } from '@jest/globals'; +import { applyInlineStyleToRawHtml } from '@/utils/newsletter'; + +describe('applyInlineStyleToRawHtml', () => { + test('should apply style to h1 tag', () => { + const theme = { + h1: { + color: 'red', + }, + }; + const rawHtml = '
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, voluptatum.
Google'; + const expected = + 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, voluptatum.
Google'; + const result = applyInlineStyleToRawHtml(rawHtml, theme); + expect(result).toBe(expected); + }); + + test('should not apply style on , tags as they might have attributes that will be erased by the function', () => { + const theme = { + h1: { + color: 'red', + }, + img: { + color: 'red', + }, + a: { + color: 'red', + }, + }; + const rawHtml = + 'Google'; + const expected = + 'Google'; + const result = applyInlineStyleToRawHtml(rawHtml, theme); + expect(result).toBe(expected); + }); +}); diff --git a/__tests__/src/utils/string.test.js b/__tests__/src/utils/string.test.js new file mode 100644 index 0000000..583c85f --- /dev/null +++ b/__tests__/src/utils/string.test.js @@ -0,0 +1,42 @@ +import { isStringEmpty, makeHidden } from '@/utils/string'; +import { describe, expect } from '@jest/globals'; + +describe('isStringEmpty', () => { + it('returns true for empty strings', () => { + expect(isStringEmpty('')).toBe(true); + }); + + it('returns true for strings with only spaces', () => { + expect(isStringEmpty(' ')).toBe(true); + }); + + it('returns false for non-empty strings', () => { + expect(isStringEmpty('Hello')).toBe(false); + }); + + it('returns false for strings with spaces', () => { + expect(isStringEmpty(' Hello ')).toBe(false); + }); +}); + +describe('makeHidden', () => { + it('replaces each character with *', () => { + expect(makeHidden('hello')).toBe('*****'); + }); + + it('works with empty string', () => { + expect(makeHidden('')).toBe(''); + }); + + it('replaces each character including spaces', () => { + expect(makeHidden('Hello, world!')).toBe('*************'); + }); + + it('handles Unicode characters', () => { + expect(makeHidden('😊🌟')).toBe('**'); + }); + + it('handles long strings', () => { + expect(makeHidden('a'.repeat(100))).toBe('*'.repeat(100)); + }); +}); diff --git a/__tests__/src/utils/url.test.js b/__tests__/src/utils/url.test.js new file mode 100644 index 0000000..64befa7 --- /dev/null +++ b/__tests__/src/utils/url.test.js @@ -0,0 +1,33 @@ +import { getDomainFromUrl, isPdfUrl } from '@/utils/url'; +import { describe, expect } from '@jest/globals'; + +describe('getDomainFromUrl', () => { + it('should extract domain from a valid URL', () => { + const url = 'https://www.example.com/path/to/resource'; + expect(getDomainFromUrl(url)).toBe('example.com'); + }); + + it('should handle URL with protocol', () => { + const url = 'http://subdomain.example.org'; + expect(getDomainFromUrl(url)).toBe('example.org'); + }); +}); + +describe('isPdfUrl', () => { + it('should return true for valid PDF URLs', () => { + // Test cases where the URL ends with '.pdf' + expect(isPdfUrl('https://example.com/file.pdf')).toBe(true); + expect(isPdfUrl('http://www.test.com/doc.pdf')).toBe(true); + expect(isPdfUrl('ftp://ftp.site.com/report.pdf')).toBe(true); + }); + + it('should return false for invalid PDF URLs', () => { + // Test cases where the URL does not end with '.pdf' + expect(isPdfUrl('https://example.com/document.pdfx')).toBe(false); + expect(isPdfUrl('http://www.test.com/file.PDF')).toBe(false); // Case-sensitive check + expect(isPdfUrl('ftp://ftp.site.com/reportpdf')).toBe(false); + expect(isPdfUrl('https://example.com/pdf')).toBe(false); + expect(isPdfUrl('https://example.com/.pdf')).toBe(false); + expect(isPdfUrl('https://example.com/pdf.')).toBe(false); + }); +}); diff --git a/src/utils/link/index.ts b/src/utils/link.ts similarity index 100% rename from src/utils/link/index.ts rename to src/utils/link.ts diff --git a/src/utils/newsletter/index.ts b/src/utils/newsletter.ts similarity index 98% rename from src/utils/newsletter/index.ts rename to src/utils/newsletter.ts index 71fbfc2..b9bbcc6 100644 --- a/src/utils/newsletter/index.ts +++ b/src/utils/newsletter.ts @@ -1,4 +1,4 @@ -import baseTheme from '../../emails/theme'; +import baseTheme from '@/emails/theme'; type Theme = { [key: string]: { diff --git a/src/utils/newsletter/index.test.js b/src/utils/newsletter/index.test.js deleted file mode 100644 index 3ced95d..0000000 --- a/src/utils/newsletter/index.test.js +++ /dev/null @@ -1,54 +0,0 @@ -import {describe, expect, test} from '@jest/globals'; -import { applyInlineStyleToRawHtml } from './index'; - -describe('applyInlineStyleToRawHtml', () => { - test('should apply style to h1 tag', () => { - const theme = { - h1: { - color: 'red', - }, - }; - const rawHtml = 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, voluptatum.
Google'; - const expected = 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, voluptatum.
Google'; - const result = applyInlineStyleToRawHtml(rawHtml, theme); - expect(result).toBe(expected); - }) - - test('should not apply style on , tags as they might have attributes that will be erased by the function', () => { - const theme = { - h1: { - color: 'red', - }, - img: { - color: 'red', - }, - a: { - color: 'red', - } - }; - const rawHtml = 'Google'; - const expected = 'Google'; - const result = applyInlineStyleToRawHtml(rawHtml, theme); - expect(result).toBe(expected); - }) -}); \ No newline at end of file diff --git a/src/utils/string.ts b/src/utils/string.ts index f86beb0..3ac0424 100644 --- a/src/utils/string.ts +++ b/src/utils/string.ts @@ -12,7 +12,7 @@ export function isStringEmpty(str: string): boolean { * Function that returns a hidden string, i.e. a string with all characters replaced by '*' */ export function makeHidden(str: string): string { - return str.replace(/./g, '*'); + return str.replace(/[\s\S]/gu, '*'); } /** diff --git a/src/utils/url.ts b/src/utils/url.ts index 7ba5d57..276703b 100644 --- a/src/utils/url.ts +++ b/src/utils/url.ts @@ -5,4 +5,13 @@ export const getDomainFromUrl = (url: string) => { return domain; }; -export const isPdfUrl = (url: string) => url.indexOf('.pdf') > -1; +export const isPdfUrl = (url: string): boolean => { + const urlObject = new URL(url); + const pathname = urlObject.pathname; + const hasExtension = pathname.endsWith('.pdf'); + if (!hasExtension) return false; + // Edge case for urls like https://example.com/.pdf should not be considered as pdf + const hasFileName = pathname.split('/').pop() !== '.pdf'; + if (!hasFileName) return false; + return hasExtension && hasFileName; +}; \ No newline at end of file