Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
fe9cb6b25a
commit
ff83f24eac
|
@ -1 +1 @@
|
|||
d483d0d4cb972dd54d23919523ddc296f0dd9590
|
||||
43e8389d447f471e889dd4521a13037f36d8a230
|
||||
|
|
|
@ -27,7 +27,7 @@ export default {
|
|||
<template>
|
||||
<div class="block gl-display-flex gl-justify-content-space-between">
|
||||
<span class="issuable-header-text hide-collapsed">
|
||||
{{ __('To Do') }}
|
||||
{{ __('To-Do') }}
|
||||
</span>
|
||||
<sidebar-todo
|
||||
v-if="!sidebarCollapsed"
|
||||
|
|
|
@ -7,7 +7,7 @@ import createAlertTodo from '../../graphql/mutations/alert_todo_create.graphql';
|
|||
export default {
|
||||
i18n: {
|
||||
UPDATE_ALERT_TODO_ERROR: s__(
|
||||
'AlertManagement|There was an error while updating the To Do of the alert.',
|
||||
'AlertManagement|There was an error while updating the To-Do of the alert.',
|
||||
),
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -97,10 +97,10 @@ export default {
|
|||
data-testid="dropzone-area"
|
||||
>
|
||||
<gl-icon name="upload" :size="iconStyles.size" :class="iconStyles.class" />
|
||||
<p class="gl-font-weight-bold gl-mb-0">
|
||||
<gl-sprintf :message="__('Drop or %{linkStart}upload%{linkEnd} Designs to attach')">
|
||||
<p class="gl-mb-0">
|
||||
<gl-sprintf :message="__('Drop or %{linkStart}upload%{linkEnd} designs to attach')">
|
||||
<template #link="{ content }">
|
||||
<gl-link class="gl-font-weight-normal" @click.stop="openFileUpload">
|
||||
<gl-link @click.stop="openFileUpload">
|
||||
{{ content }}
|
||||
</gl-link>
|
||||
</template>
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Icon,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
confidential: ({ noteableData }) => noteableData.confidential,
|
||||
dicussionLocked: ({ noteableData }) => noteableData.discussion_locked,
|
||||
}),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-display-inline-block">
|
||||
<div v-if="confidential" class="issuable-warning-icon inline">
|
||||
<icon class="icon" name="eye-slash" data-testid="confidential" />
|
||||
</div>
|
||||
|
||||
<div v-if="dicussionLocked" class="issuable-warning-icon inline">
|
||||
<icon class="icon" name="lock" data-testid="locked" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -1,8 +1,6 @@
|
|||
import Vue from 'vue';
|
||||
import issuableApp from './components/app.vue';
|
||||
import IssuableHeaderWarnings from './components/issuable_header_warnings.vue';
|
||||
import { parseIssuableData } from './utils/parse_data';
|
||||
import { store } from '~/notes/stores';
|
||||
|
||||
export default function initIssueableApp() {
|
||||
return new Vue({
|
||||
|
@ -17,13 +15,3 @@ export default function initIssueableApp() {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function issuableHeaderWarnings() {
|
||||
return new Vue({
|
||||
el: document.getElementById('js-issuable-header-warnings'),
|
||||
store,
|
||||
render(createElement) {
|
||||
return createElement(IssuableHeaderWarnings);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import store from '~/mr_notes/stores';
|
|||
import notesApp from '../notes/components/notes_app.vue';
|
||||
import discussionKeyboardNavigator from '../notes/components/discussion_keyboard_navigator.vue';
|
||||
import initWidget from '../vue_merge_request_widget';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
|
||||
export default () => {
|
||||
// eslint-disable-next-line no-new
|
||||
|
@ -20,6 +21,7 @@ export default () => {
|
|||
const noteableData = JSON.parse(notesDataset.noteableData);
|
||||
noteableData.noteableType = notesDataset.noteableType;
|
||||
noteableData.targetType = notesDataset.targetType;
|
||||
noteableData.discussion_locked = parseBoolean(notesDataset.isLocked);
|
||||
|
||||
return {
|
||||
noteableData,
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// Note: this getter is important because
|
||||
// `noteableData` is namespaced under `notes` for `~/mr_notes/stores`
|
||||
// while `noteableData` is directly available as `state.noteableData` for `~/notes/stores`
|
||||
export const getNoteableData = state => state.notes.noteableData;
|
||||
|
||||
export default {
|
||||
isLoggedIn(state, getters) {
|
||||
return Boolean(getters.getUserData.id);
|
||||
|
|
|
@ -3,16 +3,18 @@ import Issue from '~/issue';
|
|||
import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
|
||||
import ZenMode from '~/zen_mode';
|
||||
import '~/notes/index';
|
||||
import initIssueableApp, { issuableHeaderWarnings } from '~/issue_show';
|
||||
import { store } from '~/notes/stores';
|
||||
import initIssueableApp from '~/issue_show';
|
||||
import initIssuableHeaderWarning from '~/vue_shared/components/issuable/init_issuable_header_warning';
|
||||
import initSentryErrorStackTraceApp from '~/sentry_error_stack_trace';
|
||||
import initRelatedMergeRequestsApp from '~/related_merge_requests';
|
||||
import initVueIssuableSidebarApp from '~/issuable_sidebar/sidebar_bundle';
|
||||
|
||||
export default function() {
|
||||
initIssueableApp();
|
||||
initIssuableHeaderWarning(store);
|
||||
initSentryErrorStackTraceApp();
|
||||
initRelatedMergeRequestsApp();
|
||||
issuableHeaderWarnings();
|
||||
|
||||
import(/* webpackChunkName: 'design_management' */ '~/design_management')
|
||||
.then(module => module.default())
|
||||
|
|
|
@ -2,6 +2,8 @@ import initMrNotes from '~/mr_notes';
|
|||
import { initReviewBar } from '~/batch_comments';
|
||||
import initSidebarBundle from '~/sidebar/sidebar_bundle';
|
||||
import initShow from '../init_merge_request_show';
|
||||
import initIssuableHeaderWarning from '~/vue_shared/components/issuable/init_issuable_header_warning';
|
||||
import store from '~/mr_notes/stores';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initShow();
|
||||
|
@ -10,4 +12,5 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
}
|
||||
initMrNotes();
|
||||
initReviewBar();
|
||||
initIssuableHeaderWarning(store);
|
||||
});
|
||||
|
|
|
@ -13,7 +13,6 @@ export default {
|
|||
|
||||
if (value === 0) {
|
||||
this.containerRegistryEnabled = false;
|
||||
this.lfsEnabled = false;
|
||||
}
|
||||
} else if (oldValue === 0) {
|
||||
this.mergeRequestsAccessLevel = value;
|
||||
|
|
|
@ -6,7 +6,7 @@ import tooltip from '~/vue_shared/directives/tooltip';
|
|||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
|
||||
const MARK_TEXT = __('Mark as done');
|
||||
const TODO_TEXT = __('Add a To Do');
|
||||
const TODO_TEXT = __('Add a To-Do');
|
||||
|
||||
export default {
|
||||
directives: {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import Vue from 'vue';
|
||||
import IssuableHeaderWarnings from './issuable_header_warnings.vue';
|
||||
|
||||
export default function issuableHeaderWarnings(store) {
|
||||
return new Vue({
|
||||
el: document.getElementById('js-issuable-header-warnings'),
|
||||
store,
|
||||
render(createElement) {
|
||||
return createElement(IssuableHeaderWarnings);
|
||||
},
|
||||
});
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import { GlIcon } from '@gitlab/ui';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlIcon,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['getNoteableData']),
|
||||
isLocked() {
|
||||
return this.getNoteableData.discussion_locked;
|
||||
},
|
||||
isConfidential() {
|
||||
return this.getNoteableData.confidential;
|
||||
},
|
||||
warningIconsMeta() {
|
||||
return [
|
||||
{
|
||||
iconName: 'lock',
|
||||
visible: this.isLocked,
|
||||
dataTestId: 'locked',
|
||||
},
|
||||
{
|
||||
iconName: 'eye-slash',
|
||||
visible: this.isConfidential,
|
||||
dataTestId: 'confidential',
|
||||
},
|
||||
];
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-display-inline-block">
|
||||
<template v-for="meta in warningIconsMeta">
|
||||
<div v-if="meta.visible" :key="meta.iconName" class="issuable-warning-icon inline">
|
||||
<gl-icon :name="meta.iconName" :data-testid="meta.dataTestId" class="icon" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
|
@ -15,8 +15,7 @@
|
|||
= state_human_name
|
||||
|
||||
.issuable-meta
|
||||
- if @merge_request.discussion_locked?
|
||||
.issuable-warning-icon.inline= sprite_icon('lock', size: 16, css_class: 'icon')
|
||||
#js-issuable-header-warnings
|
||||
= issuable_meta(@merge_request, @project, "Merge request")
|
||||
|
||||
%a.btn.btn-default.float-right.d-block.d-sm-none.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ href: "#" }
|
||||
|
|
|
@ -70,7 +70,8 @@
|
|||
noteable_type: 'MergeRequest',
|
||||
target_type: 'merge_request',
|
||||
help_page_path: suggest_changes_help_path,
|
||||
current_user_data: @current_user_data} }
|
||||
current_user_data: @current_user_data,
|
||||
is_locked: @merge_request.discussion_locked.to_s } }
|
||||
|
||||
= render "projects/merge_requests/tabs/pane", name: "commits", id: "commits", class: "commits" do
|
||||
-# This tab is always loaded via AJAX
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Consolidate issuable_header_warning for both MR and issue
|
||||
merge_request: 37043
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Use normal font weight for Design Management dropzone text
|
||||
merge_request: 37787
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Allow LFS to be enabled in project settings even when Repository is disabled
|
||||
merge_request: 37401
|
||||
author:
|
||||
type: fixed
|
Binary file not shown.
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 16 KiB |
|
@ -1402,6 +1402,9 @@ msgstr ""
|
|||
msgid "Add a To Do"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add a To-Do"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add a bullet list"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1429,6 +1432,9 @@ msgstr ""
|
|||
msgid "Add a numbered list"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add a related issue"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add a table"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1447,9 +1453,6 @@ msgstr ""
|
|||
msgid "Add an impersonation token"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add an issue"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add another link"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2118,7 +2121,7 @@ msgstr ""
|
|||
msgid "AlertManagement|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
|
||||
msgstr ""
|
||||
|
||||
msgid "AlertManagement|There was an error while updating the To Do of the alert."
|
||||
msgid "AlertManagement|There was an error while updating the To-Do of the alert."
|
||||
msgstr ""
|
||||
|
||||
msgid "AlertManagement|There was an error while updating the assignee(s) list. Please try again."
|
||||
|
@ -8557,7 +8560,7 @@ msgstr ""
|
|||
msgid "Draft merge requests can't be merged."
|
||||
msgstr ""
|
||||
|
||||
msgid "Drop or %{linkStart}upload%{linkEnd} Designs to attach"
|
||||
msgid "Drop or %{linkStart}upload%{linkEnd} designs to attach"
|
||||
msgstr ""
|
||||
|
||||
msgid "Drop your designs to start your upload."
|
||||
|
@ -20901,6 +20904,9 @@ msgstr ""
|
|||
msgid "SecurityConfiguration|Configure"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Customize common SAST settings to suit your requirements. More advanced configuration options exist, which you can add to the configuration file this tool generates. It's important to note that if you make any configurations, they will be saved as overrides and will be %{strongStart}excluded from automatic updates%{strongEnd}."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Enable via Merge Request"
|
||||
msgstr ""
|
||||
|
||||
|
@ -25017,6 +25023,9 @@ msgstr ""
|
|||
msgid "To widen your search, change or remove filters."
|
||||
msgstr ""
|
||||
|
||||
msgid "To-Do"
|
||||
msgstr ""
|
||||
|
||||
msgid "To-Do List"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -52,9 +52,9 @@ describe('Alert Details Sidebar To Do', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('renders a button for adding a To Do', () => {
|
||||
it('renders a button for adding a To-Do', () => {
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
expect(wrapper.find('[data-testid="alert-todo-button"]').text()).toBe('Add a To Do');
|
||||
expect(wrapper.find('[data-testid="alert-todo-button"]').text()).toBe('Add a To-Do');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ exports[`Design management dropzone component when dragging renders correct temp
|
|||
/>
|
||||
|
||||
<p
|
||||
class="gl-font-weight-bold gl-mb-0"
|
||||
class="gl-mb-0"
|
||||
>
|
||||
<gl-sprintf-stub
|
||||
message="Drop or %{linkStart}upload%{linkEnd} Designs to attach"
|
||||
message="Drop or %{linkStart}upload%{linkEnd} designs to attach"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -94,10 +94,10 @@ exports[`Design management dropzone component when dragging renders correct temp
|
|||
/>
|
||||
|
||||
<p
|
||||
class="gl-font-weight-bold gl-mb-0"
|
||||
class="gl-mb-0"
|
||||
>
|
||||
<gl-sprintf-stub
|
||||
message="Drop or %{linkStart}upload%{linkEnd} Designs to attach"
|
||||
message="Drop or %{linkStart}upload%{linkEnd} designs to attach"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -170,10 +170,10 @@ exports[`Design management dropzone component when dragging renders correct temp
|
|||
/>
|
||||
|
||||
<p
|
||||
class="gl-font-weight-bold gl-mb-0"
|
||||
class="gl-mb-0"
|
||||
>
|
||||
<gl-sprintf-stub
|
||||
message="Drop or %{linkStart}upload%{linkEnd} Designs to attach"
|
||||
message="Drop or %{linkStart}upload%{linkEnd} designs to attach"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -245,10 +245,10 @@ exports[`Design management dropzone component when dragging renders correct temp
|
|||
/>
|
||||
|
||||
<p
|
||||
class="gl-font-weight-bold gl-mb-0"
|
||||
class="gl-mb-0"
|
||||
>
|
||||
<gl-sprintf-stub
|
||||
message="Drop or %{linkStart}upload%{linkEnd} Designs to attach"
|
||||
message="Drop or %{linkStart}upload%{linkEnd} designs to attach"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -320,10 +320,10 @@ exports[`Design management dropzone component when dragging renders correct temp
|
|||
/>
|
||||
|
||||
<p
|
||||
class="gl-font-weight-bold gl-mb-0"
|
||||
class="gl-mb-0"
|
||||
>
|
||||
<gl-sprintf-stub
|
||||
message="Drop or %{linkStart}upload%{linkEnd} Designs to attach"
|
||||
message="Drop or %{linkStart}upload%{linkEnd} designs to attach"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -395,10 +395,10 @@ exports[`Design management dropzone component when no slot provided renders defa
|
|||
/>
|
||||
|
||||
<p
|
||||
class="gl-font-weight-bold gl-mb-0"
|
||||
class="gl-mb-0"
|
||||
>
|
||||
<gl-sprintf-stub
|
||||
message="Drop or %{linkStart}upload%{linkEnd} Designs to attach"
|
||||
message="Drop or %{linkStart}upload%{linkEnd} designs to attach"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -22,6 +22,7 @@ export default function initVueMRPage() {
|
|||
mrDiscussionsEl.setAttribute('data-noteable-data', JSON.stringify(noteableDataMock));
|
||||
mrDiscussionsEl.setAttribute('data-notes-data', JSON.stringify(notesDataMock));
|
||||
mrDiscussionsEl.setAttribute('data-noteable-type', 'merge-request');
|
||||
mrDiscussionsEl.setAttribute('data-is-locked', 'false');
|
||||
mrTestEl.appendChild(mrDiscussionsEl);
|
||||
|
||||
const discussionCounterEl = document.createElement('div');
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||
import Vuex from 'vuex';
|
||||
import IssuableHeaderWarnings from '~/issue_show/components/issuable_header_warnings.vue';
|
||||
import createStore from '~/notes/stores';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
|
||||
describe('IssuableHeaderWarnings', () => {
|
||||
let wrapper;
|
||||
let store;
|
||||
|
||||
const findConfidential = () => wrapper.find('[data-testid="confidential"]');
|
||||
const findLocked = () => wrapper.find('[data-testid="locked"]');
|
||||
const confidentialIconName = () => findConfidential().attributes('name');
|
||||
const lockedIconName = () => findLocked().attributes('name');
|
||||
|
||||
const createComponent = () => {
|
||||
wrapper = shallowMount(IssuableHeaderWarnings, { store, localVue });
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
store = createStore();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
wrapper = null;
|
||||
store = null;
|
||||
});
|
||||
|
||||
describe('when confidential is on', () => {
|
||||
beforeEach(() => {
|
||||
store.state.noteableData.confidential = true;
|
||||
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('renders the confidential icon', () => {
|
||||
expect(confidentialIconName()).toBe('eye-slash');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when confidential is off', () => {
|
||||
beforeEach(() => {
|
||||
store.state.noteableData.confidential = false;
|
||||
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('does not find the component', () => {
|
||||
expect(findConfidential().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when discussion locked is on', () => {
|
||||
beforeEach(() => {
|
||||
store.state.noteableData.discussion_locked = true;
|
||||
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('renders the locked icon', () => {
|
||||
expect(lockedIconName()).toBe('lock');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when discussion locked is off', () => {
|
||||
beforeEach(() => {
|
||||
store.state.noteableData.discussion_locked = false;
|
||||
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('does not find the component', () => {
|
||||
expect(findLocked().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -6,6 +6,8 @@ import {
|
|||
visibilityLevelDescriptions,
|
||||
visibilityOptions,
|
||||
} from '~/pages/projects/shared/permissions/constants';
|
||||
import projectFeatureSetting from '~/pages/projects/shared/permissions/components/project_feature_setting.vue';
|
||||
import projectFeatureToggle from '~/vue_shared/components/toggle_button.vue';
|
||||
|
||||
const defaultProps = {
|
||||
currentSettings: {
|
||||
|
@ -65,7 +67,13 @@ describe('Settings Panel', () => {
|
|||
return mountComponent({ ...extraProps, currentSettings: currentSettingsProps });
|
||||
};
|
||||
|
||||
const findLFSSettingsMessage = () => wrapper.find({ ref: 'git-lfs-settings' }).find('p');
|
||||
const findLFSSettingsRow = () => wrapper.find({ ref: 'git-lfs-settings' });
|
||||
const findLFSSettingsMessage = () => findLFSSettingsRow().find('p');
|
||||
const findLFSFeatureToggle = () => findLFSSettingsRow().find(projectFeatureToggle);
|
||||
|
||||
const findRepositoryFeatureProjectRow = () => wrapper.find({ ref: 'repository-settings' });
|
||||
const findRepositoryFeatureSetting = () =>
|
||||
findRepositoryFeatureProjectRow().find(projectFeatureSetting);
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = mountComponent();
|
||||
|
@ -154,7 +162,7 @@ describe('Settings Panel', () => {
|
|||
it('should set the repository help text when the visibility level is set to private', () => {
|
||||
wrapper = overrideCurrentSettings({ visibilityLevel: visibilityOptions.PRIVATE });
|
||||
|
||||
expect(wrapper.find({ ref: 'repository-settings' }).props().helpText).toEqual(
|
||||
expect(findRepositoryFeatureProjectRow().props().helpText).toBe(
|
||||
'View and edit files in this project',
|
||||
);
|
||||
});
|
||||
|
@ -162,7 +170,7 @@ describe('Settings Panel', () => {
|
|||
it('should set the repository help text with a read access warning when the visibility level is set to non-private', () => {
|
||||
wrapper = overrideCurrentSettings({ visibilityLevel: visibilityOptions.PUBLIC });
|
||||
|
||||
expect(wrapper.find({ ref: 'repository-settings' }).props().helpText).toEqual(
|
||||
expect(findRepositoryFeatureProjectRow().props().helpText).toBe(
|
||||
'View and edit files in this project. Non-project members will only have read access',
|
||||
);
|
||||
});
|
||||
|
@ -176,7 +184,7 @@ describe('Settings Panel', () => {
|
|||
wrapper
|
||||
.find('[name="project[project_feature_attributes][merge_requests_access_level]"]')
|
||||
.props().disabledInput,
|
||||
).toEqual(false);
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('should disable the merge requests access level input when the repository is disabled', () => {
|
||||
|
@ -186,7 +194,7 @@ describe('Settings Panel', () => {
|
|||
wrapper
|
||||
.find('[name="project[project_feature_attributes][merge_requests_access_level]"]')
|
||||
.props().disabledInput,
|
||||
).toEqual(true);
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -197,7 +205,7 @@ describe('Settings Panel', () => {
|
|||
expect(
|
||||
wrapper.find('[name="project[project_feature_attributes][forking_access_level]"]').props()
|
||||
.disabledInput,
|
||||
).toEqual(false);
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('should disable the forking access level input when the repository is disabled', () => {
|
||||
|
@ -206,7 +214,7 @@ describe('Settings Panel', () => {
|
|||
expect(
|
||||
wrapper.find('[name="project[project_feature_attributes][forking_access_level]"]').props()
|
||||
.disabledInput,
|
||||
).toEqual(true);
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -217,7 +225,7 @@ describe('Settings Panel', () => {
|
|||
expect(
|
||||
wrapper.find('[name="project[project_feature_attributes][builds_access_level]"]').props()
|
||||
.disabledInput,
|
||||
).toEqual(false);
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('should disable the builds access level input when the repository is disabled', () => {
|
||||
|
@ -226,7 +234,7 @@ describe('Settings Panel', () => {
|
|||
expect(
|
||||
wrapper.find('[name="project[project_feature_attributes][builds_access_level]"]').props()
|
||||
.disabledInput,
|
||||
).toEqual(true);
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -287,7 +295,7 @@ describe('Settings Panel', () => {
|
|||
|
||||
expect(
|
||||
wrapper.find('[name="project[container_registry_enabled]"]').props().disabledInput,
|
||||
).toEqual(false);
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('should disable the container registry input when the repository is disabled', () => {
|
||||
|
@ -298,7 +306,7 @@ describe('Settings Panel', () => {
|
|||
|
||||
expect(
|
||||
wrapper.find('[name="project[container_registry_enabled]"]').props().disabledInput,
|
||||
).toEqual(true);
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -307,7 +315,7 @@ describe('Settings Panel', () => {
|
|||
wrapper.setProps({ lfsAvailable: true });
|
||||
|
||||
return wrapper.vm.$nextTick(() => {
|
||||
expect(wrapper.find({ ref: 'git-lfs-settings' }).exists()).toEqual(true);
|
||||
expect(findLFSSettingsRow().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -315,14 +323,12 @@ describe('Settings Panel', () => {
|
|||
wrapper.setProps({ lfsAvailable: false });
|
||||
|
||||
return wrapper.vm.$nextTick(() => {
|
||||
expect(wrapper.find({ ref: 'git-lfs-settings' }).exists()).toEqual(false);
|
||||
expect(findLFSSettingsRow().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('should set the LFS settings help path', () => {
|
||||
expect(wrapper.find({ ref: 'git-lfs-settings' }).props().helpPath).toBe(
|
||||
defaultProps.lfsHelpPath,
|
||||
);
|
||||
expect(findLFSSettingsRow().props().helpPath).toBe(defaultProps.lfsHelpPath);
|
||||
});
|
||||
|
||||
it('should enable the LFS input when the repository is enabled', () => {
|
||||
|
@ -331,7 +337,7 @@ describe('Settings Panel', () => {
|
|||
{ lfsAvailable: true },
|
||||
);
|
||||
|
||||
expect(wrapper.find('[name="project[lfs_enabled]"]').props().disabledInput).toEqual(false);
|
||||
expect(findLFSFeatureToggle().props().disabledInput).toBe(false);
|
||||
});
|
||||
|
||||
it('should disable the LFS input when the repository is disabled', () => {
|
||||
|
@ -340,7 +346,27 @@ describe('Settings Panel', () => {
|
|||
{ lfsAvailable: true },
|
||||
);
|
||||
|
||||
expect(wrapper.find('[name="project[lfs_enabled]"]').props().disabledInput).toEqual(true);
|
||||
expect(findLFSFeatureToggle().props().disabledInput).toBe(true);
|
||||
});
|
||||
|
||||
it('should not change lfsEnabled when disabling the repository', async () => {
|
||||
// mount over shallowMount, because we are aiming to test rendered state of toggle
|
||||
wrapper = mountComponent({ currentSettings: { lfsEnabled: true } }, mount);
|
||||
|
||||
const repositoryFeatureToggleButton = findRepositoryFeatureSetting().find('button');
|
||||
const lfsFeatureToggleButton = findLFSFeatureToggle().find('button');
|
||||
const isToggleButtonChecked = toggleButton => toggleButton.classes('is-checked');
|
||||
|
||||
// assert the initial state
|
||||
expect(isToggleButtonChecked(lfsFeatureToggleButton)).toBe(true);
|
||||
expect(isToggleButtonChecked(repositoryFeatureToggleButton)).toBe(true);
|
||||
|
||||
repositoryFeatureToggleButton.trigger('click');
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
expect(isToggleButtonChecked(repositoryFeatureToggleButton)).toBe(false);
|
||||
// LFS toggle should still be checked
|
||||
expect(isToggleButtonChecked(lfsFeatureToggleButton)).toBe(true);
|
||||
});
|
||||
|
||||
describe.each`
|
||||
|
@ -364,14 +390,14 @@ describe('Settings Panel', () => {
|
|||
expect(message.text()).toContain(
|
||||
'LFS objects from this repository are still available to forks',
|
||||
);
|
||||
expect(link.text()).toEqual('How do I remove them?');
|
||||
expect(link.attributes('href')).toEqual(
|
||||
expect(link.text()).toBe('How do I remove them?');
|
||||
expect(link.attributes('href')).toBe(
|
||||
'/help/topics/git/lfs/index#removing-objects-from-lfs',
|
||||
);
|
||||
});
|
||||
} else {
|
||||
it('does not show warning message', () => {
|
||||
expect(findLFSSettingsMessage().exists()).toEqual(false);
|
||||
expect(findLFSSettingsMessage().exists()).toBe(false);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -383,7 +409,7 @@ describe('Settings Panel', () => {
|
|||
wrapper.setProps({ packagesAvailable: true });
|
||||
|
||||
return wrapper.vm.$nextTick(() => {
|
||||
expect(wrapper.find({ ref: 'package-settings' }).exists()).toEqual(true);
|
||||
expect(wrapper.find({ ref: 'package-settings' }).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -391,7 +417,7 @@ describe('Settings Panel', () => {
|
|||
wrapper.setProps({ packagesAvailable: false });
|
||||
|
||||
return wrapper.vm.$nextTick(() => {
|
||||
expect(wrapper.find({ ref: 'package-settings' }).exists()).toEqual(false);
|
||||
expect(wrapper.find({ ref: 'package-settings' }).exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -411,9 +437,7 @@ describe('Settings Panel', () => {
|
|||
{ packagesAvailable: true },
|
||||
);
|
||||
|
||||
expect(wrapper.find('[name="project[packages_enabled]"]').props().disabledInput).toEqual(
|
||||
false,
|
||||
);
|
||||
expect(wrapper.find('[name="project[packages_enabled]"]').props().disabledInput).toBe(false);
|
||||
});
|
||||
|
||||
it('should disable the packages input when the repository is disabled', () => {
|
||||
|
@ -422,9 +446,7 @@ describe('Settings Panel', () => {
|
|||
{ packagesAvailable: true },
|
||||
);
|
||||
|
||||
expect(wrapper.find('[name="project[packages_enabled]"]').props().disabledInput).toEqual(
|
||||
true,
|
||||
);
|
||||
expect(wrapper.find('[name="project[packages_enabled]"]').props().disabledInput).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -503,7 +525,7 @@ describe('Settings Panel', () => {
|
|||
});
|
||||
|
||||
it('should contain help text', () => {
|
||||
expect(wrapper.find({ ref: 'metrics-visibility-settings' }).props().helpText).toEqual(
|
||||
expect(wrapper.find({ ref: 'metrics-visibility-settings' }).props().helpText).toBe(
|
||||
'With Metrics Dashboard you can visualize this project performance metrics',
|
||||
);
|
||||
});
|
||||
|
@ -514,7 +536,7 @@ describe('Settings Panel', () => {
|
|||
const metricsSettingsRow = wrapper.find({ ref: 'metrics-visibility-settings' });
|
||||
|
||||
expect(wrapper.vm.metricsOptionsDropdownEnabled).toBe(true);
|
||||
expect(metricsSettingsRow.find('select').attributes('disabled')).toEqual('disabled');
|
||||
expect(metricsSettingsRow.find('select').attributes('disabled')).toBe('disabled');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -36,7 +36,7 @@ describe('SidebarTodo', () => {
|
|||
|
||||
it.each`
|
||||
isTodo | iconClass | label | icon
|
||||
${false} | ${''} | ${'Add a To Do'} | ${'todo-add'}
|
||||
${false} | ${''} | ${'Add a To-Do'} | ${'todo-add'}
|
||||
${true} | ${'todo-undone'} | ${'Mark as done'} | ${'todo-done'}
|
||||
`(
|
||||
'renders proper button when `isTodo` prop is `$isTodo`',
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||
import Vuex from 'vuex';
|
||||
import IssuableHeaderWarnings from '~/vue_shared/components/issuable/issuable_header_warnings.vue';
|
||||
import createIssueStore from '~/notes/stores';
|
||||
import { createStore as createMrStore } from '~/mr_notes/stores';
|
||||
|
||||
const ISSUABLE_TYPE_ISSUE = 'issue';
|
||||
const ISSUABLE_TYPE_MR = 'merge request';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
|
||||
describe('IssuableHeaderWarnings', () => {
|
||||
let wrapper;
|
||||
let store;
|
||||
|
||||
const findConfidentialIcon = () => wrapper.find('[data-testid="confidential"]');
|
||||
const findLockedIcon = () => wrapper.find('[data-testid="locked"]');
|
||||
|
||||
const renderTestMessage = renders => (renders ? 'renders' : 'does not render');
|
||||
|
||||
const setLock = locked => {
|
||||
store.getters.getNoteableData.discussion_locked = locked;
|
||||
};
|
||||
|
||||
const setConfidential = confidential => {
|
||||
store.getters.getNoteableData.confidential = confidential;
|
||||
};
|
||||
|
||||
const createComponent = () => {
|
||||
wrapper = shallowMount(IssuableHeaderWarnings, { store, localVue });
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
wrapper = null;
|
||||
store = null;
|
||||
});
|
||||
|
||||
describe.each`
|
||||
issuableType
|
||||
${ISSUABLE_TYPE_ISSUE} | ${ISSUABLE_TYPE_MR}
|
||||
`(`when issuableType=$issuableType`, ({ issuableType }) => {
|
||||
beforeEach(() => {
|
||||
store = issuableType === ISSUABLE_TYPE_ISSUE ? createIssueStore() : createMrStore();
|
||||
createComponent();
|
||||
});
|
||||
|
||||
describe.each`
|
||||
lockStatus | confidentialStatus
|
||||
${true} | ${true}
|
||||
${true} | ${false}
|
||||
${false} | ${true}
|
||||
${false} | ${false}
|
||||
`(
|
||||
`when locked=$lockStatus and confidential=$confidentialStatus`,
|
||||
({ lockStatus, confidentialStatus }) => {
|
||||
beforeEach(() => {
|
||||
setLock(lockStatus);
|
||||
setConfidential(confidentialStatus);
|
||||
});
|
||||
|
||||
it(`${renderTestMessage(lockStatus)} the locked icon`, () => {
|
||||
expect(findLockedIcon().exists()).toBe(lockStatus);
|
||||
});
|
||||
|
||||
it(`${renderTestMessage(confidentialStatus)} the confidential icon`, () => {
|
||||
expect(findConfidentialIcon().exists()).toBe(confidentialStatus);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue