require File.dirname(__FILE__) + '/../test_helper' class CreditCardTest < Test::Unit::TestCase def setup CreditCard.require_verification_value = false @visa = credit_card("4779139500118580", :type => "visa") @solo = credit_card("676700000000000000", :type => "solo", :issue_number => '01') end def teardown CreditCard.require_verification_value = false end def test_constructor_should_properly_assign_values c = credit_card assert_equal "4242424242424242", c.number assert_equal 9, c.month assert_equal Time.now.year + 1, c.year assert_equal "Longbob Longsen", c.name assert_equal "visa", c.type assert_valid c end def test_new_credit_card_should_not_be_valid c = CreditCard.new assert_not_valid c assert_false c.errors.empty? end def test_should_be_a_valid_visa_card assert_valid @visa assert @visa.errors.empty? end def test_should_be_a_valid_solo_card assert_valid @solo assert @solo.errors.empty? end def test_cards_with_empty_names_should_not_be_valid @visa.first_name = '' @visa.last_name = '' assert_not_valid @visa assert_false @visa.errors.empty? end def test_should_be_able_to_access_errors_indifferently @visa.first_name = '' assert_not_valid @visa assert @visa.errors.on(:first_name) assert @visa.errors.on("first_name") end def test_should_be_able_to_liberate_a_bogus_card c = credit_card('', :type => 'bogus') assert_valid c c.type = 'visa' assert_not_valid c end def test_should_be_able_to_identify_invalid_card_numbers @visa.number = nil assert_not_valid @visa @visa.number = "11112222333344ff" assert_not_valid @visa assert_false @visa.errors.on(:type) assert @visa.errors.on(:number) @visa.number = "111122223333444" assert_not_valid @visa assert_false @visa.errors.on(:type) assert @visa.errors.on(:number) @visa.number = "11112222333344444" assert_not_valid @visa assert_false @visa.errors.on(:type) assert @visa.errors.on(:number) end def test_should_have_errors_with_invalid_card_type_for_otherwise_correct_number @visa.type = 'master' assert_not_valid @visa assert_not_equal @visa.errors.on(:number), @visa.errors.on(:type) end def test_should_be_invalid_when_type_cannot_be_detected @visa.number = nil @visa.type = nil assert_not_valid @visa assert_match /is required/, @visa.errors.on(:type) assert @visa.errors.on(:type) end def test_should_be_a_valid_card_number @visa.number = "4242424242424242" assert_valid @visa end def test_should_require_a_valid_card_month @visa.month = Time.now.month @visa.year = Time.now.year assert_valid @visa end def test_should_not_be_valid_with_empty_month @visa.month = '' assert_not_valid @visa assert @visa.errors.on('month') end def test_should_not_be_valid_for_edge_month_cases @visa.month = 13 @visa.year = Time.now.year assert_not_valid @visa assert @visa.errors.on('month') @visa.month = 0 @visa.year = Time.now.year assert_not_valid @visa assert @visa.errors.on('month') end def test_should_be_invalid_with_empty_year @visa.year = '' assert_not_valid @visa assert @visa.errors.on('year') end def test_should_not_be_valid_for_edge_year_cases @visa.year = Time.now.year - 1 assert_not_valid @visa assert @visa.errors.on('year') @visa.year = Time.now.year + 21 assert_not_valid @visa assert @visa.errors.on('year') end def test_should_be_a_valid_future_year @visa.year = Time.now.year + 1 assert_valid @visa end def test_should_identify_wrong_cardtype c = credit_card(:type => 'master') assert_not_valid c end def test_should_display_number assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(:number => '1111222233331234').display_number assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(:number => '111222233331234').display_number assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(:number => '1112223331234').display_number assert_equal 'XXXX-XXXX-XXXX-', CreditCard.new(:number => nil).display_number assert_equal 'XXXX-XXXX-XXXX-', CreditCard.new(:number => '').display_number assert_equal 'XXXX-XXXX-XXXX-123', CreditCard.new(:number => '123').display_number assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(:number => '1234').display_number assert_equal 'XXXX-XXXX-XXXX-1234', CreditCard.new(:number => '01234').display_number end def test_should_correctly_identify_card_type assert_equal 'visa', CreditCard.type?('4242424242424242') assert_equal 'american_express', CreditCard.type?('341111111111111') assert_nil CreditCard.type?('') end def test_should_be_able_to_require_a_verification_value CreditCard.require_verification_value = true assert CreditCard.requires_verification_value? end def test_should_not_be_valid_when_requiring_a_verification_value CreditCard.require_verification_value = true card = credit_card('4242424242424242', :verification_value => nil) assert_not_valid card card.verification_value = '123' assert_valid card end def test_should_require_valid_start_date_for_solo_or_switch @solo.start_month = nil @solo.start_year = nil @solo.issue_number = nil assert_not_valid @solo assert @solo.errors.on('start_month') assert @solo.errors.on('start_year') assert @solo.errors.on('issue_number') @solo.start_month = 2 @solo.start_year = 2007 assert_valid @solo end def test_should_require_a_valid_issue_number_for_solo_or_switch @solo.start_month = nil @solo.start_year = 2005 @solo.issue_number = nil assert_not_valid @solo assert @solo.errors.on('start_month') assert @solo.errors.on('issue_number') @solo.issue_number = 3 assert_valid @solo end def test_should_return_last_four_digits_of_card_number ccn = CreditCard.new(:number => "4779139500118580") assert_equal "8580", ccn.last_digits end def test_bogus_last_digits ccn = CreditCard.new(:number => "1") assert_equal "1", ccn.last_digits end def test_should_be_true_when_credit_card_has_a_first_name c = CreditCard.new assert_false c.first_name? c = CreditCard.new(:first_name => 'James') assert c.first_name? end def test_should_be_true_when_credit_card_has_a_last_name c = CreditCard.new assert_false c.last_name? c = CreditCard.new(:last_name => 'Herdman') assert c.last_name? end def test_should_test_for_a_full_name c = CreditCard.new assert_false c.name? c = CreditCard.new(:first_name => 'James', :last_name => 'Herdman') assert c.name? end # The following is a regression for a bug that raised an exception when # a new credit card was validated def test_validate_new_card credit_card = CreditCard.new assert_nothing_raised do credit_card.validate end end # The following is a regression for a bug where the keys of the # credit card card_companies hash were not duped when detecting the type def test_create_and_validate_credit_card_from_type credit_card = CreditCard.new(:type => CreditCard.type?('4242424242424242')) assert_nothing_raised do credit_card.valid? end end def test_autodetection_of_credit_card_type credit_card = CreditCard.new(:number => '4242424242424242') credit_card.valid? assert_equal 'visa', credit_card.type end def test_card_type_should_not_be_autodetected_when_provided credit_card = CreditCard.new(:number => '4242424242424242', :type => 'master') credit_card.valid? assert_equal 'master', credit_card.type end def test_detecting_bogus_card credit_card = CreditCard.new(:number => '1') credit_card.valid? assert_equal 'bogus', credit_card.type end def test_validating_bogus_card credit_card = credit_card('1', :type => nil) assert credit_card.valid? end def test_mask_number assert_equal 'XXXX-XXXX-XXXX-5100', CreditCard.mask('5105105105105100') end def test_strip_non_digit_characters card = credit_card('4242-4242 %%%%%%4242......4242') assert card.valid? assert_equal "4242424242424242", card.number end def test_before_validate_handles_blank_number card = credit_card(nil) assert !card.valid? assert_equal "", card.number end end