Commit 23e8ae01 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents c2060944 8896ceeb
......@@ -499,10 +499,10 @@ const Api = {
return axios.put(url, params);
},
applySuggestionBatch(ids) {
applySuggestionBatch(ids, message) {
const url = Api.buildUrl(Api.applySuggestionBatchPath);
return axios.put(url, { ids });
return axios.put(url, { ids, commit_message: message });
},
commitPipelines(projectId, sha) {
......
......@@ -51,7 +51,7 @@ export default {
},
},
computed: {
...mapGetters(['getDiscussion', 'suggestionsCount']),
...mapGetters(['getDiscussion', 'suggestionsCount', 'getSuggestionsFilePaths']),
...mapGetters('diffs', ['suggestionCommitMessage']),
discussion() {
if (!this.note.isDraft) return {};
......@@ -74,9 +74,10 @@ export default {
// Please see this issue comment for why these
// are hard-coded to 1:
// https://gitlab.com/gitlab-org/gitlab/-/issues/291027#note_468308022
const suggestionsCount = 1;
const filesCount = 1;
const filePaths = this.file ? [this.file.file_path] : [];
const suggestionsCount = this.batchSuggestionsInfo.length || 1;
const batchFilePaths = this.getSuggestionsFilePaths();
const filePaths = batchFilePaths.length ? batchFilePaths : [this.file.file_path];
const filesCount = filePaths.length;
const suggestion = this.suggestionCommitMessage({
file_paths: filePaths.join(', '),
suggestions_count: suggestionsCount,
......@@ -131,8 +132,8 @@ export default {
message,
}).then(callback);
},
applySuggestionBatch({ flashContainer }) {
return this.submitSuggestionBatch({ flashContainer });
applySuggestionBatch({ message, flashContainer }) {
return this.submitSuggestionBatch({ message, flashContainer });
},
addSuggestionToBatch(suggestionId) {
const { discussion_id: discussionId, id: noteId } = this.note;
......
......@@ -631,7 +631,7 @@ export const submitSuggestion = (
});
};
export const submitSuggestionBatch = ({ commit, dispatch, state }, { flashContainer }) => {
export const submitSuggestionBatch = ({ commit, dispatch, state }, { message, flashContainer }) => {
const suggestionIds = state.batchSuggestionsInfo.map(({ suggestionId }) => suggestionId);
const resolveAllDiscussions = () =>
......@@ -644,7 +644,7 @@ export const submitSuggestionBatch = ({ commit, dispatch, state }, { flashContai
commit(types.SET_RESOLVING_DISCUSSION, true);
dispatch('stopPolling');
return Api.applySuggestionBatch(suggestionIds)
return Api.applySuggestionBatch(suggestionIds, message)
.then(() => Promise.all(resolveAllDiscussions()))
.then(() => commit(types.CLEAR_SUGGESTION_BATCH))
.catch((err) => {
......
......@@ -283,3 +283,14 @@ export const suggestionsCount = (state, getters) =>
export const hasDrafts = (state, getters, rootState, rootGetters) =>
Boolean(rootGetters['batchComments/hasDrafts']);
export const getSuggestionsFilePaths = (state) => () =>
state.batchSuggestionsInfo.reduce((acc, suggestion) => {
const discussion = state.discussions.find((d) => d.id === suggestion.discussionId);
if (acc.indexOf(discussion?.diff_file?.file_path) === -1) {
acc.push(discussion.diff_file.file_path);
}
return acc;
}, []);
......@@ -220,6 +220,7 @@ export default {
class="gl-h-200! gl-mb-4"
single-file-selection
:valid-file-mimetypes="$options.validFileMimetypes"
:is-file-valid="() => true"
@change="setFile"
>
<div
......
<script>
import { GlDropdown, GlDropdownForm, GlFormTextarea, GlButton } from '@gitlab/ui';
import { __, n__ } from '~/locale';
export default {
components: { GlDropdown, GlDropdownForm, GlFormTextarea, GlButton },
......@@ -13,12 +14,26 @@ export default {
type: String,
required: true,
},
batchSuggestionsCount: {
type: Number,
required: false,
default: 0,
},
},
data() {
return {
message: null,
};
},
computed: {
dropdownText() {
if (this.batchSuggestionsCount <= 1) {
return __('Apply suggestion');
}
return n__('Apply %d suggestion', 'Apply %d suggestions', this.batchSuggestionsCount);
},
},
methods: {
onApply() {
this.$emit('apply', this.message);
......@@ -29,10 +44,11 @@ export default {
<template>
<gl-dropdown
:text="__('Apply suggestion')"
:text="dropdownText"
:disabled="disabled"
boundary="window"
right
lazy
menu-class="gl-w-full!"
data-qa-selector="apply_suggestion_dropdown"
@shown="$refs.commitMessage.$el.focus()"
......
......@@ -54,8 +54,8 @@ export default {
applySuggestion(callback, message) {
this.$emit('apply', { suggestionId: this.suggestion.id, callback, message });
},
applySuggestionBatch() {
this.$emit('applyBatch');
applySuggestionBatch(message) {
this.$emit('applyBatch', message);
},
addSuggestionToBatch() {
this.$emit('addToBatch', this.suggestion.id);
......
......@@ -58,12 +58,19 @@ export default {
isApplyingSingle: false,
};
},
computed: {
isApplying() {
return this.isApplyingSingle || this.isApplyingBatch;
},
tooltipMessage() {
return this.canApply ? __('This also resolves this thread') : this.inapplicableReason;
if (!this.canApply) {
return this.inapplicableReason;
}
return this.batchSuggestionsCount > 1
? __('This also resolves all related threads')
: __('This also resolves this thread');
},
isDisableButton() {
return this.isApplying || !this.canApply;
......@@ -72,13 +79,30 @@ export default {
if (this.isApplyingSingle || this.batchSuggestionsCount < 2) {
return __('Applying suggestion...');
}
return __('Applying suggestions...');
},
isLoggedIn() {
return isLoggedIn();
},
showApplySuggestion() {
if (!this.isLoggedIn) return false;
if (this.batchSuggestionsCount >= 1 && !this.isBatched) {
return false;
}
return true;
},
},
methods: {
apply(message) {
if (this.batchSuggestionsCount > 1) {
this.applySuggestionBatch(message);
} else {
this.applySuggestion(message);
}
},
applySuggestion(message) {
if (!this.canApply) return;
this.isApplyingSingle = true;
......@@ -88,9 +112,9 @@ export default {
applySuggestionCallback() {
this.isApplyingSingle = false;
},
applySuggestionBatch() {
applySuggestionBatch(message) {
if (!this.canApply) return;
this.$emit('applyBatch');
this.$emit('applyBatch', message);
},
addSuggestionToBatch() {
this.$emit('addToBatch');
......@@ -115,45 +139,35 @@ export default {
<gl-loading-icon size="sm" class="d-flex-center mr-2" />
<span>{{ applyingSuggestionsMessage }}</span>
</div>
<div v-else-if="canApply && isBatched" class="d-flex align-items-center">
<gl-button
class="btn-inverted js-remove-from-batch-btn btn-grouped"
:disabled="isApplying"
@click="removeSuggestionFromBatch"
>
{{ __('Remove from batch') }}
</gl-button>
<gl-button
v-gl-tooltip.viewport="__('This also resolves all related threads')"
class="btn-inverted js-apply-batch-btn btn-grouped"
data-qa-selector="apply_suggestions_batch_button"
:disabled="isApplying"
variant="success"
@click="applySuggestionBatch"
>
{{ __('Apply suggestions') }}
<span class="badge badge-pill badge-pill-success">
{{ batchSuggestionsCount }}
</span>
</gl-button>
</div>
<div v-else class="d-flex align-items-center">
<gl-button
v-if="suggestionsCount > 1 && !isDisableButton"
class="btn-inverted js-add-to-batch-btn btn-grouped"
data-qa-selector="add_suggestion_batch_button"
:disabled="isDisableButton"
@click="addSuggestionToBatch"
>
{{ __('Add suggestion to batch') }}
</gl-button>
<div v-else-if="canApply" class="d-flex align-items-center">
<div v-if="isBatched">
<gl-button
class="btn-inverted js-remove-from-batch-btn btn-grouped"
:disabled="isApplying"
@click="removeSuggestionFromBatch"
>
{{ __('Remove from batch') }}
</gl-button>
</div>
<div v-else>
<gl-button
v-if="!isDisableButton && suggestionsCount > 1"
class="btn-inverted js-add-to-batch-btn btn-grouped"
data-qa-selector="add_suggestion_batch_button"
:disabled="isDisableButton"
@click="addSuggestionToBatch"
>
{{ __('Add suggestion to batch') }}
</gl-button>
</div>
<apply-suggestion
v-if="isLoggedIn"
v-if="showApplySuggestion"
v-gl-tooltip.viewport="tooltipMessage"
:disabled="isDisableButton"
:default-commit-message="defaultCommitMessage"
:batch-suggestions-count="batchSuggestionsCount"
class="gl-ml-3"
@apply="applySuggestion"
@apply="apply"
/>
</div>
</div>
......
......@@ -68,6 +68,10 @@ export default {
if (this.suggestionsWatch) {
this.suggestionsWatch();
}
if (this.defaultCommitMessageWatch) {
this.defaultCommitMessageWatch();
}
},
methods: {
renderSuggestions() {
......@@ -123,12 +127,16 @@ export default {
suggestionDiff.suggestionsCount = this.suggestionsCount;
});
this.defaultCommitMessageWatch = this.$watch('defaultCommitMessage', () => {
suggestionDiff.defaultCommitMessage = this.defaultCommitMessage;
});
suggestionDiff.$on('apply', ({ suggestionId, callback, message }) => {
this.$emit('apply', { suggestionId, callback, flashContainer: this.$el, message });
});
suggestionDiff.$on('applyBatch', () => {
this.$emit('applyBatch', { flashContainer: this.$el });
suggestionDiff.$on('applyBatch', (message) => {
this.$emit('applyBatch', { message, flashContainer: this.$el });
});
suggestionDiff.$on('addToBatch', (suggestionId) => {
......
......@@ -45,7 +45,7 @@ export default {
data() {
return {
dragCounter: 0,
isDragDataValid: false,
isDragDataValid: true,
};
},
computed: {
......
......@@ -153,6 +153,10 @@
vertical-align: middle;
margin-bottom: 3px;
}
.dropdown-chevron {
margin-bottom: 0;
}
}
@include media-breakpoint-down(xs) {
......
......@@ -61,7 +61,9 @@ module Analytics
# rubocop: enable CodeReuse/ActiveRecord
def runner_configured
Ci::Runner.active.belonging_to_group_or_project(snapshot_groups, snapshot_project_ids).exists?
::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/337541') do
Ci::Runner.active.belonging_to_group_or_project(snapshot_groups, snapshot_project_ids).exists?
end
end
def pipeline_succeeded
......@@ -119,10 +121,16 @@ module Analytics
# rubocop: disable CodeReuse/ActiveRecord
def projects_count_with_artifact(artifacts_scope)
subquery = artifacts_scope.created_in_time_range(from: range_start, to: range_end)
.where(Ci::JobArtifact.arel_table[:project_id].eq(Project.arel_table[:id])).arel.exists
.where(Ci::JobArtifact.arel_table[:project_id].eq(Arel.sql('project_ids.id'))).arel.exists
snapshot_project_ids.each_slice(1000).sum do |project_ids|
Project.where(id: project_ids).where(subquery).count
ids = project_ids.map { |id| [id] }
# To avoid cross-database join, we swap out the FROM part with just the project_ids we need
Project
.select(:id)
.from("(#{Arel::Nodes::ValuesList.new(ids).to_sql}) project_ids (id)")
.where(subquery)
.count
end
end
# rubocop: enable CodeReuse/ActiveRecord
......
......@@ -17,11 +17,17 @@ module Gitlab
params '#issue'
types Issue
condition do
quick_action_target.persisted? &&
current_user.can?(:"update_#{quick_action_target.to_ability_name}", quick_action_target)
current_user.can?(:"update_#{quick_action_target.to_ability_name}", quick_action_target)
end
command :relate do |related_param|
IssueLinks::CreateService.new(quick_action_target, current_user, { issuable_references: [related_param] }).execute
command :relate do |related_reference|
service = IssueLinks::CreateService.new(quick_action_target, current_user, { issuable_references: [related_reference] })
create_issue_link = proc { service.execute }
if quick_action_target.persisted?
create_issue_link.call
else
quick_action_target.run_after_commit(&create_issue_link)
end
end
end
end
......
......@@ -4110,6 +4110,11 @@ msgstr ""
msgid "Apply"
msgstr ""
msgid "Apply %d suggestion"
msgid_plural "Apply %d suggestions"
msgstr[0] ""
msgstr[1] ""
msgid "Apply a label"
msgstr ""
......@@ -4119,9 +4124,6 @@ msgstr ""
msgid "Apply suggestion"
msgstr ""
msgid "Apply suggestions"
msgstr ""
msgid "Apply template"
msgstr ""
......
......@@ -93,7 +93,6 @@ module QA
end
view 'app/assets/javascripts/vue_shared/components/markdown/suggestion_diff_header.vue' do
element :apply_suggestions_batch_button
element :add_suggestion_batch_button
end
......@@ -353,10 +352,6 @@ module QA
all_elements(:add_suggestion_batch_button, minimum: 1).first.click
end
def apply_suggestions_batch
all_elements(:apply_suggestions_batch_button, minimum: 1).first.click
end
def cherry_pick!
click_element(:cherry_pick_button, Page::Component::CommitModal)
click_element(:submit_commit_button)
......
......@@ -50,7 +50,7 @@ module QA
Page::MergeRequest::Show.perform do |merge_request|
merge_request.click_diffs_tab
4.times { merge_request.add_suggestion_to_batch }
merge_request.apply_suggestions_batch
merge_request.apply_suggestion_with_message("Custom commit message")
expect(merge_request).to have_css('.badge-success', text: "Applied", count: 4)
end
......
......@@ -159,7 +159,12 @@ RSpec.describe 'User comments on a diff', :js do
wait_for_requests
expect(page).to have_content('Remove from batch')
expect(page).to have_content("Apply suggestions #{index + 1}")
if index < 1
expect(page).to have_content("Apply suggestion")
else
expect(page).to have_content("Apply #{index + 1} suggestions")
end
end
end
......@@ -167,13 +172,12 @@ RSpec.describe 'User comments on a diff', :js do
click_button('Remove from batch')
wait_for_requests
expect(page).to have_content('Apply suggestion')
expect(page).to have_content('Add suggestion to batch')
end
page.within("[id='#{files[1][:hash]}']") do
expect(page).to have_content('Remove from batch')
expect(page).to have_content('Apply suggestions 1')
expect(page).to have_content('Apply suggestion')
end
end
......
......@@ -19,13 +19,15 @@ RSpec.describe 'Projects > Files > User uploads files' do
wait_for_requests
end
include_examples 'it uploads and commits a new text file'
[true, false].each do |value|
include_examples 'it uploads and commits a new text file', drop: value
include_examples 'it uploads and commits a new image file'
include_examples 'it uploads and commits a new image file', drop: value
include_examples 'it uploads and commits a new pdf file'
include_examples 'it uploads and commits a new pdf file', drop: value
include_examples 'it uploads a file to a sub-directory'
include_examples 'it uploads a file to a sub-directory', drop: value
end
end
context 'when a user does not have write access' do
......@@ -35,6 +37,8 @@ RSpec.describe 'Projects > Files > User uploads files' do
visit(project_tree_path(project2))
end
include_examples 'it uploads and commits a new file to a forked project'
[true, false].each do |value|
include_examples 'it uploads and commits a new file to a forked project', drop: value
end
end
end
......@@ -21,13 +21,15 @@ RSpec.describe 'Projects > Show > User uploads files' do
wait_for_requests
end
include_examples 'it uploads and commits a new text file'
[true, false].each do |value|
include_examples 'it uploads and commits a new text file', drop: value
include_examples 'it uploads and commits a new image file'
include_examples 'it uploads and commits a new image file', drop: value
include_examples 'it uploads and commits a new pdf file'
include_examples 'it uploads and commits a new pdf file', drop: value
include_examples 'it uploads a file to a sub-directory'
include_examples 'it uploads a file to a sub-directory', drop: value
end
end
context 'when a user does not have write access' do
......@@ -37,7 +39,9 @@ RSpec.describe 'Projects > Show > User uploads files' do
visit(project_path(project2))
end
include_examples 'it uploads and commits a new file to a forked project'
[true, false].each do |value|
include_examples 'it uploads and commits a new file to a forked project', drop: value
end
end
context 'when in the empty_repo_upload experiment' do
......@@ -50,13 +54,17 @@ RSpec.describe 'Projects > Show > User uploads files' do
context 'with an empty repo' do
let(:project) { create(:project, :empty_repo, creator: user) }
include_examples 'uploads and commits a new text file via "upload file" button'
[true, false].each do |value|
include_examples 'uploads and commits a new text file via "upload file" button', drop: value
end
end
context 'with a nonempty repo' do
let(:project) { create(:project, :repository, creator: user) }
include_examples 'uploads and commits a new text file via "upload file" button'
[true, false].each do |value|
include_examples 'uploads and commits a new text file via "upload file" button', drop: value
end
end
end
end
import DropdownUtils from '~/filtered_search/dropdown_utils';
// TODO: Moving this line up throws an error about `FilteredSearchDropdown`
// being undefined in test. See gitlab-org/gitlab#321476 for more info.
import DropdownUser from '~/filtered_search/dropdown_user';
import DropdownUtils from '~/filtered_search/dropdown_utils';
import FilteredSearchTokenizer from '~/filtered_search/filtered_search_tokenizer';
import IssuableFilteredTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
......
......@@ -60,7 +60,7 @@ describe('Suggestion Diff component', () => {
expect(findHelpButton().exists()).toBe(true);
});
it('renders apply suggestion and add to batch buttons', () => {
it('renders add to batch button when more than 1 suggestion', () => {
createComponent({
suggestionsCount: 2,
});
......@@ -68,8 +68,7 @@ describe('Suggestion Diff component', () => {
const applyBtn = findApplyButton();
const addToBatchBtn = findAddToBatchButton();
expect(applyBtn.exists()).toBe(true);
expect(applyBtn.html().includes('Apply suggestion')).toBe(true);
expect(applyBtn.exists()).toBe(false);
expect(addToBatchBtn.exists()).toBe(true);
expect(addToBatchBtn.html().includes('Add suggestion to batch')).toBe(true);
......@@ -85,7 +84,7 @@ describe('Suggestion Diff component', () => {
describe('when apply suggestion is clicked', () => {
beforeEach(() => {
createComponent();
createComponent({ batchSuggestionsCount: 0 });
findApplyButton().vm.$emit('apply');
});
......@@ -140,11 +139,11 @@ describe('Suggestion Diff component', () => {
describe('apply suggestions is clicked', () => {
it('emits applyBatch', () => {
createComponent({ isBatched: true });
createComponent({ isBatched: true, batchSuggestionsCount: 2 });
findApplyBatchButton().vm.$emit('click');
findApplyButton().vm.$emit('apply');
expect(wrapper.emitted().applyBatch).toEqual([[]]);
expect(wrapper.emitted().applyBatch).toEqual([[undefined]]);
});
});
......@@ -155,23 +154,24 @@ describe('Suggestion Diff component', () => {
isBatched: true,
});
const applyBatchBtn = findApplyBatchButton();
const applyBatchBtn = findApplyButton();
const removeFromBatchBtn = findRemoveFromBatchButton();
expect(removeFromBatchBtn.exists()).toBe(true);
expect(removeFromBatchBtn.html().includes('Remove from batch')).toBe(true);
expect(applyBatchBtn.exists()).toBe(true);
expect(applyBatchBtn.html().includes('Apply suggestions')).toBe(true);
expect(applyBatchBtn.html().includes('Apply suggestion')).toBe(true);
expect(applyBatchBtn.html().includes(String('9'))).toBe(true);
});
it('hides add to batch and apply buttons', () => {
createComponent({
isBatched: true,
batchSuggestionsCount: 9,
});
expect(findApplyButton().exists()).toBe(false);
expect(findApplyButton().exists()).toBe(true);
expect(findAddToBatchButton().exists()).toBe(false);
});
......@@ -215,9 +215,8 @@ describe('Suggestion Diff component', () => {
});
it('disables apply suggestion and hides add to batch button', () => {
expect(findApplyButton().exists()).toBe(true);
expect(findApplyButton().exists()).toBe(false);
expect(findAddToBatchButton().exists()).toBe(false);
expect(findApplyButton().attributes('disabled')).toBe('true');
});
});
......@@ -225,20 +224,11 @@ describe('Suggestion Diff component', () => {
const findTooltip = () => getBinding(findApplyButton().element, 'gl-tooltip');
it('renders correct tooltip message when button is applicable', () => {
createComponent();
createComponent({ batchSuggestionsCount: 0 });
const tooltip = findTooltip();
expect(tooltip.modifiers.viewport).toBe(true);
expect(tooltip.value).toBe('This also resolves this thread');
});
it('renders the inapplicable reason in the tooltip when button is not applicable', () => {
const inapplicableReason = 'lorem';
createComponent({ canApply: false, inapplicableReason });
const tooltip = findTooltip();
expect(tooltip.modifiers.viewport).toBe(true);
expect(tooltip.value).toBe(inapplicableReason);
});
});
});
......@@ -77,7 +77,7 @@ describe('Suggestion Diff component', () => {
it.each`
event | childArgs | args
${'apply'} | ${['test-event']} | ${[{ callback: 'test-event', suggestionId }]}
${'applyBatch'} | ${[]} | ${[]}
${'applyBatch'} | ${['test-event']} | ${['test-event']}
${'addToBatch'} | ${[]} | ${[suggestionId]}
${'removeFromBatch'} | ${[]} | ${[suggestionId]}
`('emits $event event on sugestion diff header $event', ({ event, childArgs, args }) => {
......
......@@ -45,6 +45,7 @@ exports[`Upload dropzone component correctly overrides description and drop mess
>
<div
class="mw-50 gl-text-center"
style="display: none;"
>
<h3
class=""
......@@ -61,7 +62,6 @@ exports[`Upload dropzone component correctly overrides description and drop mess
<div
class="mw-50 gl-text-center"
style="display: none;"
>
<h3
class=""
......@@ -146,7 +146,6 @@ exports[`Upload dropzone component when dragging renders correct template when d
<div
class="mw-50 gl-text-center"
style=""
>
<h3
class=""
......@@ -231,7 +230,6 @@ exports[`Upload dropzone component when dragging renders correct template when d
<div
class="mw-50 gl-text-center"
style=""
>
<h3
class=""
......@@ -299,6 +297,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
>
<div
class="mw-50 gl-text-center"
style=""
>
<h3
class=""
......@@ -383,6 +382,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
>
<div
class="mw-50 gl-text-center"
style=""
>
<h3
class=""
......@@ -467,6 +467,7 @@ exports[`Upload dropzone component when dragging renders correct template when d
>
<div
class="mw-50 gl-text-center"
style=""
>
<h3
class=""
......@@ -551,6 +552,7 @@ exports[`Upload dropzone component when no slot provided renders default dropzon
>
<div
class="mw-50 gl-text-center"
style="display: none;"
>
<h3
class=""
......@@ -567,7 +569,6 @@ exports[`Upload dropzone component when no slot provided renders default dropzon
<div
class="mw-50 gl-text-center"
style="display: none;"
>
<h3
class=""
......@@ -603,6 +604,7 @@ exports[`Upload dropzone component when slot provided renders dropzone with slot
>
<div
class="mw-50 gl-text-center"
style="display: none;"
>
<h3
class=""
......@@ -619,7 +621,6 @@ exports[`Upload dropzone component when slot provided renders dropzone with slot
<div
class="mw-50 gl-text-center"
style="display: none;"
>
<h3
class=""
......
......@@ -1935,6 +1935,21 @@ RSpec.describe QuickActions::InterpretService do
it_behaves_like 'relate command'
end
context 'when quick action target is unpersisted' do
let(:issue) { build(:issue, project: project) }
let(:other_issue) { create(:issue, project: project) }
let(:issues_related) { [other_issue] }
let(:content) { "/relate #{other_issue.to_reference}" }
it 'relates the issues after the issue is persisted' do
service.execute(content, issue)
issue.save!
expect(IssueLink.where(source: issue).map(&:target)).to match_array(issues_related)
end
end
context 'empty relate command' do
let(:issues_related) { [] }
let(:content) { '/relate' }
......
......@@ -9,7 +9,6 @@
- "./ee/spec/finders/ee/namespaces/projects_finder_spec.rb"
- "./ee/spec/finders/security/findings_finder_spec.rb"
- "./ee/spec/graphql/ee/resolvers/namespace_projects_resolver_spec.rb"
- "./ee/spec/lib/analytics/devops_adoption/snapshot_calculator_spec.rb"
- "./ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_spec.rb"
- "./ee/spec/lib/ee/gitlab/background_migration/migrate_security_scans_spec.rb"
- "./ee/spec/lib/ee/gitlab/background_migration/populate_latest_pipeline_ids_spec.rb"
......
# frozen_string_literal: true
RSpec.shared_examples 'it uploads and commits a new text file' do
RSpec.shared_examples 'it uploads and commits a new text file' do |drop: false|
it 'uploads and commits a new text file', :js do
find('.add-to-tree').click
......@@ -10,7 +10,11 @@ RSpec.shared_examples 'it uploads and commits a new text file' do
wait_for_requests
end
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
if drop
find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
else
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
end
page.within('#modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
......@@ -32,7 +36,7 @@ RSpec.shared_examples 'it uploads and commits a new text file' do
end
end
RSpec.shared_examples 'it uploads and commits a new image file' do
RSpec.shared_examples 'it uploads and commits a new image file' do |drop: false|
it 'uploads and commits a new image file', :js do
find('.add-to-tree').click
......@@ -42,7 +46,11 @@ RSpec.shared_examples 'it uploads and commits a new image file' do
wait_for_requests
end
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg'), make_visible: true)
if drop
find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg'))
else
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg'), make_visible: true)
end
page.within('#modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
......@@ -58,7 +66,7 @@ RSpec.shared_examples 'it uploads and commits a new image file' do
end
end
RSpec.shared_examples 'it uploads and commits a new pdf file' do
RSpec.shared_examples 'it uploads and commits a new pdf file' do |drop: false|
it 'uploads and commits a new pdf file', :js do
find('.add-to-tree').click
......@@ -68,7 +76,11 @@ RSpec.shared_examples 'it uploads and commits a new pdf file' do
wait_for_requests
end
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'git-cheat-sheet.pdf'), make_visible: true)
if drop
find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'git-cheat-sheet.pdf'))
else
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'git-cheat-sheet.pdf'), make_visible: true)
end
page.within('#modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
......@@ -84,7 +96,7 @@ RSpec.shared_examples 'it uploads and commits a new pdf file' do
end
end
RSpec.shared_examples 'it uploads and commits a new file to a forked project' do
RSpec.shared_examples 'it uploads and commits a new file to a forked project' do |drop: false|
let(:fork_message) do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
......@@ -100,7 +112,12 @@ RSpec.shared_examples 'it uploads and commits a new file to a forked project' do
find('.add-to-tree').click
click_link('Upload file')
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
if drop
find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
else
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
end
page.within('#modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
......@@ -123,7 +140,7 @@ RSpec.shared_examples 'it uploads and commits a new file to a forked project' do
end
end
RSpec.shared_examples 'it uploads a file to a sub-directory' do
RSpec.shared_examples 'it uploads a file to a sub-directory' do |drop: false|
it 'uploads a file to a sub-directory', :js do
click_link 'files'
......@@ -133,7 +150,12 @@ RSpec.shared_examples 'it uploads a file to a sub-directory' do
find('.add-to-tree').click
click_link('Upload file')
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
if drop
find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
else
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
end
page.within('#modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
......@@ -150,11 +172,15 @@ RSpec.shared_examples 'it uploads a file to a sub-directory' do
end
end
RSpec.shared_examples 'uploads and commits a new text file via "upload file" button' do
RSpec.shared_examples 'uploads and commits a new text file via "upload file" button' do |drop: false|
it 'uploads and commits a new text file via "upload file" button', :js do
find('[data-testid="upload-file-button"]').click
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
if drop
find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
else
attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
end
page.within('#details-modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment