diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-18 15:09:15 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-18 15:09:15 +0300 |
commit | 0637ba1e6e9024f35b2cbf561d9002ec17350bb3 (patch) | |
tree | 960cebf0e892710c1b40f25e249d04aaf8f9b868 | |
parent | 4720b569f0fcbb47e9f1a60e95172ae63b6f065a (diff) |
Add latest changes from gitlab-org/gitlab@master
22 files changed, 408 insertions, 42 deletions
diff --git a/GITLAB_PAGES_VERSION b/GITLAB_PAGES_VERSION index 141f2e805be..15b989e398f 100644 --- a/GITLAB_PAGES_VERSION +++ b/GITLAB_PAGES_VERSION @@ -1 +1 @@ -1.15.0 +1.16.0 diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb index 564853fc8a1..b66bc78094f 100644 --- a/app/models/ci/job_artifact.rb +++ b/app/models/ci/job_artifact.rb @@ -42,6 +42,7 @@ module Ci metrics: :gzip, metrics_referee: :gzip, network_referee: :gzip, + lsif: :gzip, # All these file formats use `raw` as we need to store them uncompressed # for Frontend to fetch the files and do analysis @@ -53,8 +54,7 @@ module Ci dast: :raw, license_management: :raw, license_scanning: :raw, - performance: :raw, - lsif: :raw + performance: :raw }.freeze TYPE_AND_FORMAT_PAIRS = INTERNAL_TYPES.merge(REPORT_TYPES).freeze diff --git a/app/models/issue.rb b/app/models/issue.rb index be702134ced..83f9e803d42 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -128,12 +128,12 @@ class Issue < ApplicationRecord def self.reference_pattern @reference_pattern ||= %r{ (#{Project.reference_pattern})? - #{Regexp.escape(reference_prefix)}(?<issue>\d+) + #{Regexp.escape(reference_prefix)}#{Gitlab::Regex.issue} }x end def self.link_reference_pattern - @link_reference_pattern ||= super("issues", /(?<issue>\d+)/) + @link_reference_pattern ||= super("issues", Gitlab::Regex.issue) end def self.reference_valid?(reference) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 6c32bdadfa8..b469174fc63 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -48,6 +48,7 @@ class MergeRequest < ApplicationRecord # 1. There are arguments - in which case we might be trying to force-reload. # 2. This association is already loaded. # 3. The latest diff does not exist. + # 4. It doesn't have any merge_request_diffs - it returns an empty MergeRequestDiff # # The second one in particular is important - MergeRequestDiff#merge_request # is the inverse of MergeRequest#merge_request_diff, which means it may not be @@ -56,7 +57,7 @@ class MergeRequest < ApplicationRecord def merge_request_diff fallback = latest_merge_request_diff unless association(:merge_request_diff).loaded? - fallback || super + fallback || super || MergeRequestDiff.new(merge_request_id: id) end belongs_to :head_pipeline, foreign_key: "head_pipeline_id", class_name: "Ci::Pipeline" @@ -404,7 +405,7 @@ class MergeRequest < ApplicationRecord end def commits(limit: nil) - return merge_request_diff.commits(limit: limit) if persisted? + return merge_request_diff.commits(limit: limit) if merge_request_diff.persisted? commits_arr = if compare_commits reversed_commits = compare_commits.reverse @@ -421,7 +422,7 @@ class MergeRequest < ApplicationRecord end def commits_count - if persisted? + if merge_request_diff.persisted? merge_request_diff.commits_count elsif compare_commits compare_commits.size @@ -431,7 +432,7 @@ class MergeRequest < ApplicationRecord end def commit_shas(limit: nil) - return merge_request_diff.commit_shas(limit: limit) if persisted? + return merge_request_diff.commit_shas(limit: limit) if merge_request_diff.persisted? shas = if compare_commits @@ -492,11 +493,11 @@ class MergeRequest < ApplicationRecord end def first_commit - merge_request_diff ? merge_request_diff.first_commit : compare_commits.first + compare_commits.present? ? compare_commits.first : merge_request_diff.first_commit end def raw_diffs(*args) - merge_request_diff ? merge_request_diff.raw_diffs(*args) : compare.raw_diffs(*args) + compare.present? ? compare.raw_diffs(*args) : merge_request_diff.raw_diffs(*args) end def diffs(diff_options = {}) @@ -557,7 +558,7 @@ class MergeRequest < ApplicationRecord end def diff_base_commit - if persisted? + if merge_request_diff.persisted? merge_request_diff.base_commit else branch_merge_base_commit @@ -565,7 +566,7 @@ class MergeRequest < ApplicationRecord end def diff_start_commit - if persisted? + if merge_request_diff.persisted? merge_request_diff.start_commit else target_branch_head @@ -573,7 +574,7 @@ class MergeRequest < ApplicationRecord end def diff_head_commit - if persisted? + if merge_request_diff.persisted? merge_request_diff.head_commit else source_branch_head @@ -581,7 +582,7 @@ class MergeRequest < ApplicationRecord end def diff_start_sha - if persisted? + if merge_request_diff.persisted? merge_request_diff.start_commit_sha else target_branch_head.try(:sha) @@ -589,7 +590,7 @@ class MergeRequest < ApplicationRecord end def diff_base_sha - if persisted? + if merge_request_diff.persisted? merge_request_diff.base_commit_sha else branch_merge_base_commit.try(:sha) @@ -597,7 +598,7 @@ class MergeRequest < ApplicationRecord end def diff_head_sha - if persisted? + if merge_request_diff.persisted? merge_request_diff.head_commit_sha else source_branch_head.try(:sha) @@ -758,7 +759,7 @@ class MergeRequest < ApplicationRecord end def ensure_merge_request_diff - merge_request_diff || create_merge_request_diff + merge_request_diff.persisted? || create_merge_request_diff end def create_merge_request_diff @@ -1005,7 +1006,7 @@ class MergeRequest < ApplicationRecord def closes_issues(current_user = self.author) if target_branch == project.default_branch messages = [title, description] - messages.concat(commits.map(&:safe_message)) if merge_request_diff + messages.concat(commits.map(&:safe_message)) if merge_request_diff.persisted? Gitlab::ClosingIssueExtractor.new(project, current_user) .closed_by_message(messages.join("\n")) @@ -1421,7 +1422,7 @@ class MergeRequest < ApplicationRecord end def has_commits? - merge_request_diff && commits_count.to_i > 0 + merge_request_diff.persisted? && commits_count.to_i > 0 end def has_no_commits? diff --git a/app/models/project_services/issue_tracker_service.rb b/app/models/project_services/issue_tracker_service.rb index 9e1393196ff..7cdbb124dee 100644 --- a/app/models/project_services/issue_tracker_service.rb +++ b/app/models/project_services/issue_tracker_service.rb @@ -19,9 +19,9 @@ class IssueTrackerService < Service # overridden patterns. See ReferenceRegexes.external_pattern def self.reference_pattern(only_long: false) if only_long - /(\b[A-Z][A-Z0-9_]*-)(?<issue>\d+)/ + /(\b[A-Z][A-Z0-9_]*-)#{Gitlab::Regex.issue}/ else - /(\b[A-Z][A-Z0-9_]*-|#{Issue.reference_prefix})(?<issue>\d+)/ + /(\b[A-Z][A-Z0-9_]*-|#{Issue.reference_prefix})#{Gitlab::Regex.issue}/ end end diff --git a/app/models/project_services/youtrack_service.rb b/app/models/project_services/youtrack_service.rb index 02d06eeb405..0815e27850d 100644 --- a/app/models/project_services/youtrack_service.rb +++ b/app/models/project_services/youtrack_service.rb @@ -8,7 +8,7 @@ class YoutrackService < IssueTrackerService if only_long /(?<issue>\b[A-Za-z][A-Za-z0-9_]*-\d+\b)/ else - /(?<issue>\b[A-Za-z][A-Za-z0-9_]*-\d+\b)|(#{Issue.reference_prefix}(?<issue>\d+))/ + /(?<issue>\b[A-Za-z][A-Za-z0-9_]*-\d+\b)|(#{Issue.reference_prefix}#{Gitlab::Regex.issue})/ end end diff --git a/changelogs/unreleased/feat-drop-signatures-email-replies.yml b/changelogs/unreleased/feat-drop-signatures-email-replies.yml new file mode 100644 index 00000000000..1a77059c8fa --- /dev/null +++ b/changelogs/unreleased/feat-drop-signatures-email-replies.yml @@ -0,0 +1,5 @@ +--- +title: Drop signatures in email replies +merge_request: 25389 +author: Diego Louzán +type: changed diff --git a/changelogs/unreleased/pages-1-16-release.yml b/changelogs/unreleased/pages-1-16-release.yml new file mode 100644 index 00000000000..03dd2cd964d --- /dev/null +++ b/changelogs/unreleased/pages-1-16-release.yml @@ -0,0 +1,5 @@ +--- +title: Upgrade pages to 1.16.0 +merge_request: 25238 +author: +type: added diff --git a/doc/development/testing_guide/flaky_tests.md b/doc/development/testing_guide/flaky_tests.md index 9ec0a8e803f..f39151cfa59 100644 --- a/doc/development/testing_guide/flaky_tests.md +++ b/doc/development/testing_guide/flaky_tests.md @@ -87,6 +87,7 @@ For instance `RETRIES=1 bin/rspec ...` would retry the failing examples once. - [Dropdowns rendering upward or downward due to window size and scroll position](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17660) - [Lazy loaded images can cause Capybara to misclick](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18713) - [Triggering JS events before the event handlers are set up](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18742) +- [Wait for the image to be lazy-loaded when asserting on a Markdown image's src attribute](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25408) #### Capybara viewport size related issues diff --git a/lib/gitlab/email/attachment_uploader.rb b/lib/gitlab/email/attachment_uploader.rb index 0a14a909e31..d8962ec0d20 100644 --- a/lib/gitlab/email/attachment_uploader.rb +++ b/lib/gitlab/email/attachment_uploader.rb @@ -12,7 +12,7 @@ module Gitlab def execute(upload_parent:, uploader_class:) attachments = [] - message.attachments.each do |attachment| + filter_signature_attachments(message).each do |attachment| tmp = Tempfile.new("gitlab-email-attachment") begin File.open(tmp.path, "w+b") { |f| f.write attachment.body.decoded } @@ -32,6 +32,22 @@ module Gitlab attachments end + + private + + # If this is a signed message (e.g. S/MIME or PGP), remove the signature + # from the uploaded attachments + def filter_signature_attachments(message) + attachments = message.attachments + + if message.content_type&.starts_with?('multipart/signed') + signature_protocol = message.content_type_parameters[:protocol] + + attachments.delete_if { |attachment| attachment.content_type.starts_with?(signature_protocol) } if signature_protocol.present? + end + + attachments + end end end end diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb index fd6e24a96d8..38281fb1c91 100644 --- a/lib/gitlab/regex.rb +++ b/lib/gitlab/regex.rb @@ -112,7 +112,7 @@ module Gitlab # Based on Jira's project key format # https://confluence.atlassian.com/adminjiraserver073/changing-the-project-key-format-861253229.html def jira_issue_key_regex - @jira_issue_key_regex ||= /[A-Z][A-Z_0-9]+-\d+/ + @jira_issue_key_regex ||= /[A-Z][A-Z_0-9]+-\d+\b/ end def jira_transition_id_regex @@ -144,6 +144,10 @@ module Gitlab def utc_date_regex @utc_date_regex ||= /\A[0-9]{4}-[0-9]{2}-[0-9]{2}\z/.freeze end + + def issue + @issue ||= /(?<issue>\d+\b)/ + end end end diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index da26eb94fb0..3684571ff9c 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -77,6 +77,18 @@ describe Projects::MergeRequestsController do end end + context 'when diff is missing' do + render_views + + it 'renders merge request page' do + merge_request.merge_request_diff.destroy + + go(format: :html) + + expect(response).to be_successful + end + end + it "renders merge request page" do expect(::Gitlab::GitalyClient).to receive(:allow_ref_name_caching).and_call_original diff --git a/spec/factories/ci/job_artifacts.rb b/spec/factories/ci/job_artifacts.rb index 590578aec9a..296215abfa0 100644 --- a/spec/factories/ci/job_artifacts.rb +++ b/spec/factories/ci/job_artifacts.rb @@ -141,11 +141,11 @@ FactoryBot.define do trait :lsif do file_type { :lsif } - file_format { :raw } + file_format { :gzip } after(:build) do |artifact, evaluator| artifact.file = fixture_file_upload( - Rails.root.join('spec/fixtures/lsif.json.gz'), 'application/octet-stream') + Rails.root.join('spec/fixtures/lsif.json.gz'), 'application/x-gzip') end end diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb index eb55613b954..7584789b99d 100644 --- a/spec/features/snippets/user_creates_snippet_spec.rb +++ b/spec/features/snippets/user_creates_snippet_spec.rb @@ -53,7 +53,7 @@ describe 'User creates snippet', :js do page.within('#new_personal_snippet .md-preview-holder') do expect(page).to have_content('My Snippet') - link = find('a.no-attachment-icon img[alt="banana_sample"]')['src'] + link = find('a.no-attachment-icon img.js-lazy-loaded[alt="banana_sample"]')['src'] expect(link).to match(%r{/uploads/-/system/user/#{user.id}/\h{32}/banana_sample\.gif\z}) # Adds a cache buster for checking if the image exists as Selenium is now handling the cached regquests @@ -73,7 +73,7 @@ describe 'User creates snippet', :js do click_button('Create snippet') wait_for_requests - link = find('a.no-attachment-icon img[alt="banana_sample"]')['src'] + link = find('a.no-attachment-icon img.js-lazy-loaded[alt="banana_sample"]')['src'] expect(link).to match(%r{/uploads/-/system/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z}) reqs = inspect_requests { visit("#{link}?ran=#{SecureRandom.base64(20)}") } @@ -98,7 +98,7 @@ describe 'User creates snippet', :js do expect(page).to have_selector('strong') end expect(page).to have_content('Hello World!') - link = find('a.no-attachment-icon img[alt="banana_sample"]')['src'] + link = find('a.no-attachment-icon img.js-lazy-loaded[alt="banana_sample"]')['src'] expect(link).to match(%r{/uploads/-/system/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z}) reqs = inspect_requests { visit("#{link}?ran=#{SecureRandom.base64(20)}") } diff --git a/spec/fixtures/emails/.gitattributes b/spec/fixtures/emails/.gitattributes new file mode 100644 index 00000000000..6c6ba98a0dd --- /dev/null +++ b/spec/fixtures/emails/.gitattributes @@ -0,0 +1,2 @@ +# Do not mangle line endings or signature will be invalid +valid_reply_signed_smime.eml eol=crlf
\ No newline at end of file diff --git a/spec/fixtures/emails/valid_reply_signed_smime.eml b/spec/fixtures/emails/valid_reply_signed_smime.eml new file mode 100644 index 00000000000..0c5e2c439ae --- /dev/null +++ b/spec/fixtures/emails/valid_reply_signed_smime.eml @@ -0,0 +1,294 @@ +User-Agent: Microsoft-MacOutlook/10.22.0.200209 +Date: Mon, 17 Feb 2020 22:56:47 +0100 +Subject: Re: htmltest | test issue (#1) +From: "Louzan Martinez, Diego (ext) (SI BP R&D ZG)" + <diego.louzan.ext@siemens.com> +To: Administrator / htmltest + <dlouzan.dummy+c034670b1623e617e15a3df64223d363@gmail.com> +Message-ID: <012E37D9-2A3F-4AC8-B79A-871F42914D86@siemens.com> +Thread-Topic: htmltest | test issue (#1) +References: <reply-c034670b1623e617e15a3df64223d363@169.254.169.254> + <issue_451@169.254.169.254> + <note_1797@169.254.169.254> +In-Reply-To: <note_1797@169.254.169.254> +Content-type: multipart/signed; + protocol="application/pkcs7-signature"; + micalg=sha256; + boundary="B_3664825007_1904734766" +MIME-Version: 1.0 + +--B_3664825007_1904734766 +Content-type: multipart/mixed; + boundary="B_3664825007_384940722" + + +--B_3664825007_384940722 +Content-type: multipart/alternative; + boundary="B_3664825007_1519466360" + + +--B_3664825007_1519466360 +Content-type: text/plain; + charset="UTF-8" +Content-transfer-encoding: quoted-printable + +Me too, with an attachment + +=20 + +From: Administrator <dlouzan.dummy@gmail.com> +Reply to: Administrator / htmltest <dlouzan.dummy+c034670b1623e617e15a3df64= +223d363@gmail.com> +Date: Monday, 17 February 2020 at 22:55 +To: "Louzan Martinez, Diego (ext) (SOP IT STG XS)" <diego.louzan.ext@siemen= +s.com> +Subject: Re: htmltest | test issue (#1) + +=20 + +Administrator commented:=20 + +I pity the foo !!! + +=E2=80=94=20 +Reply to this email directly or view it on GitLab.=20 +You're receiving this email because of your account on 169.254.169.254. If = +you'd like to receive fewer emails, you can unsubscribe from this thread or = +adjust your notification settings.=20 + + +--B_3664825007_1519466360 +Content-type: text/html; + charset="UTF-8" +Content-transfer-encoding: quoted-printable + +<html xmlns:o=3D"urn:schemas-microsoft-com:office:office" xmlns:w=3D"urn:schema= +s-microsoft-com:office:word" xmlns:m=3D"http://schemas.microsoft.com/office/20= +04/12/omml" xmlns=3D"http://www.w3.org/TR/REC-html40"><head><meta http-equiv=3DC= +ontent-Type content=3D"text/html; charset=3Dutf-8"><meta name=3DGenerator content=3D= +"Microsoft Word 15 (filtered medium)"><title>GitLab</title><style><!-- +/* Font Definitions */ +@font-face + {font-family:"Cambria Math"; + panose-1:2 4 5 3 5 4 6 3 2 4;} +@font-face + {font-family:Calibri; + panose-1:2 15 5 2 2 2 4 3 2 4;} +/* Style Definitions */ +p.MsoNormal, li.MsoNormal, div.MsoNormal + {margin:0cm; + margin-bottom:.0001pt; + font-size:11.0pt; + font-family:"Calibri",sans-serif;} +a:link, span.MsoHyperlink + {mso-style-priority:99; + color:blue; + text-decoration:underline;} +span.EmailStyle19 + {mso-style-type:personal-reply; + font-family:"Calibri",sans-serif; + color:windowtext;} +.MsoChpDefault + {mso-style-type:export-only; + font-size:10.0pt;} +@page WordSection1 + {size:612.0pt 792.0pt; + margin:72.0pt 72.0pt 72.0pt 72.0pt;} +div.WordSection1 + {page:WordSection1;} +--></style></head><body lang=3Den-ES link=3Dblue vlink=3Dpurple><div class=3DWordSe= +ction1><p class=3DMsoNormal><span lang=3DEN-US style=3D'mso-fareast-language:EN-US= +'>Me too, with an attachment<o:p></o:p></span></p><p class=3DMsoNormal><span s= +tyle=3D'mso-fareast-language:EN-US'><o:p> </o:p></span></p><div style=3D'bo= +rder:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class= +=3DMsoNormal><b><span style=3D'font-size:12.0pt;color:black'>From: </span></b><s= +pan style=3D'font-size:12.0pt;color:black'>Administrator <dlouzan.dummy@gma= +il.com><br><b>Reply to: </b>Administrator / htmltest <dlouzan.dummy+c0= +34670b1623e617e15a3df64223d363@gmail.com><br><b>Date: </b>Monday, 17 Febr= +uary 2020 at 22:55<br><b>To: </b>"Louzan Martinez, Diego (ext) (SOP IT = +STG XS)" <diego.louzan.ext@siemens.com><br><b>Subject: </b>Re: ht= +mltest | test issue (#1)<o:p></o:p></span></p></div><div><p class=3DMsoNormal>= +<o:p> </o:p></p></div><div><p><span style=3D'color:#777777'><a href=3D"http= +://localhost:3000/root">Administrator</a> commented: <o:p></o:p></span></p><= +div><p>I pity the foo !!!<o:p></o:p></p></div></div><div style=3D'margin-top:7= +.5pt'><p><span style=3D'font-size:12.0pt;color:#777777'>=E2=80=94 <br>Reply to this = +email directly or <a href=3D"http://localhost:3000/root/htmltest/issues/1#note= +_1797">view it on GitLab</a>. <br>You're receiving this email because of you= +r account on 169.254.169.254. If you'd like to receive fewer emails, you can= + <a href=3D"http://localhost:3000/sent_notifications/c034670b1623e617e15a3df64= +223d363/unsubscribe">unsubscribe</a> from this thread or adjust your notific= +ation settings. <o:p></o:p></span></p></div></div></body></html> + +--B_3664825007_1519466360-- + + +--B_3664825007_384940722 +Content-type: image/png; name="gitlab_logo.png"; + x-mac-creator="4F50494D"; + x-mac-type="504E4766" +Content-disposition: attachment; + filename="gitlab_logo.png" +Content-transfer-encoding: base64 + + +iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAIAAABMXPacAAAABnRSTlMA/wD/AP83WBt9AAAN +1UlEQVR4AexcZXPjSBTcXxOTvMy7xxfGZWaGaJmZmZmZmZmZmdnMzB7JNwv1qs6VOJY0tuWU +p/rz5PW0q0f99JQakcxK6eItQGZlBMgIkFkZATICZFZGgIwAmZURICMAshitiybrexXblk5D +NnOk2i3G6bCvmYcJWuaMCevVohPAsWGx6h/Zd/wrd2xbWf0EcB3YqsqmfnK0LZseYZCIBEBW +E/5p4Mp+wtCvJWO3Vqufv8dtHNoZCOo6ZYd1ahEJ4LtzRZ1fC+pTF9T1P7hZnQQIvHqiKW0I +BFU5lPfiCREJYFs5C4r7Cfu6BdVJAOeutVEErfPGRRhGFAIgu1Xft0VUfYaBbRmXI1ItFuvz +Gkd0jyKo65oXNupEIYD//g11QZ2o+tRF9QJP7lUPAYJvX2haNIkmmKv0Xj0rCgHsa+dDWRgA +x+al1eT5Z9+mCglaF02KsGyKBWCcdsOA1hXWZ6A7MB5X2vtPwG8a07tCgvoehchsSLEA/sd3 +sNtUWJ+mpEHgxaN0FyD08Y2mVbMKCarzavluXkyxAI5NS3AplcG5fVXa+8+h7TEI4kSWSgEY +t9NQ3j5GfcZhXRivJ439JxgwT+gfg6C+dymymlMmQOD5Q01xgxj1acoaBV8/S2P/+fJe2+b3 +GATV+bV9d6+lTADc88FFxIZz9/r0FcB9fE+VBO2r56RGAMYL7ZFYMI3qwfp9aek/oZB5Snks +dtD4cthSIEDw1VNNaaMq69O0bBp8/yot/Uf1Wdv+zyoJqgvr+h/eSoEAzl3roIjYcB3Yko4C +eE4fxK31eAja1y9MogDQHhnZPU4BTGP74jiTZv6DwpYZw+MkaBgEja9kCRB89xLaI1VC27p5 +6NPb9BIgrP2m6/hP1eyg8fX0XlIFcO3fHE9lAPeRnWnmP+ePqbIV8RN0bF6WHAGgPdKHkwDm +iQPZUDB9XoAhy5zRnAga6Y78Gl81SLVHYkPb9o/Q149p4z96ja5LDieCmpKG0PhKuACuwzvi +rwze1LtP7EsXAbyXT6lylFw5OnesTrQA0B4ZwLU4DPPUIWw4lA4PQIx1wQQeBI3Du7JeT8IF +CH35AO0RTtC2/yus/hIR/UImva5bPg+CmrLGwTfPEi6A+/heiCfckK3wnD0sfgF818+rc2ty +ogZw7tmQWAHYMG6P0FzLAlhmjoggJG7/YW1LpvImaBrVk2vjqwb39shfvOvTdfo3rFOJ2n8s +Jn3PYn7soPGVQAE8Zw6B//BBNp5nOi5q/7l9GSbM+AFPMCZKAGiPCIF13liYZxLhsq2YJZCg +aVxfNhggLgC0R/7lXxzMMxm0IvUfu0Xfp0wAO2h8vUuIAJ4L0B7hD3UOnmc6I04BYMJMINxH +d5EVANojY/jWRH6eifyCCTPBME8aBI0vYgKEDbg9kkukPphnEtWCCTPhgMYXSQG8V05De0Qg +1Hk1YZ5JFAsmzArrCWUHja+T+4kKwLLWhRPJFAfzTCJbjo2LCRI0T8ONrzAJAaA90r2AYH36 +3iUwz5TiBRNmg9sTJKjt8HdY/ZWYAL4bvNsjMeaZropHgMDzB5ri+gQJQuOLiACsbSm0R4jB +vmqOiPxn6wriBC2zRkYQIiAAfIBHFnr4kE9kH+CRAIcP+Wpw/QCPBGCe6aYYP8AjBfiQj78A +0B75W5YIiORDPufOtQkiaJkLH/LxFYB1W22j2xjL5MaWSsIoU9iGt/LfuYQbAKnEvau2cZ0S +RNBKFzE2vTABtNfDKxqEh8jC5VLyoBWmdnVVubXUeamBKremsXXdULkiIezwoS2uy349I0gA +5uFctD0LzaFQuQSVZxEGneXoitM1vGBIAeydlYgGakQxk0Lbspg7EyIsy1eAgJ051RLtyEJb +ZWiyAg0mX6W/P6XJU6Tq9NW5Cl9fCtGkeeGDmqBAW+Tfj+5YXsRr4CkAq7+N9tT+vsvOLLRB +gcbIiWsQLpdhu1T9nRoBDKXK0GAZ+d/+KBlap8CH9v3odilY1QWeAjBPFuEtMH5psJJCw6Sk +XUji6FozVS5k61STvP8MlaLlFNopgaNj7k3lJUDQyZxp82MLgAQtpAhXTKfMhdQ5Ci95/5Gg +eRTaIf3fuZ0oivhMnAVgjffR3rq/tgBsl6EZFHEXMpSlwIX0JeT8B6x/Kr54ZdGHtlvJaq5w +FoB5tvx/u4ARbZaj8UQvZFpi71wzBf7TkZD/wOmPlaONv6w/CsyDWRwFCLmZcx2iNwIN1lJo +pIygC/n6UfiBJNn+04eo/wyXodUUnH4UmFOlEb+VgwCs6THaVz96IwC+YZZSaCixCzmUdBfS +F2P/kRM7/SEStBgu3oqwpxaru8lBAObFmkr2AkghnaWjC1k7EPQfyffMtV0a+8SYR/PjFiDs +ZS50jb3dr3Q2RfBlAC7Ul8K2kCT/yVZ4euMATMj6J/7KXLHBnG6Fg21cArCW52h/w9jbEU9n ++IFEX6pMjgC6YmVwkJxQ5pKj9XDxxsSe2qzhbnwCvNpY9XagwSoK3z9EXMjWMSku9LfM2h78 +h3Dmig3myZI4BAj7mYs9q9yLfDqjs7x9kuFC6my5pxcJ/6GjM1eVYM62iwRdVQjA2t6gA405 +CEAuneHHEhyOEu4/RRQR/4HMxQF767LGh1UJ8GY7t00hnU0QfCHTEmuiXQi/pWoH/iMsc20C +6+cA5vmqmAIgP3OlP8dNIZ0phKYzOsvTR6nmMP/La2ZNuP+MgMzFGcz5zpGQq1IBWOsrdLA5 +530hnS0TkM7AhYqVCfSfQuw/ClKZiw/2N2QN9ysVgHm5Hu2EW4UHpGiusHRGS3BEgkhM3H/M +bbH/SAVlrlmQuXiCebygcgHOdeSxI5l0Bi7UG7uQPEH+4+oJ/kMoc/HAiaJKBYh+/uF3GWwU +lM7wIwp+UEmEANoCKjBQQThz8cBuZeUCHPqdx46E0xktsbQj6kLgP214+Q9krhX8rT/qYbRy +C7oxXOjukM4W8U1ndBZ+UFFly8n7Tw++/oOJzIfMJRTMpd6VCsBanqFjuWQ0wDfVTIq/CxVS +IvKfaZC5BOPwn6z+Tswgpr+DTpaS+WNb+KYzWkrWhfBWptY18bAUn4t3HM5cckHWDzieD+8m +Y7ajXd+Ym6PQLorAZbCOYzoDF+qpxKZB0H+c3fEFwCtzraEInP4uOXOtnHV8iPuVZNiLexI8 +QhmpdBYcqNCScyFNPhUYoOCeuaRoCYmLd39j9uW6SMjNdS6IZY0PfiQDgRVI0Tzu6YyWmtsI +diHwn1ZK7v4jQbMFZS54D/P9ZSTL8B1P9xmZBzN+zcfxxjbZ997hYG4u5OpByoXkzm5KRHO0 +/kmCM9du5ffBUI9W8CdKTJD9fBQd/VdoOhvLLZ0FsAsVUAT8J4/y9+foP6MFZ67Df7Dv90aQ +n8AHGvCegLncD+2U8ddgNdd0JjW3FuxCf+PZU+w/XP7uMGGZa6eUudCNNT9NwL+rCTq+T2vt +ayAonQ2RcHCh7sJdSI5nTxGd8MwFKff79IPfkrB/WcYiVn0ZnSxJTjrDjy7afEqY/yjw7Cmi +k5K5juex/7V3Dz5yhVEUwP+cce2GjWu7cW3btm03qm27QRXVtt2ZbO8op/r2vp7qS+a+uHHP +5r7z252ze2N7UUrZZxMB0FBw6GxQUJ1JdXlEXSHcn3oB7g/MFSPN5a75fyEAQGG5QIHUWe9I +wCskBYa4Qrg/rfADSNZces1Poeb/swAoKEBnM4Lq7H372B32Ct2RAUxb3B/KXHzN/wcBcFCA +zor92sQVIic01eTzprg/pLn0mn/Hgz/mKVC4moECobMgV4gd8snnTfWM5fTL/G1ZlK75HgTA +QUGu7eJAOhNG6RMaboDXKWOuhTAXUfM9CICGAnTGD/m4AR7MNQunn6j5HgTAQgEv5CnQGTHk +IwZ4MNfE+C80iE2o+Z4GgBTSUOgFKKg6G41vl5JDPmKANyKAuVDzO6HmexAAAQVSZxjy1cMV +ogd4OP0yc1uimgs1Hx9n8zIAHgp4GSwQnUWZCQ0xwBNzzYO5yJrvfwCAwmmBQklGZ8SQDwM8 +t7mm4cVL1HzvA+ChEE5OcOoMc2JqgAdzjcU3O4ma70EAPBQup/a3cUEBOhse168QMcCDuSLB +aj7xu329CICHAnTWHzrThnz6AA//+30VcxE1388AeChAZz0jxJAPAzynuYia738AxPPqRgYK +sWJ1Fv7xCgmvlAHMtwM8mGsSzKXW/AIIQIUCdKYP+fQBnkzYVkQcNb8ian5hBQAoNMPX5nc6 +Gwyd6UM+DPB0cyk1vwACUKAAnfWJ6kO+YgZ4vcRcePHqNb9gAlCggJfBTPyaLveQzzHA6wZz +OWu+BaBAATpThnx3McBzmctR8y0ABQrQmXvIhwGe21zrSqfOjUfNtwB0KEBnUegsN+SLOQd4 +MJde8y0ARwqAQj6DudBZZsiXcA5gekSSs2EureZbAAoUquKFPDWns++HfBjgwVyo+RfmoeZb +ADQUcjobk9HZN0M+DPBgLtT8I0TNtwDcUFiW0dm3Qz7cn4E5c2Vq/gCm5lsAChSgs+wVwgAP +5krX/LV8zbcAFCisjiRnxpI9wrkhX3qAlxCsibnYD+1YAAQUJkQ/dozL8ZEBzIf28eTYaHJt +Ga7mWwAEFPalNtdNDo89bphIfwBdzLWhBlnzLQD+JwoH+7/qVvFlpwqpPT34mm8B8M/n15+P +Lf90cGHRpxf4RwvAHt8DsMcCsADssQAsAHssAAvAni8AV5380akCdgAAAABJRU5ErkJggg== +--B_3664825007_384940722-- + +--B_3664825007_1904734766 +Content-type: application/pkcs7-signature; name="smime.p7s" +Content-transfer-encoding: base64 +Content-disposition: attachment; + filename="smime.p7s" + +MIIRpwYJKoZIhvcNAQcCoIIRmDCCEZQCAQExDzANBglghkgBZQMEAgEFADALBgkqhkiG9w0B +BwGggg8VMIIHojCCBYqgAwIBAgIEZ5a6PTANBgkqhkiG9w0BAQsFADCBtjELMAkGA1UEBhMC +REUxDzANBgNVBAgMBkJheWVybjERMA8GA1UEBwwITXVlbmNoZW4xEDAOBgNVBAoMB1NpZW1l +bnMxETAPBgNVBAUTCFpaWlpaWkE2MR0wGwYDVQQLDBRTaWVtZW5zIFRydXN0IENlbnRlcjE/ +MD0GA1UEAww2U2llbWVucyBJc3N1aW5nIENBIE1lZGl1bSBTdHJlbmd0aCBBdXRoZW50aWNh +dGlvbiAyMDE2MB4XDTE5MTEyMTE0NDQ0N1oXDTIwMTEyMTE0NDQ0N1owdzERMA8GA1UEBRMI +WjAwM0gwOFQxDjAMBgNVBCoMBURpZWdvMRgwFgYDVQQEDA9Mb3V6YW4gTWFydGluZXoxGDAW +BgNVBAoMD1NpZW1lbnMtUGFydG5lcjEeMBwGA1UEAwwVTG91emFuIE1hcnRpbmV6IERpZWdv +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuInpNaC7NRYD+0pOpHDz2pk9xmPt +JGj860SF6Nmn6Eu9EMYKEDfneC6z5QcH+mPS2d0VWgqVVGbRXSPsxJtbi9TCWjQUZdHglEZK +z9zxoFDh2dvW5/+TOT5Jf78FXyqak0YtY6+oMjQ/i9RUqPL7sIlyXLrBYrILzQ9Afo+7bXZg +v3ypp6xtqAV2ctHzQWFi0onJzxLVYguiVb7fFF9rBEMvSZonuw5tvOwJIhbe5FDFOrDcfbyU +ofZ/wikIZ+A+CE5GryXuuQmGxJaC2QqOkRAWQDzLDx9nG+rKiEs5OvlfEZC7EV1PyjZ93coM +faCVdlAgcFZ5fvd37CjyjKl+1QIDAQABo4IC9DCCAvAwggEEBggrBgEFBQcBAQSB9zCB9DAy +BggrBgEFBQcwAoYmaHR0cDovL2FoLnNpZW1lbnMuY29tL3BraT9aWlpaWlpBNi5jcnQwQQYI +KwYBBQUHMAKGNWxkYXA6Ly9hbC5zaWVtZW5zLm5ldC9DTj1aWlpaWlpBNixMPVBLST9jQUNl +cnRpZmljYXRlMEkGCCsGAQUFBzAChj1sZGFwOi8vYWwuc2llbWVucy5jb20vQ049WlpaWlpa +QTYsbz1UcnVzdGNlbnRlcj9jQUNlcnRpZmljYXRlMDAGCCsGAQUFBzABhiRodHRwOi8vb2Nz +cC5wa2ktc2VydmljZXMuc2llbWVucy5jb20wHwYDVR0jBBgwFoAU+BVdRwxsd3tyxAIXkWii +tvdqCUQwDAYDVR0TAQH/BAIwADBFBgNVHSAEPjA8MDoGDSsGAQQBoWkHAgIEAQMwKTAnBggr +BgEFBQcCARYbaHR0cDovL3d3dy5zaWVtZW5zLmNvbS9wa2kvMIHKBgNVHR8EgcIwgb8wgbyg +gbmggbaGJmh0dHA6Ly9jaC5zaWVtZW5zLmNvbS9wa2k/WlpaWlpaQTYuY3JshkFsZGFwOi8v +Y2wuc2llbWVucy5uZXQvQ049WlpaWlpaQTYsTD1QS0k/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdIZJbGRhcDovL2NsLnNpZW1lbnMuY29tL0NOPVpaWlpaWkE2LG89VHJ1c3RjZW50ZXI/ +Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH +AwQwDgYDVR0PAQH/BAQDAgeAMFUGA1UdEQROMEygLAYKKwYBBAGCNxQCA6AeDBxkaWVnby5s +b3V6YW4uZXh0QHNpZW1lbnMuY29tgRxkaWVnby5sb3V6YW4uZXh0QHNpZW1lbnMuY29tMB0G +A1UdDgQWBBQj8k8aqZey68w8ALYKGJSGMt5hZDANBgkqhkiG9w0BAQsFAAOCAgEAFDHqxpb1 +R9cB4noC9vx09bkNbmXCpVfl3XCQUmAWTznC0nwEssTTjo0PWuIV4C3jnsp0MRUeHZ6lsyhZ +OzS1ETwYgvj6wzjb8RF3wgn7N/JOvFGaErMz5HZpKOfzGiNpW6/Rmd4hsRDjAwOVQOXUTqc/ +0Bj3FMoLRCSWSnTp5HdyvrY2xOKHfTrTjzmcLdFaKE2F5n7+dBkwCKVfzut8CqfVq/I7ks4m +D1IHk93/P6l9U34R2FHPt6zRTNZcWmDirRSlMH4L18CnfiNPuDN/PtRYlt3Vng5EdYN0VCg2 +NM/uees0U4ingCb0NFjg66uQ/tjfPQk55MN4Wpls4N6TkMoTCWLiqZzYTGdmVQexzroL6940 +tmMr8LoN3TpPf0OdvdKEpyH7fzsx5QlmQyywIWec6X+Fx6+l0g91VJnPEtqACpfZIBZtviHl +gfX298w+SsvBK8C48Pqs8Ijh7tLrCxx7VMLVHZqwWWPK53ga+CDWmjoSQPxi+CPZF7kao6N5 +4GrJWwSHlHh6WzTbLyLvTJZZ775Utp4W8s8xMUsQJ413iYzEaC8FcSeNjSk5UiDDiHrKmzpM +tbApD3pUXStblUMKYGTG1Mj9BcEBFkCdoGlw/ulszIrKFfOyRNDG3Ay+Dj/oMjoKsJphu3px +wyft82rTer7UW/I7o0h0DAG4lkMwggdrMIIFU6ADAgECAgR5nlqfMA0GCSqGSIb3DQEBCwUA +MIGeMQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmF5ZXJuMREwDwYDVQQHDAhNdWVuY2hlbjEQ +MA4GA1UECgwHU2llbWVuczERMA8GA1UEBRMIWlpaWlpaQTMxHTAbBgNVBAsMFFNpZW1lbnMg +VHJ1c3QgQ2VudGVyMScwJQYDVQQDDB5TaWVtZW5zIElzc3VpbmcgQ0EgRUUgRW5jIDIwMTYw +HhcNMTkwOTI3MDgwMTM5WhcNMjAwOTI3MDgwMTM3WjB3MREwDwYDVQQFEwhaMDAzSDA4VDEO +MAwGA1UEKgwFRGllZ28xGDAWBgNVBAQMD0xvdXphbiBNYXJ0aW5lejEYMBYGA1UECgwPU2ll +bWVucy1QYXJ0bmVyMR4wHAYDVQQDDBVMb3V6YW4gTWFydGluZXogRGllZ28wggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyby5qKzZIrGYWRqxnaAyMt/a/uc0uMk0F3MjwxvPM +vh5DllUpqx0l8ZDakDjPhlEXTeoL4DHNgmh+CDCs76CppM3cNG/1W1Ajo/L2iwMoXaxYuQ/F +q7ED+02KEkWX2DDVVG3fhrUGP20QAq77xPDptmVWZnUnuobZBNYkC49Xfl9HJvkJL8P0+Jqb +Eae7p4roiEr7wNkGriwrVXgA3oPNF/W+OuI76JTNTajS/6PAK/GeqIvLjfuBXpdBZTY031nE +Cztca8vI1jUjQzVhS+0dWpvpfhkVumbvOnid8DI9lapYsX8dpZFsa3ya+T3tjUdGSOOKi0kg +lWf/XYyyfhmDAgMBAAGjggLVMIIC0TAdBgNVHQ4EFgQUprhTCDwNLfPImpSfWdq+QvPTo9Mw +JwYDVR0RBCAwHoEcZGllZ28ubG91emFuLmV4dEBzaWVtZW5zLmNvbTAOBgNVHQ8BAf8EBAMC +BDAwLAYDVR0lBCUwIwYIKwYBBQUHAwQGCisGAQQBgjcKAwQGCysGAQQBgjcKAwQBMIHKBgNV +HR8EgcIwgb8wgbyggbmggbaGJmh0dHA6Ly9jaC5zaWVtZW5zLmNvbS9wa2k/WlpaWlpaQTMu +Y3JshkFsZGFwOi8vY2wuc2llbWVucy5uZXQvQ049WlpaWlpaQTMsTD1QS0k/Y2VydGlmaWNh +dGVSZXZvY2F0aW9uTGlzdIZJbGRhcDovL2NsLnNpZW1lbnMuY29tL0NOPVpaWlpaWkEzLG89 +VHJ1c3RjZW50ZXI/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDBFBgNVHSAEPjA8MDoGDSsG +AQQBoWkHAgIEAQMwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5zaWVtZW5zLmNvbS9wa2kv +MAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUoassbqB68NPCTeof8R4hivwMre8wggEEBggr +BgEFBQcBAQSB9zCB9DAyBggrBgEFBQcwAoYmaHR0cDovL2FoLnNpZW1lbnMuY29tL3BraT9a +WlpaWlpBMy5jcnQwQQYIKwYBBQUHMAKGNWxkYXA6Ly9hbC5zaWVtZW5zLm5ldC9DTj1aWlpa +WlpBMyxMPVBLST9jQUNlcnRpZmljYXRlMEkGCCsGAQUFBzAChj1sZGFwOi8vYWwuc2llbWVu +cy5jb20vQ049WlpaWlpaQTMsbz1UcnVzdGNlbnRlcj9jQUNlcnRpZmljYXRlMDAGCCsGAQUF +BzABhiRodHRwOi8vb2NzcC5wa2ktc2VydmljZXMuc2llbWVucy5jb20wDQYJKoZIhvcNAQEL +BQADggIBAF98ZMNg28LgkwdjOdvOGbC1QitsWjZTyotmQESF0nClDLUhb0O5675vVixntbrf +eB8xy1+KRiadk40GnAIJ0YzmNl4Tav6hPYv9VBWe5olsWG7C4qB3Q/SwhvW/e+owxv1cBra8 +R3oRudiN81eTZQHyNghRephVqQG/dpPYqydoANfIhEpHa79QlpaCAeYl4896AZOS8HYbkDFs +hLdv7sEHtl79YuSWI1wBjbJl70c0Sb4wLRgCPuHyQj2Uw/vQ5xJlEvBDZAIXXe1TP/nqiuY6 +7nweJbbeqfFE6ZP3kCe+mEIWGSaO0iThZyLGer8fHs1XiEmhhPgvC7P7KodzpXU6+hX+ZzbD +DxEjFfetV5sh0aNSXG9xx4hZmS9bpImBGR8MvZ7cgxqItvLtY2xvfUbYW244d4RcWesaCDq3 +ZEIo6uCIzOzJAwjUdLIac+lLV0rxiHmb7O3cQ19kjpWDB31hmfrus/TKJ55pBKVWBX5m/mFv +K8Ep5USpGrNS0EzOP7I1kQZv2VsvAhSxk/m5FMLpDy8T0O8YgbLypTXoeJFWCF6RduSjVsaZ +lkAtTQYud683pjyOMxJXaQUYGU1PmEYSOonMkVsT9aBcxYkXLp+Ln/+8G0OCYu7dRdwnj+Ut +7yR/ltxtgDcaFApCb0qBTKbgbqZk1fASmkOp+kbdYmoUMYICVjCCAlICAQEwgb8wgbYxCzAJ +BgNVBAYTAkRFMQ8wDQYDVQQIDAZCYXllcm4xETAPBgNVBAcMCE11ZW5jaGVuMRAwDgYDVQQK +DAdTaWVtZW5zMREwDwYDVQQFEwhaWlpaWlpBNjEdMBsGA1UECwwUU2llbWVucyBUcnVzdCBD +ZW50ZXIxPzA9BgNVBAMMNlNpZW1lbnMgSXNzdWluZyBDQSBNZWRpdW0gU3RyZW5ndGggQXV0 +aGVudGljYXRpb24gMjAxNgIEZ5a6PTANBglghkgBZQMEAgEFAKBpMC8GCSqGSIb3DQEJBDEi +BCAOR58AbNfSrI+vtMs+dgAQtn3IVZ3RjYC5hz3j9k+6TTAYBgkqhkiG9w0BCQMxCwYJKoZI +hvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMDAyMTcyMTU2NDdaMA0GCSqGSIb3DQEBAQUABIIB +AHLSBcFHhNHPevbwqvA2ecuVb/aKnj45CFF6l8esP1H5DRm1ee5qMKuIS84NFuFC9RUENNhW +DBzsB+BVGz64o1f8QgIklYVrIJ4JZ0q1abNG7NbkVKWIpS3CQo//YWShUTYg+JpKx4YbahGR +sP5zbufbU4eagrrqBChjPTLy+njdjwCNu0XPykBTKOOf6BMjnS33AYjHJyh83JOY7rw3IDLx +8POQH4g5EMRpl9354s0rEkIezMt7pfUAsqY3QnQ8hvlE4KTikPQ+tvLMK1l/ffcLAP8BdBNI +YA3ikb3qCoGNSLKieYzNnBPhNOIJELUtEEaljAFZYMQzMKCbI4JdiDs= + +--B_3664825007_1904734766-- diff --git a/spec/lib/gitlab/email/attachment_uploader_spec.rb b/spec/lib/gitlab/email/attachment_uploader_spec.rb index c69b2f1eabc..462be76a58d 100644 --- a/spec/lib/gitlab/email/attachment_uploader_spec.rb +++ b/spec/lib/gitlab/email/attachment_uploader_spec.rb @@ -16,5 +16,20 @@ describe Gitlab::Email::AttachmentUploader do expect(link[:alt]).to eq("bricks") expect(link[:url]).to include("bricks.png") end + + context 'with a signed message' do + let(:message_raw) { fixture_file("emails/valid_reply_signed_smime.eml") } + + it 'uploads all attachments except the signature' do + links = described_class.new(message).execute(upload_parent: project, uploader_class: FileUploader) + + expect(links).not_to include(a_hash_including(alt: 'smime.p7s')) + + image_link = links.first + expect(image_link).not_to be_nil + expect(image_link[:alt]).to eq('gitlab_logo') + expect(image_link[:url]).to include('gitlab_logo.png') + end + end end end diff --git a/spec/lib/gitlab/email/handler_spec.rb b/spec/lib/gitlab/email/handler_spec.rb index 5229b778ccf..5014e4c22ce 100644 --- a/spec/lib/gitlab/email/handler_spec.rb +++ b/spec/lib/gitlab/email/handler_spec.rb @@ -3,17 +3,23 @@ require 'spec_helper' describe Gitlab::Email::Handler do + let(:email) { Mail.new { body 'email' } } + describe '.for' do it 'picks issue handler if there is no merge request prefix' do - expect(described_class.for('email', 'project+key')).to be_an_instance_of(Gitlab::Email::Handler::CreateIssueHandler) + expect(described_class.for(email, 'project+key')).to be_an_instance_of(Gitlab::Email::Handler::CreateIssueHandler) end it 'picks merge request handler if there is merge request key' do - expect(described_class.for('email', 'project+merge-request+key')).to be_an_instance_of(Gitlab::Email::Handler::CreateMergeRequestHandler) + expect(described_class.for(email, 'project+merge-request+key')).to be_an_instance_of(Gitlab::Email::Handler::CreateMergeRequestHandler) end it 'returns nil if no handler is found' do - expect(described_class.for('email', '')).to be_nil + expect(described_class.for(email, '')).to be_nil + end + + it 'returns nil if provided email is nil' do + expect(described_class.for(nil, '')).to be_nil end end @@ -25,7 +31,7 @@ describe Gitlab::Email::Handler do it 'picks each handler at least once' do matched_handlers = addresses.map do |address| - described_class.for('email', address).class + described_class.for(email, address).class end expect(matched_handlers.uniq).to match_array(ce_handlers) @@ -34,7 +40,7 @@ describe Gitlab::Email::Handler do it 'can pick exactly one handler for each address' do addresses.each do |address| matched_handlers = ce_handlers.select do |handler| - handler.new('email', address).can_handle? + handler.new(email, address).can_handle? end expect(matched_handlers.count).to eq(1), "#{address} matches #{matched_handlers.count} handlers: #{matched_handlers}" diff --git a/spec/lib/gitlab/import_export/merge_request_parser_spec.rb b/spec/lib/gitlab/import_export/merge_request_parser_spec.rb index ab834ac3fa8..0cdb3c43992 100644 --- a/spec/lib/gitlab/import_export/merge_request_parser_spec.rb +++ b/spec/lib/gitlab/import_export/merge_request_parser_spec.rb @@ -52,10 +52,10 @@ describe Gitlab::ImportExport::MergeRequestParser do context 'when the diff is invalid' do let(:merge_request_diff) { build(:merge_request_diff, merge_request: merge_request, base_commit_sha: 'foobar') } - it 'sets the diff to nil' do + it 'sets the diff to empty diff' do expect(merge_request_diff).to be_invalid expect(merge_request_diff.merge_request).to eq merge_request - expect(parsed_merge_request.merge_request_diff).to be_nil + expect(parsed_merge_request.merge_request_diff).to be_empty end end end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 36fd5d21e73..14f50ffd689 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -662,13 +662,12 @@ describe MergeRequest do end describe '#raw_diffs' do - let(:merge_request) { build(:merge_request) } let(:options) { { paths: ['a/b', 'b/a', 'c/*'] } } context 'when there are MR diffs' do - it 'delegates to the MR diffs' do - merge_request.merge_request_diff = MergeRequestDiff.new + let(:merge_request) { create(:merge_request, :with_diffs) } + it 'delegates to the MR diffs' do expect(merge_request.merge_request_diff).to receive(:raw_diffs).with(options) merge_request.raw_diffs(options) @@ -676,6 +675,8 @@ describe MergeRequest do end context 'when there are no MR diffs' do + let(:merge_request) { build(:merge_request) } + it 'delegates to the compare object' do merge_request.compare = double(:compare) diff --git a/spec/models/project_services/youtrack_service_spec.rb b/spec/models/project_services/youtrack_service_spec.rb index 0067793f8d8..b8fff635e99 100644 --- a/spec/models/project_services/youtrack_service_spec.rb +++ b/spec/models/project_services/youtrack_service_spec.rb @@ -38,8 +38,8 @@ describe YoutrackService do expect(described_class.reference_pattern.match('YT-123')[:issue]).to eq('YT-123') end - it 'does not allow issue number to be followed by a letter' do - expect(described_class.reference_pattern.match('YT-123A')).to eq(nil) + it 'allows lowercase project key on the reference' do + expect(described_class.reference_pattern.match('yt-123')[:issue]).to eq('yt-123') end end diff --git a/spec/support/shared_examples/models/issue_tracker_service_shared_examples.rb b/spec/support/shared_examples/models/issue_tracker_service_shared_examples.rb index 0a483fd30ba..b275d594792 100644 --- a/spec/support/shared_examples/models/issue_tracker_service_shared_examples.rb +++ b/spec/support/shared_examples/models/issue_tracker_service_shared_examples.rb @@ -21,4 +21,8 @@ RSpec.shared_examples 'allows project key on reference pattern' do |url_attr| expect(described_class.reference_pattern.match('3EXT_EXT-1234')).to eq nil expect(described_class.reference_pattern.match('EXT_EXT-1234')[0]).to eq 'EXT_EXT-1234' end + + it 'does not allow issue number to finish with a letter' do + expect(described_class.reference_pattern.match('EXT-123A')).to eq(nil) + end end |