Commit 834a76f7 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '32343-productivity-analytics-mr-table-raises-a-js-error-occasionally' into 'master'

Resolve "Productivity Analytics: MR table raises a JS error occasionally"

Closes #32343

See merge request gitlab-org/gitlab!17479
parents fb532f03 ef0328fe
...@@ -22,8 +22,8 @@ export default { ...@@ -22,8 +22,8 @@ export default {
}, },
}, },
computed: { computed: {
isNumericValue() { isNumber() {
return this.value !== null && !Number.isNaN(Number(this.value)); return typeof this.value === 'number';
}, },
unit() { unit() {
return this.type === 'days_to_merge' return this.type === 'days_to_merge'
...@@ -36,7 +36,7 @@ export default { ...@@ -36,7 +36,7 @@ export default {
<template> <template>
<div class="metric-col"> <div class="metric-col">
<span class="time"> <span class="time">
<template v-if="isNumericValue"> <template v-if="isNumber">
{{ value }} {{ value }}
<span> {{ unit }} </span> <span> {{ unit }} </span>
</template> </template>
......
...@@ -39,10 +39,10 @@ export default { ...@@ -39,10 +39,10 @@ export default {
selectedMetric() { selectedMetric() {
return this.mergeRequest[this.metricType]; return this.mergeRequest[this.metricType];
}, },
metricTimeUnit() { },
return this.metricType === 'days_to_merge' methods: {
? n__('day', 'days', this.selectedMetric) isNumber(metric) {
: n__('Time|hr', 'Time|hrs', this.selectedMetric); return typeof metric === 'number';
}, },
}, },
}; };
...@@ -50,26 +50,30 @@ export default { ...@@ -50,26 +50,30 @@ export default {
<template> <template>
<div class="gl-responsive-table-row-layout gl-responsive-table-row"> <div class="gl-responsive-table-row-layout gl-responsive-table-row">
<div <div
class="table-section section-50 d-flex flex-row-reverse flex-md-row justify-content-between justify-content-md-start qa-mr-details" class="table-section section-50 d-flex flex-row-reverse flex-md-row justify-content-between justify-content-md-start js-mr-details"
> >
<div class="d-flex mr-md-2"> <div class="d-flex mr-md-2">
<gl-avatar :src="mergeRequest.author_avatar_url" :size="16" /> <gl-avatar :src="mergeRequest.author_avatar_url" :size="16" />
</div> </div>
<div class="mw-90p"> <div class="d-flex flex-column flex-grow mw-90p">
<h5 class="item-title mr-title my-0 mw-90p d-block str-truncated"> <h5 class="item-title mr-title my-0 d-block str-truncated">
<gl-link :href="mergeRequest.merge_request_url" target="_blank">{{ <gl-link :href="mergeRequest.merge_request_url" target="_blank">{{
mergeRequest.title mergeRequest.title
}}</gl-link> }}</gl-link>
</h5> </h5>
<ul class="horizontal-list list-items-separated text-secondary"> <ul class="horizontal-list list-items-separated text-secondary mb-0">
<li>{{ mrId }}</li> <li>{{ mrId }}</li>
<li>{{ commitCount }}</li> <li v-if="isNumber(mergeRequest.commits_count)" ref="commitCount">{{ commitCount }}</li>
<li>{{ locPerCommit }}</li> <li v-if="isNumber(mergeRequest.loc_per_commit)" ref="locPerCommitCount">
<li>{{ filesTouched }}</li> {{ locPerCommit }}
</li>
<li v-if="isNumber(mergeRequest.files_touched)" ref="filesTouchedCount">
{{ filesTouched }}
</li>
</ul> </ul>
</div> </div>
</div> </div>
<div class="table-section section-50 d-flex flex-row align-items-start qa-mr-metrics"> <div class="table-section section-50 d-flex flex-row align-items-start js-mr-metrics">
<metric-column <metric-column
type="days_to_merge" type="days_to_merge"
:value="mergeRequest.days_to_merge" :value="mergeRequest.days_to_merge"
......
...@@ -5,7 +5,7 @@ exports[`MergeRequestTableRow component on creation matches the snapshot 1`] = ` ...@@ -5,7 +5,7 @@ exports[`MergeRequestTableRow component on creation matches the snapshot 1`] = `
class="gl-responsive-table-row-layout gl-responsive-table-row" class="gl-responsive-table-row-layout gl-responsive-table-row"
> >
<div <div
class="table-section section-50 d-flex flex-row-reverse flex-md-row justify-content-between justify-content-md-start qa-mr-details" class="table-section section-50 d-flex flex-row-reverse flex-md-row justify-content-between justify-content-md-start js-mr-details"
> >
<div <div
class="d-flex mr-md-2" class="d-flex mr-md-2"
...@@ -20,10 +20,10 @@ exports[`MergeRequestTableRow component on creation matches the snapshot 1`] = ` ...@@ -20,10 +20,10 @@ exports[`MergeRequestTableRow component on creation matches the snapshot 1`] = `
</div> </div>
<div <div
class="mw-90p" class="d-flex flex-column flex-grow mw-90p"
> >
<h5 <h5
class="item-title mr-title my-0 mw-90p d-block str-truncated" class="item-title mr-title my-0 d-block str-truncated"
> >
<gllink-stub <gllink-stub
href="http://gitlab.example.com/gitlab-org/gitlab-test/merge_requests/10" href="http://gitlab.example.com/gitlab-org/gitlab-test/merge_requests/10"
...@@ -34,7 +34,7 @@ exports[`MergeRequestTableRow component on creation matches the snapshot 1`] = ` ...@@ -34,7 +34,7 @@ exports[`MergeRequestTableRow component on creation matches the snapshot 1`] = `
</h5> </h5>
<ul <ul
class="horizontal-list list-items-separated text-secondary" class="horizontal-list list-items-separated text-secondary mb-0"
> >
<li> <li>
!10 !10
...@@ -45,18 +45,22 @@ exports[`MergeRequestTableRow component on creation matches the snapshot 1`] = ` ...@@ -45,18 +45,22 @@ exports[`MergeRequestTableRow component on creation matches the snapshot 1`] = `
</li> </li>
<li> <li>
3 LOC/commit 3 LOC/commit
</li> </li>
<li> <li>
1 files touched 1 files touched
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
<div <div
class="table-section section-50 d-flex flex-row align-items-start qa-mr-metrics" class="table-section section-50 d-flex flex-row align-items-start js-mr-metrics"
> >
<metriccolumn-stub <metriccolumn-stub
label="Time to merge" label="Time to merge"
......
...@@ -64,21 +64,6 @@ describe('MetricColumn component', () => { ...@@ -64,21 +64,6 @@ describe('MetricColumn component', () => {
}); });
describe('computed', () => { describe('computed', () => {
describe('isNumericValue', () => {
it('returns true when the value is neither null nor undefined', () => {
factory();
expect(wrapper.vm.isNumericValue).toBe(true);
});
it('returns false when the value is null', () => {
factory({
...defaultProps,
value: null,
});
expect(wrapper.vm.isNumericValue).toBe(false);
});
});
describe('unit', () => { describe('unit', () => {
it('returns "days" for the "days_to_merge" metric', () => { it('returns "days" for the "days_to_merge" metric', () => {
factory({ factory({
......
...@@ -23,8 +23,8 @@ describe('MergeRequestTableRow component', () => { ...@@ -23,8 +23,8 @@ describe('MergeRequestTableRow component', () => {
}); });
}; };
const findMrDetails = () => wrapper.find('.qa-mr-details'); const findMrDetails = () => wrapper.find('.js-mr-details');
const findMrMetrics = () => wrapper.find('.qa-mr-metrics'); const findMrMetrics = () => wrapper.find('.js-mr-metrics');
const findMetricColumns = () => findMrMetrics().findAll(MetricColumn); const findMetricColumns = () => findMrMetrics().findAll(MetricColumn);
afterEach(() => { afterEach(() => {
...@@ -60,6 +60,26 @@ describe('MergeRequestTableRow component', () => { ...@@ -60,6 +60,26 @@ describe('MergeRequestTableRow component', () => {
expect(title.text()).toContain(defaultProps.mergeRequest.title); expect(title.text()).toContain(defaultProps.mergeRequest.title);
}); });
describe('metric list', () => {
it.each`
metric | selector
${'commits_count'} | ${'commitCount'}
${'loc_per_commit'} | ${'locPerCommitCount'}
${'files_touched'} | ${'filesTouchedCount'}
`("metric '$metric' won't be rendered if null", ({ metric, selector }) => {
// let's update our test data and set the metric to null
const props = {
...defaultProps,
mergeRequest: {
...defaultProps.mergeRequest,
[metric]: null,
},
};
factory(props);
expect(wrapper.find({ ref: selector }).exists()).toBe(false);
});
});
describe('metric columns', () => { describe('metric columns', () => {
it('renders two metric columns', () => { it('renders two metric columns', () => {
expect(findMetricColumns().length).toBe(2); expect(findMetricColumns().length).toBe(2);
...@@ -129,33 +149,5 @@ describe('MergeRequestTableRow component', () => { ...@@ -129,33 +149,5 @@ describe('MergeRequestTableRow component', () => {
expect(wrapper.vm.selectedMetric).toBe(defaultProps.mergeRequest[defaultProps.metricType]); expect(wrapper.vm.selectedMetric).toBe(defaultProps.mergeRequest[defaultProps.metricType]);
}); });
}); });
describe('metricTimeUnit', () => {
describe('when metricType is "days_to_merge"', () => {
beforeEach(() => {
factory({
...defaultProps,
metricType: 'days_to_merge',
});
});
it('returns "days"', () => {
expect(wrapper.vm.metricTimeUnit).toBe('days');
});
});
describe('when metricType is not "days_to_merge"', () => {
beforeEach(() => {
factory({
...defaultProps,
metricType: 'time_to_last_commit',
});
});
it('returns "hrs"', () => {
expect(wrapper.vm.metricTimeUnit).toBe('hrs');
});
});
});
}); });
}); });
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