summaryrefslogtreecommitdiff
path: root/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js')
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js272
1 files changed, 272 insertions, 0 deletions
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js
new file mode 100644
index 00000000000..042b2026199
--- /dev/null
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js
@@ -0,0 +1,272 @@
+import { GlDropdown, GlButton } from '@gitlab/ui';
+import { nextTick } from 'vue';
+import stubChildren from 'helpers/stub_children';
+import { mountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
+import { packageFiles as packageFilesMock } from 'jest/packages_and_registries/package_registry/mock_data';
+import PackageFiles from '~/packages_and_registries/package_registry/components/details/package_files.vue';
+import FileIcon from '~/vue_shared/components/file_icon.vue';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+
+describe('Package Files', () => {
+ let wrapper;
+
+ const findAllRows = () => wrapper.findAllByTestId('file-row');
+ const findFirstRow = () => extendedWrapper(findAllRows().at(0));
+ const findSecondRow = () => extendedWrapper(findAllRows().at(1));
+ const findFirstRowDownloadLink = () => findFirstRow().findByTestId('download-link');
+ const findFirstRowCommitLink = () => findFirstRow().findByTestId('commit-link');
+ const findSecondRowCommitLink = () => findSecondRow().findByTestId('commit-link');
+ const findFirstRowFileIcon = () => findFirstRow().findComponent(FileIcon);
+ const findFirstRowCreatedAt = () => findFirstRow().findComponent(TimeAgoTooltip);
+ const findFirstActionMenu = () => extendedWrapper(findFirstRow().findComponent(GlDropdown));
+ const findActionMenuDelete = () => findFirstActionMenu().findByTestId('delete-file');
+ const findFirstToggleDetailsButton = () => findFirstRow().findComponent(GlButton);
+ const findFirstRowShaComponent = (id) => wrapper.findByTestId(id);
+
+ const files = packageFilesMock();
+ const [file] = files;
+
+ const createComponent = ({ packageFiles = [file], canDelete = true } = {}) => {
+ wrapper = mountExtended(PackageFiles, {
+ provide: { canDelete },
+ propsData: {
+ packageFiles,
+ },
+ stubs: {
+ ...stubChildren(PackageFiles),
+ GlTable: false,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ 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', () => {
+ createComponent({ packageFiles: files });
+
+ 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(file.downloadPath);
+ });
+
+ 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(file.fileName);
+ });
+ });
+
+ describe('time-ago tooltip', () => {
+ it('exists', () => {
+ createComponent();
+
+ expect(findFirstRowCreatedAt().exists()).toBe(true);
+ });
+
+ it('has the correct props bound', () => {
+ createComponent();
+
+ expect(findFirstRowCreatedAt().props('time')).toBe(file.createdAt);
+ });
+ });
+
+ describe('commit', () => {
+ const withPipeline = {
+ ...file,
+ pipelines: [
+ {
+ sha: 'sha',
+ id: 1,
+ commitPath: 'commitPath',
+ },
+ ],
+ };
+
+ describe('when package file has a pipeline associated', () => {
+ it('exists', () => {
+ createComponent({ packageFiles: [withPipeline] });
+
+ expect(findFirstRowCommitLink().exists()).toBe(true);
+ });
+
+ it('the link points to the commit path', () => {
+ createComponent({ packageFiles: [withPipeline] });
+
+ expect(findFirstRowCommitLink().attributes('href')).toBe(
+ withPipeline.pipelines[0].commitPath,
+ );
+ });
+
+ it('the text is the pipeline sha', () => {
+ createComponent({ packageFiles: [withPipeline] });
+
+ expect(findFirstRowCommitLink().text()).toBe(withPipeline.pipelines[0].sha);
+ });
+ });
+
+ describe('when package file has no pipeline associated', () => {
+ it('does not exist', () => {
+ createComponent();
+
+ expect(findFirstRowCommitLink().exists()).toBe(false);
+ });
+ });
+
+ describe('when only one file lacks an associated pipeline', () => {
+ it('renders the commit when it exists and not otherwise', () => {
+ createComponent({ packageFiles: [withPipeline, file] });
+
+ expect(findFirstRowCommitLink().exists()).toBe(true);
+ expect(findSecondRowCommitLink().exists()).toBe(false);
+ });
+ });
+
+ 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(file.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 } = file;
+ noShaFile.fileSha256 = null;
+ noShaFile.fileMd5 = null;
+ noShaFile.fileSha1 = 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'} | ${'fileSha256'}
+ ${'md5'} | ${'MD5'} | ${'fileMd5'}
+ ${'sha-1'} | ${'SHA-1'} | ${'be93151dc23ac34a82752444556fe79b32c7a1ad'}
+ `('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 } = file;
+ missingMd5.fileMd5 = null;
+
+ createComponent({ packageFiles: [missingMd5] });
+
+ await showShaFiles();
+
+ expect(findFirstRowShaComponent('md5').exists()).toBe(false);
+ });
+ });
+ });
+});