Fixed issue #542 - Cant add new articles via Macro.

This commit is contained in:
Martin Edenhofer 2019-11-26 11:40:23 +01:00 committed by Thorsten Eckel
parent 0459023514
commit 8996134214
3 changed files with 138 additions and 53 deletions

View file

@ -766,6 +766,7 @@ class App.TicketZoom extends App.Controller
return return
ticketParams = @formParam(@$('.edit')) ticketParams = @formParam(@$('.edit'))
articleParams = @articleNew.params()
# validate ticket # validate ticket
# we need to use the full ticket because # we need to use the full ticket because
@ -784,6 +785,7 @@ class App.TicketZoom extends App.Controller
App.Ticket.macro( App.Ticket.macro(
macro: macro.perform macro: macro.perform
ticket: ticket ticket: ticket
article: articleParams
callback: callback:
tagAdd: (tag) => tagAdd: (tag) =>
return if !@sidebarWidget return if !@sidebarWidget
@ -832,7 +834,6 @@ class App.TicketZoom extends App.Controller
@autosaveStart() @autosaveStart()
return return
articleParams = @articleNew.params()
if articleParams && articleParams.body if articleParams && articleParams.body
article = new App.TicketArticle article = new App.TicketArticle
article.load(articleParams) article.load(articleParams)

View file

@ -114,6 +114,8 @@ class App.Ticket extends App.Model
@macro: (params) -> @macro: (params) ->
for key, content of params.macro for key, content of params.macro
attributes = key.split('.') attributes = key.split('.')
# apply ticket changes
if attributes[0] is 'ticket' if attributes[0] is 'ticket'
# apply tag changes # apply tag changes
@ -142,6 +144,25 @@ class App.Ticket extends App.Model
else else
params.ticket[attributes[1]] = content.value params.ticket[attributes[1]] = content.value
# apply article changes
else if attributes[0] is 'article'
# preload required attributes
if attributes[1]
type = App.TicketArticleType.findByAttribute('name', attributes[1])
if type
params.article.type_id = type.id
if !content.sender_id
sender = App.TicketArticleSender.findByAttribute('name', 'Agent')
if sender
content.sender_id = sender.id
if !content.from
content.from = App.Session.get('login')
# apply direct value changes
for articleKey, aricleValue of content
params.article[articleKey] = aricleValue
# check if selector is matching # check if selector is matching
@selector: (ticket, selector) -> @selector: (ticket, selector) ->
return true if _.isEmpty(selector) return true if _.isEmpty(selector)

View file

@ -6,12 +6,13 @@ require 'system/examples/macros_examples'
RSpec.describe 'Ticket Update', type: :system do RSpec.describe 'Ticket Update', type: :system do
let(:group) { Group.find_by(name: 'Users') } let(:group) { Group.find_by(name: 'Users') }
let(:ticket) { create(:ticket, group: group) }
# Regression test for issue #2242 - mandatory fields can be empty (or "-") on ticket update # Regression test for issue #2242 - mandatory fields can be empty (or "-") on ticket update
context 'when updating a ticket without its required select attributes' do context 'when updating a ticket without its required select attributes' do
it 'frontend checks reject the update', db_strategy: :reset do it 'frontend checks reject the update', db_strategy: :reset do
# setup and migrate a required select attribute # setup and migrate a required select attribute
attribute = create_attribute :object_manager_attribute_select, attribute = create_attribute(:object_manager_attribute_select,
screens: attributes_for(:required_screen), screens: attributes_for(:required_screen),
data_option: { data_option: {
options: { options: {
@ -23,15 +24,14 @@ RSpec.describe 'Ticket Update', type: :system do
relation: '', relation: '',
maxlength: 255, maxlength: 255,
nulloption: true, nulloption: true,
} })
# create a new ticket and attempt to update its state without the required select attribute # create a new ticket and attempt to update its state without the required select attribute
ticket = create :ticket, group: group
visit "#ticket/zoom/#{ticket.id}" visit "#ticket/zoom/#{ticket.id}"
within(:active_content) do within(:active_content) do
expect(page).to have_css('.js-objectNumber', wait: 2) expect(page).to have_selector('.js-objectNumber', text: ticket.number)
select 'closed', from: 'state_id' select('closed', from: 'state_id')
click('.js-attributeBar .js-submit') click('.js-attributeBar .js-submit')
expect(page).to have_no_css('.js-submitDropdown .js-submit[disabled]', wait: 2) expect(page).to have_no_css('.js-submitDropdown .js-submit[disabled]', wait: 2)
end end
@ -50,60 +50,123 @@ RSpec.describe 'Ticket Update', type: :system do
expect(ticket[attribute.name]).to eq('name 2') expect(ticket[attribute.name]).to eq('name 2')
expect(ticket.state.name).to eq('closed') expect(ticket.state.name).to eq('closed')
end end
end
it 'with macro and required tree_select field', db_strategy: :reset do context 'when updating a ticket with macro' do
# setup and migrate a required select attribute context 'when required tree_select field is present' do
attribute = create_attribute :object_manager_attribute_tree_select, it 'performs no validation (#2492)', db_strategy: :reset do
screens: attributes_for(:required_screen), # setup and migrate a required select attribute
data_option: { attribute = create_attribute(:object_manager_attribute_tree_select,
options: [ screens: attributes_for(:required_screen),
{ data_option: {
name: 'name 1', options: [
value: 'name 1', {
}, name: 'name 1',
{ value: 'name 1',
name: 'name 2', },
value: 'name 2', {
}, name: 'name 2',
], value: 'name 2',
default: '', },
null: false, ],
relation: '', default: '',
maxlength: 255, null: false,
nulloption: true, relation: '',
} maxlength: 255,
nulloption: true,
})
attribute_value = 'name 2' attribute_value = 'name 2'
state = Ticket::State.by_category(:closed).first state = Ticket::State.by_category(:closed).first
macro = create(:macro, macro = create(:macro,
perform: { perform: {
'ticket.state_id' => { 'ticket.state_id' => {
value: state.id, value: state.id,
},
"ticket.#{attribute.name}" => {
value: attribute_value,
},
}, },
"ticket.#{attribute.name}" => { ux_flow_next_up: 'none',)
value: attribute_value,
},
})
# refresh browser to get macro accessible # refresh browser to get macro accessible
refresh refresh
# create a new ticket and attempt to update its state without the required select attribute # create a new ticket and attempt to update its state without the required select attribute
ticket = create(:ticket, group: group) visit "#ticket/zoom/#{ticket.id}"
visit "#ticket/zoom/#{ticket.id}"
within(:active_content) do within(:active_content) do
expect(page).to have_css('.js-objectNumber', wait: 2) expect(page).to have_selector('.js-objectNumber', text: ticket.number)
click('.js-openDropdownMacro') expect(page).to have_field(attribute.name, with: '', visible: false)
click(".js-dropdownActionMacro[data-id=\"#{macro.id}\"]") expect(page).to have_select('state_id',
expect(page).not_to have_css('.js-submitDropdown .js-submit[disabled]', wait: 2) selected: 'new',
options: ['new', 'closed', 'open', 'pending close', 'pending reminder'])
click('.js-openDropdownMacro')
click(".js-dropdownActionMacro[data-id=\"#{macro.id}\"]")
expect(page).not_to have_css('.js-submitDropdown .js-submit[disabled]', wait: 2)
end
expect(page).to have_field(attribute.name, with: attribute_value, visible: false)
expect(page).to have_select('state_id',
selected: 'closed',
options: ['closed', 'open', 'pending close', 'pending reminder'])
# the update should not have failed and thus the ticket is in closed state
ticket.reload
expect(ticket[attribute.name]).to eq(attribute_value)
expect(ticket.state.name).to eq(state.name)
end end
end
# the update should not have failed and thus the ticket is in closed state context 'when macro has article configured' do
ticket.reload it 'creates an article with the configured attributes' do
expect(ticket[attribute.name]).to eq(attribute_value) state = Ticket::State.find_by(name: 'closed')
expect(ticket.state.name).to eq(state.name) macro = create(:macro,
perform: {
'ticket.state_id' => {
value: state.id,
},
'article.note' => {
'body' => 'test body',
'internal' => 'true',
'subject' => 'test sub'
},
},
ux_flow_next_up: 'none',)
# refresh browser to get macro accessible
refresh
# create a new ticket and attempt to update its state without the required select attribute
visit "#ticket/zoom/#{ticket.id}"
within(:active_content) do
expect(page).to have_selector('.js-objectNumber', text: ticket.number)
expect(page).to have_select('state_id',
selected: 'new',
options: ['new', 'closed', 'open', 'pending close', 'pending reminder'])
click('.js-openDropdownMacro')
click(".js-dropdownActionMacro[data-id=\"#{macro.id}\"]")
expect(page).not_to have_css('.js-submitDropdown .js-submit[disabled]', wait: 2)
end
expect(page).to have_selector('.content.active .article-content', text: 'test body')
expect(page).to have_select('state_id',
selected: 'closed',
options: ['closed', 'open', 'pending close', 'pending reminder'])
# the update should not have failed and thus the ticket is in closed state
ticket.reload
expect(ticket.state.name).to eq(state.name)
article = ticket.articles.last
expect(article).to be_present
expect(article.body).to eq('test body')
expect(article.subject).to eq('test sub')
expect(article.internal).to eq(true)
end
end end
end end
@ -140,10 +203,10 @@ RSpec.describe 'Ticket Update', type: :system do
end end
context 'when using text modules' do context 'when using text modules' do
include_examples 'text modules', path: "#ticket/zoom/#{Ticket.first.id}" include_examples 'text modules', path: "#ticket/zoom/#{Ticket.first.id}"
end end
context 'when using macros' do context 'when using macros' do
include_examples 'macros', path: "#ticket/zoom/#{Ticket.first.id}" include_examples 'macros', path: "#ticket/zoom/#{Ticket.first.id}"
end end
end end