kpm 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|