zold 0.14.8 → 0.14.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +0 -0
  4. data/Gemfile +2 -0
  5. data/Rakefile +2 -0
  6. data/appveyor.yml +8 -3
  7. data/features/step_definitions/steps.rb +2 -0
  8. data/features/support/env.rb +2 -0
  9. data/fixtures/merge/asserts.rb +2 -0
  10. data/fixtures/merge/into-no-wallet/assert.rb +2 -0
  11. data/fixtures/merge/random-expenses/assert.rb +2 -0
  12. data/fixtures/merge/simple-case/assert.rb +2 -0
  13. data/fixtures/scripts/_head.sh +13 -0
  14. data/fixtures/scripts/distribute-wallet.sh +86 -0
  15. data/fixtures/scripts/spread-wallets.sh +56 -0
  16. data/lib/zold.rb +2 -0
  17. data/lib/zold/amount.rb +3 -1
  18. data/lib/zold/atomic_file.rb +2 -0
  19. data/lib/zold/backtrace.rb +2 -0
  20. data/lib/zold/commands/alias.rb +2 -0
  21. data/lib/zold/commands/args.rb +2 -0
  22. data/lib/zold/commands/calculate.rb +5 -3
  23. data/lib/zold/commands/clean.rb +2 -0
  24. data/lib/zold/commands/create.rb +2 -0
  25. data/lib/zold/commands/diff.rb +2 -0
  26. data/lib/zold/commands/fetch.rb +7 -2
  27. data/lib/zold/commands/invoice.rb +2 -0
  28. data/lib/zold/commands/list.rb +2 -0
  29. data/lib/zold/commands/merge.rb +2 -0
  30. data/lib/zold/commands/node.rb +2 -0
  31. data/lib/zold/commands/pay.rb +2 -0
  32. data/lib/zold/commands/propagate.rb +2 -0
  33. data/lib/zold/commands/pull.rb +2 -0
  34. data/lib/zold/commands/push.rb +2 -0
  35. data/lib/zold/commands/remote.rb +11 -6
  36. data/lib/zold/commands/routines/bonuses.rb +78 -0
  37. data/lib/zold/commands/routines/reconnect.rb +2 -0
  38. data/lib/zold/commands/routines/spread.rb +2 -0
  39. data/lib/zold/commands/show.rb +2 -0
  40. data/lib/zold/commands/taxes.rb +2 -0
  41. data/lib/zold/copies.rb +4 -2
  42. data/lib/zold/hexnum.rb +2 -0
  43. data/lib/zold/http.rb +28 -20
  44. data/lib/zold/hungry_wallets.rb +2 -0
  45. data/lib/zold/id.rb +2 -0
  46. data/lib/zold/json_page.rb +2 -0
  47. data/lib/zold/key.rb +2 -0
  48. data/lib/zold/log.rb +2 -0
  49. data/lib/zold/metronome.rb +2 -0
  50. data/lib/zold/node/async_entrance.rb +3 -3
  51. data/lib/zold/node/emission.rb +2 -0
  52. data/lib/zold/node/entrance.rb +5 -2
  53. data/lib/zold/node/farm.rb +3 -1
  54. data/lib/zold/node/front.rb +4 -1
  55. data/lib/zold/node/safe_entrance.rb +2 -0
  56. data/lib/zold/node/spread_entrance.rb +2 -0
  57. data/lib/zold/patch.rb +2 -0
  58. data/lib/zold/prefixes.rb +2 -0
  59. data/lib/zold/remotes.rb +15 -13
  60. data/lib/zold/score.rb +62 -59
  61. data/lib/zold/signature.rb +2 -0
  62. data/lib/zold/tax.rb +3 -1
  63. data/lib/zold/txn.rb +4 -2
  64. data/lib/zold/type.rb +36 -0
  65. data/lib/zold/upgrades.rb +2 -4
  66. data/lib/zold/verbose_thread.rb +2 -0
  67. data/lib/zold/version.rb +4 -2
  68. data/lib/zold/version_file.rb +2 -0
  69. data/lib/zold/wallet.rb +4 -2
  70. data/lib/zold/wallets.rb +2 -0
  71. data/test/commands/routines/test_bonuses.rb +76 -0
  72. data/test/commands/routines/test_reconnect.rb +2 -0
  73. data/test/commands/routines/test_spread.rb +2 -0
  74. data/test/commands/test_alias.rb +2 -0
  75. data/test/commands/test_calculate.rb +2 -0
  76. data/test/commands/test_clean.rb +2 -0
  77. data/test/commands/test_create.rb +2 -0
  78. data/test/commands/test_diff.rb +2 -0
  79. data/test/commands/test_fetch.rb +2 -0
  80. data/test/commands/test_invoice.rb +2 -0
  81. data/test/commands/test_list.rb +2 -0
  82. data/test/commands/test_merge.rb +2 -0
  83. data/test/commands/test_node.rb +6 -0
  84. data/test/commands/test_pay.rb +2 -0
  85. data/test/commands/test_propagate.rb +2 -0
  86. data/test/commands/test_push.rb +2 -0
  87. data/test/commands/test_remote.rb +40 -0
  88. data/test/commands/test_show.rb +2 -0
  89. data/test/commands/test_taxes.rb +2 -0
  90. data/test/fake_home.rb +2 -0
  91. data/test/node/fake_entrance.rb +2 -0
  92. data/test/node/fake_node.rb +3 -1
  93. data/test/node/test_async_entrance.rb +2 -0
  94. data/test/node/test_emission.rb +2 -0
  95. data/test/node/test_entrance.rb +2 -0
  96. data/test/node/test_farm.rb +9 -7
  97. data/test/node/test_front.rb +15 -10
  98. data/test/node/test_safe_entrance.rb +2 -0
  99. data/test/node/test_spread_entrance.rb +2 -0
  100. data/test/test__helper.rb +2 -0
  101. data/test/test_amount.rb +2 -0
  102. data/test/test_atomic_file.rb +2 -0
  103. data/test/test_backtrace.rb +2 -0
  104. data/test/test_copies.rb +4 -1
  105. data/test/test_hexnum.rb +2 -0
  106. data/test/test_http.rb +5 -3
  107. data/test/test_id.rb +2 -0
  108. data/test/test_key.rb +2 -0
  109. data/test/test_metronome.rb +2 -0
  110. data/test/test_patch.rb +2 -0
  111. data/test/test_prefixes.rb +2 -0
  112. data/test/test_remotes.rb +11 -0
  113. data/test/test_score.rb +26 -24
  114. data/test/test_signature.rb +2 -0
  115. data/test/test_tax.rb +4 -2
  116. data/test/test_txn.rb +2 -0
  117. data/test/test_upgrades.rb +2 -0
  118. data/test/test_verbose_thread.rb +2 -0
  119. data/test/test_version.rb +2 -0
  120. data/test/test_wallet.rb +2 -0
  121. data/test/test_wallets.rb +2 -0
  122. data/test/test_zold.rb +2 -0
  123. data/test/upgrades/test_protocol_up.rb +2 -0
  124. data/upgrades/2.rb +2 -0
  125. data/upgrades/protocol_up.rb +2 -0
  126. data/upgrades/rename_foreign_wallets.rb +2 -0
  127. data/zold.gemspec +5 -1
  128. metadata +38 -4
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -21,6 +23,7 @@
21
23
  require 'openssl'
22
24
  require 'time'
23
25
  require_relative 'remotes'
26
+ require_relative 'type'
24
27
 
25
28
  # The score.
26
29
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -28,29 +31,24 @@ require_relative 'remotes'
28
31
  # License:: MIT
29
32
  module Zold
30
33
  # Score
31
- class Score
34
+ class Score < Dry::Struct
32
35
  # Default strength for the entire system, in production mode.
33
36
  STRENGTH = 6
34
37
 
35
- attr_reader :time, :host, :port, :invoice, :strength
36
- # time: UTC ISO 8601 string
37
- def initialize(time, host, port, invoice, suffixes = [], strength: STRENGTH)
38
- raise "Invalid host name: #{host}" unless host =~ /^[a-z0-9\.-]+$/
39
- raise 'Time must be of type Time' unless time.is_a?(Time)
40
- raise 'Port must be of type Integer' unless port.is_a?(Integer)
41
- raise "Invalid TCP port: #{port}" if port <= 0 || port > 65_535
42
- raise "Invoice '#{invoice}' has wrong format" unless invoice =~ /^[a-zA-Z0-9]{8,32}@[a-f0-9]{16}$/
43
- @time = time
44
- @host = host
45
- @port = port
46
- @invoice = invoice
47
- @suffixes = suffixes
48
- @strength = strength
49
- @created = Time.now
50
- end
38
+ attribute :time, Types::Strict::Time
39
+ attribute :host, Types::Strict::String.constrained(
40
+ format: /^[a-z0-9\.-]+$/
41
+ )
42
+ attribute :port, Types::Strict::Integer.constrained(gteq: 0, lt: 65_535)
43
+ attribute :invoice, Types::Strict::String.constrained(
44
+ format: /^[a-zA-Z0-9]{8,32}@[a-f0-9]{16}$/
45
+ )
46
+ attribute :suffixes, Types::Strict::Array.optional.default([])
47
+ attribute :strength, Types::Strict::Integer.optional.default(STRENGTH)
48
+ attribute :created, Types::Strict::Time.optional.default(Time.now)
51
49
 
52
50
  # The default no-value score.
53
- ZERO = Score.new(Time.now, 'localhost', 80, 'NOPREFIX@ffffffffffffffff')
51
+ ZERO = Score.new(time: Time.now, host: 'localhost', port: 80, invoice: 'NOPREFIX@ffffffffffffffff')
54
52
 
55
53
  def self.parse_json(json)
56
54
  raise "Time in JSON is broken: #{json}" unless json['time'] =~ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/
@@ -59,8 +57,8 @@ module Zold
59
57
  raise "Invoice is wrong: #{json}" unless json['invoice'] =~ /^[a-zA-Z0-9]{8,32}@[a-f0-9]{16}$/
60
58
  raise "Suffixes not array: #{json}" unless json['suffixes'].is_a?(Array)
61
59
  Score.new(
62
- Time.parse(json['time']), json['host'],
63
- json['port'], json['invoice'], json['suffixes'],
60
+ time: Time.parse(json['time']), host: json['host'],
61
+ port: json['port'], invoice: json['invoice'], suffixes: json['suffixes'],
64
62
  strength: json['strength']
65
63
  )
66
64
  end
@@ -79,9 +77,9 @@ module Zold
79
77
  m = re.match(text.strip)
80
78
  raise "Invalid score '#{text}', doesn't match: #{re}" if m.nil?
81
79
  Score.new(
82
- Time.parse(m[:time]), m[:host],
83
- m[:port].to_i, m[:invoice],
84
- m[:suffixes].split(' '),
80
+ time: Time.parse(m[:time]), host: m[:host],
81
+ port: m[:port].to_i, invoice: m[:invoice],
82
+ suffixes: m[:suffixes].split(' '),
85
83
  strength: m[:strength].to_i
86
84
  )
87
85
  end
@@ -89,71 +87,71 @@ module Zold
89
87
  def self.parse_text(text)
90
88
  parts = text.split(' ', 7)
91
89
  Score.new(
92
- Time.at(parts[1].hex),
93
- parts[2],
94
- parts[3].hex,
95
- "#{parts[4]}@#{parts[5]}",
96
- parts[6] ? parts[6].split(' ') : [],
90
+ time: Time.at(parts[1].hex),
91
+ host: parts[2],
92
+ port: parts[3].hex,
93
+ invoice: "#{parts[4]}@#{parts[5]}",
94
+ suffixes: parts[6] ? parts[6].split(' ') : [],
97
95
  strength: parts[0].to_i
98
96
  )
99
97
  end
100
98
 
101
99
  def hash
102
- raise 'Score has zero value, there is no hash' if @suffixes.empty?
103
- @suffixes.reduce(prefix) do |pfx, suffix|
100
+ raise 'Score has zero value, there is no hash' if suffixes.empty?
101
+ suffixes.reduce(prefix) do |pfx, suffix|
104
102
  OpenSSL::Digest::SHA256.new("#{pfx} #{suffix}").hexdigest
105
103
  end
106
104
  end
107
105
 
108
106
  def to_mnemo
109
- "#{value}:#{@time.strftime('%H%M')}"
107
+ "#{value}:#{time.strftime('%H%M')}"
110
108
  end
111
109
 
112
110
  def to_text
113
- pfx, bnf = @invoice.split('@')
111
+ pfx, bnf = invoice.split('@')
114
112
  [
115
- @strength,
116
- @time.to_i.to_s(16),
117
- @host,
118
- @port.to_s(16),
113
+ strength,
114
+ time.to_i.to_s(16),
115
+ host,
116
+ port.to_s(16),
119
117
  pfx,
120
118
  bnf,
121
- @suffixes.join(' ')
119
+ suffixes.join(' ')
122
120
  ].join(' ')
123
121
  end
124
122
 
125
123
  def to_s
126
124
  [
127
- "#{value}/#{@strength}:",
128
- @time.utc.iso8601,
129
- @host,
130
- @port,
131
- @invoice,
132
- @suffixes.join(' ')
125
+ "#{value}/#{strength}:",
126
+ time.utc.iso8601,
127
+ host,
128
+ port,
129
+ invoice,
130
+ suffixes.join(' ')
133
131
  ].join(' ')
134
132
  end
135
133
 
136
134
  def to_h
137
135
  {
138
136
  value: value,
139
- host: @host,
140
- port: @port,
141
- invoice: @invoice,
142
- time: @time.utc.iso8601,
143
- suffixes: @suffixes,
144
- strength: @strength,
137
+ host: host,
138
+ port: port,
139
+ invoice: invoice,
140
+ time: time.utc.iso8601,
141
+ suffixes: suffixes,
142
+ strength: strength,
145
143
  hash: value.zero? ? nil : hash,
146
144
  expired: expired?,
147
145
  valid: valid?,
148
146
  age: (age / 60).round,
149
- created: @created.utc.iso8601
147
+ created: created.utc.iso8601
150
148
  }
151
149
  end
152
150
 
153
151
  def reduced(max = 4)
154
152
  Score.new(
155
- @time, @host, @port, @invoice,
156
- @suffixes[0..[max, @suffixes.count].min - 1], strength: @strength
153
+ time: time, host: host, port: port, invoice: invoice,
154
+ suffixes: suffixes[0..[max, suffixes.count].min - 1], strength: strength, created: nil
157
155
  )
158
156
  end
159
157
 
@@ -163,17 +161,22 @@ module Zold
163
161
  loop do
164
162
  suffix = idx.to_s(16)
165
163
  score = Score.new(
166
- @time, @host, @port, @invoice, @suffixes + [suffix],
167
- strength: @strength
164
+ time: time, host: host, port: port, invoice: invoice, suffixes: suffixes + [suffix],
165
+ strength: strength
168
166
  )
169
167
  return score if score.valid?
170
- return Score.new(Time.now, @host, @port, @invoice, [], strength: @strength) if score.expired?
168
+ if score.expired?
169
+ return Score.new(
170
+ time: Time.now, host: host, port: port, invoice: invoice,
171
+ suffixes: [], strength: strength
172
+ )
173
+ end
171
174
  idx += 1
172
175
  end
173
176
  end
174
177
 
175
178
  def age
176
- Time.now - @time
179
+ Time.now - time
177
180
  end
178
181
 
179
182
  def expired?(hours = 24)
@@ -181,15 +184,15 @@ module Zold
181
184
  end
182
185
 
183
186
  def prefix
184
- "#{@time.utc.iso8601} #{@host} #{@port} #{@invoice}"
187
+ "#{time.utc.iso8601} #{host} #{port} #{invoice}"
185
188
  end
186
189
 
187
190
  def valid?
188
- @suffixes.empty? || hash.end_with?('0' * @strength)
191
+ suffixes.empty? || hash.end_with?('0' * strength)
189
192
  end
190
193
 
191
194
  def value
192
- @suffixes.length
195
+ suffixes.length
193
196
  end
194
197
 
195
198
  def zero?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -49,7 +51,7 @@ module Zold
49
51
  DAYS_INCREMENT = 32
50
52
 
51
53
  # Text prefix for taxes details
52
- PREFIX = 'TAXES'.freeze
54
+ PREFIX = 'TAXES'
53
55
 
54
56
  def initialize(wallet)
55
57
  @wallet = wallet
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -33,10 +35,10 @@ module Zold
33
35
  # A single transaction
34
36
  class Txn
35
37
  # Regular expression for details
36
- RE_DETAILS = '[a-zA-Z0-9 @\!\?\*_\-\.:,\']+'.freeze
38
+ RE_DETAILS = '[a-zA-Z0-9 @\!\?\*_\-\.:,\']+'
37
39
 
38
40
  # Regular expression for prefix
39
- RE_PREFIX = '[a-zA-Z0-9]+'.freeze
41
+ RE_PREFIX = '[a-zA-Z0-9]+'
40
42
 
41
43
  attr_reader :id, :date, :amount, :prefix, :bnf, :details, :sign
42
44
  attr_writer :sign, :amount, :bnf
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2018 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ # @todo #98:30m/DEV Right now only Score and Http classes have been refactored for using
24
+ # dry-types, even tough the issue has been boosted refactoring the whole project
25
+ # is very cumbersome. Please refer to Score and Http class on how to perform all
26
+ # the changes for the project to adopt dry-types
27
+ require 'dry-types'
28
+ require 'dry-struct'
29
+
30
+ # HTTP page.
31
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
32
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
33
+ # License:: MIT
34
+ module Types
35
+ include Dry::Types.module
36
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -29,10 +31,6 @@ module Zold
29
31
  @log = log
30
32
  end
31
33
 
32
- # @todo #285:30min Write the upgrade manager tests that ensure:
33
- # - Nothing breaks without the version file.
34
- # - The upgrade scripts run when there is a version file and there are pending upgrade scripts.
35
- # - Make sure *only* the correct upgrade scripts run.
36
34
  def run
37
35
  Dir.glob("#{@directory}/*.rb").select { |f| f =~ /^(\d+)\.rb$/ }.sort.each do |script|
38
36
  @version.apply(script)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -23,6 +25,6 @@
23
25
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
24
26
  # License:: MIT
25
27
  module Zold
26
- VERSION = '0.14.8'.freeze
27
- PROTOCOL = 2
28
+ VERSION = '0.14.9'
29
+ PROTOCOL = 1
28
30
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -43,10 +45,10 @@ module Zold
43
45
  class Wallet
44
46
  # The name of the main production network. All other networks
45
47
  # must have different names.
46
- MAIN_NETWORK = 'zold'.freeze
48
+ MAIN_NETWORK = 'zold'
47
49
 
48
50
  # The extension of the wallet files
49
- EXTENSION = '.z'.freeze
51
+ EXTENSION = '.z'
50
52
 
51
53
  def initialize(file)
52
54
  @file = file
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2018 Yegor Bugayenko
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2018 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'minitest/autorun'
24
+ require 'webmock/minitest'
25
+ require_relative '../../test__helper'
26
+ require_relative '../../fake_home'
27
+ require_relative '../../node/fake_node'
28
+ require_relative '../../../lib/zold/node/farm.rb'
29
+ require_relative '../../../lib/zold/commands/push'
30
+ require_relative '../../../lib/zold/commands/pay'
31
+ require_relative '../../../lib/zold/commands/routines/bonuses.rb'
32
+
33
+ # Bonuses test.
34
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
35
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
36
+ # License:: MIT
37
+ class TestBonuses < Minitest::Test
38
+ def test_pays_bonuses
39
+ FakeHome.new.run do |home|
40
+ FakeNode.new(log: test_log).run(['--ignore-score-weakness']) do |port|
41
+ bank = home.create_wallet
42
+ Zold::Pay.new(wallets: home.wallets, remotes: home.remotes, log: test_log).run(
43
+ ['pay', home.create_wallet.id.to_s, bank.id.to_s, '100', '--force', '--private-key=id_rsa']
44
+ )
45
+ assert_equal(Zold::Amount.new(zld: 100.0), bank.balance)
46
+ opts = {
47
+ 'ignore-score-weakness' => true,
48
+ 'routine-immediately' => true,
49
+ 'private-key' => 'id_rsa',
50
+ 'bonus-wallet' => bank.id.to_s,
51
+ 'bonus-amount' => 1,
52
+ 'bonus-time' => 0
53
+ }
54
+ score = Zold::Score.new(
55
+ time: Time.now, host: 'fake-node.local', port: 999, invoice: 'NOPREFIX@ffffffffffffffff', strength: 1
56
+ )
57
+ 16.times { score = score.next }
58
+ remotes = home.remotes
59
+ remotes.add('localhost', port)
60
+ remotes.add(score.host, score.port)
61
+ stub_request(:get, "http://#{score.host}:#{score.port}/").to_return(
62
+ status: 200,
63
+ body: {
64
+ version: Zold::VERSION,
65
+ score: score.to_h
66
+ }.to_json
67
+ )
68
+ Zold::Routines::Bonuses.new(
69
+ opts, home.wallets, remotes, home.copies(bank).root,
70
+ Zold::Farm::Empty.new, log: test_log
71
+ ).exec
72
+ assert_equal(Zold::Amount.new(zld: 99.0), bank.balance)
73
+ end
74
+ end
75
+ end
76
+ end