Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-05-23 00:08:01 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-05-23 00:08:01 +0300
commitc50e042a392687730db9b8c2607883485b258ae4 (patch)
tree519b069aa0a400241a2f8dc0f900f09625e3d8ed /spec/frontend/packages_and_registries
parent7e2f555a6dc37839727dee130d8ed4421b680d42 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/packages_and_registries')
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js206
-rw-r--r--spec/frontend/packages_and_registries/package_registry/mock_data.js15
-rw-r--r--spec/frontend/packages_and_registries/package_registry/pages/details_spec.js12
3 files changed, 132 insertions, 101 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
index 1dcac017ccf..5c36dbf9c9c 100644
--- 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
@@ -1,22 +1,34 @@
-import { GlDropdown, GlButton, GlFormCheckbox } from '@gitlab/ui';
-import { nextTick } from 'vue';
+import { GlAlert, GlDropdown, GlButton, GlFormCheckbox, GlLoadingIcon } from '@gitlab/ui';
+import Vue, { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
import { stubComponent } from 'helpers/stub_component';
import { mountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
-import { packageFiles as packageFilesMock } from 'jest/packages_and_registries/package_registry/mock_data';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import { s__ } from '~/locale';
+import {
+ packageFiles as packageFilesMock,
+ packageFilesQuery,
+} 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';
+import getPackageFiles from '~/packages_and_registries/package_registry/graphql/queries/get_package_files.query.graphql';
+
+Vue.use(VueApollo);
+
describe('Package Files', () => {
let wrapper;
+ let apolloProvider;
const findAllRows = () => wrapper.findAllByTestId('file-row');
const findDeleteSelectedButton = () => wrapper.findByTestId('delete-selected');
const findFirstRow = () => extendedWrapper(findAllRows().at(0));
const findSecondRow = () => extendedWrapper(findAllRows().at(1));
+ const findPackageFilesAlert = () => wrapper.findComponent(GlAlert);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
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));
@@ -30,16 +42,23 @@ describe('Package Files', () => {
const [file] = files;
const createComponent = ({
- packageFiles = [file],
+ packageId = '1',
+ packageType = 'NPM',
isLoading = false,
canDelete = true,
stubs,
+ resolver = jest.fn().mockResolvedValue(packageFilesQuery([file])),
} = {}) => {
+ const requestHandlers = [[getPackageFiles, resolver]];
+ apolloProvider = createMockApollo(requestHandlers);
+
wrapper = mountExtended(PackageFiles, {
+ apolloProvider,
propsData: {
canDelete,
isLoading,
- packageFiles,
+ packageId,
+ packageType,
},
stubs: {
GlTable: false,
@@ -49,35 +68,61 @@ describe('Package Files', () => {
};
describe('rows', () => {
- it('renders a single file for an npm package', () => {
+ it('do not get rendered when query is loading', () => {
createComponent();
+ expect(findLoadingIcon().exists()).toBe(true);
+ expect(findDeleteSelectedButton().props('disabled')).toBe(true);
+ });
+
+ it('renders a single file for an npm package', async () => {
+ createComponent();
+ await waitForPromises();
+
expect(findAllRows()).toHaveLength(1);
+ expect(findLoadingIcon().exists()).toBe(false);
});
- it('renders multiple files for a package that contains more than one file', () => {
- createComponent({ packageFiles: files });
+ it('renders multiple files for a package that contains more than one file', async () => {
+ createComponent({ resolver: jest.fn().mockResolvedValue(packageFilesQuery()) });
+ await waitForPromises();
expect(findAllRows()).toHaveLength(2);
});
+
+ it('does not render gl-alert', async () => {
+ createComponent();
+ await waitForPromises();
+
+ expect(findPackageFilesAlert().exists()).toBe(false);
+ });
+
+ it('renders gl-alert if load fails', async () => {
+ createComponent({ resolver: jest.fn().mockRejectedValue() });
+ await waitForPromises();
+
+ expect(findPackageFilesAlert().exists()).toBe(true);
+ expect(findPackageFilesAlert().text()).toBe(
+ s__('PackageRegistry|Something went wrong while fetching package assets.'),
+ );
+ });
});
describe('link', () => {
- it('exists', () => {
+ beforeEach(async () => {
createComponent();
+ await waitForPromises();
+ });
+ it('exists', () => {
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([[]]);
@@ -85,90 +130,43 @@ describe('Package Files', () => {
});
describe('file-icon', () => {
- it('exists', () => {
+ beforeEach(async () => {
createComponent();
+ await waitForPromises();
+ });
+ it('exists', () => {
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', () => {
+ beforeEach(async () => {
createComponent();
+ await waitForPromises();
+ });
+ it('exists', () => {
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', () => {
+ beforeEach(async () => {
createComponent();
+ await waitForPromises();
+ });
+ it('exists', () => {
expect(findFirstActionMenu().exists()).toBe(true);
expect(findFirstActionMenu().props('icon')).toBe('ellipsis_v');
expect(findFirstActionMenu().props('textSrOnly')).toBe(true);
@@ -178,14 +176,10 @@ describe('Package Files', () => {
describe('menu items', () => {
describe('delete file', () => {
it('exists', () => {
- createComponent();
-
expect(findActionMenuDelete().exists()).toBe(true);
});
it('emits a delete event when clicked', async () => {
- createComponent();
-
await findActionMenuDelete().trigger('click');
const [[items]] = wrapper.emitted('delete-files');
@@ -199,8 +193,9 @@ describe('Package Files', () => {
describe('when the user can not delete', () => {
const canDelete = false;
- it('does not exist', () => {
+ it('does not exist', async () => {
createComponent({ canDelete });
+ await waitForPromises();
expect(findFirstActionMenu().exists()).toBe(false);
});
@@ -209,22 +204,33 @@ describe('Package Files', () => {
describe('multi select', () => {
describe('when user can delete', () => {
- it('delete selected button exists & is disabled', () => {
+ it('delete selected button exists & is disabled', async () => {
createComponent();
+ await waitForPromises();
expect(findDeleteSelectedButton().exists()).toBe(true);
expect(findDeleteSelectedButton().text()).toMatchInterpolatedText('Delete selected');
expect(findDeleteSelectedButton().props('disabled')).toBe(true);
});
- it('delete selected button exists & is disabled when isLoading prop is true', () => {
- createComponent({ isLoading: true });
+ it('delete selected button exists & is disabled when isLoading prop is true', async () => {
+ createComponent();
+ await waitForPromises();
+ const first = findAllRowCheckboxes().at(0);
+
+ await first.setChecked(true);
+
+ expect(findDeleteSelectedButton().props('disabled')).toBe(false);
+
+ await wrapper.setProps({ isLoading: true });
expect(findDeleteSelectedButton().props('disabled')).toBe(true);
+ expect(findLoadingIcon().exists()).toBe(true);
});
- it('checkboxes to select file are visible', () => {
- createComponent({ packageFiles: files });
+ it('checkboxes to select file are visible', async () => {
+ createComponent({ resolver: jest.fn().mockResolvedValue(packageFilesQuery()) });
+ await waitForPromises();
expect(findCheckAllCheckbox().exists()).toBe(true);
expect(findAllRowCheckboxes()).toHaveLength(2);
@@ -232,6 +238,7 @@ describe('Package Files', () => {
it('selecting a checkbox enables delete selected button', async () => {
createComponent();
+ await waitForPromises();
const first = findAllRowCheckboxes().at(0);
@@ -244,7 +251,8 @@ describe('Package Files', () => {
it('will toggle between selecting all and deselecting all files', async () => {
const getChecked = () => findAllRowCheckboxes().filter((x) => x.element.checked === true);
- createComponent({ packageFiles: files });
+ createComponent({ resolver: jest.fn().mockResolvedValue(packageFilesQuery()) });
+ await waitForPromises();
expect(getChecked()).toHaveLength(0);
@@ -262,9 +270,10 @@ describe('Package Files', () => {
expect(findCheckAllCheckbox().props('indeterminate')).toBe(state);
createComponent({
- packageFiles: files,
+ resolver: jest.fn().mockResolvedValue(packageFilesQuery()),
stubs: { GlFormCheckbox: stubComponent(GlFormCheckbox, { props: ['indeterminate'] }) },
});
+ await waitForPromises();
expectIndeterminateState(false);
@@ -288,6 +297,7 @@ describe('Package Files', () => {
it('emits a delete event when selected', async () => {
createComponent();
+ await waitForPromises();
const first = findAllRowCheckboxes().at(0);
@@ -301,7 +311,8 @@ describe('Package Files', () => {
});
it('emits delete event with both items when all are selected', async () => {
- createComponent({ packageFiles: files });
+ createComponent({ resolver: jest.fn().mockResolvedValue(packageFilesQuery()) });
+ await waitForPromises();
await findCheckAllCheckbox().setChecked(true);
@@ -315,14 +326,16 @@ describe('Package Files', () => {
describe('when user cannot delete', () => {
const canDelete = false;
- it('delete selected button does not exist', () => {
+ it('delete selected button does not exist', async () => {
createComponent({ canDelete });
+ await waitForPromises();
expect(findDeleteSelectedButton().exists()).toBe(false);
});
- it('checkboxes to select file are not visible', () => {
- createComponent({ packageFiles: files, canDelete });
+ it('checkboxes to select file are not visible', async () => {
+ createComponent({ resolver: jest.fn().mockResolvedValue(packageFilesQuery()), canDelete });
+ await waitForPromises();
expect(findCheckAllCheckbox().exists()).toBe(false);
expect(findAllRowCheckboxes()).toHaveLength(0);
@@ -332,24 +345,27 @@ describe('Package Files', () => {
describe('additional details', () => {
describe('details toggle button', () => {
- it('exists', () => {
+ it('exists', async () => {
createComponent();
+ await waitForPromises();
expect(findFirstToggleDetailsButton().exists()).toBe(true);
});
- it('is hidden when no details is present', () => {
+ it('is hidden when no details is present', async () => {
const { ...noShaFile } = file;
noShaFile.fileSha256 = null;
noShaFile.fileMd5 = null;
noShaFile.fileSha1 = null;
- createComponent({ packageFiles: [noShaFile] });
+ createComponent({ resolver: jest.fn().mockResolvedValue(packageFilesQuery([noShaFile])) });
+ await waitForPromises();
expect(findFirstToggleDetailsButton().exists()).toBe(false);
});
it('toggles the details row', async () => {
createComponent();
+ await waitForPromises();
expect(findFirstToggleDetailsButton().props('icon')).toBe('chevron-down');
@@ -380,6 +396,7 @@ describe('Package Files', () => {
${'sha-1'} | ${'SHA-1'} | ${'be93151dc23ac34a82752444556fe79b32c7a1ad'}
`('has a $title row', async ({ selector, title, sha }) => {
createComponent();
+ await waitForPromises();
await showShaFiles();
@@ -393,7 +410,8 @@ describe('Package Files', () => {
const { ...missingMd5 } = file;
missingMd5.fileMd5 = null;
- createComponent({ packageFiles: [missingMd5] });
+ createComponent({ resolver: jest.fn().mockResolvedValue(packageFilesQuery([missingMd5])) });
+ await waitForPromises();
await showShaFiles();
diff --git a/spec/frontend/packages_and_registries/package_registry/mock_data.js b/spec/frontend/packages_and_registries/package_registry/mock_data.js
index 5fb53566d4e..fa6a69b1a1f 100644
--- a/spec/frontend/packages_and_registries/package_registry/mock_data.js
+++ b/spec/frontend/packages_and_registries/package_registry/mock_data.js
@@ -257,7 +257,7 @@ export const packageDetailsQuery = ({
pageInfo: {
hasNextPage: true,
},
- nodes: packageFiles(),
+ nodes: packageFiles().map(({ id, size }) => ({ id, size })),
__typename: 'PackageFileConnection',
},
versions: {
@@ -285,6 +285,19 @@ export const packagePipelinesQuery = (pipelines = packagePipelines()) => ({
},
});
+export const packageFilesQuery = (files = packageFiles()) => ({
+ data: {
+ package: {
+ id: 'gid://gitlab/Packages::Package/111',
+ packageFiles: {
+ nodes: files,
+ __typename: 'PackageFileConnection',
+ },
+ __typename: 'PackageDetailsType',
+ },
+ },
+});
+
export const emptyPackageDetailsQuery = () => ({
data: {
package: {
diff --git a/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
index 0962b4fa757..8b15dfd7d4a 100644
--- a/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
@@ -328,18 +328,18 @@ describe('PackagesApp', () => {
describe('package files', () => {
it('renders the package files component and has the right props', async () => {
- const expectedFile = { ...packageFiles()[0] };
- // eslint-disable-next-line no-underscore-dangle
- delete expectedFile.__typename;
createComponent();
await waitForPromises();
expect(findPackageFiles().exists()).toBe(true);
- expect(findPackageFiles().props('packageFiles')[0]).toMatchObject(expectedFile);
- expect(findPackageFiles().props('canDelete')).toBe(packageData().canDestroy);
- expect(findPackageFiles().props('isLoading')).toEqual(false);
+ expect(findPackageFiles().props()).toMatchObject({
+ canDelete: packageData().canDestroy,
+ isLoading: false,
+ packageId: packageData().id,
+ packageType: packageData().packageType,
+ });
});
it('does not render the package files table when the package is composer', async () => {