From 2059b32720e05fce371a3c56946862fdf7b5dfc2 Mon Sep 17 00:00:00 2001 From: Harshit-7373 Date: Tue, 11 Mar 2025 01:26:57 +0530 Subject: [PATCH 1/2] Removed code duplication between 2 files. #2805 --- .../Header/resolveUtils.unit.test.jsx | 67 +++++++++++++++++++ client/modules/Preview/EmbedFrame.jsx | 20 ++---- server/utils/previewGeneration.js | 16 ++--- shared_file/resolveUtils.js | 33 +++++++++ 4 files changed, 110 insertions(+), 26 deletions(-) create mode 100644 client/modules/IDE/components/Header/resolveUtils.unit.test.jsx create mode 100644 shared_file/resolveUtils.js diff --git a/client/modules/IDE/components/Header/resolveUtils.unit.test.jsx b/client/modules/IDE/components/Header/resolveUtils.unit.test.jsx new file mode 100644 index 0000000000..69be0d6c4a --- /dev/null +++ b/client/modules/IDE/components/Header/resolveUtils.unit.test.jsx @@ -0,0 +1,67 @@ +// resolveUtils.unit.test.jsx + +import resolvePathsForElementsWithAttribute from '../../../../../shared_file/resolveUtils'; +import { resolvePathToFile } from '../../../../../server/utils/filePath'; + +// Mock the dependencies +jest.mock('../../../../../server/utils/filePath', () => ({ + resolvePathToFile: jest.fn() +})); + +jest.mock('../../../../../server/utils/fileUtils', () => ({ + MEDIA_FILE_REGEX: /\.(png|jpg|jpeg|gif|svg)$/i +})); + +describe('resolvePathsForElementsWithAttribute', () => { + let mockSketchDoc; + let mockFiles; + + beforeEach(() => { + jest.clearAllMocks(); + + // Create a mock DOM environment + mockSketchDoc = document.implementation.createHTMLDocument(); + mockFiles = { + 'image.png': { url: 'https://example.com/image.png' }, + 'missing.jpg': { url: null } + }; + + resolvePathToFile.mockImplementation((fileName, files) => files[fileName]); + }); + + it('should update the attribute when the file is resolved successfully', () => { + const element = mockSketchDoc.createElement('img'); + element.setAttribute('src', 'image.png'); + mockSketchDoc.body.appendChild(element); + + resolvePathsForElementsWithAttribute('src', mockSketchDoc, mockFiles); + + expect(element.getAttribute('src')).toBe('https://example.com/image.png'); + }); + + it('should not update the attribute when the file resolution fails', () => { + const element = mockSketchDoc.createElement('img'); + element.setAttribute('src', 'missing.jpg'); + mockSketchDoc.body.appendChild(element); + + resolvePathsForElementsWithAttribute('src', mockSketchDoc, mockFiles); + + expect(element.getAttribute('src')).toBe('missing.jpg'); + }); + + it('should not update the attribute when the value does not match MEDIA_FILE_REGEX', () => { + const element = mockSketchDoc.createElement('img'); + element.setAttribute('src', 'document.pdf'); + mockSketchDoc.body.appendChild(element); + + resolvePathsForElementsWithAttribute('src', mockSketchDoc, mockFiles); + + expect(element.getAttribute('src')).toBe('document.pdf'); + }); + + it('should do nothing when no elements with the specified attribute are found', () => { + resolvePathsForElementsWithAttribute('src', mockSketchDoc, mockFiles); + + expect(mockSketchDoc.querySelectorAll('[src]').length).toBe(0); + }); +}); diff --git a/client/modules/Preview/EmbedFrame.jsx b/client/modules/Preview/EmbedFrame.jsx index 4b2ad60d9b..5f87a5f89c 100644 --- a/client/modules/Preview/EmbedFrame.jsx +++ b/client/modules/Preview/EmbedFrame.jsx @@ -8,7 +8,6 @@ import decomment from 'decomment'; import { resolvePathToFile } from '../../../server/utils/filePath'; import getConfig from '../../utils/getConfig'; import { - MEDIA_FILE_REGEX, MEDIA_FILE_QUOTED_REGEX, STRING_REGEX, PLAINTEXT_FILE_REGEX, @@ -18,6 +17,7 @@ import { import { getAllScriptOffsets } from '../../utils/consoleUtils'; import { registerFrame } from '../../utils/dispatcher'; import { createBlobUrl } from './filesReducer'; +import resolvePathsForElementsWithAttribute from '../../../shared_file/resolveUtils'; let objectUrls = {}; let objectPaths = {}; @@ -34,19 +34,6 @@ const Frame = styled.iframe` `} `; -function resolvePathsForElementsWithAttribute(attr, sketchDoc, files) { - const elements = sketchDoc.querySelectorAll(`[${attr}]`); - const elementsArray = Array.prototype.slice.call(elements); - elementsArray.forEach((element) => { - if (element.getAttribute(attr).match(MEDIA_FILE_REGEX)) { - const resolvedFile = resolvePathToFile(element.getAttribute(attr), files); - if (resolvedFile && resolvedFile.url) { - element.setAttribute(attr, resolvedFile.url); - } - } - }); -} - function resolveCSSLinksInString(content, files) { let newContent = content; let cssFileStrings = content.match(STRING_REGEX); @@ -218,7 +205,12 @@ function injectLocalFiles(files, htmlFile, options) { base.href = `${window.origin}${basePath}${basePath.length > 1 && '/'}`; sketchDoc.head.appendChild(base); + // Resolve paths for elements with the 'src' attribute + // This updates the 'src' attribute of elements (e.g., ,