提交 f0c0458b 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 c4b69460
......@@ -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) {
......
......@@ -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
......
......@@ -41,5 +41,4 @@ export default () => ({
fileFinderVisible: false,
dismissEndpoint: '',
showSuggestPopover: true,
useSingleDiffStyle: false,
});
......@@ -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,
});
},
......
......@@ -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
......
......@@ -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>
......
# 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
......@@ -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)
......
......@@ -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
......@@ -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
......
......@@ -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')
......@@ -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,
......
......@@ -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
......
......@@ -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
......
- breadcrumb_title _("Instance Statistics")
- page_title _("Instance Statistics")
#js-instance-statistics-app
......@@ -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
......
......@@ -20,6 +20,11 @@
&middot;
= 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
&middot;
%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)
---
title: Adds package count to usage data
merge_request: 40039
author:
type: added
---
title: Fix skipped status of DAG pipelines
merge_request: 39205
author:
type: fixed
---
title: Remove auto close incident feature flag
merge_request: 40612
author:
type: changed
---
title: Add the unique search visits data to the usage ping
merge_request: 40134
author:
type: changed
---
title: Show the comment authored time in comment search results
merge_request: 40472
author:
type: added
---
title: Add usage pings for project import using various importers (GitLab, Bitbucket, Gitea, GitHub and more)
merge_request: 40130
author:
type: added
---
title: Reduce Redis usage when viewing repositories with lots of branches and tags
merge_request: 40615
author:
type: performance
---
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
---
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
---
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
---
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
# 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
35c37b8dcdca08d48086dc8164c2f6a69f563366ec9bce1f60299978a94de9bc
\ No newline at end of file
......@@ -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);
......
......@@ -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)**
......
......@@ -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?
......
......@@ -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
......
......@@ -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
......
......@@ -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'
......
......@@ -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
......
......@@ -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
......@@ -13243,6 +13243,9 @@ msgstr[1] ""
msgid "Instance Configuration"
msgstr ""
msgid "Instance Statistics"
msgstr ""
msgid "Instance administrators group already exists"
msgstr ""
......
......@@ -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
......
......@@ -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)
......
......@@ -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)
......
......@@ -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);
});
});
......
......@@ -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', () => {
......
......@@ -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);
},
);
......
......@@ -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', () => {
......
......@@ -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', () => {
......
......@@ -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);
});
});
......@@ -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);
});
});
......
......@@ -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);
});
});
......
......@@ -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);
});
});
});
......
......@@ -168,7 +168,7 @@ describe('FluentdOutputSettings', () => {
});
it('displays a error message', () => {
expect(wrapper.contains(GlAlert)).toBe(true);
expect(wrapper.find(GlAlert).exists()).toBe(true);
});
});
});
......
......@@ -45,7 +45,7 @@ describe('ClustersAncestorNotice', () => {
});
it('displays link', () => {
expect(wrapper.contains(GlLink)).toBe(true);
expect(wrapper.find(GlLink).exists()).toBe(true);
});
});
});
......@@ -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', () => {
......
......@@ -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', () => {
......
......@@ -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,
......
......@@ -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);
});
});
......
......@@ -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);
});
});
......
......@@ -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',
);
......
......@@ -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', () => {
......
......@@ -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`);
});
......
......@@ -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', () => {
......
......@@ -10,7 +10,6 @@ describe('Alert integration settings form', () => {
beforeEach(() => {
wrapper = shallowMount(AlertsSettingsForm, {
provide: {
glFeatures: { autoCloseIncident: true },
service,
alertSettings: {
issueTemplateKey: 'selecte_tmpl',
......
......@@ -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);
});
});
});
......@@ -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);
});
});
......
......@@ -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);
});
});
});
......
......@@ -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', () => {
......
......@@ -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', () => {
......
......@@ -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);
});
});
......
......@@ -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', () => {
......
......@@ -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);
});
});
});
......@@ -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', () => {
......
......@@ -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', () => {
......
......@@ -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 = () =>
......
......@@ -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);
});
});
});
......
......@@ -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);
});
});
......
......@@ -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', () => {
......
......@@ -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 () => {
......
......@@ -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 () => {
......
......@@ -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 () => {
......
......@@ -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', () => {
......
......@@ -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', () => {
......
......@@ -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(() => {
......
......@@ -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);
});
});
});
......@@ -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);
});
});
......
......@@ -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);
});
});
});
......@@ -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);
});
});
});
......@@ -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);
},
);
......
......@@ -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);
},
);
});
......
......@@ -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);
});
});
......
......@@ -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);
});
});
......@@ -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', () => {
......
......@@ -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);
});
});
......
......@@ -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', () => {
......
......@@ -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);
});
});
......@@ -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`
......
......@@ -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', () => {
......
......@@ -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);
});
});
......
......@@ -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', () => {
......
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册