diff options
author | Douwe Maan <douwe@gitlab.com> | 2018-11-07 22:11:54 +0300 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2018-11-07 22:11:54 +0300 |
commit | 3632a8ab8b697c0401addf76c6676361cc5396bc (patch) | |
tree | b027b6b3fdf26680f544dedc243f8641a41fc299 /spec | |
parent | 25e53b63ae27052b5815644656d73e1dcf96b7a4 (diff) | |
parent | c85a19f920da1b544bbfae344145503c25e71048 (diff) |
Merge branch 'bvl-patches-via-mail' into 'master'
Allow to add patches to merge requests created via email
Closes #40830
See merge request gitlab-org/gitlab-ce!22723
Diffstat (limited to 'spec')
16 files changed, 801 insertions, 0 deletions
diff --git a/spec/fixtures/emails/merge_request_multiple_patches.eml b/spec/fixtures/emails/merge_request_multiple_patches.eml new file mode 100644 index 00000000000..311b99a525d --- /dev/null +++ b/spec/fixtures/emails/merge_request_multiple_patches.eml @@ -0,0 +1,181 @@ +From: "Jake the Dog" <jake@adventuretime.ooo> +To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo +Subject: new-branch-with-a-patch +Date: Wed, 31 Oct 2018 17:27:52 +0100 +X-Mailer: MailMate (1.12r5523) +Message-ID: <7BE7C2E6-F0D9-4C85-9F55-B2A4BA01BFEC@gitlab.com> +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_=" + + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_= + +This applies nicely to a branch freshly created from the root-ref + +The other attachments in this email are ignored + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_= +Content-Disposition: attachment; + filename=0002-This-does-not-apply-to-the-feature-branch.patch +Content-Transfer-Encoding: quoted-printable + +=46rom 00c68c2b4f954370ce82a1162bc29c13f524897e Mon Sep 17 00:00:00 2001 +From: Patch user <patchuser@gitlab.org> +Date: Mon, 22 Oct 2018 11:05:48 +0200 +Subject: [PATCH] This does not apply to the `feature` branch + +--- + files/ruby/feature.rb | 5 +++++ + 1 file changed, 5 insertions(+) + create mode 100644 files/ruby/feature.rb + +diff --git a/files/ruby/feature.rb b/files/ruby/feature.rb +new file mode 100644 +index 0000000..fef26e4 +--- /dev/null ++++ b/files/ruby/feature.rb +@@ -0,0 +1,5 @@ ++class Feature ++ def bar ++ puts 'foo' ++ end ++end +-- = + +2.19.1 + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_= +Content-Disposition: attachment; filename=0001-A-commit-from-a-patch.patch +Content-Transfer-Encoding: quoted-printable + +=46rom 3fee0042e610fb3563e4379e316704cb1210f3de Mon Sep 17 00:00:00 2001 +From: Patch user <patchuser@gitlab.org> +Date: Thu, 18 Oct 2018 13:40:35 +0200 +Subject: [PATCH] A commit from a patch + +--- + README | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/README b/README +index 3742e48..e40a3b9 100644 +--- a/README ++++ b/README +@@ -1 +1,3 @@ + Sample repo for testing gitlab features ++ ++This was applied in a patch! +-- = + +2.19.1 + + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_= +Content-Disposition: attachment; filename=really-not-a-patch.png +Content-Type: image/png +Content-Transfer-Encoding: base64 + +iVBORw0KGgoAAAANSUhEUgAAAjMAAAAfCAYAAAASo0ymAAABfGlDQ1BJQ0MgUHJvZmlsZQAAKJFj +YGAqSSwoyGFhYGDIzSspCnJ3UoiIjFJgv8PAzcDDIMRgxSCemFxc4BgQ4MOAE3y7xsAIoi/rgsxK +8/x506a1fP4WNq+ZclYlOrj1gQF3SmpxMgMDIweQnZxSnJwLZOcA2TrJBUUlQPYMIFu3vKQAxD4B +ZIsUAR0IZN8BsdMh7A8gdhKYzcQCVhMS5AxkSwDZAkkQtgaInQ5hW4DYyRmJKUC2B8guiBvAgNPD +RcHcwFLXkYC7SQa5OaUwO0ChxZOaFxoMcgcQyzB4MLgwKDCYMxgwWDLoMjiWpFaUgBQ65xdUFmWm +Z5QoOAJDNlXBOT+3oLQktUhHwTMvWU9HwcjA0ACkDhRnEKM/B4FNZxQ7jxDLX8jAYKnMwMDcgxBL +msbAsH0PA4PEKYSYyjwGBn5rBoZt5woSixLhDmf8xkKIX5xmbARh8zgxMLDe+///sxoDA/skBoa/ +E////73o//+/i4H2A+PsQA4AJHdp4IxrEg8AAAGcaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8 +eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA1LjQu +MCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1y +ZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAg +ICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAg +ICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjU2MzwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAg +ICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4zMTwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAg +IDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpZ5vHZAAAS+ElE +QVR4Ae2cC1QUV5rH/xnA1uZli02MiEHQqBMdTGB8ZIniA5xgfCTRycb1rBmdTHJGJ+toPBtzzGg2 +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 + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_=-- diff --git a/spec/fixtures/emails/merge_request_with_conflicting_patch.eml b/spec/fixtures/emails/merge_request_with_conflicting_patch.eml new file mode 100644 index 00000000000..ddfdfe9e24a --- /dev/null +++ b/spec/fixtures/emails/merge_request_with_conflicting_patch.eml @@ -0,0 +1,45 @@ +From: "Jake the Dog" <jake@adventuretime.ooo> +To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo +Subject: feature +Date: Wed, 31 Oct 2018 17:27:52 +0100 +X-Mailer: MailMate (1.12r5523) +Message-ID: <7BE7C2E6-F0D9-4C85-9F55-B2A4BA01BFEC@gitlab.com> +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_=" + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_= + +This does not apply + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_= +Content-Disposition: attachment; + filename=0002-This-does-not-apply-to-the-feature-branch.patch +Content-Transfer-Encoding: quoted-printable + +=46rom 00c68c2b4f954370ce82a1162bc29c13f524897e Mon Sep 17 00:00:00 2001 +From: Patch user <patchuser@gitlab.org> +Date: Mon, 22 Oct 2018 11:05:48 +0200 +Subject: [PATCH] This does not apply to the `feature` branch + +--- + files/ruby/feature.rb | 5 +++++ + 1 file changed, 5 insertions(+) + create mode 100644 files/ruby/feature.rb + +diff --git a/files/ruby/feature.rb b/files/ruby/feature.rb +new file mode 100644 +index 0000000..fef26e4 +--- /dev/null ++++ b/files/ruby/feature.rb +@@ -0,0 +1,5 @@ ++class Feature ++ def bar ++ puts 'foo' ++ end ++end +-- = + +2.19.1 + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_=-- diff --git a/spec/fixtures/emails/merge_request_with_patch_and_target_branch.eml b/spec/fixtures/emails/merge_request_with_patch_and_target_branch.eml new file mode 100644 index 00000000000..965658721cd --- /dev/null +++ b/spec/fixtures/emails/merge_request_with_patch_and_target_branch.eml @@ -0,0 +1,44 @@ +From: "Jake the Dog" <jake@adventuretime.ooo> +To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo +Subject: new-branch-with-a-patch +Date: Wed, 24 Oct 2018 16:39:49 +0200 +X-Mailer: MailMate (1.12r5523) +Message-ID: <F1F36291-728D-4E8F-AFEB-C398B8D9BB4E@gitlab.com> +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_=" + + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_= + +This applies nicely to a branch freshly created from the root-ref + +The other attachments in this email are ignored + +/target_branch with-codeowners + + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_= +Content-Disposition: attachment; filename=0001-A-commit-from-a-patch.patch +Content-Transfer-Encoding: quoted-printable + +=46rom 3fee0042e610fb3563e4379e316704cb1210f3de Mon Sep 17 00:00:00 2001 +From: Patch user <patchuser@gitlab.org> +Date: Thu, 18 Oct 2018 13:40:35 +0200 +Subject: [PATCH] A commit from a patch + +--- + README | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/README b/README +index 3742e48..e40a3b9 100644 +--- a/README ++++ b/README +@@ -1 +1,3 @@ + Sample repo for testing gitlab features ++ ++This was applied in a patch! +-- = + +2.19.1 diff --git a/spec/fixtures/emails/valid_merge_request_with_patch.eml b/spec/fixtures/emails/valid_merge_request_with_patch.eml new file mode 100644 index 00000000000..143fa77d1fa --- /dev/null +++ b/spec/fixtures/emails/valid_merge_request_with_patch.eml @@ -0,0 +1,151 @@ +From: "Jake the Dog" <jake@adventuretime.ooo> +To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo +Subject: new-branch-with-a-patch +Date: Wed, 24 Oct 2018 16:39:49 +0200 +X-Mailer: MailMate (1.12r5523) +Message-ID: <F1F36291-728D-4E8F-AFEB-C398B8D9BB4E@gitlab.com> +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_=" + + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_= + +This applies nicely to a branch freshly created from the root-ref + +The other attachments in this email are ignored + + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_= +Content-Disposition: attachment; filename=0001-A-commit-from-a-patch.patch +Content-Transfer-Encoding: quoted-printable + +=46rom 3fee0042e610fb3563e4379e316704cb1210f3de Mon Sep 17 00:00:00 2001 +From: Patch user <patchuser@gitlab.org> +Date: Thu, 18 Oct 2018 13:40:35 +0200 +Subject: [PATCH] A commit from a patch + +--- + README | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/README b/README +index 3742e48..e40a3b9 100644 +--- a/README ++++ b/README +@@ -1 +1,3 @@ + Sample repo for testing gitlab features ++ ++This was applied in a patch! +-- = + +2.19.1 + + +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_= +Content-Disposition: attachment; filename=really-not-a-patch.png +Content-Type: image/png +Content-Transfer-Encoding: base64 + +iVBORw0KGgoAAAANSUhEUgAAAjMAAAAfCAYAAAASo0ymAAABfGlDQ1BJQ0MgUHJvZmlsZQAAKJFj +YGAqSSwoyGFhYGDIzSspCnJ3UoiIjFJgv8PAzcDDIMRgxSCemFxc4BgQ4MOAE3y7xsAIoi/rgsxK +8/x506a1fP4WNq+ZclYlOrj1gQF3SmpxMgMDIweQnZxSnJwLZOcA2TrJBUUlQPYMIFu3vKQAxD4B +ZIsUAR0IZN8BsdMh7A8gdhKYzcQCVhMS5AxkSwDZAkkQtgaInQ5hW4DYyRmJKUC2B8guiBvAgNPD +RcHcwFLXkYC7SQa5OaUwO0ChxZOaFxoMcgcQyzB4MLgwKDCYMxgwWDLoMjiWpFaUgBQ65xdUFmWm +Z5QoOAJDNlXBOT+3oLQktUhHwTMvWU9HwcjA0ACkDhRnEKM/B4FNZxQ7jxDLX8jAYKnMwMDcgxBL +msbAsH0PA4PEKYSYyjwGBn5rBoZt5woSixLhDmf8xkKIX5xmbARh8zgxMLDe+///sxoDA/skBoa/ +E////73o//+/i4H2A+PsQA4AJHdp4IxrEg8AAAGcaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8 +eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA1LjQu +MCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1y +ZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAg +ICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAg +ICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjU2MzwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAg +ICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4zMTwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAg +IDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpZ5vHZAAAS+ElE +QVR4Ae2cC1QUV5rH/xnA1uZli02MiEHQqBMdTGB8ZIniA5xgfCTRycb1rBmdTHJGJ+toPBtzzGg2 +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 +--=_MailMate_D2C4B06A-4F8D-4AAB-B247-C507E35AAED6_=-- diff --git a/spec/fixtures/patchfiles/0001-A-commit-from-a-patch.patch b/spec/fixtures/patchfiles/0001-A-commit-from-a-patch.patch new file mode 100644 index 00000000000..cc38682a0ab --- /dev/null +++ b/spec/fixtures/patchfiles/0001-A-commit-from-a-patch.patch @@ -0,0 +1,19 @@ +From 3fee0042e610fb3563e4379e316704cb1210f3de Mon Sep 17 00:00:00 2001 +From: Patch User <patchuser@gitlab.org> +Date: Thu, 18 Oct 2018 13:40:35 +0200 +Subject: [PATCH] A commit from a patch + +--- + README | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/README b/README +index 3742e48..e40a3b9 100644 +--- a/README ++++ b/README +@@ -1 +1,3 @@ + Sample repo for testing gitlab features ++ ++This was applied in a patch! +-- +2.19.1 diff --git a/spec/fixtures/patchfiles/0001-This-does-not-apply-to-the-feature-branch.patch b/spec/fixtures/patchfiles/0001-This-does-not-apply-to-the-feature-branch.patch new file mode 100644 index 00000000000..905002ae898 --- /dev/null +++ b/spec/fixtures/patchfiles/0001-This-does-not-apply-to-the-feature-branch.patch @@ -0,0 +1,23 @@ +From 00c68c2b4f954370ce82a1162bc29c13f524897e Mon Sep 17 00:00:00 2001 +From: Patch User <patchuser@gitlab.org> +Date: Mon, 22 Oct 2018 11:05:48 +0200 +Subject: [PATCH] This does not apply to the `feature` branch + +--- + files/ruby/feature.rb | 5 +++++ + 1 file changed, 5 insertions(+) + create mode 100644 files/ruby/feature.rb + +diff --git a/files/ruby/feature.rb b/files/ruby/feature.rb +new file mode 100644 +index 0000000..fef26e4 +--- /dev/null ++++ b/files/ruby/feature.rb +@@ -0,0 +1,5 @@ ++class Feature ++ def bar ++ puts 'foo' ++ end ++end +-- +2.19.1 diff --git a/spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb b/spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb index ace3104f36f..f276f1a8ddf 100644 --- a/spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb +++ b/spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb @@ -93,5 +93,74 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do end end end + + context 'when the email contains patch attachments' do + let(:email_raw) { fixture_file("emails/valid_merge_request_with_patch.eml") } + + it 'creates the source branch and applies the patches' do + receiver.execute + + branch = project.repository.find_branch('new-branch-with-a-patch') + + expect(branch).not_to be_nil + expect(branch.dereferenced_target.message).to include('A commit from a patch') + end + + it 'creates the merge request' do + expect { receiver.execute } + .to change { project.merge_requests.where(source_branch: 'new-branch-with-a-patch').size }.by(1) + end + + it 'does not mention the patches in the created merge request' do + receiver.execute + + merge_request = project.merge_requests.find_by!(source_branch: 'new-branch-with-a-patch') + + expect(merge_request.description).not_to include('0001-A-commit-from-a-patch.patch') + end + + context 'when the patch could not be applied' do + let(:email_raw) { fixture_file("emails/merge_request_with_conflicting_patch.eml") } + + it 'raises an error' do + expect { receiver.execute }.to raise_error(Gitlab::Email::InvalidAttachment) + end + end + + context 'when specifying the target branch using quick actions' do + let(:email_raw) { fixture_file('emails/merge_request_with_patch_and_target_branch.eml') } + + it 'creates the merge request with the correct target branch' do + receiver.execute + + merge_request = project.merge_requests.find_by!(source_branch: 'new-branch-with-a-patch') + + expect(merge_request.target_branch).to eq('with-codeowners') + end + + it 'based the merge request of the target_branch' do + receiver.execute + + merge_request = project.merge_requests.find_by!(source_branch: 'new-branch-with-a-patch') + + expect(merge_request.diff_base_commit).to eq(project.repository.commit('with-codeowners')) + end + end + end + end + + describe '#patch_attachments' do + let(:email_raw) { fixture_file('emails/merge_request_multiple_patches.eml') } + let(:mail) { Mail::Message.new(email_raw) } + subject(:handler) { described_class.new(mail, mail_key) } + + it 'orders attachments ending in `.patch` by name' do + expected_filenames = ["0001-A-commit-from-a-patch.patch", + "0002-This-does-not-apply-to-the-feature-branch.patch"] + + attachments = handler.__send__(:patch_attachments).map(&:filename) + + expect(attachments).to eq(expected_filenames) + end end end diff --git a/spec/lib/gitlab/git/patches/collection_spec.rb b/spec/lib/gitlab/git/patches/collection_spec.rb new file mode 100644 index 00000000000..080be141c59 --- /dev/null +++ b/spec/lib/gitlab/git/patches/collection_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true +require 'spec_helper' + +describe Gitlab::Git::Patches::Collection do + let(:patches_folder) { Rails.root.join('spec/fixtures/patchfiles') } + let(:patch_content1) do + File.read(File.join(patches_folder, "0001-This-does-not-apply-to-the-feature-branch.patch")) + end + let(:patch_content2) do + File.read(File.join(patches_folder, "0001-A-commit-from-a-patch.patch")) + end + + subject(:collection) { described_class.new([patch_content1, patch_content2]) } + + describe '#size' do + it 'combines the size of the patches' do + expect(collection.size).to eq(549.bytes + 424.bytes) + end + end + + describe '#valid_size?' do + it 'is not valid if the total size is bigger than 2MB' do + expect(collection).to receive(:size).and_return(2500.kilobytes) + + expect(collection).not_to be_valid_size + end + end +end diff --git a/spec/lib/gitlab/git/patches/commit_patches_spec.rb b/spec/lib/gitlab/git/patches/commit_patches_spec.rb new file mode 100644 index 00000000000..760112155ce --- /dev/null +++ b/spec/lib/gitlab/git/patches/commit_patches_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +require 'spec_helper' + +describe Gitlab::Git::Patches::CommitPatches do + describe '#commit' do + let(:patches) do + patches_folder = Rails.root.join('spec/fixtures/patchfiles') + content_1 = File.read(File.join(patches_folder, "0001-This-does-not-apply-to-the-feature-branch.patch")) + content_2 = File.read(File.join(patches_folder, "0001-A-commit-from-a-patch.patch")) + + Gitlab::Git::Patches::Collection.new([content_1, content_2]) + end + let(:user) { build(:user) } + let(:branch_name) { 'branch-with-patches' } + let(:repository) { create(:project, :repository).repository } + + subject(:commit_patches) do + described_class.new(user, repository, branch_name, patches) + end + + it 'applies the patches' do + new_rev = commit_patches.commit + + expect(repository.commit(new_rev)).not_to be_nil + end + + it 'updates the branch cache' do + expect(repository).to receive(:after_create_branch) + + commit_patches.commit + end + + context 'when the repository does not exist' do + let(:repository) { create(:project).repository } + + it 'raises the correct error' do + expect { commit_patches.commit }.to raise_error(Gitlab::Git::Repository::NoRepository) + end + end + + context 'when the patch does not apply' do + let(:branch_name) { 'feature' } + + it 'raises the correct error' do + expect { commit_patches.commit }.to raise_error(Gitlab::Git::CommandError) + end + end + end +end diff --git a/spec/lib/gitlab/git/patches/patch_spec.rb b/spec/lib/gitlab/git/patches/patch_spec.rb new file mode 100644 index 00000000000..7466e853b65 --- /dev/null +++ b/spec/lib/gitlab/git/patches/patch_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true +require 'spec_helper' + +describe Gitlab::Git::Patches::Patch do + let(:patches_folder) { Rails.root.join('spec/fixtures/patchfiles') } + let(:patch_content) do + File.read(File.join(patches_folder, "0001-This-does-not-apply-to-the-feature-branch.patch")) + end + let(:patch) { described_class.new(patch_content) } + + describe '#size' do + it 'is correct' do + expect(patch.size).to eq(549.bytes) + end + end +end diff --git a/spec/lib/gitlab/gitaly_client/operation_service_spec.rb b/spec/lib/gitlab/gitaly_client/operation_service_spec.rb index eaf64e3c9b4..b37fe2686b6 100644 --- a/spec/lib/gitlab/gitaly_client/operation_service_spec.rb +++ b/spec/lib/gitlab/gitaly_client/operation_service_spec.rb @@ -335,4 +335,37 @@ describe Gitlab::GitalyClient::OperationService do end end end + + describe '#user_commit_patches' do + let(:patches_folder) { Rails.root.join('spec/fixtures/patchfiles') } + let(:patch_content) do + patch_names.map { |name| File.read(File.join(patches_folder, name)) }.join("\n") + end + let(:patch_names) { %w(0001-This-does-not-apply-to-the-feature-branch.patch) } + let(:branch_name) { 'branch-with-patches' } + + subject(:commit_patches) do + client.user_commit_patches(user, branch_name, patch_content) + end + + it 'applies the patch correctly' do + branch_update = commit_patches + + expect(branch_update).to be_branch_created + + commit = repository.commit(branch_update.newrev) + expect(commit.author_email).to eq('patchuser@gitlab.org') + expect(commit.committer_email).to eq(user.email) + expect(commit.message.chomp).to eq('This does not apply to the `feature` branch') + end + + context 'when the patch could not be applied' do + let(:patch_names) { %w(0001-This-does-not-apply-to-the-feature-branch.patch) } + let(:branch_name) { 'feature' } + + it 'raises the correct error' do + expect { commit_patches }.to raise_error(GRPC::FailedPrecondition) + end + end + end end diff --git a/spec/lib/gitlab/quick_actions/extractor_spec.rb b/spec/lib/gitlab/quick_actions/extractor_spec.rb index 0166f6c2ee0..873bb359d6e 100644 --- a/spec/lib/gitlab/quick_actions/extractor_spec.rb +++ b/spec/lib/gitlab/quick_actions/extractor_spec.rb @@ -272,5 +272,24 @@ describe Gitlab::QuickActions::Extractor do expect(commands).to be_empty expect(msg).to eq expected end + + it 'limits to passed commands when they are passed' do + msg = <<~MSG.strip + Hello, we should only extract the commands passed + /reopen + /labels hello world + /power + MSG + expected_msg = <<~EXPECTED.strip + Hello, we should only extract the commands passed + /power + EXPECTED + expected_commands = [['reopen'], ['labels', 'hello world']] + + msg, commands = extractor.extract_commands(msg, only: [:open, :labels]) + + expect(commands).to eq(expected_commands) + expect(msg).to eq expected_msg + end end end diff --git a/spec/services/commits/commit_patch_service_spec.rb b/spec/services/commits/commit_patch_service_spec.rb new file mode 100644 index 00000000000..f4fcec2fbc2 --- /dev/null +++ b/spec/services/commits/commit_patch_service_spec.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true +require 'spec_helper' + +describe Commits::CommitPatchService do + describe '#execute' do + let(:patches) do + patches_folder = Rails.root.join('spec/fixtures/patchfiles') + content_1 = File.read(File.join(patches_folder, "0001-This-does-not-apply-to-the-feature-branch.patch")) + content_2 = File.read(File.join(patches_folder, "0001-A-commit-from-a-patch.patch")) + + [content_1, content_2] + end + let(:user) { project.creator } + let(:branch_name) { 'branch-with-patches' } + let(:project) { create(:project, :repository) } + let(:start_branch) { nil } + let(:params) { { branch_name: branch_name, patches: patches, start_branch: start_branch } } + + subject(:service) do + described_class.new(project, user, params) + end + + it 'returns a successful result' do + result = service.execute + + branch = project.repository.find_branch(branch_name) + + expect(result[:status]).to eq(:success) + expect(result[:result]).to eq(branch.target) + end + + it 'is based off HEAD when no start ref is passed' do + service.execute + + merge_base = project.repository.merge_base(project.repository.root_ref, branch_name) + + expect(merge_base).to eq(project.repository.commit('HEAD').sha) + end + + context 'when specifying a different start branch' do + let(:start_branch) { 'with-codeowners' } + + it 'is based of the correct branch' do + service.execute + + merge_base = project.repository.merge_base(start_branch, branch_name) + + expect(merge_base).to eq(project.repository.commit(start_branch).sha) + end + end + + shared_examples 'an error response' do |expected_message| + it 'returns the correct error' do + result = service.execute + + expect(result[:status]).to eq(:error) + expect(result[:message]).to match(expected_message) + end + end + + context 'when the user does not have access' do + let(:user) { create(:user) } + + it_behaves_like 'an error response', + 'You are not allowed to push into this branch' + end + + context 'when the patches are not valid' do + let(:patches) { "a" * 2.1.megabytes } + + it_behaves_like 'an error response', 'Patches are too big' + end + + context 'when the new branch name is invalid' do + let(:branch_name) { 'HEAD' } + + it_behaves_like 'an error response', 'Branch name is invalid' + end + + context 'when the patches do not apply' do + let(:branch_name) { 'feature' } + + it_behaves_like 'an error response', 'Patch failed at' + end + + context 'when specifying a non existent start branch' do + let(:start_branch) { 'does-not-exist' } + + it_behaves_like 'an error response', 'Invalid reference name' + end + end +end diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb index 9f1da7d9419..c9a668994eb 100644 --- a/spec/services/merge_requests/build_service_spec.rb +++ b/spec/services/merge_requests/build_service_spec.rb @@ -392,5 +392,13 @@ describe MergeRequests::BuildService do expect(merge_request.source_project).to eq(project) end end + + context 'when specifying target branch in the description' do + let(:description) { "A merge request targeting another branch\n\n/target_branch with-codeowners" } + + it 'sets the attribute from the quick actions' do + expect(merge_request.target_branch).to eq('with-codeowners') + end + end end end diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb index e513ee7ae44..5a7cafcb60f 100644 --- a/spec/services/quick_actions/interpret_service_spec.rb +++ b/spec/services/quick_actions/interpret_service_spec.rb @@ -1213,6 +1213,15 @@ describe QuickActions::InterpretService do end end end + + it 'limits to commands passed ' do + content = "/shrug\n/close" + + text, commands = service.execute(content, issue, only: [:shrug]) + + expect(commands).to be_empty + expect(text).to eq("#{described_class::SHRUG}\n/close") + end end describe '#explain' do diff --git a/spec/workers/email_receiver_worker_spec.rb b/spec/workers/email_receiver_worker_spec.rb index e4e77c667b3..045135255d6 100644 --- a/spec/workers/email_receiver_worker_spec.rb +++ b/spec/workers/email_receiver_worker_spec.rb @@ -46,6 +46,21 @@ describe EmailReceiverWorker, :mailer do should_not_email_anyone end end + + context 'when the error is Gitlab::Email::InvalidAttachment' do + let(:error) { Gitlab::Email::InvalidAttachment.new("Could not deal with that") } + + it 'reports the error to the sender' do + perform_enqueued_jobs do + described_class.new.perform(raw_message) + end + + email = ActionMailer::Base.deliveries.last + expect(email).not_to be_nil + expect(email.to).to eq(["jake@adventuretime.ooo"]) + expect(email.body.parts.last.to_s).to include("Could not deal with that") + end + end end end |