From 7aab8526b20f01ddb491aaa350da43a3fe78074b Mon Sep 17 00:00:00 2001 From: Shane Maglangit Date: Thu, 11 Sep 2025 15:45:42 +0800 Subject: [PATCH] Remove discussions locked banner on archived groups/projects Changelog: removed --- .../diffs/components/diff_comment_cell.vue | 10 ++- .../components/diff_discussion_reply.vue | 17 ++-- .../javascripts/lib/utils/common_utils.js | 24 +++--- .../notes/components/comment_form.vue | 5 +- .../components/discussion_locked_widget.vue | 14 +--- .../notes/mixins/issuable_state.js | 6 -- .../components/wiki_comment_form.vue | 3 - .../components/wiki_discussion_locked.vue | 35 -------- .../components/notes/work_item_add_note.vue | 11 ++- .../notes/work_item_comment_locked.vue | 28 ++----- locale/gitlab.pot | 9 -- .../components/diff_comment_cell_spec.js | 43 ++++++++-- .../components/diff_discussion_reply_spec.js | 84 +++++++++++-------- .../notes/components/comment_form_spec.js | 26 ++++++ .../discussion_locked_widget_spec.js | 34 ++++++++ .../components/wiki_comment_form_spec.js | 60 ++++++------- .../components/wiki_discussion_locked_spec.js | 73 ---------------- .../notes/work_item_add_note_spec.js | 19 ++++- .../notes/work_item_comment_locked_spec.js | 69 +++++---------- spec/frontend/work_items/mock_data.js | 3 +- 20 files changed, 257 insertions(+), 316 deletions(-) delete mode 100644 app/assets/javascripts/wikis/wiki_notes/components/wiki_discussion_locked.vue create mode 100644 spec/frontend/notes/components/discussion_locked_widget_spec.js delete mode 100644 spec/frontend/wikis/notes/components/wiki_discussion_locked_spec.js diff --git a/app/assets/javascripts/diffs/components/diff_comment_cell.vue b/app/assets/javascripts/diffs/components/diff_comment_cell.vue index 2c91154e5fef39..b94f8fdd105b7a 100644 --- a/app/assets/javascripts/diffs/components/diff_comment_cell.vue +++ b/app/assets/javascripts/diffs/components/diff_comment_cell.vue @@ -1,12 +1,14 @@ - - diff --git a/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue b/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue index 14d3533b479702..1fecf728c1f143 100644 --- a/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue +++ b/app/assets/javascripts/work_items/components/notes/work_item_add_note.vue @@ -229,6 +229,9 @@ export default { hasEmailParticipantsWidget() { return Boolean(findEmailParticipantsWidget(this.workItem)); }, + showLockedBanner() { + return !this.isLoading && !this.canCreateNote && !this.isProjectArchived; + }, }, watch: { autofocus: { @@ -361,12 +364,8 @@ export default { diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 3abc023074081f..c3e11d9a39ef0b 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -64932,9 +64932,6 @@ msgstr "" msgid "The discussion in this %{noteableTypeText} is locked." msgstr "" -msgid "The discussion in this Wiki is locked. Only project members can comment." -msgstr "" - msgid "The discussion in this merge request is locked." msgstr "" @@ -66066,9 +66063,6 @@ msgstr "" msgid "This group has no inactive access tokens." msgstr "" -msgid "This group is archived and cannot be commented on." -msgstr "" - msgid "This group is archived. Its subgroups, projects, and data are %{strong_open}read-only%{strong_close}." msgstr "" @@ -66401,9 +66395,6 @@ msgstr "" msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources." msgstr "" -msgid "This project is archived and cannot be commented on." -msgstr "" - msgid "This project is archived and read-only. To resume pull mirroring, unarchive the project." msgstr "" diff --git a/spec/frontend/diffs/components/diff_comment_cell_spec.js b/spec/frontend/diffs/components/diff_comment_cell_spec.js index 1dec70cbc2fa77..bb1c088f6d5e71 100644 --- a/spec/frontend/diffs/components/diff_comment_cell_spec.js +++ b/spec/frontend/diffs/components/diff_comment_cell_spec.js @@ -5,6 +5,7 @@ import { createTestingPinia } from '@pinia/testing'; import DiffCommentCell from '~/diffs/components/diff_comment_cell.vue'; import DiffDiscussionReply from '~/diffs/components/diff_discussion_reply.vue'; import DiffDiscussions from '~/diffs/components/diff_discussions.vue'; +import NoteSignedOutWidget from '~/notes/components/note_signed_out_widget.vue'; Vue.use(PiniaVuePlugin); @@ -41,15 +42,45 @@ describe('DiffCommentCell', () => { expect(wrapper.findComponent(DiffDiscussions).exists()).toBe(false); }); - it('renders discussion reply if line has no draft', () => { - const wrapper = createWrapper(); + describe('when not logged in', () => { + beforeEach(() => { + window.gon.current_user_id = null; + }); + + it('renders signed out widget', () => { + const wrapper = createWrapper(); + + expect(wrapper.findComponent(NoteSignedOutWidget).exists()).toBe(true); + }); + + it('does not render discussion reply', () => { + const wrapper = createWrapper(); - expect(wrapper.findComponent(DiffDiscussionReply).exists()).toBe(true); + expect(wrapper.findComponent(DiffDiscussionReply).exists()).toBe(false); + }); }); - it('does not render discussion reply if line has draft', () => { - const wrapper = createWrapper({ hasDraft: true }); + describe('when logged in', () => { + beforeEach(() => { + window.gon.current_user_id = 1; + }); + + it('does not render signed out widget', () => { + const wrapper = createWrapper(); + + expect(wrapper.findComponent(NoteSignedOutWidget).exists()).toBe(false); + }); + + it('renders discussion reply if line has no draft', () => { + const wrapper = createWrapper(); - expect(wrapper.findComponent(DiffDiscussionReply).exists()).toBe(false); + expect(wrapper.findComponent(DiffDiscussionReply).exists()).toBe(true); + }); + + it('does not render discussion reply if line has draft', () => { + const wrapper = createWrapper({ hasDraft: true }); + + expect(wrapper.findComponent(DiffDiscussionReply).exists()).toBe(false); + }); }); }); diff --git a/spec/frontend/diffs/components/diff_discussion_reply_spec.js b/spec/frontend/diffs/components/diff_discussion_reply_spec.js index 2739cbcd9f1326..3063fe80d66896 100644 --- a/spec/frontend/diffs/components/diff_discussion_reply_spec.js +++ b/spec/frontend/diffs/components/diff_discussion_reply_spec.js @@ -4,7 +4,6 @@ import Vue from 'vue'; import { PiniaVuePlugin } from 'pinia'; import { createTestingPinia } from '@pinia/testing'; import DiffDiscussionReply from '~/diffs/components/diff_discussion_reply.vue'; -import NoteSignedOutWidget from '~/notes/components/note_signed_out_widget.vue'; import DiscussionLockedWidget from '~/notes/components/discussion_locked_widget.vue'; import { START_THREAD } from '~/diffs/i18n'; import { useNotes } from '~/notes/store/legacy_notes'; @@ -33,17 +32,57 @@ describe('DiffDiscussionReply', () => { pinia = createTestingPinia({ plugins: [globalAccessorPlugin] }); useLegacyDiffs(); useNotes(); + + useNotes().noteableData.current_user = { can_create_note: true }; + useNotes().userData = { + path: 'test-path', + avatar_url: 'avatar_url', + name: 'John Doe', + id: 1, + }; }); - describe('if user is signed in', () => { + describe('when discussion is locked', () => { beforeEach(() => { - useNotes().noteableData.current_user = { can_create_note: true }; - useNotes().userData = { - path: 'test-path', - avatar_url: 'avatar_url', - name: 'John Doe', - id: 1, - }; + useNotes().noteableData.discussion_locked = true; + + createComponent( + { + renderReplyPlaceholder: false, + hasForm: true, + }, + { + form: `
`, + }, + ); + }); + + it('shows discussion locked widget', () => { + expect(wrapper.findComponent(DiscussionLockedWidget).exists()).toBe(true); + }); + + it('does not render form', () => { + expect(wrapper.find('#test-form').exists()).toBe(false); + }); + }); + + describe('when discussion is not locked', () => { + beforeEach(() => { + useNotes().noteableData.discussion_locked = false; + + createComponent( + { + renderReplyPlaceholder: false, + hasForm: true, + }, + { + form: `
`, + }, + ); + }); + + it('does not render discussion locked widget', () => { + expect(wrapper.findComponent(DiscussionLockedWidget).exists()).toBe(false); }); it('should render a form if component has form', () => { @@ -90,32 +129,5 @@ describe('DiffDiscussionReply', () => { expect(wrapper.findComponent(GlButton).exists()).toBe(showButton); }, ); - - it('shows the locked discussion widget when the user is not allowed to create notes', () => { - useNotes().noteableData.current_user = { can_create_note: false }; - - createComponent({ - renderReplyPlaceholder: false, - hasForm: false, - }); - - expect(wrapper.findComponent(DiscussionLockedWidget).exists()).toBe(true); - }); - }); - - describe('if user is signed out', () => { - beforeEach(() => { - useNotes().noteableData.current_user = { can_create_note: false }; - useNotes().userData = null; - }); - - it('renders a signed out widget when user is not logged in', () => { - createComponent({ - renderReplyPlaceholder: false, - hasForm: false, - }); - - expect(wrapper.findComponent(NoteSignedOutWidget).exists()).toBe(true); - }); }); }); diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js index f4a35dff2c69d0..796b6b00e62516 100644 --- a/spec/frontend/notes/components/comment_form_spec.js +++ b/spec/frontend/notes/components/comment_form_spec.js @@ -28,6 +28,7 @@ import { globalAccessorPlugin } from '~/pinia/plugins'; import { useLegacyDiffs } from '~/diffs/stores/legacy_diffs'; import { useNotes } from '~/notes/store/legacy_notes'; import { useBatchComments } from '~/batch_comments/store'; +import DiscussionLockedWidget from '~/notes/components/discussion_locked_widget.vue'; import { loggedOutnoteableData, notesDataMock, userDataMock, noteableDataMock } from '../mock_data'; jest.mock('autosize'); @@ -60,6 +61,7 @@ describe('issue_comment_form component', () => { const findCommentTypeDropdown = () => wrapper.findByTestId('comment-button'); const findCommentButton = () => findCommentTypeDropdown().find('button'); const findErrorAlerts = () => wrapper.findAllComponents(GlAlert).wrappers; + const findDiscussionLockedWidget = () => wrapper.findComponent(DiscussionLockedWidget); const createNotableDataMock = (data = {}) => { return { @@ -811,6 +813,30 @@ describe('issue_comment_form component', () => { }); }); + describe('note is locked', () => { + beforeEach(() => { + mountComponent({ + noteableData: { ...noteableDataMock, discussion_locked: true }, + }); + }); + + it('renders discussion locked widget', () => { + expect(findDiscussionLockedWidget().exists()).toBe(true); + }); + }); + + describe('note is not locked', () => { + beforeEach(() => { + mountComponent({ + noteableData: { ...noteableDataMock, discussion_locked: false }, + }); + }); + + it('renders discussion locked widget', () => { + expect(findDiscussionLockedWidget().exists()).toBe(false); + }); + }); + describe('with batchComments in store', () => { describe('start review, add to review and comment now buttons', () => { it('when no drafts exist on non-merge request, should not render', () => { diff --git a/spec/frontend/notes/components/discussion_locked_widget_spec.js b/spec/frontend/notes/components/discussion_locked_widget_spec.js new file mode 100644 index 00000000000000..c1e153685bf6cd --- /dev/null +++ b/spec/frontend/notes/components/discussion_locked_widget_spec.js @@ -0,0 +1,34 @@ +import { GlIcon, GlLink } from '@gitlab/ui'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import DiscussionLockedWidget from '~/notes/components/discussion_locked_widget.vue'; + +describe('DiscussionLockedWidget', () => { + let wrapper; + + const createComponent = () => { + wrapper = shallowMountExtended(DiscussionLockedWidget, { + propsData: { + issuableType: 'issuable_type', + }, + }); + }; + + beforeEach(() => { + createComponent(); + }); + + const findIcon = () => wrapper.findComponent(GlIcon); + const findLink = () => wrapper.findComponent(GlLink); + + it('renders locked issue warning', () => { + expect(findIcon().props('name')).toBe('lock'); + expect(wrapper.text()).toContain( + 'The discussion in this issuable type is locked. Only project members can comment.', + ); + expect(findLink().text()).toBe('Learn more'); + expect(findLink().props()).toMatchObject({ + href: '/help/user/discussions/_index.md#prevent-comments-by-locking-the-discussion', + target: '_blank', + }); + }); +}); diff --git a/spec/frontend/wikis/notes/components/wiki_comment_form_spec.js b/spec/frontend/wikis/notes/components/wiki_comment_form_spec.js index 3c9af5d20a0406..89202e3b9ffa79 100644 --- a/spec/frontend/wikis/notes/components/wiki_comment_form_spec.js +++ b/spec/frontend/wikis/notes/components/wiki_comment_form_spec.js @@ -3,7 +3,6 @@ import { nextTick } from 'vue'; import WikiCommentForm from '~/wikis/wiki_notes/components/wiki_comment_form.vue'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import WikiDiscussionsSignedOut from '~/wikis/wiki_notes/components/wiki_discussions_signed_out.vue'; -import WikiDiscussionLocked from '~/wikis/wiki_notes/components/wiki_discussion_locked.vue'; import * as secretsDetection from '~/lib/utils/secret_detection'; import * as confirmViaGLModal from '~/lib/utils/confirm_via_gl_modal/confirm_action'; import { wikiCommentFormProvideData, noteableId } from '../mock_data'; @@ -15,8 +14,8 @@ describe('WikiCommentForm', () => { mutate: jest.fn(), }; - const createWrapper = ({ props, provideData } = {}) => - shallowMountExtended(WikiCommentForm, { + const createComponent = ({ props, provideData } = {}) => { + wrapper = shallowMountExtended(WikiCommentForm, { propsData: { noteableId, noteId: '12', discussionId: '1', ...props }, provide: { ...wikiCommentFormProvideData, ...provideData }, mocks: { @@ -36,12 +35,14 @@ describe('WikiCommentForm', () => { }, }, }); + }; - const wikiCommentContainer = () => wrapper.findByTestId('wiki-note-comment-form-container'); + const findWikiDiscussionsSignedOut = () => wrapper.findComponent(WikiDiscussionsSignedOut); + const findWikiNoteCommentForm = () => wrapper.findByTestId('wiki-note-comment-form'); describe('user is not logged in', () => { beforeEach(() => { - wrapper = createWrapper({ + createComponent({ provideData: { currentUserData: null, }, @@ -49,42 +50,35 @@ describe('WikiCommentForm', () => { }); it('should only render wiki discussion signed out component', () => { - expect(wikiCommentContainer().element.children).toHaveLength(1); - - const wikiDiscussionsSignedOut = - wikiCommentContainer().findComponent(WikiDiscussionsSignedOut); - expect(wikiDiscussionsSignedOut.exists()).toBe(true); + expect(findWikiDiscussionsSignedOut().exists()).toBe(true); + expect(findWikiNoteCommentForm().exists()).toBe(false); }); }); describe('user is logged in', () => { describe('user cannot create note', () => { beforeEach(() => { - wrapper = createWrapper({ + createComponent({ provideData: { isContainerArchived: true, }, }); }); - it('should render only wiki discussion locked component when user cannot create note', () => { - expect(wikiCommentContainer().element.children).toHaveLength(1); - - const wikiDiscussionLocked = wikiCommentContainer().findComponent(WikiDiscussionLocked); - expect(wikiDiscussionLocked.exists()).toBe(true); + it('does not render contents', () => { + expect(findWikiDiscussionsSignedOut().exists()).toBe(false); + expect(findWikiNoteCommentForm().exists()).toBe(false); }); }); describe('user can create note', () => { beforeEach(() => { - wrapper = createWrapper(); + createComponent(); }); - it('should render only the wiki comment form', () => { - expect(wikiCommentContainer().element.children).toHaveLength(1); - - const commentForm = wikiCommentContainer().find('[data-testid=wiki-note-comment-form]'); - expect(commentForm.exists()).toBe(true); + it('should only render the wiki comment form', () => { + expect(findWikiDiscussionsSignedOut().exists()).toBe(false); + expect(findWikiNoteCommentForm().exists()).toBe(true); }); it('should not autofocus on themarkdown editor when isReply and isEdit are false', () => { @@ -92,12 +86,12 @@ describe('WikiCommentForm', () => { }); it('should autofocus on the markdown editor when isReply is true', () => { - wrapper = createWrapper({ props: { isReply: true } }); + createComponent({ props: { isReply: true } }); expect(wrapper.vm.$refs.markdownEditor.autofocus).toBe(true); }); it('should autofocus on the markdown editor when isEdit is true', () => { - wrapper = createWrapper({ props: { isEdit: true } }); + createComponent({ props: { isEdit: true } }); expect(wrapper.vm.$refs.markdownEditor.autofocus).toBe(true); }); @@ -120,7 +114,7 @@ describe('WikiCommentForm', () => { describe('handle save', () => { const createWrapperWithNote = (props) => { - wrapper = createWrapper({ + createComponent({ props: { discussionId: '1', noteableId: '1', @@ -151,7 +145,7 @@ describe('WikiCommentForm', () => { }); it('should not emit the creating-note:start event when note is empty', async () => { - wrapper = createWrapper(); + createComponent(); await wrapper.vm.handleSave(); expect(Boolean(wrapper.emitted('creating-note:start'))).toBe(false); }); @@ -341,7 +335,7 @@ describe('WikiCommentForm', () => { const internalNoteCheckbox = () => wrapper.findComponent(GlFormCheckbox); beforeEach(() => { - wrapper = createWrapper({ props: { canSetInternalNote: true } }); + createComponent({ props: { canSetInternalNote: true } }); }); it('should render both correctly', async () => { @@ -350,13 +344,13 @@ describe('WikiCommentForm', () => { }); it('should render neither when isReply is true', () => { - wrapper = createWrapper({ props: { isReply: true } }); + createComponent({ props: { isReply: true } }); expect(submitButton().exists()).toBe(false); expect(internalNoteCheckbox().exists()).toBe(false); }); it('should render neither when isEdit is true', () => { - wrapper = createWrapper({ props: { isEdit: true } }); + createComponent({ props: { isEdit: true } }); expect(submitButton().exists()).toBe(false); expect(internalNoteCheckbox().exists()).toBe(false); }); @@ -383,7 +377,7 @@ describe('WikiCommentForm', () => { const cancelButton = () => wrapper.findByTestId('wiki-note-cancel-button'); beforeEach(() => { - wrapper = createWrapper({ props: { isEdit: true } }); + createComponent({ props: { isEdit: true } }); }); it('should render both save and cancel with correct text buttons when isEdit is true', async () => { @@ -392,13 +386,13 @@ describe('WikiCommentForm', () => { }); it('should render both save and cancel with correct text buttons when isReply is true', async () => { - wrapper = createWrapper({ props: { isReply: true, isEdit: false } }); + createComponent({ props: { isReply: true, isEdit: false } }); expect(await saveButton().text()).toBe('Reply'); expect(await cancelButton().text()).toBe('Cancel'); }); it('should not render either button when isEdit and isReply are false', () => { - wrapper = createWrapper({ props: { isReply: false, isEdit: false } }); + createComponent({ props: { isReply: false, isEdit: false } }); expect(saveButton().exists()).toBe(false); expect(cancelButton().exists()).toBe(false); }); @@ -431,7 +425,7 @@ describe('WikiCommentForm', () => { describe('when note is not empty', () => { const createWrapperWithNote = (props) => { - wrapper = createWrapper({ + createComponent({ props, }); diff --git a/spec/frontend/wikis/notes/components/wiki_discussion_locked_spec.js b/spec/frontend/wikis/notes/components/wiki_discussion_locked_spec.js deleted file mode 100644 index ff5b83c45a2e17..00000000000000 --- a/spec/frontend/wikis/notes/components/wiki_discussion_locked_spec.js +++ /dev/null @@ -1,73 +0,0 @@ -import { GlIcon } from '@gitlab/ui'; -import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; -import WikiDiscussionLocked from '~/wikis/wiki_notes/components/wiki_discussion_locked.vue'; - -describe('WikiDiscussionLocked', () => { - let wrapper; - - const createWrapper = (provideData) => - shallowMountExtended(WikiDiscussionLocked, { - provide: { - isContainerArchived: false, - containerType: 'Project', - ...provideData, - }, - }); - - describe('renders correctly', () => { - const shouldRenderLockIcon = () => { - expect(wrapper.findComponent(GlIcon).props('name')).toBe('lock'); - }; - - describe('when isContainerArchived is false', () => { - beforeEach(() => { - wrapper = createWrapper(); - }); - - it('should render lock icon', () => { - shouldRenderLockIcon(); - }); - - it('should render locked discussion warning', async () => { - expect(await wrapper.text()).toContain( - 'The discussion in this Wiki is locked. Only project members can comment.', - ); - }); - - it('should not render archived project warning', async () => { - expect(await wrapper.text()).not.toContain( - 'This project is archived and cannot be commented on.', - ); - }); - }); - - describe('when isContainerArchived is true', () => { - beforeEach(() => { - wrapper = createWrapper({ isContainerArchived: true }); - }); - it('should render lock icon', () => { - shouldRenderLockIcon(); - }); - - it('should not render locked discussion warning', async () => { - expect(await wrapper.text()).not.toContain( - 'The discussion in this Wiki is locked. Only project members can comment.', - ); - }); - - it('should render archived project warning by default', async () => { - expect(await wrapper.text()).toContain( - 'This project is archived and cannot be commented on.', - ); - }); - - it('should render archived group warning when containerType is wiki', async () => { - wrapper = createWrapper({ isContainerArchived: true, containerType: 'group' }); - - expect(await wrapper.text()).toContain( - 'This group is archived and cannot be commented on.', - ); - }); - }); - }); -}); diff --git a/spec/frontend/work_items/components/notes/work_item_add_note_spec.js b/spec/frontend/work_items/components/notes/work_item_add_note_spec.js index df2ae39c9c3ffb..d1283b43b57774 100644 --- a/spec/frontend/work_items/components/notes/work_item_add_note_spec.js +++ b/spec/frontend/work_items/components/notes/work_item_add_note_spec.js @@ -64,10 +64,12 @@ describe('Work item add note', () => { isWorkItemConfidential = false, parentId = null, hideFullscreenMarkdownButton = false, + archived = false, } = {}) => { const workItemResponse = workItemByIidResponseFactory({ canCreateNote, emailParticipantsWidgetPresent, + archived, }); workItemResponseHandler = jest.fn().mockResolvedValue(workItemResponse); @@ -377,9 +379,24 @@ describe('Work item add note', () => { it('cannot add comment', async () => { await createComponent({ isEditing: false, canCreateNote: false }); - expect(findWorkItemLockedComponent().exists()).toBe(true); expect(findCommentForm().exists()).toBe(false); }); + + describe('when project is not archived', () => { + it('shows locked component', async () => { + await createComponent({ isEditing: false, canCreateNote: false, archived: false }); + + expect(findWorkItemLockedComponent().exists()).toBe(true); + }); + }); + + describe('when project is archived', () => { + it('does not show locked component', async () => { + await createComponent({ isEditing: false, canCreateNote: false, archived: true }); + + expect(findWorkItemLockedComponent().exists()).toBe(false); + }); + }); }); describe('email participants', () => { diff --git a/spec/frontend/work_items/components/notes/work_item_comment_locked_spec.js b/spec/frontend/work_items/components/notes/work_item_comment_locked_spec.js index b809fa501cf817..81f4baa526b3fa 100644 --- a/spec/frontend/work_items/components/notes/work_item_comment_locked_spec.js +++ b/spec/frontend/work_items/components/notes/work_item_comment_locked_spec.js @@ -1,65 +1,38 @@ -import { GlLink, GlIcon } from '@gitlab/ui'; +import { GlIcon, GlLink } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import WorkItemCommentLocked from '~/work_items/components/notes/work_item_comment_locked.vue'; -const createComponent = ({ workItemType = 'Task', isProjectArchived = false } = {}) => - shallowMount(WorkItemCommentLocked, { - propsData: { - workItemType, - isProjectArchived, - }, - }); - describe('WorkItemCommentLocked', () => { let wrapper; + + const createComponent = ({ workItemType = 'Task' } = {}) => { + wrapper = shallowMount(WorkItemCommentLocked, { + propsData: { + workItemType, + }, + }); + }; + const findLockedIcon = () => wrapper.findComponent(GlIcon); const findLearnMoreLink = () => wrapper.findComponent(GlLink); + beforeEach(() => { + createComponent(); + }); + it('renders the locked icon', () => { - wrapper = createComponent(); expect(findLockedIcon().props('name')).toBe('lock'); }); - it('has the learn more link', () => { - wrapper = createComponent(); - expect(findLearnMoreLink().attributes('href')).toBe( - WorkItemCommentLocked.constantOptions.lockedIssueDocsPath, + it('renders text', () => { + expect(wrapper.text()).toMatchInterpolatedText( + 'The discussion in this task is locked. Only project members can comment. Learn more.', ); }); - describe('when the project is archived', () => { - beforeEach(() => { - wrapper = createComponent({ isProjectArchived: true }); - }); - - it('renders text', () => { - expect(wrapper.text()).toMatchInterpolatedText( - 'This project is archived and cannot be commented on. Learn more.', - ); - }); - - it('renders learn more link which links to archived project docs path', () => { - expect(findLearnMoreLink().attributes('href')).toBe( - WorkItemCommentLocked.constantOptions.archivedProjectDocsPath, - ); - }); - }); - - describe('when the work item is locked', () => { - beforeEach(() => { - wrapper = createComponent(); - }); - - it('renders text', () => { - expect(wrapper.text()).toMatchInterpolatedText( - 'The discussion in this task is locked. Only project members can comment. Learn more.', - ); - }); - - it('renders learn more link which links to locked discussions docs path', () => { - expect(findLearnMoreLink().attributes('href')).toBe( - WorkItemCommentLocked.constantOptions.lockedIssueDocsPath, - ); - }); + it('renders learn more link which links to locked discussions docs path', () => { + expect(findLearnMoreLink().attributes('href')).toBe( + WorkItemCommentLocked.constantOptions.lockedIssueDocsPath, + ); }); }); diff --git a/spec/frontend/work_items/mock_data.js b/spec/frontend/work_items/mock_data.js index 2fc6a357c75946..adb500d10791b8 100644 --- a/spec/frontend/work_items/mock_data.js +++ b/spec/frontend/work_items/mock_data.js @@ -1781,13 +1781,14 @@ export const workItemResponseFactory = ({ commentTemplatesPaths = null, hidden = false, imported = false, + archived = false, } = {}) => ({ data: { workItem: { __typename: 'WorkItem', id, iid, - archived: false, + archived, hidden, imported, title: 'Updated _title_', -- GitLab