kpm 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +25 -0
- data/Rakefile +8 -0
- data/kpm.gemspec +1 -0
- data/lib/kpm.rb +2 -0
- data/lib/kpm/account.rb +527 -0
- data/lib/kpm/database.rb +113 -0
- data/lib/kpm/plugins_directory.yml +6 -6
- data/lib/kpm/tasks.rb +105 -0
- data/lib/kpm/version.rb +1 -1
- data/spec/kpm/unit_mysql/account_spec.rb +424 -0
- data/spec/kpm/unit_mysql/account_spec.yml +12 -0
- data/spec/kpm/unit_mysql/account_test_ddl.sql +79 -0
- data/spec/spec_helper.rb +3 -0
- metadata +59 -20
data/lib/kpm/database.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
|
3
|
+
module KPM
|
4
|
+
|
5
|
+
class Database
|
6
|
+
class << self
|
7
|
+
|
8
|
+
# Mysql Information functions
|
9
|
+
LAST_INSERTED_ID = 'SELECT LAST_INSERT_ID();'
|
10
|
+
ROWS_UPDATED = 'SELECT ROW_COUNT();'
|
11
|
+
|
12
|
+
# Destination database
|
13
|
+
DATABASE = ENV['DATABASE'] || 'killbill'
|
14
|
+
USERNAME = ENV['USERNAME'] || 'root'
|
15
|
+
PASSWORD = ENV['PASSWORD'] || 'root'
|
16
|
+
COLUMN_NAME_POS = 3
|
17
|
+
|
18
|
+
STATEMENT_TMP_FILE = Dir.mktmpdir('statement') + File::SEPARATOR + 'statement.sql'
|
19
|
+
|
20
|
+
MYSQL_COMMAND_LINE = "mysql #{DATABASE} --user=#{USERNAME} --password=#{PASSWORD} "
|
21
|
+
|
22
|
+
@@mysql_command_line = MYSQL_COMMAND_LINE
|
23
|
+
@@username = USERNAME
|
24
|
+
@@password = PASSWORD
|
25
|
+
@@database = DATABASE
|
26
|
+
|
27
|
+
def set_logger(logger)
|
28
|
+
@@logger = logger
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_credentials(user = nil, password = nil)
|
32
|
+
@@username = user
|
33
|
+
@@password = password
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_database_name(database_name = nil)
|
37
|
+
@@database = database_name
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_mysql_command_line
|
41
|
+
@@mysql_command_line = "mysql #{@@database} --user=#{@@username} --password=#{@@password} "
|
42
|
+
end
|
43
|
+
|
44
|
+
def execute_insert_statement(table_name, query, qty_to_insert, table_data, record_id = nil)
|
45
|
+
|
46
|
+
if not record_id.nil?
|
47
|
+
query = "set #{record_id[:variable]}=#{record_id[:value]}; #{query}"
|
48
|
+
end
|
49
|
+
query = "SET autocommit=0; #{query} COMMIT;"
|
50
|
+
|
51
|
+
File.open(STATEMENT_TMP_FILE,'w') do |s|
|
52
|
+
s.puts query
|
53
|
+
end
|
54
|
+
|
55
|
+
response = `#{@@mysql_command_line} < "#{STATEMENT_TMP_FILE}" 2>&1`
|
56
|
+
|
57
|
+
if response.include? 'ERROR'
|
58
|
+
raise Interrupt, "Importing table #{table_name}...... \e[91;1m#{response}\e[0m"
|
59
|
+
end
|
60
|
+
|
61
|
+
if response.include? 'LAST_INSERT_ID'
|
62
|
+
@@logger.info "\e[32mImporting table #{table_name}...... Row 1 of #{qty_to_insert} success\e[0m"
|
63
|
+
|
64
|
+
return response.split("\n")[1]
|
65
|
+
end
|
66
|
+
|
67
|
+
if response.include? 'ROW_COUNT'
|
68
|
+
response_msg = response.split("\n")
|
69
|
+
row_count_inserted = response_msg[response_msg.size - 1]
|
70
|
+
@@logger.info "\e[32mImporting table #{table_name}...... Row #{ row_count_inserted || 1} of #{qty_to_insert} success\e[0m"
|
71
|
+
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
|
75
|
+
return true
|
76
|
+
end
|
77
|
+
|
78
|
+
def generate_insert_statement(tables)
|
79
|
+
|
80
|
+
statements = []
|
81
|
+
@@logger.info "\e[32mGenerating statements\e[0m"
|
82
|
+
|
83
|
+
tables.each_key do |table_name|
|
84
|
+
table = tables[table_name]
|
85
|
+
columns_names = table[:col_names].join(",").gsub(/'/,'')
|
86
|
+
|
87
|
+
rows = []
|
88
|
+
table[:rows].each do |row|
|
89
|
+
rows << row.map{|value| value.is_a?(Symbol) ? value.to_s : "'#{value.to_s.gsub(/['"]/, "'" => "\\'", '"' => '\\"')}'" }.join(",")
|
90
|
+
end
|
91
|
+
|
92
|
+
value_data = rows.map{|row| "(#{row})" }.join(",")
|
93
|
+
|
94
|
+
statements << {:query => get_insert_statement(table_name,columns_names,value_data, rows.size),
|
95
|
+
:qty_to_insert => rows.size, :table_name => table_name, :table_data => table}
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
statements
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def get_insert_statement(table_name, columns_names, values, rows_qty)
|
106
|
+
return "INSERT INTO #{table_name} ( #{columns_names} ) VALUES #{values}; #{rows_qty == 1 ? LAST_INSERTED_ID : ROWS_UPDATED}"
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -16,7 +16,7 @@
|
|
16
16
|
:0.15: 0.2.1
|
17
17
|
:0.16: 0.3.2
|
18
18
|
:0.17: 0.4.10
|
19
|
-
:0.18: 0.5.
|
19
|
+
:0.18: 0.5.3
|
20
20
|
:require:
|
21
21
|
- :org.killbill.billing.plugin.adyen.merchantAccount
|
22
22
|
- :org.killbill.billing.plugin.adyen.username
|
@@ -29,7 +29,7 @@
|
|
29
29
|
:0.15: 2.0.1
|
30
30
|
:0.16: 3.0.2
|
31
31
|
:0.17: 4.0.5
|
32
|
-
:0.18: 4.2.
|
32
|
+
:0.18: 4.2.3
|
33
33
|
:avatax:
|
34
34
|
:type: :java
|
35
35
|
:versions:
|
@@ -63,7 +63,7 @@
|
|
63
63
|
:0.14: 1.0.0
|
64
64
|
:0.15: 3.3.0
|
65
65
|
:0.16: 4.0.12
|
66
|
-
:0.18: 5.
|
66
|
+
:0.18: 5.2.1
|
67
67
|
:require:
|
68
68
|
- :login
|
69
69
|
- :password
|
@@ -138,7 +138,7 @@
|
|
138
138
|
:type: :ruby
|
139
139
|
:versions:
|
140
140
|
:0.16: 0.0.2
|
141
|
-
:0.18: 0.1.
|
141
|
+
:0.18: 0.1.4
|
142
142
|
:require:
|
143
143
|
- :login
|
144
144
|
- :password
|
@@ -157,7 +157,7 @@
|
|
157
157
|
:versions:
|
158
158
|
:0.16: 0.0.1
|
159
159
|
:0.17: 0.1.0
|
160
|
-
:0.18: 0.2.
|
160
|
+
:0.18: 0.2.2
|
161
161
|
:paypal:
|
162
162
|
:type: :ruby
|
163
163
|
:artifact_id: paypal-express-plugin
|
@@ -165,7 +165,7 @@
|
|
165
165
|
:0.14: 2.0.0
|
166
166
|
:0.15: 3.0.0
|
167
167
|
:0.16: 4.1.7
|
168
|
-
:0.18: 5.0.
|
168
|
+
:0.18: 5.0.5
|
169
169
|
:require:
|
170
170
|
- :signature
|
171
171
|
- :login
|
data/lib/kpm/tasks.rb
CHANGED
@@ -432,6 +432,111 @@ module KPM
|
|
432
432
|
options[:killbill_web_path])
|
433
433
|
end
|
434
434
|
|
435
|
+
method_option :export,
|
436
|
+
:type => :string,
|
437
|
+
:default => nil,
|
438
|
+
:desc => 'export account for a provided id.'
|
439
|
+
method_option :import,
|
440
|
+
:type => :string,
|
441
|
+
:default => nil,
|
442
|
+
:desc => 'import account for a previously exported file.'
|
443
|
+
method_option :tenant_record_id,
|
444
|
+
:type => :numeric,
|
445
|
+
:default => nil,
|
446
|
+
:desc => 'replace the tenant_record_id before importing data.'
|
447
|
+
method_option :generate_record_id,
|
448
|
+
:type => :boolean,
|
449
|
+
:default => false,
|
450
|
+
:desc => 'The generate_record_id will instruct to generate the tables record_ids that were exported'
|
451
|
+
method_option :skip_payment_methods,
|
452
|
+
:type => :boolean,
|
453
|
+
:default => false,
|
454
|
+
:desc => 'Skip or swap payment types other than __EXTERNAL_PAYMENT__.'
|
455
|
+
method_option :config_file,
|
456
|
+
:type => :string,
|
457
|
+
:default => nil,
|
458
|
+
:desc => 'Yml that contains killbill api connection and DB connection'
|
459
|
+
method_option :killbill_api_credentials,
|
460
|
+
:type => :array,
|
461
|
+
:default => nil,
|
462
|
+
:desc => 'Killbill api credentials <api_key> <api_secrets>'
|
463
|
+
method_option :killbill_credentials,
|
464
|
+
:type => :array,
|
465
|
+
:default => nil,
|
466
|
+
:desc => 'Killbill credentials <user> <password>'
|
467
|
+
method_option :killbill_url,
|
468
|
+
:type => :string,
|
469
|
+
:default => nil,
|
470
|
+
:desc => 'Killbill URL ex. http://127.0.0.1:8080'
|
471
|
+
method_option :database_name,
|
472
|
+
:type => :string,
|
473
|
+
:default => nil,
|
474
|
+
:desc => 'DB name to connect'
|
475
|
+
method_option :database_credentials,
|
476
|
+
:type => :array,
|
477
|
+
:default => nil,
|
478
|
+
:desc => 'DB credentials <user> <password>'
|
479
|
+
method_option :data_delimiter,
|
480
|
+
:type => :string,
|
481
|
+
:default => "|",
|
482
|
+
:desc => 'Data delimiter'
|
483
|
+
desc 'account', 'export/import accounts'
|
484
|
+
def account
|
485
|
+
logger.info 'Please wait processing the request!!!'
|
486
|
+
begin
|
487
|
+
config_file = nil
|
488
|
+
if options[:killbill_url] && /https?:\/\/[\S]+/.match(options[:killbill_url]).nil?
|
489
|
+
raise Interrupt,'--killbill_url, required format -> http(s)://something'
|
490
|
+
end
|
491
|
+
|
492
|
+
if options[:killbill_api_credentials] && options[:killbill_api_credentials].size != 2
|
493
|
+
raise Interrupt,'--killbill_api_credentials, required format -> <api_key> <api_secrets>'
|
494
|
+
end
|
495
|
+
|
496
|
+
if options[:killbill_credentials] && options[:killbill_credentials].size != 2
|
497
|
+
raise Interrupt,'--killbill_credentials, required format -> <user> <password>'
|
498
|
+
end
|
499
|
+
|
500
|
+
if options[:database_credentials] && options[:database_credentials].size != 2
|
501
|
+
raise Interrupt,'--database_credentials, required format -> <user> <password>'
|
502
|
+
end
|
503
|
+
|
504
|
+
if options[:database_name] && options[:database_name] == :database_name.to_s
|
505
|
+
raise Interrupt,'--database_credentials, please provide a valid database name'
|
506
|
+
end
|
507
|
+
|
508
|
+
if options[:config_file] && options[:config_file] == :config_file.to_s
|
509
|
+
config_file = File.join(File.expand_path(File.dirname(__FILE__)), 'account_export_import.yml')
|
510
|
+
end
|
511
|
+
|
512
|
+
if options[:export].nil? && options[:import].nil?
|
513
|
+
raise Interrupt,'Need to specify an action'
|
514
|
+
end
|
515
|
+
|
516
|
+
|
517
|
+
account = KPM::Account.new(config_file || options[:config_file],options[:killbill_api_credentials],options[:killbill_credentials],
|
518
|
+
options[:killbill_url],options[:database_name],options[:database_credentials],options[:data_delimiter], logger)
|
519
|
+
export_file = nil
|
520
|
+
round_trip_export_import = false
|
521
|
+
|
522
|
+
if not options[:export].nil?
|
523
|
+
export_file = account.export_data(options[:export])
|
524
|
+
round_trip_export_import = true
|
525
|
+
end
|
526
|
+
|
527
|
+
if not options[:import].nil?
|
528
|
+
account.import_data(export_file || options[:import],options[:tenant_record_id], options[:skip_payment_methods],
|
529
|
+
round_trip_export_import, options[:generate_record_id])
|
530
|
+
end
|
531
|
+
|
532
|
+
rescue Exception => e
|
533
|
+
logger.error "\e[91;1m#{e.message}\e[0m"
|
534
|
+
if not e.is_a?(Interrupt)
|
535
|
+
logger.error e.backtrace.join("\n")
|
536
|
+
end
|
537
|
+
end
|
538
|
+
end
|
539
|
+
|
435
540
|
map :pull_ruby_plugin => :install_ruby_plugin,
|
436
541
|
:pull_java_plugin => :install_java_plugin
|
437
542
|
|
data/lib/kpm/version.rb
CHANGED
@@ -0,0 +1,424 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe KPM::Account do
|
4
|
+
|
5
|
+
shared_context 'account' do
|
6
|
+
let(:logger) {logger = ::Logger.new(STDOUT)
|
7
|
+
logger.level = Logger::FATAL
|
8
|
+
logger}
|
9
|
+
let(:yml_file) {YAML::load_file(Dir["#{Dir.pwd}/**/account_spec.yml"][0])}
|
10
|
+
let(:dummy_data_file) {Dir.mktmpdir('dummy') + File::SEPARATOR + 'kbdump'}
|
11
|
+
let(:url) {"http://#{yml_file['killbill']['host']}:#{yml_file['killbill']['port']}"}
|
12
|
+
let(:killbill_api_key) {yml_file['killbill']['api_key']}
|
13
|
+
let(:killbill_api_secrets) {yml_file['killbill']['api_secret']}
|
14
|
+
let(:killbill_user) {yml_file['killbill']['user']}
|
15
|
+
let(:killbill_password) {yml_file['killbill']['password']}
|
16
|
+
let(:db_name) {yml_file['database']['name']}
|
17
|
+
let(:db_username) {yml_file['database']['user']}
|
18
|
+
let(:db_password) {yml_file['database']['password']}
|
19
|
+
let(:account_class) { described_class.new(nil,[killbill_api_key,killbill_api_secrets],
|
20
|
+
[killbill_user, killbill_password],url,
|
21
|
+
db_name, [db_username, db_password],nil,logger)}
|
22
|
+
let(:dummy_account_id) {SecureRandom.uuid}
|
23
|
+
let(:account_id_invalid) {SecureRandom.uuid}
|
24
|
+
let(:dummy_data) {
|
25
|
+
"-- accounts record_id|id|external_key|email|name|first_name_length|currency|billing_cycle_day_local|parent_account_id|is_payment_delegated_to_parent|payment_method_id|time_zone|locale|address1|address2|company_name|city|state_or_province|country|postal_code|phone|notes|migrated|is_notified_for_invoices|created_date|created_by|updated_date|updated_by|tenant_record_id\n"\
|
26
|
+
"5|#{dummy_account_id}|#{dummy_account_id}|willharnet@example.com|Will Harnet||USD|0||||UTC||||||||||||false|2017-04-03T15:50:14.000+0000|demo|2017-04-05T15:01:39.000+0000|Killbill::Stripe::PaymentPlugin|2\n"\
|
27
|
+
"-- account_history record_id|id|target_record_id|external_key|email|name|first_name_length|currency|billing_cycle_day_local|parent_account_id|payment_method_id|is_payment_delegated_to_parent|time_zone|locale|address1|address2|company_name|city|state_or_province|country|postal_code|phone|notes|migrated|is_notified_for_invoices|change_type|created_by|created_date|updated_by|updated_date|tenant_record_id\n"\
|
28
|
+
"3|#{SecureRandom.uuid}|5|#{dummy_account_id}|willharnet@example.com|Will Harnet||USD|0||||UTC||||||||||||false|INSERT|demo|2017-04-03T15:50:14.000+0000|demo|2017-04-03T15:50:14.000+0000|2\n"
|
29
|
+
}
|
30
|
+
let(:cols_names) {dummy_data.split("\n")[0].split(" ")[2]}
|
31
|
+
let(:cols_data) {dummy_data.split("\n")[1]}
|
32
|
+
let(:table_name) {dummy_data.split("\n")[0].split(" ")[1]}
|
33
|
+
let(:obfuscating_marker) {:email}
|
34
|
+
let(:mysql_cli) {"mysql #{db_name} --user=#{db_username} --password=#{db_password} "}
|
35
|
+
let(:test_ddl) {Dir["#{Dir.pwd}/**/account_test_ddl.sql"][0]}
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#initialize' do
|
39
|
+
include_context 'account'
|
40
|
+
|
41
|
+
context 'when creating an instance of account class' do
|
42
|
+
|
43
|
+
it 'when initialized with defaults' do
|
44
|
+
expect(described_class.new).to be_an_instance_of(KPM::Account)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'when initialized with options' do
|
48
|
+
account_class.should be_an_instance_of(KPM::Account)
|
49
|
+
expect(account_class.instance_variable_get(:@killbill_api_key)).to eq(killbill_api_key)
|
50
|
+
expect(account_class.instance_variable_get(:@killbill_api_secrets)).to eq(killbill_api_secrets)
|
51
|
+
expect(account_class.instance_variable_get(:@killbill_user)).to eq(killbill_user)
|
52
|
+
expect(account_class.instance_variable_get(:@killbill_password)).to eq(killbill_password)
|
53
|
+
expect(account_class.instance_variable_get(:@killbill_url)).to eq(url)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
# export data tests
|
61
|
+
describe '#fetch_export_data' do
|
62
|
+
include_context 'account'
|
63
|
+
|
64
|
+
context 'when fetching account from api' do
|
65
|
+
|
66
|
+
it 'when account id not found' do
|
67
|
+
expect{ account_class.send(:fetch_export_data, account_id_invalid) }.to raise_error(Interrupt, 'Account id not found')
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'when account id found' do
|
71
|
+
account_id = creating_account_with_client
|
72
|
+
expect(account_id).to match(/\w{8}(-\w{4}){3}-\w{12}?/)
|
73
|
+
expect{ account_class.send(:fetch_export_data, account_id) }.not_to raise_error(Interrupt, 'Account id not found')
|
74
|
+
expect(account_class.send(:fetch_export_data, account_id)).to match(account_id)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#process_export_data' do
|
82
|
+
include_context 'account'
|
83
|
+
|
84
|
+
context 'when processing data to export' do
|
85
|
+
|
86
|
+
it 'when column name qty eq column data qty' do
|
87
|
+
expect(account_class.send(:process_export_data, cols_data, table_name, cols_names.split("|")).split("|").size).to eq(cols_names.split("|").size)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'when obfuscating data' do
|
91
|
+
marker_index = 0
|
92
|
+
cols_names.split("|").each do |col_name|
|
93
|
+
if col_name.equal?(obfuscating_marker.to_s)
|
94
|
+
break
|
95
|
+
end
|
96
|
+
marker_index += 1
|
97
|
+
end
|
98
|
+
|
99
|
+
obfuscating_marker_data = account_class.send(:process_export_data, cols_data, table_name, cols_names.split("|")).split("|")
|
100
|
+
expect(obfuscating_marker_data[marker_index]).to be_nil
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '#remove_export_data' do
|
108
|
+
include_context 'account'
|
109
|
+
|
110
|
+
it 'when obfuscating value' do
|
111
|
+
expect(account_class.send(:remove_export_data, table_name, obfuscating_marker.to_s, 'willharnet@example.com')).to be_nil
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
describe '#export' do
|
117
|
+
include_context 'account'
|
118
|
+
|
119
|
+
context 'when exporting data' do
|
120
|
+
|
121
|
+
it 'when file created' do
|
122
|
+
expect(File.exist?(account_class.send(:export, dummy_data))).to be_true
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'when file contains account record' do
|
126
|
+
expect(File.readlines(account_class.send(:export, dummy_data)).grep(/#{table_name}/)).to be_true
|
127
|
+
expect(File.readlines(account_class.send(:export, dummy_data)).grep(/#{cols_names}/)).to be_true
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#export_data' do
|
135
|
+
include_context 'account'
|
136
|
+
|
137
|
+
context 'when exporting data; main method' do
|
138
|
+
|
139
|
+
it 'when no account id' do
|
140
|
+
expect{ account_class.export_data }.to raise_error(Interrupt, 'Account id not found')
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'when file created' do
|
144
|
+
account_id = creating_account_with_client
|
145
|
+
expect(account_id).to match(/\w{8}(-\w{4}){3}-\w{12}?/)
|
146
|
+
expect(File.exist?(account_class.export_data(account_id))).to be_true
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'when file contains account record' do
|
150
|
+
account_id = creating_account_with_client
|
151
|
+
expect(account_id).to match(/\w{8}(-\w{4}){3}-\w{12}?/)
|
152
|
+
expect(File.readlines(account_class.export_data(account_id)).grep(/#{table_name}/)).to be_true
|
153
|
+
expect(File.readlines(account_class.export_data(account_id)).grep(/#{cols_names}/)).to be_true
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
# import data tests
|
161
|
+
describe '#sniff_delimiter' do
|
162
|
+
include_context 'account'
|
163
|
+
|
164
|
+
it 'when data delimiter is sniffed as "|"' do
|
165
|
+
open (dummy_data_file), 'w' do |io|
|
166
|
+
io.puts(dummy_data)
|
167
|
+
end
|
168
|
+
|
169
|
+
expect(account_class.send(:sniff_delimiter, dummy_data_file)).to eq('|')
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe '#fill_empty_column' do
|
174
|
+
include_context 'account'
|
175
|
+
|
176
|
+
it 'when empty value' do
|
177
|
+
expect(account_class.send(:fill_empty_column, '')).to eq(:DEFAULT)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe '#fix_dates' do
|
182
|
+
include_context 'account'
|
183
|
+
|
184
|
+
it 'when valid date value' do
|
185
|
+
expect{DateTime.parse(account_class.send(:fix_dates, '2017-04-05T15:01:39.000+0000'))}.not_to raise_error(ArgumentError)
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'when valid date value match YYYY-MM-DD HH:MM:SS' do
|
189
|
+
expect(account_class.send(:fix_dates, '2017-04-05T15:01:39.000+0000')).to match(/^\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}/)
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'when invalid date value' do
|
193
|
+
expect{DateTime.parse(account_class.send(:fix_dates, 'JO'))}.to raise_error(ArgumentError)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe '#replace_boolean' do
|
198
|
+
include_context 'account'
|
199
|
+
|
200
|
+
context 'when value is boolean; replace' do
|
201
|
+
it 'when true' do
|
202
|
+
expect(account_class.send(:replace_boolean, true)).to eq(1)
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'when false' do
|
206
|
+
expect(account_class.send(:replace_boolean, false)).to eq(0)
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe '#replace_account_record_id' do
|
213
|
+
include_context 'account'
|
214
|
+
|
215
|
+
it 'when field is account_record_id' do
|
216
|
+
expect(account_class.send(:replace_account_record_id, table_name, 'account_record_id', '1')).to eq(:@account_record_id)
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'when field is record_id' do
|
220
|
+
expect(account_class.send(:replace_account_record_id, table_name, 'record_id', '1')).to be_nil
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'when field is target_record_id and table account_history' do
|
224
|
+
expect(account_class.send(:replace_account_record_id, 'account_history', 'target_record_id', '1')).to eq(:@account_record_id)
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'when field is search_key1 and table bus_ext_events_history' do
|
228
|
+
expect(account_class.send(:replace_account_record_id, 'bus_ext_events_history', 'search_key1', '1')).to eq(:@account_record_id)
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'when field is search_key1 and table bus_events_history' do
|
232
|
+
expect(account_class.send(:replace_account_record_id, 'bus_events_history', 'search_key1', '1')).to eq(:@account_record_id)
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
describe '#replace_tenant_record_id' do
|
238
|
+
include_context 'account'
|
239
|
+
|
240
|
+
it 'when field is tenant_record_id' do
|
241
|
+
account_class.instance_variable_set(:@tenant_record_id, 10)
|
242
|
+
expect(account_class.send(:replace_tenant_record_id, table_name, 'tenant_record_id', '1')).to eq(10)
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'when field is search_key2 and table bus_ext_events_history' do
|
246
|
+
account_class.instance_variable_set(:@tenant_record_id, 10)
|
247
|
+
expect(account_class.send(:replace_tenant_record_id, 'bus_ext_events_history', 'search_key2', '1')).to eq(10)
|
248
|
+
end
|
249
|
+
|
250
|
+
it 'when field is search_key2 and table bus_events_history' do
|
251
|
+
account_class.instance_variable_set(:@tenant_record_id, 10)
|
252
|
+
expect(account_class.send(:replace_tenant_record_id, 'bus_events_history', 'search_key2', '1')).to eq(10)
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
describe '#replace_uuid' do
|
258
|
+
include_context 'account'
|
259
|
+
|
260
|
+
context 'when round trip true' do
|
261
|
+
it 'when replace uuid value' do
|
262
|
+
account_class.instance_variable_set(:@round_trip_export_import, true)
|
263
|
+
expect(account_class.send(:replace_uuid, table_name, 'account_id', dummy_account_id)).not_to eq(dummy_account_id)
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'when do not replace value' do
|
267
|
+
account_class.instance_variable_set(:@round_trip_export_import, true)
|
268
|
+
expect(account_class.send(:replace_uuid, table_name, 'other_id', dummy_account_id)).to eq(dummy_account_id)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
273
|
+
|
274
|
+
describe '#sanitize' do
|
275
|
+
include_context 'account'
|
276
|
+
|
277
|
+
it 'when skip payment method' do
|
278
|
+
expect(account_class.send(:sanitize, 'payment_methods', 'plugin_name', 'Payment Method',true)).to eq('__EXTERNAL_PAYMENT__')
|
279
|
+
end
|
280
|
+
it 'when nothing to sanitize' do
|
281
|
+
expect(account_class.send(:sanitize, table_name, 'id', dummy_account_id,false)).to eq(dummy_account_id)
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|
285
|
+
|
286
|
+
describe '#process_import_data' do
|
287
|
+
include_context 'account'
|
288
|
+
|
289
|
+
context 'when processing data to import' do
|
290
|
+
it 'when column name qty eq column data qty without record_id' do
|
291
|
+
account_class.instance_variable_set(:@generate_record_id,true)
|
292
|
+
expect(account_class.send(:process_import_data, cols_data, table_name, cols_names.split('|'), false, []).size).to eq(cols_names.split("|").size-1)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
describe '#import_data' do
|
299
|
+
include_context 'account'
|
300
|
+
|
301
|
+
context 'when data to import; main import method' do
|
302
|
+
|
303
|
+
it 'when creating test schema' do
|
304
|
+
db = create_test_schema
|
305
|
+
expect(db).to eq(db_name)
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'when importing data with empty file' do
|
309
|
+
File.new(dummy_data_file, 'w+').close
|
310
|
+
expect{account_class.import_data(dummy_data_file,nil,true,false,true) }.to raise_error(Interrupt,"Data on #{dummy_data_file} is invalid")
|
311
|
+
File.delete(dummy_data_file)
|
312
|
+
end
|
313
|
+
|
314
|
+
it 'when importing data with no file' do
|
315
|
+
expect{account_class.import_data(dummy_data_file,nil,true,false,true) }.to raise_error(Interrupt,'Need to specify a valid file')
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'when importing data with new record_id' do
|
319
|
+
open (dummy_data_file), 'w' do |io|
|
320
|
+
io.puts(dummy_data)
|
321
|
+
end
|
322
|
+
expect{account_class.import_data(dummy_data_file,nil,true,false,true) }.not_to raise_error(Interrupt)
|
323
|
+
|
324
|
+
row_count_inserted = delete_statement('accounts','id',dummy_account_id)
|
325
|
+
expect(row_count_inserted).to eq('1')
|
326
|
+
row_count_inserted = delete_statement('account_history','external_key',dummy_account_id)
|
327
|
+
expect(row_count_inserted).to eq('1')
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'when importing data reusing record_id' do
|
331
|
+
open (dummy_data_file), 'w' do |io|
|
332
|
+
io.puts(dummy_data)
|
333
|
+
end
|
334
|
+
expect{account_class.import_data(dummy_data_file,nil,true,false,false) }.not_to raise_error(Interrupt)
|
335
|
+
|
336
|
+
row_count_inserted = delete_statement('accounts','id',dummy_account_id)
|
337
|
+
expect(row_count_inserted).to eq('1')
|
338
|
+
row_count_inserted = delete_statement('account_history','external_key',dummy_account_id)
|
339
|
+
expect(row_count_inserted).to eq('1')
|
340
|
+
end
|
341
|
+
|
342
|
+
it 'when importing data with different tenant_record_id' do
|
343
|
+
open (dummy_data_file), 'w' do |io|
|
344
|
+
io.puts(dummy_data)
|
345
|
+
end
|
346
|
+
expect{account_class.import_data(dummy_data_file,10,true,false,true) }.not_to raise_error(Interrupt)
|
347
|
+
|
348
|
+
row_count_inserted = delete_statement('accounts','id',dummy_account_id)
|
349
|
+
expect(row_count_inserted).to eq('1')
|
350
|
+
row_count_inserted = delete_statement('account_history','external_key',dummy_account_id)
|
351
|
+
expect(row_count_inserted).to eq('1')
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'when round trip' do
|
355
|
+
open (dummy_data_file), 'w' do |io|
|
356
|
+
io.puts(dummy_data)
|
357
|
+
end
|
358
|
+
expect{account_class.import_data(dummy_data_file,10,true,true,true) }.not_to raise_error(Interrupt)
|
359
|
+
new_account_id = account_class.instance_variable_get(:@tables_id)
|
360
|
+
|
361
|
+
row_count_inserted = delete_statement('accounts','id',new_account_id['accounts_id'])
|
362
|
+
expect(row_count_inserted).to eq('1')
|
363
|
+
row_count_inserted = delete_statement('account_history','external_key',new_account_id['accounts_id'])
|
364
|
+
expect(row_count_inserted).to eq('1')
|
365
|
+
end
|
366
|
+
|
367
|
+
it 'when droping test schema' do
|
368
|
+
response = drop_test_schema
|
369
|
+
expect(response).to match('')
|
370
|
+
end
|
371
|
+
|
372
|
+
end
|
373
|
+
|
374
|
+
end
|
375
|
+
|
376
|
+
private
|
377
|
+
def creating_account_with_client
|
378
|
+
if $account_id.nil?
|
379
|
+
KillBillClient.url = url
|
380
|
+
|
381
|
+
options = {
|
382
|
+
:username => killbill_user,
|
383
|
+
:password => killbill_password,
|
384
|
+
:api_key => killbill_api_key,
|
385
|
+
:api_secret => killbill_api_secrets
|
386
|
+
}
|
387
|
+
|
388
|
+
account = KillBillClient::Model::Account.new
|
389
|
+
account.name = 'KPM Account Test'
|
390
|
+
account.first_name_length = 3
|
391
|
+
account.external_key = SecureRandom.uuid
|
392
|
+
account.currency = 'USD'
|
393
|
+
account = account.create('kpm_account_test', 'kpm_account_test', 'kpm_account_test', options)
|
394
|
+
|
395
|
+
$account_id = account.account_id
|
396
|
+
|
397
|
+
end
|
398
|
+
|
399
|
+
$account_id
|
400
|
+
end
|
401
|
+
|
402
|
+
def delete_statement(table_name,column_name,account_id)
|
403
|
+
response = `#{mysql_cli} -e "DELETE FROM #{table_name} WHERE #{column_name} = '#{account_id}'; SELECT ROW_COUNT();" 2>&1`
|
404
|
+
response_msg = response.split("\n")
|
405
|
+
row_count_inserted = response_msg[response_msg.size - 1]
|
406
|
+
|
407
|
+
row_count_inserted
|
408
|
+
end
|
409
|
+
|
410
|
+
def create_test_schema
|
411
|
+
response = `mysql --user=#{db_username} --password=#{db_password} -e "CREATE DATABASE IF NOT EXISTS #{db_name};"`
|
412
|
+
response = `#{mysql_cli} < "#{test_ddl}" 2>&1`
|
413
|
+
response_msg = response.split("\n")
|
414
|
+
used_database = response_msg[response_msg.size - 1]
|
415
|
+
|
416
|
+
used_database
|
417
|
+
end
|
418
|
+
|
419
|
+
def drop_test_schema
|
420
|
+
response = `mysql --user=#{db_username} --password=#{db_password} -e "DROP DATABASE #{db_name};"`;
|
421
|
+
response
|
422
|
+
end
|
423
|
+
|
424
|
+
end
|