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>2021-04-21 02:50:22 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-04-21 02:50:22 +0300
commit9dc93a4519d9d5d7be48ff274127136236a3adb3 (patch)
tree70467ae3692a0e35e5ea56bcb803eb512a10bedb /spec/frontend/packages
parent4b0f34b6d759d6299322b3a54453e930c6121ff0 (diff)
Add latest changes from gitlab-org/gitlab@13-11-stable-eev13.11.0-rc43
Diffstat (limited to 'spec/frontend/packages')
-rw-r--r--spec/frontend/packages/details/store/getters_spec.js2
-rw-r--r--spec/frontend/packages/list/components/__snapshots__/packages_list_app_spec.js.snap10
-rw-r--r--spec/frontend/packages/list/components/packages_list_app_spec.js133
-rw-r--r--spec/frontend/packages/list/components/packages_search_spec.js29
-rw-r--r--spec/frontend/packages/list/components/packages_title_spec.js18
-rw-r--r--spec/frontend/packages/list/utils_spec.js11
-rw-r--r--spec/frontend/packages/mock_data.js17
-rw-r--r--spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap15
-rw-r--r--spec/frontend/packages/shared/components/package_icon_and_name_spec.js32
-rw-r--r--spec/frontend/packages/shared/components/package_list_row_spec.js41
-rw-r--r--spec/frontend/packages/shared/utils_spec.js1
11 files changed, 250 insertions, 59 deletions
diff --git a/spec/frontend/packages/details/store/getters_spec.js b/spec/frontend/packages/details/store/getters_spec.js
index f12b75d3b70..005adece56e 100644
--- a/spec/frontend/packages/details/store/getters_spec.js
+++ b/spec/frontend/packages/details/store/getters_spec.js
@@ -27,6 +27,7 @@ import {
mockPipelineInfo,
mavenPackage as packageWithoutBuildInfo,
pypiPackage,
+ rubygemsPackage,
} from '../../mock_data';
import {
generateMavenCommand,
@@ -104,6 +105,7 @@ describe('Getters PackageDetails Store', () => {
${npmPackage} | ${'npm'}
${nugetPackage} | ${'NuGet'}
${pypiPackage} | ${'PyPI'}
+ ${rubygemsPackage} | ${'RubyGems'}
`(`package type`, ({ packageEntity, expectedResult }) => {
beforeEach(() => setupState({ packageEntity }));
diff --git a/spec/frontend/packages/list/components/__snapshots__/packages_list_app_spec.js.snap b/spec/frontend/packages/list/components/__snapshots__/packages_list_app_spec.js.snap
index 3f17731584c..07aba62fef6 100644
--- a/spec/frontend/packages/list/components/__snapshots__/packages_list_app_spec.js.snap
+++ b/spec/frontend/packages/list/components/__snapshots__/packages_list_app_spec.js.snap
@@ -2,11 +2,11 @@
exports[`packages_list_app renders 1`] = `
<div>
- <package-title-stub
- packagehelpurl="foo"
+ <div
+ help-url="foo"
/>
- <package-search-stub />
+ <div />
<div>
<section
@@ -52,7 +52,9 @@ exports[`packages_list_app renders 1`] = `
with GitLab.
</p>
- <div>
+ <div
+ class="gl-display-flex gl-flex-wrap gl-justify-content-center"
+ >
<!---->
<!---->
diff --git a/spec/frontend/packages/list/components/packages_list_app_spec.js b/spec/frontend/packages/list/components/packages_list_app_spec.js
index 6862d23c4ff..4de2dd0789e 100644
--- a/spec/frontend/packages/list/components/packages_list_app_spec.js
+++ b/spec/frontend/packages/list/components/packages_list_app_spec.js
@@ -3,10 +3,11 @@ import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import createFlash from '~/flash';
import * as commonUtils from '~/lib/utils/common_utils';
-import PackageSearch from '~/packages/list/components/package_search.vue';
import PackageListApp from '~/packages/list/components/packages_list_app.vue';
import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '~/packages/list/constants';
import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants';
+import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
+import * as packageUtils from '~/packages_and_registries/shared/utils';
jest.mock('~/lib/utils/common_utils');
jest.mock('~/flash');
@@ -24,10 +25,19 @@ describe('packages_list_app', () => {
};
const GlLoadingIcon = { name: 'gl-loading-icon', template: '<div>loading</div>' };
+ // we need to manually stub dynamic imported components because shallowMount is not able to stub them automatically. See: https://github.com/vuejs/vue-test-utils/issues/1279
+ const PackageSearch = { name: 'PackageSearch', template: '<div></div>' };
+ const PackageTitle = { name: 'PackageTitle', template: '<div></div>' };
+ const InfrastructureTitle = { name: 'InfrastructureTitle', template: '<div></div>' };
+ const InfrastructureSearch = { name: 'InfrastructureSearch', template: '<div></div>' };
+
const emptyListHelpUrl = 'helpUrl';
const findEmptyState = () => wrapper.find(GlEmptyState);
const findListComponent = () => wrapper.find(PackageList);
const findPackageSearch = () => wrapper.find(PackageSearch);
+ const findPackageTitle = () => wrapper.find(PackageTitle);
+ const findInfrastructureTitle = () => wrapper.find(InfrastructureTitle);
+ const findInfrastructureSearch = () => wrapper.find(InfrastructureSearch);
const createStore = (filter = []) => {
store = new Vuex.Store({
@@ -45,7 +55,7 @@ describe('packages_list_app', () => {
store.dispatch = jest.fn();
};
- const mountComponent = () => {
+ const mountComponent = (provide) => {
wrapper = shallowMount(PackageListApp, {
localVue,
store,
@@ -55,12 +65,18 @@ describe('packages_list_app', () => {
PackageList,
GlSprintf,
GlLink,
+ PackageSearch,
+ PackageTitle,
+ InfrastructureTitle,
+ InfrastructureSearch,
},
+ provide,
});
};
beforeEach(() => {
createStore();
+ jest.spyOn(packageUtils, 'getQueryParams').mockReturnValue({});
});
afterEach(() => {
@@ -72,25 +88,6 @@ describe('packages_list_app', () => {
expect(wrapper.element).toMatchSnapshot();
});
- describe('empty state', () => {
- it('generate the correct empty list link', () => {
- mountComponent();
-
- const link = findListComponent().find(GlLink);
-
- expect(link.attributes('href')).toBe(emptyListHelpUrl);
- expect(link.text()).toBe('publish and share your packages');
- });
-
- it('includes the right content on the default tab', () => {
- mountComponent();
-
- const heading = findEmptyState().find('h1');
-
- expect(heading.text()).toBe('There are no packages yet');
- });
- });
-
it('call requestPackagesList on page:changed', () => {
mountComponent();
store.dispatch.mockClear();
@@ -108,10 +105,75 @@ describe('packages_list_app', () => {
expect(store.dispatch).toHaveBeenCalledWith('requestDeletePackage', 'foo');
});
- it('does not call requestPackagesList two times on render', () => {
+ it('does call requestPackagesList only one time on render', () => {
mountComponent();
- expect(store.dispatch).toHaveBeenCalledTimes(1);
+ expect(store.dispatch).toHaveBeenCalledTimes(3);
+ expect(store.dispatch).toHaveBeenNthCalledWith(1, 'setSorting', expect.any(Object));
+ expect(store.dispatch).toHaveBeenNthCalledWith(2, 'setFilter', expect.any(Array));
+ expect(store.dispatch).toHaveBeenNthCalledWith(3, 'requestPackagesList');
+ });
+
+ describe('url query string handling', () => {
+ const defaultQueryParamsMock = {
+ search: [1, 2],
+ type: 'npm',
+ sort: 'asc',
+ orderBy: 'created',
+ };
+
+ it('calls setSorting with the query string based sorting', () => {
+ jest.spyOn(packageUtils, 'getQueryParams').mockReturnValue(defaultQueryParamsMock);
+
+ mountComponent();
+
+ expect(store.dispatch).toHaveBeenNthCalledWith(1, 'setSorting', {
+ orderBy: defaultQueryParamsMock.orderBy,
+ sort: defaultQueryParamsMock.sort,
+ });
+ });
+
+ it('calls setFilter with the query string based filters', () => {
+ jest.spyOn(packageUtils, 'getQueryParams').mockReturnValue(defaultQueryParamsMock);
+
+ mountComponent();
+
+ expect(store.dispatch).toHaveBeenNthCalledWith(2, 'setFilter', [
+ { type: 'type', value: { data: defaultQueryParamsMock.type } },
+ { type: FILTERED_SEARCH_TERM, value: { data: defaultQueryParamsMock.search[0] } },
+ { type: FILTERED_SEARCH_TERM, value: { data: defaultQueryParamsMock.search[1] } },
+ ]);
+ });
+
+ it('calls setSorting and setFilters with the results of extractFilterAndSorting', () => {
+ jest
+ .spyOn(packageUtils, 'extractFilterAndSorting')
+ .mockReturnValue({ filters: ['foo'], sorting: { sort: 'desc' } });
+
+ mountComponent();
+
+ expect(store.dispatch).toHaveBeenNthCalledWith(1, 'setSorting', { sort: 'desc' });
+ expect(store.dispatch).toHaveBeenNthCalledWith(2, 'setFilter', ['foo']);
+ });
+ });
+
+ describe('empty state', () => {
+ it('generate the correct empty list link', () => {
+ mountComponent();
+
+ const link = findListComponent().find(GlLink);
+
+ expect(link.attributes('href')).toBe(emptyListHelpUrl);
+ expect(link.text()).toBe('publish and share your packages');
+ });
+
+ it('includes the right content on the default tab', () => {
+ mountComponent();
+
+ const heading = findEmptyState().find('h1');
+
+ expect(heading.text()).toBe('There are no packages yet');
+ });
});
describe('filter without results', () => {
@@ -145,6 +207,31 @@ describe('packages_list_app', () => {
});
});
+ describe('Infrastructure config', () => {
+ it('defaults to package registry components', () => {
+ mountComponent();
+
+ expect(findPackageSearch().exists()).toBe(true);
+ expect(findPackageTitle().exists()).toBe(true);
+
+ expect(findInfrastructureTitle().exists()).toBe(false);
+ expect(findInfrastructureSearch().exists()).toBe(false);
+ });
+
+ it('mount different component based on the provided values', () => {
+ mountComponent({
+ titleComponent: 'InfrastructureTitle',
+ searchComponent: 'InfrastructureSearch',
+ });
+
+ expect(findPackageSearch().exists()).toBe(false);
+ expect(findPackageTitle().exists()).toBe(false);
+
+ expect(findInfrastructureTitle().exists()).toBe(true);
+ expect(findInfrastructureSearch().exists()).toBe(true);
+ });
+ });
+
describe('delete alert handling', () => {
const { location } = window.location;
const search = `?${SHOW_DELETE_SUCCESS_ALERT}=true`;
diff --git a/spec/frontend/packages/list/components/packages_search_spec.js b/spec/frontend/packages/list/components/packages_search_spec.js
index 9b62dde8d2b..30fad74b493 100644
--- a/spec/frontend/packages/list/components/packages_search_spec.js
+++ b/spec/frontend/packages/list/components/packages_search_spec.js
@@ -2,8 +2,9 @@ import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import component from '~/packages/list/components/package_search.vue';
import PackageTypeToken from '~/packages/list/components/tokens/package_type_token.vue';
-import getTableHeaders from '~/packages/list/utils';
+import { sortableFields } from '~/packages/list/utils';
import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
+import UrlSync from '~/vue_shared/components/url_sync.vue';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -12,7 +13,8 @@ describe('Package Search', () => {
let wrapper;
let store;
- const findRegistrySearch = () => wrapper.find(RegistrySearch);
+ const findRegistrySearch = () => wrapper.findComponent(RegistrySearch);
+ const findUrlSync = () => wrapper.findComponent(UrlSync);
const createStore = (isGroupPage) => {
const state = {
@@ -37,6 +39,9 @@ describe('Package Search', () => {
wrapper = shallowMount(component, {
localVue,
store,
+ stubs: {
+ UrlSync,
+ },
});
};
@@ -55,7 +60,7 @@ describe('Package Search', () => {
tokens: expect.arrayContaining([
expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
]),
- sortableFields: getTableHeaders(),
+ sortableFields: sortableFields(),
});
});
@@ -72,7 +77,7 @@ describe('Package Search', () => {
tokens: expect.arrayContaining([
expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
]),
- sortableFields: getTableHeaders(isGroupPage),
+ sortableFields: sortableFields(isGroupPage),
});
});
@@ -104,4 +109,20 @@ describe('Package Search', () => {
expect(wrapper.emitted('update')).toEqual([[]]);
});
+
+ it('has a UrlSync component', () => {
+ mountComponent();
+
+ expect(findUrlSync().exists()).toBe(true);
+ });
+
+ it('on query:changed calls updateQuery from UrlSync', () => {
+ jest.spyOn(UrlSync.methods, 'updateQuery').mockImplementation(() => {});
+
+ mountComponent();
+
+ findRegistrySearch().vm.$emit('query:changed');
+
+ expect(UrlSync.methods.updateQuery).toHaveBeenCalled();
+ });
});
diff --git a/spec/frontend/packages/list/components/packages_title_spec.js b/spec/frontend/packages/list/components/packages_title_spec.js
index 3716e8daa7c..a17f72e3133 100644
--- a/spec/frontend/packages/list/components/packages_title_spec.js
+++ b/spec/frontend/packages/list/components/packages_title_spec.js
@@ -11,7 +11,7 @@ describe('PackageTitle', () => {
const findTitleArea = () => wrapper.find(TitleArea);
const findMetadataItem = () => wrapper.find(MetadataItem);
- const mountComponent = (propsData = { packageHelpUrl: 'foo' }) => {
+ const mountComponent = (propsData = { helpUrl: 'foo' }) => {
wrapper = shallowMount(PackageTitle, {
store,
propsData,
@@ -44,15 +44,15 @@ describe('PackageTitle', () => {
});
describe.each`
- packagesCount | exist | text
- ${null} | ${false} | ${''}
- ${undefined} | ${false} | ${''}
- ${0} | ${true} | ${'0 Packages'}
- ${1} | ${true} | ${'1 Package'}
- ${2} | ${true} | ${'2 Packages'}
- `('when packagesCount is $packagesCount metadata item', ({ packagesCount, exist, text }) => {
+ count | exist | text
+ ${null} | ${false} | ${''}
+ ${undefined} | ${false} | ${''}
+ ${0} | ${true} | ${'0 Packages'}
+ ${1} | ${true} | ${'1 Package'}
+ ${2} | ${true} | ${'2 Packages'}
+ `('when count is $count metadata item', ({ count, exist, text }) => {
beforeEach(() => {
- mountComponent({ packagesCount, packageHelpUrl: 'foo' });
+ mountComponent({ count, helpUrl: 'foo' });
});
it(`is ${exist} that it exists`, () => {
diff --git a/spec/frontend/packages/list/utils_spec.js b/spec/frontend/packages/list/utils_spec.js
index 5bcc3784752..4e4f7b8a723 100644
--- a/spec/frontend/packages/list/utils_spec.js
+++ b/spec/frontend/packages/list/utils_spec.js
@@ -1,6 +1,15 @@
-import { getNewPaginationPage } from '~/packages/list/utils';
+import { SORT_FIELDS } from '~/packages/list/constants';
+import { getNewPaginationPage, sortableFields } from '~/packages/list/utils';
describe('Packages list utils', () => {
+ describe('sortableFields', () => {
+ it('returns the correct list when is a project page', () => {
+ expect(sortableFields()).toEqual(SORT_FIELDS.filter((f) => f.orderBy !== 'project_path'));
+ });
+ it('returns the full list on the group page', () => {
+ expect(sortableFields(true)).toEqual(SORT_FIELDS);
+ });
+ });
describe('packageTypeDisplay', () => {
it('returns the current page when total items exceeds pagniation', () => {
expect(getNewPaginationPage(2, 20, 21)).toBe(2);
diff --git a/spec/frontend/packages/mock_data.js b/spec/frontend/packages/mock_data.js
index fbc167729d9..06009daba54 100644
--- a/spec/frontend/packages/mock_data.js
+++ b/spec/frontend/packages/mock_data.js
@@ -134,6 +134,23 @@ export const nugetPackage = {
},
};
+export const rubygemsPackage = {
+ created_at: '2015-12-10',
+ id: 4,
+ name: 'RubyGem1',
+ package_files: [],
+ package_type: 'rubygems',
+ project_id: 1,
+ tags: [],
+ updated_at: '2015-12-10',
+ version: '1.0.0',
+ rubygems_metadatum: {
+ author: 'Fake Name',
+ summary: 'My gem',
+ email: 'tanuki@fake.com',
+ },
+};
+
export const pypiPackage = {
created_at: '2015-12-10',
id: 5,
diff --git a/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap b/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
index 77095f7c611..03b98478f3e 100644
--- a/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
+++ b/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
@@ -51,20 +51,7 @@ exports[`packages_list_row renders 1`] = `
<!---->
- <div
- class="d-flex align-items-center"
- data-testid="package-type"
- >
- <gl-icon-stub
- class="gl-ml-3 gl-mr-2"
- name="package"
- size="16"
- />
-
- <span>
- Maven
- </span>
- </div>
+ <div />
<package-path-stub
path="foo/bar/baz"
diff --git a/spec/frontend/packages/shared/components/package_icon_and_name_spec.js b/spec/frontend/packages/shared/components/package_icon_and_name_spec.js
new file mode 100644
index 00000000000..c96a570a29c
--- /dev/null
+++ b/spec/frontend/packages/shared/components/package_icon_and_name_spec.js
@@ -0,0 +1,32 @@
+import { GlIcon } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import PackageIconAndName from '~/packages/shared/components/package_icon_and_name.vue';
+
+describe('PackageIconAndName', () => {
+ let wrapper;
+
+ const findIcon = () => wrapper.find(GlIcon);
+
+ const mountComponent = () => {
+ wrapper = shallowMount(PackageIconAndName, {
+ slots: {
+ default: 'test',
+ },
+ });
+ };
+
+ it('has an icon', () => {
+ mountComponent();
+
+ const icon = findIcon();
+
+ expect(icon.exists()).toBe(true);
+ expect(icon.props('name')).toBe('package');
+ });
+
+ it('renders the slot content', () => {
+ mountComponent();
+
+ expect(wrapper.text()).toBe('test');
+ });
+});
diff --git a/spec/frontend/packages/shared/components/package_list_row_spec.js b/spec/frontend/packages/shared/components/package_list_row_spec.js
index 1c0ef7e3539..fd54cd0f25d 100644
--- a/spec/frontend/packages/shared/components/package_list_row_spec.js
+++ b/spec/frontend/packages/shared/components/package_list_row_spec.js
@@ -1,7 +1,9 @@
import { shallowMount } from '@vue/test-utils';
+
import PackagesListRow from '~/packages/shared/components/package_list_row.vue';
import PackagePath from '~/packages/shared/components/package_path.vue';
import PackageTags from '~/packages/shared/components/package_tags.vue';
+
import ListItem from '~/vue_shared/components/registry/list_item.vue';
import { packageList } from '../../mock_data';
@@ -11,20 +13,30 @@ describe('packages_list_row', () => {
const [packageWithoutTags, packageWithTags] = packageList;
+ const InfrastructureIconAndName = { name: 'InfrastructureIconAndName', template: '<div></div>' };
+ const PackageIconAndName = { name: 'PackageIconAndName', template: '<div></div>' };
+
const findPackageTags = () => wrapper.find(PackageTags);
const findPackagePath = () => wrapper.find(PackagePath);
const findDeleteButton = () => wrapper.find('[data-testid="action-delete"]');
- const findPackageType = () => wrapper.find('[data-testid="package-type"]');
+ const findPackageIconAndName = () => wrapper.find(PackageIconAndName);
+ const findInfrastructureIconAndName = () => wrapper.find(InfrastructureIconAndName);
const mountComponent = ({
isGroup = false,
packageEntity = packageWithoutTags,
showPackageType = true,
disableDelete = false,
+ provide,
} = {}) => {
wrapper = shallowMount(PackagesListRow, {
store,
- stubs: { ListItem },
+ provide,
+ stubs: {
+ ListItem,
+ InfrastructureIconAndName,
+ PackageIconAndName,
+ },
propsData: {
packageLink: 'foo',
packageEntity,
@@ -72,13 +84,13 @@ describe('packages_list_row', () => {
it('shows the type when set', () => {
mountComponent();
- expect(findPackageType().exists()).toBe(true);
+ expect(findPackageIconAndName().exists()).toBe(true);
});
it('does not show the type when not set', () => {
mountComponent({ showPackageType: false });
- expect(findPackageType().exists()).toBe(false);
+ expect(findPackageIconAndName().exists()).toBe(false);
});
});
@@ -113,4 +125,25 @@ describe('packages_list_row', () => {
expect(wrapper.emitted('packageToDelete')[0]).toEqual([packageWithoutTags]);
});
});
+
+ describe('Infrastructure config', () => {
+ it('defaults to package registry components', () => {
+ mountComponent();
+
+ expect(findPackageIconAndName().exists()).toBe(true);
+ expect(findInfrastructureIconAndName().exists()).toBe(false);
+ });
+
+ it('mounts different component based on the provided values', () => {
+ mountComponent({
+ provide: {
+ iconComponent: 'InfrastructureIconAndName',
+ },
+ });
+
+ expect(findPackageIconAndName().exists()).toBe(false);
+
+ expect(findInfrastructureIconAndName().exists()).toBe(true);
+ });
+ });
});
diff --git a/spec/frontend/packages/shared/utils_spec.js b/spec/frontend/packages/shared/utils_spec.js
index 4a95def1bef..463e4a4febb 100644
--- a/spec/frontend/packages/shared/utils_spec.js
+++ b/spec/frontend/packages/shared/utils_spec.js
@@ -38,6 +38,7 @@ describe('Packages shared utils', () => {
${'npm'} | ${'npm'}
${'nuget'} | ${'NuGet'}
${'pypi'} | ${'PyPI'}
+ ${'rubygems'} | ${'RubyGems'}
${'composer'} | ${'Composer'}
${'foo'} | ${null}
`(`package type`, ({ packageType, expectedResult }) => {