require 'test_helper'

class SagePayFormNotificationTest < Test::Unit::TestCase
  include OffsitePayments::Integrations
  include OffsitePayments::Integrations::SagePayForm::Encryption

  def setup
    @options = {:credential2 => 'EncryptionKey123'}
  end

  def test_successful_purchase
    n = SagePayForm::Notification.new(successful_purchase, @options)
    assert n.complete?
    assert_false n.cancelled?

    assert_equal 'Completed', n.status
    assert_equal 'OK', n.status_code
    assert_equal 'Successfully Authorised Transaction', n.message
    assert_equal 'order-28', n.item_id
    assert_equal '{2D370B0B-692D-4D07-B616-91B86CCDF85A}', n.transaction_id
    assert_equal '7349', n.auth_id
    assert_equal '1231.47', n.gross
    assert_equal 'ALL MATCH', n.avs_cv2_result
    assert_equal 'MATCHED', n.address_result
    assert_equal 'MATCHED', n.post_code_result
    assert_equal 'MATCHED', n.cv2_result
    assert_equal 'OK', n.buyer_auth_result
    assert_equal 'MNG8ZAJDJRUKW90GGYZNTH', n.buyer_auth_result_code
    assert_equal 'VISA', n.credit_card_type
    assert_equal '8356', n.credit_card_last_4_digits

    assert_false n.gift_aid?
    assert_false n.payer_verified?
    assert_false n.test?

    assert_nil n.address_status
    assert_equal Money::NULL_CURRENCY, n.currency
  end

  def test_failed_purchase
    n = SagePayForm::Notification.new(failed_purchase, @options)
    assert_false n.complete?
    assert_false n.cancelled?

    assert_equal 'Failed', n.status
    assert_equal 'NOTAUTHED', n.status_code
    assert_equal 'NOTAUTHED message generated by Simulator', n.message
    assert_equal 'order-28', n.item_id
    assert_equal '{2D370B0B-692D-4D07-B616-91B86CCDF85A}', n.transaction_id
    assert_equal '31.47', n.gross
    assert_equal 'ALL MATCH', n.avs_cv2_result
    assert_equal 'MATCHED', n.address_result
    assert_equal 'MATCHED', n.post_code_result
    assert_equal 'MATCHED', n.cv2_result
    assert_equal 'OK', n.buyer_auth_result
    assert_equal 'MNVJYYXXHMCNH0BOTBT97Z', n.buyer_auth_result_code
    assert_equal 'VISA', n.credit_card_type
    assert_equal '4353', n.credit_card_last_4_digits

    assert_false n.gift_aid?
    assert_false n.payer_verified?
    assert_false n.test?

    assert_nil n.auth_id
    assert_nil n.address_status
    assert_equal Money::NULL_CURRENCY, n.currency
  end

  def test_cancelled_purchase
    n = SagePayForm::Notification.new(cancelled_purchase, @options)
    assert_false n.complete?
    assert n.cancelled?

    assert_equal 'Failed', n.status
    assert_equal 'ABORT', n.status_code
    assert_equal 'ABORT message generated by Simulator', n.message
    assert_equal 'order-5', n.item_id
    assert_equal '{90A42BA2-1281-4CA9-8E84-E43C0E7FD85F}', n.transaction_id
    assert_equal '148.99', n.gross
    assert_equal 'ALL MATCH', n.avs_cv2_result
    assert_equal 'MATCHED', n.address_result
    assert_equal 'MATCHED', n.post_code_result
    assert_equal 'MATCHED', n.cv2_result
    assert_equal 'OK', n.buyer_auth_result
    assert_equal 'MNJ8W58FNX1Q5OAV4TZKW2', n.buyer_auth_result_code
    assert_equal 'VISA', n.credit_card_type
    assert_equal '6425', n.credit_card_last_4_digits

    assert_false n.gift_aid?
    assert_false n.payer_verified?
    assert_false n.test?

    assert_nil n.auth_id
    assert_nil n.address_status
    assert_equal Money::NULL_CURRENCY, n.currency
  end

  def test_compositions
    n = SagePayForm::Notification.new(successful_purchase, @options)
    assert_equal Money.from_amount(1231.47, Money::NULL_CURRENCY), n.amount
  end

  def test_bogus_crypt
    assert_raises SagePayForm::Notification::InvalidCryptData do
      SagePayForm::Notification.new('crypt=SomeInvalidCryptField', @options)
    end
  end

  def test_missing_crypt
    assert_raises SagePayForm::Notification::MissingCryptData do
      SagePayForm::Notification.new('other=stuff', @options)
    end
  end

  def test_missing_key
    assert_raises SagePayForm::Notification::MissingCryptKey do
      SagePayForm::Notification.new(successful_purchase, {})
    end
  end

  private

  def successful_purchase
    encrypt_params(raw_successful_purchase)
  end

  def failed_purchase
    encrypt_params(raw_failed_purchase)
  end

  def cancelled_purchase
    encrypt_params(raw_cancelled_purchase)
  end

  def encrypt_params(raw)
    "utm_nooverride=1&crypt=#{sage_encrypt(raw, @options[:credential2])}"
  end

  def raw_successful_purchase
    "Status=OK&StatusDetail=Successfully Authorised Transaction&VendorTxCode=order-28-1234&VPSTxId={2D370B0B-692D-4D07-B616-91B86CCDF85A}&TxAuthNo=7349&Amount=1,231.47&AVSCV2=ALL MATCH&AddressResult=MATCHED&PostCodeResult=MATCHED&CV2Result=MATCHED&GiftAid=0&3DSecureStatus=OK&CAVV=MNG8ZAJDJRUKW90GGYZNTH&CardType=VISA&Last4Digits=8356"
  end

  def raw_failed_purchase
    "Status=NOTAUTHED&StatusDetail=NOTAUTHED message generated by Simulator&VendorTxCode=order-28-1234&VPSTxId={2D370B0B-692D-4D07-B616-91B86CCDF85A}&Amount=31.47&AVSCV2=ALL MATCH&AddressResult=MATCHED&PostCodeResult=MATCHED&CV2Result=MATCHED&GiftAid=0&3DSecureStatus=OK&CAVV=MNVJYYXXHMCNH0BOTBT97Z&CardType=VISA&Last4Digits=4353"
  end

  def raw_cancelled_purchase
    "Status=ABORT&StatusDetail=ABORT message generated by Simulator&VendorTxCode=order-5-1234&VPSTxId={90A42BA2-1281-4CA9-8E84-E43C0E7FD85F}&Amount=148.99&AVSCV2=ALL MATCH&AddressResult=MATCHED&PostCodeResult=MATCHED&CV2Result=MATCHED&GiftAid=0&3DSecureStatus=OK&CAVV=MNJ8W58FNX1Q5OAV4TZKW2&CardType=VISA&Last4Digits=6425"
  end
end
