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 @@
+
+
+
+ @{{ author.username }}
+
+
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 @@
+
+
+
+
+
+
+
+
+
{{ __('A deleted user') }}
+
+
+
+
+
+
+
+
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);
+ });
+});