zold 0.14.8 → 0.14.9

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.
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