Skip to content

Commit

Permalink
#6 real tests
Browse files Browse the repository at this point in the history
  • Loading branch information
yegor256 committed Jul 5, 2019
1 parent bcdc2fd commit 1e542bf
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 137 deletions.
2 changes: 2 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Layout/EmptyLineAfterGuardClause:
Enabled: false
Layout/EndOfLine:
EnforcedStyle: lf
Style/ClassAndModuleChildren:
Enabled: false
Metrics/AbcSize:
Max: 45
Metrics/BlockLength:
Expand Down
291 changes: 160 additions & 131 deletions lib/zold/wts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,160 +33,189 @@
# Author:: Yegor Bugayenko (yegor256@gmail.com)
# Copyright:: Copyright (c) 2018-2019 Yegor Bugayenko
# License:: MIT
module Zold
# WTS
class WTS
# Makes a new object of the class. The <tt>key</tt> you are supposed
# to obtain at this page: https://wts.zold.io/api. You will have to login
# and confirm your account first. Keep this key secret, to avoid
# information lost. However, even knowing the secret no payments can
# be sent without they keygap.
def initialize(key, log: Loog::NULL)
raise 'Key can\'t be nil' if key.nil?
@key = key
raise 'Log can\'t be nil' if log.nil?
@log = log
end

# Initiate PULL request. The server will pull your wallet form the network,
# and make it ready for future requests. Without this operation you won't
# be able to perform <tt>find()</tt> or <tt>balance()</tt> requests.
#
# The method returns the job ID, which you should wait for completion
# using the method <tt>wait()</tt>.
class Zold::WTS
# Fake implementation.
class Fake
def pull
start = Time.now
job = job_of(
clean(
Typhoeus::Request.get(
'https://wts.zold.io/pull',
headers: headers
)
)
)
@log.debug("PULL job #{job} started in #{Zold::Age.new(start)}")
job
'job-id'
end

# Get wallet balance.
def balance
start = Time.now
http = clean(
Typhoeus::Request.get(
'https://wts.zold.io/balance',
headers: headers
)
)
balance = Zold::Amount.new(zents: http.body.to_i)
@log.debug("The balance #{balance} retrieved in #{Zold::Age.new(start)}")
balance
Zold::Amount.new(zld: 4.0)
end

# Get wallet ID.
def id
start = Time.now
http = clean(
Typhoeus::Request.get(
'https://wts.zold.io/id',
headers: headers
)
)
id = Zold::Id.new(http.body.to_s)
@log.debug("Wallet ID #{id} retrieved in #{Zold::Age.new(start)}")
id
Zold::Id::ROOT
end

# Initiate PAY request. The <tt>keygap</tt> is a string you get
# when you confirm the account. The <tt>bnf</tt> is the name of the
# GitHub account, the wallet ID or the invoice (up to you). The
# <tt>amount</tt> is the amount in ZLD, e.g. "19.99". The <tt>details</tt>
# is the text to add to the transaction.
#
# The method returns the job ID, which you should wait for completion
# using the method <tt>wait()</tt>.
def pay(keygap, bnf, amount, details)
start = Time.now
job = job_of(
clean(
Typhoeus::Request.post(
'https://wts.zold.io/do-pay',
headers: headers,
body: { keygap: keygap, bnf: bnf, amount: amount, details: details }
)
)
)
@log.debug("PAY job #{job} started in #{Zold::Age.new(start)}")
job
def pay(_keygap, _bnf, _amount, _details)
'job-id'
end

# Find transactions by the criteria. All criterias are regular expressions
# and their summary result is concatenated by OR. For example, this request
# will return all transactions that have "pizza" in details OR which
# are coming from the root wallet:
#
# find(details: /pizza/, bnf: '0000000000000000')
#
# The method returns an array of Zold::Txn objects.
def find(query)
start = Time.now
http = clean(
def find(_query)
[]
end

def wait(_job, time: 5 * 60)
raise 'Time must be positive' if time.negative?
'OK'
end
end

# Makes a new object of the class. The <tt>key</tt> you are supposed
# to obtain at this page: https://wts.zold.io/api. You will have to login
# and confirm your account first. Keep this key secret, to avoid
# information lost. However, even knowing the secret no payments can
# be sent without they keygap.
def initialize(key, log: Loog::NULL)
raise 'Key can\'t be nil' if key.nil?
@key = key
raise 'Log can\'t be nil' if log.nil?
@log = log
end

# Initiate PULL request. The server will pull your wallet form the network,
# and make it ready for future requests. Without this operation you won't
# be able to perform <tt>find()</tt> or <tt>balance()</tt> requests.
#
# The method returns the job ID, which you should wait for completion
# using the method <tt>wait()</tt>.
def pull
start = Time.now
job = job_of(
clean(
Typhoeus::Request.get(
'https://wts.zold.io/find?' + query.map do |k, v|
"#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"
end.join('&'),
'https://wts.zold.io/pull',
headers: headers
)
)
txns = http.body.split("\n").map { |t| Zold::Txn.parse(t) }
@log.debug("#{txns.count} transactions found in #{Zold::Age.new(start)}")
txns
end
)
@log.debug("PULL job #{job} started in #{Zold::Age.new(start)}")
job
end

# Wait for the job to complete. If the job completes successfully, the
# method returns 'OK' in a few seconds (up to a few minutes). If the
# is some error, the exception will be raised.
def wait(job, time: 5 * 60)
start = Time.now
loop do
if Time.now - start > time
raise "Can't wait any longer for the job #{job} to complete"
end
http = Typhoeus::Request.get(
'https://wts.zold.io/job?id=' + job,
headers: headers
# Get wallet balance.
def balance
start = Time.now
http = clean(
Typhoeus::Request.get(
'https://wts.zold.io/balance',
headers: headers
)
)
balance = Zold::Amount.new(zents: http.body.to_i)
@log.debug("The balance #{balance} retrieved in #{Zold::Age.new(start)}")
balance
end

# Get wallet ID.
def id
start = Time.now
http = clean(
Typhoeus::Request.get(
'https://wts.zold.io/id',
headers: headers
)
)
id = Zold::Id.new(http.body.to_s)
@log.debug("Wallet ID #{id} retrieved in #{Zold::Age.new(start)}")
id
end

# Initiate PAY request. The <tt>keygap</tt> is a string you get
# when you confirm the account. The <tt>bnf</tt> is the name of the
# GitHub account, the wallet ID or the invoice (up to you). The
# <tt>amount</tt> is the amount in ZLD, e.g. "19.99". The <tt>details</tt>
# is the text to add to the transaction.
#
# The method returns the job ID, which you should wait for completion
# using the method <tt>wait()</tt>.
def pay(keygap, bnf, amount, details)
start = Time.now
job = job_of(
clean(
Typhoeus::Request.post(
'https://wts.zold.io/do-pay',
headers: headers,
body: { keygap: keygap, bnf: bnf, amount: amount, details: details }
)
raise "Job #{job} not found on the server" if http.code == 404
raise "Unpredictable response code #{http.code}" unless http.code == 200
next if http.body == 'Running'
raise http.body unless http.body == 'OK'
@log.debug("Job #{job} completed, in #{Zold::Age.new(start)}")
return http.body
)
)
@log.debug("PAY job #{job} started in #{Zold::Age.new(start)}")
job
end

# Find transactions by the criteria. All criterias are regular expressions
# and their summary result is concatenated by OR. For example, this request
# will return all transactions that have "pizza" in details OR which
# are coming from the root wallet:
#
# find(details: /pizza/, bnf: '0000000000000000')
#
# The method returns an array of Zold::Txn objects.
def find(query)
start = Time.now
http = clean(
Typhoeus::Request.get(
'https://wts.zold.io/find?' + query.map do |k, v|
"#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"
end.join('&'),
headers: headers
)
)
txns = http.body.split("\n").map { |t| Zold::Txn.parse(t) }
@log.debug("#{txns.count} transactions found in #{Zold::Age.new(start)}")
txns
end

# Wait for the job to complete. If the job completes successfully, the
# method returns 'OK' in a few seconds (up to a few minutes). If the
# is some error, the exception will be raised.
def wait(job, time: 5 * 60)
start = Time.now
loop do
if Time.now - start > time
raise "Can't wait any longer for the job #{job} to complete"
end
http = Typhoeus::Request.get(
'https://wts.zold.io/job?id=' + job,
headers: headers
)
raise "Job #{job} not found on the server" if http.code == 404
raise "Unpredictable response code #{http.code}" unless http.code == 200
if http.body == 'Running'
@log.debug("Job #{job} is still running, #{Zold::Age.new(start)} already...")
sleep 1
next
end
raise http.body unless http.body == 'OK'
@log.debug("Job #{job} completed, in #{Zold::Age.new(start)}")
return http.body
end
end

private
private

def headers
{
'X-Zold-WTS': @key,
'User-Agent': 'zold-ruby-sdk'
}
end
def headers
{
'X-Zold-WTS': @key,
'User-Agent': 'zold-ruby-sdk'
}
end

def job_of(http)
job = http.headers['X-Zold-Job']
raise 'Job ID is not returned, for some reason' if job.nil?
job
end
def job_of(http)
job = http.headers['X-Zold-Job']
raise 'Job ID is not returned, for some reason' if job.nil?
job
end

def clean(http)
error = http.headers['X-Zold-Error']
raise error unless error.nil?
unless http.code == 200 || http.code == 302
@log.debug(http.body)
raise "Unexpected response code #{http.code}"
end
http
def clean(http)
error = http.headers['X-Zold-Error']
raise error unless error.nil?
unless http.code == 200 || http.code == 302
@log.debug(http.body)
raise "Unexpected response code #{http.code}"
end
http
end
end
15 changes: 9 additions & 6 deletions test/zold/test_wts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,35 +29,38 @@
# Copyright:: Copyright (c) 2018-2019 Yegor Bugayenko
# License:: MIT
class TestWTS < Minitest::Test
KEY = '8HNxjYuEFp0....LYOWxsEaC3rQ=='
KEY = '0000000000000000-b416493aefae4ca487c4739050aaec15'

def test_pulls
skip if KEY.length < 50
wts = Zold::WTS.new(KEY, log: Loog::VERBOSE)
job = wts.pull
wts.wait(job)
assert(!job.nil?)
end

def test_finds_transactions
skip if KEY.length < 50
wts = Zold::WTS.new(KEY, log: Loog::VERBOSE)
job = wts.pull
wts.wait(job)
assert_equal(1, wts.find(details: /^for hosting$/).count)
assert_equal(0, wts.find(details: /^for hosting$/).count)
end

def test_retrieves_wallet_id
skip if KEY.length < 50
wts = Zold::WTS.new(KEY, log: Loog::VERBOSE)
assert(!wts.id.nil?)
end

def test_retrieves_balance
skip if KEY.length < 50
wts = Zold::WTS.new(KEY, log: Loog::VERBOSE)
job = wts.pull
wts.wait(job)
assert(!wts.balance.nil?)
end

def test_works_with_fake
wts = Zold::WTS::Fake.new
job = wts.pull
wts.wait(job)
assert(!wts.balance.zero?)
end
end

0 comments on commit 1e542bf

Please sign in to comment.