diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue index f3b306d75910bbf202d111e3df855c810eea081c..38ef2fd4232da02d225d8576b6a77661917d4d6b 100644 --- a/app/assets/javascripts/diffs/components/app.vue +++ b/app/assets/javascripts/diffs/components/app.vue @@ -21,7 +21,7 @@ import { helpPagePath } from '~/helpers/help_page_helper'; import { parseBoolean, handleLocationHash } from '~/lib/utils/common_utils'; import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; import { Mousetrap } from '~/lib/mousetrap'; -import { updateHistory } from '~/lib/utils/url_utility'; +import { updateHistory, getLocationHash } from '~/lib/utils/url_utility'; import { __ } from '~/locale'; import notesEventHub from '~/notes/event_hub'; @@ -379,6 +379,7 @@ export default { queueRedisHllEvents(events, { verifyCap: true }); this.subscribeToVirtualScrollingEvents(); + window.addEventListener('hashchange', this.handleHashChange); }, beforeCreate() { diffsApp.instrument(); @@ -405,6 +406,8 @@ export default { this.unsubscribeFromEvents(); this.removeEventListeners(); + window.removeEventListener('hashchange', this.handleHashChange); + diffsEventHub.$off('scrollToFileHash', this.scrollVirtualScrollerToFileHash); diffsEventHub.$off('scrollToIndex', this.scrollVirtualScrollerToIndex); }, @@ -421,6 +424,7 @@ export default { 'rereadNoteHash', 'startRenderDiffsQueue', 'assignDiscussionsToDiff', + 'setCurrentFileHash', 'setHighlightedRow', 'goToFile', 'setShowTreeList', @@ -490,6 +494,18 @@ export default { } } }, + handleHashChange() { + let hash = getLocationHash(); + + if (this.viewDiffsFileByFile) { + if (!hash) { + hash = this.diffFiles[0].file_hash; + } + + this.setCurrentFileHash(hash); + this.fetchFileByFile(); + } + }, navigateToDiffFileNumber(number) { this.navigateToDiffFileIndex(number - 1); }, diff --git a/spec/frontend/diffs/components/app_spec.js b/spec/frontend/diffs/components/app_spec.js index 22c17f02cb0f9c319b5c575e05a6e5579f16ab2d..69f40e9875d1d26d8e9fb55789bf20e4414cf280 100644 --- a/spec/frontend/diffs/components/app_spec.js +++ b/spec/frontend/diffs/components/app_spec.js @@ -814,6 +814,110 @@ describe('diffs/components/app', () => { }, ); }); + + describe('non-UI navigation', () => { + describe('in single-file review mode', () => { + let currentHash; + let fetchFbf; + + beforeEach(() => { + currentHash = jest.fn(); + fetchFbf = jest.fn(); + window.location.hash = '123'; + + createComponent({ + actions: { + diffs: { + setCurrentFileHash: currentHash, + fetchFileByFile: fetchFbf, + }, + }, + extendStore: ({ state }) => { + state.diffs.treeEntries = { + 123: { + type: 'blob', + fileHash: '123', + filePaths: { old: '1234', new: '123' }, + parentPath: '/', + }, + 312: { + type: 'blob', + fileHash: '312', + filePaths: { old: '3124', new: '312' }, + parentPath: '/', + }, + }; + state.diffs.diffFiles = [{ file_hash: '123' }, { file_hash: '312' }]; + }, + baseConfig: { viewDiffsFileByFile: true }, + }); + }); + + it.each` + hash | updated | alias + ${'312'} | ${'312'} | ${'312'} + ${''} | ${'123'} | ${'(nothing)'} + `( + 'reacts to the hash changing to "$alias" externally (e.g. browser back/forward)', + async ({ hash, updated }) => { + window.location.hash = hash; + window.dispatchEvent(new Event('hashchange')); + + await nextTick(); + + expect(currentHash).toHaveBeenCalledWith(expect.anything(), updated); + expect(fetchFbf).toHaveBeenCalled(); + }, + ); + }); + + describe('in "normal" (multi-file) mode', () => { + let currentHash; + let fetchFbf; + + beforeEach(() => { + currentHash = jest.fn(); + fetchFbf = jest.fn(); + window.location.hash = '123'; + + createComponent({ + actions: { + diffs: { + setCurrentFileHash: currentHash, + fetchFileByFile: fetchFbf, + }, + }, + extendStore: ({ state }) => { + state.diffs.treeEntries = { + 123: { + type: 'blob', + fileHash: '123', + filePaths: { old: '1234', new: '123' }, + parentPath: '/', + }, + 312: { + type: 'blob', + fileHash: '312', + filePaths: { old: '3124', new: '312' }, + parentPath: '/', + }, + }; + state.diffs.diffFiles = [{ file_hash: '123' }, { file_hash: '312' }]; + }, + }); + }); + + it('does not react to the hash changing when in regular (multi-file) mode', async () => { + window.location.hash = '312'; + window.dispatchEvent(new Event('hashchange')); + + await nextTick(); + + expect(currentHash).not.toHaveBeenCalled(); + expect(fetchFbf).not.toHaveBeenCalled(); + }); + }); + }); }); describe('autoscroll', () => {