Commit c1f3d5e8 authored by Frédéric Caplette's avatar Frédéric Caplette

Merge branch '340777-new-setting-for-ttl-for-the-dependency-proxy-2' into 'master'

New setting for TTL for the dependency proxy

See merge request gitlab-org/gitlab!75633
parents 444a076a bb4d1993
...@@ -2,9 +2,14 @@ ...@@ -2,9 +2,14 @@
import { GlToggle, GlSprintf, GlLink } from '@gitlab/ui'; import { GlToggle, GlSprintf, GlLink } from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue'; import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
import SettingsTitles from '~/packages_and_registries/settings/group/components/settings_titles.vue';
import updateDependencyProxySettings from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_settings.mutation.graphql'; import updateDependencyProxySettings from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_settings.mutation.graphql';
import updateDependencyProxyImageTtlGroupPolicy from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_image_ttl_group_policy.mutation.graphql';
import { updateGroupPackageSettings } from '~/packages_and_registries/settings/group/graphql/utils/cache_update'; import { updateGroupPackageSettings } from '~/packages_and_registries/settings/group/graphql/utils/cache_update';
import { updateGroupDependencyProxySettingsOptimisticResponse } from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses'; import {
updateGroupDependencyProxySettingsOptimisticResponse,
updateDependencyProxyImageTtlGroupPolicyOptimisticResponse,
} from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses';
import { import {
DEPENDENCY_PROXY_HEADER, DEPENDENCY_PROXY_HEADER,
...@@ -19,14 +24,20 @@ export default { ...@@ -19,14 +24,20 @@ export default {
GlSprintf, GlSprintf,
GlLink, GlLink,
SettingsBlock, SettingsBlock,
SettingsTitles,
}, },
i18n: { i18n: {
DEPENDENCY_PROXY_HEADER, DEPENDENCY_PROXY_HEADER,
DEPENDENCY_PROXY_SETTINGS_DESCRIPTION, DEPENDENCY_PROXY_SETTINGS_DESCRIPTION,
label: s__('DependencyProxy|Enable Dependency Proxy'), enabledProxyLabel: s__('DependencyProxy|Enable Dependency Proxy'),
enabledProxyHelpText: s__( enabledProxyHelpText: s__(
'DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}', 'DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}',
), ),
storageSettingsTitle: s__('DependencyProxy|Storage settings'),
ttlPolicyEnabledLabel: s__('DependencyProxy|Clear the Dependency Proxy cache automatically'),
ttlPolicyEnabledHelpText: s__(
'DependencyProxy|When enabled, images older than 90 days will be removed from the cache.',
),
}, },
links: { links: {
DEPENDENCY_PROXY_DOCS_PATH, DEPENDENCY_PROXY_DOCS_PATH,
...@@ -37,6 +48,10 @@ export default { ...@@ -37,6 +48,10 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
dependencyProxyImageTtlPolicy: {
type: Object,
required: true,
},
isLoading: { isLoading: {
type: Boolean, type: Boolean,
required: false, required: false,
...@@ -52,29 +67,35 @@ export default { ...@@ -52,29 +67,35 @@ export default {
this.updateSettings({ enabled }); this.updateSettings({ enabled });
}, },
}, },
ttlEnabled: {
get() {
return this.dependencyProxyImageTtlPolicy.enabled;
},
set(enabled) {
const payload = {
enabled,
ttl: 90, // hardocded TTL for the MVC version
};
this.updateDependencyProxyImageTtlGroupPolicy(payload);
},
},
helpText() { helpText() {
return this.enabled ? this.$options.i18n.enabledProxyHelpText : ''; return this.enabled ? this.$options.i18n.enabledProxyHelpText : '';
}, },
}, },
methods: { methods: {
async updateSettings(payload) { mutationVariables(payload) {
return {
input: {
groupPath: this.groupPath,
...payload,
},
};
},
async executeMutation(config, resource) {
try { try {
const { data } = await this.$apollo.mutate({ const { data } = await this.$apollo.mutate(config);
mutation: updateDependencyProxySettings, if (data[resource]?.errors.length > 0) {
variables: {
input: {
groupPath: this.groupPath,
...payload,
},
},
update: updateGroupPackageSettings(this.groupPath),
optimisticResponse: updateGroupDependencyProxySettingsOptimisticResponse({
...this.dependencyProxySettings,
...payload,
}),
});
if (data.updateDependencyProxySettings?.errors?.length > 0) {
throw new Error(); throw new Error();
} else { } else {
this.$emit('success'); this.$emit('success');
...@@ -83,6 +104,32 @@ export default { ...@@ -83,6 +104,32 @@ export default {
this.$emit('error'); this.$emit('error');
} }
}, },
async updateSettings(payload) {
const apolloConfig = {
mutation: updateDependencyProxySettings,
variables: this.mutationVariables(payload),
update: updateGroupPackageSettings(this.groupPath),
optimisticResponse: updateGroupDependencyProxySettingsOptimisticResponse({
...this.dependencyProxySettings,
...payload,
}),
};
this.executeMutation(apolloConfig, 'updateDependencyProxySettings');
},
async updateDependencyProxyImageTtlGroupPolicy(payload) {
const apolloConfig = {
mutation: updateDependencyProxyImageTtlGroupPolicy,
variables: this.mutationVariables(payload),
update: updateGroupPackageSettings(this.groupPath),
optimisticResponse: updateDependencyProxyImageTtlGroupPolicyOptimisticResponse({
...this.dependencyProxyImageTtlPolicy,
...payload,
}),
};
this.executeMutation(apolloConfig, 'updateDependencyProxyImageTtlGroupPolicy');
},
}, },
}; };
</script> </script>
...@@ -111,7 +158,7 @@ export default { ...@@ -111,7 +158,7 @@ export default {
<gl-toggle <gl-toggle
v-model="enabled" v-model="enabled"
:disabled="isLoading" :disabled="isLoading"
:label="$options.i18n.label" :label="$options.i18n.enabledProxyLabel"
:help="helpText" :help="helpText"
data-qa-selector="dependency_proxy_setting_toggle" data-qa-selector="dependency_proxy_setting_toggle"
data-testid="dependency-proxy-setting-toggle" data-testid="dependency-proxy-setting-toggle"
...@@ -128,6 +175,15 @@ export default { ...@@ -128,6 +175,15 @@ export default {
</span> </span>
</template> </template>
</gl-toggle> </gl-toggle>
<settings-titles :title="$options.i18n.storageSettingsTitle" class="gl-my-6" />
<gl-toggle
v-model="ttlEnabled"
:disabled="isLoading"
:label="$options.i18n.ttlPolicyEnabledLabel"
:help="$options.i18n.ttlPolicyEnabledHelpText"
data-testid="dependency-proxy-ttl-policies-toggle"
/>
</div> </div>
</template> </template>
</settings-block> </settings-block>
......
...@@ -37,6 +37,9 @@ export default { ...@@ -37,6 +37,9 @@ export default {
dependencyProxySettings() { dependencyProxySettings() {
return this.group?.dependencyProxySetting || {}; return this.group?.dependencyProxySetting || {};
}, },
dependencyProxyImageTtlPolicy() {
return this.group?.dependencyProxyImageTtlPolicy || {};
},
isLoading() { isLoading() {
return this.$apollo.queries.group.loading; return this.$apollo.queries.group.loading;
}, },
...@@ -82,6 +85,7 @@ export default { ...@@ -82,6 +85,7 @@ export default {
<dependency-proxy-settings <dependency-proxy-settings
v-if="dependencyProxyAvailable" v-if="dependencyProxyAvailable"
:dependency-proxy-settings="dependencyProxySettings" :dependency-proxy-settings="dependencyProxySettings"
:dependency-proxy-image-ttl-policy="dependencyProxyImageTtlPolicy"
:is-loading="isLoading" :is-loading="isLoading"
@success="handleSuccess" @success="handleSuccess"
@error="handleError" @error="handleError"
......
...@@ -8,7 +8,8 @@ export default { ...@@ -8,7 +8,8 @@ export default {
}, },
subTitle: { subTitle: {
type: String, type: String,
required: true, required: false,
default: '',
}, },
}, },
}; };
...@@ -16,10 +17,10 @@ export default { ...@@ -16,10 +17,10 @@ export default {
<template> <template>
<div> <div>
<h5 class="gl-border-b-solid gl-border-b-1 gl-border-gray-200"> <h5 class="gl-border-b-solid gl-border-b-1 gl-border-gray-200 gl-pb-3">
{{ title }} {{ title }}
</h5> </h5>
<p>{{ subTitle }}</p> <p v-if="subTitle">{{ subTitle }}</p>
<slot></slot> <slot></slot>
</div> </div>
</template> </template>
mutation updateDependencyProxyImageTtlGroupPolicy(
$input: UpdateDependencyProxyImageTtlGroupPolicyInput!
) {
updateDependencyProxyImageTtlGroupPolicy(input: $input) {
dependencyProxyImageTtlPolicy {
enabled
ttl
}
errors
}
}
...@@ -4,6 +4,10 @@ query getGroupPackagesSettings($fullPath: ID!) { ...@@ -4,6 +4,10 @@ query getGroupPackagesSettings($fullPath: ID!) {
dependencyProxySetting { dependencyProxySetting {
enabled enabled
} }
dependencyProxyImageTtlPolicy {
ttl
enabled
}
packageSettings { packageSettings {
mavenDuplicatesAllowed mavenDuplicatesAllowed
mavenDuplicateExceptionRegex mavenDuplicateExceptionRegex
......
...@@ -19,6 +19,11 @@ export const updateGroupPackageSettings = (fullPath) => (client, { data: updated ...@@ -19,6 +19,11 @@ export const updateGroupPackageSettings = (fullPath) => (client, { data: updated
...updatedData.updateDependencyProxySettings.dependencyProxySetting, ...updatedData.updateDependencyProxySettings.dependencyProxySetting,
}; };
} }
if (updatedData.updateDependencyProxyImageTtlGroupPolicy) {
draftState.group.dependencyProxyImageTtlPolicy = {
...updatedData.updateDependencyProxyImageTtlGroupPolicy.dependencyProxyImageTtlPolicy,
};
}
}); });
client.writeQuery({ client.writeQuery({
......
...@@ -21,3 +21,15 @@ export const updateGroupDependencyProxySettingsOptimisticResponse = (changes) => ...@@ -21,3 +21,15 @@ export const updateGroupDependencyProxySettingsOptimisticResponse = (changes) =>
}, },
}, },
}); });
export const updateDependencyProxyImageTtlGroupPolicyOptimisticResponse = (changes) => ({
// eslint-disable-next-line @gitlab/require-i18n-strings
__typename: 'Mutation',
updateDependencyProxyImageTtlGroupPolicy: {
__typename: 'UpdateDependencyProxyImageTtlGroupPolicyPayload',
errors: [],
dependencyProxyImageTtlPolicy: {
...changes,
},
},
});
...@@ -11531,6 +11531,9 @@ msgstr "" ...@@ -11531,6 +11531,9 @@ msgstr ""
msgid "DependencyProxy|Cached %{time}" msgid "DependencyProxy|Cached %{time}"
msgstr "" msgstr ""
msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
msgstr ""
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})" msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr "" msgstr ""
...@@ -11555,6 +11558,9 @@ msgstr "" ...@@ -11555,6 +11558,9 @@ msgstr ""
msgid "DependencyProxy|Image list" msgid "DependencyProxy|Image list"
msgstr "" msgstr ""
msgid "DependencyProxy|Storage settings"
msgstr ""
msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}." msgid "DependencyProxy|The Dependency Proxy is disabled. %{docLinkStart}Learn how to enable it%{docLinkEnd}."
msgstr "" msgstr ""
...@@ -11564,6 +11570,9 @@ msgstr "" ...@@ -11564,6 +11570,9 @@ msgstr ""
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}" msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
msgstr "" msgstr ""
msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
msgstr ""
msgid "Depends on %d merge request being merged" msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged" msgid_plural "Depends on %d merge requests being merged"
msgstr[0] "" msgstr[0] ""
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
exports[`settings_titles renders properly 1`] = ` exports[`settings_titles renders properly 1`] = `
<div> <div>
<h5 <h5
class="gl-border-b-solid gl-border-b-1 gl-border-gray-200" class="gl-border-b-solid gl-border-b-1 gl-border-gray-200 gl-pb-3"
> >
foo foo
......
...@@ -13,14 +13,21 @@ import { ...@@ -13,14 +13,21 @@ import {
} from '~/packages_and_registries/settings/group/constants'; } from '~/packages_and_registries/settings/group/constants';
import updateDependencyProxySettings from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_settings.mutation.graphql'; import updateDependencyProxySettings from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_settings.mutation.graphql';
import updateDependencyProxyImageTtlGroupPolicy from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_image_ttl_group_policy.mutation.graphql';
import getGroupPackagesSettingsQuery from '~/packages_and_registries/settings/group/graphql/queries/get_group_packages_settings.query.graphql'; import getGroupPackagesSettingsQuery from '~/packages_and_registries/settings/group/graphql/queries/get_group_packages_settings.query.graphql';
import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue'; import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
import { updateGroupDependencyProxySettingsOptimisticResponse } from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses'; import SettingsTitles from '~/packages_and_registries/settings/group/components/settings_titles.vue';
import {
updateGroupDependencyProxySettingsOptimisticResponse,
updateDependencyProxyImageTtlGroupPolicyOptimisticResponse,
} from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses';
import { import {
dependencyProxySettings as dependencyProxySettingsMock, dependencyProxySettings as dependencyProxySettingsMock,
dependencyProxyImageTtlPolicy as dependencyProxyImageTtlPolicyMock,
dependencyProxySettingMutationMock, dependencyProxySettingMutationMock,
groupPackageSettingsMock, groupPackageSettingsMock,
dependencyProxySettingMutationErrorMock, mutationErrorMock,
dependencyProxyUpdateTllPolicyMutationMock,
} from '../mock_data'; } from '../mock_data';
jest.mock('~/flash'); jest.mock('~/flash');
...@@ -31,6 +38,8 @@ const localVue = createLocalVue(); ...@@ -31,6 +38,8 @@ const localVue = createLocalVue();
describe('DependencyProxySettings', () => { describe('DependencyProxySettings', () => {
let wrapper; let wrapper;
let apolloProvider; let apolloProvider;
let updateSettingsMutationResolver;
let updateTtlPoliciesMutationResolver;
const defaultProvide = { const defaultProvide = {
defaultExpanded: false, defaultExpanded: false,
...@@ -42,11 +51,14 @@ describe('DependencyProxySettings', () => { ...@@ -42,11 +51,14 @@ describe('DependencyProxySettings', () => {
const mountComponent = ({ const mountComponent = ({
provide = defaultProvide, provide = defaultProvide,
mutationResolver = jest.fn().mockResolvedValue(dependencyProxySettingMutationMock()),
isLoading = false, isLoading = false,
dependencyProxySettings = dependencyProxySettingsMock(), dependencyProxySettings = dependencyProxySettingsMock(),
dependencyProxyImageTtlPolicy = dependencyProxyImageTtlPolicyMock(),
} = {}) => { } = {}) => {
const requestHandlers = [[updateDependencyProxySettings, mutationResolver]]; const requestHandlers = [
[updateDependencyProxySettings, updateSettingsMutationResolver],
[updateDependencyProxyImageTtlGroupPolicy, updateTtlPoliciesMutationResolver],
];
apolloProvider = createMockApollo(requestHandlers); apolloProvider = createMockApollo(requestHandlers);
...@@ -56,6 +68,7 @@ describe('DependencyProxySettings', () => { ...@@ -56,6 +68,7 @@ describe('DependencyProxySettings', () => {
provide, provide,
propsData: { propsData: {
dependencyProxySettings, dependencyProxySettings,
dependencyProxyImageTtlPolicy,
isLoading, isLoading,
}, },
stubs: { stubs: {
...@@ -66,14 +79,26 @@ describe('DependencyProxySettings', () => { ...@@ -66,14 +79,26 @@ describe('DependencyProxySettings', () => {
}); });
}; };
beforeEach(() => {
updateSettingsMutationResolver = jest
.fn()
.mockResolvedValue(dependencyProxySettingMutationMock());
updateTtlPoliciesMutationResolver = jest
.fn()
.mockResolvedValue(dependencyProxyUpdateTllPolicyMutationMock());
});
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
}); });
const findSettingsBlock = () => wrapper.findComponent(SettingsBlock); const findSettingsBlock = () => wrapper.findComponent(SettingsBlock);
const findSettingsTitles = () => wrapper.findComponent(SettingsTitles);
const findDescription = () => wrapper.findByTestId('description'); const findDescription = () => wrapper.findByTestId('description');
const findDescriptionLink = () => wrapper.findByTestId('description-link'); const findDescriptionLink = () => wrapper.findByTestId('description-link');
const findToggle = () => wrapper.findComponent(GlToggle); const findEnableProxyToggle = () => wrapper.findByTestId('dependency-proxy-setting-toggle');
const findEnableTtlPoliciesToggle = () =>
wrapper.findByTestId('dependency-proxy-ttl-policies-toggle');
const findToggleHelpLink = () => wrapper.findByTestId('toggle-help-link'); const findToggleHelpLink = () => wrapper.findByTestId('toggle-help-link');
const fillApolloCache = () => { const fillApolloCache = () => {
...@@ -86,10 +111,6 @@ describe('DependencyProxySettings', () => { ...@@ -86,10 +111,6 @@ describe('DependencyProxySettings', () => {
}); });
}; };
const emitSettingsUpdate = (value = false) => {
findToggle().vm.$emit('change', value);
};
it('renders a settings block', () => { it('renders a settings block', () => {
mountComponent(); mountComponent();
...@@ -127,8 +148,8 @@ describe('DependencyProxySettings', () => { ...@@ -127,8 +148,8 @@ describe('DependencyProxySettings', () => {
it('exists', () => { it('exists', () => {
mountComponent(); mountComponent();
expect(findToggle().props()).toMatchObject({ expect(findEnableProxyToggle().props()).toMatchObject({
label: component.i18n.label, label: component.i18n.enabledProxyLabel,
}); });
}); });
...@@ -138,13 +159,13 @@ describe('DependencyProxySettings', () => { ...@@ -138,13 +159,13 @@ describe('DependencyProxySettings', () => {
}); });
it('has the help prop correctly set', () => { it('has the help prop correctly set', () => {
expect(findToggle().props()).toMatchObject({ expect(findEnableProxyToggle().props()).toMatchObject({
help: component.i18n.enabledProxyHelpText, help: component.i18n.enabledProxyHelpText,
}); });
}); });
it('has help text with a link', () => { it('has help text with a link', () => {
expect(findToggle().text()).toContain( expect(findEnableProxyToggle().text()).toContain(
'To see the image prefix and what is in the cache, visit the Dependency Proxy', 'To see the image prefix and what is in the cache, visit the Dependency Proxy',
); );
expect(findToggleHelpLink().attributes()).toMatchObject({ expect(findToggleHelpLink().attributes()).toMatchObject({
...@@ -161,7 +182,7 @@ describe('DependencyProxySettings', () => { ...@@ -161,7 +182,7 @@ describe('DependencyProxySettings', () => {
}); });
it('has the help prop set to empty', () => { it('has the help prop set to empty', () => {
expect(findToggle().props()).toMatchObject({ expect(findEnableProxyToggle().props()).toMatchObject({
help: '', help: '',
}); });
}); });
...@@ -172,13 +193,38 @@ describe('DependencyProxySettings', () => { ...@@ -172,13 +193,38 @@ describe('DependencyProxySettings', () => {
}); });
}); });
describe('settings update', () => { describe('storage settings', () => {
it('the component has the settings title', () => {
mountComponent();
expect(findSettingsTitles().props()).toMatchObject({
title: component.i18n.storageSettingsTitle,
});
});
describe('enable proxy ttl policies', () => {
it('exists', () => {
mountComponent();
expect(findEnableTtlPoliciesToggle().props()).toMatchObject({
label: component.i18n.ttlPolicyEnabledLabel,
help: component.i18n.ttlPolicyEnabledHelpText,
});
});
});
});
describe.each`
toggleName | toggleFinder | localErrorMock | optimisticResponse
${'enable proxy'} | ${findEnableProxyToggle} | ${dependencyProxySettingMutationMock} | ${updateGroupDependencyProxySettingsOptimisticResponse}
${'enable ttl policies'} | ${findEnableTtlPoliciesToggle} | ${dependencyProxyUpdateTllPolicyMutationMock} | ${updateDependencyProxyImageTtlGroupPolicyOptimisticResponse}
`('$toggleName settings update ', ({ optimisticResponse, toggleFinder, localErrorMock }) => {
describe('success state', () => { describe('success state', () => {
it('emits a success event', async () => { it('emits a success event', async () => {
mountComponent(); mountComponent();
fillApolloCache(); fillApolloCache();
emitSettingsUpdate(); toggleFinder().vm.$emit('change', false);
await waitForPromises(); await waitForPromises();
...@@ -190,26 +236,28 @@ describe('DependencyProxySettings', () => { ...@@ -190,26 +236,28 @@ describe('DependencyProxySettings', () => {
fillApolloCache(); fillApolloCache();
expect(findToggle().props('value')).toBe(true); expect(toggleFinder().props('value')).toBe(true);
emitSettingsUpdate(); toggleFinder().vm.$emit('change', false);
expect(updateGroupDependencyProxySettingsOptimisticResponse).toHaveBeenCalledWith({ expect(optimisticResponse).toHaveBeenCalledWith(
enabled: false, expect.objectContaining({
}); enabled: false,
}),
);
}); });
}); });
describe('errors', () => { describe('errors', () => {
it('mutation payload with root level errors', async () => { it('mutation payload with root level errors', async () => {
const mutationResolver = jest updateSettingsMutationResolver = jest.fn().mockResolvedValue(mutationErrorMock);
.fn() updateTtlPoliciesMutationResolver = jest.fn().mockResolvedValue(mutationErrorMock);
.mockResolvedValue(dependencyProxySettingMutationErrorMock);
mountComponent({ mutationResolver }); mountComponent();
fillApolloCache(); fillApolloCache();
emitSettingsUpdate(); toggleFinder().vm.$emit('change', false);
await waitForPromises(); await waitForPromises();
...@@ -217,14 +265,16 @@ describe('DependencyProxySettings', () => { ...@@ -217,14 +265,16 @@ describe('DependencyProxySettings', () => {
}); });
it.each` it.each`
type | mutationResolver type | mutationResolverMock
${'local'} | ${jest.fn().mockResolvedValue(dependencyProxySettingMutationMock({ errors: ['foo'] }))} ${'local'} | ${jest.fn().mockResolvedValue(localErrorMock({ errors: ['foo'] }))}
${'network'} | ${jest.fn().mockRejectedValue()} ${'network'} | ${jest.fn().mockRejectedValue()}
`('mutation payload with $type error', async ({ mutationResolver }) => { `('mutation payload with $type error', async ({ mutationResolverMock }) => {
mountComponent({ mutationResolver }); updateSettingsMutationResolver = mutationResolverMock;
updateTtlPoliciesMutationResolver = mutationResolverMock;
mountComponent();
fillApolloCache(); fillApolloCache();
emitSettingsUpdate(); toggleFinder().vm.$emit('change', false);
await waitForPromises(); await waitForPromises();
...@@ -234,10 +284,16 @@ describe('DependencyProxySettings', () => { ...@@ -234,10 +284,16 @@ describe('DependencyProxySettings', () => {
}); });
describe('when isLoading is true', () => { describe('when isLoading is true', () => {
it('disables enable toggle', () => { it('disables enable proxy toggle', () => {
mountComponent({ isLoading: true });
expect(findEnableProxyToggle().props('disabled')).toBe(true);
});
it('disables enable ttl policies toggle', () => {
mountComponent({ isLoading: true }); mountComponent({ isLoading: true });
expect(findToggle().props('disabled')).toBe(true); expect(findEnableTtlPoliciesToggle().props('disabled')).toBe(true);
}); });
}); });
}); });
...@@ -10,7 +10,12 @@ import DependencyProxySettings from '~/packages_and_registries/settings/group/co ...@@ -10,7 +10,12 @@ import DependencyProxySettings from '~/packages_and_registries/settings/group/co
import component from '~/packages_and_registries/settings/group/components/group_settings_app.vue'; import component from '~/packages_and_registries/settings/group/components/group_settings_app.vue';
import getGroupPackagesSettingsQuery from '~/packages_and_registries/settings/group/graphql/queries/get_group_packages_settings.query.graphql'; import getGroupPackagesSettingsQuery from '~/packages_and_registries/settings/group/graphql/queries/get_group_packages_settings.query.graphql';
import { groupPackageSettingsMock, packageSettings, dependencyProxySettings } from '../mock_data'; import {
groupPackageSettingsMock,
packageSettings,
dependencyProxySettings,
dependencyProxyImageTtlPolicy,
} from '../mock_data';
jest.mock('~/flash'); jest.mock('~/flash');
...@@ -66,11 +71,17 @@ describe('Group Settings App', () => { ...@@ -66,11 +71,17 @@ describe('Group Settings App', () => {
await nextTick(); await nextTick();
}; };
const packageSettingsProps = { packageSettings: packageSettings() };
const dependencyProxyProps = {
dependencyProxySettings: dependencyProxySettings(),
dependencyProxyImageTtlPolicy: dependencyProxyImageTtlPolicy(),
};
describe.each` describe.each`
finder | entityProp | entityValue | successMessage | errorMessage finder | entitySpecificProps | successMessage | errorMessage
${findPackageSettings} | ${'packageSettings'} | ${packageSettings()} | ${'Settings saved successfully'} | ${'An error occurred while saving the settings'} ${findPackageSettings} | ${packageSettingsProps} | ${'Settings saved successfully'} | ${'An error occurred while saving the settings'}
${findDependencyProxySettings} | ${'dependencyProxySettings'} | ${dependencyProxySettings()} | ${'Setting saved successfully'} | ${'An error occurred while saving the setting'} ${findDependencyProxySettings} | ${dependencyProxyProps} | ${'Setting saved successfully'} | ${'An error occurred while saving the setting'}
`('settings blocks', ({ finder, entityProp, entityValue, successMessage, errorMessage }) => { `('settings blocks', ({ finder, entitySpecificProps, successMessage, errorMessage }) => {
beforeEach(() => { beforeEach(() => {
mountComponent(); mountComponent();
return waitForApolloQueryAndRender(); return waitForApolloQueryAndRender();
...@@ -83,7 +94,7 @@ describe('Group Settings App', () => { ...@@ -83,7 +94,7 @@ describe('Group Settings App', () => {
it('binds the correctProps', () => { it('binds the correctProps', () => {
expect(finder().props()).toMatchObject({ expect(finder().props()).toMatchObject({
isLoading: false, isLoading: false,
[entityProp]: entityValue, ...entitySpecificProps,
}); });
}); });
......
...@@ -4,15 +4,19 @@ import SettingsTitles from '~/packages_and_registries/settings/group/components/ ...@@ -4,15 +4,19 @@ import SettingsTitles from '~/packages_and_registries/settings/group/components/
describe('settings_titles', () => { describe('settings_titles', () => {
let wrapper; let wrapper;
const mountComponent = () => { const defaultProps = {
title: 'foo',
subTitle: 'bar',
};
const mountComponent = (propsData = defaultProps) => {
wrapper = shallowMount(SettingsTitles, { wrapper = shallowMount(SettingsTitles, {
propsData: { propsData,
title: 'foo',
subTitle: 'bar',
},
}); });
}; };
const findSubTitle = () => wrapper.find('p');
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
}); });
...@@ -22,4 +26,10 @@ describe('settings_titles', () => { ...@@ -22,4 +26,10 @@ describe('settings_titles', () => {
expect(wrapper.element).toMatchSnapshot(); expect(wrapper.element).toMatchSnapshot();
}); });
it('does not render the subtitle paragraph when no subtitle is passed', () => {
mountComponent({ title: defaultProps.title });
expect(findSubTitle().exists()).toBe(false);
});
}); });
...@@ -17,6 +17,13 @@ describe('Package and Registries settings group cache updates', () => { ...@@ -17,6 +17,13 @@ describe('Package and Registries settings group cache updates', () => {
}, },
}; };
const updateDependencyProxyImageTtlGroupPolicyPayload = {
dependencyProxyImageTtlPolicy: {
enabled: false,
ttl: 45,
},
};
const cacheMock = { const cacheMock = {
group: { group: {
packageSettings: { packageSettings: {
...@@ -26,6 +33,10 @@ describe('Package and Registries settings group cache updates', () => { ...@@ -26,6 +33,10 @@ describe('Package and Registries settings group cache updates', () => {
dependencyProxySetting: { dependencyProxySetting: {
enabled: true, enabled: true,
}, },
dependencyProxyImageTtlPolicy: {
enabled: true,
ttl: 45,
},
}, },
}; };
...@@ -42,15 +53,26 @@ describe('Package and Registries settings group cache updates', () => { ...@@ -42,15 +53,26 @@ describe('Package and Registries settings group cache updates', () => {
}); });
describe.each` describe.each`
updateNamespacePackageSettings | updateDependencyProxySettings updateNamespacePackageSettings | updateDependencyProxySettings | updateDependencyProxyImageTtlGroupPolicy
${updateNamespacePackageSettingsPayload} | ${updateDependencyProxySettingsPayload} ${updateNamespacePackageSettingsPayload} | ${updateDependencyProxySettingsPayload} | ${undefined}
${undefined} | ${updateDependencyProxySettingsPayload} ${undefined} | ${updateDependencyProxySettingsPayload} | ${undefined}
${updateNamespacePackageSettingsPayload} | ${undefined} ${updateNamespacePackageSettingsPayload} | ${undefined} | ${undefined}
${undefined} | ${undefined} ${undefined} | ${undefined} | ${updateDependencyProxyImageTtlGroupPolicyPayload}
${undefined} | ${undefined} | ${undefined}
`( `(
'updateGroupPackageSettings', 'updateGroupPackageSettings',
({ updateNamespacePackageSettings, updateDependencyProxySettings }) => { ({
const payload = { data: { updateNamespacePackageSettings, updateDependencyProxySettings } }; updateNamespacePackageSettings,
updateDependencyProxySettings,
updateDependencyProxyImageTtlGroupPolicy,
}) => {
const payload = {
data: {
updateNamespacePackageSettings,
updateDependencyProxySettings,
updateDependencyProxyImageTtlGroupPolicy,
},
};
it('calls readQuery', () => { it('calls readQuery', () => {
updateGroupPackageSettings('foo')(client, payload); updateGroupPackageSettings('foo')(client, payload);
expect(client.readQuery).toHaveBeenCalledWith(queryAndVariables); expect(client.readQuery).toHaveBeenCalledWith(queryAndVariables);
...@@ -65,6 +87,7 @@ describe('Package and Registries settings group cache updates', () => { ...@@ -65,6 +87,7 @@ describe('Package and Registries settings group cache updates', () => {
...cacheMock.group, ...cacheMock.group,
...payload.data.updateNamespacePackageSettings, ...payload.data.updateNamespacePackageSettings,
...payload.data.updateDependencyProxySettings, ...payload.data.updateDependencyProxySettings,
...payload.data.updateDependencyProxyImageTtlGroupPolicy,
}, },
}, },
}); });
......
import { import {
updateGroupPackagesSettingsOptimisticResponse, updateGroupPackagesSettingsOptimisticResponse,
updateGroupDependencyProxySettingsOptimisticResponse, updateGroupDependencyProxySettingsOptimisticResponse,
updateDependencyProxyImageTtlGroupPolicyOptimisticResponse,
} from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses'; } from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses';
describe('Optimistic responses', () => { describe('Optimistic responses', () => {
...@@ -38,4 +39,22 @@ describe('Optimistic responses', () => { ...@@ -38,4 +39,22 @@ describe('Optimistic responses', () => {
`); `);
}); });
}); });
describe('updateDependencyProxyImageTtlGroupPolicyOptimisticResponse', () => {
it('returns the correct structure', () => {
expect(updateDependencyProxyImageTtlGroupPolicyOptimisticResponse({ foo: 'bar' }))
.toMatchInlineSnapshot(`
Object {
"__typename": "Mutation",
"updateDependencyProxyImageTtlGroupPolicy": Object {
"__typename": "UpdateDependencyProxyImageTtlGroupPolicyPayload",
"dependencyProxyImageTtlPolicy": Object {
"foo": "bar",
},
"errors": Array [],
},
}
`);
});
});
}); });
...@@ -10,6 +10,12 @@ export const dependencyProxySettings = (extend) => ({ ...@@ -10,6 +10,12 @@ export const dependencyProxySettings = (extend) => ({
...extend, ...extend,
}); });
export const dependencyProxyImageTtlPolicy = (extend) => ({
ttl: 90,
enabled: true,
...extend,
});
export const groupPackageSettingsMock = { export const groupPackageSettingsMock = {
data: { data: {
group: { group: {
...@@ -17,6 +23,7 @@ export const groupPackageSettingsMock = { ...@@ -17,6 +23,7 @@ export const groupPackageSettingsMock = {
fullPath: 'foo_group_path', fullPath: 'foo_group_path',
packageSettings: packageSettings(), packageSettings: packageSettings(),
dependencyProxySetting: dependencyProxySettings(), dependencyProxySetting: dependencyProxySettings(),
dependencyProxyImageTtlPolicy: dependencyProxyImageTtlPolicy(),
}, },
}, },
}; };
...@@ -46,6 +53,16 @@ export const dependencyProxySettingMutationMock = (override) => ({ ...@@ -46,6 +53,16 @@ export const dependencyProxySettingMutationMock = (override) => ({
}, },
}); });
export const dependencyProxyUpdateTllPolicyMutationMock = (override) => ({
data: {
updateDependencyProxyImageTtlGroupPolicy: {
dependencyProxyImageTtlPolicy: dependencyProxyImageTtlPolicy(),
errors: [],
...override,
},
},
});
export const groupPackageSettingsMutationErrorMock = { export const groupPackageSettingsMutationErrorMock = {
errors: [ errors: [
{ {
...@@ -70,7 +87,8 @@ export const groupPackageSettingsMutationErrorMock = { ...@@ -70,7 +87,8 @@ export const groupPackageSettingsMutationErrorMock = {
}, },
], ],
}; };
export const dependencyProxySettingMutationErrorMock = {
export const mutationErrorMock = {
errors: [ errors: [
{ {
message: 'Some error', message: 'Some error',
......
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