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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/boards/components/board_add_new_column_form.vue29
-rw-r--r--app/assets/javascripts/pipelines/components/test_reports/test_reports.vue6
-rw-r--r--app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue16
-rw-r--r--app/assets/javascripts/pipelines/components/test_reports/test_summary.vue55
-rw-r--r--app/assets/javascripts/pipelines/components/test_reports/test_summary_table.vue54
-rw-r--r--app/assets/javascripts/runner/graphql/list/list_item_shared.fragment.graphql1
-rw-r--r--app/assets/stylesheets/page_bundles/pipeline.scss6
-rw-r--r--app/models/hooks/web_hook.rb15
-rw-r--r--app/services/web_hooks/log_execution_service.rb25
-rw-r--r--app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml7
-rw-r--r--data/whats_new/202206220001_15_1.yml4
-rw-r--r--doc/development/integrations/secure.md4
-rw-r--r--spec/features/admin/admin_appearance_spec.rb2
-rw-r--r--spec/features/profile_spec.rb2
-rw-r--r--spec/features/profiles/password_spec.rb15
-rw-r--r--spec/features/users/login_spec.rb28
-rw-r--r--spec/frontend/boards/components/board_add_new_column_form_spec.js28
-rw-r--r--spec/frontend/fixtures/runner.rb8
-rw-r--r--spec/frontend/ide/components/activity_bar_spec.js72
-rw-r--r--spec/frontend/ide/components/ide_status_bar_spec.js124
-rw-r--r--spec/frontend/ide/components/new_dropdown/index_spec.js82
-rw-r--r--spec/models/hooks/web_hook_spec.rb12
-rw-r--r--spec/services/web_hooks/log_execution_service_spec.rb61
23 files changed, 298 insertions, 358 deletions
diff --git a/app/assets/javascripts/boards/components/board_add_new_column_form.vue b/app/assets/javascripts/boards/components/board_add_new_column_form.vue
index 10c7a3db2d3..c4a2f83ab50 100644
--- a/app/assets/javascripts/boards/components/board_add_new_column_form.vue
+++ b/app/assets/javascripts/boards/components/board_add_new_column_form.vue
@@ -19,6 +19,7 @@ export default {
scope: __('Scope'),
scopeDescription: __('Issues must match this scope to appear in this list.'),
selected: __('Selected'),
+ requiredFieldFeedback: __('This field is required.'),
},
components: {
GlButton,
@@ -55,12 +56,21 @@ export default {
data() {
return {
searchValue: '',
+ selectedIdValid: true,
};
},
+ computed: {
+ toggleClassList() {
+ return `gl-max-w-full gl-display-flex gl-align-items-center gl-text-trunate ${
+ this.selectedIdValid ? '' : 'gl-inset-border-1-red-400!'
+ }`;
+ },
+ },
watch: {
selectedId(val) {
if (val) {
this.$refs.dropdown.hide(true);
+ this.selectedIdValid = true;
}
},
},
@@ -74,6 +84,13 @@ export default {
this.$emit('filter-items', '');
this.$emit('hide');
},
+ onSubmit() {
+ if (!this.selectedId) {
+ this.selectedIdValid = false;
+ } else {
+ this.$emit('add-list');
+ }
+ },
},
};
</script>
@@ -103,11 +120,16 @@ export default {
<slot name="select-list-type"></slot>
- <gl-form-group class="gl-px-5 lg-mb-3 gl-max-w-full" :label="searchLabel">
+ <gl-form-group
+ class="gl-px-5 lg-mb-3 gl-max-w-full"
+ :label="searchLabel"
+ :state="selectedIdValid"
+ :invalid-feedback="$options.i18n.requiredFieldFeedback"
+ >
<gl-dropdown
ref="dropdown"
class="gl-mb-3 gl-max-w-full"
- toggle-class="gl-max-w-full gl-display-flex gl-align-items-center gl-text-trunate"
+ :toggle-class="toggleClassList"
boundary="viewport"
@shown="setFocus"
@hide="onHide"
@@ -147,10 +169,9 @@ export default {
<div class="gl-display-flex gl-mb-4">
<gl-button
data-testid="addNewColumnButton"
- :disabled="!selectedId"
variant="confirm"
class="gl-mr-3 gl-ml-4"
- @click="$emit('add-list')"
+ @click="onSubmit"
>{{ $options.i18n.add }}</gl-button
>
<gl-button data-testid="cancelAddNewColumn" @click="setAddColumnFormVisibility(false)">{{
diff --git a/app/assets/javascripts/pipelines/components/test_reports/test_reports.vue b/app/assets/javascripts/pipelines/components/test_reports/test_reports.vue
index 3fb46a4f128..13e942e55d3 100644
--- a/app/assets/javascripts/pipelines/components/test_reports/test_reports.vue
+++ b/app/assets/javascripts/pipelines/components/test_reports/test_reports.vue
@@ -74,7 +74,7 @@ export default {
<div
v-else-if="!isLoading && showTests"
ref="container"
- class="position-relative"
+ class="gl-relative"
data-testid="tests-detail"
>
<transition
@@ -82,13 +82,13 @@ export default {
@before-enter="beforeEnterTransition"
@after-leave="afterLeaveTransition"
>
- <div v-if="showSuite" key="detail" class="w-100 slide-enter-to-element">
+ <div v-if="showSuite" key="detail" class="gl-w-full slide-enter-to-element">
<test-summary :report="getSelectedSuite" show-back @on-back-click="summaryBackClick" />
<test-suite-table />
</div>
- <div v-else key="summary" class="w-100 slide-enter-from-element">
+ <div v-else key="summary" class="gl-w-full slide-enter-from-element">
<test-summary :report="testReports" />
<test-summary-table @row-click="summaryTableRowClick" />
diff --git a/app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue b/app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue
index 1f438c63fee..7d0f1ba4b5f 100644
--- a/app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue
+++ b/app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue
@@ -80,7 +80,10 @@ export default {
<h4>{{ heading }}</h4>
</div>
</div>
- <div role="row" class="gl-responsive-table-row table-row-header font-weight-bold fgray">
+ <div
+ role="row"
+ class="gl-responsive-table-row table-row-header gl-font-weight-bold gl-fill-gray-700"
+ >
<div role="rowheader" class="table-section section-20">
{{ __('Suite') }}
</div>
@@ -104,7 +107,7 @@ export default {
<div
v-for="(testCase, index) in getSuiteTests"
:key="index"
- class="gl-responsive-table-row rounded align-items-md-start"
+ class="gl-responsive-table-row gl-rounded-base gl-align-items-flex-start"
data-testid="test-case-row"
>
<div class="table-section section-20 section-wrap">
@@ -142,11 +145,8 @@ export default {
<div class="table-section section-10 section-wrap">
<div role="rowheader" class="table-mobile-header">{{ __('Status') }}</div>
- <div class="table-mobile-content text-center">
- <div
- class="ci-status-icon d-flex align-items-center justify-content-end justify-content-md-center"
- :class="`ci-status-icon-${testCase.status}`"
- >
+ <div class="table-mobile-content gl-md-display-flex gl-justify-content-center">
+ <div class="ci-status-icon" :class="`ci-status-icon-${testCase.status}`">
<gl-icon :size="24" :name="testCase.icon" />
</div>
</div>
@@ -156,7 +156,7 @@ export default {
<div role="rowheader" class="table-mobile-header">
{{ __('Duration') }}
</div>
- <div class="table-mobile-content pr-sm-1">
+ <div class="table-mobile-content gl-sm-pr-2">
{{ testCase.formattedTime }}
</div>
</div>
diff --git a/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue b/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue
index 2f5301715c3..6b723ad5481 100644
--- a/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue
+++ b/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue
@@ -65,58 +65,53 @@ export default {
<template>
<div>
- <div class="row">
- <div class="col-12 d-flex gl-mt-3 align-items-center">
- <gl-button
- v-if="showBack"
- size="small"
- class="gl-mr-3 js-back-button"
- icon="chevron-lg-left"
- :aria-label="__('Go back')"
- @click="onBackClick"
- />
+ <div class="gl-w-full gl-display-flex gl-mt-3 gl-align-items-center">
+ <gl-button
+ v-if="showBack"
+ size="small"
+ class="gl-mr-3 js-back-button"
+ icon="chevron-lg-left"
+ :aria-label="__('Go back')"
+ @click="onBackClick"
+ />
- <h4>{{ heading }}</h4>
- </div>
+ <h4>{{ heading }}</h4>
</div>
- <div class="row mt-2">
- <div class="col-4 col-md">
- <span class="js-total-tests">{{
+ <div
+ class="gl-display-flex gl-flex-direction-column gl-md-flex-direction-row gl-w-full gl-mt-3"
+ >
+ <div class="gl-display-flex gl-justify-content-space-between gl-flex-basis-half">
+ <span class="js-total-tests gl-flex-grow-1">{{
sprintf(s__('TestReports|%{count} tests'), { count: report.total_count })
}}</span>
- </div>
- <div class="col-4 col-md text-center text-md-center">
- <span class="js-failed-tests">{{
+ <span class="js-failed-tests gl-flex-grow-1">{{
sprintf(s__('TestReports|%{count} failures'), { count: report.failed_count })
}}</span>
- </div>
- <div class="col-4 col-md text-right text-md-center">
<span class="js-errored-tests">{{
sprintf(s__('TestReports|%{count} errors'), { count: report.error_count })
}}</span>
</div>
-
- <div class="col-6 mt-3 col-md mt-md-0 text-md-center">
- <span class="js-success-rate">{{
+ <div class="gl-display-flex gl-justify-content-space-between gl-flex-grow-1">
+ <div class="gl-display-none gl-md-display-block gl-flex-grow-1"></div>
+ <span class="js-success-rate gl-flex-grow-1">{{
sprintf(s__('TestReports|%{rate}%{sign} success rate'), {
rate: successPercentage,
sign: '%',
})
}}</span>
- </div>
- <div class="col-6 mt-3 col-md mt-md-0 text-right">
<span class="js-duration">{{ formattedDuration }}</span>
</div>
</div>
- <div class="row mt-3">
- <div class="col-12">
- <gl-progress-bar :value="successPercentage" :variant="progressBarVariant" height="10px" />
- </div>
- </div>
+ <gl-progress-bar
+ class="gl-mt-5"
+ :value="successPercentage"
+ :variant="progressBarVariant"
+ height="10px"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/pipelines/components/test_reports/test_summary_table.vue b/app/assets/javascripts/pipelines/components/test_reports/test_summary_table.vue
index 8389c2a5104..7ab48da1a9d 100644
--- a/app/assets/javascripts/pipelines/components/test_reports/test_summary_table.vue
+++ b/app/assets/javascripts/pipelines/components/test_reports/test_summary_table.vue
@@ -34,33 +34,31 @@ export default {
<template>
<div>
- <div class="row gl-mt-3">
- <div class="col-12">
- <h4>{{ heading }}</h4>
- </div>
+ <div class="gl-mt-5">
+ <h4>{{ heading }}</h4>
</div>
- <div v-if="hasSuites" class="test-reports-table gl-mb-3 js-test-suites-table">
- <div role="row" class="gl-responsive-table-row table-row-header font-weight-bold">
- <div role="rowheader" class="table-section section-25 pl-3">
+ <div v-if="hasSuites" class="js-test-suites-table">
+ <div role="row" class="gl-responsive-table-row table-row-header gl-font-weight-bold">
+ <div role="rowheader" class="table-section section-25 gl-pl-5">
{{ __('Job') }}
</div>
<div role="rowheader" class="table-section section-25">
{{ __('Duration') }}
</div>
- <div role="rowheader" class="table-section section-10 text-center">
+ <div role="rowheader" class="table-section section-10 gl-text-center">
{{ __('Failed') }}
</div>
- <div role="rowheader" class="table-section section-10 text-center">
+ <div role="rowheader" class="table-section section-10 gl-text-center">
{{ __('Errors'), }}
</div>
- <div role="rowheader" class="table-section section-10 text-center">
+ <div role="rowheader" class="table-section section-10 gl-text-center">
{{ __('Skipped'), }}
</div>
- <div role="rowheader" class="table-section section-10 text-center">
+ <div role="rowheader" class="table-section section-10 gl-text-center">
{{ __('Passed'), }}
</div>
- <div role="rowheader" class="table-section section-10 pr-3 text-right">
+ <div role="rowheader" class="table-section section-10 gl-pr-5 gl-text-right">
{{ __('Total') }}
</div>
</div>
@@ -69,17 +67,17 @@ export default {
v-for="(testSuite, index) in getTestSuites"
:key="index"
role="row"
- class="gl-responsive-table-row test-reports-summary-row rounded js-suite-row"
+ class="gl-responsive-table-row gl-rounded-base js-suite-row"
:class="{
- 'gl-responsive-table-row-clickable cursor-pointer': !testSuite.suite_error,
+ 'gl-responsive-table-row-clickable gl-cursor-pointer': !testSuite.suite_error,
}"
@click="tableRowClick(index)"
>
<div class="table-section section-25">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Suite') }}
</div>
- <div class="table-mobile-content underline cgray pl-3">
+ <div class="table-mobile-content underline gl-text-gray-900 gl-pl-5">
{{ testSuite.name }}
<gl-icon
v-if="testSuite.suite_error"
@@ -93,44 +91,44 @@ export default {
</div>
<div class="table-section section-25">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Duration') }}
</div>
- <div class="table-mobile-content text-md-left">
+ <div class="table-mobile-content gl-text-left">
{{ testSuite.formattedTime }}
</div>
</div>
- <div class="table-section section-10 text-center">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div class="table-section section-10 gl-text-center">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Failed') }}
</div>
<div class="table-mobile-content">{{ testSuite.failed_count }}</div>
</div>
- <div class="table-section section-10 text-center">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div class="table-section section-10 gl-text-center">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Errors') }}
</div>
<div class="table-mobile-content">{{ testSuite.error_count }}</div>
</div>
- <div class="table-section section-10 text-center">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div class="table-section section-10 gl-text-center">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Skipped') }}
</div>
<div class="table-mobile-content">{{ testSuite.skipped_count }}</div>
</div>
- <div class="table-section section-10 text-center">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div class="table-section section-10 gl-text-center">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Passed') }}
</div>
<div class="table-mobile-content">{{ testSuite.success_count }}</div>
</div>
- <div class="table-section section-10 text-right pr-md-3">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div class="table-section section-10 gl-text-right pr-md-3">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Total') }}
</div>
<div class="table-mobile-content">{{ testSuite.total_count }}</div>
diff --git a/app/assets/javascripts/runner/graphql/list/list_item_shared.fragment.graphql b/app/assets/javascripts/runner/graphql/list/list_item_shared.fragment.graphql
index cf925359ffb..5e873135480 100644
--- a/app/assets/javascripts/runner/graphql/list/list_item_shared.fragment.graphql
+++ b/app/assets/javascripts/runner/graphql/list/list_item_shared.fragment.graphql
@@ -5,7 +5,6 @@ fragment ListItemShared on CiRunner {
runnerType
shortSha
version
- revision
ipAddress
active
locked
diff --git a/app/assets/stylesheets/page_bundles/pipeline.scss b/app/assets/stylesheets/page_bundles/pipeline.scss
index e6afc70acbb..59d2c1bb6e6 100644
--- a/app/assets/stylesheets/page_bundles/pipeline.scss
+++ b/app/assets/stylesheets/page_bundles/pipeline.scss
@@ -225,12 +225,6 @@
}
}
-.test-reports-table {
- .build-log {
- @include build-log();
- }
-}
-
.progress-bar.bg-primary {
background-color: var(--blue-500, $blue-500) !important;
}
diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb
index f428d07cd7f..925a8628196 100644
--- a/app/models/hooks/web_hook.rb
+++ b/app/models/hooks/web_hook.rb
@@ -57,14 +57,14 @@ class WebHook < ApplicationRecord
!temporarily_disabled? && !permanently_disabled?
end
- def temporarily_disabled?(ignore_flag: false)
- return false unless ignore_flag || web_hooks_disable_failed?
+ def temporarily_disabled?
+ return false unless web_hooks_disable_failed?
disabled_until.present? && disabled_until >= Time.current
end
- def permanently_disabled?(ignore_flag: false)
- return false unless ignore_flag || web_hooks_disable_failed?
+ def permanently_disabled?
+ return false unless web_hooks_disable_failed?
recent_failures > FAILURE_THRESHOLD
end
@@ -126,13 +126,6 @@ class WebHook < ApplicationRecord
save(validate: false)
end
- def active_state(ignore_flag: false)
- return :permanently_disabled if permanently_disabled?(ignore_flag: ignore_flag)
- return :temporarily_disabled if temporarily_disabled?(ignore_flag: ignore_flag)
-
- :enabled
- end
-
# @return [Boolean] Whether or not the WebHook is currently throttled.
def rate_limited?
rate_limiter.rate_limited?
diff --git a/app/services/web_hooks/log_execution_service.rb b/app/services/web_hooks/log_execution_service.rb
index 17dcf615830..5be8aee3ae8 100644
--- a/app/services/web_hooks/log_execution_service.rb
+++ b/app/services/web_hooks/log_execution_service.rb
@@ -14,7 +14,6 @@ module WebHooks
@hook = hook
@log_data = log_data.transform_keys(&:to_sym)
@response_category = response_category
- @prev_state = hook.active_state(ignore_flag: true)
end
def execute
@@ -43,36 +42,12 @@ module WebHooks
hook.failed!
end
- log_state_change
hook.update_last_failure
end
rescue Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError
raise if raise_lock_error?
end
- def log_state_change
- new_state = hook.active_state(ignore_flag: true)
-
- return if @prev_state == new_state
-
- Gitlab::AuthLogger.info(
- message: 'WebHook change active_state',
- # identification
- hook_id: hook.id,
- hook_type: hook.type,
- project_id: hook.project_id,
- group_id: hook.group_id,
- # relevant data
- prev_state: @prev_state,
- new_state: new_state,
- duration: log_data[:execution_duration],
- response_status: log_data[:response_status],
- recent_hook_failures: hook.recent_failures,
- # context
- **Gitlab::ApplicationContext.current
- )
- end
-
def lock_name
"web_hooks:update_hook_failure_state:#{hook.id}"
end
diff --git a/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml b/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
index 6b367c735c3..62cd8bd94e3 100644
--- a/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
+++ b/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
@@ -34,9 +34,10 @@
= display_issuable_type
- unless current_controller?('conflicts')
- - if current_user && moved_mr_sidebar_enabled? && !@merge_request.merged?
- %li.gl-new-dropdown-divider
- %hr.dropdown-divider
+ - if current_user && moved_mr_sidebar_enabled?
+ - if !@merge_request.merged?
+ %li.gl-new-dropdown-divider
+ %hr.dropdown-divider
%li.gl-new-dropdown-item.js-sidebar-subscriptions-entry-point
- unless issuable_author_is_current_user(@merge_request)
%li.gl-new-dropdown-item
diff --git a/data/whats_new/202206220001_15_1.yml b/data/whats_new/202206220001_15_1.yml
index 76ef7fd1a46..eacad83f378 100644
--- a/data/whats_new/202206220001_15_1.yml
+++ b/data/whats_new/202206220001_15_1.yml
@@ -42,7 +42,7 @@
gitlab-com: true
packages: [Free, Premium, Ultimate]
url: https://docs.gitlab.com/ee/ci/runners/configure_runners.html#artifact-attestation
- image_url: https://www.youtube.com/embed/MlIdqrDgI8U
+ image_url: https://img.youtube.com/vi/MlIdqrDgI8U/hqdefault.jpg
published_at: 2022-06-22
release: 15.1
- title: "Link to included CI/CD configuration from the pipeline editor"
@@ -54,6 +54,6 @@
gitlab-com: true
packages: [Free, Premium, Ultimate]
url: https://docs.gitlab.com/ee/ci/pipeline_editor/
- image_url: https://www.youtube.com/embed/7BNDUYfY_ok
+ image_url: https://img.youtube.com/vi/7BNDUYfY_ok/hqdefault.jpg
published_at: 2022-06-22
release: 15.1
diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md
index 3dae0d159a5..2788cd02fcf 100644
--- a/doc/development/integrations/secure.md
+++ b/doc/development/integrations/secure.md
@@ -253,6 +253,10 @@ then `artifacts:reports:dependency_scanning` must be set to `depscan.json`.
Following the POSIX exit code standard, the scanner exits with 0 for success and any number from 1 to 255 for anything else.
Success also includes the case when vulnerabilities are found.
+When a CI job fails, security report results are not ingested by GitLab, even if the job
+[allows failure](../../ci/yaml/#allow_failure). The report artifacts are still uploaded to GitLab and available
+for [download in the pipeline security tab](../../user/application_security/vulnerability_report/pipeline.md#download-security-scan-outputs).
+
When executing a scanning job using the [Docker-in-Docker privileged mode](../../user/application_security/sast/index.md#requirements),
we reserve the following standard exit codes.
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
index 8bf8ef56353..ec0399e0ee3 100644
--- a/spec/features/admin/admin_appearance_spec.rb
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -101,7 +101,7 @@ RSpec.describe 'Admin Appearance' do
context 'Profile page with custom profile image guidelines' do
before do
- sign_in(create(:admin))
+ sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
visit admin_application_settings_appearances_path
fill_in 'appearance_profile_image_guidelines', with: 'Custom profile image guidelines, please :smile:!'
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 1013937ebb9..2836ac2f801 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -30,7 +30,7 @@ RSpec.describe 'Profile account page', :js do
it 'deletes user', :js, :sidekiq_might_not_need_inline do
click_button 'Delete account'
- fill_in 'password', with: '12345678'
+ fill_in 'password', with: user.password
page.within '.modal' do
click_button 'Delete account'
diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb
index 07dfbca8cbd..1d0db488751 100644
--- a/spec/features/profiles/password_spec.rb
+++ b/spec/features/profiles/password_spec.rb
@@ -13,6 +13,7 @@ RSpec.describe 'Profile > Password' do
end
context 'Password authentication enabled' do
+ let(:new_password) { User.random_password }
let(:user) { create(:user, password_automatically_set: true) }
before do
@@ -23,7 +24,7 @@ RSpec.describe 'Profile > Password' do
context 'User with password automatically set' do
describe 'User puts different passwords in the field and in the confirmation' do
it 'shows an error message' do
- fill_passwords('mypassword', 'mypassword2')
+ fill_passwords(new_password, "#{new_password}2")
page.within('.gl-alert-danger') do
expect(page).to have_content("Password confirmation doesn't match Password")
@@ -31,7 +32,7 @@ RSpec.describe 'Profile > Password' do
end
it 'does not contain the current password field after an error' do
- fill_passwords('mypassword', 'mypassword2')
+ fill_passwords(new_password, "#{new_password}2")
expect(page).to have_no_field('user[current_password]')
end
@@ -39,7 +40,7 @@ RSpec.describe 'Profile > Password' do
describe 'User puts the same passwords in the field and in the confirmation' do
it 'shows a success message' do
- fill_passwords('mypassword', 'mypassword')
+ fill_passwords(new_password, new_password)
page.within('[data-testid="alert-info"]') do
expect(page).to have_content('Password was successfully updated. Please sign in again.')
@@ -79,7 +80,7 @@ RSpec.describe 'Profile > Password' do
end
context 'Change password' do
- let(:new_password) { '22233344' }
+ let(:new_password) { User.random_password }
before do
sign_in(user)
@@ -156,6 +157,8 @@ RSpec.describe 'Profile > Password' do
end
context 'when password is expired' do
+ let(:new_password) { User.random_password }
+
before do
sign_in(user)
@@ -170,8 +173,8 @@ RSpec.describe 'Profile > Password' do
expect(page).to have_current_path new_profile_password_path, ignore_query: true
fill_in :user_password, with: user.password
- fill_in :user_new_password, with: '12345678'
- fill_in :user_password_confirmation, with: '12345678'
+ fill_in :user_new_password, with: new_password
+ fill_in :user_password_confirmation, with: new_password
click_button 'Set new password'
expect(page).to have_current_path new_user_session_path, ignore_query: true
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index 08d0a8d556a..259a82498b9 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -49,15 +49,15 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect(page).to have_current_path edit_user_password_path, ignore_query: true
expect(page).to have_content('Please create a password for your new account.')
- fill_in 'user_password', with: 'password'
- fill_in 'user_password_confirmation', with: 'password'
+ fill_in 'user_password', with: user.password
+ fill_in 'user_password_confirmation', with: user.password
click_button 'Change your password'
expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(page).to have_content(I18n.t('devise.passwords.updated_not_active'))
fill_in 'user_login', with: user.username
- fill_in 'user_password', with: 'password'
+ fill_in 'user_password', with: user.password
click_button 'Sign in'
expect_single_session_with_authenticated_ttl
@@ -231,7 +231,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
end
it 'does not allow sign-in if the user password is updated before entering a one-time code' do
- user.update!(password: 'new_password')
+ user.update!(password: User.random_password)
enter_code(user.current_otp)
@@ -468,7 +468,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: user.password
click_button 'Sign in'
expect(page).to have_current_path(new_profile_password_path, ignore_query: true)
@@ -788,7 +788,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: user.password
click_button 'Sign in'
@@ -809,7 +809,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: user.password
click_button 'Sign in'
@@ -830,7 +830,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: user.password
click_button 'Sign in'
@@ -873,7 +873,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: user.password
click_button 'Sign in'
fill_in 'user_otp_attempt', with: user.reload.current_otp
@@ -899,7 +899,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
visit new_user_session_path
fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_password', with: user.password
click_button 'Sign in'
expect_to_be_on_terms_page
@@ -907,9 +907,11 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect(page).to have_current_path(new_profile_password_path, ignore_query: true)
- fill_in 'user_password', with: '12345678'
- fill_in 'user_new_password', with: 'new password'
- fill_in 'user_password_confirmation', with: 'new password'
+ new_password = User.random_password
+
+ fill_in 'user_password', with: user.password
+ fill_in 'user_new_password', with: new_password
+ fill_in 'user_password_confirmation', with: new_password
click_button 'Set new password'
expect(page).to have_content('Password successfully changed')
diff --git a/spec/frontend/boards/components/board_add_new_column_form_spec.js b/spec/frontend/boards/components/board_add_new_column_form_spec.js
index 3b26ca57d6f..7855b041951 100644
--- a/spec/frontend/boards/components/board_add_new_column_form_spec.js
+++ b/spec/frontend/boards/components/board_add_new_column_form_spec.js
@@ -61,7 +61,7 @@ describe('Board card layout', () => {
const formTitle = () => wrapper.findByTestId('board-add-column-form-title').text();
const findSearchInput = () => wrapper.find(GlSearchBoxByType);
- const findSearchLabel = () => wrapper.find(GlFormGroup);
+ const findSearchLabelFormGroup = () => wrapper.find(GlFormGroup);
const cancelButton = () => wrapper.findByTestId('cancelAddNewColumn');
const submitButton = () => wrapper.findByTestId('addNewColumnButton');
const findDropdown = () => wrapper.findComponent(GlDropdown);
@@ -121,10 +121,17 @@ describe('Board card layout', () => {
mountComponent(props);
- expect(findSearchLabel().attributes('label')).toEqual(props.searchLabel);
+ expect(findSearchLabelFormGroup().attributes('label')).toEqual(props.searchLabel);
expect(findSearchInput().attributes('placeholder')).toEqual(props.searchPlaceholder);
});
+ it('does not show the dropdown as invalid by default', () => {
+ mountComponent();
+
+ expect(findSearchLabelFormGroup().attributes('state')).toBe('true');
+ expect(findDropdown().props('toggleClass')).not.toContain('gl-inset-border-1-red-400!');
+ });
+
it('emits filter event on input', () => {
mountComponent();
@@ -137,13 +144,13 @@ describe('Board card layout', () => {
});
describe('Add list button', () => {
- it('is disabled if no item is selected', () => {
+ it('is enabled by default', () => {
mountComponent();
- expect(submitButton().props('disabled')).toBe(true);
+ expect(submitButton().props('disabled')).toBe(false);
});
- it('emits add-list event on click', () => {
+ it('emits add-list event on click when an ID is selected', () => {
mountComponent({
selectedId: mockLabelList.label.id,
});
@@ -152,5 +159,16 @@ describe('Board card layout', () => {
expect(wrapper.emitted('add-list')).toEqual([[]]);
});
+
+ it('does not emit the add-list event on click and shows the dropdown as invalid when no ID is selected', async () => {
+ mountComponent();
+
+ await submitButton().vm.$emit('click');
+
+ expect(findSearchLabelFormGroup().attributes('state')).toBeUndefined();
+ expect(findDropdown().props('toggleClass')).toContain('gl-inset-border-1-red-400!');
+
+ expect(wrapper.emitted('add-list')).toBeUndefined();
+ });
});
});
diff --git a/spec/frontend/fixtures/runner.rb b/spec/frontend/fixtures/runner.rb
index 91eef8b485c..22039d076b2 100644
--- a/spec/frontend/fixtures/runner.rb
+++ b/spec/frontend/fixtures/runner.rb
@@ -13,10 +13,10 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
let_it_be(:project) { create(:project, :repository, :public) }
let_it_be(:project_2) { create(:project, :repository, :public) }
- let_it_be(:instance_runner) { create(:ci_runner, :instance, version: '1.0.0', revision: '123', description: 'Instance runner', ip_address: '127.0.0.1') }
- let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group], active: false, version: '2.0.0', revision: '456', description: 'Group runner', ip_address: '127.0.0.1') }
- let_it_be(:group_runner_2) { create(:ci_runner, :group, groups: [group], active: false, version: '2.0.0', revision: '456', description: 'Group runner 2', ip_address: '127.0.0.1') }
- let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project, project_2], active: false, version: '2.0.0', revision: '456', description: 'Project runner', ip_address: '127.0.0.1') }
+ let_it_be(:instance_runner) { create(:ci_runner, :instance, version: '1.0.0', description: 'Instance runner', ip_address: '127.0.0.1') }
+ let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group], active: false, version: '2.0.0', description: 'Group runner', ip_address: '127.0.0.1') }
+ let_it_be(:group_runner_2) { create(:ci_runner, :group, groups: [group], active: false, version: '2.0.0', description: 'Group runner 2', ip_address: '127.0.0.1') }
+ let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project, project_2], active: false, version: '2.0.0', description: 'Project runner', ip_address: '127.0.0.1') }
let_it_be(:build) { create(:ci_build, runner: instance_runner) }
query_path = 'runner/graphql/'
diff --git a/spec/frontend/ide/components/activity_bar_spec.js b/spec/frontend/ide/components/activity_bar_spec.js
index 39fe2c7e723..a97e883a8bf 100644
--- a/spec/frontend/ide/components/activity_bar_spec.js
+++ b/spec/frontend/ide/components/activity_bar_spec.js
@@ -1,86 +1,82 @@
-import Vue, { nextTick } from 'vue';
-import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
+import { GlBadge } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
import ActivityBar from '~/ide/components/activity_bar.vue';
import { leftSidebarViews } from '~/ide/constants';
import { createStore } from '~/ide/stores';
-describe('IDE activity bar', () => {
- const Component = Vue.extend(ActivityBar);
- let vm;
+describe('IDE ActivityBar component', () => {
+ let wrapper;
let store;
- const findChangesBadge = () => vm.$el.querySelector('.badge');
+ const findChangesBadge = () => wrapper.findComponent(GlBadge);
- beforeEach(() => {
+ const mountComponent = (state) => {
store = createStore();
-
- Vue.set(store.state.projects, 'abcproject', {
- web_url: 'testing',
+ store.replaceState({
+ ...store.state,
+ projects: { abcproject: { web_url: 'testing' } },
+ currentProjectId: 'abcproject',
+ ...state,
});
- Vue.set(store.state, 'currentProjectId', 'abcproject');
- vm = createComponentWithStore(Component, store);
- });
+ wrapper = shallowMount(ActivityBar, { store });
+ };
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
describe('updateActivityBarView', () => {
beforeEach(() => {
- jest.spyOn(vm, 'updateActivityBarView').mockImplementation(() => {});
-
- vm.$mount();
+ mountComponent();
+ jest.spyOn(wrapper.vm, 'updateActivityBarView').mockImplementation(() => {});
});
it('calls updateActivityBarView with edit value on click', () => {
- vm.$el.querySelector('.js-ide-edit-mode').click();
+ wrapper.find('.js-ide-edit-mode').trigger('click');
- expect(vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.edit.name);
+ expect(wrapper.vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.edit.name);
});
it('calls updateActivityBarView with commit value on click', () => {
- vm.$el.querySelector('.js-ide-commit-mode').click();
+ wrapper.find('.js-ide-commit-mode').trigger('click');
- expect(vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.commit.name);
+ expect(wrapper.vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.commit.name);
});
it('calls updateActivityBarView with review value on click', () => {
- vm.$el.querySelector('.js-ide-review-mode').click();
+ wrapper.find('.js-ide-review-mode').trigger('click');
- expect(vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.review.name);
+ expect(wrapper.vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.review.name);
});
});
describe('active item', () => {
- beforeEach(() => {
- vm.$mount();
- });
-
it('sets edit item active', () => {
- expect(vm.$el.querySelector('.js-ide-edit-mode').classList).toContain('active');
+ mountComponent();
+
+ expect(wrapper.find('.js-ide-edit-mode').classes()).toContain('active');
});
- it('sets commit item active', async () => {
- vm.$store.state.currentActivityView = leftSidebarViews.commit.name;
+ it('sets commit item active', () => {
+ mountComponent({ currentActivityView: leftSidebarViews.commit.name });
- await nextTick();
- expect(vm.$el.querySelector('.js-ide-commit-mode').classList).toContain('active');
+ expect(wrapper.find('.js-ide-commit-mode').classes()).toContain('active');
});
});
describe('changes badge', () => {
it('is rendered when files are staged', () => {
- store.state.stagedFiles = [{ path: '/path/to/file' }];
- vm.$mount();
+ mountComponent({ stagedFiles: [{ path: '/path/to/file' }] });
- expect(findChangesBadge()).toBeTruthy();
- expect(findChangesBadge().textContent.trim()).toBe('1');
+ expect(findChangesBadge().exists()).toBe(true);
+ expect(findChangesBadge().text()).toBe('1');
});
it('is not rendered when no changes are present', () => {
- vm.$mount();
- expect(findChangesBadge()).toBeFalsy();
+ mountComponent();
+
+ expect(findChangesBadge().exists()).toBe(false);
});
});
});
diff --git a/spec/frontend/ide/components/ide_status_bar_spec.js b/spec/frontend/ide/components/ide_status_bar_spec.js
index 17a5aa17b1f..e6e0ebaf1e8 100644
--- a/spec/frontend/ide/components/ide_status_bar_spec.js
+++ b/spec/frontend/ide/components/ide_status_bar_spec.js
@@ -1,8 +1,8 @@
+import { mount } from '@vue/test-utils';
import _ from 'lodash';
-import Vue, { nextTick } from 'vue';
import { TEST_HOST } from 'helpers/test_constants';
-import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import IdeStatusBar from '~/ide/components/ide_status_bar.vue';
+import IdeStatusMR from '~/ide/components/ide_status_mr.vue';
import { rightSidebarViews } from '~/ide/constants';
import { createStore } from '~/ide/stores';
import { projectData } from '../mock_data';
@@ -13,42 +13,48 @@ const TEST_MERGE_REQUEST_URL = `${TEST_HOST}merge-requests/${TEST_MERGE_REQUEST_
jest.mock('~/lib/utils/poll');
-describe('ideStatusBar', () => {
- let store;
- let vm;
+describe('IdeStatusBar component', () => {
+ let wrapper;
+
+ const findMRStatus = () => wrapper.findComponent(IdeStatusMR);
+
+ const mountComponent = (state = {}) => {
+ const store = createStore();
+ store.replaceState({
+ ...store.state,
+ currentBranchId: 'main',
+ currentProjectId: TEST_PROJECT_ID,
+ projects: {
+ ...store.state.projects,
+ [TEST_PROJECT_ID]: _.clone(projectData),
+ },
+ ...state,
+ });
- const createComponent = () => {
- vm = createComponentWithStore(Vue.extend(IdeStatusBar), store).$mount();
+ wrapper = mount(IdeStatusBar, { store });
};
- const findMRStatus = () => vm.$el.querySelector('.js-ide-status-mr');
-
- beforeEach(() => {
- store = createStore();
- store.state.currentProjectId = TEST_PROJECT_ID;
- store.state.projects[TEST_PROJECT_ID] = _.clone(projectData);
- store.state.currentBranchId = 'main';
- });
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
describe('default', () => {
- beforeEach(() => {
- createComponent();
- });
-
it('triggers a setInterval', () => {
- expect(vm.intervalId).not.toBe(null);
+ mountComponent();
+
+ expect(wrapper.vm.intervalId).not.toBe(null);
});
it('renders the statusbar', () => {
- expect(vm.$el.className).toBe('ide-status-bar');
+ mountComponent();
+
+ expect(wrapper.classes()).toEqual(['ide-status-bar']);
});
describe('commitAgeUpdate', () => {
beforeEach(() => {
- jest.spyOn(vm, 'commitAgeUpdate').mockImplementation(() => {});
+ mountComponent();
+ jest.spyOn(wrapper.vm, 'commitAgeUpdate').mockImplementation(() => {});
});
afterEach(() => {
@@ -56,70 +62,82 @@ describe('ideStatusBar', () => {
});
it('gets called every second', () => {
- expect(vm.commitAgeUpdate).not.toHaveBeenCalled();
+ expect(wrapper.vm.commitAgeUpdate).not.toHaveBeenCalled();
jest.advanceTimersByTime(1000);
- expect(vm.commitAgeUpdate.mock.calls.length).toEqual(1);
+ expect(wrapper.vm.commitAgeUpdate.mock.calls).toHaveLength(1);
jest.advanceTimersByTime(1000);
- expect(vm.commitAgeUpdate.mock.calls.length).toEqual(2);
+ expect(wrapper.vm.commitAgeUpdate.mock.calls).toHaveLength(2);
});
});
describe('getCommitPath', () => {
it('returns the path to the commit details', () => {
- expect(vm.getCommitPath('abc123de')).toBe('/commit/abc123de');
+ mountComponent();
+
+ expect(wrapper.vm.getCommitPath('abc123de')).toBe('/commit/abc123de');
});
});
describe('pipeline status', () => {
- it('opens right sidebar on clicking icon', async () => {
- jest.spyOn(vm, 'openRightPane').mockImplementation(() => {});
- Vue.set(vm.$store.state.pipelines, 'latestPipeline', {
- details: {
- status: {
- text: 'success',
- details_path: 'test',
- icon: 'status_success',
+ it('opens right sidebar on clicking icon', () => {
+ const pipelines = {
+ latestPipeline: {
+ details: {
+ status: {
+ text: 'success',
+ details_path: 'test',
+ icon: 'status_success',
+ },
+ },
+ commit: {
+ author_gravatar_url: 'www',
},
},
- commit: {
- author_gravatar_url: 'www',
- },
- });
+ };
+ mountComponent({ pipelines });
+ jest.spyOn(wrapper.vm, 'openRightPane').mockImplementation(() => {});
- await nextTick();
- vm.$el.querySelector('.ide-status-pipeline button').click();
+ wrapper.find('button').trigger('click');
- expect(vm.openRightPane).toHaveBeenCalledWith(rightSidebarViews.pipelines);
+ expect(wrapper.vm.openRightPane).toHaveBeenCalledWith(rightSidebarViews.pipelines);
});
});
it('does not show merge request status', () => {
- expect(findMRStatus()).toBe(null);
+ mountComponent();
+
+ expect(findMRStatus().exists()).toBe(false);
});
});
describe('with merge request in store', () => {
beforeEach(() => {
- store.state.projects[TEST_PROJECT_ID].mergeRequests = {
- [TEST_MERGE_REQUEST_ID]: {
- web_url: TEST_MERGE_REQUEST_URL,
- references: {
- short: `!${TEST_MERGE_REQUEST_ID}`,
+ const state = {
+ currentMergeRequestId: TEST_MERGE_REQUEST_ID,
+ projects: {
+ [TEST_PROJECT_ID]: {
+ ..._.clone(projectData),
+ mergeRequests: {
+ [TEST_MERGE_REQUEST_ID]: {
+ web_url: TEST_MERGE_REQUEST_URL,
+ references: {
+ short: `!${TEST_MERGE_REQUEST_ID}`,
+ },
+ },
+ },
},
},
};
- store.state.currentMergeRequestId = TEST_MERGE_REQUEST_ID;
-
- createComponent();
+ mountComponent(state);
});
it('shows merge request status', () => {
- expect(findMRStatus().textContent.trim()).toEqual(`Merge request !${TEST_MERGE_REQUEST_ID}`);
- expect(findMRStatus().querySelector('a').href).toEqual(TEST_MERGE_REQUEST_URL);
+ expect(findMRStatus().text()).toBe(`Merge request !${TEST_MERGE_REQUEST_ID}`);
+ expect(findMRStatus().find('a').attributes('href')).toBe(TEST_MERGE_REQUEST_URL);
});
});
});
diff --git a/spec/frontend/ide/components/new_dropdown/index_spec.js b/spec/frontend/ide/components/new_dropdown/index_spec.js
index 19dcd9569b3..747c099db33 100644
--- a/spec/frontend/ide/components/new_dropdown/index_spec.js
+++ b/spec/frontend/ide/components/new_dropdown/index_spec.js
@@ -1,70 +1,66 @@
-import Vue, { nextTick } from 'vue';
-import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
-import newDropdown from '~/ide/components/new_dropdown/index.vue';
+import { mount } from '@vue/test-utils';
+import NewDropdown from '~/ide/components/new_dropdown/index.vue';
+import Button from '~/ide/components/new_dropdown/button.vue';
import { createStore } from '~/ide/stores';
describe('new dropdown component', () => {
- let store;
- let vm;
-
- beforeEach(() => {
- store = createStore();
-
- const component = Vue.extend(newDropdown);
-
- vm = createComponentWithStore(component, store, {
- branch: 'main',
- path: '',
- mouseOver: false,
- type: 'tree',
+ let wrapper;
+
+ const findAllButtons = () => wrapper.findAllComponents(Button);
+
+ const mountComponent = () => {
+ const store = createStore();
+ store.state.currentProjectId = 'abcproject';
+ store.state.path = '';
+ store.state.trees['abcproject/mybranch'] = { tree: [] };
+
+ wrapper = mount(NewDropdown, {
+ store,
+ propsData: {
+ branch: 'main',
+ path: '',
+ mouseOver: false,
+ type: 'tree',
+ },
});
+ };
- vm.$store.state.currentProjectId = 'abcproject';
- vm.$store.state.path = '';
- vm.$store.state.trees['abcproject/mybranch'] = {
- tree: [],
- };
-
- vm.$mount();
-
- jest.spyOn(vm.$refs.newModal, 'open').mockImplementation(() => {});
+ beforeEach(() => {
+ mountComponent();
+ jest.spyOn(wrapper.vm.$refs.newModal, 'open').mockImplementation(() => {});
});
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
it('renders new file, upload and new directory links', () => {
- const buttons = vm.$el.querySelectorAll('.dropdown-menu button');
-
- expect(buttons[0].textContent.trim()).toBe('New file');
- expect(buttons[1].textContent.trim()).toBe('Upload file');
- expect(buttons[2].textContent.trim()).toBe('New directory');
+ expect(findAllButtons().at(0).text()).toBe('New file');
+ expect(findAllButtons().at(1).text()).toBe('Upload file');
+ expect(findAllButtons().at(2).text()).toBe('New directory');
});
describe('createNewItem', () => {
it('opens modal for a blob when new file is clicked', () => {
- vm.$el.querySelectorAll('.dropdown-menu button')[0].click();
+ findAllButtons().at(0).trigger('click');
- expect(vm.$refs.newModal.open).toHaveBeenCalledWith('blob', '');
+ expect(wrapper.vm.$refs.newModal.open).toHaveBeenCalledWith('blob', '');
});
it('opens modal for a tree when new directory is clicked', () => {
- vm.$el.querySelectorAll('.dropdown-menu button')[2].click();
+ findAllButtons().at(2).trigger('click');
- expect(vm.$refs.newModal.open).toHaveBeenCalledWith('tree', '');
+ expect(wrapper.vm.$refs.newModal.open).toHaveBeenCalledWith('tree', '');
});
});
describe('isOpen', () => {
it('scrolls dropdown into view', async () => {
- jest.spyOn(vm.$refs.dropdownMenu, 'scrollIntoView').mockImplementation(() => {});
-
- vm.isOpen = true;
+ jest.spyOn(wrapper.vm.$refs.dropdownMenu, 'scrollIntoView').mockImplementation(() => {});
- await nextTick();
+ await wrapper.setProps({ isOpen: true });
- expect(vm.$refs.dropdownMenu.scrollIntoView).toHaveBeenCalledWith({
+ expect(wrapper.vm.$refs.dropdownMenu.scrollIntoView).toHaveBeenCalledWith({
block: 'nearest',
});
});
@@ -72,11 +68,11 @@ describe('new dropdown component', () => {
describe('delete entry', () => {
it('calls delete action', () => {
- jest.spyOn(vm, 'deleteEntry').mockImplementation(() => {});
+ jest.spyOn(wrapper.vm, 'deleteEntry').mockImplementation(() => {});
- vm.$el.querySelectorAll('.dropdown-menu button')[4].click();
+ findAllButtons().at(4).trigger('click');
- expect(vm.deleteEntry).toHaveBeenCalledWith('');
+ expect(wrapper.vm.deleteEntry).toHaveBeenCalledWith('');
});
});
});
diff --git a/spec/models/hooks/web_hook_spec.rb b/spec/models/hooks/web_hook_spec.rb
index 9faa5e1567c..036d2effc0f 100644
--- a/spec/models/hooks/web_hook_spec.rb
+++ b/spec/models/hooks/web_hook_spec.rb
@@ -482,12 +482,6 @@ RSpec.describe WebHook do
expect(hook).not_to be_temporarily_disabled
end
-
- it 'can ignore the feature flag' do
- stub_feature_flags(web_hooks_disable_failed: false)
-
- expect(hook).to be_temporarily_disabled(ignore_flag: true)
- end
end
end
@@ -510,12 +504,6 @@ RSpec.describe WebHook do
expect(hook).not_to be_permanently_disabled
end
-
- it 'can ignore the feature flag' do
- stub_feature_flags(web_hooks_disable_failed: false)
-
- expect(hook).to be_permanently_disabled(ignore_flag: true)
- end
end
end
diff --git a/spec/services/web_hooks/log_execution_service_spec.rb b/spec/services/web_hooks/log_execution_service_spec.rb
index 873f6adc8dc..1967a8368fb 100644
--- a/spec/services/web_hooks/log_execution_service_spec.rb
+++ b/spec/services/web_hooks/log_execution_service_spec.rb
@@ -101,27 +101,6 @@ RSpec.describe WebHooks::LogExecutionService do
it 'resets the failure count' do
expect { service.execute }.to change(project_hook, :recent_failures).to(0)
end
-
- it 'sends a message to AuthLogger if the hook as not previously enabled' do
- project_hook.update!(recent_failures: ::WebHook::FAILURE_THRESHOLD + 1)
-
- expect(Gitlab::AuthLogger).to receive(:info).with include(
- message: 'WebHook change active_state',
- # identification
- hook_id: project_hook.id,
- hook_type: project_hook.type,
- project_id: project_hook.project_id,
- group_id: nil,
- # relevant data
- prev_state: :permanently_disabled,
- new_state: :enabled,
- duration: 1.2,
- response_status: '200',
- recent_hook_failures: 0
- )
-
- service.execute
- end
end
end
@@ -158,27 +137,6 @@ RSpec.describe WebHooks::LogExecutionService do
expect { service.execute }.not_to change(project_hook, :recent_failures)
end
end
-
- it 'sends a message to AuthLogger if the state would change' do
- project_hook.update!(recent_failures: ::WebHook::FAILURE_THRESHOLD)
-
- expect(Gitlab::AuthLogger).to receive(:info).with include(
- message: 'WebHook change active_state',
- # identification
- hook_id: project_hook.id,
- hook_type: project_hook.type,
- project_id: project_hook.project_id,
- group_id: nil,
- # relevant data
- prev_state: :enabled,
- new_state: :permanently_disabled,
- duration: (be > 0),
- response_status: data[:response_status],
- recent_hook_failures: ::WebHook::FAILURE_THRESHOLD + 1
- )
-
- service.execute
- end
end
context 'when response_category is :error' do
@@ -200,25 +158,6 @@ RSpec.describe WebHooks::LogExecutionService do
expect { service.execute }.to change(project_hook, :backoff_count).by(1)
end
- it 'sends a message to AuthLogger if the state would change' do
- expect(Gitlab::AuthLogger).to receive(:info).with include(
- message: 'WebHook change active_state',
- # identification
- hook_id: project_hook.id,
- hook_type: project_hook.type,
- project_id: project_hook.project_id,
- group_id: nil,
- # relevant data
- prev_state: :enabled,
- new_state: :temporarily_disabled,
- duration: (be > 0),
- response_status: data[:response_status],
- recent_hook_failures: 0
- )
-
- service.execute
- end
-
context 'when the previous cool-off was near the maximum' do
before do
project_hook.update!(disabled_until: 5.minutes.ago, backoff_count: 8)