debian-mirror-gitlab/spec/frontend/time_tracking/components/timelogs_table_spec.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

224 lines
7 KiB
JavaScript
Raw Normal View History

2023-06-20 00:43:36 +05:30
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { GlTable } from '@gitlab/ui';
import { mountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
import TimelogsTable from '~/time_tracking/components/timelogs_table.vue';
import TimelogSourceCell from '~/time_tracking/components/timelog_source_cell.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import { STATUS_OPEN, STATUS_CLOSED, STATUS_MERGED } from '~/issues/constants';
const baseTimelogMock = {
timeSpent: 600,
project: {
fullPath: 'group/project',
},
user: {
name: 'John Smith',
avatarUrl: 'https://example.gitlab.com/john.jpg',
webPath: 'https://example.gitlab.com/john',
},
spentAt: '2023-03-27T21:00:00Z',
note: null,
summary: 'Summary from timelog field',
issue: {
title: 'Issue title',
webUrl: 'https://example.gitlab.com/issue_url_a',
state: STATUS_OPEN,
reference: '#111',
},
mergeRequest: null,
};
const timelogsMock = [
baseTimelogMock,
{
timeSpent: 3600,
project: {
fullPath: 'group/project_b',
},
user: {
name: 'Paul Reed',
avatarUrl: 'https://example.gitlab.com/paul.jpg',
webPath: 'https://example.gitlab.com/paul',
},
spentAt: '2023-03-28T16:00:00Z',
note: {
body: 'Summary from the body',
},
summary: null,
issue: {
title: 'Other issue title',
webUrl: 'https://example.gitlab.com/issue_url_b',
state: STATUS_CLOSED,
reference: '#112',
},
mergeRequest: null,
},
{
timeSpent: 27 * 60 * 60, // 27h or 3d 3h (3 days of 8 hours)
project: {
fullPath: 'group/project_b',
},
user: {
name: 'Les Gibbons',
avatarUrl: 'https://example.gitlab.com/les.jpg',
webPath: 'https://example.gitlab.com/les',
},
spentAt: '2023-03-28T18:00:00Z',
note: null,
summary: 'Other timelog summary',
issue: null,
mergeRequest: {
title: 'MR title',
webUrl: 'https://example.gitlab.com/mr_url',
state: STATUS_MERGED,
reference: '!99',
},
},
];
describe('TimelogsTable component', () => {
Vue.use(VueApollo);
let wrapper;
const findTable = () => wrapper.findComponent(GlTable);
const findTableRows = () => findTable().find('tbody').findAll('tr');
const findRowSpentAt = (rowIndex) =>
extendedWrapper(findTableRows().at(rowIndex)).findByTestId('date-container');
const findRowSource = (rowIndex) => findTableRows().at(rowIndex).findComponent(TimelogSourceCell);
const findRowUser = (rowIndex) => findTableRows().at(rowIndex).findComponent(UserAvatarLink);
const findRowTimeSpent = (rowIndex) =>
extendedWrapper(findTableRows().at(rowIndex)).findByTestId('time-spent-container');
const findRowSummary = (rowIndex) =>
extendedWrapper(findTableRows().at(rowIndex)).findByTestId('summary-container');
const mountComponent = (props = {}) => {
wrapper = mountExtended(TimelogsTable, {
propsData: {
entries: timelogsMock,
limitToHours: false,
...props,
},
stubs: { GlTable },
});
};
describe('when there are no entries', () => {
it('show the empty table message and no rows', () => {
mountComponent({ entries: [] });
expect(findTable().text()).toContain('There are no records to show');
expect(findTableRows()).toHaveLength(1);
});
});
describe('when there are some entries', () => {
it('does not show the empty table message and has the correct number of rows', () => {
mountComponent();
expect(findTable().text()).not.toContain('There are no records to show');
expect(findTableRows()).toHaveLength(3);
});
describe('Spent at column', () => {
it('shows the spent at value with in the correct format', () => {
mountComponent();
expect(findRowSpentAt(0).text()).toBe('March 27, 2023, 21:00 (UTC: +0000)');
});
});
describe('Source column', () => {
it('creates the source cell component passing the right props', () => {
mountComponent();
expect(findRowSource(0).props()).toMatchObject({
timelog: timelogsMock[0],
});
expect(findRowSource(1).props()).toMatchObject({
timelog: timelogsMock[1],
});
expect(findRowSource(2).props()).toMatchObject({
timelog: timelogsMock[2],
});
});
});
describe('User column', () => {
it('creates the user avatar component passing the right props', () => {
mountComponent();
expect(findRowUser(0).props()).toMatchObject({
linkHref: timelogsMock[0].user.webPath,
imgSrc: timelogsMock[0].user.avatarUrl,
imgSize: 16,
imgAlt: timelogsMock[0].user.name,
tooltipText: timelogsMock[0].user.name,
username: timelogsMock[0].user.name,
});
expect(findRowUser(1).props()).toMatchObject({
linkHref: timelogsMock[1].user.webPath,
imgSrc: timelogsMock[1].user.avatarUrl,
imgSize: 16,
imgAlt: timelogsMock[1].user.name,
tooltipText: timelogsMock[1].user.name,
username: timelogsMock[1].user.name,
});
expect(findRowUser(2).props()).toMatchObject({
linkHref: timelogsMock[2].user.webPath,
imgSrc: timelogsMock[2].user.avatarUrl,
imgSize: 16,
imgAlt: timelogsMock[2].user.name,
tooltipText: timelogsMock[2].user.name,
username: timelogsMock[2].user.name,
});
});
});
describe('Time spent column', () => {
it('shows the time spent value with the correct format when `limitToHours` is false', () => {
mountComponent();
expect(findRowTimeSpent(0).text()).toBe('10m');
expect(findRowTimeSpent(1).text()).toBe('1h');
expect(findRowTimeSpent(2).text()).toBe('3d 3h');
});
it('shows the time spent value with the correct format when `limitToHours` is true', () => {
mountComponent({ limitToHours: true });
expect(findRowTimeSpent(0).text()).toBe('10m');
expect(findRowTimeSpent(1).text()).toBe('1h');
expect(findRowTimeSpent(2).text()).toBe('27h');
});
});
describe('Summary column', () => {
it('shows the summary from the note when note body is present and not empty', () => {
mountComponent({
entries: [{ ...baseTimelogMock, note: { body: 'Summary from note body' } }],
});
expect(findRowSummary(0).text()).toBe('Summary from note body');
});
it('shows the summary from the timelog note body is present but empty', () => {
mountComponent({
entries: [{ ...baseTimelogMock, note: { body: '' } }],
});
expect(findRowSummary(0).text()).toBe('Summary from timelog field');
});
it('shows the summary from the timelog note body is not present', () => {
mountComponent({
entries: [baseTimelogMock],
});
expect(findRowSummary(0).text()).toBe('Summary from timelog field');
});
});
});
});