From 6b4d0a87bf73edfa1fe40868ca915d3152c7ffef Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Mon, 15 Nov 2021 13:50:20 -0500 Subject: [PATCH] Update rubocop And use settings from sgx-jmp --- .rubocop.yml | 146 +++++++++++++++------------ bin/active_tels_on_catapult | 1 + bin/billing_monthly_cronjob | 29 ++++-- bin/correct_duplicate_addrs | 10 +- bin/detect_duplicate_addrs | 3 +- bin/process_pending_btc_transactions | 29 ++++-- config.ru | 85 ++++++++-------- lib/blather_notify.rb | 4 +- lib/electrum.rb | 15 ++- lib/redis_addresses.rb | 13 ++- lib/transaction.rb | 7 +- test/test_electrum.rb | 18 ++-- 12 files changed, 206 insertions(+), 154 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 5f876f4..5330a6a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,113 +1,133 @@ AllCops: - TargetRubyVersion: 2.3 + TargetRubyVersion: 2.5 + NewCops: enable -Metrics/LineLength: - Max: 80 +Metrics/ClassLength: + Exclude: + - test/* + +Metrics/MethodLength: + Exclude: + - test/* Metrics/BlockLength: ExcludedMethods: - route - "on" + Exclude: + - test/* + +Metrics/AbcSize: + Exclude: + - test/* + +Naming/MethodParameterName: + AllowNamesEndingInNumbers: false + AllowedNames: + - m + - e + - r + - q + - s + - k + - v + - ex + - tx + - id + - iq + - ip + - db + +Layout/CaseIndentation: + EnforcedStyle: end -Layout/Tab: +Layout/IndentationStyle: Enabled: false + EnforcedStyle: tabs + IndentationWidth: 4 Layout/IndentationWidth: Width: 1 # one tab -Lint/EndAlignment: - EnforcedStyleAlignWith: variable +Layout/LineLength: + Max: 80 + Exclude: + - Gemfile -Lint/RescueException: - Enabled: false +Layout/SpaceAroundEqualsInParameterDefault: + EnforcedStyle: no_space -Style/AndOr: - Enabled: false +Layout/AccessModifierIndentation: + EnforcedStyle: outdent -Layout/AlignParameters: - Enabled: false +Layout/FirstParameterIndentation: + EnforcedStyle: consistent -Style/BlockDelimiters: +Style/AccessModifierDeclarations: Enabled: false -Layout/CaseIndentation: - EnforcedStyle: end +Style/StringLiterals: + EnforcedStyle: double_quotes -Style/Documentation: +Style/NumericLiterals: Enabled: false -Style/FormatString: - EnforcedStyle: percent - -Layout/LeadingCommentSpace: - Enabled: false +Style/SymbolArray: + EnforcedStyle: brackets -Layout/MultilineMethodCallBraceLayout: - Enabled: false +Style/WordArray: + EnforcedStyle: brackets -Layout/MultilineOperationIndentation: +Style/Documentation: Enabled: false -Style/MultilineTernaryOperator: +Style/DoubleNegation: + EnforcedStyle: allowed_in_returns Enabled: false -Style/Next: +Style/PerlBackrefs: Enabled: false -Style/Not: - Enabled: false +Style/SpecialGlobalVars: + EnforcedStyle: use_perl_names -Style/NumericLiterals: - MinDigits: 20 - Strict: true +Style/RegexpLiteral: + EnforcedStyle: slashes + AllowInnerSlashes: true -Style/NumericPredicate: - Enabled: false +Lint/EndAlignment: + EnforcedStyleAlignWith: variable -Layout/SpaceAroundOperators: +Lint/OutOfRangeRegexpRef: Enabled: false -Layout/SpaceInsideHashLiteralBraces: - EnforcedStyle: no_space - -Style/StringLiterals: - EnforcedStyle: double_quotes - -Style/NegatedIf: +Lint/MissingSuper: Enabled: false -Style/RedundantReturn: - Enabled: false +Style/BlockDelimiters: + EnforcedStyle: semantic + AllowBracesOnProceduralOneLiners: true + ProceduralMethods: + - execute_command Style/MultilineBlockChain: Enabled: false -Layout/SpaceAroundEqualsInParameterDefault: - EnforcedStyle: no_space - -Layout/IndentArray: +Layout/FirstArgumentIndentation: EnforcedStyle: consistent -Style/SymbolArray: - EnforcedStyle: brackets - -Layout/FirstParameterIndentation: +Layout/FirstArrayElementIndentation: EnforcedStyle: consistent -Style/Lambda: - EnforcedStyle: lambda - -Layout/AccessModifierIndentation: - EnforcedStyle: outdent +Style/FormatString: + EnforcedStyle: percent Style/FormatStringToken: - Enabled: false + EnforcedStyle: unannotated -Style/WordArray: - EnforcedStyle: brackets - -Lint/UriEscapeUnescape: - Enabled: false +Style/FrozenStringLiteralComment: + Exclude: + - forms/* -Style/RescueModifier: +Naming/AccessorMethodName: Enabled: false diff --git a/bin/active_tels_on_catapult b/bin/active_tels_on_catapult index 35ff019..50caefe 100755 --- a/bin/active_tels_on_catapult +++ b/bin/active_tels_on_catapult @@ -37,6 +37,7 @@ DB.exec( ).each do |row| cid = row["customer_id"] next if REDIS.exists?("catapult_cred-customer_#{cid}@jmp.chat") + jid = REDIS.get("jmp_customer_jid-#{cid}") tel = REDIS.lindex("catapult_cred-#{jid}", 3) location = get_location(tel) diff --git a/bin/billing_monthly_cronjob b/bin/billing_monthly_cronjob index f01c6fa..c6b6ff5 100755 --- a/bin/billing_monthly_cronjob +++ b/bin/billing_monthly_cronjob @@ -71,7 +71,7 @@ end stats = Stats.new( not_renewed: 0, renewed: 0, - revenue: BigDecimal.new(0) + revenue: BigDecimal(0) ) class Plan @@ -85,7 +85,7 @@ class Plan end def price - BigDecimal.new(@plan["monthly_price"].to_i) * 0.0001 + BigDecimal(@plan["monthly_price"].to_i) * 0.0001 end def bill_customer(db, customer_id) @@ -147,18 +147,29 @@ class ExpiredCustomer def try_renew(_, stats) stats.add(:not_renewed, 1) - if REDIS.exists?("jmp_customer_auto_top_up_amount-#{customer_id}") && \ - @row["expires_at"] > LAST_WEEK - @db.exec_params("SELECT pg_notify('low_balance', $1)", [customer_id]) + topup = "jmp_customer_auto_top_up_amount-#{customer_id}" + if REDIS.exists?(topup) && @row["expires_at"] > LAST_WEEK + @db.exec_params( + "SELECT pg_notify('low_balance', $1)", + [customer_id] + ) else - return if REDIS.exists?("jmp_customer_low_balance-#{customer_id}") - REDIS.set("jmp_customer_low_balance-#{customer_id}", Time.now, ex: ONE_WEEK) - send_notification + notify_if_needed end end protected + def notify_if_needed + return if REDIS.exists?("jmp_customer_low_balance-#{customer_id}") + + REDIS.set( + "jmp_customer_low_balance-#{customer_id}", + Time.now, ex: ONE_WEEK + ) + send_notification + end + def jid REDIS.get("jmp_customer_jid-#{customer_id}") end @@ -175,12 +186,14 @@ class ExpiredCustomer def btc_addresses_for_notification return if btc_addresses.empty? + "\nYou can buy credit by sending any amount of Bitcoin to one of "\ "these addresses:\n#{btc_addresses.join("\n")}" end def send_notification raise "No JID for #{customer_id}, cannot notify" unless jid + BlatherNotify.say( CONFIG[:notify_using][:target].call(jid), CONFIG[:notify_using][:body].call( diff --git a/bin/correct_duplicate_addrs b/bin/correct_duplicate_addrs index 4bb8bfa..225cad9 100755 --- a/bin/correct_duplicate_addrs +++ b/bin/correct_duplicate_addrs @@ -12,14 +12,14 @@ redis = Redis.new customer_id = ENV["DEFAULT_CUSTOMER_ID"] unless customer_id - puts "The env-var DEFAULT_CUSTOMER_ID must be set to the ID of the customer "\ - "who will receive the duplicated addrs, preferably a support customer or "\ - "something linked to notifications when stray money is sent to these "\ - "addresses" + puts "The env-var DEFAULT_CUSTOMER_ID must be set to the ID " \ + "of the customer who will receive the duplicated addrs, preferably " \ + "a support customer or something linked to notifications when " \ + "stray money is sent to these addresses" exit 1 end -STDIN.each_line do |line| +$stdin.each_line do |line| match = line.match(/^(\w+) is used by the following \d+ keys: (.*)/) unless match puts "The following line can't be understood and is being ignored" diff --git a/bin/detect_duplicate_addrs b/bin/detect_duplicate_addrs index 4f47d34..bcfdb6a 100755 --- a/bin/detect_duplicate_addrs +++ b/bin/detect_duplicate_addrs @@ -8,6 +8,7 @@ redis = Redis.new get_addresses_with_users(redis).each do |addr, keys| if keys.length > 1 - puts "#{addr} is used by the following #{keys.length} keys: #{keys.join(' ')}" + puts "#{addr} is used by the following " \ + "#{keys.length} keys: #{keys.join(' ')}" end end diff --git a/bin/process_pending_btc_transactions b/bin/process_pending_btc_transactions index 60df892..e38183b 100755 --- a/bin/process_pending_btc_transactions +++ b/bin/process_pending_btc_transactions @@ -48,7 +48,7 @@ unless (cad_to_usd = REDIS.get("cad_to_usd")&.to_f) oxr.app_id = CONFIG.fetch(:oxr_app_id) oxr.update_rates cad_to_usd = oxr.get_rate("CAD", "USD") - REDIS.set("cad_to_usd", cad_to_usd, ex: 60*60) + REDIS.set("cad_to_usd", cad_to_usd, ex: 60 * 60) end canadianbitcoins = Nokogiri::HTML.parse( @@ -59,7 +59,7 @@ bitcoin_row = canadianbitcoins.at("#ticker > table > tbody > tr") raise "Bitcoin row has moved" unless bitcoin_row.at("td").text == "Bitcoin" btc_sell_price = {} -btc_sell_price[:CAD] = BigDecimal.new( +btc_sell_price[:CAD] = BigDecimal( bitcoin_row.at("td:nth-of-type(3)").text.match(/^\$(\d+\.\d+)/)[1] ) btc_sell_price[:USD] = btc_sell_price[:CAD] * cad_to_usd @@ -82,6 +82,7 @@ class Plan def self.from_name(customer, plan_name, klass: Plan) return unless plan_name + plan = CONFIG[:plans].find { |p| p[:name] == plan_name } klass.new(customer, plan) if plan end @@ -100,7 +101,8 @@ class Plan end def bonus_for(fiat_amount) - return BigDecimal.new(0) if fiat_amount <= 15 + return BigDecimal(0) if fiat_amount <= 15 + fiat_amount * case fiat_amount when (15..29.99) 0.01 @@ -112,7 +114,7 @@ class Plan end def price - BigDecimal.new(@plan[:monthly_price].to_i) * 0.0001 + BigDecimal(@plan[:monthly_price].to_i) * 0.0001 end def insert(start:, expire:) @@ -134,7 +136,7 @@ class Plan end def activation_amount - camnt = BigDecimal.new(CONFIG[:activation_amount].to_i) * 0.0001 + camnt = BigDecimal(CONFIG[:activation_amount].to_i) * 0.0001 [camnt, price].max end @@ -159,6 +161,7 @@ class Plan -price, "Activate pending plan" ) + insert(start: Date.today, expire: @go_until) REDIS.del("pending_plan_for-#{@customer.id}") notify_approved @@ -186,6 +189,7 @@ class Customer def notify(body) jid = REDIS.get("jmp_customer_jid-#{@customer_id}") raise "No JID for #{customer_id}" unless jid + BlatherNotify.say( CONFIG[:notify_using][:target].call(jid), CONFIG[:notify_using][:body].call(jid, body) @@ -204,12 +208,13 @@ class Customer result = DB.exec_params(<<-SQL, [@customer_id]).first&.[]("balance") SELECT balance FROM balances WHERE customer_id=$1 SQL - result || BigDecimal.new(0) + result || BigDecimal(0) end def add_btc_credit(txid, btc_amount, fiat_amount) return unless add_transaction(txid, fiat_amount, "Bitcoin payment") - if (bonus = plan.bonus_for(fiat_amount)) > 0 + + if (bonus = plan.bonus_for(fiat_amount)).positive? add_transaction("bonus_for_#{txid}", bonus, "Bitcoin payment bonus") end notify_btc_credit(txid, btc_amount, fiat_amount, bonus) @@ -220,13 +225,14 @@ class Customer notify([ "Your Bitcoin transaction of #{btc_amount.to_s('F')} BTC ", "has been added as $#{'%.4f' % fiat_amount} (#{plan.currency}) ", - ("+ $#{'%.4f' % bonus} bonus " if bonus > 0), + ("+ $#{'%.4f' % bonus} bonus " if bonus.positive?), "to your account.\n(txhash: #{tx_hash})" ].compact.join) end def add_transaction(id, amount, note) - DB.exec_params(<<-SQL, [@customer_id, id, amount, note]).cmd_tuples > 0 + args = [@customer_id, id, amount, note] + DB.exec_params(<<-SQL, args).cmd_tuples.positive? INSERT INTO transactions (customer_id, transaction_id, amount, note) VALUES @@ -236,10 +242,11 @@ class Customer end end -done = REDIS.hgetall("pending_btc_transactions").map do |(txid, customer_id)| +done = REDIS.hgetall("pending_btc_transactions").map { |(txid, customer_id)| tx_hash, address = txid.split("/", 2) transaction = ELECTRUM.gettransaction(tx_hash) next unless transaction.confirmations >= CONFIG[:required_confirmations] + btc = transaction.amount_for(address) if btc <= 0 # This is a send, not a receive, do not record it @@ -258,6 +265,6 @@ done = REDIS.hgetall("pending_btc_transactions").map do |(txid, customer_id)| warn "No plan for #{customer_id} cannot save #{txid}" end end -end +} puts done.compact.join("\n") diff --git a/config.ru b/config.ru index 53f738d..da5b85f 100644 --- a/config.ru +++ b/config.ru @@ -4,6 +4,7 @@ require "braintree" require "date" require "delegate" require "dhall" +require "forwardable" require "pg" require "redis" require "roda" @@ -44,7 +45,7 @@ class Plan end def price(months=1) - (BigDecimal.new(@plan[:monthly_price].to_i) * months) / 10000 + (BigDecimal(@plan[:monthly_price].to_i) * months) / 10000 end def currency @@ -56,7 +57,7 @@ class Plan end def self.active?(customer_id) - DB.exec_params(<<~SQL, [customer_id]).first&.[]("count").to_i > 0 + DB.exec_params(<<~SQL, [customer_id]).first&.[]("count").to_i.positive? SELECT count(1) AS count FROM customer_plans WHERE customer_id=$1 AND expires_at > NOW() SQL @@ -139,6 +140,7 @@ class CreditCardGateway result = @gateway.customer.create raise "Braintree customer create failed" unless result.success? + @customer_id = result.customer.id save_customer_id! end @@ -183,6 +185,7 @@ class CreditCardGateway def sale(ip:, **kwargs) return nil unless decline_guard(ip) + tx = Transaction.sale(@gateway, **kwargs) return tx if tx @@ -200,7 +203,7 @@ class CreditCardGateway amount: plan.price(5), payment_method_nonce: nonce, merchant_account_id: plan.merchant_account, - options: {submit_for_settlement: true} + options: { submit_for_settlement: true } )&.insert && plan.bill_plan(@customer_id) end @@ -219,15 +222,18 @@ class UnknownTransactions def self.from(customer_id, address, tx_hashes) self.for( customer_id, - fetch_rows_for(address, tx_hashes).map { |row| row["transaction_id"] } + fetch_rows_for(address, tx_hashes).map { |row| + row["transaction_id"] + } ) end def self.fetch_rows_for(address, tx_hashes) - values = tx_hashes.map do |tx_hash| + values = tx_hashes.map { |tx_hash| "('#{DB.escape_string(tx_hash)}/#{DB.escape_string(address)}')" - end + } return [] if values.empty? + DB.exec_params(<<-SQL) SELECT transaction_id FROM (VALUES #{values.join(',')}) AS t(transaction_id) @@ -257,24 +263,25 @@ class UnknownTransactions end end -# This class must contain all of the routes because of how the DSL works -# rubocop:disable Metrics/ClassLength class JmpPay < Roda SENTRY_DSN = ENV["SENTRY_DSN"] && URI(ENV["SENTRY_DSN"]) plugin :render, engine: "slim" plugin :common_logger, $stdout + extend Forwardable + def_delegators :request, :params + def redis_key_btc_addresses - "jmp_customer_btc_addresses-#{request.params['customer_id']}" + "jmp_customer_btc_addresses-#{params['customer_id']}" end def verify_address_customer_id(r) - return if REDIS.sismember(redis_key_btc_addresses, request.params["address"]) + return if REDIS.sismember(redis_key_btc_addresses, params["address"]) warn "Address and customer_id do not match" r.halt([ 403, - {"Content-Type" => "text/plain"}, + { "Content-Type" => "text/plain" }, "Address and customer_id do not match" ]) end @@ -284,10 +291,10 @@ class JmpPay < Roda verify_address_customer_id(r) UnknownTransactions.from( - request.params["customer_id"], - request.params["address"], + params["customer_id"], + params["address"], ELECTRUM - .getaddresshistory(request.params["address"]) + .getaddresshistory(params["address"]) .map { |item| item["tx_hash"] } ).enqueue! @@ -295,19 +302,17 @@ class JmpPay < Roda end r.on :jid do |jid| - Sentry.set_user(id: request.params["customer_id"], jid: jid) + Sentry.set_user(id: params["customer_id"], jid: jid) - gateway = CreditCardGateway.new( - jid, - request.params["customer_id"] - ) + gateway = CreditCardGateway.new(jid, params["customer_id"]) + topup = "jmp_customer_auto_top_up_amount-#{gateway.customer_id}" r.on "activate" do Sentry.configure_scope do |scope| scope.set_transaction_name("activate") scope.set_context( "activate", - plan_name: request.params["plan_name"] + plan_name: params["plan_name"] ) end @@ -324,28 +329,25 @@ class JmpPay < Roda r.get do if Plan.active?(gateway.customer_id) - r.redirect request.params["return_to"], 303 + r.redirect params["return_to"], 303 else render.call end end r.post do - result = DB.transaction do + result = DB.transaction { Plan.active?(gateway.customer_id) || gateway.buy_plan( - request.params["plan_name"], - request.params["braintree_nonce"], + params["plan_name"], + params["braintree_nonce"], request.ip ) - end - if request.params["auto_top_up_amount"].to_i >= 15 - REDIS.set( - "jmp_customer_auto_top_up_amount-#{gateway.customer_id}", - request.params["auto_top_up_amount"].to_i - ) + } + if params["auto_top_up_amount"].to_i >= 15 + REDIS.set(topup, params["auto_top_up_amount"].to_i) end if result - r.redirect request.params["return_to"], 303 + r.redirect params["return_to"], 303 else render.call(error: true) end @@ -359,24 +361,18 @@ class JmpPay < Roda locals: { token: gateway.client_token, customer_id: gateway.customer_id, - auto_top_up: REDIS.get( - "jmp_customer_auto_top_up_amount-#{gateway.customer_id}" - ) || (gateway.payment_methods? ? "" : "15") + auto_top_up: REDIS.get(topup) || + (gateway.payment_methods? ? "" : "15") } ) end r.post do - gateway.default_payment_method = request.params["braintree_nonce"] - if request.params["auto_top_up_amount"].to_i >= 15 - REDIS.set( - "jmp_customer_auto_top_up_amount-#{gateway.customer_id}", - request.params["auto_top_up_amount"].to_i - ) - elsif request.params["auto_top_up_amount"].to_i == 0 - REDIS.del( - "jmp_customer_auto_top_up_amount-#{gateway.customer_id}" - ) + gateway.default_payment_method = params["braintree_nonce"] + if params["auto_top_up_amount"].to_i >= 15 + REDIS.set(topup, params["auto_top_up_amount"].to_i) + elsif params["auto_top_up_amount"].to_i.zero? + REDIS.del(topup) end "OK" end @@ -384,6 +380,5 @@ class JmpPay < Roda end end end -# rubocop:enable Metrics/ClassLength run JmpPay.freeze.app diff --git a/lib/blather_notify.rb b/lib/blather_notify.rb index 9024a73..7ecb9de 100644 --- a/lib/blather_notify.rb +++ b/lib/blather_notify.rb @@ -16,11 +16,11 @@ module BlatherNotify EM.error_handler(&method(:panic)) - @thread = Thread.new do + @thread = Thread.new { EM.run do client.run end - end + } Timeout.timeout(30) { @ready.pop } at_exit { wait_then_exit } diff --git a/lib/electrum.rb b/lib/electrum.rb index f4489eb..6ef56e9 100644 --- a/lib/electrum.rb +++ b/lib/electrum.rb @@ -47,7 +47,7 @@ class Electrum end def amount_for(*addresses) - BigDecimal.new( + BigDecimal( @tx["outputs"] .select { |o| addresses.include?(o["address"]) } .map { |o| o["value_sats"] } @@ -67,16 +67,23 @@ protected ).body) end - def post_json(data) - req = Net::HTTP::Post.new(@rpc_uri, "Content-Type" => "application/json") + def post_json_req(data) + req = Net::HTTP::Post.new( + @rpc_uri, + "Content-Type" => "application/json" + ) req.basic_auth(@rpc_username, @rpc_password) req.body = data.to_json + req + end + + def post_json(data) Net::HTTP.start( @rpc_uri.hostname, @rpc_uri.port, use_ssl: @rpc_uri.scheme == "https" ) do |http| - http.request(req) + http.request(post_json_req(data)) end end end diff --git a/lib/redis_addresses.rb b/lib/redis_addresses.rb index 1566440..17ba12e 100644 --- a/lib/redis_addresses.rb +++ b/lib/redis_addresses.rb @@ -25,12 +25,15 @@ end module RedisBtcAddresses def self.each_user(redis) - # I picked 1000 because it made a relatively trivial case take 15 seconds - # instead of forever. + # I picked 1000 because it made a relatively trivial case take + # 15 seconds instead of forever. # Basically it's "how long does each command take" - # The lower it is (default is 10), it will go back and forth to the client a - # ton - redis.scan_each(match: "jmp_customer_btc_addresses-*", count: 1000) do |key| + # The lower it is (default is 10), it will go back and forth + # to the client a ton + redis.scan_each( + match: "jmp_customer_btc_addresses-*", + count: 1000 + ) do |key| yield key, redis.smembers(key) end end diff --git a/lib/transaction.rb b/lib/transaction.rb index 1c4eb29..f8762d8 100644 --- a/lib/transaction.rb +++ b/lib/transaction.rb @@ -29,6 +29,7 @@ class Transaction def bonus return BigDecimal(0) if amount <= 15 + amount * case amount when (15..29.99) @@ -59,7 +60,11 @@ protected def insert_bonus return if bonus <= 0 - params = [@customer_id, "bonus_for_#{@transaction_id}", @created_at, bonus] + + params = [ + @customer_id, "bonus_for_#{@transaction_id}", + @created_at, bonus + ] DB.exec(<<~SQL, params) INSERT INTO transactions (customer_id, transaction_id, created_at, amount, note) diff --git a/test/test_electrum.rb b/test/test_electrum.rb index a77d05b..d444f9e 100644 --- a/test/test_electrum.rb +++ b/test/test_electrum.rb @@ -16,7 +16,7 @@ class ElectrumTest < Minitest::Test def stub_rpc(method, params) stub_request(:post, RPC_URI).with( - headers: {"Content-Type" => "application/json"}, + headers: { "Content-Type" => "application/json" }, basic_auth: ["username", "password"], body: hash_including( method: method, @@ -29,7 +29,7 @@ class ElectrumTest < Minitest::Test def getaddresshistory(address) req = stub_rpc("getaddresshistory", address: address) - .to_return(body: {result: "result"}.to_json) + .to_return(body: { result: "result" }.to_json) assert_equal "result", @electrum.getaddresshistory(address) assert_requested(req) end @@ -38,7 +38,7 @@ class ElectrumTest < Minitest::Test def get_tx_status(tx_hash) req = stub_rpc("get_tx_status", txid: tx_hash) - .to_return(body: {result: "result"}.to_json) + .to_return(body: { result: "result" }.to_json) assert_equal "result", @electrum.get_tx_status(tx_hash) assert_requested(req) end @@ -47,10 +47,10 @@ class ElectrumTest < Minitest::Test def gettransaction(tx_hash, dummy_tx) req1 = stub_rpc("gettransaction", txid: tx_hash) - .to_return(body: {result: dummy_tx}.to_json) + .to_return(body: { result: dummy_tx }.to_json) req2 = stub_rpc("deserialize", [dummy_tx]) - .to_return(body: {result: {outputs: []}}.to_json) + .to_return(body: { result: { outputs: [] } }.to_json) assert_kind_of Electrum::Transaction, @electrum.gettransaction(tx_hash) assert_requested(req1) assert_requested(req2) @@ -73,7 +73,7 @@ class ElectrumTest < Minitest::Test electrum_mock, tx = transaction electrum_mock.expect( :get_tx_status, - {"confirmations" => 1234}, + { "confirmations" => 1234 }, ["txhash"] ) assert_equal 1234, tx.confirmations @@ -85,17 +85,17 @@ class ElectrumTest < Minitest::Test end def test_amount_for_address_not_present - _, tx = transaction([{"address" => "address", "value_sats" => 1}]) + _, tx = transaction([{ "address" => "address", "value_sats" => 1 }]) assert_equal 0, tx.amount_for("other_address") end def test_amount_for_address_present - _, tx = transaction([{"address" => "address", "value_sats" => 1}]) + _, tx = transaction([{ "address" => "address", "value_sats" => 1 }]) assert_equal 0.00000001, tx.amount_for("address") end def test_amount_for_one_of_address_present - _, tx = transaction([{"address" => "address", "value_sats" => 1}]) + _, tx = transaction([{ "address" => "address", "value_sats" => 1 }]) assert_equal 0.00000001, tx.amount_for("boop", "address", "lol") end end -- 2.38.5