Skip to content
Snippets Groups Projects
Commit f14507e5 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent f4d27d53
No related branches found
No related tags found
No related merge requests found
Showing
with 432 additions and 337 deletions
Loading
Loading
@@ -4,7 +4,7 @@ import component from '~/registry/settings/components/registry_settings_app.vue'
import SettingsForm from '~/registry/settings/components/settings_form.vue';
import { createStore } from '~/registry/settings/store/';
import { SET_IS_DISABLED } from '~/registry/settings/store/mutation_types';
import { FETCH_SETTINGS_ERROR_MESSAGE } from '~/registry/settings/constants';
import { FETCH_SETTINGS_ERROR_MESSAGE } from '~/registry/shared/constants';
 
describe('Registry Settings App', () => {
let wrapper;
Loading
Loading
import { mount } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import Tracking from '~/tracking';
import stubChildren from 'helpers/stub_children';
import component from '~/registry/settings/components/settings_form.vue';
import expirationPolicyForm from '~/registry/shared/components/expiration_policy_form.vue';
import { createStore } from '~/registry/settings/store/';
import {
NAME_REGEX_LENGTH,
UPDATE_SETTINGS_ERROR_MESSAGE,
UPDATE_SETTINGS_SUCCESS_MESSAGE,
} from '~/registry/settings/constants';
import { stringifiedFormOptions } from '../mock_data';
} from '~/registry/shared/constants';
import { stringifiedFormOptions } from '../../shared/mock_data';
 
describe('Settings Form', () => {
let wrapper;
let store;
let dispatchSpy;
 
const FORM_ELEMENTS_ID_PREFIX = '#expiration-policy';
const trackingPayload = {
label: 'docker_container_retention_and_expiration_policies',
};
 
const GlLoadingIcon = { name: 'gl-loading-icon-stub', template: '<svg></svg>' };
const findForm = () => wrapper.find(expirationPolicyForm);
 
const findFormGroup = name => wrapper.find(`${FORM_ELEMENTS_ID_PREFIX}-${name}-group`);
const findFormElements = (name, parent = wrapper) =>
parent.find(`${FORM_ELEMENTS_ID_PREFIX}-${name}`);
const findCancelButton = () => wrapper.find({ ref: 'cancel-button' });
const findSaveButton = () => wrapper.find({ ref: 'save-button' });
const findForm = () => wrapper.find({ ref: 'form-element' });
const findLoadingIcon = (parent = wrapper) => parent.find(GlLoadingIcon);
const mountComponent = (options = {}) => {
wrapper = mount(component, {
stubs: {
...stubChildren(component),
GlCard: false,
GlLoadingIcon,
},
const mountComponent = () => {
wrapper = shallowMount(component, {
mocks: {
$toast: {
show: jest.fn(),
},
},
store,
...options,
});
};
 
Loading
Loading
@@ -59,170 +43,50 @@ describe('Settings Form', () => {
wrapper.destroy();
});
 
it('renders', () => {
expect(wrapper.element).toMatchSnapshot();
});
describe.each`
elementName | modelName | value | disabledByToggle
${'toggle'} | ${'enabled'} | ${true} | ${'not disabled'}
${'interval'} | ${'older_than'} | ${'foo'} | ${'disabled'}
${'schedule'} | ${'cadence'} | ${'foo'} | ${'disabled'}
${'latest'} | ${'keep_n'} | ${'foo'} | ${'disabled'}
${'name-matching'} | ${'name_regex'} | ${'foo'} | ${'disabled'}
`(
`${FORM_ELEMENTS_ID_PREFIX}-$elementName form element`,
({ elementName, modelName, value, disabledByToggle }) => {
let formGroup;
beforeEach(() => {
formGroup = findFormGroup(elementName);
});
it(`${elementName} form group exist in the dom`, () => {
expect(formGroup.exists()).toBe(true);
});
it(`${elementName} form group has a label-for property`, () => {
expect(formGroup.attributes('label-for')).toBe(`expiration-policy-${elementName}`);
});
it(`${elementName} form group has a label-cols property`, () => {
expect(formGroup.attributes('label-cols')).toBe(`${wrapper.vm.$options.labelsConfig.cols}`);
});
it(`${elementName} form group has a label-align property`, () => {
expect(formGroup.attributes('label-align')).toBe(
`${wrapper.vm.$options.labelsConfig.align}`,
);
});
it(`${elementName} form group contains an input element`, () => {
expect(findFormElements(elementName, formGroup).exists()).toBe(true);
});
it(`${elementName} form element change updated ${modelName} with ${value}`, () => {
const element = findFormElements(elementName, formGroup);
const modelUpdateEvent = element.vm.$options.model
? element.vm.$options.model.event
: 'input';
element.vm.$emit(modelUpdateEvent, value);
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm[modelName]).toBe(value);
});
});
it(`${elementName} is ${disabledByToggle} by enabled set to false`, () => {
store.dispatch('updateSettings', { enabled: false });
const expectation = disabledByToggle === 'disabled' ? 'true' : undefined;
expect(findFormElements(elementName, formGroup).attributes('disabled')).toBe(expectation);
});
},
);
describe('form actions', () => {
describe('form', () => {
let form;
beforeEach(() => {
form = findForm();
});
 
describe('cancel button', () => {
it('has type reset', () => {
expect(findCancelButton().attributes('type')).toBe('reset');
});
it('is disabled the form was not changed from his original value', () => {
store.dispatch('receiveSettingsSuccess', { foo: 'bar' });
return wrapper.vm.$nextTick().then(() => {
expect(findCancelButton().attributes('disabled')).toBe('true');
});
});
it('is disabled when the form data is loading', () => {
store.dispatch('toggleLoading');
return wrapper.vm.$nextTick().then(() => {
expect(findCancelButton().attributes('disabled')).toBe('true');
});
});
it('is enabled when the user changed something in the form and the data is not being loaded', () => {
store.dispatch('receiveSettingsSuccess', { foo: 'bar' });
store.dispatch('updateSettings', { foo: 'baz' });
return wrapper.vm.$nextTick().then(() => {
expect(findCancelButton().attributes('disabled')).toBe(undefined);
});
describe('data binding', () => {
it('v-model change update the settings property', () => {
dispatchSpy.mockReturnValue();
form.vm.$emit('input', 'foo');
expect(dispatchSpy).toHaveBeenCalledWith('updateSettings', { settings: 'foo' });
});
});
 
describe('form cancel event', () => {
describe('form reset event', () => {
it('calls the appropriate function', () => {
dispatchSpy.mockReturnValue();
form.trigger('reset');
form.vm.$emit('reset');
expect(dispatchSpy).toHaveBeenCalledWith('resetSettings');
});
 
it('tracks the reset event', () => {
dispatchSpy.mockReturnValue();
form.trigger('reset');
form.vm.$emit('reset');
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'reset_form', trackingPayload);
});
});
 
it('save has type submit', () => {
expect(findSaveButton().attributes('type')).toBe('submit');
});
describe('when isLoading is true', () => {
beforeEach(() => {
store.dispatch('toggleLoading');
});
afterEach(() => {
store.dispatch('toggleLoading');
});
it.each`
elementName
${'toggle'}
${'interval'}
${'schedule'}
${'latest'}
${'name-matching'}
`(`${FORM_ELEMENTS_ID_PREFIX}-$elementName is disabled`, ({ elementName }) => {
expect(findFormElements(elementName).attributes('disabled')).toBe('true');
});
it('submit button is disabled and shows a spinner', () => {
const button = findSaveButton();
expect(button.attributes('disabled')).toBeTruthy();
expect(findLoadingIcon(button)).toExist();
});
it('cancel button is disabled', () => {
expect(findCancelButton().attributes('disabled')).toBeTruthy();
});
});
describe('form submit event ', () => {
it('calls the appropriate function', () => {
dispatchSpy.mockResolvedValue();
form.trigger('submit');
expect(dispatchSpy).toHaveBeenCalled();
});
it('dispatches the saveSettings action', () => {
dispatchSpy.mockResolvedValue();
form.trigger('submit');
form.vm.$emit('submit');
expect(dispatchSpy).toHaveBeenCalledWith('saveSettings');
});
 
it('tracks the submit event', () => {
dispatchSpy.mockResolvedValue();
form.trigger('submit');
form.vm.$emit('submit');
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'submit_form', trackingPayload);
});
 
it('show a success toast when submit succeed', () => {
dispatchSpy.mockResolvedValue();
form.trigger('submit');
form.vm.$emit('submit');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_SUCCESS_MESSAGE, {
type: 'success',
Loading
Loading
@@ -232,7 +96,7 @@ describe('Settings Form', () => {
 
it('show an error toast when submit fails', () => {
dispatchSpy.mockRejectedValue();
form.trigger('submit');
form.vm.$emit('submit');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE, {
type: 'error',
Loading
Loading
@@ -241,45 +105,4 @@ describe('Settings Form', () => {
});
});
});
describe('form validation', () => {
describe(`when name regex is longer than ${NAME_REGEX_LENGTH}`, () => {
const invalidString = new Array(NAME_REGEX_LENGTH + 2).join(',');
beforeEach(() => {
store.dispatch('updateSettings', { name_regex: invalidString });
});
it('save btn is disabled', () => {
expect(findSaveButton().attributes('disabled')).toBeTruthy();
});
it('nameRegexState is false', () => {
expect(wrapper.vm.nameRegexState).toBe(false);
});
});
it('if the user did not type validation is null', () => {
store.dispatch('updateSettings', { name_regex: null });
expect(wrapper.vm.nameRegexState).toBe(null);
return wrapper.vm.$nextTick().then(() => {
expect(findSaveButton().attributes('disabled')).toBeFalsy();
});
});
it(`if the user typed and is less than ${NAME_REGEX_LENGTH} state is true`, () => {
store.dispatch('updateSettings', { name_regex: 'abc' });
expect(wrapper.vm.nameRegexState).toBe(true);
});
});
describe('help text', () => {
it('toggleDescriptionText text reflects enabled property', () => {
const toggleHelpText = findFormGroup('toggle').find('span');
expect(toggleHelpText.html()).toContain('disabled');
wrapper.setData({ enabled: true });
return wrapper.vm.$nextTick().then(() => {
expect(toggleHelpText.html()).toContain('enabled');
});
});
});
});
Loading
Loading
@@ -10,11 +10,14 @@ describe('Actions Registry Store', () => {
${'updateSettings'} | ${types.UPDATE_SETTINGS} | ${'foo'}
${'toggleLoading'} | ${types.TOGGLE_LOADING} | ${undefined}
${'resetSettings'} | ${types.RESET_SETTINGS} | ${undefined}
`('%s action invokes %s mutation with payload %s', ({ actionName, mutationName, payload }) => {
it('should set the initial state', done => {
testAction(actions[actionName], payload, {}, [{ type: mutationName, payload }], [], done);
});
});
`(
'$actionName invokes $mutationName with payload $payload',
({ actionName, mutationName, payload }) => {
it('should set state', done => {
testAction(actions[actionName], payload, {}, [{ type: mutationName, payload }], [], done);
});
},
);
 
describe('receiveSettingsSuccess', () => {
it('calls SET_SETTINGS when data is present', () => {
Loading
Loading
import * as getters from '~/registry/settings/store/getters';
import * as utils from '~/registry/settings/utils';
import { formOptions } from '../mock_data';
import * as utils from '~/registry/shared/utils';
import { formOptions } from '../../shared/mock_data';
 
describe('Getters registry settings store', () => {
const settings = {
Loading
Loading
import mutations from '~/registry/settings/store/mutations';
import * as types from '~/registry/settings/store/mutation_types';
import createState from '~/registry/settings/store/state';
import { formOptions, stringifiedFormOptions } from '../mock_data';
import { formOptions, stringifiedFormOptions } from '../../shared/mock_data';
 
describe('Mutations Registry Store', () => {
let mockState;
Loading
Loading
@@ -28,7 +28,7 @@ describe('Mutations Registry Store', () => {
mockState.settings = { foo: 'bar' };
const payload = { foo: 'baz' };
const expectedState = { ...mockState, settings: payload };
mutations[types.UPDATE_SETTINGS](mockState, payload);
mutations[types.UPDATE_SETTINGS](mockState, { settings: payload });
expect(mockState.settings).toEqual(expectedState.settings);
});
});
Loading
Loading
// Jest Snapshot v1, https://goo.gl/fbAQLP
 
exports[`Settings Form renders 1`] = `
<form>
exports[`Expiration Policy Form renders 1`] = `
<form
class="lh-2"
>
<div
class="card"
>
Loading
Loading
@@ -56,7 +58,6 @@ exports[`Settings Form renders 1`] = `
<glformselect-stub
disabled="true"
id="expiration-policy-interval"
value="bar"
>
<option
value="foo"
Loading
Loading
@@ -85,7 +86,6 @@ exports[`Settings Form renders 1`] = `
<glformselect-stub
disabled="true"
id="expiration-policy-schedule"
value="bar"
>
<option
value="foo"
Loading
Loading
@@ -114,7 +114,6 @@ exports[`Settings Form renders 1`] = `
<glformselect-stub
disabled="true"
id="expiration-policy-latest"
value="bar"
>
<option
value="foo"
Loading
Loading
@@ -159,7 +158,6 @@ exports[`Settings Form renders 1`] = `
>
<glbutton-stub
class="mr-2 d-block"
disabled="true"
size="md"
type="reset"
variant="secondary"
Loading
Loading
import { mount } from '@vue/test-utils';
import stubChildren from 'helpers/stub_children';
import component from '~/registry/shared/components/expiration_policy_form.vue';
import { NAME_REGEX_LENGTH } from '~/registry/shared/constants';
import { formOptions } from '../mock_data';
describe('Expiration Policy Form', () => {
let wrapper;
const FORM_ELEMENTS_ID_PREFIX = '#expiration-policy';
const GlLoadingIcon = { name: 'gl-loading-icon-stub', template: '<svg></svg>' };
const findFormGroup = name => wrapper.find(`${FORM_ELEMENTS_ID_PREFIX}-${name}-group`);
const findFormElements = (name, parent = wrapper) =>
parent.find(`${FORM_ELEMENTS_ID_PREFIX}-${name}`);
const findCancelButton = () => wrapper.find({ ref: 'cancel-button' });
const findSaveButton = () => wrapper.find({ ref: 'save-button' });
const findForm = () => wrapper.find({ ref: 'form-element' });
const findLoadingIcon = (parent = wrapper) => parent.find(GlLoadingIcon);
const mountComponent = props => {
wrapper = mount(component, {
stubs: {
...stubChildren(component),
GlCard: false,
GlLoadingIcon,
},
propsData: {
formOptions,
...props,
},
methods: {
// override idGenerator to avoid having to test with dynamic uid
idGenerator: value => value,
},
});
};
afterEach(() => {
wrapper.destroy();
});
it('renders', () => {
mountComponent();
expect(wrapper.element).toMatchSnapshot();
});
describe.each`
elementName | modelName | value | disabledByToggle
${'toggle'} | ${'enabled'} | ${true} | ${'not disabled'}
${'interval'} | ${'older_than'} | ${'foo'} | ${'disabled'}
${'schedule'} | ${'cadence'} | ${'foo'} | ${'disabled'}
${'latest'} | ${'keep_n'} | ${'foo'} | ${'disabled'}
${'name-matching'} | ${'name_regex'} | ${'foo'} | ${'disabled'}
`(
`${FORM_ELEMENTS_ID_PREFIX}-$elementName form element`,
({ elementName, modelName, value, disabledByToggle }) => {
it(`${elementName} form group exist in the dom`, () => {
mountComponent();
const formGroup = findFormGroup(elementName);
expect(formGroup.exists()).toBe(true);
});
it(`${elementName} form group has a label-for property`, () => {
mountComponent();
const formGroup = findFormGroup(elementName);
expect(formGroup.attributes('label-for')).toBe(`expiration-policy-${elementName}`);
});
it(`${elementName} form group has a label-cols property`, () => {
mountComponent({ labelCols: '1' });
const formGroup = findFormGroup(elementName);
return wrapper.vm.$nextTick().then(() => {
expect(formGroup.attributes('label-cols')).toBe('1');
});
});
it(`${elementName} form group has a label-align property`, () => {
mountComponent({ labelAlign: 'foo' });
const formGroup = findFormGroup(elementName);
return wrapper.vm.$nextTick().then(() => {
expect(formGroup.attributes('label-align')).toBe('foo');
});
});
it(`${elementName} form group contains an input element`, () => {
mountComponent();
const formGroup = findFormGroup(elementName);
expect(findFormElements(elementName, formGroup).exists()).toBe(true);
});
it(`${elementName} form element change updated ${modelName} with ${value}`, () => {
mountComponent();
const formGroup = findFormGroup(elementName);
const element = findFormElements(elementName, formGroup);
const modelUpdateEvent = element.vm.$options.model
? element.vm.$options.model.event
: 'input';
element.vm.$emit(modelUpdateEvent, value);
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted('input')).toEqual([[{ [modelName]: value }]]);
});
});
it(`${elementName} is ${disabledByToggle} by enabled set to false`, () => {
mountComponent({ settings: { enabled: false } });
const formGroup = findFormGroup(elementName);
const expectation = disabledByToggle === 'disabled' ? 'true' : undefined;
expect(findFormElements(elementName, formGroup).attributes('disabled')).toBe(expectation);
});
},
);
describe('form actions', () => {
describe('cancel button', () => {
it('has type reset', () => {
mountComponent();
expect(findCancelButton().attributes('type')).toBe('reset');
});
it('is disabled when disableCancelButton is true', () => {
mountComponent({ disableCancelButton: true });
return wrapper.vm.$nextTick().then(() => {
expect(findCancelButton().attributes('disabled')).toBe('true');
});
});
it('is disabled isLoading is true', () => {
mountComponent({ isLoading: true });
return wrapper.vm.$nextTick().then(() => {
expect(findCancelButton().attributes('disabled')).toBe('true');
});
});
it('is enabled when isLoading and disableCancelButton are false', () => {
mountComponent({ disableCancelButton: false, isLoading: false });
return wrapper.vm.$nextTick().then(() => {
expect(findCancelButton().attributes('disabled')).toBe(undefined);
});
});
});
describe('form cancel event', () => {
it('calls the appropriate function', () => {
mountComponent();
findForm().trigger('reset');
expect(wrapper.emitted('reset')).toBeTruthy();
});
});
it('save has type submit', () => {
mountComponent();
expect(findSaveButton().attributes('type')).toBe('submit');
});
describe('when isLoading is true', () => {
beforeEach(() => {
mountComponent({ isLoading: true });
});
it.each`
elementName
${'toggle'}
${'interval'}
${'schedule'}
${'latest'}
${'name-matching'}
`(`${FORM_ELEMENTS_ID_PREFIX}-$elementName is disabled`, ({ elementName }) => {
expect(findFormElements(elementName).attributes('disabled')).toBe('true');
});
it('submit button is disabled and shows a spinner', () => {
const button = findSaveButton();
expect(button.attributes('disabled')).toBeTruthy();
expect(findLoadingIcon(button)).toExist();
});
});
describe('form submit event ', () => {
it('calls the appropriate function', () => {
mountComponent();
findForm().trigger('submit');
expect(wrapper.emitted('submit')).toBeTruthy();
});
});
});
describe('form validation', () => {
describe(`when name regex is longer than ${NAME_REGEX_LENGTH}`, () => {
const invalidString = new Array(NAME_REGEX_LENGTH + 2).join(',');
beforeEach(() => {
mountComponent({ value: { name_regex: invalidString } });
});
it('save btn is disabled', () => {
expect(findSaveButton().attributes('disabled')).toBeTruthy();
});
it('nameRegexState is false', () => {
expect(wrapper.vm.nameRegexState).toBe(false);
});
});
it('if the user did not type validation is null', () => {
mountComponent({ value: { name_regex: '' } });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.nameRegexState).toBe(null);
expect(findSaveButton().attributes('disabled')).toBeFalsy();
});
});
it(`if the user typed and is less than ${NAME_REGEX_LENGTH} state is true`, () => {
mountComponent({ value: { name_regex: 'foo' } });
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.nameRegexState).toBe(true);
});
});
});
describe('help text', () => {
it('toggleDescriptionText show disabled when settings.enabled is false', () => {
mountComponent();
const toggleHelpText = findFormGroup('toggle').find('span');
expect(toggleHelpText.html()).toContain('disabled');
});
it('toggleDescriptionText show enabled when settings.enabled is true', () => {
mountComponent({ value: { enabled: true } });
const toggleHelpText = findFormGroup('toggle').find('span');
expect(toggleHelpText.html()).toContain('enabled');
});
});
});
import Vuex from 'vuex';
import { mount } from '@vue/test-utils';
import ReleaseDetailApp from '~/releases/detail/components/app';
import ReleaseDetailApp from '~/releases/detail/components/app.vue';
import { release } from '../../mock_data';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
 
Loading
Loading
Loading
Loading
@@ -4,7 +4,7 @@ import ConfidentialIssueSidebar from '~/sidebar/components/confidential/confiden
import EditForm from '~/sidebar/components/confidential/edit_form.vue';
import SidebarService from '~/sidebar/services/sidebar_service';
import createFlash from '~/flash';
import RecaptchaModal from '~/vue_shared/components/recaptcha_modal';
import RecaptchaModal from '~/vue_shared/components/recaptcha_modal.vue';
 
jest.mock('~/flash');
jest.mock('~/sidebar/services/sidebar_service');
Loading
Loading
Loading
Loading
@@ -2,7 +2,7 @@ import { shallowMount } from '@vue/test-utils';
 
import { eventHub } from '~/vue_shared/components/recaptcha_eventhub';
 
import RecaptchaModal from '~/vue_shared/components/recaptcha_modal';
import RecaptchaModal from '~/vue_shared/components/recaptcha_modal.vue';
 
describe('RecaptchaModal', () => {
const recaptchaFormId = 'recaptcha-form';
Loading
Loading
import { shallowMount } from '@vue/test-utils';
 
import SlotSwitch from '~/vue_shared/components/slot_switch';
import SlotSwitch from '~/vue_shared/components/slot_switch.vue';
 
describe('SlotSwitch', () => {
const slots = {
Loading
Loading
Loading
Loading
@@ -173,7 +173,7 @@ describe ButtonHelper do
expect(element.attr('data-clipboard-text')).to eq(nil)
expect(element.inner_text).to eq("")
 
expect(element.to_html).to include sprite_icon('duplicate')
expect(element.to_html).to include sprite_icon('copy-to-clipboard')
end
end
 
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe DeleteWithLimit do
describe '.delete_with_limit' do
it 'deletes a limited amount of rows' do
create_list(:web_hook_log, 4)
expect do
WebHookLog.delete_with_limit(2)
end.to change { WebHookLog.count }.by(-2)
end
end
end
Loading
Loading
@@ -21,6 +21,22 @@ describe EmailsOnPushService do
end
end
 
context 'when properties is missing branches_to_be_notified' do
subject { described_class.new(properties: {}) }
it 'sets the default value to all' do
expect(subject.branches_to_be_notified).to eq('all')
end
end
context 'when branches_to_be_notified is already set' do
subject { described_class.new(properties: { branches_to_be_notified: 'protected' }) }
it 'does not overwrite it with the default value' do
expect(subject.branches_to_be_notified).to eq('protected')
end
end
context 'project emails' do
let(:push_data) { { object_kind: 'push' } }
let(:project) { create(:project, :repository) }
Loading
Loading
Loading
Loading
@@ -127,21 +127,6 @@ describe API::Services do
expect(json_response['properties'].keys).to match_array(service_instance.api_field_names)
end
 
it "returns empty hash or nil values if properties and data fields are empty" do
# deprecated services are not valid for update
initialized_service.update_attribute(:properties, {})
if initialized_service.data_fields_present?
initialized_service.data_fields.destroy
initialized_service.reload
end
get api("/projects/#{project.id}/services/#{dashed_service}", user)
expect(response).to have_gitlab_http_status(200)
expect(json_response['properties'].values.compact).to be_empty
end
it "returns error when authenticated but not a project owner" do
project.add_developer(user2)
get api("/projects/#{project.id}/services/#{dashed_service}", user2)
Loading
Loading
Loading
Loading
@@ -705,18 +705,22 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
 
"@gitlab/eslint-config@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@gitlab/eslint-config/-/eslint-config-2.0.0.tgz#e30dbf2b170a7a4ca003a321de9f4170a2512510"
integrity sha512-3Zw3ww8Q4hhVYxO7vliByD0yTeAQn4iBxOyqlASAZepZgdu/OmM4NPbWyntpTfDyHGoRGxmzEaCqv7DS6ubACA==
dependencies:
babel-eslint "^10.0.1"
eslint-config-airbnb-base "^13.1.0"
eslint-config-prettier "^3.3.0"
"@gitlab/eslint-config@^2.1.1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@gitlab/eslint-config/-/eslint-config-2.1.1.tgz#64fcc8135f1a6055181fd64b991e33eb43913153"
integrity sha512-+rQA+gIcZbkaQ7GIjDjfMnYz41fFtsEaF0cRmk0KSqXWTKmOi4gcYZppIPdRvJWKhNPRS735Y5Of3gdIObINYQ==
dependencies:
"@gitlab/eslint-plugin-i18n" "^1.1.0"
"@gitlab/eslint-plugin-vue-i18n" "^1.2.0"
babel-eslint "^10.0.3"
eslint-config-airbnb-base "^13.2.0"
eslint-config-prettier "^3.6.0"
eslint-plugin-babel "^5.3.0"
eslint-plugin-filenames "^1.3.2"
eslint-plugin-import "^2.18.2"
eslint-plugin-promise "^4.1.1"
eslint-plugin-vue "^5.0.0"
eslint-plugin-import "^2.20.0"
eslint-plugin-no-jquery "^2.3.1"
eslint-plugin-promise "^4.2.1"
eslint-plugin-vue "^5.2.3"
 
"@gitlab/eslint-plugin-i18n@^1.1.0":
version "1.1.0"
Loading
Loading
@@ -1675,6 +1679,14 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
 
array.prototype.flat@^1.2.1:
version "1.2.3"
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b"
integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==
dependencies:
define-properties "^1.1.3"
es-abstract "^1.17.0-next.1"
arraybuffer.slice@~0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
Loading
Loading
@@ -1832,17 +1844,17 @@ babel-code-frame@^6.26.0:
esutils "^2.0.2"
js-tokens "^3.0.2"
 
babel-eslint@^10.0.1:
version "10.0.1"
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed"
integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==
babel-eslint@^10.0.3:
version "10.0.3"
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a"
integrity sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==
dependencies:
"@babel/code-frame" "^7.0.0"
"@babel/parser" "^7.0.0"
"@babel/traverse" "^7.0.0"
"@babel/types" "^7.0.0"
eslint-scope "3.7.1"
eslint-visitor-keys "^1.0.0"
resolve "^1.12.0"
 
babel-jest@^24.1.0, babel-jest@^24.8.0:
version "24.8.0"
Loading
Loading
@@ -2878,6 +2890,11 @@ configstore@^3.0.0:
write-file-atomic "^2.0.0"
xdg-basedir "^3.0.0"
 
confusing-browser-globals@^1.0.5:
version "1.0.9"
resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd"
integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==
connect-history-api-fallback@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
Loading
Loading
@@ -4156,21 +4173,22 @@ error-ex@^1.2.0, error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
 
es-abstract@^1.12.0, es-abstract@^1.5.1, es-abstract@^1.6.1, es-abstract@^1.7.0:
version "1.16.2"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.16.2.tgz#4e874331645e9925edef141e74fc4bd144669d34"
integrity sha512-jYo/J8XU2emLXl3OLwfwtuFfuF2w6DYPs+xy9ZfVyPkDcrauu6LYrw/q2TyCtrbc/KUdCiC5e9UajRhgNkVopA==
es-abstract@^1.12.0, es-abstract@^1.17.0-next.1, es-abstract@^1.5.1, es-abstract@^1.7.0:
version "1.17.4"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184"
integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==
dependencies:
es-to-primitive "^1.2.1"
function-bind "^1.1.1"
has "^1.0.3"
has-symbols "^1.0.1"
is-callable "^1.1.4"
is-regex "^1.0.4"
is-callable "^1.1.5"
is-regex "^1.0.5"
object-inspect "^1.7.0"
object-keys "^1.1.1"
string.prototype.trimleft "^2.1.0"
string.prototype.trimright "^2.1.0"
object.assign "^4.1.0"
string.prototype.trimleft "^2.1.1"
string.prototype.trimright "^2.1.1"
 
es-to-primitive@^1.2.1:
version "1.2.1"
Loading
Loading
@@ -4213,19 +4231,19 @@ escodegen@^1.9.1:
optionalDependencies:
source-map "~0.6.1"
 
eslint-config-airbnb-base@^13.1.0:
version "13.1.0"
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz#b5a1b480b80dfad16433d6c4ad84e6605052c05c"
integrity sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw==
eslint-config-airbnb-base@^13.2.0:
version "13.2.0"
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.2.0.tgz#f6ea81459ff4dec2dda200c35f1d8f7419d57943"
integrity sha512-1mg/7eoB4AUeB0X1c/ho4vb2gYkNH8Trr/EgCT/aGmKhhG+F6vF5s8+iRBlWAzFIAphxIdp3YfEKgEl0f9Xg+w==
dependencies:
eslint-restricted-globals "^0.1.1"
confusing-browser-globals "^1.0.5"
object.assign "^4.1.0"
object.entries "^1.0.4"
object.entries "^1.1.0"
 
eslint-config-prettier@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.3.0.tgz#41afc8d3b852e757f06274ed6c44ca16f939a57d"
integrity sha512-Bc3bh5bAcKNvs3HOpSi6EfGA2IIp7EzWcg2tS4vP7stnXu/J1opihHDM7jI9JCIckyIDTgZLSWn7J3HY0j2JfA==
eslint-config-prettier@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.6.0.tgz#8ca3ffac4bd6eeef623a0651f9d754900e3ec217"
integrity sha512-ixJ4U3uTLXwJts4rmSVW/lMXjlGwCijhBJHk8iVqKKSifeI0qgFEfWl8L63isfc8Od7EiBALF6BX3jKLluf/jQ==
dependencies:
get-stdin "^6.0.0"
 
Loading
Loading
@@ -4262,14 +4280,21 @@ eslint-import-resolver-webpack@^0.10.1:
resolve "^1.4.0"
semver "^5.3.0"
 
eslint-module-utils@^2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz#7b4675875bf96b0dbf1b21977456e5bb1f5e018c"
integrity sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==
eslint-module-utils@^2.4.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz#7878f7504824e1b857dd2505b59a8e5eda26a708"
integrity sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==
dependencies:
debug "^2.6.8"
debug "^2.6.9"
pkg-dir "^2.0.0"
 
eslint-plugin-babel@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-babel/-/eslint-plugin-babel-5.3.0.tgz#2e7f251ccc249326da760c1a4c948a91c32d0023"
integrity sha512-HPuNzSPE75O+SnxHIafbW5QB45r2w78fxqwK3HmjqIUoPfPzVrq6rD+CINU3yzoDSzEhUkX07VUphbF73Lth/w==
dependencies:
eslint-rule-composer "^0.3.0"
eslint-plugin-filenames@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-filenames/-/eslint-plugin-filenames-1.3.2.tgz#7094f00d7aefdd6999e3ac19f72cea058e590cf7"
Loading
Loading
@@ -4280,22 +4305,23 @@ eslint-plugin-filenames@^1.3.2:
lodash.snakecase "4.1.1"
lodash.upperfirst "4.3.1"
 
eslint-plugin-import@^2.18.2:
version "2.18.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6"
integrity sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==
eslint-plugin-import@^2.20.0:
version "2.20.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.0.tgz#d749a7263fb6c29980def8e960d380a6aa6aecaa"
integrity sha512-NK42oA0mUc8Ngn4kONOPsPB1XhbUvNHqF+g307dPV28aknPoiNnKLFd9em4nkswwepdF5ouieqv5Th/63U7YJQ==
dependencies:
array-includes "^3.0.3"
array.prototype.flat "^1.2.1"
contains-path "^0.1.0"
debug "^2.6.9"
doctrine "1.5.0"
eslint-import-resolver-node "^0.3.2"
eslint-module-utils "^2.4.0"
eslint-module-utils "^2.4.1"
has "^1.0.3"
minimatch "^3.0.4"
object.values "^1.1.0"
read-pkg-up "^2.0.0"
resolve "^1.11.0"
resolve "^1.12.0"
 
eslint-plugin-jasmine@^2.10.1:
version "2.10.1"
Loading
Loading
@@ -4307,35 +4333,27 @@ eslint-plugin-jest@^22.3.0:
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.3.0.tgz#a10f10dedfc92def774ec9bb5bfbd2fb8e1c96d2"
integrity sha512-P1mYVRNlOEoO5T9yTqOfucjOYf1ktmJ26NjwjH8sxpCFQa6IhBGr5TpKl3hcAAT29hOsRJVuMWmTsHoUVo9FoA==
 
eslint-plugin-no-jquery@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.3.0.tgz#fccdad84afa61baa4c0527dd6249cdcbfa0f74a8"
integrity sha512-XQQZM5yKO72Y8QAojNhH8oYLnLZU34FovNHVoJlPLBuBPJk0kkiPNOS/K6wRFbVgn47iZHsT6E+7mSLwbcQEsg==
eslint-plugin-no-jquery@^2.3.0, eslint-plugin-no-jquery@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.3.1.tgz#1c364cb863a38cc1570c8020155b6004cca62178"
integrity sha512-/fiQUBSOMUETnfBuiK5ewvtRbek1IRTy5ov/6RZ6nlybvZ337vyGaNPWM1KgaIoIeN7dairNrPfq0h7A0tpT3A==
 
eslint-plugin-promise@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.1.1.tgz#1e08cb68b5b2cd8839f8d5864c796f56d82746db"
integrity sha512-faAHw7uzlNPy7b45J1guyjazw28M+7gJokKUjC5JSFoYfUEyy6Gw/i7YQvmv2Yk00sUjWcmzXQLpU1Ki/C2IZQ==
eslint-plugin-promise@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a"
integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==
 
eslint-plugin-vue@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-5.0.0.tgz#4a2cc1c0e71ea45e1bd9c1a60f925bfe68bb5710"
integrity sha512-mSv2Ebz3RaPP+XJO/mu7F+SdR9lrMyGISSExnarLFqqf3pF5wTmwWNrhHW1o9zKzKI811UVTIIkWJJvgO6SsUQ==
eslint-plugin-vue@^5.2.3:
version "5.2.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-5.2.3.tgz#3ee7597d823b5478804b2feba9863b1b74273961"
integrity sha512-mGwMqbbJf0+VvpGR5Lllq0PMxvTdrZ/ZPjmhkacrCHbubJeJOt+T6E3HUzAifa2Mxi7RSdJfC9HFpOeSYVMMIw==
dependencies:
vue-eslint-parser "^4.0.2"
vue-eslint-parser "^5.0.0"
 
eslint-restricted-globals@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7"
integrity sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=
eslint-scope@3.7.1:
version "3.7.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=
dependencies:
esrecurse "^4.1.0"
estraverse "^4.1.1"
eslint-rule-composer@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9"
integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==
 
eslint-scope@^4.0.0, eslint-scope@^4.0.3:
version "4.0.3"
Loading
Loading
@@ -5033,7 +5051,7 @@ fstream@^1.0.0, fstream@^1.0.12:
mkdirp ">=0.5 0"
rimraf "2"
 
function-bind@^1.1.0, function-bind@^1.1.1:
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
Loading
Loading
@@ -5932,10 +5950,10 @@ is-buffer@^2.0.0, is-buffer@^2.0.2:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725"
integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==
 
is-callable@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
is-callable@^1.1.4, is-callable@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
 
is-ci@^1.0.10:
version "1.2.1"
Loading
Loading
@@ -6153,12 +6171,12 @@ is-redirect@^1.0.0:
resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24"
integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=
 
is-regex@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=
is-regex@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==
dependencies:
has "^1.0.1"
has "^1.0.3"
 
is-regexp@^1.0.0:
version "1.0.0"
Loading
Loading
@@ -8254,15 +8272,15 @@ object.assign@^4.1.0:
has-symbols "^1.0.0"
object-keys "^1.0.11"
 
object.entries@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f"
integrity sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8=
object.entries@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.1.tgz#ee1cf04153de02bb093fec33683900f57ce5399b"
integrity sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==
dependencies:
define-properties "^1.1.2"
es-abstract "^1.6.1"
function-bind "^1.1.0"
has "^1.0.1"
define-properties "^1.1.3"
es-abstract "^1.17.0-next.1"
function-bind "^1.1.1"
has "^1.0.3"
 
object.getownpropertydescriptors@^2.0.3:
version "2.0.3"
Loading
Loading
@@ -9811,10 +9829,10 @@ resolve@1.1.7:
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
 
resolve@1.x, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0:
version "1.12.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6"
integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==
resolve@1.x, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0:
version "1.15.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.0.tgz#1b7ca96073ebb52e741ffd799f6b39ea462c67f5"
integrity sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==
dependencies:
path-parse "^1.0.6"
 
Loading
Loading
@@ -10593,18 +10611,18 @@ string-width@^4.1.0:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^5.2.0"
 
string.prototype.trimleft@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634"
integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==
string.prototype.trimleft@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74"
integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==
dependencies:
define-properties "^1.1.3"
function-bind "^1.1.1"
 
string.prototype.trimright@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58"
integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==
string.prototype.trimright@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9"
integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==
dependencies:
define-properties "^1.1.3"
function-bind "^1.1.1"
Loading
Loading
@@ -11659,10 +11677,10 @@ vue-apollo@^3.0.0-beta.28:
chalk "^2.4.1"
throttle-debounce "^2.0.0"
 
vue-eslint-parser@^4.0.2:
version "4.0.3"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-4.0.3.tgz#80cf162e484387b2640371ad21ba1f86e0c10a61"
integrity sha512-AUeQsYdO6+7QXCems+WvGlrXd37PHv/zcRQSQdY1xdOMwdFAPEnMBsv7zPvk0TPGulXkK/5p/ITgrjiYB7k3ag==
vue-eslint-parser@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-5.0.0.tgz#00f4e4da94ec974b821a26ff0ed0f7a78402b8a1"
integrity sha512-JlHVZwBBTNVvzmifwjpZYn0oPWH2SgWv5dojlZBsrhablDu95VFD+hriB1rQGwbD+bms6g+rAFhQHk6+NyiS6g==
dependencies:
debug "^4.1.0"
eslint-scope "^4.0.0"
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment