Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
04f4e68f19
commit
a12e6607e2
|
|
@ -1234,7 +1234,6 @@ RSpec/FeatureCategory:
|
|||
- 'spec/controllers/projects/releases/evidences_controller_spec.rb'
|
||||
- 'spec/controllers/projects/releases_controller_spec.rb'
|
||||
- 'spec/controllers/projects/security/configuration_controller_spec.rb'
|
||||
- 'spec/controllers/projects/service_ping_controller_spec.rb'
|
||||
- 'spec/controllers/projects/settings/merge_requests_controller_spec.rb'
|
||||
- 'spec/controllers/projects/snippets/blobs_controller_spec.rb'
|
||||
- 'spec/controllers/projects/snippets_controller_spec.rb'
|
||||
|
|
@ -3044,7 +3043,6 @@ RSpec/FeatureCategory:
|
|||
- 'spec/lib/gitlab/usage_data_counters/merge_request_widget_extension_counter_spec.rb'
|
||||
- 'spec/lib/gitlab/usage_data_counters/quick_action_activity_unique_counter_spec.rb'
|
||||
- 'spec/lib/gitlab/usage_data_counters/vscode_extension_activity_unique_counter_spec.rb'
|
||||
- 'spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb'
|
||||
- 'spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb'
|
||||
- 'spec/lib/gitlab/usage_data_counters_spec.rb'
|
||||
- 'spec/lib/gitlab/usage_data_non_sql_metrics_spec.rb'
|
||||
|
|
|
|||
|
|
@ -189,7 +189,6 @@ Style/ClassAndModuleChildren:
|
|||
- 'app/controllers/projects/runner_projects_controller.rb'
|
||||
- 'app/controllers/projects/runners_controller.rb'
|
||||
- 'app/controllers/projects/service_desk_controller.rb'
|
||||
- 'app/controllers/projects/service_ping_controller.rb'
|
||||
- 'app/controllers/projects/snippets/application_controller.rb'
|
||||
- 'app/controllers/projects/snippets/blobs_controller.rb'
|
||||
- 'app/controllers/projects/snippets_controller.rb'
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ Style/SendWithLiteralMethodName:
|
|||
- 'lib/sidebars/context.rb'
|
||||
- 'spec/lib/api/entities/ci/runner_manager_spec.rb'
|
||||
- 'spec/lib/gitlab/ci/config/entry/retry_spec.rb'
|
||||
- 'spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb'
|
||||
- 'spec/policies/project_policy_spec.rb'
|
||||
- 'spec/support/helpers/javascript_fixtures_helpers.rb'
|
||||
- 'spec/support/shared_examples/quick_actions/issuable/close_quick_action_shared_examples.rb'
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ export default {
|
|||
return this.searchType === SEARCH_TYPE_ADVANCED;
|
||||
},
|
||||
shouldShowAuthorFilter() {
|
||||
return this.isAdvancedSearch && this.glFeatures.searchMrFilterAuthor;
|
||||
return this.isAdvancedSearch;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import dateFormat from '~/lib/dateformat';
|
|||
import { formatDate, getDayDifference, fallsBefore } from '~/lib/utils/datetime_utility';
|
||||
import { localeDateFormat } from '~/lib/utils/datetime/locale_dateformat';
|
||||
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
||||
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { INSTRUMENT_TODO_ITEM_FOLLOW, TODO_STATE_DONE } from '../constants';
|
||||
import TodoItemTitle from './todo_item_title.vue';
|
||||
import TodoItemBody from './todo_item_body.vue';
|
||||
|
|
@ -28,7 +27,7 @@ export default {
|
|||
TodoItemActions,
|
||||
TodoItemTitleHiddenBySaml,
|
||||
},
|
||||
mixins: [timeagoMixin, glFeatureFlagMixin()],
|
||||
mixins: [timeagoMixin],
|
||||
inject: ['currentTab'],
|
||||
props: {
|
||||
currentUserId: {
|
||||
|
|
@ -51,7 +50,7 @@ export default {
|
|||
return this.todo.state === TODO_STATE_DONE;
|
||||
},
|
||||
isSnoozed() {
|
||||
if (!this.glFeatures.todosSnoozing || this.todo.snoozedUntil == null) {
|
||||
if (this.todo.snoozedUntil == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -59,9 +58,6 @@ export default {
|
|||
return !fallsBefore(snoozedUntil, new Date());
|
||||
},
|
||||
hasReachedSnoozeTimestamp() {
|
||||
if (!this.glFeatures.todosSnoozing) {
|
||||
return false;
|
||||
}
|
||||
return this.todo.snoozedUntil != null && !this.isSnoozed;
|
||||
},
|
||||
targetUrl() {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { GlButton, GlTooltipDirective } from '@gitlab/ui';
|
|||
import { reportToSentry } from '~/ci/utils';
|
||||
import { s__ } from '~/locale';
|
||||
import Tracking from '~/tracking';
|
||||
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { INSTRUMENT_TODO_ITEM_CLICK, TODO_STATE_DONE, TODO_STATE_PENDING } from '../constants';
|
||||
import markAsDoneMutation from './mutations/mark_as_done.mutation.graphql';
|
||||
import markAsPendingMutation from './mutations/mark_as_pending.mutation.graphql';
|
||||
|
|
@ -17,7 +16,7 @@ export default {
|
|||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
mixins: [Tracking.mixin(), glFeatureFlagMixin()],
|
||||
mixins: [Tracking.mixin()],
|
||||
props: {
|
||||
todo: {
|
||||
type: Object,
|
||||
|
|
@ -30,9 +29,6 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
showToggleSnoozed() {
|
||||
if (!this.glFeatures.todosSnoozing) {
|
||||
return false;
|
||||
}
|
||||
return (!this.isSnoozed && this.isPending) || this.isSnoozed;
|
||||
},
|
||||
isDone() {
|
||||
|
|
@ -113,7 +109,6 @@ export default {
|
|||
<template>
|
||||
<div class="gl-flex gl-gap-2">
|
||||
<toggle-snoozed-status
|
||||
v-if="glFeatures.todosSnoozing"
|
||||
:todo="todo"
|
||||
:is-snoozed="isSnoozed"
|
||||
:is-pending="isPending"
|
||||
|
|
|
|||
|
|
@ -13,14 +13,13 @@ import * as Sentry from '~/sentry/sentry_browser_wrapper';
|
|||
import { createAlert } from '~/alert';
|
||||
import { s__ } from '~/locale';
|
||||
import Tracking from '~/tracking';
|
||||
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import {
|
||||
DEFAULT_PAGE_SIZE,
|
||||
getInstrumentTabLabels,
|
||||
INSTRUMENT_TAB_LABELS,
|
||||
INSTRUMENT_TODO_FILTER_CHANGE,
|
||||
getStatusByTab,
|
||||
STATUS_BY_TAB,
|
||||
TODO_WAIT_BEFORE_RELOAD,
|
||||
getTabsIndices,
|
||||
TABS_INDICES,
|
||||
} from '~/todos/constants';
|
||||
import getTodosQuery from './queries/get_todos.query.graphql';
|
||||
import getPendingTodosCount from './queries/get_pending_todos_count.query.graphql';
|
||||
|
|
@ -47,7 +46,7 @@ export default {
|
|||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
mixins: [Tracking.mixin(), glFeatureFlagMixin()],
|
||||
mixins: [Tracking.mixin()],
|
||||
provide() {
|
||||
return {
|
||||
currentTab: computed(() => this.currentTab),
|
||||
|
|
@ -67,7 +66,7 @@ export default {
|
|||
currentUserId: null,
|
||||
pageInfo: {},
|
||||
todos: [],
|
||||
currentTab: getTabsIndices().pending,
|
||||
currentTab: TABS_INDICES.pending,
|
||||
pendingTodosCount: '-',
|
||||
queryFilterValues: {
|
||||
groupId: [],
|
||||
|
|
@ -122,7 +121,7 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
statusByTab() {
|
||||
return getStatusByTab()[this.currentTab];
|
||||
return STATUS_BY_TAB[this.currentTab];
|
||||
},
|
||||
isLoading() {
|
||||
return this.$apollo.queries.todos.loading;
|
||||
|
|
@ -133,13 +132,13 @@ export default {
|
|||
return Object.values(filters).some((value) => value.length > 0);
|
||||
},
|
||||
isOnSnoozedTab() {
|
||||
return this.glFeatures.todosSnoozing && this.currentTab === getTabsIndices().snoozed;
|
||||
return this.currentTab === TABS_INDICES.snoozed;
|
||||
},
|
||||
showEmptyState() {
|
||||
return !this.isLoading && this.todos.length === 0;
|
||||
},
|
||||
showMarkAllAsDone() {
|
||||
return this.currentTab === getTabsIndices().pending && !this.showEmptyState;
|
||||
return this.currentTab === TABS_INDICES.pending && !this.showEmptyState;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
|
@ -147,13 +146,13 @@ export default {
|
|||
const stateFromUrl = searchParams.get('state');
|
||||
switch (stateFromUrl) {
|
||||
case 'snoozed':
|
||||
this.currentTab = getTabsIndices().snoozed;
|
||||
this.currentTab = TABS_INDICES.snoozed;
|
||||
break;
|
||||
case 'done':
|
||||
this.currentTab = getTabsIndices().done;
|
||||
this.currentTab = TABS_INDICES.done;
|
||||
break;
|
||||
case 'all':
|
||||
this.currentTab = getTabsIndices().all;
|
||||
this.currentTab = TABS_INDICES.all;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -179,7 +178,7 @@ export default {
|
|||
}
|
||||
|
||||
this.track(INSTRUMENT_TODO_FILTER_CHANGE, {
|
||||
label: getInstrumentTabLabels()[tabIndex],
|
||||
label: INSTRUMENT_TAB_LABELS[tabIndex],
|
||||
});
|
||||
this.currentTab = tabIndex;
|
||||
|
||||
|
|
@ -194,14 +193,12 @@ export default {
|
|||
},
|
||||
syncActiveTabToUrl() {
|
||||
const tabIndexToUrlStateParam = {
|
||||
[getTabsIndices().done]: 'done',
|
||||
[getTabsIndices().all]: 'all',
|
||||
[TABS_INDICES.snoozed]: 'snoozed',
|
||||
[TABS_INDICES.done]: 'done',
|
||||
[TABS_INDICES.all]: 'all',
|
||||
};
|
||||
if (this.glFeatures.todosSnoozing) {
|
||||
tabIndexToUrlStateParam[getTabsIndices().snoozed] = 'snoozed';
|
||||
}
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
if (this.currentTab === getTabsIndices().pending) {
|
||||
if (this.currentTab === TABS_INDICES.pending) {
|
||||
searchParams.delete('state');
|
||||
} else {
|
||||
searchParams.set('state', tabIndexToUrlStateParam[this.currentTab]);
|
||||
|
|
@ -280,7 +277,7 @@ export default {
|
|||
</gl-badge>
|
||||
</template>
|
||||
</gl-tab>
|
||||
<gl-tab v-if="glFeatures.todosSnoozing">
|
||||
<gl-tab>
|
||||
<template #title>
|
||||
<span>{{ s__('Todos|Snoozed') }}</span>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ import emptyTodosAllDoneSvg from '@gitlab/svgs/dist/illustrations/empty-todos-al
|
|||
import emptyTodosSvg from '@gitlab/svgs/dist/illustrations/empty-todos-md.svg';
|
||||
import { s__ } from '~/locale';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { TODO_EMPTY_TITLE_POOL, getTabsIndices } from '../constants';
|
||||
import { TODO_EMPTY_TITLE_POOL, TABS_INDICES } from '../constants';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -13,7 +12,6 @@ export default {
|
|||
GlLink,
|
||||
GlSprintf,
|
||||
},
|
||||
mixins: [glFeatureFlagMixin()],
|
||||
inject: {
|
||||
currentTab: {
|
||||
type: Number,
|
||||
|
|
@ -54,10 +52,10 @@ export default {
|
|||
return this.$options.emptyTodosAllDoneSvg;
|
||||
},
|
||||
isDoneTab() {
|
||||
return this.currentTab === getTabsIndices().done;
|
||||
return this.currentTab === TABS_INDICES.done;
|
||||
},
|
||||
isSnoozedTab() {
|
||||
return this.glFeatures.todosSnoozing && this.currentTab === getTabsIndices().snoozed;
|
||||
return this.currentTab === TABS_INDICES.snoozed;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -36,25 +36,13 @@ export const TODO_EMPTY_TITLE_POOL = [
|
|||
s__('Todos|Henceforth, you shall be known as "To-Do Destroyer"'),
|
||||
];
|
||||
|
||||
/**
|
||||
* Note: This is a function so we can insert items depending on the todosSnoozing feature flag's state.
|
||||
* When removing the feature flag, this can be converted back to a plain constant. Same goes for a
|
||||
* couple other functions below.
|
||||
*/
|
||||
export const getStatusByTab = () => {
|
||||
const STATUS_BY_TAB = [['pending'], ['done'], ['pending', 'done']];
|
||||
if (gon.features?.todosSnoozing) {
|
||||
STATUS_BY_TAB.splice(1, 0, ['pending']);
|
||||
}
|
||||
return STATUS_BY_TAB;
|
||||
};
|
||||
|
||||
export const getTabsIndices = () => ({
|
||||
export const STATUS_BY_TAB = [['pending'], ['pending'], ['done'], ['pending', 'done']];
|
||||
export const TABS_INDICES = {
|
||||
pending: 0,
|
||||
snoozed: 1,
|
||||
done: gon.features?.todosSnoozing ? 2 : 1,
|
||||
all: gon.features?.todosSnoozing ? 3 : 2,
|
||||
});
|
||||
done: 2,
|
||||
all: 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* Instrumentation
|
||||
|
|
@ -64,13 +52,12 @@ export const INSTRUMENT_TODO_ITEM_FOLLOW = 'follow_todo_link';
|
|||
export const INSTRUMENT_TODO_SORT_CHANGE = 'sort_todo_list';
|
||||
export const INSTRUMENT_TODO_FILTER_CHANGE = 'filter_todo_list';
|
||||
|
||||
export const getInstrumentTabLabels = () => {
|
||||
const INSTRUMENT_TAB_LABELS = ['status_pending', 'status_done', 'status_all'];
|
||||
if (gon.features?.todosSnoozing) {
|
||||
INSTRUMENT_TAB_LABELS.splice(1, 0, 'status_snoozed');
|
||||
}
|
||||
return INSTRUMENT_TAB_LABELS;
|
||||
};
|
||||
export const INSTRUMENT_TAB_LABELS = [
|
||||
'status_pending',
|
||||
'status_snoozed',
|
||||
'status_done',
|
||||
'status_all',
|
||||
];
|
||||
|
||||
export const DEFAULT_PAGE_SIZE = 20;
|
||||
export const TODO_WAIT_BEFORE_RELOAD = 1 * 1000; // 1 second
|
||||
|
|
|
|||
|
|
@ -4,9 +4,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
|
|||
feature_category :notifications
|
||||
urgency :low
|
||||
|
||||
def index
|
||||
push_frontend_feature_flag(:todos_snoozing, current_user)
|
||||
end
|
||||
def index; end
|
||||
|
||||
def destroy
|
||||
todo = current_user.todos.find(params[:id])
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Projects::ServicePingController < Projects::ApplicationController
|
||||
before_action :authenticate_user!
|
||||
|
||||
feature_category :web_ide
|
||||
|
||||
def web_ide_pipelines_count
|
||||
Gitlab::UsageDataCounters::WebIdeCounter.increment_pipelines_count
|
||||
|
||||
head(:ok)
|
||||
end
|
||||
end
|
||||
|
|
@ -38,8 +38,6 @@ class Projects::WebIdeTerminalsController < Projects::ApplicationController
|
|||
current_build = pipeline.builds.last
|
||||
|
||||
if current_build
|
||||
Gitlab::UsageDataCounters::WebIdeCounter.increment_terminals_count
|
||||
|
||||
render_terminal(current_build)
|
||||
else
|
||||
render status: :bad_request, json: pipeline.errors.full_messages
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class TodosFinder
|
|||
items = by_action(items)
|
||||
items = by_author(items)
|
||||
items = by_state(items)
|
||||
items = by_snoozed_status(items) if Feature.enabled?(:todos_snoozing, current_user)
|
||||
items = by_snoozed_status(items)
|
||||
items = by_target_id(items)
|
||||
items = by_types(items)
|
||||
items = by_group(items)
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ module WorkItems
|
|||
created_at: work_item.created_at,
|
||||
updated_at: work_item.updated_at,
|
||||
updated_by: work_item.updated_by,
|
||||
last_edited_at: work_item.last_edited_at,
|
||||
last_edited_by: work_item.last_edited_by,
|
||||
closed_at: work_item.closed_at,
|
||||
closed_by: work_item.closed_by,
|
||||
duplicated_to_id: work_item.duplicated_to_id,
|
||||
|
|
|
|||
|
|
@ -5,12 +5,28 @@ module WorkItems
|
|||
module Widgets
|
||||
class Description < Base
|
||||
def before_create
|
||||
# set description, e.g.
|
||||
# work_item.description = target_work_item.description
|
||||
return unless target_work_item.get_widget(:description)
|
||||
|
||||
# The service returns `description`, `description_html` and also `skip_markdown_cache_validation`.
|
||||
# We need to assign all of those attributes to the target work item.
|
||||
description_params = MarkdownContentRewriterService.new(
|
||||
current_user,
|
||||
work_item,
|
||||
:description,
|
||||
work_item.namespace,
|
||||
target_work_item.namespace
|
||||
).execute
|
||||
|
||||
target_work_item.assign_attributes(
|
||||
description_params.merge(
|
||||
last_edited_at: work_item.last_edited_at,
|
||||
last_edited_by: work_item.last_edited_by
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def post_move_cleanup
|
||||
# do it
|
||||
# Description is a field in the work_item record, it will be removed upon the work_item deletion
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: todos_snoozing
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/17712
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/175163
|
||||
rollout_issue_url:
|
||||
milestone: '17.7'
|
||||
group: group::personal productivity
|
||||
type: wip
|
||||
default_enabled: false
|
||||
|
|
@ -6,7 +6,7 @@ product_group: remote_development
|
|||
product_categories:
|
||||
- web_ide
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: redis
|
||||
instrumentation_class: RedisMetric
|
||||
|
|
@ -24,3 +24,5 @@ tiers:
|
|||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54332
|
||||
milestone_removed: "17.9"
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176298
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ product_group: remote_development
|
|||
product_categories:
|
||||
- web_ide
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: redis
|
||||
instrumentation_class: RedisMetric
|
||||
|
|
@ -24,3 +24,5 @@ tiers:
|
|||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54332
|
||||
milestone_removed: "17.9"
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176298
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ product_group: remote_development
|
|||
product_categories:
|
||||
- web_ide
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: redis
|
||||
instrumentation_class: RedisMetric
|
||||
|
|
@ -24,3 +24,5 @@ tiers:
|
|||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54332
|
||||
milestone_removed: "17.9"
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176298
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ product_group: remote_development
|
|||
product_categories:
|
||||
- web_ide
|
||||
value_type: number
|
||||
status: active
|
||||
status: removed
|
||||
time_frame: all
|
||||
data_source: redis
|
||||
instrumentation_class: RedisMetric
|
||||
|
|
@ -21,3 +21,5 @@ tiers:
|
|||
performance_indicator_type: []
|
||||
milestone: "14.8"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54332
|
||||
milestone_removed: "17.9"
|
||||
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176298
|
||||
|
|
|
|||
|
|
@ -622,10 +622,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
|
|||
end
|
||||
end
|
||||
|
||||
scope :service_ping, controller: :service_ping do
|
||||
post :web_ide_pipelines_count # rubocop:todo Cop/PutProjectRoutesUnderScope
|
||||
end
|
||||
|
||||
resources :web_ide_terminals, path: :ide_terminals, only: [:create, :show], constraints: { id: /\d+/, format: :json } do # rubocop: disable Cop/PutProjectRoutesUnderScope
|
||||
member do
|
||||
post :cancel # rubocop:todo Cop/PutProjectRoutesUnderScope
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
- title: "SAST jobs no longer use global cache settings"
|
||||
removal_milestone: "18.0"
|
||||
announcement_milestone: "17.9"
|
||||
breaking_change: true
|
||||
window: 1
|
||||
reporter: thiagocsf
|
||||
stage: application security testing
|
||||
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/512564
|
||||
impact: medium
|
||||
scope: instance
|
||||
resolution_role: Developer
|
||||
manual_task: true
|
||||
body: | # (required) Don't change this line.
|
||||
In GitLab 18.0, we will update SAST and IaC Scanning to explicitly [disable the use of the CI/CD job cache](https://docs.gitlab.com/ee/ci/caching/#disable-cache-for-specific-jobs) by default.
|
||||
|
||||
This change affects the CI/CD templates for:
|
||||
|
||||
- SAST: `SAST.gitlab-ci.yml`.
|
||||
- IaC Scanning: `SAST-IaC.gitlab-ci.yml`.
|
||||
|
||||
We already updated the `latest` templates `SAST.latest.gitlab-ci.yml` and `SAST-IaC.latest.gitlab-ci.yml`. See [stable and latest templates](https://docs.gitlab.com/ee/user/application_security/sast/#stable-vs-latest-sast-templates) for more details on these template versions.
|
||||
|
||||
The cache directories are not in scope for scanning in most projects, so fetching the cache can cause timeouts or false-positive results.
|
||||
|
||||
If you need to use the cache when scanning a project, you can restore the previous behavior by [overriding](https://docs.gitlab.com/ee/user/application_security/sast/#overriding-sast-jobs) the
|
||||
[`cache`](https://docs.gitlab.com/ee/ci/yaml/#cache) property in the project's CI configuration.
|
||||
|
|
@ -22209,6 +22209,7 @@ The currently authenticated GitLab user.
|
|||
| <a id="currentuserbio"></a>`bio` | [`String`](#string) | Bio of the user. |
|
||||
| <a id="currentuserbot"></a>`bot` | [`Boolean!`](#boolean) | Indicates if the user is a bot. |
|
||||
| <a id="currentusercallouts"></a>`callouts` | [`UserCalloutConnection`](#usercalloutconnection) | User callouts that belong to the user. (see [Connections](#connections)) |
|
||||
| <a id="currentusercodesuggestionscontexts"></a>`codeSuggestionsContexts` **{warning-solid}** | [`[String!]!`](#string) | **Introduced** in GitLab 17.9. **Status**: Experiment. List of additional contexts enabled for Code Suggestions. |
|
||||
| <a id="currentusercommitemail"></a>`commitEmail` | [`String`](#string) | User's default commit email. |
|
||||
| <a id="currentusercreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of when the user was created. |
|
||||
| <a id="currentuserdiscord"></a>`discord` | [`String`](#string) | Discord ID of the user. |
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ Auto Build builds an application using a project's `Dockerfile` if present. If n
|
|||
application into a Docker image. The feature uses the
|
||||
[`pack` command](https://github.com/buildpacks/pack).
|
||||
The default [builder](https://buildpacks.io/docs/for-app-developers/concepts/builder/)
|
||||
is `heroku/buildpacks:18` but a different builder can be selected using
|
||||
is `heroku/buildpacks:22` but a different builder can be selected using
|
||||
the CI/CD variable `AUTO_DEVOPS_BUILD_IMAGE_CNB_BUILDER`.
|
||||
|
||||
Each buildpack requires your project's repository to contain certain files for
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ This window takes place on April 21 - 23, 2025 from 09:00 UTC to 22:00 UTC.
|
|||
| [`maxHoursBeforeTermination` GraphQL field is deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/509787) | Low | Create | Project |
|
||||
| [`RemoteDevelopmentAgentConfig` GraphQL type is deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/509787) | Low | Create | Project |
|
||||
| [`defaultMaxHoursBeforeTermination` and `maxHoursBeforeTerminationLimit` fields are deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/509787) | Low | Create | Project |
|
||||
| [SAST jobs no longer use global cache settings](https://gitlab.com/gitlab-org/gitlab/-/issues/512564) | Medium | Application security testing | Instance |
|
||||
|
||||
## Window 2
|
||||
|
||||
|
|
|
|||
|
|
@ -1252,6 +1252,34 @@ In GitLab 18.0, only the runner registration methods implemented in the new GitL
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### SAST jobs no longer use global cache settings
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
||||
- Announced in GitLab <span class="milestone">17.9</span>
|
||||
- Removal in GitLab <span class="milestone">18.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
|
||||
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/512564).
|
||||
|
||||
</div>
|
||||
|
||||
In GitLab 18.0, we will update SAST and IaC Scanning to explicitly [disable the use of the CI/CD job cache](https://docs.gitlab.com/ee/ci/caching/#disable-cache-for-specific-jobs) by default.
|
||||
|
||||
This change affects the CI/CD templates for:
|
||||
|
||||
- SAST: `SAST.gitlab-ci.yml`.
|
||||
- IaC Scanning: `SAST-IaC.gitlab-ci.yml`.
|
||||
|
||||
We already updated the `latest` templates `SAST.latest.gitlab-ci.yml` and `SAST-IaC.latest.gitlab-ci.yml`. See [stable and latest templates](https://docs.gitlab.com/ee/user/application_security/sast/#stable-vs-latest-sast-templates) for more details on these template versions.
|
||||
|
||||
The cache directories are not in scope for scanning in most projects, so fetching the cache can cause timeouts or false-positive results.
|
||||
|
||||
If you need to use the cache when scanning a project, you can restore the previous behavior by [overriding](https://docs.gitlab.com/ee/user/application_security/sast/#overriding-sast-jobs) the
|
||||
[`cache`](https://docs.gitlab.com/ee/ci/yaml/#cache) property in the project's CI configuration.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Support for REST API endpoints that reset runner registration tokens
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ module Gitlab
|
|||
module UsageDataCounters
|
||||
COUNTERS = [
|
||||
DiffsCounter,
|
||||
WebIdeCounter,
|
||||
MergeRequestWidgetExtensionCounter
|
||||
].freeze
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module UsageDataCounters
|
||||
class WebIdeCounter < BaseCounter
|
||||
KNOWN_EVENTS = %w[commits views merge_requests previews previews_success terminals pipelines].freeze
|
||||
PREFIX = 'web_ide'
|
||||
|
||||
class << self
|
||||
def increment_terminals_count
|
||||
count('terminals')
|
||||
end
|
||||
|
||||
def increment_pipelines_count
|
||||
count('pipelines')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redis_key(event)
|
||||
require_known_event(event)
|
||||
|
||||
"#{prefix}_#{event}_count".upcase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -156,7 +156,7 @@ module QA
|
|||
end
|
||||
|
||||
def running_on_release?
|
||||
gitlab_host.include?('release.gitlab.net') || gitlab_host.include?('release.gke.gitlab.net')
|
||||
gitlab_host.include?('release.gitlab.net')
|
||||
end
|
||||
|
||||
def running_on_dev?
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ module QA
|
|||
#
|
||||
# @return [Boolean]
|
||||
def create_unique_test_user?
|
||||
!Env.running_on_dot_com? && !Env.personal_access_tokens_disabled? && admin_api_client
|
||||
!Env.running_on_live_env? && !Env.personal_access_tokens_disabled? && admin_api_client
|
||||
end
|
||||
|
||||
# Create api client with provided token with fallback to UI creation of token
|
||||
|
|
|
|||
|
|
@ -45,10 +45,10 @@ tests = [
|
|||
|
||||
{
|
||||
explanation: 'https://gitlab.com/gitlab-org/gitlab/-/issues/368628',
|
||||
changed_file: 'lib/gitlab/usage_data_counters/web_ide_counter.rb',
|
||||
changed_file: 'lib/gitlab/usage_data_counters/work_item_activity_unique_counter.rb',
|
||||
expected: %w[
|
||||
spec/lib/gitlab/usage_data_spec.rb
|
||||
spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb
|
||||
spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb
|
||||
]
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Projects::ServicePingController do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
sign_in(user) if user
|
||||
end
|
||||
|
||||
shared_examples 'counter is not increased' do
|
||||
context 'when the user is not authenticated' do
|
||||
let(:user) { nil }
|
||||
|
||||
it 'returns 302' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:found)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user does not have access to the project' do
|
||||
it 'returns 404' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'counter is increased' do |counter|
|
||||
context 'when the authenticated user has access to the project' do
|
||||
let(:user) { project.first_owner }
|
||||
|
||||
it 'increments the usage counter' do
|
||||
expect do
|
||||
subject
|
||||
end.to change { Gitlab::UsageDataCounters::WebIdeCounter.total_count(counter) }.by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #web_ide_pipelines_count' do
|
||||
subject { post :web_ide_pipelines_count, params: { namespace_id: project.namespace, project_id: project } }
|
||||
|
||||
it_behaves_like 'counter is not increased'
|
||||
it_behaves_like 'counter is increased', 'WEB_IDE_PIPELINES_COUNT'
|
||||
end
|
||||
end
|
||||
|
|
@ -167,20 +167,6 @@ RSpec.describe Projects::WebIdeTerminalsController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'increases the web ide terminal counter' do
|
||||
expect(Gitlab::UsageDataCounters::WebIdeCounter).to receive(:increment_terminals_count)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'web ide terminal usage counter' do
|
||||
it 'does not increase', :enable_admin_mode do
|
||||
expect(Gitlab::UsageDataCounters::WebIdeCounter).not_to receive(:increment_terminals_count)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
context 'when branch does not exist' do
|
||||
|
|
@ -192,8 +178,6 @@ RSpec.describe Projects::WebIdeTerminalsController do
|
|||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
|
||||
it_behaves_like 'web ide terminal usage counter'
|
||||
end
|
||||
|
||||
context 'when there is an error creating the job' do
|
||||
|
|
@ -210,8 +194,6 @@ RSpec.describe Projects::WebIdeTerminalsController do
|
|||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
|
||||
it_behaves_like 'web ide terminal usage counter'
|
||||
end
|
||||
|
||||
context 'when the current build is nil' do
|
||||
|
|
@ -229,8 +211,6 @@ RSpec.describe Projects::WebIdeTerminalsController do
|
|||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
|
||||
it_behaves_like 'web ide terminal usage counter'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -230,18 +230,6 @@ RSpec.describe TodosFinder, feature_category: :notifications do
|
|||
|
||||
expect(todos).to match_array([todo2])
|
||||
end
|
||||
|
||||
context 'when todos_snoozing feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(todos_snoozing: false)
|
||||
end
|
||||
|
||||
it 'returns all pending todos' do
|
||||
todos = finder.new(user, { is_snoozed: true }).execute
|
||||
|
||||
expect(todos).to match_array([todo1, todo2, todo3])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'by project' do
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ describe('GlobalSearch MergeRequestsFilters', () => {
|
|||
provide = {
|
||||
glFeatures: {
|
||||
searchMrFilterSourceBranch: true,
|
||||
searchMrFilterAuthor: true,
|
||||
},
|
||||
},
|
||||
) => {
|
||||
|
|
@ -115,16 +114,6 @@ describe('GlobalSearch MergeRequestsFilters', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('When feature flag search_mr_filter_author is disabled', () => {
|
||||
beforeEach(() => {
|
||||
createComponent(null, { glFeatures: { searchMrFilterAuthor: false } });
|
||||
});
|
||||
|
||||
it(`will not render AuthorFilter`, () => {
|
||||
expect(findAuthorFilter().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#hasMissingProjectContext getter', () => {
|
||||
beforeEach(() => {
|
||||
defaultGetters.hasMissingProjectContext = () => false;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ describe('TodoItemActions', () => {
|
|||
},
|
||||
});
|
||||
|
||||
const createComponent = ({ props = {}, todosSnoozingEnabled = true } = {}) => {
|
||||
const createComponent = ({ props = {} } = {}) => {
|
||||
const mockApollo = createMockApollo([
|
||||
[markAsDoneMutation, markAsDoneMutationSuccessHandler],
|
||||
[markAsPendingMutation, markAsPendingMutationSuccessHandler],
|
||||
|
|
@ -49,11 +49,6 @@ describe('TodoItemActions', () => {
|
|||
isSnoozed: false,
|
||||
...props,
|
||||
},
|
||||
provide: {
|
||||
glFeatures: {
|
||||
todosSnoozing: todosSnoozingEnabled,
|
||||
},
|
||||
},
|
||||
mocks: {
|
||||
$toast: {
|
||||
show: mockToastShow,
|
||||
|
|
@ -139,12 +134,4 @@ describe('TodoItemActions', () => {
|
|||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('when the `todosSnoozing` feature flag is disabled', () => {
|
||||
it('never renders the ToggleSnoozedStatus component', () => {
|
||||
createComponent({ todosSnoozingEnabled: false, props: { isSnoozed: false } });
|
||||
|
||||
expect(findToggleSnoozedStatus().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ describe('TodoItem', () => {
|
|||
|
||||
const findTodoItemTimestamp = () => wrapper.findComponent(TodoItemTimestamp);
|
||||
|
||||
const createComponent = (props = {}, todosSnoozingEnabled = true) => {
|
||||
const createComponent = (props = {}) => {
|
||||
wrapper = shallowMount(TodoItem, {
|
||||
propsData: {
|
||||
currentUserId: '1',
|
||||
|
|
@ -35,7 +35,6 @@ describe('TodoItem', () => {
|
|||
},
|
||||
provide: {
|
||||
currentTab: 0,
|
||||
glFeatures: { todosSnoozing: todosSnoozingEnabled },
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
@ -133,36 +132,6 @@ describe('TodoItem', () => {
|
|||
expect(icon.exists()).toBe(true);
|
||||
expect(icon.props('name')).toBe('clock');
|
||||
});
|
||||
|
||||
it('renders the TodoItemTimestamp when the `todosSnoozing` feature flag is disabled and the item is snoozed', () => {
|
||||
createComponent(
|
||||
{
|
||||
todo: {
|
||||
...MR_REVIEW_REQUEST_TODO,
|
||||
snoozedUntil: mockForAnHour,
|
||||
},
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
expect(findTodoItemTimestamp().exists()).toBe(true);
|
||||
expect(wrapper.text()).not.toContain('Snoozed until');
|
||||
});
|
||||
|
||||
it('renders the TodoItemTimestamp when the `todosSnoozing` feature flag is disabled and the item was snoozed', () => {
|
||||
createComponent(
|
||||
{
|
||||
todo: {
|
||||
...MR_REVIEW_REQUEST_TODO,
|
||||
snoozedUntil: mockYesterday,
|
||||
},
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
expect(findTodoItemTimestamp().exists()).toBe(true);
|
||||
expect(wrapper.text()).not.toContain('First sent 4 months ago');
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSnoozed status', () => {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import TodosFilterBar from '~/todos/components/todos_filter_bar.vue';
|
|||
import TodosMarkAllDoneButton from '~/todos/components/todos_mark_all_done_button.vue';
|
||||
import TodosPagination, { CURSOR_CHANGED_EVENT } from '~/todos/components/todos_pagination.vue';
|
||||
import getTodosQuery from '~/todos/components/queries/get_todos.query.graphql';
|
||||
import { getInstrumentTabLabels, getStatusByTab, TODO_WAIT_BEFORE_RELOAD } from '~/todos/constants';
|
||||
import { INSTRUMENT_TAB_LABELS, STATUS_BY_TAB, TODO_WAIT_BEFORE_RELOAD } from '~/todos/constants';
|
||||
import { mockTracking, unmockTracking } from 'jest/__helpers__/tracking_helper';
|
||||
import getPendingTodosCount from '~/todos/components/queries/get_pending_todos_count.query.graphql';
|
||||
import { todosResponse, getPendingTodosCountResponse } from '../mock_data';
|
||||
|
|
@ -28,7 +28,6 @@ describe('TodosApp', () => {
|
|||
const createComponent = ({
|
||||
todosQueryHandler = todosQuerySuccessHandler,
|
||||
todosCountsQueryHandler = todosCountsQuerySuccessHandler,
|
||||
glFeatures = { todosSnoozing: true },
|
||||
} = {}) => {
|
||||
const mockApollo = createMockApollo();
|
||||
mockApollo.defaultClient.setRequestHandler(getTodosQuery, todosQueryHandler);
|
||||
|
|
@ -36,9 +35,6 @@ describe('TodosApp', () => {
|
|||
|
||||
wrapper = shallowMountExtended(TodosApp, {
|
||||
apolloProvider: mockApollo,
|
||||
provide: {
|
||||
glFeatures,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -54,12 +50,8 @@ describe('TodosApp', () => {
|
|||
|
||||
ignoreConsoleMessages([/\[Vue warn\]: \(deprecation TRANSITION_GROUP_ROOT\)/]);
|
||||
|
||||
beforeEach(() => {
|
||||
gon.features = { todosSnoozing: true };
|
||||
});
|
||||
|
||||
it('should have a tracking event for each tab', () => {
|
||||
expect(getStatusByTab().length).toBe(getInstrumentTabLabels().length);
|
||||
expect(STATUS_BY_TAB.length).toBe(INSTRUMENT_TAB_LABELS.length);
|
||||
});
|
||||
|
||||
it('shows a loading state while fetching todos', () => {
|
||||
|
|
|
|||
|
|
@ -3,16 +3,12 @@ import emptyTodosAllDoneSvg from '@gitlab/svgs/dist/illustrations/empty-todos-al
|
|||
import emptyTodosSvg from '@gitlab/svgs/dist/illustrations/empty-todos-md.svg';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import TodosEmptyState from '~/todos/components/todos_empty_state.vue';
|
||||
import { TODO_EMPTY_TITLE_POOL, getTabsIndices } from '~/todos/constants';
|
||||
import { TODO_EMPTY_TITLE_POOL, TABS_INDICES } from '~/todos/constants';
|
||||
|
||||
describe('TodosEmptyState', () => {
|
||||
let wrapper;
|
||||
|
||||
const createComponent = (
|
||||
props = {},
|
||||
currentTab = getTabsIndices().pending,
|
||||
todosSnoozingEnabled = true,
|
||||
) => {
|
||||
const createComponent = (props = {}, currentTab = TABS_INDICES.pending) => {
|
||||
wrapper = shallowMountExtended(TodosEmptyState, {
|
||||
propsData: {
|
||||
isFiltered: false,
|
||||
|
|
@ -22,9 +18,6 @@ describe('TodosEmptyState', () => {
|
|||
issuesDashboardPath: '/dashboard/issues',
|
||||
mergeRequestsDashboardPath: '/dashboard/merge_requests',
|
||||
currentTab,
|
||||
glFeatures: {
|
||||
todosSnoozing: todosSnoozingEnabled,
|
||||
},
|
||||
},
|
||||
stubs: {
|
||||
GlSprintf,
|
||||
|
|
@ -34,10 +27,6 @@ describe('TodosEmptyState', () => {
|
|||
|
||||
const findDocLink = () => wrapper.findByTestId('doc-link');
|
||||
|
||||
beforeEach(() => {
|
||||
gon.features = { todosSnoozing: true };
|
||||
});
|
||||
|
||||
it('renders the empty state component', () => {
|
||||
createComponent();
|
||||
expect(wrapper.findComponent(GlEmptyState).exists()).toBe(true);
|
||||
|
|
@ -96,7 +85,7 @@ describe('TodosEmptyState', () => {
|
|||
|
||||
describe('when on "Snoozed" tab', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ isFiltered: false }, getTabsIndices().snoozed);
|
||||
createComponent({ isFiltered: false }, TABS_INDICES.snoozed);
|
||||
});
|
||||
|
||||
it('renders the correct title', () => {
|
||||
|
|
@ -118,7 +107,7 @@ describe('TodosEmptyState', () => {
|
|||
|
||||
describe('when on "Done" tab', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ isFiltered: false }, getTabsIndices().done);
|
||||
createComponent({ isFiltered: false }, TABS_INDICES.done);
|
||||
});
|
||||
|
||||
it('renders the correct title', () => {
|
||||
|
|
@ -135,20 +124,4 @@ describe('TodosEmptyState', () => {
|
|||
expect(wrapper.findComponent(GlEmptyState).props('svgPath')).toBe(emptyTodosSvg);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the todosSnoozing feature flag is diabled', () => {
|
||||
const todosSnoozingEnabled = false;
|
||||
|
||||
beforeEach(() => {
|
||||
gon.features = { todosSnoozing: todosSnoozingEnabled };
|
||||
});
|
||||
|
||||
it('renders the "Done" tab at the "Snoozed" tab\'s index', () => {
|
||||
createComponent({ isFiltered: false }, getTabsIndices().snoozed, todosSnoozingEnabled);
|
||||
|
||||
expect(wrapper.findComponent(GlEmptyState).props('title')).toBe(
|
||||
'There are no done to-do items yet.',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -133,18 +133,6 @@ RSpec.describe Resolvers::TodosResolver, feature_category: :notifications do
|
|||
|
||||
expect(todos.items).to eq([todo2, todo3])
|
||||
end
|
||||
|
||||
context 'when todos_snoozing feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(todos_snoozing: false)
|
||||
end
|
||||
|
||||
it 'ignores the is_snoozed filter' do
|
||||
todos = resolve_todos(args: { is_snoozed: true, sort: 'CREATED_ASC' }, context: { current_user: new_user })
|
||||
|
||||
expect(todos.items).to eq([todo1, todo2, todo3])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require "fast_spec_helper"
|
||||
|
||||
RSpec.describe Gitlab::Fp::Settings::PublicApi, :web_ide_fast, feature_category: :web_ide do
|
||||
RSpec.describe Gitlab::Fp::Settings::PublicApi, feature_category: :web_ide do
|
||||
let(:settings_module) { Module.new { extend Gitlab::Fp::Settings::PublicApi } }
|
||||
let(:settings_main_class) { double(Class.new) } # rubocop:disable RSpec/VerifiedDoubles -- we want to use 'fast_spec_helper' so we don't want to refer to a concrete class
|
||||
let(:options) { {} }
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::UsageDataCounters::WebIdeCounter, :clean_gitlab_redis_shared_state do
|
||||
shared_examples 'counter examples' do |event|
|
||||
it 'increments counter and return the total count' do
|
||||
expect(described_class.public_send(:total_count, event)).to eq(0)
|
||||
|
||||
2.times { described_class.public_send(:"increment_#{event}_count") }
|
||||
|
||||
redis_key = "web_ide_#{event}_count".upcase
|
||||
expect(described_class.public_send(:total_count, redis_key)).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'terminals counter' do
|
||||
it_behaves_like 'counter examples', 'terminals'
|
||||
end
|
||||
|
||||
describe 'pipelines counter' do
|
||||
it_behaves_like 'counter examples', 'pipelines'
|
||||
end
|
||||
|
||||
describe '.totals' do
|
||||
terminals = 1
|
||||
pipelines = 2
|
||||
|
||||
before do
|
||||
terminals.times { described_class.increment_terminals_count }
|
||||
pipelines.times { described_class.increment_pipelines_count }
|
||||
end
|
||||
|
||||
it 'can report all totals' do
|
||||
expect(described_class.totals).to include(
|
||||
web_ide_terminals: terminals
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -13,10 +13,10 @@ RSpec.describe Gitlab::UsageDataCounters do
|
|||
describe '.count' do
|
||||
subject { described_class.count(event_name) }
|
||||
|
||||
let(:event_name) { 'web_ide_views' }
|
||||
let(:event_name) { 'diff_searches' }
|
||||
|
||||
it 'increases a view counter' do
|
||||
expect(Gitlab::UsageDataCounters::WebIdeCounter).to receive(:count).with('views')
|
||||
it 'increases a searches counter' do
|
||||
expect(Gitlab::UsageDataCounters::DiffsCounter).to receive(:count).with('searches')
|
||||
|
||||
subject
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require "fast_spec_helper"
|
||||
|
||||
RSpec.describe WebIde::Settings::ExtensionsGalleryMetadataGenerator, :web_ide_fast, feature_category: :web_ide do
|
||||
RSpec.describe WebIde::Settings::ExtensionsGalleryMetadataGenerator, feature_category: :web_ide do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
let(:input_context) do
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require "fast_spec_helper"
|
||||
|
||||
RSpec.describe WebIde::Settings::ExtensionsGalleryMetadataValidator, :web_ide_fast, feature_category: :web_ide do
|
||||
RSpec.describe WebIde::Settings::ExtensionsGalleryMetadataValidator, feature_category: :web_ide do
|
||||
include ResultMatchers
|
||||
|
||||
let(:context) do
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require "fast_spec_helper"
|
||||
|
||||
RSpec.describe WebIde::Settings::ExtensionsGalleryValidator, :web_ide_fast, feature_category: :web_ide do
|
||||
RSpec.describe WebIde::Settings::ExtensionsGalleryValidator, feature_category: :web_ide do
|
||||
include ResultMatchers
|
||||
|
||||
let(:service_url) { "https://open-vsx.org/vscode/gallery" }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require "fast_spec_helper"
|
||||
|
||||
RSpec.describe WebIde::Settings::Main, :web_ide_fast, feature_category: :web_ide do
|
||||
RSpec.describe WebIde::Settings::Main, feature_category: :web_ide do
|
||||
let(:settings) { 'some settings' }
|
||||
let(:context_passed_along_steps) { { settings: settings } }
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require "fast_spec_helper"
|
||||
|
||||
RSpec.describe WebIde::Settings::SettingsInitializer, :web_ide_fast, feature_category: :web_ide do
|
||||
RSpec.describe WebIde::Settings::SettingsInitializer, feature_category: :web_ide do
|
||||
let(:all_possible_requested_setting_names) { WebIde::Settings::DefaultSettings.default_settings.keys }
|
||||
let(:context) do
|
||||
{ requested_setting_names: all_possible_requested_setting_names }
|
||||
|
|
|
|||
|
|
@ -950,12 +950,6 @@ RSpec.describe 'project routing', feature_category: :groups_and_projects do
|
|||
end
|
||||
end
|
||||
|
||||
describe Projects::ServicePingController, 'routing' do
|
||||
it 'routes to service_ping#web_ide_pipelines_count' do
|
||||
expect(post('/gitlab/gitlabhq/service_ping/web_ide_pipelines_count')).to route_to('projects/service_ping#web_ide_pipelines_count', namespace_id: 'gitlab', project_id: 'gitlabhq')
|
||||
end
|
||||
end
|
||||
|
||||
describe Projects::EnvironmentsController, 'routing' do
|
||||
describe 'legacy routing' do
|
||||
it_behaves_like 'redirecting a legacy path', "/gitlab/gitlabhq/environments", "/gitlab/gitlabhq/-/environments"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe WorkItems::DataSync::Widgets::Description, feature_category: :team_planning do
|
||||
let_it_be(:current_user) { create(:user) }
|
||||
let_it_be(:last_edited_at) { DateTime.now }
|
||||
let_it_be(:work_item) do
|
||||
create(:work_item, description: "Move weight widget data", last_edited_at: last_edited_at,
|
||||
last_edited_by: current_user)
|
||||
end
|
||||
|
||||
let_it_be(:target_work_item) { create(:work_item) }
|
||||
|
||||
let(:params) { {} }
|
||||
|
||||
subject(:callback) do
|
||||
described_class.new(
|
||||
work_item: work_item, target_work_item: target_work_item, current_user: current_user, params: params
|
||||
)
|
||||
end
|
||||
|
||||
describe '#before_create' do
|
||||
context 'when target work item does not have description widget' do
|
||||
before do
|
||||
allow(target_work_item).to receive(:get_widget).with(:description).and_return(false)
|
||||
end
|
||||
|
||||
it 'does not copy any description data' do
|
||||
expect { callback.before_create }.to not_change { target_work_item.description }
|
||||
.and not_change { target_work_item.description_html }
|
||||
.and not_change { target_work_item.last_edited_at }
|
||||
.and not_change { target_work_item.last_edited_by }
|
||||
end
|
||||
end
|
||||
|
||||
it 'copies all the description data' do
|
||||
expect { callback.before_create }.to change { target_work_item.description }.from(nil).to(work_item.description)
|
||||
.and change { target_work_item.description_html }.from("").to(work_item.description_html)
|
||||
.and change { target_work_item.last_edited_at }.from(nil).to(last_edited_at)
|
||||
.and change { target_work_item.last_edited_by }.from(nil).to(current_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -160,7 +160,6 @@
|
|||
- :use_sql_query_cache
|
||||
- :use_sql_query_cache_for_tracking_db
|
||||
- :uses_fast_spec_helper_but_runs_slow
|
||||
- :web_ide_fast
|
||||
- :with_clean_rails_cache
|
||||
- :with_cloud_connector
|
||||
- :with_current_organization
|
||||
|
|
|
|||
|
|
@ -2629,7 +2629,6 @@
|
|||
- './spec/controllers/projects/releases/evidences_controller_spec.rb'
|
||||
- './spec/controllers/projects/repositories_controller_spec.rb'
|
||||
- './spec/controllers/projects/security/configuration_controller_spec.rb'
|
||||
- './spec/controllers/projects/service_ping_controller_spec.rb'
|
||||
- './spec/controllers/projects/settings/ci_cd_controller_spec.rb'
|
||||
- './spec/controllers/projects/settings/integration_hook_logs_controller_spec.rb'
|
||||
- './spec/controllers/projects/settings/integrations_controller_spec.rb'
|
||||
|
|
@ -5609,7 +5608,6 @@
|
|||
- './spec/lib/gitlab/usage_data_counters/redis_counter_spec.rb'
|
||||
- './spec/lib/gitlab/usage_data_counters_spec.rb'
|
||||
- './spec/lib/gitlab/usage_data_counters/vscode_extension_activity_unique_counter_spec.rb'
|
||||
- './spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb'
|
||||
- './spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb'
|
||||
- './spec/lib/gitlab/usage_data_metrics_spec.rb'
|
||||
- './spec/lib/gitlab/usage_data_non_sql_metrics_spec.rb'
|
||||
|
|
|
|||
Loading…
Reference in New Issue