Commit 4c103b09 authored by Phil Hughes's avatar Phil Hughes

Merge branch...

Merge branch '293755-add-a-setting-for-allowing-disallowing-duplicate-generic-package-uploads' into 'master'

Setting for duplicate generic package uploads

See merge request gitlab-org/gitlab!61339
parents cdfb639a fc7019a2
<script>
import { GlSprintf, GlToggle, GlFormGroup, GlFormInput } from '@gitlab/ui';
import { isEqual } from 'lodash';
import {
DUPLICATES_TOGGLE_LABEL,
DUPLICATES_ALLOWED_DISABLED,
DUPLICATES_ALLOWED_ENABLED,
DUPLICATES_SETTING_EXCEPTION_TITLE,
DUPLICATES_SETTINGS_EXCEPTION_LEGEND,
} from '~/packages_and_registries/settings/group/constants';
export default {
name: 'DuplicatesSettings',
i18n: {
DUPLICATES_TOGGLE_LABEL,
DUPLICATES_SETTING_EXCEPTION_TITLE,
DUPLICATES_SETTINGS_EXCEPTION_LEGEND,
},
components: {
GlSprintf,
GlToggle,
GlFormGroup,
GlFormInput,
},
props: {
loading: {
type: Boolean,
required: false,
default: false,
},
duplicatesAllowed: {
type: Boolean,
default: false,
required: false,
},
duplicateExceptionRegex: {
type: String,
default: '',
required: false,
},
duplicateExceptionRegexError: {
type: String,
default: '',
required: false,
},
modelNames: {
type: Object,
required: true,
validator(value) {
return isEqual(Object.keys(value), ['allowed', 'exception']);
},
},
toggleQaSelector: {
type: String,
required: false,
default: null,
},
labelQaSelector: {
type: String,
required: false,
default: null,
},
},
computed: {
enabledButtonLabel() {
return this.duplicatesAllowed ? DUPLICATES_ALLOWED_ENABLED : DUPLICATES_ALLOWED_DISABLED;
},
isExceptionRegexValid() {
return !this.duplicateExceptionRegexError;
},
},
methods: {
update(type, value) {
this.$emit('update', { [type]: value });
},
},
};
</script>
<template>
<form>
<div class="gl-display-flex">
<gl-toggle
:data-qa-selector="toggleQaSelector"
:label="$options.i18n.DUPLICATES_TOGGLE_LABEL"
label-position="hidden"
:value="duplicatesAllowed"
@change="update(modelNames.allowed, $event)"
/>
<div class="gl-ml-5">
<div data-testid="toggle-label" :data-qa-selector="labelQaSelector">
<gl-sprintf :message="enabledButtonLabel">
<template #bold="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</div>
<gl-form-group
v-if="!duplicatesAllowed"
class="gl-mt-4"
:label="$options.i18n.DUPLICATES_SETTING_EXCEPTION_TITLE"
label-size="sm"
:state="isExceptionRegexValid"
:invalid-feedback="duplicateExceptionRegexError"
:description="$options.i18n.DUPLICATES_SETTINGS_EXCEPTION_LEGEND"
label-for="maven-duplicated-settings-regex-input"
>
<gl-form-input
id="maven-duplicated-settings-regex-input"
:value="duplicateExceptionRegex"
@change="update(modelNames.exception, $event)"
/>
</gl-form-group>
</div>
</div>
</form>
</template>
<script>
import { s__ } from '~/locale';
import SettingsTitles from '~/packages_and_registries/settings/group/components/settings_titles.vue';
export default {
name: 'GenericSettings',
components: {
SettingsTitles,
},
i18n: {
title: s__('PackageRegistry|Generic'),
subTitle: s__('PackageRegistry|Settings for Generic packages'),
},
modelNames: {
allowed: 'genericDuplicatesAllowed',
exception: 'genericDuplicateExceptionRegex',
},
};
</script>
<template>
<div>
<settings-titles :title="$options.i18n.title" :sub-title="$options.i18n.subTitle" />
<slot :model-names="$options.modelNames"></slot>
</div>
</template>
<script>
import { GlSprintf, GlLink, GlAlert } from '@gitlab/ui';
import DuplicatesSettings from '~/packages_and_registries/settings/group/components/duplicates_settings.vue';
import GenericSettings from '~/packages_and_registries/settings/group/components/generic_settings.vue';
import MavenSettings from '~/packages_and_registries/settings/group/components/maven_settings.vue';
import {
PACKAGE_SETTINGS_HEADER,
PACKAGE_SETTINGS_DESCRIPTION,
......@@ -30,6 +31,8 @@ export default {
GlLink,
SettingsBlock,
MavenSettings,
GenericSettings,
DuplicatesSettings,
},
inject: ['defaultExpanded', 'groupPath'],
apollo: {
......@@ -128,13 +131,32 @@ export default {
</span>
</template>
<template #default>
<maven-settings
:maven-duplicates-allowed="packageSettings.mavenDuplicatesAllowed"
:maven-duplicate-exception-regex="packageSettings.mavenDuplicateExceptionRegex"
:maven-duplicate-exception-regex-error="errors.mavenDuplicateExceptionRegex"
:loading="isLoading"
@update="updateSettings"
/>
<maven-settings data-testid="maven-settings">
<template #default="{ modelNames }">
<duplicates-settings
:duplicates-allowed="packageSettings.mavenDuplicatesAllowed"
:duplicate-exception-regex="packageSettings.mavenDuplicateExceptionRegex"
:duplicate-exception-regex-error="errors.mavenDuplicateExceptionRegex"
:model-names="modelNames"
:loading="isLoading"
toggle-qa-selector="allow_duplicates_toggle"
label-qa-selector="allow_duplicates_label"
@update="updateSettings"
/>
</template>
</maven-settings>
<generic-settings class="gl-mt-6" data-testid="generic-settings">
<template #default="{ modelNames }">
<duplicates-settings
:duplicates-allowed="packageSettings.genericDuplicatesAllowed"
:duplicate-exception-regex="packageSettings.genericDuplicateExceptionRegex"
:duplicate-exception-regex-error="errors.genericDuplicateExceptionRegex"
:model-names="modelNames"
:loading="isLoading"
@update="updateSettings"
/>
</template>
</generic-settings>
</template>
</settings-block>
</div>
......
<script>
import { GlSprintf, GlToggle, GlFormGroup, GlFormInput } from '@gitlab/ui';
import {
MAVEN_TOGGLE_LABEL,
MAVEN_TITLE,
MAVEN_SETTINGS_SUBTITLE,
MAVEN_DUPLICATES_ALLOWED_DISABLED,
MAVEN_DUPLICATES_ALLOWED_ENABLED,
MAVEN_SETTING_EXCEPTION_TITLE,
MAVEN_SETTINGS_EXCEPTION_LEGEND,
MAVEN_DUPLICATES_ALLOWED,
MAVEN_DUPLICATE_EXCEPTION_REGEX,
} from '~/packages_and_registries/settings/group/constants';
import { s__ } from '~/locale';
import SettingsTitles from '~/packages_and_registries/settings/group/components/settings_titles.vue';
export default {
name: 'MavenSettings',
i18n: {
MAVEN_TOGGLE_LABEL,
MAVEN_TITLE,
MAVEN_SETTINGS_SUBTITLE,
MAVEN_SETTING_EXCEPTION_TITLE,
MAVEN_SETTINGS_EXCEPTION_LEGEND,
},
modelNames: {
MAVEN_DUPLICATES_ALLOWED,
MAVEN_DUPLICATE_EXCEPTION_REGEX,
},
components: {
GlSprintf,
GlToggle,
GlFormGroup,
GlFormInput,
},
props: {
loading: {
type: Boolean,
required: false,
default: false,
},
mavenDuplicatesAllowed: {
type: Boolean,
default: false,
required: true,
},
mavenDuplicateExceptionRegex: {
type: String,
default: '',
required: true,
},
mavenDuplicateExceptionRegexError: {
type: String,
default: '',
required: false,
},
SettingsTitles,
},
computed: {
enabledButtonLabel() {
return this.mavenDuplicatesAllowed
? MAVEN_DUPLICATES_ALLOWED_ENABLED
: MAVEN_DUPLICATES_ALLOWED_DISABLED;
},
isMavenDuplicateExceptionRegexValid() {
return !this.mavenDuplicateExceptionRegexError;
},
i18n: {
title: s__('PackageRegistry|Maven'),
subTitle: s__('PackageRegistry|Settings for Maven packages'),
},
methods: {
update(type, value) {
this.$emit('update', { [type]: value });
},
modelNames: {
allowed: 'mavenDuplicatesAllowed',
exception: 'mavenDuplicateExceptionRegex',
},
};
</script>
<template>
<div>
<h5 class="gl-border-b-solid gl-border-b-1 gl-border-gray-200">
{{ $options.i18n.MAVEN_TITLE }}
</h5>
<p>{{ $options.i18n.MAVEN_SETTINGS_SUBTITLE }}</p>
<form>
<div class="gl-display-flex">
<gl-toggle
data-qa-selector="allow_duplicates_toggle"
:label="$options.i18n.MAVEN_TOGGLE_LABEL"
label-position="hidden"
:value="mavenDuplicatesAllowed"
@change="update($options.modelNames.MAVEN_DUPLICATES_ALLOWED, $event)"
/>
<div class="gl-ml-5">
<div data-testid="toggle-label" data-qa-selector="allow_duplicates_label">
<gl-sprintf :message="enabledButtonLabel">
<template #bold="{ content }">
<strong>{{ content }}</strong>
</template>
</gl-sprintf>
</div>
<gl-form-group
v-if="!mavenDuplicatesAllowed"
class="gl-mt-4"
:label="$options.i18n.MAVEN_SETTING_EXCEPTION_TITLE"
label-size="sm"
:state="isMavenDuplicateExceptionRegexValid"
:invalid-feedback="mavenDuplicateExceptionRegexError"
:description="$options.i18n.MAVEN_SETTINGS_EXCEPTION_LEGEND"
label-for="maven-duplicated-settings-regex-input"
>
<gl-form-input
id="maven-duplicated-settings-regex-input"
:value="mavenDuplicateExceptionRegex"
@change="update($options.modelNames.MAVEN_DUPLICATE_EXCEPTION_REGEX, $event)"
/>
</gl-form-group>
</div>
</div>
</form>
<settings-titles :title="$options.i18n.title" :sub-title="$options.i18n.subTitle" />
<slot :model-names="$options.modelNames"></slot>
</div>
</template>
<script>
export default {
name: 'SettingsTitle',
props: {
title: {
type: String,
required: true,
},
subTitle: {
type: String,
required: true,
},
},
};
</script>
<template>
<div>
<h5 class="gl-border-b-solid gl-border-b-1 gl-border-gray-200">
{{ title }}
</h5>
<p>{{ subTitle }}</p>
<slot></slot>
</div>
</template>
......@@ -6,17 +6,15 @@ export const PACKAGE_SETTINGS_DESCRIPTION = s__(
'PackageRegistry|GitLab Packages allows organizations to utilize GitLab as a private repository for a variety of common package formats. %{linkStart}More Information%{linkEnd}',
);
export const MAVEN_TITLE = s__('PackageRegistry|Maven');
export const MAVEN_SETTINGS_SUBTITLE = s__('PackageRegistry|Settings for Maven packages');
export const MAVEN_TOGGLE_LABEL = s__('PackageRegistry|Allow duplicates');
export const MAVEN_DUPLICATES_ALLOWED_DISABLED = s__(
export const DUPLICATES_TOGGLE_LABEL = s__('PackageRegistry|Allow duplicates');
export const DUPLICATES_ALLOWED_DISABLED = s__(
'PackageRegistry|%{boldStart}Do not allow duplicates%{boldEnd} - Packages with the same name and version are rejected.',
);
export const MAVEN_DUPLICATES_ALLOWED_ENABLED = s__(
export const DUPLICATES_ALLOWED_ENABLED = s__(
'PackageRegistry|%{boldStart}Allow duplicates%{boldEnd} - Packages with the same name and version are accepted.',
);
export const MAVEN_SETTING_EXCEPTION_TITLE = __('Exceptions');
export const MAVEN_SETTINGS_EXCEPTION_LEGEND = s__(
export const DUPLICATES_SETTING_EXCEPTION_TITLE = __('Exceptions');
export const DUPLICATES_SETTINGS_EXCEPTION_LEGEND = s__(
'PackageRegistry|Packages can be published if their name or version matches this regex',
);
......
......@@ -3,6 +3,8 @@ mutation updateNamespacePackageSettings($input: UpdateNamespacePackageSettingsIn
packageSettings {
mavenDuplicatesAllowed
mavenDuplicateExceptionRegex
genericDuplicatesAllowed
genericDuplicateExceptionRegex
}
errors
}
......
......@@ -3,6 +3,8 @@ query getGroupPackagesSettings($fullPath: ID!) {
packageSettings {
mavenDuplicatesAllowed
mavenDuplicateExceptionRegex
genericDuplicatesAllowed
genericDuplicateExceptionRegex
}
}
}
......@@ -23437,6 +23437,9 @@ msgstr ""
msgid "PackageRegistry|RubyGems"
msgstr ""
msgid "PackageRegistry|Settings for Generic packages"
msgstr ""
msgid "PackageRegistry|Settings for Maven packages"
msgstr ""
......
......@@ -11,7 +11,7 @@ module QA
element :package_registry_settings_content
end
view 'app/assets/javascripts/packages_and_registries/settings/group/components/maven_settings.vue' do
view 'app/assets/javascripts/packages_and_registries/settings/group/components/group_settings_app.vue' do
element :allow_duplicates_toggle
element :allow_duplicates_label
end
......
......@@ -66,28 +66,31 @@ RSpec.describe 'Group Packages & Registries settings' do
it 'automatically saves changes to the server', :js do
visit_settings_page
expect(page).to have_content('Allow duplicates')
within '[data-testid="maven-settings"]' do
expect(page).to have_content('Allow duplicates')
find('.gl-toggle').click
find('.gl-toggle').click
expect(page).to have_content('Do not allow duplicates')
expect(page).to have_content('Do not allow duplicates')
visit_settings_page
visit_settings_page
expect(page).to have_content('Do not allow duplicates')
expect(page).to have_content('Do not allow duplicates')
end
end
it 'shows an error on wrong regex', :js do
visit_settings_page
expect(page).to have_content('Allow duplicates')
find('.gl-toggle').click
within '[data-testid="maven-settings"]' do
expect(page).to have_content('Allow duplicates')
expect(page).to have_content('Do not allow duplicates')
find('.gl-toggle').click
fill_in 'Exceptions', with: ')'
expect(page).to have_content('Do not allow duplicates')
fill_in 'Exceptions', with: ')'
end
# simulate blur event
find('body').click
......@@ -98,11 +101,13 @@ RSpec.describe 'Group Packages & Registries settings' do
it 'works correctly', :js do
visit_sub_group_settings_page
expect(page).to have_content('Allow duplicates')
within '[data-testid="maven-settings"]' do
expect(page).to have_content('Allow duplicates')
find('.gl-toggle').click
find('.gl-toggle').click
expect(page).to have_content('Do not allow duplicates')
expect(page).to have_content('Do not allow duplicates')
end
end
end
end
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`settings_titles renders properly 1`] = `
<div>
<h5
class="gl-border-b-solid gl-border-b-1 gl-border-gray-200"
>
foo
</h5>
<p>
bar
</p>
</div>
`;
import { GlSprintf, GlToggle, GlFormGroup, GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import component from '~/packages_and_registries/settings/group/components/duplicates_settings.vue';
import {
DUPLICATES_TOGGLE_LABEL,
DUPLICATES_ALLOWED_ENABLED,
DUPLICATES_ALLOWED_DISABLED,
DUPLICATES_SETTING_EXCEPTION_TITLE,
DUPLICATES_SETTINGS_EXCEPTION_LEGEND,
} from '~/packages_and_registries/settings/group/constants';
describe('Duplicates Settings', () => {
let wrapper;
const defaultProps = {
duplicatesAllowed: false,
duplicateExceptionRegex: 'foo',
modelNames: {
allowed: 'allowedModel',
exception: 'exceptionModel',
},
};
const mountComponent = (propsData = defaultProps) => {
wrapper = shallowMount(component, {
propsData,
stubs: {
GlSprintf,
},
});
};
afterEach(() => {
wrapper.destroy();
});
const findToggle = () => wrapper.findComponent(GlToggle);
const findToggleLabel = () => wrapper.find('[data-testid="toggle-label"');
const findInputGroup = () => wrapper.findComponent(GlFormGroup);
const findInput = () => wrapper.findComponent(GlFormInput);
it('has a toggle', () => {
mountComponent();
expect(findToggle().exists()).toBe(true);
expect(findToggle().props()).toMatchObject({
label: DUPLICATES_TOGGLE_LABEL,
value: defaultProps.duplicatesAllowed,
});
});
it('toggle emits an update event', () => {
mountComponent();
findToggle().vm.$emit('change', false);
expect(wrapper.emitted('update')).toStrictEqual([
[{ [defaultProps.modelNames.allowed]: false }],
]);
});
describe('when the duplicates are disabled', () => {
it('the toggle has the disabled message', () => {
mountComponent();
expect(findToggleLabel().exists()).toBe(true);
expect(findToggleLabel().text()).toMatchInterpolatedText(DUPLICATES_ALLOWED_DISABLED);
});
it('shows a form group with an input field', () => {
mountComponent();
expect(findInputGroup().exists()).toBe(true);
expect(findInputGroup().attributes()).toMatchObject({
'label-for': 'maven-duplicated-settings-regex-input',
label: DUPLICATES_SETTING_EXCEPTION_TITLE,
description: DUPLICATES_SETTINGS_EXCEPTION_LEGEND,
});
});
it('shows an input field', () => {
mountComponent();
expect(findInput().exists()).toBe(true);
expect(findInput().attributes()).toMatchObject({
id: 'maven-duplicated-settings-regex-input',
value: defaultProps.duplicateExceptionRegex,
});
});
it('input change event emits an update event', () => {
mountComponent();
findInput().vm.$emit('change', 'bar');
expect(wrapper.emitted('update')).toStrictEqual([
[{ [defaultProps.modelNames.exception]: 'bar' }],
]);
});
describe('valid state', () => {
it('form group has correct props', () => {
mountComponent();
expect(findInputGroup().attributes()).toMatchObject({
state: 'true',
'invalid-feedback': '',
});
});
});
describe('invalid state', () => {
it('form group has correct props', () => {
const propsWithError = {
...defaultProps,
duplicateExceptionRegexError: 'some error string',
};
mountComponent(propsWithError);
expect(findInputGroup().attributes()).toMatchObject({
'invalid-feedback': propsWithError.duplicateExceptionRegexError,
});
});
});
});
describe('when the duplicates are enabled', () => {
it('has the correct toggle label', () => {
mountComponent({ ...defaultProps, duplicatesAllowed: true });
expect(findToggleLabel().exists()).toBe(true);
expect(findToggleLabel().text()).toMatchInterpolatedText(DUPLICATES_ALLOWED_ENABLED);
});
it('hides the form input group', () => {
mountComponent({ ...defaultProps, duplicatesAllowed: true });
expect(findInputGroup().exists()).toBe(false);
});
});
});
import { shallowMount } from '@vue/test-utils';
import GenericSettings from '~/packages_and_registries/settings/group/components/generic_settings.vue';
import SettingsTitles from '~/packages_and_registries/settings/group/components/settings_titles.vue';
describe('generic_settings', () => {
let wrapper;
const mountComponent = () => {
wrapper = shallowMount(GenericSettings, {
scopedSlots: {
default: '<div data-testid="default-slot">{{props.modelNames}}</div>',
},
});
};
const findSettingsTitle = () => wrapper.findComponent(SettingsTitles);
const findDefaultSlot = () => wrapper.find('[data-testid="default-slot"]');
afterEach(() => {
wrapper.destroy();
});
describe('title component', () => {
it('has a title component', () => {
mountComponent();
expect(findSettingsTitle().exists()).toBe(true);
});
it('passes the correct props', () => {
mountComponent();
expect(findSettingsTitle().props()).toMatchObject({
title: 'Generic',
subTitle: 'Settings for Generic packages',
});
});
});
describe('default slot', () => {
it('accept a default slots', () => {
mountComponent();
expect(findDefaultSlot().exists()).toBe(true);
});
it('binds model names', () => {
mountComponent();
expect(findDefaultSlot().text()).toContain('genericDuplicatesAllowed');
expect(findDefaultSlot().text()).toContain('genericDuplicateExceptionRegex');
});
});
});
......@@ -3,6 +3,8 @@ import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import DuplicatesSettings from '~/packages_and_registries/settings/group/components/duplicates_settings.vue';
import GenericSettings from '~/packages_and_registries/settings/group/components/generic_settings.vue';
import component from '~/packages_and_registries/settings/group/components/group_settings_app.vue';
import MavenSettings from '~/packages_and_registries/settings/group/components/maven_settings.vue';
import {
......@@ -63,6 +65,8 @@ describe('Group Settings App', () => {
stubs: {
GlSprintf,
SettingsBlock,
MavenSettings,
GenericSettings,
},
mocks: {
$toast: {
......@@ -78,14 +82,17 @@ describe('Group Settings App', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findSettingsBlock = () => wrapper.find(SettingsBlock);
const findSettingsBlock = () => wrapper.findComponent(SettingsBlock);
const findDescription = () => wrapper.find('[data-testid="description"');
const findLink = () => wrapper.find(GlLink);
const findMavenSettings = () => wrapper.find(MavenSettings);
const findAlert = () => wrapper.find(GlAlert);
const findLink = () => wrapper.findComponent(GlLink);
const findAlert = () => wrapper.findComponent(GlAlert);
const findMavenSettings = () => wrapper.findComponent(MavenSettings);
const findMavenDuplicatedSettings = () => findMavenSettings().findComponent(DuplicatesSettings);
const findGenericSettings = () => wrapper.findComponent(GenericSettings);
const findGenericDuplicatedSettings = () =>
findGenericSettings().findComponent(DuplicatesSettings);
const waitForApolloQueryAndRender = async () => {
await waitForPromises();
......@@ -93,7 +100,7 @@ describe('Group Settings App', () => {
};
const emitSettingsUpdate = (override) => {
findMavenSettings().vm.$emit('update', {
findMavenDuplicatedSettings().vm.$emit('update', {
mavenDuplicateExceptionRegex: ')',
...override,
});
......@@ -152,7 +159,7 @@ describe('Group Settings App', () => {
it('assigns duplication allowness and exception props', async () => {
mountComponent();
expect(findMavenSettings().props('loading')).toBe(true);
expect(findMavenDuplicatedSettings().props('loading')).toBe(true);
await waitForApolloQueryAndRender();
......@@ -161,10 +168,10 @@ describe('Group Settings App', () => {
mavenDuplicateExceptionRegex,
} = groupPackageSettingsMock.data.group.packageSettings;
expect(findMavenSettings().props()).toMatchObject({
mavenDuplicatesAllowed,
mavenDuplicateExceptionRegex,
mavenDuplicateExceptionRegexError: '',
expect(findMavenDuplicatedSettings().props()).toMatchObject({
duplicatesAllowed: mavenDuplicatesAllowed,
duplicateExceptionRegex: mavenDuplicateExceptionRegex,
duplicateExceptionRegexError: '',
loading: false,
});
});
......@@ -183,6 +190,49 @@ describe('Group Settings App', () => {
});
});
describe('generic settings', () => {
it('exists', () => {
mountComponent();
expect(findGenericSettings().exists()).toBe(true);
});
it('assigns duplication allowness and exception props', async () => {
mountComponent();
expect(findGenericDuplicatedSettings().props('loading')).toBe(true);
await waitForApolloQueryAndRender();
const {
genericDuplicatesAllowed,
genericDuplicateExceptionRegex,
} = groupPackageSettingsMock.data.group.packageSettings;
expect(findGenericDuplicatedSettings().props()).toMatchObject({
duplicatesAllowed: genericDuplicatesAllowed,
duplicateExceptionRegex: genericDuplicateExceptionRegex,
duplicateExceptionRegexError: '',
loading: false,
});
});
it('on update event calls the mutation', async () => {
const mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock());
mountComponent({ mutationResolver });
await waitForApolloQueryAndRender();
findMavenDuplicatedSettings().vm.$emit('update', {
genericDuplicateExceptionRegex: ')',
});
expect(mutationResolver).toHaveBeenCalledWith({
input: { genericDuplicateExceptionRegex: ')', namespacePath: 'foo_group_path' },
});
});
});
describe('settings update', () => {
describe('success state', () => {
it('shows a success alert', async () => {
......@@ -205,21 +255,21 @@ describe('Group Settings App', () => {
await waitForApolloQueryAndRender();
expect(findMavenSettings().props('mavenDuplicateExceptionRegex')).toBe('');
expect(findMavenDuplicatedSettings().props('duplicateExceptionRegex')).toBe('');
emitSettingsUpdate({ mavenDuplicateExceptionRegex });
// wait for apollo to update the model with the optimistic response
await wrapper.vm.$nextTick();
expect(findMavenSettings().props('mavenDuplicateExceptionRegex')).toBe(
expect(findMavenDuplicatedSettings().props('duplicateExceptionRegex')).toBe(
mavenDuplicateExceptionRegex,
);
// wait for the call to resolve
await waitForPromises();
expect(findMavenSettings().props('mavenDuplicateExceptionRegex')).toBe(
expect(findMavenDuplicatedSettings().props('duplicateExceptionRegex')).toBe(
mavenDuplicateExceptionRegex,
);
});
......@@ -245,7 +295,7 @@ describe('Group Settings App', () => {
await waitForApolloQueryAndRender();
// errors are bound to the component
expect(findMavenSettings().props('mavenDuplicateExceptionRegexError')).toBe(
expect(findMavenDuplicatedSettings().props('duplicateExceptionRegexError')).toBe(
groupPackageSettingsMutationErrorMock.errors[0].extensions.problems[0].message,
);
......@@ -258,7 +308,7 @@ describe('Group Settings App', () => {
await wrapper.vm.$nextTick();
// errors are reset on mutation call
expect(findMavenSettings().props('mavenDuplicateExceptionRegexError')).toBe('');
expect(findMavenDuplicatedSettings().props('duplicateExceptionRegexError')).toBe('');
});
it.each`
......
import { GlSprintf, GlToggle, GlFormGroup, GlFormInput } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import component from '~/packages_and_registries/settings/group/components/maven_settings.vue';
import MavenSettings from '~/packages_and_registries/settings/group/components/maven_settings.vue';
import SettingsTitles from '~/packages_and_registries/settings/group/components/settings_titles.vue';
import {
MAVEN_TITLE,
MAVEN_SETTINGS_SUBTITLE,
MAVEN_DUPLICATES_ALLOWED_DISABLED,
MAVEN_DUPLICATES_ALLOWED_ENABLED,
MAVEN_SETTING_EXCEPTION_TITLE,
MAVEN_SETTINGS_EXCEPTION_LEGEND,
} from '~/packages_and_registries/settings/group/constants';
describe('Maven Settings', () => {
describe('maven_settings', () => {
let wrapper;
const defaultProps = {
mavenDuplicatesAllowed: false,
mavenDuplicateExceptionRegex: 'foo',
};
const mountComponent = (propsData = defaultProps) => {
wrapper = shallowMount(component, {
propsData,
stubs: {
GlSprintf,
const mountComponent = () => {
wrapper = shallowMount(MavenSettings, {
scopedSlots: {
default: '<div data-testid="default-slot">{{props.modelNames}}</div>',
},
});
};
const findSettingsTitle = () => wrapper.findComponent(SettingsTitles);
const findDefaultSlot = () => wrapper.find('[data-testid="default-slot"]');
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findTitle = () => wrapper.find('h5');
const findSubTitle = () => wrapper.find('p');
const findToggle = () => wrapper.find(GlToggle);
const findToggleLabel = () => wrapper.find('[data-testid="toggle-label"');
const findInputGroup = () => wrapper.find(GlFormGroup);
const findInput = () => wrapper.find(GlFormInput);
it('has a title', () => {
mountComponent();
expect(findTitle().exists()).toBe(true);
expect(findTitle().text()).toBe(MAVEN_TITLE);
});
it('has a subtitle', () => {
mountComponent();
expect(findSubTitle().exists()).toBe(true);
expect(findSubTitle().text()).toBe(MAVEN_SETTINGS_SUBTITLE);
});
it('has a toggle', () => {
mountComponent();
expect(findToggle().exists()).toBe(true);
expect(findToggle().props()).toMatchObject({
label: component.i18n.MAVEN_TOGGLE_LABEL,
value: defaultProps.mavenDuplicatesAllowed,
});
});
it('toggle emits an update event', () => {
mountComponent();
findToggle().vm.$emit('change', false);
expect(wrapper.emitted('update')).toEqual([[{ mavenDuplicatesAllowed: false }]]);
});
describe('when the duplicates are disabled', () => {
it('the toggle has the disabled message', () => {
describe('title component', () => {
it('has a title component', () => {
mountComponent();
expect(findToggleLabel().exists()).toBe(true);
expect(findToggleLabel().text()).toMatchInterpolatedText(MAVEN_DUPLICATES_ALLOWED_DISABLED);
expect(findSettingsTitle().exists()).toBe(true);
});
it('shows a form group with an input field', () => {
it('passes the correct props', () => {
mountComponent();
expect(findInputGroup().exists()).toBe(true);
expect(findInputGroup().attributes()).toMatchObject({
'label-for': 'maven-duplicated-settings-regex-input',
label: MAVEN_SETTING_EXCEPTION_TITLE,
description: MAVEN_SETTINGS_EXCEPTION_LEGEND,
expect(findSettingsTitle().props()).toMatchObject({
title: 'Maven',
subTitle: 'Settings for Maven packages',
});
});
});
it('shows an input field', () => {
describe('default slot', () => {
it('accept a default slots', () => {
mountComponent();
expect(findInput().exists()).toBe(true);
expect(findInput().attributes()).toMatchObject({
id: 'maven-duplicated-settings-regex-input',
value: defaultProps.mavenDuplicateExceptionRegex,
});
expect(findDefaultSlot().exists()).toBe(true);
});
it('input change event emits an update event', () => {
it('binds model names', () => {
mountComponent();
findInput().vm.$emit('change', 'bar');
expect(wrapper.emitted('update')).toEqual([[{ mavenDuplicateExceptionRegex: 'bar' }]]);
});
describe('valid state', () => {
it('form group has correct props', () => {
mountComponent();
expect(findInputGroup().attributes()).toMatchObject({
state: 'true',
'invalid-feedback': '',
});
});
});
describe('invalid state', () => {
it('form group has correct props', () => {
const propsWithError = {
...defaultProps,
mavenDuplicateExceptionRegexError: 'some error string',
};
mountComponent(propsWithError);
expect(findInputGroup().attributes()).toMatchObject({
'invalid-feedback': propsWithError.mavenDuplicateExceptionRegexError,
});
});
});
});
describe('when the duplicates are enabled', () => {
it('has the correct toggle label', () => {
mountComponent({ ...defaultProps, mavenDuplicatesAllowed: true });
expect(findToggleLabel().exists()).toBe(true);
expect(findToggleLabel().text()).toMatchInterpolatedText(MAVEN_DUPLICATES_ALLOWED_ENABLED);
});
it('hides the form input group', () => {
mountComponent({ ...defaultProps, mavenDuplicatesAllowed: true });
expect(findInputGroup().exists()).toBe(false);
expect(findDefaultSlot().text()).toContain('mavenDuplicatesAllowed');
expect(findDefaultSlot().text()).toContain('mavenDuplicateExceptionRegex');
});
});
});
import { shallowMount } from '@vue/test-utils';
import SettingsTitles from '~/packages_and_registries/settings/group/components/settings_titles.vue';
describe('settings_titles', () => {
let wrapper;
const mountComponent = () => {
wrapper = shallowMount(SettingsTitles, {
propsData: {
title: 'foo',
subTitle: 'bar',
},
});
};
afterEach(() => {
wrapper.destroy();
});
it('renders properly', () => {
mountComponent();
expect(wrapper.element).toMatchSnapshot();
});
});
......@@ -4,6 +4,8 @@ export const groupPackageSettingsMock = {
packageSettings: {
mavenDuplicatesAllowed: true,
mavenDuplicateExceptionRegex: '',
genericDuplicatesAllowed: true,
genericDuplicateExceptionRegex: '',
},
},
},
......@@ -15,6 +17,8 @@ export const groupPackageSettingsMutationMock = (override) => ({
packageSettings: {
mavenDuplicatesAllowed: true,
mavenDuplicateExceptionRegex: 'latest[main]something',
genericDuplicatesAllowed: true,
genericDuplicateExceptionRegex: 'latest[main]somethingGeneric',
},
errors: [],
...override,
......
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