diff options
19 files changed, 278 insertions, 79 deletions
@@ -46,7 +46,7 @@ gem 'rack-oauth2', '~> 1.9.3' gem 'jwt', '~> 2.1.0' # Spam and anti-bot protection -gem 'recaptcha', '~> 3.0', require: 'recaptcha/rails' +gem 'recaptcha', '~> 4.11', require: 'recaptcha/rails' gem 'akismet', '~> 2.0' # Two-factor authentication diff --git a/Gemfile.lock b/Gemfile.lock index f0f9b523a3b..ec34d3f9d67 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -679,7 +679,7 @@ GEM optimist (>= 3.0.0) rdoc (6.0.4) re2 (1.1.1) - recaptcha (3.0.0) + recaptcha (4.13.1) json recursive-open-struct (1.1.0) redis (3.3.5) @@ -1113,7 +1113,7 @@ DEPENDENCIES rbtrace (~> 0.4) rdoc (~> 6.0) re2 (~> 1.1.1) - recaptcha (~> 3.0) + recaptcha (~> 4.11) redis (~> 3.2) redis-namespace (~> 1.6.0) redis-rails (~> 5.0.2) diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue index 33963d5e1e6..0312b147b62 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue @@ -14,6 +14,10 @@ export default { type: Boolean, required: true, }, + isFastForwardEnabled: { + type: Boolean, + required: true, + }, commitsCount: { type: Number, required: false, @@ -37,16 +41,22 @@ export default { return n__(__('%d commit'), __('%d commits'), this.isSquashEnabled ? 1 : this.commitsCount); }, modifyLinkMessage() { - return this.isSquashEnabled ? __('Modify commit messages') : __('Modify merge commit'); + if (this.isFastForwardEnabled) return __('Modify commit message'); + else if (this.isSquashEnabled) return __('Modify commit messages'); + return __('Modify merge commit'); }, ariaLabel() { return this.expanded ? __('Collapse') : __('Expand'); }, message() { + const message = this.isFastForwardEnabled + ? s__('mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}.') + : s__( + 'mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}.', + ); + return sprintf( - s__( - 'mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}.', - ), + message, { commitCount: `<strong class="commits-count-message">${this.commitsCountMessage}</strong>`, mergeCommitCount: `<strong>${s__('mrWidgetCommitsAdded|1 merge commit')}</strong>`, diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue index 9b4e80ee3a3..8e043ed50c9 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue @@ -113,6 +113,12 @@ export default { shouldShowMergeControls() { return this.mr.isMergeAllowed || this.shouldShowMergeWhenPipelineSucceedsText; }, + shouldShowSquashEdit() { + return this.squashBeforeMerge && this.shouldShowSquashBeforeMerge; + }, + shouldShowMergeEdit() { + return !this.mr.ffOnlyEnabled; + }, }, methods: { updateMergeCommitMessage(includeDescription) { @@ -321,43 +327,44 @@ export default { <div v-if="mr.ffOnlyEnabled" class="mr-fast-forward-message"> {{ __('Fast-forward merge without a merge commit') }} </div> - <template v-else> - <commits-header - :is-squash-enabled="squashBeforeMerge" - :commits-count="mr.commitsCount" - :target-branch="mr.targetBranch" - > - <ul class="border-top content-list commits-list flex-list"> - <commit-edit - v-if="squashBeforeMerge && shouldShowSquashBeforeMerge" + <commits-header + v-if="shouldShowSquashEdit || shouldShowMergeEdit" + :is-squash-enabled="squashBeforeMerge" + :commits-count="mr.commitsCount" + :target-branch="mr.targetBranch" + :is-fast-forward-enabled="mr.ffOnlyEnabled" + > + <ul class="border-top content-list commits-list flex-list"> + <commit-edit + v-if="shouldShowSquashEdit" + v-model="squashCommitMessage" + :label="__('Squash commit message')" + input-id="squash-message-edit" + squash + > + <commit-message-dropdown + slot="header" v-model="squashCommitMessage" - :label="__('Squash commit message')" - input-id="squash-message-edit" - squash - > - <commit-message-dropdown - slot="header" - v-model="squashCommitMessage" - :commits="mr.commits" + :commits="mr.commits" + /> + </commit-edit> + <commit-edit + v-if="shouldShowMergeEdit" + v-model="commitMessage" + :label="__('Merge commit message')" + input-id="merge-message-edit" + > + <label slot="checkbox"> + <input + id="include-description" + type="checkbox" + @change="updateMergeCommitMessage($event.target.checked)" /> - </commit-edit> - <commit-edit - v-model="commitMessage" - :label="__('Merge commit message')" - input-id="merge-message-edit" - > - <label slot="checkbox"> - <input - id="include-description" - type="checkbox" - @change="updateMergeCommitMessage($event.target.checked)" - /> - {{ __('Include merge request description') }} - </label> - </commit-edit> - </ul> - </commits-header> - </template> + {{ __('Include merge request description') }} + </label> + </commit-edit> + </ul> + </commits-header> </template> </div> </template> diff --git a/app/views/layouts/nav/sidebar/_admin.html.haml b/app/views/layouts/nav/sidebar/_admin.html.haml index 2fdd65f639b..bb2d206ba91 100644 --- a/app/views/layouts/nav/sidebar/_admin.html.haml +++ b/app/views/layouts/nav/sidebar/_admin.html.haml @@ -220,7 +220,7 @@ = _('Repository') - if template_exists?('admin/application_settings/templates') = nav_link(path: 'application_settings#templates') do - = link_to templates_admin_application_settings_path, title: _('Templates') do + = link_to templates_admin_application_settings_path, title: _('Templates'), class: 'qa-admin-settings-template-item' do %span = _('Templates') = nav_link(path: 'application_settings#ci_cd') do diff --git a/changelogs/unreleased/48324-enable-squash-message-on-fast-forward.yml b/changelogs/unreleased/48324-enable-squash-message-on-fast-forward.yml new file mode 100644 index 00000000000..789ff4f9f89 --- /dev/null +++ b/changelogs/unreleased/48324-enable-squash-message-on-fast-forward.yml @@ -0,0 +1,5 @@ +--- +title: Allow modifying squash commit message for fast-forward only merge method +merge_request: 26017 +author: +type: fixed diff --git a/changelogs/unreleased/fix-review-app-env-url.yml b/changelogs/unreleased/fix-review-app-env-url.yml new file mode 100644 index 00000000000..963cd0c2992 --- /dev/null +++ b/changelogs/unreleased/fix-review-app-env-url.yml @@ -0,0 +1,5 @@ +--- +title: Fixes long review app subdomains +merge_request: 25990 +author: walkafwalka +type: fixed diff --git a/changelogs/unreleased/pravi-gitlab-ce-update-recaptcha.yml b/changelogs/unreleased/pravi-gitlab-ce-update-recaptcha.yml new file mode 100644 index 00000000000..95379fb2ec1 --- /dev/null +++ b/changelogs/unreleased/pravi-gitlab-ce-update-recaptcha.yml @@ -0,0 +1,5 @@ +--- +title: Apply recaptcha API change in 4.0 +merge_request: 25921 +author: Praveen Arimbrathodiyil +type: other diff --git a/config/webpack.config.js b/config/webpack.config.js index 11970b620bc..55122e341c3 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -1,3 +1,4 @@ +const fs = require('fs'); const path = require('path'); const glob = require('glob'); const webpack = require('webpack'); @@ -11,6 +12,10 @@ const ROOT_PATH = path.resolve(__dirname, '..'); const CACHE_PATH = process.env.WEBPACK_CACHE_PATH || path.join(ROOT_PATH, 'tmp/cache'); const IS_PRODUCTION = process.env.NODE_ENV === 'production'; const IS_DEV_SERVER = process.argv.join(' ').indexOf('webpack-dev-server') !== -1; +const IS_EE = + process.env.EE !== undefined + ? JSON.parse(process.env.EE) + : fs.existsSync(path.join(ROOT_PATH, 'ee')); const DEV_SERVER_HOST = process.env.DEV_SERVER_HOST || 'localhost'; const DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10) || 3808; const DEV_SERVER_LIVERELOAD = IS_DEV_SERVER && process.env.DEV_SERVER_LIVERELOAD !== 'false'; @@ -44,6 +49,14 @@ function generateEntries() { pageEntries.forEach(path => generateAutoEntries(path)); + if (IS_EE) { + const eePageEntries = glob.sync('pages/**/index.js', { + cwd: path.join(ROOT_PATH, 'ee/app/assets/javascripts'), + }); + eePageEntries.forEach(path => generateAutoEntries(path, 'ee')); + watchAutoEntries.push(path.join(ROOT_PATH, 'ee/app/assets/javascripts/pages/')); + } + const autoEntryKeys = Object.keys(autoEntriesMap); autoEntriesCount = autoEntryKeys.length; @@ -68,6 +81,31 @@ function generateEntries() { return Object.assign(manualEntries, autoEntries); } +const alias = { + '~': path.join(ROOT_PATH, 'app/assets/javascripts'), + emojis: path.join(ROOT_PATH, 'fixtures/emojis'), + empty_states: path.join(ROOT_PATH, 'app/views/shared/empty_states'), + icons: path.join(ROOT_PATH, 'app/views/shared/icons'), + images: path.join(ROOT_PATH, 'app/assets/images'), + vendor: path.join(ROOT_PATH, 'vendor/assets/javascripts'), + vue$: 'vue/dist/vue.esm.js', + spec: path.join(ROOT_PATH, 'spec/javascripts'), + + // the following resolves files which are different between CE and EE + ee_else_ce: path.join(ROOT_PATH, 'app/assets/javascripts'), +}; + +if (IS_EE) { + Object.assign(alias, { + ee: path.join(ROOT_PATH, 'ee/app/assets/javascripts'), + ee_empty_states: path.join(ROOT_PATH, 'ee/app/views/shared/empty_states'), + ee_icons: path.join(ROOT_PATH, 'ee/app/views/shared/icons'), + ee_images: path.join(ROOT_PATH, 'ee/app/assets/images'), + ee_spec: path.join(ROOT_PATH, 'ee/spec/javascripts'), + ee_else_ce: path.join(ROOT_PATH, 'ee/app/assets/javascripts'), + }); +} + module.exports = { mode: IS_PRODUCTION ? 'production' : 'development', @@ -85,19 +123,7 @@ module.exports = { resolve: { extensions: ['.js', '.gql', '.graphql'], - alias: { - '~': path.join(ROOT_PATH, 'app/assets/javascripts'), - emojis: path.join(ROOT_PATH, 'fixtures/emojis'), - empty_states: path.join(ROOT_PATH, 'app/views/shared/empty_states'), - icons: path.join(ROOT_PATH, 'app/views/shared/icons'), - images: path.join(ROOT_PATH, 'app/assets/images'), - vendor: path.join(ROOT_PATH, 'vendor/assets/javascripts'), - vue$: 'vue/dist/vue.esm.js', - spec: path.join(ROOT_PATH, 'spec/javascripts'), - - // the following resolves files which are different between CE and EE - ee_else_ce: path.join(ROOT_PATH, 'app/assets/javascripts'), - }, + alias, }, module: { diff --git a/doc/administration/git_protocol.md b/doc/administration/git_protocol.md index 11b2adeeeb8..345e8646f9b 100644 --- a/doc/administration/git_protocol.md +++ b/doc/administration/git_protocol.md @@ -5,13 +5,16 @@ description: "Set and configure Git protocol v2" # Configuring Git Protocol v2 > [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/46555) in GitLab 11.4. -> [Temporarily disabled](https://gitlab.com/gitlab-org/gitlab-ce/issues/55769) in GitLab 11.5.8, 11.6.6, 11.7.1, and 11.8+ +> Temporarily disabled (see [confidential issue](../user/project/issues/confidential_issues.md) +> `https://gitlab.com/gitlab-org/gitlab-ce/issues/55769`) in GitLab 11.5.8, 11.6.6, 11.7.1, and 11.8+. NOTE: **Note:** -Git protocol v2 support has been [temporarily disabled](https://gitlab.com/gitlab-org/gitlab-ce/issues/55769), -as a feature used to hide certain internal references does not function when it +Git protocol v2 support has been temporarily disabled +because a feature used to hide certain internal references does not function when it is enabled, and this has a security impact. Once this problem has been resolved, -protocol v2 support will be re-enabled. +protocol v2 support will be re-enabled. For more information, see the +[confidential issue](../user/project/issues/confidential_issues.md) +`https://gitlab.com/gitlab-org/gitlab-ce/issues/55769`. Git protocol v2 improves the v1 wire protocol in several ways and is enabled by default in GitLab for HTTP requests. In order to enable SSH, diff --git a/doc/topics/authentication/index.md b/doc/topics/authentication/index.md index eef26612d5b..0fc7f57feab 100644 --- a/doc/topics/authentication/index.md +++ b/doc/topics/authentication/index.md @@ -21,7 +21,7 @@ This page gathers all the resources for the topic **Authentication** within GitL - [Enforce Two-factor Authentication (2FA)](../../security/two_factor_authentication.md#enforce-two-factor-authentication-2fa) - **Articles:** - [How to Configure LDAP with GitLab CE](../../administration/auth/how_to_configure_ldap_gitlab_ce/index.md) - - [How to Configure LDAP with GitLab EE](https://docs.gitlab.com/ee/administration/auth/how_to_configure_ldap_gitlab_ee/index.md) + - [How to Configure LDAP with GitLab EE](https://docs.gitlab.com/ee/administration/auth/how_to_configure_ldap_gitlab_ee/index.html) - [Feature Highlight: LDAP Integration](https://about.gitlab.com/2014/07/10/feature-highlight-ldap-sync/) - [Debugging LDAP](https://about.gitlab.com/handbook/support/workflows/support-engineering/ldap/debugging_ldap.html) - **Integrations:** diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md index 24fd4d70b9f..758b8b3f4ee 100644 --- a/doc/topics/autodevops/index.md +++ b/doc/topics/autodevops/index.md @@ -442,10 +442,10 @@ process. Auto Review Apps create a Review App for each branch. Auto Review Apps will deploy your app to your Kubernetes cluster only. When no cluster is available, no deployment will occur. -The Review App will have a unique URL based on the project name, the branch +The Review App will have a unique URL based on the project ID, the branch or tag name, and a unique number, combined with the Auto DevOps base domain. For -example, `user-project-branch-1234.example.com`. A link to the Review App shows -up in the merge request widget for easy discovery. When the branch is deleted, +example, `13083-review-project-branch-123456.example.com`. A link to the Review App shows +up in the merge request widget for easy discovery. When the branch or tag is deleted, for example after the merge request is merged, the Review App will automatically be deleted. diff --git a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml index 3c46eb36cdb..cb9b1484dc2 100644 --- a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml @@ -262,7 +262,7 @@ review: - persist_environment_url environment: name: review/$CI_COMMIT_REF_NAME - url: http://$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_SLUG.$KUBE_INGRESS_BASE_DOMAIN + url: http://$CI_PROJECT_ID-$CI_ENVIRONMENT_SLUG.$KUBE_INGRESS_BASE_DOMAIN on_stop: stop_review artifacts: paths: [environment_url.txt] diff --git a/lib/gitlab/recaptcha.rb b/lib/gitlab/recaptcha.rb index 6559c3e3c57..772d743c9b0 100644 --- a/lib/gitlab/recaptcha.rb +++ b/lib/gitlab/recaptcha.rb @@ -5,8 +5,8 @@ module Gitlab def self.load_configurations! if Gitlab::CurrentSettings.recaptcha_enabled ::Recaptcha.configure do |config| - config.public_key = Gitlab::CurrentSettings.recaptcha_site_key - config.private_key = Gitlab::CurrentSettings.recaptcha_private_key + config.site_key = Gitlab::CurrentSettings.recaptcha_site_key + config.secret_key = Gitlab::CurrentSettings.recaptcha_private_key end true diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 90dab37a33b..29cbf59cee2 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4920,6 +4920,9 @@ msgstr "" msgid "Modal|Close" msgstr "" +msgid "Modify commit message" +msgstr "" + msgid "Modify commit messages" msgstr "" @@ -9089,6 +9092,9 @@ msgstr "" msgid "mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}." msgstr "" +msgid "mrWidgetCommitsAdded|%{commitCount} will be added to %{targetBranch}." +msgstr "" + msgid "mrWidgetCommitsAdded|1 merge commit" msgstr "" diff --git a/qa/qa/page/component/select2.rb b/qa/qa/page/component/select2.rb index 98bcb96b92c..3c3461d6b20 100644 --- a/qa/qa/page/component/select2.rb +++ b/qa/qa/page/component/select2.rb @@ -3,7 +3,7 @@ module QA module Component module Select2 def select_item(item_text) - find('.select2-result-label', text: item_text).click + find('.select2-result-label', text: item_text, match: :prefer_exact).click end def clear_current_selection_if_present diff --git a/qa/qa/page/project/new.rb b/qa/qa/page/project/new.rb index eabeae1acc4..552b2293115 100644 --- a/qa/qa/page/project/new.rb +++ b/qa/qa/page/project/new.rb @@ -24,11 +24,14 @@ module QA end def choose_test_namespace + choose_namespace(Runtime::Namespace.path) + end + + def choose_namespace(namespace) retry_on_exception do click_body click_element :project_namespace_select - - search_and_select(Runtime::Namespace.path) + search_and_select(namespace) end end diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_commits_header_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_commits_header_spec.js index 5cf6408cf34..9ee2f88c78d 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_commits_header_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_commits_header_spec.js @@ -15,6 +15,7 @@ describe('Commits header component', () => { isSquashEnabled: false, targetBranch: 'master', commitsCount: 5, + isFastForwardEnabled: false, ...props, }, }); @@ -31,6 +32,27 @@ describe('Commits header component', () => { const findTargetBranchMessage = () => wrapper.find('.label-branch'); const findModifyButton = () => wrapper.find('.modify-message-button'); + describe('when fast-forward is enabled', () => { + beforeEach(() => { + createComponent({ + isFastForwardEnabled: true, + isSquashEnabled: true, + }); + }); + + it('has commits count message showing 1 commit', () => { + expect(findCommitsCountMessage().text()).toBe('1 commit'); + }); + + it('has button with modify commit message', () => { + expect(findModifyButton().text()).toBe('Modify commit message'); + }); + + it('does not have merge commit part of the message', () => { + expect(findHeaderWrapper().text()).not.toContain('1 merge commit'); + }); + }); + describe('when collapsed', () => { it('toggle has aria-label equal to Expand', () => { createComponent(); @@ -78,6 +100,10 @@ describe('Commits header component', () => { expect(findTargetBranchMessage().text()).toBe('master'); }); + + it('does has merge commit part of the message', () => { + expect(findHeaderWrapper().text()).toContain('1 merge commit'); + }); }); describe('when expanded', () => { diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js index 08e173b0a10..6ed654250e6 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js @@ -18,6 +18,7 @@ const createTestMr = customConfig => { isPipelinePassing: false, isMergeAllowed: true, onlyAllowMergeIfPipelineSucceeds: false, + ffOnlyEnabled: false, hasCI: false, ciStatus: null, sha: '12345678', @@ -624,6 +625,10 @@ describe('ReadyToMerge', () => { const findCommitsHeaderElement = () => wrapper.find(CommitsHeader); const findCommitEditElements = () => wrapper.findAll(CommitEdit); const findCommitDropdownElement = () => wrapper.find(CommitMessageDropdown); + const findFirstCommitEditLabel = () => + findCommitEditElements() + .at(0) + .props('label'); describe('squash checkbox', () => { it('should be rendered when squash before merge is enabled and there is more than 1 commit', () => { @@ -648,31 +653,129 @@ describe('ReadyToMerge', () => { }); describe('commits count collapsible header', () => { - it('should be rendered if fast-forward is disabled', () => { + it('should be rendered when fast-forward is disabled', () => { createLocalComponent(); expect(findCommitsHeaderElement().exists()).toBeTruthy(); }); - it('should not be rendered if fast-forward is enabled', () => { - createLocalComponent({ mr: { ffOnlyEnabled: true } }); + describe('when fast-forward is enabled', () => { + it('should be rendered if squash and squash before are enabled and there is more than 1 commit', () => { + createLocalComponent({ + mr: { + ffOnlyEnabled: true, + enableSquashBeforeMerge: true, + squash: true, + commitsCount: 2, + }, + }); + + expect(findCommitsHeaderElement().exists()).toBeTruthy(); + }); + + it('should not be rendered if squash before merge is disabled', () => { + createLocalComponent({ + mr: { + ffOnlyEnabled: true, + enableSquashBeforeMerge: false, + squash: true, + commitsCount: 2, + }, + }); + + expect(findCommitsHeaderElement().exists()).toBeFalsy(); + }); + + it('should not be rendered if squash is disabled', () => { + createLocalComponent({ + mr: { + ffOnlyEnabled: true, + squash: false, + enableSquashBeforeMerge: true, + commitsCount: 2, + }, + }); + + expect(findCommitsHeaderElement().exists()).toBeFalsy(); + }); + + it('should not be rendered if commits count is 1', () => { + createLocalComponent({ + mr: { + ffOnlyEnabled: true, + squash: true, + enableSquashBeforeMerge: true, + commitsCount: 1, + }, + }); - expect(findCommitsHeaderElement().exists()).toBeFalsy(); + expect(findCommitsHeaderElement().exists()).toBeFalsy(); + }); }); }); describe('commits edit components', () => { + describe('when fast-forward merge is enabled', () => { + it('should not be rendered if squash is disabled', () => { + createLocalComponent({ + mr: { + ffOnlyEnabled: true, + squash: false, + enableSquashBeforeMerge: true, + commitsCount: 2, + }, + }); + + expect(findCommitEditElements().length).toBe(0); + }); + + it('should not be rendered if squash before merge is disabled', () => { + createLocalComponent({ + mr: { + ffOnlyEnabled: true, + squash: true, + enableSquashBeforeMerge: false, + commitsCount: 2, + }, + }); + + expect(findCommitEditElements().length).toBe(0); + }); + + it('should not be rendered if there is only one commit', () => { + createLocalComponent({ + mr: { + ffOnlyEnabled: true, + squash: true, + enableSquashBeforeMerge: true, + commitsCount: 1, + }, + }); + + expect(findCommitEditElements().length).toBe(0); + }); + + it('should have one edit component if squash is enabled and there is more than 1 commit', () => { + createLocalComponent({ + mr: { + ffOnlyEnabled: true, + squash: true, + enableSquashBeforeMerge: true, + commitsCount: 2, + }, + }); + + expect(findCommitEditElements().length).toBe(1); + expect(findFirstCommitEditLabel()).toBe('Squash commit message'); + }); + }); + it('should have one edit component when squash is disabled', () => { createLocalComponent(); expect(findCommitEditElements().length).toBe(1); }); - const findFirstCommitEditLabel = () => - findCommitEditElements() - .at(0) - .props('label'); - it('should have two edit components when squash is enabled and there is more than 1 commit', () => { createLocalComponent({ mr: { |