Fixed issue #542 - Cant add new articles via Macro.
This commit is contained in:
parent
0459023514
commit
8996134214
3 changed files with 138 additions and 53 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue