Fixes #4064 - Freshdesk import currently doesn't handle the ticket type field.

This commit is contained in:
Dominik Klein 2022-04-25 12:55:32 +02:00
parent 43aa552d8c
commit 2cc110fd42
10 changed files with 129 additions and 71 deletions

View file

@ -17,7 +17,7 @@ class Sequencer
state.provide(:config) do state.provide(:config) do
{ {
object: model_class.to_s, object: model_class.to_s,
name: sanitized_name, name: DEFAULT_FIELD_NAME_MAP[resource['name']] || sanitized_name,
display: resource['label'], display: resource['label'],
data_type: data_type, data_type: data_type,
data_option: data_option, data_option: data_option,
@ -43,6 +43,11 @@ class Sequencer
'custom_decimal' => 'input', # Don't use 'integer' as it would cut off the fractional part. 'custom_decimal' => 'input', # Don't use 'integer' as it would cut off the fractional part.
'custom_url' => 'input', 'custom_url' => 'input',
'custom_phone_number' => 'input', 'custom_phone_number' => 'input',
'default_ticket_type' => 'select',
}.freeze
DEFAULT_FIELD_NAME_MAP = {
'ticket_type' => 'type',
}.freeze }.freeze
def data_type def data_type

View file

@ -15,7 +15,6 @@ class Sequencer
private private
def unsanitized_name def unsanitized_name
# active_customer
resource['name'] resource['name']
end end
end end

View file

@ -11,10 +11,16 @@ class Sequencer
provides :action provides :action
def process def process
return if !resource['default'] return if !resource['default'] || allowed_default_attributes.include?(resource['name'])
state.provide(:action, :skipped) state.provide(:action, :skipped)
end end
private
def allowed_default_attributes
@allowed_default_attributes ||= %w[ticket_type]
end
end end
end end
end end

View file

@ -40,6 +40,7 @@ class Sequencer
state_id: state_map[resource['status']], state_id: state_map[resource['status']],
owner_id: owner_id, owner_id: owner_id,
customer_id: customer_id, customer_id: customer_id,
type: resource['type'],
created_at: resource['created_at'], created_at: resource['created_at'],
updated_at: resource['updated_at'], updated_at: resource['updated_at'],
} }

View file

@ -115,38 +115,36 @@ RSpec.describe ExternalCredential::Google do
channel = described_class.link_account(request_token, authorization_payload) channel = described_class.link_account(request_token, authorization_payload)
expect(channel.options).to match( expect(channel.options).to include(
a_hash_including( 'inbound' => include(
'inbound' => a_hash_including( 'options' => include(
'options' => a_hash_including( 'auth_type' => 'XOAUTH2',
'auth_type' => 'XOAUTH2', 'host' => 'imap.gmail.com',
'host' => 'imap.gmail.com', 'ssl' => 'ssl',
'ssl' => 'ssl', 'user' => primary_email,
'user' => primary_email, )
) ),
), 'outbound' => include(
'outbound' => a_hash_including( 'options' => include(
'options' => a_hash_including( 'authentication' => 'xoauth2',
'authentication' => 'xoauth2', 'host' => 'smtp.gmail.com',
'host' => 'smtp.gmail.com', 'port' => 465,
'port' => 465, 'ssl' => true,
'ssl' => true, 'user' => primary_email,
'user' => primary_email, )
) ),
), 'auth' => include(
'auth' => a_hash_including( 'access_token' => access_token,
'access_token' => access_token, 'expires_in' => token_ttl,
'expires_in' => token_ttl, 'refresh_token' => refresh_token,
'refresh_token' => refresh_token, 'scope' => scope_stub,
'scope' => scope_stub, 'token_type' => 'Bearer',
'token_type' => 'Bearer', 'id_token' => id_token,
'id_token' => id_token, 'created_at' => Time.zone.now,
'created_at' => Time.zone.now, 'type' => 'XOAUTH2',
'type' => 'XOAUTH2', 'client_id' => client_id,
'client_id' => client_id, 'client_secret' => client_secret,
'client_secret' => client_secret, ),
),
)
) )
end end
end end
@ -267,7 +265,7 @@ RSpec.describe ExternalCredential::Google do
it 'refreshes token' do it 'refreshes token' do
expect do expect do
channel.refresh_xoauth2! channel.refresh_xoauth2!
end.to change { channel.options['auth'] }.to a_hash_including( end.to change { channel.options['auth'] }.to include(
'created_at' => Time.zone.now, 'created_at' => Time.zone.now,
'access_token' => refreshed_access_token, 'access_token' => refreshed_access_token,
) )

View file

@ -81,37 +81,35 @@ RSpec.describe ExternalCredential::Microsoft365 do
channel = described_class.link_account(request_token, authorization_payload) channel = described_class.link_account(request_token, authorization_payload)
expect(channel.options).to match( expect(channel.options).to include(
a_hash_including( 'inbound' => include(
'inbound' => a_hash_including( 'options' => include(
'options' => a_hash_including( 'auth_type' => 'XOAUTH2',
'auth_type' => 'XOAUTH2', 'host' => 'outlook.office365.com',
'host' => 'outlook.office365.com', 'ssl' => 'ssl',
'ssl' => 'ssl', 'user' => email_address,
'user' => email_address, )
) ),
), 'outbound' => include(
'outbound' => a_hash_including( 'options' => include(
'options' => a_hash_including( 'authentication' => 'xoauth2',
'authentication' => 'xoauth2', 'host' => 'smtp.office365.com',
'host' => 'smtp.office365.com', 'port' => 587,
'port' => 587, 'user' => email_address,
'user' => email_address, )
) ),
), 'auth' => include(
'auth' => a_hash_including( 'access_token' => access_token,
'access_token' => access_token, 'expires_in' => token_ttl,
'expires_in' => token_ttl, 'refresh_token' => refresh_token,
'refresh_token' => refresh_token, 'scope' => scope_stub,
'scope' => scope_stub, 'token_type' => 'Bearer',
'token_type' => 'Bearer', 'id_token' => id_token,
'id_token' => id_token, 'created_at' => Time.zone.now,
'created_at' => Time.zone.now, 'type' => 'XOAUTH2',
'type' => 'XOAUTH2', 'client_id' => client_id,
'client_id' => client_id, 'client_secret' => client_secret,
'client_secret' => client_secret, ),
),
)
) )
end end
end end
@ -231,7 +229,7 @@ RSpec.describe ExternalCredential::Microsoft365 do
it 'refreshes token' do it 'refreshes token' do
expect do expect do
channel.refresh_xoauth2! channel.refresh_xoauth2!
end.to change { channel.options['auth'] }.to a_hash_including( end.to change { channel.options['auth'] }.to include(
'created_at' => Time.zone.now, 'created_at' => Time.zone.now,
'access_token' => refreshed_access_token, 'access_token' => refreshed_access_token,
) )

View file

@ -194,5 +194,37 @@ RSpec.describe ::Sequencer::Sequence::Import::Freshdesk::TicketField, sequencer:
expect { process(process_payload) }.to raise_error(RuntimeError, "The custom field type 'custom_unknown' cannot be mapped to an internal field, aborting.") expect { process(process_payload) }.to raise_error(RuntimeError, "The custom field type 'custom_unknown' cannot be mapped to an internal field, aborting.")
end end
end end
context 'when importing default fields' do
let(:resource) do
base_resource.merge(
{
'name' => 'ticket_type',
'label' => 'Type',
'type' => 'default_ticket_type',
'default' => true,
'choices' => [
'Question',
'Incident',
'Problem',
'Feature Request',
'Refunds and Returns',
'Bulk orders',
'Refund',
'Request',
]
}
)
end
it "activate the already existing ticket 'type' field" do
expect { process(process_payload) }.to change { ObjectManager::Attribute.get(object: 'Ticket', name: 'type').active }.from(false).to(true)
end
it "import the fixed option list for the ticket 'type' field" do
process(process_payload)
expect(ObjectManager::Attribute.get(object: 'Ticket', name: 'type').data_option[:options]).to include(resource['choices'].to_h { |choice| [choice, choice] })
end
end
end end
end end

View file

@ -29,7 +29,7 @@ RSpec.describe ::Sequencer::Sequence::Import::Freshdesk::Ticket, sequencer: :seq
'to_emails' => ['info@zammad.org'], 'to_emails' => ['info@zammad.org'],
'product_id' => nil, 'product_id' => nil,
'id' => 13, 'id' => 13,
'type' => nil, 'type' => 'Incident',
'due_by' => '2021-05-17T12:29:27Z', 'due_by' => '2021-05-17T12:29:27Z',
'fr_due_by' => '2021-05-15T12:29:27Z', 'fr_due_by' => '2021-05-15T12:29:27Z',
'is_escalated' => false, 'is_escalated' => false,
@ -116,6 +116,7 @@ RSpec.describe ::Sequencer::Sequence::Import::Freshdesk::Ticket, sequencer: :seq
priority_id: 1, priority_id: 1,
owner_id: owner.id, owner_id: owner.id,
customer_id: User.last.id, customer_id: User.last.id,
type: 'Incident',
cf_custom_dropdown: 'key_2', cf_custom_dropdown: 'key_2',
cf_custom_integer: 999, cf_custom_integer: 999,
cf_test_checkbox: true, cf_test_checkbox: true,
@ -207,5 +208,23 @@ RSpec.describe ::Sequencer::Sequence::Import::Freshdesk::Ticket, sequencer: :seq
expect(Ticket.last.tag_list).to eq(%w[example test]) expect(Ticket.last.tag_list).to eq(%w[example test])
end end
end end
context 'when importing without a type' do
let(:resource) do
super().merge(
'type' => nil
)
end
let(:imported_ticket) do
super().merge(
type: nil
)
end
it 'correct attributes for added ticket' do
process(process_payload)
expect(Ticket.last).to have_attributes(imported_ticket)
end
end
end end
end end

View file

@ -47,7 +47,7 @@ RSpec.describe ::Sequencer::Sequence::Import::Kayako::CaseField, sequencer: :seq
it "import the fixed option list for the ticket 'type' field" do it "import the fixed option list for the ticket 'type' field" do
process(process_payload) process(process_payload)
expect(ObjectManager::Attribute.get(object: 'Ticket', name: 'type').data_option[:options]).to a_hash_including(imported_type_options) expect(ObjectManager::Attribute.get(object: 'Ticket', name: 'type').data_option[:options]).to include(imported_type_options)
end end
end end
end end

View file

@ -23,7 +23,7 @@ RSpec.describe Channel::Filter::AutoResponseCheck, type: :channel_filter do
it 'check filter result' do it 'check filter result' do
filter(mail) filter(mail)
expect(mail).to match(a_hash_including(mail_auto_response)) expect(mail).to include(mail_auto_response)
end end
end end