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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-03-31 09:08:58 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-03-31 09:08:58 +0300
commit4fbd3e553515d506bd82b42e1ffbb516cf0f178a (patch)
treee4fe69014d6a660a63e2b31928b5f7fd20615da6
parent89cd4b410196971a1259463e6d1121ba85d45a6f (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue16
-rw-r--r--app/assets/javascripts/alerts_settings/constants.js3
-rw-r--r--app/assets/javascripts/boards/components/sidebar/board_sidebar_due_date.vue1
-rw-r--r--app/assets/javascripts/boards/components/sidebar/board_sidebar_milestone_select.vue3
-rw-r--r--app/models/milestone.rb4
-rw-r--r--app/presenters/search_service_presenter.rb3
-rw-r--r--changelogs/unreleased/21044-controller-profiles-slackscontroller-edit-executes-more-than-100-sq.yml5
-rw-r--r--changelogs/unreleased/227383-fix-search-n-plus-1.yml5
-rw-r--r--changelogs/unreleased/325820-update-validation-trigger.yml5
-rw-r--r--doc/user/application_security/sast/analyzers.md12
-rw-r--r--doc/user/project/issues/related_issues.md34
-rw-r--r--locale/gitlab.pot18
-rw-r--r--spec/features/boards/sidebar_due_date_spec.rb6
-rw-r--r--spec/features/boards/sidebar_labels_spec.rb35
-rw-r--r--spec/features/boards/sidebar_milestones_spec.rb14
-rw-r--r--spec/features/boards/sidebar_spec.rb4
-rw-r--r--spec/frontend/alerts_settings/components/alerts_settings_form_spec.js40
17 files changed, 140 insertions, 68 deletions
diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue
index c0e13d665c3..5ffaebae6fd 100644
--- a/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue
+++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue
@@ -223,6 +223,10 @@ export default {
testAlertModal() {
return this.isFormDirty ? testAlertModalId : null;
},
+ prometheusUrlInvalidFeedback() {
+ const { blankUrlError, invalidUrlError } = i18n.integrationFormSteps.prometheusFormUrl;
+ return this.integrationForm.apiUrl?.length ? invalidUrlError : blankUrlError;
+ },
},
watch: {
tabIndex(val) {
@@ -288,6 +292,9 @@ export default {
if (this.isHttp) {
this.validationState.apiUrl = true;
this.validateName();
+ if (!this.validationState.name) {
+ this.$refs.integrationName.$el.scrollIntoView({ behavior: 'smooth', block: 'center' });
+ }
} else if (this.isPrometheus) {
this.validationState.name = true;
this.validateApiUrl();
@@ -300,6 +307,11 @@ export default {
this.$emit('save-and-test-alert-payload', this.dataForSave, this.testAlertPayload);
},
submit(testAfterSubmit = false) {
+ this.triggerValidation();
+
+ if (!this.isFormValid) {
+ return;
+ }
const event = this.currentIntegration ? 'update-integration' : 'create-new-integration';
this.$emit(event, this.dataForSave, testAfterSubmit);
},
@@ -412,7 +424,6 @@ export default {
:disabled="isSelectDisabled"
class="gl-max-w-full"
:options="integrationTypesOptions"
- @change="triggerValidation"
/>
<alert-settings-form-help-block
@@ -439,6 +450,7 @@ export default {
>
<gl-form-input
id="name-integration"
+ ref="integrationName"
v-model="integrationForm.name"
type="text"
:placeholder="$options.i18n.integrationFormSteps.nameIntegration.placeholder"
@@ -473,7 +485,7 @@ export default {
class="gl-my-4"
:label="$options.i18n.integrationFormSteps.prometheusFormUrl.label"
label-for="api-url"
- :invalid-feedback="$options.i18n.integrationFormSteps.prometheusFormUrl.error"
+ :invalid-feedback="prometheusUrlInvalidFeedback"
:state="validationState.apiUrl"
>
<gl-form-input
diff --git a/app/assets/javascripts/alerts_settings/constants.js b/app/assets/javascripts/alerts_settings/constants.js
index d64ac55ff98..c73804d1722 100644
--- a/app/assets/javascripts/alerts_settings/constants.js
+++ b/app/assets/javascripts/alerts_settings/constants.js
@@ -70,7 +70,8 @@ export const i18n = {
prometheusFormUrl: {
label: s__('AlertSettings|Prometheus API base URL'),
help: s__('AlertSettings|URL cannot be blank and must start with http or https'),
- error: s__('AlertSettings|URL is invalid.'),
+ blankUrlError: __('URL cannot be blank'),
+ invalidUrlError: __('URL is invalid'),
},
restKeyInfo: {
label: s__(
diff --git a/app/assets/javascripts/boards/components/sidebar/board_sidebar_due_date.vue b/app/assets/javascripts/boards/components/sidebar/board_sidebar_due_date.vue
index 6d928337396..c6836efc32d 100644
--- a/app/assets/javascripts/boards/components/sidebar/board_sidebar_due_date.vue
+++ b/app/assets/javascripts/boards/components/sidebar/board_sidebar_due_date.vue
@@ -69,6 +69,7 @@ export default {
<board-editable-item
ref="sidebarItem"
class="board-sidebar-due-date"
+ data-testid="sidebar-due-date"
:title="$options.i18n.dueDate"
:loading="loading"
@open="openDatePicker"
diff --git a/app/assets/javascripts/boards/components/sidebar/board_sidebar_milestone_select.vue b/app/assets/javascripts/boards/components/sidebar/board_sidebar_milestone_select.vue
index 829f1c72806..cce3172d985 100644
--- a/app/assets/javascripts/boards/components/sidebar/board_sidebar_milestone_select.vue
+++ b/app/assets/javascripts/boards/components/sidebar/board_sidebar_milestone_select.vue
@@ -113,7 +113,8 @@ export default {
ref="sidebarItem"
:title="$options.i18n.milestone"
:loading="loading"
- @open="handleOpen()"
+ data-testid="sidebar-milestones"
+ @open="handleOpen"
@close="handleClose"
>
<template v-if="hasMilestone" #collapsed>
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index aa4ddfede99..4cf0e423a15 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -89,6 +89,10 @@ class Milestone < ApplicationRecord
.order(:project_id, :group_id, :due_date).select('DISTINCT ON (project_id, group_id) id')
end
+ def self.with_web_entity_associations
+ preload(:group, project: [:project_feature, group: [:parent], namespace: :route])
+ end
+
def participants
User.joins(assigned_issues: :milestone).where("milestones.id = ?", id).distinct
end
diff --git a/app/presenters/search_service_presenter.rb b/app/presenters/search_service_presenter.rb
index a5e6ffd55b3..ca5c3094509 100644
--- a/app/presenters/search_service_presenter.rb
+++ b/app/presenters/search_service_presenter.rb
@@ -10,7 +10,8 @@ class SearchServicePresenter < Gitlab::View::Presenter::Delegated
issues: :with_web_entity_associations,
merge_requests: :with_web_entity_associations,
epics: :with_web_entity_associations,
- notes: :with_web_entity_associations
+ notes: :with_web_entity_associations,
+ milestones: :with_web_entity_associations
}.freeze
SORT_ENABLED_SCOPES = %w(issues merge_requests).freeze
diff --git a/changelogs/unreleased/21044-controller-profiles-slackscontroller-edit-executes-more-than-100-sq.yml b/changelogs/unreleased/21044-controller-profiles-slackscontroller-edit-executes-more-than-100-sq.yml
new file mode 100644
index 00000000000..0d7848d58b3
--- /dev/null
+++ b/changelogs/unreleased/21044-controller-profiles-slackscontroller-edit-executes-more-than-100-sq.yml
@@ -0,0 +1,5 @@
+---
+title: Reduce number of SQL queries in Profiles::SlacksController#edit
+merge_request: 57674
+author:
+type: performance
diff --git a/changelogs/unreleased/227383-fix-search-n-plus-1.yml b/changelogs/unreleased/227383-fix-search-n-plus-1.yml
new file mode 100644
index 00000000000..a06d4df1460
--- /dev/null
+++ b/changelogs/unreleased/227383-fix-search-n-plus-1.yml
@@ -0,0 +1,5 @@
+---
+title: Fix N+1 for searching milestone scope
+merge_request: 57715
+author:
+type: performance
diff --git a/changelogs/unreleased/325820-update-validation-trigger.yml b/changelogs/unreleased/325820-update-validation-trigger.yml
new file mode 100644
index 00000000000..1b5905cb4f6
--- /dev/null
+++ b/changelogs/unreleased/325820-update-validation-trigger.yml
@@ -0,0 +1,5 @@
+---
+title: Update validation trigger flow on the alerts integration form
+merge_request: 57697
+author:
+type: changed
diff --git a/doc/user/application_security/sast/analyzers.md b/doc/user/application_security/sast/analyzers.md
index 83f85951388..12d61a4921c 100644
--- a/doc/user/application_security/sast/analyzers.md
+++ b/doc/user/application_security/sast/analyzers.md
@@ -43,6 +43,18 @@ dedicated containers for each analysis.
SAST is pre-configured with a set of **default images** that are maintained by
GitLab, but users can also integrate their own **custom images**.
+## SAST analyzer features
+
+For an analyzer to be considered Generally Available, it is expected to minimally
+support the following features:
+
+- [Customizable configuration](index.md#available-variables)
+- [Customizable rulesets](index.md#customize-rulesets)
+- [Scan projects](index.md#supported-languages-and-frameworks)
+- [Multi-project support](index.md#multi-project-support)
+- [Offline support](index.md#running-sast-in-an-offline-environment)
+- [Emits JSON report format](index.md#reports-json-format)
+
## Official default analyzers
Any custom change to the official analyzers can be achieved by using a
diff --git a/doc/user/project/issues/related_issues.md b/doc/user/project/issues/related_issues.md
index 91c26d49532..43939da4c4a 100644
--- a/doc/user/project/issues/related_issues.md
+++ b/doc/user/project/issues/related_issues.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Related issues **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1797) in [GitLab Starter](https://about.gitlab.com/pricing/) 9.4.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1797) in GitLab 9.4.
> - The simple "relates to" relationship [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212329) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.4.
Related issues are a bi-directional relationship between any two issues
@@ -16,8 +16,8 @@ and projects.
You can set any issue as:
- Related to another issue
-- Blocking another issue **(STARTER)**
-- Blocked by another issue **(STARTER)**
+- Blocking another issue **(PREMIUM)**
+- Blocked by another issue **(PREMIUM)**
The relationship only shows up in the UI if the user can see both issues.
@@ -28,28 +28,30 @@ To manage related issues through our API, visit the [issue links API documentati
## Adding a related issue
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2035) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.8.
-> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/34239) to warn when attempting to close an issue that is blocked by others in [GitLab Starter](https://about.gitlab.com/pricing/) 13.0.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2035) in GitLab 12.8.
+> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/34239) to warn when attempting to close an issue that is blocked by others in GitLab 13.0.
> When you try to close an issue with open blockers, you see a warning that you can dismiss.
1. Relate one issue to another by clicking the related issues "+" button
in the header of the related issue block.
+1. Select the relationship the between the two issues. Either:
+ - **relates to**.
+ - **blocks**. **(PREMIUM)**
+ - **is blocked by**. **(PREMIUM)**
1. Input the issue reference number or paste in the full URL of the issue.
-1. **(STARTER)** Select whether the current issue relates to, blocks, or is blocked by the issues being entered.
+ ![Adding a related issue](img/related_issues_add_v12_8.png)
- ![Adding a related issue](img/related_issues_add_v12_8.png)
+ Issues of the same project can be specified just by the reference number.
+ Issues from a different project require additional information like the
+ group and the project name. For example:
- Issues of the same project can be specified just by the reference number.
- Issues from a different project require additional information like the
- group and the project name. For example:
+ - The same project: `#44`
+ - The same group: `project#44`
+ - Different group: `group/project#44`
- - same project: `#44`
- - same group: `project#44`
- - different group: `group/project#44`
-
- Valid references are added to a temporary list that you can review.
+ Valid references are added to a temporary list that you can review.
1. When you have added all the related issues, click **Add** to submit.
@@ -60,7 +62,7 @@ them categorized so their relationships can be better understood visually.
## Removing a related issue
-In the related issues block, click the "x" icon on the right-side of each issue
+In the related issues block, click the remove button (**{close}**) on the right-side of each issue
token that you wish to remove.
Due to the bi-directional relationship, it no longer appears in either issue.
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index c130b2f1f8b..5ac5e30310b 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3005,9 +3005,6 @@ msgstr ""
msgid "AlertSettings|URL cannot be blank and must start with http or https"
msgstr ""
-msgid "AlertSettings|URL is invalid."
-msgstr ""
-
msgid "AlertSettings|Utilize the URL and authorization key below to authorize Prometheus to send alerts to GitLab. Review the Prometheus documentation to learn where to add these details, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
msgstr ""
@@ -8726,6 +8723,12 @@ msgstr ""
msgid "Could not load usage counts. Please refresh the page to try again."
msgstr ""
+msgid "Could not remove %{user} from %{group}. Cannot remove last group owner."
+msgstr ""
+
+msgid "Could not remove %{user} from %{group}. User is not a group member."
+msgstr ""
+
msgid "Could not remove the trigger."
msgstr ""
@@ -32403,6 +32406,12 @@ msgstr ""
msgid "URL"
msgstr ""
+msgid "URL cannot be blank"
+msgstr ""
+
+msgid "URL is invalid"
+msgstr ""
+
msgid "URL is required"
msgstr ""
@@ -33165,6 +33174,9 @@ msgstr ""
msgid "User %{username} was successfully removed."
msgstr ""
+msgid "User %{user} was removed from %{group}."
+msgstr ""
+
msgid "User ID"
msgstr ""
diff --git a/spec/features/boards/sidebar_due_date_spec.rb b/spec/features/boards/sidebar_due_date_spec.rb
index 52ec51c317e..03d6c8dfaf9 100644
--- a/spec/features/boards/sidebar_due_date_spec.rb
+++ b/spec/features/boards/sidebar_due_date_spec.rb
@@ -17,8 +17,6 @@ RSpec.describe 'Project issue boards sidebar due date', :js do
end
before do
- stub_feature_flags(graphql_board_lists: false)
-
project.add_maintainer(user)
sign_in(user)
@@ -31,10 +29,10 @@ RSpec.describe 'Project issue boards sidebar due date', :js do
it 'updates due date' do
click_card(card)
- page.within('.due_date') do
+ page.within('[data-testid="sidebar-due-date"]') do
today = Date.today.day
- click_link 'Edit'
+ click_button 'Edit'
click_button today.to_s
diff --git a/spec/features/boards/sidebar_labels_spec.rb b/spec/features/boards/sidebar_labels_spec.rb
index 37de561e689..7d89ef63f6c 100644
--- a/spec/features/boards/sidebar_labels_spec.rb
+++ b/spec/features/boards/sidebar_labels_spec.rb
@@ -18,8 +18,6 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
let(:card) { find('.board:nth-child(2)').first('.board-card') }
before do
- stub_feature_flags(graphql_board_lists: false)
-
project.add_maintainer(user)
sign_in(user)
@@ -29,7 +27,8 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
end
context 'labels' do
- it 'shows current labels when editing' do
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/322725
+ xit 'shows current labels when editing' do
click_card(card)
page.within('.labels') do
@@ -49,15 +48,15 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
click_card(card)
page.within('.labels') do
- click_link 'Edit'
+ click_button 'Edit'
wait_for_requests
click_link bug.title
- wait_for_requests
+ find('[data-testid="close-icon"]').click
- find('.dropdown-menu-close-icon').click
+ wait_for_requests
page.within('.value') do
expect(page).to have_selector('.gl-label-text', count: 3)
@@ -74,19 +73,17 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
click_card(card)
page.within('.labels') do
- click_link 'Edit'
+ click_button 'Edit'
wait_for_requests
click_link bug.title
- wait_for_requests
-
click_link regression.title
- wait_for_requests
+ find('[data-testid="close-icon"]').click
- find('.dropdown-menu-close-icon').click
+ wait_for_requests
page.within('.value') do
expect(page).to have_selector('.gl-label-text', count: 4)
@@ -105,17 +102,15 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
click_card(card)
page.within('.labels') do
- click_link 'Edit'
+ click_button 'Edit'
wait_for_requests
- within('.dropdown-menu-labels') do
- click_link stretch.title
- end
+ click_link stretch.title
- wait_for_requests
+ find('[data-testid="close-icon"]').click
- find('.dropdown-menu-close-icon').click
+ wait_for_requests
page.within('.value') do
expect(page).to have_selector('.gl-label-text', count: 1)
@@ -128,7 +123,8 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
expect(card).not_to have_content(stretch.title)
end
- it 'creates project label' do
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/324290
+ xit 'creates project label' do
click_card(card)
page.within('.labels') do
@@ -146,7 +142,8 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
expect(page).to have_selector('.board', count: 3)
end
- it 'creates project label and list' do
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/324290
+ xit 'creates project label and list' do
click_card(card)
page.within('.labels') do
diff --git a/spec/features/boards/sidebar_milestones_spec.rb b/spec/features/boards/sidebar_milestones_spec.rb
index d815d60d5b0..a8d8d20c10b 100644
--- a/spec/features/boards/sidebar_milestones_spec.rb
+++ b/spec/features/boards/sidebar_milestones_spec.rb
@@ -16,8 +16,6 @@ RSpec.describe 'Project issue boards sidebar milestones', :js do
let(:card2) { find('.board:nth-child(1) .board-card:nth-of-type(2)') }
before do
- stub_feature_flags(graphql_board_lists: false)
-
project.add_maintainer(user)
sign_in(user)
@@ -30,12 +28,12 @@ RSpec.describe 'Project issue boards sidebar milestones', :js do
it 'adds a milestone' do
click_card(card1)
- page.within('.milestone') do
- click_link 'Edit'
+ page.within('[data-testid="sidebar-milestones"]') do
+ click_button 'Edit'
wait_for_requests
- click_link milestone.title
+ click_button milestone.title
wait_for_requests
@@ -48,12 +46,12 @@ RSpec.describe 'Project issue boards sidebar milestones', :js do
it 'removes a milestone' do
click_card(card2)
- page.within('.milestone') do
- click_link 'Edit'
+ page.within('[data-testid="sidebar-milestones"]') do
+ click_button 'Edit'
wait_for_requests
- click_link "No milestone"
+ click_button "No milestone"
wait_for_requests
diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb
index 45fe5ab8376..57e88fac013 100644
--- a/spec/features/boards/sidebar_spec.rb
+++ b/spec/features/boards/sidebar_spec.rb
@@ -13,8 +13,6 @@ RSpec.describe 'Project issue boards sidebar', :js do
let(:card) { find('.board:nth-child(1)').first('.board-card') }
before do
- stub_feature_flags(graphql_board_lists: false)
-
project.add_maintainer(user)
sign_in(user)
@@ -44,7 +42,7 @@ RSpec.describe 'Project issue boards sidebar', :js do
expect(page).to have_selector('.issue-boards-sidebar')
- find('.gutter-toggle').click
+ find("[data-testid='sidebar-drawer'] .gl-drawer-close-button").click
expect(page).not_to have_selector('.issue-boards-sidebar')
end
diff --git a/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js b/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js
index 00f2fa60360..9912ac433a5 100644
--- a/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js
+++ b/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js
@@ -10,6 +10,9 @@ import alertFields from '../mocks/alert_fields.json';
import parsedMapping from '../mocks/parsed_mapping.json';
import { defaultAlertSettingsConfig } from './util';
+const scrollIntoViewMock = jest.fn();
+HTMLElement.prototype.scrollIntoView = scrollIntoViewMock;
+
describe('AlertsSettingsForm', () => {
let wrapper;
const mockToastShow = jest.fn();
@@ -410,33 +413,35 @@ describe('AlertsSettingsForm', () => {
createComponent();
});
- it('should not be able to submit when no integration type is selected', () => {
- selectOptionAtIndex(0);
+ it('should not be able to submit when no integration type is selected', async () => {
+ await selectOptionAtIndex(0);
expect(findSubmitButton().attributes('disabled')).toBe('disabled');
});
- it('should not be able to submit when HTTP integration form is invalid', () => {
- selectOptionAtIndex(1);
-
+ it('should not be able to submit when HTTP integration form is invalid', async () => {
+ await selectOptionAtIndex(1);
+ await findFormFields().at(0).vm.$emit('input', '');
expect(findSubmitButton().attributes('disabled')).toBe('disabled');
});
it('should be able to submit when HTTP integration form is valid', async () => {
await selectOptionAtIndex(1);
- await findFormFields().at(0).setValue('Name');
+ await findFormFields().at(0).vm.$emit('input', 'Name');
expect(findSubmitButton().attributes('disabled')).toBe(undefined);
});
- it('should not be able to submit when Prometheus integration form is invalid', () => {
- selectOptionAtIndex(2);
+ it('should not be able to submit when Prometheus integration form is invalid', async () => {
+ await selectOptionAtIndex(2);
+ await findFormFields().at(0).vm.$emit('input', '');
expect(findSubmitButton().attributes('disabled')).toBe('disabled');
});
it('should be able to submit when Prometheus integration form is valid', async () => {
await selectOptionAtIndex(2);
- await findFormFields().at(0).setValue('http://valid.url');
+ await findFormFields().at(0).vm.$emit('input', 'http://valid.url');
+
expect(findSubmitButton().attributes('disabled')).toBe(undefined);
});
@@ -445,7 +450,7 @@ describe('AlertsSettingsForm', () => {
currentIntegration: { type: typeSet.http, name: 'Existing integration' },
});
await nextTick();
- await findFormFields().at(0).setValue('Updated name');
+ await findFormFields().at(0).vm.$emit('input', 'Updated name');
expect(findSubmitButton().attributes('disabled')).toBe(undefined);
});
@@ -458,5 +463,20 @@ describe('AlertsSettingsForm', () => {
expect(findSubmitButton().attributes('disabled')).toBe('disabled');
});
+
+ it('should disable submit button after click on validation failure', async () => {
+ await selectOptionAtIndex(1);
+ findSubmitButton().trigger('click');
+ await nextTick();
+
+ expect(findSubmitButton().attributes('disabled')).toBe('disabled');
+ });
+
+ it('should scroll to invalid field on validation failure', async () => {
+ await selectOptionAtIndex(1);
+ findSubmitButton().trigger('click');
+
+ expect(scrollIntoViewMock).toHaveBeenCalledWith({ behavior: 'smooth', block: 'center' });
+ });
});
});