2021-09-04 01:27:46 +05:30
|
|
|
import { GlDropdown, GlButton } from '@gitlab/ui';
|
2021-02-22 17:27:13 +05:30
|
|
|
import { mount } from '@vue/test-utils';
|
2021-09-04 01:27:46 +05:30
|
|
|
import { nextTick } from 'vue/';
|
2021-02-22 17:27:13 +05:30
|
|
|
import stubChildren from 'helpers/stub_children';
|
|
|
|
import component from '~/packages/details/components/package_files.vue';
|
2021-03-11 19:13:27 +05:30
|
|
|
import FileIcon from '~/vue_shared/components/file_icon.vue';
|
|
|
|
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
2021-02-22 17:27:13 +05:30
|
|
|
|
|
|
|
import { npmFiles, mavenFiles } from '../../mock_data';
|
|
|
|
|
|
|
|
describe('Package Files', () => {
|
|
|
|
let wrapper;
|
|
|
|
|
|
|
|
const findAllRows = () => wrapper.findAll('[data-testid="file-row"');
|
|
|
|
const findFirstRow = () => findAllRows().at(0);
|
2021-06-08 01:23:25 +05:30
|
|
|
const findSecondRow = () => findAllRows().at(1);
|
2021-09-04 01:27:46 +05:30
|
|
|
const findFirstRowDownloadLink = () => findFirstRow().find('[data-testid="download-link"]');
|
|
|
|
const findFirstRowCommitLink = () => findFirstRow().find('[data-testid="commit-link"]');
|
|
|
|
const findSecondRowCommitLink = () => findSecondRow().find('[data-testid="commit-link"]');
|
2021-02-22 17:27:13 +05:30
|
|
|
const findFirstRowFileIcon = () => findFirstRow().find(FileIcon);
|
|
|
|
const findFirstRowCreatedAt = () => findFirstRow().find(TimeAgoTooltip);
|
2021-09-04 01:27:46 +05:30
|
|
|
const findFirstActionMenu = () => findFirstRow().findComponent(GlDropdown);
|
|
|
|
const findActionMenuDelete = () => findFirstActionMenu().find('[data-testid="delete-file"]');
|
|
|
|
const findFirstToggleDetailsButton = () => findFirstRow().findComponent(GlButton);
|
|
|
|
const findFirstRowShaComponent = (id) => wrapper.find(`[data-testid="${id}"]`);
|
2021-02-22 17:27:13 +05:30
|
|
|
|
2021-09-04 01:27:46 +05:30
|
|
|
const createComponent = ({ packageFiles = npmFiles, canDelete = true } = {}) => {
|
2021-02-22 17:27:13 +05:30
|
|
|
wrapper = mount(component, {
|
|
|
|
propsData: {
|
|
|
|
packageFiles,
|
2021-09-04 01:27:46 +05:30
|
|
|
canDelete,
|
2021-02-22 17:27:13 +05:30
|
|
|
},
|
|
|
|
stubs: {
|
|
|
|
...stubChildren(component),
|
|
|
|
GlTable: false,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
wrapper.destroy();
|
|
|
|
wrapper = null;
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('rows', () => {
|
|
|
|
it('renders a single file for an npm package', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findAllRows()).toHaveLength(1);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders multiple files for a package that contains more than one file', () => {
|
2021-09-04 01:27:46 +05:30
|
|
|
createComponent({ packageFiles: mavenFiles });
|
2021-02-22 17:27:13 +05:30
|
|
|
|
|
|
|
expect(findAllRows()).toHaveLength(2);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('link', () => {
|
|
|
|
it('exists', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstRowDownloadLink().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('has the correct attrs bound', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstRowDownloadLink().attributes('href')).toBe(npmFiles[0].download_path);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('emits "download-file" event on click', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
findFirstRowDownloadLink().vm.$emit('click');
|
|
|
|
|
|
|
|
expect(wrapper.emitted('download-file')).toEqual([[]]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('file-icon', () => {
|
|
|
|
it('exists', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstRowFileIcon().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('has the correct props bound', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstRowFileIcon().props('fileName')).toBe(npmFiles[0].file_name);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('time-ago tooltip', () => {
|
|
|
|
it('exists', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstRowCreatedAt().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('has the correct props bound', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstRowCreatedAt().props('time')).toBe(npmFiles[0].created_at);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('commit', () => {
|
|
|
|
describe('when package file has a pipeline associated', () => {
|
|
|
|
it('exists', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstRowCommitLink().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('the link points to the commit url', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstRowCommitLink().attributes('href')).toBe(
|
|
|
|
npmFiles[0].pipelines[0].project.commit_url,
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('the text is git_commit_message', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstRowCommitLink().text()).toBe(npmFiles[0].pipelines[0].git_commit_message);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
describe('when package file has no pipeline associated', () => {
|
|
|
|
it('does not exist', () => {
|
2021-09-04 01:27:46 +05:30
|
|
|
createComponent({ packageFiles: mavenFiles });
|
2021-02-22 17:27:13 +05:30
|
|
|
|
|
|
|
expect(findFirstRowCommitLink().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
});
|
2021-06-08 01:23:25 +05:30
|
|
|
|
|
|
|
describe('when only one file lacks an associated pipeline', () => {
|
|
|
|
it('renders the commit when it exists and not otherwise', () => {
|
2021-09-04 01:27:46 +05:30
|
|
|
createComponent({ packageFiles: [npmFiles[0], mavenFiles[0]] });
|
2021-06-08 01:23:25 +05:30
|
|
|
|
|
|
|
expect(findFirstRowCommitLink().exists()).toBe(true);
|
|
|
|
expect(findSecondRowCommitLink().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
});
|
2021-09-04 01:27:46 +05:30
|
|
|
|
|
|
|
describe('action menu', () => {
|
|
|
|
describe('when the user can delete', () => {
|
|
|
|
it('exists', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstActionMenu().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('menu items', () => {
|
|
|
|
describe('delete file', () => {
|
|
|
|
it('exists', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findActionMenuDelete().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('emits a delete event when clicked', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
findActionMenuDelete().vm.$emit('click');
|
|
|
|
|
|
|
|
const [[{ id }]] = wrapper.emitted('delete-file');
|
|
|
|
expect(id).toBe(npmFiles[0].id);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when the user can not delete', () => {
|
|
|
|
const canDelete = false;
|
|
|
|
|
|
|
|
it('does not exist', () => {
|
|
|
|
createComponent({ canDelete });
|
|
|
|
|
|
|
|
expect(findFirstActionMenu().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('additional details', () => {
|
|
|
|
describe('details toggle button', () => {
|
|
|
|
it('exists', () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstToggleDetailsButton().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('is hidden when no details is present', () => {
|
|
|
|
const [{ ...noShaFile }] = npmFiles;
|
|
|
|
noShaFile.file_sha256 = null;
|
|
|
|
noShaFile.file_md5 = null;
|
|
|
|
noShaFile.file_sha1 = null;
|
|
|
|
createComponent({ packageFiles: [noShaFile] });
|
|
|
|
|
|
|
|
expect(findFirstToggleDetailsButton().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('toggles the details row', async () => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
expect(findFirstToggleDetailsButton().props('icon')).toBe('angle-down');
|
|
|
|
|
|
|
|
findFirstToggleDetailsButton().vm.$emit('click');
|
|
|
|
await nextTick();
|
|
|
|
|
|
|
|
expect(findFirstRowShaComponent('sha-256').exists()).toBe(true);
|
|
|
|
expect(findFirstToggleDetailsButton().props('icon')).toBe('angle-up');
|
|
|
|
|
|
|
|
findFirstToggleDetailsButton().vm.$emit('click');
|
|
|
|
await nextTick();
|
|
|
|
|
|
|
|
expect(findFirstRowShaComponent('sha-256').exists()).toBe(false);
|
|
|
|
expect(findFirstToggleDetailsButton().props('icon')).toBe('angle-down');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('file shas', () => {
|
|
|
|
const showShaFiles = () => {
|
|
|
|
findFirstToggleDetailsButton().vm.$emit('click');
|
|
|
|
return nextTick();
|
|
|
|
};
|
|
|
|
|
|
|
|
it.each`
|
|
|
|
selector | title | sha
|
|
|
|
${'sha-256'} | ${'SHA-256'} | ${'file_sha256'}
|
|
|
|
${'md5'} | ${'MD5'} | ${'file_md5'}
|
|
|
|
${'sha-1'} | ${'SHA-1'} | ${'file_sha1'}
|
|
|
|
`('has a $title row', async ({ selector, title, sha }) => {
|
|
|
|
createComponent();
|
|
|
|
|
|
|
|
await showShaFiles();
|
|
|
|
|
|
|
|
expect(findFirstRowShaComponent(selector).props()).toMatchObject({
|
|
|
|
title,
|
|
|
|
sha,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not display a row when the data is missing', async () => {
|
|
|
|
const [{ ...missingMd5 }] = npmFiles;
|
|
|
|
missingMd5.file_md5 = null;
|
|
|
|
|
|
|
|
createComponent({ packageFiles: [missingMd5] });
|
|
|
|
|
|
|
|
await showShaFiles();
|
|
|
|
|
|
|
|
expect(findFirstRowShaComponent('md5').exists()).toBe(false);
|
|
|
|
});
|
|
|
|
});
|
2021-02-22 17:27:13 +05:30
|
|
|
});
|
|
|
|
});
|