Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
8b430e689c
commit
a4dacb5d7e
|
|
@ -1,20 +1,25 @@
|
|||
<script>
|
||||
import { uniqueId, isObject } from 'lodash';
|
||||
import { GlAlert, GlButton, GlForm, GlFormFields, GlFormTextarea } from '@gitlab/ui';
|
||||
import { isObject } from 'lodash';
|
||||
import { GlAccordion, GlAccordionItem, GlAlert, GlToggle } from '@gitlab/ui';
|
||||
import { updateApplicationSettings } from '~/rest_api';
|
||||
import { sprintf, s__, __ } from '~/locale';
|
||||
import { sprintf, s__ } from '~/locale';
|
||||
import { logError } from '~/lib/logger';
|
||||
import toast from '~/vue_shared/plugins/global_toast';
|
||||
import SettingsForm from './settings_form.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlAccordion,
|
||||
GlAccordionItem,
|
||||
GlAlert,
|
||||
GlButton,
|
||||
GlForm,
|
||||
GlFormFields,
|
||||
GlFormTextarea,
|
||||
GlToggle,
|
||||
SettingsForm,
|
||||
},
|
||||
props: {
|
||||
presets: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
initialSettings: {
|
||||
type: Object,
|
||||
required: false,
|
||||
|
|
@ -23,18 +28,12 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
formId: uniqueId('extension-marketplace-settings-form-'),
|
||||
formValues: {
|
||||
settings: JSON.stringify(this.initialSettings, null, 2),
|
||||
},
|
||||
isEnabled: Boolean(this.initialSettings.enabled),
|
||||
isLoading: false,
|
||||
errorMessage: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
payload() {
|
||||
return JSON.parse(this.formValues.settings);
|
||||
},
|
||||
errorContent() {
|
||||
if (!this.errorMessage) {
|
||||
return null;
|
||||
|
|
@ -61,22 +60,51 @@ export default {
|
|||
),
|
||||
};
|
||||
},
|
||||
submitButtonAttrs() {
|
||||
return {
|
||||
'aria-describedby': 'extension-marketplace-settings-error-alert',
|
||||
loading: this.isLoading,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async onSubmit() {
|
||||
async submitEnabled(enabled) {
|
||||
// NOTE: We can update just `vscode_extension_marketplace_enabled` to control enabled without touching the rest
|
||||
const isSuccess = await this.submit({ vscode_extension_marketplace_enabled: enabled });
|
||||
|
||||
if (isSuccess) {
|
||||
this.isEnabled = enabled;
|
||||
}
|
||||
},
|
||||
async submitForm(values) {
|
||||
// NOTE: We'll go ahead and update all of `vscode_extension_marketplace`.
|
||||
// Let's spread ontop of original `initialSettings` so that we don't unintentionally
|
||||
// overwrite anything.
|
||||
return this.submit({
|
||||
vscode_extension_marketplace: {
|
||||
...this.initialSettings,
|
||||
enabled: this.isEnabled,
|
||||
...values,
|
||||
},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @return {boolean} Whether the `submit` was successful or not. This encapsulated error handling already.
|
||||
*/
|
||||
async submit(params) {
|
||||
if (this.isLoading) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
this.isLoading = true;
|
||||
this.errorMessage = '';
|
||||
|
||||
try {
|
||||
await updateApplicationSettings({
|
||||
vscode_extension_marketplace: this.payload,
|
||||
});
|
||||
await updateApplicationSettings(params);
|
||||
|
||||
toast(s__('ExtensionMarketplace|Extension marketplace settings updated.'));
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line @gitlab/require-i18n-strings
|
||||
logError('Failed to update extension marketplace settings. See error info:', e);
|
||||
|
|
@ -84,66 +112,56 @@ export default {
|
|||
this.errorMessage =
|
||||
e?.response?.data?.message ||
|
||||
s__('ExtensionMarketplace|An unknown error occurred. Please try again.');
|
||||
|
||||
return false;
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
FIELDS: {
|
||||
settings: {
|
||||
label: __('Settings'),
|
||||
},
|
||||
},
|
||||
FIELDS: {},
|
||||
MSG_ENABLE_LABEL: s__('ExtensionMarketplace|Enable Extension Marketplace'),
|
||||
MSG_ENABLE_DESCRIPTION: s__(
|
||||
'ExtensionMarketplace|Enable the VS Code extension marketplace for all users.',
|
||||
),
|
||||
MSG_INNER_FORM: s__('ExtensionMarketplace|Extension registry settings'),
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<gl-form :id="formId" @submit.prevent>
|
||||
<gl-alert
|
||||
v-if="errorContent"
|
||||
id="extensions-marketplace-settings-error-alert"
|
||||
class="gl-mb-3"
|
||||
variant="danger"
|
||||
:dismissible="false"
|
||||
>
|
||||
{{ errorContent.title }}
|
||||
<ul v-if="errorContent.list" class="gl-mb-0 gl-mt-3">
|
||||
<li v-for="({ key, value }, idx) in errorContent.list" :key="idx">
|
||||
<code>{{ key }}</code>
|
||||
<span>:</span>
|
||||
<span>{{ value }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</gl-alert>
|
||||
<gl-form-fields
|
||||
v-model="formValues"
|
||||
:fields="$options.FIELDS"
|
||||
:form-id="formId"
|
||||
@submit="onSubmit"
|
||||
>
|
||||
<template #input(settings)="{ id, value, input, blur }">
|
||||
<gl-form-textarea
|
||||
:id="id"
|
||||
class="!gl-font-monospace"
|
||||
:value="value"
|
||||
:state="!Boolean(errorContent)"
|
||||
@input="input"
|
||||
@blur="blur"
|
||||
/>
|
||||
</template>
|
||||
</gl-form-fields>
|
||||
<div class="gl-flex">
|
||||
<gl-button
|
||||
class="js-no-auto-disable"
|
||||
aria-describedby="extensions-marketplace-settings-error-alert"
|
||||
type="submit"
|
||||
variant="confirm"
|
||||
category="primary"
|
||||
:loading="isLoading"
|
||||
>
|
||||
{{ __('Save changes') }}
|
||||
</gl-button>
|
||||
</div>
|
||||
</gl-form>
|
||||
<gl-alert
|
||||
v-if="errorContent"
|
||||
id="extension-marketplace-settings-error-alert"
|
||||
class="gl-mb-3"
|
||||
variant="danger"
|
||||
:dismissible="false"
|
||||
>
|
||||
{{ errorContent.title }}
|
||||
<ul v-if="errorContent.list" class="gl-mb-0 gl-mt-3">
|
||||
<li v-for="({ key, value }, idx) in errorContent.list" :key="idx">
|
||||
<code>{{ key }}</code>
|
||||
<span>:</span>
|
||||
<span>{{ value }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</gl-alert>
|
||||
<gl-toggle
|
||||
:value="isEnabled"
|
||||
:is-loading="isLoading"
|
||||
:label="$options.MSG_ENABLE_LABEL"
|
||||
:help="$options.MSG_ENABLE_DESCRIPTION"
|
||||
label-position="top"
|
||||
@change="submitEnabled"
|
||||
/>
|
||||
<gl-accordion :header-level="3" class="gl-pt-3">
|
||||
<gl-accordion-item :title="$options.MSG_INNER_FORM" class="gl-font-normal">
|
||||
<settings-form
|
||||
:presets="presets"
|
||||
:initial-settings="initialSettings"
|
||||
:submit-button-attrs="submitButtonAttrs"
|
||||
@submit="submitForm"
|
||||
/>
|
||||
</gl-accordion-item>
|
||||
</gl-accordion>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,215 @@
|
|||
<script>
|
||||
import { uniqueId, pick } from 'lodash';
|
||||
import { GlButton, GlForm, GlFormFields, GlIcon, GlLink, GlSprintf, GlToggle } from '@gitlab/ui';
|
||||
import { s__ } from '~/locale';
|
||||
import { isValidURL, isAbsolute } from '~/lib/utils/url_utility';
|
||||
import { PRESET_OPEN_VSX, PRESET_CUSTOM } from '../constants';
|
||||
|
||||
const validateRequired = (invalidMsg) => (val) => {
|
||||
if (val) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return invalidMsg;
|
||||
};
|
||||
|
||||
const validateURL = (invalidMsg) => (val) => {
|
||||
if (isAbsolute(val) && isValidURL(val)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return invalidMsg;
|
||||
};
|
||||
|
||||
const MSG_VALID_URL = s__('ExtensionMarketplace|A valid URL is required.');
|
||||
|
||||
const createUrlField = (label) => ({
|
||||
label,
|
||||
validators: [validateURL(MSG_VALID_URL), validateRequired(MSG_VALID_URL)],
|
||||
inputAttrs: {
|
||||
width: 'lg',
|
||||
placeholder: 'https://...',
|
||||
},
|
||||
});
|
||||
|
||||
const createReadonlyUrlField = (label) => ({
|
||||
label,
|
||||
inputAttrs: {
|
||||
width: 'lg',
|
||||
readonly: true,
|
||||
'aria-description': s__(
|
||||
'ExtensionMarketplace|Disable Open VSX extension registry to set a custom value for this field.',
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
const FIELDS = {
|
||||
useOpenVsx: {
|
||||
label: s__('ExtensionMarketplace|Use Open VSX extension registry'),
|
||||
},
|
||||
serviceUrl: createUrlField(s__('ExtensionMarketplace|Service URL')),
|
||||
itemUrl: createUrlField(s__('ExtensionMarketplace|Item URL')),
|
||||
resourceUrlTemplate: createUrlField(s__('ExtensionMarketplace|Resource URL Template')),
|
||||
presetServiceUrl: createReadonlyUrlField(s__('ExtensionMarketplace|Service URL')),
|
||||
presetItemUrl: createReadonlyUrlField(s__('ExtensionMarketplace|Item URL')),
|
||||
presetResourceUrlTemplate: createReadonlyUrlField(
|
||||
s__('ExtensionMarketplace|Resource URL Template'),
|
||||
),
|
||||
};
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlButton,
|
||||
GlForm,
|
||||
GlFormFields,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
GlSprintf,
|
||||
GlToggle,
|
||||
},
|
||||
props: {
|
||||
presets: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
initialSettings: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({}),
|
||||
},
|
||||
submitButtonAttrs: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const { preset, custom_values: initialCustomValues } = this.initialSettings;
|
||||
|
||||
return {
|
||||
formId: uniqueId('extension-marketplace-settings-form-'),
|
||||
formValues: {
|
||||
useOpenVsx: !preset || preset === PRESET_OPEN_VSX,
|
||||
// URL fields for "custom" preset.
|
||||
serviceUrl: '',
|
||||
itemUrl: '',
|
||||
resourceUrlTemplate: '',
|
||||
// URL fields for other presets. The inputs are readonly.
|
||||
presetServiceUrl: '',
|
||||
presetItemUrl: '',
|
||||
presetResourceUrlTemplate: '',
|
||||
},
|
||||
customValues: {
|
||||
serviceUrl: initialCustomValues?.service_url || '',
|
||||
itemUrl: initialCustomValues?.item_url || '',
|
||||
resourceUrlTemplate: initialCustomValues?.resource_url_template || '',
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
preset() {
|
||||
return this.formValues.useOpenVsx ? PRESET_OPEN_VSX : PRESET_CUSTOM;
|
||||
},
|
||||
isCustomPreset() {
|
||||
return this.preset === PRESET_CUSTOM;
|
||||
},
|
||||
payload() {
|
||||
if (this.isCustomPreset) {
|
||||
return {
|
||||
preset: this.preset,
|
||||
custom_values: {
|
||||
service_url: this.formValues.serviceUrl,
|
||||
item_url: this.formValues.itemUrl,
|
||||
resource_url_template: this.formValues.resourceUrlTemplate,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
preset: this.preset,
|
||||
};
|
||||
},
|
||||
formFields() {
|
||||
if (this.isCustomPreset) {
|
||||
return pick(FIELDS, ['useOpenVsx', 'serviceUrl', 'itemUrl', 'resourceUrlTemplate']);
|
||||
}
|
||||
|
||||
return pick(FIELDS, [
|
||||
'useOpenVsx',
|
||||
'presetServiceUrl',
|
||||
'presetItemUrl',
|
||||
'presetResourceUrlTemplate',
|
||||
]);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
preset: {
|
||||
immediate: true,
|
||||
handler(val, prevVal) {
|
||||
if (prevVal === PRESET_CUSTOM) {
|
||||
this.customValues.serviceUrl = this.formValues.serviceUrl;
|
||||
this.customValues.itemUrl = this.formValues.itemUrl;
|
||||
this.customValues.resourceUrlTemplate = this.formValues.resourceUrlTemplate;
|
||||
}
|
||||
|
||||
if (val === PRESET_CUSTOM) {
|
||||
this.formValues.serviceUrl = this.customValues.serviceUrl;
|
||||
this.formValues.itemUrl = this.customValues.itemUrl;
|
||||
this.formValues.resourceUrlTemplate = this.customValues.resourceUrlTemplate;
|
||||
} else {
|
||||
const values = this.presets.find(({ key }) => key === val)?.values;
|
||||
|
||||
this.formValues.presetServiceUrl = values?.serviceUrl;
|
||||
this.formValues.presetItemUrl = values?.itemUrl;
|
||||
this.formValues.presetResourceUrlTemplate = values?.resourceUrlTemplate;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
this.$emit('submit', this.payload);
|
||||
},
|
||||
},
|
||||
MSG_OPEN_VSX_DESCRIPTION: s__(
|
||||
'ExtensionMarketplace|Learn more about the %{linkStart}Open VSX Registry%{linkEnd}',
|
||||
),
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<gl-form :id="formId" @submit.prevent>
|
||||
<gl-form-fields v-model="formValues" :fields="formFields" :form-id="formId" @submit="onSubmit">
|
||||
<template #input(useOpenVsx)="{ id, value, input, blur }">
|
||||
<gl-toggle
|
||||
:id="id"
|
||||
:label="formFields.useOpenVsx.label"
|
||||
label-position="hidden"
|
||||
:value="value"
|
||||
@change="input"
|
||||
@blur="blur"
|
||||
/>
|
||||
</template>
|
||||
<template #group(useOpenVsx)-description>
|
||||
<gl-sprintf :message="$options.MSG_OPEN_VSX_DESCRIPTION">
|
||||
<template #link="{ content }">
|
||||
<gl-link href="https://open-vsx.org/about" target="_blank"
|
||||
>{{ content }} <gl-icon name="external-link"
|
||||
/></gl-link>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</template>
|
||||
</gl-form-fields>
|
||||
<div class="gl-flex">
|
||||
<gl-button
|
||||
class="js-no-auto-disable"
|
||||
type="submit"
|
||||
variant="confirm"
|
||||
category="primary"
|
||||
v-bind="submitButtonAttrs"
|
||||
>
|
||||
{{ __('Save changes') }}
|
||||
</gl-button>
|
||||
</div>
|
||||
</gl-form>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
export const PRESET_OPEN_VSX = 'open_vsx';
|
||||
export const PRESET_CUSTOM = 'custom';
|
||||
|
|
@ -587,7 +587,8 @@ module ApplicationSettingsHelper
|
|||
:global_search_users_enabled,
|
||||
:global_search_issues_enabled,
|
||||
:global_search_merge_requests_enabled,
|
||||
:vscode_extension_marketplace
|
||||
:vscode_extension_marketplace,
|
||||
:vscode_extension_marketplace_enabled
|
||||
].tap do |settings|
|
||||
unless Gitlab.com?
|
||||
settings << :resource_usage_limits
|
||||
|
|
@ -689,10 +690,15 @@ module ApplicationSettingsHelper
|
|||
# NOTE: This is intentionally not scoped to a specific actor since it affects instance-level settings.
|
||||
return unless Feature.enabled?(:vscode_extension_marketplace_settings, nil)
|
||||
|
||||
presets = ::WebIde::ExtensionMarketplacePreset.all.map do |preset|
|
||||
preset.to_h.deep_transform_keys { |key| key.to_s.camelize(:lower) }
|
||||
end
|
||||
|
||||
{
|
||||
title: _('VS Code Extension Marketplace'),
|
||||
description: vscode_extension_marketplace_settings_description,
|
||||
view_model: {
|
||||
presets: presets,
|
||||
initialSettings: @application_setting.vscode_extension_marketplace || {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,6 @@ class ApplicationSetting < ApplicationRecord
|
|||
attribute :repository_storages_weighted, default: -> { {} }
|
||||
attribute :kroki_formats, default: -> { {} }
|
||||
attribute :default_branch_protection_defaults, default: -> { {} }
|
||||
attribute :vscode_extension_marketplace, default: -> { {} }
|
||||
|
||||
chronic_duration_attr_writer :archive_builds_in_human_readable, :archive_builds_in_seconds
|
||||
|
||||
|
|
@ -950,6 +949,9 @@ class ApplicationSetting < ApplicationRecord
|
|||
validates :vscode_extension_marketplace,
|
||||
json_schema: { filename: "application_setting_vscode_extension_marketplace", detail_errors: true }
|
||||
|
||||
jsonb_accessor :vscode_extension_marketplace,
|
||||
vscode_extension_marketplace_enabled: [:boolean, { default: false, store_key: :enabled }]
|
||||
|
||||
before_validation :ensure_uuid!
|
||||
before_validation :coerce_repository_storages_weighted, if: :repository_storages_weighted_changed?
|
||||
before_validation :normalize_default_branch_name
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ module ApplicationSettingImplementation
|
|||
seat_control: 0,
|
||||
show_migrate_from_jenkins_banner: true,
|
||||
ropc_without_client_credentials: true,
|
||||
vscode_extension_marketplace: {}
|
||||
vscode_extension_marketplace_enabled: false
|
||||
}.tap do |hsh|
|
||||
hsh.merge!(non_production_defaults) unless Rails.env.production?
|
||||
end
|
||||
|
|
|
|||
|
|
@ -24507,18 +24507,48 @@ msgstr ""
|
|||
msgid "Exported requirements"
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|A valid URL is required."
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|An unknown error occurred. Please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Disable Open VSX extension registry to set a custom value for this field."
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Enable Extension Marketplace"
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Enable the VS Code extension marketplace for all users."
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Extension marketplace settings updated."
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Extension registry settings"
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Failed to update extension marketplace settings."
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Failed to update extension marketplace settings. %{message}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Item URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Learn more about the %{linkStart}Open VSX Registry%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Resource URL Template"
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Service URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "ExtensionMarketplace|Use Open VSX extension registry"
|
||||
msgstr ""
|
||||
|
||||
msgid "External URL"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,29 @@
|
|||
import { nextTick } from 'vue';
|
||||
import { GlAlert, GlButton, GlForm, GlFormFields, GlFormTextarea } from '@gitlab/ui';
|
||||
import { GlAlert, GlAccordion, GlAccordionItem, GlToggle } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { logError } from '~/lib/logger';
|
||||
import SettingsApp from '~/vscode_extension_marketplace/components/settings_app.vue';
|
||||
import SettingsForm from '~/vscode_extension_marketplace/components/settings_form.vue';
|
||||
import toast from '~/vue_shared/plugins/global_toast';
|
||||
import { PRESETS } from '../mock_data';
|
||||
|
||||
jest.mock('~/lib/logger');
|
||||
jest.mock('~/vue_shared/plugins/global_toast');
|
||||
jest.mock('lodash/uniqueId', () => (x) => `${x}testUnique`);
|
||||
|
||||
const TEST_NEW_SETTINGS = { enabled: false, preset: 'open_vsx' };
|
||||
const EXPECTED_FORM_ID = 'extension-marketplace-settings-form-testUnique';
|
||||
const TEST_NEW_SETTINGS = { preset: 'open_vsx' };
|
||||
const TEST_INIT_SETTINGS = {
|
||||
enabled: true,
|
||||
preset: 'custom',
|
||||
custom_values: {
|
||||
item_url: 'abc',
|
||||
service_url: 'def',
|
||||
resource_url_template: 'ghi',
|
||||
},
|
||||
};
|
||||
|
||||
describe('~/vscode_extension_marketplace/components/settings_app.vue', () => {
|
||||
let wrapper;
|
||||
|
|
@ -22,18 +33,16 @@ describe('~/vscode_extension_marketplace/components/settings_app.vue', () => {
|
|||
const createComponent = (props = {}) => {
|
||||
wrapper = shallowMount(SettingsApp, {
|
||||
propsData: {
|
||||
presets: PRESETS,
|
||||
...props,
|
||||
},
|
||||
stubs: {
|
||||
GlFormFields,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const findForm = () => wrapper.findComponent(GlForm);
|
||||
const findFormFields = () => wrapper.findComponent(GlFormFields);
|
||||
const findTextarea = () => wrapper.findComponent(GlFormTextarea);
|
||||
const findSaveButton = () => wrapper.findComponent(GlButton);
|
||||
const findAccordion = () => wrapper.findComponent(GlAccordion);
|
||||
const findAccordionItem = () => findAccordion().findComponent(GlAccordionItem);
|
||||
const findSettingsForm = () => findAccordionItem().findComponent(SettingsForm);
|
||||
const findToggle = () => wrapper.findComponent(GlToggle);
|
||||
const findErrorAlert = () => wrapper.findComponent(GlAlert);
|
||||
const findErrorAlertItems = () =>
|
||||
findErrorAlert()
|
||||
|
|
@ -58,63 +67,67 @@ describe('~/vscode_extension_marketplace/components/settings_app.vue', () => {
|
|||
createComponent();
|
||||
});
|
||||
|
||||
it('renders form', () => {
|
||||
expect(findForm().attributes('id')).toBe(EXPECTED_FORM_ID);
|
||||
it('renders toggle', () => {
|
||||
expect(findToggle().props()).toMatchObject({
|
||||
value: false,
|
||||
isLoading: false,
|
||||
label: 'Enable Extension Marketplace',
|
||||
help: 'Enable the VS Code extension marketplace for all users.',
|
||||
labelPosition: 'top',
|
||||
});
|
||||
});
|
||||
|
||||
it('renders form fields', () => {
|
||||
expect(findFormFields().props()).toMatchObject({
|
||||
formId: EXPECTED_FORM_ID,
|
||||
values: {
|
||||
settings: {},
|
||||
it('renders accordion and accordion item', () => {
|
||||
expect(findAccordion().props()).toMatchObject({
|
||||
headerLevel: 3,
|
||||
});
|
||||
|
||||
expect(findAccordionItem().props()).toMatchObject({
|
||||
title: 'Extension registry settings',
|
||||
});
|
||||
});
|
||||
|
||||
it('renders inner form', () => {
|
||||
expect(findSettingsForm().props()).toEqual({
|
||||
initialSettings: {},
|
||||
presets: PRESETS,
|
||||
submitButtonAttrs: {
|
||||
'aria-describedby': 'extension-marketplace-settings-error-alert',
|
||||
loading: false,
|
||||
},
|
||||
fields: SettingsApp.FIELDS,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders settings textarea', () => {
|
||||
expect(findTextarea().attributes()).toMatchObject({
|
||||
id: 'gl-form-field-testUnique',
|
||||
value: '{}',
|
||||
});
|
||||
});
|
||||
|
||||
it('renders save button', () => {
|
||||
expect(findSaveButton().attributes()).toMatchObject({
|
||||
type: 'submit',
|
||||
variant: 'confirm',
|
||||
category: 'primary',
|
||||
'aria-describedby': 'extensions-marketplace-settings-error-alert',
|
||||
});
|
||||
expect(findSaveButton().props('loading')).toBe(false);
|
||||
expect(findSaveButton().text()).toBe('Save changes');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when submitted', () => {
|
||||
beforeEach(async () => {
|
||||
describe('when enablement toggle is changed', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
|
||||
findTextarea().vm.$emit('input', JSON.stringify(TEST_NEW_SETTINGS));
|
||||
await nextTick();
|
||||
|
||||
findFormFields().vm.$emit('submit');
|
||||
findToggle().vm.$emit('change', true);
|
||||
});
|
||||
|
||||
it('triggers loading', () => {
|
||||
expect(findSaveButton().props('loading')).toBe(true);
|
||||
expect(findSettingsForm().props('submitButtonAttrs')).toEqual({
|
||||
'aria-describedby': 'extension-marketplace-settings-error-alert',
|
||||
loading: true,
|
||||
});
|
||||
|
||||
expect(findToggle().props()).toMatchObject({
|
||||
value: false,
|
||||
isLoading: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('makes submit request', () => {
|
||||
expect(submitSpy).toHaveBeenCalledTimes(1);
|
||||
expect(submitSpy).toHaveBeenCalledWith({
|
||||
vscode_extension_marketplace: TEST_NEW_SETTINGS,
|
||||
vscode_extension_marketplace_enabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('while loading, prevents extra submit', () => {
|
||||
findFormFields().vm.$emit('submit');
|
||||
findFormFields().vm.$emit('submit');
|
||||
findToggle().vm.$emit('change', true);
|
||||
findToggle().vm.$emit('change', true);
|
||||
|
||||
expect(submitSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
|
@ -126,7 +139,7 @@ describe('~/vscode_extension_marketplace/components/settings_app.vue', () => {
|
|||
|
||||
expect(toast).toHaveBeenCalledTimes(1);
|
||||
expect(toast).toHaveBeenCalledWith('Extension marketplace settings updated.');
|
||||
expect(findSaveButton().props('loading')).toBe(false);
|
||||
expect(findToggle().props('isLoading')).toBe(false);
|
||||
});
|
||||
|
||||
it('does not show error alert', () => {
|
||||
|
|
@ -134,13 +147,49 @@ describe('~/vscode_extension_marketplace/components/settings_app.vue', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('with initial settings', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
initialSettings: TEST_INIT_SETTINGS,
|
||||
});
|
||||
});
|
||||
|
||||
it('initializes settings in toggle', () => {
|
||||
expect(findToggle().props('value')).toBe(true);
|
||||
});
|
||||
|
||||
it('initializes settings in form', () => {
|
||||
expect(findSettingsForm().props('initialSettings')).toBe(TEST_INIT_SETTINGS);
|
||||
});
|
||||
|
||||
it('when submitted, submits settings', async () => {
|
||||
expect(submitSpy).not.toHaveBeenCalled();
|
||||
|
||||
findSettingsForm().vm.$emit('submit', TEST_NEW_SETTINGS);
|
||||
await waitForPromises();
|
||||
|
||||
expect(submitSpy).toHaveBeenCalledTimes(1);
|
||||
expect(submitSpy).toHaveBeenCalledWith({
|
||||
vscode_extension_marketplace: {
|
||||
enabled: true,
|
||||
preset: 'open_vsx',
|
||||
custom_values: {
|
||||
item_url: 'abc',
|
||||
service_url: 'def',
|
||||
resource_url_template: 'ghi',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when submitted and errored', () => {
|
||||
beforeEach(() => {
|
||||
submitSpy.mockReturnValue([400]);
|
||||
|
||||
createComponent();
|
||||
|
||||
findFormFields().vm.$emit('submit');
|
||||
findSettingsForm().vm.$emit('submit', {});
|
||||
});
|
||||
|
||||
it('shows error message', async () => {
|
||||
|
|
@ -149,7 +198,7 @@ describe('~/vscode_extension_marketplace/components/settings_app.vue', () => {
|
|||
await axios.waitForAll();
|
||||
|
||||
expect(findErrorAlert().exists()).toBe(true);
|
||||
expect(findErrorAlert().attributes('id')).toBe('extensions-marketplace-settings-error-alert');
|
||||
expect(findErrorAlert().attributes('id')).toBe('extension-marketplace-settings-error-alert');
|
||||
expect(findErrorAlert().props('dismissible')).toBe(false);
|
||||
expect(findErrorAlert().text()).toBe(
|
||||
'Failed to update extension marketplace settings. An unknown error occurred. Please try again.',
|
||||
|
|
@ -168,20 +217,12 @@ describe('~/vscode_extension_marketplace/components/settings_app.vue', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('updates state on textarea', async () => {
|
||||
expect(findTextarea().attributes('state')).toBe('true');
|
||||
|
||||
await axios.waitForAll();
|
||||
|
||||
expect(findTextarea().attributes('state')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('hides error message with another submit', async () => {
|
||||
await axios.waitForAll();
|
||||
|
||||
expect(findErrorAlert().exists()).toBe(true);
|
||||
|
||||
findFormFields().vm.$emit('submit');
|
||||
findSettingsForm().vm.$emit('submit', TEST_NEW_SETTINGS);
|
||||
await nextTick();
|
||||
|
||||
expect(findErrorAlert().exists()).toBe(false);
|
||||
|
|
@ -197,7 +238,7 @@ describe('~/vscode_extension_marketplace/components/settings_app.vue', () => {
|
|||
|
||||
createComponent();
|
||||
|
||||
findFormFields().vm.$emit('submit');
|
||||
findSettingsForm().vm.$emit('submit', TEST_NEW_SETTINGS);
|
||||
});
|
||||
|
||||
it('shows error message', async () => {
|
||||
|
|
@ -213,16 +254,4 @@ describe('~/vscode_extension_marketplace/components/settings_app.vue', () => {
|
|||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with initialSettings', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
initialSettings: TEST_NEW_SETTINGS,
|
||||
});
|
||||
});
|
||||
|
||||
it('initializes the form with given settings', () => {
|
||||
expect(findTextarea().props('value')).toBe(JSON.stringify(TEST_NEW_SETTINGS, null, 2));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,240 @@
|
|||
import { GlForm, GlFormFields, GlToggle, GlButton } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import SettingsForm from '~/vscode_extension_marketplace/components/settings_form.vue';
|
||||
import { PRESETS } from '../mock_data';
|
||||
|
||||
jest.mock('lodash/uniqueId', () => (x) => `${x}uniqueId`);
|
||||
|
||||
const TEST_FORM_ID = 'extension-marketplace-settings-form-uniqueId';
|
||||
const TEST_SUBMIT_BUTTON_ATTRS = {
|
||||
'aria-describedby': 'extension-marketplace-settings-error-alert',
|
||||
};
|
||||
const TEST_CUSTOM_VALUES = {
|
||||
item_url: 'abc',
|
||||
service_url: 'def',
|
||||
resource_url_template: 'ghi',
|
||||
};
|
||||
|
||||
describe('~/vscode_extension_marketplace/components/settings_form.vue', () => {
|
||||
let wrapper;
|
||||
|
||||
const findForm = () => wrapper.findComponent(GlForm);
|
||||
const findFormFields = () => findForm().findComponent(GlFormFields);
|
||||
const findOpenVsxToggle = () => findFormFields().findComponent(GlToggle);
|
||||
const findButton = () => findForm().findComponent(GlButton);
|
||||
|
||||
const createComponent = (props = {}) => {
|
||||
wrapper = shallowMount(SettingsForm, {
|
||||
propsData: {
|
||||
presets: PRESETS,
|
||||
submitButtonAttrs: TEST_SUBMIT_BUTTON_ATTRS,
|
||||
...props,
|
||||
},
|
||||
stubs: {
|
||||
GlFormFields,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
describe('default', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('renders form', () => {
|
||||
expect(findForm().attributes('id')).toBe(TEST_FORM_ID);
|
||||
});
|
||||
|
||||
it('renders form fields', () => {
|
||||
const expectedInputAttrs = {
|
||||
readonly: true,
|
||||
'aria-description':
|
||||
'Disable Open VSX extension registry to set a custom value for this field.',
|
||||
width: 'lg',
|
||||
};
|
||||
|
||||
expect(findFormFields().props()).toEqual({
|
||||
formId: TEST_FORM_ID,
|
||||
serverValidations: {},
|
||||
fields: {
|
||||
useOpenVsx: {
|
||||
label: 'Use Open VSX extension registry',
|
||||
},
|
||||
presetItemUrl: {
|
||||
label: 'Item URL',
|
||||
inputAttrs: expectedInputAttrs,
|
||||
},
|
||||
presetServiceUrl: {
|
||||
label: 'Service URL',
|
||||
inputAttrs: expectedInputAttrs,
|
||||
},
|
||||
presetResourceUrlTemplate: {
|
||||
label: 'Resource URL Template',
|
||||
inputAttrs: expectedInputAttrs,
|
||||
},
|
||||
},
|
||||
values: {
|
||||
useOpenVsx: true,
|
||||
presetItemUrl: 'https://open-vsx.org/vscode/item',
|
||||
presetResourceUrlTemplate:
|
||||
'https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}',
|
||||
presetServiceUrl: 'https://open-vsx.org/vscode/gallery',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('renders open vsx toggle', () => {
|
||||
expect(findOpenVsxToggle().props('value')).toEqual(true);
|
||||
expect(findOpenVsxToggle().attributes()).toMatchObject({
|
||||
id: 'gl-form-field-uniqueId',
|
||||
label: 'Use Open VSX extension registry',
|
||||
labelposition: 'hidden',
|
||||
});
|
||||
});
|
||||
|
||||
it('renders save button', () => {
|
||||
expect(findButton().attributes()).toMatchObject({
|
||||
type: 'submit',
|
||||
variant: 'confirm',
|
||||
category: 'primary',
|
||||
...TEST_SUBMIT_BUTTON_ATTRS,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with preset=open_vsx and custom_values', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
initialSettings: {
|
||||
custom_values: TEST_CUSTOM_VALUES,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('changes values when openvsx is toggled', async () => {
|
||||
// NOTE: gl-form-fields emits `input` on mount to only include fiels created with
|
||||
expect(findFormFields().props('values')).toEqual({
|
||||
useOpenVsx: true,
|
||||
presetItemUrl: 'https://open-vsx.org/vscode/item',
|
||||
presetServiceUrl: 'https://open-vsx.org/vscode/gallery',
|
||||
presetResourceUrlTemplate:
|
||||
'https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}',
|
||||
});
|
||||
|
||||
await findOpenVsxToggle().vm.$emit('change', false);
|
||||
|
||||
expect(findFormFields().props('values')).toEqual({
|
||||
useOpenVsx: false,
|
||||
presetItemUrl: 'https://open-vsx.org/vscode/item',
|
||||
presetServiceUrl: 'https://open-vsx.org/vscode/gallery',
|
||||
presetResourceUrlTemplate:
|
||||
'https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}',
|
||||
itemUrl: 'abc',
|
||||
serviceUrl: 'def',
|
||||
resourceUrlTemplate: 'ghi',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with preset=custom and custom_values', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
initialSettings: {
|
||||
custom_values: TEST_CUSTOM_VALUES,
|
||||
preset: 'custom',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('stores custom values when preset is changed back and forth', async () => {
|
||||
await findFormFields().vm.$emit('input', {
|
||||
useOpenVsx: false,
|
||||
itemUrl: 'xyz',
|
||||
serviceUrl: 'xyz',
|
||||
resourceUrlTemplate: 'xyz',
|
||||
});
|
||||
await findOpenVsxToggle().vm.$emit('change', true);
|
||||
|
||||
expect(findFormFields().props('values')).toEqual({
|
||||
useOpenVsx: true,
|
||||
itemUrl: 'xyz',
|
||||
serviceUrl: 'xyz',
|
||||
resourceUrlTemplate: 'xyz',
|
||||
presetItemUrl: 'https://open-vsx.org/vscode/item',
|
||||
presetServiceUrl: 'https://open-vsx.org/vscode/gallery',
|
||||
presetResourceUrlTemplate:
|
||||
'https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}',
|
||||
});
|
||||
|
||||
await findOpenVsxToggle().vm.$emit('change', false);
|
||||
|
||||
expect(findFormFields().props('values')).toEqual({
|
||||
useOpenVsx: false,
|
||||
itemUrl: 'xyz',
|
||||
serviceUrl: 'xyz',
|
||||
resourceUrlTemplate: 'xyz',
|
||||
presetItemUrl: 'https://open-vsx.org/vscode/item',
|
||||
presetServiceUrl: 'https://open-vsx.org/vscode/gallery',
|
||||
presetResourceUrlTemplate:
|
||||
'https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}',
|
||||
});
|
||||
});
|
||||
|
||||
it('renders customizable fields', () => {
|
||||
expect(findFormFields().props('fields')).toEqual(
|
||||
expect.objectContaining({
|
||||
itemUrl: {
|
||||
label: 'Item URL',
|
||||
inputAttrs: {
|
||||
placeholder: 'https://...',
|
||||
width: 'lg',
|
||||
},
|
||||
validators: expect.any(Array),
|
||||
},
|
||||
serviceUrl: {
|
||||
label: 'Service URL',
|
||||
inputAttrs: {
|
||||
placeholder: 'https://...',
|
||||
width: 'lg',
|
||||
},
|
||||
validators: expect.any(Array),
|
||||
},
|
||||
resourceUrlTemplate: {
|
||||
label: 'Resource URL Template',
|
||||
inputAttrs: {
|
||||
placeholder: 'https://...',
|
||||
width: 'lg',
|
||||
},
|
||||
validators: expect.any(Array),
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it.each`
|
||||
fieldName | value | expectation
|
||||
${'itemUrl'} | ${''} | ${'A valid URL is required.'}
|
||||
${'itemUrl'} | ${'abc def'} | ${'A valid URL is required.'}
|
||||
${'itemUrl'} | ${'https://example.com'} | ${''}
|
||||
${'serviceUrl'} | ${''} | ${'A valid URL is required.'}
|
||||
${'serviceUrl'} | ${'abc def'} | ${'A valid URL is required.'}
|
||||
${'serviceUrl'} | ${'https://example.com'} | ${''}
|
||||
${'resourceUrlTemplate'} | ${''} | ${'A valid URL is required.'}
|
||||
${'resourceUrlTemplate'} | ${'abc def'} | ${'A valid URL is required.'}
|
||||
${'resourceUrlTemplate'} | ${'https://example.com'} | ${''}
|
||||
`(
|
||||
'validates $fieldName where $value is "$expectation"',
|
||||
({ fieldName, value, expectation }) => {
|
||||
const field = findFormFields().props('fields')[fieldName];
|
||||
|
||||
const result = field.validators.reduce((msg, validator) => msg || validator(value), '');
|
||||
|
||||
expect(result).toBe(expectation);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
export const PRESETS = [
|
||||
{
|
||||
key: 'open_vsx',
|
||||
name: 'Open VSX',
|
||||
values: {
|
||||
serviceUrl: 'https://open-vsx.org/vscode/gallery',
|
||||
itemUrl: 'https://open-vsx.org/vscode/item',
|
||||
resourceUrlTemplate: 'https://open-vsx.org/vscode/unpkg/{publisher}/{name}/{version}/{path}',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
@ -462,11 +462,14 @@ RSpec.describe ApplicationSettingsHelper, feature_category: :shared do
|
|||
|
||||
context 'with flag on' do
|
||||
it 'returns hash of view properties' do
|
||||
expect(helper.vscode_extension_marketplace_settings_view).to eq({
|
||||
expect(helper.vscode_extension_marketplace_settings_view).to match({
|
||||
title: _('VS Code Extension Marketplace'),
|
||||
description: _('Enable VS Code Extension Marketplace and configure the extensions registry for Web IDE.'),
|
||||
view_model: {
|
||||
initialSettings: vscode_extension_marketplace
|
||||
initialSettings: vscode_extension_marketplace,
|
||||
presets: [
|
||||
hash_including("key" => "open_vsx")
|
||||
]
|
||||
}
|
||||
})
|
||||
end
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do
|
|||
it { expect(setting.global_search_merge_requests_enabled).to be(true) }
|
||||
it { expect(setting.global_search_snippet_titles_enabled).to be(true) }
|
||||
it { expect(setting.global_search_users_enabled).to be(true) }
|
||||
it { expect(setting.vscode_extension_marketplace).to eq({}) }
|
||||
it { expect(setting.vscode_extension_marketplace).to eq({ "enabled" => false }) }
|
||||
it { expect(setting.vscode_extension_marketplace_enabled?).to be(false) }
|
||||
|
||||
it do
|
||||
expect(setting.sign_in_restrictions).to eq({
|
||||
|
|
@ -1776,7 +1777,7 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'vscode_extension_marketplace' do
|
||||
describe '#vscode_extension_marketplace' do
|
||||
let(:invalid_custom) { { enabled: false, preset: "custom", custom_values: {} } }
|
||||
let(:valid_open_vsx) { { enabled: true, preset: "open_vsx" } }
|
||||
let(:valid_custom) do
|
||||
|
|
@ -1802,6 +1803,24 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do
|
|||
it { is_expected.not_to allow_value(invalid_custom).for(:vscode_extension_marketplace) }
|
||||
end
|
||||
|
||||
describe '#vscode_extension_marketplace_enabled' do
|
||||
it 'is updated when underlying vscode_extension_marketplace changes' do
|
||||
expect(setting.vscode_extension_marketplace_enabled).to be(false)
|
||||
|
||||
setting.vscode_extension_marketplace = { enabled: true, preset: "open_vsx" }
|
||||
|
||||
expect(setting.vscode_extension_marketplace_enabled).to be(true)
|
||||
end
|
||||
|
||||
it 'updates the underlying vscode_extension_marketplace when changed' do
|
||||
setting.vscode_extension_marketplace = { enabled: true, preset: "open_vsx" }
|
||||
|
||||
setting.vscode_extension_marketplace_enabled = false
|
||||
|
||||
expect(setting.vscode_extension_marketplace).to eq({ "enabled" => false, "preset" => "open_vsx" })
|
||||
end
|
||||
end
|
||||
|
||||
describe '#static_objects_external_storage_auth_token=', :aggregate_failures do
|
||||
subject { setting.static_objects_external_storage_auth_token = token }
|
||||
|
||||
|
|
|
|||
|
|
@ -1221,5 +1221,16 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting, featu
|
|||
expect(json_response['resource_usage_limits']).to eq(hash)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with vscode_extension_marketplace_enabled' do
|
||||
it 'updates underlying vscode_extension_marketplace field' do
|
||||
put api("/application/settings", admin),
|
||||
params: { vscode_extension_marketplace_enabled: true }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response['vscode_extension_marketplace_enabled']).to eq(true)
|
||||
expect(json_response['vscode_extension_marketplace']).to eq({ "enabled" => true })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -31,7 +31,22 @@ RSpec.describe 'admin/application_settings/_extension_marketplace', feature_cate
|
|||
|
||||
it 'renders data-view-model for vue app' do
|
||||
vue_app = page.at('#js-extension-marketplace-settings-app')
|
||||
expected_json = { initialSettings: {} }.to_json
|
||||
expected_presets = ::WebIde::ExtensionMarketplacePreset.all.map do |x|
|
||||
{
|
||||
key: x.key,
|
||||
name: x.name,
|
||||
values: {
|
||||
serviceUrl: x.values[:service_url],
|
||||
itemUrl: x.values[:item_url],
|
||||
resourceUrlTemplate: x.values[:resource_url_template]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
expected_json = {
|
||||
presets: expected_presets,
|
||||
initialSettings: { enabled: false }
|
||||
}.to_json
|
||||
|
||||
expect(vue_app).not_to be_nil
|
||||
expect(vue_app['data-view-model']).to eq(expected_json)
|
||||
|
|
|
|||
Loading…
Reference in New Issue