zold 0.0.8 → 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +12 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +11 -0
  4. data/.rubocop.yml +9 -1
  5. data/.simplecov +2 -2
  6. data/.travis.yml +1 -1
  7. data/Gemfile +1 -1
  8. data/LICENSE.txt +1 -1
  9. data/Procfile +1 -1
  10. data/README.md +208 -101
  11. data/Rakefile +2 -1
  12. data/bin/zold +135 -54
  13. data/features/cli.feature +1 -1
  14. data/features/step_definitions/steps.rb +1 -1
  15. data/features/support/env.rb +1 -1
  16. data/fixtures/scripts/push-and-pull.sh +35 -0
  17. data/lib/zold.rb +2 -2
  18. data/lib/zold/amount.rb +10 -2
  19. data/lib/zold/commands/{send.rb → clean.rb} +16 -16
  20. data/lib/zold/commands/create.rb +7 -5
  21. data/lib/zold/commands/diff.rb +59 -0
  22. data/lib/zold/commands/fetch.rb +74 -0
  23. data/lib/zold/commands/{pull.rb → list.rb} +11 -17
  24. data/lib/zold/commands/merge.rb +50 -0
  25. data/lib/zold/commands/node.rb +94 -0
  26. data/lib/zold/commands/pay.rb +58 -0
  27. data/lib/zold/commands/{check.rb → propagate.rb} +19 -20
  28. data/lib/zold/commands/push.rb +12 -12
  29. data/lib/zold/commands/remote.rb +115 -0
  30. data/lib/zold/commands/{balance.rb → show.rb} +11 -7
  31. data/lib/zold/copies.rb +126 -0
  32. data/lib/zold/http.rb +70 -0
  33. data/lib/zold/id.rb +8 -3
  34. data/lib/zold/key.rb +2 -2
  35. data/lib/zold/log.rb +51 -2
  36. data/lib/zold/node/farm.rb +81 -0
  37. data/lib/zold/node/front.rb +94 -46
  38. data/lib/zold/patch.rb +58 -0
  39. data/lib/zold/remotes.rb +106 -0
  40. data/lib/zold/score.rb +101 -0
  41. data/lib/zold/signature.rb +48 -0
  42. data/lib/zold/version.rb +3 -3
  43. data/lib/zold/wallet.rb +87 -55
  44. data/lib/zold/wallets.rb +13 -6
  45. data/resources/remotes +1 -0
  46. data/test/commands/test_clean.rb +41 -0
  47. data/test/commands/test_create.rb +2 -2
  48. data/test/commands/test_diff.rb +61 -0
  49. data/test/commands/test_fetch.rb +65 -0
  50. data/test/commands/test_list.rb +42 -0
  51. data/test/commands/test_merge.rb +62 -0
  52. data/test/commands/test_node.rb +56 -0
  53. data/test/commands/{test_send.rb → test_pay.rb} +10 -11
  54. data/test/commands/test_remote.rb +60 -0
  55. data/test/commands/{test_balance.rb → test_show.rb} +6 -8
  56. data/test/node/fake_node.rb +73 -0
  57. data/test/node/test_farm.rb +34 -0
  58. data/test/node/test_front.rb +26 -57
  59. data/test/test__helper.rb +1 -1
  60. data/test/test_amount.rb +10 -2
  61. data/test/test_copies.rb +73 -0
  62. data/test/test_http.rb +42 -0
  63. data/test/test_id.rb +2 -2
  64. data/test/test_key.rb +10 -10
  65. data/test/test_patch.rb +59 -0
  66. data/test/test_remotes.rb +72 -0
  67. data/test/test_score.rb +79 -0
  68. data/test/test_signature.rb +45 -0
  69. data/test/test_wallet.rb +18 -35
  70. data/test/test_wallets.rb +14 -3
  71. data/test/test_zold.rb +52 -5
  72. data/zold.gemspec +5 -3
  73. metadata +92 -21
  74. data/CONTRIBUTING.md +0 -19
  75. data/views/index.haml +0 -6
  76. data/views/layout.haml +0 -26
  77. data/views/not_found.haml +0 -3
@@ -0,0 +1,48 @@
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'time'
22
+ require_relative 'key.rb'
23
+ require_relative 'id.rb'
24
+ require_relative 'amount.rb'
25
+
26
+ # The signature of a transaction.
27
+ #
28
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
29
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
30
+ # License:: MIT
31
+ module Zold
32
+ # A signature
33
+ class Signature
34
+ def sign(pvt, txn)
35
+ pvt.sign(block(txn))
36
+ end
37
+
38
+ def valid?(pub, txn)
39
+ pub.verify(txn[:sign], block(txn))
40
+ end
41
+
42
+ private
43
+
44
+ def block(txn)
45
+ "#{txn[:id]};#{txn[:amount].to_i};#{txn[:bnf]};#{txn[:details]}"
46
+ end
47
+ end
48
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2018 Zerocracy, Inc.
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -20,8 +20,8 @@
20
20
 
21
21
  # Zold main module.
22
22
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
23
- # Copyright:: Copyright (c) 2018 Zerocracy, Inc.
23
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
24
24
  # License:: MIT
25
25
  module Zold
26
- VERSION = '0.0.8'.freeze
26
+ VERSION = '0.1'.freeze
27
27
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2018 Zerocracy, Inc.
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -19,10 +19,19 @@
19
19
  # SOFTWARE.
20
20
 
21
21
  require 'time'
22
+ require_relative 'key.rb'
23
+ require_relative 'id.rb'
24
+ require_relative 'amount.rb'
25
+ require_relative 'signature.rb'
22
26
 
23
27
  # The wallet.
28
+ #
29
+ # It is a text file with a name equal to the wallet ID, which is
30
+ # a hexadecimal number of 16 digits, for example: "0123456789abcdef".
31
+ # More details about its format is in README.md.
32
+ #
24
33
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
25
- # Copyright:: Copyright (c) 2018 Zerocracy, Inc.
34
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
26
35
  # License:: MIT
27
36
  module Zold
28
37
  # A single wallet
@@ -31,6 +40,10 @@ module Zold
31
40
  @file = file
32
41
  end
33
42
 
43
+ def ==(other)
44
+ to_s == other.to_s
45
+ end
46
+
34
47
  def to_s
35
48
  id.to_s
36
49
  end
@@ -43,16 +56,11 @@ module Zold
43
56
  @file
44
57
  end
45
58
 
46
- def init(id, pubkey)
47
- raise "File '#{@file}' already exists" if File.exist?(@file)
59
+ def init(id, pubkey, overwrite: false)
60
+ raise "File '#{@file}' already exists" if File.exist?(@file) && !overwrite
48
61
  File.write(@file, "#{id}\n#{pubkey.to_pub}\n\n")
49
62
  end
50
63
 
51
- def version
52
- all = txns
53
- all.empty? ? 0 : all.map { |t| t[0] }.map(&:to_i).max
54
- end
55
-
56
64
  def root?
57
65
  id == Id::ROOT
58
66
  end
@@ -62,68 +70,92 @@ module Zold
62
70
  end
63
71
 
64
72
  def balance
65
- Amount.new(
66
- coins: txns.map { |t| t[2] }.map(&:to_i).inject(0) { |sum, n| sum + n }
67
- )
73
+ txns.inject(Amount::ZERO) { |sum, t| sum + t[:amount] }
68
74
  end
69
75
 
70
- def sub(amount, target, pvtkey)
71
- date = Time.now
72
- txn = version + 1
73
- line = [
74
- txn,
75
- date.iso8601,
76
- -amount.to_i,
77
- target,
78
- pvtkey.sign("#{txn};#{amount.to_i};#{target}")
79
- ].join(';') + "\n"
80
- File.write(@file, (lines << line).join(''))
81
- {
82
- id: txn,
83
- date: date,
84
- amount: amount,
85
- beneficiary: id
76
+ def sub(amount, target, pvtkey, details = '-')
77
+ txn = {
78
+ id: max + 1,
79
+ date: Time.now,
80
+ amount: amount.mul(-1),
81
+ bnf: target,
82
+ details: details
86
83
  }
84
+ txn[:sign] = Signature.new.sign(pvtkey, txn)
85
+ File.write(@file, (lines << to_line(txn)).join)
86
+ txn[:amount] = amount
87
+ txn
87
88
  end
88
89
 
89
90
  def add(txn)
90
- line = [
91
- "/#{txn[:id]}",
92
- txn[:date].iso8601,
93
- txn[:amount].to_i,
94
- txn[:beneficiary]
95
- ].join(';') + "\n"
96
- File.write(@file, (lines << line).join(''))
91
+ open(@file, 'a') { |f| f.print to_line(txn) }
97
92
  end
98
93
 
99
- def check(id, amount, beneficiary)
100
- txn = txns.find { |t| t[0].to_i == id }
101
- raise "Transaction ##{id} not found" if txn.nil?
102
- xamount = Amount.new(coins: txn[2].to_i).mul(-1)
103
- raise "#{xamount} != #{amount}" if xamount != amount
104
- xbeneficiary = Id.new(txn[3].to_s)
105
- raise "#{xbeneficiary} != #{beneficiary}" if xbeneficiary != beneficiary
106
- data = "#{id};#{amount.to_i};#{beneficiary}"
107
- valid = Key.new(text: lines[1].strip).verify(txn[4], data)
108
- raise "Signature is not confirming this data: '#{data}'" unless valid
109
- true
94
+ def has?(id, bnf)
95
+ !txns.find { |t| t[:id] == id && t[:bnf] == bnf }.nil?
96
+ end
97
+
98
+ def key
99
+ Key.new(text: lines[1].strip)
110
100
  end
111
101
 
112
102
  def income
113
- txns.select { |t| t[2].to_i > 0 }.each do |t|
114
- hash = {
115
- id: t[0][1..-1].to_i,
116
- beneficiary: Id.new(t[3]),
117
- amount: Amount.new(coins: t[2].to_i)
118
- }
119
- yield hash
103
+ txns.each do |t|
104
+ yield t unless t[:amount].negative?
120
105
  end
121
106
  end
122
107
 
108
+ def txns
109
+ lines.drop(3)
110
+ .each_with_index
111
+ .map { |t, i| fields(t, i + 4) }
112
+ .sort_by { |a| a[:date] }
113
+ end
114
+
123
115
  private
124
116
 
125
- def txns
126
- lines.drop(3).map { |t| t.split(';') }
117
+ def max
118
+ all = txns
119
+ if all.empty?
120
+ 0
121
+ else
122
+ all.select { |t| t[:amount].negative? }.max_by { |t| t[:id] }[:id]
123
+ end
124
+ end
125
+
126
+ def to_line(txn)
127
+ [
128
+ txn[:id],
129
+ txn[:date].utc.iso8601,
130
+ txn[:amount].to_i,
131
+ txn[:bnf],
132
+ txn[:details],
133
+ txn[:sign]
134
+ ].join(';') + "\n"
135
+ end
136
+
137
+ def fields(line, idx)
138
+ regex = Regexp.new(
139
+ [
140
+ '([0-9]+)',
141
+ '([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)',
142
+ '(-?[0-9]+)',
143
+ '([a-f0-9]{16})',
144
+ '([a-zA-Z0-9 -.]{1,128})',
145
+ '([A-Za-z0-9+/]+={0,3})?'
146
+ ].join(';')
147
+ )
148
+ clean = line.strip
149
+ raise "Invalid line ##{idx}: #{line.inspect}" unless regex.match(clean)
150
+ parts = clean.split(';')
151
+ {
152
+ id: parts[0].to_i,
153
+ date: Time.parse(parts[1]),
154
+ amount: Amount.new(coins: parts[2].to_i),
155
+ bnf: Id.new(parts[3]),
156
+ details: parts[4],
157
+ sign: parts[5]
158
+ }
127
159
  end
128
160
 
129
161
  def lines
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2018 Zerocracy, Inc.
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -18,11 +18,12 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
19
  # SOFTWARE.
20
20
 
21
+ require_relative 'id.rb'
21
22
  require_relative 'wallet.rb'
22
23
 
23
24
  # The local collection of wallets.
24
25
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
25
- # Copyright:: Copyright (c) 2018 Zerocracy, Inc.
26
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
26
27
  # License:: MIT
27
28
  module Zold
28
29
  # Collection of local wallets
@@ -31,12 +32,18 @@ module Zold
31
32
  @dir = dir
32
33
  end
33
34
 
34
- def to_s
35
- @dir
35
+ def path
36
+ File.expand_path(@dir)
36
37
  end
37
38
 
38
- def total
39
- Dir.new(@dir).select { |f| File.file?(File.join(@dir, f)) }.count
39
+ def all
40
+ Dir.new(@dir).select do |f|
41
+ file = File.join(@dir, f)
42
+ File.file?(file) &&
43
+ !File.directory?(file) &&
44
+ f =~ /[0-9a-fA-F]{16}/ &&
45
+ Id.new(f).to_s == f
46
+ end
40
47
  end
41
48
 
42
49
  def find(id)
@@ -0,0 +1 @@
1
+ b1.zold.io,80,0
@@ -0,0 +1,41 @@
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'minitest/autorun'
22
+ require 'tmpdir'
23
+ require 'time'
24
+ require_relative '../../lib/zold/copies.rb'
25
+ require_relative '../../lib/zold/commands/clean.rb'
26
+
27
+ # CLEAN test.
28
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
29
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
30
+ # License:: MIT
31
+ class TestClean < Minitest::Test
32
+ def test_cleans_copies
33
+ Dir.mktmpdir 'test' do |dir|
34
+ copies = Zold::Copies.new(File.join(dir, 'copies'))
35
+ copies.add('a1', 'host-1', 80, 1, Time.now - 26 * 60)
36
+ copies.add('a2', 'host-2', 80, 2, Time.now - 26 * 60)
37
+ Zold::Clean.new(copies: copies).run
38
+ assert(copies.all.empty?)
39
+ end
40
+ end
41
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2018 Zerocracy, Inc.
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the 'Software'), to deal
@@ -26,7 +26,7 @@ require_relative '../../lib/zold/commands/create.rb'
26
26
 
27
27
  # CREATE test.
28
28
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
29
- # Copyright:: Copyright (c) 2018 Zerocracy, Inc.
29
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
30
30
  # License:: MIT
31
31
  class TestCreate < Minitest::Test
32
32
  def test_creates_wallet
@@ -0,0 +1,61 @@
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'minitest/autorun'
22
+ require 'tmpdir'
23
+ require 'json'
24
+ require 'time'
25
+ require 'webmock/minitest'
26
+ require_relative '../../lib/zold/wallet.rb'
27
+ require_relative '../../lib/zold/id.rb'
28
+ require_relative '../../lib/zold/copies.rb'
29
+ require_relative '../../lib/zold/key.rb'
30
+ require_relative '../../lib/zold/commands/pay.rb'
31
+ require_relative '../../lib/zold/commands/diff.rb'
32
+
33
+ # DIFF test.
34
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
35
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
36
+ # License:: MIT
37
+ class TestDiff < Minitest::Test
38
+ def test_diff_with_copies
39
+ Dir.mktmpdir 'test' do |dir|
40
+ id = Zold::Id.new
41
+ file = File.join(dir, id.to_s)
42
+ wallet = Zold::Wallet.new(file)
43
+ wallet.init(id, Zold::Key.new(file: 'fixtures/id_rsa.pub'))
44
+ first = Zold::Wallet.new(File.join(dir, 'copy-1'))
45
+ File.write(first.path, File.read(wallet.path))
46
+ second = Zold::Wallet.new(File.join(dir, 'copy-2'))
47
+ File.write(second.path, File.read(wallet.path))
48
+ Zold::Pay.new(
49
+ payer: first,
50
+ receiver: second,
51
+ amount: Zold::Amount.new(zld: 14.95),
52
+ pvtkey: Zold::Key.new(file: 'fixtures/id_rsa')
53
+ ).run(['--force'])
54
+ copies = Zold::Copies.new(File.join(dir, 'copies'))
55
+ copies.add(File.read(first.path), 'host-1', 80, 5)
56
+ copies.add(File.read(second.path), 'host-2', 80, 5)
57
+ diff = Zold::Diff.new(wallet: wallet, copies: copies).run
58
+ assert(diff.include?('+1;'))
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,65 @@
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'minitest/autorun'
22
+ require 'tmpdir'
23
+ require 'json'
24
+ require 'time'
25
+ require 'webmock/minitest'
26
+ require_relative '../../lib/zold/wallet.rb'
27
+ require_relative '../../lib/zold/remotes.rb'
28
+ require_relative '../../lib/zold/id.rb'
29
+ require_relative '../../lib/zold/copies.rb'
30
+ require_relative '../../lib/zold/key.rb'
31
+ require_relative '../../lib/zold/score.rb'
32
+ require_relative '../../lib/zold/commands/fetch.rb'
33
+
34
+ # FETCH test.
35
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
36
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
37
+ # License:: MIT
38
+ class TestFetch < Minitest::Test
39
+ def test_fetches_wallet
40
+ Dir.mktmpdir 'test' do |dir|
41
+ id = Zold::Id.new
42
+ file = File.join(dir, id.to_s)
43
+ wallet = Zold::Wallet.new(file)
44
+ wallet.init(id, Zold::Key.new(file: 'fixtures/id_rsa.pub'))
45
+ copies = Zold::Copies.new(File.join(dir, 'copies'))
46
+ remotes = Zold::Remotes.new(File.join(dir, 'remotes.csv'))
47
+ remotes.clean
48
+ stub_request(:get, "http://fake-1/wallet/#{id}").to_return(
49
+ status: 200,
50
+ body: {
51
+ 'score': Zold::Score::ZERO.to_h,
52
+ 'body': File.read(wallet.path)
53
+ }.to_json
54
+ )
55
+ stub_request(:get, "http://fake-2/wallet/#{id}").to_return(
56
+ status: 404
57
+ )
58
+ remotes.add('fake-1', 80)
59
+ remotes.add('fake-2', 80)
60
+ Zold::Fetch.new(wallet: wallet, copies: copies, remotes: remotes).run
61
+ assert_equal(copies.all[0][:name], '1')
62
+ assert_equal(copies.all[0][:score], 0)
63
+ end
64
+ end
65
+ end