Skip to content

Commit

Permalink
Deprecate #type method on CreditCard
Browse files Browse the repository at this point in the history
  • Loading branch information
John Duff committed Jun 8, 2012
1 parent db60a1f commit 80801ad
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 26 deletions.
44 changes: 27 additions & 17 deletions lib/active_merchant/billing/credit_card.rb
Expand Up @@ -22,12 +22,12 @@ module Billing #:nodoc:
# * Forbrugsforeningen
# * Laser
#
# For testing purposes, use the 'bogus' credit card type. This skips the vast majority of
# For testing purposes, use the 'bogus' credit card brand. This skips the vast majority of
# validations, allowing you to focus on your core concerns until you're ready to be more concerned
# with the details of particular credit cards or your gateway.
#
# == Testing With CreditCard
# Often when testing we don't care about the particulars of a given card type. When using the 'test'
# Often when testing we don't care about the particulars of a given card brand. When using the 'test'
# mode in your {Gateway}, there are six different valid card numbers: 1, 2, 3, 'success', 'fail',
# and 'error'.
#
Expand All @@ -39,7 +39,7 @@ module Billing #:nodoc:
# :last_name => 'Smith',
# :month => '9',
# :year => '2010',
# :type => 'visa',
# :brand => 'visa',
# :number => '4242424242424242'
# )
#
Expand Down Expand Up @@ -68,7 +68,7 @@ class CreditCard
# @return [Integer]
attr_accessor :year

# Returns or sets the credit card type.
# Returns or sets the credit card brand.
#
# Valid card types are
#
Expand All @@ -87,8 +87,8 @@ class CreditCard
#
# Or, if you wish to test your implementation, +'bogus'+.
#
# @return (String) the credit card type
attr_accessor :type
# @return (String) the credit card brand
attr_accessor :brand

# Returns or sets the first name of the card holder.
#
Expand All @@ -112,7 +112,15 @@ class CreditCard
# @return [String] the verification value
attr_accessor :verification_value

alias_method :brand, :type
def type
self.class.deprecated "Support for type is deprecated and will be removed from a future release of ActiveMerchant. Please use brand instead."
brand
end

def type=(value)
self.class.deprecated "Support for type is deprecated and will be removed from a future release of ActiveMerchant. Please use brand instead."
self.brand = value
end

# Provides proxy access to an expiry date object
#
Expand Down Expand Up @@ -189,9 +197,9 @@ def validate
validate_essential_attributes

# Bogus card is pretty much for testing purposes. Lets just skip these extra tests if its used
return if type == 'bogus'
return if brand == 'bogus'

validate_card_type
validate_card_brand
validate_card_number
validate_verification_value
validate_switch_or_solo_attributes
Expand All @@ -209,8 +217,8 @@ def before_validate #:nodoc:
self.start_month = start_month.to_i unless start_month.nil?
self.start_year = start_year.to_i unless start_year.nil?
self.number = number.to_s.gsub(/[^\d]/, "")
self.type.downcase! if type.respond_to?(:downcase)
self.type = self.class.type?(number) if type.blank?
self.brand.downcase! if brand.respond_to?(:downcase)
self.brand = self.class.brand?(number) if brand.blank?
end

def validate_card_number #:nodoc:
Expand All @@ -220,16 +228,18 @@ def validate_card_number #:nodoc:
errors.add :number, "is not a valid credit card number"
end

unless errors.on(:number) || errors.on(:type)
errors.add :type, "is not the correct card type" unless CreditCard.matching_type?(number, type)
unless errors.on(:number) || errors.on(:brand)
errors.add :brand, "is not the correct card brand" unless CreditCard.matching_brand?(number, brand)
end
end

def validate_card_type #:nodoc:
errors.add :type, "is required" if type.blank? && number.present?
errors.add :type, "is invalid" unless type.blank? || CreditCard.card_companies.keys.include?(type)
def validate_card_brand #:nodoc:
errors.add :brand, "is required" if brand.blank? && number.present?
errors.add :brand, "is invalid" unless brand.blank? || CreditCard.card_companies.keys.include?(brand)
end

alias_method :validate_card_type, :validate_card_brand

def validate_essential_attributes #:nodoc:
errors.add :first_name, "cannot be empty" if @first_name.blank?
errors.add :last_name, "cannot be empty" if @last_name.blank?
Expand All @@ -245,7 +255,7 @@ def validate_essential_attributes #:nodoc:
end

def validate_switch_or_solo_attributes #:nodoc:
if %w[switch solo].include?(type)
if %w[switch solo].include?(brand)
unless valid_month?(@start_month) && valid_start_year?(@start_year) || valid_issue_number?(@issue_number)
errors.add :start_month, "is invalid" unless valid_month?(@start_month)
errors.add :start_year, "is invalid" unless valid_start_year?(@start_year)
Expand Down
32 changes: 23 additions & 9 deletions lib/active_merchant/billing/credit_card_methods.rb
Expand Up @@ -38,8 +38,8 @@ def valid_issue_number?(number)
end

module ClassMethods
# Returns true if it validates. Optionally, you can pass a card type as an argument and
# make sure it is of the correct type.
# Returns true if it validates. Optionally, you can pass a card brand as an argument and
# make sure it is of the correct brand.
#
# References:
# - http://perl.about.com/compute/perl/library/nosearch/P073000.htm
Expand All @@ -59,20 +59,20 @@ def card_companies
CARD_COMPANIES
end

# Returns a string containing the type of card from the list of known information below.
# Returns a string containing the brand of card from the list of known information below.
# Need to check the cards in a particular order, as there is some overlap of the allowable ranges
#--
# TODO Refactor this method. We basically need to tighten up the Maestro Regexp.
#
# Right now the Maestro regexp overlaps with the MasterCard regexp (IIRC). If we can tighten
# things up, we can boil this whole thing down to something like...
#
# def type?(number)
# def brand?(number)
# return 'visa' if valid_test_mode_card_number?(number)
# card_companies.find([nil]) { |type, regexp| number =~ regexp }.first.dup
# card_companies.find([nil]) { |brand, regexp| number =~ regexp }.first.dup
# end
#
def type?(number)
def brand?(number)
return 'bogus' if valid_test_mode_card_number?(number)

card_companies.reject { |c,p| c == 'maestro' }.each do |company, pattern|
Expand All @@ -83,6 +83,11 @@ def type?(number)

return nil
end

def type?(number)
deprecated "Support for type? is deprecated and will be removed from a future release of ActiveMerchant. Please use brand? instead."
brand?(number)
end

def first_digits(number)
number.to_s.slice(0,6)
Expand All @@ -96,9 +101,18 @@ def mask(number)
"XXXX-XXXX-XXXX-#{last_digits(number)}"
end

# Checks to see if the calculated type matches the specified type
def matching_type?(number, type)
type?(number) == type
# Checks to see if the calculated brand matches the specified brand
def matching_brand?(number, brand)
brand?(number) == brand
end

def matching_type?(number, brand)
deprecated "Support for matching_type? is deprecated and will be removed from a future release of ActiveMerchant. Please use matching_brand? instead."
matching_brand?(number, brand)
end

def deprecated(message)
warn(Kernel.caller[1] + message)
end

private
Expand Down

0 comments on commit 80801ad

Please sign in to comment.