From b8d8d405c2ae5785b8de4ab9aa4c0367204f44d7 Mon Sep 17 00:00:00 2001 From: Thomas Randolph Date: Wed, 8 Mar 2023 01:16:43 -0700 Subject: [PATCH] Add helper to get the file ID from the URL hash --- app/assets/javascripts/diffs/store/utils.js | 29 ++++++++++++++ spec/frontend/diffs/store/utils_spec.js | 44 +++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js index 0519ca3d7151e6..84a2af6c5936d2 100644 --- a/app/assets/javascripts/diffs/store/utils.js +++ b/app/assets/javascripts/diffs/store/utils.js @@ -19,6 +19,8 @@ import { } from '../constants'; import { prepareRawDiffFile } from '../utils/diff_file'; +const SHA1 = /\b([a-f0-9]{40})\b/; + export const isAdded = (line) => ['new', 'new-nonewline'].includes(line.type); export const isRemoved = (line) => ['old', 'old-nonewline'].includes(line.type); export const isUnchanged = (line) => !line.type; @@ -556,3 +558,30 @@ export const allDiscussionWrappersExpanded = (diff) => { return discussionsExpanded; }; + +export function isUrlHashNoteLink(urlHash) { + const id = urlHash.replace(/^#/, ''); + + return id.startsWith('note'); +} + +export function isUrlHashFileHeader(urlHash) { + const id = urlHash.replace(/^#/, ''); + + return id.startsWith('diff-content'); +} + +export function parseUrlHashAsFileHash(urlHash, currentDiffFileId = '') { + const isNoteLink = isUrlHashNoteLink(urlHash); + let id = urlHash.replace(/^#/, ''); + + if (isNoteLink && currentDiffFileId) { + id = currentDiffFileId; + } else if (isUrlHashFileHeader(urlHash)) { + id = id.replace('diff-content-', ''); + } else if (!SHA1.test(id) || isNoteLink) { + id = null; + } + + return id; +} diff --git a/spec/frontend/diffs/store/utils_spec.js b/spec/frontend/diffs/store/utils_spec.js index b5c44b084d8b90..68bbbdbe17637a 100644 --- a/spec/frontend/diffs/store/utils_spec.js +++ b/spec/frontend/diffs/store/utils_spec.js @@ -892,4 +892,48 @@ describe('DiffsStoreUtils', () => { expect(files[6].right).toBeNull(); }); }); + + describe('isUrlHashNoteLink', () => { + it.each` + input | bool + ${'#note_12345'} | ${true} + ${'#12345'} | ${false} + ${'note_12345'} | ${true} + ${'12345'} | ${false} + `('returns $bool for $input', ({ bool, input }) => { + expect(utils.isUrlHashNoteLink(input)).toBe(bool); + }); + }); + + describe('isUrlHashFileHeader', () => { + it.each` + input | bool + ${'#diff-content-12345'} | ${true} + ${'#12345'} | ${false} + ${'diff-content-12345'} | ${true} + ${'12345'} | ${false} + `('returns $bool for $input', ({ bool, input }) => { + expect(utils.isUrlHashFileHeader(input)).toBe(bool); + }); + }); + + describe('parseUrlHashAsFileHash', () => { + it.each` + input | currentDiffId | resultId + ${'#note_12345'} | ${'1A2B3C'} | ${'1A2B3C'} + ${'note_12345'} | ${'1A2B3C'} | ${'1A2B3C'} + ${'#note_12345'} | ${undefined} | ${null} + ${'note_12345'} | ${undefined} | ${null} + ${'#diff-content-12345'} | ${undefined} | ${'12345'} + ${'diff-content-12345'} | ${undefined} | ${'12345'} + ${'#diff-content-12345'} | ${'98765'} | ${'12345'} + ${'diff-content-12345'} | ${'98765'} | ${'12345'} + ${'#e334a2a10f036c00151a04cea7938a5d4213a818'} | ${undefined} | ${'e334a2a10f036c00151a04cea7938a5d4213a818'} + ${'e334a2a10f036c00151a04cea7938a5d4213a818'} | ${undefined} | ${'e334a2a10f036c00151a04cea7938a5d4213a818'} + ${'#Z334a2a10f036c00151a04cea7938a5d4213a818'} | ${undefined} | ${null} + ${'Z334a2a10f036c00151a04cea7938a5d4213a818'} | ${undefined} | ${null} + `('returns $resultId for $input and $currentDiffId', ({ input, currentDiffId, resultId }) => { + expect(utils.parseUrlHashAsFileHash(input, currentDiffId)).toBe(resultId); + }); + }); }); -- GitLab