Commit 2a72b51d authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '336498-split-package-and-terraform-registry-codebase' into 'master'

Detach new and old package registry

See merge request gitlab-org/gitlab!74383
parents 4957dd4a b60d2a0e
<script>
import { mapState, mapActions } from 'vuex';
import { s__ } from '~/locale';
import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
import UrlSync from '~/vue_shared/components/url_sync.vue';
import { sortableFields } from '../utils';
import PackageTypeToken from './tokens/package_type_token.vue';
export default {
tokens: [
{
type: 'type',
icon: 'package',
title: s__('PackageRegistry|Type'),
unique: true,
token: PackageTypeToken,
operators: OPERATOR_IS_ONLY,
},
],
components: { RegistrySearch, UrlSync },
computed: {
...mapState({
isGroupPage: (state) => state.config.isGroupPage,
sorting: (state) => state.sorting,
filter: (state) => state.filter,
}),
sortableFields() {
return sortableFields(this.isGroupPage);
},
},
methods: {
...mapActions(['setSorting', 'setFilter']),
updateSorting(newValue) {
this.setSorting(newValue);
this.$emit('update');
},
},
};
</script>
<template>
<url-sync>
<template #default="{ updateQuery }">
<registry-search
:filter="filter"
:sorting="sorting"
:tokens="$options.tokens"
:sortable-fields="sortableFields"
@sorting:changed="updateSorting"
@filter:changed="setFilter"
@filter:submit="$emit('update')"
@query:changed="updateQuery"
/>
</template>
</url-sync>
</template>
<script>
import { n__ } from '~/locale';
import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
import { LIST_INTRO_TEXT, LIST_TITLE_TEXT } from '../constants';
export default {
name: 'PackageTitle',
components: {
TitleArea,
MetadataItem,
},
props: {
count: {
type: Number,
required: false,
default: null,
},
helpUrl: {
type: String,
required: true,
},
},
computed: {
showPackageCount() {
return Number.isInteger(this.count);
},
packageAmountText() {
return n__(`%d Package`, `%d Packages`, this.count);
},
infoMessages() {
return [{ text: LIST_INTRO_TEXT, link: this.helpUrl }];
},
},
i18n: {
LIST_TITLE_TEXT,
},
};
</script>
<template>
<title-area :title="$options.i18n.LIST_TITLE_TEXT" :info-messages="infoMessages">
<template #metadata-amount>
<metadata-item v-if="showPackageCount" icon="package" :text="packageAmountText" />
</template>
</title-area>
</template>
...@@ -7,6 +7,8 @@ import { s__ } from '~/locale'; ...@@ -7,6 +7,8 @@ import { s__ } from '~/locale';
import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants'; import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants';
import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants'; import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
import { getQueryParams, extractFilterAndSorting } from '~/packages_and_registries/shared/utils'; import { getQueryParams, extractFilterAndSorting } from '~/packages_and_registries/shared/utils';
import InfrastructureTitle from '~/packages_and_registries/infrastructure_registry/components/infrastructure_title.vue';
import InfrastructureSearch from '~/packages_and_registries/infrastructure_registry/components/infrastructure_search.vue';
import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '../constants'; import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '../constants';
import PackageList from './packages_list.vue'; import PackageList from './packages_list.vue';
...@@ -16,28 +18,10 @@ export default { ...@@ -16,28 +18,10 @@ export default {
GlLink, GlLink,
GlSprintf, GlSprintf,
PackageList, PackageList,
PackageTitle: () => InfrastructureTitle,
import(/* webpackChunkName: 'package_registry_components' */ './package_title.vue'), InfrastructureSearch,
PackageSearch: () =>
import(/* webpackChunkName: 'package_registry_components' */ './package_search.vue'),
InfrastructureTitle: () =>
import(
/* webpackChunkName: 'infrastructure_registry_components' */ '~/packages_and_registries/infrastructure_registry/components/infrastructure_title.vue'
),
InfrastructureSearch: () =>
import(
/* webpackChunkName: 'infrastructure_registry_components' */ '~/packages_and_registries/infrastructure_registry/components/infrastructure_search.vue'
),
}, },
inject: { inject: {
titleComponent: {
from: 'titleComponent',
default: 'PackageTitle',
},
searchComponent: {
from: 'searchComponent',
default: 'PackageSearch',
},
emptyPageTitle: { emptyPageTitle: {
from: 'emptyPageTitle', from: 'emptyPageTitle',
default: s__('PackageRegistry|There are no packages yet'), default: s__('PackageRegistry|There are no packages yet'),
...@@ -111,8 +95,8 @@ export default { ...@@ -111,8 +95,8 @@ export default {
<template> <template>
<div> <div>
<component :is="titleComponent" :help-url="packageHelpUrl" :count="packagesCount" /> <infrastructure-title :help-url="packageHelpUrl" :count="packagesCount" />
<component :is="searchComponent" @update="requestPackagesList" /> <infrastructure-search @update="requestPackagesList" />
<package-list @page:changed="onPageChanged" @package:delete="onPackageDeleteRequest"> <package-list @page:changed="onPageChanged" @package:delete="onPackageDeleteRequest">
<template #empty-state> <template #empty-state>
......
<script>
import { GlFilteredSearchToken, GlFilteredSearchSuggestion } from '@gitlab/ui';
import { PACKAGE_TYPES } from '../../constants';
export default {
components: {
GlFilteredSearchToken,
GlFilteredSearchSuggestion,
},
PACKAGE_TYPES,
};
</script>
<template>
<gl-filtered-search-token v-bind="{ ...$attrs }" v-on="$listeners">
<template #suggestions>
<gl-filtered-search-suggestion
v-for="(type, index) in $options.PACKAGE_TYPES"
:key="index"
:value="type.type"
>
{{ type.title }}
</gl-filtered-search-suggestion>
</template>
</gl-filtered-search-token>
</template>
...@@ -96,10 +96,4 @@ export const PACKAGE_TYPES = [ ...@@ -96,10 +96,4 @@ export const PACKAGE_TYPES = [
}, },
]; ];
export const LIST_TITLE_TEXT = s__('PackageRegistry|Package Registry');
export const LIST_INTRO_TEXT = s__(
'PackageRegistry|Publish and share packages for a variety of common package managers. %{docLinkStart}More information%{docLinkEnd}',
);
export const TERRAFORM_SEARCH_TYPE = Object.freeze({ value: { data: 'terraform_module' } }); export const TERRAFORM_SEARCH_TYPE = Object.freeze({ value: { data: 'terraform_module' } });
...@@ -3,6 +3,8 @@ import destroyPackageMutation from '~/packages_and_registries/package_registry/g ...@@ -3,6 +3,8 @@ import destroyPackageMutation from '~/packages_and_registries/package_registry/g
import createFlash from '~/flash'; import createFlash from '~/flash';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '~/packages_and_registries/package_registry/constants';
export default { export default {
props: { props: {
refetchQueries: { refetchQueries: {
...@@ -18,7 +20,7 @@ export default { ...@@ -18,7 +20,7 @@ export default {
}, },
i18n: { i18n: {
errorMessage: s__('PackageRegistry|Something went wrong while deleting the package.'), errorMessage: s__('PackageRegistry|Something went wrong while deleting the package.'),
successMessage: s__('PackageRegistry|Package deleted successfully'), successMessage: DELETE_PACKAGE_SUCCESS_MESSAGE,
}, },
methods: { methods: {
async deletePackage(packageEntity) { async deletePackage(packageEntity) {
......
...@@ -3,12 +3,12 @@ import { GlEmptyState, GlLink, GlSprintf } from '@gitlab/ui'; ...@@ -3,12 +3,12 @@ import { GlEmptyState, GlLink, GlSprintf } from '@gitlab/ui';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { historyReplaceState } from '~/lib/utils/common_utils'; import { historyReplaceState } from '~/lib/utils/common_utils';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '~/packages/list/constants';
import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants'; import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants';
import { import {
PROJECT_RESOURCE_TYPE, PROJECT_RESOURCE_TYPE,
GROUP_RESOURCE_TYPE, GROUP_RESOURCE_TYPE,
GRAPHQL_PAGE_SIZE, GRAPHQL_PAGE_SIZE,
DELETE_PACKAGE_SUCCESS_MESSAGE,
} from '~/packages_and_registries/package_registry/constants'; } from '~/packages_and_registries/package_registry/constants';
import getPackagesQuery from '~/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql'; import getPackagesQuery from '~/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql';
......
<script> <script>
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { sortableFields } from '~/packages/list/utils'; import { sortableFields } from '~/packages_and_registries/package_registry/utils';
import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants'; import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue'; import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
import UrlSync from '~/vue_shared/components/url_sync.vue'; import UrlSync from '~/vue_shared/components/url_sync.vue';
......
<script> <script>
import { n__ } from '~/locale'; import { n__, s__ } from '~/locale';
import { LIST_INTRO_TEXT, LIST_TITLE_TEXT } from '~/packages/list/constants';
import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue'; import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue'; import TitleArea from '~/vue_shared/components/registry/title_area.vue';
...@@ -29,11 +28,14 @@ export default { ...@@ -29,11 +28,14 @@ export default {
return n__(`%d Package`, `%d Packages`, this.count); return n__(`%d Package`, `%d Packages`, this.count);
}, },
infoMessages() { infoMessages() {
return [{ text: LIST_INTRO_TEXT, link: this.helpUrl }]; return [{ text: this.$options.i18n.LIST_INTRO_TEXT, link: this.helpUrl }];
}, },
}, },
i18n: { i18n: {
LIST_TITLE_TEXT, LIST_TITLE_TEXT: s__('PackageRegistry|Package Registry'),
LIST_INTRO_TEXT: s__(
'PackageRegistry|Publish and share packages for a variety of common package managers. %{docLinkStart}More information%{docLinkEnd}',
),
}, },
}; };
</script> </script>
......
<script> <script>
import { GlFilteredSearchToken, GlFilteredSearchSuggestion } from '@gitlab/ui'; import { GlFilteredSearchToken, GlFilteredSearchSuggestion } from '@gitlab/ui';
import { PACKAGE_TYPES } from '~/packages/list/constants'; import { PACKAGE_TYPES } from '~/packages_and_registries/package_registry/constants';
export default { export default {
components: { components: {
...@@ -17,9 +17,9 @@ export default { ...@@ -17,9 +17,9 @@ export default {
<gl-filtered-search-suggestion <gl-filtered-search-suggestion
v-for="(type, index) in $options.PACKAGE_TYPES" v-for="(type, index) in $options.PACKAGE_TYPES"
:key="index" :key="index"
:value="type.type" :value="type"
> >
{{ type.title }} {{ type }}
</gl-filtered-search-suggestion> </gl-filtered-search-suggestion>
</template> </template>
</gl-filtered-search-token> </gl-filtered-search-token>
......
import { s__ } from '~/locale'; import { s__, __ } from '~/locale';
export const PACKAGE_TYPE_CONAN = 'CONAN'; export const PACKAGE_TYPE_CONAN = 'CONAN';
export const PACKAGE_TYPE_MAVEN = 'MAVEN'; export const PACKAGE_TYPE_MAVEN = 'MAVEN';
...@@ -70,6 +70,8 @@ export const FETCH_PACKAGE_DETAILS_ERROR_MESSAGE = s__( ...@@ -70,6 +70,8 @@ export const FETCH_PACKAGE_DETAILS_ERROR_MESSAGE = s__(
'PackageRegistry|Failed to load the package data', 'PackageRegistry|Failed to load the package data',
); );
export const DELETE_PACKAGE_SUCCESS_MESSAGE = s__('PackageRegistry|Package deleted successfully');
export const PACKAGE_ERROR_STATUS = 'ERROR'; export const PACKAGE_ERROR_STATUS = 'ERROR';
export const PACKAGE_DEFAULT_STATUS = 'DEFAULT'; export const PACKAGE_DEFAULT_STATUS = 'DEFAULT';
export const PACKAGE_HIDDEN_STATUS = 'HIDDEN'; export const PACKAGE_HIDDEN_STATUS = 'HIDDEN';
...@@ -84,3 +86,51 @@ export const INSTANCE_PACKAGE_ENDPOINT_TYPE = 'instance'; ...@@ -84,3 +86,51 @@ export const INSTANCE_PACKAGE_ENDPOINT_TYPE = 'instance';
export const PROJECT_RESOURCE_TYPE = 'project'; export const PROJECT_RESOURCE_TYPE = 'project';
export const GROUP_RESOURCE_TYPE = 'group'; export const GROUP_RESOURCE_TYPE = 'group';
export const GRAPHQL_PAGE_SIZE = 20; export const GRAPHQL_PAGE_SIZE = 20;
export const LIST_KEY_NAME = 'name';
export const LIST_KEY_PROJECT = 'project_path';
export const LIST_KEY_VERSION = 'version';
export const LIST_KEY_PACKAGE_TYPE = 'type';
export const LIST_KEY_CREATED_AT = 'created_at';
export const LIST_LABEL_NAME = __('Name');
export const LIST_LABEL_PROJECT = __('Project');
export const LIST_LABEL_VERSION = __('Version');
export const LIST_LABEL_PACKAGE_TYPE = __('Type');
export const LIST_LABEL_CREATED_AT = __('Published');
export const SORT_FIELDS = [
{
orderBy: LIST_KEY_NAME,
label: LIST_LABEL_NAME,
},
{
orderBy: LIST_KEY_PROJECT,
label: LIST_LABEL_PROJECT,
},
{
orderBy: LIST_KEY_VERSION,
label: LIST_LABEL_VERSION,
},
{
orderBy: LIST_KEY_PACKAGE_TYPE,
label: LIST_LABEL_PACKAGE_TYPE,
},
{
orderBy: LIST_KEY_CREATED_AT,
label: LIST_LABEL_CREATED_AT,
},
];
export const PACKAGE_TYPES = [
s__('PackageRegistry|Composer'),
s__('PackageRegistry|Conan'),
s__('PackageRegistry|Generic'),
s__('PackageRegistry|Maven'),
s__('PackageRegistry|npm'),
s__('PackageRegistry|NuGet'),
s__('PackageRegistry|PyPI'),
s__('PackageRegistry|RubyGems'),
s__('PackageRegistry|Debian'),
s__('PackageRegistry|Helm'),
];
...@@ -11,6 +11,8 @@ import { ...@@ -11,6 +11,8 @@ import {
PACKAGE_TYPE_GENERIC, PACKAGE_TYPE_GENERIC,
PACKAGE_TYPE_DEBIAN, PACKAGE_TYPE_DEBIAN,
PACKAGE_TYPE_HELM, PACKAGE_TYPE_HELM,
LIST_KEY_PROJECT,
SORT_FIELDS,
} from './constants'; } from './constants';
export const getPackageTypeLabel = (packageType) => { export const getPackageTypeLabel = (packageType) => {
...@@ -41,3 +43,6 @@ export const getPackageTypeLabel = (packageType) => { ...@@ -41,3 +43,6 @@ export const getPackageTypeLabel = (packageType) => {
}; };
export const packageTypeToTrackCategory = (type) => `UI::${capitalize(type)}Packages`; export const packageTypeToTrackCategory = (type) => `UI::${capitalize(type)}Packages`;
export const sortableFields = (isGroupPage) =>
SORT_FIELDS.filter((f) => f.orderBy !== LIST_KEY_PROJECT || isGroupPage);
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
exports[`packages_list_app renders 1`] = ` exports[`packages_list_app renders 1`] = `
<div> <div>
<div <infrastructure-title-stub
help-url="foo" helpurl="foo"
/> />
<div /> <infrastructure-search-stub />
<div> <div>
<section <section
......
...@@ -9,6 +9,7 @@ import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '~/packages/list/constants'; ...@@ -9,6 +9,7 @@ import { DELETE_PACKAGE_SUCCESS_MESSAGE } from '~/packages/list/constants';
import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants'; import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants';
import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants'; import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
import * as packageUtils from '~/packages_and_registries/shared/utils'; import * as packageUtils from '~/packages_and_registries/shared/utils';
import InfrastructureSearch from '~/packages_and_registries/infrastructure_registry/components/infrastructure_search.vue';
jest.mock('~/lib/utils/common_utils'); jest.mock('~/lib/utils/common_utils');
jest.mock('~/flash'); jest.mock('~/flash');
...@@ -26,18 +27,9 @@ describe('packages_list_app', () => { ...@@ -26,18 +27,9 @@ describe('packages_list_app', () => {
}; };
const GlLoadingIcon = { name: 'gl-loading-icon', template: '<div>loading</div>' }; 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 emptyListHelpUrl = 'helpUrl';
const findEmptyState = () => wrapper.find(GlEmptyState); const findEmptyState = () => wrapper.find(GlEmptyState);
const findListComponent = () => wrapper.find(PackageList); 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 findInfrastructureSearch = () => wrapper.find(InfrastructureSearch);
const createStore = (filter = []) => { const createStore = (filter = []) => {
...@@ -66,10 +58,6 @@ describe('packages_list_app', () => { ...@@ -66,10 +58,6 @@ describe('packages_list_app', () => {
PackageList, PackageList,
GlSprintf, GlSprintf,
GlLink, GlLink,
PackageSearch,
PackageTitle,
InfrastructureTitle,
InfrastructureSearch,
}, },
provide, provide,
}); });
...@@ -191,48 +179,23 @@ describe('packages_list_app', () => { ...@@ -191,48 +179,23 @@ describe('packages_list_app', () => {
}); });
}); });
describe('Package Search', () => { describe('Search', () => {
it('exists', () => { it('exists', () => {
mountComponent(); mountComponent();
expect(findPackageSearch().exists()).toBe(true); expect(findInfrastructureSearch().exists()).toBe(true);
}); });
it('on update fetches data from the store', () => { it('on update fetches data from the store', () => {
mountComponent(); mountComponent();
store.dispatch.mockClear(); store.dispatch.mockClear();
findPackageSearch().vm.$emit('update'); findInfrastructureSearch().vm.$emit('update');
expect(store.dispatch).toHaveBeenCalledWith('requestPackagesList'); expect(store.dispatch).toHaveBeenCalledWith('requestPackagesList');
}); });
}); });
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', () => { describe('delete alert handling', () => {
const originalLocation = window.location.href; const originalLocation = window.location.href;
const search = `?${SHOW_DELETE_SUCCESS_ALERT}=true`; const search = `?${SHOW_DELETE_SUCCESS_ALERT}=true`;
......
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 { 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);
describe('Package Search', () => {
let wrapper;
let store;
const findRegistrySearch = () => wrapper.findComponent(RegistrySearch);
const findUrlSync = () => wrapper.findComponent(UrlSync);
const createStore = (isGroupPage) => {
const state = {
config: {
isGroupPage,
},
sorting: {
orderBy: 'version',
sort: 'desc',
},
filter: [],
};
store = new Vuex.Store({
state,
});
store.dispatch = jest.fn();
};
const mountComponent = (isGroupPage = false) => {
createStore(isGroupPage);
wrapper = shallowMount(component, {
localVue,
store,
stubs: {
UrlSync,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('has a registry search component', () => {
mountComponent();
expect(findRegistrySearch().exists()).toBe(true);
expect(findRegistrySearch().props()).toMatchObject({
filter: store.state.filter,
sorting: store.state.sorting,
tokens: expect.arrayContaining([
expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
]),
sortableFields: sortableFields(),
});
});
it.each`
isGroupPage | page
${false} | ${'project'}
${true} | ${'group'}
`('in a $page page binds the right props', ({ isGroupPage }) => {
mountComponent(isGroupPage);
expect(findRegistrySearch().props()).toMatchObject({
filter: store.state.filter,
sorting: store.state.sorting,
tokens: expect.arrayContaining([
expect.objectContaining({ token: PackageTypeToken, type: 'type', icon: 'package' }),
]),
sortableFields: sortableFields(isGroupPage),
});
});
it('on sorting:changed emits update event and calls vuex setSorting', () => {
const payload = { sort: 'foo' };
mountComponent();
findRegistrySearch().vm.$emit('sorting:changed', payload);
expect(store.dispatch).toHaveBeenCalledWith('setSorting', payload);
expect(wrapper.emitted('update')).toEqual([[]]);
});
it('on filter:changed calls vuex setFilter', () => {
const payload = ['foo'];
mountComponent();
findRegistrySearch().vm.$emit('filter:changed', payload);
expect(store.dispatch).toHaveBeenCalledWith('setFilter', payload);
});
it('on filter:submit emits update event', () => {
mountComponent();
findRegistrySearch().vm.$emit('filter:submit');
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();
});
});
import { shallowMount } from '@vue/test-utils';
import { LIST_INTRO_TEXT, LIST_TITLE_TEXT } from '~/packages/list//constants';
import PackageTitle from '~/packages/list/components/package_title.vue';
import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
describe('PackageTitle', () => {
let wrapper;
let store;
const findTitleArea = () => wrapper.find(TitleArea);
const findMetadataItem = () => wrapper.find(MetadataItem);
const mountComponent = (propsData = { helpUrl: 'foo' }) => {
wrapper = shallowMount(PackageTitle, {
store,
propsData,
stubs: {
TitleArea,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('title area', () => {
it('exists', () => {
mountComponent();
expect(findTitleArea().exists()).toBe(true);
});
it('has the correct props', () => {
mountComponent();
expect(findTitleArea().props()).toMatchObject({
title: LIST_TITLE_TEXT,
infoMessages: [{ text: LIST_INTRO_TEXT, link: 'foo' }],
});
});
});
describe.each`
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({ count, helpUrl: 'foo' });
});
it(`is ${exist} that it exists`, () => {
expect(findMetadataItem().exists()).toBe(exist);
});
if (exist) {
it('has the correct props', () => {
expect(findMetadataItem().props()).toMatchObject({
icon: 'package',
text,
});
});
}
});
});
import { GlFilteredSearchToken, GlFilteredSearchSuggestion } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import component from '~/packages/list/components/tokens/package_type_token.vue';
import { PACKAGE_TYPES } from '~/packages/list/constants';
describe('packages_filter', () => {
let wrapper;
const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
const findFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
const mountComponent = ({ attrs, listeners } = {}) => {
wrapper = shallowMount(component, {
attrs,
listeners,
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('it binds all of his attrs to filtered search token', () => {
mountComponent({ attrs: { foo: 'bar' } });
expect(findFilteredSearchToken().attributes('foo')).toBe('bar');
});
it('it binds all of his events to filtered search token', () => {
const clickListener = jest.fn();
mountComponent({ listeners: { click: clickListener } });
findFilteredSearchToken().vm.$emit('click');
expect(clickListener).toHaveBeenCalled();
});
it.each(PACKAGE_TYPES.map((p, index) => [p, index]))(
'displays a suggestion for %p',
(packageType, index) => {
mountComponent();
const item = findFilteredSearchSuggestions().at(index);
expect(item.text()).toBe(packageType.title);
expect(item.props('value')).toBe(packageType.type);
},
);
});
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { sortableFields } from '~/packages/list/utils'; import { sortableFields } from '~/packages_and_registries/package_registry/utils';
import component from '~/packages_and_registries/package_registry/components/list/package_search.vue'; import component from '~/packages_and_registries/package_registry/components/list/package_search.vue';
import PackageTypeToken from '~/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue'; import PackageTypeToken from '~/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue';
import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue'; import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { LIST_INTRO_TEXT, LIST_TITLE_TEXT } from '~/packages/list/constants';
import PackageTitle from '~/packages_and_registries/package_registry/components/list/package_title.vue'; import PackageTitle from '~/packages_and_registries/package_registry/components/list/package_title.vue';
import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue'; import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue'; import TitleArea from '~/vue_shared/components/registry/title_area.vue';
...@@ -37,8 +36,8 @@ describe('PackageTitle', () => { ...@@ -37,8 +36,8 @@ describe('PackageTitle', () => {
mountComponent(); mountComponent();
expect(findTitleArea().props()).toMatchObject({ expect(findTitleArea().props()).toMatchObject({
title: LIST_TITLE_TEXT, title: PackageTitle.i18n.LIST_TITLE_TEXT,
infoMessages: [{ text: LIST_INTRO_TEXT, link: 'foo' }], infoMessages: [{ text: PackageTitle.i18n.LIST_INTRO_TEXT, link: 'foo' }],
}); });
}); });
}); });
......
import { GlFilteredSearchToken, GlFilteredSearchSuggestion } from '@gitlab/ui'; import { GlFilteredSearchToken, GlFilteredSearchSuggestion } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import component from '~/packages/list/components/tokens/package_type_token.vue'; import component from '~/packages_and_registries/package_registry/components/list/tokens/package_type_token.vue';
import { PACKAGE_TYPES } from '~/packages/list/constants'; import { PACKAGE_TYPES } from '~/packages_and_registries/package_registry/constants';
describe('packages_filter', () => { describe('packages_filter', () => {
let wrapper; let wrapper;
...@@ -41,8 +41,8 @@ describe('packages_filter', () => { ...@@ -41,8 +41,8 @@ describe('packages_filter', () => {
(packageType, index) => { (packageType, index) => {
mountComponent(); mountComponent();
const item = findFilteredSearchSuggestions().at(index); const item = findFilteredSearchSuggestions().at(index);
expect(item.text()).toBe(packageType.title); expect(item.text()).toBe(packageType);
expect(item.props('value')).toBe(packageType.type); expect(item.props('value')).toBe(packageType);
}, },
); );
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment