debian-mirror-gitlab/spec/frontend/registry/explorer/components/details_page/details_header_spec.js
2021-04-17 20:07:23 +05:30

253 lines
7.5 KiB
JavaScript

import { GlButton, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { useFakeDate } from 'helpers/fake_date';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import component from '~/registry/explorer/components/details_page/details_header.vue';
import {
UNSCHEDULED_STATUS,
SCHEDULED_STATUS,
ONGOING_STATUS,
UNFINISHED_STATUS,
CLEANUP_DISABLED_TEXT,
CLEANUP_DISABLED_TOOLTIP,
CLEANUP_SCHEDULED_TOOLTIP,
CLEANUP_ONGOING_TOOLTIP,
CLEANUP_UNFINISHED_TOOLTIP,
ROOT_IMAGE_TEXT,
ROOT_IMAGE_TOOLTIP,
} from '~/registry/explorer/constants';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
describe('Details Header', () => {
let wrapper;
const defaultImage = {
name: 'foo',
updatedAt: '2020-11-03T13:29:21Z',
tagsCount: 10,
canDelete: true,
project: {
visibility: 'public',
containerExpirationPolicy: {
enabled: false,
},
},
};
// set the date to Dec 4, 2020
useFakeDate(2020, 11, 4);
const findByTestId = (testId) => wrapper.find(`[data-testid="${testId}"]`);
const findLastUpdatedAndVisibility = () => findByTestId('updated-and-visibility');
const findTitle = () => findByTestId('title');
const findTagsCount = () => findByTestId('tags-count');
const findCleanup = () => findByTestId('cleanup');
const findDeleteButton = () => wrapper.find(GlButton);
const findInfoIcon = () => wrapper.find(GlIcon);
const waitForMetadataItems = async () => {
// Metadata items are printed by a loop in the title-area and it takes two ticks for them to be available
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
};
const mountComponent = (propsData = { image: defaultImage }) => {
wrapper = shallowMount(component, {
propsData,
directives: {
GlTooltip: createMockDirective(),
},
stubs: {
TitleArea,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('image name', () => {
describe('missing image name', () => {
it('root image ', () => {
mountComponent({ image: { ...defaultImage, name: '' } });
expect(findTitle().text()).toBe(ROOT_IMAGE_TEXT);
});
it('has an icon', () => {
mountComponent({ image: { ...defaultImage, name: '' } });
expect(findInfoIcon().exists()).toBe(true);
expect(findInfoIcon().props('name')).toBe('information-o');
});
it('has a tooltip', () => {
mountComponent({ image: { ...defaultImage, name: '' } });
const tooltip = getBinding(findInfoIcon().element, 'gl-tooltip');
expect(tooltip.value).toBe(ROOT_IMAGE_TOOLTIP);
});
});
describe('with image name present', () => {
it('shows image.name ', () => {
mountComponent();
expect(findTitle().text()).toContain('foo');
});
it('has no icon', () => {
mountComponent();
expect(findInfoIcon().exists()).toBe(false);
});
});
});
describe('delete button', () => {
it('exists', () => {
mountComponent();
expect(findDeleteButton().exists()).toBe(true);
});
it('is hidden while loading', () => {
mountComponent({ image: defaultImage, metadataLoading: true });
expect(findDeleteButton().exists()).toBe(false);
});
it('has the correct text', () => {
mountComponent();
expect(findDeleteButton().text()).toBe('Delete');
});
it('has the correct props', () => {
mountComponent();
expect(findDeleteButton().props()).toMatchObject({
variant: 'danger',
disabled: false,
});
});
it('emits the correct event', () => {
mountComponent();
findDeleteButton().vm.$emit('click');
expect(wrapper.emitted('delete')).toEqual([[]]);
});
it.each`
canDelete | disabled | isDisabled
${true} | ${false} | ${false}
${true} | ${true} | ${true}
${false} | ${false} | ${true}
${false} | ${true} | ${true}
`(
'when canDelete is $canDelete and disabled is $disabled is $isDisabled that the button is disabled',
({ canDelete, disabled, isDisabled }) => {
mountComponent({ image: { ...defaultImage, canDelete }, disabled });
expect(findDeleteButton().props('disabled')).toBe(isDisabled);
},
);
});
describe('metadata items', () => {
describe('tags count', () => {
it('when there is more than one tag has the correct text', async () => {
mountComponent();
await waitForMetadataItems();
expect(findTagsCount().props('text')).toBe('10 tags');
});
it('when there is one tag has the correct text', async () => {
mountComponent({ image: { ...defaultImage, tagsCount: 1 } });
await waitForMetadataItems();
expect(findTagsCount().props('text')).toBe('1 tag');
});
it('has the correct icon', async () => {
mountComponent();
await waitForMetadataItems();
expect(findTagsCount().props('icon')).toBe('tag');
});
});
describe('cleanup metadata item', () => {
it('has the correct icon', async () => {
mountComponent();
await waitForMetadataItems();
expect(findCleanup().props('icon')).toBe('expire');
});
it('when the expiration policy is disabled', async () => {
mountComponent();
await waitForMetadataItems();
expect(findCleanup().props()).toMatchObject({
text: CLEANUP_DISABLED_TEXT,
textTooltip: CLEANUP_DISABLED_TOOLTIP,
});
});
it.each`
status | text | tooltip
${UNSCHEDULED_STATUS} | ${'Cleanup will run in 1 month'} | ${''}
${SCHEDULED_STATUS} | ${'Cleanup pending'} | ${CLEANUP_SCHEDULED_TOOLTIP}
${ONGOING_STATUS} | ${'Cleanup in progress'} | ${CLEANUP_ONGOING_TOOLTIP}
${UNFINISHED_STATUS} | ${'Cleanup incomplete'} | ${CLEANUP_UNFINISHED_TOOLTIP}
`(
'when the status is $status the text is $text and the tooltip is $tooltip',
async ({ status, text, tooltip }) => {
mountComponent({
image: {
...defaultImage,
expirationPolicyCleanupStatus: status,
project: {
containerExpirationPolicy: { enabled: true, nextRunAt: '2021-01-03T14:29:21Z' },
},
},
});
await waitForMetadataItems();
expect(findCleanup().props()).toMatchObject({
text,
textTooltip: tooltip,
});
},
);
});
describe('visibility and updated at ', () => {
it('has last updated text', async () => {
mountComponent();
await waitForMetadataItems();
expect(findLastUpdatedAndVisibility().props('text')).toBe('Last updated 1 month ago');
});
describe('visibility icon', () => {
it('shows an eye when the project is public', async () => {
mountComponent();
await waitForMetadataItems();
expect(findLastUpdatedAndVisibility().props('icon')).toBe('eye');
});
it('shows an eye slashed when the project is not public', async () => {
mountComponent({ image: { ...defaultImage, project: { visibility: 'private' } } });
await waitForMetadataItems();
expect(findLastUpdatedAndVisibility().props('icon')).toBe('eye-slash');
});
});
});
});
});