diff options
114 files changed, 706 insertions, 535 deletions
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue index 9ed27edd71a..e6a411d20d5 100644 --- a/app/assets/javascripts/diffs/components/app.vue +++ b/app/assets/javascripts/diffs/components/app.vue @@ -229,7 +229,6 @@ export default { projectPath: this.projectPath, dismissEndpoint: this.dismissEndpoint, showSuggestPopover: this.showSuggestPopover, - useSingleDiffStyle: this.glFeatures.singleMrDiffView, viewDiffsFileByFile: this.viewDiffsFileByFile, }); @@ -306,14 +305,10 @@ export default { ); }, needsReload() { - return ( - this.glFeatures.singleMrDiffView && - this.diffFiles.length && - isSingleViewStyle(this.diffFiles[0]) - ); + return this.diffFiles.length && isSingleViewStyle(this.diffFiles[0]); }, needsFirstLoad() { - return this.glFeatures.singleMrDiffView && !this.diffFiles.length; + return !this.diffFiles.length; }, fetchData(toggleTree = true) { if (this.glFeatures.diffsBatchLoad) { diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js index 8e26f5e9ffe..fc381adf218 100644 --- a/app/assets/javascripts/diffs/store/actions.js +++ b/app/assets/javascripts/diffs/store/actions.js @@ -52,7 +52,6 @@ export const setBaseConfig = ({ commit }, options) => { projectPath, dismissEndpoint, showSuggestPopover, - useSingleDiffStyle, } = options; commit(types.SET_BASE_CONFIG, { endpoint, @@ -62,7 +61,6 @@ export const setBaseConfig = ({ commit }, options) => { projectPath, dismissEndpoint, showSuggestPopover, - useSingleDiffStyle, }); }; @@ -70,13 +68,10 @@ export const fetchDiffFiles = ({ state, commit }) => { const worker = new TreeWorker(); const urlParams = { w: state.showWhitespace ? '0' : '1', + view: window.gon?.features?.unifiedDiffLines ? 'inline' : state.diffViewType, }; let returnData; - if (state.useSingleDiffStyle) { - urlParams.view = window.gon?.features?.unifiedDiffLines ? 'inline' : state.diffViewType; - } - commit(types.SET_LOADING, true); worker.addEventListener('message', ({ data }) => { @@ -111,12 +106,9 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => { const urlParams = { per_page: DIFFS_PER_PAGE, w: state.showWhitespace ? '0' : '1', + view: window.gon?.features?.unifiedDiffLines ? 'inline' : state.diffViewType, }; - if (state.useSingleDiffStyle) { - urlParams.view = window.gon?.features?.unifiedDiffLines ? 'inline' : state.diffViewType; - } - commit(types.SET_BATCH_LOADING, true); commit(types.SET_RETRIEVING_BATCHES, true); @@ -175,11 +167,9 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => { export const fetchDiffFilesMeta = ({ commit, state }) => { const worker = new TreeWorker(); - const urlParams = {}; - - if (state.useSingleDiffStyle) { - urlParams.view = window.gon?.features?.unifiedDiffLines ? 'inline' : state.diffViewType; - } + const urlParams = { + view: window.gon?.features?.unifiedDiffLines ? 'inline' : state.diffViewType, + }; commit(types.SET_LOADING, true); @@ -240,10 +230,7 @@ export const assignDiscussionsToDiff = ( ) => { const id = window?.location?.hash; const isNoteLink = id.indexOf('#note') === 0; - const diffPositionByLineCode = getDiffPositionByLineCode( - state.diffFiles, - state.useSingleDiffStyle, - ); + const diffPositionByLineCode = getDiffPositionByLineCode(state.diffFiles); const hash = getLocationHash(); discussions diff --git a/app/assets/javascripts/diffs/store/modules/diff_state.js b/app/assets/javascripts/diffs/store/modules/diff_state.js index d31a600e354..c8f6f6bb0e5 100644 --- a/app/assets/javascripts/diffs/store/modules/diff_state.js +++ b/app/assets/javascripts/diffs/store/modules/diff_state.js @@ -41,5 +41,4 @@ export default () => ({ fileFinderVisible: false, dismissEndpoint: '', showSuggestPopover: true, - useSingleDiffStyle: false, }); diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js index 3b03cce86fd..3be73d78c42 100644 --- a/app/assets/javascripts/diffs/store/mutations.js +++ b/app/assets/javascripts/diffs/store/mutations.js @@ -25,7 +25,6 @@ export default { projectPath, dismissEndpoint, showSuggestPopover, - useSingleDiffStyle, } = options; Object.assign(state, { endpoint, @@ -35,7 +34,6 @@ export default { projectPath, dismissEndpoint, showSuggestPopover, - useSingleDiffStyle, }); }, diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js index 9286d7fdcb0..320b44bd537 100644 --- a/app/assets/javascripts/diffs/store/utils.js +++ b/app/assets/javascripts/diffs/store/utils.js @@ -495,11 +495,11 @@ export function prepareDiffData(diff, priorFiles = []) { return deduplicateFilesList([...priorFiles, ...cleanedFiles]); } -export function getDiffPositionByLineCode(diffFiles, useSingleDiffStyle) { +export function getDiffPositionByLineCode(diffFiles) { let lines = []; const hasInlineDiffs = diffFiles.some(file => file.highlighted_diff_lines.length > 0); - if (!useSingleDiffStyle || hasInlineDiffs) { + if (hasInlineDiffs) { // In either of these cases, we can use `highlighted_diff_lines` because // that will include all of the parallel diff lines, too diff --git a/app/assets/javascripts/incidents_settings/components/alerts_form.vue b/app/assets/javascripts/incidents_settings/components/alerts_form.vue index 636d9fc4b90..85a8241789d 100644 --- a/app/assets/javascripts/incidents_settings/components/alerts_form.vue +++ b/app/assets/javascripts/incidents_settings/components/alerts_form.vue @@ -9,7 +9,6 @@ import { GlNewDropdown, GlNewDropdownItem, } from '@gitlab/ui'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { I18N_ALERT_SETTINGS_FORM, NO_ISSUE_TEMPLATE_SELECTED, @@ -28,7 +27,6 @@ export default { GlNewDropdown, GlNewDropdownItem, }, - mixins: [glFeatureFlagsMixin()], inject: ['service', 'alertSettings'], data() { return { @@ -127,7 +125,7 @@ export default { <span>{{ $options.i18n.sendEmail.label }}</span> </gl-form-checkbox> </gl-form-group> - <gl-form-group v-if="glFeatures.autoCloseIncident" class="gl-pl-0 gl-mb-5"> + <gl-form-group class="gl-pl-0 gl-mb-5"> <gl-form-checkbox v-model="autoCloseIncident"> <span>{{ $options.i18n.autoCloseIncidents.label }}</span> </gl-form-checkbox> diff --git a/app/controllers/admin/instance_statistics_controller.rb b/app/controllers/admin/instance_statistics_controller.rb new file mode 100644 index 00000000000..ad2fea5983d --- /dev/null +++ b/app/controllers/admin/instance_statistics_controller.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class Admin::InstanceStatisticsController < Admin::ApplicationController + before_action :check_feature_flag + + def index + end + + def check_feature_flag + render_404 unless Feature.enabled?(:instance_analytics) + end +end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 43baa849007..11d15692f7b 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -27,7 +27,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo before_action only: [:show] do push_frontend_feature_flag(:diffs_batch_load, @project, default_enabled: true) push_frontend_feature_flag(:deploy_from_footer, @project, default_enabled: true) - push_frontend_feature_flag(:single_mr_diff_view, @project, default_enabled: true) push_frontend_feature_flag(:suggest_pipeline) if experiment_enabled?(:suggest_pipeline) push_frontend_feature_flag(:code_navigation, @project, default_enabled: true) push_frontend_feature_flag(:widget_visibility_polling, @project, default_enabled: true) diff --git a/app/controllers/projects/metrics_dashboard_controller.rb b/app/controllers/projects/metrics_dashboard_controller.rb index 51307c3665c..ae3f0a7a0c2 100644 --- a/app/controllers/projects/metrics_dashboard_controller.rb +++ b/app/controllers/projects/metrics_dashboard_controller.rb @@ -6,6 +6,8 @@ module Projects # app/controllers/projects/environments_controller.rb # See https://gitlab.com/gitlab-org/gitlab/-/issues/226002 for more details. + include Gitlab::Utils::StrongMemoize + before_action :authorize_metrics_dashboard! before_action do push_frontend_feature_flag(:prometheus_computed_alerts) @@ -15,6 +17,8 @@ module Projects def show if environment render 'projects/environments/metrics' + elsif default_environment + redirect_to project_metrics_dashboard_path(project, environment: default_environment) else render 'projects/environments/empty_metrics' end @@ -23,12 +27,15 @@ module Projects private def environment - @environment ||= - if params[:environment] - project.environments.find(params[:environment]) - else - project.default_environment - end + strong_memoize(:environment) do + project.environments.find(params[:environment]) if params[:environment] + end + end + + def default_environment + strong_memoize(:default_environment) do + project.default_environment + end end end end diff --git a/app/controllers/projects/settings/operations_controller.rb b/app/controllers/projects/settings/operations_controller.rb index 12543e5f780..781b850ddfe 100644 --- a/app/controllers/projects/settings/operations_controller.rb +++ b/app/controllers/projects/settings/operations_controller.rb @@ -6,10 +6,6 @@ module Projects before_action :authorize_admin_operations! before_action :authorize_read_prometheus_alerts!, only: [:reset_alerting_token] - before_action do - push_frontend_feature_flag(:auto_close_incident) - end - respond_to :json, only: [:reset_alerting_token, :reset_pagerduty_token] helper_method :error_tracking_setting diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 56b6a5201e7..c882e1a8358 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -4,12 +4,15 @@ class SearchController < ApplicationController include ControllerWithCrossProjectAccessCheck include SearchHelper include RendersCommits + include RedisTracking SCOPE_PRELOAD_METHOD = { projects: :with_web_entity_associations, issues: :with_web_entity_associations }.freeze + track_redis_hll_event :show, name: 'i_search_total', feature: :search_track_unique_users + around_action :allow_gitaly_ref_name_caching skip_before_action :authenticate_user! @@ -126,3 +129,5 @@ class SearchController < ApplicationController payload[:metadata]['meta.search.scope'] = params[:scope] end end + +SearchController.prepend_if_ee('EE::SearchController') diff --git a/app/models/project.rb b/app/models/project.rb index ab687896e2e..87bb34fb9c2 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -545,6 +545,8 @@ class Project < ApplicationRecord preload(:project_feature, :route, namespace: [:route, :owner]) } + scope :imported_from, -> (type) { where(import_type: type) } + enum auto_cancel_pending_pipelines: { disabled: 0, enabled: 1 } chronic_duration_attr :build_timeout_human_readable, :build_timeout, diff --git a/app/serializers/diff_file_entity.rb b/app/serializers/diff_file_entity.rb index 26a42d2e9eb..e3fefbb46b6 100644 --- a/app/serializers/diff_file_entity.rb +++ b/app/serializers/diff_file_entity.rb @@ -71,15 +71,11 @@ class DiffFileEntity < DiffFileBaseEntity private def parallel_diff_view?(options, diff_file) - return true unless Feature.enabled?(:single_mr_diff_view, diff_file.repository.project, default_enabled: true) - # If we're not rendering inline, we must be rendering parallel !inline_diff_view?(options, diff_file) end def inline_diff_view?(options, diff_file) - return true unless Feature.enabled?(:single_mr_diff_view, diff_file.repository.project, default_enabled: true) - # If nothing is present, inline will be the default. options.fetch(:diff_view, :inline).to_sym == :inline end diff --git a/app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb b/app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb index d0aa8b04775..aeabbb99468 100644 --- a/app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb +++ b/app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb @@ -77,15 +77,8 @@ module Ci private def status_for_array(statuses, dag:) - # TODO: This is hack to support - # the same exact behaviour for Atomic and Legacy processing - # that DAG is blocked from executing if dependent is not "complete" - if dag && statuses.any? { |status| Ci::HasStatus::COMPLETED_STATUSES.exclude?(status[:status]) } - return 'pending' - end - result = Gitlab::Ci::Status::Composite - .new(statuses) + .new(statuses, dag: dag) .status result || 'success' end diff --git a/app/views/admin/instance_statistics/index.html.haml b/app/views/admin/instance_statistics/index.html.haml new file mode 100644 index 00000000000..ab28a2471e6 --- /dev/null +++ b/app/views/admin/instance_statistics/index.html.haml @@ -0,0 +1,4 @@ +- breadcrumb_title _("Instance Statistics") +- page_title _("Instance Statistics") + +#js-instance-statistics-app diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml index 08dbd71bd0c..2e915a38c46 100644 --- a/app/views/layouts/nav/sidebar/_admin.html.haml +++ b/app/views/layouts/nav/sidebar/_admin.html.haml @@ -69,6 +69,11 @@ = link_to admin_cohorts_path, title: _('Cohorts') do %span = _('Cohorts') + - if Feature.enabled?(:instance_statistics) + = nav_link(controller: :instance_statistics) do + = link_to admin_instance_statistics_path, title: _('Instance Statistics') do + %span + = _('Instance Statistics') = nav_link(controller: admin_monitoring_nav_links) do = link_to admin_system_info_path, data: { qa_selector: 'admin_monitoring_link' } do diff --git a/app/views/search/results/_note.html.haml b/app/views/search/results/_note.html.haml index 270223fc508..d88b7b32ed6 100644 --- a/app/views/search/results/_note.html.haml +++ b/app/views/search/results/_note.html.haml @@ -20,6 +20,11 @@ · = link_to note.noteable.title, note_url, data: {track_event: 'click_text', track_label: 'noteable_title', track_property: 'search_result'} + %span.note-headline-light.note-headline-meta + %span.system-note-separator + · + %span.system-note-separator= time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago') + .note-search-result .term = search_md_sanitize(note.note) diff --git a/changelogs/unreleased/205578-add-package-count-to-usage-data.yml b/changelogs/unreleased/205578-add-package-count-to-usage-data.yml new file mode 100644 index 00000000000..6e23906e70c --- /dev/null +++ b/changelogs/unreleased/205578-add-package-count-to-usage-data.yml @@ -0,0 +1,5 @@ +--- +title: Adds package count to usage data +merge_request: 40039 +author: +type: added diff --git a/changelogs/unreleased/213080-fix-skipped-status-problem-of-needs.yml b/changelogs/unreleased/213080-fix-skipped-status-problem-of-needs.yml new file mode 100644 index 00000000000..ed59d696c44 --- /dev/null +++ b/changelogs/unreleased/213080-fix-skipped-status-problem-of-needs.yml @@ -0,0 +1,5 @@ +--- +title: Fix skipped status of DAG pipelines +merge_request: 39205 +author: +type: fixed diff --git a/changelogs/unreleased/225254-remove-feature-flag.yml b/changelogs/unreleased/225254-remove-feature-flag.yml new file mode 100644 index 00000000000..3cb326d6e5c --- /dev/null +++ b/changelogs/unreleased/225254-remove-feature-flag.yml @@ -0,0 +1,5 @@ +--- +title: Remove auto close incident feature flag +merge_request: 40612 +author: +type: changed diff --git a/changelogs/unreleased/238116-redis-hll-search-analytics.yml b/changelogs/unreleased/238116-redis-hll-search-analytics.yml new file mode 100644 index 00000000000..84b7160eca2 --- /dev/null +++ b/changelogs/unreleased/238116-redis-hll-search-analytics.yml @@ -0,0 +1,5 @@ +--- +title: Add the unique search visits data to the usage ping +merge_request: 40134 +author: +type: changed diff --git a/changelogs/unreleased/authored-date-on-comments-in-search.yml b/changelogs/unreleased/authored-date-on-comments-in-search.yml new file mode 100644 index 00000000000..7a25554d01c --- /dev/null +++ b/changelogs/unreleased/authored-date-on-comments-in-search.yml @@ -0,0 +1,5 @@ +--- +title: Show the comment authored time in comment search results +merge_request: 40472 +author: +type: added diff --git a/changelogs/unreleased/georgekoltsov-add-importing-projects-usage-ping.yml b/changelogs/unreleased/georgekoltsov-add-importing-projects-usage-ping.yml new file mode 100644 index 00000000000..ddfe1d8f27c --- /dev/null +++ b/changelogs/unreleased/georgekoltsov-add-importing-projects-usage-ping.yml @@ -0,0 +1,5 @@ +--- +title: Add usage pings for project import using various importers (GitLab, Bitbucket, Gitea, GitHub and more) +merge_request: 40130 +author: +type: added diff --git a/changelogs/unreleased/remove-extracts-path-optimization-flag.yml b/changelogs/unreleased/remove-extracts-path-optimization-flag.yml new file mode 100644 index 00000000000..b67b3605606 --- /dev/null +++ b/changelogs/unreleased/remove-extracts-path-optimization-flag.yml @@ -0,0 +1,5 @@ +--- +title: Reduce Redis usage when viewing repositories with lots of branches and tags +merge_request: 40615 +author: +type: performance diff --git a/config/feature_flags/development/ci_matrix_job_names.yml b/config/feature_flags/development/ci_matrix_job_names.yml new file mode 100644 index 00000000000..d8f7b2a5543 --- /dev/null +++ b/config/feature_flags/development/ci_matrix_job_names.yml @@ -0,0 +1,7 @@ +--- +name: ci_matrix_job_names +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39985 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/239012 +group: 'group::continuous integration' +type: development +default_enabled: false diff --git a/config/feature_flags/development/instance_statistics.yml b/config/feature_flags/development/instance_statistics.yml new file mode 100644 index 00000000000..212b7b39615 --- /dev/null +++ b/config/feature_flags/development/instance_statistics.yml @@ -0,0 +1,7 @@ +--- +name: instance_statistics +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40583 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/241711 +group: group::analytics +type: development +default_enabled: false
\ No newline at end of file diff --git a/config/feature_flags/development/search_track_unique_users.yml b/config/feature_flags/development/search_track_unique_users.yml new file mode 100644 index 00000000000..cd190396e5a --- /dev/null +++ b/config/feature_flags/development/search_track_unique_users.yml @@ -0,0 +1,7 @@ +--- +name: search_track_unique_users +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40134 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/240906 +group: group::global search +type: development +default_enabled: false diff --git a/config/feature_flags/development/security-on-demand-scans-site-validation.yml b/config/feature_flags/development/security-on-demand-scans-site-validation.yml new file mode 100644 index 00000000000..381c173b1bf --- /dev/null +++ b/config/feature_flags/development/security-on-demand-scans-site-validation.yml @@ -0,0 +1,7 @@ +--- +name: security-on-demand-scans-site-validation +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40685 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/241815 +group: group::dynamic analysis +type: development +default_enabled: false diff --git a/db/migrate/20200826092324_add_projects_index_on_import_type_creator_id_created_at.rb b/db/migrate/20200826092324_add_projects_index_on_import_type_creator_id_created_at.rb new file mode 100644 index 00000000000..94d2e5cb4ab --- /dev/null +++ b/db/migrate/20200826092324_add_projects_index_on_import_type_creator_id_created_at.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class AddProjectsIndexOnImportTypeCreatorIdCreatedAt < ActiveRecord::Migration[6.0] + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + INDEX_NAME = 'index_imported_projects_on_import_type_creator_id_created_at'.freeze + + disable_ddl_transaction! + + def up + add_concurrent_index :projects, + [:import_type, :creator_id, :created_at], + where: 'import_type IS NOT NULL', + name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :projects, INDEX_NAME + end +end diff --git a/db/schema_migrations/20200826092324 b/db/schema_migrations/20200826092324 new file mode 100644 index 00000000000..8745b628965 --- /dev/null +++ b/db/schema_migrations/20200826092324 @@ -0,0 +1 @@ +35c37b8dcdca08d48086dc8164c2f6a69f563366ec9bce1f60299978a94de9bc
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 119d34610a3..06b9e1fdfc5 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -19884,6 +19884,8 @@ CREATE INDEX index_import_failures_on_project_id_and_correlation_id_value ON pub CREATE INDEX index_import_failures_on_project_id_not_null ON public.import_failures USING btree (project_id) WHERE (project_id IS NOT NULL); +CREATE INDEX index_imported_projects_on_import_type_creator_id_created_at ON public.projects USING btree (import_type, creator_id, created_at) WHERE (import_type IS NOT NULL); + CREATE UNIQUE INDEX index_index_statuses_on_project_id ON public.index_statuses USING btree (project_id); CREATE INDEX index_insights_on_namespace_id ON public.insights USING btree (namespace_id); diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md index 1480b8acecd..5acaf7cfcce 100644 --- a/doc/ci/variables/README.md +++ b/doc/ci/variables/README.md @@ -745,7 +745,7 @@ so `&&` is evaluated before `||`. #### Parentheses > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/230938) in GitLab 13.3 -> - It's [deployed behind a feature flag](../../user/feature_flags.md), enabled by default. +> - It's deployed behind a feature flag, enabled by default. > - It's enabled on GitLab.com. > - It's recommended for production use. > - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-parenthesis-support-for-variables-core-only). **(CORE ONLY)** diff --git a/lib/extracts_ref.rb b/lib/extracts_ref.rb index 5ef2d888550..adbe93cfa3a 100644 --- a/lib/extracts_ref.rb +++ b/lib/extracts_ref.rb @@ -111,7 +111,6 @@ module ExtractsRef end def use_first_path_segment?(ref) - return false unless ::Feature.enabled?(:extracts_path_optimization) return false unless repository_container return false if repository_container.repository.has_ambiguous_refs? diff --git a/lib/gitlab/ci/config/normalizer/matrix_strategy.rb b/lib/gitlab/ci/config/normalizer/matrix_strategy.rb index db21274a9ed..2865b2dcdb7 100644 --- a/lib/gitlab/ci/config/normalizer/matrix_strategy.rb +++ b/lib/gitlab/ci/config/normalizer/matrix_strategy.rb @@ -48,18 +48,29 @@ module Gitlab } end - def name_with_details - vars = variables.map { |key, value| "#{key}=#{value}"}.join('; ') + def name + if Gitlab::Ci::Features.new_matrix_job_names_enabled? + name_with_variable_details + else + old_name + end + end + + private - "#{job_name} (#{vars})" + def name_with_variable_details + vars = variables + .values + .compact + .join(', ') + + "#{job_name}: [#{vars}]" end - def name + def old_name "#{job_name} #{instance}/#{total}" end - private - attr_reader :job_name, :instance, :variables, :total end end diff --git a/lib/gitlab/ci/features.rb b/lib/gitlab/ci/features.rb index 386788c751f..da66cec935c 100644 --- a/lib/gitlab/ci/features.rb +++ b/lib/gitlab/ci/features.rb @@ -76,6 +76,10 @@ module Gitlab Feature.enabled?(:project_transactionless_destroy, project, default_enabled: false) end + def self.new_matrix_job_names_enabled? + ::Feature.enabled?(:ci_matrix_job_names, default_enabled: false) + end + def self.coverage_report_view?(project) ::Feature.enabled?(:coverage_report_view, project) end diff --git a/lib/gitlab/ci/status/composite.rb b/lib/gitlab/ci/status/composite.rb index 04a9fc29802..9a4f5644f7d 100644 --- a/lib/gitlab/ci/status/composite.rb +++ b/lib/gitlab/ci/status/composite.rb @@ -7,7 +7,7 @@ module Gitlab include Gitlab::Utils::StrongMemoize # This class accepts an array of arrays/hashes/or objects - def initialize(all_statuses, with_allow_failure: true) + def initialize(all_statuses, with_allow_failure: true, dag: false) unless all_statuses.respond_to?(:pluck) raise ArgumentError, "all_statuses needs to respond to `.pluck`" end @@ -15,6 +15,7 @@ module Gitlab @status_set = Set.new @status_key = 0 @allow_failure_key = 1 if with_allow_failure + @dag = dag consume_all_statuses(all_statuses) end @@ -31,7 +32,13 @@ module Gitlab return if none? strong_memoize(:status) do - if only_of?(:skipped, :ignored) + if @dag && any_of?(:skipped) + # The DAG job is skipped if one of the needs does not run at all. + 'skipped' + elsif @dag && !only_of?(:success, :failed, :canceled, :skipped, :success_with_warnings) + # DAG is blocked from executing if a dependent is not "complete" + 'pending' + elsif only_of?(:skipped, :ignored) 'skipped' elsif only_of?(:success, :skipped, :success_with_warnings, :ignored) 'success' diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb index 1ba21d99277..ffd5b9aee2f 100644 --- a/lib/gitlab/usage_data.rb +++ b/lib/gitlab/usage_data.rb @@ -38,6 +38,7 @@ module Gitlab .merge(usage_activity_by_stage(:usage_activity_by_stage_monthly, last_28_days_time_period)) .merge(analytics_unique_visits_data) .merge(compliance_unique_visits_data) + .merge(search_unique_visits_data) end end @@ -130,6 +131,7 @@ module Gitlab milestone_lists: count(List.milestone), milestones: count(Milestone), projects_with_packages: distinct_count(::Packages::Package, :project_id), + packages: count(::Packages::Package), pages_domains: count(PagesDomain), pool_repositories: count(PoolRepository), projects: count(Project), @@ -511,7 +513,17 @@ module Gitlab events: distinct_count(::Event.where(time_period), :author_id), groups: distinct_count(::GroupMember.where(time_period), :user_id), users_created: count(::User.where(time_period), start: user_minimum_id, finish: user_maximum_id), - omniauth_providers: filtered_omniauth_provider_names.reject { |name| name == 'group_saml' } + omniauth_providers: filtered_omniauth_provider_names.reject { |name| name == 'group_saml' }, + projects_imported: { + gitlab_project: projects_imported_count('gitlab_project', time_period), + gitlab: projects_imported_count('gitlab', time_period), + github: projects_imported_count('github', time_period), + bitbucket: projects_imported_count('bitbucket', time_period), + bitbucket_server: projects_imported_count('bitbucket_server', time_period), + gitea: projects_imported_count('gitea', time_period), + git: projects_imported_count('git', time_period), + manifest: projects_imported_count('manifest', time_period) + } } end # rubocop: enable CodeReuse/ActiveRecord @@ -608,6 +620,18 @@ module Gitlab { compliance_unique_visits: results } end + def search_unique_visits_data + events = ::Gitlab::UsageDataCounters::HLLRedisCounter.events_for_category('search') + results = events.each_with_object({}) do |event, hash| + hash[event] = redis_usage_data { ::Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: event, start_date: 7.days.ago.to_date, end_date: Date.current) } + end + + results['search_unique_visits_for_any_target_weekly'] = redis_usage_data { ::Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: events, start_date: 7.days.ago.to_date, end_date: Date.current) } + results['search_unique_visits_for_any_target_monthly'] = redis_usage_data { ::Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(event_names: events, start_date: 4.weeks.ago.to_date, end_date: Date.current) } + + { search_unique_visits: results } + end + def action_monthly_active_users(time_period) counter = Gitlab::UsageDataCounters::TrackUniqueEvents @@ -774,6 +798,10 @@ module Gitlab def deployment_count(relation) count relation, start: deployment_minimum_id, finish: deployment_maximum_id end + + def projects_imported_count(from, time_period) + distinct_count(::Project.imported_from(from).where(time_period), :creator_id) # rubocop: disable CodeReuse/ActiveRecord + end end end end diff --git a/lib/gitlab/usage_data_counters/known_events.yml b/lib/gitlab/usage_data_counters/known_events.yml index feda3aeedfe..cd4d31345d7 100644 --- a/lib/gitlab/usage_data_counters/known_events.yml +++ b/lib/gitlab/usage_data_counters/known_events.yml @@ -84,3 +84,15 @@ redis_slot: edit expiry: 29 aggregation: daily +- name: i_search_total + category: search + redis_slot: search + aggregation: weekly +- name: i_search_advanced + category: search + redis_slot: search + aggregation: weekly +- name: i_search_paid + category: search + redis_slot: search + aggregation: weekly diff --git a/locale/gitlab.pot b/locale/gitlab.pot index c6958960c5c..ee9bc0fa54e 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -13243,6 +13243,9 @@ msgstr[1] "" msgid "Instance Configuration" msgstr "" +msgid "Instance Statistics" +msgstr "" + msgid "Instance administrators group already exists" msgstr "" diff --git a/package.json b/package.json index 7ecd87b02ba..74d353cceef 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@babel/preset-env": "^7.10.1", "@gitlab/at.js": "1.5.5", "@gitlab/svgs": "1.161.0", - "@gitlab/ui": "20.10.0", + "@gitlab/ui": "20.11.0", "@gitlab/visual-review-tools": "1.6.1", "@rails/actioncable": "^6.0.3-1", "@sentry/browser": "^5.10.2", diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index a41ff28841d..d66a0246c2d 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -149,6 +149,11 @@ RSpec.describe SearchController do expect(assigns[:search_objects].first).to eq note end + it_behaves_like 'tracking unique hll events', :show do + let(:request_params) { { scope: 'projects', search: 'term' } } + let(:target_id) { 'i_search_total' } + end + context 'on restricted projects' do context 'when signed out' do before do diff --git a/spec/features/merge_request/maintainer_edits_fork_spec.rb b/spec/features/merge_request/maintainer_edits_fork_spec.rb index be12f774c29..0e65cb358da 100644 --- a/spec/features/merge_request/maintainer_edits_fork_spec.rb +++ b/spec/features/merge_request/maintainer_edits_fork_spec.rb @@ -20,8 +20,6 @@ RSpec.describe 'a maintainer edits files on a source-branch of an MR from a fork end before do - stub_feature_flags(single_mr_diff_view: false) - target_project.add_maintainer(user) sign_in(user) diff --git a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb index 1a7baff2fb1..9a79a80abe9 100644 --- a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb +++ b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb @@ -10,7 +10,6 @@ RSpec.describe 'Batch diffs', :js do let(:merge_request) { create(:merge_request, source_project: project, source_branch: 'master', target_branch: 'empty-branch') } before do - stub_feature_flags(single_mr_diff_view: project) stub_feature_flags(diffs_batch_load: true) sign_in(project.owner) diff --git a/spec/frontend/alert_management/components/alert_management_table_spec.js b/spec/frontend/alert_management/components/alert_management_table_spec.js index dc5a38bbf26..bcad415eb19 100644 --- a/spec/frontend/alert_management/components/alert_management_table_spec.js +++ b/spec/frontend/alert_management/components/alert_management_table_spec.js @@ -218,7 +218,11 @@ describe('AlertManagementTable', () => { data: { alerts: { list: mockAlerts }, alertsCount, hasError: false }, loading: false, }); - expect(findStatusDropdown().contains('.dropdown-title')).toBe(false); + expect( + findStatusDropdown() + .find('.dropdown-title') + .exists(), + ).toBe(false); }); it('shows correct severity icons', () => { @@ -517,7 +521,11 @@ describe('AlertManagementTable', () => { await selectFirstStatusOption(); expect(findAlertError().exists()).toBe(true); - expect(findAlertError().contains('[data-testid="htmlError"]')).toBe(true); + expect( + findAlertError() + .find('[data-testid="htmlError"]') + .exists(), + ).toBe(true); }); }); diff --git a/spec/frontend/alert_management/components/sidebar/alert_sidebar_status_spec.js b/spec/frontend/alert_management/components/sidebar/alert_sidebar_status_spec.js index 5bd0d3b3c17..a8fe40687e1 100644 --- a/spec/frontend/alert_management/components/sidebar/alert_sidebar_status_spec.js +++ b/spec/frontend/alert_management/components/sidebar/alert_sidebar_status_spec.js @@ -56,7 +56,11 @@ describe('Alert Details Sidebar Status', () => { }); it('displays the dropdown status header', () => { - expect(findStatusDropdown().contains('.dropdown-title')).toBe(true); + expect( + findStatusDropdown() + .find('.dropdown-title') + .exists(), + ).toBe(true); }); describe('updating the alert status', () => { diff --git a/spec/frontend/blob/components/blob_content_spec.js b/spec/frontend/blob/components/blob_content_spec.js index 9232a709194..3db95e5ad3f 100644 --- a/spec/frontend/blob/components/blob_content_spec.js +++ b/spec/frontend/blob/components/blob_content_spec.js @@ -36,20 +36,20 @@ describe('Blob Content component', () => { describe('rendering', () => { it('renders loader if `loading: true`', () => { createComponent({ loading: true }); - expect(wrapper.contains(GlLoadingIcon)).toBe(true); - expect(wrapper.contains(BlobContentError)).toBe(false); - expect(wrapper.contains(RichViewer)).toBe(false); - expect(wrapper.contains(SimpleViewer)).toBe(false); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); + expect(wrapper.find(BlobContentError).exists()).toBe(false); + expect(wrapper.find(RichViewer).exists()).toBe(false); + expect(wrapper.find(SimpleViewer).exists()).toBe(false); }); it('renders error if there is any in the viewer', () => { const renderError = 'Oops'; const viewer = { ...SimpleViewerMock, renderError }; createComponent({}, viewer); - expect(wrapper.contains(GlLoadingIcon)).toBe(false); - expect(wrapper.contains(BlobContentError)).toBe(true); - expect(wrapper.contains(RichViewer)).toBe(false); - expect(wrapper.contains(SimpleViewer)).toBe(false); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); + expect(wrapper.find(BlobContentError).exists()).toBe(true); + expect(wrapper.find(RichViewer).exists()).toBe(false); + expect(wrapper.find(SimpleViewer).exists()).toBe(false); }); it.each` @@ -60,7 +60,7 @@ describe('Blob Content component', () => { 'renders $type viewer when activeViewer is $type and no loading or error detected', ({ mock, viewer }) => { createComponent({}, mock); - expect(wrapper.contains(viewer)).toBe(true); + expect(wrapper.find(viewer).exists()).toBe(true); }, ); diff --git a/spec/frontend/blob/components/blob_edit_content_spec.js b/spec/frontend/blob/components/blob_edit_content_spec.js index 3cc210e972c..a01ac751a61 100644 --- a/spec/frontend/blob/components/blob_edit_content_spec.js +++ b/spec/frontend/blob/components/blob_edit_content_spec.js @@ -58,7 +58,7 @@ describe('Blob Header Editing', () => { createComponent({ value: undefined }); expect(spy).not.toHaveBeenCalled(); - expect(wrapper.contains('#editor')).toBe(true); + expect(wrapper.find('#editor').exists()).toBe(true); }); it('initialises Editor Lite', () => { diff --git a/spec/frontend/blob/components/blob_edit_header_spec.js b/spec/frontend/blob/components/blob_edit_header_spec.js index c71595a79cf..4355f46db7e 100644 --- a/spec/frontend/blob/components/blob_edit_header_spec.js +++ b/spec/frontend/blob/components/blob_edit_header_spec.js @@ -31,7 +31,7 @@ describe('Blob Header Editing', () => { }); it('contains a form input field', () => { - expect(wrapper.contains(GlFormInput)).toBe(true); + expect(wrapper.find(GlFormInput).exists()).toBe(true); }); it('does not show delete button', () => { diff --git a/spec/frontend/boards/components/board_content_spec.js b/spec/frontend/boards/components/board_content_spec.js index 26906763622..2bf16b6b950 100644 --- a/spec/frontend/boards/components/board_content_spec.js +++ b/spec/frontend/boards/components/board_content_spec.js @@ -62,7 +62,7 @@ describe('BoardContent', () => { }); it('does not display EpicsSwimlanes component', () => { - expect(wrapper.contains(EpicsSwimlanes)).toBe(false); - expect(wrapper.contains(GlAlert)).toBe(false); + expect(wrapper.find(EpicsSwimlanes).exists()).toBe(false); + expect(wrapper.find(GlAlert).exists()).toBe(false); }); }); diff --git a/spec/frontend/boards/components/issue_count_spec.js b/spec/frontend/boards/components/issue_count_spec.js index 819d878f4e2..d1ff0bdbf88 100644 --- a/spec/frontend/boards/components/issue_count_spec.js +++ b/spec/frontend/boards/components/issue_count_spec.js @@ -29,7 +29,7 @@ describe('IssueCount', () => { }); it('does not contains maxIssueCount in the template', () => { - expect(vm.contains('.js-max-issue-size')).toBe(false); + expect(vm.find('.js-max-issue-size').exists()).toBe(false); }); }); diff --git a/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js b/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js index 4e35243f484..ab32fb12058 100644 --- a/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js +++ b/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js @@ -49,7 +49,7 @@ describe('Ci variable modal', () => { }); it('does not render the autocomplete dropdown', () => { - expect(wrapper.contains(GlFormCombobox)).toBe(false); + expect(wrapper.find(GlFormCombobox).exists()).toBe(false); }); }); diff --git a/spec/frontend/clusters/components/application_row_spec.js b/spec/frontend/clusters/components/application_row_spec.js index 82fa7cf8d0a..0a964426c95 100644 --- a/spec/frontend/clusters/components/application_row_spec.js +++ b/spec/frontend/clusters/components/application_row_spec.js @@ -300,11 +300,11 @@ describe('Application Row', () => { beforeEach(() => mountComponent({ updateAvailable: true })); it('the modal is not rendered', () => { - expect(wrapper.contains(UpdateApplicationConfirmationModal)).toBe(false); + expect(wrapper.find(UpdateApplicationConfirmationModal).exists()).toBe(false); }); it('the correct button is rendered', () => { - expect(wrapper.contains("[data-qa-selector='update_button']")).toBe(true); + expect(wrapper.find("[data-qa-selector='update_button']").exists()).toBe(true); }); }); @@ -318,11 +318,13 @@ describe('Application Row', () => { }); it('displays a modal', () => { - expect(wrapper.contains(UpdateApplicationConfirmationModal)).toBe(true); + expect(wrapper.find(UpdateApplicationConfirmationModal).exists()).toBe(true); }); it('the correct button is rendered', () => { - expect(wrapper.contains("[data-qa-selector='update_button_with_confirmation']")).toBe(true); + expect(wrapper.find("[data-qa-selector='update_button_with_confirmation']").exists()).toBe( + true, + ); }); it('triggers updateApplication event', () => { @@ -344,8 +346,10 @@ describe('Application Row', () => { version: '1.1.2', }); - expect(wrapper.contains("[data-qa-selector='update_button_with_confirmation']")).toBe(true); - expect(wrapper.contains(UpdateApplicationConfirmationModal)).toBe(true); + expect(wrapper.find("[data-qa-selector='update_button_with_confirmation']").exists()).toBe( + true, + ); + expect(wrapper.find(UpdateApplicationConfirmationModal).exists()).toBe(true); }); it('does not need confirmation is version is 3.0.0', () => { @@ -355,8 +359,8 @@ describe('Application Row', () => { version: '3.0.0', }); - expect(wrapper.contains("[data-qa-selector='update_button']")).toBe(true); - expect(wrapper.contains(UpdateApplicationConfirmationModal)).toBe(false); + expect(wrapper.find("[data-qa-selector='update_button']").exists()).toBe(true); + expect(wrapper.find(UpdateApplicationConfirmationModal).exists()).toBe(false); }); it('does not need confirmation if version is higher than 3.0.0', () => { @@ -366,8 +370,8 @@ describe('Application Row', () => { version: '5.2.1', }); - expect(wrapper.contains("[data-qa-selector='update_button']")).toBe(true); - expect(wrapper.contains(UpdateApplicationConfirmationModal)).toBe(false); + expect(wrapper.find("[data-qa-selector='update_button']").exists()).toBe(true); + expect(wrapper.find(UpdateApplicationConfirmationModal).exists()).toBe(false); }); }); }); diff --git a/spec/frontend/clusters/components/fluentd_output_settings_spec.js b/spec/frontend/clusters/components/fluentd_output_settings_spec.js index 0bc4eb73bf9..c263679a45c 100644 --- a/spec/frontend/clusters/components/fluentd_output_settings_spec.js +++ b/spec/frontend/clusters/components/fluentd_output_settings_spec.js @@ -168,7 +168,7 @@ describe('FluentdOutputSettings', () => { }); it('displays a error message', () => { - expect(wrapper.contains(GlAlert)).toBe(true); + expect(wrapper.find(GlAlert).exists()).toBe(true); }); }); }); diff --git a/spec/frontend/clusters_list/components/ancestor_notice_spec.js b/spec/frontend/clusters_list/components/ancestor_notice_spec.js index c2fa8506014..436f1e97b04 100644 --- a/spec/frontend/clusters_list/components/ancestor_notice_spec.js +++ b/spec/frontend/clusters_list/components/ancestor_notice_spec.js @@ -45,7 +45,7 @@ describe('ClustersAncestorNotice', () => { }); it('displays link', () => { - expect(wrapper.contains(GlLink)).toBe(true); + expect(wrapper.find(GlLink).exists()).toBe(true); }); }); }); diff --git a/spec/frontend/diffs/components/app_spec.js b/spec/frontend/diffs/components/app_spec.js index 1f274456ded..dea2108b393 100644 --- a/spec/frontend/diffs/components/app_spec.js +++ b/spec/frontend/diffs/components/app_spec.js @@ -160,10 +160,6 @@ describe('diffs/components/app', () => { }); } - beforeEach(() => { - wrapper.vm.glFeatures.singleMrDiffView = true; - }); - it('fetches diffs if it has none', done => { wrapper.vm.isLatestVersion = () => false; @@ -320,7 +316,7 @@ describe('diffs/components/app', () => { state.diffs.isParallelView = false; }); - expect(wrapper.contains('.container-limited.limit-container-width')).toBe(true); + expect(wrapper.find('.container-limited.limit-container-width').exists()).toBe(true); }); it('does not add container-limiting classes when showFileTree is false with inline diffs', () => { @@ -329,7 +325,7 @@ describe('diffs/components/app', () => { state.diffs.isParallelView = false; }); - expect(wrapper.contains('.container-limited.limit-container-width')).toBe(false); + expect(wrapper.find('.container-limited.limit-container-width').exists()).toBe(false); }); it('does not add container-limiting classes when isFluidLayout', () => { @@ -337,7 +333,7 @@ describe('diffs/components/app', () => { state.diffs.isParallelView = false; }); - expect(wrapper.contains('.container-limited.limit-container-width')).toBe(false); + expect(wrapper.find('.container-limited.limit-container-width').exists()).toBe(false); }); it('displays loading icon on loading', () => { @@ -345,7 +341,7 @@ describe('diffs/components/app', () => { state.diffs.isLoading = true; }); - expect(wrapper.contains(GlLoadingIcon)).toBe(true); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); it('displays loading icon on batch loading', () => { @@ -353,20 +349,20 @@ describe('diffs/components/app', () => { state.diffs.isBatchLoading = true; }); - expect(wrapper.contains(GlLoadingIcon)).toBe(true); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); it('displays diffs container when not loading', () => { createComponent(); - expect(wrapper.contains(GlLoadingIcon)).toBe(false); - expect(wrapper.contains('#diffs')).toBe(true); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); + expect(wrapper.find('#diffs').exists()).toBe(true); }); it('does not show commit info', () => { createComponent(); - expect(wrapper.contains('.blob-commit-info')).toBe(false); + expect(wrapper.find('.blob-commit-info').exists()).toBe(false); }); describe('row highlighting', () => { @@ -442,7 +438,7 @@ describe('diffs/components/app', () => { it('renders empty state when no diff files exist', () => { createComponent(); - expect(wrapper.contains(NoChanges)).toBe(true); + expect(wrapper.find(NoChanges).exists()).toBe(true); }); it('does not render empty state when diff files exist', () => { @@ -452,7 +448,7 @@ describe('diffs/components/app', () => { }); }); - expect(wrapper.contains(NoChanges)).toBe(false); + expect(wrapper.find(NoChanges).exists()).toBe(false); expect(wrapper.findAll(DiffFile).length).toBe(1); }); @@ -462,7 +458,7 @@ describe('diffs/components/app', () => { state.diffs.mergeRequestDiff = mergeRequestDiff; }); - expect(wrapper.contains(NoChanges)).toBe(false); + expect(wrapper.find(NoChanges).exists()).toBe(false); }); }); @@ -722,7 +718,7 @@ describe('diffs/components/app', () => { state.diffs.mergeRequestDiff = mergeRequestDiff; }); - expect(wrapper.contains(CompareVersions)).toBe(true); + expect(wrapper.find(CompareVersions).exists()).toBe(true); expect(wrapper.find(CompareVersions).props()).toEqual( expect.objectContaining({ mergeRequestDiffs: diffsMockData, @@ -739,7 +735,7 @@ describe('diffs/components/app', () => { state.diffs.size = 1; }); - expect(wrapper.contains(HiddenFilesWarning)).toBe(true); + expect(wrapper.find(HiddenFilesWarning).exists()).toBe(true); expect(wrapper.find(HiddenFilesWarning).props()).toEqual( expect.objectContaining({ total: '5', @@ -757,7 +753,7 @@ describe('diffs/components/app', () => { }; }); - expect(wrapper.contains(CommitWidget)).toBe(true); + expect(wrapper.find(CommitWidget).exists()).toBe(true); }); it('should display diff file if there are diff files', () => { @@ -765,7 +761,7 @@ describe('diffs/components/app', () => { state.diffs.diffFiles.push({ sha: '123' }); }); - expect(wrapper.contains(DiffFile)).toBe(true); + expect(wrapper.find(DiffFile).exists()).toBe(true); }); it('should render tree list', () => { diff --git a/spec/frontend/diffs/components/no_changes_spec.js b/spec/frontend/diffs/components/no_changes_spec.js index 2795c68b4ee..78805a1cddc 100644 --- a/spec/frontend/diffs/components/no_changes_spec.js +++ b/spec/frontend/diffs/components/no_changes_spec.js @@ -36,7 +36,7 @@ describe('Diff no changes empty state', () => { }; }); - expect(vm.contains('script')).toBe(false); + expect(vm.find('script').exists()).toBe(false); }); describe('Renders', () => { diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js index 5fef35d6c5b..2a83305f29a 100644 --- a/spec/frontend/diffs/store/actions_spec.js +++ b/spec/frontend/diffs/store/actions_spec.js @@ -101,7 +101,6 @@ describe('DiffsStoreActions', () => { const projectPath = '/root/project'; const dismissEndpoint = '/-/user_callouts'; const showSuggestPopover = false; - const useSingleDiffStyle = false; testAction( setBaseConfig, @@ -113,7 +112,6 @@ describe('DiffsStoreActions', () => { projectPath, dismissEndpoint, showSuggestPopover, - useSingleDiffStyle, }, { endpoint: '', @@ -123,7 +121,6 @@ describe('DiffsStoreActions', () => { projectPath: '', dismissEndpoint: '', showSuggestPopover: true, - useSingleDiffStyle: true, }, [ { @@ -136,7 +133,6 @@ describe('DiffsStoreActions', () => { projectPath, dismissEndpoint, showSuggestPopover, - useSingleDiffStyle, }, }, ], @@ -169,13 +165,6 @@ describe('DiffsStoreActions', () => { done(); }, ); - - fetchDiffFiles({ state: { endpoint }, commit: () => null }) - .then(data => { - expect(data).toEqual(res); - done(); - }) - .catch(done.fail); }); }); @@ -223,7 +212,7 @@ describe('DiffsStoreActions', () => { testAction( fetchDiffFilesBatch, {}, - { endpointBatch, useSingleDiffStyle: true, diffViewType: 'inline' }, + { endpointBatch, diffViewType: 'inline' }, [ { type: types.SET_BATCH_LOADING, payload: true }, { type: types.SET_RETRIEVING_BATCHES, payload: true }, @@ -253,7 +242,6 @@ describe('DiffsStoreActions', () => { commit: () => {}, state: { endpointBatch: `${endpointBatch}?view=${otherView}`, - useSingleDiffStyle: true, diffViewType: viewStyle, }, }) @@ -283,7 +271,7 @@ describe('DiffsStoreActions', () => { testAction( fetchDiffFilesMeta, {}, - { endpointMetadata }, + { endpointMetadata, diffViewType: 'inline' }, [ { type: types.SET_LOADING, payload: true }, { type: types.SET_LOADING, payload: false }, @@ -299,146 +287,6 @@ describe('DiffsStoreActions', () => { }); }); - describe('when the single diff view feature flag is off', () => { - describe('fetchDiffFiles', () => { - it('should fetch diff files', done => { - const endpoint = '/fetch/diff/files?w=1'; - const mock = new MockAdapter(axios); - const res = { diff_files: 1, merge_request_diffs: [] }; - mock.onGet(endpoint).reply(200, res); - - testAction( - fetchDiffFiles, - {}, - { - endpoint, - diffFiles: [], - showWhitespace: false, - diffViewType: 'inline', - useSingleDiffStyle: false, - currentDiffFileId: null, - }, - [ - { type: types.SET_LOADING, payload: true }, - { type: types.SET_LOADING, payload: false }, - { type: types.SET_MERGE_REQUEST_DIFFS, payload: res.merge_request_diffs }, - { type: types.SET_DIFF_DATA, payload: res }, - ], - [], - () => { - mock.restore(); - done(); - }, - ); - - fetchDiffFiles({ state: { endpoint }, commit: () => null }) - .then(data => { - expect(data).toEqual(res); - done(); - }) - .catch(done.fail); - }); - }); - - describe('fetchDiffFilesBatch', () => { - let mock; - - beforeEach(() => { - mock = new MockAdapter(axios); - }); - - afterEach(() => { - mock.restore(); - }); - - it('should fetch batch diff files', done => { - const endpointBatch = '/fetch/diffs_batch'; - const res1 = { diff_files: [{ file_hash: 'test' }], pagination: { next_page: 2 } }; - const res2 = { diff_files: [{ file_hash: 'test2' }], pagination: {} }; - mock - .onGet(mergeUrlParams({ per_page: DIFFS_PER_PAGE, w: '1', page: 1 }, endpointBatch)) - .reply(200, res1) - .onGet(mergeUrlParams({ per_page: DIFFS_PER_PAGE, w: '1', page: 2 }, endpointBatch)) - .reply(200, res2); - - testAction( - fetchDiffFilesBatch, - {}, - { endpointBatch, useSingleDiffStyle: false, currentDiffFileId: null }, - [ - { type: types.SET_BATCH_LOADING, payload: true }, - { type: types.SET_RETRIEVING_BATCHES, payload: true }, - { type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: res1.diff_files } }, - { type: types.SET_BATCH_LOADING, payload: false }, - { type: types.UPDATE_CURRENT_DIFF_FILE_ID, payload: 'test' }, - { type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: res2.diff_files } }, - { type: types.SET_BATCH_LOADING, payload: false }, - { type: types.UPDATE_CURRENT_DIFF_FILE_ID, payload: 'test2' }, - { type: types.SET_RETRIEVING_BATCHES, payload: false }, - ], - [], - done, - ); - }); - - it.each` - querystrings | requestUrl - ${'?view=parallel'} | ${'/fetch/diffs_batch?view=parallel'} - ${'?view=inline'} | ${'/fetch/diffs_batch?view=inline'} - ${''} | ${'/fetch/diffs_batch'} - `( - 'should use the endpoint $requestUrl if the endpointBatch in state includes `$querystrings` as a querystring', - ({ querystrings, requestUrl }) => { - const endpointBatch = '/fetch/diffs_batch'; - - fetchDiffFilesBatch({ - commit: () => {}, - state: { - endpointBatch: `${endpointBatch}${querystrings}`, - diffViewType: 'inline', - }, - }) - .then(() => { - expect(mock.history.get[0].url).toEqual(requestUrl); - }) - .catch(() => {}); - }, - ); - }); - - describe('fetchDiffFilesMeta', () => { - const endpointMetadata = '/fetch/diffs_metadata.json'; - const noFilesData = { ...diffMetadata }; - let mock; - - beforeEach(() => { - mock = new MockAdapter(axios); - - delete noFilesData.diff_files; - - mock.onGet(endpointMetadata).reply(200, diffMetadata); - }); - it('should fetch diff meta information', done => { - testAction( - fetchDiffFilesMeta, - {}, - { endpointMetadata, useSingleDiffStyle: false }, - [ - { type: types.SET_LOADING, payload: true }, - { type: types.SET_LOADING, payload: false }, - { type: types.SET_MERGE_REQUEST_DIFFS, payload: diffMetadata.merge_request_diffs }, - { type: types.SET_DIFF_DATA, payload: noFilesData }, - ], - [], - () => { - mock.restore(); - done(); - }, - ); - }); - }); - }); - describe('fetchCoverageFiles', () => { let mock; const endpointCoverage = '/fetch'; @@ -589,7 +437,7 @@ describe('DiffsStoreActions', () => { testAction( assignDiscussionsToDiff, [], - { diffFiles: [], useSingleDiffStyle: true }, + { diffFiles: [] }, [], [{ type: 'setCurrentDiffFileIdFromNote', payload: '123' }], done, diff --git a/spec/frontend/diffs/store/mutations_spec.js b/spec/frontend/diffs/store/mutations_spec.js index 70047899612..705005b809c 100644 --- a/spec/frontend/diffs/store/mutations_spec.js +++ b/spec/frontend/diffs/store/mutations_spec.js @@ -11,13 +11,11 @@ describe('DiffsStoreMutations', () => { const state = {}; const endpoint = '/diffs/endpoint'; const projectPath = '/root/project'; - const useSingleDiffStyle = false; - mutations[types.SET_BASE_CONFIG](state, { endpoint, projectPath, useSingleDiffStyle }); + mutations[types.SET_BASE_CONFIG](state, { endpoint, projectPath }); expect(state.endpoint).toEqual(endpoint); expect(state.projectPath).toEqual(projectPath); - expect(state.useSingleDiffStyle).toEqual(useSingleDiffStyle); }); }); diff --git a/spec/frontend/error_tracking/components/error_tracking_list_spec.js b/spec/frontend/error_tracking/components/error_tracking_list_spec.js index bad70a31599..97e6d1781f4 100644 --- a/spec/frontend/error_tracking/components/error_tracking_list_spec.js +++ b/spec/frontend/error_tracking/components/error_tracking_list_spec.js @@ -163,7 +163,7 @@ describe('ErrorTrackingList', () => { it('each error in the list should have an action button set', () => { findErrorListRows().wrappers.forEach(row => { - expect(row.contains(ErrorTrackingActions)).toBe(true); + expect(row.find(ErrorTrackingActions).exists()).toBe(true); }); }); diff --git a/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js b/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js index 204bbfb9c2f..c5155315bb9 100644 --- a/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js +++ b/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js @@ -69,8 +69,8 @@ describe('FrequentItemsSearchInputComponent', () => { describe('template', () => { it('should render component element', () => { expect(wrapper.classes()).toContain('search-input-container'); - expect(wrapper.contains('input.form-control')).toBe(true); - expect(wrapper.contains('.search-icon')).toBe(true); + expect(wrapper.find('input.form-control').exists()).toBe(true); + expect(wrapper.find('.search-icon').exists()).toBe(true); expect(wrapper.find('input.form-control').attributes('placeholder')).toBe( 'Search your projects', ); diff --git a/spec/frontend/import_projects/components/bitbucket_status_table_spec.js b/spec/frontend/import_projects/components/bitbucket_status_table_spec.js index 132ccd0e324..b65b388fd5f 100644 --- a/spec/frontend/import_projects/components/bitbucket_status_table_spec.js +++ b/spec/frontend/import_projects/components/bitbucket_status_table_spec.js @@ -33,7 +33,7 @@ describe('BitbucketStatusTable', () => { it('renders import table component', () => { createComponent({ providerTitle: 'Test' }); - expect(wrapper.contains(ImportProjectsTable)).toBe(true); + expect(wrapper.find(ImportProjectsTable).exists()).toBe(true); }); it('passes alert in incompatible-repos-warning slot', () => { diff --git a/spec/frontend/import_projects/components/import_projects_table_spec.js b/spec/frontend/import_projects/components/import_projects_table_spec.js index a5810431afe..83d27635af9 100644 --- a/spec/frontend/import_projects/components/import_projects_table_spec.js +++ b/spec/frontend/import_projects/components/import_projects_table_spec.js @@ -77,13 +77,13 @@ describe('ImportProjectsTable', () => { it('renders a loading icon while repos are loading', () => { createComponent({ state: { isLoadingRepos: true } }); - expect(wrapper.contains(GlLoadingIcon)).toBe(true); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); it('renders a loading icon while namespaces are loading', () => { createComponent({ state: { isLoadingNamespaces: true } }); - expect(wrapper.contains(GlLoadingIcon)).toBe(true); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); it('renders a table with provider repos', () => { @@ -97,8 +97,8 @@ describe('ImportProjectsTable', () => { state: { namespaces: [{ fullPath: 'path' }], repositories }, }); - expect(wrapper.contains(GlLoadingIcon)).toBe(false); - expect(wrapper.contains('table')).toBe(true); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); + expect(wrapper.find('table').exists()).toBe(true); expect( wrapper .findAll('th') @@ -132,7 +132,7 @@ describe('ImportProjectsTable', () => { it('renders an empty state if there are no projects available', () => { createComponent({ state: { repositories: [] } }); - expect(wrapper.contains(ProviderRepoTableRow)).toBe(false); + expect(wrapper.find(ProviderRepoTableRow).exists()).toBe(false); expect(wrapper.text()).toContain(`No ${providerTitle} repositories found`); }); diff --git a/spec/frontend/import_projects/components/provider_repo_table_row_spec.js b/spec/frontend/import_projects/components/provider_repo_table_row_spec.js index 7a743b5dc04..03e30ef610e 100644 --- a/spec/frontend/import_projects/components/provider_repo_table_row_spec.js +++ b/spec/frontend/import_projects/components/provider_repo_table_row_spec.js @@ -82,7 +82,7 @@ describe('ProviderRepoTableRow', () => { }); it('renders a select2 namespace select', () => { - expect(wrapper.contains(Select2Select)).toBe(true); + expect(wrapper.find(Select2Select).exists()).toBe(true); expect(wrapper.find(Select2Select).props().options.data).toBe(availableNamespaces); }); @@ -133,7 +133,7 @@ describe('ProviderRepoTableRow', () => { }); it('does not renders a namespace select', () => { - expect(wrapper.contains(Select2Select)).toBe(false); + expect(wrapper.find(Select2Select).exists()).toBe(false); }); it('does not render import button', () => { diff --git a/spec/frontend/incidents_settings/components/alerts_form_spec.js b/spec/frontend/incidents_settings/components/alerts_form_spec.js index 32d13b8edc0..2516e8afdfa 100644 --- a/spec/frontend/incidents_settings/components/alerts_form_spec.js +++ b/spec/frontend/incidents_settings/components/alerts_form_spec.js @@ -10,7 +10,6 @@ describe('Alert integration settings form', () => { beforeEach(() => { wrapper = shallowMount(AlertsSettingsForm, { provide: { - glFeatures: { autoCloseIncident: true }, service, alertSettings: { issueTemplateKey: 'selecte_tmpl', diff --git a/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js b/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js index f58825f6297..70ab8fa7bcf 100644 --- a/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js +++ b/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js @@ -57,7 +57,7 @@ describe('JiraIssuesFields', () => { // As per https://vuejs.org/v2/guide/forms.html#Checkbox-1, // browsers don't include unchecked boxes in form submissions. it('includes issues_enabled as false even if unchecked', () => { - expect(wrapper.contains('input[name="service[issues_enabled]"]')).toBe(true); + expect(wrapper.find('input[name="service[issues_enabled]"]').exists()).toBe(true); }); it('disables project_key input', () => { @@ -90,7 +90,7 @@ describe('JiraIssuesFields', () => { it('contains link to editProjectPath', () => { createComponent(); - expect(wrapper.contains(`a[href="${defaultProps.editProjectPath}"]`)).toBe(true); + expect(wrapper.find(`a[href="${defaultProps.editProjectPath}"]`).exists()).toBe(true); }); }); }); diff --git a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js index f6f64dd7fbb..0f88e4d71fe 100644 --- a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js +++ b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js @@ -40,7 +40,7 @@ describe('RelatedIssuesBlock', () => { }); it('add related issues form is hidden', () => { - expect(wrapper.contains('.js-add-related-issues-form-area')).toBe(false); + expect(wrapper.find('.js-add-related-issues-form-area').exists()).toBe(false); }); }); @@ -120,7 +120,7 @@ describe('RelatedIssuesBlock', () => { }); it('shows add related issues form', () => { - expect(wrapper.contains('.js-add-related-issues-form-area')).toBe(true); + expect(wrapper.find('.js-add-related-issues-form-area').exists()).toBe(true); }); }); diff --git a/spec/frontend/issuables_list/components/issuable_list_root_app_spec.js b/spec/frontend/issuables_list/components/issuable_list_root_app_spec.js index aee49076b5d..7aa1c290f61 100644 --- a/spec/frontend/issuables_list/components/issuable_list_root_app_spec.js +++ b/spec/frontend/issuables_list/components/issuable_list_root_app_spec.js @@ -47,7 +47,7 @@ describe('IssuableListRootApp', () => { it('does not show an alert', () => { wrapper = mountComponent(); - expect(wrapper.contains(GlAlert)).toBe(false); + expect(wrapper.find(GlAlert).exists()).toBe(false); }); }); @@ -103,12 +103,12 @@ describe('IssuableListRootApp', () => { shouldShowInProgressAlert: true, }); - expect(wrapper.contains(GlAlert)).toBe(true); + expect(wrapper.find(GlAlert).exists()).toBe(true); findAlert().vm.$emit('dismiss'); return Vue.nextTick(() => { - expect(wrapper.contains(GlAlert)).toBe(false); + expect(wrapper.find(GlAlert).exists()).toBe(false); }); }); }); diff --git a/spec/frontend/issuables_list/components/issuable_spec.js b/spec/frontend/issuables_list/components/issuable_spec.js index c7b7fb2eac1..74be7d87847 100644 --- a/spec/frontend/issuables_list/components/issuable_spec.js +++ b/spec/frontend/issuables_list/components/issuable_spec.js @@ -97,7 +97,7 @@ describe('Issuable component', () => { const findUnscopedLabels = () => findLabels().filter(w => !isScopedLabel({ title: w.text() })); const findIssuableTitle = () => wrapper.find('[data-testid="issuable-title"]'); const findIssuableStatus = () => wrapper.find('[data-testid="issuable-status"]'); - const containsJiraLogo = () => wrapper.contains('[data-testid="jira-logo"]'); + const containsJiraLogo = () => wrapper.find('[data-testid="jira-logo"]').exists(); const findHealthStatus = () => wrapper.find('.health-status'); describe('when mounted', () => { diff --git a/spec/frontend/issuables_list/components/issuables_list_app_spec.js b/spec/frontend/issuables_list/components/issuables_list_app_spec.js index 65b87ddf6a6..9db03c49994 100644 --- a/spec/frontend/issuables_list/components/issuables_list_app_spec.js +++ b/spec/frontend/issuables_list/components/issuables_list_app_spec.js @@ -169,7 +169,7 @@ describe('Issuables list component', () => { it('does not display empty state', () => { expect(wrapper.vm.issuables.length).toBeGreaterThan(0); expect(wrapper.vm.emptyState).toEqual({}); - expect(wrapper.contains(GlEmptyState)).toBe(false); + expect(wrapper.find(GlEmptyState).exists()).toBe(false); }); it('sets the proper page and total items', () => { diff --git a/spec/frontend/issue_show/components/app_spec.js b/spec/frontend/issue_show/components/app_spec.js index f76f42cb9ae..10806499d5e 100644 --- a/spec/frontend/issue_show/components/app_spec.js +++ b/spec/frontend/issue_show/components/app_spec.js @@ -134,7 +134,7 @@ describe('Issuable output', () => { wrapper.vm.showForm = true; return wrapper.vm.$nextTick().then(() => { - expect(wrapper.contains('.markdown-selector')).toBe(true); + expect(wrapper.find('.markdown-selector').exists()).toBe(true); }); }); @@ -143,7 +143,7 @@ describe('Issuable output', () => { wrapper.setProps({ canUpdate: false }); return wrapper.vm.$nextTick().then(() => { - expect(wrapper.contains('.markdown-selector')).toBe(false); + expect(wrapper.find('.markdown-selector').exists()).toBe(false); }); }); @@ -403,7 +403,7 @@ describe('Issuable output', () => { .then(() => { expect(wrapper.vm.formState.lockedWarningVisible).toEqual(true); expect(wrapper.vm.formState.lock_version).toEqual(1); - expect(wrapper.contains('.alert')).toBe(true); + expect(wrapper.find('.alert').exists()).toBe(true); }); }); }); @@ -441,14 +441,14 @@ describe('Issuable output', () => { describe('show inline edit button', () => { it('should not render by default', () => { - expect(wrapper.contains('.btn-edit')).toBe(true); + expect(wrapper.find('.btn-edit').exists()).toBe(true); }); it('should render if showInlineEditButton', () => { wrapper.setProps({ showInlineEditButton: true }); return wrapper.vm.$nextTick(() => { - expect(wrapper.contains('.btn-edit')).toBe(true); + expect(wrapper.find('.btn-edit').exists()).toBe(true); }); }); }); @@ -531,7 +531,7 @@ describe('Issuable output', () => { describe('sticky header', () => { describe('when title is in view', () => { it('is not shown', () => { - expect(wrapper.contains('.issue-sticky-header')).toBe(false); + expect(wrapper.find('.issue-sticky-header').exists()).toBe(false); }); }); diff --git a/spec/frontend/jira_import/components/jira_import_form_spec.js b/spec/frontend/jira_import/components/jira_import_form_spec.js index 6ef28a71f48..39cb63af2f0 100644 --- a/spec/frontend/jira_import/components/jira_import_form_spec.js +++ b/spec/frontend/jira_import/components/jira_import_form_spec.js @@ -100,7 +100,7 @@ describe('JiraImportForm', () => { it('is shown', () => { wrapper = mountComponent(); - expect(wrapper.contains(GlFormSelect)).toBe(true); + expect(wrapper.find(GlFormSelect).exists()).toBe(true); }); it('contains a list of Jira projects to select from', () => { diff --git a/spec/frontend/jobs/components/log/line_header_spec.js b/spec/frontend/jobs/components/log/line_header_spec.js index 5ce69221dab..bb90949b1f4 100644 --- a/spec/frontend/jobs/components/log/line_header_spec.js +++ b/spec/frontend/jobs/components/log/line_header_spec.js @@ -38,7 +38,7 @@ describe('Job Log Header Line', () => { }); it('renders the line number component', () => { - expect(wrapper.contains(LineNumber)).toBe(true); + expect(wrapper.find(LineNumber).exists()).toBe(true); }); it('renders a span the provided text', () => { @@ -90,7 +90,7 @@ describe('Job Log Header Line', () => { }); it('renders the duration badge', () => { - expect(wrapper.contains(DurationBadge)).toBe(true); + expect(wrapper.find(DurationBadge).exists()).toBe(true); }); }); }); diff --git a/spec/frontend/jobs/components/log/line_spec.js b/spec/frontend/jobs/components/log/line_spec.js index ec3a3968f14..c2412a807c3 100644 --- a/spec/frontend/jobs/components/log/line_spec.js +++ b/spec/frontend/jobs/components/log/line_spec.js @@ -35,7 +35,7 @@ describe('Job Log Line', () => { }); it('renders the line number component', () => { - expect(wrapper.contains(LineNumber)).toBe(true); + expect(wrapper.find(LineNumber).exists()).toBe(true); }); it('renders a span the provided text', () => { diff --git a/spec/frontend/jobs/components/log/log_spec.js b/spec/frontend/jobs/components/log/log_spec.js index a6285fe64b5..015d5e01a46 100644 --- a/spec/frontend/jobs/components/log/log_spec.js +++ b/spec/frontend/jobs/components/log/log_spec.js @@ -62,7 +62,11 @@ describe('Job Log', () => { }); it('renders an icon with the open state', () => { - expect(findCollapsibleLine().contains('[data-testid="angle-down-icon"]')).toBe(true); + expect( + findCollapsibleLine() + .find('[data-testid="angle-down-icon"]') + .exists(), + ).toBe(true); }); describe('on click header section', () => { diff --git a/spec/frontend/monitoring/alert_widget_spec.js b/spec/frontend/monitoring/alert_widget_spec.js index 193dbb3e63f..d004b1da0b6 100644 --- a/spec/frontend/monitoring/alert_widget_spec.js +++ b/spec/frontend/monitoring/alert_widget_spec.js @@ -84,7 +84,7 @@ describe('AlertWidget', () => { }, }); }; - const hasLoadingIcon = () => wrapper.contains(GlLoadingIcon); + const hasLoadingIcon = () => wrapper.find(GlLoadingIcon).exists(); const findWidgetForm = () => wrapper.find({ ref: 'widgetForm' }); const findAlertErrorMessage = () => wrapper.find({ ref: 'alertErrorMessage' }); const findCurrentSettingsText = () => diff --git a/spec/frontend/mr_popover/mr_popover_spec.js b/spec/frontend/mr_popover/mr_popover_spec.js index 3f62dca4a57..094d1a6472c 100644 --- a/spec/frontend/mr_popover/mr_popover_spec.js +++ b/spec/frontend/mr_popover/mr_popover_spec.js @@ -61,7 +61,7 @@ describe('MR Popover', () => { }); return wrapper.vm.$nextTick().then(() => { - expect(wrapper.contains(CiIcon)).toBe(false); + expect(wrapper.find(CiIcon).exists()).toBe(false); }); }); }); diff --git a/spec/frontend/packages/details/components/package_title_spec.js b/spec/frontend/packages/details/components/package_title_spec.js index a30dc4b8aba..6c15ecf656e 100644 --- a/spec/frontend/packages/details/components/package_title_spec.js +++ b/spec/frontend/packages/details/components/package_title_spec.js @@ -146,7 +146,11 @@ describe('PackageTitle', () => { it('correctly shows the package ref if there is one', () => { createComponent({ packageEntity: npmPackage }); - expect(packageRef().contains('gl-icon-stub')).toBe(true); + expect( + packageRef() + .find('gl-icon-stub') + .exists(), + ).toBe(true); expect(packageRef().text()).toBe(npmPackage.pipeline.ref); }); }); diff --git a/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js b/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js index e83fb04a688..fbe2274c40d 100644 --- a/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js +++ b/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js @@ -38,16 +38,16 @@ describe('CustomizeHomepageBanner', () => { }); it('should render the banner when not dismissed', () => { - expect(wrapper.contains(GlBanner)).toBe(true); + expect(wrapper.find(GlBanner).exists()).toBe(true); }); it('should close the banner when dismiss is clicked', async () => { mockAxios.onPost(provide.calloutsPath).replyOnce(200); - expect(wrapper.contains(GlBanner)).toBe(true); + expect(wrapper.find(GlBanner).exists()).toBe(true); wrapper.find(GlBanner).vm.$emit('close'); await wrapper.vm.$nextTick(); - expect(wrapper.contains(GlBanner)).toBe(false); + expect(wrapper.find(GlBanner).exists()).toBe(false); }); it('includes the body text from options', () => { diff --git a/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js b/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js index 0bb96ee33d4..67ace608127 100644 --- a/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js +++ b/spec/frontend/pages/import/bitbucket_server/components/bitbucket_server_status_table_spec.js @@ -36,7 +36,7 @@ describe('BitbucketServerStatusTable', () => { it('renders bitbucket status table component', () => { createComponent(); - expect(wrapper.contains(BitbucketStatusTable)).toBe(true); + expect(wrapper.find(BitbucketStatusTable).exists()).toBe(true); }); it('renders Reconfigure button', async () => { diff --git a/spec/frontend/pages/projects/forks/new/components/fork_groups_list_spec.js b/spec/frontend/pages/projects/forks/new/components/fork_groups_list_spec.js index 2ec608569e3..9993e4da980 100644 --- a/spec/frontend/pages/projects/forks/new/components/fork_groups_list_spec.js +++ b/spec/frontend/pages/projects/forks/new/components/fork_groups_list_spec.js @@ -70,7 +70,7 @@ describe('Fork groups list component', () => { replyWith(() => new Promise(() => {})); createWrapper(); - expect(wrapper.contains(GlLoadingIcon)).toBe(true); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); it('displays empty text if no groups are available', async () => { @@ -89,7 +89,7 @@ describe('Fork groups list component', () => { await waitForPromises(); - expect(wrapper.contains(GlSearchBoxByType)).toBe(true); + expect(wrapper.find(GlSearchBoxByType).exists()).toBe(true); }); it('renders list items for each available group', async () => { diff --git a/spec/frontend/pages/projects/graphs/code_coverage_spec.js b/spec/frontend/pages/projects/graphs/code_coverage_spec.js index 54a080fb62b..8884f7815ab 100644 --- a/spec/frontend/pages/projects/graphs/code_coverage_spec.js +++ b/spec/frontend/pages/projects/graphs/code_coverage_spec.js @@ -124,7 +124,7 @@ describe('Code Coverage', () => { }); it('renders the dropdown with all custom names as options', () => { - expect(wrapper.contains(GlDeprecatedDropdown)).toBeDefined(); + expect(wrapper.find(GlDeprecatedDropdown).exists()).toBeDefined(); expect(findAllDropdownItems()).toHaveLength(codeCoverageMockData.length); expect(findFirstDropdownItem().text()).toBe(codeCoverageMockData[0].group_name); }); @@ -150,7 +150,11 @@ describe('Code Coverage', () => { .find(GlIcon) .exists(), ).toBe(false); - expect(findSecondDropdownItem().contains(GlIcon)).toBe(true); + expect( + findSecondDropdownItem() + .find(GlIcon) + .exists(), + ).toBe(true); }); it('updates the graph data when selecting a different option in dropdown', async () => { diff --git a/spec/frontend/pipelines/pipeline_triggerer_spec.js b/spec/frontend/pipelines/pipeline_triggerer_spec.js index 6fd9a143d82..ad8136890e6 100644 --- a/spec/frontend/pipelines/pipeline_triggerer_spec.js +++ b/spec/frontend/pipelines/pipeline_triggerer_spec.js @@ -36,7 +36,7 @@ describe('Pipelines Triggerer', () => { }); it('should render a table cell', () => { - expect(wrapper.contains('.table-section')).toBe(true); + expect(wrapper.find('.table-section').exists()).toBe(true); }); it('should pass triggerer information when triggerer is provided', () => { diff --git a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js index 7fe310aa400..2ea0957b347 100644 --- a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js +++ b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js @@ -26,16 +26,16 @@ describe('ServiceDeskSetting', () => { }); it('should see activation checkbox', () => { - expect(wrapper.contains('#service-desk-checkbox')).toBe(true); + expect(wrapper.find('#service-desk-checkbox').exists()).toBe(true); }); it('should see main panel with the email info', () => { - expect(wrapper.contains('#incoming-email-describer')).toBe(true); + expect(wrapper.find('#incoming-email-describer').exists()).toBe(true); }); it('should see loading spinner and not the incoming email', () => { expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); - expect(wrapper.contains('.incoming-email')).toBe(false); + expect(wrapper.find('.incoming-email').exists()).toBe(false); }); }); }); @@ -78,7 +78,7 @@ describe('ServiceDeskSetting', () => { }); it('renders a copy to clipboard button', () => { - expect(wrapper.contains('.qa-clipboard-button')).toBe(true); + expect(wrapper.find('.qa-clipboard-button').exists()).toBe(true); expect(wrapper.find('.qa-clipboard-button').element.dataset.clipboardText).toBe( incomingEmail, ); @@ -93,7 +93,7 @@ describe('ServiceDeskSetting', () => { }, }); - expect(wrapper.contains('#service-desk-template-select')).toBe(true); + expect(wrapper.find('#service-desk-template-select').exists()).toBe(true); }); it('renders a dropdown with a default value of ""', () => { @@ -202,15 +202,15 @@ describe('ServiceDeskSetting', () => { }); it('does not render email panel', () => { - expect(wrapper.contains('#incoming-email-describer')).toBe(false); + expect(wrapper.find('#incoming-email-describer').exists()).toBe(false); }); it('does not render template dropdown', () => { - expect(wrapper.contains('#service-desk-template-select')).toBe(false); + expect(wrapper.find('#service-desk-template-select').exists()).toBe(false); }); it('does not render template save button', () => { - expect(wrapper.contains('button.btn-success')).toBe(false); + expect(wrapper.find('button.btn-success').exists()).toBe(false); }); it('emits an event to turn on Service Desk when the toggle is clicked', () => { diff --git a/spec/frontend/releases/components/release_block_assets_spec.js b/spec/frontend/releases/components/release_block_assets_spec.js index 5e84290716c..3453ecbf8ab 100644 --- a/spec/frontend/releases/components/release_block_assets_spec.js +++ b/spec/frontend/releases/components/release_block_assets_spec.js @@ -128,7 +128,7 @@ describe('Release block assets', () => { describe('external vs internal links', () => { const containsExternalSourceIndicator = () => - wrapper.contains('[data-testid="external-link-indicator"]'); + wrapper.find('[data-testid="external-link-indicator"]').exists(); describe('when a link is external', () => { beforeEach(() => { diff --git a/spec/frontend/reports/codequality_report/grouped_codequality_reports_app_spec.js b/spec/frontend/reports/codequality_report/grouped_codequality_reports_app_spec.js index 533528e1dca..c9bd040aaf5 100644 --- a/spec/frontend/reports/codequality_report/grouped_codequality_reports_app_spec.js +++ b/spec/frontend/reports/codequality_report/grouped_codequality_reports_app_spec.js @@ -126,7 +126,11 @@ describe('Grouped code quality reports app', () => { }); it('renders a help icon with more information', () => { - expect(findWidget().contains('[data-testid="question-icon"]')).toBe(true); + expect( + findWidget() + .find('[data-testid="question-icon"]') + .exists(), + ).toBe(true); }); }); @@ -140,7 +144,11 @@ describe('Grouped code quality reports app', () => { }); it('does not render a help icon', () => { - expect(findWidget().contains('[data-testid="question-icon"]')).toBe(false); + expect( + findWidget() + .find('[data-testid="question-icon"]') + .exists(), + ).toBe(false); }); }); }); diff --git a/spec/frontend/reports/components/grouped_issues_list_spec.js b/spec/frontend/reports/components/grouped_issues_list_spec.js index 1f8f4a0e4c1..1172e514707 100644 --- a/spec/frontend/reports/components/grouped_issues_list_spec.js +++ b/spec/frontend/reports/components/grouped_issues_list_spec.js @@ -42,7 +42,7 @@ describe('Grouped Issues List', () => { }); it.each('resolved', 'unresolved')('does not render report items for %s issues', () => { - expect(wrapper.contains(ReportItem)).toBe(false); + expect(wrapper.find(ReportItem).exists()).toBe(false); }); }); diff --git a/spec/frontend/sidebar/participants_spec.js b/spec/frontend/sidebar/participants_spec.js index ebe94582588..93c9b3b84c3 100644 --- a/spec/frontend/sidebar/participants_spec.js +++ b/spec/frontend/sidebar/participants_spec.js @@ -37,7 +37,7 @@ describe('Participants', () => { loading: true, }); - expect(wrapper.contains(GlLoadingIcon)).toBe(true); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); it('does not show loading spinner not loading', () => { @@ -45,7 +45,7 @@ describe('Participants', () => { loading: false, }); - expect(wrapper.contains(GlLoadingIcon)).toBe(false); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); }); it('shows participant count when given', () => { @@ -74,7 +74,7 @@ describe('Participants', () => { loading: true, }); - expect(wrapper.contains(GlLoadingIcon)).toBe(true); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); it('when only showing visible participants, shows an avatar only for each participant under the limit', () => { @@ -196,11 +196,11 @@ describe('Participants', () => { }); it('does not show sidebar collapsed icon', () => { - expect(wrapper.contains('.sidebar-collapsed-icon')).toBe(false); + expect(wrapper.find('.sidebar-collapsed-icon').exists()).toBe(false); }); it('does not show participants label title', () => { - expect(wrapper.contains('.title')).toBe(false); + expect(wrapper.find('.title').exists()).toBe(false); }); }); }); diff --git a/spec/frontend/sidebar/subscriptions_spec.js b/spec/frontend/sidebar/subscriptions_spec.js index cce35666985..dddb9c2bba9 100644 --- a/spec/frontend/sidebar/subscriptions_spec.js +++ b/spec/frontend/sidebar/subscriptions_spec.js @@ -100,7 +100,7 @@ describe('Subscriptions', () => { }); it('does not render the toggle button', () => { - expect(wrapper.contains('.js-issuable-subscribe-button')).toBe(false); + expect(wrapper.find('.js-issuable-subscribe-button').exists()).toBe(false); }); }); }); diff --git a/spec/frontend/snippets/components/edit_spec.js b/spec/frontend/snippets/components/edit_spec.js index 25cef3a8045..33152591d42 100644 --- a/spec/frontend/snippets/components/edit_spec.js +++ b/spec/frontend/snippets/components/edit_spec.js @@ -168,10 +168,10 @@ describe('Snippet Edit app', () => { props => { createComponent(props); - expect(wrapper.contains(TitleField)).toBe(true); - expect(wrapper.contains(SnippetDescriptionEdit)).toBe(true); - expect(wrapper.contains(SnippetVisibilityEdit)).toBe(true); - expect(wrapper.contains(FormFooterActions)).toBe(true); + expect(wrapper.find(TitleField).exists()).toBe(true); + expect(wrapper.find(SnippetDescriptionEdit).exists()).toBe(true); + expect(wrapper.find(SnippetVisibilityEdit).exists()).toBe(true); + expect(wrapper.find(FormFooterActions).exists()).toBe(true); expect(findBlobActions().exists()).toBe(true); }, ); diff --git a/spec/frontend/snippets/components/show_spec.js b/spec/frontend/snippets/components/show_spec.js index 24c9600fb53..b5ab7def753 100644 --- a/spec/frontend/snippets/components/show_spec.js +++ b/spec/frontend/snippets/components/show_spec.js @@ -66,7 +66,7 @@ describe('Snippet view app', () => { }, }, }); - expect(wrapper.contains(EmbedDropdown)).toBe(true); + expect(wrapper.find(EmbedDropdown).exists()).toBe(true); }); it('renders correct snippet-blob components', () => { @@ -97,7 +97,7 @@ describe('Snippet view app', () => { }, }, }); - expect(wrapper.contains(EmbedDropdown)).toBe(isRendered); + expect(wrapper.find(EmbedDropdown).exists()).toBe(isRendered); }); }); @@ -119,7 +119,7 @@ describe('Snippet view app', () => { }, }, }); - expect(wrapper.contains(CloneDropdownButton)).toBe(isRendered); + expect(wrapper.find(CloneDropdownButton).exists()).toBe(isRendered); }, ); }); diff --git a/spec/frontend/snippets/components/snippet_visibility_edit_spec.js b/spec/frontend/snippets/components/snippet_visibility_edit_spec.js index a8df13787a5..4ba3e906fc3 100644 --- a/spec/frontend/snippets/components/snippet_visibility_edit_spec.js +++ b/spec/frontend/snippets/components/snippet_visibility_edit_spec.js @@ -96,7 +96,11 @@ describe('Snippet Visibility Edit component', () => { it('when helpLink is not defined, does not render label help link', () => { createComponent({ helpLink: null }); - expect(findLabel().contains(GlLink)).toBe(false); + expect( + findLabel() + .find(GlLink) + .exists(), + ).toBe(false); }); }); diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_container_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_container_spec.js index 932574610c9..4e3e918f7fb 100644 --- a/spec/frontend/vue_mr_widget/components/mr_widget_container_spec.js +++ b/spec/frontend/vue_mr_widget/components/mr_widget_container_spec.js @@ -21,7 +21,7 @@ describe('MrWidgetContainer', () => { factory(); expect(wrapper.classes()).toContain('mr-widget-heading'); - expect(wrapper.contains('.mr-widget-content')).toBe(true); + expect(wrapper.find('.mr-widget-content').exists()).toBe(true); }); it('accepts default slot', () => { @@ -31,7 +31,7 @@ describe('MrWidgetContainer', () => { }, }); - expect(wrapper.contains('.mr-widget-content .test-body')).toBe(true); + expect(wrapper.find('.mr-widget-content .test-body').exists()).toBe(true); }); it('accepts footer slot', () => { @@ -42,7 +42,7 @@ describe('MrWidgetContainer', () => { }, }); - expect(wrapper.contains('.mr-widget-content .test-body')).toBe(true); - expect(wrapper.contains('.test-footer')).toBe(true); + expect(wrapper.find('.mr-widget-content .test-body').exists()).toBe(true); + expect(wrapper.find('.test-footer').exists()).toBe(true); }); }); diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_expandable_section_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_expandable_section_spec.js index 69a50899d4d..3e111cd308a 100644 --- a/spec/frontend/vue_mr_widget/components/mr_widget_expandable_section_spec.js +++ b/spec/frontend/vue_mr_widget/components/mr_widget_expandable_section_spec.js @@ -18,7 +18,7 @@ describe('MrWidgetExpanableSection', () => { }); it('renders Icon', () => { - expect(wrapper.contains(GlIcon)).toBe(true); + expect(wrapper.find(GlIcon).exists()).toBe(true); }); it('renders header slot', () => { diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js index c3a16a776a7..19f8a67d066 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js @@ -148,8 +148,8 @@ describe('MRWidgetConflicts', () => { }, }); - expect(vm.contains('.js-resolve-conflicts-button')).toBe(false); - expect(vm.contains('.js-merge-locally-button')).toBe(false); + expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false); + expect(vm.find('.js-merge-locally-button').exists()).toBe(false); }); it('should not have resolve button when no conflict resolution path', () => { @@ -161,7 +161,7 @@ describe('MRWidgetConflicts', () => { }, }); - expect(vm.contains('.js-resolve-conflicts-button')).toBe(false); + expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false); }); }); diff --git a/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js b/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js index ffcf9b1477a..7dfb265c035 100644 --- a/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js +++ b/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js @@ -49,8 +49,8 @@ describe('MrWidgetTerraformConainer', () => { }); it('diplays loading skeleton', () => { - expect(wrapper.contains(GlSkeletonLoading)).toBe(true); - expect(wrapper.contains(MrWidgetExpanableSection)).toBe(false); + expect(wrapper.find(GlSkeletonLoading).exists()).toBe(true); + expect(wrapper.find(MrWidgetExpanableSection).exists()).toBe(false); }); }); @@ -61,8 +61,8 @@ describe('MrWidgetTerraformConainer', () => { }); it('displays terraform content', () => { - expect(wrapper.contains(GlSkeletonLoading)).toBe(false); - expect(wrapper.contains(MrWidgetExpanableSection)).toBe(true); + expect(wrapper.find(GlSkeletonLoading).exists()).toBe(false); + expect(wrapper.find(MrWidgetExpanableSection).exists()).toBe(true); expect(findPlans()).toEqual(Object.values(plans)); }); @@ -156,7 +156,7 @@ describe('MrWidgetTerraformConainer', () => { }); it('stops loading', () => { - expect(wrapper.contains(GlSkeletonLoading)).toBe(false); + expect(wrapper.find(GlSkeletonLoading).exists()).toBe(false); }); it('generates one broken plan', () => { diff --git a/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js b/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js index 5cf42ecdc1d..22643a17b2b 100644 --- a/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js +++ b/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js @@ -36,6 +36,6 @@ describe('Blob Rich Viewer component', () => { }); it('is using Markdown View Field', () => { - expect(wrapper.contains(MarkdownFieldView)).toBe(true); + expect(wrapper.find(MarkdownFieldView).exists()).toBe(true); }); }); diff --git a/spec/frontend/vue_shared/components/clone_dropdown_spec.js b/spec/frontend/vue_shared/components/clone_dropdown_spec.js index d9829874b93..1354578cc64 100644 --- a/spec/frontend/vue_shared/components/clone_dropdown_spec.js +++ b/spec/frontend/vue_shared/components/clone_dropdown_spec.js @@ -40,7 +40,7 @@ describe('Clone Dropdown Button', () => { createComponent(); const group = wrapper.findAll(GlFormInputGroup).at(index); expect(group.props('value')).toBe(value); - expect(group.contains(GlFormInputGroup)).toBe(true); + expect(group.find(GlFormInputGroup).exists()).toBe(true); }); it.each` diff --git a/spec/frontend/vue_shared/components/file_row_spec.js b/spec/frontend/vue_shared/components/file_row_spec.js index 1acd2e05464..c5917249f0a 100644 --- a/spec/frontend/vue_shared/components/file_row_spec.js +++ b/spec/frontend/vue_shared/components/file_row_spec.js @@ -118,7 +118,7 @@ describe('File row component', () => { level: 0, }); - expect(wrapper.contains(FileHeader)).toBe(true); + expect(wrapper.find(FileHeader).exists()).toBe(true); }); it('matches the current route against encoded file URL', () => { diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js index 73dbecadd89..440a93eaf64 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js @@ -52,10 +52,10 @@ describe('FilteredSearchBarRoot', () => { expect(wrapper.vm.filterValue).toEqual([]); expect(wrapper.vm.selectedSortOption).toBe(mockSortOptions[0].sortDirection.descending); expect(wrapper.vm.selectedSortDirection).toBe(SortDirection.descending); - expect(wrapper.contains(GlButtonGroup)).toBe(true); - expect(wrapper.contains(GlButton)).toBe(true); - expect(wrapper.contains(GlDropdown)).toBe(true); - expect(wrapper.contains(GlDropdownItem)).toBe(true); + expect(wrapper.find(GlButtonGroup).exists()).toBe(true); + expect(wrapper.find(GlButton).exists()).toBe(true); + expect(wrapper.find(GlDropdown).exists()).toBe(true); + expect(wrapper.find(GlDropdownItem).exists()).toBe(true); }); it('does not initialize `selectedSortOption` and `selectedSortDirection` when `sortOptions` is not applied and hides the sort dropdown', () => { @@ -63,10 +63,10 @@ describe('FilteredSearchBarRoot', () => { expect(wrapperNoSort.vm.filterValue).toEqual([]); expect(wrapperNoSort.vm.selectedSortOption).toBe(undefined); - expect(wrapperNoSort.contains(GlButtonGroup)).toBe(false); - expect(wrapperNoSort.contains(GlButton)).toBe(false); - expect(wrapperNoSort.contains(GlDropdown)).toBe(false); - expect(wrapperNoSort.contains(GlDropdownItem)).toBe(false); + expect(wrapperNoSort.find(GlButtonGroup).exists()).toBe(false); + expect(wrapperNoSort.find(GlButton).exists()).toBe(false); + expect(wrapperNoSort.find(GlDropdown).exists()).toBe(false); + expect(wrapperNoSort.find(GlDropdownItem).exists()).toBe(false); }); }); diff --git a/spec/frontend/vue_shared/components/notes/timeline_entry_item_spec.js b/spec/frontend/vue_shared/components/notes/timeline_entry_item_spec.js index 36099d108f6..bd4b6a463ab 100644 --- a/spec/frontend/vue_shared/components/notes/timeline_entry_item_spec.js +++ b/spec/frontend/vue_shared/components/notes/timeline_entry_item_spec.js @@ -19,7 +19,7 @@ describe(`TimelineEntryItem`, () => { expect(wrapper.classes()).toContain('timeline-entry'); - expect(wrapper.contains('.timeline-entry-inner')).toBe(true); + expect(wrapper.find('.timeline-entry-inner').exists()).toBe(true); }); it('accepts default slot', () => { diff --git a/spec/frontend/vue_shared/components/paginated_list_spec.js b/spec/frontend/vue_shared/components/paginated_list_spec.js index 46e45296c37..c0ee49f194f 100644 --- a/spec/frontend/vue_shared/components/paginated_list_spec.js +++ b/spec/frontend/vue_shared/components/paginated_list_spec.js @@ -48,7 +48,7 @@ describe('Pagination links component', () => { describe('rendering', () => { it('it renders the gl-paginated-list', () => { - expect(wrapper.contains('ul.list-group')).toBe(true); + expect(wrapper.find('ul.list-group').exists()).toBe(true); expect(wrapper.findAll('li.list-group-item').length).toBe(2); }); }); diff --git a/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js b/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js index 385134c4a3f..d0a602cb950 100644 --- a/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js +++ b/spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js @@ -29,7 +29,7 @@ describe('ProjectListItem component', () => { it('does not render a check mark icon if selected === false', () => { wrapper = shallowMount(Component, options); - expect(wrapper.contains('.js-selected-icon.js-unselected')).toBe(true); + expect(wrapper.find('.js-selected-icon.js-unselected').exists()).toBe(true); }); it('renders a check mark icon if selected === true', () => { @@ -37,7 +37,7 @@ describe('ProjectListItem component', () => { wrapper = shallowMount(Component, options); - expect(wrapper.contains('.js-selected-icon.js-selected')).toBe(true); + expect(wrapper.find('.js-selected-icon.js-selected').exists()).toBe(true); }); it(`emits a "clicked" event when clicked`, () => { @@ -53,7 +53,7 @@ describe('ProjectListItem component', () => { it(`renders the project avatar`, () => { wrapper = shallowMount(Component, options); - expect(wrapper.contains('.js-project-avatar')).toBe(true); + expect(wrapper.find('.js-project-avatar').exists()).toBe(true); }); it(`renders a simple namespace name with a trailing slash`, () => { diff --git a/spec/frontend/vue_shared/components/remove_member_modal_spec.js b/spec/frontend/vue_shared/components/remove_member_modal_spec.js index 2d380b25a0a..78fe6d53eee 100644 --- a/spec/frontend/vue_shared/components/remove_member_modal_spec.js +++ b/spec/frontend/vue_shared/components/remove_member_modal_spec.js @@ -48,7 +48,7 @@ describe('RemoveMemberModal', () => { }); it(`${checkboxTestDescription}`, () => { - expect(wrapper.contains(GlFormCheckbox)).toBe(checkboxExpected); + expect(wrapper.find(GlFormCheckbox).exists()).toBe(checkboxExpected); }); it('submits the form when the modal is submitted', () => { diff --git a/spec/lib/gitlab/ci/config/normalizer/matrix_strategy_spec.rb b/spec/lib/gitlab/ci/config/normalizer/matrix_strategy_spec.rb index bab604c4504..81f17e0f528 100644 --- a/spec/lib/gitlab/ci/config/normalizer/matrix_strategy_spec.rb +++ b/spec/lib/gitlab/ci/config/normalizer/matrix_strategy_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'fast_spec_helper' +require 'spec_helper' RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do describe '.applies_to?' do @@ -39,64 +39,114 @@ RSpec.describe Gitlab::Ci::Config::Normalizer::MatrixStrategy do it { expect(subject.size).to eq(4) } - it 'has attributes' do - expect(subject.map(&:attributes)).to match_array( - [ - { - name: 'test 1/4', - instance: 1, - parallel: { total: 4 }, - variables: { - 'PROVIDER' => 'aws', - 'STACK' => 'app1' - } - }, - { - name: 'test 2/4', - instance: 2, - parallel: { total: 4 }, - variables: { - 'PROVIDER' => 'aws', - 'STACK' => 'app2' - } - }, - { - name: 'test 3/4', - instance: 3, - parallel: { total: 4 }, - variables: { - 'PROVIDER' => 'ovh', - 'STACK' => 'app' - } - }, - { - name: 'test 4/4', - instance: 4, - parallel: { total: 4 }, - variables: { - 'PROVIDER' => 'gcp', - 'STACK' => 'app' + context 'with new_matrix_job_names_enabled ff disabled' do + before do + stub_feature_flags(ci_matrix_job_names: false) + end + + it 'has attributes' do + expect(subject.map(&:attributes)).to match_array( + [ + { + name: 'test 1/4', + instance: 1, + parallel: { total: 4 }, + variables: { + 'PROVIDER' => 'aws', + 'STACK' => 'app1' + } + }, + { + name: 'test 2/4', + instance: 2, + parallel: { total: 4 }, + variables: { + 'PROVIDER' => 'aws', + 'STACK' => 'app2' + } + }, + { + name: 'test 3/4', + instance: 3, + parallel: { total: 4 }, + variables: { + 'PROVIDER' => 'ovh', + 'STACK' => 'app' + } + }, + { + name: 'test 4/4', + instance: 4, + parallel: { total: 4 }, + variables: { + 'PROVIDER' => 'gcp', + 'STACK' => 'app' + } } - } - ] - ) - end + ] + ) + end - it 'has parallelized name' do - expect(subject.map(&:name)).to match_array( - ['test 1/4', 'test 2/4', 'test 3/4', 'test 4/4'] - ) + it 'has parallelized name' do + expect(subject.map(&:name)).to match_array( + ['test 1/4', 'test 2/4', 'test 3/4', 'test 4/4'] + ) + end end - it 'has details' do - expect(subject.map(&:name_with_details)).to match_array( - [ - 'test (PROVIDER=aws; STACK=app1)', - 'test (PROVIDER=aws; STACK=app2)', - 'test (PROVIDER=gcp; STACK=app)', - 'test (PROVIDER=ovh; STACK=app)' - ] - ) + context 'with new_matrix_job_names_enabled ff enabled' do + before do + stub_feature_flags(ci_matrix_job_names: true) + end + + it 'has attributes' do + expect(subject.map(&:attributes)).to match_array( + [ + { + name: 'test: [aws, app1]', + instance: 1, + parallel: { total: 4 }, + variables: { + 'PROVIDER' => 'aws', + 'STACK' => 'app1' + } + }, + { + name: 'test: [aws, app2]', + instance: 2, + parallel: { total: 4 }, + variables: { + 'PROVIDER' => 'aws', + 'STACK' => 'app2' + } + }, + { + name: 'test: [ovh, app]', + instance: 3, + parallel: { total: 4 }, + variables: { + 'PROVIDER' => 'ovh', + 'STACK' => 'app' + } + }, + { + name: 'test: [gcp, app]', + instance: 4, + parallel: { total: 4 }, + variables: { + 'PROVIDER' => 'gcp', + 'STACK' => 'app' + } + } + ] + ) + end + + it 'has parallelized name' do + expect(subject.map(&:name)).to match_array( + ['test: [aws, app1]', 'test: [aws, app2]', 'test: [gcp, app]', 'test: [ovh, app]'] + ) + end end end end diff --git a/spec/lib/gitlab/ci/config/normalizer_spec.rb b/spec/lib/gitlab/ci/config/normalizer_spec.rb index 949af8cdc4c..75e6abf68de 100644 --- a/spec/lib/gitlab/ci/config/normalizer_spec.rb +++ b/spec/lib/gitlab/ci/config/normalizer_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'fast_spec_helper' +require 'spec_helper' RSpec.describe Gitlab::Ci::Config::Normalizer do let(:job_name) { :rspec } @@ -178,39 +178,28 @@ RSpec.describe Gitlab::Ci::Config::Normalizer do { matrix: [ { - VAR_1: [1], - VAR_2: [2, 3] + VAR_1: ['A'], + VAR_2: %w[B C] } ] } end - let(:expanded_job_names) do - [ - 'rspec 1/2', - 'rspec 2/2' - ] - end - it 'does not have original job' do is_expected.not_to include(job_name) end - it 'has parallelized jobs' do - is_expected.to include(*expanded_job_names.map(&:to_sym)) - end - it 'sets job instance in options' do expect(subject.values).to all(include(:instance)) end it 'sets job variables', :aggregate_failures do expect(subject.values[0]).to match( - a_hash_including(variables: { VAR_1: 1, VAR_2: 2, USER_VARIABLE: 'user value' }) + a_hash_including(variables: { VAR_1: 'A', VAR_2: 'B', USER_VARIABLE: 'user value' }) ) expect(subject.values[1]).to match( - a_hash_including(variables: { VAR_1: 1, VAR_2: 3, USER_VARIABLE: 'user value' }) + a_hash_including(variables: { VAR_1: 'A', VAR_2: 'C', USER_VARIABLE: 'user value' }) ) end @@ -226,8 +215,45 @@ RSpec.describe Gitlab::Ci::Config::Normalizer do expect(configs).to all(match(a_hash_including(original_config))) end - it_behaves_like 'parallel dependencies' - it_behaves_like 'parallel needs' + context 'with new_matrix_job_names_enabled ff enabled' do + let(:expanded_job_names) do + [ + 'rspec: [A, B]', + 'rspec: [A, C]' + ] + end + + before do + stub_feature_flags(ci_matrix_job_names: true) + end + + it 'has parallelized jobs' do + is_expected.to include(*expanded_job_names.map(&:to_sym)) + end + + it_behaves_like 'parallel dependencies' + it_behaves_like 'parallel needs' + end + + context 'with new_matrix_job_names_enabled ff disabled' do + let(:expanded_job_names) do + [ + 'rspec 1/2', + 'rspec 2/2' + ] + end + + before do + stub_feature_flags(ci_matrix_job_names: false) + end + + it 'has parallelized jobs' do + is_expected.to include(*expanded_job_names.map(&:to_sym)) + end + + it_behaves_like 'parallel dependencies' + it_behaves_like 'parallel needs' + end end context 'when parallel config does not matches a factory' do diff --git a/spec/lib/gitlab/ci/status/composite_spec.rb b/spec/lib/gitlab/ci/status/composite_spec.rb index e1dcd05373f..bcfb9f19792 100644 --- a/spec/lib/gitlab/ci/status/composite_spec.rb +++ b/spec/lib/gitlab/ci/status/composite_spec.rb @@ -20,7 +20,7 @@ RSpec.describe Gitlab::Ci::Status::Composite do shared_examples 'compares status and warnings' do let(:composite_status) do - described_class.new(all_statuses) + described_class.new(all_statuses, dag: dag) end it 'returns status and warnings?' do @@ -30,21 +30,29 @@ RSpec.describe Gitlab::Ci::Status::Composite do end context 'allow_failure: false' do - where(:build_statuses, :result, :has_warnings) do - %i(skipped) | 'skipped' | false - %i(skipped success) | 'success' | false - %i(created) | 'created' | false - %i(preparing) | 'preparing' | false - %i(canceled success skipped) | 'canceled' | false - %i(pending created skipped) | 'pending' | false - %i(pending created skipped success) | 'running' | false - %i(running created skipped success) | 'running' | false - %i(success waiting_for_resource) | 'waiting_for_resource' | false - %i(success manual) | 'manual' | false - %i(success scheduled) | 'scheduled' | false - %i(created preparing) | 'preparing' | false - %i(created success pending) | 'running' | false - %i(skipped success failed) | 'failed' | false + where(:build_statuses, :dag, :result, :has_warnings) do + %i(skipped) | false | 'skipped' | false + %i(skipped success) | false | 'success' | false + %i(skipped success) | true | 'skipped' | false + %i(created) | false | 'created' | false + %i(preparing) | false | 'preparing' | false + %i(canceled success skipped) | false | 'canceled' | false + %i(canceled success skipped) | true | 'skipped' | false + %i(pending created skipped) | false | 'pending' | false + %i(pending created skipped success) | false | 'running' | false + %i(running created skipped success) | false | 'running' | false + %i(pending created skipped) | true | 'skipped' | false + %i(pending created skipped success) | true | 'skipped' | false + %i(running created skipped success) | true | 'skipped' | false + %i(success waiting_for_resource) | false | 'waiting_for_resource' | false + %i(success manual) | false | 'manual' | false + %i(success scheduled) | false | 'scheduled' | false + %i(created preparing) | false | 'preparing' | false + %i(created success pending) | false | 'running' | false + %i(skipped success failed) | false | 'failed' | false + %i(skipped success failed) | true | 'skipped' | false + %i(success manual) | true | 'pending' | false + %i(success failed created) | true | 'pending' | false end with_them do @@ -57,11 +65,12 @@ RSpec.describe Gitlab::Ci::Status::Composite do end context 'allow_failure: true' do - where(:build_statuses, :result, :has_warnings) do - %i(manual) | 'skipped' | false - %i(skipped failed) | 'success' | true - %i(created failed) | 'created' | true - %i(preparing manual) | 'preparing' | false + where(:build_statuses, :dag, :result, :has_warnings) do + %i(manual) | false | 'skipped' | false + %i(skipped failed) | false | 'success' | true + %i(skipped failed) | true | 'skipped' | true + %i(created failed) | false | 'created' | true + %i(preparing manual) | false | 'preparing' | false end with_them do diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 4bbb64c8e4a..b3074f3655e 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -194,6 +194,45 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ) end + it 'includes project imports usage data' do + for_defined_days_back do + user = create(:user) + + %w(gitlab_project gitlab github bitbucket bitbucket_server gitea git manifest).each do |type| + create(:project, import_type: type, creator_id: user.id) + end + end + + expect(described_class.usage_activity_by_stage_manage({})).to include( + { + projects_imported: { + gitlab_project: 2, + gitlab: 2, + github: 2, + bitbucket: 2, + bitbucket_server: 2, + gitea: 2, + git: 2, + manifest: 2 + } + } + ) + expect(described_class.usage_activity_by_stage_manage(described_class.last_28_days_time_period)).to include( + { + projects_imported: { + gitlab_project: 1, + gitlab: 1, + github: 1, + bitbucket: 1, + bitbucket_server: 1, + gitea: 1, + git: 1, + manifest: 1 + } + } + ) + end + def omniauth_providers [ OpenStruct.new(name: 'google_oauth2'), @@ -417,6 +456,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do expect(count_data[:project_snippets]).to eq(4) expect(count_data[:projects_with_packages]).to eq(2) + expect(count_data[:packages]).to eq(3) end it 'gathers object store usage correctly' do @@ -1020,6 +1060,32 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do end end + describe '.search_unique_visits_data' do + subject { described_class.search_unique_visits_data } + + before do + described_class.clear_memoization(:unique_visit_service) + events = ::Gitlab::UsageDataCounters::HLLRedisCounter.events_for_category('search') + events.each do |event| + allow(::Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:unique_events).with(event_names: event, start_date: 7.days.ago.to_date, end_date: Date.current).and_return(123) + end + allow(::Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:unique_events).with(event_names: events, start_date: 7.days.ago.to_date, end_date: Date.current).and_return(543) + allow(::Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:unique_events).with(event_names: events, start_date: 4.weeks.ago.to_date, end_date: Date.current).and_return(987) + end + + it 'returns the number of unique visits to pages with search features' do + expect(subject).to eq({ + search_unique_visits: { + 'i_search_total' => 123, + 'i_search_advanced' => 123, + 'i_search_paid' => 123, + 'search_unique_visits_for_any_target_weekly' => 543, + 'search_unique_visits_for_any_target_monthly' => 987 + } + }) + end + end + describe '.service_desk_counts' do subject { described_class.send(:service_desk_counts) } diff --git a/spec/requests/projects/metrics_dashboard_spec.rb b/spec/requests/projects/metrics_dashboard_spec.rb index f571e4a4309..f35af571e79 100644 --- a/spec/requests/projects/metrics_dashboard_spec.rb +++ b/spec/requests/projects/metrics_dashboard_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe 'metrics dashboard page' do +RSpec.describe 'Projects::MetricsDashboardController' do let_it_be(:project) { create(:project) } let_it_be(:environment) { create(:environment, project: project) } let_it_be(:environment2) { create(:environment, project: project) } @@ -16,12 +16,12 @@ RSpec.describe 'metrics dashboard page' do describe 'GET /:namespace/:project/-/metrics' do it 'returns 200' do send_request - expect(response).to have_gitlab_http_status(:ok) + expect(response).to redirect_to(dashboard_route(environment: environment)) end - it 'assigns environment' do + it 'assigns default_environment' do send_request - expect(assigns(:environment).id).to eq(environment.id) + expect(assigns(:default_environment).id).to eq(environment.id) end context 'with anonymous user and public dashboard visibility' do @@ -64,12 +64,12 @@ RSpec.describe 'metrics dashboard page' do let(:dashboard_path) { '.gitlab/dashboards/dashboard_path.yml' } it 'returns 200' do - send_request(dashboard_path: dashboard_path) + send_request(dashboard_path: dashboard_path, environment: environment.id) expect(response).to have_gitlab_http_status(:ok) end it 'assigns environment' do - send_request(dashboard_path: dashboard_path) + send_request(dashboard_path: dashboard_path, environment: environment.id) expect(assigns(:environment).id).to eq(environment.id) end end @@ -98,14 +98,14 @@ RSpec.describe 'metrics dashboard page' do describe 'GET :/namespace/:project/-/metrics/:page' do it 'returns 200 with path param page' do # send_request(page: 'panel/new') cannot be used because it encodes '/' - get "#{dashboard_route}/panel/new" + get "#{dashboard_route}/panel/new?environment=#{environment.id}" expect(response).to have_gitlab_http_status(:ok) end it 'returns 200 with dashboard and path param page' do # send_request(page: 'panel/new') cannot be used because it encodes '/' - get "#{dashboard_route(dashboard_path: 'dashboard.yml')}/panel/new" + get "#{dashboard_route(dashboard_path: 'dashboard.yml')}/panel/new?environment=#{environment.id}" expect(response).to have_gitlab_http_status(:ok) end diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds_deploy_needs_one_build_and_test.yml b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds_deploy_needs_one_build_and_test.yml index a133023b12d..ef4ddff9b64 100644 --- a/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds_deploy_needs_one_build_and_test.yml +++ b/spec/services/ci/pipeline_processing/test_cases/dag_build_fails_other_build_succeeds_deploy_needs_one_build_and_test.yml @@ -47,16 +47,13 @@ transitions: - event: drop jobs: [build_2] expect: - pipeline: running + pipeline: failed stages: build: failed test: skipped - deploy: pending + deploy: skipped jobs: build_1: success build_2: failed test: skipped - deploy: pending - -# TODO: should we run deploy? -# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080 + deploy: skipped diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure_deploy_needs_one_build_and_test.yml b/spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure_deploy_needs_one_build_and_test.yml index f324525bd56..29c1562389c 100644 --- a/spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure_deploy_needs_one_build_and_test.yml +++ b/spec/services/ci/pipeline_processing/test_cases/dag_builds_succeed_test_on_failure_deploy_needs_one_build_and_test.yml @@ -34,30 +34,13 @@ transitions: - event: success jobs: [build_1, build_2] expect: - pipeline: running - stages: - build: success - test: skipped - deploy: pending - jobs: - build_1: success - build_2: success - test: skipped - deploy: pending - - - event: success - jobs: [deploy] - expect: pipeline: success stages: build: success test: skipped - deploy: success + deploy: skipped jobs: build_1: success build_2: success test: skipped - deploy: success - -# TODO: should we run deploy? -# Further discussions: https://gitlab.com/gitlab-org/gitlab/-/issues/213080 + deploy: skipped diff --git a/spec/support/shared_examples/controllers/unique_hll_events_examples.rb b/spec/support/shared_examples/controllers/unique_hll_events_examples.rb new file mode 100644 index 00000000000..ff86d44f5e8 --- /dev/null +++ b/spec/support/shared_examples/controllers/unique_hll_events_examples.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'tracking unique hll events' do |method| + it 'tracks unique event if the format is HTML' do + expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event).with(instance_of(String), target_id) + + get method, params: request_params, format: :html + end + + it 'tracks unique event if DNT is not enabled' do + expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event).with(instance_of(String), target_id) + request.headers['DNT'] = '0' + + get method, params: request_params, format: :html + end + + it 'does not track unique event if DNT is enabled' do + expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event).with(instance_of(String), target_id) + request.headers['DNT'] = '1' + + get method, params: request_params, format: :html + end + + it 'does not track unique event if the format is JSON' do + expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event).with(instance_of(String), target_id) + + get method, params: request_params, format: :json + end +end diff --git a/spec/support/shared_examples/path_extraction_shared_examples.rb b/spec/support/shared_examples/path_extraction_shared_examples.rb index ff55bc9a490..39c7c1f2a94 100644 --- a/spec/support/shared_examples/path_extraction_shared_examples.rb +++ b/spec/support/shared_examples/path_extraction_shared_examples.rb @@ -146,20 +146,6 @@ RSpec.shared_examples 'extracts refs' do expect(extract_ref('release/app/doc/README.md')).to eq(['release/app', 'doc/README.md']) end - - context 'when the extracts_path_optimization feature flag is disabled' do - before do - stub_feature_flags(extracts_path_optimization: false) - end - - it 'always fetches all ref names' do - expect(self).to receive(:ref_names).and_call_original - expect(container.repository).not_to receive(:branch_names_include?) - expect(container.repository).not_to receive(:tag_names_include?) - - expect(extract_ref('v1.0.0/doc/README.md')).to eq(['v1.0.0', 'doc/README.md']) - end - end end context 'when the repository has ambiguous refs' do diff --git a/spec/support/shared_examples/serializers/diff_file_entity_shared_examples.rb b/spec/support/shared_examples/serializers/diff_file_entity_shared_examples.rb index 1ef08de31a9..7608f1c7f8a 100644 --- a/spec/support/shared_examples/serializers/diff_file_entity_shared_examples.rb +++ b/spec/support/shared_examples/serializers/diff_file_entity_shared_examples.rb @@ -57,16 +57,6 @@ RSpec.shared_examples 'diff file entity' do expect(subject).to include(:highlighted_diff_lines) end end - - context 'when the `single_mr_diff_view` feature is disabled' do - before do - stub_feature_flags(single_mr_diff_view: false) - end - - it 'contains both kinds of diffs' do - expect(subject).to include(:highlighted_diff_lines, :parallel_diff_lines) - end - end end end diff --git a/yarn.lock b/yarn.lock index 93d7859acbd..50dbab0db5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -848,10 +848,10 @@ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.161.0.tgz#661e8d19862dfba0e4c558e2eb6d64b402c1453e" integrity sha512-qsbboEICn08ZoEoAX/TuYygsFaXlzsCY+CfmdOzqvJbOdfHhVXmrJBxd2hP2qqjTZm2PkbRRmn+03+ce1jvatQ== -"@gitlab/ui@20.10.0": - version "20.10.0" - resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-20.10.0.tgz#5efdb5394d7cc8c95ce4bc5ec5b85d33e15b41d6" - integrity sha512-A6SDIZb7Vgj+k5iYKNLMYOp61bWFhjtsab2u3Z32sgx7GkOIZo5dB9ILJHBlLvZ5oOfQ/7Ch+3FmhGxsDjRIuQ== +"@gitlab/ui@20.11.0": + version "20.11.0" + resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-20.11.0.tgz#6570ca518195b05e14861df5ea6a319d4dbe2298" + integrity sha512-vFR/xFx/D7ndRDDoqHQ8GH/YU4lCE3P3eXR3mlpNIMxgak3MuS9w9tfu78z4fRT6gTWuBZEkeoZnjZBgQewqKQ== dependencies: "@babel/standalone" "^7.0.0" "@gitlab/vue-toasted" "^1.3.0" |