Read about our upcoming Code of Conduct on this issue

This instance will be upgraded to Heptapod 0.28.0 on 2022-01-18 at 14:00 UTC+1 (a few minutes of down time)

Commit da347fc5 authored by Phil Hughes's avatar Phil Hughes
Browse files

Merge branch 'fl-mr-widget-2' into 'master'

Moves author components into vue files

See merge request gitlab-org/gitlab-ce!16863
import tooltip from '../../vue_shared/directives/tooltip';
export default {
name: 'MRWidgetAuthor',
props: {
author: { type: Object, required: true },
showAuthorName: { type: Boolean, required: false, default: true },
showAuthorTooltip: { type: Boolean, required: false, default: false },
},
directives: {
tooltip,
},
template: `
<a
:href="author.webUrl || author.web_url"
class="author-link inline"
:v-tooltip="showAuthorTooltip"
:title="author.name">
<img
:src="author.avatarUrl || author.avatar_url"
class="avatar avatar-inline s16" />
<span
v-if="showAuthorName"
class="author">{{author.name}}
</span>
</a>
`,
};
<script>
export default {
name: 'MRWidgetAuthor',
props: {
author: {
type: Object,
required: true,
},
},
computed: {
authorUrl() {
return this.author.webUrl || this.author.web_url;
},
avatarUrl() {
return this.author.avatarUrl || this.author.avatar_url;
},
},
};
</script>
<template>
<a
:href="authorUrl"
class="author-link inline"
>
<img
:src="avatarUrl"
class="avatar avatar-inline s16"
/>
<span class="author">
{{ author.name }}
</span>
</a>
</template>
import MRWidgetAuthor from './mr_widget_author';
export default {
name: 'MRWidgetAuthorTime',
props: {
actionText: { type: String, required: true },
author: { type: Object, required: true },
dateTitle: { type: String, required: true },
dateReadable: { type: String, required: true },
},
components: {
'mr-widget-author': MRWidgetAuthor,
},
template: `
<h4 class="js-mr-widget-author">
{{actionText}}
<mr-widget-author :author="author" />
<time
:title="dateTitle"
data-toggle="tooltip"
data-placement="top"
data-container="body">
{{dateReadable}}
</time>
</h4>
`,
};
<script>
import mrWidgetAuthor from './mr_widget_author.vue';
export default {
name: 'MRWidgetAuthorTime',
components: {
mrWidgetAuthor,
},
props: {
actionText: {
type: String,
required: true,
},
author: {
type: Object,
required: true,
},
dateTitle: {
type: String,
required: true,
},
dateReadable: {
type: String,
required: true,
},
},
};
</script>
<template>
<h4 class="js-mr-widget-author">
{{ actionText }}
<mr-widget-author :author="author" />
<time
:title="dateTitle"
data-toggle="tooltip"
data-placement="top"
data-container="body"
>
{{ dateReadable }}
</time>
</h4>
</template>
<script>
import mrWidgetAuthorTime from '../../components/mr_widget_author_time';
import mrWidgetAuthorTime from '../../components/mr_widget_author_time.vue';
import statusIcon from '../mr_widget_status_icon.vue';
export default {
......
<script>
import Flash from '../../../flash';
import statusIcon from '../mr_widget_status_icon.vue';
import mrWidgetAuthor from '../../components/mr_widget_author';
import mrWidgetAuthor from '../../components/mr_widget_author.vue';
import eventHub from '../../event_hub';
export default {
......
......@@ -3,7 +3,7 @@
import tooltip from '~/vue_shared/directives/tooltip';
import loadingIcon from '~/vue_shared/components/loading_icon.vue';
import { s__, __ } from '~/locale';
import mrWidgetAuthorTime from '../../components/mr_widget_author_time';
import mrWidgetAuthorTime from '../../components/mr_widget_author_time.vue';
import statusIcon from '../mr_widget_status_icon.vue';
import eventHub from '../../event_hub';
......
import Vue from 'vue';
import authorComponent from '~/vue_merge_request_widget/components/mr_widget_author';
const author = {
webUrl: 'http://foo.bar',
avatarUrl: 'http://gravatar.com/foo',
name: 'fatihacet',
};
const createComponent = () => {
const Component = Vue.extend(authorComponent);
return new Component({
el: document.createElement('div'),
propsData: { author },
});
};
import authorComponent from '~/vue_merge_request_widget/components/mr_widget_author.vue';
import mountComponent from '../../helpers/vue_mount_component_helper';
describe('MRWidgetAuthor', () => {
describe('props', () => {
it('should have props', () => {
const authorProp = authorComponent.props.author;
let vm;
beforeEach(() => {
const Component = Vue.extend(authorComponent);
vm = mountComponent(Component, {
author: {
name: 'Administrator',
username: 'root',
webUrl: 'http://localhost:3000/root',
avatarUrl: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
},
expect(authorProp).toBeDefined();
expect(authorProp.type instanceof Object).toBeTruthy();
expect(authorProp.required).toBeTruthy();
});
});
describe('template', () => {
it('should have correct elements', () => {
const el = createComponent().$el;
afterEach(() => {
vm.$destroy();
});
expect(el.tagName).toEqual('A');
expect(el.getAttribute('href')).toEqual(author.webUrl);
expect(el.querySelector('img').getAttribute('src')).toEqual(author.avatarUrl);
expect(el.querySelector('.author').innerText.trim()).toEqual(author.name);
});
it('renders link with the author web url', () => {
expect(vm.$el.getAttribute('href')).toEqual('http://localhost:3000/root');
});
it('renders image with avatar url', () => {
expect(
vm.$el.querySelector('img').getAttribute('src'),
).toEqual('http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon');
});
it('renders author name', () => {
expect(vm.$el.textContent.trim()).toEqual('Administrator');
});
});
import Vue from 'vue';
import authorTimeComponent from '~/vue_merge_request_widget/components/mr_widget_author_time';
const props = {
actionText: 'Merged by',
author: {
webUrl: 'http://foo.bar',
avatarUrl: 'http://gravatar.com/foo',
name: 'fatihacet',
},
dateTitle: '2017-03-23T23:02:00.807Z',
dateReadable: '12 hours ago',
};
const createComponent = () => {
const Component = Vue.extend(authorTimeComponent);
return new Component({
el: document.createElement('div'),
propsData: props,
});
};
import authorTimeComponent from '~/vue_merge_request_widget/components/mr_widget_author_time.vue';
import mountComponent from '../../helpers/vue_mount_component_helper';
describe('MRWidgetAuthorTime', () => {
describe('props', () => {
it('should have props', () => {
const { actionText, author, dateTitle, dateReadable } = authorTimeComponent.props;
const ActionTextClass = actionText.type;
const DateTitleClass = dateTitle.type;
const DateReadableClass = dateReadable.type;
expect(new ActionTextClass() instanceof String).toBeTruthy();
expect(actionText.required).toBeTruthy();
expect(author.type instanceof Object).toBeTruthy();
expect(author.required).toBeTruthy();
expect(new DateTitleClass() instanceof String).toBeTruthy();
expect(dateTitle.required).toBeTruthy();
expect(new DateReadableClass() instanceof String).toBeTruthy();
expect(dateReadable.required).toBeTruthy();
let vm;
beforeEach(() => {
const Component = Vue.extend(authorTimeComponent);
vm = mountComponent(Component, {
actionText: 'Merged by',
author: {
name: 'Administrator',
username: 'root',
webUrl: 'http://localhost:3000/root',
avatarUrl: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
},
dateTitle: '2017-03-23T23:02:00.807Z',
dateReadable: '12 hours ago',
});
});
describe('components', () => {
it('should have components', () => {
expect(authorTimeComponent.components['mr-widget-author']).toBeDefined();
});
afterEach(() => {
vm.$destroy();
});
it('renders provided action text', () => {
expect(vm.$el.textContent).toContain('Merged by');
});
describe('template', () => {
it('should have correct elements', () => {
const el = createComponent().$el;
it('renders author', () => {
expect(vm.$el.textContent).toContain('Administrator');
});
expect(el.tagName).toEqual('H4');
expect(el.querySelector('a').getAttribute('href')).toEqual(props.author.webUrl);
expect(el.querySelector('time').innerText).toContain(props.dateReadable);
expect(el.querySelector('time').getAttribute('title')).toEqual(props.dateTitle);
});
it('renders provided time', () => {
expect(vm.$el.querySelector('time').getAttribute('title')).toEqual('2017-03-23T23:02:00.807Z');
expect(vm.$el.querySelector('time').textContent.trim()).toEqual('12 hours ago');
});
});
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment