Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-06-02 15:09:21 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-02 15:09:21 +0300
commitd2eb61914a7ad4667136815d2120a619b6045b58 (patch)
treee1ccb573a1004f8e08230d778d75fec6a4feaa6e
parent9cd5033338348e41c06b09211161a32ed9a8b18a (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/issues/show/components/description.vue3
-rw-r--r--app/assets/javascripts/issues/show/index.js3
-rw-r--r--app/assets/javascripts/work_items/components/work_item_description.vue3
-rw-r--r--app/assets/javascripts/work_items/components/work_item_detail.vue24
-rw-r--r--app/assets/javascripts/work_items/components/work_item_state.vue3
-rw-r--r--app/assets/javascripts/work_items/components/work_item_title.vue4
-rw-r--r--app/assets/javascripts/work_items/components/work_item_weight.vue26
-rw-r--r--app/assets/javascripts/work_items/constants.js3
-rw-r--r--app/assets/javascripts/work_items/graphql/provider.js5
-rw-r--r--app/assets/javascripts/work_items/graphql/typedefs.graphql6
-rw-r--r--app/assets/javascripts/work_items/graphql/work_item.query.graphql4
-rw-r--r--app/assets/javascripts/work_items/index.js4
-rw-r--r--app/controllers/concerns/zuora_csp.rb26
-rw-r--r--app/controllers/projects/issues_controller.rb2
-rw-r--r--app/controllers/projects/pipelines_controller.rb18
-rw-r--r--app/controllers/projects/work_items_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb2
-rw-r--r--app/helpers/work_items_helper.rb10
-rw-r--r--app/views/projects/work_items/index.html.haml2
-rw-r--r--config/feature_flags/development/work_items_mvc_2.yml (renamed from config/feature_flags/development/work_item_assignees.yml)4
-rw-r--r--danger/roulette/Dangerfile31
-rw-r--r--doc/architecture/blueprints/ci_data_decay/index.md16
-rw-r--r--doc/ci/pipelines/settings.md1
-rw-r--r--doc/development/project_templates.md139
-rw-r--r--doc/user/project/working_with_projects.md2
-rw-r--r--qa/tasks/knapsack.rake2
-rw-r--r--spec/features/users/zuora_csp_spec.rb20
-rw-r--r--spec/frontend/issues/show/components/description_spec.js5
-rw-r--r--spec/frontend/work_items/components/work_item_state_spec.js5
-rw-r--r--spec/frontend/work_items/components/work_item_title_spec.js6
-rw-r--r--spec/frontend/work_items/components/work_item_weight_spec.js47
-rw-r--r--spec/frontend/work_items/pages/work_item_detail_spec.js52
32 files changed, 324 insertions, 156 deletions
diff --git a/app/assets/javascripts/issues/show/components/description.vue b/app/assets/javascripts/issues/show/components/description.vue
index a1e83591694..d6ea06d172e 100644
--- a/app/assets/javascripts/issues/show/components/description.vue
+++ b/app/assets/javascripts/issues/show/components/description.vue
@@ -23,6 +23,7 @@ import workItemQuery from '~/work_items/graphql/work_item.query.graphql';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import WorkItemDetailModal from '~/work_items/components/work_item_detail_modal.vue';
+import { TRACKING_CATEGORY_SHOW } from '~/work_items/constants';
import CreateWorkItem from '~/work_items/pages/create_work_item.vue';
import animateMixin from '../mixins/animate';
import { convertDescriptionWithNewSort } from '../utils';
@@ -314,7 +315,7 @@ export default {
this.workItemId = workItemId;
this.updateWorkItemIdUrlQuery(issue);
this.track('viewed_work_item_from_modal', {
- category: 'workItems:show',
+ category: TRACKING_CATEGORY_SHOW,
label: 'work_item_view',
property: `type_${referenceType}`,
});
diff --git a/app/assets/javascripts/issues/show/index.js b/app/assets/javascripts/issues/show/index.js
index 6b0b26ef2e3..3f149e39c4e 100644
--- a/app/assets/javascripts/issues/show/index.js
+++ b/app/assets/javascripts/issues/show/index.js
@@ -83,7 +83,7 @@ export function initIssueApp(issueData, store) {
bootstrapApollo({ ...issueState, issueType: el.dataset.issueType });
- const { canCreateIncident, ...issueProps } = issueData;
+ const { canCreateIncident, hasIssueWeightsFeature, ...issueProps } = issueData;
return new Vue({
el,
@@ -93,6 +93,7 @@ export function initIssueApp(issueData, store) {
provide: {
canCreateIncident,
fullPath,
+ hasIssueWeightsFeature,
},
computed: {
...mapGetters(['getNoteableData']),
diff --git a/app/assets/javascripts/work_items/components/work_item_description.vue b/app/assets/javascripts/work_items/components/work_item_description.vue
index 60ba71e3260..a4118cc48c4 100644
--- a/app/assets/javascripts/work_items/components/work_item_description.vue
+++ b/app/assets/javascripts/work_items/components/work_item_description.vue
@@ -1,6 +1,7 @@
<script>
import { GlSafeHtmlDirective } from '@gitlab/ui';
import Tracking from '~/tracking';
+import { TRACKING_CATEGORY_SHOW } from '../constants';
export default {
directives: {
@@ -21,7 +22,7 @@ export default {
computed: {
tracking() {
return {
- category: 'workItems:show',
+ category: TRACKING_CATEGORY_SHOW,
label: 'item_description',
property: `type_${this.workItem.workItemType.name}`,
};
diff --git a/app/assets/javascripts/work_items/components/work_item_detail.vue b/app/assets/javascripts/work_items/components/work_item_detail.vue
index a512f87c00a..82ef907bb70 100644
--- a/app/assets/javascripts/work_items/components/work_item_detail.vue
+++ b/app/assets/javascripts/work_items/components/work_item_detail.vue
@@ -1,7 +1,12 @@
<script>
import { GlAlert, GlSkeletonLoader } from '@gitlab/ui';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-import { i18n, WIDGET_TYPE_ASSIGNEE, WIDGET_TYPE_DESCRIPTION } from '../constants';
+import {
+ i18n,
+ WIDGET_TYPE_ASSIGNEE,
+ WIDGET_TYPE_DESCRIPTION,
+ WIDGET_TYPE_WEIGHT,
+} from '../constants';
import workItemQuery from '../graphql/work_item.query.graphql';
import workItemTitleSubscription from '../graphql/work_item_title.subscription.graphql';
import WorkItemActions from './work_item_actions.vue';
@@ -10,6 +15,7 @@ import WorkItemTitle from './work_item_title.vue';
import WorkItemDescription from './work_item_description.vue';
import WorkItemLinks from './work_item_links/work_item_links.vue';
import WorkItemAssignees from './work_item_assignees.vue';
+import WorkItemWeight from './work_item_weight.vue';
export default {
i18n,
@@ -22,6 +28,7 @@ export default {
WorkItemTitle,
WorkItemState,
WorkItemLinks,
+ WorkItemWeight,
},
mixins: [glFeatureFlagMixin()],
props: {
@@ -77,12 +84,15 @@ export default {
workItemDescription() {
return this.workItem?.widgets?.find((widget) => widget.type === WIDGET_TYPE_DESCRIPTION);
},
- workItemAssigneesEnabled() {
- return this.glFeatures.workItemAssignees;
+ workItemsMvc2Enabled() {
+ return this.glFeatures.workItemsMvc2;
},
workItemAssignees() {
return this.workItem?.mockWidgets?.find((widget) => widget.type === WIDGET_TYPE_ASSIGNEE);
},
+ workItemWeight() {
+ return this.workItem?.mockWidgets?.find((widget) => widget.type === WIDGET_TYPE_WEIGHT);
+ },
},
};
</script>
@@ -117,10 +127,10 @@ export default {
@error="error = $event"
/>
</div>
- <work-item-assignees
- v-if="workItemAssigneesEnabled && workItemAssignees"
- :assignees="workItemAssignees.nodes"
- />
+ <template v-if="workItemsMvc2Enabled">
+ <work-item-assignees v-if="workItemAssignees" :assignees="workItemAssignees.nodes" />
+ <work-item-weight v-if="workItemWeight" :weight="workItemWeight.weight" />
+ </template>
<work-item-state
:work-item="workItem"
@error="error = $event"
diff --git a/app/assets/javascripts/work_items/components/work_item_state.vue b/app/assets/javascripts/work_items/components/work_item_state.vue
index 51db4c804eb..7e506ba748c 100644
--- a/app/assets/javascripts/work_items/components/work_item_state.vue
+++ b/app/assets/javascripts/work_items/components/work_item_state.vue
@@ -7,6 +7,7 @@ import {
STATE_CLOSED,
STATE_EVENT_CLOSE,
STATE_EVENT_REOPEN,
+ TRACKING_CATEGORY_SHOW,
} from '../constants';
import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql';
import ItemState from './item_state.vue';
@@ -33,7 +34,7 @@ export default {
},
tracking() {
return {
- category: 'workItems:show',
+ category: TRACKING_CATEGORY_SHOW,
label: 'item_state',
property: `type_${this.workItemType}`,
};
diff --git a/app/assets/javascripts/work_items/components/work_item_title.vue b/app/assets/javascripts/work_items/components/work_item_title.vue
index d2e6d3c0bbf..cd5363d36c4 100644
--- a/app/assets/javascripts/work_items/components/work_item_title.vue
+++ b/app/assets/javascripts/work_items/components/work_item_title.vue
@@ -1,6 +1,6 @@
<script>
import Tracking from '~/tracking';
-import { i18n } from '../constants';
+import { i18n, TRACKING_CATEGORY_SHOW } from '../constants';
import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql';
import ItemTitle from './item_title.vue';
@@ -29,7 +29,7 @@ export default {
computed: {
tracking() {
return {
- category: 'workItems:show',
+ category: TRACKING_CATEGORY_SHOW,
label: 'item_title',
property: `type_${this.workItemType}`,
};
diff --git a/app/assets/javascripts/work_items/components/work_item_weight.vue b/app/assets/javascripts/work_items/components/work_item_weight.vue
new file mode 100644
index 00000000000..b0f2b3aa14a
--- /dev/null
+++ b/app/assets/javascripts/work_items/components/work_item_weight.vue
@@ -0,0 +1,26 @@
+<script>
+import { __ } from '~/locale';
+
+export default {
+ inject: ['hasIssueWeightsFeature'],
+ props: {
+ weight: {
+ type: Number,
+ required: false,
+ default: undefined,
+ },
+ },
+ computed: {
+ weightText() {
+ return this.weight ?? __('None');
+ },
+ },
+};
+</script>
+
+<template>
+ <div v-if="hasIssueWeightsFeature" class="gl-mb-5">
+ <span class="gl-display-inline-block gl-font-weight-bold gl-w-15">{{ __('Weight') }}</span>
+ {{ weightText }}
+ </div>
+</template>
diff --git a/app/assets/javascripts/work_items/constants.js b/app/assets/javascripts/work_items/constants.js
index 7e5beafa8db..d3bc314fa58 100644
--- a/app/assets/javascripts/work_items/constants.js
+++ b/app/assets/javascripts/work_items/constants.js
@@ -6,6 +6,8 @@ export const STATE_CLOSED = 'CLOSED';
export const STATE_EVENT_REOPEN = 'REOPEN';
export const STATE_EVENT_CLOSE = 'CLOSE';
+export const TRACKING_CATEGORY_SHOW = 'workItems:show';
+
export const i18n = {
fetchError: s__('WorkItem|Something went wrong when fetching the work item. Please try again.'),
updateError: s__('WorkItem|Something went wrong while updating the work item. Please try again.'),
@@ -15,3 +17,4 @@ export const DEFAULT_MODAL_TYPE = 'Task';
export const WIDGET_TYPE_ASSIGNEE = 'ASSIGNEES';
export const WIDGET_TYPE_DESCRIPTION = 'DESCRIPTION';
+export const WIDGET_TYPE_WEIGHT = 'WEIGHT';
diff --git a/app/assets/javascripts/work_items/graphql/provider.js b/app/assets/javascripts/work_items/graphql/provider.js
index aa30094f345..e393354705b 100644
--- a/app/assets/javascripts/work_items/graphql/provider.js
+++ b/app/assets/javascripts/work_items/graphql/provider.js
@@ -39,6 +39,11 @@ export const temporaryConfig = {
},
],
},
+ {
+ __typename: 'LocalWorkItemWeight',
+ type: 'WEIGHT',
+ weight: 0,
+ },
];
},
},
diff --git a/app/assets/javascripts/work_items/graphql/typedefs.graphql b/app/assets/javascripts/work_items/graphql/typedefs.graphql
index 0e2c8593a04..68a0986f411 100644
--- a/app/assets/javascripts/work_items/graphql/typedefs.graphql
+++ b/app/assets/javascripts/work_items/graphql/typedefs.graphql
@@ -1,5 +1,6 @@
enum LocalWidgetType {
ASSIGNEES
+ WEIGHT
}
interface LocalWorkItemWidget {
@@ -11,6 +12,11 @@ type LocalWorkItemAssignees implements LocalWorkItemWidget {
nodes: [UserCore]
}
+type LocalWorkItemWeight implements LocalWorkItemWidget {
+ type: LocalWidgetType!
+ weight: Int
+}
+
extend type WorkItem {
mockWidgets: [LocalWorkItemWidget]
}
diff --git a/app/assets/javascripts/work_items/graphql/work_item.query.graphql b/app/assets/javascripts/work_items/graphql/work_item.query.graphql
index ff9341c4c0c..30bc61f5c59 100644
--- a/app/assets/javascripts/work_items/graphql/work_item.query.graphql
+++ b/app/assets/javascripts/work_items/graphql/work_item.query.graphql
@@ -14,6 +14,10 @@ query workItem($id: WorkItemID!) {
webUrl
}
}
+ ... on LocalWorkItemWeight {
+ type
+ weight
+ }
}
}
}
diff --git a/app/assets/javascripts/work_items/index.js b/app/assets/javascripts/work_items/index.js
index e39b0d6a353..33e28831b54 100644
--- a/app/assets/javascripts/work_items/index.js
+++ b/app/assets/javascripts/work_items/index.js
@@ -1,11 +1,12 @@
import Vue from 'vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
import App from './components/app.vue';
import { createRouter } from './router';
import { createApolloProvider } from './graphql/provider';
export const initWorkItemsRoot = () => {
const el = document.querySelector('#js-work-items');
- const { fullPath, issuesListPath } = el.dataset;
+ const { fullPath, hasIssueWeightsFeature, issuesListPath } = el.dataset;
return new Vue({
el,
@@ -13,6 +14,7 @@ export const initWorkItemsRoot = () => {
apolloProvider: createApolloProvider(),
provide: {
fullPath,
+ hasIssueWeightsFeature: parseBoolean(hasIssueWeightsFeature),
issuesListPath,
},
render(createElement) {
diff --git a/app/controllers/concerns/zuora_csp.rb b/app/controllers/concerns/zuora_csp.rb
new file mode 100644
index 00000000000..5f9be11d7b9
--- /dev/null
+++ b/app/controllers/concerns/zuora_csp.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module ZuoraCSP
+ extend ActiveSupport::Concern
+
+ ZUORA_URL = 'https://*.zuora.com'
+
+ included do
+ content_security_policy do |policy|
+ next if policy.directives.blank?
+
+ default_script_src = policy.directives['script-src'] || policy.directives['default-src']
+ script_src_values = Array.wrap(default_script_src) | ["'self'", "'unsafe-eval'", ZUORA_URL]
+
+ default_frame_src = policy.directives['frame-src'] || policy.directives['default-src']
+ frame_src_values = Array.wrap(default_frame_src) | ["'self'", ZUORA_URL]
+
+ default_child_src = policy.directives['child-src'] || policy.directives['default-src']
+ child_src_values = Array.wrap(default_child_src) | ["'self'", ZUORA_URL]
+
+ policy.script_src(*script_src_values)
+ policy.frame_src(*frame_src_values)
+ policy.child_src(*child_src_values)
+ end
+ end
+end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index acca85c0bf9..3f4337a5dd9 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -49,7 +49,7 @@ class Projects::IssuesController < Projects::ApplicationController
push_frontend_feature_flag(:paginated_issue_discussions, project)
push_frontend_feature_flag(:realtime_labels, project)
push_force_frontend_feature_flag(:work_items, project&.work_items_feature_flag_enabled?)
- push_frontend_feature_flag(:work_item_assignees)
+ push_frontend_feature_flag(:work_items_mvc_2)
end
around_action :allow_gitaly_ref_name_caching, only: [:discussions]
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index cab055cebca..ac9a9a376dd 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -4,6 +4,7 @@ class Projects::PipelinesController < Projects::ApplicationController
include ::Gitlab::Utils::StrongMemoize
include RedisTracking
include ProjectStatsRefreshConflictsGuard
+ include ZuoraCSP
urgency :low, [
:index, :new, :builds, :show, :failures, :create,
@@ -43,23 +44,6 @@ class Projects::PipelinesController < Projects::ApplicationController
POLLING_INTERVAL = 10_000
- content_security_policy do |policy|
- next if policy.directives.blank?
-
- default_script_src = policy.directives['script-src'] || policy.directives['default-src']
- script_src_values = Array.wrap(default_script_src) | ["'self'", "'unsafe-eval'", 'https://*.zuora.com']
-
- default_frame_src = policy.directives['frame-src'] || policy.directives['default-src']
- frame_src_values = Array.wrap(default_frame_src) | ["'self'", 'https://*.zuora.com']
-
- default_child_src = policy.directives['child-src'] || policy.directives['default-src']
- child_src_values = Array.wrap(default_child_src) | ["'self'", 'https://*.zuora.com']
-
- policy.script_src(*script_src_values)
- policy.frame_src(*frame_src_values)
- policy.child_src(*child_src_values)
- end
-
feature_category :continuous_integration, [
:charts, :show, :config_variables, :stage, :cancel, :retry,
:builds, :dag, :failures, :status,
diff --git a/app/controllers/projects/work_items_controller.rb b/app/controllers/projects/work_items_controller.rb
index 6db83a19d43..ba23af41bb0 100644
--- a/app/controllers/projects/work_items_controller.rb
+++ b/app/controllers/projects/work_items_controller.rb
@@ -3,7 +3,7 @@
class Projects::WorkItemsController < Projects::ApplicationController
before_action do
push_force_frontend_feature_flag(:work_items, project&.work_items_feature_flag_enabled?)
- push_frontend_feature_flag(:work_item_assignees)
+ push_frontend_feature_flag(:work_items_mvc_2)
push_frontend_feature_flag(:work_items_hierarchy, project)
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 5e1d80a4b09..56b919dddba 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -42,7 +42,7 @@ class ProjectsController < Projects::ApplicationController
push_licensed_feature(:file_locks) if @project.present? && @project.licensed_feature_available?(:file_locks)
push_licensed_feature(:security_orchestration_policies) if @project.present? && @project.licensed_feature_available?(:security_orchestration_policies)
push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?)
- push_frontend_feature_flag(:work_item_assignees)
+ push_frontend_feature_flag(:work_items_mvc_2)
push_frontend_feature_flag(:package_registry_access_level)
end
diff --git a/app/helpers/work_items_helper.rb b/app/helpers/work_items_helper.rb
new file mode 100644
index 00000000000..2c61fc20ca8
--- /dev/null
+++ b/app/helpers/work_items_helper.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module WorkItemsHelper
+ def work_items_index_data(project)
+ {
+ full_path: project.full_path,
+ issues_list_path: project_issues_path(project)
+ }
+ end
+end
diff --git a/app/views/projects/work_items/index.html.haml b/app/views/projects/work_items/index.html.haml
index 356f93c6ed5..1f36afc48aa 100644
--- a/app/views/projects/work_items/index.html.haml
+++ b/app/views/projects/work_items/index.html.haml
@@ -1,3 +1,3 @@
- page_title s_('WorkItem|Work Items')
-#js-work-items{ data: { full_path: @project.full_path, issues_list_path: project_issues_path(@project) } }
+#js-work-items{ data: work_items_index_data(@project) }
diff --git a/config/feature_flags/development/work_item_assignees.yml b/config/feature_flags/development/work_items_mvc_2.yml
index 16b4f7c2dd1..871c3d3a82c 100644
--- a/config/feature_flags/development/work_item_assignees.yml
+++ b/config/feature_flags/development/work_items_mvc_2.yml
@@ -1,6 +1,6 @@
---
-name: work_item_assignees
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/88003
+name: work_items_mvc_2
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89028
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/363030
milestone: '15.1'
type: development
diff --git a/danger/roulette/Dangerfile b/danger/roulette/Dangerfile
index ba2d50657e0..527cdf58391 100644
--- a/danger/roulette/Dangerfile
+++ b/danger/roulette/Dangerfile
@@ -60,29 +60,22 @@ NOT_AVAILABLE_TEMPLATES = {
integrations_fe: group_not_available_template('#g_ecosystem_integrations', '@gitlab-org/ecosystem-stage/integrations')
}.freeze
-def note_for_spins_role(spins, role, category)
+def note_for_spin_role(spin, role, category)
template = NOT_AVAILABLE_TEMPLATES[category] || NOT_AVAILABLE_TEMPLATES[:default]
- spins.each do |spin|
- note = note_for_spin_role(spin, role)
+ note =
+ if spin.optional_role == role
+ OPTIONAL_REVIEW_TEMPLATE % { role: role.capitalize, category: helper.label_for_category(spin.category) }
+ else
+ spin.public_send(role)&.markdown_name(author: roulette.team_mr_author) # rubocop:disable GitlabSecurity/PublicSend
+ end
- return note if note
- end
-
- template % { role: role }
-end
-
-def note_for_spin_role(spin, role)
- if spin.optional_role == role
- return OPTIONAL_REVIEW_TEMPLATE % { role: role.capitalize, category: helper.label_for_category(spin.category) }
- end
-
- spin.public_send(role)&.markdown_name(author: roulette.team_mr_author) # rubocop:disable GitlabSecurity/PublicSend
+ note || template % { role: role }
end
-def markdown_row_for_spins(category, spins_array)
- maintainer_note = note_for_spins_role(spins_array, :maintainer, category)
- reviewer_note = note_for_spins_role(spins_array, :reviewer, category)
+def markdown_row_for_spin(category, spin)
+ maintainer_note = note_for_spin_role(spin, :maintainer, category)
+ reviewer_note = note_for_spin_role(spin, :reviewer, category)
"| #{helper.label_for_category(category)} | #{reviewer_note} | #{maintainer_note} |"
end
@@ -115,7 +108,7 @@ if changes.any?
random_roulette_spins = roulette.spin(nil, categories, timezone_experiment: false)
rows = random_roulette_spins.map do |spin|
- markdown_row_for_spins(spin.category, [spin])
+ markdown_row_for_spin(spin.category, spin)
end
markdown(REVIEW_ROULETTE_SECTION)
diff --git a/doc/architecture/blueprints/ci_data_decay/index.md b/doc/architecture/blueprints/ci_data_decay/index.md
index ed202d00700..8808a526df0 100644
--- a/doc/architecture/blueprints/ci_data_decay/index.md
+++ b/doc/architecture/blueprints/ci_data_decay/index.md
@@ -230,6 +230,22 @@ All three tracks can be worked on in parallel:
In progress.
+## Timeline
+
+- 2021-01-21: Parent [CI Scaling](../ci_scale/) blueprint [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52203) created.
+- 2021-04-26: CI Scaling blueprint approved and merged.
+- 2021-09-10: CI/CD data time decay blueprint discussions started.
+- 2022-01-07: CI/CD data time decay blueprint [merged](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70052).
+- 2022-02-01: Blueprint [updated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79110) with new content and links to epics.
+- 2022-02-08: Pipeline partitioning PoC [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80186) started.
+- 2022-02-23: Pipeline partitioning PoC [successful](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80186#note_852704724)
+- 2022-03-07: A way to attach an existing table as a partition [found and proven](https://gitlab.com/gitlab-org/gitlab/-/issues/353380#note_865237214).
+- 2022-03-23: Pipeline partitioning design [Google Doc](https://docs.google.com/document/d/1ARdoTZDy4qLGf6Z1GIHh83-stG_ZLpqsibjKr_OXMgc) started.
+- 2022-03-29: Pipeline partitioning PoC [concluded](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80186#note_892674358).
+- 2022-04-15: Partitioned pipeline data associations PoC [shipped](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84071).
+- 2022-04-30: Additional [benchmarking started](https://gitlab.com/gitlab-org/gitlab/-/issues/361019) to evaluate impact.
+- 2022-06-31: [Pipeline partitioning design](pipeline_partitioning.md) document [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87683) merged.
+
## Who
Proposal:
diff --git a/doc/ci/pipelines/settings.md b/doc/ci/pipelines/settings.md
index 16fbadee2d7..e409b63e098 100644
--- a/doc/ci/pipelines/settings.md
+++ b/doc/ci/pipelines/settings.md
@@ -287,6 +287,7 @@ Use this regex for commonly used test tools.
- .NET (OpenCover). Example: `(Visited Points).*\((.*)\)`.
- .NET (`dotnet test` line coverage). Example: `Total\s*\|\s*(\d+(?:\.\d+)?)`.
- tarpaulin (Rust). Example: `^\d+.\d+% coverage`.
+- Pester (PowerShell). Example: `Covered (\d+\.\d+%)`.
<!-- vale gitlab.Spelling = YES -->
diff --git a/doc/development/project_templates.md b/doc/development/project_templates.md
index 74ded9c93fc..f688d54ad4f 100644
--- a/doc/development/project_templates.md
+++ b/doc/development/project_templates.md
@@ -4,59 +4,56 @@ group: Workspace
info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
---
-# Contribute to GitLab project templates
+# Contribute a built-in project template
-Thanks for considering a contribution to the GitLab
-[built-in project templates](../user/project/working_with_projects.md#create-a-project-from-a-built-in-template).
+This page provides instructions about how to contribute a
+[built-in project template](../user/project/working_with_projects.md#create-a-project-from-a-built-in-template).
+
+To contribute a built-in project template, you must complete the following tasks:
+
+1. [Create a project template for GitLab review](#create-a-project-template-for-review)
+1. [Add the template SVG icon to GitLab SVGs](#add-the-template-svg-icon-to-gitlab-svgs)
+1. [Create a merge request with vendor details](#create-a-merge-request-with-vendor-details)
+
+You can contribute the following types of project templates:
+
+- Enterprise: For users with GitLab Premium and above.
+- Non-enterprise: For users with GitLab Free and above.
## Prerequisites
-To add a new or update an existing template, you must have the following tools
+To add or update an existing template, you must have the following tools
installed:
- `wget`
- `tar`
-- `jq`
-
-## Create a new project
-To contribute a new built-in project template to be distributed with GitLab:
+## Create a project template for review
-1. Create a new public project with the project content you'd like to contribute
- in a namespace of your choosing. You can [view a working example](https://gitlab.com/gitlab-org/project-templates/dotnetcore).
- Projects should be as simple as possible and free of any unnecessary assets or dependencies.
-1. When the project is ready for review, [create a new issue](https://gitlab.com/gitlab-org/gitlab/issues) with a link to your project.
- In your issue, `@` mention the relevant Backend Engineering Manager and Product
- Manager for the [Templates feature](https://about.gitlab.com/handbook/product/categories/#source-code-group).
+1. In your selected namespace, create a public project.
+1. Add the project content you want to use in the template. Do not include unnecessary assets or dependencies. For an example,
+[see this project](https://gitlab.com/gitlab-org/project-templates/dotnetcore).
+1. When the project is ready for review, [create an issue](https://gitlab.com/gitlab-org/gitlab/issues) with a link to your project.
+ In your issue, mention the relevant [Backend Engineering Manager and Product Manager](https://about.gitlab.com/handbook/product/categories/#source-code-group)
+ for the Templates feature.
-## Add the SVG icon to GitLab SVGs
+## Add the template SVG icon to GitLab SVGs
-If the template you're adding has an SVG icon, you need to first add it to
-<https://gitlab.com/gitlab-org/gitlab-svgs>:
+If the project template has an SVG icon, you must add it to the
+[GitLab SVGs project](https://gitlab.com/gitlab-org/gitlab-svgs/-/blob/main/README.md#adding-icons-or-illustrations)
+before you can create a merge request with vendor details.
-1. Follow the steps outlined in the
- [GitLab SVGs project](https://gitlab.com/gitlab-org/gitlab-svgs/-/blob/main/README.md#adding-icons-or-illustrations)
- and submit a merge request.
-1. When the merge request is merged, `gitlab-bot` will pull the new changes in
- the `gitlab-org/gitlab` project.
-1. You can now continue on the vendoring process.
+## Create a merge request with vendor details
-## Vendoring process
-
-To make the project template available when creating a new project, the vendoring
-process will have to be completed:
+Before GitLab can implement the project template, you must [create a merge request](../user/project/merge_requests/creating_merge_requests.md) in [`gitlab-org/gitlab`](https://gitlab.com/gitlab-org/gitlab) that includes vendor details about the project.
1. [Export the project](../user/project/settings/import_export.md#export-a-project-and-its-data)
- you created in the previous step and save the file as `<name>.tar.gz`, where
- `<name>` is the short name of the project.
-1. Edit the following files to include the project template. Two types of built-in
- templates are available within GitLab:
- - **Normal templates**: Available in GitLab Free and above (this is the most common type of built-in template).
- See MR [!25318](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25318) for an example.
-
- To add a normal template:
-
- 1. Open `lib/gitlab/project_template.rb` and add details of the template
+ and save the file as `<name>.tar.gz`, where `<name>` is the short name of the project.
+ Move this file to the root directory of `gitlab-org/gitlab`.
+1. In `gitlab-org/gitlab`, create and checkout a new branch.
+1. Edit the following files to include the project template:
+ - For **non-Enterprise** project templates:
+ - In `lib/gitlab/project_template.rb`, add details about the template
in the `localized_templates_table` method. In the following example,
the short name of the project is `hugo`:
@@ -64,11 +61,11 @@ process will have to be completed:
ProjectTemplate.new('hugo', 'Pages/Hugo', _('Everything you need to create a GitLab Pages site using Hugo'), 'https://gitlab.com/pages/hugo', 'illustrations/logos/hugo.svg'),
```
- If the vendored project doesn't have an SVG icon, omit `, 'illustrations/logos/hugo.svg'`.
+ If the project doesn't have an SVG icon, exclude `, 'illustrations/logos/hugo.svg'`.
- 1. Open `spec/lib/gitlab/project_template_spec.rb` and add the short name
- of the template in the `.all` test.
- 1. Open `app/assets/javascripts/projects/default_project_templates.js` and
+ - In `spec/support/helpers/project_template_test_helper.rb`, append the short name
+ of the template in the `all_templates` method.
+ - In `app/assets/javascripts/projects/default_project_templates.js`,
add details of the template. For example:
```javascript
@@ -78,25 +75,19 @@ process will have to be completed:
},
```
- If the vendored project doesn't have an SVG icon, use `.icon-gitlab_logo`
+ If the project doesn't have an SVG icon, use `.icon-gitlab_logo`
instead.
-
- - **Enterprise templates**: Introduced in GitLab 12.10, that are available only in GitLab Premium and above.
- See MR [!28187](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28187) for an example.
-
- To add an Enterprise template:
-
- 1. Open `ee/lib/ee/gitlab/project_template.rb` and add details of the template
- in the `localized_ee_templates_table` method. For example:
+ - For **Enterprise** project templates:
+ - In `ee/lib/ee/gitlab/project_template.rb`, in the `localized_ee_templates_table` method, add details about the template. For example:
```ruby
::Gitlab::ProjectTemplate.new('hipaa_audit_protocol', 'HIPAA Audit Protocol', _('A project containing issues for each audit inquiry in the HIPAA Audit Protocol published by the U.S. Department of Health & Human Services'), 'https://gitlab.com/gitlab-org/project-templates/hipaa-audit-protocol', 'illustrations/logos/asklepian.svg')
```
- 1. Open `ee/spec/lib/gitlab/project_template_spec.rb` and add the short name
+ - In `ee/spec/lib/gitlab/project_template_spec.rb`, add the short name
of the template in the `.all` test.
- 1. Open `ee/app/assets/javascripts/projects/default_project_templates.js` and
- add details of the template. For example:
+ - In `ee/app/assets/javascripts/projects/default_project_templates.js`,
+ add the template details. For example:
```javascript
hipaa_audit_protocol: {
@@ -105,10 +96,11 @@ process will have to be completed:
},
```
-1. Run the `vendor_template` script. Make sure to pass the correct arguments:
+1. Run the following Rake task, where `<path>/<name>` is the
+ name you gave the template in `lib/gitlab/project_template.rb`:
```shell
- scripts/vendor_template <git_repo_url> <name> <comment>
+ bin/rake gitlab:update_project_templates\[<path>/<name>\]
```
1. Regenerate `gitlab.pot`:
@@ -117,41 +109,24 @@ process will have to be completed:
bin/rake gettext:regenerate
```
-1. By now, there should be one new file under `vendor/project_templates/` and
- 4 changed files. Commit all of them in a new branch and create a merge
- request.
+1. After you run the scripts, there is one new file in `vendor/project_templates/` and four changed files. Commit all changes and push your branch to update the merge request. For an example, see this [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25318).
-## Test with GDK
+## Test your built-in project with the GitLab Development Kit
-If you are using the GitLab Development Kit (GDK) you must disable `praefect`
-and regenerate the Procfile, as the Rake task is not currently compatible with it:
+Complete the following steps to test the project template in your own GitLab Development Kit instance:
-```yaml
-# gitlab-development-kit/gdk.yml
-praefect:
- enabled: false
-```
-
-1. Follow the steps described in the [vendoring process](#vendoring-process).
-1. Run the following Rake task where `<path>/<name>` is the
+1. Run the following Rake task, where `<path>/<name>` is the
name you gave the template in `lib/gitlab/project_template.rb`:
```shell
- bin/rake gitlab:update_project_templates[<path>/<name>]
+ bin/rake gitlab:update_project_templates\[<path>/<name>\]
```
-You can now test to create a new project by importing the new template in GDK.
-
## Contribute an improvement to an existing template
-Existing templates are imported from the following groups:
-
-- [`project-templates`](https://gitlab.com/gitlab-org/project-templates)
-- [`pages`](htps://gitlab.com/pages)
-
-To contribute a change, open a merge request in the relevant project
-and mention `@gitlab-org/manage/import/backend` when you are ready for a review.
+To update an existing built-in project template:
-Then, if your merge request gets accepted, either [open an issue](https://gitlab.com/gitlab-org/gitlab/-/issues)
-to ask for it to get updated, or open a merge request updating
-the [vendored template](#vendoring-process).
+1. Create a merge request in the relevant project of the `project-templates` and `pages` group and mention `@gitlab-org/manage/import/backend` when you are ready for a review.
+1. If your merge request is accepted, either:
+ - [Create an issue](https://gitlab.com/gitlab-org/gitlab/-/issues) to ask for the template to get updated.
+ - [Create a merge request with vendor details](#create-a-merge-request-with-vendor-details) to update the template.
diff --git a/doc/user/project/working_with_projects.md b/doc/user/project/working_with_projects.md
index 87e3c7f3311..c239b28411b 100644
--- a/doc/user/project/working_with_projects.md
+++ b/doc/user/project/working_with_projects.md
@@ -115,7 +115,7 @@ Built-in templates are sourced from the following groups:
- [`project-templates`](https://gitlab.com/gitlab-org/project-templates)
- [`pages`](https://gitlab.com/pages)
-Anyone can contribute a built-in template by following [these steps](https://about.gitlab.com/community/contribute/project-templates/).
+Anyone can [contribute a built-in template](../../development/project_templates.md).
To create a project from a built-in template:
diff --git a/qa/tasks/knapsack.rake b/qa/tasks/knapsack.rake
index 2ffc18eb3d5..fe9a9c4586f 100644
--- a/qa/tasks/knapsack.rake
+++ b/qa/tasks/knapsack.rake
@@ -34,7 +34,7 @@ namespace :knapsack do
desc "Report long running spec files"
task :notify_long_running_specs do
- QA::Support::LongRunningSpecReporter.execute
+ QA::Tools::LongRunningSpecReporter.execute
end
end
# rubocop:enable Rails/RakeEnvironment
diff --git a/spec/features/users/zuora_csp_spec.rb b/spec/features/users/zuora_csp_spec.rb
new file mode 100644
index 00000000000..f3fd27d6495
--- /dev/null
+++ b/spec/features/users/zuora_csp_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Zuora content security policy' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ it 'has proper Content Security Policy headers' do
+ visit pipeline_path(pipeline)
+
+ expect(response_headers['Content-Security-Policy']).to include('https://*.zuora.com')
+ end
+end
diff --git a/spec/frontend/issues/show/components/description_spec.js b/spec/frontend/issues/show/components/description_spec.js
index 1ae04531a6b..2cc27309e59 100644
--- a/spec/frontend/issues/show/components/description_spec.js
+++ b/spec/frontend/issues/show/components/description_spec.js
@@ -17,6 +17,7 @@ import { updateHistory } from '~/lib/utils/url_utility';
import workItemQuery from '~/work_items/graphql/work_item.query.graphql';
import TaskList from '~/task_list';
import WorkItemDetailModal from '~/work_items/components/work_item_detail_modal.vue';
+import { TRACKING_CATEGORY_SHOW } from '~/work_items/constants';
import CreateWorkItem from '~/work_items/pages/create_work_item.vue';
import {
descriptionProps as initialProps,
@@ -370,10 +371,10 @@ describe('Description component', () => {
await findTaskLink().trigger('click');
expect(trackingSpy).toHaveBeenCalledWith(
- 'workItems:show',
+ TRACKING_CATEGORY_SHOW,
'viewed_work_item_from_modal',
{
- category: 'workItems:show',
+ category: TRACKING_CATEGORY_SHOW,
label: 'work_item_view',
property: 'type_task',
},
diff --git a/spec/frontend/work_items/components/work_item_state_spec.js b/spec/frontend/work_items/components/work_item_state_spec.js
index 9e48f56d9e9..0e4b73933b1 100644
--- a/spec/frontend/work_items/components/work_item_state_spec.js
+++ b/spec/frontend/work_items/components/work_item_state_spec.js
@@ -12,6 +12,7 @@ import {
STATE_CLOSED,
STATE_EVENT_CLOSE,
STATE_EVENT_REOPEN,
+ TRACKING_CATEGORY_SHOW,
} from '~/work_items/constants';
import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql';
import { updateWorkItemMutationResponse, workItemQueryResponse } from '../mock_data';
@@ -107,8 +108,8 @@ describe('WorkItemState component', () => {
findItemState().vm.$emit('changed', STATE_CLOSED);
await waitForPromises();
- expect(trackingSpy).toHaveBeenCalledWith('workItems:show', 'updated_state', {
- category: 'workItems:show',
+ expect(trackingSpy).toHaveBeenCalledWith(TRACKING_CATEGORY_SHOW, 'updated_state', {
+ category: TRACKING_CATEGORY_SHOW,
label: 'item_state',
property: 'type_Task',
});
diff --git a/spec/frontend/work_items/components/work_item_title_spec.js b/spec/frontend/work_items/components/work_item_title_spec.js
index 19b56362ac0..168a742090b 100644
--- a/spec/frontend/work_items/components/work_item_title_spec.js
+++ b/spec/frontend/work_items/components/work_item_title_spec.js
@@ -6,7 +6,7 @@ import { mockTracking } from 'helpers/tracking_helper';
import waitForPromises from 'helpers/wait_for_promises';
import ItemTitle from '~/work_items/components/item_title.vue';
import WorkItemTitle from '~/work_items/components/work_item_title.vue';
-import { i18n } from '~/work_items/constants';
+import { i18n, TRACKING_CATEGORY_SHOW } from '~/work_items/constants';
import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql';
import { updateWorkItemMutationResponse, workItemQueryResponse } from '../mock_data';
@@ -91,8 +91,8 @@ describe('WorkItemTitle component', () => {
findItemTitle().vm.$emit('title-changed', 'new title');
await waitForPromises();
- expect(trackingSpy).toHaveBeenCalledWith('workItems:show', 'updated_title', {
- category: 'workItems:show',
+ expect(trackingSpy).toHaveBeenCalledWith(TRACKING_CATEGORY_SHOW, 'updated_title', {
+ category: TRACKING_CATEGORY_SHOW,
label: 'item_title',
property: 'type_Task',
});
diff --git a/spec/frontend/work_items/components/work_item_weight_spec.js b/spec/frontend/work_items/components/work_item_weight_spec.js
new file mode 100644
index 00000000000..80a1d032ad7
--- /dev/null
+++ b/spec/frontend/work_items/components/work_item_weight_spec.js
@@ -0,0 +1,47 @@
+import { shallowMount } from '@vue/test-utils';
+import WorkItemWeight from '~/work_items/components/work_item_weight.vue';
+
+describe('WorkItemAssignees component', () => {
+ let wrapper;
+
+ const createComponent = ({ weight, hasIssueWeightsFeature = true } = {}) => {
+ wrapper = shallowMount(WorkItemWeight, {
+ propsData: {
+ weight,
+ },
+ provide: {
+ hasIssueWeightsFeature,
+ },
+ });
+ };
+
+ describe('weight licensed feature', () => {
+ describe.each`
+ description | hasIssueWeightsFeature | exists
+ ${'when available'} | ${true} | ${true}
+ ${'when not available'} | ${false} | ${false}
+ `('$description', ({ hasIssueWeightsFeature, exists }) => {
+ it(hasIssueWeightsFeature ? 'renders component' : 'does not render component', () => {
+ createComponent({ hasIssueWeightsFeature });
+
+ expect(wrapper.find('div').exists()).toBe(exists);
+ });
+ });
+ });
+
+ describe('weight text', () => {
+ describe.each`
+ description | weight | text
+ ${'renders 1'} | ${1} | ${'1'}
+ ${'renders 0'} | ${0} | ${'0'}
+ ${'renders None'} | ${null} | ${'None'}
+ ${'renders None'} | ${undefined} | ${'None'}
+ `('when weight is $weight', ({ description, weight, text }) => {
+ it(description, () => {
+ createComponent({ weight });
+
+ expect(wrapper.text()).toContain(text);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/work_items/pages/work_item_detail_spec.js b/spec/frontend/work_items/pages/work_item_detail_spec.js
index fe13f8945f5..33cf2636dd5 100644
--- a/spec/frontend/work_items/pages/work_item_detail_spec.js
+++ b/spec/frontend/work_items/pages/work_item_detail_spec.js
@@ -9,6 +9,7 @@ import WorkItemDescription from '~/work_items/components/work_item_description.v
import WorkItemState from '~/work_items/components/work_item_state.vue';
import WorkItemTitle from '~/work_items/components/work_item_title.vue';
import WorkItemAssignees from '~/work_items/components/work_item_assignees.vue';
+import WorkItemWeight from '~/work_items/components/work_item_weight.vue';
import { i18n } from '~/work_items/constants';
import workItemQuery from '~/work_items/graphql/work_item.query.graphql';
import workItemTitleSubscription from '~/work_items/graphql/work_item_title.subscription.graphql';
@@ -29,13 +30,14 @@ describe('WorkItemDetail component', () => {
const findWorkItemState = () => wrapper.findComponent(WorkItemState);
const findWorkItemDescription = () => wrapper.findComponent(WorkItemDescription);
const findWorkItemAssignees = () => wrapper.findComponent(WorkItemAssignees);
+ const findWorkItemWeight = () => wrapper.findComponent(WorkItemWeight);
const createComponent = ({
workItemId = workItemQueryResponse.data.workItem.id,
handler = successHandler,
subscriptionHandler = initialSubscriptionHandler,
- assigneesEnabled = false,
- includeAssigneesWidget = false,
+ workItemsMvc2Enabled = false,
+ includeWidgets = false,
} = {}) => {
wrapper = shallowMount(WorkItemDetail, {
apolloProvider: createMockApollo(
@@ -45,13 +47,13 @@ describe('WorkItemDetail component', () => {
],
{},
{
- typePolicies: includeAssigneesWidget ? temporaryConfig.cacheConfig.typePolicies : {},
+ typePolicies: includeWidgets ? temporaryConfig.cacheConfig.typePolicies : {},
},
),
propsData: { workItemId },
provide: {
glFeatures: {
- workItemAssignees: assigneesEnabled,
+ workItemsMvc2: workItemsMvc2Enabled,
},
},
});
@@ -153,11 +155,11 @@ describe('WorkItemDetail component', () => {
expect(wrapper.emitted('workItemUpdated')).toEqual([[], []]);
});
- describe('when assignees feature flag is enabled', () => {
+ describe('when work_items_mvc_2 feature flag is enabled', () => {
it('renders assignees component when assignees widget is returned from the API', async () => {
createComponent({
- assigneesEnabled: true,
- includeAssigneesWidget: true,
+ workItemsMvc2Enabled: true,
+ includeWidgets: true,
});
await waitForPromises();
@@ -166,8 +168,8 @@ describe('WorkItemDetail component', () => {
it('does not render assignees component when assignees widget is not returned from the API', async () => {
createComponent({
- assigneesEnabled: true,
- includeAssigneesWidget: false,
+ workItemsMvc2Enabled: true,
+ includeWidgets: false,
});
await waitForPromises();
@@ -181,4 +183,36 @@ describe('WorkItemDetail component', () => {
expect(findWorkItemAssignees().exists()).toBe(false);
});
+
+ describe('weight widget', () => {
+ describe('when work_items_mvc_2 feature flag is enabled', () => {
+ describe.each`
+ description | includeWidgets | exists
+ ${'when widget is returned from API'} | ${true} | ${true}
+ ${'when widget is not returned from API'} | ${false} | ${false}
+ `('$description', ({ includeWidgets, exists }) => {
+ it(`${includeWidgets ? 'renders' : 'does not render'} weight component`, async () => {
+ createComponent({ includeWidgets, workItemsMvc2Enabled: true });
+ await waitForPromises();
+
+ expect(findWorkItemWeight().exists()).toBe(exists);
+ });
+ });
+ });
+
+ describe('when work_items_mvc_2 feature flag is disabled', () => {
+ describe.each`
+ description | includeWidgets | exists
+ ${'when widget is returned from API'} | ${true} | ${false}
+ ${'when widget is not returned from API'} | ${false} | ${false}
+ `('$description', ({ includeWidgets, exists }) => {
+ it(`${includeWidgets ? 'renders' : 'does not render'} weight component`, async () => {
+ createComponent({ includeWidgets, workItemsMvc2Enabled: false });
+ await waitForPromises();
+
+ expect(findWorkItemWeight().exists()).toBe(exists);
+ });
+ });
+ });
+ });
});