Module: StripeMock::RequestHandlers::Helpers
- Included in:
- Instance
- Defined in:
- lib/stripe_mock/request_handlers/helpers/card_helpers.rb,
lib/stripe_mock/request_handlers/helpers/token_helpers.rb,
lib/stripe_mock/request_handlers/helpers/charge_helpers.rb,
lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb,
lib/stripe_mock/request_handlers/helpers/search_helpers.rb,
lib/stripe_mock/request_handlers/helpers/bank_account_helpers.rb,
lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb,
lib/stripe_mock/request_handlers/helpers/external_account_helpers.rb
Constant Summary collapse
- QUERYSTRING_PATTERN =
Only supports exact matches on a single field, e.g.
-
‘amount:100’
-
‘email:“[email protected]”’
-
‘name:“Foo Bar”’
-
‘metadata:“bar”’
-
/\A(?<field>[\w\.]+)(\[['"](?<metadata_key>[^'"]*)['"]\])?:['"]?(?<value>[^'"]*)['"]?\z/
Instance Method Summary collapse
- #add_card_to(type, type_id, params, objects) ⇒ Object
- #add_card_to_object(type, card, object, replace_current = false) ⇒ Object
- #add_coupon_to_object(object, coupon) ⇒ Object
- #add_external_account_to(type, type_id, params, objects) ⇒ Object
- #add_external_account_to_object(type, source, object, replace_current = false) ⇒ Object
- #add_refund_to_charge(refund, charge) ⇒ Object
- #add_source_to(type, type_id, params, objects) ⇒ Object
- #add_source_to_object(type, source, object, replace_current = false) ⇒ Object
- #add_subscription_to_customer(cus, sub) ⇒ Object
- #bank_from_params(attrs_or_token) ⇒ Object
- #card_from_params(attrs_or_token) ⇒ Object
- #custom_subscription_params(plans, cus, options = {}) ⇒ Object
- #delete_card_from(type, type_id, card_id, objects) ⇒ Object
- #delete_coupon_from_object(object) ⇒ Object
- #delete_subscription_from_customer(cus, subscription) ⇒ Object
- #exact_match?(actual:, expected:) ⇒ Boolean
- #field_value(resource, field:) ⇒ Object
- #filter_by_timestamp(subscriptions, field:, value:) ⇒ Object
- #generate_bank_token(bank_params = {}) ⇒ Object
- #generate_card_token(card_params = {}) ⇒ Object
- #get_bank_by_token(token) ⇒ Object
- #get_card(object, card_id, class_name = 'Customer') ⇒ Object
- #get_card_by_token(token) ⇒ Object
- #get_card_or_bank_by_token(token) ⇒ Object
- #get_customer_subscription(customer, sub_id) ⇒ Object
-
#get_ending_time(start_time, plan, intervals = 1) ⇒ Object
‘intervals` is set to 1 when calculating current_period_end from current_period_start & plan `intervals` is set to 2 when calculating Stripe::Invoice.upcoming end from current_period_start & plan.
- #resolve_subscription_changes(subscription, plans, customer, options = {}) ⇒ Object
- #retrieve_object_cards(type, type_id, objects) ⇒ Object
- #search_results(all_values, querystring, fields: [], resource_name:) ⇒ Object
- #total_items_amount(items) ⇒ Object
- #validate_card(card) ⇒ Object
- #verify_bank_account(object, bank_account_id, class_name = 'Customer') ⇒ Object
- #verify_trial_end(trial_end) ⇒ Object
Instance Method Details
#add_card_to(type, type_id, params, objects) ⇒ Object
104 105 106 107 108 109 |
# File 'lib/stripe_mock/request_handlers/helpers/card_helpers.rb', line 104 def add_card_to(type, type_id, params, objects) resource = assert_existence type, type_id, objects[type_id] card = card_from_params(params[:card] || params[:source] || params[:external_accounts]) add_card_to_object(type, card, resource) end |
#add_card_to_object(type, card, object, replace_current = false) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/stripe_mock/request_handlers/helpers/card_helpers.rb', line 37 def add_card_to_object(type, card, object, replace_current=false) card[type] = object[:id] cards_or_sources = object[:cards] || object[:sources] || object[:external_accounts] is_customer = object.has_key?(:sources) if replace_current && cards_or_sources[:data] cards_or_sources[:data].delete_if {|card| card[:id] == object[:default_card]} object[:default_card] = card[:id] unless is_customer object[:default_source] = card[:id] if is_customer cards_or_sources[:data] = [card] else cards_or_sources[:total_count] = (cards_or_sources[:total_count] || 0) + 1 (cards_or_sources[:data] ||= []) << card end object[:default_card] = card[:id] if !is_customer && object[:default_card].nil? object[:default_source] = card[:id] if is_customer && object[:default_source].nil? card end |
#add_coupon_to_object(object, coupon) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 |
# File 'lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb', line 4 def add_coupon_to_object(object, coupon) discount_attrs = {}.tap do |attrs| attrs[object[:object]] = object[:id] attrs[:coupon] = coupon attrs[:start] = Time.now.to_i attrs[:end] = (DateTime.now >> coupon[:duration_in_months].to_i).to_time.to_i if coupon[:duration] == 'repeating' attrs[:id] = new_id("di") end object[:discount] = Stripe::Discount.construct_from(discount_attrs) object end |
#add_external_account_to(type, type_id, params, objects) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/stripe_mock/request_handlers/helpers/external_account_helpers.rb', line 5 def add_external_account_to(type, type_id, params, objects) resource = assert_existence type, type_id, objects[type_id] source = if params[:card] card_from_params(params[:card]) elsif params[:bank_account] bank_from_params(params[:bank_account]) else begin get_card_by_token(params[:external_account]) rescue Stripe::InvalidRequestError bank_from_params(params[:external_account]) end end add_external_account_to_object(type, source, resource) end |
#add_external_account_to_object(type, source, object, replace_current = false) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/stripe_mock/request_handlers/helpers/external_account_helpers.rb', line 23 def add_external_account_to_object(type, source, object, replace_current=false) source[type] = object[:id] accounts = object[:external_accounts] if replace_current && accounts[:data] accounts[:data].delete_if {|source| source[:id] == object[:default_source]} object[:default_source] = source[:id] accounts[:data] = [source] else accounts[:total_count] = (accounts[:total_count] || 0) + 1 (accounts[:data] ||= []) << source end object[:default_source] = source[:id] if object[:default_source].nil? source end |
#add_refund_to_charge(refund, charge) ⇒ Object
5 6 7 8 9 10 11 12 |
# File 'lib/stripe_mock/request_handlers/helpers/charge_helpers.rb', line 5 def add_refund_to_charge(refund, charge) refunds = charge[:refunds] refunds[:data] << refund refunds[:total_count] = refunds[:data].count charge[:amount_refunded] = refunds[:data].reduce(0) {|sum, r| sum + r[:amount].to_i } charge[:refunded] = true end |
#add_source_to(type, type_id, params, objects) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/stripe_mock/request_handlers/helpers/card_helpers.rb', line 85 def add_source_to(type, type_id, params, objects) resource = assert_existence type, type_id, objects[type_id] source = if params[:card] card_from_params(params[:card]) elsif params[:bank_account] get_bank_by_token(params[:bank_account]) else begin get_card_by_token(params[:source]) rescue Stripe::InvalidRequestError get_bank_by_token(params[:source]) end end source[:metadata].merge!(params[:metadata]) if params[:metadata] add_source_to_object(type, source, resource) end |
#add_source_to_object(type, source, object, replace_current = false) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/stripe_mock/request_handlers/helpers/card_helpers.rb', line 20 def add_source_to_object(type, source, object, replace_current=false) source[type] = object[:id] sources = object[:sources] if replace_current && sources[:data] sources[:data].delete_if {|source| source[:id] == object[:default_source]} object[:default_source] = source[:id] sources[:data] = [source] else sources[:total_count] = (sources[:total_count] || 0) + 1 (sources[:data] ||= []) << source end object[:default_source] = source[:id] if object[:default_source].nil? source end |
#add_subscription_to_customer(cus, sub) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb', line 62 def add_subscription_to_customer(cus, sub) if sub[:trial_end].nil? || sub[:trial_end] == "now" id = new_id('ch') charges[id] = Data.mock_charge( :id => id, :customer => cus[:id], :amount => (sub[:plan] ? sub[:plan][:amount] : total_items_amount(sub[:items][:data])) ) end if cus[:currency].nil? cus[:currency] = sub[:items][:data][0][:plan][:currency] elsif cus[:currency] != sub[:items][:data][0][:plan][:currency] raise Stripe::InvalidRequestError.new( "Can't combine currencies on a single customer. This customer has had a subscription, coupon, or invoice item with currency #{cus[:currency]}", 'currency', http_status: 400) end cus[:subscriptions][:total_count] = (cus[:subscriptions][:total_count] || 0) + 1 cus[:subscriptions][:data].unshift sub end |
#bank_from_params(attrs_or_token) ⇒ Object
40 41 42 43 44 45 |
# File 'lib/stripe_mock/request_handlers/helpers/external_account_helpers.rb', line 40 def bank_from_params(attrs_or_token) if attrs_or_token.is_a? Hash attrs_or_token = generate_bank_token(attrs_or_token) end get_bank_by_token(attrs_or_token) end |
#card_from_params(attrs_or_token) ⇒ Object
118 119 120 121 122 123 124 |
# File 'lib/stripe_mock/request_handlers/helpers/card_helpers.rb', line 118 def card_from_params(attrs_or_token) if attrs_or_token.is_a? Hash attrs_or_token = generate_card_token(attrs_or_token) end card = get_card_by_token(attrs_or_token) validate_card(card) end |
#custom_subscription_params(plans, cus, options = {}) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb', line 30 def custom_subscription_params(plans, cus, = {}) verify_trial_end([:trial_end]) if [:trial_end] plan = plans.first if plans.size == 1 now = Time.now.utc.to_i created_time = [:created] || now start_time = [:current_period_start] || now params = { customer: cus[:id], current_period_start: start_time, created: created_time } params.merge!({ :plan => (plans.size == 1 ? plans.first : nil) }) keys_to_merge = /application_fee_percent|quantity|metadata|tax_percent|billing|days_until_due|default_tax_rates|pending_invoice_item_interval|default_payment_method|collection_method/ params.merge! .select {|k,v| k =~ keys_to_merge} if [:cancel_at_period_end] == true params.merge!(cancel_at_period_end: true, canceled_at: now) elsif [:cancel_at_period_end] == false params.merge!(cancel_at_period_end: false, canceled_at: nil) end # TODO: Implement coupon logic if (((plan && plan[:trial_period_days]) || 0) == 0 && [:trial_end].nil?) || [:trial_end] == "now" end_time = [:billing_cycle_anchor] || get_ending_time(start_time, plan) params.merge!({status: 'active', current_period_end: end_time, trial_start: nil, trial_end: nil, billing_cycle_anchor: [:billing_cycle_anchor] || created_time}) else end_time = [:trial_end] || (Time.now.utc.to_i + plan[:trial_period_days]*86400) params.merge!({status: 'trialing', current_period_end: end_time, trial_start: start_time, trial_end: end_time, billing_cycle_anchor: [:billing_cycle_anchor] || created_time}) end params end |
#delete_card_from(type, type_id, card_id, objects) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/stripe_mock/request_handlers/helpers/card_helpers.rb', line 66 def delete_card_from(type, type_id, card_id, objects) resource = assert_existence type, type_id, objects[type_id] assert_existence :card, card_id, get_card(resource, card_id) card = { id: card_id, deleted: true } cards_or_sources = resource[:cards] || resource[:sources] || resource[:external_accounts] cards_or_sources[:data].reject!{|cc| cc[:id] == card[:id] } is_customer = resource.has_key?(:sources) new_default = cards_or_sources[:data].count > 0 ? cards_or_sources[:data].first[:id] : nil resource[:default_card] = new_default unless is_customer resource[:sources][:total_count] = cards_or_sources[:data].count if is_customer resource[:default_source] = new_default if is_customer card end |
#delete_coupon_from_object(object) ⇒ Object
17 18 19 20 |
# File 'lib/stripe_mock/request_handlers/helpers/coupon_helpers.rb', line 17 def delete_coupon_from_object(object) object[:discount] = nil object end |
#delete_subscription_from_customer(cus, subscription) ⇒ Object
81 82 83 84 85 86 |
# File 'lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb', line 81 def delete_subscription_from_customer(cus, subscription) cus[:subscriptions][:data].reject!{|sub| sub[:id] == subscription[:id] } cus[:subscriptions][:total_count] -=1 end |
#exact_match?(actual:, expected:) ⇒ Boolean
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/stripe_mock/request_handlers/helpers/search_helpers.rb', line 42 def exact_match?(actual:, expected:) # allow comparisons of integers if actual.respond_to?(:to_i) && actual.to_i == actual expected = expected.to_i end # allow comparisons of boolean case expected when "true" expected = true when "false" expected = false end actual == expected end |
#field_value(resource, field:) ⇒ Object
58 59 60 61 62 63 64 |
# File 'lib/stripe_mock/request_handlers/helpers/search_helpers.rb', line 58 def field_value(resource, field:) value = resource field.split('.').each do |segment| value = value[segment.to_sym] end value end |
#filter_by_timestamp(subscriptions, field:, value:) ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb', line 129 def (subscriptions, field:, value:) if value.is_a?(Hash) operator_mapping = { gt: :>, gte: :>=, lt: :<, lte: :<= } subscriptions.filter do |sub| sub[field].public_send(operator_mapping[value.keys[0]], value.values[0]) end else subscriptions.filter do |sub| sub[field] == value end end end |
#generate_bank_token(bank_params = {}) ⇒ Object
5 6 7 8 9 10 |
# File 'lib/stripe_mock/request_handlers/helpers/token_helpers.rb', line 5 def generate_bank_token(bank_params = {}) token = new_id 'btok' bank_params[:id] = new_id 'bank_account' @bank_tokens[token] = Data.mock_bank_account bank_params token end |
#generate_card_token(card_params = {}) ⇒ Object
12 13 14 15 16 17 |
# File 'lib/stripe_mock/request_handlers/helpers/token_helpers.rb', line 12 def generate_card_token(card_params = {}) token = new_id 'tok' card_params[:id] = new_id 'cc' @card_tokens[token] = Data.mock_card symbolize_names(card_params) token end |
#get_bank_by_token(token) ⇒ Object
19 20 21 22 23 24 25 |
# File 'lib/stripe_mock/request_handlers/helpers/token_helpers.rb', line 19 def get_bank_by_token(token) if token.nil? || @bank_tokens[token].nil? Data.mock_bank_account else @bank_tokens.delete(token) end end |
#get_card(object, card_id, class_name = 'Customer') ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/stripe_mock/request_handlers/helpers/card_helpers.rb', line 5 def get_card(object, card_id, class_name='Customer') cards = object[:cards] || object[:sources] || object[:external_accounts] card = cards[:data].find{|cc| cc[:id] == card_id } if card.nil? if class_name == 'Recipient' msg = "#{class_name} #{object[:id]} does not have a card with ID #{card_id}" raise Stripe::InvalidRequestError.new(msg, 'card', http_status: 404) else msg = "There is no source with ID #{card_id}" raise Stripe::InvalidRequestError.new(msg, 'id', http_status: 404) end end card end |
#get_card_by_token(token) ⇒ Object
27 28 29 30 31 32 33 34 35 |
# File 'lib/stripe_mock/request_handlers/helpers/token_helpers.rb', line 27 def get_card_by_token(token) if token.nil? || @card_tokens[token].nil? # TODO: Make this strict msg = "Invalid token id: #{token}" raise Stripe::InvalidRequestError.new(msg, 'tok', http_status: 404) else @card_tokens.delete(token) end end |
#get_card_or_bank_by_token(token) ⇒ Object
37 38 39 40 |
# File 'lib/stripe_mock/request_handlers/helpers/token_helpers.rb', line 37 def get_card_or_bank_by_token(token) token_id = token['id'] || token @card_tokens[token_id] || @bank_tokens[token_id] || raise(Stripe::InvalidRequestError.new("Invalid token id: #{token_id}", 'tok', http_status: 404)) end |
#get_customer_subscription(customer, sub_id) ⇒ Object
5 6 7 |
# File 'lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb', line 5 def get_customer_subscription(customer, sub_id) customer[:subscriptions][:data].find{|sub| sub[:id] == sub_id } end |
#get_ending_time(start_time, plan, intervals = 1) ⇒ Object
‘intervals` is set to 1 when calculating current_period_end from current_period_start & plan `intervals` is set to 2 when calculating Stripe::Invoice.upcoming end from current_period_start & plan
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb', line 90 def get_ending_time(start_time, plan, intervals = 1) return start_time unless plan interval = plan[:interval] || plan.dig(:recurring, :interval) interval_count = plan[:interval_count] || plan.dig(:recurring, :interval_count) || 1 case interval when "week" start_time + (604800 * (interval_count) * intervals) when "month" (Time.at(start_time).to_datetime >> ((interval_count) * intervals)).to_time.to_i when "year" (Time.at(start_time).to_datetime >> (12 * intervals)).to_time.to_i # max period is 1 year else start_time end end |
#resolve_subscription_changes(subscription, plans, customer, options = {}) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb', line 9 def resolve_subscription_changes(subscription, plans, customer, = {}) subscription.merge!(custom_subscription_params(plans, customer, )) items = [:items] items = items.values if items.respond_to?(:values) subscription[:items][:data] = plans.map do |plan| matching_item = items && items.detect { |item| [item[:price], item[:plan]].include? plan[:id] } if matching_item matching_item[:quantity] ||= 1 matching_item[:id] ||= new_id('si') params = matching_item.merge(plan: plan) params[:price] = plan if plan[:object] == "price" Data.mock_subscription_item(params) else params = { plan: plan, id: new_id('si') } params[:price] = plan if plan[:object] == "price" Data.mock_subscription_item(params) end end subscription end |
#retrieve_object_cards(type, type_id, objects) ⇒ Object
59 60 61 62 63 64 |
# File 'lib/stripe_mock/request_handlers/helpers/card_helpers.rb', line 59 def retrieve_object_cards(type, type_id, objects) resource = assert_existence type, type_id, objects[type_id] cards = resource[:cards] || resource[:sources] || resource[:external_accounts] Data.mock_list_object(cards[:data]) end |
#search_results(all_values, querystring, fields: [], resource_name:) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/stripe_mock/request_handlers/helpers/search_helpers.rb', line 10 def search_results(all_values, querystring, fields: [], resource_name:) values = all_values.dup query_match = QUERYSTRING_PATTERN.match(querystring) raise Stripe::InvalidRequestError.new( 'We were unable to parse your search query.' \ ' Try using the format `metadata["key"]:"value"` to query for metadata or key:"value" to query for other fields.', nil, http_status: 400, ) unless query_match case query_match[:field] when *fields values = values.select { |resource| exact_match?(actual: field_value(resource, field: query_match[:field]), expected: query_match[:value]) } when "metadata" values = values.select { |resource| resource[:metadata] && exact_match?(actual: resource[:metadata][query_match[:metadata_key].to_sym], expected: query_match[:value]) } else raise Stripe::InvalidRequestError.new( "Field `#{query_match[:field]}` is an unsupported search field for resource `#{resource_name}`." \ " See http://stripe.com/docs/search#query-fields-for-#{resource_name.gsub('_', '-')} for a list of supported fields.", nil, http_status: 400, ) end values end |
#total_items_amount(items) ⇒ Object
119 120 121 122 123 124 125 126 127 |
# File 'lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb', line 119 def total_items_amount(items) total = 0 items.each do |item| quantity = item[:quantity] || 1 amount = item[:plan][:unit_amount] || item[:plan][:amount] total += quantity * amount end total end |
#validate_card(card) ⇒ Object
111 112 113 114 115 116 |
# File 'lib/stripe_mock/request_handlers/helpers/card_helpers.rb', line 111 def validate_card(card) [:exp_month, :exp_year].each do |field| card[field] = card[field].to_i end card end |
#verify_bank_account(object, bank_account_id, class_name = 'Customer') ⇒ Object
5 6 7 8 9 10 11 |
# File 'lib/stripe_mock/request_handlers/helpers/bank_account_helpers.rb', line 5 def verify_bank_account(object, bank_account_id, class_name='Customer') bank_accounts = object[:external_accounts] || object[:bank_accounts] || object[:sources] bank_account = bank_accounts[:data].find{|acc| acc[:id] == bank_account_id } return if bank_account.nil? bank_account['status'] = 'verified' bank_account end |
#verify_trial_end(trial_end) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/stripe_mock/request_handlers/helpers/subscription_helpers.rb', line 107 def verify_trial_end(trial_end) if trial_end != "now" if !trial_end.is_a? Integer raise Stripe::InvalidRequestError.new('Invalid timestamp: must be an integer', nil, http_status: 400) elsif trial_end < Time.now.utc.to_i raise Stripe::InvalidRequestError.new('Invalid timestamp: must be an integer Unix timestamp in the future', nil, http_status: 400) elsif trial_end > Time.now.utc.to_i + 31557600*5 # five years raise Stripe::InvalidRequestError.new('Invalid timestamp: can be no more than five years in the future', nil, http_status: 400) end end end |