Fixes #2485: Add attachment via Trigger and scheduler if wanted by admin
This commit is contained in:
parent
0b394f6baf
commit
cc2c5678f0
8 changed files with 308 additions and 21 deletions
|
@ -455,7 +455,17 @@ class App.UiElement.ticket_perform_action
|
|||
translate: true
|
||||
)
|
||||
|
||||
includeAttachmentsCheckbox = App.UiElement.select.render(
|
||||
name: "#{name}::include_attachments"
|
||||
multiple: false
|
||||
null: false
|
||||
options: { true: 'Yes', false: 'No' }
|
||||
value: meta.include_attachments || 'false'
|
||||
translate: true
|
||||
)
|
||||
|
||||
notificationElement.find('.js-internal').html(visibilitySelection)
|
||||
notificationElement.find('.js-include_attachments').html(includeAttachmentsCheckbox)
|
||||
|
||||
notificationElement.find('.js-body div[contenteditable="true"]').ce(
|
||||
mode: 'richtext'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="<%= @attribute.class %> checkbox checkbox--list">
|
||||
<% for row in @attribute.options: %>
|
||||
<label class="checkbox-replacement<%= ' is-disabled' if row.disabled %>">
|
||||
<label class="checkbox-replacement<%= ' is-disabled' if row.disabled %> <%= row.class %>">
|
||||
<input type="checkbox" value="<%= row.value %>" name="<%= @attribute.name %>" <%= row.checked %> <%= row.disabled %> <% if @attribute.disabled: %> disabled<% end %>>
|
||||
<%- @Icon('checkbox', 'icon-unchecked') %>
|
||||
<%- @Icon('checkbox-checked', 'icon-checked') %>
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
</div>
|
||||
<div class="controls js-subject"><input type="text" name="<%= @name %>::subject" value="<%= @meta.subject %>" style="width: 100%;" placeholder="<%- @T('Subject') %>" class="form-control"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="formGroup-label">
|
||||
<label><%- @T('Include attachments of the article?') %></label>
|
||||
</div>
|
||||
<div class="js-include_attachments"></div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="form-group">
|
||||
<div class="formGroup-label">
|
||||
|
|
|
@ -1755,6 +1755,11 @@ result
|
|||
end
|
||||
|
||||
original_article = objects[:article]
|
||||
|
||||
if ActiveModel::Type::Boolean.new.cast(value['include_attachments']) == true && original_article&.attachments.present?
|
||||
original_article.clone_attachments('Ticket::Article', message.id, only_attached_attachments: true)
|
||||
end
|
||||
|
||||
if original_article&.should_clone_inline_attachments? # rubocop:disable Style/GuardClause
|
||||
original_article.clone_attachments('Ticket::Article', message.id, only_inline_attachments: true)
|
||||
original_article.should_clone_inline_attachments = false # cancel the temporary flag after cloning
|
||||
|
|
|
@ -413,7 +413,8 @@ test('form checks', function() {
|
|||
recipient: 'ticket_customer',
|
||||
subject: 'some subject',
|
||||
body: "some<br>\nbody",
|
||||
internal: 'false'
|
||||
internal: 'false',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -486,7 +487,8 @@ test('form checks', function() {
|
|||
recipient: 'ticket_customer',
|
||||
subject: 'some subject',
|
||||
body: "some<br>\nbody",
|
||||
internal: 'false'
|
||||
internal: 'false',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -548,6 +550,7 @@ test('form checks', function() {
|
|||
subject: 'some subject',
|
||||
body: "some<br>\nbody",
|
||||
internal: 'false',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -660,7 +663,8 @@ test('form checks', function() {
|
|||
recipient: 'ticket_owner',
|
||||
subject: 'some subject',
|
||||
body: 'lala',
|
||||
internal: 'false'
|
||||
internal: 'false',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -681,7 +685,8 @@ test('form checks', function() {
|
|||
recipient: 'ticket_customer',
|
||||
subject: 'some subject',
|
||||
body: "some<br>\nbody",
|
||||
internal: 'false'
|
||||
internal: 'false',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -711,6 +716,7 @@ test('form checks', function() {
|
|||
subject: 'some subject',
|
||||
body: "some<br>\nbody",
|
||||
internal: 'false',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -730,7 +736,8 @@ test('form checks', function() {
|
|||
recipient: 'ticket_customer',
|
||||
subject: 'some subject',
|
||||
body: "some<br>\nbody",
|
||||
internal: 'false'
|
||||
internal: 'false',
|
||||
include_attachments: 'true',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -758,7 +765,8 @@ test('form checks', function() {
|
|||
recipient: 'ticket_customer',
|
||||
subject: 'some subject',
|
||||
body: "some<br>\nbody",
|
||||
internal: 'false'
|
||||
internal: 'false',
|
||||
include_attachments: 'true',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -51,7 +51,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'false',
|
||||
recipient: ['ticket_owner', 'ticket_customer'],
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
},
|
||||
ticket_perform_action3: {
|
||||
|
@ -103,7 +104,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'false',
|
||||
recipient: ['ticket_owner', 'ticket_customer'],
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
'ticket.priority_id': {
|
||||
value: '2'
|
||||
|
@ -139,7 +141,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'false',
|
||||
recipient: ['ticket_owner', 'ticket_customer'],
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
'ticket.priority_id': {
|
||||
value: '2'
|
||||
|
@ -153,7 +156,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'false',
|
||||
recipient: 'ticket_owner',
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
'ticket.state_id': {
|
||||
value: '3'
|
||||
|
@ -177,7 +181,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'false',
|
||||
recipient: 'ticket_customer',
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
'ticket.priority_id': {
|
||||
value: '2'
|
||||
|
@ -191,7 +196,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'false',
|
||||
recipient: 'ticket_owner',
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
'ticket.state_id': {
|
||||
value: '3'
|
||||
|
@ -215,7 +221,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'true',
|
||||
recipient: 'ticket_customer',
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
'ticket.priority_id': {
|
||||
value: '2'
|
||||
|
@ -229,7 +236,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'false',
|
||||
recipient: 'ticket_owner',
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
'ticket.state_id': {
|
||||
value: '3'
|
||||
|
@ -262,7 +270,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'true',
|
||||
recipient: 'ticket_customer',
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
'ticket.priority_id': {
|
||||
value: '2'
|
||||
|
@ -276,7 +285,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'false',
|
||||
recipient: 'ticket_owner',
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
'ticket.pending_time': {
|
||||
operator: 'static',
|
||||
|
@ -314,7 +324,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'true',
|
||||
recipient: 'ticket_customer',
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
'ticket.priority_id': {
|
||||
value: '2'
|
||||
|
@ -328,7 +339,8 @@ test( "ticket_perform_action check", function(assert) {
|
|||
body: 'some body',
|
||||
internal: 'false',
|
||||
recipient: 'ticket_owner',
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'false',
|
||||
},
|
||||
'ticket.pending_time': {
|
||||
operator: 'relative',
|
||||
|
@ -354,7 +366,8 @@ test( "ticket_perform_action backwards check after issue #2782", function() {
|
|||
'notification.email': {
|
||||
body: 'some body',
|
||||
recipient: ['ticket_owner', 'ticket_customer'],
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'true',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -382,7 +395,8 @@ test( "ticket_perform_action backwards check after issue #2782", function() {
|
|||
body: 'some body',
|
||||
internal: 'false',
|
||||
recipient: ['ticket_owner', 'ticket_customer'],
|
||||
subject: 'some subject'
|
||||
subject: 'some subject',
|
||||
include_attachments: 'true',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -520,6 +520,117 @@ RSpec.describe Ticket, type: :model do
|
|||
include_examples 'verify log visibility status'
|
||||
end
|
||||
|
||||
shared_examples 'add a new article' do
|
||||
it 'adds a new article' do
|
||||
expect { ticket.perform_changes(performable, 'trigger', ticket, user) }
|
||||
.to change { ticket.articles.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'add attachment to new article' do
|
||||
include_examples 'add a new article'
|
||||
|
||||
it 'adds attachment to the new article' do
|
||||
ticket.perform_changes(performable, 'trigger', ticket, user)
|
||||
article = ticket.articles.last
|
||||
|
||||
expect(article.type.name).to eq('email')
|
||||
expect(article.sender.name).to eq('System')
|
||||
expect(article.attachments.count).to eq(1)
|
||||
expect(article.attachments[0].filename).to eq('some_file.pdf')
|
||||
expect(article.attachments[0].preferences['Content-ID']).to eq('image/pdf@01CAB192.K8H512Y9')
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'does not add attachment to new article' do
|
||||
include_examples 'add a new article'
|
||||
|
||||
it 'does not add attachment to the new article' do
|
||||
ticket.perform_changes(performable, 'trigger', ticket, user)
|
||||
article = ticket.articles.last
|
||||
|
||||
expect(article.type.name).to eq('email')
|
||||
expect(article.sender.name).to eq('System')
|
||||
expect(article.attachments.count).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'dispatching email with include attachment present' do
|
||||
let(:notification_type) { :email }
|
||||
let(:additional_options) do
|
||||
{
|
||||
notification_key => {
|
||||
include_attachments: 'true'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
context 'when ticket has an attachment' do
|
||||
|
||||
before do
|
||||
UserInfo.current_user_id = 1
|
||||
ticket_article = create(:ticket_article, ticket: ticket)
|
||||
|
||||
Store.add(
|
||||
object: 'Ticket::Article',
|
||||
o_id: ticket_article.id,
|
||||
data: 'dGVzdCAxMjM=',
|
||||
filename: 'some_file.pdf',
|
||||
preferences: {
|
||||
'Content-Type': 'image/pdf',
|
||||
'Content-ID': 'image/pdf@01CAB192.K8H512Y9',
|
||||
},
|
||||
created_by_id: 1,
|
||||
)
|
||||
end
|
||||
|
||||
include_examples 'add attachment to new article'
|
||||
end
|
||||
|
||||
context 'when ticket does not have an attachment' do
|
||||
|
||||
include_examples 'does not add attachment to new article'
|
||||
end
|
||||
end
|
||||
|
||||
context 'dispatching email with include attachment not present' do
|
||||
let(:notification_type) { :email }
|
||||
let(:additional_options) do
|
||||
{
|
||||
notification_key => {
|
||||
include_attachments: 'false'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
context 'when ticket has an attachment' do
|
||||
|
||||
before do
|
||||
UserInfo.current_user_id = 1
|
||||
ticket_article = create(:ticket_article, ticket: ticket)
|
||||
|
||||
Store.add(
|
||||
object: 'Ticket::Article',
|
||||
o_id: ticket_article.id,
|
||||
data: 'dGVzdCAxMjM=',
|
||||
filename: 'some_file.pdf',
|
||||
preferences: {
|
||||
'Content-Type': 'image/pdf',
|
||||
'Content-ID': 'image/pdf@01CAB192.K8H512Y9',
|
||||
},
|
||||
created_by_id: 1,
|
||||
)
|
||||
end
|
||||
|
||||
include_examples 'does not add attachment to new article'
|
||||
end
|
||||
|
||||
context 'when ticket does not have an attachment' do
|
||||
|
||||
include_examples 'does not add attachment to new article'
|
||||
end
|
||||
end
|
||||
|
||||
context 'dispatching SMS' do
|
||||
let(:notification_type) { :sms }
|
||||
|
||||
|
|
|
@ -55,6 +55,135 @@ RSpec.describe Trigger, type: :model do
|
|||
}
|
||||
end
|
||||
|
||||
shared_examples 'include ticket attachment' do
|
||||
context 'notification.email include_attachments' do
|
||||
let(:perform) do
|
||||
{
|
||||
'notification.email' => {
|
||||
'recipient' => 'ticket_customer',
|
||||
'subject' => 'Example subject',
|
||||
'body' => 'Example body',
|
||||
}
|
||||
}.deep_merge(additional_options).deep_stringify_keys
|
||||
end
|
||||
|
||||
let(:ticket) { create(:ticket) }
|
||||
|
||||
shared_examples 'add a new article' do
|
||||
it 'adds a new article' do
|
||||
expect { TransactionDispatcher.commit }
|
||||
.to change(ticket.articles, :count).by(1)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'add attachment to new article' do
|
||||
include_examples 'add a new article'
|
||||
|
||||
it 'adds attachment to the new article' do
|
||||
ticket && trigger
|
||||
|
||||
TransactionDispatcher.commit
|
||||
article = ticket.articles.last
|
||||
|
||||
expect(article.type.name).to eq('email')
|
||||
expect(article.sender.name).to eq('System')
|
||||
expect(article.attachments.count).to eq(1)
|
||||
expect(article.attachments[0].filename).to eq('some_file.pdf')
|
||||
expect(article.attachments[0].preferences['Content-ID']).to eq('image/pdf@01CAB192.K8H512Y9')
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'does not add attachment to new article' do
|
||||
include_examples 'add a new article'
|
||||
|
||||
it 'does not add attachment to the new article' do
|
||||
ticket && trigger
|
||||
|
||||
TransactionDispatcher.commit
|
||||
article = ticket.articles.last
|
||||
|
||||
expect(article.type.name).to eq('email')
|
||||
expect(article.sender.name).to eq('System')
|
||||
expect(article.attachments.count).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with include attachment present' do
|
||||
let(:additional_options) do
|
||||
{
|
||||
'notification.email' => {
|
||||
include_attachments: 'true'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
context 'when ticket has an attachment' do
|
||||
|
||||
before do
|
||||
UserInfo.current_user_id = 1
|
||||
ticket_article = create(:ticket_article, ticket: ticket)
|
||||
|
||||
Store.add(
|
||||
object: 'Ticket::Article',
|
||||
o_id: ticket_article.id,
|
||||
data: 'dGVzdCAxMjM=',
|
||||
filename: 'some_file.pdf',
|
||||
preferences: {
|
||||
'Content-Type': 'image/pdf',
|
||||
'Content-ID': 'image/pdf@01CAB192.K8H512Y9',
|
||||
},
|
||||
created_by_id: 1,
|
||||
)
|
||||
end
|
||||
|
||||
include_examples 'add attachment to new article'
|
||||
end
|
||||
|
||||
context 'when ticket does not have an attachment' do
|
||||
|
||||
include_examples 'does not add attachment to new article'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with include attachment not present' do
|
||||
let(:additional_options) do
|
||||
{
|
||||
'notification.email' => {
|
||||
include_attachments: 'false'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
context 'when ticket has an attachment' do
|
||||
|
||||
before do
|
||||
UserInfo.current_user_id = 1
|
||||
ticket_article = create(:ticket_article, ticket: ticket)
|
||||
|
||||
Store.add(
|
||||
object: 'Ticket::Article',
|
||||
o_id: ticket_article.id,
|
||||
data: 'dGVzdCAxMjM=',
|
||||
filename: 'some_file.pdf',
|
||||
preferences: {
|
||||
'Content-Type': 'image/pdf',
|
||||
'Content-ID': 'image/pdf@01CAB192.K8H512Y9',
|
||||
},
|
||||
created_by_id: 1,
|
||||
)
|
||||
end
|
||||
|
||||
include_examples 'does not add attachment to new article'
|
||||
end
|
||||
|
||||
context 'when ticket does not have an attachment' do
|
||||
|
||||
include_examples 'does not add attachment to new article'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'for condition "ticket created"' do
|
||||
let(:condition) do
|
||||
{ 'ticket.action' => { 'operator' => 'is', 'value' => 'create' } }
|
||||
|
@ -417,6 +546,8 @@ RSpec.describe Trigger, type: :model do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
include_examples 'include ticket attachment'
|
||||
end
|
||||
|
||||
context 'for condition "ticket updated"' do
|
||||
|
@ -575,6 +706,8 @@ RSpec.describe Trigger, type: :model do
|
|||
expect(Ticket::Article.where(ticket: ticket).last.to).not_to eq(system_address.email)
|
||||
end
|
||||
end
|
||||
|
||||
include_examples 'include ticket attachment'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue