Introduced create_if_not_exists_with_ref and create_or_update_with_ref for automatically lookup references by name/login.
This commit is contained in:
parent
b348d70f23
commit
5d13730515
5 changed files with 490 additions and 47 deletions
|
@ -288,12 +288,30 @@ returns
|
|||
|
||||
do name/login/email based lookup for associations
|
||||
|
||||
params = {
|
||||
login: 'some login',
|
||||
firstname: 'some firstname',
|
||||
lastname: 'some lastname',
|
||||
email: 'some email',
|
||||
organization: 'some organization',
|
||||
roles: ['Agent', 'Admin'],
|
||||
}
|
||||
|
||||
attributes = Model.param_association_lookup(params)
|
||||
|
||||
returns
|
||||
|
||||
attributes = params # params with possible lookups
|
||||
|
||||
attributes = {
|
||||
login: 'some login',
|
||||
firstname: 'some firstname',
|
||||
lastname: 'some lastname',
|
||||
email: 'some email',
|
||||
organization_id: 123,
|
||||
role_ids: [2,1],
|
||||
}
|
||||
|
||||
=end
|
||||
|
||||
def self.param_association_lookup(params)
|
||||
|
@ -309,19 +327,25 @@ returns
|
|||
value = data[assoc.name.to_sym]
|
||||
next if !value # next if we do not have a value
|
||||
ref_name = "#{assoc.name}_id"
|
||||
next if !available_attributes.include?(ref_name) # next if we do not have an _id attribute
|
||||
next if data[ref_name.to_sym] # next if we have already the id filled
|
||||
|
||||
# handle _id values
|
||||
if available_attributes.include?(ref_name) # if we do have an _id attribute
|
||||
next if data[ref_name.to_sym] # next if we have already the _id filled
|
||||
|
||||
# get association class and do lookup
|
||||
class_object = assoc.klass
|
||||
lookup = nil
|
||||
if class_object == User
|
||||
if value.class == String
|
||||
if !lookup
|
||||
lookup = class_object.lookup(login: value)
|
||||
end
|
||||
if !lookup
|
||||
lookup = class_object.lookup(email: value)
|
||||
end
|
||||
else
|
||||
raise "String is needed as ref value #{value.inspect} for '#{assoc.name}'"
|
||||
end
|
||||
else
|
||||
lookup = class_object.lookup(name: value)
|
||||
end
|
||||
|
@ -336,6 +360,51 @@ returns
|
|||
|
||||
# remember id reference
|
||||
data[ref_name.to_sym] = lookup.id
|
||||
next
|
||||
end
|
||||
|
||||
next if value.class != Array
|
||||
next if value.empty?
|
||||
next if value[0].class != String
|
||||
|
||||
# handle _ids values
|
||||
ref_names = "#{assoc.name[0, assoc.name.length - 1]}_ids"
|
||||
generic_object_tmp = new
|
||||
next unless generic_object_tmp.respond_to?(ref_names) # if we do have an _ids attribute
|
||||
next if data[ref_names.to_sym] # next if we have already the _ids filled
|
||||
|
||||
# get association class and do lookup
|
||||
class_object = assoc.klass
|
||||
lookup_ids = []
|
||||
value.each {|item|
|
||||
lookup = nil
|
||||
if class_object == User
|
||||
if item.class == String
|
||||
if !lookup
|
||||
lookup = class_object.lookup(login: item)
|
||||
end
|
||||
if !lookup
|
||||
lookup = class_object.lookup(email: item)
|
||||
end
|
||||
else
|
||||
raise "String is needed in array ref as ref value #{value.inspect} for '#{assoc.name}'"
|
||||
end
|
||||
else
|
||||
lookup = class_object.lookup(name: item)
|
||||
end
|
||||
|
||||
# complain if we found no reference
|
||||
if !lookup
|
||||
raise "No lookup value found for '#{assoc.name}': #{item.inspect}"
|
||||
end
|
||||
lookup_ids.push lookup.id
|
||||
}
|
||||
|
||||
# release data value
|
||||
data.delete(assoc.name.to_sym)
|
||||
|
||||
# remember id reference
|
||||
data[ref_names.to_sym] = lookup_ids
|
||||
}
|
||||
|
||||
data
|
||||
|
@ -613,6 +682,23 @@ returns
|
|||
|
||||
=begin
|
||||
|
||||
Model.create_if_not_exists with ref lookups
|
||||
|
||||
result = Model.create_if_not_exists_with_ref(attributes)
|
||||
|
||||
returns
|
||||
|
||||
result = model # with all attributes
|
||||
|
||||
=end
|
||||
|
||||
def self.create_if_not_exists_with_ref(data)
|
||||
data = param_association_lookup(data)
|
||||
create_or_update(data)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
create or update model (check exists based on id, name, login, email or locale)
|
||||
|
||||
result = Model.create_or_update(attributes)
|
||||
|
@ -708,6 +794,23 @@ returns
|
|||
|
||||
=begin
|
||||
|
||||
Model.create_or_update with ref lookups
|
||||
|
||||
result = Model.create_or_update(attributes)
|
||||
|
||||
returns
|
||||
|
||||
result = model # with all attributes
|
||||
|
||||
=end
|
||||
|
||||
def self.create_or_update_with_ref(data)
|
||||
data = param_association_lookup(data)
|
||||
create_or_update(data)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
activate latest change on create, update, touch and destroy
|
||||
|
||||
class Model < ApplicationModel
|
||||
|
|
|
@ -12,7 +12,14 @@
|
|||
"firstname": "Agent 1",
|
||||
"lastname": "Test",
|
||||
"email": "agent1@example.com",
|
||||
"password": "test"
|
||||
"password": "test",
|
||||
"roles": ["Agent"]
|
||||
}
|
||||
],
|
||||
"Groups": [
|
||||
{
|
||||
"name": "some group1",
|
||||
"users": ["master@example.com","agent1@example.com"]
|
||||
}
|
||||
],
|
||||
"Settings": [
|
||||
|
|
|
@ -77,38 +77,34 @@ returns
|
|||
}
|
||||
end
|
||||
|
||||
# create Organizations
|
||||
if auto_wizard_hash['Organizations']
|
||||
auto_wizard_hash['Organizations'].each { |organization_data|
|
||||
Organization.create_or_update(organization_data.symbolize_keys)
|
||||
# create EmailAddresses/Channels/Signatures
|
||||
model_map = {
|
||||
'Organizations' => 'Organization',
|
||||
}
|
||||
model_map.each {|map_name, model|
|
||||
next if !auto_wizard_hash[map_name]
|
||||
auto_wizard_hash[map_name].each {|data|
|
||||
generic_object = Kernel.const_get(model)
|
||||
data.symbolize_keys!
|
||||
generic_object.create_or_update_with_ref(data)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
# create Users
|
||||
if auto_wizard_hash['Users']
|
||||
|
||||
roles = Role.where( name: %w(Agent Admin) )
|
||||
groups = Group.all
|
||||
|
||||
auto_wizard_hash['Users'].each { |user_data|
|
||||
user_data.symbolize_keys!
|
||||
|
||||
# lookup organization
|
||||
if user_data['organization'] && !user_data['organization'].empty?
|
||||
organization = Organization.find_by(name: user_data['organization'])
|
||||
if organization
|
||||
user_data['organization_id'] = organization.id
|
||||
if admin_user.id == 1
|
||||
if !user_data[:roles] && !user_data[:role_ids]
|
||||
user_data[:roles] = Role.where(name: %w(Agent Admin))
|
||||
end
|
||||
if !user_data[:groups] && !user_data[:group_ids]
|
||||
user_data[:groups] = Group.all
|
||||
end
|
||||
end
|
||||
user_data.delete('organization')
|
||||
|
||||
user_data_symbolized = user_data.symbolize_keys.merge(
|
||||
{
|
||||
active: true,
|
||||
roles: roles,
|
||||
groups: groups,
|
||||
}
|
||||
)
|
||||
created_user = User.create_or_update(user_data_symbolized)
|
||||
created_user = User.create_or_update_with_ref(user_data)
|
||||
|
||||
# use first created user as admin
|
||||
next if admin_user.id != 1
|
||||
|
@ -133,11 +129,9 @@ returns
|
|||
model_map.each {|map_name, model|
|
||||
next if !auto_wizard_hash[map_name]
|
||||
auto_wizard_hash[map_name].each {|data|
|
||||
if data['id'] || data['name']
|
||||
Kernel.const_get(model).create_or_update(data.symbolize_keys)
|
||||
else
|
||||
Kernel.const_get(model).create(data.symbolize_keys)
|
||||
end
|
||||
generic_object = Kernel.const_get(model)
|
||||
data.symbolize_keys!
|
||||
generic_object.create_or_update_with_ref(data)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
170
test/unit/auto_wizard_test.rb
Normal file
170
test/unit/auto_wizard_test.rb
Normal file
|
@ -0,0 +1,170 @@
|
|||
# encoding: utf-8
|
||||
require 'test_helper'
|
||||
|
||||
class AutoWizardTest < ActiveSupport::TestCase
|
||||
|
||||
test 'simple' do
|
||||
auto_wizard_data = {
|
||||
Users: [
|
||||
{
|
||||
login: 'master_unit_test01@example.com',
|
||||
firstname: 'Test Master',
|
||||
lastname: 'Agent',
|
||||
email: 'master_unit_test01@example.com',
|
||||
password: 'test',
|
||||
},
|
||||
{
|
||||
login: 'agent1_unit_test01@example.com',
|
||||
firstname: 'Agent 1',
|
||||
lastname: 'Test',
|
||||
email: 'agent1_unit_test01@example.com',
|
||||
password: 'test',
|
||||
roles: ['Agent'],
|
||||
}
|
||||
],
|
||||
Groups: [
|
||||
{
|
||||
name: 'some group1',
|
||||
users: ['master_unit_test01@example.com', 'agent1_unit_test01@example.com']
|
||||
}
|
||||
],
|
||||
Settings: [
|
||||
{
|
||||
name: 'developer_mode',
|
||||
value: true
|
||||
},
|
||||
{
|
||||
name: 'product_name',
|
||||
value: 'Zammad UnitTest01 System'
|
||||
},
|
||||
]
|
||||
}
|
||||
assert_equal(false, AutoWizard.enabled?)
|
||||
auto_wizard_file_write(auto_wizard_data)
|
||||
assert_equal(true, AutoWizard.enabled?)
|
||||
AutoWizard.setup
|
||||
assert_equal(false, AutoWizard.enabled?)
|
||||
|
||||
# check first user roles
|
||||
auto_wizard_data[:Users][0][:roles] = %w(Agent Admin)
|
||||
|
||||
auto_wizard_data[:Users].each {|local_user|
|
||||
user = User.find_by(login: local_user[:login])
|
||||
assert_equal(local_user[:login], user.login)
|
||||
assert_equal(local_user[:firstname], user.firstname)
|
||||
assert_equal(local_user[:lastname], user.lastname)
|
||||
assert_equal(local_user[:email], user.email)
|
||||
assert_equal(local_user[:roles].count, user.role_ids.count)
|
||||
next unless local_user[:roles]
|
||||
local_user[:roles].each {|local_role_name|
|
||||
local_role = Role.find_by(name: local_role_name)
|
||||
assert(user.role_ids.include?(local_role.id))
|
||||
}
|
||||
}
|
||||
auto_wizard_data[:Groups].each {|local_group|
|
||||
group = Group.find_by(name: local_group[:name])
|
||||
assert_equal(local_group[:name], group.name)
|
||||
next unless local_group[:users]
|
||||
local_group[:users].each {|local_user_login|
|
||||
local_user = User.find_by(login: local_user_login)
|
||||
assert(group.user_ids.include?(local_user.id))
|
||||
}
|
||||
}
|
||||
auto_wizard_data[:Settings].each {|local_setting|
|
||||
setting_value = Setting.get(local_setting[:name])
|
||||
assert_equal(local_setting[:value], setting_value)
|
||||
}
|
||||
end
|
||||
|
||||
test 'complex' do
|
||||
auto_wizard_data = {
|
||||
Organizations: [
|
||||
{
|
||||
name: 'Auto Wizard Test Org',
|
||||
shared: false,
|
||||
}
|
||||
],
|
||||
Users: [
|
||||
{
|
||||
login: 'master_unit_test01@example.com',
|
||||
firstname: 'Test Master',
|
||||
lastname: 'Agent',
|
||||
email: 'master_unit_test01@example.com',
|
||||
password: 'test',
|
||||
organization: 'Auto Wizard Test Org',
|
||||
roles: ['Admin'],
|
||||
},
|
||||
{
|
||||
login: 'agent1_unit_test01@example.com',
|
||||
firstname: 'Agent 1',
|
||||
lastname: 'Test',
|
||||
email: 'agent1_unit_test01@example.com',
|
||||
password: 'test',
|
||||
roles: ['Agent'],
|
||||
}
|
||||
],
|
||||
Groups: [
|
||||
{
|
||||
name: 'some group1',
|
||||
users: ['master_unit_test01@example.com', 'agent1_unit_test01@example.com']
|
||||
}
|
||||
],
|
||||
Settings: [
|
||||
{
|
||||
name: 'developer_mode',
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
name: 'product_name',
|
||||
value: 'Zammad UnitTest02 System'
|
||||
},
|
||||
]
|
||||
}
|
||||
assert_equal(false, AutoWizard.enabled?)
|
||||
auto_wizard_file_write(auto_wizard_data)
|
||||
assert_equal(true, AutoWizard.enabled?)
|
||||
AutoWizard.setup
|
||||
assert_equal(false, AutoWizard.enabled?)
|
||||
|
||||
auto_wizard_data[:Users].each {|local_user|
|
||||
user = User.find_by(login: local_user[:login])
|
||||
assert_equal(local_user[:login], user.login)
|
||||
assert_equal(local_user[:firstname], user.firstname)
|
||||
assert_equal(local_user[:lastname], user.lastname)
|
||||
assert_equal(local_user[:email], user.email)
|
||||
next unless local_user[:roles]
|
||||
assert_equal(local_user[:roles].count, user.role_ids.count)
|
||||
local_user[:roles].each {|local_role_name|
|
||||
local_role = Role.find_by(name: local_role_name)
|
||||
assert(user.role_ids.include?(local_role.id))
|
||||
}
|
||||
}
|
||||
auto_wizard_data[:Groups].each {|local_group|
|
||||
group = Group.find_by(name: local_group[:name])
|
||||
assert_equal(local_group[:name], group.name)
|
||||
next unless local_group[:users]
|
||||
local_group[:users].each {|local_user_login|
|
||||
local_user = User.find_by(login: local_user_login)
|
||||
assert(group.user_ids.include?(local_user.id))
|
||||
}
|
||||
}
|
||||
auto_wizard_data[:Settings].each {|local_setting|
|
||||
setting_value = Setting.get(local_setting[:name])
|
||||
assert_equal(local_setting[:value], setting_value)
|
||||
}
|
||||
end
|
||||
|
||||
def auto_wizard_file_write(data)
|
||||
location = "#{Rails.root}/auto_wizard.json"
|
||||
file = File.new(location, 'wb')
|
||||
file.write(data.to_json)
|
||||
file.close
|
||||
end
|
||||
|
||||
def auto_wizard_file_exists?
|
||||
location = "#{Rails.root}/auto_wizard.json"
|
||||
return false if File.exist?(location)
|
||||
true
|
||||
end
|
||||
|
||||
end
|
169
test/unit/object_create_update_with_ref_name_test.rb
Normal file
169
test/unit/object_create_update_with_ref_name_test.rb
Normal file
|
@ -0,0 +1,169 @@
|
|||
# encoding: utf-8
|
||||
require 'test_helper'
|
||||
|
||||
class ObjectCreateUpdateWithRefNameTest < ActiveSupport::TestCase
|
||||
test 'organization' do
|
||||
roles = Role.where(name: %w(Agent Admin))
|
||||
groups = Group.all
|
||||
user1 = User.create_or_update(
|
||||
login: 'object_ref_name1@example.org',
|
||||
firstname: 'object_ref_name1',
|
||||
lastname: 'object_ref_name1',
|
||||
email: 'object_ref_name1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
roles: roles,
|
||||
groups: groups,
|
||||
)
|
||||
user2 = User.create_or_update(
|
||||
login: 'object_ref_name2@example.org',
|
||||
firstname: 'object_ref_name2',
|
||||
lastname: 'object_ref_name2',
|
||||
email: 'object_ref_name2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
roles: roles,
|
||||
groups: groups,
|
||||
)
|
||||
|
||||
org1 = Organization.create_if_not_exists_with_ref(
|
||||
name: 'some org update_with_ref member',
|
||||
members: ['object_ref_name1@example.org'],
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
assert(org1.member_ids.sort.include?(user1.id))
|
||||
assert_not(org1.member_ids.sort.include?(user2.id))
|
||||
|
||||
org2 = Organization.create_or_update_with_ref(
|
||||
name: 'some org update_with_ref member',
|
||||
members: ['object_ref_name2@example.org'],
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
assert_not(org2.member_ids.sort.include?(user1.id))
|
||||
assert(org2.member_ids.sort.include?(user2.id))
|
||||
assert_equal(org1.id, org2.id)
|
||||
|
||||
org3 = Organization.create_or_update_with_ref(
|
||||
name: 'some org update_with_ref member2',
|
||||
members: ['object_ref_name2@example.org'],
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
assert_not(org3.member_ids.sort.include?(user1.id))
|
||||
assert(org3.member_ids.sort.include?(user2.id))
|
||||
assert_not_equal(org2.id, org3.id)
|
||||
|
||||
assert_raises( ActiveRecord::AssociationTypeMismatch ) {
|
||||
Organization.create_or_update_with_ref(
|
||||
name: 'some org update_with_ref member2',
|
||||
members: ['object_ref_name2@example.org'],
|
||||
member_ids: [2],
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
test 'user' do
|
||||
org1 = Organization.create_if_not_exists_with_ref(
|
||||
name: 'some org update_with_ref user',
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
user1 = User.create_or_update_with_ref(
|
||||
login: 'object_ref_name1@example.org',
|
||||
firstname: 'object_ref_name1',
|
||||
lastname: 'object_ref_name1',
|
||||
email: 'object_ref_name1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
organization: 'some org update_with_ref user',
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
roles: %w(Agent Admin),
|
||||
groups: ['Users'],
|
||||
)
|
||||
user2 = User.create_or_update_with_ref(
|
||||
login: 'object_ref_name2@example.org',
|
||||
firstname: 'object_ref_name2',
|
||||
lastname: 'object_ref_name2',
|
||||
email: 'object_ref_name2@example.org',
|
||||
password: 'some_pass',
|
||||
organization_id: nil,
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
roles: ['Customer'],
|
||||
groups: [],
|
||||
)
|
||||
admin_role = Role.lookup(name: 'Admin')
|
||||
agent_role = Role.lookup(name: 'Agent')
|
||||
customer_role = Role.lookup(name: 'Customer')
|
||||
|
||||
users_group = Group.lookup(name: 'Users')
|
||||
|
||||
assert(user1.organization.name, 'some org update_with_ref user')
|
||||
assert(user1.group_ids.include?(users_group.id))
|
||||
assert(user1.role_ids.include?(admin_role.id))
|
||||
assert(user1.role_ids.include?(agent_role.id))
|
||||
assert_not(user1.role_ids.include?(customer_role.id))
|
||||
|
||||
assert_equal(nil, user2.organization_id)
|
||||
assert_not(user2.group_ids.include?(users_group.id))
|
||||
assert_not(user2.role_ids.include?(admin_role.id))
|
||||
assert_not(user2.role_ids.include?(agent_role.id))
|
||||
assert(user2.role_ids.include?(customer_role.id))
|
||||
|
||||
end
|
||||
|
||||
test 'group' do
|
||||
user1 = User.create_or_update_with_ref(
|
||||
login: 'object_ref_name1@example.org',
|
||||
firstname: 'object_ref_name1',
|
||||
lastname: 'object_ref_name1',
|
||||
email: 'object_ref_name1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
organization_id: nil,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
roles: %w(Agent Admin),
|
||||
groups: [],
|
||||
)
|
||||
user2 = User.create_or_update_with_ref(
|
||||
login: 'object_ref_name2@example.org',
|
||||
firstname: 'object_ref_name2',
|
||||
lastname: 'object_ref_name2',
|
||||
email: 'object_ref_name2@example.org',
|
||||
password: 'some_pass',
|
||||
organization_id: nil,
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
roles: ['Customer'],
|
||||
groups: [],
|
||||
)
|
||||
|
||||
group1 = Group.create_if_not_exists_with_ref(
|
||||
name: 'some group update_with_ref',
|
||||
users: ['object_ref_name1@example.org'],
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
assert(group1.name, 'some group update_with_ref')
|
||||
assert(group1.user_ids.include?(user1.id))
|
||||
assert_not(group1.user_ids.include?(user2.id))
|
||||
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue