diff --git a/app/assets/javascripts/app/controllers/import_zendesk.coffee b/app/assets/javascripts/app/controllers/import_zendesk.coffee index 1858adde1..c49004230 100644 --- a/app/assets/javascripts/app/controllers/import_zendesk.coffee +++ b/app/assets/javascripts/app/controllers/import_zendesk.coffee @@ -154,35 +154,35 @@ class Index extends App.ControllerContent processData: true success: (data, status, xhr) => - if data.result is 'import_done' - window.location.reload() - return - - if data.result is 'error' - @$('.js-error').removeClass('hide') - @$('.js-error').html(App.i18n.translateContent(data.message)) - else - @$('.js-error').addClass('hide') - - if data.message is 'not running' && @updateMigrationDisplayLoop > 16 + if _.isEmpty(data.result) && @updateMigrationDisplayLoop > 16 @$('.js-error').removeClass('hide') @$('.js-error').html(App.i18n.translateContent('Background process did not start or has not finished! Please contact your support.')) return - if data.result is 'in_progress' - for key, item of data.data - if item.done > item.total - item.done = item.total + if !_.isEmpty(data.result['error']) + @$('.js-error').removeClass('hide') + @$('.js-error').html(App.i18n.translateContent(data.result['error'])) + else + @$('.js-error').addClass('hide') - if key == 'Ticket' && item.total >= 1000 + if !_.isEmpty(data.finished_at) && _.isEmpty(data.result['error']) + window.location.reload() + return + + if !_.isEmpty(data.result) + for model, stats of data.result + if stats.sum > stats.total + stats.sum = stats.total + + if model == 'Ticket' && stats.total >= 1000 @ticketCountInfo.removeClass('hide') - element = @$('.js-' + key.toLowerCase() ) - element.find('.js-done').text(item.done) - element.find('.js-total').text(item.total) - element.find('progress').attr('max', item.total ) - element.find('progress').attr('value', item.done ) - if item.total <= item.done + element = @$('.js-' + model.toLowerCase() ) + element.find('.js-done').text(stats.sum) + element.find('.js-total').text(stats.total) + element.find('progress').attr('max', stats.total ) + element.find('progress').attr('value', stats.sum ) + if stats.total <= stats.sum element.addClass('is-done') else element.removeClass('is-done') diff --git a/app/assets/javascripts/app/views/import/zendesk.jst.eco b/app/assets/javascripts/app/views/import/zendesk.jst.eco index eeb7f95c9..e48d4d4a5 100644 --- a/app/assets/javascripts/app/views/import/zendesk.jst.eco +++ b/app/assets/javascripts/app/views/import/zendesk.jst.eco @@ -64,7 +64,7 @@
-/- | <%- @T('Groups') %> | @@ -73,7 +73,7 @@ <%- @Icon('checkmark') %> |
-/- | <%- @T('Organizations') %> | @@ -82,7 +82,7 @@ <%- @Icon('checkmark') %> |
-/- | <%- @T('Users') %> | @@ -91,7 +91,7 @@ <%- @Icon('checkmark') %> |
-/- | <%- @T('Tickets') %> |
diff --git a/app/controllers/import_zendesk_controller.rb b/app/controllers/import_zendesk_controller.rb
index 28bdbd609..c3ee3587c 100644
--- a/app/controllers/import_zendesk_controller.rb
+++ b/app/controllers/import_zendesk_controller.rb
@@ -74,7 +74,9 @@ class ImportZendeskController < ApplicationController
Setting.set('import_zendesk_endpoint_username', params[:username])
Setting.set('import_zendesk_endpoint_key', params[:token])
- if !Import::Zendesk.connection_test
+ result = Sequencer.process('Import::Zendesk::ConnectionTest')
+
+ if !result[:connected]
Setting.set('import_zendesk_endpoint_username', nil)
Setting.set('import_zendesk_endpoint_key', nil)
@@ -96,8 +98,8 @@ class ImportZendeskController < ApplicationController
Setting.set('import_mode', true)
Setting.set('import_backend', 'zendesk')
- # start migration
- Import::Zendesk.delay.start_bg
+ job = ImportJob.create(name: 'Import::Zendesk')
+ job.delay.start
render json: {
result: 'ok',
@@ -105,11 +107,13 @@ class ImportZendeskController < ApplicationController
end
def import_status
- result = Import::Zendesk.status_bg
- if result[:result] == 'import_done'
+ job = ImportJob.find_by(name: 'Import::Zendesk')
+
+ if job.finished_at.present?
Setting.reload
end
- render json: result
+
+ model_show_render_item(job)
end
private
diff --git a/lib/import/base_resource.rb b/lib/import/base_resource.rb
deleted file mode 100644
index 04cb8efad..000000000
--- a/lib/import/base_resource.rb
+++ /dev/null
@@ -1,256 +0,0 @@
-module Import
- class BaseResource
- include Import::Helper
-
- attr_reader :resource, :errors
-
- def initialize(resource, *args)
- @action = :unknown
- handle_args(resource, *args)
- initialize_associations_states
- import(resource, *args)
- end
-
- def import_class
- raise NoMethodError, "#{self.class.name} has no implementation of the needed 'import_class' method"
- end
-
- def source
- self.class.source
- end
-
- def remote_id(resource, *_args)
- @remote_id ||= resource.delete(:id)
- end
-
- def action
- return :failed if errors.present?
- return :skipped if @resource.blank?
- return :unchanged if !attributes_changed?
- @action
- end
-
- def attributes_changed?
- changed_attributes.present? || changed_associations.present?
- end
-
- def changed_attributes
- return if @resource.blank?
- # dry run
- return @resource.changes_to_save if @resource.has_changes_to_save?
- # live run
- @resource.previous_changes
- end
-
- def changed_associations
- changes = {}
- tracked_associations.each do |association|
- # skip if no new value will get assigned (no change is performed)
- next if !@associations[:after].key?(association)
- # skip if both values are equal
- next if @associations[:before][association] == @associations[:after][association]
- # skip if both values are blank
- next if @associations[:before][association].blank? && @associations[:after][association].blank?
- # store changes
- changes[association] = [@associations[:before][association], @associations[:after][association]]
- end
- changes
- end
-
- def self.source
- import_class_namespace
- end
-
- def self.import_class_namespace
- @import_class_namespace ||= name.to_s.sub('Import::', '')
- end
-
- private
-
- def initialize_associations_states
- @associations = {}
- %i[before after].each do |state|
- @associations[state] ||= {}
- end
- end
-
- def import(resource, *args)
- create_or_update(map(resource, *args), *args)
- rescue => e
- # Don't catch own thrown exceptions from above
- raise if e.is_a?(NoMethodError)
- handle_error(e)
- end
-
- def create_or_update(resource, *args)
- return if updated?(resource, *args)
- create(resource, *args)
- end
-
- def updated?(resource, *args)
- @resource = lookup_existing(resource, *args)
- return false if !@resource
-
- # lock the current resource for write access
- @resource.with_lock do
-
- # delete since we have an update and
- # the record is already created
- resource.delete(:created_by_id)
-
- # store the current state of the associations
- # from the resource hash because if we assign
- # them to the instance some (e.g. has_many)
- # will get stored even in the dry run :/
- store_associations(:after, resource)
-
- associations = tracked_associations
- @resource.assign_attributes(resource.except(*associations))
-
- # the return value here is kind of misleading
- # and should not be trusted to indicate if a
- # resource was actually updated.
- # Use .action instead
- return true if !attributes_changed?
-
- @action = :updated
-
- return true if @dry_run
- @resource.assign_attributes(resource.slice(*associations))
- @resource.save!
- true
- end
- end
-
- def lookup_existing(resource, *_args)
-
- synced_instance = ExternalSync.find_by(
- source: source,
- source_id: remote_id(resource),
- object: import_class.name,
- )
- return if !synced_instance
- instance = import_class.find_by(id: synced_instance.o_id)
-
- store_associations(:before, instance)
-
- instance
- end
-
- def store_associations(state, source)
- @associations[state] = associations_state(source)
- end
-
- def associations_state(source)
- state = {}
- tracked_associations.each do |association|
- # we have to support instances and (resource) hashes
- # here since in case of an update we only have the
- # hash as a source but on create we have an instance
- if source.is_a?(Hash)
- # ignore if there is no key for the association
- # of the Hash (update)
- # otherwise wrong changes may get detected
- next if !source.key?(association)
- state[association] = source[association]
- else
- state[association] = source.send(association)
- end
-
- # sort arrays to avoid wrong change detection
- next if !state[association].respond_to?(:sort!)
- state[association].sort!
- end
- state
- end
-
- def tracked_associations
- # loop over all reflections
- import_class.reflect_on_all_associations.collect do |reflection|
- # refection name is something like groups or organization (singular/plural)
- reflection_name = reflection.name.to_s
- # key is something like group_id or organization_id (singular)
- key = reflection.klass.name.foreign_key
-
- # add trailing 's' to get pluralized key
- if reflection_name.singularize != reflection_name
- key = "#{key}s"
- end
-
- key.to_sym
- end
- end
-
- def create(resource, *_args)
- @resource = import_class.new(resource)
- store_associations(:after, @resource)
- @action = :created
- return if @dry_run
- @resource.save!
- external_sync_create(
- local: @resource,
- remote: resource,
- )
- end
-
- def external_sync_create(local:, remote:)
- ExternalSync.create(
- source: source,
- source_id: remote_id(remote),
- object: import_class.name,
- o_id: local.id
- )
- end
-
- def defaults(_resource, *_args)
- {
- created_by_id: 1,
- updated_by_id: 1,
- }
- end
-
- def map(resource, *args)
- mapped = from_mapping(resource, *args)
- attributes = defaults(resource, *args).merge(mapped)
- attributes.symbolize_keys
- end
-
- def from_mapping(resource, *args)
- mapping = mapping(*args)
- return resource if !mapping
-
- ExternalSync.map(
- mapping: mapping,
- source: resource
- )
- end
-
- def mapping(*args)
- Setting.get(mapping_config(*args))
- end
-
- def mapping_config(*_args)
- self.class.import_class_namespace.gsub('::', '_').underscore + '_mapping'
- end
-
- def handle_args(_resource, *args)
- return if !args
- return if !args.is_a?(Array)
- return if args.blank?
-
- last_arg = args.last
- return if !last_arg.is_a?(Hash)
- handle_modifiers(last_arg)
- end
-
- def handle_modifiers(modifiers)
- @dry_run = modifiers.fetch(:dry_run, false)
- end
-
- def handle_error(e)
- @errors ||= []
- @errors.push(e)
- Rails.logger.error e
- end
- end
-end
diff --git a/lib/import/zendesk.rb b/lib/import/zendesk.rb
index 110124103..ff143d281 100644
--- a/lib/import/zendesk.rb
+++ b/lib/import/zendesk.rb
@@ -1,68 +1,15 @@
-require 'base64'
-require 'zendesk_api'
+# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
module Import
-end
-module Import::Zendesk
- extend Import::Helper
- extend Import::Zendesk::Async
- extend Import::Zendesk::ImportStats
+ class Zendesk < Import::Base
+ include Import::Mixin::Sequence
- # rubocop:disable Style/ModuleFunction
- extend self
+ def start
+ process
+ end
- def start
- log 'Start import...'
-
- checks
-
- Import::Zendesk::GroupFactory.import(client.groups)
-
- Import::Zendesk::OrganizationFieldFactory.import(client.organization_fields)
- Import::Zendesk::OrganizationFactory.import(client.organizations)
-
- Import::Zendesk::UserFieldFactory.import(client.user_fields)
- Import::Zendesk::UserFactory.import(client.users)
-
- Import::Zendesk::TicketFieldFactory.import(client.ticket_fields)
- Import::Zendesk::TicketFactory.import(all_tickets)
-
- # TODO
- Setting.set( 'system_init_done', true )
- Setting.set( 'import_mode', false )
-
- true
- end
-
- def connection_test
- Import::Zendesk::Requester.connection_test
- end
-
- private
-
- # this special ticket logic is needed since Zendesk archives tickets
- # after 120 days and doesn't return them via the client.tickets
- # endpoint as described here:
- # https://github.com/zammad/zammad/issues/558#issuecomment-267951351
- # the proper way is to use the 'incremental' endpoint which is not available
- # via the ruby gem yet but a pull request is pending:
- # https://github.com/zendesk/zendesk_api_client_rb/pull/287
- # the following workaround is needed to use this functionality
- def all_tickets
- ZendeskAPI::Collection.new(
- client,
- ZendeskAPI::Ticket,
- path: 'incremental/tickets?start_time=1'
- )
- end
-
- def client
- Import::Zendesk::Requester.client
- end
-
- def checks
- check_import_mode
- check_system_init_done
- connection_test
+ def sequence_name
+ 'Import::Zendesk::Full'
+ end
end
end
diff --git a/lib/import/zendesk/async.rb b/lib/import/zendesk/async.rb
deleted file mode 100644
index 7ae735bc8..000000000
--- a/lib/import/zendesk/async.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-module Import
- module Zendesk
- module Async
- # rubocop:disable Style/ModuleFunction
- extend self
-
- def start_bg
- Setting.reload
-
- Import::Zendesk.connection_test
-
- # get statistic before starting import
- statistic
-
- # start thread to observe current state
- status_update_thread = Thread.new do
- loop do
- result = {
- data: current_state,
- result: 'in_progress',
- }
- Cache.write('import:state', result, expires_in: 10.minutes)
- sleep 8
- end
- end
- sleep 2
-
- # start import data
- begin
- Import::Zendesk.start
- rescue => e
- status_update_thread.exit
- status_update_thread.join
- Rails.logger.error e
- result = {
- message: e.message,
- result: 'error',
- }
- Cache.write('import:state', result, expires_in: 10.hours)
- return false
- end
- sleep 16 # wait until new finished import state is on client
- status_update_thread.exit
- status_update_thread.join
-
- result = {
- result: 'import_done',
- }
- Cache.write('import:state', result, expires_in: 10.hours)
-
- Setting.set('system_init_done', true)
- Setting.set('import_mode', false)
- end
-
- def status_bg
- state = Cache.get('import:state')
- return state if state
- {
- message: 'not running',
- }
- end
- end
- end
-end
diff --git a/lib/import/zendesk/base_factory.rb b/lib/import/zendesk/base_factory.rb
deleted file mode 100644
index 3e2753b7e..000000000
--- a/lib/import/zendesk/base_factory.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module Import
- module Zendesk
- module BaseFactory
- include Import::Factory
-
- # rubocop:disable Style/ModuleFunction
- extend self
-
- private
-
- def import_loop(records, *_args, &import_block)
- records.all!(&import_block)
- end
- end
- end
-end
diff --git a/lib/import/zendesk/group.rb b/lib/import/zendesk/group.rb
deleted file mode 100644
index 0c0c14566..000000000
--- a/lib/import/zendesk/group.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-module Import
- module Zendesk
- class Group
- include Import::Helper
-
- attr_reader :zendesk_id, :id
-
- def initialize(group)
- local_group = ::Group.create_if_not_exists(
- name: group.name,
- active: !group.deleted,
- updated_by_id: 1,
- created_by_id: 1
- )
-
- @zendesk_id = group.id
- @id = local_group.id
- end
- end
- end
-end
diff --git a/lib/import/zendesk/group_factory.rb b/lib/import/zendesk/group_factory.rb
deleted file mode 100644
index 3386da928..000000000
--- a/lib/import/zendesk/group_factory.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-module Import
- module Zendesk
- module GroupFactory
- extend Import::Zendesk::BaseFactory
- extend Import::Zendesk::LocalIDMapperHook
- end
- end
-end
diff --git a/lib/import/zendesk/helper.rb b/lib/import/zendesk/helper.rb
deleted file mode 100644
index 34c606b71..000000000
--- a/lib/import/zendesk/helper.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-module Import
- module Zendesk
- module Helper
- # rubocop:disable Style/ModuleFunction
- extend self
-
- private
-
- def get_fields(zendesk_fields)
- return {} if !zendesk_fields
- fields = {}
- zendesk_fields.each do |key, value|
- fields[key] = value
- end
- fields
- end
- end
- end
-end
diff --git a/lib/import/zendesk/import_stats.rb b/lib/import/zendesk/import_stats.rb
deleted file mode 100644
index 28773ba5c..000000000
--- a/lib/import/zendesk/import_stats.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-module Import
- module Zendesk
- module ImportStats
- # rubocop:disable Style/ModuleFunction
- extend self
-
- def current_state
-
- data = statistic
-
- {
- Group: {
- done: ::Group.count,
- total: data['Groups'] || 0,
- },
- Organization: {
- done: ::Organization.count,
- total: data['Organizations'] || 0,
- },
- User: {
- done: ::User.count,
- total: data['Users'] || 0,
- },
- Ticket: {
- done: ::Ticket.count,
- total: data['Tickets'] || 0,
- },
- }
- end
-
- def statistic
-
- # check cache
- cache = Cache.get('import_zendesk_stats')
- return cache if cache
-
- # retrive statistic
- result = {
- 'Tickets' => 0,
- 'TicketFields' => 0,
- 'UserFields' => 0,
- 'OrganizationFields' => 0,
- 'Groups' => 0,
- 'Organizations' => 0,
- 'Users' => 0,
- 'GroupMemberships' => 0,
- 'Macros' => 0,
- 'Views' => 0,
- 'Automations' => 0,
- }
-
- result.each_key do |object|
- result[ object ] = statistic_count(object)
- end
-
- Cache.write('import_zendesk_stats', result)
- result
- end
-
- private
-
- def statistic_count(object)
- statistic_count_data(object).count!
- end
-
- def statistic_count_data(object)
- return all_tickets if object == 'Tickets'
- Import::Zendesk::Requester.client.send( object.underscore.to_sym )
- end
- end
- end
-end
diff --git a/lib/import/zendesk/local_id_mapper_hook.rb b/lib/import/zendesk/local_id_mapper_hook.rb
deleted file mode 100644
index b300caa9a..000000000
--- a/lib/import/zendesk/local_id_mapper_hook.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-module Import
- module Zendesk
- module LocalIDMapperHook
-
- # rubocop:disable Style/ModuleFunction
- extend self
-
- def local_id(zendesk_id)
- init_mapping
- @zendesk_mapping[ zendesk_id ]
- end
-
- def post_import_hook(_record, backend_instance)
- init_mapping
- @zendesk_mapping[ backend_instance.zendesk_id ] = backend_instance.id
- end
-
- private
-
- def init_mapping
- @zendesk_mapping ||= {}
- end
- end
- end
-end
diff --git a/lib/import/zendesk/object_attribute.rb b/lib/import/zendesk/object_attribute.rb
deleted file mode 100644
index 440f2b220..000000000
--- a/lib/import/zendesk/object_attribute.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-module Import
- module Zendesk
- class ObjectAttribute
-
- def initialize(object, name, attribute)
-
- initialize_data_option(attribute)
- init_callback(attribute)
-
- add(object, name, attribute)
- end
-
- private
-
- def init_callback(_attribute); end
-
- def add(object, name, attribute)
- ObjectManager::Attribute.add( attribute_config(object, name, attribute) )
- ObjectManager::Attribute.migration_execute(false)
- rescue => e
- # rubocop:disable Style/SpecialGlobalVars
- raise $!, "Problem with ObjectManager Attribute '#{name}': #{$!}", $!.backtrace
- end
-
- def attribute_config(object, name, attribute)
- {
- object: object,
- name: name,
- display: attribute.title,
- data_type: data_type(attribute),
- data_option: @data_option,
- editable: !attribute.removable,
- active: attribute.active,
- screens: screens(attribute),
- position: attribute.position,
- created_by_id: 1,
- updated_by_id: 1,
- }
- end
-
- def screens(attribute)
- config = {
- view: {
- '-all-' => {
- shown: true,
- },
- }
- }
-
- return config if !attribute.visible_in_portal && attribute.required_in_portal
-
- {
- edit: {
- Customer: {
- shown: attribute.visible_in_portal,
- null: !attribute.required_in_portal,
- },
- }.merge(config)
- }
- end
-
- def initialize_data_option(attribute)
- @data_option = {
- null: !attribute.required,
- note: attribute.description,
- }
- end
-
- def data_type(attribute)
- attribute.type
- end
- end
- end
-end
diff --git a/lib/import/zendesk/object_attribute/base.rb b/lib/import/zendesk/object_attribute/base.rb
new file mode 100644
index 000000000..a444a1c3f
--- /dev/null
+++ b/lib/import/zendesk/object_attribute/base.rb
@@ -0,0 +1,76 @@
+module Import
+ class Zendesk
+ module ObjectAttribute
+ class Base
+
+ def initialize(object, name, attribute)
+
+ initialize_data_option(attribute)
+ init_callback(attribute)
+
+ add(object, name, attribute)
+ end
+
+ private
+
+ def init_callback(_attribute); end
+
+ def add(object, name, attribute)
+ ObjectManager::Attribute.add( attribute_config(object, name, attribute) )
+ ObjectManager::Attribute.migration_execute(false)
+ rescue => e
+ # rubocop:disable Style/SpecialGlobalVars
+ raise $!, "Problem with ObjectManager Attribute '#{name}': #{$!}", $!.backtrace
+ end
+
+ def attribute_config(object, name, attribute)
+ {
+ object: object,
+ name: name,
+ display: attribute.title,
+ data_type: data_type(attribute),
+ data_option: @data_option,
+ editable: !attribute.removable,
+ active: attribute.active,
+ screens: screens(attribute),
+ position: attribute.position,
+ created_by_id: 1,
+ updated_by_id: 1,
+ }
+ end
+
+ def screens(attribute)
+ config = {
+ view: {
+ '-all-' => {
+ shown: true,
+ },
+ }
+ }
+
+ return config if !attribute.visible_in_portal && attribute.required_in_portal
+
+ {
+ edit: {
+ Customer: {
+ shown: attribute.visible_in_portal,
+ null: !attribute.required_in_portal,
+ },
+ }.merge(config)
+ }
+ end
+
+ def initialize_data_option(attribute)
+ @data_option = {
+ null: !attribute.required,
+ note: attribute.description,
+ }
+ end
+
+ def data_type(attribute)
+ attribute.type
+ end
+ end
+ end
+ end
+end
diff --git a/lib/import/zendesk/object_attribute/checkbox.rb b/lib/import/zendesk/object_attribute/checkbox.rb
index 143b629e6..310712126 100644
--- a/lib/import/zendesk/object_attribute/checkbox.rb
+++ b/lib/import/zendesk/object_attribute/checkbox.rb
@@ -1,7 +1,13 @@
+# this require is required (hehe) because of Rails autoloading
+# which causes strange behavior not inheriting correctly
+# from Import::OTRS::DynamicField
+require 'import/zendesk/object_attribute/base'
+
module Import
- module Zendesk
- class ObjectAttribute
- class Checkbox < Import::Zendesk::ObjectAttribute
+ class Zendesk
+ module ObjectAttribute
+ class Checkbox < Import::Zendesk::ObjectAttribute::Base
+
def init_callback(_object_attribte)
@data_option.merge!(
default: false,
diff --git a/lib/import/zendesk/object_attribute/date.rb b/lib/import/zendesk/object_attribute/date.rb
index ed7ba4165..7e7c57df7 100644
--- a/lib/import/zendesk/object_attribute/date.rb
+++ b/lib/import/zendesk/object_attribute/date.rb
@@ -1,12 +1,12 @@
# this require is required (hehe) because of Rails autoloading
# which causes strange behavior not inheriting correctly
# from Import::OTRS::DynamicField
-require 'import/zendesk/object_attribute'
+require 'import/zendesk/object_attribute/base'
module Import
- module Zendesk
- class ObjectAttribute
- class Date < Import::Zendesk::ObjectAttribute
+ class Zendesk
+ module ObjectAttribute
+ class Date < Import::Zendesk::ObjectAttribute::Base
def init_callback(_object_attribte)
@data_option.merge!(
future: true,
diff --git a/lib/import/zendesk/object_attribute/decimal.rb b/lib/import/zendesk/object_attribute/decimal.rb
index 6067a7540..24e9f7a4b 100644
--- a/lib/import/zendesk/object_attribute/decimal.rb
+++ b/lib/import/zendesk/object_attribute/decimal.rb
@@ -1,6 +1,6 @@
module Import
- module Zendesk
- class ObjectAttribute
+ class Zendesk
+ module ObjectAttribute
class Decimal < Import::Zendesk::ObjectAttribute::Text
end
end
diff --git a/lib/import/zendesk/object_attribute/dropdown.rb b/lib/import/zendesk/object_attribute/dropdown.rb
index 871e87df1..20ce3990a 100644
--- a/lib/import/zendesk/object_attribute/dropdown.rb
+++ b/lib/import/zendesk/object_attribute/dropdown.rb
@@ -1,6 +1,6 @@
module Import
- module Zendesk
- class ObjectAttribute
+ class Zendesk
+ module ObjectAttribute
class Dropdown < Import::Zendesk::ObjectAttribute::Select
end
end
diff --git a/lib/import/zendesk/object_attribute/integer.rb b/lib/import/zendesk/object_attribute/integer.rb
index d16e94233..eb8a2ab22 100644
--- a/lib/import/zendesk/object_attribute/integer.rb
+++ b/lib/import/zendesk/object_attribute/integer.rb
@@ -1,12 +1,13 @@
# this require is required (hehe) because of Rails autoloading
# which causes strange behavior not inheriting correctly
# from Import::OTRS::DynamicField
-require 'import/zendesk/object_attribute'
+require 'import/zendesk/object_attribute/base'
module Import
- module Zendesk
- class ObjectAttribute
- class Integer < Import::Zendesk::ObjectAttribute
+ class Zendesk
+ module ObjectAttribute
+ class Integer < Import::Zendesk::ObjectAttribute::Base
+
def init_callback(_object_attribte)
@data_option.merge!(
min: 0,
diff --git a/lib/import/zendesk/object_attribute/regexp.rb b/lib/import/zendesk/object_attribute/regexp.rb
index b557dab66..b56093acc 100644
--- a/lib/import/zendesk/object_attribute/regexp.rb
+++ b/lib/import/zendesk/object_attribute/regexp.rb
@@ -1,12 +1,13 @@
# this require is required (hehe) because of Rails autoloading
# which causes strange behavior not inheriting correctly
# from Import::OTRS::DynamicField
-require 'import/zendesk/object_attribute'
+require 'import/zendesk/object_attribute/base'
module Import
- module Zendesk
- class ObjectAttribute
- class Regexp < Import::Zendesk::ObjectAttribute
+ class Zendesk
+ module ObjectAttribute
+ class Regexp < Import::Zendesk::ObjectAttribute::Base
+
def init_callback(object_attribte)
@data_option.merge!(
type: 'text',
diff --git a/lib/import/zendesk/object_attribute/select.rb b/lib/import/zendesk/object_attribute/select.rb
index c041adec4..43ca8633e 100644
--- a/lib/import/zendesk/object_attribute/select.rb
+++ b/lib/import/zendesk/object_attribute/select.rb
@@ -1,7 +1,13 @@
+# this require is required (hehe) because of Rails autoloading
+# which causes strange behavior not inheriting correctly
+# from Import::OTRS::DynamicField
+require 'import/zendesk/object_attribute/base'
+
module Import
- module Zendesk
- class ObjectAttribute
- class Select < Import::Zendesk::ObjectAttribute
+ class Zendesk
+ module ObjectAttribute
+ class Select < Import::Zendesk::ObjectAttribute::Base
+
def init_callback(object_attribte)
@data_option.merge!(
default: '',
diff --git a/lib/import/zendesk/object_attribute/tagger.rb b/lib/import/zendesk/object_attribute/tagger.rb
index c8481b586..7db751300 100644
--- a/lib/import/zendesk/object_attribute/tagger.rb
+++ b/lib/import/zendesk/object_attribute/tagger.rb
@@ -1,6 +1,6 @@
module Import
- module Zendesk
- class ObjectAttribute
+ class Zendesk
+ module ObjectAttribute
class Tagger < Import::Zendesk::ObjectAttribute::Select
end
end
diff --git a/lib/import/zendesk/object_attribute/text.rb b/lib/import/zendesk/object_attribute/text.rb
index 3d68dfcbe..6676173e4 100644
--- a/lib/import/zendesk/object_attribute/text.rb
+++ b/lib/import/zendesk/object_attribute/text.rb
@@ -1,7 +1,13 @@
+# this require is required (hehe) because of Rails autoloading
+# which causes strange behavior not inheriting correctly
+# from Import::OTRS::DynamicField
+require 'import/zendesk/object_attribute/base'
+
module Import
- module Zendesk
- class ObjectAttribute
- class Text < Import::Zendesk::ObjectAttribute
+ class Zendesk
+ module ObjectAttribute
+ class Text < Import::Zendesk::ObjectAttribute::Base
+
def init_callback(_object_attribte)
@data_option.merge!(
type: 'text',
diff --git a/lib/import/zendesk/object_attribute/textarea.rb b/lib/import/zendesk/object_attribute/textarea.rb
index f2e6b9013..9562d3d0a 100644
--- a/lib/import/zendesk/object_attribute/textarea.rb
+++ b/lib/import/zendesk/object_attribute/textarea.rb
@@ -1,7 +1,13 @@
+# this require is required (hehe) because of Rails autoloading
+# which causes strange behavior not inheriting correctly
+# from Import::OTRS::DynamicField
+require 'import/zendesk/object_attribute/base'
+
module Import
- module Zendesk
- class ObjectAttribute
- class Textarea < Import::Zendesk::ObjectAttribute
+ class Zendesk
+ module ObjectAttribute
+ class Textarea < Import::Zendesk::ObjectAttribute::Base
+
def init_callback(_object_attribte)
@data_option.merge!(
type: 'textarea',
diff --git a/lib/import/zendesk/object_field.rb b/lib/import/zendesk/object_field.rb
deleted file mode 100644
index 814a8e913..000000000
--- a/lib/import/zendesk/object_field.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-module Import
- module Zendesk
- class ObjectField
-
- attr_reader :zendesk_id, :id
-
- def initialize(object_field)
-
- import(object_field)
-
- @zendesk_id = object_field.id
- @id = local_name(object_field)
- end
-
- private
-
- def local_name(object_field)
- @local_name ||= remote_name(object_field).gsub(%r{[\s\/]}, '_').underscore.gsub(/_{2,}/, '_').gsub(/_id(s?)$/, '_no\1')
- end
-
- def remote_name(object_field)
- object_field['key'] # TODO: y?!
- end
-
- def import(object_field)
- backend_class(object_field).new(object_name, local_name(object_field), object_field)
- end
-
- def backend_class(object_field)
- "Import::Zendesk::ObjectAttribute::#{object_field.type.capitalize}".constantize
- end
-
- def object_name
- self.class.name.to_s.sub(/Import::Zendesk::/, '').sub(/Field/, '')
- end
- end
- end
-end
diff --git a/lib/import/zendesk/organization.rb b/lib/import/zendesk/organization.rb
deleted file mode 100644
index 961035c29..000000000
--- a/lib/import/zendesk/organization.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# https://developer.zendesk.com/rest_api/docs/core/organizations
-module Import
- module Zendesk
- class Organization
- include Import::Zendesk::Helper
-
- attr_reader :zendesk_id, :id
-
- def initialize(organization)
- local_organization = ::Organization.create_if_not_exists(local_organization_fields(organization))
- @zendesk_id = organization.id
- @id = local_organization.id
- end
-
- private
-
- def local_organization_fields(organization)
- {
- name: organization.name,
- note: organization.note,
- shared: organization.shared_tickets,
- # shared: organization.shared_comments, # TODO, not yet implemented
- # }.merge(organization.organization_fields) # TODO
- updated_by_id: 1,
- created_by_id: 1
- }.merge(custom_fields(organization))
- end
-
- def custom_fields(organization)
- get_fields(organization.organization_fields)
- end
- end
- end
-end
diff --git a/lib/import/zendesk/organization_factory.rb b/lib/import/zendesk/organization_factory.rb
deleted file mode 100644
index 5f1af7584..000000000
--- a/lib/import/zendesk/organization_factory.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module Import
- module Zendesk
- module OrganizationFactory
- # we need to loop over each instead of all!
- # so we can use the default import factory here
- extend Import::Factory
- extend Import::Zendesk::LocalIDMapperHook
- end
- end
-end
diff --git a/lib/import/zendesk/organization_field.rb b/lib/import/zendesk/organization_field.rb
deleted file mode 100644
index f29fb53ef..000000000
--- a/lib/import/zendesk/organization_field.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Import
- module Zendesk
- class OrganizationField < Import::Zendesk::ObjectField
- end
- end
-end
diff --git a/lib/import/zendesk/organization_field_factory.rb b/lib/import/zendesk/organization_field_factory.rb
deleted file mode 100644
index cf235422b..000000000
--- a/lib/import/zendesk/organization_field_factory.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-module Import
- module Zendesk
- module OrganizationFieldFactory
- extend Import::Zendesk::BaseFactory
- extend Import::Zendesk::LocalIDMapperHook
- end
- end
-end
diff --git a/lib/import/zendesk/priority.rb b/lib/import/zendesk/priority.rb
deleted file mode 100644
index 25b7e9c44..000000000
--- a/lib/import/zendesk/priority.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-module Import
- module Zendesk
- class Priority
-
- MAPPING = {
- 'low' => '1 low',
- nil => '2 normal',
- 'normal' => '2 normal',
- 'high' => '3 high',
- 'urgent' => '3 high',
- }.freeze
-
- class << self
-
- def lookup(ticket)
- remote_priority = ticket.priority
- @mapping ||= {}
- if @mapping[ remote_priority ]
- return @mapping[ remote_priority ]
- end
- @mapping[ remote_priority ] = ::Ticket::Priority.lookup( name: map(remote_priority) )
- end
-
- private
-
- def map(priority)
- MAPPING.fetch(priority, MAPPING[nil])
- end
- end
- end
- end
-end
diff --git a/lib/import/zendesk/requester.rb b/lib/import/zendesk/requester.rb
deleted file mode 100644
index 53b717e4f..000000000
--- a/lib/import/zendesk/requester.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-module Import
- module Zendesk
- module Requester
-
- # rubocop:disable Style/ModuleFunction
- extend self
-
- def connection_test
- # make sure to reinitialize client
- # to react to config changes
- initialize_client
- return true if client.users.first
- false
- end
-
- def client
- return @client if @client
- initialize_client
- @client
- end
-
- private
-
- def initialize_client
- @client = ZendeskAPI::Client.new do |config|
- config.url = Setting.get('import_zendesk_endpoint')
-
- # Basic / Token Authentication
- config.username = Setting.get('import_zendesk_endpoint_username')
- config.token = Setting.get('import_zendesk_endpoint_key')
-
- # when hitting the rate limit, sleep automatically,
- # then retry the request.
- config.retry = true
-
- # disable cache to avoid unneeded memory consumption
- # since we are using each object only once
- # Inspired by: https://medium.com/swiftype-engineering/using-jmat-to-find-analyze-memory-in-jruby-1c4196c1ec72
- config.cache = false
- end
- end
- end
- end
-end
diff --git a/lib/import/zendesk/state.rb b/lib/import/zendesk/state.rb
deleted file mode 100644
index 30dfd4895..000000000
--- a/lib/import/zendesk/state.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-module Import
- module Zendesk
- class State
-
- MAPPING = {
- 'pending' => 'pending reminder',
- 'solved' => 'closed',
- 'deleted' => 'removed',
- }.freeze
-
- class << self
-
- def lookup(ticket)
- remote_state = ticket.status
- @mapping ||= {}
- if @mapping[ remote_state ]
- return @mapping[ remote_state ]
- end
- @mapping[ remote_state ] = ::Ticket::State.lookup( name: map( remote_state ) )
- end
-
- private
-
- def map(state)
- MAPPING.fetch(state, state)
- end
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket.rb b/lib/import/zendesk/ticket.rb
deleted file mode 100644
index 7a18c0079..000000000
--- a/lib/import/zendesk/ticket.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# https://developer.zendesk.com/rest_api/docs/core/tickets
-# https://developer.zendesk.com/rest_api/docs/core/ticket_comments#ticket-comments
-# https://developer.zendesk.com/rest_api/docs/core/ticket_audits#the-via-object
-# https://developer.zendesk.com/rest_api/docs/help_center/article_attachments
-# https://developer.zendesk.com/rest_api/docs/core/ticket_audits # v2
-module Import
- module Zendesk
- class Ticket
- include Import::Helper
-
- def initialize(ticket)
- create_or_update(ticket)
- Import::Zendesk::Ticket::TagFactory.import(ticket.tags, @local_ticket, ticket)
- Import::Zendesk::Ticket::CommentFactory.import(ticket.comments, @local_ticket, ticket)
- end
-
- private
-
- def create_or_update(ticket)
- mapped_ticket = local_ticket_fields(ticket)
- return if updated?(mapped_ticket)
- create(mapped_ticket)
- end
-
- def updated?(ticket)
- @local_ticket = ::Ticket.find_by(id: ticket[:id])
- return false if !@local_ticket
- @local_ticket.update!(ticket)
- true
- end
-
- def create(ticket)
- @local_ticket = ::Ticket.create(ticket)
- reset_primary_key_sequence('tickets')
- end
-
- def local_ticket_fields(ticket)
- local_user_id = Import::Zendesk::UserFactory.local_id( ticket.requester_id ) || 1
-
- {
- id: ticket.id,
- title: ticket.subject || ticket.description || '-',
- owner_id: Import::Zendesk::UserFactory.local_id( ticket.assignee ) || 1,
- note: ticket.description,
- group_id: Import::Zendesk::GroupFactory.local_id( ticket.group_id ) || 1,
- customer_id: local_user_id,
- organization_id: Import::Zendesk::OrganizationFactory.local_id( ticket.organization_id ),
- priority: Import::Zendesk::Priority.lookup(ticket),
- state: Import::Zendesk::State.lookup(ticket),
- pending_time: ticket.due_at,
- updated_at: ticket.updated_at,
- created_at: ticket.created_at,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- create_article_sender_id: Import::Zendesk::Ticket::Comment::Sender.local_id(local_user_id),
- create_article_type_id: Import::Zendesk::Ticket::Comment::Type.local_id(ticket),
- }.merge(custom_fields(ticket))
- end
-
- def custom_fields(ticket)
- custom_fields = ticket.custom_fields
- fields = {}
- return fields if !custom_fields
- custom_fields.each do |custom_field|
- field_name = Import::Zendesk::TicketFieldFactory.local_id(custom_field['id'])
- field_value = custom_field['value']
- next if field_value.nil?
- fields[ field_name.to_sym ] = field_value
- end
- fields
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket/comment.rb b/lib/import/zendesk/ticket/comment.rb
deleted file mode 100644
index d03f3b657..000000000
--- a/lib/import/zendesk/ticket/comment.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-module Import
- module Zendesk
- class Ticket
- class Comment
-
- def initialize(comment, local_ticket, _zendesk_ticket)
- create_or_update(comment, local_ticket)
- import_attachments(comment)
- end
-
- private
-
- def create_or_update(comment, local_ticket)
- mapped_article = local_article_fields(comment, local_ticket)
- return if updated?(mapped_article)
- create(mapped_article)
- end
-
- def updated?(article)
- @local_article = ::Ticket::Article.find_by(message_id: article[:message_id])
- return false if !@local_article
- @local_article.update!(article)
- true
- end
-
- def create(article)
- @local_article = ::Ticket::Article.create(article)
- end
-
- def local_article_fields(comment, local_ticket)
-
- local_user_id = Import::Zendesk::UserFactory.local_id( comment.author_id ) || 1
-
- {
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: Import::Zendesk::Ticket::Comment::Sender.local_id( local_user_id ),
- type_id: Import::Zendesk::Ticket::Comment::Type.local_id(comment),
- }.merge(from_to(comment))
- end
-
- def from_to(comment)
- if comment.via.channel == 'email'
- {
- from: comment.via.source.from.address,
- to: comment.via.source.to.address # Notice comment.via.from.original_recipients = [\"another@gmail.com\", \"support@example.zendesk.com\"]
- }
- elsif comment.via.channel == 'facebook'
- {
- from: comment.via.source.from.facebook_id,
- to: comment.via.source.to.facebook_id
- }
- else
- {}
- end
- end
-
- def import_attachments(comment)
- attachments = comment.attachments
- return if attachments.blank?
- Import::Zendesk::Ticket::Comment::AttachmentFactory.import(attachments, @local_article)
- end
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket/comment/attachment.rb b/lib/import/zendesk/ticket/comment/attachment.rb
deleted file mode 100644
index 15728baf4..000000000
--- a/lib/import/zendesk/ticket/comment/attachment.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-module Import
- module Zendesk
- class Ticket
- class Comment
- class Attachment
- include Import::Helper
-
- def initialize(attachment, local_article)
-
- response = request(attachment)
- return if !response
-
- ::Store.add(
- object: 'Ticket::Article',
- o_id: local_article.id,
- data: response.body,
- filename: attachment.file_name,
- preferences: {
- 'Content-Type' => attachment.content_type
- },
- created_by_id: 1
- )
- rescue => e
- log e.message
- end
-
- private
-
- def request(attachment)
- response = UserAgent.get(
- attachment.content_url,
- {},
- {
- open_timeout: 10,
- read_timeout: 60,
- },
- )
- return response if response.success?
- log response.error
- nil
- end
- end
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket/comment/attachment_factory.rb b/lib/import/zendesk/ticket/comment/attachment_factory.rb
deleted file mode 100644
index 167ff8192..000000000
--- a/lib/import/zendesk/ticket/comment/attachment_factory.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-module Import
- module Zendesk
- class Ticket
- class Comment
- module AttachmentFactory
- # we need to loop over each instead of all!
- # so we can use the default import factory here
- extend Import::Factory
-
- # rubocop:disable Style/ModuleFunction
- extend self
-
- private
-
- # special handling which only starts import if needed
- # Attention: skip? method can't be used since it (currently)
- # only checks for single records - not all
- def import_loop(records, *args, &import_block)
- local_article = args[0]
- local_attachments = local_article.attachments
-
- return if local_attachments.count == records.count
- # get a common ground
- local_attachments.each(&:delete)
- return if records.blank?
-
- records.each(&import_block)
- end
-
- def create_instance(record, *args)
- local_article = args[0]
- backend_class(record).new(record, local_article)
- end
- end
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket/comment/sender.rb b/lib/import/zendesk/ticket/comment/sender.rb
deleted file mode 100644
index f8d3ab028..000000000
--- a/lib/import/zendesk/ticket/comment/sender.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-module Import
- module Zendesk
- class Ticket
- class Comment
- module Sender
-
- # rubocop:disable Style/ModuleFunction
- extend self
-
- def local_id(user_id)
- author = author_lookup(user_id)
- sender_id(author)
- end
-
- private
-
- def author_lookup(user_id)
- ::User.find( user_id )
- end
-
- def sender_id(author)
- if author.role?('Customer')
- article_sender_customer
- elsif author.role?('Agent')
- article_sender_agent
- else
- article_sender_system
- end
- end
-
- def article_sender_customer
- return @article_sender_customer if @article_sender_customer
- @article_sender_customer = ::Ticket::Article::Sender.lookup(name: 'Customer').id
- end
-
- def article_sender_agent
- return @article_sender_agent if @article_sender_agent
- @article_sender_agent = ::Ticket::Article::Sender.lookup(name: 'Agent').id
- end
-
- def article_sender_system
- return @article_sender_system if @article_sender_system
- @article_sender_system = ::Ticket::Article::Sender.lookup(name: 'System').id
- end
- end
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket/comment/type.rb b/lib/import/zendesk/ticket/comment/type.rb
deleted file mode 100644
index 8dad31905..000000000
--- a/lib/import/zendesk/ticket/comment/type.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-module Import
- module Zendesk
- class Ticket
- class Comment
- module Type
-
- # rubocop:disable Style/ModuleFunction
- extend self
-
- def local_id(object)
- case object.via.channel
- when 'web'
- article_type_id[:web]
- when 'email'
- article_type_id[:email]
- when 'sample_ticket'
- article_type_id[:note]
- when 'twitter'
- if object.via.source.rel == 'mention'
- article_type_id[:twitter_status]
- else
- article_type_id[:twitter_direct_message]
- end
- when 'facebook'
- if object.via.source.rel == 'post'
- article_type_id[:facebook_feed_post]
- else
- article_type_id[:facebook_feed_comment]
- end
- # fallback for other not (yet) supported article types
- # See:
- # https://support.zendesk.com/hc/en-us/articles/203661746-Zendesk-Glossary#topic_zie_aqe_tf
- # https://support.zendesk.com/hc/en-us/articles/203661596-About-Zendesk-Support-channels
- else
- article_type_id[:web]
- end
- end
-
- private
-
- def article_type_id
- return @article_type_id if @article_type_id
-
- article_types = ['web', 'note', 'email', 'twitter status',
- 'twitter direct-message', 'facebook feed post',
- 'facebook feed comment']
- @article_type_id = {}
- article_types.each do |article_type|
-
- article_type_key = article_type.gsub(/\s|\-/, '_').to_sym
-
- @article_type_id[article_type_key] = ::Ticket::Article::Type.lookup(name: article_type).id
- end
- @article_type_id
- end
- end
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket/comment_factory.rb b/lib/import/zendesk/ticket/comment_factory.rb
deleted file mode 100644
index 99f96429d..000000000
--- a/lib/import/zendesk/ticket/comment_factory.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module Import
- module Zendesk
- class Ticket
- module CommentFactory
- extend Import::Zendesk::Ticket::SubObjectFactory
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket/sub_object_factory.rb b/lib/import/zendesk/ticket/sub_object_factory.rb
deleted file mode 100644
index aa67e0861..000000000
--- a/lib/import/zendesk/ticket/sub_object_factory.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-module Import
- module Zendesk
- class Ticket
- module SubObjectFactory
- # we need to loop over each instead of all!
- # so we can use the default import factory here
- include Import::Factory
-
- private
-
- def create_instance(record, *args)
-
- local_ticket = args[0]
- zendesk_ticket = args[1]
-
- backend_class(record).new(record, local_ticket, zendesk_ticket)
- end
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket/tag.rb b/lib/import/zendesk/ticket/tag.rb
deleted file mode 100644
index f4a07a079..000000000
--- a/lib/import/zendesk/ticket/tag.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module Import
- module Zendesk
- class Ticket
- class Tag
- def initialize(tag, local_ticket, zendesk_ticket)
- ::Tag.tag_add(
- object: 'Ticket',
- o_id: local_ticket.id,
- item: tag.id,
- created_by_id: Import::Zendesk::UserFactory.local_id(zendesk_ticket.requester_id) || 1,
- )
- end
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket/tag_factory.rb b/lib/import/zendesk/ticket/tag_factory.rb
deleted file mode 100644
index 7fed1c5d8..000000000
--- a/lib/import/zendesk/ticket/tag_factory.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module Import
- module Zendesk
- class Ticket
- module TagFactory
- extend Import::Zendesk::Ticket::SubObjectFactory
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket_factory.rb b/lib/import/zendesk/ticket_factory.rb
deleted file mode 100644
index ebc313724..000000000
--- a/lib/import/zendesk/ticket_factory.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-module Import
- module Zendesk
- module TicketFactory
- extend Import::Zendesk::BaseFactory
-
- # rubocop:disable Style/ModuleFunction
- extend self
-
- private
-
- def import_loop(records, *args)
-
- count_update_hook = proc do |record|
- yield(record)
- update_ticket_count(records)
- end
-
- super(records, *args, &count_update_hook)
- end
-
- def update_ticket_count(collection)
-
- cache_key = 'import_zendesk_stats'
- count_variable = :@count
- page_variable = :@next_page
-
- next_page = collection.instance_variable_get(page_variable)
- @last_page ||= next_page
-
- return if @last_page == next_page
- return if !collection.instance_variable_get(count_variable)
-
- @last_page = next_page
-
- # check cache
- cache = Cache.get(cache_key)
- return if !cache
-
- cache['Tickets'] ||= 0
- cache['Tickets'] += collection.instance_variable_get(count_variable)
-
- Cache.write(cache_key, cache)
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket_field.rb b/lib/import/zendesk/ticket_field.rb
deleted file mode 100644
index 1a84bd374..000000000
--- a/lib/import/zendesk/ticket_field.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-module Import
- module Zendesk
- class TicketField < Import::Zendesk::ObjectField
-
- private
-
- def remote_name(ticket_field)
- ticket_field.title
- end
- end
- end
-end
diff --git a/lib/import/zendesk/ticket_field_factory.rb b/lib/import/zendesk/ticket_field_factory.rb
deleted file mode 100644
index 14138ee8e..000000000
--- a/lib/import/zendesk/ticket_field_factory.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-module Import
- module Zendesk
- module TicketFieldFactory
- extend Import::Zendesk::BaseFactory
- extend Import::Zendesk::LocalIDMapperHook
-
- MAPPING = {
- 'subject' => 'title',
- 'description' => 'note',
- 'status' => 'state_id',
- 'tickettype' => 'type',
- 'priority' => 'priority_id',
- 'basic_priority' => 'priority_id',
- 'group' => 'group_id',
- 'assignee' => 'owner_id',
- }.freeze
-
- # rubocop:disable Style/ModuleFunction
- extend self
-
- def skip?(field, *_args)
- # check if the Ticket object already has a same named column / attribute
- # so we want to skip instead of importing it
- ::Ticket.column_names.include?( local_attribute(field) )
- end
-
- private
-
- def local_attribute(field)
- MAPPING.fetch(field.type, field.type)
- end
- end
- end
-end
diff --git a/lib/import/zendesk/user.rb b/lib/import/zendesk/user.rb
deleted file mode 100644
index bda0b4d8c..000000000
--- a/lib/import/zendesk/user.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-# Rails autoload has some issues with same namend sub-classes
-# in the importer folder require AND simultaniuos requiring
-# of the same file in different threads so we need to
-# require them ourself
-require 'import/zendesk/user/group'
-require 'import/zendesk/user/role'
-
-# https://developer.zendesk.com/rest_api/docs/core/users
-module Import
- module Zendesk
- class User
- include Import::Zendesk::Helper
-
- attr_reader :zendesk_id, :id
-
- def initialize(user)
- local_user = ::User.create_or_update( local_user_fields(user) )
- @zendesk_id = user.id
- @id = local_user.id
- end
-
- private
-
- def local_user_fields(user)
- {
- login: login(user),
- firstname: user.name,
- email: user.email,
- phone: user.phone,
- password: password(user),
- active: !user.suspended,
- groups: Import::Zendesk::User::Group.for(user),
- roles: roles(user),
- note: user.notes,
- verified: user.verified,
- organization_id: Import::Zendesk::OrganizationFactory.local_id( user.organization_id ),
- last_login: user.last_login_at,
- image_source: photo(user),
- updated_by_id: 1,
- created_by_id: 1
- }.merge(custom_fields(user))
- end
-
- def login(user)
- return user.email if user.email
- # Zendesk users may have no other identifier than the ID, e.g. twitter users
- user.id.to_s
- end
-
- def password(user)
- return Setting.get('import_zendesk_endpoint_key') if import_user?(user)
- ''
- end
-
- def roles(user)
- return Import::Zendesk::User::Role.map(user, 'admin') if import_user?(user)
- Import::Zendesk::User::Role.for(user)
- end
-
- def import_user?(user)
- return false if user.email.blank?
- user.email == Setting.get('import_zendesk_endpoint_username')
- end
-
- def photo(user)
- return if !user.photo
- user.photo.content_url
- end
-
- def custom_fields(user)
- get_fields(user.user_fields)
- end
- end
- end
-end
diff --git a/lib/import/zendesk/user/group.rb b/lib/import/zendesk/user/group.rb
deleted file mode 100644
index 9fe4782a8..000000000
--- a/lib/import/zendesk/user/group.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# this require is required (hehe) because of Rails autoloading
-# which causes strange behavior not inheriting correctly
-# from Import::OTRS::DynamicField
-require 'import/zendesk/user'
-
-# https://developer.zendesk.com/rest_api/docs/core/groups
-module Import
- module Zendesk
- class User
- module Group
-
- # rubocop:disable Style/ModuleFunction
- extend self
-
- def for(user)
- groups = []
- return groups if mapping[user.id].blank?
-
- mapping[user.id].each do |zendesk_group_id|
-
- local_group_id = Import::Zendesk::GroupFactory.local_id(zendesk_group_id)
-
- next if !local_group_id
-
- group = ::Group.find( local_group_id )
-
- groups.push(group)
- end
- groups
- end
-
- private
-
- def mapping
-
- return @mapping if !@mapping.nil?
-
- @mapping = {}
-
- Import::Zendesk::Requester.client.group_memberships.all! do |group_membership|
-
- @mapping[ group_membership.user_id ] ||= []
- @mapping[ group_membership.user_id ].push( group_membership.group_id )
- end
-
- @mapping
- end
- end
- end
- end
-end
diff --git a/lib/import/zendesk/user/role.rb b/lib/import/zendesk/user/role.rb
deleted file mode 100644
index fdc960c37..000000000
--- a/lib/import/zendesk/user/role.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-# this require is required (hehe) because of Rails autoloading
-# which causes strange behavior not inheriting correctly
-# from Import::OTRS::DynamicField
-require 'import/zendesk/user'
-
-module Import
- module Zendesk
- class User
- module Role
- extend Import::Helper
-
- # rubocop:disable Style/ModuleFunction
- extend self
-
- def for(user)
- map(user, group_method( user.role.name ))
- end
-
- def map(user, role)
- send(role.to_sym, user)
- rescue NoMethodError => e
- log "Unknown mapping for role '#{user.role.name}' and user with id '#{user.id}'"
- []
- end
-
- private
-
- def end_user(_user)
- [role_customer]
- end
-
- def agent(user)
- return [ role_agent ] if user.restricted_agent
- admin(user)
- end
-
- def admin(_user)
- [role_admin, role_agent]
- end
-
- def group_method(role)
- role.tr('-', '_')
- end
-
- def role_admin
- @role_admin ||= lookup('Admin')
- end
-
- def role_agent
- @role_agent ||= lookup('Agent')
- end
-
- def role_customer
- @role_customer ||= lookup('Customer')
- end
-
- def lookup(role_name)
- ::Role.lookup(name: role_name)
- end
-
- end
- end
- end
-end
diff --git a/lib/import/zendesk/user_factory.rb b/lib/import/zendesk/user_factory.rb
deleted file mode 100644
index ec3fafe5b..000000000
--- a/lib/import/zendesk/user_factory.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-module Import
- module Zendesk
- module UserFactory
- extend Import::Zendesk::BaseFactory
- extend Import::Zendesk::LocalIDMapperHook
- end
- end
-end
diff --git a/lib/import/zendesk/user_field.rb b/lib/import/zendesk/user_field.rb
deleted file mode 100644
index 5b8f615f1..000000000
--- a/lib/import/zendesk/user_field.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Import
- module Zendesk
- class UserField < Import::Zendesk::ObjectField
- end
- end
-end
diff --git a/lib/import/zendesk/user_field_factory.rb b/lib/import/zendesk/user_field_factory.rb
deleted file mode 100644
index 101d50178..000000000
--- a/lib/import/zendesk/user_field_factory.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-module Import
- module Zendesk
- module UserFieldFactory
- extend Import::Zendesk::BaseFactory
- extend Import::Zendesk::LocalIDMapperHook
- end
- end
-end
diff --git a/lib/sequencer/sequence/import/zendesk/connection_test.rb b/lib/sequencer/sequence/import/zendesk/connection_test.rb
new file mode 100644
index 000000000..2e6663567
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/connection_test.rb
@@ -0,0 +1,21 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class ConnectionTest < Sequencer::Sequence::Base
+
+ def self.expecting
+ [:connected]
+ end
+
+ def self.sequence
+ [
+ 'Zendesk::Client',
+ 'Zendesk::Connected',
+ ]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/sequence/import/zendesk/full.rb b/lib/sequencer/sequence/import/zendesk/full.rb
new file mode 100644
index 000000000..969106c11
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/full.rb
@@ -0,0 +1,32 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class Full < Sequencer::Sequence::Base
+
+ def self.sequence
+ [
+ 'Import::Common::ImportMode::Check',
+ 'Import::Common::SystemInitDone::Check',
+ 'Zendesk::Client',
+ 'Import::Zendesk::ObjectsTotalCount',
+ 'Import::Common::ImportJob::Statistics::Update',
+ 'Import::Common::ImportJob::Statistics::Store',
+ 'Import::Common::ImportJob::DryRun',
+ 'Import::Zendesk::Groups',
+ 'Import::Zendesk::OrganizationFields',
+ 'Import::Zendesk::Organizations',
+ 'Import::Zendesk::UserFields',
+ 'Import::Zendesk::UserGroupMap',
+ 'Import::Zendesk::Users',
+ 'Import::Zendesk::TicketFields',
+ 'Import::Zendesk::Tickets',
+ 'Import::Common::SystemInitDone::Set',
+ 'Import::Common::ImportMode::Unset',
+ ]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/sequence/import/zendesk/group.rb b/lib/sequencer/sequence/import/zendesk/group.rb
new file mode 100644
index 000000000..7feaf1396
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/group.rb
@@ -0,0 +1,25 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class Group < Sequencer::Sequence::Base
+
+ def self.sequence
+ [
+ 'Common::ModelClass::Group',
+ 'Import::Zendesk::Group::Mapping',
+ 'Import::Common::Model::Attributes::AddByIds',
+ 'Import::Common::Model::FindBy::Name',
+ 'Import::Common::Model::Update',
+ 'Import::Common::Model::Create',
+ 'Import::Common::Model::Save',
+ 'Import::Common::Model::Statistics::Diff::ModelKey',
+ 'Import::Common::ImportJob::Statistics::Update',
+ 'Import::Common::ImportJob::Statistics::Store',
+ ]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/sequence/import/zendesk/organization.rb b/lib/sequencer/sequence/import/zendesk/organization.rb
new file mode 100644
index 000000000..9b2aef744
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/organization.rb
@@ -0,0 +1,26 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class Organization < Sequencer::Sequence::Base
+
+ def self.sequence
+ [
+ 'Common::ModelClass::Organization',
+ 'Import::Zendesk::Organization::Mapping',
+ 'Import::Zendesk::Organization::CustomFields',
+ 'Import::Common::Model::Attributes::AddByIds',
+ 'Import::Common::Model::FindBy::Name',
+ 'Import::Common::Model::Update',
+ 'Import::Common::Model::Create',
+ 'Import::Common::Model::Save',
+ 'Import::Common::Model::Statistics::Diff::ModelKey',
+ 'Import::Common::ImportJob::Statistics::Update',
+ 'Import::Common::ImportJob::Statistics::Store',
+ ]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/sequence/import/zendesk/organization_field.rb b/lib/sequencer/sequence/import/zendesk/organization_field.rb
new file mode 100644
index 000000000..718171ece
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/organization_field.rb
@@ -0,0 +1,18 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class OrganizationField < Sequencer::Sequence::Base
+
+ def self.sequence
+ [
+ 'Common::ModelClass::Organization',
+ 'Import::Zendesk::ObjectAttribute::SanitizedName',
+ 'Import::Zendesk::ObjectAttribute::Add',
+ ]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/sequence/import/zendesk/ticket.rb b/lib/sequencer/sequence/import/zendesk/ticket.rb
new file mode 100644
index 000000000..7c9681c10
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/ticket.rb
@@ -0,0 +1,37 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class Ticket < Sequencer::Sequence::Base
+
+ def self.sequence
+ [
+ 'Import::Zendesk::Ticket::UserID',
+ 'Import::Zendesk::Ticket::OwnerID',
+ 'Import::Zendesk::Ticket::GroupID',
+ 'Import::Zendesk::Ticket::OrganizationID',
+ 'Import::Zendesk::Ticket::PriorityID',
+ 'Import::Zendesk::Ticket::StateID',
+ 'Import::Zendesk::Common::ArticleSenderID',
+ 'Import::Zendesk::Common::ArticleTypeID',
+ 'Import::Zendesk::Ticket::Subject',
+ 'Import::Zendesk::Ticket::CustomFields',
+ 'Import::Zendesk::Ticket::Mapping',
+ 'Common::ModelClass::Ticket',
+ 'Import::Common::Model::FindBy::Id',
+ 'Import::Common::Model::Update',
+ 'Import::Common::Model::Create',
+ 'Import::Common::Model::Save',
+ 'Import::Common::Model::ResetPrimaryKeySequence',
+ 'Import::Zendesk::Ticket::Tags',
+ 'Import::Zendesk::Ticket::Comments',
+ 'Import::Common::Model::Statistics::Diff::ModelKey',
+ 'Import::Common::ImportJob::Statistics::Update',
+ 'Import::Common::ImportJob::Statistics::Store',
+ ]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/sequence/import/zendesk/ticket/comment.rb b/lib/sequencer/sequence/import/zendesk/ticket/comment.rb
new file mode 100644
index 000000000..986aa8d04
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/ticket/comment.rb
@@ -0,0 +1,30 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class Ticket < Sequencer::Sequence::Base
+ class Comment < Sequencer::Sequence::Base
+
+ def self.sequence
+ [
+ 'Import::Zendesk::Ticket::Comment::UserID',
+ 'Import::Zendesk::Common::ArticleSenderID',
+ 'Import::Zendesk::Common::ArticleTypeID',
+ 'Import::Zendesk::Ticket::Comment::From',
+ 'Import::Zendesk::Ticket::Comment::To',
+ 'Import::Zendesk::Ticket::Comment::Mapping',
+ 'Import::Zendesk::Ticket::Comment::UnsetInstance',
+ 'Common::ModelClass::Ticket::Article',
+ 'Import::Common::Model::FindBy::Id',
+ 'Import::Common::Model::Update',
+ 'Import::Common::Model::Create',
+ 'Import::Common::Model::Save',
+ 'Import::Zendesk::Ticket::Comment::Attachments',
+ ]
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/sequence/import/zendesk/ticket/comment/attachment.rb b/lib/sequencer/sequence/import/zendesk/ticket/comment/attachment.rb
new file mode 100644
index 000000000..6a0929ede
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/ticket/comment/attachment.rb
@@ -0,0 +1,21 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class Ticket < Sequencer::Sequence::Base
+ class Comment < Sequencer::Sequence::Base
+ class Attachment < Sequencer::Sequence::Base
+
+ def self.sequence
+ [
+ 'Import::Zendesk::Ticket::Comment::Attachment::Request',
+ 'Import::Zendesk::Ticket::Comment::Attachment::Add',
+ ]
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/sequence/import/zendesk/ticket/tag.rb b/lib/sequencer/sequence/import/zendesk/ticket/tag.rb
new file mode 100644
index 000000000..ac3b400b2
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/ticket/tag.rb
@@ -0,0 +1,19 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class Ticket < Sequencer::Sequence::Base
+ class Tag < Sequencer::Sequence::Base
+
+ def self.sequence
+ [
+ 'Import::Zendesk::Ticket::Tag::Item',
+ 'Common::Tag::Add',
+ ]
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/sequence/import/zendesk/ticket_field.rb b/lib/sequencer/sequence/import/zendesk/ticket_field.rb
new file mode 100644
index 000000000..b7ad03cba
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/ticket_field.rb
@@ -0,0 +1,19 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class TicketField < Sequencer::Sequence::Base
+
+ def self.sequence
+ [
+ 'Common::ModelClass::Ticket',
+ 'Import::Zendesk::TicketField::CheckCustom',
+ 'Import::Zendesk::TicketField::SanitizedName',
+ 'Import::Zendesk::TicketField::Add',
+ ]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/sequence/import/zendesk/user.rb b/lib/sequencer/sequence/import/zendesk/user.rb
new file mode 100644
index 000000000..62d582b39
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/user.rb
@@ -0,0 +1,33 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class User < Sequencer::Sequence::Base
+
+ def self.sequence
+ [
+ 'Import::Zendesk::User::Initiator',
+ 'Import::Zendesk::User::Roles',
+ 'Import::Zendesk::User::Groups',
+ 'Import::Zendesk::User::Login',
+ 'Import::Zendesk::User::Password',
+ 'Import::Zendesk::User::ImageSource',
+ 'Import::Zendesk::User::OrganizationID',
+ 'Common::ModelClass::User',
+ 'Import::Zendesk::User::Mapping',
+ 'Import::Zendesk::User::CustomFields',
+ 'Import::Common::Model::Attributes::AddByIds',
+ 'Import::Common::Model::FindBy::UserAttributes',
+ 'Import::Common::Model::Update',
+ 'Import::Common::Model::Create',
+ 'Import::Common::Model::Save',
+ 'Import::Common::Model::Statistics::Diff::ModelKey',
+ 'Import::Common::ImportJob::Statistics::Update',
+ 'Import::Common::ImportJob::Statistics::Store',
+ ]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/sequence/import/zendesk/user_field.rb b/lib/sequencer/sequence/import/zendesk/user_field.rb
new file mode 100644
index 000000000..b4549d1eb
--- /dev/null
+++ b/lib/sequencer/sequence/import/zendesk/user_field.rb
@@ -0,0 +1,18 @@
+class Sequencer
+ class Sequence
+ module Import
+ module Zendesk
+ class UserField < Sequencer::Sequence::Base
+
+ def self.sequence
+ [
+ 'Common::ModelClass::User',
+ 'Import::Zendesk::ObjectAttribute::SanitizedName',
+ 'Import::Zendesk::ObjectAttribute::Add',
+ ]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/common/model_class/group.rb b/lib/sequencer/unit/common/model_class/group.rb
new file mode 100644
index 000000000..537e718a0
--- /dev/null
+++ b/lib/sequencer/unit/common/model_class/group.rb
@@ -0,0 +1,10 @@
+class Sequencer
+ class Unit
+ module Common
+ module ModelClass
+ class Group < Sequencer::Unit::Common::ModelClass::Base
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/common/model_class/organization.rb b/lib/sequencer/unit/common/model_class/organization.rb
new file mode 100644
index 000000000..9ced58f55
--- /dev/null
+++ b/lib/sequencer/unit/common/model_class/organization.rb
@@ -0,0 +1,10 @@
+class Sequencer
+ class Unit
+ module Common
+ module ModelClass
+ class Organization < Sequencer::Unit::Common::ModelClass::Base
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/common/model_class/ticket.rb b/lib/sequencer/unit/common/model_class/ticket.rb
new file mode 100644
index 000000000..80cda1dbd
--- /dev/null
+++ b/lib/sequencer/unit/common/model_class/ticket.rb
@@ -0,0 +1,10 @@
+class Sequencer
+ class Unit
+ module Common
+ module ModelClass
+ class Ticket < Sequencer::Unit::Common::ModelClass::Base
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/common/model_class/ticket/article.rb b/lib/sequencer/unit/common/model_class/ticket/article.rb
new file mode 100644
index 000000000..86de53c2a
--- /dev/null
+++ b/lib/sequencer/unit/common/model_class/ticket/article.rb
@@ -0,0 +1,12 @@
+class Sequencer
+ class Unit
+ module Common
+ module ModelClass
+ class Ticket < Sequencer::Unit::Common::ModelClass::Base
+ class Article < Sequencer::Unit::Common::ModelClass::Base
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/common/tag/add.rb b/lib/sequencer/unit/common/tag/add.rb
new file mode 100644
index 000000000..38d9b1181
--- /dev/null
+++ b/lib/sequencer/unit/common/tag/add.rb
@@ -0,0 +1,21 @@
+class Sequencer
+ class Unit
+ module Common
+ module Tag
+ class Add < Sequencer::Unit::Base
+
+ uses :model_class, :instance, :item, :user_id
+
+ def process
+ ::Tag.tag_add(
+ object: model_class.name,
+ o_id: instance.id,
+ item: item,
+ created_by_id: user_id,
+ )
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/common/unset_attributes.rb b/lib/sequencer/unit/common/unset_attributes.rb
new file mode 100644
index 000000000..86576281f
--- /dev/null
+++ b/lib/sequencer/unit/common/unset_attributes.rb
@@ -0,0 +1,17 @@
+class Sequencer
+ class Unit
+ module Common
+ class UnsetAttributes < Sequencer::Unit::Base
+
+ def process
+ uses = self.class.uses
+ return if uses.blank?
+
+ uses.each do |attribute|
+ state.unset(attribute)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/common/import_mode/check.rb b/lib/sequencer/unit/import/common/import_mode/check.rb
new file mode 100644
index 000000000..288a14bf3
--- /dev/null
+++ b/lib/sequencer/unit/import/common/import_mode/check.rb
@@ -0,0 +1,18 @@
+class Sequencer
+ class Unit
+ module Import
+ module Common
+ module ImportMode
+ class Check < Sequencer::Unit::Base
+
+ def process
+ # check if system is in import mode
+ return if Setting.get('import_mode')
+ raise 'System is not in import mode!'
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/common/import_mode/unset.rb b/lib/sequencer/unit/import/common/import_mode/unset.rb
new file mode 100644
index 000000000..dfc37cdc2
--- /dev/null
+++ b/lib/sequencer/unit/import/common/import_mode/unset.rb
@@ -0,0 +1,16 @@
+class Sequencer
+ class Unit
+ module Import
+ module Common
+ module ImportMode
+ class Unset < Sequencer::Unit::Base
+
+ def process
+ Setting.set('import_mode', false)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/common/model/find_by/id.rb b/lib/sequencer/unit/import/common/model/find_by/id.rb
new file mode 100644
index 000000000..403e96751
--- /dev/null
+++ b/lib/sequencer/unit/import/common/model/find_by/id.rb
@@ -0,0 +1,14 @@
+class Sequencer
+ class Unit
+ module Import
+ module Common
+ module Model
+ module FindBy
+ class Id < Sequencer::Unit::Import::Common::Model::FindBy::SameNamedAttribute
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/common/model/find_by/name.rb b/lib/sequencer/unit/import/common/model/find_by/name.rb
new file mode 100644
index 000000000..81e4fd11c
--- /dev/null
+++ b/lib/sequencer/unit/import/common/model/find_by/name.rb
@@ -0,0 +1,14 @@
+class Sequencer
+ class Unit
+ module Import
+ module Common
+ module Model
+ module FindBy
+ class Name < Sequencer::Unit::Import::Common::Model::FindBy::SameNamedAttribute
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/common/model/find_by/same_named_attribute.rb b/lib/sequencer/unit/import/common/model/find_by/same_named_attribute.rb
new file mode 100644
index 000000000..8d939637e
--- /dev/null
+++ b/lib/sequencer/unit/import/common/model/find_by/same_named_attribute.rb
@@ -0,0 +1,20 @@
+class Sequencer
+ class Unit
+ module Import
+ module Common
+ module Model
+ module FindBy
+ class SameNamedAttribute < Sequencer::Unit::Import::Common::Model::Lookup::Attributes
+
+ private
+
+ def attribute
+ self.class.name.demodulize.underscore.to_sym
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/common/model/find_by/user_attributes.rb b/lib/sequencer/unit/import/common/model/find_by/user_attributes.rb
new file mode 100644
index 000000000..c91b7f752
--- /dev/null
+++ b/lib/sequencer/unit/import/common/model/find_by/user_attributes.rb
@@ -0,0 +1,20 @@
+class Sequencer
+ class Unit
+ module Import
+ module Common
+ module Model
+ module FindBy
+ class UserAttributes < Sequencer::Unit::Import::Common::Model::Lookup::Attributes
+
+ private
+
+ def attributes
+ %i[login email]
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/common/model/reset_primary_key_sequence.rb b/lib/sequencer/unit/import/common/model/reset_primary_key_sequence.rb
new file mode 100644
index 000000000..b5e3eaee6
--- /dev/null
+++ b/lib/sequencer/unit/import/common/model/reset_primary_key_sequence.rb
@@ -0,0 +1,20 @@
+class Sequencer
+ class Unit
+ module Import
+ module Common
+ module Model
+ class ResetPrimaryKeySequence < Sequencer::Unit::Base
+
+ uses :model_class
+
+ delegate table_name: :model_class
+
+ def process
+ DbHelper.import_post(table_name)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/common/model/statistics/mixin/common.rb b/lib/sequencer/unit/import/common/model/statistics/mixin/common.rb
index 7d7202624..0091c3493 100644
--- a/lib/sequencer/unit/import/common/model/statistics/mixin/common.rb
+++ b/lib/sequencer/unit/import/common/model/statistics/mixin/common.rb
@@ -12,12 +12,16 @@ class Sequencer
%i[skipped created updated unchanged failed deactivated]
end
+ def results
+ %i[sum total]
+ end
+
def empty_diff
possible_actions.collect { |key| [key, 0] }.to_h
end
def possible_actions
- @possible_actions ||= actions
+ @possible_actions ||= actions + results
end
end
end
diff --git a/lib/sequencer/unit/import/common/model/statistics/total.rb b/lib/sequencer/unit/import/common/model/statistics/total.rb
new file mode 100644
index 000000000..772619e73
--- /dev/null
+++ b/lib/sequencer/unit/import/common/model/statistics/total.rb
@@ -0,0 +1,29 @@
+class Sequencer
+ class Unit
+ module Import
+ module Common
+ module Model
+ module Statistics
+ class Total < Sequencer::Unit::Base
+ include ::Sequencer::Unit::Import::Common::Model::Statistics::Mixin::EmptyDiff
+
+ def process
+ state.provide(:statistics_diff) do
+ diff.merge(
+ total: total
+ )
+ end
+ end
+
+ private
+
+ def total
+ raise "Missing implementation if total method for class #{self.class.name}"
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/common/object_attribute/sanitized_name.rb b/lib/sequencer/unit/import/common/object_attribute/sanitized_name.rb
new file mode 100644
index 000000000..4afd75537
--- /dev/null
+++ b/lib/sequencer/unit/import/common/object_attribute/sanitized_name.rb
@@ -0,0 +1,46 @@
+class Sequencer
+ class Unit
+ module Import
+ module Common
+ module ObjectAttribute
+ class SanitizedName < Sequencer::Unit::Common::Provider::Named
+
+ private
+
+ def sanitized_name
+ # model_no
+ # model_nos
+ # model_name
+ # model_name
+ without_double_underscores.gsub(/_id(s?)$/, '_no\1')
+ end
+
+ def without_double_underscores
+ # model_id
+ # model_ids
+ # model_name
+ # model_name
+ without_spaces_and_slashes.gsub(/_{2,}/, '_')
+ end
+
+ def without_spaces_and_slashes
+ # model_id
+ # model_ids
+ # model___name
+ # model_name
+ unsanitized_name.gsub(%r{[\s\/]}, '_').underscore
+ end
+
+ def unsanitized_name
+ # Model ID
+ # Model IDs
+ # Model / Name
+ # Model Name
+ raise 'Missing implementation for unsanitized_name method'
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/common/system_init_done/check.rb b/lib/sequencer/unit/import/common/system_init_done/check.rb
new file mode 100644
index 000000000..a3dac83c7
--- /dev/null
+++ b/lib/sequencer/unit/import/common/system_init_done/check.rb
@@ -0,0 +1,17 @@
+class Sequencer
+ class Unit
+ module Import
+ module Common
+ module SystemInitDone
+ class Check < Sequencer::Unit::Base
+
+ def process
+ return if !Setting.get('system_init_done')
+ raise 'System is already system_init_done!'
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/common/system_init_done/set.rb b/lib/sequencer/unit/import/common/system_init_done/set.rb
new file mode 100644
index 000000000..73c7a43ab
--- /dev/null
+++ b/lib/sequencer/unit/import/common/system_init_done/set.rb
@@ -0,0 +1,16 @@
+class Sequencer
+ class Unit
+ module Import
+ module Common
+ module SystemInitDone
+ class Set < Sequencer::Unit::Base
+
+ def process
+ Setting.set('system_init_done', true)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/common/article_sender_id.rb b/lib/sequencer/unit/import/zendesk/common/article_sender_id.rb
new file mode 100644
index 000000000..d6e9f9b3f
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/common/article_sender_id.rb
@@ -0,0 +1,30 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Common
+ class ArticleSenderID < Sequencer::Unit::Common::Provider::Named
+
+ uses :user_id
+
+ private
+
+ def article_sender_id
+ return article_sender('Customer') if author.role?('Customer')
+ return article_sender('Agent') if author.role?('Agent')
+ article_sender('System')
+ end
+
+ def author
+ @author ||= ::User.find(user_id)
+ end
+
+ def article_sender(name)
+ ::Ticket::Article::Sender.select(:id).find_by(name: name).id
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/common/article_type_id.rb b/lib/sequencer/unit/import/zendesk/common/article_type_id.rb
new file mode 100644
index 000000000..918a2d623
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/common/article_type_id.rb
@@ -0,0 +1,52 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Common
+ class ArticleTypeID < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource
+
+ private
+
+ def article_type_id
+ ::Ticket::Article::Type.select(:id).find_by(name: name).id
+ end
+
+ def name
+ known_channel || 'web'
+ end
+
+ def known_channel
+ channel = resource.via.channel
+ direct_mapping.fetch(channel, indirect_map(channel))
+ end
+
+ def indirect_map(channel)
+ method_name = "remote_name_#{channel}".to_sym
+ send(method_name) if respond_to?(method_name, true)
+ end
+
+ def remote_name_facebook
+ return 'facebook feed post' if resource.via.source.rel == 'post'
+ 'facebook feed comment'
+ end
+
+ def remote_name_twitter
+ return 'twitter status' if resource.via.source.rel == 'mention'
+ 'twitter direct message'
+ end
+
+ def direct_mapping
+ {
+ 'web' => 'web',
+ 'email' => 'email',
+ 'sample_ticket' => 'note',
+ }.freeze
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/common/custom_fields.rb b/lib/sequencer/unit/import/zendesk/common/custom_fields.rb
new file mode 100644
index 000000000..beec7436c
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/common/custom_fields.rb
@@ -0,0 +1,39 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Common
+ class CustomFields < Sequencer::Unit::Base
+ include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
+
+ uses :resource
+
+ def process
+ provide_mapped do
+ attributes_hash
+ end
+ end
+
+ private
+
+ def remote_fields
+ raise 'Missing implementation of remote_fields method'
+ end
+
+ def fields
+ @fields ||= remote_fields
+ end
+
+ def attributes_hash
+ return {} if fields.blank?
+ fields.each_with_object({}) do |(key, value), result|
+ next if value.nil?
+ result[key] = value
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/group/mapping.rb b/lib/sequencer/unit/import/zendesk/group/mapping.rb
new file mode 100644
index 000000000..14e0992a9
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/group/mapping.rb
@@ -0,0 +1,24 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Group
+ class Mapping < Sequencer::Unit::Base
+ include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
+
+ uses :resource
+
+ def process
+ provide_mapped do
+ {
+ name: resource.name,
+ active: !resource.deleted,
+ }
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/groups.rb b/lib/sequencer/unit/import/zendesk/groups.rb
new file mode 100644
index 000000000..705621390
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/groups.rb
@@ -0,0 +1,10 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ class Groups < Sequencer::Unit::Import::Zendesk::SubSequence::Object
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/object_attribute/add.rb b/lib/sequencer/unit/import/zendesk/object_attribute/add.rb
new file mode 100644
index 000000000..1fd67e150
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/object_attribute/add.rb
@@ -0,0 +1,25 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module ObjectAttribute
+ class Add < Sequencer::Unit::Base
+
+ uses :model_class, :sanitized_name, :resource
+ provides :instance
+
+ def process
+ state.provide(:instance) do
+ backend_class.new(model_class, sanitized_name, resource)
+ end
+ end
+
+ def backend_class
+ "Import::Zendesk::ObjectAttribute::#{resource.type.capitalize}".constantize
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/object_attribute/sanitized_name.rb b/lib/sequencer/unit/import/zendesk/object_attribute/sanitized_name.rb
new file mode 100644
index 000000000..cfc9f10a9
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/object_attribute/sanitized_name.rb
@@ -0,0 +1,24 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module ObjectAttribute
+ class SanitizedName < Sequencer::Unit::Import::Common::ObjectAttribute::SanitizedName
+
+ uses :resource
+
+ private
+
+ def unsanitized_name
+ # Model ID
+ # Model IDs
+ # Model / Name
+ # Model Name
+ resource['key']
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/objects_total_count.rb b/lib/sequencer/unit/import/zendesk/objects_total_count.rb
new file mode 100644
index 000000000..44294c24e
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/objects_total_count.rb
@@ -0,0 +1,50 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ class ObjectsTotalCount < Sequencer::Unit::Common::Provider::Attribute
+ include ::Sequencer::Unit::Import::Common::Model::Statistics::Mixin::EmptyDiff
+
+ uses :client
+
+ private
+
+ def statistics_diff
+ %i[Groups Users Organizations Tickets].each_with_object({}) do |object, stats|
+ stats[object] = empty_diff.merge(
+ total: request(object).count!
+ )
+ end
+ end
+
+ def request(object)
+ return tickets if object == 'Tickets'
+ generic(object)
+ end
+
+ def generic(object)
+ client.send(object.to_s.underscore.to_sym)
+ end
+
+ # this special ticket logic is needed since Zendesk archives tickets
+ # after 120 days and doesn't return them via the client.tickets
+ # endpoint as described here:
+ # https://github.com/zammad/zammad/issues/558#issuecomment-267951351
+ # the proper way is to use the 'incremental' endpoint which is not available
+ # via the ruby gem yet but a pull request is pending:
+ # https://github.com/zendesk/zendesk_api_client_rb/pull/287
+ # the following workaround is needed to use this functionality
+ # Counting Tickets has the limitations that max. 1000 are returned
+ # that's why we need to update the number when it's exceeded while importing
+ def tickets
+ ZendeskAPI::Collection.new(
+ client,
+ ZendeskAPI::Ticket,
+ path: 'incremental/tickets?start_time=1'
+ )
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/organization/custom_fields.rb b/lib/sequencer/unit/import/zendesk/organization/custom_fields.rb
new file mode 100644
index 000000000..54f4461ec
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/organization/custom_fields.rb
@@ -0,0 +1,18 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Organization
+ class CustomFields < Sequencer::Unit::Import::Zendesk::Common::CustomFields
+
+ private
+
+ def remote_fields
+ resource.organization_fields
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/organization/mapping.rb b/lib/sequencer/unit/import/zendesk/organization/mapping.rb
new file mode 100644
index 000000000..df7273637
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/organization/mapping.rb
@@ -0,0 +1,25 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Organization
+ class Mapping < Sequencer::Unit::Base
+ include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
+
+ uses :resource
+
+ def process
+ provide_mapped do
+ {
+ name: resource.name,
+ note: resource.note,
+ shared: resource.shared_tickets,
+ }
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/organization_fields.rb b/lib/sequencer/unit/import/zendesk/organization_fields.rb
new file mode 100644
index 000000000..49e861a1a
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/organization_fields.rb
@@ -0,0 +1,10 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ class OrganizationFields < Sequencer::Unit::Import::Zendesk::SubSequence::ObjectFields
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/organizations.rb b/lib/sequencer/unit/import/zendesk/organizations.rb
new file mode 100644
index 000000000..2f06d1040
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/organizations.rb
@@ -0,0 +1,16 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ class Organizations < Sequencer::Unit::Import::Zendesk::SubSequence::Object
+
+ private
+
+ def resource_iteration_method
+ :all!
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/sub_sequence/base.rb b/lib/sequencer/unit/import/zendesk/sub_sequence/base.rb
new file mode 100644
index 000000000..758f3fa3b
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/sub_sequence/base.rb
@@ -0,0 +1,60 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module SubSequence
+ module Base
+ module ClassMethods
+
+ def resource_klass
+ @resource_klass ||= name.split('::').last.singularize
+ end
+ end
+
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.uses :dry_run, :import_job
+ end
+
+ private
+
+ def default_params
+ {
+ dry_run: dry_run,
+ import_job: import_job,
+ }
+ end
+
+ def resource_klass
+ # base.instance_delegate [:resource_klass] => base
+ # doesn't work since we are included and then inherited
+ # there might be multiple inherited hooks which overwrite
+ # each other :/
+ self.class.resource_klass
+ end
+
+ def sequence_name
+ "Import::Zendesk::#{resource_klass}"
+ end
+
+ def resource_iteration(&block)
+ resource_collection.public_send(resource_iteration_method, &block)
+ end
+
+ def resource_collection
+ collection_provider.public_send(resource_collection_attribute)
+ end
+
+ def resource_iteration_method
+ :all!
+ end
+
+ def resource_collection_attribute
+ @resource_collection_attribute ||= resource_klass.pluralize.underscore
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/sub_sequence/mapped.rb b/lib/sequencer/unit/import/zendesk/sub_sequence/mapped.rb
new file mode 100644
index 000000000..1c3d1d111
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/sub_sequence/mapped.rb
@@ -0,0 +1,80 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module SubSequence
+ module Mapped
+ module ClassMethods
+
+ def resource_map
+ "#{resource_klass.underscore}_map".to_sym
+ end
+
+ def inherited(base)
+ base.provides(base.resource_map)
+
+ base.extend(Forwardable)
+ base.instance_delegate [:resource_map] => base
+ end
+ end
+
+ def self.included(base)
+ base.uses :client
+
+ base.extend(ClassMethods)
+ end
+
+ def process
+ state.provide(resource_map) do
+ process_sub_sequence
+ mapping
+ end
+ end
+
+ private
+
+ def expecting
+ raise 'Missing implementation of expecting method'
+ end
+
+ def collection_provider
+ client
+ end
+
+ def process_sub_sequence
+ resource_iteration do |resource|
+
+ expected_value = expected(resource)
+
+ next if expected_value.blank?
+
+ mapping[resource.id] = mapping_value(expected_value)
+ end
+ end
+
+ def expected(resource)
+ result = sub_sequence(resource)
+ result[expecting]
+ end
+
+ def sub_sequence(resource)
+ ::Sequencer.process(sequence_name,
+ parameters: default_params.merge(
+ resource: resource
+ ),
+ expecting: [expecting])
+ end
+
+ def mapping_value(expected_value)
+ expected_value
+ end
+
+ def mapping
+ @mapping ||= {}
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/sub_sequence/object.rb b/lib/sequencer/unit/import/zendesk/sub_sequence/object.rb
new file mode 100644
index 000000000..a73d35bbf
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/sub_sequence/object.rb
@@ -0,0 +1,24 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module SubSequence
+ class Object < Sequencer::Unit::Base
+ include ::Sequencer::Unit::Import::Zendesk::SubSequence::Base
+ include ::Sequencer::Unit::Import::Zendesk::SubSequence::Mapped
+
+ private
+
+ def expecting
+ :instance
+ end
+
+ def mapping_value(expected_value)
+ expected_value.id
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/sub_sequence/object_fields.rb b/lib/sequencer/unit/import/zendesk/sub_sequence/object_fields.rb
new file mode 100644
index 000000000..c3dc1eedb
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/sub_sequence/object_fields.rb
@@ -0,0 +1,20 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module SubSequence
+ class ObjectFields < Sequencer::Unit::Base
+ include ::Sequencer::Unit::Import::Zendesk::SubSequence::Base
+ include ::Sequencer::Unit::Import::Zendesk::SubSequence::Mapped
+
+ private
+
+ def expecting
+ :sanitized_name
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/sub_sequence/sub_object.rb b/lib/sequencer/unit/import/zendesk/sub_sequence/sub_object.rb
new file mode 100644
index 000000000..12ce1ee8f
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/sub_sequence/sub_object.rb
@@ -0,0 +1,39 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module SubSequence
+ class SubObject < Sequencer::Unit::Base
+ include ::Sequencer::Unit::Import::Zendesk::SubSequence::Base
+
+ uses :resource, :instance, :user_id, :model_class
+
+ def process
+ resource_iteration do |sub_resource|
+
+ ::Sequencer.process(sequence_name,
+ parameters: default_params.merge(
+ resource: sub_resource
+ ),)
+ end
+ end
+
+ private
+
+ def collection_provider
+ resource
+ end
+
+ def default_params
+ super.merge(
+ instance: instance,
+ user_id: user_id,
+ model_class: model_class,
+ )
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/sub_sequence/ticket_sub_object.rb b/lib/sequencer/unit/import/zendesk/sub_sequence/ticket_sub_object.rb
new file mode 100644
index 000000000..30e752462
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/sub_sequence/ticket_sub_object.rb
@@ -0,0 +1,18 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module SubSequence
+ class TicketSubObject < Sequencer::Unit::Import::Zendesk::SubSequence::SubObject
+
+ private
+
+ def sequence_name
+ "Import::Zendesk::Ticket::#{resource_klass}"
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/attachment/add.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/attachment/add.rb
new file mode 100644
index 000000000..abe9fadab
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/comment/attachment/add.rb
@@ -0,0 +1,37 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ module Comment
+ module Attachment
+ class Add < Sequencer::Unit::Base
+ prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
+ include ::Sequencer::Unit::Import::Common::Model::Mixin::HandleFailure
+
+ skip_action :skipped
+
+ uses :instance, :resource, :response, :model_class
+
+ def process
+ ::Store.add(
+ object: model_class.name,
+ o_id: instance.id,
+ data: response.body,
+ filename: resource.file_name,
+ preferences: {
+ 'Content-Type' => resource.content_type
+ },
+ created_by_id: 1
+ )
+ rescue => e
+ handle_failure(e)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/attachment/request.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/attachment/request.rb
new file mode 100644
index 000000000..b7322ca69
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/comment/attachment/request.rb
@@ -0,0 +1,51 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ module Comment
+ module Attachment
+ class Request < Sequencer::Unit::Base
+ prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
+
+ skip_action :skipped
+
+ uses :resource
+ provides :response, :action
+
+ def process
+ if failed?
+ state.provide(:action, :skipped)
+ else
+ state.provide(:response, response)
+ end
+ end
+
+ private
+
+ def failed?
+ return false if response.success?
+ logger.error response.error
+ true
+ end
+
+ def response
+ @response ||= begin
+ UserAgent.get(
+ resource.content_url,
+ {},
+ {
+ open_timeout: 10,
+ read_timeout: 60,
+ },
+ )
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/attachments.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/attachments.rb
new file mode 100644
index 000000000..f3d318476
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/comment/attachments.rb
@@ -0,0 +1,58 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ module Comment
+ class Attachments < Sequencer::Unit::Import::Zendesk::SubSequence::SubObject
+
+ def process
+ # check if we need to import the attachments
+ return if skip?
+ # if so call the original .process from SubObject class
+ super
+ end
+
+ private
+
+ # for better readability
+ alias remote_attachments resource_collection
+
+ # for better readability
+ def local_attachments
+ instance.attachments
+ end
+
+ def skip?
+ ensure_common_ground
+ attachments_equal?
+ end
+
+ def ensure_common_ground
+ return if common_ground?
+ local_attachments.each(&:delete)
+ end
+
+ def common_ground?
+ return false if remote_attachments.blank?
+ attachments_equal?
+ end
+
+ def attachments_equal?
+ remote_attachments.count == local_attachments.count
+ end
+
+ def sequence_name
+ "Import::Zendesk::Ticket::Comment::#{resource_klass}"
+ end
+
+ def resource_iteration_method
+ :each
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/from.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/from.rb
new file mode 100644
index 000000000..72f13b09a
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/comment/from.rb
@@ -0,0 +1,24 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ module Comment
+ class From < Sequencer::Unit::Import::Zendesk::Ticket::Comment::SourceBased
+
+ private
+
+ def email
+ resource.via.source.from.address
+ end
+
+ def facebook
+ resource.via.source.from.facebook_id
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/mapping.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/mapping.rb
new file mode 100644
index 000000000..0f728ba17
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/comment/mapping.rb
@@ -0,0 +1,36 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ module Comment
+ class Mapping < Sequencer::Unit::Base
+ include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
+
+ uses :instance, :resource, :user_id, :from, :to, :article_sender_id, :article_type_id
+ provides :mapped
+
+ def process
+ provide_mapped do
+ {
+ from: from,
+ to: to,
+ ticket_id: instance.id,
+ body: resource.html_body,
+ content_type: 'text/html',
+ internal: !resource.public,
+ message_id: resource.id,
+ updated_by_id: user_id,
+ created_by_id: user_id,
+ sender_id: article_sender_id,
+ type_id: article_type_id,
+ }
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/source_based.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/source_based.rb
new file mode 100644
index 000000000..ee130de05
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/comment/source_based.rb
@@ -0,0 +1,22 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ module Comment
+ class SourceBased < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource
+
+ def value
+ method_name = resource.via.channel.to_sym
+ return if !respond_to?(method_name, true)
+ send(method_name)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/to.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/to.rb
new file mode 100644
index 000000000..e595f94e3
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/comment/to.rb
@@ -0,0 +1,25 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ module Comment
+ class To < Sequencer::Unit::Import::Zendesk::Ticket::Comment::SourceBased
+
+ private
+
+ def email
+ # Notice resource.via.from.original_recipients = [\"another@gmail.com\", \"support@example.zendesk.com\"]
+ resource.via.source.to.address
+ end
+
+ def facebook
+ resource.via.source.to.facebook_id
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/unset_instance.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/unset_instance.rb
new file mode 100644
index 000000000..063444ddd
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/comment/unset_instance.rb
@@ -0,0 +1,16 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ module Comment
+ class UnsetInstance < Sequencer::Unit::Common::UnsetAttributes
+
+ uses :instance
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/comment/user_id.rb b/lib/sequencer/unit/import/zendesk/ticket/comment/user_id.rb
new file mode 100644
index 000000000..fc5e8f472
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/comment/user_id.rb
@@ -0,0 +1,23 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ module Comment
+ class UserID < Sequencer::Unit::Base
+
+ uses :resource, :user_map
+ provides :user_id
+
+ def process
+ state.provide(:user_id) do
+ user_map.fetch(resource.author_id, 1)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/comments.rb b/lib/sequencer/unit/import/zendesk/ticket/comments.rb
new file mode 100644
index 000000000..469a4bac8
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/comments.rb
@@ -0,0 +1,22 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ class Comments < Sequencer::Unit::Import::Zendesk::SubSequence::TicketSubObject
+
+ uses :user_map
+
+ private
+
+ def default_params
+ super.merge(
+ user_map: user_map,
+ )
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/custom_fields.rb b/lib/sequencer/unit/import/zendesk/ticket/custom_fields.rb
new file mode 100644
index 000000000..fb6970c03
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/custom_fields.rb
@@ -0,0 +1,28 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ class CustomFields < Sequencer::Unit::Import::Zendesk::Common::CustomFields
+
+ uses :ticket_field_map
+
+ private
+
+ def remote_fields
+ custom_fields = resource.custom_fields
+ return {} if custom_fields.blank?
+
+ custom_fields.map do |custom_field|
+ [
+ ticket_field_map[ custom_field['id'] ].to_sym, # remote_name
+ custom_field['value']
+ ]
+ end.to_h
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/group_id.rb b/lib/sequencer/unit/import/zendesk/ticket/group_id.rb
new file mode 100644
index 000000000..5ae1e5617
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/group_id.rb
@@ -0,0 +1,20 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ class GroupID < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource, :group_map
+
+ private
+
+ def group_id
+ group_map.fetch(resource.group_id, 1)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/mapping.rb b/lib/sequencer/unit/import/zendesk/ticket/mapping.rb
new file mode 100644
index 000000000..bf1e5cebd
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/mapping.rb
@@ -0,0 +1,41 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ class Mapping < Sequencer::Unit::Base
+ include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
+
+ uses :resource, :user_id, :owner_id, :group_id,
+ :organization_id, :priority_id, :state_id,
+ :article_sender_id, :article_type_id,
+ :subject
+
+ def process
+ provide_mapped do
+ {
+ id: resource.id,
+ title: subject,
+ owner_id: owner_id,
+ note: resource.description,
+ group_id: group_id,
+ customer_id: user_id,
+ organization_id: organization_id,
+ priority_id: priority_id,
+ state_id: state_id,
+ pending_time: resource.due_at,
+ updated_at: resource.updated_at,
+ created_at: resource.created_at,
+ updated_by_id: user_id,
+ created_by_id: user_id,
+ create_article_sender_id: article_sender_id,
+ create_article_type_id: article_type_id,
+ }
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/organization_id.rb b/lib/sequencer/unit/import/zendesk/ticket/organization_id.rb
new file mode 100644
index 000000000..514b5a888
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/organization_id.rb
@@ -0,0 +1,20 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ class OrganizationID < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource, :organization_map
+
+ private
+
+ def organization_id
+ organization_map[resource.organization_id]
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/owner_id.rb b/lib/sequencer/unit/import/zendesk/ticket/owner_id.rb
new file mode 100644
index 000000000..232ac6130
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/owner_id.rb
@@ -0,0 +1,20 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ class OwnerID < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource, :user_map
+
+ private
+
+ def owner_id
+ user_map.fetch(resource.assignee, 1)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/priority_id.rb b/lib/sequencer/unit/import/zendesk/ticket/priority_id.rb
new file mode 100644
index 000000000..7d19a8707
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/priority_id.rb
@@ -0,0 +1,34 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ class PriorityID < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource
+
+ private
+
+ def priority_id
+ ::Ticket::Priority.select(:id).find_by(name: local).id
+ end
+
+ def local
+ mapping.fetch(resource.priority, mapping[nil])
+ end
+
+ def mapping
+ {
+ 'low' => '1 low',
+ nil => '2 normal',
+ 'normal' => '2 normal',
+ 'high' => '3 high',
+ 'urgent' => '3 high',
+ }.freeze
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/state_id.rb b/lib/sequencer/unit/import/zendesk/ticket/state_id.rb
new file mode 100644
index 000000000..e6336a955
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/state_id.rb
@@ -0,0 +1,32 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ class StateID < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource
+
+ private
+
+ def state_id
+ ::Ticket::State.select(:id).find_by(name: local).id
+ end
+
+ def local
+ mapping.fetch(resource.status, resource.status)
+ end
+
+ def mapping
+ {
+ 'pending' => 'pending reminder',
+ 'solved' => 'closed',
+ 'deleted' => 'removed',
+ }.freeze
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/subject.rb b/lib/sequencer/unit/import/zendesk/ticket/subject.rb
new file mode 100644
index 000000000..f4a8dd29a
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/subject.rb
@@ -0,0 +1,20 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ class Subject < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource
+
+ private
+
+ def subject
+ resource.subject || resource.description || '-'
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/tag/item.rb b/lib/sequencer/unit/import/zendesk/ticket/tag/item.rb
new file mode 100644
index 000000000..ac9521da4
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/tag/item.rb
@@ -0,0 +1,20 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ module Tag
+ class Item < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource
+
+ def item
+ resource.id
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/tags.rb b/lib/sequencer/unit/import/zendesk/ticket/tags.rb
new file mode 100644
index 000000000..a91fd04c8
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/tags.rb
@@ -0,0 +1,12 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ class Tags < Sequencer::Unit::Import::Zendesk::SubSequence::TicketSubObject
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket/user_id.rb b/lib/sequencer/unit/import/zendesk/ticket/user_id.rb
new file mode 100644
index 000000000..84d8d9bcf
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket/user_id.rb
@@ -0,0 +1,20 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module Ticket
+ class UserID < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource, :user_map
+
+ private
+
+ def user_id
+ user_map.fetch(resource.requester_id, 1)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket_field/add.rb b/lib/sequencer/unit/import/zendesk/ticket_field/add.rb
new file mode 100644
index 000000000..0522ec456
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket_field/add.rb
@@ -0,0 +1,17 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module TicketField
+ class Add < Sequencer::Unit::Import::Zendesk::ObjectAttribute::Add
+ prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
+
+ skip_action :skipped
+
+ uses :action
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket_field/check_custom.rb b/lib/sequencer/unit/import/zendesk/ticket_field/check_custom.rb
new file mode 100644
index 000000000..2a5e03a74
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket_field/check_custom.rb
@@ -0,0 +1,43 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module TicketField
+ class CheckCustom < Sequencer::Unit::Base
+
+ uses :resource, :model_class
+ provides :action
+
+ def process
+ return if custom?
+ state.provide(:action, :skipped)
+ end
+
+ private
+
+ def custom?
+ model_class.column_names.exclude?(attribute)
+ end
+
+ def attribute
+ mapping.fetch(resource.type, resource.type)
+ end
+
+ def mapping
+ {
+ 'subject' => 'title',
+ 'description' => 'note',
+ 'status' => 'state_id',
+ 'tickettype' => 'type',
+ 'priority' => 'priority_id',
+ 'basic_priority' => 'priority_id',
+ 'group' => 'group_id',
+ 'assignee' => 'owner_id',
+ }.freeze
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket_field/sanitized_name.rb b/lib/sequencer/unit/import/zendesk/ticket_field/sanitized_name.rb
new file mode 100644
index 000000000..e35ba2ce9
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket_field/sanitized_name.rb
@@ -0,0 +1,27 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module TicketField
+ class SanitizedName < Sequencer::Unit::Import::Common::ObjectAttribute::SanitizedName
+ prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
+
+ skip_action :skipped
+
+ uses :resource, :action
+
+ private
+
+ def unsanitized_name
+ # Model ID
+ # Model IDs
+ # Model / Name
+ # Model Name
+ resource.title
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/ticket_fields.rb b/lib/sequencer/unit/import/zendesk/ticket_fields.rb
new file mode 100644
index 000000000..01ab5d93c
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/ticket_fields.rb
@@ -0,0 +1,10 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ class TicketFields < Sequencer::Unit::Import::Zendesk::SubSequence::ObjectFields
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/tickets.rb b/lib/sequencer/unit/import/zendesk/tickets.rb
new file mode 100644
index 000000000..075ee4772
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/tickets.rb
@@ -0,0 +1,77 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ class Tickets < Sequencer::Unit::Import::Zendesk::SubSequence::Object
+
+ uses :user_map, :organization_map, :group_map, :ticket_field_map
+
+ private
+
+ def default_params
+ super.merge(
+ user_map: user_map,
+ group_map: group_map,
+ organization_map: organization_map,
+ ticket_field_map: ticket_field_map,
+ )
+ end
+
+ def resource_iteration
+ super do |record|
+ # call passed/originally intended block
+ yield(record)
+
+ # add hook to check if ticket count
+ # update is needed because the request
+ # might have changed
+ update_ticket_count
+ end
+ end
+
+ # The source if this is the limitation of not knowing
+ # how much tickets there are in total before requesting the endpoint
+ # This is caused by the Zendesk API which only returns max. 1000
+ # per request
+ def update_ticket_count
+ update_import_job
+ previous_page = next_page
+ end
+
+ attr_accessor :previous_page
+
+ def update_import_job
+ return if !update_required?
+ state.provide(import_job, updated_import_job)
+ end
+
+ def updated_import_job
+ import_job.result[:Tickets].merge(
+ total: import_job.result[:Tickets][:total] + current_request_count
+ )
+ end
+
+ def update_required?
+ return false if previous_page.blank?
+ return false if previous_page == next_page
+ current_request_count.present?
+ end
+
+ def current_request_count
+ # access the internal instance method of the
+ # Zendesk collection request to get the current
+ # count of the endpoint (max. 1000)
+ resource_collection_attribute.instance_variable_get(:@count)
+ end
+
+ def next_page
+ # access the internal instance method of the
+ # Zendesk collection request to get the next
+ # page number of the endpoint
+ resource_collection_attribute.instance_variable_get(:@next_page)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/user/custom_fields.rb b/lib/sequencer/unit/import/zendesk/user/custom_fields.rb
new file mode 100644
index 000000000..2b9986e98
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/user/custom_fields.rb
@@ -0,0 +1,18 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module User
+ class CustomFields < Sequencer::Unit::Import::Zendesk::Common::CustomFields
+
+ private
+
+ def remote_fields
+ resource.user_fields
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/user/groups.rb b/lib/sequencer/unit/import/zendesk/user/groups.rb
new file mode 100644
index 000000000..a3a5d9f50
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/user/groups.rb
@@ -0,0 +1,27 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module User
+ class Groups < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource, :group_map, :user_group_map
+
+ private
+
+ def groups
+ remote_ids.map { |remote_id| group_map[remote_id] }
+ .compact
+ .map { |local_id| ::Group.find(local_id) }
+ end
+
+ def remote_ids
+ return [] if user_group_map.blank?
+ user_group_map.fetch(resource.id, [])
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/user/image_source.rb b/lib/sequencer/unit/import/zendesk/user/image_source.rb
new file mode 100644
index 000000000..1a68db5ce
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/user/image_source.rb
@@ -0,0 +1,20 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module User
+ class ImageSource < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource
+
+ private
+
+ def image_source
+ resource&.photo&.content_url
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/user/initiator.rb b/lib/sequencer/unit/import/zendesk/user/initiator.rb
new file mode 100644
index 000000000..8f91258b8
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/user/initiator.rb
@@ -0,0 +1,26 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module User
+ class Initiator < Sequencer::Unit::Base
+
+ uses :resource
+ provides :initiator
+
+ def process
+ state.provide(:initiator, initiator?)
+ end
+
+ private
+
+ def initiator?
+ return false if resource.email.blank?
+ resource.email == Setting.get('import_zendesk_endpoint_username')
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/user/login.rb b/lib/sequencer/unit/import/zendesk/user/login.rb
new file mode 100644
index 000000000..d03d8c5fc
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/user/login.rb
@@ -0,0 +1,21 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module User
+ class Login < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource
+
+ private
+
+ def login
+ # Zendesk users may have no other identifier than the ID, e.g. twitter users
+ resource.email || resource.id.to_s
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/user/mapping.rb b/lib/sequencer/unit/import/zendesk/user/mapping.rb
new file mode 100644
index 000000000..0f69176bf
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/user/mapping.rb
@@ -0,0 +1,35 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module User
+ class Mapping < Sequencer::Unit::Base
+ include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
+
+ uses :resource, :login, :password, :roles, :groups, :organization_id, :image_source
+
+ def process
+ provide_mapped do
+ {
+ login: login,
+ firstname: resource.name,
+ email: resource.email,
+ phone: resource.phone,
+ password: password,
+ active: !resource.suspended,
+ groups: groups,
+ roles: roles,
+ note: resource.notes,
+ verified: resource.verified,
+ organization_id: organization_id,
+ last_login: resource.last_login_at,
+ image_source: image_source,
+ }
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/user/organization_id.rb b/lib/sequencer/unit/import/zendesk/user/organization_id.rb
new file mode 100644
index 000000000..5fd7708f4
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/user/organization_id.rb
@@ -0,0 +1,22 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module User
+ class OrganizationID < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource, :organization_map
+
+ private
+
+ def organization_id
+ remote_id = resource.organization_id
+ return if remote_id.blank?
+ organization_map[remote_id]
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/user/password.rb b/lib/sequencer/unit/import/zendesk/user/password.rb
new file mode 100644
index 000000000..cb2b6a6ff
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/user/password.rb
@@ -0,0 +1,26 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module User
+ class Password < Sequencer::Unit::Common::Provider::Named
+
+ uses :initiator
+
+ private
+
+ def password
+ # set the used import key as the admin password
+ # since we have no other confidential value
+ # that is known to Zammad and the User
+ return Setting.get('import_zendesk_endpoint_key') if initiator
+ # otherwise set an empty password so the user
+ # has to re-set a new password for Zammad
+ ''
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/user/roles.rb b/lib/sequencer/unit/import/zendesk/user/roles.rb
new file mode 100644
index 000000000..ed9cdb6db
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/user/roles.rb
@@ -0,0 +1,60 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ module User
+ class Roles < Sequencer::Unit::Common::Provider::Named
+
+ uses :resource, :initiator
+
+ private
+
+ def roles
+ return admin if initiator
+ map_roles
+ end
+
+ def map_roles
+ return send(zendesk_role) if respond_to?(zendesk_role, true)
+ logger.error "Unknown mapping for role '#{resource.role.name}' (method: #{zendesk_role})"
+ end_user
+ end
+
+ def zendesk_role
+ @zendesk_role ||= resource.role.name.tr('-', '_').to_sym
+ end
+
+ def end_user
+ [role_customer]
+ end
+
+ def agent
+ return [role_agent] if resource.restricted_agent
+ admin
+ end
+
+ def admin
+ [role_admin, role_agent]
+ end
+
+ def role_admin
+ @role_admin ||= lookup('Admin')
+ end
+
+ def role_agent
+ @role_agent ||= lookup('Agent')
+ end
+
+ def role_customer
+ @role_customer ||= lookup('Customer')
+ end
+
+ def lookup(role_name)
+ ::Role.lookup(name: role_name)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/user_fields.rb b/lib/sequencer/unit/import/zendesk/user_fields.rb
new file mode 100644
index 000000000..12992a039
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/user_fields.rb
@@ -0,0 +1,10 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ class UserFields < Sequencer::Unit::Import::Zendesk::SubSequence::ObjectFields
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/user_group_map.rb b/lib/sequencer/unit/import/zendesk/user_group_map.rb
new file mode 100644
index 000000000..d9a6bd19a
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/user_group_map.rb
@@ -0,0 +1,28 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ class UserGroupMap < Sequencer::Unit::Base
+
+ uses :client
+ provides :user_group_map
+
+ def process
+ state.provide(:user_group_map, mapping)
+ end
+
+ private
+
+ def mapping
+ result = {}
+ client.group_memberships.all! do |group_membership|
+ result[ group_membership.user_id ] ||= []
+ result[ group_membership.user_id ].push( group_membership.group_id )
+ end
+ result
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/import/zendesk/users.rb b/lib/sequencer/unit/import/zendesk/users.rb
new file mode 100644
index 000000000..b89b5a9f1
--- /dev/null
+++ b/lib/sequencer/unit/import/zendesk/users.rb
@@ -0,0 +1,22 @@
+class Sequencer
+ class Unit
+ module Import
+ module Zendesk
+ class Users < Sequencer::Unit::Import::Zendesk::SubSequence::Object
+
+ uses :organization_map, :group_map, :user_group_map
+
+ private
+
+ def default_params
+ super.merge(
+ organization_map: organization_map,
+ group_map: group_map,
+ user_group_map: user_group_map,
+ )
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/zendesk/client.rb b/lib/sequencer/unit/zendesk/client.rb
new file mode 100644
index 000000000..ae4054af2
--- /dev/null
+++ b/lib/sequencer/unit/zendesk/client.rb
@@ -0,0 +1,31 @@
+class Sequencer
+ class Unit
+ module Zendesk
+ class Client < Sequencer::Unit::Common::Provider::Fallback
+
+ provides :client
+
+ private
+
+ def client
+ ZendeskAPI::Client.new do |config|
+ config.url = Setting.get('import_zendesk_endpoint')
+
+ # Basic / Token Authentication
+ config.username = Setting.get('import_zendesk_endpoint_username')
+ config.token = Setting.get('import_zendesk_endpoint_key')
+
+ # when hitting the rate limit, sleep automatically,
+ # then retry the request.
+ config.retry = true
+
+ # disable cache to avoid unneeded memory consumption
+ # since we are using each object only once
+ # Inspired by: https://medium.com/swiftype-engineering/using-jmat-to-find-analyze-memory-in-jruby-1c4196c1ec72
+ config.cache = false
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sequencer/unit/zendesk/connected.rb b/lib/sequencer/unit/zendesk/connected.rb
new file mode 100644
index 000000000..7149cc4b3
--- /dev/null
+++ b/lib/sequencer/unit/zendesk/connected.rb
@@ -0,0 +1,16 @@
+class Sequencer
+ class Unit
+ module Zendesk
+ class Connected < Sequencer::Unit::Common::Provider::Named
+
+ uses :client
+
+ private
+
+ def connected
+ client.current_user.id.present?
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/import/base_resource_spec.rb b/spec/lib/import/base_resource_spec.rb
deleted file mode 100644
index d2392051c..000000000
--- a/spec/lib/import/base_resource_spec.rb
+++ /dev/null
@@ -1,149 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Import::BaseResource do
-
- it "needs an implementation of the 'import_class' method" do
- expect do
- described_class.new(attributes_for(:group))
- end.to raise_error(NoMethodError)
- end
-
- context "implemented 'import_class' method" do
-
- before do
- module Import
- class Test < Import::Base
- class Group < Import::BaseResource
-
- def import_class
- ::Group
- end
-
- def source
- 'RSpec-TEST'
- end
- end
- end
- end
- end
-
- after do
- Import::Test.send(:remove_const, :Group)
- end
-
- let(:attributes) do
- attributes = attributes_for(:group)
- attributes[:id] = 1337
- attributes
- end
-
- context 'live run' do
-
- it 'creates new resources' do
- expect do
- Import::Test::Group.new(attributes)
- end
- .to change {
- Group.count
- }.by(1)
- .and change {
- ExternalSync.count
- }.by(1)
- end
-
- it 'updates existing resources' do
-
- # initial import
- Import::Test::Group.new(attributes)
- group = Group.last
-
- # simulate next import run
- travel 20.minutes
-
- attributes[:note] = 'TEST'
-
- expect do
- Import::Test::Group.new(attributes)
- group.reload
- end
- .to change {
- group.note
- }
- end
- end
-
- context 'dry run' do
-
- it "doesn't create new resources" do
- expect do
- Import::Test::Group.new(attributes, dry_run: true)
- end
- .to not_change {
- Group.count
- }
- .and not_change {
- ExternalSync.count
- }
- end
-
- it "doesn't update existing resources" do
-
- # initial import
- Import::Test::Group.new(attributes)
- group = Group.last
-
- # simulate next import run
- travel 20.minutes
-
- attributes[:note] = 'TEST'
-
- expect do
- Import::Test::Group.new(attributes, dry_run: true)
- group.reload
- end
- .to not_change {
- group.note
- }
- .and not_change {
- Group.count
- }
- .and not_change {
- ExternalSync.count
- }
- end
-
- it "doesn't update associations of existing resources" do
-
- # initial import
- Import::Test::Group.new(attributes)
- group = Group.last
-
- old_signature = create(:signature)
- old_users = create_list(:user, 2)
-
- group.update!(signature_id: old_signature.id)
- group.update!(user_ids: old_users.collect(&:id))
-
- # simulate next import run
- travel 20.minutes
-
- new_signature = create(:signature)
- new_users = create_list(:user, 2)
- attributes[:signature_id] = new_signature.id
- attributes[:user_ids] = new_users.collect(&:id)
-
- expect do
- Import::Test::Group.new(attributes, dry_run: true)
- group.reload
- end
- .to not_change {
- group.signature_id
- }
- .and not_change {
- group.user_ids
- }
- end
- end
- end
-
-end
diff --git a/spec/lib/import/zendesk/base_factory_examples.rb b/spec/lib/import/zendesk/base_factory_examples.rb
deleted file mode 100644
index bc38c2063..000000000
--- a/spec/lib/import/zendesk/base_factory_examples.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-require 'lib/import/factory_examples'
-
-RSpec.shared_examples 'Import::Zendesk::BaseFactory' do
- it_behaves_like 'Import::Factory'
-
- it 'calls .all! on parameter object' do
- parameter = double()
- expect(parameter).to receive('all!')
- described_class.import(parameter)
- end
-
- it 'calls new on determined backend object' do
- expect(described_class).to receive(:backend_class).and_return(Class)
- expect(described_class).to receive('skip?')
- expect(described_class).to receive(:pre_import_hook)
- expect(described_class).to receive(:post_import_hook)
- record = double()
- expect(Class).to receive(:new).with(record, any_args)
- parameter = double()
- expect(parameter).to receive('all!').and_yield(record)
- described_class.import(parameter)
- end
-end
diff --git a/spec/lib/import/zendesk/base_factory_spec.rb b/spec/lib/import/zendesk/base_factory_spec.rb
deleted file mode 100644
index d0f00e68a..000000000
--- a/spec/lib/import/zendesk/base_factory_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/base_factory_examples'
-
-RSpec.describe Import::Zendesk::BaseFactory do
- it_behaves_like 'Import::Zendesk::BaseFactory'
-end
diff --git a/spec/lib/import/zendesk/group_factory_spec.rb b/spec/lib/import/zendesk/group_factory_spec.rb
deleted file mode 100644
index dd34d6174..000000000
--- a/spec/lib/import/zendesk/group_factory_spec.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/base_factory_examples'
-require 'lib/import/zendesk/local_id_mapper_hook_examples'
-
-RSpec.describe Import::Zendesk::GroupFactory do
- it_behaves_like 'Import::Zendesk::BaseFactory'
- it_behaves_like 'Import::Zendesk::LocalIDMapperHook'
-end
diff --git a/spec/lib/import/zendesk/group_spec.rb b/spec/lib/import/zendesk/group_spec.rb
deleted file mode 100644
index 014f0e405..000000000
--- a/spec/lib/import/zendesk/group_spec.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Import::Zendesk::Group do
-
- it 'creates a group if not exists' do
-
- group = double(
- id: 31_337,
- name: 'Test Group',
- deleted: true
- )
-
- local_group = instance_double(::Group, id: 1337)
-
- expect(::Group).to receive(:create_if_not_exists).with(hash_including(name: group.name, active: !group.deleted)).and_return(local_group)
-
- created_instance = described_class.new(group)
-
- expect(created_instance).to respond_to(:id)
- expect(created_instance.id).to eq(local_group.id)
-
- expect(created_instance).to respond_to(:zendesk_id)
- expect(created_instance.zendesk_id).to eq(group.id)
- end
-end
diff --git a/spec/lib/import/zendesk/local_id_mapper_hook_examples.rb b/spec/lib/import/zendesk/local_id_mapper_hook_examples.rb
deleted file mode 100644
index 27dfddfe8..000000000
--- a/spec/lib/import/zendesk/local_id_mapper_hook_examples.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-RSpec.shared_examples 'Import::Zendesk::LocalIDMapperHook' do
-
- it 'responds to local_id' do
- expect(described_class).to respond_to('local_id')
- end
-
- it 'responds to post_import_hook' do
- expect(described_class).to respond_to('post_import_hook')
- end
-
- it 'stores an ID mapping and makes it accessable' do
- backend_instance = double(
- zendesk_id: 31_337,
- id: 1337,
- )
-
- described_class.post_import_hook(nil, backend_instance)
- expect(described_class.local_id(backend_instance.zendesk_id)).to eq(backend_instance.id)
- end
-end
diff --git a/spec/lib/import/zendesk/local_id_mapper_hook_spec.rb b/spec/lib/import/zendesk/local_id_mapper_hook_spec.rb
deleted file mode 100644
index bf5c2ff46..000000000
--- a/spec/lib/import/zendesk/local_id_mapper_hook_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/local_id_mapper_hook_examples'
-
-RSpec.describe Import::Zendesk::LocalIDMapperHook do
- it_behaves_like 'Import::Zendesk::LocalIDMapperHook'
-end
diff --git a/spec/lib/import/zendesk/lookup_backend_examples.rb b/spec/lib/import/zendesk/lookup_backend_examples.rb
deleted file mode 100644
index f1e8220ff..000000000
--- a/spec/lib/import/zendesk/lookup_backend_examples.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-RSpec.shared_examples 'Lookup backend' do
- it 'responds to lookup' do
- expect(described_class).to respond_to('lookup')
- end
-end
diff --git a/spec/lib/import/zendesk/object_attribute_spec.rb b/spec/lib/import/zendesk/object_attribute/base_spec.rb
similarity index 94%
rename from spec/lib/import/zendesk/object_attribute_spec.rb
rename to spec/lib/import/zendesk/object_attribute/base_spec.rb
index 0539fa263..a253f0ce0 100644
--- a/spec/lib/import/zendesk/object_attribute_spec.rb
+++ b/spec/lib/import/zendesk/object_attribute/base_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-RSpec.describe Import::Zendesk::ObjectAttribute do
+RSpec.describe Import::Zendesk::ObjectAttribute::Base do
it 'extends ObjectManager Attribute exception text' do
diff --git a/spec/lib/import/zendesk/object_field_examples.rb b/spec/lib/import/zendesk/object_field_examples.rb
deleted file mode 100644
index 6ad9993d6..000000000
--- a/spec/lib/import/zendesk/object_field_examples.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-RSpec.shared_examples 'Import::Zendesk::ObjectField' do
-
- it 'initializes a object field backend import' do
-
- object_field = double(id: 31_337, title: 'Example Field')
- allow(object_field).to receive(:[]).with('key').and_return(object_field.title)
-
- dummy_instance = double()
-
- local_name = 'example_field'
- dummy_backend = instance_double(Class)
- expect(dummy_backend).to receive(:new).with(kind_of(String), local_name, object_field).and_return(dummy_instance)
- expect_any_instance_of(described_class).to receive(:backend_class).and_return(dummy_backend)
- created_instance = described_class.new(object_field)
-
- expect(created_instance).to respond_to(:id)
- expect(created_instance.id).to eq(local_name)
-
- expect(created_instance).to respond_to(:zendesk_id)
- expect(created_instance.zendesk_id).to eq(object_field.id)
- end
-end
diff --git a/spec/lib/import/zendesk/object_field_spec.rb b/spec/lib/import/zendesk/object_field_spec.rb
deleted file mode 100644
index 035129ddb..000000000
--- a/spec/lib/import/zendesk/object_field_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/object_field_examples'
-
-RSpec.describe Import::Zendesk::ObjectField do
- it_behaves_like 'Import::Zendesk::ObjectField'
-end
diff --git a/spec/lib/import/zendesk/organization_factory_spec.rb b/spec/lib/import/zendesk/organization_factory_spec.rb
deleted file mode 100644
index 380ccb064..000000000
--- a/spec/lib/import/zendesk/organization_factory_spec.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'rails_helper'
-require 'lib/import/factory_examples'
-require 'lib/import/zendesk/local_id_mapper_hook_examples'
-
-RSpec.describe Import::Zendesk::OrganizationFieldFactory do
- it_behaves_like 'Import::Factory'
- it_behaves_like 'Import::Zendesk::LocalIDMapperHook'
-end
diff --git a/spec/lib/import/zendesk/organization_field_factory_spec.rb b/spec/lib/import/zendesk/organization_field_factory_spec.rb
deleted file mode 100644
index d48fb5ccb..000000000
--- a/spec/lib/import/zendesk/organization_field_factory_spec.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/base_factory_examples'
-require 'lib/import/zendesk/local_id_mapper_hook_examples'
-
-RSpec.describe Import::Zendesk::OrganizationFieldFactory do
- it_behaves_like 'Import::Zendesk::BaseFactory'
- it_behaves_like 'Import::Zendesk::LocalIDMapperHook'
-end
diff --git a/spec/lib/import/zendesk/organization_field_spec.rb b/spec/lib/import/zendesk/organization_field_spec.rb
deleted file mode 100644
index 01b6264ef..000000000
--- a/spec/lib/import/zendesk/organization_field_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/object_field_examples'
-
-RSpec.describe Import::Zendesk::OrganizationField do
- it_behaves_like 'Import::Zendesk::ObjectField'
-end
diff --git a/spec/lib/import/zendesk/organization_spec.rb b/spec/lib/import/zendesk/organization_spec.rb
deleted file mode 100644
index 24ba4f850..000000000
--- a/spec/lib/import/zendesk/organization_spec.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Import::Zendesk::Organization do
-
- it 'creates a organization if not exists' do
-
- organization = double(
- id: 31_337,
- name: 'Test Organization',
- note: 'Test Organization note',
- shared_tickets: true,
- organization_fields: nil
- )
-
- local_organization = instance_double(::Organization, id: 1337)
-
- expect(::Organization).to receive(:create_if_not_exists).with(hash_including(name: organization.name, note: organization.note, shared: organization.shared_tickets)).and_return(local_organization)
-
- created_instance = described_class.new(organization)
-
- expect(created_instance).to respond_to(:id)
- expect(created_instance).to respond_to(:zendesk_id)
-
- expect(created_instance.id).to eq(local_organization.id)
- expect(created_instance.zendesk_id).to eq(organization.id)
- end
-end
diff --git a/spec/lib/import/zendesk/priority_spec.rb b/spec/lib/import/zendesk/priority_spec.rb
deleted file mode 100644
index 711d8cc96..000000000
--- a/spec/lib/import/zendesk/priority_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/lookup_backend_examples'
-
-RSpec.describe Import::Zendesk::Priority do
- it_behaves_like 'Lookup backend'
-
- it 'looks up ticket priority' do
-
- ticket = double(priority: nil)
- dummy_result = 'dummy result'
- expect(::Ticket::Priority).to receive(:lookup).and_return(dummy_result)
- expect(described_class.lookup(ticket)).to eq(dummy_result)
- end
-end
diff --git a/spec/lib/import/zendesk/state_spec.rb b/spec/lib/import/zendesk/state_spec.rb
deleted file mode 100644
index efcb4622a..000000000
--- a/spec/lib/import/zendesk/state_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/lookup_backend_examples'
-
-RSpec.describe Import::Zendesk::State do
- it_behaves_like 'Lookup backend'
-
- it 'looks up ticket state' do
-
- ticket = double(status: nil)
- dummy_result = 'dummy result'
- expect(::Ticket::State).to receive(:lookup).and_return(dummy_result)
- expect(described_class.lookup(ticket)).to eq(dummy_result)
- end
-end
diff --git a/spec/lib/import/zendesk/ticket/comment/attachment_factory_spec.rb b/spec/lib/import/zendesk/ticket/comment/attachment_factory_spec.rb
deleted file mode 100644
index 706d6ba64..000000000
--- a/spec/lib/import/zendesk/ticket/comment/attachment_factory_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require 'rails_helper'
-require 'lib/import/factory_examples'
-
-RSpec.describe Import::Zendesk::Ticket::Comment::AttachmentFactory do
- it_behaves_like 'Import::Factory'
-
- it 'tunnels attachment and local article to backend' do
- expect(described_class).to receive(:backend_class).and_return(Class)
- expect(described_class).to receive('skip?')
- expect(described_class).to receive(:pre_import_hook)
- expect(described_class).to receive(:post_import_hook)
- record = double()
- local_article = double(attachments: [])
- expect(Class).to receive(:new).with(record, local_article)
- parameter = [record]
- described_class.import(parameter, local_article)
- end
-end
diff --git a/spec/lib/import/zendesk/ticket/comment/attachment_spec.rb b/spec/lib/import/zendesk/ticket/comment/attachment_spec.rb
deleted file mode 100644
index 5376e8059..000000000
--- a/spec/lib/import/zendesk/ticket/comment/attachment_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Import::Zendesk::Ticket::Comment::Attachment do
-
- it 'downloads and stores attachments' do
-
- local_article = double(id: 1337)
-
- attachment = double(
- file_name: 'Example.zip',
- content_type: 'application/zip',
- content_url: 'https://dl.remote.tld/394r0eifwskfjwlw3slf'
- )
-
- response = double(
- body: 'content',
- success?: true,
- )
-
- expect(UserAgent).to receive(:get).with(attachment.content_url, any_args).and_return(response)
-
- add_args = {
- object: 'Ticket::Article',
- o_id: local_article.id,
- data: response.body,
- filename: attachment.file_name,
- preferences: {
- 'Content-Type' => attachment.content_type
- },
- created_by_id: 1
- }
-
- expect(Store).to receive(:add).with(add_args)
-
- described_class.new(attachment, local_article)
- end
-end
diff --git a/spec/lib/import/zendesk/ticket/comment/local_id_lookup_backend_examples.rb b/spec/lib/import/zendesk/ticket/comment/local_id_lookup_backend_examples.rb
deleted file mode 100644
index 254eaaa9b..000000000
--- a/spec/lib/import/zendesk/ticket/comment/local_id_lookup_backend_examples.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-require 'rails_helper'
-
-RSpec.shared_examples 'local_id lookup backend' do
- it 'responds to local_id' do
- expect(described_class).to respond_to(:local_id)
- end
-end
diff --git a/spec/lib/import/zendesk/ticket/comment/sender_spec.rb b/spec/lib/import/zendesk/ticket/comment/sender_spec.rb
deleted file mode 100644
index af88a3380..000000000
--- a/spec/lib/import/zendesk/ticket/comment/sender_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/ticket/comment/local_id_lookup_backend_examples'
-
-RSpec.describe Import::Zendesk::Ticket::Comment::Sender do
- it_behaves_like 'local_id lookup backend'
-end
diff --git a/spec/lib/import/zendesk/ticket/comment/type_spec.rb b/spec/lib/import/zendesk/ticket/comment/type_spec.rb
deleted file mode 100644
index 526ceb8a6..000000000
--- a/spec/lib/import/zendesk/ticket/comment/type_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/ticket/comment/local_id_lookup_backend_examples'
-
-RSpec.describe Import::Zendesk::Ticket::Comment::Type do
- it_behaves_like 'local_id lookup backend'
-end
diff --git a/spec/lib/import/zendesk/ticket/comment_factory_spec.rb b/spec/lib/import/zendesk/ticket/comment_factory_spec.rb
deleted file mode 100644
index 13ab0aa82..000000000
--- a/spec/lib/import/zendesk/ticket/comment_factory_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/ticket/sub_object_factory_examples'
-
-RSpec.describe Import::Zendesk::Ticket::CommentFactory do
- it_behaves_like 'Import::Zendesk::Ticket::SubObjectFactory'
-end
diff --git a/spec/lib/import/zendesk/ticket/comment_spec.rb b/spec/lib/import/zendesk/ticket/comment_spec.rb
deleted file mode 100644
index 354f057d4..000000000
--- a/spec/lib/import/zendesk/ticket/comment_spec.rb
+++ /dev/null
@@ -1,637 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Import::Zendesk::Ticket::Comment do
-
- context 'email' do
-
- it 'creates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: ' Hello World! ',
- via: double(
- channel: 'email',
- source: double(
- from: double(address: 'from@sender.tld'),
- to: double(address: 'to@receiver.tld')
- ),
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- create_structure = {
- from: comment.via.source.from.address,
- to: comment.via.source.to.address,
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 1,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(create_structure[:sender_id])
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id)
-
- expect(::Ticket::Article).to receive(:create).with(create_structure)
-
- described_class.new(comment, local_ticket, nil)
- end
-
- it 'updates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'email',
- source: double(
- from: double(address: 'from@sender.tld'),
- to: double(address: 'to@receiver.tld')
- ),
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- update_structure = {
- from: comment.via.source.from.address,
- to: comment.via.source.to.address,
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 1,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(update_structure[:sender_id])
-
- local_article = double()
- expect(local_article).to receive(:update!).with(update_structure)
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id).and_return(local_article)
-
- described_class.new(comment, local_ticket, nil)
- end
- end
-
- context 'facebook' do
-
- context 'post' do
-
- it 'creates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'facebook',
- source: double(
- from: double(facebook_id: 3_129_033),
- to: double(facebook_id: 1_230_920),
- rel: 'post',
- ),
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- create_structure = {
- from: comment.via.source.from.facebook_id,
- to: comment.via.source.to.facebook_id,
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 8,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(create_structure[:sender_id])
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id)
-
- expect(::Ticket::Article).to receive(:create).with(create_structure)
-
- described_class.new(comment, local_ticket, nil)
- end
-
- it 'updates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'facebook',
- source: double(
- from: double(facebook_id: 3_129_033),
- to: double(facebook_id: 1_230_920),
- rel: 'post',
- ),
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- update_structure = {
- from: comment.via.source.from.facebook_id,
- to: comment.via.source.to.facebook_id,
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 8,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(update_structure[:sender_id])
-
- local_article = double()
- expect(local_article).to receive(:update!).with(update_structure)
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id).and_return(local_article)
-
- described_class.new(comment, local_ticket, nil)
- end
- end
-
- context 'comment' do
-
- it 'creates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'facebook',
- source: double(
- from: double(facebook_id: 3_129_033),
- to: double(facebook_id: 1_230_920),
- rel: 'comment',
- ),
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- create_structure = {
- from: comment.via.source.from.facebook_id,
- to: comment.via.source.to.facebook_id,
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 9,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(create_structure[:sender_id])
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id)
-
- expect(::Ticket::Article).to receive(:create).with(create_structure)
-
- described_class.new(comment, local_ticket, nil)
- end
-
- it 'updates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'facebook',
- source: double(
- from: double(facebook_id: 3_129_033),
- to: double(facebook_id: 1_230_920),
- rel: 'comment',
- ),
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- update_structure = {
- from: comment.via.source.from.facebook_id,
- to: comment.via.source.to.facebook_id,
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 9,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(update_structure[:sender_id])
-
- local_article = double()
- expect(local_article).to receive(:update!).with(update_structure)
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id).and_return(local_article)
-
- described_class.new(comment, local_ticket, nil)
- end
- end
- end
-
- context 'twitter' do
-
- context 'mention' do
-
- it 'creates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'twitter',
- source: double(
- rel: 'mention',
- ),
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- create_structure = {
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 6,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(create_structure[:sender_id])
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id)
-
- expect(::Ticket::Article).to receive(:create).with(create_structure)
-
- described_class.new(comment, local_ticket, nil)
- end
-
- it 'updates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'twitter',
- source: double(
- rel: 'mention',
- ),
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- update_structure = {
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 6,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(update_structure[:sender_id])
-
- local_article = double()
- expect(local_article).to receive(:update!).with(update_structure)
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id).and_return(local_article)
-
- described_class.new(comment, local_ticket, nil)
- end
- end
-
- context 'direct_message' do
-
- it 'creates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'twitter',
- source: double(
- rel: 'direct_message',
- ),
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- create_structure = {
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 7,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(create_structure[:sender_id])
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id)
-
- expect(::Ticket::Article).to receive(:create).with(create_structure)
-
- described_class.new(comment, local_ticket, nil)
- end
-
- it 'updates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'twitter',
- source: double(
- rel: 'direct_message',
- ),
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- update_structure = {
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 7,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(update_structure[:sender_id])
-
- local_article = double()
- expect(local_article).to receive(:update!).with(update_structure)
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id).and_return(local_article)
-
- described_class.new(comment, local_ticket, nil)
- end
- end
- end
-
- context 'web' do
-
- it 'creates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'web',
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- create_structure = {
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 11,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(create_structure[:sender_id])
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id)
-
- expect(::Ticket::Article).to receive(:create).with(create_structure)
-
- described_class.new(comment, local_ticket, nil)
- end
-
- it 'updates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'web',
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- update_structure = {
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 11,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(update_structure[:sender_id])
-
- local_article = double()
- expect(local_article).to receive(:update!).with(update_structure)
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id).and_return(local_article)
-
- described_class.new(comment, local_ticket, nil)
- end
- end
-
- context 'sample_ticket' do
-
- it 'creates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'sample_ticket',
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- create_structure = {
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 10,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(create_structure[:sender_id])
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id)
-
- expect(::Ticket::Article).to receive(:create).with(create_structure)
-
- described_class.new(comment, local_ticket, nil)
- end
-
- it 'updates' do
-
- comment = double(
- id: 1337,
- author_id: 42,
- public: true,
- html_body: 'Hello World! ',
- via: double(
- channel: 'sample_ticket',
- ),
- attachments: []
- )
-
- local_ticket = double(id: 31_337)
-
- local_user_id = 99
-
- update_structure = {
- ticket_id: local_ticket.id,
- body: comment.html_body,
- content_type: 'text/html',
- internal: !comment.public,
- message_id: comment.id,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- sender_id: 23,
- type_id: 10,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( comment.author_id ).and_return(local_user_id)
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(update_structure[:sender_id])
-
- local_article = double()
- expect(local_article).to receive(:update!).with(update_structure)
-
- expect(::Ticket::Article).to receive(:find_by).with(message_id: comment.id).and_return(local_article)
-
- described_class.new(comment, local_ticket, nil)
- end
- end
-
-end
diff --git a/spec/lib/import/zendesk/ticket/sub_object_factory_examples.rb b/spec/lib/import/zendesk/ticket/sub_object_factory_examples.rb
deleted file mode 100644
index 89564b600..000000000
--- a/spec/lib/import/zendesk/ticket/sub_object_factory_examples.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require 'rails_helper'
-require 'lib/import/factory_examples'
-
-RSpec.shared_examples 'Import::Zendesk::Ticket::SubObjectFactory' do
- it_behaves_like 'Import::Factory'
-
- it 'tunnels local and remote ticket object to backend' do
-
- expect(described_class).to receive(:backend_class).and_return(Class)
- expect(described_class).to receive('skip?')
- expect(described_class).to receive(:pre_import_hook)
- expect(described_class).to receive(:post_import_hook)
- record = double()
- local_ticket = double()
- zendesk_ticket = double()
- expect(Class).to receive(:new).with(record, local_ticket, zendesk_ticket)
- parameter = double()
- expect(parameter).to receive(:each).and_yield(record)
- described_class.import(parameter, local_ticket, zendesk_ticket)
- end
-end
diff --git a/spec/lib/import/zendesk/ticket/tag_factory_spec.rb b/spec/lib/import/zendesk/ticket/tag_factory_spec.rb
deleted file mode 100644
index 9b893b229..000000000
--- a/spec/lib/import/zendesk/ticket/tag_factory_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/ticket/sub_object_factory_examples'
-
-RSpec.describe Import::Zendesk::Ticket::TagFactory do
- it_behaves_like 'Import::Zendesk::Ticket::SubObjectFactory'
-end
diff --git a/spec/lib/import/zendesk/ticket/tag_spec.rb b/spec/lib/import/zendesk/ticket/tag_spec.rb
deleted file mode 100644
index 62bad3e2c..000000000
--- a/spec/lib/import/zendesk/ticket/tag_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require 'rails_helper'
-
-# required due to some of rails autoloading issues
-require 'import/zendesk/ticket/tag'
-
-RSpec.describe Import::Zendesk::Ticket::Tag do
-
- it 'creates ticket tags' do
-
- tag = double(id: 'Test Tag')
-
- local_ticket = instance_double(::Ticket, id: 1337)
-
- zendesk_ticket = double(requester_id: 31_337)
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with(zendesk_ticket.requester_id)
- expect(::Tag).to receive(:tag_add).with(hash_including(item: tag.id, o_id: local_ticket.id))
-
- described_class.new(tag, local_ticket, zendesk_ticket)
- end
-end
diff --git a/spec/lib/import/zendesk/ticket_factory_spec.rb b/spec/lib/import/zendesk/ticket_factory_spec.rb
deleted file mode 100644
index 6bfe6e105..000000000
--- a/spec/lib/import/zendesk/ticket_factory_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/base_factory_examples'
-
-RSpec.describe Import::Zendesk::TicketFactory do
- it_behaves_like 'Import::Zendesk::BaseFactory'
-end
diff --git a/spec/lib/import/zendesk/ticket_field_factory_spec.rb b/spec/lib/import/zendesk/ticket_field_factory_spec.rb
deleted file mode 100644
index f39a2df6e..000000000
--- a/spec/lib/import/zendesk/ticket_field_factory_spec.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/base_factory_examples'
-require 'lib/import/zendesk/local_id_mapper_hook_examples'
-
-RSpec.describe Import::Zendesk::TicketFieldFactory do
- it_behaves_like 'Import::Zendesk::BaseFactory'
- it_behaves_like 'Import::Zendesk::LocalIDMapperHook'
-end
diff --git a/spec/lib/import/zendesk/ticket_field_spec.rb b/spec/lib/import/zendesk/ticket_field_spec.rb
deleted file mode 100644
index 327acc058..000000000
--- a/spec/lib/import/zendesk/ticket_field_spec.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/object_field_examples'
-
-RSpec.describe Import::Zendesk::TicketField do
- it_behaves_like 'Import::Zendesk::ObjectField'
-
- it 'handles fields with dashes in title' do
-
- zendesk_object = double(
- id: 1337,
- title: 'Priority - Simple',
- key: 'priority_simple',
- type: 'text',
- removable: true,
- active: true,
- position: 1,
- required_in_portal: true,
- visible_in_portal: true,
- required: true,
- description: 'Example field',
- )
-
- expect(ObjectManager::Attribute).to receive(:migration_execute).and_return(true)
-
- expect do
- described_class.new(zendesk_object)
- end.not_to raise_error
-
- ObjectManager::Attribute.remove(
- object: 'Ticket',
- name: zendesk_object.key,
- )
- end
-end
diff --git a/spec/lib/import/zendesk/ticket_spec.rb b/spec/lib/import/zendesk/ticket_spec.rb
deleted file mode 100644
index 3ffaec04b..000000000
--- a/spec/lib/import/zendesk/ticket_spec.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-require 'rails_helper'
-
-# required due to some of rails autoloading issues
-require 'import/zendesk/ticket'
-
-RSpec.describe Import::Zendesk::Ticket do
-
- it 'creates' do
-
- ticket = double(
- id: 1337,
- subject: 'The ticket title',
- description: 'An example ticket',
- assignee: 69,
- requester_id: 42,
- group_id: 909,
- organization_id: 101,
- due_at: DateTime.tomorrow,
- updated_at: DateTime.yesterday,
- created_at: DateTime.yesterday,
- tags: [],
- comments: [],
- custom_fields: [],
- )
-
- local_user_id = 23
-
- expected_structure = {
- id: ticket.id,
- title: ticket.subject,
- note: ticket.description,
- group_id: 3,
- owner_id: 101,
- customer_id: local_user_id,
- organization_id: 89,
- state: 13,
- priority: 7,
- pending_time: ticket.due_at,
- updated_at: ticket.updated_at,
- created_at: ticket.created_at,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- create_article_sender_id: 21,
- create_article_type_id: 555,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( ticket.requester_id ).and_return(local_user_id)
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( ticket.assignee ).and_return(expected_structure[:owner_id])
-
- expect(Import::Zendesk::GroupFactory).to receive(:local_id).with( ticket.group_id ).and_return(expected_structure[:group_id])
- expect(Import::Zendesk::OrganizationFactory).to receive(:local_id).with( ticket.organization_id ).and_return(expected_structure[:organization_id])
- expect(Import::Zendesk::Priority).to receive(:lookup).with(ticket).and_return(expected_structure[:priority])
- expect(Import::Zendesk::State).to receive(:lookup).with(ticket).and_return(expected_structure[:state])
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(expected_structure[:create_article_sender_id])
- expect(Import::Zendesk::Ticket::Comment::Type).to receive(:local_id).with(ticket).and_return(expected_structure[:create_article_type_id])
-
- local_ticket = double()
-
- expect(Import::Zendesk::Ticket::TagFactory).to receive(:import).with(ticket.tags, local_ticket, ticket)
- expect(Import::Zendesk::Ticket::CommentFactory).to receive(:import).with(ticket.comments, local_ticket, ticket)
-
- expect(::Ticket).to receive(:find_by).with(id: expected_structure[:id])
- expect(::Ticket).to receive(:create).with(expected_structure).and_return(local_ticket)
-
- expect_any_instance_of(described_class).to receive(:reset_primary_key_sequence)
-
- created_instance = described_class.new(ticket)
- end
-
- it 'updates' do
-
- ticket = double(
- id: 1337,
- subject: 'The ticket title',
- description: 'An example ticket',
- assignee: 69,
- requester_id: 42,
- group_id: 909,
- organization_id: 101,
- due_at: DateTime.tomorrow,
- updated_at: DateTime.yesterday,
- created_at: DateTime.yesterday,
- tags: [],
- comments: [],
- custom_fields: [],
- )
-
- local_user_id = 23
-
- expected_structure = {
- id: ticket.id,
- title: ticket.subject,
- note: ticket.description,
- group_id: 3,
- owner_id: 101,
- customer_id: local_user_id,
- organization_id: 89,
- state: 13,
- priority: 7,
- pending_time: ticket.due_at,
- updated_at: ticket.updated_at,
- created_at: ticket.created_at,
- updated_by_id: local_user_id,
- created_by_id: local_user_id,
- create_article_sender_id: 21,
- create_article_type_id: 555,
- }
-
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( ticket.requester_id ).and_return(local_user_id)
- expect(Import::Zendesk::UserFactory).to receive(:local_id).with( ticket.assignee ).and_return(expected_structure[:owner_id])
-
- expect(Import::Zendesk::GroupFactory).to receive(:local_id).with( ticket.group_id ).and_return(expected_structure[:group_id])
- expect(Import::Zendesk::OrganizationFactory).to receive(:local_id).with( ticket.organization_id ).and_return(expected_structure[:organization_id])
- expect(Import::Zendesk::Priority).to receive(:lookup).with(ticket).and_return(expected_structure[:priority])
- expect(Import::Zendesk::State).to receive(:lookup).with(ticket).and_return(expected_structure[:state])
- expect(Import::Zendesk::Ticket::Comment::Sender).to receive(:local_id).with(local_user_id).and_return(expected_structure[:create_article_sender_id])
- expect(Import::Zendesk::Ticket::Comment::Type).to receive(:local_id).with(ticket).and_return(expected_structure[:create_article_type_id])
-
- local_ticket = double()
-
- expect(Import::Zendesk::Ticket::TagFactory).to receive(:import).with(ticket.tags, local_ticket, ticket)
- expect(Import::Zendesk::Ticket::CommentFactory).to receive(:import).with(ticket.comments, local_ticket, ticket)
-
- expect(::Ticket).to receive(:find_by).with(id: expected_structure[:id]).and_return(local_ticket)
- expect(local_ticket).to receive(:update!).with(expected_structure)
-
- created_instance = described_class.new(ticket)
- end
-end
diff --git a/spec/lib/import/zendesk/user/group_spec.rb b/spec/lib/import/zendesk/user/group_spec.rb
deleted file mode 100644
index 97ae249f8..000000000
--- a/spec/lib/import/zendesk/user/group_spec.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/user/lookup_backend_examples'
-
-# required due to some of rails autoloading issues
-require 'import/zendesk/user/group'
-
-RSpec.describe Import::Zendesk::User::Group do
- it_behaves_like 'lookup backend'
-end
diff --git a/spec/lib/import/zendesk/user/lookup_backend_examples.rb b/spec/lib/import/zendesk/user/lookup_backend_examples.rb
deleted file mode 100644
index 47ef2f94c..000000000
--- a/spec/lib/import/zendesk/user/lookup_backend_examples.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-require 'rails_helper'
-
-RSpec.shared_examples 'lookup backend' do
- it 'responds to for' do
- expect(described_class).to respond_to(:for)
- end
-end
diff --git a/spec/lib/import/zendesk/user/role_spec.rb b/spec/lib/import/zendesk/user/role_spec.rb
deleted file mode 100644
index 9a0dff009..000000000
--- a/spec/lib/import/zendesk/user/role_spec.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/user/lookup_backend_examples'
-
-# required due to some of rails autoloading issues
-require 'import/zendesk/user/role'
-
-RSpec.describe Import::Zendesk::User::Role do
- it_behaves_like 'lookup backend'
-
- it 'responds to map' do
- expect(described_class).to respond_to(:map)
- end
-end
diff --git a/spec/lib/import/zendesk/user_factory_spec.rb b/spec/lib/import/zendesk/user_factory_spec.rb
deleted file mode 100644
index 294a3f656..000000000
--- a/spec/lib/import/zendesk/user_factory_spec.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/base_factory_examples'
-require 'lib/import/zendesk/local_id_mapper_hook_examples'
-
-RSpec.describe Import::Zendesk::UserFactory do
- it_behaves_like 'Import::Zendesk::BaseFactory'
- it_behaves_like 'Import::Zendesk::LocalIDMapperHook'
-end
diff --git a/spec/lib/import/zendesk/user_field_factory_spec.rb b/spec/lib/import/zendesk/user_field_factory_spec.rb
deleted file mode 100644
index 601b0ab25..000000000
--- a/spec/lib/import/zendesk/user_field_factory_spec.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/base_factory_examples'
-require 'lib/import/zendesk/local_id_mapper_hook_examples'
-
-RSpec.describe Import::Zendesk::UserFieldFactory do
- it_behaves_like 'Import::Zendesk::BaseFactory'
- it_behaves_like 'Import::Zendesk::LocalIDMapperHook'
-end
diff --git a/spec/lib/import/zendesk/user_field_spec.rb b/spec/lib/import/zendesk/user_field_spec.rb
deleted file mode 100644
index 2325622b7..000000000
--- a/spec/lib/import/zendesk/user_field_spec.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-require 'rails_helper'
-require 'lib/import/zendesk/object_field_examples'
-
-RSpec.describe Import::Zendesk::UserField do
- it_behaves_like 'Import::Zendesk::ObjectField'
-end
diff --git a/spec/lib/import/zendesk/user_spec.rb b/spec/lib/import/zendesk/user_spec.rb
deleted file mode 100644
index 3c3d43eaa..000000000
--- a/spec/lib/import/zendesk/user_spec.rb
+++ /dev/null
@@ -1,165 +0,0 @@
-require 'rails_helper'
-
-# required due to some of rails autoloading issues
-require 'import/zendesk/user'
-
-RSpec.describe Import::Zendesk::User do
-
- it 'create_or_updates user' do
-
- user = double(
- id: 1337,
- name: 'Example User',
- email: 'user@example.com',
- phone: '+49-123-345673',
- suspended: false,
- notes: 'Nice guy',
- verified: true,
- organization_id: 42,
- last_login_at: DateTime.yesterday,
- photo: double(content_url: 'https://img.remote.tld/w40293402zz394eed'),
- user_fields: [],
- )
-
- expected_structure = {
- login: user.email,
- firstname: user.name,
- email: user.email,
- phone: user.phone,
- password: '',
- active: !user.suspended,
- groups: [1, 2, 3],
- roles: [3],
- note: user.notes,
- verified: user.verified,
- organization_id: 101,
- last_login: user.last_login_at,
- image_source: user.photo.content_url,
- updated_by_id: 1,
- created_by_id: 1
- }
-
- local_user = double(id: 31_337)
-
- expect(Import::Zendesk::User::Group).to receive(:for).with(user).and_return(expected_structure[:groups])
- expect(Import::Zendesk::User::Role).to receive(:for).with(user).and_return(expected_structure[:roles])
- expect(Import::Zendesk::OrganizationFactory).to receive(:local_id).with( user.organization_id ).and_return(expected_structure[:organization_id])
-
- expect(::User).to receive(:create_or_update).with( expected_structure ).and_return(local_user)
-
- created_instance = described_class.new(user)
-
- expect(created_instance).to respond_to(:id)
- expect(created_instance.id).to eq(local_user.id)
-
- expect(created_instance).to respond_to(:zendesk_id)
- expect(created_instance.zendesk_id).to eq(user.id)
- end
-
- it 'imports id as login if no email address is available' do
-
- user = double(
- id: 1337,
- name: 'Example User',
- email: nil,
- phone: '+49-123-345673',
- suspended: false,
- notes: 'Nice guy',
- verified: true,
- organization_id: 42,
- last_login_at: DateTime.yesterday,
- photo: double(content_url: 'https://img.remote.tld/w40293402zz394eed'),
- user_fields: [],
- )
-
- expected_structure = {
- login: user.id.to_s,
- firstname: user.name,
- email: user.email,
- phone: user.phone,
- password: '',
- active: !user.suspended,
- groups: [1, 2, 3],
- roles: [3],
- note: user.notes,
- verified: user.verified,
- organization_id: 101,
- last_login: user.last_login_at,
- image_source: user.photo.content_url,
- updated_by_id: 1,
- created_by_id: 1
- }
-
- local_user = double(id: 31_337)
-
- expect(Import::Zendesk::User::Group).to receive(:for).with(user).and_return(expected_structure[:groups])
- expect(Import::Zendesk::User::Role).to receive(:for).with(user).and_return(expected_structure[:roles])
- expect(Import::Zendesk::OrganizationFactory).to receive(:local_id).with( user.organization_id ).and_return(expected_structure[:organization_id])
-
- expect(::User).to receive(:create_or_update).with( expected_structure ).and_return(local_user)
-
- created_instance = described_class.new(user)
-
- expect(created_instance).to respond_to(:id)
- expect(created_instance.id).to eq(local_user.id)
-
- expect(created_instance).to respond_to(:zendesk_id)
- expect(created_instance.zendesk_id).to eq(user.id)
- end
-
- it 'handles import user credentials and privileges specially' do
-
- user = double(
- id: 1337,
- name: 'Example User',
- email: 'user@example.com',
- phone: '+49-123-345673',
- suspended: false,
- notes: 'Nice guy',
- verified: true,
- organization_id: 42,
- last_login_at: DateTime.yesterday,
- photo: double(content_url: 'https://img.remote.tld/w40293402zz394eed'),
- user_fields: [],
- )
-
- password = 'apikeyprovidedfortheimportbytheuser'
-
- expected_structure = {
- login: user.email,
- firstname: user.name,
- email: user.email,
- phone: user.phone,
- password: password,
- active: !user.suspended,
- groups: [1, 2, 3],
- roles: [1, 2],
- note: user.notes,
- verified: user.verified,
- organization_id: 101,
- last_login: user.last_login_at,
- image_source: user.photo.content_url,
- updated_by_id: 1,
- created_by_id: 1
- }
-
- local_user = double(id: 31_337)
-
- expect(Import::Zendesk::User::Group).to receive(:for).with(user).and_return(expected_structure[:groups])
- expect(Import::Zendesk::User::Role).to receive(:map).with(user, 'admin').and_return(expected_structure[:roles])
- expect(Import::Zendesk::OrganizationFactory).to receive(:local_id).with( user.organization_id ).and_return(expected_structure[:organization_id])
-
- expect(Setting).to receive(:get).with('import_zendesk_endpoint_username').twice.and_return(user.email)
- expect(Setting).to receive(:get).with('import_zendesk_endpoint_key').and_return(password)
-
- expect(::User).to receive(:create_or_update).with( expected_structure ).and_return(local_user)
-
- created_instance = described_class.new(user)
-
- expect(created_instance).to respond_to(:id)
- expect(created_instance.id).to eq(local_user.id)
-
- expect(created_instance).to respond_to(:zendesk_id)
- expect(created_instance.zendesk_id).to eq(user.id)
- end
-end
diff --git a/spec/lib/import/zendesk_spec.rb b/spec/lib/import/zendesk_spec.rb
deleted file mode 100644
index 153fe393b..000000000
--- a/spec/lib/import/zendesk_spec.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-require 'rails_helper'
-require 'lib/import/helper_examples'
-require 'lib/import/importer_examples'
-require 'lib/import/async_examples'
-require 'lib/import/import_stats_examples'
-
-RSpec.describe Import::Zendesk do
- it_behaves_like 'Import backend'
- it_behaves_like 'Import::Helper'
- it_behaves_like 'Import::Async'
- it_behaves_like 'Import::ImportStats'
-end
diff --git a/spec/lib/sequencer/unit/import/common/object_attribute/sanitized_name_spec.rb b/spec/lib/sequencer/unit/import/common/object_attribute/sanitized_name_spec.rb
new file mode 100644
index 000000000..ea4d43c40
--- /dev/null
+++ b/spec/lib/sequencer/unit/import/common/object_attribute/sanitized_name_spec.rb
@@ -0,0 +1,46 @@
+require 'rails_helper'
+
+RSpec.describe Sequencer::Unit::Import::Common::ObjectAttribute::SanitizedName, sequencer: :unit do
+
+ it 'requires implementation of .unsanitized_name' do
+
+ expect do
+ process
+ end.to raise_error(RuntimeError)
+ end
+
+ context 'sanitizes' do
+
+ it 'whitespaces' do
+ provided = process do |instance|
+ expect(instance).to receive(:unsanitized_name).and_return('model name')
+ end
+
+ expect(provided[:sanitized_name]).to eq('model_name')
+ end
+
+ it 'dashes' do
+ provided = process do |instance|
+ expect(instance).to receive(:unsanitized_name).and_return('model-name')
+ end
+
+ expect(provided[:sanitized_name]).to eq('model_name')
+ end
+
+ it 'ids suffix' do
+ provided = process do |instance|
+ expect(instance).to receive(:unsanitized_name).and_return('Model Ids')
+ end
+
+ expect(provided[:sanitized_name]).to eq('model_nos')
+ end
+
+ it 'id suffix' do
+ provided = process do |instance|
+ expect(instance).to receive(:unsanitized_name).and_return('Model Id')
+ end
+
+ expect(provided[:sanitized_name]).to eq('model_no')
+ end
+ end
+end
diff --git a/test/integration/zendesk_import_browser_test.rb b/test/integration/zendesk_import_browser_test.rb
index 1963ac81d..da26c7f6d 100644
--- a/test/integration/zendesk_import_browser_test.rb
+++ b/test/integration/zendesk_import_browser_test.rb
@@ -79,32 +79,27 @@ class ZendeskImportBrowserTest < TestCase
click(css: '.js-migration-start')
watch_for(
- css: '.js-group .js-done',
+ css: '.js-groups .js-done',
value: '2',
timeout: 120,
)
watch_for(
- css: '.js-organization .js-done',
+ css: '.js-organizations .js-done',
value: '1',
timeout: 120,
)
watch_for(
- css: '.js-user .js-done',
+ css: '.js-users .js-done',
value: '141',
timeout: 120,
)
- watch_for(
- css: '.js-ticket .js-done',
- value: '143',
- timeout: 800,
- )
-
watch_for(
css: 'body',
value: 'login',
+ timeout: 800,
)
end
end
diff --git a/test/integration/zendesk_import_test.rb b/test/integration/zendesk_import_test.rb
index fe598f861..1b781a9a1 100644
--- a/test/integration/zendesk_import_test.rb
+++ b/test/integration/zendesk_import_test.rb
@@ -20,29 +20,58 @@ class ZendeskImportTest < ActiveSupport::TestCase
Setting.set('import_zendesk_endpoint_username', ENV['IMPORT_ZENDESK_ENDPOINT_USERNAME'])
Setting.set('import_mode', true)
Setting.set('system_init_done', false)
- Import::Zendesk.start
+
+ job = ImportJob.create(name: 'Import::Zendesk')
+ job.start
# check statistic count
test 'check statistic' do
- remote_statistic = Import::Zendesk.statistic
-
# retrive statistic
compare_statistic = {
- 'Tickets' => 143,
- 'TicketFields' => 13,
- 'UserFields' => 2,
- 'OrganizationFields' => 2,
- 'Groups' => 2,
- 'Organizations' => 1,
- 'Users' => 141,
- 'GroupMemberships' => 3,
- 'Macros' => 5,
- 'Views' => 19,
- 'Automations' => 5
+ Groups: {
+ skipped: 0,
+ created: 2,
+ updated: 0,
+ unchanged: 0,
+ failed: 0,
+ deactivated: 0,
+ sum: 2,
+ total: 2
+ },
+ Users: {
+ skipped: 0,
+ created: 141,
+ updated: 0,
+ unchanged: 0,
+ failed: 0,
+ deactivated: 0,
+ sum: 141,
+ total: 141
+ },
+ Organizations: {
+ skipped: 0,
+ created: 1,
+ updated: 0,
+ unchanged: 0,
+ failed: 0,
+ deactivated: 0,
+ sum: 1,
+ total: 1
+ },
+ Tickets: {
+ skipped: 0,
+ created: 142,
+ updated: 1,
+ unchanged: 0,
+ failed: 0,
+ deactivated: 0,
+ sum: 143,
+ total: 143
+ }
}
- assert_equal(compare_statistic, remote_statistic, 'statistic')
+ assert_equal(compare_statistic.with_indifferent_access, job.result, 'statistic')
end
# check count of imported items
|