Commit 8600043b authored by Sean McGivern's avatar Sean McGivern

Merge branch '29951-issue-creation-by-email-without-subaddressing' into 'master'

Support new issue creation by email without subaddressing

Closes #29951

See merge request gitlab-org/gitlab-ce!23523
parents 626f3d03 4a0801b9
...@@ -912,11 +912,16 @@ class Project < ActiveRecord::Base ...@@ -912,11 +912,16 @@ class Project < ActiveRecord::Base
def new_issuable_address(author, address_type) def new_issuable_address(author, address_type)
return unless Gitlab::IncomingEmail.supports_issue_creation? && author return unless Gitlab::IncomingEmail.supports_issue_creation? && author
# check since this can come from a request parameter
return unless %w(issue merge_request).include?(address_type)
author.ensure_incoming_email_token! author.ensure_incoming_email_token!
suffix = address_type == 'merge_request' ? '+merge-request' : '' suffix = address_type.dasherize
Gitlab::IncomingEmail.reply_address(
"#{full_path}#{suffix}+#{author.incoming_email_token}") # example: incoming+h5bp-html5-boilerplate-8-1234567890abcdef123456789-issue@localhost.com
# example: incoming+h5bp-html5-boilerplate-8-1234567890abcdef123456789-merge-request@localhost.com
Gitlab::IncomingEmail.reply_address("#{full_path_slug}-#{project_id}-#{author.incoming_email_token}-#{suffix}")
end end
def build_commit_note(commit) def build_commit_note(commit)
......
---
title: No longer require email subaddressing for issue creation by email
merge_request: 23523
author:
type: changed
...@@ -6,12 +6,14 @@ module Gitlab ...@@ -6,12 +6,14 @@ module Gitlab
class BaseHandler class BaseHandler
attr_reader :mail, :mail_key attr_reader :mail, :mail_key
HANDLER_ACTION_BASE_REGEX ||= /(?<project_slug>.+)-(?<project_id>\d+)/.freeze
def initialize(mail, mail_key) def initialize(mail, mail_key)
@mail = mail @mail = mail
@mail_key = mail_key @mail_key = mail_key
end end
def can_execute? def can_handle?
raise NotImplementedError raise NotImplementedError
end end
......
...@@ -2,21 +2,33 @@ ...@@ -2,21 +2,33 @@
require 'gitlab/email/handler/base_handler' require 'gitlab/email/handler/base_handler'
# handles issue creation emails with these formats:
# incoming+gitlab-org-gitlab-ce-20-Author_Token12345678-issue@incoming.gitlab.com
# incoming+gitlab-org/gitlab-ce+Author_Token12345678@incoming.gitlab.com (legacy)
module Gitlab module Gitlab
module Email module Email
module Handler module Handler
class CreateIssueHandler < BaseHandler class CreateIssueHandler < BaseHandler
include ReplyProcessing include ReplyProcessing
attr_reader :project_path, :incoming_email_token
HANDLER_REGEX = /\A#{HANDLER_ACTION_BASE_REGEX}-(?<incoming_email_token>.+)-issue\z/.freeze
HANDLER_REGEX_LEGACY = /\A(?<project_path>[^\+]*)\+(?<incoming_email_token>.*)\z/.freeze
def initialize(mail, mail_key) def initialize(mail, mail_key)
super(mail, mail_key) super(mail, mail_key)
@project_path, @incoming_email_token =
mail_key && mail_key.split('+', 2) if !mail_key&.include?('/') && (matched = HANDLER_REGEX.match(mail_key.to_s))
@project_slug = matched[:project_slug]
@project_id = matched[:project_id]&.to_i
@incoming_email_token = matched[:incoming_email_token]
elsif matched = HANDLER_REGEX_LEGACY.match(mail_key.to_s)
@project_path = matched[:project_path]
@incoming_email_token = matched[:incoming_email_token]
end
end end
def can_handle? def can_handle?
!incoming_email_token.nil? && !incoming_email_token.include?("+") && !mail_key.include?(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX) incoming_email_token && (project_id || can_handle_legacy_format?)
end end
def execute def execute
...@@ -36,10 +48,6 @@ module Gitlab ...@@ -36,10 +48,6 @@ module Gitlab
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
def project
@project ||= Project.find_by_full_path(project_path)
end
private private
def create_issue def create_issue
...@@ -50,6 +58,10 @@ module Gitlab ...@@ -50,6 +58,10 @@ module Gitlab
description: message_including_reply description: message_including_reply
).execute ).execute
end end
def can_handle_legacy_format?
project_path && !incoming_email_token.include?('+') && !mail_key.include?(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX_LEGACY)
end
end end
end end
end end
......
...@@ -3,23 +3,33 @@ ...@@ -3,23 +3,33 @@
require 'gitlab/email/handler/base_handler' require 'gitlab/email/handler/base_handler'
require 'gitlab/email/handler/reply_processing' require 'gitlab/email/handler/reply_processing'
# handles merge request creation emails with these formats:
# incoming+gitlab-org-gitlab-ce-20-Author_Token12345678-merge-request@incoming.gitlab.com
# incoming+gitlab-org/gitlab-ce+merge-request+Author_Token12345678@incoming.gitlab.com (legacy)
module Gitlab module Gitlab
module Email module Email
module Handler module Handler
class CreateMergeRequestHandler < BaseHandler class CreateMergeRequestHandler < BaseHandler
include ReplyProcessing include ReplyProcessing
attr_reader :project_path, :incoming_email_token
HANDLER_REGEX = /\A#{HANDLER_ACTION_BASE_REGEX}-(?<incoming_email_token>.+)-merge-request\z/.freeze
HANDLER_REGEX_LEGACY = /\A(?<project_path>[^\+]*)\+merge-request\+(?<incoming_email_token>.*)/.freeze
def initialize(mail, mail_key) def initialize(mail, mail_key)
super(mail, mail_key) super(mail, mail_key)
if m = /\A([^\+]*)\+merge-request\+(.*)/.match(mail_key.to_s) if !mail_key&.include?('/') && (matched = HANDLER_REGEX.match(mail_key.to_s))
@project_path, @incoming_email_token = m.captures @project_slug = matched[:project_slug]
@project_id = matched[:project_id]&.to_i
@incoming_email_token = matched[:incoming_email_token]
elsif matched = HANDLER_REGEX_LEGACY.match(mail_key.to_s)
@project_path = matched[:project_path]
@incoming_email_token = matched[:incoming_email_token]
end end
end end
def can_handle? def can_handle?
@project_path && @incoming_email_token incoming_email_token && (project_id || project_path)
end end
def execute def execute
...@@ -40,10 +50,6 @@ module Gitlab ...@@ -40,10 +50,6 @@ module Gitlab
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
def project
@project ||= Project.find_by_full_path(project_path)
end
def metrics_params def metrics_params
super.merge(includes_patches: patch_attachments.any?) super.merge(includes_patches: patch_attachments.any?)
end end
...@@ -97,7 +103,7 @@ module Gitlab ...@@ -97,7 +103,7 @@ module Gitlab
def remove_patch_attachments def remove_patch_attachments
patch_attachments.each { |patch| mail.parts.delete(patch) } patch_attachments.each { |patch| mail.parts.delete(patch) }
# reset the message, so it needs to be reporocessed when the attachments # reset the message, so it needs to be reprocessed when the attachments
# have been modified # have been modified
@message = nil @message = nil
end end
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
require 'gitlab/email/handler/base_handler' require 'gitlab/email/handler/base_handler'
require 'gitlab/email/handler/reply_processing' require 'gitlab/email/handler/reply_processing'
# handles note/reply creation emails with these formats:
# incoming+1234567890abcdef1234567890abcdef@incoming.gitlab.com
module Gitlab module Gitlab
module Email module Email
module Handler module Handler
......
...@@ -6,14 +6,27 @@ module Gitlab ...@@ -6,14 +6,27 @@ module Gitlab
module ReplyProcessing module ReplyProcessing
private private
attr_reader :project_id, :project_slug, :project_path, :incoming_email_token
def author def author
raise NotImplementedError raise NotImplementedError
end end
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def project def project
raise NotImplementedError return @project if instance_variable_defined?(:@project)
if project_id
@project = Project.find_by_id(project_id)
@project = nil unless valid_project_slug?(@project)
else
@project = Project.find_by_full_path(project_path)
end end
@project
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
def message def message
@message ||= process_message @message ||= process_message
end end
...@@ -58,6 +71,10 @@ module Gitlab ...@@ -58,6 +71,10 @@ module Gitlab
raise invalid_exception, msg raise invalid_exception, msg
end end
def valid_project_slug?(found_project)
project_slug == found_project.full_path_slug
end
end end
end end
end end
......
...@@ -2,14 +2,28 @@ ...@@ -2,14 +2,28 @@
require 'gitlab/email/handler/base_handler' require 'gitlab/email/handler/base_handler'
# handles unsubscribe emails with these formats:
# incoming+1234567890abcdef1234567890abcdef-unsubscribe@incoming.gitlab.com
# incoming+1234567890abcdef1234567890abcdef+unsubscribe@incoming.gitlab.com (legacy)
module Gitlab module Gitlab
module Email module Email
module Handler module Handler
class UnsubscribeHandler < BaseHandler class UnsubscribeHandler < BaseHandler
delegate :project, to: :sent_notification, allow_nil: true delegate :project, to: :sent_notification, allow_nil: true
HANDLER_REGEX_FOR = -> (suffix) { /\A(?<reply_token>\w+)#{Regexp.escape(suffix)}\z/ }.freeze
HANDLER_REGEX = HANDLER_REGEX_FOR.call(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX).freeze
HANDLER_REGEX_LEGACY = HANDLER_REGEX_FOR.call(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX_LEGACY).freeze
def initialize(mail, mail_key)
super(mail, mail_key)
matched = HANDLER_REGEX.match(mail_key.to_s) || HANDLER_REGEX_LEGACY.match(mail_key.to_s)
@reply_token = matched[:reply_token] if matched
end
def can_handle? def can_handle?
mail_key =~ /\A\w+#{Regexp.escape(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX)}\z/ reply_token.present?
end end
def execute def execute
...@@ -24,12 +38,10 @@ module Gitlab ...@@ -24,12 +38,10 @@ module Gitlab
private private
def sent_notification attr_reader :reply_token
@sent_notification ||= SentNotification.for(reply_key)
end
def reply_key def sent_notification
mail_key.sub(Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX, '') @sent_notification ||= SentNotification.for(reply_token)
end end
end end
end end
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
module Gitlab module Gitlab
module IncomingEmail module IncomingEmail
UNSUBSCRIBE_SUFFIX = '+unsubscribe'.freeze UNSUBSCRIBE_SUFFIX = '-unsubscribe'.freeze
UNSUBSCRIBE_SUFFIX_LEGACY = '+unsubscribe'.freeze
WILDCARD_PLACEHOLDER = '%{key}'.freeze WILDCARD_PLACEHOLDER = '%{key}'.freeze
class << self class << self
...@@ -22,6 +23,7 @@ module Gitlab ...@@ -22,6 +23,7 @@ module Gitlab
config.address.sub(WILDCARD_PLACEHOLDER, key) config.address.sub(WILDCARD_PLACEHOLDER, key)
end end
# example: incoming+1234567890abcdef1234567890abcdef-unsubscribe@incoming.gitlab.com
def unsubscribe_address(key) def unsubscribe_address(key)
config.address.sub(WILDCARD_PLACEHOLDER, "#{key}#{UNSUBSCRIBE_SUFFIX}") config.address.sub(WILDCARD_PLACEHOLDER, "#{key}#{UNSUBSCRIBE_SUFFIX}")
end end
......
From: "Jake the Dog" <jake@adventuretime.ooo> From: "Jake the Dog" <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo To: incoming+gitlabhq-gitlabhq-project_id-auth_token-merge-request@appmail.adventuretime.ooo
Subject: new-branch-with-a-patch Subject: new-branch-with-a-patch
Date: Wed, 31 Oct 2018 17:27:52 +0100 Date: Wed, 31 Oct 2018 17:27:52 +0100
X-Mailer: MailMate (1.12r5523) X-Mailer: MailMate (1.12r5523)
......
From: "Jake the Dog" <jake@adventuretime.ooo> From: "Jake the Dog" <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo To: incoming+gitlabhq-gitlabhq-project_id-auth_token-merge-request@appmail.adventuretime.ooo
Subject: feature Subject: feature
Date: Wed, 31 Oct 2018 17:27:52 +0100 Date: Wed, 31 Oct 2018 17:27:52 +0100
X-Mailer: MailMate (1.12r5523) X-Mailer: MailMate (1.12r5523)
......
From: "Jake the Dog" <jake@adventuretime.ooo> From: "Jake the Dog" <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo To: incoming+gitlabhq-gitlabhq-project_id-auth_token-merge-request@appmail.adventuretime.ooo
Subject: new-branch-with-a-patch Subject: new-branch-with-a-patch
Date: Wed, 24 Oct 2018 16:39:49 +0200 Date: Wed, 24 Oct 2018 16:39:49 +0200
X-Mailer: MailMate (1.12r5523) X-Mailer: MailMate (1.12r5523)
......
From: "Jake the Dog" <jake@adventuretime.ooo> From: "Jake the Dog" <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo To: incoming+gitlabhq-gitlabhq-project_id-auth_token-merge-request@appmail.adventuretime.ooo
Subject: new-branch-with-a-patch Subject: new-branch-with-a-patch
Date: Wed, 24 Oct 2018 16:39:49 +0200 Date: Wed, 24 Oct 2018 16:39:49 +0200
X-Mailer: MailMate (1.12r5523) X-Mailer: MailMate (1.12r5523)
......
Return-Path: <jake@adventuretime.ooo> Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400 Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700 Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq-gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400 Date: Thu, 13 Jun 2013 17:03:48 -0400
From: Jake the Dog <jake@adventuretime.ooo> From: Jake the Dog <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+auth_token@appmail.adventuretime.ooo To: incoming+gitlabhq-gitlabhq-project_id-auth_token-issue@appmail.adventuretime.ooo
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
Subject: New Issue by email Subject: New Issue by email
Mime-Version: 1.0 Mime-Version: 1.0
......
Return-Path: <jake@adventuretime.ooo> Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400 Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700 Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq-gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400 Date: Thu, 13 Jun 2013 17:03:48 -0400
From: Jake the Dog <jake@adventuretime.ooo> From: Jake the Dog <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+auth_token@appmail.adventuretime.ooo To: incoming+gitlabhq-gitlabhq-project_id-auth_token-issue@appmail.adventuretime.ooo
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
Subject: New Issue by email Subject: New Issue by email
Mime-Version: 1.0 Mime-Version: 1.0
......
Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400
From: Jake the Dog <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+auth_token@appmail.adventuretime.ooo
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
Subject: New Issue by email
Mime-Version: 1.0
Content-Type: text/plain;
charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Sieve: CMU Sieve 2.2
X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
13 Jun 2013 14:03:48 -0700 (PDT)
X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
The reply by email functionality should be extended to allow creating a new issue by email.
* Allow an admin to specify which project the issue should be created under by checking the sender domain.
* Possibly allow the use of regular expression matches within the subject/body to specify which project the issue should be created under.
Return-Path: <jake@adventuretime.ooo> Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400 Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700 Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq-gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400 Date: Thu, 13 Jun 2013 17:03:48 -0400
From: Jake the Dog <jake@adventuretime.ooo> From: Jake the Dog <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+auth_token@appmail.adventuretime.ooo To: incoming+gitlabhq-gitlabhq-project_id-auth_token-issue@appmail.adventuretime.ooo
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
Subject: New Issue by email Subject: New Issue by email
Mime-Version: 1.0 Mime-Version: 1.0
......
Return-Path: <jake@adventuretime.ooo> Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400 Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq-gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700 Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq-gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400 Date: Thu, 13 Jun 2013 17:03:48 -0400
From: Jake the Dog <jake@adventuretime.ooo> From: Jake the Dog <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo To: incoming+gitlabhq-gitlabhq-project_id-auth_token-merge-request@appmail.adventuretime.ooo
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
Subject: feature Subject: feature
Mime-Version: 1.0 Mime-Version: 1.0
......
Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq-gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400
From: Jake the Dog <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
Subject: feature
Mime-Version: 1.0
Content-Type: text/plain;
charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Sieve: CMU Sieve 2.2
X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
13 Jun 2013 14:03:48 -0700 (PDT)
X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
Merge request description
Return-Path: <jake@adventuretime.ooo> Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400 Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700 Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq-gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400 Date: Thu, 13 Jun 2013 17:03:48 -0400
From: Jake the Dog <jake@adventuretime.ooo> From: Jake the Dog <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo To: incoming+gitlabhq-gitlabhq-project_id-auth_token-merge-request@appmail.adventuretime.ooo
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
Subject: feature Subject: feature
Mime-Version: 1.0 Mime-Version: 1.0
......
Return-Path: <jake@adventuretime.ooo> Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400 Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700 Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq-gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400 Date: Thu, 13 Jun 2013 17:03:48 -0400
From: Jake the Dog <jake@adventuretime.ooo> From: Jake the Dog <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+merge-request+auth_token@appmail.adventuretime.ooo To: incoming+gitlabhq-gitlabhq-project_id-auth_token-merge-request@appmail.adventuretime.ooo
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
Subject: Subject:
Mime-Version: 1.0 Mime-Version: 1.0
......
Return-Path: <jake@adventuretime.ooo> Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400 Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400 Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700 Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq-gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700 Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400 Date: Thu, 13 Jun 2013 17:03:48 -0400
From: Jake the Dog <jake@adventuretime.ooo> From: Jake the Dog <jake@adventuretime.ooo>
To: incoming+gitlabhq/gitlabhq+bad_token@appmail.adventuretime.ooo To: incoming+gitlabhq-gitlabhq-project_id-bad_token-issue@appmail.adventuretime.ooo
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com> Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
Subject: New Issue by email Subject: New Issue by email
Mime-Version: 1.0 Mime-Version: 1.0
......
Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq-gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400
From: Jake the Dog <jake@adventuretime.ooo>
To: incoming+gitlabhq-gitlabhq-project_id-bad_token-merge-request@appmail.adventuretime.ooo
Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
Subject: New Issue by email
Mime-Version: 1.0
Content-Type: text/plain;
charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Sieve: CMU Sieve 2.2
X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
13 Jun 2013 14:03:48 -0700 (PDT)
X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
...@@ -11,7 +11,7 @@ describe Gitlab::Email::Handler::CreateIssueHandler do ...@@ -11,7 +11,7 @@ describe Gitlab::Email::Handler::CreateIssueHandler do
stub_config_setting(host: 'localhost') stub_config_setting(host: 'localhost')
end end
let(:email_raw) { fixture_file('emails/valid_new_issue.eml') } let(:email_raw) { email_fixture('emails/valid_new_issue.eml') }
let(:namespace) { create(:namespace, path: 'gitlabhq') } let(:namespace) { create(:namespace, path: 'gitlabhq') }
let!(:project) { create(:project, :public, namespace: namespace, path: 'gitlabhq') } let!(:project) { create(:project, :public, namespace: namespace, path: 'gitlabhq') }
...@@ -23,7 +23,35 @@ describe Gitlab::Email::Handler::CreateIssueHandler do ...@@ -23,7 +23,35 @@ describe Gitlab::Email::Handler::CreateIssueHandler do
) )
end end
context "when email key" do
let(:mail) { Mail::Message.new(email_raw) }
it "matches the new format" do
handler = described_class.new(mail, "gitlabhq-gitlabhq-#{project.project_id}-#{user.incoming_email_token}-issue")
expect(handler.instance_variable_get(:@project_id)).to eq project.project_id
expect(handler.instance_variable_get(:@project_slug)).to eq project.full_path_slug
expect(handler.instance_variable_get(:@incoming_email_token)).to eq user.incoming_email_token
expect(handler.can_handle?).to be_truthy
end
it "matches the legacy format" do
handler = described_class.new(mail, "h5bp/html5-boilerplate+#{user.incoming_email_token}")
expect(handler.instance_variable_get(:@project_path)).to eq 'h5bp/html5-boilerplate'
expect(handler.instance_variable_get(:@incoming_email_token)).to eq user.incoming_email_token
expect(handler.can_handle?).to be_truthy
end
it "doesn't match either format" do
handler = described_class.new(mail, "h5bp-html5-boilerplate+something+invalid")
expect(handler.can_handle?).to be_falsey
end
end
context "when everything is fine" do context "when everything is fine" do
shared_examples "a new issue" do
it "creates a new issue" do it "creates a new issue" do
setup_attachment setup_attachment
...@@ -35,9 +63,18 @@ describe Gitlab::Email::Handler::CreateIssueHandler do ...@@ -35,9 +63,18 @@ describe Gitlab::Email::Handler::CreateIssueHandler do
expect(issue.description).to include('reply by email') expect(issue.description).to include('reply by email')
expect(issue.description).to include(markdown) expect(issue.description).to include(markdown)
end end
end
it_behaves_like "a new issue"
context "creates a new issue with legacy email address" do
let(:email_raw) { fixture_file('emails/valid_new_issue_legacy.eml') }
it_behaves_like "a new issue"
end
context "when the reply is blank" do context "when the reply is blank" do
let(:email_raw) { fixture_file("emails/valid_new_issue_empty.eml") } let(:email_raw) { email_fixture("emails/valid_new_issue_empty.eml") }
it "creates a new issue" do it "creates a new issue" do
expect { receiver.execute }.to change { project.issues.count }.by(1) expect { receiver.execute }.to change { project.issues.count }.by(1)
...@@ -50,7 +87,7 @@ describe Gitlab::Email::Handler::CreateIssueHandler do ...@@ -50,7 +87,7 @@ describe Gitlab::Email::Handler::CreateIssueHandler do
end end
context "when there are quotes in email" do context "when there are quotes in email" do
let(:email_raw) { fixture_file("emails/valid_new_issue_with_quote.eml") } let(:email_raw) { email_fixture("emails/valid_new_issue_with_quote.eml") }
it "creates a new issue" do it "creates a new issue" do
expect { receiver.execute }.to change { project.issues.count }.by(1) expect { receiver.execute }.to change { project.issues.count }.by(1)
...@@ -76,7 +113,7 @@ describe Gitlab::Email::Handler::CreateIssueHandler do ...@@ -76,7 +113,7 @@ describe Gitlab::Email::Handler::CreateIssueHandler do
end end
context "when we can't find the incoming_email_token" do context "when we can't find the incoming_email_token" do
let(:email_raw) { fixture_file("emails/wrong_incoming_email_token.eml") } let(:email_raw) { email_fixture("emails/wrong_issue_incoming_email_token.eml") }
it "raises an UserNotFoundError" do it "raises an UserNotFoundError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::UserNotFoundError) expect { receiver.execute }.to raise_error(Gitlab::Email::UserNotFoundError)
...@@ -91,4 +128,8 @@ describe Gitlab::Email::Handler::CreateIssueHandler do ...@@ -91,4 +128,8 @@ describe Gitlab::Email::Handler::CreateIssueHandler do
end end
end end
end end
def email_fixture(path)
fixture_file(path).gsub('project_id', project.project_id.to_s)
end
end end
...@@ -15,7 +15,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -15,7 +15,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
TestEnv.clean_test_path TestEnv.clean_test_path
end end
let(:email_raw) { fixture_file('emails/valid_new_merge_request.eml') } let(:email_raw) { email_fixture('emails/valid_new_merge_request.eml') }
let(:namespace) { create(:namespace, path: 'gitlabhq') } let(:namespace) { create(:namespace, path: 'gitlabhq') }
let!(:project) { create(:project, :public, :repository, namespace: namespace, path: 'gitlabhq') } let!(:project) { create(:project, :public, :repository, namespace: namespace, path: 'gitlabhq') }
...@@ -27,6 +27,33 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -27,6 +27,33 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
) )
end end
context "when email key" do
let(:mail) { Mail::Message.new(email_raw) }
it "matches the new format" do
handler = described_class.new(mail, "gitlabhq-gitlabhq-#{project.project_id}-#{user.incoming_email_token}-merge-request")
expect(handler.instance_variable_get(:@project_id)).to eq project.project_id
expect(handler.instance_variable_get(:@project_slug)).to eq project.full_path_slug
expect(handler.instance_variable_get(:@incoming_email_token)).to eq user.incoming_email_token
expect(handler.can_handle?).to be_truthy
end
it "matches the legacy format" do
handler = described_class.new(mail, "h5bp/html5-boilerplate+merge-request+#{user.incoming_email_token}")
expect(handler.instance_variable_get(:@project_path)).to eq 'h5bp/html5-boilerplate'
expect(handler.instance_variable_get(:@incoming_email_token)).to eq user.incoming_email_token
expect(handler.can_handle?).to be_truthy
end
it "doesn't match either format" do
handler = described_class.new(mail, "h5bp-html5-boilerplate+merge-request")
expect(handler.can_handle?).to be_falsey
end
end
context "as a non-developer" do context "as a non-developer" do
before do before do
project.add_guest(user) project.add_guest(user)
...@@ -43,6 +70,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -43,6 +70,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
end end
context "when everything is fine" do context "when everything is fine" do
shared_examples "a new merge request" do
it "creates a new merge request" do it "creates a new merge request" do
expect { receiver.execute }.to change { project.merge_requests.count }.by(1) expect { receiver.execute }.to change { project.merge_requests.count }.by(1)
merge_request = project.merge_requests.last merge_request = project.merge_requests.last
...@@ -55,6 +83,15 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -55,6 +83,15 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
end end
end end
it_behaves_like "a new merge request"
context "creates a new merge request with legacy email address" do
let(:email_raw) { fixture_file('emails/valid_new_merge_request_legacy.eml') }
it_behaves_like "a new merge request"
end
end
context "something is wrong" do context "something is wrong" do
context "when the merge request could not be saved" do context "when the merge request could not be saved" do
before do before do
...@@ -67,7 +104,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -67,7 +104,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
end end
context "when we can't find the incoming_email_token" do context "when we can't find the incoming_email_token" do
let(:email_raw) { fixture_file("emails/wrong_incoming_email_token.eml") } let(:email_raw) { email_fixture("emails/wrong_merge_request_incoming_email_token.eml") }
it "raises an UserNotFoundError" do it "raises an UserNotFoundError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::UserNotFoundError) expect { receiver.execute }.to raise_error(Gitlab::Email::UserNotFoundError)
...@@ -75,7 +112,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -75,7 +112,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
end end
context "when the subject is blank" do context "when the subject is blank" do
let(:email_raw) { fixture_file("emails/valid_new_merge_request_no_subject.eml") } let(:email_raw) { email_fixture("emails/valid_new_merge_request_no_subject.eml") }
it "raises an InvalidMergeRequestError" do it "raises an InvalidMergeRequestError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::InvalidMergeRequestError) expect { receiver.execute }.to raise_error(Gitlab::Email::InvalidMergeRequestError)
...@@ -83,7 +120,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -83,7 +120,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
end end
context "when the message body is blank" do context "when the message body is blank" do
let(:email_raw) { fixture_file("emails/valid_new_merge_request_no_description.eml") } let(:email_raw) { email_fixture("emails/valid_new_merge_request_no_description.eml") }
it "creates a new merge request with description set from the last commit" do it "creates a new merge request with description set from the last commit" do
expect { receiver.execute }.to change { project.merge_requests.count }.by(1) expect { receiver.execute }.to change { project.merge_requests.count }.by(1)
...@@ -95,7 +132,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -95,7 +132,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
end end
context 'when the email contains patch attachments' do context 'when the email contains patch attachments' do
let(:email_raw) { fixture_file("emails/valid_merge_request_with_patch.eml") } let(:email_raw) { email_fixture("emails/valid_merge_request_with_patch.eml") }
it 'creates the source branch and applies the patches' do it 'creates the source branch and applies the patches' do
receiver.execute receiver.execute
...@@ -120,7 +157,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -120,7 +157,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
end end
context 'when the patch could not be applied' do context 'when the patch could not be applied' do
let(:email_raw) { fixture_file("emails/merge_request_with_conflicting_patch.eml") } let(:email_raw) { email_fixture("emails/merge_request_with_conflicting_patch.eml") }
it 'raises an error' do it 'raises an error' do
expect { receiver.execute }.to raise_error(Gitlab::Email::InvalidAttachment) expect { receiver.execute }.to raise_error(Gitlab::Email::InvalidAttachment)
...@@ -128,7 +165,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -128,7 +165,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
end end
context 'when specifying the target branch using quick actions' do context 'when specifying the target branch using quick actions' do
let(:email_raw) { fixture_file('emails/merge_request_with_patch_and_target_branch.eml') } let(:email_raw) { email_fixture('emails/merge_request_with_patch_and_target_branch.eml') }
it 'creates the merge request with the correct target branch' do it 'creates the merge request with the correct target branch' do
receiver.execute receiver.execute
...@@ -150,7 +187,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -150,7 +187,7 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
end end
describe '#patch_attachments' do describe '#patch_attachments' do
let(:email_raw) { fixture_file('emails/merge_request_multiple_patches.eml') } let(:email_raw) { email_fixture('emails/merge_request_multiple_patches.eml') }
let(:mail) { Mail::Message.new(email_raw) } let(:mail) { Mail::Message.new(email_raw) }
subject(:handler) { described_class.new(mail, mail_key) } subject(:handler) { described_class.new(mail, mail_key) }
...@@ -163,4 +200,8 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -163,4 +200,8 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
expect(attachments).to eq(expected_filenames) expect(attachments).to eq(expected_filenames)
end end
end end
def email_fixture(path)
fixture_file(path).gsub('project_id', project.project_id.to_s)
end
end end
...@@ -10,13 +10,35 @@ describe Gitlab::Email::Handler::UnsubscribeHandler do ...@@ -10,13 +10,35 @@ describe Gitlab::Email::Handler::UnsubscribeHandler do
stub_config_setting(host: 'localhost') stub_config_setting(host: 'localhost')
end end
let(:email_raw) { fixture_file('emails/valid_reply.eml').gsub(mail_key, "#{mail_key}+unsubscribe") } let(:email_raw) { fixture_file('emails/valid_reply.eml').gsub(mail_key, "#{mail_key}#{Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX}") }
let(:project) { create(:project, :public) } let(:project) { create(:project, :public) }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:noteable) { create(:issue, project: project) } let(:noteable) { create(:issue, project: project) }
let!(:sent_notification) { SentNotification.record(noteable, user.id, mail_key) } let!(:sent_notification) { SentNotification.record(noteable, user.id, mail_key) }
context "when email key" do
let(:mail) { Mail::Message.new(email_raw) }
it "matches the new format" do
handler = described_class.new(mail, "#{mail_key}#{Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX}")
expect(handler.can_handle?).to be_truthy
end
it "matches the legacy format" do
handler = described_class.new(mail, "#{mail_key}#{Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX_LEGACY}")
expect(handler.can_handle?).to be_truthy
end
it "doesn't match either format" do
handler = described_class.new(mail, "+#{mail_key}#{Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX}")
expect(handler.can_handle?).to be_falsey
end
end
context 'when notification concerns a commit' do context 'when notification concerns a commit' do
let(:commit) { create(:commit, project: project) } let(:commit) { create(:commit, project: project) }
let!(:sent_notification) { SentNotification.record(commit, user.id, mail_key) } let!(:sent_notification) { SentNotification.record(commit, user.id, mail_key) }
...@@ -40,6 +62,14 @@ describe Gitlab::Email::Handler::UnsubscribeHandler do ...@@ -40,6 +62,14 @@ describe Gitlab::Email::Handler::UnsubscribeHandler do
it 'unsubscribes user from notable' do it 'unsubscribes user from notable' do
expect { receiver.execute }.to change { noteable.subscribed?(user) }.from(true).to(false) expect { receiver.execute }.to change { noteable.subscribed?(user) }.from(true).to(false)
end end
context 'when using old style unsubscribe link' do
let(:email_raw) { fixture_file('emails/valid_reply.eml').gsub(mail_key, "#{mail_key}#{Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX_LEGACY}") }
it 'unsubscribes user from notable' do
expect { receiver.execute }.to change { noteable.subscribed?(user) }.from(true).to(false)
end
end
end end
context 'when the noteable could not be found' do context 'when the noteable could not be found' do
......
...@@ -19,7 +19,8 @@ describe Gitlab::Email::Handler do ...@@ -19,7 +19,8 @@ describe Gitlab::Email::Handler do
describe 'regexps are set properly' do describe 'regexps are set properly' do
let(:addresses) do let(:addresses) do
%W(sent_notification_key#{Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX} sent_notification_key path/to/project+merge-request+user_email_token path/to/project+user_email_token) %W(sent_notification_key#{Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX} sent_notification_key path-to-project-123-user_email_token-merge-request path-to-project-123-user_email_token-issue) +
%W(sent_notification_key#{Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX_LEGACY} sent_notification_key path/to/project+merge-request+user_email_token path/to/project+user_email_token)
end end
it 'picks each handler at least once' do it 'picks each handler at least once' do
......
...@@ -61,7 +61,7 @@ describe Gitlab::IncomingEmail do ...@@ -61,7 +61,7 @@ describe Gitlab::IncomingEmail do
end end
it 'returns the address with interpolated reply key and unsubscribe suffix' do it 'returns the address with interpolated reply key and unsubscribe suffix' do
expect(described_class.unsubscribe_address('key')).to eq('replies+key+unsubscribe@example.com') expect(described_class.unsubscribe_address('key')).to eq("replies+key#{Gitlab::IncomingEmail::UNSUBSCRIBE_SUFFIX}@example.com")
end end
end end
......
...@@ -610,16 +610,20 @@ describe Project do ...@@ -610,16 +610,20 @@ describe Project do
end end
it 'returns the address to create a new issue' do it 'returns the address to create a new issue' do
address = "p+#{project.full_path}+#{user.incoming_email_token}@gl.ab" address = "p+#{project.full_path_slug}-#{project.project_id}-#{user.incoming_email_token}-issue@gl.ab"
expect(project.new_issuable_address(user, 'issue')).to eq(address) expect(project.new_issuable_address(user, 'issue')).to eq(address)
end end
it 'returns the address to create a new merge request' do it 'returns the address to create a new merge request' do
address = "p+#{project.full_path}+merge-request+#{user.incoming_email_token}@gl.ab" address = "p+#{project.full_path_slug}-#{project.project_id}-#{user.incoming_email_token}-merge-request@gl.ab"
expect(project.new_issuable_address(user, 'merge_request')).to eq(address) expect(project.new_issuable_address(user, 'merge_request')).to eq(address)
end end
it 'returns nil with invalid address type' do
expect(project.new_issuable_address(user, 'invalid_param')).to be_nil
end
end end
context 'incoming email disabled' do context 'incoming email disabled' do
......
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