diff --git a/app/assets/javascripts/rapid_diffs/app/discussions/discussion_notes.vue b/app/assets/javascripts/rapid_diffs/app/discussions/discussion_notes.vue index 7a81950d5392c8cf34bca97cb2944836370f8700..35ed20d1dd57021e8dbbc0985ebec9c66e9cc74c 100644 --- a/app/assets/javascripts/rapid_diffs/app/discussions/discussion_notes.vue +++ b/app/assets/javascripts/rapid_diffs/app/discussions/discussion_notes.vue @@ -1,13 +1,12 @@ + + diff --git a/app/assets/javascripts/rapid_diffs/app/discussions/note_header.vue b/app/assets/javascripts/rapid_diffs/app/discussions/note_header.vue index 0563bf483c1c51c758fc2bebab584bb7b0ee1ebe..828fda253442e434a42ca101ad7a5b80c6017714 100644 --- a/app/assets/javascripts/rapid_diffs/app/discussions/note_header.vue +++ b/app/assets/javascripts/rapid_diffs/app/discussions/note_header.vue @@ -4,6 +4,7 @@ import { isGid, getIdFromGraphQLId } from '~/graphql_shared/utils'; import { s__ } from '~/locale'; import ImportedBadge from '~/vue_shared/components/imported_badge.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; +import NoteAuthor from './note_author.vue'; export default { name: 'NoteHeader', @@ -14,6 +15,7 @@ export default { GlLoadingIcon, GlAvatarLink, GlAvatar, + NoteAuthor, }, directives: { GlTooltip: GlTooltipDirective, @@ -98,20 +100,7 @@ export default { - - - @{{ author.username }} - - - + {{ __('A deleted user') }} diff --git a/app/assets/javascripts/rapid_diffs/app/discussions/system_note.vue b/app/assets/javascripts/rapid_diffs/app/discussions/system_note.vue new file mode 100644 index 0000000000000000000000000000000000000000..c47d5b47a1189d0c345536efadf10e8aa727fdc7 --- /dev/null +++ b/app/assets/javascripts/rapid_diffs/app/discussions/system_note.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/spec/frontend/rapid_diffs/app/discussions/discussion_notes_spec.js b/spec/frontend/rapid_diffs/app/discussions/discussion_notes_spec.js index 6196ca0b6edf4bf8f729e37de515a5ed37143ec5..09fdc64fcd85eff167343598d9ae722659565078 100644 --- a/spec/frontend/rapid_diffs/app/discussions/discussion_notes_spec.js +++ b/spec/frontend/rapid_diffs/app/discussions/discussion_notes_spec.js @@ -5,15 +5,6 @@ import NoteableNote from '~/rapid_diffs/app/discussions/noteable_note.vue'; import SystemNote from '~/vue_shared/components/notes/system_note.vue'; import ToggleRepliesWidget from '~/notes/components/toggle_replies_widget.vue'; -jest.mock('~/vue_shared/components/notes/system_note.vue', () => { - return { - props: jest.requireActual('~/vue_shared/components/notes/system_note.vue').default.props, - render() { - return null; - }, - }; -}); - describe('DiscussionNotes', () => { let wrapper; @@ -28,9 +19,6 @@ describe('DiscussionNotes', () => { propsData, provide: merge(defaultProvisions, provide), scopedSlots, - stubs: { - SystemNote, - }, }); }; diff --git a/spec/frontend/rapid_diffs/app/discussions/note_author_spec.js b/spec/frontend/rapid_diffs/app/discussions/note_author_spec.js new file mode 100644 index 0000000000000000000000000000000000000000..8e709c1446258541a5be678dd06a95a35024596d --- /dev/null +++ b/spec/frontend/rapid_diffs/app/discussions/note_author_spec.js @@ -0,0 +1,70 @@ +import { shallowMount } from '@vue/test-utils'; +import NoteAuthor from '~/rapid_diffs/app/discussions/note_author.vue'; + +describe('NoteAuthor', () => { + let wrapper; + + const createComponent = (props = {}, slots = {}) => { + wrapper = shallowMount(NoteAuthor, { + propsData: props, + slots, + }); + }; + + const findAuthorLink = () => wrapper.find('a'); + + it('renders link with author path', () => { + const author = { + id: 'gid://gitlab/User/123', + name: 'John Doe', + username: 'johndoe', + path: '/johndoe', + }; + createComponent({ author }); + + const link = findAuthorLink(); + expect(link.exists()).toBe(true); + expect(link.attributes('href')).toBe('/johndoe'); + expect(link.text()).toBe('John Doe@johndoe'); + expect(link.attributes('data-user-id')).toBe('123'); + expect(link.attributes('data-username')).toBe('johndoe'); + }); + + it('skips username when not present', () => { + const author = { + id: 'gid://gitlab/User/123', + name: 'John Doe', + username: undefined, + path: '/johndoe', + }; + createComponent({ author }); + + const link = findAuthorLink(); + expect(link.text()).toBe('John Doe'); + }); + + it('skips username when showUsername is false', () => { + const author = { + id: 'gid://gitlab/User/123', + name: 'John Doe', + username: 'johndoe', + path: '/johndoe', + }; + createComponent({ author, showUsername: false }); + + const link = findAuthorLink(); + expect(link.text()).toBe('John Doe'); + }); + + it('uses webUrl when path is not available', () => { + const author = { + id: 'gid://gitlab/User/123', + name: 'John Doe', + username: 'johndoe', + webUrl: 'https://example.com/johndoe', + }; + createComponent({ author }); + + expect(findAuthorLink().attributes('href')).toBe('https://example.com/johndoe'); + }); +}); diff --git a/spec/frontend/rapid_diffs/app/discussions/note_header_spec.js b/spec/frontend/rapid_diffs/app/discussions/note_header_spec.js index 5338401bfa5003f0d9a36dde7531d18e2d174b5e..8036c848172f1fcd38153921ae2589a28ecc4bd8 100644 --- a/spec/frontend/rapid_diffs/app/discussions/note_header_spec.js +++ b/spec/frontend/rapid_diffs/app/discussions/note_header_spec.js @@ -3,6 +3,7 @@ import { GlAvatar, GlAvatarLink, GlBadge, GlLoadingIcon } from '@gitlab/ui'; import NoteHeader from '~/rapid_diffs/app/discussions/note_header.vue'; import ImportedBadge from '~/vue_shared/components/imported_badge.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; +import NoteAuthor from '~/rapid_diffs/app/discussions/note_author.vue'; describe('NoteHeader', () => { let wrapper; @@ -42,7 +43,7 @@ describe('NoteHeader', () => { }); }); - it('shows author name and username', () => { + it('shows author', () => { const author = { id: 'gid://gitlab/User/123', name: 'John Doe', @@ -50,35 +51,7 @@ describe('NoteHeader', () => { path: '/johndoe', }; createComponent({ author }); - const authorLink = findAuthorLink(); - expect(authorLink.exists()).toBe(true); - expect(authorLink.attributes('href')).toBe('/johndoe'); - expect(authorLink.attributes('data-user-id')).toBe('123'); - expect(authorLink.attributes('data-username')).toBe('johndoe'); - expect(authorLink.text()).toContain('John Doe'); - expect(authorLink.text()).toContain('@johndoe'); - }); - - it('uses webUrl when path is not available', () => { - const author = { - id: 'gid://gitlab/User/123', - name: 'John Doe', - username: 'johndoe', - webUrl: 'https://example.com/johndoe', - }; - createComponent({ author }); - expect(findAuthorLink().attributes('href')).toBe('https://example.com/johndoe'); - }); - - it('shows username', () => { - const author = { - id: 'gid://gitlab/User/123', - name: 'John Doe', - username: 'johndoe', - path: '/johndoe', - }; - createComponent({ author }); - expect(wrapper.text()).toContain(author.username); + expect(wrapper.findComponent(NoteAuthor).props('author')).toStrictEqual(author); }); it('shows deleted user message instead of user link when no author is provided', () => { diff --git a/spec/frontend/rapid_diffs/app/discussions/system_note_spec.js b/spec/frontend/rapid_diffs/app/discussions/system_note_spec.js new file mode 100644 index 0000000000000000000000000000000000000000..6cd7beabbd499daf954ffdc0e694d6fa82bce239 --- /dev/null +++ b/spec/frontend/rapid_diffs/app/discussions/system_note_spec.js @@ -0,0 +1,40 @@ +import { shallowMount } from '@vue/test-utils'; +import SystemNote from '~/rapid_diffs/app/discussions/system_note.vue'; +import NoteAuthor from '~/rapid_diffs/app/discussions/note_author.vue'; +import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; + +describe('SystemNote', () => { + let wrapper; + + const createComponent = (props = {}) => { + wrapper = shallowMount(SystemNote, { + propsData: props, + }); + }; + + it('shows system message', () => { + const note = { note_html: '

test

' }; + createComponent({ note }); + expect(wrapper.find('p#test').text()).toBe('test'); + }); + + it('shows message author', () => { + const note = { note_html: 'test', author: { username: 'user' } }; + createComponent({ note }); + const author = wrapper.findComponent(NoteAuthor); + expect(author.props('author')).toStrictEqual(note.author); + expect(author.props('showUsername')).toBe(false); + }); + + it('shows deleted author', () => { + const note = { note_html: 'test' }; + createComponent({ note }); + expect(wrapper.text()).toContain('A deleted user'); + }); + + it('shows timestamp', () => { + const note = { note_html: 'test', created_at: Date.now().toString() }; + createComponent({ note }); + expect(wrapper.findComponent(TimeAgoTooltip).props('time')).toBe(note.created_at); + }); +});