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,13 +6,26 @@ module Gitlab ...@@ -6,13 +6,26 @@ 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
@project
end end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
def message def message
@message ||= process_message @message ||= process_message
...@@ -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,8 +2,9 @@ ...@@ -2,8 +2,9 @@
module Gitlab module Gitlab
module IncomingEmail module IncomingEmail
UNSUBSCRIBE_SUFFIX = '+unsubscribe'.freeze UNSUBSCRIBE_SUFFIX = '-unsubscribe'.freeze
WILDCARD_PLACEHOLDER = '%{key}'.freeze UNSUBSCRIBE_SUFFIX_LEGACY = '+unsubscribe'.freeze
WILDCARD_PLACEHOLDER = '%{key}'.freeze
class << self class << self
def enabled? def enabled?
...@@ -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,21 +23,58 @@ describe Gitlab::Email::Handler::CreateIssueHandler do ...@@ -23,21 +23,58 @@ 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
it "creates a new issue" do shared_examples "a new issue" do
setup_attachment it "creates a new issue" do
setup_attachment
expect { receiver.execute }.to change { project.issues.count }.by(1) expect { receiver.execute }.to change { project.issues.count }.by(1)
issue = project.issues.last issue = project.issues.last
expect(issue.author).to eq(user)
expect(issue.title).to eq('New Issue by email')
expect(issue.description).to include('reply by email')
expect(issue.description).to include(markdown)
end
end
it_behaves_like "a new issue"
expect(issue.author).to eq(user) context "creates a new issue with legacy email address" do
expect(issue.title).to eq('New Issue by email') let(:email_raw) { fixture_file('emails/valid_new_issue_legacy.eml') }
expect(issue.description).to include('reply by email')
expect(issue.description).to include(markdown) it_behaves_like "a new issue"
end 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,15 +70,25 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do ...@@ -43,15 +70,25 @@ describe Gitlab::Email::Handler::CreateMergeRequestHandler do
end end
context "when everything is fine" do context "when everything is fine" do
it "creates a new merge request" do shared_examples "a new merge request" do
expect { receiver.execute }.to change { project.merge_requests.count }.by(1) it "creates a new merge request" do
merge_request = project.merge_requests.last expect { receiver.execute }.to change { project.merge_requests.count }.by(1)
merge_request = project.merge_requests.last
expect(merge_request.author).to eq(user)
expect(merge_request.source_branch).to eq('feature') expect(merge_request.author).to eq(user)
expect(merge_request.title).to eq('Feature added') expect(merge_request.source_branch).to eq('feature')
expect(merge_request.description).to eq('Merge request description') expect(merge_request.title).to eq('Feature added')
expect(merge_request.target_branch).to eq(project.default_branch) expect(merge_request.description).to eq('Merge request description')
expect(merge_request.target_branch).to eq(project.default_branch)
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
end end
...@@ -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