From 1e542bf21609a835c8a5663faff09b6a110d0288 Mon Sep 17 00:00:00 2001 From: Yegor Bugayenko Date: Fri, 5 Jul 2019 23:08:01 +0300 Subject: [PATCH] #6 real tests --- .rubocop.yml | 2 + lib/zold/wts.rb | 291 +++++++++++++++++++++++------------------- test/zold/test_wts.rb | 15 ++- 3 files changed, 171 insertions(+), 137 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index d8d1401..888c362 100755 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -6,6 +6,8 @@ Layout/EmptyLineAfterGuardClause: Enabled: false Layout/EndOfLine: EnforcedStyle: lf +Style/ClassAndModuleChildren: + Enabled: false Metrics/AbcSize: Max: 45 Metrics/BlockLength: diff --git a/lib/zold/wts.rb b/lib/zold/wts.rb index 8d4d3ff..e3fc37e 100644 --- a/lib/zold/wts.rb +++ b/lib/zold/wts.rb @@ -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 key 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 find() or balance() requests. - # - # The method returns the job ID, which you should wait for completion - # using the method wait(). +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 keygap is a string you get - # when you confirm the account. The bnf is the name of the - # GitHub account, the wallet ID or the invoice (up to you). The - # amount is the amount in ZLD, e.g. "19.99". The details - # is the text to add to the transaction. - # - # The method returns the job ID, which you should wait for completion - # using the method wait(). - 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 key 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 find() or balance() requests. + # + # The method returns the job ID, which you should wait for completion + # using the method wait(). + 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 keygap is a string you get + # when you confirm the account. The bnf is the name of the + # GitHub account, the wallet ID or the invoice (up to you). The + # amount is the amount in ZLD, e.g. "19.99". The details + # is the text to add to the transaction. + # + # The method returns the job ID, which you should wait for completion + # using the method wait(). + 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 diff --git a/test/zold/test_wts.rb b/test/zold/test_wts.rb index 460f37b..7d87348 100644 --- a/test/zold/test_wts.rb +++ b/test/zold/test_wts.rb @@ -29,10 +29,9 @@ # 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) @@ -40,24 +39,28 @@ def test_pulls 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