require 'test_helper'

class RemoteDataCashTest < Test::Unit::TestCase
  def setup
    # gateway to connect to Datacash
    @gateway = DataCashGateway.new(fixtures(:data_cash))

    @mastercard = CreditCard.new(
      number: '5120790000000034',
      month: 3,
      year: Date.today.year + 2,
      first_name: 'Mark',
      last_name: 'McBride',
      brand: :master
    )

    @mastercard_declined = CreditCard.new(
      number: '5473000000000106',
      month: 3,
      year: Date.today.year + 2,
      first_name: 'Mark',
      last_name: 'McBride',
      brand: :master,
      verification_value: '547'
    )

    @visa_delta = CreditCard.new(
      number: '4539792100000003',
      month: 3,
      year: Date.today.year + 2,
      first_name: 'Mark',
      last_name: 'McBride',
      brand: :visa,
      verification_value: '444'
    )

    @solo = CreditCard.new(
      first_name: 'Cody',
      last_name: 'Fauser',
      number: '633499100000000004',
      month: 3,
      year: Date.today.year + 2,
      brand: :solo,
      start_month: 12,
      start_year: 2006
    )

    @address = {
      name: 'Mark McBride',
      address1: 'Flat 12/3',
      address2: '45 Main Road',
      city: 'Sometown',
      state: 'Somecounty',
      zip: 'A987AA',
      phone: '(555)555-5555'
    }

    @params = {
      order_id: generate_unique_id
    }

    @amount = 198
  end

  # Testing that we can successfully make a purchase in a one step
  # operation
  def test_successful_purchase
    response = @gateway.purchase(@amount, @mastercard, @params)
    assert_success response
    assert response.test?
  end

  # the amount is changed to £1.99 - the DC test server won't check the
  # address details - this is more a check on the passed ExtendedPolicy
  def test_successful_purchase_without_address_check
    response = @gateway.purchase(199, @mastercard, @params)
    assert_success response
  end

  # Note the Datacash test server regularly times out on switch requests
  def test_successful_purchase_with_solo_card
    response = @gateway.purchase(@amount, @solo, @params)
    assert_success response
  end

  # this card number won't check the address details - testing extended
  # policy
  def test_successful_purchase_without_address_check2
    @solo.number = '633499110000000003'

    response = @gateway.purchase(@amount, @solo, @params)
    assert_success response
  end

  # Testing purchase with request to set up recurring payment account
  def test_successful_purchase_without_account_set_up_and_repeat_payments
    response = @gateway.purchase(@amount, @mastercard, @params)
    assert_success response
    assert response.authorization.to_s.split(';')[2].blank?
  end

  # Testing purchase with request to set up recurring payment account
  def test_successful_purchase_with_account_set_up_and_repeat_payments
    @params[:set_up_continuous_authority] = true
    response = @gateway.purchase(@amount, @mastercard, @params)
    assert_success response
    assert !response.authorization.to_s.split(';')[2].blank?
    assert response.test?

    # Make second payment on the continuous authorization that was set up in the first purchase
    second_order_params = { order_id: generate_unique_id }
    purchase = @gateway.purchase(201, response.authorization, second_order_params)
    assert_success purchase
  end

  def test_successful_purchase_with_account_set_up_and_repeat_payments_with_visa_delta_card
    @params[:set_up_continuous_authority] = true
    response = @gateway.purchase(@amount, @visa_delta, @params)
    assert_success response
    assert !response.authorization.to_s.split(';')[2].blank?

    # Make second payment on the continuous authorization that was set up in the first purchase
    second_order_params = { order_id: generate_unique_id }
    purchase = @gateway.purchase(201, response.authorization, second_order_params)
    assert_success purchase
  end

  def test_purchase_with_account_set_up_for_repeat_payments_fails_for_solo_card
    @params[:set_up_continuous_authority] = true
    response = @gateway.purchase(@amount, @solo, @params)
    assert_equal '92', response.params['status'] # Error code for CA not supported
    assert_equal 'CA Not Supported', response.message
  end

  def test_successful_authorization_and_capture_with_account_set_up_and_second_purchase
    # Authorize first payment
    @params[:set_up_continuous_authority] = true
    first_authorization = @gateway.authorize(@amount, @mastercard, @params)
    assert_success first_authorization
    assert !first_authorization.authorization.to_s.split(';')[2].blank?
    assert first_authorization.test?

    # Capture first payment
    capture = @gateway.capture(@amount, first_authorization.authorization, @params)
    assert_success capture
    assert capture.test?

    # Collect second purchase
    second_order_params = { order_id: generate_unique_id }
    purchase = @gateway.purchase(201, first_authorization.authorization, second_order_params)
    assert_success purchase
    assert purchase.test?
  end

  def test_duplicate_order_id
    response = @gateway.purchase(@amount, @mastercard, @params)
    assert_success response

    duplicate_response = @gateway.purchase(@amount, @mastercard, @params)
    assert_failure duplicate_response
    assert_equal 'Duplicate reference', duplicate_response.message
    assert duplicate_response.test?
  end

  def test_invalid_verification_number
    @mastercard.number = 1000350000000007
    @mastercard.verification_value = 123
    response = @gateway.purchase(@amount, @mastercard, @params)
    assert_failure response
    assert_equal 'CV2AVS DECLINED', response.message
    assert response.test?
  end

  def test_invalid_expiry_month
    @mastercard.month = 13
    response = @gateway.purchase(@amount, @mastercard, @params)
    assert_failure response
    assert_equal 'Expiry date invalid', response.message
    assert response.test?
  end

  def test_invalid_expiry_year
    @mastercard.number = 1000350000000353
    response = @gateway.purchase(@amount, @mastercard, @params)
    assert_failure response
    assert_equal 'expired', response.message
    assert response.test?
  end

  def test_declined_card
    response = @gateway.purchase(@amount, @mastercard_declined, @params)
    assert_failure response
    assert_equal 'DECLINED', response.message
    assert response.test?
  end

  def test_successful_authorization_and_capture
    authorization = @gateway.authorize(@amount, @mastercard, @params)
    assert_success authorization
    assert authorization.test?

    capture = @gateway.capture(@amount, authorization.authorization, @params)
    assert_success capture
    assert capture.test?
  end

  def test_unsuccessful_capture
    response = @gateway.capture(@amount, ';1234', @params)
    assert_failure response
    assert_equal 'Invalid fulfill ref', response.message
    assert response.test?
  end

  def test_successful_authorization_and_void
    authorization = @gateway.authorize(@amount, @mastercard, @params)
    assert_success authorization
    assert authorization.test?

    void = @gateway.void(authorization.authorization, @params)
    assert_success void
    assert void.test?
  end

  def test_successfully_purchase_and_void
    purchase = @gateway.purchase(@amount, @mastercard, @params)
    assert_success purchase
    assert purchase.test?

    void = @gateway.void(purchase.authorization, @params)
    assert_success void
    assert void.test?
  end

  def test_successful_credit
    response = @gateway.credit(@amount, @mastercard, @params)
    assert_success response
    assert !response.params['datacash_reference'].blank?
    assert !response.params['merchantreference'].blank?

    assert response.test?
  end

  def test_successful_refund
    purchase = @gateway.purchase(@amount, @mastercard, @params)
    assert_success purchase

    refund = @gateway.refund(@amount, purchase.authorization)
    assert_success refund
    assert !refund.params['datacash_reference'].blank?
    assert !refund.params['merchantreference'].blank?
    assert refund.test?
  end

  def test_successful_refund_with_money_set_to_nil
    purchase = @gateway.purchase(@amount, @mastercard, @params)
    assert_success purchase

    refund = @gateway.refund(nil, purchase.authorization)
    assert_success refund
  end

  def test_successful_partial_refund
    purchase = @gateway.purchase(@amount, @mastercard, @params)
    assert_success purchase

    first_partial_refund = @gateway.refund(100, purchase.authorization)
    assert_success first_partial_refund

    second_partial_refund = @gateway.refund(98, purchase.authorization)
    assert_success second_partial_refund
  end

  def test_failed_refund
    purchase = @gateway.purchase(@amount, @mastercard, @params)
    assert_success purchase

    refund_too_much = @gateway.refund(500, purchase.authorization)
    assert_failure refund_too_much
    assert_equal 'Refund amount > orig 1.98', refund_too_much.message
  end

  def test_fail_to_refund_with_declined_purchase_reference
    declined_purchase = @gateway.purchase(@amount, @mastercard_declined, @params)
    assert_failure declined_purchase

    refund = @gateway.refund(@amount, declined_purchase.authorization)
    assert_failure refund
    assert_equal 'Cannot refund transaction', refund.message
  end

  def test_fail_to_refund_purchase_which_is_already_refunded
    purchase = @gateway.purchase(@amount, @mastercard, @params)
    assert_success purchase
    assert purchase.test?

    first_refund = @gateway.refund(nil, purchase.authorization)
    assert_success first_refund

    second_refund = @gateway.refund(@amount, purchase.authorization)
    assert_failure second_refund
    assert_equal '1.98 > remaining funds 0.00', second_refund.message
  end

  def test_successful_refund_of_a_repeat_payment
    @params[:set_up_continuous_authority] = true
    response = @gateway.purchase(@amount, @mastercard, @params)
    assert_success response
    assert !response.authorization.to_s.split(';')[2].blank?
    assert response.test?

    # Make second payment on the continuous authorization that was set up in the first purchase
    second_order_params = { order_id: generate_unique_id }
    purchase = @gateway.purchase(201, response.authorization, second_order_params)
    assert_success purchase

    # Refund payment that was made via the continuous authorization payment above
    refund = @gateway.refund(201, purchase.authorization)
    assert_success refund
  end

  def test_order_id_that_is_too_short
    @params[:order_id] = @params[:order_id].first(5)
    response = @gateway.purchase(@amount, @mastercard, @params)
    assert_success response
  end

  def test_order_id_that_is_too_long
    @params[:order_id] = "#{@params[:order_id]}1234356"
    response = @gateway.purchase(@amount, @mastercard, @params)
    assert_success response
    assert response.test?
  end

  def test_transcript_scrubbing
    transcript = capture_transcript(@gateway) do
      @gateway.purchase(@amount, @visa_delta, @params)
    end
    transcript = @gateway.scrub(transcript)

    assert_scrubbed(@visa_delta.number, transcript)
    assert_scrubbed(@visa_delta.verification_value, transcript)
    assert_scrubbed(@gateway.options[:password], transcript)
  end
end
