summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-04-27 06:13:06 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-04-27 06:13:06 +0000
commit3fbe43541ef99c27a9e4ab9c545ec0eb9bb50a9e (patch)
treedf71ce391f93b65a4f44fa719c8def2b9e45d40f
parent0e1350d51ca2135e37743dfb7af98eae43c72892 (diff)
downloadgitlab-ce-3fbe43541ef99c27a9e4ab9c545ec0eb9bb50a9e.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/issuable/components/related_issuable_item.vue2
-rw-r--r--app/assets/javascripts/issues/related_merge_requests/components/related_merge_requests.vue1
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/api.js9
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item.vue45
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/app.vue5
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/sign_in_legacy_button.vue40
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue6
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/user_link.vue14
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/constants.js2
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/index.js6
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_com.vue3
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue2
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/store/actions.js32
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js3
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/store/mutations.js9
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/store/state.js3
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/utils.js27
-rw-r--r--app/assets/javascripts/notes/components/discussion_filter.vue76
-rw-r--r--app/assets/javascripts/pages/jira_connect/oauth_callbacks/index.js7
-rw-r--r--app/assets/javascripts/related_issues/components/related_issues_list.vue1
-rw-r--r--app/assets/stylesheets/framework/common.scss3
-rw-r--r--app/controllers/admin/application_settings_controller.rb93
-rw-r--r--app/helpers/application_settings_helper.rb22
-rw-r--r--app/helpers/jira_connect_helper.rb2
-rw-r--r--app/services/metrics/dashboard/clone_dashboard_service.rb4
-rw-r--r--config/routes/admin.rb5
-rw-r--r--doc/user/application_security/secret_detection/post_processing.md26
-rw-r--r--lib/gitlab/database.rb2
-rw-r--r--lib/gitlab/metrics/dashboard/finder.rb21
-rw-r--r--lib/gitlab/metrics/dashboard/service_selector.rb1
-rw-r--r--locale/gitlab.pot18
-rw-r--r--spec/features/issues/user_sorts_issue_comments_spec.rb3
-rw-r--r--spec/frontend/bootstrap_linked_tabs_spec.js5
-rw-r--r--spec/frontend/jira_connect/subscriptions/api_spec.js25
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js3
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/sign_in_legacy_button_spec.js54
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js2
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/user_link_spec.js4
-rw-r--r--spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_com_spec.js4
-rw-r--r--spec/frontend/jira_connect/subscriptions/store/actions_spec.js20
-rw-r--r--spec/frontend/jira_connect/subscriptions/store/mutations_spec.js16
-rw-r--r--spec/frontend/jira_connect/subscriptions/utils_spec.js46
-rw-r--r--spec/frontend/merge_request_spec.js8
-rw-r--r--spec/frontend/notes/components/discussion_filter_spec.js35
-rw-r--r--spec/frontend/settings_panels_spec.js5
-rw-r--r--spec/helpers/application_settings_helper_spec.rb64
-rw-r--r--spec/helpers/jira_connect_helper_spec.rb6
-rw-r--r--spec/lib/gitlab/metrics/dashboard/finder_spec.rb37
-rw-r--r--spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb6
-rw-r--r--spec/requests/self_monitoring_project_spec.rb213
-rw-r--r--spec/services/metrics/dashboard/clone_dashboard_service_spec.rb4
-rw-r--r--spec/services/metrics/dashboard/self_monitoring_dashboard_service_spec.rb6
-rw-r--r--spec/support/helpers/metrics_dashboard_helpers.rb4
-rw-r--r--spec/tooling/danger/product_intelligence_spec.rb13
-rw-r--r--tooling/danger/product_intelligence.rb4
56 files changed, 161 insertions, 918 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 0f4b55a20b9..14a5c3966b9 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-3ce8f3a93ef7a00dfe5d65d92aa917a24e74e499
+20bc01b4d81c0e101a3a6639a926a6b9d0d7d9ba
diff --git a/app/assets/javascripts/issuable/components/related_issuable_item.vue b/app/assets/javascripts/issuable/components/related_issuable_item.vue
index 63386d2e33d..e76b4c133a9 100644
--- a/app/assets/javascripts/issuable/components/related_issuable_item.vue
+++ b/app/assets/javascripts/issuable/components/related_issuable_item.vue
@@ -124,7 +124,7 @@ export default {
'issuable-info-container': !canReorder,
'card-body': canReorder,
}"
- class="item-body gl-display-flex gl-align-items-center gl-gap-3 gl-mx-n2"
+ class="item-body gl-display-flex gl-align-items-center gl-gap-3"
>
<div
class="item-contents gl-display-flex gl-align-items-center gl-flex-wrap gl-flex-grow-1 gl-gap-2 gl-px-3 gl-py-2 py-xl-0 flex-xl-nowrap gl-min-h-7"
diff --git a/app/assets/javascripts/issues/related_merge_requests/components/related_merge_requests.vue b/app/assets/javascripts/issues/related_merge_requests/components/related_merge_requests.vue
index c3f87699d58..8490ffd33cd 100644
--- a/app/assets/javascripts/issues/related_merge_requests/components/related_merge_requests.vue
+++ b/app/assets/javascripts/issues/related_merge_requests/components/related_merge_requests.vue
@@ -116,6 +116,7 @@ export default {
:is-merge-request="true"
:pipeline-status="mr.head_pipeline && mr.head_pipeline.detailed_status"
path-id-separator="!"
+ class="gl-mx-n2"
/>
</li>
</ul>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/api.js b/app/assets/javascripts/jira_connect/subscriptions/api.js
index 8c5dc88f183..184635e63f3 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/api.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/api.js
@@ -16,15 +16,6 @@ export const setApiBaseURL = (baseURL = null) => {
axiosInstance.defaults.baseURL = baseURL;
};
-export const addSubscription = async (addPath, namespace) => {
- const jwt = await getJwt();
-
- return axiosInstance.post(addPath, {
- jwt,
- namespace_path: namespace,
- });
-};
-
export const removeSubscription = async (removePath) => {
const jwt = await getJwt();
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item.vue b/app/assets/javascripts/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item.vue
index d918559a49f..cd0f4c2f66f 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item.vue
@@ -1,27 +1,15 @@
<script>
import { mapActions } from 'vuex';
import { GlButton } from '@gitlab/ui';
-import { addSubscription } from '~/jira_connect/subscriptions/api';
-import { persistAlert, reloadPage } from '~/jira_connect/subscriptions/utils';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import GroupItemName from '../group_item_name.vue';
-import {
- INTEGRATIONS_DOC_LINK,
- I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
- I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
- I18N_ADD_SUBSCRIPTIONS_ERROR_MESSAGE,
-} from '../../constants';
+import { I18N_ADD_SUBSCRIPTIONS_ERROR_MESSAGE } from '../../constants';
export default {
components: {
GlButton,
GroupItemName,
},
- mixins: [glFeatureFlagMixin()],
inject: {
- addSubscriptionsPath: {
- default: '',
- },
subscriptionsPath: {
default: '',
},
@@ -46,30 +34,15 @@ export default {
...mapActions(['addSubscription']),
async onClick() {
this.isLoading = true;
- await this.addSubscription({
- namespacePath: this.group.full_path,
- subscriptionsPath: this.subscriptionsPath,
- });
- this.isLoading = false;
- },
- deprecatedAddSubscription() {
- this.isLoading = true;
-
- addSubscription(this.addSubscriptionsPath, this.group.full_path)
- .then(() => {
- persistAlert({
- title: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
- message: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
- linkUrl: INTEGRATIONS_DOC_LINK,
- variant: 'success',
- });
-
- reloadPage();
- })
- .catch((error) => {
- this.$emit('error', error?.response?.data?.error || I18N_ADD_SUBSCRIPTIONS_ERROR_MESSAGE);
- this.isLoading = false;
+ try {
+ await this.addSubscription({
+ namespacePath: this.group.full_path,
+ subscriptionsPath: this.subscriptionsPath,
});
+ } catch (error) {
+ this.$emit('error', error?.response?.data?.error || I18N_ADD_SUBSCRIPTIONS_ERROR_MESSAGE);
+ }
+ this.isLoading = false;
},
},
};
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/app.vue b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
index 1dc3f76b253..15e61ff1cd9 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
@@ -4,7 +4,6 @@ import { isEmpty } from 'lodash';
import { mapState, mapMutations, mapActions } from 'vuex';
import { retrieveAlert } from '~/jira_connect/subscriptions/utils';
import AccessorUtilities from '~/lib/utils/accessor';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { I18N_DEFAULT_SIGN_IN_ERROR_MESSAGE } from '../constants';
import { SET_ALERT } from '../store/mutation_types';
import SignInPage from '../pages/sign_in/sign_in_page.vue';
@@ -23,11 +22,7 @@ export default {
SubscriptionsPage,
UserLink,
},
- mixins: [glFeatureFlagMixin()],
inject: {
- usersPath: {
- default: '',
- },
subscriptionsPath: {
default: '',
},
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_legacy_button.vue b/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_legacy_button.vue
deleted file mode 100644
index ec718d5b3ca..00000000000
--- a/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_legacy_button.vue
+++ /dev/null
@@ -1,40 +0,0 @@
-<script>
-import { GlButton } from '@gitlab/ui';
-import { getGitlabSignInURL } from '~/jira_connect/subscriptions/utils';
-import { I18N_DEFAULT_SIGN_IN_BUTTON_TEXT } from '~/jira_connect/subscriptions/constants';
-
-export default {
- components: {
- GlButton,
- },
- props: {
- usersPath: {
- type: String,
- required: true,
- },
- },
- data() {
- return {
- signInURL: '',
- };
- },
- created() {
- this.setSignInURL();
- },
- methods: {
- async setSignInURL() {
- this.signInURL = await getGitlabSignInURL(this.usersPath);
- },
- },
- i18n: {
- defaultButtonText: I18N_DEFAULT_SIGN_IN_BUTTON_TEXT,
- },
-};
-</script>
-<template>
- <gl-button category="primary" variant="info" :href="signInURL" target="_blank">
- <slot>
- {{ $options.i18n.defaultButtonText }}
- </slot>
- </gl-button>
-</template>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue b/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue
index 65c69bcfa82..bc8cdf35701 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue
@@ -12,6 +12,7 @@ import {
I18N_OAUTH_FAILED_MESSAGE,
OAUTH_SELF_MANAGED_DOC_LINK,
OAUTH_WINDOW_OPTIONS,
+ OAUTH_CALLBACK_MESSAGE_TYPE,
PKCE_CODE_CHALLENGE_DIGEST_ALGORITHM,
} from '~/jira_connect/subscriptions/constants';
import { fetchOAuthApplicationId, fetchOAuthToken } from '~/jira_connect/subscriptions/api';
@@ -130,6 +131,11 @@ export default {
}
},
async handleWindowMessage(event) {
+ // Make sure this ia a message from the OAuth flow in pages/jira_connect/oauth_callbacks/index.js
+ if (event.data?.type !== OAUTH_CALLBACK_MESSAGE_TYPE) {
+ return;
+ }
+
if (window.origin !== event.origin) {
this.loading = false;
return;
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/user_link.vue b/app/assets/javascripts/jira_connect/subscriptions/components/user_link.vue
index 9e1203f21d2..d05e0d8610e 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/components/user_link.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/user_link.vue
@@ -1,8 +1,6 @@
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { __ } from '~/locale';
-import { getGitlabSignInURL } from '~/jira_connect/subscriptions/utils';
export default {
components: {
@@ -10,11 +8,7 @@ export default {
GlSprintf,
SignInOauthButton: () => import('./sign_in_oauth_button.vue'),
},
- mixins: [glFeatureFlagMixin()],
inject: {
- usersPath: {
- default: '',
- },
gitlabUserPath: {
default: '',
},
@@ -34,11 +28,6 @@ export default {
default: null,
},
},
- data() {
- return {
- signInURL: '',
- };
- },
computed: {
gitlabUserName() {
return gon.current_username ?? this.user?.username;
@@ -55,9 +44,6 @@ export default {
: this.$options.i18n.signedInText;
},
},
- async created() {
- this.signInURL = await getGitlabSignInURL(this.usersPath);
- },
i18n: {
signInText: __('Sign in to GitLab'),
signedInAsUserText: __('Signed in to GitLab as %{user_link}'),
diff --git a/app/assets/javascripts/jira_connect/subscriptions/constants.js b/app/assets/javascripts/jira_connect/subscriptions/constants.js
index bb22a4ef252..321d10205e6 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/constants.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/constants.js
@@ -54,6 +54,8 @@ export const OAUTH_WINDOW_OPTIONS = [
`top=${window.screen.height / 2 - OAUTH_WINDOW_SIZE / 2}`,
].join(',');
+export const OAUTH_CALLBACK_MESSAGE_TYPE = 'jiraConnectOauthCallback';
+
export const PKCE_CODE_CHALLENGE_DIGEST_ALGORITHM = {
long: 'SHA-256',
short: 'S256',
diff --git a/app/assets/javascripts/jira_connect/subscriptions/index.js b/app/assets/javascripts/jira_connect/subscriptions/index.js
index 21ff85e58e2..8854157054d 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/index.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/index.js
@@ -2,7 +2,6 @@ import '~/webpack';
import setConfigs from '@gitlab/ui/dist/config';
import Vue from 'vue';
-import GlFeatureFlagsPlugin from '~/vue_shared/gl_feature_flags_plugin';
import Translate from '~/vue_shared/translate';
import JiraConnectApp from './components/app.vue';
@@ -17,14 +16,11 @@ export function initJiraConnect() {
setConfigs();
Vue.use(Translate);
- Vue.use(GlFeatureFlagsPlugin);
const {
groupsPath,
subscriptions,
- addSubscriptionsPath,
subscriptionsPath,
- usersPath,
gitlabUserPath,
oauthMetadata,
publicKeyStorageEnabled,
@@ -38,9 +34,7 @@ export function initJiraConnect() {
store,
provide: {
groupsPath,
- addSubscriptionsPath,
subscriptionsPath,
- usersPath,
gitlabUserPath,
oauthMetadata: oauthMetadata ? JSON.parse(oauthMetadata) : null,
publicKeyStorageEnabled,
diff --git a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_com.vue b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_com.vue
index 8a3a1768d5e..113ce34fdcd 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_com.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_com.vue
@@ -2,7 +2,6 @@
import { s__ } from '~/locale';
import { GITLAB_COM_BASE_PATH } from '~/jira_connect/subscriptions/constants';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import SubscriptionsList from '../../components/subscriptions_list.vue';
export default {
@@ -11,8 +10,6 @@ export default {
SubscriptionsList,
SignInOauthButton: () => import('../../components/sign_in_oauth_button.vue'),
},
- mixins: [glFeatureFlagMixin()],
- inject: ['usersPath'],
props: {
hasSubscriptions: {
type: Boolean,
diff --git a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue
index 97ac88a03e9..ee20e21011f 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in/sign_in_page.vue
@@ -1,12 +1,10 @@
<script>
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import SignInGitlabCom from './sign_in_gitlab_com.vue';
import SignInGitlabMultiversion from './sign_in_gitlab_multiversion/index.vue';
export default {
name: 'SignInPage',
components: { SignInGitlabCom, SignInGitlabMultiversion },
- mixins: [glFeatureFlagMixin()],
props: {
hasSubscriptions: {
type: Boolean,
diff --git a/app/assets/javascripts/jira_connect/subscriptions/store/actions.js b/app/assets/javascripts/jira_connect/subscriptions/store/actions.js
index fff34e1d75d..3b8e4c7540b 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/store/actions.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/store/actions.js
@@ -14,8 +14,6 @@ import {
SET_SUBSCRIPTIONS,
SET_SUBSCRIPTIONS_LOADING,
SET_SUBSCRIPTIONS_ERROR,
- ADD_SUBSCRIPTION_LOADING,
- ADD_SUBSCRIPTION_ERROR,
SET_ALERT,
SET_CURRENT_USER,
SET_CURRENT_USER_ERROR,
@@ -51,25 +49,17 @@ export const addSubscription = async (
{ commit, state, dispatch },
{ namespacePath, subscriptionsPath },
) => {
- try {
- commit(ADD_SUBSCRIPTION_LOADING, true);
-
- await addJiraConnectSubscription(namespacePath, {
- jwt: await getJwt(),
- accessToken: state.accessToken,
- });
+ await addJiraConnectSubscription(namespacePath, {
+ jwt: await getJwt(),
+ accessToken: state.accessToken,
+ });
- commit(SET_ALERT, {
- title: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
- message: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
- linkUrl: INTEGRATIONS_DOC_LINK,
- variant: 'success',
- });
+ commit(SET_ALERT, {
+ title: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_TITLE,
+ message: I18N_ADD_SUBSCRIPTION_SUCCESS_ALERT_MESSAGE,
+ linkUrl: INTEGRATIONS_DOC_LINK,
+ variant: 'success',
+ });
- dispatch('fetchSubscriptions', subscriptionsPath);
- } catch (e) {
- commit(ADD_SUBSCRIPTION_ERROR, e);
- } finally {
- commit(ADD_SUBSCRIPTION_LOADING, false);
- }
+ dispatch('fetchSubscriptions', subscriptionsPath);
};
diff --git a/app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js b/app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js
index d4893fbcaf6..63aad27aeb6 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/store/mutation_types.js
@@ -4,9 +4,6 @@ export const SET_SUBSCRIPTIONS = 'SET_SUBSCRIPTIONS';
export const SET_SUBSCRIPTIONS_LOADING = 'SET_SUBSCRIPTIONS_LOADING';
export const SET_SUBSCRIPTIONS_ERROR = 'SET_SUBSCRIPTIONS_ERROR';
-export const ADD_SUBSCRIPTION_LOADING = 'ADD_SUBSCRIPTION_LOADING';
-export const ADD_SUBSCRIPTION_ERROR = 'ADD_SUBSCRIPTION_ERROR';
-
export const SET_CURRENT_USER = 'SET_CURRENT_USER';
export const SET_CURRENT_USER_ERROR = 'SET_CURRENT_USER_ERROR';
diff --git a/app/assets/javascripts/jira_connect/subscriptions/store/mutations.js b/app/assets/javascripts/jira_connect/subscriptions/store/mutations.js
index 60076c918fd..270ce9fab66 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/store/mutations.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/store/mutations.js
@@ -3,8 +3,6 @@ import {
SET_SUBSCRIPTIONS,
SET_SUBSCRIPTIONS_LOADING,
SET_SUBSCRIPTIONS_ERROR,
- ADD_SUBSCRIPTION_LOADING,
- ADD_SUBSCRIPTION_ERROR,
SET_CURRENT_USER,
SET_CURRENT_USER_ERROR,
SET_ACCESS_TOKEN,
@@ -25,13 +23,6 @@ export default {
state.subscriptionsError = subscriptionsError;
},
- [ADD_SUBSCRIPTION_LOADING](state, loading) {
- state.addSubscriptionLoading = loading;
- },
- [ADD_SUBSCRIPTION_ERROR](state, error) {
- state.addSubscriptionError = error;
- },
-
[SET_CURRENT_USER](state, currentUser) {
state.currentUser = currentUser;
},
diff --git a/app/assets/javascripts/jira_connect/subscriptions/store/state.js b/app/assets/javascripts/jira_connect/subscriptions/store/state.js
index 82a8517b511..f35f79e3f53 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/store/state.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/store/state.js
@@ -10,9 +10,6 @@ export default function createState({
subscriptionsLoading,
subscriptionsError: false,
- addSubscriptionLoading: false,
- addSubscriptionError: false,
-
currentUser,
currentUserError: null,
diff --git a/app/assets/javascripts/jira_connect/subscriptions/utils.js b/app/assets/javascripts/jira_connect/subscriptions/utils.js
index 6db8b62d692..0b88e83f8da 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/utils.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/utils.js
@@ -1,5 +1,4 @@
import AccessorUtilities from '~/lib/utils/accessor';
-import { objectToQuery } from '~/lib/utils/url_utility';
import { ALERT_LOCALSTORAGE_KEY, BASE_URL_LOCALSTORAGE_KEY } from './constants';
const isFunction = (fn) => typeof fn === 'function';
@@ -76,18 +75,6 @@ export const getJwt = () => {
});
};
-export const getLocation = () => {
- return new Promise((resolve) => {
- if (isFunction(AP?.getLocation)) {
- AP.getLocation((location) => {
- resolve(location);
- });
- } else {
- resolve();
- }
- });
-};
-
export const reloadPage = () => {
if (isFunction(AP?.navigator?.reload)) {
AP.navigator.reload();
@@ -101,17 +88,3 @@ export const sizeToParent = () => {
AP.sizeToParent();
}
};
-
-export const getGitlabSignInURL = async (signInURL) => {
- const location = await getLocation();
-
- if (location) {
- const queryParams = {
- return_to: location,
- };
-
- return `${signInURL}?${objectToQuery(queryParams)}`;
- }
-
- return signInURL;
-};
diff --git a/app/assets/javascripts/notes/components/discussion_filter.vue b/app/assets/javascripts/notes/components/discussion_filter.vue
index 21b48a2a666..692fd6cc500 100644
--- a/app/assets/javascripts/notes/components/discussion_filter.vue
+++ b/app/assets/javascripts/notes/components/discussion_filter.vue
@@ -1,5 +1,10 @@
<script>
-import { GlDropdown, GlDropdownItem, GlDropdownDivider } from '@gitlab/ui';
+import {
+ GlIcon,
+ GlDisclosureDropdown,
+ GlDisclosureDropdownGroup,
+ GlDisclosureDropdownItem,
+} from '@gitlab/ui';
import { mapGetters, mapActions } from 'vuex';
import { getLocationHash, doesHashExistInUrl } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
@@ -25,9 +30,10 @@ const SORT_OPTIONS = [
export default {
SORT_OPTIONS,
components: {
- GlDropdown,
- GlDropdownItem,
- GlDropdownDivider,
+ GlIcon,
+ GlDisclosureDropdown,
+ GlDisclosureDropdownGroup,
+ GlDisclosureDropdownItem,
LocalStorageSync,
},
mixins: [Tracking.mixin()],
@@ -164,44 +170,64 @@ export default {
as-string
@input="setDiscussionSortDirection({ direction: $event })"
/>
- <gl-dropdown
+ <gl-disclosure-dropdown
id="discussion-preferences-dropdown"
class="full-width-mobile"
data-qa-selector="discussion_preferences_dropdown"
- :text="__('Sort or filter')"
+ :toggle-text="__('Sort or filter')"
:disabled="isLoading"
- right
+ placement="right"
>
- <div id="discussion-sort">
- <gl-dropdown-item
+ <gl-disclosure-dropdown-group id="discussion-sort">
+ <gl-disclosure-dropdown-item
v-for="{ text, key, cls } in $options.SORT_OPTIONS"
:key="text"
:class="cls"
- is-check-item
- :is-checked="isSortDropdownItemActive(key)"
- @click="fetchSortedDiscussions(key)"
+ :is-selected="isSortDropdownItemActive(key)"
+ @action="fetchSortedDiscussions(key)"
>
- {{ text }}
- </gl-dropdown-item>
- </div>
- <gl-dropdown-divider />
- <div
+ <template #list-item>
+ <gl-icon
+ name="mobile-issue-close"
+ data-testid="dropdown-item-checkbox"
+ :class="[
+ 'gl-dropdown-item-check-icon',
+ { 'gl-visibility-hidden': !isSortDropdownItemActive(key) },
+ 'gl-text-blue-400',
+ ]"
+ />
+ {{ text }}
+ </template>
+ </gl-disclosure-dropdown-item>
+ </gl-disclosure-dropdown-group>
+ <gl-disclosure-dropdown-group
id="discussion-filter"
class="discussion-filter-container js-discussion-filter-container"
+ bordered
>
- <gl-dropdown-item
+ <gl-disclosure-dropdown-item
v-for="filter in filters"
:key="filter.value"
- is-check-item
- :is-checked="filter.value === currentValue"
+ :is-selected="filter.value === currentValue"
:class="{ 'is-active': filter.value === currentValue }"
:data-filter-type="filterType(filter.value)"
data-qa-selector="filter_menu_item"
- @click.prevent="selectFilter(filter.value)"
+ @action="selectFilter(filter.value)"
>
- {{ filter.title }}
- </gl-dropdown-item>
- </div>
- </gl-dropdown>
+ <template #list-item>
+ <gl-icon
+ name="mobile-issue-close"
+ data-testid="dropdown-item-checkbox"
+ :class="[
+ 'gl-dropdown-item-check-icon',
+ { 'gl-visibility-hidden': filter.value !== currentValue },
+ 'gl-text-blue-400',
+ ]"
+ />
+ {{ filter.title }}
+ </template>
+ </gl-disclosure-dropdown-item>
+ </gl-disclosure-dropdown-group>
+ </gl-disclosure-dropdown>
</div>
</template>
diff --git a/app/assets/javascripts/pages/jira_connect/oauth_callbacks/index.js b/app/assets/javascripts/pages/jira_connect/oauth_callbacks/index.js
index 3fe238dcb35..6e92f136e4d 100644
--- a/app/assets/javascripts/pages/jira_connect/oauth_callbacks/index.js
+++ b/app/assets/javascripts/pages/jira_connect/oauth_callbacks/index.js
@@ -1,3 +1,5 @@
+import { OAUTH_CALLBACK_MESSAGE_TYPE } from '~/jira_connect/subscriptions/constants';
+
function getOriginURL() {
const origin = new URL(window.opener.location);
origin.hash = '';
@@ -7,7 +9,10 @@ function getOriginURL() {
}
function postMessageToJiraConnectApp(data) {
- window.opener.postMessage(data, getOriginURL().toString());
+ window.opener.postMessage(
+ { ...data, type: OAUTH_CALLBACK_MESSAGE_TYPE },
+ getOriginURL().toString(),
+ );
}
function initOAuthCallbacks() {
diff --git a/app/assets/javascripts/related_issues/components/related_issues_list.vue b/app/assets/javascripts/related_issues/components/related_issues_list.vue
index 4429c1beb00..6a047ff7e9d 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_list.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_list.vue
@@ -146,6 +146,7 @@ export default {
:work-item-type="issue.type"
event-namespace="relatedIssue"
data-qa-selector="related_issuable_content"
+ class="gl-mx-n2"
@relatedIssueRemoveRequest="$emit('relatedIssueRemoveRequest', $event)"
/>
</li>
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index d033a076832..febb597e26e 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -474,7 +474,8 @@ li.note {
width: 100%;
> .dropdown-menu,
- > .btn {
+ > .btn,
+ > .gl-new-dropdown-toggle > .gl-button-text {
width: 100%;
}
}
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 96d78034ad6..dff1c04311d 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -22,17 +22,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:preferences, :update, :reset_health_check_token
]
- feature_category :metrics, [
- :create_self_monitoring_project,
- :status_create_self_monitoring_project,
- :delete_self_monitoring_project,
- :status_delete_self_monitoring_project
- ]
urgency :low, [
- :create_self_monitoring_project,
- :status_create_self_monitoring_project,
- :delete_self_monitoring_project,
- :status_delete_self_monitoring_project,
:reset_error_tracking_access_token
]
@@ -124,91 +114,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
redirect_to ::Gitlab::LetsEncrypt.terms_of_service_url
end
- # Specs are in spec/requests/self_monitoring_project_spec.rb
- def create_self_monitoring_project
- job_id = SelfMonitoringProjectCreateWorker.with_status.perform_async # rubocop:disable CodeReuse/Worker
-
- render status: :accepted, json: {
- job_id: job_id,
- monitor_status: status_create_self_monitoring_project_admin_application_settings_path
- }
- end
-
- # Specs are in spec/requests/self_monitoring_project_spec.rb
- def status_create_self_monitoring_project
- job_id = params[:job_id].to_s
-
- unless job_id.length <= PARAM_JOB_ID_MAX_SIZE
- return render status: :bad_request, json: {
- message: format(_('Parameter "job_id" cannot exceed length of %{job_id_max_size}'), job_id_max_size: PARAM_JOB_ID_MAX_SIZE)
- }
- end
-
- if SelfMonitoringProjectCreateWorker.in_progress?(job_id) # rubocop:disable CodeReuse/Worker
- ::Gitlab::PollingInterval.set_header(response, interval: 3_000)
-
- return render status: :accepted, json: {
- message: _('Job to create self-monitoring project is in progress')
- }
- end
-
- return render status: :ok, json: self_monitoring_data if @application_setting.self_monitoring_project_id.present?
-
- render status: :bad_request, json: {
- message: _('Self-monitoring project does not exist. Please check logs ' \
- 'for any error messages')
- }
- end
-
- # Specs are in spec/requests/self_monitoring_project_spec.rb
- def delete_self_monitoring_project
- job_id = SelfMonitoringProjectDeleteWorker.with_status.perform_async # rubocop:disable CodeReuse/Worker
-
- render status: :accepted, json: {
- job_id: job_id,
- monitor_status: status_delete_self_monitoring_project_admin_application_settings_path
- }
- end
-
- # Specs are in spec/requests/self_monitoring_project_spec.rb
- def status_delete_self_monitoring_project
- job_id = params[:job_id].to_s
-
- unless job_id.length <= PARAM_JOB_ID_MAX_SIZE
- return render status: :bad_request, json: {
- message: format(_('Parameter "job_id" cannot exceed length of %{job_id_max_size}'), job_id_max_size: PARAM_JOB_ID_MAX_SIZE)
- }
- end
-
- if SelfMonitoringProjectDeleteWorker.in_progress?(job_id) # rubocop:disable CodeReuse/Worker
- ::Gitlab::PollingInterval.set_header(response, interval: 3_000)
-
- return render status: :accepted, json: {
- message: _('Job to delete self-monitoring project is in progress')
- }
- end
-
- if @application_setting.self_monitoring_project_id.nil?
- return render status: :ok, json: {
- message: _('Self-monitoring project has been successfully deleted')
- }
- end
-
- render status: :bad_request, json: {
- message: _('Self-monitoring project was not deleted. Please check logs ' \
- 'for any error messages')
- }
- end
-
private
- def self_monitoring_data
- {
- project_id: @application_setting.self_monitoring_project_id,
- project_full_path: @application_setting.self_monitoring_project&.full_path
- }
- end
-
def set_application_setting
@application_setting = ApplicationSetting.current_without_cache
@plans = Plan.all
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index a7694c58588..05f679df2c9 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -542,28 +542,6 @@ module ApplicationSettingsHelper
Rack::Attack.throttles.key?('protected paths')
end
- def self_monitoring_project_data
- {
- 'create_self_monitoring_project_path' =>
- create_self_monitoring_project_admin_application_settings_path,
-
- 'status_create_self_monitoring_project_path' =>
- status_create_self_monitoring_project_admin_application_settings_path,
-
- 'delete_self_monitoring_project_path' =>
- delete_self_monitoring_project_admin_application_settings_path,
-
- 'status_delete_self_monitoring_project_path' =>
- status_delete_self_monitoring_project_admin_application_settings_path,
-
- 'self_monitoring_project_exists' =>
- Gitlab::CurrentSettings.self_monitoring_project.present?.to_s,
-
- 'self_monitoring_project_full_path' =>
- Gitlab::CurrentSettings.self_monitoring_project&.full_path
- }
- end
-
def valid_runner_registrars
Gitlab::CurrentSettings.valid_runner_registrars
end
diff --git a/app/helpers/jira_connect_helper.rb b/app/helpers/jira_connect_helper.rb
index af2c09554f0..5cf68db0611 100644
--- a/app/helpers/jira_connect_helper.rb
+++ b/app/helpers/jira_connect_helper.rb
@@ -7,9 +7,7 @@ module JiraConnectHelper
{
groups_path: api_v4_groups_path(params: { min_access_level: Gitlab::Access::MAINTAINER, skip_groups: skip_groups }),
subscriptions: subscriptions.map { |s| serialize_subscription(s) }.to_json,
- add_subscriptions_path: jira_connect_subscriptions_path,
subscriptions_path: jira_connect_subscriptions_path(format: :json),
- users_path: current_user ? nil : jira_connect_users_path, # users_path is used to determine if user is signed in
gitlab_user_path: current_user ? user_path(current_user) : nil,
oauth_metadata: jira_connect_oauth_data(installation).to_json,
public_key_storage_enabled: Gitlab::CurrentSettings.jira_connect_public_key_storage_enabled?
diff --git a/app/services/metrics/dashboard/clone_dashboard_service.rb b/app/services/metrics/dashboard/clone_dashboard_service.rb
index d9bd9423a1b..18623ad336d 100644
--- a/app/services/metrics/dashboard/clone_dashboard_service.rb
+++ b/app/services/metrics/dashboard/clone_dashboard_service.rb
@@ -16,10 +16,6 @@ module Metrics
::Gitlab::Metrics::Dashboard::Stages::CustomMetricsInserter
].freeze,
- ::Metrics::Dashboard::SelfMonitoringDashboardService::DASHBOARD_PATH => [
- ::Gitlab::Metrics::Dashboard::Stages::CustomMetricsInserter
- ].freeze,
-
::Metrics::Dashboard::ClusterDashboardService::DASHBOARD_PATH => [
::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter
].freeze
diff --git a/config/routes/admin.rb b/config/routes/admin.rb
index 0ebf13ac8d0..6130f7c2fe2 100644
--- a/config/routes/admin.rb
+++ b/config/routes/admin.rb
@@ -156,11 +156,6 @@ namespace :admin do
match :general, :integrations, :repository, :ci_cd, :reporting, :metrics_and_profiling, :network, :preferences, via: [:get, :patch]
get :lets_encrypt_terms_of_service
- post :create_self_monitoring_project
- get :status_create_self_monitoring_project
- delete :delete_self_monitoring_project
- get :status_delete_self_monitoring_project
-
get :service_usage_data
resource :appearances, only: [:show, :create, :update], path: 'appearance', module: 'application_settings' do
diff --git a/doc/user/application_security/secret_detection/post_processing.md b/doc/user/application_security/secret_detection/post_processing.md
index 3657e3cd024..a898a63e33b 100644
--- a/doc/user/application_security/secret_detection/post_processing.md
+++ b/doc/user/application_security/secret_detection/post_processing.md
@@ -4,26 +4,24 @@ group: Static Analysis
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
-# Secret Detection post-processing and revocation **(ULTIMATE)**
+# Automatic response to leaked secrets **(ULTIMATE)**
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4639) in GitLab 13.6.
-> - [Disabled by default for GitLab personal access tokens](https://gitlab.com/gitlab-org/gitlab/-/issues/371658) in GitLab 15.6 [with a flag](../../../administration/feature_flags.md) named `gitlab_pat_auto_revocation`. Available to GitLab.com only.
-> - [Enabled by default for GitLab personal access tokens](https://gitlab.com/gitlab-org/gitlab/-/issues/371658) in GitLab 15.9
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4639) in GitLab 13.6.
-GitLab.com and self-managed supports running post-processing hooks after detecting a secret. These
-hooks can perform actions, like notifying the vendor that issued the secret.
-The vendor can then confirm the credentials and take remediation actions, like:
+GitLab Secret Detection automatically responds when it finds certain types of leaked secrets.
+Automatic responses can:
-- Revoking a secret.
-- Reissuing a secret.
-- Notifying the creator of the secret.
+- Automatically revoke the secret.
+- Notify the partner that issued the secret. The partner can then revoke the secret, notify its owner, or otherwise protect against abuse.
-GitLab supports post-processing for the following vendors and secrets:
+## Supported secret types and actions
-| Vendor | Secret | GitLab.com | Self-managed |
+GitLab supports automatic response for the following types of secrets:
+
+| Secret type | Action taken | Supported on GitLab.com | Supported in self-managed |
| ----- | --- | --- | --- |
-| GitLab | [Personal access tokens](../../profile/personal_access_tokens.md) | ✅ | ✅ 15.9 and later |
-| Amazon Web Services (AWS) | [IAM access keys](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) | ✅ | ⚙ |
+| GitLab [Personal access tokens](../../profile/personal_access_tokens.md) | Immediately revoke token, send email to owner | ✅ | ✅ [15.9 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/371658) |
+| Amazon Web Services (AWS) [IAM access keys](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) | Notify AWS | ✅ | ⚙ |
**Component legend**
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb
index f77169f6d2b..57caf1b07e6 100644
--- a/lib/gitlab/database.rb
+++ b/lib/gitlab/database.rb
@@ -35,7 +35,7 @@ module Gitlab
MAX_TEXT_SIZE_LIMIT = 1_000_000
# Migrations before this version may have been removed
- MIN_SCHEMA_GITLAB_VERSION = '15.0'
+ MIN_SCHEMA_GITLAB_VERSION = '15.11'
# Schema we store dynamically managed partitions in (e.g. for time partitioning)
DYNAMIC_PARTITIONS_SCHEMA = :gitlab_partitions_dynamic
diff --git a/lib/gitlab/metrics/dashboard/finder.rb b/lib/gitlab/metrics/dashboard/finder.rb
index a4964ae0ebc..12f7c347b2d 100644
--- a/lib/gitlab/metrics/dashboard/finder.rb
+++ b/lib/gitlab/metrics/dashboard/finder.rb
@@ -64,7 +64,7 @@ module Gitlab
# display_name: String,
# default: Boolean }]
def find_all_paths(project)
- dashboards = user_facing_dashboard_services(project).flat_map do |service|
+ dashboards = user_facing_dashboard_services.flat_map do |service|
service.all_dashboard_paths(project)
end
@@ -73,19 +73,8 @@ module Gitlab
private
- def user_facing_dashboard_services(project)
- predefined_dashboard_services_for(project) + [project_service]
- end
-
- def predefined_dashboard_services_for(project)
- # Only list the self-monitoring dashboard on the self-monitoring project,
- # since it is the only dashboard (at time of writing) that shows data
- # about GitLab itself.
- if project.self_monitoring?
- return [self_monitoring_service]
- end
-
- PREDEFINED_DASHBOARD_LIST
+ def user_facing_dashboard_services
+ PREDEFINED_DASHBOARD_LIST + [project_service]
end
def system_service
@@ -96,10 +85,6 @@ module Gitlab
::Metrics::Dashboard::CustomDashboardService
end
- def self_monitoring_service
- ::Metrics::Dashboard::SelfMonitoringDashboardService
- end
-
def service_for(options)
Gitlab::Metrics::Dashboard::ServiceSelector.call(options)
end
diff --git a/lib/gitlab/metrics/dashboard/service_selector.rb b/lib/gitlab/metrics/dashboard/service_selector.rb
index 6d4b49676e5..67bf4ce7e9a 100644
--- a/lib/gitlab/metrics/dashboard/service_selector.rb
+++ b/lib/gitlab/metrics/dashboard/service_selector.rb
@@ -23,7 +23,6 @@ module Gitlab
::Metrics::Dashboard::DefaultEmbedService,
::Metrics::Dashboard::SystemDashboardService,
::Metrics::Dashboard::PodDashboardService,
- ::Metrics::Dashboard::SelfMonitoringDashboardService,
::Metrics::Dashboard::CustomDashboardService
].freeze
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ed0a33684c1..9815086b073 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -25041,12 +25041,6 @@ msgstr ""
msgid "Job logs and artifacts"
msgstr ""
-msgid "Job to create self-monitoring project is in progress"
-msgstr ""
-
-msgid "Job to delete self-monitoring project is in progress"
-msgstr ""
-
msgid "Job was retried"
msgstr ""
@@ -31727,9 +31721,6 @@ msgstr ""
msgid "Parameter"
msgstr ""
-msgid "Parameter \"job_id\" cannot exceed length of %{job_id_max_size}"
-msgstr ""
-
msgid "Parent"
msgstr ""
@@ -40821,15 +40812,6 @@ msgstr ""
msgid "Self-monitoring project does not exist"
msgstr ""
-msgid "Self-monitoring project does not exist. Please check logs for any error messages"
-msgstr ""
-
-msgid "Self-monitoring project has been successfully deleted"
-msgstr ""
-
-msgid "Self-monitoring project was not deleted. Please check logs for any error messages"
-msgstr ""
-
msgid "Self-monitoring was %{deprecation}deprecated%{link_end} in GitLab 14.9, and is %{removal}scheduled for removal%{link_end} in GitLab 16.0. For information on a possible replacement, %{opstrace}learn more about Opstrace%{link_end}."
msgstr ""
diff --git a/spec/features/issues/user_sorts_issue_comments_spec.rb b/spec/features/issues/user_sorts_issue_comments_spec.rb
index ca52e620ea7..153066343f2 100644
--- a/spec/features/issues/user_sorts_issue_comments_spec.rb
+++ b/spec/features/issues/user_sorts_issue_comments_spec.rb
@@ -16,9 +16,8 @@ RSpec.describe 'Comment sort direction', feature_category: :team_planning do
it 'saves sort order' do
# open dropdown, and select 'Newest first'
page.within('.issuable-details') do
- find('#discussion-preferences-dropdown').click
+ click_button('Sort or filter')
click_button('Oldest first')
- find('#discussion-preferences-dropdown').click
click_button('Newest first')
end
diff --git a/spec/frontend/bootstrap_linked_tabs_spec.js b/spec/frontend/bootstrap_linked_tabs_spec.js
index 5ee1ca32141..f900cd9da3b 100644
--- a/spec/frontend/bootstrap_linked_tabs_spec.js
+++ b/spec/frontend/bootstrap_linked_tabs_spec.js
@@ -1,9 +1,10 @@
-import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
+import htmlLinkedTabs from 'test_fixtures_static/linked_tabs.html';
+import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import LinkedTabs from '~/lib/utils/bootstrap_linked_tabs';
describe('Linked Tabs', () => {
beforeEach(() => {
- loadHTMLFixture('static/linked_tabs.html');
+ setHTMLFixture(htmlLinkedTabs);
});
afterEach(() => {
diff --git a/spec/frontend/jira_connect/subscriptions/api_spec.js b/spec/frontend/jira_connect/subscriptions/api_spec.js
index 5a28c6d9789..36e2c7bbab2 100644
--- a/spec/frontend/jira_connect/subscriptions/api_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/api_spec.js
@@ -1,7 +1,6 @@
import MockAdapter from 'axios-mock-adapter';
import {
axiosInstance,
- addSubscription,
removeSubscription,
fetchGroups,
getCurrentUser,
@@ -19,7 +18,6 @@ describe('JiraConnect API', () => {
let axiosMock;
let response;
- const mockAddPath = 'addPath';
const mockRemovePath = 'removePath';
const mockNamespace = 'namespace';
const mockJwt = 'jwt';
@@ -36,29 +34,6 @@ describe('JiraConnect API', () => {
response = null;
});
- describe('addSubscription', () => {
- const makeRequest = () => addSubscription(mockAddPath, mockNamespace);
-
- it('returns success response', async () => {
- jest.spyOn(axiosInstance, 'post');
- axiosMock
- .onPost(mockAddPath, {
- jwt: mockJwt,
- namespace_path: mockNamespace,
- })
- .replyOnce(HTTP_STATUS_OK, mockResponse);
-
- response = await makeRequest();
-
- expect(getJwt).toHaveBeenCalled();
- expect(axiosInstance.post).toHaveBeenCalledWith(mockAddPath, {
- jwt: mockJwt,
- namespace_path: mockNamespace,
- });
- expect(response.data).toEqual(mockResponse);
- });
- });
-
describe('removeSubscription', () => {
const makeRequest = () => removeSubscription(mockRemovePath);
diff --git a/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js b/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js
index 9b54c6d5c49..c5035a12bd1 100644
--- a/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js
@@ -10,8 +10,6 @@ describe('GroupsListItem', () => {
let wrapper;
let store;
- const mockAddSubscriptionsPath = '/addSubscriptionsPath';
-
const createComponent = ({ mountFn = shallowMount, provide } = {}) => {
store = createStore();
@@ -23,7 +21,6 @@ describe('GroupsListItem', () => {
group: mockGroup1,
},
provide: {
- addSubscriptionsPath: mockAddSubscriptionsPath,
...provide,
},
});
diff --git a/spec/frontend/jira_connect/subscriptions/components/sign_in_legacy_button_spec.js b/spec/frontend/jira_connect/subscriptions/components/sign_in_legacy_button_spec.js
deleted file mode 100644
index 0dadec598e4..00000000000
--- a/spec/frontend/jira_connect/subscriptions/components/sign_in_legacy_button_spec.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import { GlButton } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { getGitlabSignInURL } from '~/jira_connect/subscriptions/utils';
-import SignInLegacyButton from '~/jira_connect/subscriptions/components/sign_in_legacy_button.vue';
-import waitForPromises from 'helpers/wait_for_promises';
-
-const MOCK_USERS_PATH = '/user';
-
-jest.mock('~/jira_connect/subscriptions/utils');
-
-describe('SignInLegacyButton', () => {
- let wrapper;
-
- const createComponent = ({ slots } = {}) => {
- wrapper = shallowMount(SignInLegacyButton, {
- propsData: {
- usersPath: MOCK_USERS_PATH,
- },
- slots,
- });
- };
-
- const findButton = () => wrapper.findComponent(GlButton);
-
- it('displays a button', () => {
- createComponent();
-
- expect(findButton().exists()).toBe(true);
- expect(findButton().text()).toBe(SignInLegacyButton.i18n.defaultButtonText);
- });
-
- describe.each`
- expectedHref
- ${MOCK_USERS_PATH}
- ${`${MOCK_USERS_PATH}?return_to=${encodeURIComponent('https://test.jira.com')}`}
- `('when getGitlabSignInURL resolves with `$expectedHref`', ({ expectedHref }) => {
- it(`sets button href to ${expectedHref}`, async () => {
- getGitlabSignInURL.mockResolvedValue(expectedHref);
- createComponent();
-
- await waitForPromises();
-
- expect(findButton().attributes('href')).toBe(expectedHref);
- });
- });
-
- describe('with slot', () => {
- const mockSlotContent = 'custom button content!';
- it('renders slot content in button', () => {
- createComponent({ slots: { default: mockSlotContent } });
- expect(wrapper.text()).toMatchInterpolatedText(mockSlotContent);
- });
- });
-});
diff --git a/spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js b/spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js
index 9d39b82c05f..ee272d55e0e 100644
--- a/spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js
@@ -157,6 +157,7 @@ describe('SignInOauthButton', () => {
const mockEvent = {
origin: messageOrigin,
data: {
+ type: 'jiraConnectOauthCallback',
state: messageState,
code: '1234',
},
@@ -182,6 +183,7 @@ describe('SignInOauthButton', () => {
const mockEvent = {
origin: window.origin,
data: {
+ type: 'jiraConnectOauthCallback',
state: mockOauthMetadata.state,
code: '1234',
},
diff --git a/spec/frontend/jira_connect/subscriptions/components/user_link_spec.js b/spec/frontend/jira_connect/subscriptions/components/user_link_spec.js
index 20cbcda8661..a10e352ed85 100644
--- a/spec/frontend/jira_connect/subscriptions/components/user_link_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/user_link_spec.js
@@ -4,10 +4,6 @@ import SignInOauthButton from '~/jira_connect/subscriptions/components/sign_in_o
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-jest.mock('~/jira_connect/subscriptions/utils', () => ({
- getGitlabSignInURL: jest.fn().mockImplementation((path) => Promise.resolve(path)),
-}));
-
describe('UserLink', () => {
let wrapper;
diff --git a/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_com_spec.js b/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_com_spec.js
index cb9eb5f67f9..4cfd925db34 100644
--- a/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_com_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_com_spec.js
@@ -1,7 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import SignInGitlabCom from '~/jira_connect/subscriptions/pages/sign_in/sign_in_gitlab_com.vue';
-import SignInLegacyButton from '~/jira_connect/subscriptions/components/sign_in_legacy_button.vue';
import SignInOauthButton from '~/jira_connect/subscriptions/components/sign_in_oauth_button.vue';
import SubscriptionsList from '~/jira_connect/subscriptions/components/subscriptions_list.vue';
import createStore from '~/jira_connect/subscriptions/store';
@@ -9,10 +8,8 @@ import { I18N_DEFAULT_SIGN_IN_BUTTON_TEXT } from '~/jira_connect/subscriptions/c
jest.mock('~/jira_connect/subscriptions/utils');
-const mockUsersPath = '/test';
const defaultProvide = {
oauthMetadata: {},
- usersPath: mockUsersPath,
};
describe('SignInGitlabCom', () => {
@@ -32,7 +29,6 @@ describe('SignInGitlabCom', () => {
},
propsData: props,
stubs: {
- SignInLegacyButton,
SignInOauthButton,
},
});
diff --git a/spec/frontend/jira_connect/subscriptions/store/actions_spec.js b/spec/frontend/jira_connect/subscriptions/store/actions_spec.js
index 5e3c30269b5..e53c3e766d2 100644
--- a/spec/frontend/jira_connect/subscriptions/store/actions_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/store/actions_spec.js
@@ -117,7 +117,7 @@ describe('JiraConnect actions', () => {
});
describe('when API request succeeds', () => {
- it('commits the SET_ACCESS_TOKEN and SET_CURRENT_USER mutations', async () => {
+ it('commits the SET_ALERT mutation', async () => {
jest.spyOn(api, 'addJiraConnectSubscription').mockResolvedValue({ success: true });
await testAction(
@@ -125,7 +125,6 @@ describe('JiraConnect actions', () => {
{ namespacePath: mockNamespace, subscriptionsPath: mockSubscriptionsPath },
mockedState,
[
- { type: types.ADD_SUBSCRIPTION_LOADING, payload: true },
{
type: types.SET_ALERT,
payload: {
@@ -135,7 +134,6 @@ describe('JiraConnect actions', () => {
variant: 'success',
},
},
- { type: types.ADD_SUBSCRIPTION_LOADING, payload: false },
],
[{ type: 'fetchSubscriptions', payload: mockSubscriptionsPath }],
);
@@ -148,20 +146,18 @@ describe('JiraConnect actions', () => {
});
describe('when API request fails', () => {
- it('commits the SET_CURRENT_USER_ERROR mutation', async () => {
+ it('does not commit the SET_ALERT mutation', () => {
jest.spyOn(api, 'addJiraConnectSubscription').mockRejectedValue();
- await testAction(
+ // We need the empty catch(), since we are testing rejecting the promise,
+ // which would otherwise cause the test to fail.
+ testAction(
addSubscription,
- mockNamespace,
+ { namespacePath: mockNamespace, subscriptionsPath: mockSubscriptionsPath },
mockedState,
- [
- { type: types.ADD_SUBSCRIPTION_LOADING, payload: true },
- { type: types.ADD_SUBSCRIPTION_ERROR },
- { type: types.ADD_SUBSCRIPTION_LOADING, payload: false },
- ],
[],
- );
+ [],
+ ).catch(() => {});
});
});
});
diff --git a/spec/frontend/jira_connect/subscriptions/store/mutations_spec.js b/spec/frontend/jira_connect/subscriptions/store/mutations_spec.js
index aeb136a76b9..e41bcec19b7 100644
--- a/spec/frontend/jira_connect/subscriptions/store/mutations_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/store/mutations_spec.js
@@ -51,22 +51,6 @@ describe('JiraConnect store mutations', () => {
});
});
- describe('ADD_SUBSCRIPTION_LOADING', () => {
- it('sets addSubscriptionLoading', () => {
- mutations.ADD_SUBSCRIPTION_LOADING(localState, true);
-
- expect(localState.addSubscriptionLoading).toBe(true);
- });
- });
-
- describe('ADD_SUBSCRIPTION_ERROR', () => {
- it('sets addSubscriptionError', () => {
- mutations.ADD_SUBSCRIPTION_ERROR(localState, true);
-
- expect(localState.addSubscriptionError).toBe(true);
- });
- });
-
describe('SET_CURRENT_USER', () => {
it('sets currentUser', () => {
const mockUser = { name: 'root' };
diff --git a/spec/frontend/jira_connect/subscriptions/utils_spec.js b/spec/frontend/jira_connect/subscriptions/utils_spec.js
index 762d9eb3443..d1588dbad2c 100644
--- a/spec/frontend/jira_connect/subscriptions/utils_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/utils_spec.js
@@ -5,10 +5,8 @@ import {
persistAlert,
retrieveAlert,
getJwt,
- getLocation,
reloadPage,
sizeToParent,
- getGitlabSignInURL,
} from '~/jira_connect/subscriptions/utils';
describe('JiraConnect utils', () => {
@@ -69,29 +67,6 @@ describe('JiraConnect utils', () => {
});
});
- describe('getLocation', () => {
- const mockLocation = 'test/location';
- const getLocationSpy = jest.fn((callback) => callback(mockLocation));
-
- it('resolves to the function call when AP.getLocation is a function', async () => {
- global.AP = {
- getLocation: getLocationSpy,
- };
-
- const location = await getLocation();
-
- expect(getLocationSpy).toHaveBeenCalled();
- expect(location).toBe(mockLocation);
- });
-
- it('resolves to undefined when AP.getLocation is not a function', async () => {
- const location = await getLocation();
-
- expect(getLocationSpy).not.toHaveBeenCalled();
- expect(location).toBeUndefined();
- });
- });
-
describe('reloadPage', () => {
const reloadSpy = jest.fn();
@@ -138,25 +113,4 @@ describe('JiraConnect utils', () => {
});
});
});
-
- describe('getGitlabSignInURL', () => {
- const mockSignInURL = 'https://gitlab.com/sign_in';
-
- it.each`
- returnTo | expectResult
- ${undefined} | ${mockSignInURL}
- ${''} | ${mockSignInURL}
- ${'/test/location'} | ${`${mockSignInURL}?return_to=${encodeURIComponent('/test/location')}`}
- `(
- 'returns `$expectResult` when `AP.getLocation` resolves to `$returnTo`',
- async ({ returnTo, expectResult }) => {
- global.AP = {
- getLocation: jest.fn().mockImplementation((cb) => cb(returnTo)),
- };
-
- const url = await getGitlabSignInURL(mockSignInURL);
- expect(url).toBe(expectResult);
- },
- );
- });
});
diff --git a/spec/frontend/merge_request_spec.js b/spec/frontend/merge_request_spec.js
index be16b5ebfd2..6f80f8e6aab 100644
--- a/spec/frontend/merge_request_spec.js
+++ b/spec/frontend/merge_request_spec.js
@@ -1,6 +1,8 @@
import MockAdapter from 'axios-mock-adapter';
import $ from 'jquery';
-import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
+import htmlMergeRequestWithTaskList from 'test_fixtures/merge_requests/merge_request_with_task_list.html';
+import htmlMergeRequestOfCurrentUser from 'test_fixtures/merge_requests/merge_request_of_current_user.html';
+import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import { TEST_HOST } from 'spec/test_constants';
import waitForPromises from 'helpers/wait_for_promises';
import { createAlert } from '~/alert';
@@ -16,7 +18,7 @@ describe('MergeRequest', () => {
let mock;
beforeEach(() => {
- loadHTMLFixture('merge_requests/merge_request_with_task_list.html');
+ setHTMLFixture(htmlMergeRequestWithTaskList);
jest.spyOn(axios, 'patch');
mock = new MockAdapter(axios);
@@ -112,7 +114,7 @@ describe('MergeRequest', () => {
describe('hideCloseButton', () => {
describe('merge request of current_user', () => {
beforeEach(() => {
- loadHTMLFixture('merge_requests/merge_request_of_current_user.html');
+ setHTMLFixture(htmlMergeRequestOfCurrentUser);
test.el = document.querySelector('.js-issuable-actions');
MergeRequest.hideCloseButton();
});
diff --git a/spec/frontend/notes/components/discussion_filter_spec.js b/spec/frontend/notes/components/discussion_filter_spec.js
index 28e5e65c177..7d8347b20d4 100644
--- a/spec/frontend/notes/components/discussion_filter_spec.js
+++ b/spec/frontend/notes/components/discussion_filter_spec.js
@@ -1,4 +1,4 @@
-import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { GlDisclosureDropdown, GlDisclosureDropdownItem } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import AxiosMockAdapter from 'axios-mock-adapter';
@@ -34,7 +34,8 @@ describe('DiscussionFilter component', () => {
const filterDiscussion = jest.fn();
const findFilter = (filterType) =>
- wrapper.find(`.dropdown-item[data-filter-type="${filterType}"]`);
+ wrapper.find(`.gl-new-dropdown-item[data-filter-type="${filterType}"]`);
+ const findGlDisclosureDropdownItem = () => wrapper.findComponent(GlDisclosureDropdownItem);
const findLocalStorageSync = () => wrapper.findComponent(LocalStorageSync);
@@ -109,7 +110,7 @@ describe('DiscussionFilter component', () => {
describe('when the dropdown is clicked', () => {
it('calls the right actions', () => {
- wrapper.find('.js-newest-first').vm.$emit('click');
+ wrapper.find('.js-newest-first').vm.$emit('action');
expect(store.dispatch).toHaveBeenCalledWith('setDiscussionSortDirection', {
direction: DESC,
@@ -130,7 +131,7 @@ describe('DiscussionFilter component', () => {
describe('when the dropdown item is clicked', () => {
it('calls the right actions', () => {
- wrapper.find('.js-oldest-first').vm.$emit('click');
+ wrapper.find('.js-oldest-first').vm.$emit('action');
expect(store.dispatch).toHaveBeenCalledWith('setDiscussionSortDirection', {
direction: ASC,
@@ -140,8 +141,8 @@ describe('DiscussionFilter component', () => {
});
});
- it('sets is-checked to true on the active button in the dropdown', () => {
- expect(wrapper.find('.js-newest-first').props('isChecked')).toBe(true);
+ it('sets is-selected to true on the active button in the dropdown', () => {
+ expect(findGlDisclosureDropdownItem().attributes('is-selected')).toBe('true');
});
});
});
@@ -152,13 +153,13 @@ describe('DiscussionFilter component', () => {
});
it('renders the all filters', () => {
- expect(wrapper.findAll('.discussion-filter-container .dropdown-item').length).toBe(
+ expect(wrapper.findAll('.discussion-filter-container .gl-new-dropdown-item').length).toBe(
discussionFiltersMock.length,
);
});
it('renders the default selected item', () => {
- expect(wrapper.find('.discussion-filter-container .dropdown-item').text().trim()).toBe(
+ expect(wrapper.find('.discussion-filter-container .gl-new-dropdown-item').text().trim()).toBe(
discussionFiltersMock[0].title,
);
});
@@ -166,19 +167,19 @@ describe('DiscussionFilter component', () => {
it('disables the dropdown when discussions are loading', () => {
store.state.isLoading = true;
- expect(wrapper.findComponent(GlDropdown).props('disabled')).toBe(true);
+ expect(wrapper.findComponent(GlDisclosureDropdown).props('disabled')).toBe(true);
});
it('updates to the selected item', () => {
const filterItem = findFilter(DISCUSSION_FILTER_TYPES.ALL);
- filterItem.trigger('click');
+ filterItem.vm.$emit('action');
expect(filterItem.text().trim()).toBe('Show all activity');
});
it('only updates when selected filter changes', () => {
- findFilter(DISCUSSION_FILTER_TYPES.ALL).trigger('click');
+ findFilter(DISCUSSION_FILTER_TYPES.ALL).vm.$emit('action');
expect(filterDiscussion).not.toHaveBeenCalled();
});
@@ -186,19 +187,19 @@ describe('DiscussionFilter component', () => {
it('disables timeline view if it was enabled', () => {
store.state.isTimelineEnabled = true;
- findFilter(DISCUSSION_FILTER_TYPES.HISTORY).trigger('click');
+ findFilter(DISCUSSION_FILTER_TYPES.HISTORY).vm.$emit('action');
expect(store.state.isTimelineEnabled).toBe(false);
});
it('disables commenting when "Show history only" filter is applied', () => {
- findFilter(DISCUSSION_FILTER_TYPES.HISTORY).trigger('click');
+ findFilter(DISCUSSION_FILTER_TYPES.HISTORY).vm.$emit('action');
expect(store.state.commentsDisabled).toBe(true);
});
it('enables commenting when "Show history only" filter is not applied', () => {
- findFilter(DISCUSSION_FILTER_TYPES.ALL).trigger('click');
+ findFilter(DISCUSSION_FILTER_TYPES.ALL).vm.$emit('action');
expect(store.state.commentsDisabled).toBe(false);
});
@@ -229,7 +230,7 @@ describe('DiscussionFilter component', () => {
});
describe('URL with Links to notes', () => {
- const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+ const findGlDisclosureDropdownItems = () => wrapper.findAllComponents(GlDisclosureDropdownItem);
afterEach(() => {
window.location.hash = '';
@@ -240,7 +241,7 @@ describe('DiscussionFilter component', () => {
wrapper = mountComponent();
await nextTick();
- const filtered = findDropdownItems().filter((el) => el.classes('is-active'));
+ const filtered = findGlDisclosureDropdownItems().filter((el) => el.classes('is-active'));
expect(filtered).toHaveLength(1);
expect(filtered.at(0).text()).toBe(discussionFiltersMock[0].title);
@@ -251,7 +252,7 @@ describe('DiscussionFilter component', () => {
wrapper = mountComponent();
await nextTick();
- const filtered = findDropdownItems().filter((el) => el.classes('is-active'));
+ const filtered = findGlDisclosureDropdownItems().filter((el) => el.classes('is-active'));
expect(filtered).toHaveLength(1);
expect(filtered.at(0).text()).toBe(discussionFiltersMock[0].title);
diff --git a/spec/frontend/settings_panels_spec.js b/spec/frontend/settings_panels_spec.js
index d59e1a20b27..1ef91181e1d 100644
--- a/spec/frontend/settings_panels_spec.js
+++ b/spec/frontend/settings_panels_spec.js
@@ -1,10 +1,11 @@
import $ from 'jquery';
-import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
+import htmlGroupsEdit from 'test_fixtures/groups/edit.html';
+import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import initSettingsPanels, { isExpanded } from '~/settings_panels';
describe('Settings Panels', () => {
beforeEach(() => {
- loadHTMLFixture('groups/edit.html');
+ setHTMLFixture(htmlGroupsEdit);
});
afterEach(() => {
diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb
index 93db4661c82..91be16b6aea 100644
--- a/spec/helpers/application_settings_helper_spec.rb
+++ b/spec/helpers/application_settings_helper_spec.rb
@@ -98,70 +98,6 @@ RSpec.describe ApplicationSettingsHelper do
end
end
- describe '.self_monitoring_project_data' do
- context 'when self-monitoring project does not exist' do
- it 'returns create_self_monitoring_project_path' do
- expect(helper.self_monitoring_project_data).to include(
- 'create_self_monitoring_project_path' =>
- create_self_monitoring_project_admin_application_settings_path
- )
- end
-
- it 'returns status_create_self_monitoring_project_path' do
- expect(helper.self_monitoring_project_data).to include(
- 'status_create_self_monitoring_project_path' =>
- status_create_self_monitoring_project_admin_application_settings_path
- )
- end
-
- it 'returns delete_self_monitoring_project_path' do
- expect(helper.self_monitoring_project_data).to include(
- 'delete_self_monitoring_project_path' =>
- delete_self_monitoring_project_admin_application_settings_path
- )
- end
-
- it 'returns status_delete_self_monitoring_project_path' do
- expect(helper.self_monitoring_project_data).to include(
- 'status_delete_self_monitoring_project_path' =>
- status_delete_self_monitoring_project_admin_application_settings_path
- )
- end
-
- it 'returns self_monitoring_project_exists false' do
- expect(helper.self_monitoring_project_data).to include(
- 'self_monitoring_project_exists' => "false"
- )
- end
-
- it 'returns nil for project full_path' do
- expect(helper.self_monitoring_project_data).to include(
- 'self_monitoring_project_full_path' => nil
- )
- end
- end
-
- context 'when self-monitoring project exists' do
- let(:project) { build(:project) }
-
- before do
- stub_application_setting(self_monitoring_project: project)
- end
-
- it 'returns self_monitoring_project_exists true' do
- expect(helper.self_monitoring_project_data).to include(
- 'self_monitoring_project_exists' => "true"
- )
- end
-
- it 'returns project full_path' do
- expect(helper.self_monitoring_project_data).to include(
- 'self_monitoring_project_full_path' => project.full_path
- )
- end
- end
- end
-
describe '#storage_weights' do
let(:application_setting) { build(:application_setting) }
diff --git a/spec/helpers/jira_connect_helper_spec.rb b/spec/helpers/jira_connect_helper_spec.rb
index 454e4bf3fda..b7c25320a0e 100644
--- a/spec/helpers/jira_connect_helper_spec.rb
+++ b/spec/helpers/jira_connect_helper_spec.rb
@@ -27,18 +27,12 @@ RSpec.describe JiraConnectHelper, feature_category: :integrations do
it 'includes Jira Connect app attributes' do
is_expected.to include(
:groups_path,
- :add_subscriptions_path,
:subscriptions_path,
- :users_path,
:subscriptions,
:gitlab_user_path
)
end
- it 'assigns users_path with value' do
- expect(subject[:users_path]).to eq(jira_connect_users_path)
- end
-
context 'with oauth_metadata' do
let(:oauth_metadata) { helper.jira_connect_app_data([subscription], installation)[:oauth_metadata] }
diff --git a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb b/spec/lib/gitlab/metrics/dashboard/finder_spec.rb
index f922eff2980..d3cb9760052 100644
--- a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/finder_spec.rb
@@ -44,12 +44,6 @@ RSpec.describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store
it_behaves_like 'valid dashboard service response'
end
- context 'when the self-monitoring dashboard is specified' do
- let(:dashboard_path) { self_monitoring_dashboard_path }
-
- it_behaves_like 'valid dashboard service response'
- end
-
context 'when no dashboard is specified' do
let(:service_call) { described_class.find(project, user, environment: environment) }
@@ -180,36 +174,5 @@ RSpec.describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store
expect(all_dashboard_paths).to eq([project_dashboard2, k8s_pod_health_dashboard, project_dashboard1, system_dashboard])
end
end
-
- context 'when the project is self-monitoring' do
- let(:self_monitoring_dashboard) do
- {
- path: self_monitoring_dashboard_path,
- display_name: 'Overview',
- default: true,
- system_dashboard: true,
- out_of_the_box_dashboard: true
- }
- end
-
- let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
- let(:project) { project_with_dashboard(dashboard_path) }
-
- before do
- stub_application_setting(self_monitoring_project_id: project.id)
- end
-
- it 'includes self-monitoring and project dashboards' do
- project_dashboard = {
- path: dashboard_path,
- display_name: 'test.yml',
- default: false,
- system_dashboard: false,
- out_of_the_box_dashboard: false
- }
-
- expect(all_dashboard_paths).to eq([self_monitoring_dashboard, project_dashboard])
- end
- end
end
end
diff --git a/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb b/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb
index b41b51f53c3..343596af5cf 100644
--- a/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/service_selector_spec.rb
@@ -30,12 +30,6 @@ RSpec.describe Gitlab::Metrics::Dashboard::ServiceSelector do
end
end
- context 'when the path is for the self-monitoring dashboard' do
- let(:arguments) { { dashboard_path: self_monitoring_dashboard_path } }
-
- it { is_expected.to be Metrics::Dashboard::SelfMonitoringDashboardService }
- end
-
context 'when the embedded flag is provided' do
let(:arguments) { { embedded: true } }
diff --git a/spec/requests/self_monitoring_project_spec.rb b/spec/requests/self_monitoring_project_spec.rb
deleted file mode 100644
index ce4dd10a52d..00000000000
--- a/spec/requests/self_monitoring_project_spec.rb
+++ /dev/null
@@ -1,213 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Self-Monitoring project requests', feature_category: :projects do
- let(:admin) { create(:admin) }
-
- describe 'POST #create_self_monitoring_project' do
- let(:worker_class) { SelfMonitoringProjectCreateWorker }
-
- subject { post create_self_monitoring_project_admin_application_settings_path }
-
- it_behaves_like 'not accessible to non-admin users'
-
- context 'with admin user', :enable_admin_mode do
- before do
- login_as(admin)
- end
-
- context 'when the self-monitoring project is created' do
- let(:status_api) { status_create_self_monitoring_project_admin_application_settings_path }
-
- it_behaves_like 'triggers async worker, returns sidekiq job_id with response accepted'
- end
- end
- end
-
- describe 'GET #status_create_self_monitoring_project' do
- let(:worker_class) { SelfMonitoringProjectCreateWorker }
- let(:job_id) { 'job_id' }
-
- subject do
- get status_create_self_monitoring_project_admin_application_settings_path,
- params: { job_id: job_id }
- end
-
- it_behaves_like 'not accessible to non-admin users'
-
- context 'with admin user', :enable_admin_mode do
- before do
- login_as(admin)
- end
-
- context 'when the self-monitoring project is being created' do
- it_behaves_like 'handles invalid job_id'
-
- context 'when job is in progress' do
- before do
- allow(worker_class).to receive(:in_progress?)
- .with(job_id)
- .and_return(true)
- end
-
- it_behaves_like 'sets polling header and returns accepted' do
- let(:in_progress_message) { 'Job to create self-monitoring project is in progress' }
- end
- end
-
- context 'when self-monitoring project and job do not exist' do
- let(:job_id) { nil }
-
- it 'returns bad_request' do
- create(:application_setting)
-
- subject
-
- aggregate_failures do
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response).to eq(
- 'message' => 'Self-monitoring project does not exist. Please check logs ' \
- 'for any error messages'
- )
- end
- end
- end
-
- context 'when self-monitoring project exists' do
- let(:project) { create(:project) }
-
- before do
- create(:application_setting, self_monitoring_project_id: project.id)
- end
-
- it 'does not need job_id' do
- get status_create_self_monitoring_project_admin_application_settings_path
-
- aggregate_failures do
- expect(response).to have_gitlab_http_status(:success)
- expect(json_response).to eq(
- 'project_id' => project.id,
- 'project_full_path' => project.full_path
- )
- end
- end
-
- it 'returns success with job_id' do
- subject
-
- aggregate_failures do
- expect(response).to have_gitlab_http_status(:success)
- expect(json_response).to eq(
- 'project_id' => project.id,
- 'project_full_path' => project.full_path
- )
- end
- end
- end
- end
- end
- end
-
- describe 'DELETE #delete_self_monitoring_project' do
- let(:worker_class) { SelfMonitoringProjectDeleteWorker }
-
- subject { delete delete_self_monitoring_project_admin_application_settings_path }
-
- it_behaves_like 'not accessible to non-admin users'
-
- context 'with admin user', :enable_admin_mode do
- before do
- login_as(admin)
- end
-
- context 'when the self-monitoring project is deleted' do
- let(:status_api) { status_delete_self_monitoring_project_admin_application_settings_path }
-
- it_behaves_like 'triggers async worker, returns sidekiq job_id with response accepted'
- end
- end
- end
-
- describe 'GET #status_delete_self_monitoring_project' do
- let(:worker_class) { SelfMonitoringProjectDeleteWorker }
- let(:job_id) { 'job_id' }
-
- subject do
- get status_delete_self_monitoring_project_admin_application_settings_path,
- params: { job_id: job_id }
- end
-
- it_behaves_like 'not accessible to non-admin users'
-
- context 'with admin user', :enable_admin_mode do
- before do
- login_as(admin)
- end
-
- context 'when the self-monitoring project is being deleted' do
- it_behaves_like 'handles invalid job_id'
-
- context 'when job is in progress' do
- before do
- allow(worker_class).to receive(:in_progress?)
- .with(job_id)
- .and_return(true)
-
- stub_application_setting(self_monitoring_project_id: 1)
- end
-
- it_behaves_like 'sets polling header and returns accepted' do
- let(:in_progress_message) { 'Job to delete self-monitoring project is in progress' }
- end
- end
-
- context 'when self-monitoring project exists and job does not exist' do
- before do
- create(:application_setting, self_monitoring_project_id: create(:project).id)
- end
-
- it 'returns bad_request' do
- subject
-
- aggregate_failures do
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response).to eq(
- 'message' => 'Self-monitoring project was not deleted. Please check logs ' \
- 'for any error messages'
- )
- end
- end
- end
-
- context 'when self-monitoring project does not exist' do
- before do
- create(:application_setting)
- end
-
- it 'does not need job_id' do
- get status_delete_self_monitoring_project_admin_application_settings_path
-
- aggregate_failures do
- expect(response).to have_gitlab_http_status(:success)
- expect(json_response).to eq(
- 'message' => 'Self-monitoring project has been successfully deleted'
- )
- end
- end
-
- it 'returns success with job_id' do
- subject
-
- aggregate_failures do
- expect(response).to have_gitlab_http_status(:success)
- expect(json_response).to eq(
- 'message' => 'Self-monitoring project has been successfully deleted'
- )
- end
- end
- end
- end
- end
- end
-end
diff --git a/spec/services/metrics/dashboard/clone_dashboard_service_spec.rb b/spec/services/metrics/dashboard/clone_dashboard_service_spec.rb
index 40ec37c393d..bb11b905a7c 100644
--- a/spec/services/metrics/dashboard/clone_dashboard_service_spec.rb
+++ b/spec/services/metrics/dashboard/clone_dashboard_service_spec.rb
@@ -92,10 +92,6 @@ RSpec.describe Metrics::Dashboard::CloneDashboardService, :use_clean_rails_memor
::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter
]
- it_behaves_like 'valid dashboard cloning process',
- ::Metrics::Dashboard::SelfMonitoringDashboardService::DASHBOARD_PATH,
- [::Gitlab::Metrics::Dashboard::Stages::CustomMetricsInserter]
-
context 'selected branch already exists' do
let(:branch) { 'existing_branch' }
diff --git a/spec/services/metrics/dashboard/self_monitoring_dashboard_service_spec.rb b/spec/services/metrics/dashboard/self_monitoring_dashboard_service_spec.rb
index 930789ed701..bc7af95957b 100644
--- a/spec/services/metrics/dashboard/self_monitoring_dashboard_service_spec.rb
+++ b/spec/services/metrics/dashboard/self_monitoring_dashboard_service_spec.rb
@@ -67,12 +67,6 @@ RSpec.describe Metrics::Dashboard::SelfMonitoringDashboardService, :use_clean_ra
it { is_expected.to be_truthy }
end
- context 'with dashboard_path' do
- let(:params) { { dashboard_path: self_monitoring_dashboard_path } }
-
- it { is_expected.to be_truthy }
- end
-
context 'with a different dashboard selected' do
let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
let(:params) { { dashboard_path: dashboard_path, environment: environment } }
diff --git a/spec/support/helpers/metrics_dashboard_helpers.rb b/spec/support/helpers/metrics_dashboard_helpers.rb
index a384e44f428..417baeda33a 100644
--- a/spec/support/helpers/metrics_dashboard_helpers.rb
+++ b/spec/support/helpers/metrics_dashboard_helpers.rb
@@ -49,8 +49,4 @@ module MetricsDashboardHelpers
def business_metric_title
Enums::PrometheusMetric.group_details[:business][:group_title]
end
-
- def self_monitoring_dashboard_path
- Metrics::Dashboard::SelfMonitoringDashboardService::DASHBOARD_PATH
- end
end
diff --git a/spec/tooling/danger/product_intelligence_spec.rb b/spec/tooling/danger/product_intelligence_spec.rb
index c4cd0e5bfb6..bc6b9debfe0 100644
--- a/spec/tooling/danger/product_intelligence_spec.rb
+++ b/spec/tooling/danger/product_intelligence_spec.rb
@@ -32,10 +32,12 @@ RSpec.describe Tooling::Danger::ProductIntelligence do
let(:approved_label) { 'product intelligence::approved' }
let(:changed_files) { ['metrics/counts_7d/test_metric.yml'] }
let(:changed_lines) { ['+tier: ee'] }
+ let(:fake_changes) { instance_double(Gitlab::Dangerfiles::Changes, files: changed_files) }
before do
+ allow(fake_changes).to receive(:by_category).with(:product_intelligence).and_return(fake_changes)
+ allow(fake_helper).to receive(:changes).and_return(fake_changes)
allow(fake_helper).to receive(:all_changed_files).and_return(changed_files)
- allow(fake_helper).to receive(:changes_by_category).and_return(product_intelligence: changed_files, database: ['other_files.yml'])
allow(fake_helper).to receive(:markdown_list).with(changed_files).and_return(markdown_formatted_list)
end
@@ -61,6 +63,15 @@ RSpec.describe Tooling::Danger::ProductIntelligence do
expect(labels_to_add).to match_array [previous_label_to_add, review_pending_label]
end
+
+ it 'receives all the changed files by calling the correct helper method', :aggregate_failures do
+ expect(fake_helper).not_to receive(:changes_by_category)
+ expect(fake_helper).to receive(:changes)
+ expect(fake_changes).to receive(:by_category).with(:product_intelligence)
+ expect(fake_changes).to receive(:files)
+
+ subject
+ end
end
context 'with growth experiment label' do
diff --git a/tooling/danger/product_intelligence.rb b/tooling/danger/product_intelligence.rb
index d25f966504f..00dc31b9bb9 100644
--- a/tooling/danger/product_intelligence.rb
+++ b/tooling/danger/product_intelligence.rb
@@ -33,8 +33,8 @@ module Tooling
].freeze
def check!
- # exit if not matching files or if no product intelligence labels
- product_intelligence_paths_to_review = helper.changes_by_category[:product_intelligence]
+ product_intelligence_paths_to_review = helper.changes.by_category(:product_intelligence).files
+
labels_to_add = missing_labels
return if product_intelligence_paths_to_review.empty? || skip_review?