Commit 655f8035 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch...

Merge branch '322841-move-dependency-proxy-enable-under-settings-packages-registries-2' into 'master'

Finalise move of dependency proxy enable settings

See merge request gitlab-org/gitlab!71988
parents a49be57c 18a7ce38
......@@ -19,6 +19,7 @@ export default () => {
apolloProvider,
provide: {
defaultExpanded: parseBoolean(el.dataset.defaultExpanded),
dependencyProxyAvailable: parseBoolean(el.dataset.dependencyProxyAvailable),
groupPath: el.dataset.groupPath,
},
render(createElement) {
......
<script>
import { GlToggle, GlSprintf, GlLink } from '@gitlab/ui';
import { s__ } from '~/locale';
import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
import updateDependencyProxySettings from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_settings.mutation.graphql';
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 {
DEPENDENCY_PROXY_HEADER,
DEPENDENCY_PROXY_SETTINGS_DESCRIPTION,
DEPENDENCY_PROXY_DOCS_PATH,
} from '~/packages_and_registries/settings/group/constants';
export default {
name: 'DependencyProxySettings',
components: {
GlToggle,
GlSprintf,
GlLink,
SettingsBlock,
},
i18n: {
DEPENDENCY_PROXY_HEADER,
DEPENDENCY_PROXY_SETTINGS_DESCRIPTION,
label: s__('DependencyProxy|Enable Proxy'),
},
links: {
DEPENDENCY_PROXY_DOCS_PATH,
},
inject: ['defaultExpanded', 'groupPath'],
props: {
dependencyProxySettings: {
type: Object,
required: true,
},
isLoading: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
enabled: {
get() {
return this.dependencyProxySettings.enabled;
},
set(enabled) {
this.updateSettings({ enabled });
},
},
},
methods: {
async updateSettings(payload) {
try {
const { data } = await this.$apollo.mutate({
mutation: updateDependencyProxySettings,
variables: {
input: {
groupPath: this.groupPath,
...payload,
},
},
update: updateGroupPackageSettings(this.groupPath),
optimisticResponse: updateGroupDependencyProxySettingsOptimisticResponse({
...this.dependencyProxySettings,
...payload,
}),
});
if (data.updateDependencyProxySettings?.errors?.length > 0) {
throw new Error();
} else {
this.$emit('success');
}
} catch {
this.$emit('error');
}
},
},
};
</script>
<template>
<settings-block
:default-expanded="defaultExpanded"
data-qa-selector="dependency_proxy_settings_content"
>
<template #title> {{ $options.i18n.DEPENDENCY_PROXY_HEADER }} </template>
<template #description>
<span data-testid="description">
<gl-sprintf :message="$options.i18n.DEPENDENCY_PROXY_SETTINGS_DESCRIPTION">
<template #docLink="{ content }">
<gl-link :href="$options.links.DEPENDENCY_PROXY_DOCS_PATH">{{ content }}</gl-link>
</template>
</gl-sprintf>
</span>
</template>
<template #default>
<div>
<gl-toggle
v-model="enabled"
:disabled="isLoading"
:label="$options.i18n.label"
data-qa-selector="dependency_proxy_setting_toggle"
/>
</div>
</template>
</settings-block>
</template>
......@@ -86,6 +86,7 @@ export default {
:label="$options.i18n.DUPLICATES_TOGGLE_LABEL"
label-position="hidden"
:value="duplicatesAllowed"
:disabled="loading"
@change="update(modelNames.allowed, $event)"
/>
<div class="gl-ml-5">
......@@ -108,6 +109,7 @@ export default {
>
<gl-form-input
id="maven-duplicated-settings-regex-input"
:disabled="loading"
:value="duplicateExceptionRegex"
@change="update(modelNames.exception, $event)"
/>
......
<script>
import { GlAlert } from '@gitlab/ui';
import {
ERROR_UPDATING_SETTINGS,
SUCCESS_UPDATING_SETTINGS,
} from '~/packages_and_registries/settings/group/constants';
import { n__ } from '~/locale';
import PackagesSettings from '~/packages_and_registries/settings/group/components/packages_settings.vue';
import DependencyProxySettings from '~/packages_and_registries/settings/group/components/dependency_proxy_settings.vue';
import getGroupPackagesSettingsQuery from '~/packages_and_registries/settings/group/graphql/queries/get_group_packages_settings.query.graphql';
......@@ -13,8 +11,9 @@ export default {
components: {
GlAlert,
PackagesSettings,
DependencyProxySettings,
},
inject: ['groupPath'],
inject: ['groupPath', 'dependencyProxyAvailable'],
apollo: {
group: {
query: getGroupPackagesSettingsQuery,
......@@ -35,6 +34,9 @@ export default {
packageSettings() {
return this.group?.packageSettings || {};
},
dependencyProxySettings() {
return this.group?.dependencyProxySetting || {};
},
isLoading() {
return this.$apollo.queries.group.loading;
},
......@@ -43,12 +45,22 @@ export default {
dismissAlert() {
this.alertMessage = null;
},
handleSuccess() {
this.$toast.show(SUCCESS_UPDATING_SETTINGS);
handleSuccess(amount = 1) {
const successMessage = n__(
'Setting saved successfully',
'Settings saved successfully',
amount,
);
this.$toast.show(successMessage);
this.dismissAlert();
},
handleError() {
this.alertMessage = ERROR_UPDATING_SETTINGS;
handleError(amount = 1) {
const errorMessage = n__(
'An error occurred while saving the setting',
'An error occurred while saving the settings',
amount,
);
this.alertMessage = errorMessage;
},
},
};
......@@ -63,6 +75,14 @@ export default {
<packages-settings
:package-settings="packageSettings"
:is-loading="isLoading"
@success="handleSuccess(2)"
@error="handleError(2)"
/>
<dependency-proxy-settings
v-if="dependencyProxyAvailable"
:dependency-proxy-settings="dependencyProxySettings"
:is-loading="isLoading"
@success="handleSuccess"
@error="handleError"
/>
......
......@@ -18,11 +18,6 @@ export const DUPLICATES_SETTINGS_EXCEPTION_LEGEND = s__(
'PackageRegistry|Publish packages if their name or version matches this regex.',
);
export const SUCCESS_UPDATING_SETTINGS = s__('PackageRegistry|Settings saved successfully');
export const ERROR_UPDATING_SETTINGS = s__(
'PackageRegistry|An error occurred while saving the settings',
);
export const DEPENDENCY_PROXY_HEADER = s__('DependencyProxy|Dependency Proxy');
export const DEPENDENCY_PROXY_SETTINGS_DESCRIPTION = s__(
'DependencyProxy|Create a local proxy for storing frequently used upstream images. %{docLinkStart}Learn more%{docLinkEnd} about dependency proxies.',
......
mutation updateDependencyProxySettings($input: UpdateDependencyProxySettingsInput!) {
updateDependencyProxySettings(input: $input) {
dependencyProxySetting {
enabled
}
errors
}
}
query getGroupPackagesSettings($fullPath: ID!) {
group(fullPath: $fullPath) {
dependencyProxySetting {
enabled
}
packageSettings {
mavenDuplicatesAllowed
mavenDuplicateExceptionRegex
......
......@@ -9,9 +9,16 @@ export const updateGroupPackageSettings = (fullPath) => (client, { data: updated
const sourceData = client.readQuery(queryAndParams);
const data = produce(sourceData, (draftState) => {
draftState.group.packageSettings = {
...updatedData.updateNamespacePackageSettings.packageSettings,
};
if (updatedData.updateNamespacePackageSettings) {
draftState.group.packageSettings = {
...updatedData.updateNamespacePackageSettings.packageSettings,
};
}
if (updatedData.updateDependencyProxySettings) {
draftState.group.dependencyProxySetting = {
...updatedData.updateDependencyProxySettings.dependencyProxySetting,
};
}
});
client.writeQuery({
......
......@@ -9,3 +9,15 @@ export const updateGroupPackagesSettingsOptimisticResponse = (changes) => ({
},
},
});
export const updateGroupDependencyProxySettingsOptimisticResponse = (changes) => ({
// eslint-disable-next-line @gitlab/require-i18n-strings
__typename: 'Mutation',
updateDependencyProxySettings: {
__typename: 'UpdateDependencyProxySettingsPayload',
errors: [],
dependencyProxySetting: {
...changes,
},
},
});
......@@ -234,6 +234,10 @@ module Types
)
end
def dependency_proxy_setting
group.dependency_proxy_setting || group.create_dependency_proxy_setting
end
private
def group
......
......@@ -8,20 +8,9 @@
= _('Create a local proxy for storing frequently used upstream images. %{link_start}Learn more%{link_end} about dependency proxies.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
- if Feature.enabled?(:dependency_proxy_for_private_groups, default_enabled: true) || @group.public?
- if can?(current_user, :admin_dependency_proxy, @group)
= form_for(@dependency_proxy, method: :put, url: group_dependency_proxy_path(@group)) do |f|
.form-group
%h5.prepend-top-20= _('Enable proxy')
.js-dependency-proxy-toggle-area
= render "shared/buttons/project_feature_toggle", is_checked: @dependency_proxy.enabled?, label: s_("DependencyProxy|Toggle Dependency Proxy"), data: { qa_selector: 'dependency_proxy_setting_toggle' } do
= f.hidden_field :enabled, { class: 'js-project-feature-toggle-input'}
- if @dependency_proxy.enabled
= render 'groups/dependency_proxies/url'
- if @dependency_proxy.enabled
= render 'groups/dependency_proxies/url'
- else
- if @dependency_proxy.enabled
= render 'groups/dependency_proxies/url'
- else
.gl-alert.gl-alert-info
.gl-alert-container
......
- breadcrumb_title _('Packages & Registries')
- page_title _('Packages & Registries')
- @content_class = 'limit-container-width' unless fluid_layout
- dependency_proxy_available = Feature.enabled?(:dependency_proxy_for_private_groups, default_enabled: true) || @group.public?
%section#js-packages-and-registries-settings{ data: { default_expanded: expanded_by_default?.to_s, group_path: @group.full_path } }
%section#js-packages-and-registries-settings{ data: { default_expanded: expanded_by_default?.to_s,
group_path: @group.full_path,
dependency_proxy_available: dependency_proxy_available.to_s } }
......@@ -3827,6 +3827,11 @@ msgstr ""
msgid "An error occurred while saving changes: %{error}"
msgstr ""
msgid "An error occurred while saving the setting"
msgid_plural "An error occurred while saving the settings"
msgstr[0] ""
msgstr[1] ""
msgid "An error occurred while subscribing to notifications."
msgstr ""
......@@ -11217,7 +11222,7 @@ msgstr ""
msgid "DependencyProxy|Dependency Proxy"
msgstr ""
msgid "DependencyProxy|Toggle Dependency Proxy"
msgid "DependencyProxy|Enable Proxy"
msgstr ""
msgid "Depends on %d merge request being merged"
......@@ -12714,9 +12719,6 @@ msgstr ""
msgid "Enable protected paths rate limit"
msgstr ""
msgid "Enable proxy"
msgstr ""
msgid "Enable reCAPTCHA"
msgstr ""
......@@ -24230,9 +24232,6 @@ msgstr ""
msgid "PackageRegistry|Allow duplicates"
msgstr ""
msgid "PackageRegistry|An error occurred while saving the settings"
msgstr ""
msgid "PackageRegistry|App group: %{group}"
msgstr ""
......@@ -24464,9 +24463,6 @@ msgstr ""
msgid "PackageRegistry|Settings for Maven packages"
msgstr ""
msgid "PackageRegistry|Settings saved successfully"
msgstr ""
msgid "PackageRegistry|Show Composer commands"
msgstr ""
......@@ -31325,6 +31321,11 @@ msgstr ""
msgid "Setting enforced"
msgstr ""
msgid "Setting saved successfully"
msgid_plural "Settings saved successfully"
msgstr[0] ""
msgstr[1] ""
msgid "Setting this to 0 means using the system default timeout value."
msgstr ""
......
......@@ -4,19 +4,10 @@ module QA
module Page
module Group
class DependencyProxy < QA::Page::Base
view 'app/views/groups/dependency_proxies/show.html.haml' do
element :dependency_proxy_setting_toggle
end
view 'app/views/groups/dependency_proxies/_url.html.haml' do
element :dependency_proxy_count
end
def has_dependency_proxy_enabled?
toggle = find_element(:dependency_proxy_setting_toggle)
toggle[:class].include?('is-checked')
end
def has_blob_count?(blob_text)
has_element?(:dependency_proxy_count, text: blob_text)
end
......
......@@ -9,13 +9,15 @@ module QA
view 'app/assets/javascripts/packages_and_registries/settings/group/components/packages_settings.vue' do
element :package_registry_settings_content
end
view 'app/assets/javascripts/packages_and_registries/settings/group/components/packages_settings.vue' do
element :allow_duplicates_toggle
element :allow_duplicates_label
end
view 'app/assets/javascripts/packages_and_registries/settings/group/components/dependency_proxy_settings.vue' do
element :dependency_proxy_settings_content
element :dependency_proxy_setting_toggle
end
def set_allow_duplicates_disabled
expand_content :package_registry_settings_content do
click_element(:allow_duplicates_toggle) if duplicates_enabled?
......@@ -35,6 +37,15 @@ module QA
def duplicates_disabled?
has_element?(:allow_duplicates_label, text: 'Do not allow duplicates')
end
def has_dependency_proxy_enabled?
expand_content :dependency_proxy_settings_content do
within_element :dependency_proxy_setting_toggle do
toggle = find('button.gl-toggle')
toggle[:class].include?('is-checked')
end
end
end
end
end
end
......
......@@ -28,9 +28,9 @@ module QA
project.group.visit!
Page::Group::Menu.perform(&:go_to_dependency_proxy)
Page::Group::Menu.perform(&:go_to_package_settings)
Page::Group::DependencyProxy.perform do |index|
Page::Group::Settings::PackageRegistries.perform do |index|
expect(index).to have_dependency_proxy_enabled
end
end
......
......@@ -3,13 +3,14 @@
require 'spec_helper'
RSpec.describe 'Group Dependency Proxy' do
let(:developer) { create(:user) }
let(:owner) { create(:user) }
let(:reporter) { create(:user) }
let(:group) { create(:group) }
let(:path) { group_dependency_proxy_path(group) }
let(:settings_path) { group_settings_packages_and_registries_path(group) }
before do
group.add_developer(developer)
group.add_owner(owner)
group.add_reporter(reporter)
enable_feature
......@@ -22,42 +23,46 @@ RSpec.describe 'Group Dependency Proxy' do
visit path
expect(page).not_to have_css('.js-dependency-proxy-toggle-area')
expect(page).not_to have_css('.js-dependency-proxy-url')
end
end
context 'feature is available', :js do
context 'when logged in as group developer' do
context 'when logged in as group owner' do
before do
sign_in(developer)
visit path
sign_in(owner)
end
it 'sidebar menu is open' do
visit path
sidebar = find('.nav-sidebar')
expect(sidebar).to have_link _('Dependency Proxy')
end
it 'toggles defaults to enabled' do
page.within('.js-dependency-proxy-toggle-area') do
expect(find('.js-project-feature-toggle-input', visible: false).value).to eq('true')
end
visit path
expect(page).to have_css('.js-dependency-proxy-url')
end
it 'shows the proxy URL' do
page.within('.edit_dependency_proxy_group_setting') do
expect(find('.js-dependency-proxy-url').value).to have_content('/dependency_proxy/containers')
end
visit path
expect(find('.js-dependency-proxy-url').value).to have_content('/dependency_proxy/containers')
end
it 'hides the proxy URL when feature is disabled' do
page.within('.edit_dependency_proxy_group_setting') do
find('.js-project-feature-toggle').click
end
visit settings_path
wait_for_requests
click_button 'Enable Proxy'
expect(page).to have_button 'Enable Proxy', class: '!is-checked'
visit path
expect(page).not_to have_css('.js-dependency-proxy-url')
expect(find('.js-project-feature-toggle-input', visible: false).value).to eq('false')
end
end
......@@ -68,7 +73,6 @@ RSpec.describe 'Group Dependency Proxy' do
end
it 'does not show the feature toggle but shows the proxy URL' do
expect(page).not_to have_css('.js-dependency-proxy-toggle-area')
expect(find('.js-dependency-proxy-url').value).to have_content('/dependency_proxy/containers')
end
end
......@@ -76,7 +80,7 @@ RSpec.describe 'Group Dependency Proxy' do
context 'feature is not avaible' do
before do
sign_in(developer)
sign_in(owner)
end
context 'feature flag is disabled' do
......
import { GlSprintf, GlLink, GlToggle } from '@gitlab/ui';
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 component from '~/packages_and_registries/settings/group/components/dependency_proxy_settings.vue';
import {
DEPENDENCY_PROXY_HEADER,
DEPENDENCY_PROXY_SETTINGS_DESCRIPTION,
DEPENDENCY_PROXY_DOCS_PATH,
} from '~/packages_and_registries/settings/group/constants';
import updateDependencyProxySettings from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_settings.mutation.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 { updateGroupDependencyProxySettingsOptimisticResponse } from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses';
import {
dependencyProxySettings,
dependencyProxySettingMutationMock,
groupPackageSettingsMock,
dependencyProxySettingMutationErrorMock,
} from '../mock_data';
jest.mock('~/flash');
jest.mock('~/packages_and_registries/settings/group/graphql/utils/optimistic_responses');
const localVue = createLocalVue();
describe('DependencyProxySettings', () => {
let wrapper;
let apolloProvider;
const defaultProvide = {
defaultExpanded: false,
groupPath: 'foo_group_path',
};
localVue.use(VueApollo);
const mountComponent = ({
provide = defaultProvide,
mutationResolver = jest.fn().mockResolvedValue(dependencyProxySettingMutationMock()),
isLoading = false,
} = {}) => {
const requestHandlers = [[updateDependencyProxySettings, mutationResolver]];
apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMount(component, {
localVue,
apolloProvider,
provide,
propsData: {
dependencyProxySettings: dependencyProxySettings(),
isLoading,
},
stubs: {
GlSprintf,
SettingsBlock,
},
});
};
afterEach(() => {
wrapper.destroy();
});
const findSettingsBlock = () => wrapper.findComponent(SettingsBlock);
const findDescription = () => wrapper.find('[data-testid="description"');
const findLink = () => wrapper.findComponent(GlLink);
const findToggle = () => wrapper.findComponent(GlToggle);
const fillApolloCache = () => {
apolloProvider.defaultClient.cache.writeQuery({
query: getGroupPackagesSettingsQuery,
variables: {
fullPath: defaultProvide.groupPath,
},
...groupPackageSettingsMock,
});
};
const emitSettingsUpdate = (value = false) => {
findToggle().vm.$emit('change', value);
};
it('renders a settings block', () => {
mountComponent();
expect(findSettingsBlock().exists()).toBe(true);
});
it('passes the correct props to settings block', () => {
mountComponent();
expect(findSettingsBlock().props('defaultExpanded')).toBe(false);
});
it('has the correct header text', () => {
mountComponent();
expect(wrapper.text()).toContain(DEPENDENCY_PROXY_HEADER);
});
it('has the correct description text', () => {
mountComponent();
expect(findDescription().text()).toMatchInterpolatedText(DEPENDENCY_PROXY_SETTINGS_DESCRIPTION);
});
it('has the correct link', () => {
mountComponent();
expect(findLink().attributes()).toMatchObject({
href: DEPENDENCY_PROXY_DOCS_PATH,
});
expect(findLink().text()).toBe('Learn more');
});
describe('settings update', () => {
describe('success state', () => {
it('emits a success event', async () => {
mountComponent();
fillApolloCache();
emitSettingsUpdate();
await waitForPromises();
expect(wrapper.emitted('success')).toEqual([[]]);
});
it('has an optimistic response', () => {
mountComponent();
fillApolloCache();
expect(findToggle().props('value')).toBe(true);
emitSettingsUpdate();
expect(updateGroupDependencyProxySettingsOptimisticResponse).toHaveBeenCalledWith({
enabled: false,
});
});
});
describe('errors', () => {
it('mutation payload with root level errors', async () => {
const mutationResolver = jest
.fn()
.mockResolvedValue(dependencyProxySettingMutationErrorMock);
mountComponent({ mutationResolver });
fillApolloCache();
emitSettingsUpdate();
await waitForPromises();
expect(wrapper.emitted('error')).toEqual([[]]);
});
it.each`
type | mutationResolver
${'local'} | ${jest.fn().mockResolvedValue(dependencyProxySettingMutationMock({ errors: ['foo'] }))}
${'network'} | ${jest.fn().mockRejectedValue()}
`('mutation payload with $type error', async ({ mutationResolver }) => {
mountComponent({ mutationResolver });
fillApolloCache();
emitSettingsUpdate();
await waitForPromises();
expect(wrapper.emitted('error')).toEqual([[]]);
});
});
});
describe('when isLoading is true', () => {
it('disables enable toggle', () => {
mountComponent({ isLoading: true });
expect(findToggle().props('disabled')).toBe(true);
});
});
});
......@@ -143,4 +143,18 @@ describe('Duplicates Settings', () => {
expect(findInputGroup().exists()).toBe(false);
});
});
describe('loading', () => {
beforeEach(() => {
mountComponent({ ...defaultProps, loading: true });
});
it('disables the enable toggle', () => {
expect(findToggle().props('disabled')).toBe(true);
});
it('disables the form input', () => {
expect(findInput().attributes('disabled')).toBe('true');
});
});
});
......@@ -5,16 +5,12 @@ import { nextTick } from 'vue';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import PackagesSettings from '~/packages_and_registries/settings/group/components/packages_settings.vue';
import DependencyProxySettings from '~/packages_and_registries/settings/group/components/dependency_proxy_settings.vue';
import component from '~/packages_and_registries/settings/group/components/group_settings_app.vue';
import {
ERROR_UPDATING_SETTINGS,
SUCCESS_UPDATING_SETTINGS,
} from '~/packages_and_registries/settings/group/constants';
import getGroupPackagesSettingsQuery from '~/packages_and_registries/settings/group/graphql/queries/get_group_packages_settings.query.graphql';
import { groupPackageSettingsMock, packageSettings } from '../mock_data';
import { groupPackageSettingsMock, packageSettings, dependencyProxySettings } from '../mock_data';
jest.mock('~/flash');
......@@ -28,10 +24,12 @@ describe('Group Settings App', () => {
const defaultProvide = {
defaultExpanded: false,
groupPath: 'foo_group_path',
dependencyProxyAvailable: true,
};
const mountComponent = ({
resolver = jest.fn().mockResolvedValue(groupPackageSettingsMock),
provide = defaultProvide,
} = {}) => {
localVue.use(VueApollo);
......@@ -42,7 +40,7 @@ describe('Group Settings App', () => {
wrapper = shallowMount(component, {
localVue,
apolloProvider,
provide: defaultProvide,
provide,
mocks: {
$toast: {
show,
......@@ -61,6 +59,7 @@ describe('Group Settings App', () => {
const findAlert = () => wrapper.findComponent(GlAlert);
const findPackageSettings = () => wrapper.findComponent(PackagesSettings);
const findDependencyProxySettings = () => wrapper.findComponent(DependencyProxySettings);
const waitForApolloQueryAndRender = async () => {
await waitForPromises();
......@@ -68,9 +67,10 @@ describe('Group Settings App', () => {
};
describe.each`
finder | entityProp | entityValue
${findPackageSettings} | ${'packageSettings'} | ${packageSettings()}
`('settings blocks', ({ finder, entityProp, entityValue }) => {
finder | entityProp | entityValue | successMessage | errorMessage
${findPackageSettings} | ${'packageSettings'} | ${packageSettings()} | ${'Settings saved successfully'} | ${'An error occurred while saving the settings'}
${findDependencyProxySettings} | ${'dependencyProxySettings'} | ${dependencyProxySettings()} | ${'Setting saved successfully'} | ${'An error occurred while saving the setting'}
`('settings blocks', ({ finder, entityProp, entityValue, successMessage, errorMessage }) => {
beforeEach(() => {
mountComponent();
return waitForApolloQueryAndRender();
......@@ -90,7 +90,7 @@ describe('Group Settings App', () => {
describe('success event', () => {
it('shows a success toast', () => {
finder().vm.$emit('success');
expect(show).toHaveBeenCalledWith(SUCCESS_UPDATING_SETTINGS);
expect(show).toHaveBeenCalledWith(successMessage);
});
it('hides the error alert', async () => {
......@@ -117,7 +117,7 @@ describe('Group Settings App', () => {
});
it('alert has the right text', () => {
expect(findAlert().text()).toBe(ERROR_UPDATING_SETTINGS);
expect(findAlert().text()).toBe(errorMessage);
});
it('dismissing the alert removes it', async () => {
......@@ -131,4 +131,15 @@ describe('Group Settings App', () => {
});
});
});
describe('when the dependency proxy is not available', () => {
beforeEach(() => {
mountComponent({ provide: { ...defaultProvide, dependencyProxyAvailable: false } });
return waitForApolloQueryAndRender();
});
it('the setting block is hidden', () => {
expect(findDependencyProxySettings().exists()).toBe(false);
});
});
});
......@@ -4,14 +4,16 @@ import { updateGroupPackageSettings } from '~/packages_and_registries/settings/g
describe('Package and Registries settings group cache updates', () => {
let client;
const payload = {
data: {
updateNamespacePackageSettings: {
packageSettings: {
mavenDuplicatesAllowed: false,
mavenDuplicateExceptionRegex: 'latest[main]something',
},
},
const updateNamespacePackageSettingsPayload = {
packageSettings: {
mavenDuplicatesAllowed: false,
mavenDuplicateExceptionRegex: 'latest[main]something',
},
};
const updateDependencyProxySettingsPayload = {
dependencyProxySetting: {
enabled: false,
},
};
......@@ -21,6 +23,9 @@ describe('Package and Registries settings group cache updates', () => {
mavenDuplicatesAllowed: true,
mavenDuplicateExceptionRegex: '',
},
dependencyProxySetting: {
enabled: true,
},
},
};
......@@ -35,22 +40,35 @@ describe('Package and Registries settings group cache updates', () => {
writeQuery: jest.fn(),
};
});
describe('updateGroupPackageSettings', () => {
it('calls readQuery', () => {
updateGroupPackageSettings('foo')(client, payload);
expect(client.readQuery).toHaveBeenCalledWith(queryAndVariables);
});
it('writes the correct result in the cache', () => {
updateGroupPackageSettings('foo')(client, payload);
expect(client.writeQuery).toHaveBeenCalledWith({
...queryAndVariables,
data: {
group: {
...payload.data.updateNamespacePackageSettings,
describe.each`
updateNamespacePackageSettings | updateDependencyProxySettings
${updateNamespacePackageSettingsPayload} | ${updateDependencyProxySettingsPayload}
${undefined} | ${updateDependencyProxySettingsPayload}
${updateNamespacePackageSettingsPayload} | ${undefined}
${undefined} | ${undefined}
`(
'updateGroupPackageSettings',
({ updateNamespacePackageSettings, updateDependencyProxySettings }) => {
const payload = { data: { updateNamespacePackageSettings, updateDependencyProxySettings } };
it('calls readQuery', () => {
updateGroupPackageSettings('foo')(client, payload);
expect(client.readQuery).toHaveBeenCalledWith(queryAndVariables);
});
it('writes the correct result in the cache', () => {
updateGroupPackageSettings('foo')(client, payload);
expect(client.writeQuery).toHaveBeenCalledWith({
...queryAndVariables,
data: {
group: {
...cacheMock.group,
...payload.data.updateNamespacePackageSettings,
...payload.data.updateDependencyProxySettings,
},
},
},
});
});
});
});
},
);
});
import { updateGroupPackagesSettingsOptimisticResponse } from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses';
import {
updateGroupPackagesSettingsOptimisticResponse,
updateGroupDependencyProxySettingsOptimisticResponse,
} from '~/packages_and_registries/settings/group/graphql/utils/optimistic_responses';
describe('Optimistic responses', () => {
describe('updateGroupPackagesSettingsOptimisticResponse', () => {
......@@ -17,4 +20,22 @@ describe('Optimistic responses', () => {
`);
});
});
describe('updateGroupDependencyProxySettingsOptimisticResponse', () => {
it('returns the correct structure', () => {
expect(updateGroupDependencyProxySettingsOptimisticResponse({ foo: 'bar' }))
.toMatchInlineSnapshot(`
Object {
"__typename": "Mutation",
"updateDependencyProxySettings": Object {
"__typename": "UpdateDependencyProxySettingsPayload",
"dependencyProxySetting": Object {
"foo": "bar",
},
"errors": Array [],
},
}
`);
});
});
});
......@@ -5,11 +5,16 @@ export const packageSettings = () => ({
genericDuplicateExceptionRegex: '',
});
export const dependencyProxySettings = () => ({
enabled: true,
});
export const groupPackageSettingsMock = {
data: {
group: {
fullPath: 'foo_group_path',
packageSettings: packageSettings(),
dependencyProxySetting: dependencyProxySettings(),
},
},
};
......@@ -29,6 +34,16 @@ export const groupPackageSettingsMutationMock = (override) => ({
},
});
export const dependencyProxySettingMutationMock = (override) => ({
data: {
updateDependencyProxySettings: {
dependencyProxySetting: dependencyProxySettings(),
errors: [],
...override,
},
},
});
export const groupPackageSettingsMutationErrorMock = {
errors: [
{
......@@ -53,3 +68,23 @@ export const groupPackageSettingsMutationErrorMock = {
},
],
};
export const dependencyProxySettingMutationErrorMock = {
errors: [
{
message: 'Some error',
locations: [{ line: 1, column: 41 }],
extensions: {
value: {
enabled: 'gitlab-org',
},
problems: [
{
path: ['enabled'],
explanation: 'explaination',
message: 'message',
},
],
},
},
],
};
......@@ -33,46 +33,59 @@ RSpec.describe 'getting dependency proxy settings for a group' do
before do
stub_config(dependency_proxy: { enabled: true })
group.create_dependency_proxy_setting!(enabled: true)
end
subject { post_graphql(query, current_user: user, variables: variables) }
it_behaves_like 'a working graphql query' do
before do
subject
end
end
context 'with different permissions' do
where(:group_visibility, :role, :access_granted) do
:private | :maintainer | true
:private | :developer | true
:private | :reporter | true
:private | :guest | true
:private | :anonymous | false
:public | :maintainer | true
:public | :developer | true
:public | :reporter | true
:public | :guest | true
:public | :anonymous | false
shared_examples 'dependency proxy group setting query' do
it_behaves_like 'a working graphql query' do
before do
subject
end
end
with_them do
before do
group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
group.add_user(user, role) unless role == :anonymous
context 'with different permissions' do
where(:group_visibility, :role, :access_granted) do
:private | :maintainer | true
:private | :developer | true
:private | :reporter | true
:private | :guest | true
:private | :anonymous | false
:public | :maintainer | true
:public | :developer | true
:public | :reporter | true
:public | :guest | true
:public | :anonymous | false
end
it 'return the proper response' do
subject
with_them do
before do
group.update_column(:visibility_level, Gitlab::VisibilityLevel.const_get(group_visibility.to_s.upcase, false))
group.add_user(user, role) unless role == :anonymous
end
it 'return the proper response' do
subject
if access_granted
expect(dependency_proxy_group_setting_response).to eq('enabled' => true)
else
expect(dependency_proxy_group_setting_response).to be_blank
if access_granted
expect(dependency_proxy_group_setting_response).to eq('enabled' => true)
else
expect(dependency_proxy_group_setting_response).to be_blank
end
end
end
end
end
context 'with the settings model created' do
before do
group.create_dependency_proxy_setting!(enabled: true)
end
it_behaves_like 'dependency proxy group setting query'
end
context 'without the settings model created' do
it_behaves_like 'dependency proxy group setting query'
end
end
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