ActiveMerchant-FatZebra 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "ActiveMerchant-FatZebra"
6
+ s.version = "1.0.0"
7
+ s.authors = ["Matthew Savage"]
8
+ s.email = ["matthew.savage@fatzebra.com.au"]
9
+ s.homepage = "https://www.fatzebra.com.au"
10
+ s.summary = %q{Fat Zebra support for Active Merchant, as a gem}
11
+ s.description = %q{Fat Zebra support for Active Merchant - temporary gem until support is combined into active_merchant core.}
12
+
13
+ s.rubyforge_project = "ActiveMerchant-FatZebra"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_runtime_dependency "activemerchant"
21
+ s.add_development_dependency "rake"
22
+ s.add_development_dependency('mocha', '~> 0.11.3')
23
+ s.add_development_dependency('rails', '>= 2.3.11')
24
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ActiveMerchant-FatZebra.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,62 @@
1
+ FatZebra ActiveMerchant integration
2
+ ===================================
3
+
4
+ The quick 30-second rundown
5
+ ---------------------------
6
+
7
+ 1. Install the gem in your Gemfile
8
+
9
+ gem "active_merchant_fat_zebra"
10
+
11
+ Then `bundle install`
12
+
13
+ 2. Setup the gateway in your app:
14
+
15
+ ```ruby
16
+
17
+ options = {
18
+ :login => "test",
19
+ :token => "test_token"
20
+ }
21
+ gateway = ActiveMerchant::Billing::FatZebraGateway.new(options)
22
+
23
+ # If you are testing, uncomment the following line
24
+ # ActiveMerchant::Billing::Base.gateway_mode = :test
25
+ ```
26
+
27
+ 3. Setup the transaction data and then... transact!
28
+
29
+ ```ruby
30
+ cc = ActiveMerchant::Billing::CreditCard.new(:first_name => "Joe",
31
+ :last_name => "Smith",
32
+ :number => "4444333322221111",
33
+ :month => 12,
34
+ :year => 2013,
35
+ :verification_value => 123)
36
+
37
+ amount = 10000 # 100.00 in cents
38
+
39
+ result = gateway.purchase(amount, cc, { :order_id => "ORD18239", :ip => request.ip }) # If you are using rails you would use request.remote_ip
40
+ ```
41
+
42
+ 4. Handle the response - the data you get back is:
43
+
44
+ ```ruby
45
+ result.success? # True or False depending on if the txn was successful
46
+ result.message # e.g. "Approved" or "Declined"
47
+ result.id # The transaction ID
48
+ result.test? # Indicates if this was a test transaction
49
+ result.params # Parameters passed by the gateway (e.g. may be additional info like fraud review score.)
50
+ result.params["result"]["id"] # The transaction ID
51
+ result.params["result"]["token"] # The card token (when storing a card)
52
+ ```
53
+
54
+
55
+ Refunds
56
+ -------
57
+ ```ruby
58
+ # Refunding the amount of $100.00, for the original transaction ID of "AB12887Z"
59
+ response = gateway.refund(10000, "AB12887Z", "REFUND1")
60
+
61
+ response.success? # true or false
62
+ ```
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ $:.unshift File.expand_path('../lib', __FILE__)
4
+
5
+ begin
6
+ require 'bundler'
7
+ Bundler.setup
8
+ rescue LoadError => e
9
+ puts "Error loading bundler (#{e.message}): \"gem install bundler\" for bundler support."
10
+ require 'rubygems'
11
+ end
12
+
13
+ require 'rake'
14
+ require 'rake/testtask'
15
+
16
+ desc "Run the unit test suite"
17
+ task :default => 'test:all'
18
+
19
+ namespace :test do
20
+
21
+ Rake::TestTask.new(:units) do |t|
22
+ t.pattern = 'test/unit/**/*_test.rb'
23
+ t.ruby_opts << '-rubygems'
24
+ t.libs << 'test'
25
+ t.verbose = true
26
+ end
27
+
28
+ Rake::TestTask.new(:remote) do |t|
29
+ t.pattern = 'test/remote/**/*_test.rb'
30
+ t.ruby_opts << '-rubygems'
31
+ t.libs << 'test'
32
+ t.verbose = true
33
+ end
34
+
35
+ desc "Test all"
36
+ task :all => [:units, :remote]
37
+ end
@@ -0,0 +1,2 @@
1
+ require 'active_merchant'
2
+ require "active_merchant/billing/gateways/fat_zebra"
@@ -0,0 +1,153 @@
1
+ require 'json'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class FatZebraGateway < Gateway
6
+ LIVE_URL = "https://gateway.fatzebra.com.au/v1.0"
7
+ SANDBOX_URL = "https://gateway.sandbox.fatzebra.com.au/v1.0"
8
+
9
+ self.supported_countries = ['AU']
10
+ self.default_currency = 'AUD'
11
+ self.money_format = :cents
12
+ self.supported_cardtypes = [:visa, :master, :american_express, :jcb]
13
+
14
+ self.homepage_url = 'https://www.fatzebra.com.au/'
15
+ self.display_name = 'Fat Zebra'
16
+
17
+ # Setup a new instance of the gateway.
18
+ #
19
+ # The options hash should include :username and :token
20
+ # You can find your username and token at https://dashboard.fatzebra.com.au
21
+ # Under the Your Account section
22
+ def initialize(options = {})
23
+ requires!(options, :username)
24
+ requires!(options, :token)
25
+ @username = options[:username]
26
+ @token = options[:token]
27
+ super
28
+ end
29
+
30
+ # To create a purchase on a credit card use:
31
+ #
32
+ # purchase(money, creditcard , { ... })
33
+ #
34
+ # To charge a tokenized card
35
+ #
36
+ # purchase(money, {:token => "abzy87u", :cvv => "123"}, { ... }})
37
+ def purchase(money, creditcard, options = {})
38
+ post = {}
39
+
40
+ add_amount(post, money, options)
41
+ add_creditcard(post, creditcard, options)
42
+ post[:reference] = options[:order_id]
43
+ post[:customer_ip] = options[:ip]
44
+
45
+ commit(:post, 'purchases', post)
46
+ end
47
+
48
+ # Refund a transaction
49
+ #
50
+ # amount - Integer - the amount to refund
51
+ # txn_id - String - the original transaction to be refunded
52
+ # reference - String - your transaction reference
53
+ def refund(money, txn_id, reference)
54
+ post = {}
55
+
56
+ post[:amount] = money
57
+ post[:transaction_id] = txn_id
58
+ post[:reference] = reference
59
+
60
+ commit(:post, "refunds", post)
61
+ end
62
+
63
+ # Tokenize a credit card
64
+ def store(creditcard)
65
+ post = {}
66
+ add_creditcard(post, creditcard)
67
+
68
+ commit(:post, "credit_cards", post)
69
+ end
70
+
71
+ private
72
+ # Add the money details to the request
73
+ def add_amount(post, money, options)
74
+ post[:amount] = money
75
+ end
76
+
77
+ # Add the credit card details to the request
78
+ def add_creditcard(post, creditcard, options = {})
79
+ if creditcard.respond_to?(:number)
80
+ post[:card_number] = creditcard.number
81
+ post[:card_expiry] = "#{creditcard.month}/#{creditcard.year}"
82
+ post[:cvv] = creditcard.verification_value if creditcard.verification_value?
83
+ post[:card_holder] = creditcard.name if creditcard.name
84
+ else
85
+ post[:card_token] = creditcard[:token]
86
+ post[:cvv] = creditcard[:cvv]
87
+ end
88
+ end
89
+
90
+ # Post the data to the gateway
91
+ def commit(method, uri, parameters=nil)
92
+ raw_response = response = nil
93
+ success = false
94
+ begin
95
+ raw_response = ssl_request(method, get_url(uri), parameters.to_json, headers)
96
+ response = parse(raw_response)
97
+ success = response["successful"] && (response["response"]["successful"] || response["response"]["token"])
98
+ rescue ResponseError => e
99
+ if e.response.code == "401"
100
+ return Response.new(false, "Invalid Login")
101
+ end
102
+
103
+ raw_response = e.response.body
104
+ response = parse(raw_response)
105
+ rescue JSON::ParserError
106
+ response = json_error(raw_response)
107
+ end
108
+
109
+ message = response["response"]["message"]
110
+ unless response["successful"]
111
+ # There is an error, so we will show that instead
112
+ message = response["errors"].empty? ? "Unknown Error" : response["errors"].join(", ")
113
+ end
114
+
115
+ Response.new(success,
116
+ message,
117
+ response,
118
+ :test => response.has_key?("test") ? response["test"] : false,
119
+ :authorization => response["response"]["authorization"],
120
+ :id => response["response"]["id"])
121
+ end
122
+
123
+ # Parse the returned JSON, if parse errors are raised then return a detailed error.
124
+ def parse(response)
125
+ begin
126
+ JSON.parse(response)
127
+ rescue JSON::ParserError
128
+ msg = 'Invalid JSON response received from Fat Zebra. Please contact support@fatzebra.com.au if you continue to receive this message.'
129
+ msg += " (The raw response returned by the API was #{response.inspect})"
130
+ {
131
+ "successful" => false,
132
+ "response" => {},
133
+ "errors" => [msg]
134
+ }
135
+ end
136
+ end
137
+
138
+ # Build the URL based on the AM mode and the URI
139
+ def get_url(uri)
140
+ base = test? ? SANDBOX_URL : LIVE_URL
141
+ base + "/" + uri
142
+ end
143
+
144
+ # Builds the auth and U-A headers for the request
145
+ def headers
146
+ {
147
+ "Authorization" => "Basic " + Base64.encode64(@username.to_s + ":" + @token.to_s).strip,
148
+ "User-Agent" => "Fat Zebra v1.0/ActiveMerchant #{ActiveMerchant::VERSION}"
149
+ }
150
+ end
151
+ end
152
+ end
153
+ end
data/test/comm_stub.rb ADDED
@@ -0,0 +1,39 @@
1
+ module CommStub
2
+ class Stub
3
+ def initialize(gateway, action)
4
+ @gateway = gateway
5
+ @action = action
6
+ @complete = false
7
+ end
8
+
9
+ def check_request(&block)
10
+ @check = block
11
+ self
12
+ end
13
+
14
+ def respond_with(*responses)
15
+ @complete = true
16
+ check = @check
17
+ (class << @gateway; self; end).send(:define_method, :ssl_post) do |*args|
18
+ check.call(*args) if check
19
+ (responses.size == 1 ? responses.last : responses.shift)
20
+ end
21
+ @action.call
22
+ end
23
+
24
+ def complete?
25
+ @complete
26
+ end
27
+ end
28
+
29
+ def stub_comms(gateway=@gateway, &action)
30
+ if @last_comm_stub
31
+ assert @last_comm_stub.complete?, "Tried to stub communications when there's a stub already in progress."
32
+ end
33
+ @last_comm_stub = Stub.new(gateway, action)
34
+ end
35
+
36
+ def teardown
37
+ assert(@last_comm_stub.complete?) if @last_comm_stub
38
+ end
39
+ end
data/test/fixtures.yml ADDED
@@ -0,0 +1,3 @@
1
+ fat_zebra:
2
+ username: TEST
3
+ token: TEST
@@ -0,0 +1,76 @@
1
+ require 'test_helper'
2
+
3
+ class RemoteFatZebraTest < Test::Unit::TestCase
4
+
5
+
6
+ def setup
7
+ @gateway = FatZebraGateway.new(fixtures(:fat_zebra))
8
+
9
+ @amount = 100
10
+ @credit_card = credit_card('5123456789012346')
11
+ @declined_card = credit_card('4557012345678902')
12
+
13
+ @options = {
14
+ :order_id => rand(100000).to_s,
15
+ :ip => "123.1.2.3"
16
+ }
17
+ end
18
+
19
+ def test_successful_purchase
20
+ assert response = @gateway.purchase(@amount, @credit_card, @options)
21
+ assert_success response
22
+ assert_equal 'Approved', response.message
23
+ end
24
+
25
+ def test_unsuccessful_purchase
26
+ assert response = @gateway.purchase(@amount, @declined_card, @options)
27
+ assert_failure response
28
+ assert_equal 'Declined', response.message
29
+ end
30
+
31
+ def test_invalid_data
32
+ @options.delete(:ip)
33
+ assert response = @gateway.purchase(@amount, @declined_card, @options)
34
+ assert_failure response
35
+ assert_equal "Customer ip can't be blank", response.message
36
+ end
37
+
38
+ def test_refund
39
+ purchase = @gateway.purchase(@amount, @credit_card, @options)
40
+
41
+ assert response = @gateway.refund(@amount, purchase.params["response"]["id"], rand(1000000).to_s)
42
+ assert_success response
43
+ assert_match /Approved/, response.message
44
+ end
45
+
46
+ def test_invalid_refund
47
+ purchase = @gateway.purchase(@amount, @credit_card, @options)
48
+
49
+ assert response = @gateway.refund(@amount, nil, rand(1000000).to_s)
50
+ assert_failure response
51
+ assert_match /Original transaction is required/, response.message
52
+ end
53
+
54
+ def test_store
55
+ assert card = @gateway.store(@credit_card)
56
+
57
+ assert_success card
58
+ assert_false card.params["response"]["token"].nil?
59
+ end
60
+
61
+ def test_purchase_with_token
62
+ assert card = @gateway.store(@credit_card)
63
+ assert purchase = @gateway.purchase(@amount, {:cvv => 123, :token => card.params["response"]["token"]}, @options)
64
+ assert_success purchase
65
+ end
66
+
67
+ def test_invalid_login
68
+ gateway = FatZebraGateway.new(
69
+ :username => 'invalid',
70
+ :token => 'wrongtoken'
71
+ )
72
+ assert response = gateway.purchase(@amount, @credit_card, @options)
73
+ assert_failure response
74
+ assert_equal 'Invalid Login', response.message
75
+ end
76
+ end
@@ -0,0 +1,252 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path('../../lib', __FILE__)
3
+
4
+ begin
5
+ require 'rubygems'
6
+ require 'bundler'
7
+ Bundler.setup
8
+ rescue LoadError => e
9
+ puts "Error loading bundler (#{e.message}): \"gem install bundler\" for bundler support."
10
+ end
11
+
12
+ require 'test/unit'
13
+ require 'money'
14
+ require 'mocha'
15
+ require 'yaml'
16
+ require 'active_merchant'
17
+ require 'active_merchant/billing/gateways/fat_zebra'
18
+ require 'comm_stub'
19
+
20
+ require 'active_support/core_ext/integer/time'
21
+ require 'active_support/core_ext/numeric/time'
22
+
23
+
24
+
25
+ begin
26
+ require 'active_support/core_ext/time/acts_like'
27
+ rescue LoadError
28
+ end
29
+
30
+ begin
31
+ gem 'actionpack'
32
+ rescue LoadError
33
+ raise StandardError, "The view tests need ActionPack installed as gem to run"
34
+ end
35
+
36
+ require 'action_controller'
37
+ require "action_view/template"
38
+ begin
39
+ require 'active_support/core_ext/module/deprecation'
40
+ require 'action_dispatch/testing/test_process'
41
+ rescue LoadError
42
+ require 'action_controller/test_process'
43
+ end
44
+ require 'active_merchant/billing/integrations/action_view_helper'
45
+
46
+ ActiveMerchant::Billing::Base.mode = :test
47
+
48
+ if ENV['DEBUG_ACTIVE_MERCHANT'] == 'true'
49
+ require 'logger'
50
+ ActiveMerchant::Billing::Gateway.logger = Logger.new(STDOUT)
51
+ ActiveMerchant::Billing::Gateway.wiredump_device = STDOUT
52
+ end
53
+
54
+ # Test gateways
55
+ class SimpleTestGateway < ActiveMerchant::Billing::Gateway
56
+ end
57
+
58
+ class SubclassGateway < SimpleTestGateway
59
+ end
60
+
61
+
62
+ module ActiveMerchant
63
+ module Assertions
64
+ AssertionClass = RUBY_VERSION > '1.9' ? MiniTest::Assertion : Test::Unit::AssertionFailedError
65
+
66
+ def assert_field(field, value)
67
+ clean_backtrace do
68
+ assert_equal value, @helper.fields[field]
69
+ end
70
+ end
71
+
72
+ # Allows the testing of you to check for negative assertions:
73
+ #
74
+ # # Instead of
75
+ # assert !something_that_is_false
76
+ #
77
+ # # Do this
78
+ # assert_false something_that_should_be_false
79
+ #
80
+ # An optional +msg+ parameter is available to help you debug.
81
+ def assert_false(boolean, message = nil)
82
+ message = build_message message, '<?> is not false or nil.', boolean
83
+
84
+ clean_backtrace do
85
+ assert_block message do
86
+ not boolean
87
+ end
88
+ end
89
+ end
90
+
91
+ # A handy little assertion to check for a successful response:
92
+ #
93
+ # # Instead of
94
+ # assert_success response
95
+ #
96
+ # # DRY that up with
97
+ # assert_success response
98
+ #
99
+ # A message will automatically show the inspection of the response
100
+ # object if things go afoul.
101
+ def assert_success(response)
102
+ clean_backtrace do
103
+ assert response.success?, "Response failed: #{response.inspect}"
104
+ end
105
+ end
106
+
107
+ # The negative of +assert_success+
108
+ def assert_failure(response)
109
+ clean_backtrace do
110
+ assert_false response.success?, "Response expected to fail: #{response.inspect}"
111
+ end
112
+ end
113
+
114
+ def assert_valid(validateable)
115
+ clean_backtrace do
116
+ assert validateable.valid?, "Expected to be valid"
117
+ end
118
+ end
119
+
120
+ def assert_not_valid(validateable)
121
+ clean_backtrace do
122
+ assert_false validateable.valid?, "Expected to not be valid"
123
+ end
124
+ end
125
+
126
+ def assert_deprecation_warning(message, target)
127
+ target.expects(:deprecated).with(message)
128
+ yield
129
+ end
130
+
131
+ private
132
+ def clean_backtrace(&block)
133
+ yield
134
+ rescue AssertionClass => e
135
+ path = File.expand_path(__FILE__)
136
+ raise AssertionClass, e.message, e.backtrace.reject { |line| File.expand_path(line) =~ /#{path}/ }
137
+ end
138
+ end
139
+
140
+ module Fixtures
141
+ HOME_DIR = RUBY_PLATFORM =~ /mswin32/ ? ENV['HOMEPATH'] : ENV['HOME'] unless defined?(HOME_DIR)
142
+ LOCAL_CREDENTIALS = File.join(HOME_DIR.to_s, '.active_merchant/fixtures.yml') unless defined?(LOCAL_CREDENTIALS)
143
+ DEFAULT_CREDENTIALS = File.join(File.dirname(__FILE__), 'fixtures.yml') unless defined?(DEFAULT_CREDENTIALS)
144
+
145
+ private
146
+ def credit_card(number = '4242424242424242', options = {})
147
+ defaults = {
148
+ :number => number,
149
+ :month => 9,
150
+ :year => Time.now.year + 1,
151
+ :first_name => 'Longbob',
152
+ :last_name => 'Longsen',
153
+ :verification_value => '123',
154
+ :brand => 'visa'
155
+ }.update(options)
156
+
157
+ Billing::CreditCard.new(defaults)
158
+ end
159
+
160
+ def check(options = {})
161
+ defaults = {
162
+ :name => 'Jim Smith',
163
+ :routing_number => '244183602',
164
+ :account_number => '15378535',
165
+ :account_holder_type => 'personal',
166
+ :account_type => 'checking',
167
+ :number => '1'
168
+ }.update(options)
169
+
170
+ Billing::Check.new(defaults)
171
+ end
172
+
173
+ def address(options = {})
174
+ {
175
+ :name => 'Jim Smith',
176
+ :address1 => '1234 My Street',
177
+ :address2 => 'Apt 1',
178
+ :company => 'Widgets Inc',
179
+ :city => 'Ottawa',
180
+ :state => 'ON',
181
+ :zip => 'K1C2N6',
182
+ :country => 'CA',
183
+ :phone => '(555)555-5555',
184
+ :fax => '(555)555-6666'
185
+ }.update(options)
186
+ end
187
+
188
+ def all_fixtures
189
+ @@fixtures ||= load_fixtures
190
+ end
191
+
192
+ def fixtures(key)
193
+ data = all_fixtures[key] || raise(StandardError, "No fixture data was found for '#{key}'")
194
+
195
+ data.dup
196
+ end
197
+
198
+ def load_fixtures
199
+ [DEFAULT_CREDENTIALS, LOCAL_CREDENTIALS].inject({}) do |credentials, file_name|
200
+ if File.exists?(file_name)
201
+ yaml_data = YAML.load(File.read(file_name))
202
+ credentials.merge!(symbolize_keys(yaml_data))
203
+ end
204
+ credentials
205
+ end
206
+ end
207
+
208
+ def symbolize_keys(hash)
209
+ return unless hash.is_a?(Hash)
210
+
211
+ hash.symbolize_keys!
212
+ hash.each{|k,v| symbolize_keys(v)}
213
+ end
214
+ end
215
+ end
216
+
217
+ Test::Unit::TestCase.class_eval do
218
+ include ActiveMerchant::Billing
219
+ include ActiveMerchant::Assertions
220
+ include ActiveMerchant::Utils
221
+ include ActiveMerchant::Fixtures
222
+ end
223
+
224
+ module ActionViewHelperTestHelper
225
+
226
+ def self.included(base)
227
+ base.send(:include, ActiveMerchant::Billing::Integrations::ActionViewHelper)
228
+ base.send(:include, ActionView::Helpers::FormHelper)
229
+ base.send(:include, ActionView::Helpers::FormTagHelper)
230
+ base.send(:include, ActionView::Helpers::UrlHelper)
231
+ base.send(:include, ActionView::Helpers::TagHelper)
232
+ base.send(:include, ActionView::Helpers::CaptureHelper)
233
+ base.send(:include, ActionView::Helpers::TextHelper)
234
+ base.send(:attr_accessor, :output_buffer)
235
+ end
236
+
237
+ def setup
238
+ @controller = Class.new do
239
+ attr_reader :url_for_options
240
+ def url_for(options, *parameters_for_method_reference)
241
+ @url_for_options = options
242
+ end
243
+ end
244
+ @controller = @controller.new
245
+ @output_buffer = ''
246
+ end
247
+
248
+ protected
249
+ def protect_against_forgery?
250
+ false
251
+ end
252
+ end
@@ -0,0 +1,172 @@
1
+ require 'test_helper'
2
+
3
+ class FatZebraTest < Test::Unit::TestCase
4
+ def setup
5
+ @gateway = FatZebraGateway.new(
6
+ :username => 'TEST',
7
+ :token => 'TEST'
8
+ )
9
+
10
+ @credit_card = credit_card
11
+ @amount = 100
12
+
13
+ @options = {
14
+ :order_id => rand(10000),
15
+ :billing_address => address,
16
+ :description => 'Store Purchase'
17
+ }
18
+ end
19
+
20
+ def test_successful_purchase
21
+ @gateway.expects(:ssl_request).returns(successful_purchase_response)
22
+
23
+ assert response = @gateway.purchase(@amount, @credit_card, @options)
24
+ assert_success response
25
+
26
+ # Replace with authorization number from the successful response
27
+ assert_equal '55355', response.authorization
28
+ assert response.test?
29
+ end
30
+
31
+ def test_unsuccessful_request
32
+ @gateway.expects(:ssl_request).returns(failed_purchase_response)
33
+
34
+ assert response = @gateway.purchase(@amount, @credit_card, @options)
35
+ assert_failure response
36
+ assert response.test?
37
+ assert_match /Invalid Card Number/, response.message
38
+ end
39
+
40
+ def test_declined_purchase
41
+ @gateway.expects(:ssl_request).returns(declined_purchase_response)
42
+
43
+ assert response = @gateway.purchase(@amount, @credit_card, @options)
44
+ assert_failure response
45
+ assert response.test?
46
+ assert_match /Card Declined/, response.message
47
+ end
48
+
49
+ def test_parse_error
50
+ @gateway.expects(:ssl_request).returns("{") # Some invalid JSON
51
+ assert response = @gateway.purchase(@amount, @credit_card, @options)
52
+ assert_failure response
53
+ assert_match /Invalid JSON response/, response.message
54
+ end
55
+
56
+ def test_request_error
57
+ @gateway.expects(:ssl_request).returns(missing_data_response)
58
+
59
+ assert response = @gateway.purchase(@amount, @credit_card, @options)
60
+ assert_failure response
61
+ assert_match /Card Number is required/, response.message
62
+ end
63
+
64
+ def test_successful_tokenization
65
+ @gateway.expects(:ssl_request).returns(successful_tokenize_response)
66
+
67
+ assert response = @gateway.store(@credit_card)
68
+ assert_success response
69
+ end
70
+
71
+ def test_unsuccessful_tokenization
72
+ @gateway.expects(:ssl_request).returns(failed_tokenize_response)
73
+
74
+ assert response = @gateway.store(@credit_card)
75
+ assert_failure response
76
+ end
77
+
78
+ private
79
+
80
+ # Place raw successful response from gateway here
81
+ def successful_purchase_response
82
+ {
83
+ :successful => true,
84
+ :response => {
85
+ :authorization => "55355",
86
+ :id => "001-P-12345AA",
87
+ :card_number => "XXXXXXXXXXXX1111",
88
+ :card_holder => "John Smith",
89
+ :card_expiry => "10/2011",
90
+ :card_token => "a1bhj98j",
91
+ :amount => 349,
92
+ :successful => true,
93
+ :reference => "ABC123",
94
+ :message => "Approved",
95
+ },
96
+ :test => true,
97
+ :errors => []
98
+ }.to_json
99
+ end
100
+
101
+ def declined_purchase_response
102
+ {
103
+ :successful => true,
104
+ :response => {
105
+ :authorization_id => nil,
106
+ :id => nil,
107
+ :card_number => "XXXXXXXXXXXX1111",
108
+ :card_holder => "John Smith",
109
+ :card_expiry => "10/2011",
110
+ :amount => 100,
111
+ :authorized => false,
112
+ :reference => "ABC123",
113
+ :message => "Card Declined - check with issuer",
114
+ },
115
+ :test => true,
116
+ :errors => []
117
+ }.to_json
118
+ end
119
+
120
+ def successful_tokenize_response
121
+ {
122
+ :successful => true,
123
+ :response => {
124
+ :token => "e1q7dbj2",
125
+ :card_holder => "Bob Smith",
126
+ :card_number => "XXXXXXXXXXXX2346",
127
+ :card_expiry => "2013-05-31T23:59:59+10:00",
128
+ :authorized => true,
129
+ :transaction_count => 0
130
+ },
131
+ :errors => [],
132
+ :test => true
133
+ }.to_json
134
+ end
135
+
136
+ def failed_tokenize_response
137
+ {
138
+ :successful => false,
139
+ :response => {
140
+ :token => nil,
141
+ :card_holder => "Bob ",
142
+ :card_number => "512345XXXXXX2346",
143
+ :card_expiry => nil,
144
+ :authorized => false,
145
+ :transaction_count => 10
146
+ },
147
+ :errors => [
148
+ "Expiry date can't be blank"
149
+ ],
150
+ :test => false
151
+ }.to_json
152
+ end
153
+
154
+ # Place raw failed response from gateway here
155
+ def failed_purchase_response
156
+ {
157
+ :successful => false,
158
+ :response => {},
159
+ :test => true,
160
+ :errors => ["Invalid Card Number"]
161
+ }.to_json
162
+ end
163
+
164
+ def missing_data_response
165
+ {
166
+ :successful => false,
167
+ :response => {},
168
+ :test => true,
169
+ :errors => ["Card Number is required"]
170
+ }.to_json
171
+ end
172
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ActiveMerchant-FatZebra
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matthew Savage
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activemerchant
16
+ requirement: &70121469611100 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70121469611100
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &70121469610340 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70121469610340
36
+ - !ruby/object:Gem::Dependency
37
+ name: mocha
38
+ requirement: &70121469608900 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.11.3
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70121469608900
47
+ - !ruby/object:Gem::Dependency
48
+ name: rails
49
+ requirement: &70121469645180 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 2.3.11
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70121469645180
58
+ description: Fat Zebra support for Active Merchant - temporary gem until support is
59
+ combined into active_merchant core.
60
+ email:
61
+ - matthew.savage@fatzebra.com.au
62
+ executables: []
63
+ extensions: []
64
+ extra_rdoc_files: []
65
+ files:
66
+ - .gitignore
67
+ - ActiveMerchant-FatZebra.gemspec
68
+ - Gemfile
69
+ - README.md
70
+ - Rakefile
71
+ - lib/ActiveMerchant-FatZebra.rb
72
+ - lib/active_merchant/billing/gateways/fat_zebra.rb
73
+ - test/comm_stub.rb
74
+ - test/fixtures.yml
75
+ - test/remote/gateways/remote_fat_zebra_test.rb
76
+ - test/test_helper.rb
77
+ - test/unit/gateways/fat_zebra_test.rb
78
+ homepage: https://www.fatzebra.com.au
79
+ licenses: []
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ segments:
91
+ - 0
92
+ hash: 3400427441090863407
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ segments:
100
+ - 0
101
+ hash: 3400427441090863407
102
+ requirements: []
103
+ rubyforge_project: ActiveMerchant-FatZebra
104
+ rubygems_version: 1.8.10
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: Fat Zebra support for Active Merchant, as a gem
108
+ test_files:
109
+ - test/comm_stub.rb
110
+ - test/fixtures.yml
111
+ - test/remote/gateways/remote_fat_zebra_test.rb
112
+ - test/test_helper.rb
113
+ - test/unit/gateways/fat_zebra_test.rb