mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
1586 lines
50 KiB
Ruby
1586 lines
50 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#-- copyright
|
|
# OpenProject is an open source project management software.
|
|
# Copyright (C) the OpenProject GmbH
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License version 3.
|
|
#
|
|
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
|
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
# Copyright (C) 2010-2013 the ChiliProject Team
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
# See COPYRIGHT and LICENSE files for more details.
|
|
#++
|
|
|
|
require "spec_helper"
|
|
|
|
RSpec.describe IncomingEmails::MailHandler do # rubocop:disable RSpec/SpecFilePathFormat
|
|
# we need these run first so the anonymous and system users are created and
|
|
# there is a default work package priority to save any work packages
|
|
shared_let(:anno_user) { User.anonymous }
|
|
shared_let(:system_user) { User.system }
|
|
shared_let(:priority_low) { create(:priority_low, name: "Low", is_default: true) }
|
|
|
|
shared_let(:project) { create(:valid_project, identifier: "onlinestore", name: "OnlineStore", public: false) }
|
|
|
|
before do
|
|
allow(UserMailer)
|
|
.to receive(:incoming_email_error)
|
|
.and_return instance_double(ActionMailer::MessageDelivery, deliver_later: nil)
|
|
end
|
|
|
|
after do
|
|
User.current = nil
|
|
allow(Setting).to receive(:default_language).and_return("en")
|
|
end
|
|
|
|
shared_context "for wp_on_given_project" do
|
|
let(:permissions) { %i[add_work_packages assign_versions work_package_assigned] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_on_given_project.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "for wp_on_given_project_case_insensitive" do
|
|
let(:permissions) { %i[add_work_packages assign_versions] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let(:submit_options) { { allow_override: "version" } }
|
|
|
|
subject do
|
|
submit_email("wp_on_given_project_case_insensitive.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "for wp on given project group assignment" do
|
|
let(:permissions) { %i[add_work_packages] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let!(:group) do
|
|
create(:group,
|
|
lastname: "A-Team",
|
|
member_with_permissions: { project => [:work_package_assigned] })
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_on_given_project_group_assignment.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a reply to a wp mention with quotes above" do
|
|
let(:permissions) { %i[edit_work_packages view_work_packages] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
|
|
let!(:work_package) do
|
|
create(:work_package,
|
|
id: 2,
|
|
project:) do |wp|
|
|
wp.journals.last.update_column(:id, 891223)
|
|
end
|
|
end
|
|
|
|
subject do
|
|
submit_email("wp_reply_with_quoted_reply_above.eml")
|
|
end
|
|
end
|
|
|
|
shared_context "with wp create with cc" do
|
|
let(:permissions) { %i[add_work_packages view_work_packages add_work_package_watchers] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let!(:cc_user) do
|
|
create(:user,
|
|
mail: "dlopper@somenet.foo",
|
|
firstname: "D",
|
|
lastname: "Lopper",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let(:submit_options) { { issue: { project: project.identifier } } }
|
|
|
|
subject do
|
|
submit_email("ticket_with_cc.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a reply to a wp mention" do
|
|
let(:permissions) { %i[add_work_package_comments view_work_packages] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "j.doe@openproject.org",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
|
|
let!(:work_package) do
|
|
create(:work_package,
|
|
subject: "Some subject of the bug",
|
|
id: 39733,
|
|
project:) do |wp|
|
|
wp.journals.last.update_column(:id, 99999999)
|
|
end
|
|
end
|
|
|
|
subject do
|
|
submit_email("wp_mention_reply.eml")
|
|
end
|
|
end
|
|
|
|
shared_context "with a reply to a wp mention with attributes" do
|
|
let(:permissions) { %i[add_work_package_comments view_work_packages edit_work_packages work_package_assigned] }
|
|
let(:role) do
|
|
create(:project_role, permissions:)
|
|
end
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "j.doe@openproject.org",
|
|
member_with_roles: { project => role })
|
|
end
|
|
|
|
let!(:work_package) do
|
|
create(:work_package,
|
|
subject: "Some subject of the bug",
|
|
id: 39733,
|
|
project:,
|
|
status: original_status) do |wp|
|
|
wp.journals.last.update_column(:id, 99999999)
|
|
end
|
|
end
|
|
let!(:original_status) do
|
|
create(:default_status)
|
|
end
|
|
let!(:resolved_status) do
|
|
create(:status,
|
|
name: "Resolved") do |status|
|
|
create(:workflow,
|
|
old_status: original_status,
|
|
new_status: status,
|
|
role:,
|
|
type: work_package.type)
|
|
end
|
|
end
|
|
let!(:other_user) do
|
|
create(:user,
|
|
mail: "jsmith@somenet.foo",
|
|
member_with_roles: { project => [role] })
|
|
end
|
|
let!(:float_cf) do
|
|
create(:float_wp_custom_field,
|
|
name: "float field") do |cf|
|
|
project.work_package_custom_fields << cf
|
|
work_package.type.custom_fields << cf
|
|
end
|
|
end
|
|
|
|
subject do
|
|
submit_email("wp_mention_reply_with_attributes.eml")
|
|
end
|
|
end
|
|
|
|
shared_context "with a reply to a message" do
|
|
let(:permissions) { %i[view_messages add_messages] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "j.doe@openproject.org",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
|
|
let!(:message) do
|
|
create(:message,
|
|
id: 70917,
|
|
forum: create(:forum, project:)) do |wp|
|
|
wp.journals.last.update_column(:id, 99999999)
|
|
end
|
|
end
|
|
|
|
subject do
|
|
submit_email("message_reply.eml")
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with attributes" do
|
|
let(:permissions) { %i[add_work_packages assign_versions work_package_assigned] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let!(:feature_type) do
|
|
create(:type,
|
|
name: "Feature request") do |type|
|
|
project.types << type
|
|
end
|
|
end
|
|
let!(:stock_category) do
|
|
project.categories.create(name: "Stock management")
|
|
end
|
|
let!(:urgent_priority) do
|
|
create(:priority_urgent)
|
|
end
|
|
let!(:high_priority) do
|
|
create(:priority_high)
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_with_attributes.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with attributes with additional spaces" do
|
|
let(:permissions) { %i[add_work_packages assign_versions work_package_assigned] }
|
|
let(:role) do
|
|
create(:project_role, permissions:)
|
|
end
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let!(:feature_type) do
|
|
create(:type,
|
|
name: "Feature request") do |type|
|
|
project.types << type
|
|
end
|
|
end
|
|
let!(:stock_category) do
|
|
project.categories.create(name: "Stock management")
|
|
end
|
|
let!(:urgent_priority) do
|
|
create(:priority_urgent)
|
|
end
|
|
let!(:high_priority) do
|
|
create(:priority_high)
|
|
end
|
|
let!(:version) { create(:version, name: "alpha", project:) }
|
|
let!(:original_status) do
|
|
create(:default_status)
|
|
end
|
|
let!(:resolved_status) do
|
|
create(:status,
|
|
name: "Resolved") do |status|
|
|
create(:workflow,
|
|
old_status: original_status,
|
|
new_status: status,
|
|
role:,
|
|
type: feature_type)
|
|
end
|
|
end
|
|
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_with_spaces_between_attribute_and_separator.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with attributes in japanese" do
|
|
let(:permissions) { %i[add_work_packages] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let!(:japanese_type) do
|
|
create(:type,
|
|
name: "開発") do |type|
|
|
project.types << type
|
|
end
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_with_attributes_japanese.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with attachment" do
|
|
# The work package is created first and only then the attachment is added.
|
|
let(:permissions) { %i[add_work_packages add_work_package_attachments] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_with_attachment.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with attachment in apple format" do
|
|
# The work package is created first and only then the attachment is added.
|
|
let(:permissions) { %i[add_work_packages add_work_package_attachments] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_with_attachment_apple.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with a custom field" do
|
|
let(:permissions) { %i[add_work_packages] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let!(:custom_field) do
|
|
create(:string_wp_custom_field, name: "Searchable field") do |cf|
|
|
project.work_package_custom_fields << cf
|
|
project.types.first.custom_fields << cf
|
|
end
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_with_custom_field.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with invalid attributes" do
|
|
let(:permissions) { %i[add_work_packages] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_with_invalid_attributes.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with localized attributes" do
|
|
let(:permissions) { %i[add_work_packages] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
language: "de",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
let!(:feature_type) do
|
|
create(:type,
|
|
name: "Feature request") do |type|
|
|
project.types << type
|
|
end
|
|
end
|
|
let!(:stock_category) do
|
|
project.categories.create(name: "Stock management")
|
|
end
|
|
let!(:urgent_priority) do
|
|
create(:priority_urgent)
|
|
end
|
|
|
|
subject do
|
|
submit_email("wp_with_localized_attributes.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with iso 8859 1 subject" do
|
|
let(:permissions) { %i[add_work_packages] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
language: "de",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_with_iso_8859_1_subject.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with long subject" do
|
|
let(:permissions) { %i[add_work_packages] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
language: "de",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_with_long_subject.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with html only description" do
|
|
let(:permissions) { %i[add_work_packages] }
|
|
let!(:user) do
|
|
create(:user,
|
|
mail: "JSmith@somenet.foo",
|
|
firstname: "John",
|
|
lastname: "Smith",
|
|
language: "de",
|
|
member_with_permissions: { project => permissions })
|
|
end
|
|
let(:submit_options) { {} }
|
|
|
|
subject do
|
|
submit_email("wp_with_html_only_description.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
shared_context "with a new work package with the sender fullname in utf-8" do
|
|
let(:submit_options) { {} }
|
|
|
|
before do
|
|
ProjectRole.non_member.update_attribute :permissions, [:add_work_packages]
|
|
project.update_attribute :public, true
|
|
end
|
|
|
|
subject do
|
|
submit_email("wp_with_utf8_fullname_of_sender.eml", **submit_options)
|
|
end
|
|
end
|
|
|
|
describe "#receive" do
|
|
shared_examples_for "work package created" do
|
|
it "creates the work package" do
|
|
expect(subject)
|
|
.to be_a(WorkPackage)
|
|
|
|
expect(subject)
|
|
.to be_persisted
|
|
end
|
|
end
|
|
|
|
shared_examples_for "journal created" do
|
|
it "creates the journal" do
|
|
expect(subject)
|
|
.to be_a(Journal)
|
|
|
|
expect(subject)
|
|
.to be_persisted
|
|
end
|
|
end
|
|
|
|
context "when sending a mail not as a reply" do
|
|
context "for a given project" do
|
|
let(:type) { project.types.first }
|
|
let!(:status) { create(:status, name: "Resolved", workflow_for_type: type) }
|
|
let!(:version) { create(:version, name: "alpha", project:) }
|
|
|
|
include_context "for wp_on_given_project" do
|
|
let(:submit_options) { { allow_override: "version" } }
|
|
end
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the referenced project" do
|
|
expect(subject.project)
|
|
.to eql(project)
|
|
end
|
|
|
|
it "sets the first type in the project" do
|
|
expect(subject.type)
|
|
.to eql(type)
|
|
end
|
|
|
|
it "sets the subject" do
|
|
expect(subject.subject)
|
|
.to eql("New ticket on a given project")
|
|
end
|
|
|
|
it "sets the sender as the author" do
|
|
expect(subject.author)
|
|
.to eql(user)
|
|
end
|
|
|
|
it "set the description" do
|
|
expect(subject.description)
|
|
.to include("Lorem ipsum dolor sit amet, consectetuer adipiscing elit.")
|
|
end
|
|
|
|
it "sets the start date" do
|
|
expect(subject.start_date.to_s)
|
|
.to eql("2010-01-01")
|
|
end
|
|
|
|
it "sets the due date" do
|
|
expect(subject.due_date.to_s)
|
|
.to eql("2010-12-31")
|
|
end
|
|
|
|
it "sets the accountable" do
|
|
expect(subject.responsible)
|
|
.to eql(user)
|
|
end
|
|
|
|
it "sets the assignee" do
|
|
expect(subject.assigned_to)
|
|
.to eql(user)
|
|
end
|
|
|
|
it "sets the status" do
|
|
expect(subject.status)
|
|
.to eql(status)
|
|
end
|
|
|
|
it "sets the version" do
|
|
expect(subject.version)
|
|
.to eql(version)
|
|
end
|
|
|
|
it "sets the estimated_hours" do
|
|
expect(subject.estimated_hours)
|
|
.to be(2.5)
|
|
end
|
|
|
|
it "sets the done_ratio" do
|
|
expect(subject.done_ratio)
|
|
.to be(30)
|
|
end
|
|
|
|
it "removes keywords" do
|
|
expect(subject.description)
|
|
.not_to match(/^Project:/i)
|
|
|
|
expect(subject.description)
|
|
.not_to match(/^Status:/i)
|
|
|
|
expect(subject.description)
|
|
.not_to match(/^Start Date:/i)
|
|
end
|
|
|
|
it "sends notifications to watching users" do
|
|
# User gets all updates
|
|
user = create(:user,
|
|
member_with_permissions: { project => %i(view_work_packages) },
|
|
notification_settings: [build(:notification_setting, all: true)])
|
|
|
|
expect do
|
|
perform_enqueued_jobs do
|
|
subject
|
|
end
|
|
end.to change(Notification.where(recipient: user), :count).by(1)
|
|
end
|
|
|
|
it "does not send an error reply email" do
|
|
subject # send mail
|
|
|
|
expect(UserMailer).not_to have_received(:incoming_email_error)
|
|
end
|
|
end
|
|
|
|
context "for a given project with a default type" do
|
|
let(:default_type) do
|
|
create(:type, is_default: true) do |t|
|
|
project.types << t
|
|
end
|
|
end
|
|
|
|
include_context "for wp_on_given_project" do
|
|
let(:submit_options) { { issue: { type: default_type.name } } }
|
|
end
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the default type" do
|
|
expect(subject.type.name)
|
|
.to eql(default_type.name)
|
|
end
|
|
end
|
|
|
|
context "for a given project with a locked user" do
|
|
let!(:status) { create(:status, name: "Resolved") }
|
|
|
|
before do
|
|
user.locked!
|
|
end
|
|
|
|
include_context "for wp_on_given_project"
|
|
|
|
it "does not create the work package" do
|
|
expect { subject }
|
|
.not_to change(WorkPackage, :count)
|
|
end
|
|
end
|
|
|
|
context "for a given project with group assignment" do
|
|
include_context "for wp on given project group assignment"
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the accountable to the group" do
|
|
expect(subject.responsible)
|
|
.to eql(group)
|
|
end
|
|
|
|
it "sets the assignee to the group" do
|
|
expect(subject.assigned_to)
|
|
.to eql(group)
|
|
end
|
|
end
|
|
|
|
context "for an email by unknown user" do
|
|
context "with unknown_user: 'create'" do
|
|
it "adds a work_package by create user on public project" do
|
|
ProjectRole.non_member.update_attribute :permissions, [:add_work_packages]
|
|
project.update_attribute :public, true
|
|
expect do
|
|
work_package = submit_email("ticket_by_unknown_user.eml", issue: { project: "onlinestore" }, unknown_user: "create")
|
|
work_package_created(work_package)
|
|
expect(work_package.author).to be_active
|
|
expect(work_package.author.mail).to eq("john.doe@somenet.foo")
|
|
expect(work_package.author.firstname).to eq("John")
|
|
expect(work_package.author.lastname).to eq("Doe")
|
|
|
|
# account information
|
|
perform_enqueued_jobs
|
|
|
|
email = ActionMailer::Base.deliveries.first
|
|
expect(email).not_to be_nil
|
|
expect(email.subject).to eq(I18n.t("mail_subject_register", value: Setting.app_title))
|
|
login = email.body.encoded.match(/\* Username: (\S+)\s?$/)[1]
|
|
password = email.body.encoded.match(/\* Password: (\S+)\s?$/)[1]
|
|
|
|
# Can't log in here since randomly assigned password must be changed
|
|
found_user = User.find_by(login:)
|
|
expect(work_package.author).to eq(found_user)
|
|
expect(found_user).to be_check_password(password)
|
|
end.to change(User, :count).by(1)
|
|
end
|
|
end
|
|
|
|
context "with unknown_user: 'create' and an utf8 encoded fullname" do
|
|
include_context "with a new work package with the sender fullname in utf-8"
|
|
let(:submit_options) { { issue: { project: "onlinestore" }, unknown_user: "create" } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "adds the user with decoded fullname" do
|
|
expect do
|
|
expect(subject.author).to be_active
|
|
expect(subject.author.mail).to eq("foo@example.org")
|
|
expect(subject.author.firstname).to eq((+"\xc3\x84\xc3\xa4").force_encoding("UTF-8"))
|
|
expect(subject.author.lastname).to eq((+"\xc3\x96\xc3\xb6").force_encoding("UTF-8"))
|
|
end.to change(User, :count).by(1)
|
|
end
|
|
end
|
|
|
|
context "with unknown_user: nil (default)" do
|
|
let(:results) { [] }
|
|
|
|
before do
|
|
results << submit_email(
|
|
"ticket_by_unknown_user.eml",
|
|
issue: { project: project.identifier },
|
|
unknown_user: nil
|
|
)
|
|
end
|
|
|
|
it "ignores the email" do
|
|
expect(results).to eq [nil]
|
|
end
|
|
|
|
it "does not respond with an error email" do
|
|
expect(UserMailer).not_to have_received(:incoming_email_error)
|
|
end
|
|
end
|
|
|
|
context "with unknown_user: 'accept' and permission check present" do
|
|
let(:expected) do
|
|
"MailHandler: work_package could not be created by Anonymous due to " \
|
|
'#["Type was attempted to be written but is not writable.", ' \
|
|
'"Project was attempted to be written but is not writable.", ' \
|
|
'"Subject was attempted to be written but is not writable.", ' \
|
|
'"Description was attempted to be written but is not writable.", ' \
|
|
'"may not be accessed."]'
|
|
end
|
|
let(:permission) { nil }
|
|
|
|
subject(:work_package) do
|
|
submit_email(
|
|
"ticket_by_unknown_user.eml",
|
|
issue: { project: project.identifier },
|
|
unknown_user: "accept"
|
|
)
|
|
end
|
|
|
|
before do
|
|
allow(Rails.logger).to receive(:error).with(expected)
|
|
ProjectRole.anonymous.add_permission!(permission) if permission
|
|
end
|
|
|
|
context "with anonymous lacking permissions" do
|
|
before do
|
|
work_package
|
|
end
|
|
|
|
it "rejects the email, and does not save the work package" do
|
|
expect(work_package).to be_new_record
|
|
expect(work_package.errors).not_to be_empty
|
|
end
|
|
|
|
it "logs the error" do
|
|
expect(Rails.logger).to have_received(:error).with(expected)
|
|
end
|
|
|
|
context "with report_incoming_email_errors true (default)" do
|
|
it "responds with an error email" do
|
|
expect(UserMailer).to have_received(:incoming_email_error) do |user, mail, logs|
|
|
expect(user).to eq anno_user
|
|
expect(mail[:subject]).to eq "Ticket by unknown user"
|
|
expect(logs).to eq [expected.sub(/^MailHandler/, "error")]
|
|
end
|
|
end
|
|
end
|
|
|
|
context "with report_incoming_email_errors false", with_settings: { report_incoming_email_errors: false } do
|
|
it "does not respond with an error email" do
|
|
expect(UserMailer).not_to have_received(:incoming_email_error)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "with anonymous having permissions in a public project" do
|
|
let(:permission) { :add_work_packages }
|
|
|
|
before do
|
|
project.update_attribute(:public, true)
|
|
end
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the author to anonymous" do
|
|
expect(work_package.author)
|
|
.to eql User.anonymous
|
|
end
|
|
|
|
it "creates no user" do
|
|
expect { work_package }
|
|
.not_to change(User, :count)
|
|
end
|
|
end
|
|
|
|
context "with anonymous having permissions in a private project" do
|
|
let(:permission) { :add_work_packages }
|
|
|
|
before do
|
|
project.update_attribute(:public, false)
|
|
end
|
|
|
|
it "creates no work package" do
|
|
expect { work_package }
|
|
.not_to change(WorkPackage, :count)
|
|
end
|
|
|
|
it "creates no user" do
|
|
expect { work_package }
|
|
.not_to change(User, :count)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "for unknown_user: 'accept' and no_permission_check" do
|
|
subject(:work_package) do
|
|
submit_email "ticket_by_unknown_user.eml",
|
|
issue: { project: project.identifier },
|
|
unknown_user: "accept",
|
|
no_permission_check: 1
|
|
end
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the author to anonymous" do
|
|
expect(work_package.author).to eq(User.anonymous)
|
|
end
|
|
end
|
|
|
|
context "for unknown_user: 'accept' and without from header" do
|
|
subject(:work_package) do
|
|
ProjectRole.anonymous.add_permission!(:add_work_packages)
|
|
|
|
submit_email "wp_without_from_header.eml",
|
|
issue: { project: project.identifier },
|
|
unknown_user: "accept"
|
|
end
|
|
|
|
it "creates no work package" do
|
|
expect { work_package }
|
|
.not_to change(WorkPackage, :count)
|
|
end
|
|
end
|
|
|
|
context "for unknown_user: 'accept' and without permission checks and without from header" do
|
|
subject(:work_package) do
|
|
submit_email "wp_without_from_header.eml",
|
|
issue: { project: project.identifier },
|
|
unknown_user: "accept",
|
|
no_permission_check: 1
|
|
end
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the author to anonymous" do
|
|
expect(work_package.author).to eq(User.anonymous)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "for email from emission address", with_settings: { mail_from: "openproject@example.net" } do
|
|
before do
|
|
ProjectRole.non_member.add_permission!(:add_work_packages)
|
|
end
|
|
|
|
subject do
|
|
project.update(public: true)
|
|
submit_email("ticket_from_emission_address.eml",
|
|
issue: { project: project.identifier },
|
|
unknown_user: "create")
|
|
end
|
|
|
|
it "returns false" do
|
|
expect(subject).to be_falsey
|
|
end
|
|
|
|
it "does not create the user" do
|
|
expect { subject }
|
|
.not_to(change(User, :count))
|
|
end
|
|
|
|
it "does not create the work_package" do
|
|
expect { subject }
|
|
.not_to(change(WorkPackage, :count))
|
|
end
|
|
|
|
it "does not result in an error email response" do
|
|
subject # send email
|
|
|
|
expect(UserMailer).not_to have_received(:incoming_email_error)
|
|
end
|
|
end
|
|
|
|
context "for wp with status" do
|
|
let(:type) { project.types.first }
|
|
let!(:status) { create(:status, name: "Resolved", workflow_for_type: type) }
|
|
|
|
# This email contains: 'Project: onlinestore' and 'Status: Resolved'
|
|
include_context "for wp_on_given_project"
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "assigns the status to the created work package" do
|
|
expect(subject.status)
|
|
.to eql(status)
|
|
end
|
|
end
|
|
|
|
context "for wp with status case insensitive" do
|
|
let(:type) { project.types.first }
|
|
let!(:status) { create(:status, name: "Resolved", workflow_for_type: type) }
|
|
let!(:version) { create(:version, name: "alpha", project:) }
|
|
|
|
# This email contains: 'Project: onlinestore' and 'Status: resolved'
|
|
include_context "for wp_on_given_project_case_insensitive"
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "assigns the status to the created work package" do
|
|
expect(subject.status).to eq(status)
|
|
expect(subject.version).to eq(version)
|
|
expect(subject.priority).to eq priority_low
|
|
end
|
|
end
|
|
|
|
context "for wp with cc" do
|
|
include_context "with wp create with cc"
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "assigns cc and author as watcher" do
|
|
expect(subject.watcher_users)
|
|
.to contain_exactly(user, cc_user)
|
|
end
|
|
end
|
|
|
|
context "for a wp overriding attributes" do
|
|
include_context "with a new work package with attributes"
|
|
let(:submit_options) { { allow_override: "type,category,priority" } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the provided attributes" do
|
|
expect(subject.project)
|
|
.to eql project
|
|
|
|
expect(subject.type)
|
|
.to eql feature_type
|
|
|
|
expect(subject.category)
|
|
.to eql stock_category
|
|
|
|
expect(subject.priority)
|
|
.to eql urgent_priority
|
|
end
|
|
end
|
|
|
|
context "for a wp overriding attributes partially" do
|
|
include_context "with a new work package with attributes"
|
|
let(:submit_options) { { issue: { priority: "High" }, allow_override: ["type"] } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the provided attributes only to the extend allowed and uses default" do
|
|
expect(subject.project)
|
|
.to eql project
|
|
|
|
expect(subject.type)
|
|
.to eql feature_type
|
|
|
|
expect(subject.category)
|
|
.to be_nil
|
|
|
|
expect(subject.priority)
|
|
.to eql high_priority
|
|
end
|
|
end
|
|
|
|
context "for a wp overriding attributes with spaces between attribute and separator" do
|
|
include_context "with a new work package with attributes with additional spaces"
|
|
let(:submit_options) { { allow_override: "type,category,priority" } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the provided attributes" do
|
|
expect(subject.project)
|
|
.to eql project
|
|
|
|
expect(subject.type)
|
|
.to eql feature_type
|
|
|
|
expect(subject.category)
|
|
.to eql stock_category
|
|
|
|
expect(subject.priority)
|
|
.to eql urgent_priority
|
|
end
|
|
end
|
|
|
|
context "for a wp overriding attributes in japanese" do
|
|
include_context "with a new work package with attributes in japanese"
|
|
let(:submit_options) { { issue: { project: "onlinestore" }, allow_override: "type" } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the provided attributes" do
|
|
expect(subject.type)
|
|
.to eql japanese_type
|
|
end
|
|
end
|
|
|
|
context "for a wp with attachment" do
|
|
include_context "with a new work package with attachment"
|
|
let(:submit_options) { { issue: { project: "onlinestore" } } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "adds the attachment" do
|
|
expect(subject.attachments.count)
|
|
.to be 1
|
|
|
|
expect(subject.attachments.first.filename)
|
|
.to eql "Paella.jpg"
|
|
|
|
expect(subject.attachments.first.content_type)
|
|
.to eql "image/jpeg"
|
|
|
|
expect(subject.attachments.first.filesize)
|
|
.to be 10790
|
|
end
|
|
end
|
|
|
|
context "for a wp with attachment in apple format" do
|
|
include_context "with a new work package with attachment in apple format"
|
|
let(:submit_options) { { issue: { project: "onlinestore" } } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "adds the attachment" do
|
|
expect(subject.attachments.count)
|
|
.to be 1
|
|
|
|
expect(subject.attachments.first.filename)
|
|
.to eql "paella.jpg"
|
|
|
|
expect(subject.attachments.first.content_type)
|
|
.to eql "image/jpeg"
|
|
|
|
expect(subject.attachments.first.filesize)
|
|
.to be 10790
|
|
end
|
|
end
|
|
|
|
context "for a wp with a custom field value" do
|
|
include_context "with a new work package with a custom field"
|
|
let(:submit_options) { { issue: { project: "onlinestore" } } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the custom field value and removes it from the text" do
|
|
expect(subject.custom_value_attributes)
|
|
.to eql(custom_field.id => "Value for a custom field")
|
|
|
|
expect(subject.description)
|
|
.not_to include "searchable field"
|
|
end
|
|
end
|
|
|
|
context "for a wp with invalid attributes" do
|
|
include_context "with a new work package with invalid attributes"
|
|
let(:submit_options) { { issue: { project: "onlinestore" }, allow_override: "type,category,priority" } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "ignores the invalid attributes and set default ones where possible" do
|
|
expect(subject.responsible)
|
|
.to be_nil
|
|
|
|
expect(subject.assigned_to)
|
|
.to be_nil
|
|
|
|
expect(subject.start_date)
|
|
.to be_nil
|
|
|
|
expect(subject.due_date)
|
|
.to be_nil
|
|
|
|
expect(subject.done_ratio)
|
|
.to be_nil
|
|
|
|
expect(subject.priority)
|
|
.to eql priority_low
|
|
end
|
|
end
|
|
|
|
context "for a wp with localized attributes" do
|
|
include_context "with a new work package with localized attributes"
|
|
let(:submit_options) { { allow_override: "type,category,priority" } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the provided attributes" do
|
|
expect(subject.project)
|
|
.to eql project
|
|
|
|
expect(subject.type)
|
|
.to eql feature_type
|
|
|
|
expect(subject.category)
|
|
.to eql stock_category
|
|
|
|
expect(subject.priority)
|
|
.to eql urgent_priority
|
|
end
|
|
end
|
|
|
|
context "for a wp with iso 8859 1 subject" do
|
|
include_context "with a new work package with iso 8859 1 subject"
|
|
let(:submit_options) { { issue: { project: "onlinestore" } } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the subject" do
|
|
expect(subject.subject)
|
|
.to eql "Testmail from Webmail: ä ö ü..."
|
|
end
|
|
end
|
|
|
|
context "for a wp with long subject" do
|
|
include_context "with a new work package with long subject"
|
|
let(:submit_options) { { issue: { project: "onlinestore" } } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the subject" do
|
|
original_subject = <<~MSG.squish
|
|
New ticket on a given project with a very long subject line
|
|
which exceeds 255 chars and should not be ignored but chopped off.
|
|
And if the subject line is still not long enough, we just add more text.
|
|
And more text. Wow, this is really annoying. Especially, if you have nothing to say...
|
|
MSG
|
|
|
|
expect(subject.subject)
|
|
.to eql original_subject[0, 255]
|
|
end
|
|
end
|
|
|
|
context "for a wp with html only description" do
|
|
include_context "with a new work package with html only description"
|
|
let(:submit_options) { { issue: { project: "onlinestore" } } }
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "sets the description" do
|
|
expect(subject.description)
|
|
.to eql "This is a html-only email."
|
|
end
|
|
end
|
|
|
|
context "for a wp with attribute keys" do
|
|
include_context "with a new work package with attributes with additional spaces"
|
|
it_behaves_like "work package created"
|
|
|
|
subject do
|
|
submit_email("wp_with_attribute_keys.eml", allow_override: ["category"])
|
|
end
|
|
|
|
it "sets the description" do
|
|
expect(subject.description).to eq("Some description here")
|
|
expect(subject.subject).to eq("New ticket with full attributes")
|
|
expect(subject.type).to eq(feature_type)
|
|
expect(subject.status).to eq(resolved_status)
|
|
expect(subject.version).to eq(version)
|
|
expect(subject.priority).to eq(urgent_priority)
|
|
expect(subject.assigned_to).to eq(user)
|
|
expect(subject.responsible).to eq(user)
|
|
expect(subject.start_date).to eq(Date.parse("2025-01-01"))
|
|
expect(subject.due_date).to eq(Date.parse("2025-12-31"))
|
|
expect(subject.estimated_hours).to eq(20)
|
|
expect(subject.remaining_hours).to eq(10.5)
|
|
expect(subject.category).to eq(stock_category)
|
|
end
|
|
|
|
context "with the user having a german locale" do
|
|
before do
|
|
user.update!(language: "de")
|
|
end
|
|
|
|
subject do
|
|
submit_email("wp_with_attributes_i18n_de.eml", allow_override: ["category"])
|
|
end
|
|
|
|
it "sets the description" do
|
|
expect(subject.description).to eq("Beschreibung würde hier stehen.")
|
|
expect(subject.subject).to eq("Neues Arbeitspaket")
|
|
expect(subject.type).to eq(feature_type)
|
|
expect(subject.status).to eq(resolved_status)
|
|
expect(subject.version).to eq(version)
|
|
expect(subject.priority).to eq(urgent_priority)
|
|
expect(subject.assigned_to).to eq(user)
|
|
expect(subject.responsible).to eq(user)
|
|
expect(subject.start_date).to eq(Date.parse("2025-01-01"))
|
|
expect(subject.due_date).to eq(Date.parse("2025-12-31"))
|
|
expect(subject.estimated_hours).to eq(20)
|
|
expect(subject.remaining_hours).to eq(10.5)
|
|
expect(subject.category).to eq(stock_category)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when sending a reply to work package mail" do
|
|
let!(:mail_user) { create(:admin, mail: "user@example.org") }
|
|
let!(:work_package) { create(:work_package, project:) }
|
|
|
|
before do
|
|
# Avoid trying to extract text
|
|
allow(OpenProject::Database).to receive(:allows_tsv?).and_return false
|
|
end
|
|
|
|
context "with attachments to be added" do
|
|
it "updates a work package with attachment" do
|
|
allow(WorkPackage).to receive(:find_by).with(id: 123).and_return(work_package)
|
|
|
|
# Mail with two attachments, one of which is skipped by signature.asc filename match
|
|
submit_email "update_ticket_with_attachment_and_sig.eml", issue: { project: "onlinestore" }
|
|
|
|
work_package.reload
|
|
|
|
# Expect comment
|
|
expect(work_package.journals.last.notes).to eq "Reply to work package #123"
|
|
expect(work_package.journals.last.user).to eq mail_user
|
|
|
|
# Expect filename without signature to be saved
|
|
expect(work_package.attachments.count).to eq(1)
|
|
expect(work_package.attachments.first.filename).to eq("Photo25.jpg")
|
|
end
|
|
end
|
|
|
|
context "with existing attachment" do
|
|
let!(:attachment) { create(:attachment, container: work_package) }
|
|
|
|
it "does not replace it (Regression #29722)" do
|
|
work_package.reload
|
|
allow(WorkPackage).to receive(:find_by).with(id: 123).and_return(work_package)
|
|
|
|
# Mail with two attachments, one of which is skipped by signature.asc filename match
|
|
submit_email "update_ticket_with_attachment_and_sig.eml", issue: { project: "onlinestore" }
|
|
|
|
expect(work_package.attachments.length).to eq 2
|
|
end
|
|
end
|
|
|
|
context "with reply text" do
|
|
include_context "with a reply to a wp mention with quotes above"
|
|
|
|
it_behaves_like "journal created"
|
|
|
|
it "sends notifications" do
|
|
assignee = create(:user,
|
|
member_with_permissions: { project => %i(view_work_packages) },
|
|
notification_settings: [build(:notification_setting, assignee: true, responsible: true)])
|
|
|
|
responsible = create(:user,
|
|
member_with_permissions: { project => %i(view_work_packages) },
|
|
notification_settings: [build(:notification_setting, assignee: true, responsible: true)])
|
|
work_package.update_column(:assigned_to_id, assignee.id)
|
|
work_package.update_column(:responsible_id, responsible.id)
|
|
|
|
# Sends notifications for the assignee and the author who is listening for all changes.
|
|
expect do
|
|
perform_enqueued_jobs do
|
|
subject
|
|
end
|
|
end.to change(Notification, :count).by(2)
|
|
end
|
|
end
|
|
|
|
context "when replying to mention mail with only text" do
|
|
include_context "with a reply to a wp mention"
|
|
|
|
it_behaves_like "journal created"
|
|
|
|
it "adds the content to the last journal" do
|
|
subject
|
|
|
|
expect(work_package.journals.reload.last.notes)
|
|
.to include "The text of the reply."
|
|
end
|
|
|
|
it "does not alter any attributes" do
|
|
subject
|
|
|
|
expect(work_package.journals.reload.last.details)
|
|
.to be_empty
|
|
end
|
|
|
|
it "performs the changes in the name of the sender" do
|
|
subject
|
|
|
|
expect(work_package.journals.reload.last.user)
|
|
.to eql user
|
|
end
|
|
end
|
|
|
|
context "when replying to mention mail with text and attributes" do
|
|
include_context "with a reply to a wp mention with attributes"
|
|
|
|
it_behaves_like "journal created"
|
|
|
|
it "adds the content to the last journal" do
|
|
subject
|
|
|
|
expect(work_package.journals.reload.last.notes)
|
|
.to include "The text of the reply."
|
|
end
|
|
|
|
it "alters the attributes" do
|
|
subject
|
|
|
|
expect(work_package.journals.reload.last.details)
|
|
.to eql(
|
|
"due_date" => [nil, Date.parse("Fri, 31 Dec 2010")],
|
|
"status_id" => [original_status.id, resolved_status.id],
|
|
"responsible_id" => [nil, other_user.id],
|
|
"assigned_to_id" => [nil, other_user.id],
|
|
"start_date" => [nil, Date.parse("Fri, 01 Jan 2010")],
|
|
"duration" => [nil, 365],
|
|
"custom_fields_#{float_cf.id}" => [nil, "52.6"]
|
|
)
|
|
end
|
|
|
|
it "performs the changes in the name of the sender" do
|
|
subject
|
|
|
|
expect(work_package.journals.reload.last.user)
|
|
.to eql user
|
|
end
|
|
end
|
|
|
|
context "with a custom field" do
|
|
let(:work_package) { create(:work_package, project:) }
|
|
let(:type) { create(:type) }
|
|
|
|
before do
|
|
type.custom_fields << custom_field
|
|
type.save!
|
|
|
|
allow(work_package).to receive(:available_custom_fields).and_return([custom_field])
|
|
|
|
allow(WorkPackage).to receive(:find_by).with(id: 42).and_return(work_package)
|
|
allow(User).to receive(:find_by_mail).with("h.wurst@openproject.com").and_return(mail_user)
|
|
end
|
|
|
|
context "as type text" do
|
|
let(:custom_field) { create(:text_wp_custom_field, name: "Notes") }
|
|
|
|
before do
|
|
submit_email "wp_reply_with_text_custom_field.eml", issue: { project: project.identifier }
|
|
|
|
work_package.reload
|
|
end
|
|
|
|
it "sets the value" do
|
|
value = work_package.custom_values.where(custom_field_id: custom_field.id).pick(:value)
|
|
|
|
expect(value).to eq "some text" # as given in .eml fixture
|
|
end
|
|
end
|
|
|
|
context "as type list" do
|
|
let(:custom_field) { create(:list_wp_custom_field, name: "Letters", possible_values: %w(A B C)) }
|
|
|
|
before do
|
|
submit_email "wp_reply_with_list_custom_field.eml", issue: { project: project.identifier }
|
|
|
|
work_package.reload
|
|
end
|
|
|
|
it "sets the value" do
|
|
option = CustomOption.where(custom_field_id: custom_field.id, value: "B").first # as given in .eml fixture
|
|
value = work_package.custom_values.where(custom_field_id: custom_field.id).pick(:value)
|
|
|
|
expect(value).to eq option.id.to_s
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when receiving an auto reply" do
|
|
include_context "with a reply to a wp mention with quotes above" do
|
|
[
|
|
"X-Auto-Response-Suppress: OOF",
|
|
"Auto-Submitted: auto-replied",
|
|
"Auto-Submitted: Auto-Replied",
|
|
"Auto-Submitted: auto-generated"
|
|
].each do |header|
|
|
subject do
|
|
raw = File.read(File.join("#{File.dirname(__FILE__)}/../fixtures/mail_handler",
|
|
"wp_reply_with_quoted_reply_above.eml"))
|
|
raw = "#{header}\n#{raw}"
|
|
|
|
described_class.receive(raw)
|
|
end
|
|
|
|
it "does not update the work package" do
|
|
expect { subject }
|
|
.not_to change(Journal, :count)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when sending a reply to a message mail" do
|
|
include_context "with a reply to a message"
|
|
|
|
it "creates a new message in the name of the sender", :aggregate_failures do
|
|
expect(subject)
|
|
.to be_a Message
|
|
|
|
expect(subject.subject)
|
|
.to eql("Response to the original message")
|
|
|
|
expect(subject.content)
|
|
.to include("Test message")
|
|
|
|
expect(subject.author)
|
|
.to eql user
|
|
|
|
expect(subject.forum)
|
|
.to eql message.forum
|
|
|
|
expect(subject.parent)
|
|
.to eql message
|
|
end
|
|
end
|
|
|
|
describe "truncate emails based on the Setting" do
|
|
context "with no setting", with_settings: { mail_handler_body_delimiters: "" } do
|
|
include_context "for wp_on_given_project"
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "adds the entire email into the work_package" do
|
|
expect(subject.description)
|
|
.to include("---")
|
|
|
|
expect(subject.description)
|
|
.to include("This paragraph is after the delimiter")
|
|
end
|
|
end
|
|
|
|
context "with a single string", with_settings: { mail_handler_body_delimiters: "---" } do
|
|
include_context "for wp_on_given_project"
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "truncates the email at the delimiter for the work package" do
|
|
expect(subject.description)
|
|
.to include("This paragraph is before delimiters")
|
|
|
|
expect(subject.description)
|
|
.to include("--- This line starts with a delimiter")
|
|
|
|
expect(subject.description)
|
|
.not_to match(/^---$/)
|
|
|
|
expect(subject.description)
|
|
.not_to include("This paragraph is after the delimiter")
|
|
end
|
|
end
|
|
|
|
context "with a single quoted reply (e.g. reply to a OpenProject email notification)",
|
|
with_settings: { mail_handler_body_delimiters: "--- Reply above. Do not remove this line. ---" } do
|
|
include_context "with a reply to a wp mention with quotes above"
|
|
|
|
it_behaves_like "journal created"
|
|
|
|
it "truncates the email at the delimiter with the quoted reply symbols (>)" do
|
|
expect(subject.notes)
|
|
.to include("An update to the issue by the sender.")
|
|
|
|
expect(subject.notes)
|
|
.not_to match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
|
|
|
|
expect(subject.notes)
|
|
.not_to include("Looks like the JSON api for projects was missed.")
|
|
end
|
|
end
|
|
|
|
context "with multiple strings",
|
|
with_settings: { mail_handler_body_delimiters: "---\nBREAK" } do
|
|
include_context "for wp_on_given_project"
|
|
|
|
it_behaves_like "work package created"
|
|
|
|
it "truncates the email at the first delimiter found (BREAK)" do
|
|
expect(subject.description)
|
|
.to include("This paragraph is before delimiters")
|
|
|
|
expect(subject.description)
|
|
.not_to include("BREAK")
|
|
|
|
expect(subject.description)
|
|
.not_to include("This paragraph is between delimiters")
|
|
|
|
expect(subject.description)
|
|
.not_to match(/^---$/)
|
|
|
|
expect(subject.description)
|
|
.not_to include("This paragraph is after the delimiter")
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "category" do
|
|
let!(:category) { create(:category, project:, name: "Foobar") }
|
|
|
|
it "adds a work_package with category" do
|
|
allow(Setting).to receive(:default_language).and_return("en")
|
|
ProjectRole.non_member.update_attribute :permissions, [:add_work_packages]
|
|
project.update_attribute :public, true
|
|
|
|
work_package = submit_email "ticket_with_category.eml",
|
|
issue: { project: "onlinestore" },
|
|
allow_override: ["category"],
|
|
unknown_user: "create"
|
|
work_package_created(work_package)
|
|
expect(work_package.category).to eq(category)
|
|
end
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def read_email(filename)
|
|
File.read(File.join("#{File.dirname(__FILE__)}/../fixtures/mail_handler", filename))
|
|
end
|
|
|
|
def submit_email(filename, options = {})
|
|
IncomingEmails::MailHandler.receive(read_email(filename), options)
|
|
end
|
|
|
|
def work_package_created(work_package)
|
|
expect(work_package).to be_a(WorkPackage)
|
|
expect(work_package).not_to be_new_record
|
|
work_package.reload
|
|
end
|
|
end
|