summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-23 21:08:31 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-23 21:08:31 +0000
commite679965983c591a9f009f6356b67a844582ca1bb (patch)
tree03648473fe38e9ff4c720d4ec8c58caa048c7181
parent7e1e5ca371cbfe77bdf56fcf65a4e749e6e86a06 (diff)
downloadgitlab-ce-e679965983c591a9f009f6356b67a844582ca1bb.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/badges/components/badge.vue14
-rw-r--r--app/assets/javascripts/boards/components/boards_selector.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/stage.vue2
-rw-r--r--app/assets/javascripts/related_issues/components/related_issues_list.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/gl_mentions.vue20
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/field.vue2
-rw-r--r--app/assets/stylesheets/bootstrap_migration.scss6
-rw-r--r--app/helpers/blob_helper.rb19
-rw-r--r--app/helpers/gitlab_routing_helper.rb12
-rw-r--r--app/serializers/diff_file_base_entity.rb2
-rw-r--r--app/views/shared/_ping_consent.html.haml20
-rw-r--r--changelogs/unreleased/233669-remove-bootstrap-ping.yml5
-rw-r--r--changelogs/unreleased/268301-mr-ide-button.yml5
-rw-r--r--config/routes.rb1
-rw-r--r--doc/.vale/gitlab/ToDo.yml13
-rw-r--r--doc/development/code_review.md10
-rw-r--r--doc/development/documentation/styleguide.md2
-rw-r--r--lib/api/api.rb2
-rw-r--r--lib/support/nginx/gitlab2
-rw-r--r--lib/support/nginx/gitlab-ssl2
-rw-r--r--locale/gitlab.pot14
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb15
-rw-r--r--spec/helpers/blob_helper_spec.rb49
23 files changed, 169 insertions, 54 deletions
diff --git a/app/assets/javascripts/badges/components/badge.vue b/app/assets/javascripts/badges/components/badge.vue
index 3dd05f73841..0b8c6aff219 100644
--- a/app/assets/javascripts/badges/components/badge.vue
+++ b/app/assets/javascripts/badges/components/badge.vue
@@ -1,5 +1,5 @@
<script>
-import { GlLoadingIcon, GlTooltipDirective, GlIcon } from '@gitlab/ui';
+import { GlLoadingIcon, GlTooltipDirective, GlIcon, GlButton } from '@gitlab/ui';
export default {
// name: 'Badge' is a false positive: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/25
@@ -8,6 +8,7 @@ export default {
components: {
GlIcon,
GlLoadingIcon,
+ GlButton,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -90,15 +91,16 @@ export default {
</div>
</div>
- <button
+ <gl-button
v-show="hasError"
v-gl-tooltip.hover
:title="s__('Badges|Reload badge image')"
- class="btn btn-transparent btn-sm text-primary"
+ category="tertiary"
+ variant="success"
type="button"
+ icon="retry"
+ size="small"
@click="reloadImage"
- >
- <gl-icon :size="16" name="retry" />
- </button>
+ />
</div>
</template>
diff --git a/app/assets/javascripts/boards/components/boards_selector.vue b/app/assets/javascripts/boards/components/boards_selector.vue
index 271e1fc4b5f..0b079c78209 100644
--- a/app/assets/javascripts/boards/components/boards_selector.vue
+++ b/app/assets/javascripts/boards/components/boards_selector.vue
@@ -261,7 +261,7 @@ export default {
>
<gl-deprecated-dropdown-item
v-show="filteredBoards.length === 0"
- class="no-pointer-events text-secondary"
+ class="gl-pointer-events-none text-secondary"
>
{{ s__('IssueBoards|No matching boards found') }}
</gl-deprecated-dropdown-item>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue b/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue
index 4045f450104..581ea5fbb35 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue
@@ -168,7 +168,7 @@ export default {
aria-expanded="false"
@click="onClickStage"
>
- <span :aria-label="stage.title" aria-hidden="true" class="no-pointer-events">
+ <span :aria-label="stage.title" aria-hidden="true" class="gl-pointer-events-none">
<gl-icon :name="borderlessIcon" />
</span>
</button>
diff --git a/app/assets/javascripts/related_issues/components/related_issues_list.vue b/app/assets/javascripts/related_issues/components/related_issues_list.vue
index a75fe4397bb..dbceac91c39 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_list.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_list.vue
@@ -3,13 +3,9 @@ import { GlLoadingIcon } from '@gitlab/ui';
import Sortable from 'sortablejs';
import sortableConfig from 'ee_else_ce/sortable/sortable_config';
import RelatedIssuableItem from '~/vue_shared/components/issue/related_issuable_item.vue';
-import tooltip from '~/vue_shared/directives/tooltip';
export default {
name: 'RelatedIssuesList',
- directives: {
- tooltip,
- },
components: {
GlLoadingIcon,
RelatedIssuableItem,
diff --git a/app/assets/javascripts/vue_shared/components/gl_mentions.vue b/app/assets/javascripts/vue_shared/components/gl_mentions.vue
index e895a7a52ab..6d07eaa9c2f 100644
--- a/app/assets/javascripts/vue_shared/components/gl_mentions.vue
+++ b/app/assets/javascripts/vue_shared/components/gl_mentions.vue
@@ -10,6 +10,7 @@ const AutoComplete = {
Labels: 'labels',
Members: 'members',
MergeRequests: 'mergeRequests',
+ Milestones: 'milestones',
};
const groupType = 'Group'; // eslint-disable-line @gitlab/require-i18n-strings
@@ -120,6 +121,14 @@ const autoCompleteMap = {
return `<small>${original.reference || original.iid}</small> ${escape(original.title)}`;
},
},
+ [AutoComplete.Milestones]: {
+ filterValues() {
+ return this[AutoComplete.Milestones];
+ },
+ menuItemTemplate({ original }) {
+ return escape(original.title);
+ },
+ },
};
export default {
@@ -157,8 +166,8 @@ export default {
menuItemTemplate: autoCompleteMap[AutoComplete.Labels].menuItemTemplate,
selectTemplate: ({ original }) =>
NON_WORD_OR_INTEGER.test(original.title)
- ? `~"${original.title}"`
- : `~${original.title}`,
+ ? `~"${escape(original.title)}"`
+ : `~${escape(original.title)}`,
values: this.getValues(AutoComplete.Labels),
},
{
@@ -168,6 +177,13 @@ export default {
selectTemplate: ({ original }) => original.reference || `!${original.iid}`,
values: this.getValues(AutoComplete.MergeRequests),
},
+ {
+ trigger: '%',
+ lookup: 'title',
+ menuItemTemplate: autoCompleteMap[AutoComplete.Milestones].menuItemTemplate,
+ selectTemplate: ({ original }) => `%"${escape(original.title)}"`,
+ values: this.getValues(AutoComplete.Milestones),
+ },
],
});
diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue
index 65116ed8ca3..6a36ca162dd 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/field.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue
@@ -175,7 +175,7 @@ export default {
issues: this.enableAutocomplete && !this.glFeatures.tributeAutocomplete,
mergeRequests: this.enableAutocomplete && !this.glFeatures.tributeAutocomplete,
epics: this.enableAutocomplete,
- milestones: this.enableAutocomplete,
+ milestones: this.enableAutocomplete && !this.glFeatures.tributeAutocomplete,
labels: this.enableAutocomplete && !this.glFeatures.tributeAutocomplete,
snippets: this.enableAutocomplete,
},
diff --git a/app/assets/stylesheets/bootstrap_migration.scss b/app/assets/stylesheets/bootstrap_migration.scss
index aac32e7fb2d..165feba4a81 100644
--- a/app/assets/stylesheets/bootstrap_migration.scss
+++ b/app/assets/stylesheets/bootstrap_migration.scss
@@ -131,12 +131,6 @@ table {
border-spacing: 0;
}
-.tooltip,
-.no-pointer-events {
- // Fix bootstrap4 bug whereby tooltips flicker when they are hovered over their borders
- pointer-events: none;
-}
-
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 806fea3ab44..69e7556ef20 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -26,6 +26,25 @@ module BlobHelper
File.join(segments)
end
+ def ide_merge_request_path(merge_request, path = '')
+ target_project = merge_request.target_project
+ source_project = merge_request.source_project
+
+ if merge_request.merged?
+ branch = merge_request.target_branch_exists? ? merge_request.target_branch : target_project.default_branch
+
+ return ide_edit_path(target_project, branch, path)
+ end
+
+ if target_project != source_project
+ params = { target_project: target_project.full_path }
+ end
+
+ result = File.join(ide_path, 'project', source_project.full_path, 'merge_requests', merge_request.to_param)
+ result += "?#{params.to_query}" unless params.nil?
+ result
+ end
+
def ide_fork_and_edit_path(project = @project, ref = @ref, path = @path, options = {})
fork_path_for_current_user(project, ide_edit_path(project, ref, path))
end
diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb
index 7df6bef7914..d71e6b4c004 100644
--- a/app/helpers/gitlab_routing_helper.rb
+++ b/app/helpers/gitlab_routing_helper.rb
@@ -343,18 +343,6 @@ module GitlabRoutingHelper
Gitlab::UrlBuilder.wiki_page_url(wiki, page, only_path: true, **options)
end
- def gitlab_ide_merge_request_path(merge_request)
- target_project = merge_request.target_project
- source_project = merge_request.source_project
- params = {}
-
- if target_project != source_project
- params = { target_project: target_project.full_path }
- end
-
- ide_merge_request_path(source_project.namespace, source_project, merge_request, params)
- end
-
private
def snippet_query_params(snippet, *args)
diff --git a/app/serializers/diff_file_base_entity.rb b/app/serializers/diff_file_base_entity.rb
index 596f5d686da..5036f28184c 100644
--- a/app/serializers/diff_file_base_entity.rb
+++ b/app/serializers/diff_file_base_entity.rb
@@ -48,7 +48,7 @@ class DiffFileBaseEntity < Grape::Entity
next unless has_edit_path?(merge_request)
- gitlab_ide_merge_request_path(merge_request)
+ ide_merge_request_path(merge_request, diff_file.new_path)
end
expose :old_path_html do |diff_file|
diff --git a/app/views/shared/_ping_consent.html.haml b/app/views/shared/_ping_consent.html.haml
index ded9b55056a..d0f1e4d7221 100644
--- a/app/views/shared/_ping_consent.html.haml
+++ b/app/views/shared/_ping_consent.html.haml
@@ -1,12 +1,14 @@
- if session[:ask_for_usage_stats_consent]
- .ping-consent-message.alert.alert-warning.flex-alert
- - settings_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" class="alert-link">'.html_safe % { url: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings') }
- - info_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer" class="alert-link">'.html_safe % { url: help_page_path('user/admin_area/settings/usage_statistics.md') }
- .alert-message
- = s_('To help improve GitLab, we would like to periodically collect usage information. This can be changed at any time in %{settings_link_start}Settings%{link_end}. %{info_link_start}More Information%{link_end}').html_safe % { settings_link_start: settings_link_start, info_link_start: info_link_start, link_end: '</a>'.html_safe }
- .alert-link-group
+ .ping-consent-message.gl-alert.gl-alert-info
+ = sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+ %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
+ = sprite_icon('close', css_class: 'gl-icon')
+ .gl-alert-body
+ - docs_link = link_to _('collect usage information'), help_page_path('user/admin_area/settings/usage_statistics.md'), class: 'gl-link'
+ - settings_link = link_to _('your settings'), metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), class: 'gl-link'
+ = s_('To help improve GitLab, we would like to periodically %{docs_link}. This can be changed at any time in %{settings_link}.').html_safe % { docs_link: docs_link, settings_link: settings_link }
+ .gl-alert-actions.gl-mt-3
- send_usage_data_path = admin_application_settings_path(application_setting: { version_check_enabled: 1, usage_ping_enabled: 1 })
- not_now_path = admin_application_settings_path(application_setting: { version_check_enabled: 0, usage_ping_enabled: 0 })
- = link_to _("Send usage data"), send_usage_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-ping-enabled': true, class: 'alert-link js-usage-consent-action'
- |
- = link_to _('Not now'), not_now_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': false, 'data-ping-enabled': false, class: 'hide-ping-consent-message alert-link js-usage-consent-action'
+ = link_to _("Send usage data"), send_usage_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-ping-enabled': true, class: 'js-usage-consent-action alert-link btn gl-button btn-info'
+ = link_to _("Don't send usage data"), not_now_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': false, 'data-ping-enabled': false, class: 'js-usage-consent-action alert-link btn gl-button btn-default gl-ml-2'
diff --git a/changelogs/unreleased/233669-remove-bootstrap-ping.yml b/changelogs/unreleased/233669-remove-bootstrap-ping.yml
new file mode 100644
index 00000000000..8306ec9862b
--- /dev/null
+++ b/changelogs/unreleased/233669-remove-bootstrap-ping.yml
@@ -0,0 +1,5 @@
+---
+title: Replace bootstrap classes for alerts in ping consent
+merge_request: 45723
+author:
+type: other
diff --git a/changelogs/unreleased/268301-mr-ide-button.yml b/changelogs/unreleased/268301-mr-ide-button.yml
new file mode 100644
index 00000000000..5528d05d6d4
--- /dev/null
+++ b/changelogs/unreleased/268301-mr-ide-button.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Merge Request "Edit in Web IDE" dropdown link on MR diffs page
+merge_request: 45653
+author:
+type: fixed
diff --git a/config/routes.rb b/config/routes.rb
index f6c8bb95eb3..3ef14acbdd9 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -122,7 +122,6 @@ Rails.application.routes.draw do
get 'ide' => 'ide#index'
get 'ide/*vueroute' => 'ide#index', format: false
- get 'ide/project/:namespace/:project/merge_requests/:id' => 'ide#index', format: false, as: :ide_merge_request
draw :operations
draw :jira_connect
diff --git a/doc/.vale/gitlab/ToDo.yml b/doc/.vale/gitlab/ToDo.yml
new file mode 100644
index 00000000000..fcb5c854e7e
--- /dev/null
+++ b/doc/.vale/gitlab/ToDo.yml
@@ -0,0 +1,13 @@
+---
+# Warning: gitlab.ToDo
+#
+# You should not use "To Do", unless it refers to the UI element.
+#
+# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
+extends: substitution
+message: 'Use "%s" instead of "%s" unless referring to the "Add a To Do" button in the UI.'
+link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#feature-names
+level: warning
+ignorecase: true
+swap:
+ 'to dos': to-do items
diff --git a/doc/development/code_review.md b/doc/development/code_review.md
index 3ff802d3b23..239012c7221 100644
--- a/doc/development/code_review.md
+++ b/doc/development/code_review.md
@@ -91,8 +91,14 @@ with [domain expertise](#domain-experts).
**approved by a [frontend maintainer](https://about.gitlab.com/handbook/engineering/projects/#gitlab_maintainers_frontend)**.
1. If your merge request includes UX changes (*1*), it must be
**approved by a [UX team member](https://about.gitlab.com/company/team/)**.
-1. If your merge request includes adding a new JavaScript library (*1*), it must be
- **approved by a [frontend lead](https://about.gitlab.com/company/team/)**.
+1. If your merge request includes adding a new JavaScript library (*1*)...
+ - If the library significantly increases the
+ [bundle size](https://gitlab.com/gitlab-org/frontend/playground/webpack-memory-metrics/-/blob/master/doc/report.md), it must
+ be **approved by a [frontend foundations member](https://about.gitlab.com/direction/create/ecosystem/frontend-ux-foundations/)**.
+ - If the license used by the new library hasn't been approved for use in
+ GitLab, the license must be **approved by a [legal department member](https://about.gitlab.com/handbook/legal/)**.
+ More information about license compatiblity can be found in our
+ [GitLab Licensing and Compatibility documentation](./licensing.md).
1. If your merge request includes adding a new UI/UX paradigm (*1*), it must be
**approved by a [UX lead](https://about.gitlab.com/company/team/)**.
1. If your merge request includes a new dependency or a filesystem change, it must be
diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md
index 032b0713ca3..51053e37dae 100644
--- a/doc/development/documentation/styleguide.md
+++ b/doc/development/documentation/styleguide.md
@@ -369,7 +369,7 @@ create an issue or an MR to propose a change to the user interface text.
- milestones
- reorder issues
- runner, runners, shared runners
- - a to-do item, to dos
+ - a to-do item (tested in [`ToDo.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/ToDo.yml))
- *Some features are capitalized*, typically nouns naming GitLab-specific
capabilities or tools. For example:
- GitLab CI/CD
diff --git a/lib/api/api.rb b/lib/api/api.rb
index ec252faa6cb..5a58f1adbc1 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -118,7 +118,7 @@ module API
# There is a small chance some users depend on the old behavior.
# We this change under a feature flag to see if affects GitLab.com users.
- if Feature.enabled?(:api_json_content_type)
+ if Gitlab::Database.cached_table_exists?('features') && Feature.enabled?(:api_json_content_type)
content_type :json, 'application/json'
else
content_type :txt, 'text/plain'
diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab
index fc984d737d5..9eafa5ef008 100644
--- a/lib/support/nginx/gitlab
+++ b/lib/support/nginx/gitlab
@@ -18,7 +18,7 @@
upstream gitlab-workhorse {
# GitLab socket file,
- # for Omnibus this would be: unix:/var/opt/gitlab/gitlab-workhorse/socket
+ # for Omnibus this would be: unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket
server unix:/home/git/gitlab/tmp/sockets/gitlab-workhorse.socket fail_timeout=0;
}
diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl
index ba01e250bbb..ae5c88455e4 100644
--- a/lib/support/nginx/gitlab-ssl
+++ b/lib/support/nginx/gitlab-ssl
@@ -22,7 +22,7 @@
upstream gitlab-workhorse {
# GitLab socket file,
- # for Omnibus this would be: unix:/var/opt/gitlab/gitlab-workhorse/socket
+ # for Omnibus this would be: unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket
server unix:/home/git/gitlab/tmp/sockets/gitlab-workhorse.socket fail_timeout=0;
}
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 3cbac2eab55..23cca889ab2 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -9451,6 +9451,9 @@ msgstr ""
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr ""
+msgid "Don't send usage data"
+msgstr ""
+
msgid "Don't show again"
msgstr ""
@@ -18164,9 +18167,6 @@ msgstr ""
msgid "Not found."
msgstr ""
-msgid "Not now"
-msgstr ""
-
msgid "Not ready yet. Try again later."
msgstr ""
@@ -27690,7 +27690,7 @@ msgstr ""
msgid "To help improve GitLab and its user experience, GitLab will periodically collect usage information."
msgstr ""
-msgid "To help improve GitLab, we would like to periodically collect usage information. This can be changed at any time in %{settings_link_start}Settings%{link_end}. %{info_link_start}More Information%{link_end}"
+msgid "To help improve GitLab, we would like to periodically %{docs_link}. This can be changed at any time in %{settings_link}."
msgstr ""
msgid "To import an SVN repository, check out %{svn_link}."
@@ -31153,6 +31153,9 @@ msgstr ""
msgid "closed issue"
msgstr ""
+msgid "collect usage information"
+msgstr ""
+
msgid "comment"
msgstr ""
@@ -32287,3 +32290,6 @@ msgstr ""
msgid "yaml invalid"
msgstr ""
+
+msgid "your settings"
+msgstr ""
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index ff78b9e608f..3b81f199267 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -535,6 +535,21 @@ RSpec.describe 'GFM autocomplete', :js do
expect(find('.tribute-container ul', visible: true)).to have_text(user_xss.username)
end
+ it 'opens autocomplete menu for Milestone when field starts with text with item escaping HTML characters' do
+ milestone_xss_title = 'alert milestone &lt;img src=x onerror="alert(\'Hello xss\');" a'
+ create(:milestone, project: project, title: milestone_xss_title)
+
+ page.within '.timeline-content-form' do
+ find('#note-body').native.send_keys('%')
+ end
+
+ wait_for_requests
+
+ expect(page).to have_selector('.tribute-container', visible: true)
+
+ expect(find('.tribute-container ul', visible: true)).to have_text('alert milestone')
+ end
+
it 'selects the first item for assignee dropdowns' do
page.within '.timeline-content-form' do
find('#note-body').native.send_keys('@')
diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb
index baa97781efa..48516141a85 100644
--- a/spec/helpers/blob_helper_spec.rb
+++ b/spec/helpers/blob_helper_spec.rb
@@ -444,6 +444,55 @@ RSpec.describe BlobHelper do
end
end
+ describe '#ide_merge_request_path' do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:merge_request) { create(:merge_request, source_project: project)}
+
+ it 'returns IDE path for the given MR if MR is not merged' do
+ expect(helper.ide_merge_request_path(merge_request)).to eq("/-/ide/project/#{project.full_path}/merge_requests/#{merge_request.iid}")
+ end
+
+ context 'when the MR comes from a fork' do
+ include ProjectForksHelper
+
+ let(:forked_project) { fork_project(project, nil, repository: true) }
+ let(:merge_request) { create(:merge_request, source_project: forked_project, target_project: project) }
+
+ it 'returns IDE path for MR in the forked repo with target project included as param' do
+ expect(helper.ide_merge_request_path(merge_request)).to eq("/-/ide/project/#{forked_project.full_path}/merge_requests/#{merge_request.iid}?target_project=#{CGI.escape(project.full_path)}")
+ end
+ end
+
+ context 'when the MR is merged' do
+ let(:current_user) { build(:user) }
+
+ let_it_be(:merge_request) { create(:merge_request, :merged, source_project: project, source_branch: 'testing-1', target_branch: 'feature-1') }
+
+ before do
+ allow(helper).to receive(:current_user).and_return(current_user)
+ allow(helper).to receive(:can?).and_return(true)
+ end
+
+ it 'returns default IDE url with master branch' do
+ expect(helper.ide_merge_request_path(merge_request)).to eq("/-/ide/project/#{project.full_path}/edit/master")
+ end
+
+ it 'includes file path passed' do
+ expect(helper.ide_merge_request_path(merge_request, 'README.md')).to eq("/-/ide/project/#{project.full_path}/edit/master/-/README.md")
+ end
+
+ context 'when target branch exists' do
+ before do
+ allow(merge_request).to receive(:target_branch_exists?).and_return(true)
+ end
+
+ it 'returns IDE edit url with the target branch' do
+ expect(helper.ide_merge_request_path(merge_request)).to eq("/-/ide/project/#{project.full_path}/edit/feature-1")
+ end
+ end
+ end
+ end
+
describe '#ide_fork_and_edit_path' do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }