Initial generic csv based import of text modules, users, organizations and tickets for model and controller.
This commit is contained in:
parent
4537a281a3
commit
6a0f5d4c25
30 changed files with 1882 additions and 38 deletions
|
@ -323,4 +323,43 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co
|
||||||
render json: history
|
render json: history
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @path [GET] /organizations/import_example
|
||||||
|
#
|
||||||
|
# @summary Download of example CSV file.
|
||||||
|
# @notes The requester have 'admin.organization' permissions to be able to download it.
|
||||||
|
# @example curl -u 'me@example.com:test' http://localhost:3000/api/v1/organizations/import_example
|
||||||
|
#
|
||||||
|
# @response_message 200 File download.
|
||||||
|
# @response_message 401 Invalid session.
|
||||||
|
def import_example
|
||||||
|
permission_check('admin.organization')
|
||||||
|
send_data(
|
||||||
|
Organization.csv_example,
|
||||||
|
filename: 'organization-example.csv',
|
||||||
|
type: 'text/csv',
|
||||||
|
disposition: 'attachment'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @path [POST] /organizations/import
|
||||||
|
#
|
||||||
|
# @summary Starts import.
|
||||||
|
# @notes The requester have 'admin.text_module' permissions to be create a new import.
|
||||||
|
# @example curl -u 'me@example.com:test' -F 'file=@/path/to/file/organizations.csv' 'https://your.zammad/api/v1/organizations/import?try=true'
|
||||||
|
# @example curl -u 'me@example.com:test' -F 'file=@/path/to/file/organizations.csv' 'https://your.zammad/api/v1/organizations/import'
|
||||||
|
#
|
||||||
|
# @response_message 201 Import started.
|
||||||
|
# @response_message 401 Invalid session.
|
||||||
|
def import_start
|
||||||
|
permission_check('admin.user')
|
||||||
|
result = Organization.csv_import(
|
||||||
|
string: params[:file].read.force_encoding('utf-8'),
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: params[:try],
|
||||||
|
)
|
||||||
|
render json: result, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -152,4 +152,48 @@ curl http://localhost/api/v1/text_modules.json -v -u #{login}:#{password} -H "Co
|
||||||
permission_check('admin.text_module')
|
permission_check('admin.text_module')
|
||||||
model_destroy_render(TextModule, params)
|
model_destroy_render(TextModule, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @path [GET] /text_modules/import_example
|
||||||
|
#
|
||||||
|
# @summary Download of example CSV file.
|
||||||
|
# @notes The requester have 'admin.text_module' permissions to be able to download it.
|
||||||
|
# @example curl -u 'me@example.com:test' http://localhost:3000/api/v1/text_modules/import_example
|
||||||
|
#
|
||||||
|
# @response_message 200 File download.
|
||||||
|
# @response_message 401 Invalid session.
|
||||||
|
def import_example
|
||||||
|
permission_check('admin.text_module')
|
||||||
|
csv_string = TextModule.csv_example(
|
||||||
|
col_sep: ',',
|
||||||
|
)
|
||||||
|
send_data(
|
||||||
|
csv_string,
|
||||||
|
filename: 'example.csv',
|
||||||
|
type: 'text/csv',
|
||||||
|
disposition: 'attachment'
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# @path [POST] /text_modules/import
|
||||||
|
#
|
||||||
|
# @summary Starts import.
|
||||||
|
# @notes The requester have 'admin.text_module' permissions to be create a new import.
|
||||||
|
# @example curl -u 'me@example.com:test' -F 'file=@/path/to/file/Textbausteine_final2.csv' 'https://your.zammad/api/v1/text_modules/import?try=true'
|
||||||
|
# @example curl -u 'me@example.com:test' -F 'file=@/path/to/file/Textbausteine_final2.csv' 'https://your.zammad/api/v1/text_modules/import'
|
||||||
|
#
|
||||||
|
# @response_message 201 Import started.
|
||||||
|
# @response_message 401 Invalid session.
|
||||||
|
def import_start
|
||||||
|
permission_check('admin.text_module')
|
||||||
|
result = TextModule.csv_import(
|
||||||
|
string: params[:file].read.force_encoding('utf-8'),
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: params[:try],
|
||||||
|
)
|
||||||
|
render json: result, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -276,6 +276,52 @@ class TicketArticlesController < ApplicationController
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @path [GET] /ticket_articles/import_example
|
||||||
|
#
|
||||||
|
# @summary Download of example CSV file.
|
||||||
|
# @notes The requester have 'admin' permissions to be able to download it.
|
||||||
|
# @example curl -u 'me@example.com:test' http://localhost:3000/api/v1/ticket_articles/import_example
|
||||||
|
#
|
||||||
|
# @response_message 200 File download.
|
||||||
|
# @response_message 401 Invalid session.
|
||||||
|
def import_example
|
||||||
|
permission_check('admin')
|
||||||
|
csv_string = Ticket::Article.csv_example(
|
||||||
|
col_sep: ',',
|
||||||
|
)
|
||||||
|
send_data(
|
||||||
|
csv_string,
|
||||||
|
filename: 'example.csv',
|
||||||
|
type: 'text/csv',
|
||||||
|
disposition: 'attachment'
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# @path [POST] /ticket_articles/import
|
||||||
|
#
|
||||||
|
# @summary Starts import.
|
||||||
|
# @notes The requester have 'admin' permissions to be create a new import.
|
||||||
|
# @example curl -u 'me@example.com:test' -F 'file=@/path/to/file/ticket_articles.csv' 'https://your.zammad/api/v1/ticket_articles/import?try=true'
|
||||||
|
# @example curl -u 'me@example.com:test' -F 'file=@/path/to/file/ticket_articles.csv' 'https://your.zammad/api/v1/ticket_articles/import'
|
||||||
|
#
|
||||||
|
# @response_message 201 Import started.
|
||||||
|
# @response_message 401 Invalid session.
|
||||||
|
def import_start
|
||||||
|
permission_check('admin')
|
||||||
|
if Setting.get('import_mode') != true
|
||||||
|
raise 'Only can import tickets if system is in import mode.'
|
||||||
|
end
|
||||||
|
result = Ticket::Article.csv_import(
|
||||||
|
string: params[:file].read.force_encoding('utf-8'),
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: params[:try],
|
||||||
|
)
|
||||||
|
render json: result, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def sanitized_disposition
|
def sanitized_disposition
|
||||||
|
|
|
@ -598,6 +598,52 @@ class TicketsController < ApplicationController
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @path [GET] /tickets/import_example
|
||||||
|
#
|
||||||
|
# @summary Download of example CSV file.
|
||||||
|
# @notes The requester have 'admin' permissions to be able to download it.
|
||||||
|
# @example curl -u 'me@example.com:test' http://localhost:3000/api/v1/tickets/import_example
|
||||||
|
#
|
||||||
|
# @response_message 200 File download.
|
||||||
|
# @response_message 401 Invalid session.
|
||||||
|
def import_example
|
||||||
|
permission_check('admin')
|
||||||
|
csv_string = Ticket.csv_example(
|
||||||
|
col_sep: ',',
|
||||||
|
)
|
||||||
|
send_data(
|
||||||
|
csv_string,
|
||||||
|
filename: 'example.csv',
|
||||||
|
type: 'text/csv',
|
||||||
|
disposition: 'attachment'
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# @path [POST] /tickets/import
|
||||||
|
#
|
||||||
|
# @summary Starts import.
|
||||||
|
# @notes The requester have 'admin' permissions to be create a new import.
|
||||||
|
# @example curl -u 'me@example.com:test' -F 'file=@/path/to/file/tickets.csv' 'https://your.zammad/api/v1/tickets/import?try=true'
|
||||||
|
# @example curl -u 'me@example.com:test' -F 'file=@/path/to/file/tickets.csv' 'https://your.zammad/api/v1/tickets/import'
|
||||||
|
#
|
||||||
|
# @response_message 201 Import started.
|
||||||
|
# @response_message 401 Invalid session.
|
||||||
|
def import_start
|
||||||
|
permission_check('admin')
|
||||||
|
if Setting.get('import_mode') != true
|
||||||
|
raise 'Only can import tickets if system is in import mode.'
|
||||||
|
end
|
||||||
|
result = Ticket.csv_import(
|
||||||
|
string: params[:file].read.force_encoding('utf-8'),
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: params[:try],
|
||||||
|
)
|
||||||
|
render json: result, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def follow_up_possible_check
|
def follow_up_possible_check
|
||||||
|
|
|
@ -1061,6 +1061,45 @@ curl http://localhost/api/v1/users/avatar -v -u #{login}:#{password} -H "Content
|
||||||
render json: { avatars: result }, status: :ok
|
render json: { avatars: result }, status: :ok
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @path [GET] /users/import_example
|
||||||
|
#
|
||||||
|
# @summary Download of example CSV file.
|
||||||
|
# @notes The requester have 'admin.user' permissions to be able to download it.
|
||||||
|
# @example curl -u 'me@example.com:test' http://localhost:3000/api/v1/users/import_example
|
||||||
|
#
|
||||||
|
# @response_message 200 File download.
|
||||||
|
# @response_message 401 Invalid session.
|
||||||
|
def import_example
|
||||||
|
permission_check('admin.user')
|
||||||
|
send_data(
|
||||||
|
User.csv_example,
|
||||||
|
filename: 'user-example.csv',
|
||||||
|
type: 'text/csv',
|
||||||
|
disposition: 'attachment'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @path [POST] /users/import
|
||||||
|
#
|
||||||
|
# @summary Starts import.
|
||||||
|
# @notes The requester have 'admin.text_module' permissions to be create a new import.
|
||||||
|
# @example curl -u 'me@example.com:test' -F 'file=@/path/to/file/users.csv' 'https://your.zammad/api/v1/users/import?try=true'
|
||||||
|
# @example curl -u 'me@example.com:test' -F 'file=@/path/to/file/users.csv' 'https://your.zammad/api/v1/users/import'
|
||||||
|
#
|
||||||
|
# @response_message 201 Import started.
|
||||||
|
# @response_message 401 Invalid session.
|
||||||
|
def import_start
|
||||||
|
permission_check('admin.user')
|
||||||
|
result = User.csv_import(
|
||||||
|
string: params[:file].read.force_encoding('utf-8'),
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: params[:try],
|
||||||
|
)
|
||||||
|
render json: result, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def password_policy(password)
|
def password_policy(password)
|
||||||
|
|
|
@ -63,6 +63,9 @@ returns
|
||||||
real_values = real_values.to_sym
|
real_values = real_values.to_sym
|
||||||
next if !respond_to?(real_values)
|
next if !respond_to?(real_values)
|
||||||
next if !params[real_values]
|
next if !params[real_values]
|
||||||
|
if params[real_values].instance_of?(String) || params[real_values].instance_of?(Integer) || params[real_values].instance_of?(Float)
|
||||||
|
params[real_values] = [params[real_values]]
|
||||||
|
end
|
||||||
next if !params[real_values].instance_of?(Array)
|
next if !params[real_values].instance_of?(Array)
|
||||||
list = []
|
list = []
|
||||||
class_object = assoc.klass
|
class_object = assoc.klass
|
||||||
|
|
|
@ -39,10 +39,9 @@ returns
|
||||||
where(name: data[:name])
|
where(name: data[:name])
|
||||||
end
|
end
|
||||||
records.each do |loop_record|
|
records.each do |loop_record|
|
||||||
if loop_record.name == data[:name]
|
next if loop_record.name != data[:name]
|
||||||
cache_set(data[:name], loop_record)
|
cache_set(data[:name], loop_record)
|
||||||
return loop_record
|
return loop_record
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
elsif data[:login]
|
elsif data[:login]
|
||||||
|
@ -56,10 +55,9 @@ returns
|
||||||
where(login: data[:login])
|
where(login: data[:login])
|
||||||
end
|
end
|
||||||
records.each do |loop_record|
|
records.each do |loop_record|
|
||||||
if loop_record.login == data[:login]
|
next if loop_record.login != data[:login]
|
||||||
cache_set(data[:login], loop_record)
|
cache_set(data[:login], loop_record)
|
||||||
return loop_record
|
return loop_record
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
elsif data[:email]
|
elsif data[:email]
|
||||||
|
@ -73,15 +71,27 @@ returns
|
||||||
where(email: data[:email])
|
where(email: data[:email])
|
||||||
end
|
end
|
||||||
records.each do |loop_record|
|
records.each do |loop_record|
|
||||||
if loop_record.email == data[:email]
|
next if loop_record.email != data[:email]
|
||||||
cache_set(data[:email], loop_record)
|
cache_set(data[:email], loop_record)
|
||||||
return loop_record
|
return loop_record
|
||||||
end
|
end
|
||||||
|
return
|
||||||
|
elsif data[:number]
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(number) = LOWER(?)', data[:number])
|
||||||
|
else
|
||||||
|
where(number: data[:number])
|
||||||
|
end
|
||||||
|
records.each do |loop_record|
|
||||||
|
next if loop_record.number != data[:number]
|
||||||
|
return loop_record
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
raise ArgumentError, 'Need name, id, login or email for lookup()'
|
raise ArgumentError, 'Need name, id, number, login or email for lookup()'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
351
app/models/concerns/can_csv_import.rb
Normal file
351
app/models/concerns/can_csv_import.rb
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
require 'csv'
|
||||||
|
|
||||||
|
module CanCsvImport
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
result = Model.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ',',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = Model.csv_import(
|
||||||
|
file: '/file/location/of/file.csv',
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ',',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = TextModule.csv_import(
|
||||||
|
file: '/Users/me/Downloads/Textbausteine_final.csv',
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ',',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
records: [record1, ...]
|
||||||
|
try: true, # true|false
|
||||||
|
success: true, # true|false
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def csv_import(data)
|
||||||
|
|
||||||
|
if data[:file].present?
|
||||||
|
raise Exceptions::UnprocessableEntity, "No such file '#{data[:file]}'" if !File.exist?(data[:file])
|
||||||
|
begin
|
||||||
|
file = File.open(data[:file], 'r:UTF-8')
|
||||||
|
data[:string] = file.read
|
||||||
|
rescue => e
|
||||||
|
raise Exceptions::UnprocessableEntity, "Unable to read file '#{data[:file]}': #{e.inspect}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if data[:string].blank?
|
||||||
|
raise Exceptions::UnprocessableEntity, 'Unable to parse empty file/string!'
|
||||||
|
end
|
||||||
|
|
||||||
|
rows = CSV.parse(data[:string], data[:parse_params])
|
||||||
|
header = rows.shift
|
||||||
|
if header.blank?
|
||||||
|
raise Exceptions::UnprocessableEntity, 'Unable to parse file/string without header!'
|
||||||
|
end
|
||||||
|
header.each do |item|
|
||||||
|
if item.respond_to?(:strip!)
|
||||||
|
item.strip!
|
||||||
|
end
|
||||||
|
next if !item.respond_to?(:downcase!)
|
||||||
|
item.downcase!
|
||||||
|
end
|
||||||
|
|
||||||
|
# get payload based on csv
|
||||||
|
payload = []
|
||||||
|
rows.each do |row|
|
||||||
|
if row[0].blank? && row[1].blank?
|
||||||
|
payload_last = payload.last
|
||||||
|
row.each_with_index do |item, count|
|
||||||
|
next if item.blank?
|
||||||
|
if payload_last[header[count].to_sym].class != Array
|
||||||
|
payload_last[header[count].to_sym] = [payload_last[header[count].to_sym]]
|
||||||
|
end
|
||||||
|
payload_last[header[count].to_sym].push item.strip
|
||||||
|
end
|
||||||
|
next
|
||||||
|
end
|
||||||
|
attributes = {}
|
||||||
|
row.each_with_index do |item, count|
|
||||||
|
next if !item
|
||||||
|
next if header[count].blank?
|
||||||
|
next if @csv_attributes_ignored&.include?(header[count].to_sym)
|
||||||
|
attributes[header[count].to_sym] = if item.respond_to?(:strip)
|
||||||
|
item.strip
|
||||||
|
else
|
||||||
|
item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
data[:fixed_params]&.each do |key, value|
|
||||||
|
attributes[key] = value
|
||||||
|
end
|
||||||
|
payload.push attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
# create or update records
|
||||||
|
csv_object_ids_ignored = @csv_object_ids_ignored || []
|
||||||
|
records = []
|
||||||
|
stats = {
|
||||||
|
created: 0,
|
||||||
|
updated: 0,
|
||||||
|
}
|
||||||
|
errors = []
|
||||||
|
line_count = 0
|
||||||
|
payload.each do |attributes|
|
||||||
|
line_count += 1
|
||||||
|
record = nil
|
||||||
|
%i[id number name login email].each do |lookup_by|
|
||||||
|
next if !attributes[lookup_by]
|
||||||
|
params = {}
|
||||||
|
params[lookup_by] = attributes[lookup_by]
|
||||||
|
record = lookup(params)
|
||||||
|
break if record
|
||||||
|
end
|
||||||
|
|
||||||
|
if attributes[:id].present? && !record
|
||||||
|
errors.push "Line #{line_count}: unknown record with id '#{attributes[:id]}' for #{new.class}."
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
if record && csv_object_ids_ignored.include?(record.id)
|
||||||
|
errors.push "Line #{line_count}: unable to update record with id '#{attributes[:id]}' for #{new.class}."
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
clean_params = association_name_to_id_convert(attributes)
|
||||||
|
rescue => e
|
||||||
|
errors.push "Line #{line_count}: #{e.message}"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
# create object
|
||||||
|
Transaction.execute(disable_notification: true, reset_user_id: true) do
|
||||||
|
UserInfo.current_user_id = clean_params[:updated_by_id] || clean_params[:created_by_id]
|
||||||
|
if !record
|
||||||
|
stats[:created] += 1
|
||||||
|
begin
|
||||||
|
csv_verify_attributes(clean_params)
|
||||||
|
clean_params = param_cleanup(clean_params)
|
||||||
|
|
||||||
|
if !UserInfo.current_user_id
|
||||||
|
clean_params[:created_by_id] = 1
|
||||||
|
clean_params[:updated_by_id] = 1
|
||||||
|
end
|
||||||
|
record = new(clean_params)
|
||||||
|
next if data[:try] == 'true' || data[:try] == true
|
||||||
|
record.associations_from_param(attributes)
|
||||||
|
record.save!
|
||||||
|
rescue => e
|
||||||
|
errors.push "Line #{line_count}: #{e.message}"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
else
|
||||||
|
stats[:updated] += 1
|
||||||
|
next if data[:try] == 'true' || data[:try] == true
|
||||||
|
begin
|
||||||
|
csv_verify_attributes(clean_params)
|
||||||
|
clean_params = param_cleanup(clean_params)
|
||||||
|
|
||||||
|
if !UserInfo.current_user_id
|
||||||
|
clean_params[:updated_by_id] = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
record.with_lock do
|
||||||
|
record.associations_from_param(attributes)
|
||||||
|
record.update_attributes!(clean_params)
|
||||||
|
end
|
||||||
|
rescue => e
|
||||||
|
errors.push "Line #{line_count}: #{e.message}"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
records.push record
|
||||||
|
end
|
||||||
|
|
||||||
|
result = 'success'
|
||||||
|
if errors.present?
|
||||||
|
result = 'failed'
|
||||||
|
end
|
||||||
|
|
||||||
|
{
|
||||||
|
stats: stats,
|
||||||
|
records: records,
|
||||||
|
errors: errors,
|
||||||
|
try: data[:try],
|
||||||
|
result: result,
|
||||||
|
}
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
verify if attributes are valid, will raise an ArgumentError with "unknown attribute '#{key}' for #{new.class}."
|
||||||
|
|
||||||
|
Model.csv_verify_attributes({'attribute': 'some value'})
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def csv_verify_attributes(clean_params)
|
||||||
|
all_clean_attributes = {}
|
||||||
|
new.attributes.each_key do |attribute|
|
||||||
|
all_clean_attributes[attribute.to_sym] = true
|
||||||
|
end
|
||||||
|
reflect_on_all_associations.map do |assoc|
|
||||||
|
all_clean_attributes[assoc.name.to_sym] = true
|
||||||
|
ref = if assoc.name.to_s.end_with?('_id')
|
||||||
|
"#{assoc.name}_id"
|
||||||
|
else
|
||||||
|
"#{assoc.name.to_s.chop}_ids"
|
||||||
|
end
|
||||||
|
all_clean_attributes[ref.to_sym] = true
|
||||||
|
end
|
||||||
|
clean_params.each_key do |key|
|
||||||
|
next if all_clean_attributes.key?(key.to_sym)
|
||||||
|
raise ArgumentError, "unknown attribute '#{key}' for #{new.class}."
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
csv_string = Model.csv_example(
|
||||||
|
col_sep: ',',
|
||||||
|
)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
csv_string
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def csv_example(params = {})
|
||||||
|
header = []
|
||||||
|
csv_object_ids_ignored = @csv_object_ids_ignored || []
|
||||||
|
records = where.not(id: csv_object_ids_ignored).offset(1).limit(23).to_a
|
||||||
|
if records.count < 20
|
||||||
|
record_ids = records.pluck(:id).concat(csv_object_ids_ignored)
|
||||||
|
local_records = where.not(id: record_ids).limit(20 - records.count)
|
||||||
|
records = records.concat(local_records)
|
||||||
|
end
|
||||||
|
records_attributes_with_association_names = []
|
||||||
|
records.each do |record|
|
||||||
|
record_attributes_with_association_names = record.attributes_with_association_names
|
||||||
|
records_attributes_with_association_names.push record_attributes_with_association_names
|
||||||
|
record_attributes_with_association_names.each do |key, value|
|
||||||
|
next if value.class == ActiveSupport::HashWithIndifferentAccess
|
||||||
|
next if value.class == Hash
|
||||||
|
next if @csv_attributes_ignored&.include?(key.to_sym)
|
||||||
|
next if key.match?(/_id$/)
|
||||||
|
next if key.match?(/_ids$/)
|
||||||
|
next if key == 'created_by'
|
||||||
|
next if key == 'updated_by'
|
||||||
|
next if key == 'created_at'
|
||||||
|
next if key == 'updated_at'
|
||||||
|
next if header.include?(key)
|
||||||
|
header.push key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
rows = []
|
||||||
|
records_attributes_with_association_names.each do |record|
|
||||||
|
row = []
|
||||||
|
rows_to_add = []
|
||||||
|
position = -1
|
||||||
|
header.each do |key|
|
||||||
|
position += 1
|
||||||
|
if record[key].class == ActiveSupport::TimeWithZone
|
||||||
|
row.push record[key].iso8601
|
||||||
|
next
|
||||||
|
end
|
||||||
|
if record[key].class == Array
|
||||||
|
entry_count = -2
|
||||||
|
record[key].each do |entry|
|
||||||
|
entry_count += 1
|
||||||
|
next if entry_count == -1
|
||||||
|
if !rows_to_add[entry_count]
|
||||||
|
rows_to_add[entry_count] = Array.new(header.count + 1) { '' }
|
||||||
|
end
|
||||||
|
rows_to_add[entry_count][position] = entry
|
||||||
|
end
|
||||||
|
record[key] = record[key][0]
|
||||||
|
end
|
||||||
|
row.push record[key]
|
||||||
|
end
|
||||||
|
rows.push row
|
||||||
|
next unless rows_to_add.count.positive?
|
||||||
|
rows_to_add.each do |item|
|
||||||
|
rows.push item
|
||||||
|
end
|
||||||
|
rows_to_add = []
|
||||||
|
end
|
||||||
|
CSV.generate(params) do |csv|
|
||||||
|
csv << header
|
||||||
|
rows.each do |row|
|
||||||
|
csv << row
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
serve methode to ignore model based on id
|
||||||
|
|
||||||
|
class Model < ApplicationModel
|
||||||
|
include CanCsvImport
|
||||||
|
csv_object_ids_ignored(1, 2, 3)
|
||||||
|
end
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def csv_object_ids_ignored(*object_ids)
|
||||||
|
@csv_object_ids_ignored = object_ids
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
serve methode to ignore model attributes
|
||||||
|
|
||||||
|
class Model < ApplicationModel
|
||||||
|
include CanCsvImport
|
||||||
|
csv_attributes_ignored :password,
|
||||||
|
:image_source,
|
||||||
|
:login_failed,
|
||||||
|
:source,
|
||||||
|
:image_source,
|
||||||
|
:image,
|
||||||
|
:authorizations,
|
||||||
|
:organizations
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def csv_attributes_ignored(*attributes)
|
||||||
|
@csv_attributes_ignored = attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,6 +6,7 @@ class Organization < ApplicationModel
|
||||||
include ChecksLatestChangeObserved
|
include ChecksLatestChangeObserved
|
||||||
include HasHistory
|
include HasHistory
|
||||||
include HasSearchIndexBackend
|
include HasSearchIndexBackend
|
||||||
|
include CanCsvImport
|
||||||
include Organization::ChecksAccess
|
include Organization::ChecksAccess
|
||||||
|
|
||||||
load 'organization/assets.rb'
|
load 'organization/assets.rb'
|
||||||
|
|
|
@ -3,10 +3,14 @@
|
||||||
class TextModule < ApplicationModel
|
class TextModule < ApplicationModel
|
||||||
include ChecksClientNotification
|
include ChecksClientNotification
|
||||||
include ChecksHtmlSanitized
|
include ChecksHtmlSanitized
|
||||||
|
include CanCsvImport
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :content, presence: true
|
validates :content, presence: true
|
||||||
|
|
||||||
|
before_create :validate_content
|
||||||
|
before_update :validate_content
|
||||||
|
|
||||||
sanitized_html :content
|
sanitized_html :content
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -97,4 +101,14 @@ push text_modules to online
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def validate_content
|
||||||
|
return true if content.blank?
|
||||||
|
return true if content.match?(/<.+?>/)
|
||||||
|
content.gsub!(/(\r\n|\n\r|\r)/, "\n")
|
||||||
|
self.content = content.text2html
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,7 @@ class Ticket < ApplicationModel
|
||||||
include HasActivityStreamLog
|
include HasActivityStreamLog
|
||||||
include ChecksClientNotification
|
include ChecksClientNotification
|
||||||
include ChecksLatestChangeObserved
|
include ChecksLatestChangeObserved
|
||||||
|
include CanCsvImport
|
||||||
include HasHistory
|
include HasHistory
|
||||||
include HasTags
|
include HasTags
|
||||||
include HasSearchIndexBackend
|
include HasSearchIndexBackend
|
||||||
|
|
|
@ -4,6 +4,7 @@ class Ticket::Article < ApplicationModel
|
||||||
include ChecksClientNotification
|
include ChecksClientNotification
|
||||||
include HasHistory
|
include HasHistory
|
||||||
include ChecksHtmlSanitized
|
include ChecksHtmlSanitized
|
||||||
|
include CanCsvImport
|
||||||
include Ticket::Article::ChecksAccess
|
include Ticket::Article::ChecksAccess
|
||||||
|
|
||||||
load 'ticket/article/assets.rb'
|
load 'ticket/article/assets.rb'
|
||||||
|
|
|
@ -28,6 +28,7 @@ class User < ApplicationModel
|
||||||
include ChecksClientNotification
|
include ChecksClientNotification
|
||||||
include HasHistory
|
include HasHistory
|
||||||
include HasSearchIndexBackend
|
include HasSearchIndexBackend
|
||||||
|
include CanCsvImport
|
||||||
include HasGroups
|
include HasGroups
|
||||||
include HasRoles
|
include HasRoles
|
||||||
include User::ChecksAccess
|
include User::ChecksAccess
|
||||||
|
@ -74,6 +75,18 @@ class User < ApplicationModel
|
||||||
:source,
|
:source,
|
||||||
:login_failed
|
:login_failed
|
||||||
|
|
||||||
|
csv_object_ids_ignored 1
|
||||||
|
|
||||||
|
csv_attributes_ignored :password,
|
||||||
|
:login_failed,
|
||||||
|
:source,
|
||||||
|
:image_source,
|
||||||
|
:image,
|
||||||
|
:authorizations,
|
||||||
|
:organizations,
|
||||||
|
:groups,
|
||||||
|
:user_groups
|
||||||
|
|
||||||
def ignore_search_indexing?(_action)
|
def ignore_search_indexing?(_action)
|
||||||
# ignore internal user
|
# ignore internal user
|
||||||
return true if id == 1
|
return true if id == 1
|
||||||
|
|
|
@ -2,12 +2,14 @@ Zammad::Application.routes.draw do
|
||||||
api_path = Rails.configuration.api_path
|
api_path = Rails.configuration.api_path
|
||||||
|
|
||||||
# organizations
|
# organizations
|
||||||
match api_path + '/organizations/search', to: 'organizations#search', via: %i[get post]
|
match api_path + '/organizations/import_example', to: 'organizations#import_example', via: :get
|
||||||
match api_path + '/organizations', to: 'organizations#index', via: :get
|
match api_path + '/organizations/import', to: 'organizations#import_start', via: :post
|
||||||
match api_path + '/organizations/:id', to: 'organizations#show', via: :get
|
match api_path + '/organizations/search', to: 'organizations#search', via: %i[get post]
|
||||||
match api_path + '/organizations', to: 'organizations#create', via: :post
|
match api_path + '/organizations', to: 'organizations#index', via: :get
|
||||||
match api_path + '/organizations/:id', to: 'organizations#update', via: :put
|
match api_path + '/organizations/:id', to: 'organizations#show', via: :get
|
||||||
match api_path + '/organizations/:id', to: 'organizations#destroy', via: :delete
|
match api_path + '/organizations', to: 'organizations#create', via: :post
|
||||||
match api_path + '/organizations/history/:id', to: 'organizations#history', via: :get
|
match api_path + '/organizations/:id', to: 'organizations#update', via: :put
|
||||||
|
match api_path + '/organizations/:id', to: 'organizations#destroy', via: :delete
|
||||||
|
match api_path + '/organizations/history/:id', to: 'organizations#history', via: :get
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,10 +2,12 @@ Zammad::Application.routes.draw do
|
||||||
api_path = Rails.configuration.api_path
|
api_path = Rails.configuration.api_path
|
||||||
|
|
||||||
# text_modules
|
# text_modules
|
||||||
match api_path + '/text_modules', to: 'text_modules#index', via: :get
|
match api_path + '/text_modules/import_example', to: 'text_modules#import_example', via: :get
|
||||||
match api_path + '/text_modules/:id', to: 'text_modules#show', via: :get
|
match api_path + '/text_modules/import', to: 'text_modules#import_start', via: :post
|
||||||
match api_path + '/text_modules', to: 'text_modules#create', via: :post
|
match api_path + '/text_modules', to: 'text_modules#index', via: :get
|
||||||
match api_path + '/text_modules/:id', to: 'text_modules#update', via: :put
|
match api_path + '/text_modules/:id', to: 'text_modules#show', via: :get
|
||||||
match api_path + '/text_modules/:id', to: 'text_modules#destroy', via: :delete
|
match api_path + '/text_modules', to: 'text_modules#create', via: :post
|
||||||
|
match api_path + '/text_modules/:id', to: 'text_modules#update', via: :put
|
||||||
|
match api_path + '/text_modules/:id', to: 'text_modules#destroy', via: :delete
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@ Zammad::Application.routes.draw do
|
||||||
api_path = Rails.configuration.api_path
|
api_path = Rails.configuration.api_path
|
||||||
|
|
||||||
# users
|
# users
|
||||||
match api_path + '/users/search', to: 'users#search', via: %i[get post]
|
match api_path + '/users/search', to: 'users#search', via: %i[get post option]
|
||||||
match api_path + '/users/recent', to: 'users#recent', via: %i[get post]
|
match api_path + '/users/recent', to: 'users#recent', via: %i[get post]
|
||||||
match api_path + '/users/password_reset', to: 'users#password_reset_send', via: :post
|
match api_path + '/users/password_reset', to: 'users#password_reset_send', via: :post
|
||||||
match api_path + '/users/password_reset_verify', to: 'users#password_reset_verify', via: :post
|
match api_path + '/users/password_reset_verify', to: 'users#password_reset_verify', via: :post
|
||||||
|
@ -11,6 +11,9 @@ Zammad::Application.routes.draw do
|
||||||
match api_path + '/users/out_of_office', to: 'users#out_of_office', via: :put
|
match api_path + '/users/out_of_office', to: 'users#out_of_office', via: :put
|
||||||
match api_path + '/users/account', to: 'users#account_remove', via: :delete
|
match api_path + '/users/account', to: 'users#account_remove', via: :delete
|
||||||
|
|
||||||
|
match api_path + '/users/import_example', to: 'users#import_example', via: :get
|
||||||
|
match api_path + '/users/import', to: 'users#import_start', via: :post
|
||||||
|
|
||||||
match api_path + '/users/avatar', to: 'users#avatar_new', via: :post
|
match api_path + '/users/avatar', to: 'users#avatar_new', via: :post
|
||||||
match api_path + '/users/avatar', to: 'users#avatar_list', via: :get
|
match api_path + '/users/avatar', to: 'users#avatar_list', via: :get
|
||||||
match api_path + '/users/avatar', to: 'users#avatar_destroy', via: :delete
|
match api_path + '/users/avatar', to: 'users#avatar_destroy', via: :delete
|
||||||
|
|
|
@ -14,17 +14,6 @@ class OrganizationControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
UserInfo.current_user_id = 1
|
UserInfo.current_user_id = 1
|
||||||
|
|
||||||
@backup_admin = User.create_or_update(
|
|
||||||
login: 'backup-admin',
|
|
||||||
firstname: 'Backup',
|
|
||||||
lastname: 'Agent',
|
|
||||||
email: 'backup-admin@example.com',
|
|
||||||
password: 'adminpw',
|
|
||||||
active: true,
|
|
||||||
roles: roles,
|
|
||||||
groups: groups,
|
|
||||||
)
|
|
||||||
|
|
||||||
@admin = User.create_or_update(
|
@admin = User.create_or_update(
|
||||||
login: 'rest-admin',
|
login: 'rest-admin',
|
||||||
firstname: 'Rest',
|
firstname: 'Rest',
|
||||||
|
@ -510,4 +499,110 @@ class OrganizationControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test '05.01 csv example - customer no access' do
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-customer1@example.com', 'customer1pw')
|
||||||
|
|
||||||
|
get '/api/v1/organizations/import_example', params: {}, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
assert_response(401)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal('Not authorized (user)!', result['error'])
|
||||||
|
end
|
||||||
|
|
||||||
|
test '05.02 csv example - admin access' do
|
||||||
|
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw')
|
||||||
|
|
||||||
|
get '/api/v1/organizations/import_example', params: {}, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
assert_response(200)
|
||||||
|
|
||||||
|
rows = CSV.parse(@response.body)
|
||||||
|
header = rows.shift
|
||||||
|
|
||||||
|
assert_equal('id', header[0])
|
||||||
|
assert_equal('name', header[1])
|
||||||
|
assert_equal('shared', header[2])
|
||||||
|
assert_equal('domain', header[3])
|
||||||
|
assert_equal('domain_assignment', header[4])
|
||||||
|
assert_equal('active', header[5])
|
||||||
|
assert_equal('note', header[6])
|
||||||
|
assert(header.include?('members'))
|
||||||
|
end
|
||||||
|
|
||||||
|
test '05.03 csv import - admin access' do
|
||||||
|
|
||||||
|
UserInfo.current_user_id = 1
|
||||||
|
customer1 = User.create_or_update(
|
||||||
|
login: 'customer1-members@example.com',
|
||||||
|
firstname: 'Member',
|
||||||
|
lastname: 'Customer',
|
||||||
|
email: 'customer1-members@example.com',
|
||||||
|
password: 'customerpw',
|
||||||
|
active: true,
|
||||||
|
)
|
||||||
|
customer2 = User.create_or_update(
|
||||||
|
login: 'customer2-members@example.com',
|
||||||
|
firstname: 'Member',
|
||||||
|
lastname: 'Customer',
|
||||||
|
email: 'customer2-members@example.com',
|
||||||
|
password: 'customerpw',
|
||||||
|
active: true,
|
||||||
|
)
|
||||||
|
UserInfo.current_user_id = nil
|
||||||
|
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw')
|
||||||
|
|
||||||
|
# invalid file
|
||||||
|
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'organization_simple_col_not_existing.csv'), 'text/csv')
|
||||||
|
post '/api/v1/organizations/import?try=true', params: { file: csv_file }, headers: { 'Authorization' => credentials }
|
||||||
|
assert_response(200)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
|
||||||
|
assert_equal('true', result['try'])
|
||||||
|
assert_equal(2, result['records'].count)
|
||||||
|
assert_equal('failed', result['result'])
|
||||||
|
assert_equal(2, result['errors'].count)
|
||||||
|
assert_equal("Line 1: unknown attribute 'name2' for Organization.", result['errors'][0])
|
||||||
|
assert_equal("Line 2: unknown attribute 'name2' for Organization.", result['errors'][1])
|
||||||
|
|
||||||
|
# valid file try
|
||||||
|
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'organization_simple.csv'), 'text/csv')
|
||||||
|
post '/api/v1/organizations/import?try=true', params: { file: csv_file }, headers: { 'Authorization' => credentials }
|
||||||
|
assert_response(200)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
|
||||||
|
assert_equal('true', result['try'])
|
||||||
|
assert_equal(2, result['records'].count)
|
||||||
|
assert_equal('success', result['result'])
|
||||||
|
|
||||||
|
assert_nil(Organization.find_by(name: 'organization-member-import1'))
|
||||||
|
assert_nil(Organization.find_by(name: 'organization-member-import2'))
|
||||||
|
|
||||||
|
# valid file
|
||||||
|
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'organization_simple.csv'), 'text/csv')
|
||||||
|
post '/api/v1/organizations/import', params: { file: csv_file }, headers: { 'Authorization' => credentials }
|
||||||
|
assert_response(200)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
|
||||||
|
assert_nil(result['try'])
|
||||||
|
assert_equal(2, result['records'].count)
|
||||||
|
assert_equal('success', result['result'])
|
||||||
|
|
||||||
|
organization1 = Organization.find_by(name: 'organization-member-import1')
|
||||||
|
assert(organization1)
|
||||||
|
assert_equal(organization1.name, 'organization-member-import1')
|
||||||
|
assert_equal(organization1.members.count, 1)
|
||||||
|
assert_equal(organization1.members.first.login, customer1.login)
|
||||||
|
assert_equal(organization1.active, true)
|
||||||
|
organization2 = Organization.find_by(name: 'organization-member-import2')
|
||||||
|
assert(organization2)
|
||||||
|
assert_equal(organization2.name, 'organization-member-import2')
|
||||||
|
assert_equal(organization2.members.count, 1)
|
||||||
|
assert_equal(organization2.members.first.login, customer2.login)
|
||||||
|
assert_equal(organization2.active, false)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
157
test/controllers/text_module_controller_test.rb
Normal file
157
test/controllers/text_module_controller_test.rb
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
|
||||||
|
require 'test_helper'
|
||||||
|
require 'rake'
|
||||||
|
|
||||||
|
class TextModuleControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
setup do
|
||||||
|
|
||||||
|
# set accept header
|
||||||
|
@headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
|
||||||
|
|
||||||
|
# create agent
|
||||||
|
roles = Role.where(name: %w[Admin Agent])
|
||||||
|
groups = Group.all
|
||||||
|
|
||||||
|
UserInfo.current_user_id = 1
|
||||||
|
|
||||||
|
@admin = User.create_or_update(
|
||||||
|
login: 'rest-admin',
|
||||||
|
firstname: 'Rest',
|
||||||
|
lastname: 'Agent',
|
||||||
|
email: 'rest-admin@example.com',
|
||||||
|
password: 'adminpw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
groups: groups,
|
||||||
|
)
|
||||||
|
|
||||||
|
# create agent
|
||||||
|
roles = Role.where(name: 'Agent')
|
||||||
|
@agent = User.create_or_update(
|
||||||
|
login: 'rest-agent@example.com',
|
||||||
|
firstname: 'Rest',
|
||||||
|
lastname: 'Agent',
|
||||||
|
email: 'rest-agent@example.com',
|
||||||
|
password: 'agentpw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
groups: groups,
|
||||||
|
)
|
||||||
|
|
||||||
|
# create customer without org
|
||||||
|
roles = Role.where(name: 'Customer')
|
||||||
|
@customer_without_org = User.create_or_update(
|
||||||
|
login: 'rest-customer1@example.com',
|
||||||
|
firstname: 'Rest',
|
||||||
|
lastname: 'Customer1',
|
||||||
|
email: 'rest-customer1@example.com',
|
||||||
|
password: 'customer1pw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
)
|
||||||
|
|
||||||
|
# create customer
|
||||||
|
@customer_with_org = User.create_or_update(
|
||||||
|
login: 'rest-customer2@example.com',
|
||||||
|
firstname: 'Rest',
|
||||||
|
lastname: 'Customer2',
|
||||||
|
email: 'rest-customer2@example.com',
|
||||||
|
password: 'customer2pw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
)
|
||||||
|
|
||||||
|
UserInfo.current_user_id = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
test '05.01 csv example - customer no access' do
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-customer1@example.com', 'customer1pw')
|
||||||
|
|
||||||
|
get '/api/v1/text_modules/import_example', params: {}, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
assert_response(401)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal('Not authorized (user)!', result['error'])
|
||||||
|
end
|
||||||
|
|
||||||
|
test '05.02 csv example - admin access' do
|
||||||
|
TextModule.load('en-en')
|
||||||
|
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw')
|
||||||
|
|
||||||
|
get '/api/v1/text_modules/import_example', params: {}, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
assert_response(200)
|
||||||
|
rows = CSV.parse(@response.body)
|
||||||
|
header = rows.shift
|
||||||
|
|
||||||
|
assert_equal('id', header[0])
|
||||||
|
assert_equal('name', header[1])
|
||||||
|
assert_equal('keywords', header[2])
|
||||||
|
assert_equal('content', header[3])
|
||||||
|
assert_equal('note', header[4])
|
||||||
|
assert_equal('active', header[5])
|
||||||
|
assert_not(header.include?('organization'))
|
||||||
|
assert_not(header.include?('priority'))
|
||||||
|
assert_not(header.include?('state'))
|
||||||
|
assert_not(header.include?('owner'))
|
||||||
|
assert_not(header.include?('customer'))
|
||||||
|
end
|
||||||
|
|
||||||
|
test '05.03 csv import - admin access' do
|
||||||
|
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw')
|
||||||
|
|
||||||
|
# invalid file
|
||||||
|
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'text_module_simple_col_not_existing.csv'), 'text/csv')
|
||||||
|
post '/api/v1/text_modules/import?try=true', params: { file: csv_file }, headers: { 'Authorization' => credentials }
|
||||||
|
assert_response(200)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
|
||||||
|
assert_equal('true', result['try'])
|
||||||
|
assert_equal(2, result['records'].count)
|
||||||
|
assert_equal('failed', result['result'])
|
||||||
|
assert_equal(2, result['errors'].count)
|
||||||
|
assert_equal("Line 1: unknown attribute 'keywords2' for TextModule.", result['errors'][0])
|
||||||
|
assert_equal("Line 2: unknown attribute 'keywords2' for TextModule.", result['errors'][1])
|
||||||
|
|
||||||
|
# valid file try
|
||||||
|
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'text_module_simple.csv'), 'text/csv')
|
||||||
|
post '/api/v1/text_modules/import?try=true', params: { file: csv_file }, headers: { 'Authorization' => credentials }
|
||||||
|
assert_response(200)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
|
||||||
|
assert_equal('true', result['try'])
|
||||||
|
assert_equal(2, result['records'].count)
|
||||||
|
assert_equal('success', result['result'])
|
||||||
|
|
||||||
|
assert_nil(TextModule.find_by(name: 'some name1'))
|
||||||
|
assert_nil(TextModule.find_by(name: 'some name2'))
|
||||||
|
|
||||||
|
# valid file
|
||||||
|
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'text_module_simple.csv'), 'text/csv')
|
||||||
|
post '/api/v1/text_modules/import', params: { file: csv_file }, headers: { 'Authorization' => credentials }
|
||||||
|
assert_response(200)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
|
||||||
|
assert_nil(result['try'])
|
||||||
|
assert_equal(2, result['records'].count)
|
||||||
|
assert_equal('success', result['result'])
|
||||||
|
|
||||||
|
text_module1 = TextModule.find_by(name: 'some name1')
|
||||||
|
assert(text_module1)
|
||||||
|
assert_equal(text_module1.name, 'some name1')
|
||||||
|
assert_equal(text_module1.keywords, 'keyword1')
|
||||||
|
assert_equal(text_module1.content, 'some<br>content1')
|
||||||
|
assert_equal(text_module1.active, true)
|
||||||
|
text_module2 = TextModule.find_by(name: 'some name2')
|
||||||
|
assert(text_module2)
|
||||||
|
assert_equal(text_module2.name, 'some name2')
|
||||||
|
assert_equal(text_module2.keywords, 'keyword2')
|
||||||
|
assert_equal(text_module2.content, 'some content<br>test123')
|
||||||
|
assert_equal(text_module2.active, true)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -957,4 +957,93 @@ class UserControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test '05.01 csv example - customer no access' do
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-customer1@example.com', 'customer1pw')
|
||||||
|
|
||||||
|
get '/api/v1/users/import_example', params: {}, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
assert_response(401)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal('Not authorized (user)!', result['error'])
|
||||||
|
end
|
||||||
|
|
||||||
|
test '05.02 csv example - admin access' do
|
||||||
|
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw')
|
||||||
|
|
||||||
|
get '/api/v1/users/import_example', params: {}, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
assert_response(200)
|
||||||
|
|
||||||
|
rows = CSV.parse(@response.body)
|
||||||
|
header = rows.shift
|
||||||
|
|
||||||
|
assert_equal('id', header[0])
|
||||||
|
assert_equal('login', header[1])
|
||||||
|
assert_equal('firstname', header[2])
|
||||||
|
assert_equal('lastname', header[3])
|
||||||
|
assert_equal('email', header[4])
|
||||||
|
assert(header.include?('organization'))
|
||||||
|
end
|
||||||
|
|
||||||
|
test '05.03 csv import - admin access' do
|
||||||
|
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('rest-admin@example.com', 'adminpw')
|
||||||
|
|
||||||
|
# invalid file
|
||||||
|
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'user_simple_col_not_existing.csv'), 'text/csv')
|
||||||
|
post '/api/v1/users/import?try=true', params: { file: csv_file }, headers: { 'Authorization' => credentials }
|
||||||
|
assert_response(200)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
|
||||||
|
assert_equal('true', result['try'])
|
||||||
|
assert_equal(2, result['records'].count)
|
||||||
|
assert_equal('failed', result['result'])
|
||||||
|
assert_equal(2, result['errors'].count)
|
||||||
|
assert_equal("Line 1: unknown attribute 'firstname2' for User.", result['errors'][0])
|
||||||
|
assert_equal("Line 2: unknown attribute 'firstname2' for User.", result['errors'][1])
|
||||||
|
|
||||||
|
# valid file try
|
||||||
|
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'user_simple.csv'), 'text/csv')
|
||||||
|
post '/api/v1/users/import?try=true', params: { file: csv_file }, headers: { 'Authorization' => credentials }
|
||||||
|
assert_response(200)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
|
||||||
|
assert_equal('true', result['try'])
|
||||||
|
assert_equal(2, result['records'].count)
|
||||||
|
assert_equal('success', result['result'])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-import1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-import2'))
|
||||||
|
|
||||||
|
# valid file
|
||||||
|
csv_file = ::Rack::Test::UploadedFile.new(Rails.root.join('test', 'fixtures', 'csv', 'user_simple.csv'), 'text/csv')
|
||||||
|
post '/api/v1/users/import', params: { file: csv_file }, headers: { 'Authorization' => credentials }
|
||||||
|
assert_response(200)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
|
||||||
|
assert_nil(result['try'])
|
||||||
|
assert_equal(2, result['records'].count)
|
||||||
|
assert_equal('success', result['result'])
|
||||||
|
|
||||||
|
user1 = User.find_by(login: 'user-simple-import1')
|
||||||
|
assert(user1)
|
||||||
|
assert_equal(user1.login, 'user-simple-import1')
|
||||||
|
assert_equal(user1.firstname, 'firstname-simple-import1')
|
||||||
|
assert_equal(user1.lastname, 'lastname-simple-import1')
|
||||||
|
assert_equal(user1.email, 'user-simple-import1@example.com')
|
||||||
|
assert_equal(user1.active, true)
|
||||||
|
user2 = User.find_by(login: 'user-simple-import2')
|
||||||
|
assert(user2)
|
||||||
|
assert_equal(user2.login, 'user-simple-import2')
|
||||||
|
assert_equal(user2.firstname, 'firstname-simple-import2')
|
||||||
|
assert_equal(user2.lastname, 'lastname-simple-import2')
|
||||||
|
assert_equal(user2.email, 'user-simple-import2@example.com')
|
||||||
|
assert_equal(user2.active, false)
|
||||||
|
|
||||||
|
user1.destroy!
|
||||||
|
user2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
4
test/fixtures/csv/organization_simple.csv
vendored
Normal file
4
test/fixtures/csv/organization_simple.csv
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
id;name;members;active
|
||||||
|
;organization-member-import1;customer1-members@example.com
|
||||||
|
;organization-member-import2;customer2-members@example.com;false
|
||||||
|
|
|
3
test/fixtures/csv/organization_simple_col_not_existing.csv
vendored
Normal file
3
test/fixtures/csv/organization_simple_col_not_existing.csv
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
id;name2;shared;domain;domain_assignment;active;note
|
||||||
|
;org-simple-import1;true;org-simple-import1.example.com;false;true;some note1
|
||||||
|
;org-simple-import2;true;org-simple-import2.example.com;false;false;some note2
|
|
4
test/fixtures/csv/text_module_simple.csv
vendored
Normal file
4
test/fixtures/csv/text_module_simple.csv
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
name;keywords;content;note;active;
|
||||||
|
some name1;keyword1;"some
|
||||||
|
content1";-;
|
||||||
|
some name2;keyword2;some content<br>test123
|
Can't render this file because it has a wrong number of fields in line 2.
|
3
test/fixtures/csv/text_module_simple_col_not_existing.csv
vendored
Normal file
3
test/fixtures/csv/text_module_simple_col_not_existing.csv
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
name;keywords2;content;note;active;
|
||||||
|
some name1;keyword1;"some content1";-;
|
||||||
|
some name2;keyword2;some content<br>test123
|
Can't render this file because it has a wrong number of fields in line 2.
|
3
test/fixtures/csv/user_simple.csv
vendored
Normal file
3
test/fixtures/csv/user_simple.csv
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
login;firstname;lastname;email;active;
|
||||||
|
user-simple-import1;firstname-simple-import1;lastname-simple-import1;user-simple-import1@example.com;true
|
||||||
|
user-simple-import2;firstname-simple-import2;lastname-simple-import2;user-simple-import2@example.com;false
|
|
3
test/fixtures/csv/user_simple_col_not_existing.csv
vendored
Normal file
3
test/fixtures/csv/user_simple_col_not_existing.csv
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
login;firstname2;lastname;email;active;
|
||||||
|
user-simple-import1;firstname-simple-import1;lastname-simple-import1;user-simple-import1@example.com;true
|
||||||
|
user-simple-import2;firstname-simple-import2;lastname-simple-import2;user-simple-import2@example.com;false
|
|
209
test/unit/organization_csv_import_test.rb
Normal file
209
test/unit/organization_csv_import_test.rb
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class OrganizationCsvImportTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
|
test 'import example verify' do
|
||||||
|
csv_string = Organization.csv_example
|
||||||
|
|
||||||
|
rows = CSV.parse(csv_string)
|
||||||
|
header = rows.shift
|
||||||
|
assert_equal('id', header[0])
|
||||||
|
assert_equal('name', header[1])
|
||||||
|
assert_equal('shared', header[2])
|
||||||
|
assert_equal('domain', header[3])
|
||||||
|
assert_equal('domain_assignment', header[4])
|
||||||
|
assert_equal('active', header[5])
|
||||||
|
assert_equal('note', header[6])
|
||||||
|
assert(header.include?('members'))
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'simple import' do
|
||||||
|
|
||||||
|
csv_string = "id;name;shared;domain;domain_assignment;active;note\n;org-simple-import1;true;org-simple-import1.example.com;false;true;some note1\n;org-simple-import2;true;org-simple-import2.example.com;false;false;some note2\n"
|
||||||
|
result = Organization.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
assert_nil(Organization.find_by(name: 'org-simple-import1'))
|
||||||
|
assert_nil(Organization.find_by(name: 'org-simple-import2'))
|
||||||
|
|
||||||
|
result = Organization.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
organization1 = Organization.find_by(name: 'org-simple-import1')
|
||||||
|
assert(organization1)
|
||||||
|
assert_equal(organization1.name, 'org-simple-import1')
|
||||||
|
assert_equal(organization1.shared, true)
|
||||||
|
assert_equal(organization1.domain, 'org-simple-import1.example.com')
|
||||||
|
assert_equal(organization1.domain_assignment, false)
|
||||||
|
assert_equal(organization1.note, 'some note1')
|
||||||
|
assert_equal(organization1.active, true)
|
||||||
|
organization2 = Organization.find_by(name: 'org-simple-import2')
|
||||||
|
assert(organization2)
|
||||||
|
assert_equal(organization2.name, 'org-simple-import2')
|
||||||
|
assert_equal(organization2.shared, true)
|
||||||
|
assert_equal(organization2.domain, 'org-simple-import2.example.com')
|
||||||
|
assert_equal(organization2.domain_assignment, false)
|
||||||
|
assert_equal(organization2.note, 'some note2')
|
||||||
|
assert_equal(organization2.active, false)
|
||||||
|
|
||||||
|
organization1.destroy!
|
||||||
|
organization2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'simple import with invalid id' do
|
||||||
|
|
||||||
|
csv_string = "id;name;shared;domain;domain_assignment;active;note;\n999999999;organization-simple-invalid_id-import1;\n;organization-simple-invalid_id-import2;\n"
|
||||||
|
result = Organization.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(1, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
assert_equal("Line 1: unknown record with id '999999999' for Organization.", result[:errors][0])
|
||||||
|
|
||||||
|
assert_nil(Organization.find_by(name: 'organization-simple-invalid_id-import1'))
|
||||||
|
assert_nil(Organization.find_by(name: 'organization-simple-invalid_id-import2'))
|
||||||
|
|
||||||
|
result = Organization.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(1, result[:records].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
|
||||||
|
assert_nil(Organization.find_by(name: 'organization-simple-invalid_id-import1'))
|
||||||
|
|
||||||
|
organization2 = Organization.find_by(name: 'organization-simple-invalid_id-import2')
|
||||||
|
assert(organization2)
|
||||||
|
assert_equal(organization2.name, 'organization-simple-invalid_id-import2')
|
||||||
|
assert_equal(organization2.active, true)
|
||||||
|
|
||||||
|
organization2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'simple import with members' do
|
||||||
|
UserInfo.current_user_id = 1
|
||||||
|
|
||||||
|
name = rand(999_999_999)
|
||||||
|
customer1 = User.create_or_update(
|
||||||
|
login: "customer1-members#{name}@example.com",
|
||||||
|
firstname: 'Member',
|
||||||
|
lastname: "Customer#{name}",
|
||||||
|
email: "customer1-members#{name}@example.com",
|
||||||
|
password: 'customerpw',
|
||||||
|
active: true,
|
||||||
|
)
|
||||||
|
customer2 = User.create_or_update(
|
||||||
|
login: "customer2-members#{name}@example.com",
|
||||||
|
firstname: 'Member',
|
||||||
|
lastname: "Customer#{name}",
|
||||||
|
email: "customer2-members#{name}@example.com",
|
||||||
|
password: 'customerpw',
|
||||||
|
active: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
csv_string = "id;name;members;\n;organization-member-import1;\n;organization-member-import2;#{customer1.email}\n;;#{customer2.email}"
|
||||||
|
result = Organization.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
assert_nil(Organization.find_by(name: 'organization-member-import1'))
|
||||||
|
assert_nil(Organization.find_by(name: 'organization-member-import2'))
|
||||||
|
|
||||||
|
result = Organization.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
organization1 = Organization.find_by(name: 'organization-member-import1')
|
||||||
|
assert(organization1)
|
||||||
|
assert_equal(organization1.name, 'organization-member-import1')
|
||||||
|
assert_equal(organization1.members.count, 0)
|
||||||
|
organization2 = Organization.find_by(name: 'organization-member-import2')
|
||||||
|
assert(organization2)
|
||||||
|
assert_equal(organization2.name, 'organization-member-import2')
|
||||||
|
assert_equal(organization2.members.count, 2)
|
||||||
|
|
||||||
|
customer1.destroy!
|
||||||
|
customer2.destroy!
|
||||||
|
organization1.destroy!
|
||||||
|
organization2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'invalid attributes' do
|
||||||
|
|
||||||
|
csv_string = "name;note;not existing\norganization-invalid-import1;some note;abc\norganization-invalid-import2;some other note;123; with not exsiting header\n"
|
||||||
|
result = Organization.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(2, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
assert_equal("Line 1: unknown attribute 'not existing' for Organization.", result[:errors][0])
|
||||||
|
assert_equal("Line 2: unknown attribute 'not existing' for Organization.", result[:errors][1])
|
||||||
|
|
||||||
|
assert_nil(Organization.find_by(name: 'organization-invalid-import1'))
|
||||||
|
assert_nil(Organization.find_by(name: 'organization-invalid-import2'))
|
||||||
|
|
||||||
|
result = Organization.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(2, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
assert_equal("Line 1: unknown attribute 'not existing' for Organization.", result[:errors][0])
|
||||||
|
assert_equal("Line 2: unknown attribute 'not existing' for Organization.", result[:errors][1])
|
||||||
|
|
||||||
|
assert_nil(Organization.find_by(name: 'organization-invalid-import1'))
|
||||||
|
assert_nil(Organization.find_by(name: 'organization-invalid-import2'))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
72
test/unit/text_module_csv_import_test.rb
Normal file
72
test/unit/text_module_csv_import_test.rb
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class TextModuleCsvImportTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
|
test 'import example verify' do
|
||||||
|
TextModule.load('en-en')
|
||||||
|
csv_string = TextModule.csv_example
|
||||||
|
|
||||||
|
rows = CSV.parse(csv_string)
|
||||||
|
header = rows.shift
|
||||||
|
assert_equal('id', header[0])
|
||||||
|
assert_equal('name', header[1])
|
||||||
|
assert_equal('keywords', header[2])
|
||||||
|
assert_equal('content', header[3])
|
||||||
|
assert_equal('note', header[4])
|
||||||
|
assert_equal('active', header[5])
|
||||||
|
assert_not(header.include?('organization'))
|
||||||
|
assert_not(header.include?('priority'))
|
||||||
|
assert_not(header.include?('state'))
|
||||||
|
assert_not(header.include?('owner'))
|
||||||
|
assert_not(header.include?('customer'))
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'simple import' do
|
||||||
|
|
||||||
|
csv_string = "name;keywords;content;note;active;\nsome name1;keyword1;\"some\ncontent1\";-;\nsome name2;keyword2;some content<br>test123\n"
|
||||||
|
result = TextModule.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
assert_nil(TextModule.find_by(name: 'some name1'))
|
||||||
|
assert_nil(TextModule.find_by(name: 'some name2'))
|
||||||
|
|
||||||
|
result = TextModule.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
text_module1 = TextModule.find_by(name: 'some name1')
|
||||||
|
assert(text_module1)
|
||||||
|
assert_equal(text_module1.name, 'some name1')
|
||||||
|
assert_equal(text_module1.keywords, 'keyword1')
|
||||||
|
assert_equal(text_module1.content, 'some<br>content1')
|
||||||
|
assert_equal(text_module1.active, true)
|
||||||
|
text_module2 = TextModule.find_by(name: 'some name2')
|
||||||
|
assert(text_module2)
|
||||||
|
assert_equal(text_module2.name, 'some name2')
|
||||||
|
assert_equal(text_module2.keywords, 'keyword2')
|
||||||
|
assert_equal(text_module2.content, 'some content<br>test123')
|
||||||
|
assert_equal(text_module2.active, true)
|
||||||
|
|
||||||
|
text_module1.destroy!
|
||||||
|
text_module2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
172
test/unit/ticket_csv_import_test.rb
Normal file
172
test/unit/ticket_csv_import_test.rb
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class TicketCsvImportTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
|
test 'import example verify' do
|
||||||
|
csv_string = Ticket.csv_example
|
||||||
|
|
||||||
|
rows = CSV.parse(csv_string)
|
||||||
|
header = rows.shift
|
||||||
|
assert_equal('id', header[0])
|
||||||
|
assert_equal('number', header[1])
|
||||||
|
assert_equal('title', header[2])
|
||||||
|
assert_equal('note', header[3])
|
||||||
|
assert_equal('first_response_at', header[4])
|
||||||
|
assert_equal('first_response_escalation_at', header[5])
|
||||||
|
assert(header.include?('organization'))
|
||||||
|
assert(header.include?('priority'))
|
||||||
|
assert(header.include?('state'))
|
||||||
|
assert(header.include?('owner'))
|
||||||
|
assert(header.include?('customer'))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'simple import' do
|
||||||
|
|
||||||
|
csv_string = "id;number;title;state;priority;owner;customer;group;note\n;123456;some title1;new;2 normal;-;nicole.braun@zammad.org;Users;some note1\n;123457;some title2;closed;1 low;admin@example.com;nicole.braun@zammad.org;Users;some note2\n"
|
||||||
|
result = Ticket.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
assert_nil(Ticket.find_by(number: '123456'))
|
||||||
|
assert_nil(Ticket.find_by(number: '123457'))
|
||||||
|
|
||||||
|
result = Ticket.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
ticket1 = Ticket.find_by(number: '123456')
|
||||||
|
assert(ticket1)
|
||||||
|
assert_equal(ticket1.number, '123456')
|
||||||
|
assert_equal(ticket1.title, 'some title1')
|
||||||
|
assert_equal(ticket1.state.name, 'new')
|
||||||
|
assert_equal(ticket1.priority.name, '2 normal')
|
||||||
|
assert_equal(ticket1.owner.login, '-')
|
||||||
|
assert_equal(ticket1.customer.login, 'nicole.braun@zammad.org')
|
||||||
|
assert_equal(ticket1.note, 'some note1')
|
||||||
|
ticket2 = Ticket.find_by(number: '123457')
|
||||||
|
assert(ticket2)
|
||||||
|
assert_equal(ticket2.number, '123457')
|
||||||
|
assert_equal(ticket2.title, 'some title2')
|
||||||
|
assert_equal(ticket2.state.name, 'closed')
|
||||||
|
assert_equal(ticket2.priority.name, '1 low')
|
||||||
|
assert_equal(ticket2.owner.login, 'admin@example.com')
|
||||||
|
assert_equal(ticket2.customer.login, 'nicole.braun@zammad.org')
|
||||||
|
assert_equal(ticket2.note, 'some note2')
|
||||||
|
|
||||||
|
ticket1.destroy!
|
||||||
|
ticket2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'simple import with invalid id' do
|
||||||
|
|
||||||
|
csv_string = "id;number;title;state;priority;owner;customer;group;note\n999999999;123456;some title1;new;2 normal;-;nicole.braun@zammad.org;Users;some note1\n;123457;some title2;closed;1 low;admin@example.com;nicole.braun@zammad.org;Users;some note2\n"
|
||||||
|
result = Ticket.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(1, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
assert_equal("Line 1: unknown record with id '999999999' for Ticket.", result[:errors][0])
|
||||||
|
|
||||||
|
assert_nil(Ticket.find_by(number: '123456'))
|
||||||
|
assert_nil(Ticket.find_by(number: '123457'))
|
||||||
|
|
||||||
|
result = Ticket.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(1, result[:records].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
|
||||||
|
assert_nil(Ticket.find_by(number: '123456'))
|
||||||
|
|
||||||
|
ticket2 = Ticket.find_by(number: '123457')
|
||||||
|
assert(ticket2)
|
||||||
|
assert_equal(ticket2.title, 'some title2')
|
||||||
|
assert_equal(ticket2.note, 'some note2')
|
||||||
|
|
||||||
|
csv_string = "id;number;title;state;priority;owner;customer;group;note\n999999999;123456;some title1;new;2 normal;-;nicole.braun@zammad.org;Users;some note1\n;123457;some title22;closed;1 low;admin@example.com;nicole.braun@zammad.org;Users;some note22\n"
|
||||||
|
|
||||||
|
result = Ticket.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(1, result[:records].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
|
||||||
|
assert_nil(Ticket.find_by(number: '123456'))
|
||||||
|
|
||||||
|
ticket2 = Ticket.find_by(number: '123457')
|
||||||
|
assert(ticket2)
|
||||||
|
assert_equal(ticket2.title, 'some title22')
|
||||||
|
assert_equal(ticket2.note, 'some note22')
|
||||||
|
|
||||||
|
ticket2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'invalid attributes' do
|
||||||
|
|
||||||
|
csv_string = "id;number;not_existing;state;priority;owner;customer;group;note\n;123456;some title1;new;2 normal;-;nicole.braun@zammad.org;Users;some note1\n;123457;some title2;closed;1 low;admin@example.com;nicole.braun@zammad.org;Users;some note2\n"
|
||||||
|
result = Ticket.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(2, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
assert_equal("Line 1: unknown attribute 'not_existing' for Ticket.", result[:errors][0])
|
||||||
|
assert_equal("Line 2: unknown attribute 'not_existing' for Ticket.", result[:errors][1])
|
||||||
|
|
||||||
|
assert_nil(Ticket.find_by(number: '123456'))
|
||||||
|
assert_nil(Ticket.find_by(number: '123457'))
|
||||||
|
|
||||||
|
result = Ticket.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(2, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
assert_equal("Line 1: unknown attribute 'not_existing' for Ticket.", result[:errors][0])
|
||||||
|
assert_equal("Line 2: unknown attribute 'not_existing' for Ticket.", result[:errors][1])
|
||||||
|
|
||||||
|
assert_nil(Ticket.find_by(number: '123456'))
|
||||||
|
assert_nil(Ticket.find_by(number: '123457'))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
416
test/unit/user_csv_import_test.rb
Normal file
416
test/unit/user_csv_import_test.rb
Normal file
|
@ -0,0 +1,416 @@
|
||||||
|
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class UserCsvImportTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
|
test 'import example verify' do
|
||||||
|
csv_string = User.csv_example
|
||||||
|
|
||||||
|
rows = CSV.parse(csv_string)
|
||||||
|
header = rows.shift
|
||||||
|
|
||||||
|
assert_equal('id', header[0])
|
||||||
|
assert_equal('login', header[1])
|
||||||
|
assert_equal('firstname', header[2])
|
||||||
|
assert_equal('lastname', header[3])
|
||||||
|
assert_equal('email', header[4])
|
||||||
|
assert(header.include?('organization'))
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'simple import' do
|
||||||
|
|
||||||
|
csv_string = "login;firstname;lastname;email;active;\nuser-simple-import1;firstname-simple-import1;lastname-simple-import1;user-simple-import1@example.com;true\nuser-simple-import2;firstname-simple-import2;lastname-simple-import2;user-simple-import2@example.com;false\n"
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-import1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-import2'))
|
||||||
|
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
user1 = User.find_by(login: 'user-simple-import1')
|
||||||
|
assert(user1)
|
||||||
|
assert_equal(user1.login, 'user-simple-import1')
|
||||||
|
assert_equal(user1.firstname, 'firstname-simple-import1')
|
||||||
|
assert_equal(user1.lastname, 'lastname-simple-import1')
|
||||||
|
assert_equal(user1.email, 'user-simple-import1@example.com')
|
||||||
|
assert_equal(user1.active, true)
|
||||||
|
user2 = User.find_by(login: 'user-simple-import2')
|
||||||
|
assert(user2)
|
||||||
|
assert_equal(user2.login, 'user-simple-import2')
|
||||||
|
assert_equal(user2.firstname, 'firstname-simple-import2')
|
||||||
|
assert_equal(user2.lastname, 'lastname-simple-import2')
|
||||||
|
assert_equal(user2.email, 'user-simple-import2@example.com')
|
||||||
|
assert_equal(user2.active, false)
|
||||||
|
|
||||||
|
user1.destroy!
|
||||||
|
user2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'simple import with invalid id' do
|
||||||
|
|
||||||
|
csv_string = "id;login;firstname;lastname;email;active;\n999999999;user-simple-invalid_id-import1;firstname-simple-import1;lastname-simple-import1;user-simple-invalid_id-import1@example.com;true\n;user-simple-invalid_id-import2;firstname-simple-import2;lastname-simple-import2;user-simple-invalid_id-import2@example.com;false\n"
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(1, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
assert_equal("Line 1: unknown record with id '999999999' for User.", result[:errors][0])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-invalid_id-import1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-invalid_id-import2'))
|
||||||
|
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(1, result[:records].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-invalid_id-import1'))
|
||||||
|
|
||||||
|
user2 = User.find_by(login: 'user-simple-invalid_id-import2')
|
||||||
|
assert(user2)
|
||||||
|
assert_equal(user2.login, 'user-simple-invalid_id-import2')
|
||||||
|
assert_equal(user2.firstname, 'firstname-simple-import2')
|
||||||
|
assert_equal(user2.lastname, 'lastname-simple-import2')
|
||||||
|
assert_equal(user2.email, 'user-simple-invalid_id-import2@example.com')
|
||||||
|
assert_equal(user2.active, false)
|
||||||
|
|
||||||
|
user2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'simple import with read only id' do
|
||||||
|
|
||||||
|
csv_string = "id;login;firstname;lastname;email;active;\n1;user-simple-readonly_id-import1;firstname-simple-import1;lastname-simple-import1;user-simple-readonly_id-import1@example.com;true\n;user-simple-readonly_id-import2;firstname-simple-import2;lastname-simple-import2;user-simple-readonly_id-import2@example.com;false\n"
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(1, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
assert_equal("Line 1: unable to update record with id '1' for User.", result[:errors][0])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-readonly_id-import1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-readonly_id-import2'))
|
||||||
|
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(1, result[:records].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-readonly_id-import1'))
|
||||||
|
|
||||||
|
user2 = User.find_by(login: 'user-simple-readonly_id-import2')
|
||||||
|
assert(user2)
|
||||||
|
assert_equal(user2.login, 'user-simple-readonly_id-import2')
|
||||||
|
assert_equal(user2.firstname, 'firstname-simple-import2')
|
||||||
|
assert_equal(user2.lastname, 'lastname-simple-import2')
|
||||||
|
assert_equal(user2.email, 'user-simple-readonly_id-import2@example.com')
|
||||||
|
assert_equal(user2.active, false)
|
||||||
|
|
||||||
|
user2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'simple import with roles' do
|
||||||
|
UserInfo.current_user_id = 1
|
||||||
|
|
||||||
|
admin = User.create_or_update(
|
||||||
|
login: 'admin1@example.com',
|
||||||
|
firstname: 'Admin',
|
||||||
|
lastname: '1',
|
||||||
|
email: 'admin1@example.com',
|
||||||
|
password: 'agentpw',
|
||||||
|
active: true,
|
||||||
|
roles: Role.where(name: 'Admin'),
|
||||||
|
)
|
||||||
|
|
||||||
|
csv_string = "login;firstname;lastname;email;roles;\nuser-role-import1;firstname-role-import1;lastname-role-import1;user-role-import1@example.com;Customer;\nuser-role-import2;firstname-role-import2;lastname-role-import2;user-role-import2@example.com;Agent\n;;;;Admin"
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-role-import1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-role-import2'))
|
||||||
|
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
user1 = User.find_by(login: 'user-role-import1')
|
||||||
|
assert(user1)
|
||||||
|
assert_equal(user1.login, 'user-role-import1')
|
||||||
|
assert_equal(user1.firstname, 'firstname-role-import1')
|
||||||
|
assert_equal(user1.lastname, 'lastname-role-import1')
|
||||||
|
assert_equal(user1.email, 'user-role-import1@example.com')
|
||||||
|
assert_equal(user1.roles.count, 1)
|
||||||
|
user2 = User.find_by(login: 'user-role-import2')
|
||||||
|
assert(user2)
|
||||||
|
assert_equal(user2.login, 'user-role-import2')
|
||||||
|
assert_equal(user2.firstname, 'firstname-role-import2')
|
||||||
|
assert_equal(user2.lastname, 'lastname-role-import2')
|
||||||
|
assert_equal(user2.email, 'user-role-import2@example.com')
|
||||||
|
assert_equal(user2.roles.count, 2)
|
||||||
|
|
||||||
|
user1.destroy!
|
||||||
|
user2.destroy!
|
||||||
|
admin.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'simple import + fixed params' do
|
||||||
|
|
||||||
|
csv_string = "login;firstname;lastname;email\nuser-simple-import-fixed1;firstname-simple-import-fixed1;lastname-simple-import-fixed1;user-simple-import-fixed1@example.com\nuser-simple-import-fixed2;firstname-simple-import-fixed2;lastname-simple-import-fixed2;user-simple-import-fixed2@example.com\n"
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
fixed_params: {
|
||||||
|
note: 'some note',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-import-fixed1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-simple-import-fixed2'))
|
||||||
|
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
fixed_params: {
|
||||||
|
note: 'some note',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(2, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
user1 = User.find_by(login: 'user-simple-import-fixed1')
|
||||||
|
user2 = User.find_by(login: 'user-simple-import-fixed2')
|
||||||
|
assert(user1)
|
||||||
|
assert_equal('some note', user1.note)
|
||||||
|
assert_equal('user-simple-import-fixed1', user1.login)
|
||||||
|
assert_equal('firstname-simple-import-fixed1', user1.firstname)
|
||||||
|
assert_equal('lastname-simple-import-fixed1', user1.lastname)
|
||||||
|
assert_equal('user-simple-import-fixed1@example.com', user1.email)
|
||||||
|
|
||||||
|
assert(user2)
|
||||||
|
assert_equal('some note', user2.note)
|
||||||
|
assert_equal('user-simple-import-fixed2', user2.login)
|
||||||
|
assert_equal('firstname-simple-import-fixed2', user2.firstname)
|
||||||
|
assert_equal('lastname-simple-import-fixed2', user2.lastname)
|
||||||
|
assert_equal('user-simple-import-fixed2@example.com', user2.email)
|
||||||
|
|
||||||
|
user1.destroy!
|
||||||
|
user2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'duplicate import' do
|
||||||
|
|
||||||
|
csv_string = "login;firstname;lastname;email\nuser-duplicate-import1;firstname-duplicate-import1;firstname-duplicate-import1;user-duplicate-import1@example.com\nuser-duplicate-import2;firstname-duplicate-import2;firstname-duplicate-import2;user-duplicate-import2@example.com\nuser-duplicate-import2;firstname-duplicate-import3;firstname-duplicate-import3;user-duplicate-import3@example.com"
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(3, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-duplicate-import1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-duplicate-import2'))
|
||||||
|
assert_nil(User.find_by(login: 'user-duplicate-import3'))
|
||||||
|
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(3, result[:records].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
assert(User.find_by(login: 'user-duplicate-import1'))
|
||||||
|
assert(User.find_by(login: 'user-duplicate-import2'))
|
||||||
|
assert_nil(User.find_by(login: 'user-duplicate-import3'))
|
||||||
|
|
||||||
|
User.find_by(login: 'user-duplicate-import1').destroy!
|
||||||
|
User.find_by(login: 'user-duplicate-import2').destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'invalid attributes' do
|
||||||
|
|
||||||
|
csv_string = "login;firstname2;lastname;email\nuser-invalid-import1;firstname-invalid-import1;firstname-invalid-import1;user-invalid-import1@example.com\nuser-invalid-import2;firstname-invalid-import2;firstname-invalid-import2;user-invalid-import2@example.com\n"
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(2, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
assert_equal("Line 1: unknown attribute 'firstname2' for User.", result[:errors][0])
|
||||||
|
assert_equal("Line 2: unknown attribute 'firstname2' for User.", result[:errors][1])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-invalid-import1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-invalid-import2'))
|
||||||
|
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(2, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
assert_equal("Line 1: unknown attribute 'firstname2' for User.", result[:errors][0])
|
||||||
|
assert_equal("Line 2: unknown attribute 'firstname2' for User.", result[:errors][1])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-invalid-import1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-invalid-import2'))
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'reference import' do
|
||||||
|
|
||||||
|
csv_string = "login;firstname;lastname;email;organization\nuser-reference-import1;firstname-reference-import1;firstname-reference-import1;user-reference-import1@example.com;organization-reference-import1\nuser-reference-import2;firstname-reference-import2;firstname-reference-import2;user-reference-import2@example.com;organization-reference-import2\nuser-reference-import3;firstname-reference-import3;firstname-reference-import3;user-reference-import3@example.com;Zammad Foundation\n"
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(2, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
assert_nil(User.find_by(login: 'user-reference-import1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-reference-import2'))
|
||||||
|
assert_nil(User.find_by(login: 'user-reference-import3'))
|
||||||
|
assert_equal("Line 1: No lookup value found for 'organization': \"organization-reference-import1\"", result[:errors][0])
|
||||||
|
assert_equal("Line 2: No lookup value found for 'organization': \"organization-reference-import2\"", result[:errors][1])
|
||||||
|
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(2, result[:errors].count)
|
||||||
|
assert_equal('failed', result[:result])
|
||||||
|
|
||||||
|
assert_nil(User.find_by(login: 'user-reference-import1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-reference-import2'))
|
||||||
|
assert(User.find_by(login: 'user-reference-import3'))
|
||||||
|
assert_equal("Line 1: No lookup value found for 'organization': \"organization-reference-import1\"", result[:errors][0])
|
||||||
|
assert_equal("Line 2: No lookup value found for 'organization': \"organization-reference-import2\"", result[:errors][1])
|
||||||
|
|
||||||
|
UserInfo.current_user_id = 1
|
||||||
|
orgaization1 = Organization.create_if_not_exists(name: 'organization-reference-import1')
|
||||||
|
orgaization2 = Organization.create_if_not_exists(name: 'organization-reference-import2')
|
||||||
|
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: true,
|
||||||
|
)
|
||||||
|
assert_equal(true, result[:try])
|
||||||
|
assert_equal(0, result[:errors].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
assert_nil(User.find_by(login: 'user-reference-import1'))
|
||||||
|
assert_nil(User.find_by(login: 'user-reference-import2'))
|
||||||
|
assert(User.find_by(login: 'user-reference-import3'))
|
||||||
|
|
||||||
|
result = User.csv_import(
|
||||||
|
string: csv_string,
|
||||||
|
parse_params: {
|
||||||
|
col_sep: ';',
|
||||||
|
},
|
||||||
|
try: false,
|
||||||
|
)
|
||||||
|
assert_equal(false, result[:try])
|
||||||
|
assert_equal(0, result[:errors].count)
|
||||||
|
assert_equal('success', result[:result])
|
||||||
|
|
||||||
|
assert(User.find_by(login: 'user-reference-import1'))
|
||||||
|
assert(User.find_by(login: 'user-reference-import2'))
|
||||||
|
assert(User.find_by(login: 'user-reference-import3'))
|
||||||
|
|
||||||
|
User.find_by(login: 'user-reference-import1').destroy!
|
||||||
|
User.find_by(login: 'user-reference-import2').destroy!
|
||||||
|
User.find_by(login: 'user-reference-import3').destroy!
|
||||||
|
|
||||||
|
orgaization1.destroy!
|
||||||
|
orgaization2.destroy!
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -570,7 +570,6 @@ class UserTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
test 'ensure roles' do
|
test 'ensure roles' do
|
||||||
name = rand(999_999_999)
|
name = rand(999_999_999)
|
||||||
|
|
||||||
admin = User.create_or_update(
|
admin = User.create_or_update(
|
||||||
login: "admin-role#{name}@example.com",
|
login: "admin-role#{name}@example.com",
|
||||||
firstname: 'Role',
|
firstname: 'Role',
|
||||||
|
|
Loading…
Reference in a new issue