maxmind 0.4.2 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 86e1f00f56877745ccb1a9abb4def3a574ab5e39
4
+ data.tar.gz: 6cb391c94e902c903a4231c3760e49e0c1e45fe3
5
+ SHA512:
6
+ metadata.gz: fa6c8d0f6338fdf40e435fad867ac08d882bc96cdc547a25f393f59ffdf5359df1a5677c0eea7b53b8e51640b169afd953abbfbefda1264db6d3c301f3496930
7
+ data.tar.gz: 1ceffa7a4b3c2bac93c89f36a8912a85e39c2290cda325cc4438b6f3ca0033a1379924e2bbfe630e42c9f80182575cc1998f7a31933db2fbc4225621200c4c94
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - '1.8.7'
4
+ - '1.9.2'
5
+ - '1.9.3'
6
+
data/Gemfile CHANGED
@@ -1,2 +1,9 @@
1
- source :rubygems
2
- gemspec
1
+ source 'http://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'guard-rspec'
5
+ gem 'rake'
6
+ gem 'rdoc'
7
+ gem 'rspec'
8
+ gem 'mocha'
9
+ gem 'webmock'
data/Guardfile CHANGED
@@ -4,3 +4,25 @@ guard 'rspec', :version => 2, :cli => '--color --format doc' do
4
4
  watch('lib/eventricle.rb') { "spec/eventricle.rb" }
5
5
  watch('spec/spec_helper.rb') { "spec" }
6
6
  end
7
+
8
+ guard :rspec do
9
+ watch(%r{^spec/.+_spec\.rb$})
10
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
11
+ watch('spec/spec_helper.rb') { "spec" }
12
+
13
+ # Rails example
14
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
15
+ watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
16
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
17
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
18
+ watch('config/routes.rb') { "spec/routing" }
19
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
20
+
21
+ # Capybara features specs
22
+ watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
23
+
24
+ # Turnip features and steps
25
+ watch(%r{^spec/acceptance/(.+)\.feature$})
26
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
27
+ end
28
+
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Adam
1
+ Copyright (c) 2009 Adam Daniels
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -15,7 +15,7 @@ Tests
15
15
  ------------
16
16
 
17
17
  bundle install
18
- guard
18
+ bundle exec guard
19
19
 
20
20
  Dependencies
21
21
  ------------
@@ -27,7 +27,7 @@ Running Tests
27
27
 
28
28
  Run `bundle install` to make sure you have all the dependencies. Once that's done, run:
29
29
 
30
- rake test
30
+ rake spec
31
31
 
32
32
  Usage
33
33
  -----
@@ -104,9 +104,6 @@ This is every field available.
104
104
 
105
105
  response = request.process!
106
106
 
107
-
108
- Also see examples/example.rb
109
-
110
107
  TODO
111
108
  ----
112
109
  * Improve specs (eg, test server failover)
@@ -115,15 +112,58 @@ Reference
115
112
  ---------
116
113
  [minFraud API Reference](http://www.maxmind.com/app/ccv)
117
114
 
115
+ Also see examples/example.rb
116
+
117
+ Chargeback Service
118
+ ------------------
119
+
120
+ You can help improve the Minfraud service by reporting instances of fraud. Only the IP address of a suspected fraudulent order is required, but you can pass additional information. Note that your Maxmind User ID is required in addition to your license key.
121
+
122
+ Chargeback Service Usage
123
+ ------------------------
124
+
125
+ ### Minimum Required ###
126
+ These are the only required fields to acquire a response from MaxMind.
127
+
128
+ require 'maxmind'
129
+ Maxmind.license_key = 'LICENSE_KEY'
130
+ Maxmind.user_id = 'MAXMIND_USER_ID'
131
+ request = Maxmind::ChargebackRequest.new(
132
+ :client_ip => '24.24.24.24'
133
+ )
134
+
135
+ response = request.process!
136
+
137
+
138
+ ### Recommended ###
139
+ For increased accuracy, these are the recommended fields to submit to MaxMind. The additional
140
+ fields here are optional and can be all or none.
141
+
142
+ require 'maxmind'
143
+ Maxmind.license_key = 'LICENSE_KEY'
144
+ Maxmind.user_id = 'MAXMIND_USER_ID'
145
+ request = Maxmind::ChargebackRequest.new(
146
+ :client_ip => '24.24.24.24',
147
+ :chargeback_code => 'Fraud',
148
+ :fraud_score => 'suspected_fraud',
149
+ :maxmind_id => 'KW36L83C',
150
+ :transaction_id => '12345'
151
+ )
152
+
153
+ response = request.process!
154
+
155
+ [minFraud Chargeback reference](http://dev.maxmind.com/minfraud/chargeback)
156
+
118
157
  Contributors
119
158
  ------------
120
- Sam Oliver <sam@samoliver.com>
121
- Nick Wilson <nick@di.fm>
122
- Wolfram Arnold <wolfram@rubyfocus.biz>
123
- Jonathan Lim <snowblink@gmail.com>
124
- Tom Blomfield
125
- Thomas Morgan
126
- Tinu Cleatus <tinu.cleatus@me.com>
159
+ * Sam Oliver <sam@samoliver.com>
160
+ * Nick Wilson <nick@di.fm>
161
+ * Wolfram Arnold <wolfram@rubyfocus.biz>
162
+ * Jonathan Lim <snowblink@gmail.com>
163
+ * Tom Blomfield
164
+ * Thomas Morgan
165
+ * Tinu Cleatus <tinu.cleatus@me.com>
166
+ * Don Pflaster <dpflaster@gmail.com>
127
167
 
128
168
  Thanks to all :)
129
169
 
@@ -0,0 +1,20 @@
1
+ require 'pp'
2
+ require File.join(File.dirname(__FILE__), '..', 'lib/maxmind')
3
+
4
+ required_fields = {
5
+ :client_ip => '24.24.24.24'
6
+ }
7
+
8
+ recommended_fields = {
9
+ :client_ip => '24.24.24.24',
10
+ :chargeback_code => 'Fraud',
11
+ :fraud_score => 'suspected_fraud',
12
+ :maxmind_id => 'KW36L83C',
13
+ :transaction_id => '12345'
14
+ }
15
+
16
+ Maxmind.license_key = 'LICENSE_KEY'
17
+ Maxmind.user_id = 'MAXMIND_USER_ID'
18
+ request = Maxmind::ChargebackRequest.new(required_fields.merge(recommended_fields))
19
+ response = request.process!
20
+ pp response
@@ -1,11 +1,18 @@
1
- require 'active_support'
2
- unless Module.respond_to?(:mattr_accessor)
3
- require 'active_support/core_ext/module/attribute_accessors'# rescue nil # this may be needed for ActiveSupport versions >= 3.x
4
- end
5
- require 'active_support/core_ext/hash'
6
- require 'net/http'
7
1
  require 'net/https'
8
2
  require 'uri'
9
3
  require 'digest/md5'
10
- require File.join(File.dirname(__FILE__), 'maxmind/request')
11
- require File.join(File.dirname(__FILE__), 'maxmind/response')
4
+
5
+ require 'maxmind/version'
6
+ require 'maxmind/request'
7
+ require 'maxmind/chargeback_request'
8
+ require 'maxmind/chargeback_response'
9
+ require 'maxmind/response'
10
+
11
+ module Maxmind
12
+ SERVERS = %w(minfraud.maxmind.com minfraud-us-east.maxmind.com minfraud-us-west.maxmind.com)
13
+
14
+ class << self
15
+ attr_accessor :license_key
16
+ attr_accessor :user_id
17
+ end
18
+ end
@@ -0,0 +1,94 @@
1
+ module Maxmind
2
+ class ChargebackRequest
3
+ DefaultTimeout = 60
4
+
5
+ # optionally set a default request type (one of 'standard' or 'premium')
6
+ # Maxmind's default behavior is to use premium if you have credits, else use standard
7
+ class << self
8
+ attr_accessor :default_request_type
9
+ attr_accessor :timeout
10
+ end
11
+
12
+ # Required Fields
13
+ attr_accessor :client_ip
14
+
15
+ # Optional Fields
16
+ attr_accessor :chargeback_code, :fraud_score, :maxmind_id, :transaction_id
17
+
18
+ def initialize(attrs={})
19
+ self.attributes = attrs
20
+ end
21
+
22
+ def attributes=(attrs={})
23
+ attrs.each do |k, v|
24
+ self.send("#{k}=", v)
25
+ end
26
+ end
27
+
28
+ def process!
29
+ resp = post(query)
30
+ Maxmind::ChargebackResponse.new(resp.message, resp.code)
31
+ end
32
+
33
+ def process
34
+ process!
35
+ rescue Exception => e
36
+ false
37
+ end
38
+
39
+ def query
40
+ validate
41
+
42
+ required_fields = {
43
+ :ip_address => @client_ip,
44
+ }
45
+
46
+ optional_fields = {
47
+ :chargeback_code => @chargeback_code,
48
+ :fraud_score => @fraud_score,
49
+ :maxmind_id => @maxmind_id,
50
+ :transaction_id => @transaction_id
51
+ }
52
+
53
+ field_set = required_fields.merge(optional_fields)
54
+ field_set.reject {|k, v| v.nil? }.to_json
55
+ end
56
+
57
+ private
58
+
59
+ # Upon a failure at the first URL, will automatically retry with the
60
+ # second & third ones before finally raising an exception
61
+ # Returns an HTTPResponse object
62
+ def post(query_params)
63
+ servers ||= SERVERS.map{|hostname| "https://#{hostname}/minfraud/chargeback"}
64
+ url = URI.parse(servers.shift)
65
+
66
+ req = Net::HTTP::Post.new(url.path, initheader = {'Content-Type' =>'application/json'})
67
+ req.basic_auth Maxmind::user_id, Maxmind::license_key
68
+ req.body = query_params
69
+
70
+ h = Net::HTTP.new(url.host, url.port)
71
+ h.use_ssl = true
72
+ h.verify_mode = OpenSSL::SSL::VERIFY_NONE
73
+
74
+ # set some timeouts
75
+ h.open_timeout = 60 # this blocks forever by default, lets be a bit less crazy.
76
+ h.read_timeout = self.class.timeout || DefaultTimeout
77
+ h.ssl_timeout = self.class.timeout || DefaultTimeout
78
+
79
+ h.start { |http| http.request(req) }
80
+
81
+ rescue Exception => e
82
+ retry if servers.size > 0
83
+ raise e
84
+ end
85
+
86
+ protected
87
+
88
+ def validate
89
+ raise ArgumentError, 'License key is required' unless Maxmind::license_key
90
+ raise ArgumentError, 'User ID is required' unless Maxmind::user_id
91
+ raise ArgumentError, 'IP address is required' unless client_ip
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,12 @@
1
+ module Maxmind
2
+ class ChargebackResponse
3
+ attr_accessor :attributes
4
+ attr_reader :response, :http_code
5
+
6
+ def initialize(response = nil, http_code = nil)
7
+ raise ArgumentError, 'Missing response string' unless response
8
+ @response = response
9
+ @http_code = http_code.to_i if http_code
10
+ end
11
+ end
12
+ end
@@ -1,11 +1,4 @@
1
1
  module Maxmind
2
- # Your license key
3
- class << self
4
- attr_accessor :license_key
5
- end
6
-
7
- SERVERS = %w(minfraud.maxmind.com minfraud-us-east.maxmind.com minfraud-us-west.maxmind.com)
8
-
9
2
  class Request
10
3
  DefaultTimeout = 60
11
4
 
@@ -16,7 +9,6 @@ module Maxmind
16
9
  attr_accessor :timeout
17
10
  end
18
11
 
19
-
20
12
  # Required Fields
21
13
  attr_accessor :client_ip, :city, :region, :postal, :country
22
14
 
@@ -25,20 +17,18 @@ module Maxmind
25
17
  :forwarded_ip, :email, :username, :password, :transaction_id, :session_id,
26
18
  :shipping_address, :shipping_city, :shipping_region, :shipping_postal,
27
19
  :shipping_country, :user_agent, :accept_language, :order_amount,
28
- :order_currency
20
+ :order_currency, :avs_result, :cvv_result, :txn_type
29
21
 
30
22
  def initialize(attrs={})
31
23
  self.attributes = attrs
32
24
  end
33
25
 
34
-
35
26
  def attributes=(attrs={})
36
27
  attrs.each do |k, v|
37
28
  self.send("#{k}=", v)
38
29
  end
39
30
  end
40
31
 
41
-
42
32
  # email domain ... if a full email is provided, take just the domain portion
43
33
  def domain=(email)
44
34
  @domain = if email =~ /@(.+)/
@@ -51,16 +41,16 @@ module Maxmind
51
41
  # customer email ... sends just an MD5 hash of the email.
52
42
  # also sets the email domain at the same time.
53
43
  def email=(email)
54
- @email = Digest::MD5.hexdigest(email.downcase)
44
+ @email = md5_digest(email)
55
45
  self.domain = email unless domain
56
46
  end
57
47
 
58
48
  def username=(username)
59
- @username = Digest::MD5.hexdigest(username.downcase)
49
+ @username = md5_digest(username)
60
50
  end
61
51
 
62
52
  def password=(password)
63
- @password = Digest::MD5.hexdigest(password.downcase)
53
+ @password = md5_digest(password)
64
54
  end
65
55
 
66
56
  # if a full card number is passed, grab just the first 6 digits (which is the bank id number)
@@ -68,10 +58,10 @@ module Maxmind
68
58
  @bin = bin ? bin[0,6] : nil
69
59
  end
70
60
 
71
-
72
61
  def process!
73
62
  resp = post(query)
74
- Maxmind::Response.new(resp)
63
+ resp.body.encode!("utf-8", "iso-8859-1") if resp.body.respond_to?(:encode!)
64
+ Maxmind::Response.new(resp.body, resp.code)
75
65
  end
76
66
 
77
67
  def process
@@ -80,9 +70,6 @@ module Maxmind
80
70
  false
81
71
  end
82
72
 
83
-
84
- private
85
-
86
73
  def query
87
74
  validate
88
75
 
@@ -114,15 +101,22 @@ module Maxmind
114
101
  :txnID => @transaction_id,
115
102
  :sessionID => @session_id,
116
103
  :user_agent => @user_agent,
117
- :accept_language => @accept_langage
104
+ :accept_language => @accept_language,
105
+ :avs_result => @avs_result,
106
+ :cvv_result => @cvv_result,
107
+ :txn_type => @txn_type,
108
+ :order_amount => @order_amount
118
109
  }
119
110
 
120
111
  field_set = required_fields.merge(optional_fields)
121
112
  field_set.reject {|k, v| v.nil? }
122
113
  end
123
114
 
115
+ private
116
+
124
117
  # Upon a failure at the first URL, will automatically retry with the
125
118
  # second & third ones before finally raising an exception
119
+ # Returns an HTTPResponse object
126
120
  def post(query_params)
127
121
  servers ||= SERVERS.map{|hostname| "https://#{hostname}/app/ccv2r"}
128
122
  url = URI.parse(servers.shift)
@@ -139,13 +133,20 @@ module Maxmind
139
133
  h.read_timeout = self.class.timeout || DefaultTimeout
140
134
  h.ssl_timeout = self.class.timeout || DefaultTimeout
141
135
 
142
- response = h.start { |http| http.request(req) }
143
- response.body
136
+ h.start { |http| http.request(req) }
144
137
 
145
138
  rescue Exception => e
146
139
  retry if servers.size > 0
147
140
  raise e
148
141
  end
142
+
143
+ def md5_digest(value)
144
+ if value =~ /^[0-9a-f]{32}$/i
145
+ value
146
+ else
147
+ Digest::MD5.hexdigest(value.downcase)
148
+ end
149
+ end
149
150
 
150
151
  protected
151
152
  def validate
@@ -1,16 +1,20 @@
1
1
  module Maxmind
2
2
  class Response
3
3
  attr_accessor :attributes
4
+ attr_reader :body, :http_code
4
5
 
5
6
  ATTRIBUTE_MAP = {
6
7
  'custPhoneInBillingLoc' => 'phone_in_billing_location',
7
8
  'maxmindID' => 'maxmind_id',
8
9
  'isTransProxy' => 'is_transparent_proxy',
9
- 'err' => 'error'
10
+ 'err' => 'error',
11
+ 'carderEmail' => 'high_risk_email'
10
12
  }
11
13
 
12
- def initialize(response = nil)
14
+ def initialize(response = nil, http_code = nil)
13
15
  raise ArgumentError, 'Missing response string' unless response
16
+ @body = response
17
+ @http_code = http_code.to_i if http_code
14
18
  @attributes = {}
15
19
  parse(response)
16
20
  end
@@ -34,8 +38,8 @@ module Maxmind
34
38
  end
35
39
 
36
40
  def method_missing(meth, *args)
37
- if meth.to_s[-1] == '?'
38
- send(meth[0..-2])
41
+ if meth.to_s[-1, 1] == '?'
42
+ send(meth.to_s[0..-2])
39
43
  elsif attributes.has_key?(meth)
40
44
  attributes[meth]
41
45
  else
@@ -44,7 +48,7 @@ module Maxmind
44
48
  end
45
49
 
46
50
  def respond_to?(meth)
47
- if meth.to_s[-1] == '?'
51
+ if meth.to_s[-1, 1] == '?'
48
52
  respond_to? meth[0..-2]
49
53
  else
50
54
  super
@@ -64,13 +68,13 @@ module Maxmind
64
68
  v = Integer(v) rescue Float(v) rescue v;
65
69
 
66
70
  case v
67
- when /[Yy]es/
71
+ when 'Yes', 'yes'
68
72
  attributes[k] = true
69
- when /[Nn]o/
73
+ when 'No', 'no'
70
74
  attributes[k] = false
71
75
  else
72
76
  attributes[k] = v
73
77
  end
74
78
  end
75
79
  end
76
- end
80
+ end
@@ -1,3 +1,3 @@
1
1
  module Maxmind
2
- VERSION = '0.4.2'
3
- end
2
+ VERSION = '0.4.5'
3
+ end
@@ -3,28 +3,21 @@ $:.push File.expand_path('../lib', __FILE__)
3
3
  require 'maxmind/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
- s.name = "maxmind"
7
- s.version = Maxmind::VERSION
6
+ s.name = "maxmind"
7
+ s.version = Maxmind::VERSION
8
8
 
9
- s.authors = ["Adam Daniels", "Tinu Cleatus", "t.e.morgan", "Sam Oliver"]
10
- s.date = "2012-01-06"
11
- s.description = "A wrapper around MaxMind's minFraud anti-fraud service. \n\nhttp://www.maxmind.com/app/ccv_overview\n"
12
- s.email = "adam@mediadrive.ca"
9
+ s.authors = ["Adam Daniels"]
10
+ s.description = "A wrapper around MaxMind's minFraud anti-fraud service. \n\nhttp://www.maxmind.com/app/ccv_overview\n"
11
+ s.email = "adam@mediadrive.ca"
13
12
  s.extra_rdoc_files = [
14
13
  "LICENSE",
15
14
  "README.md"
16
15
  ]
17
-
18
- s.files = `git ls-files`.split("\n")
19
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
- s.homepage = "http://github.com/adam12/maxmind"
21
- s.require_paths = ["lib"]
22
- s.summary = "Wrapper for MaxMind's minFraud service"
23
16
 
24
- s.add_development_dependency 'rspec'
25
- s.add_development_dependency 'mocha'
26
- s.add_development_dependency 'webmock'
27
-
28
- s.add_runtime_dependency 'active_support', '>= 3.0.0'
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.homepage = "http://github.com/adam12/maxmind"
20
+ s.require_paths = ["lib"]
21
+ s.summary = "Wrapper for MaxMind's minFraud service"
22
+ s.license = 'MIT'
29
23
  end
30
-
@@ -1 +1 @@
1
- distance=329;countryMatch=Yes;countryCode=US;freeMail=Yes;anonymousProxy=No;score=7.66;binMatch=Yes;binCountry=US;err=;proxyScore=0.00;ip_region=NY;ip_city=Syracuse;ip_latitude=43.0514;ip_longitude=-76.1495;binName=;ip_isp=Road Runner;ip_org=Road Runner;binNameMatch=Yes;binPhoneMatch=Yes;binPhone=;custPhoneInBillingLoc=No;highRiskCountry=No;queriesRemaining=955;cityPostalMatch=No;shipCityPostalMatch=Yes;maxmindID=9VSOSDE2;isTransProxy=No;carderEmail=No;shipForward=Yes;highRiskUsername=No;highRiskPassword=No;riskScore=2.00;explanation=This order is very high risk, and we suggest you not accept it. This order is considered to be very slightly higher risk because the distance between the billing address and the user's actual location is larger than expected. The order is slightly riskier because the e-mail domain, yahoo.com, is a free e-mail provider. The order is slightly riskier because the phone number supplied by the user is not located within the zip code of the billing address for the credit card. The order is riskier because the shipping address given is a mail forwarding address, so there is no way to know where the products are actually going
1
+ distance=329;countryMatch=Yes;countryCode=US;freeMail=Yes;anonymousProxy=No;score=7.66;binMatch=Yes;binCountry=US;err=;proxyScore=0.00;ip_region=NY;ip_city=Syracuse;ip_latitude=43.0514;ip_longitude=-76.1495;binName=;ip_isp=Road Runnere�;ip_org=Road Runner;binNameMatch=Yes;binPhoneMatch=Yes;binPhone=;custPhoneInBillingLoc=No;highRiskCountry=No;queriesRemaining=955;cityPostalMatch=No;shipCityPostalMatch=Yes;maxmindID=9VSOSDE2;isTransProxy=No;carderEmail=Yes;shipForward=Yes;highRiskUsername=No;highRiskPassword=No;riskScore=2.00;explanation=This order is very high risk, and we suggest you not accept it. This order is considered to be very slightly higher risk because the distance between the billing address and the user's actual location is larger than expected. The order is slightly riskier because the e-mail domain, yahoo.com, is a free e-mail provider. The order is slightly riskier because the phone number supplied by the user is not located within the zip code of the billing address for the credit card. The order is riskier because the shipping address given is a mail forwarding address, so there is no way to know where the products are actually going
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Maxmind::ChargebackRequest do
4
+ before do
5
+ Maxmind.user_id = 'user'
6
+ Maxmind.license_key = 'key'
7
+ @request = Maxmind::ChargebackRequest.new(:client_ip => '198.51.100.2')
8
+ end
9
+
10
+ it "requires a License Key" do
11
+ Maxmind.license_key = nil
12
+ expect { @request.send(:validate) }.to raise_error(ArgumentError)
13
+ Maxmind.license_key = 'key'
14
+ end
15
+
16
+ it "requires a User ID" do
17
+ Maxmind.user_id = nil
18
+ expect { @request.send(:validate) }.to raise_error(ArgumentError)
19
+ Maxmind.user_id = 'user'
20
+ end
21
+
22
+ it "requires a client IP" do
23
+ @request.client_ip = nil
24
+ expect { @request.send(:validate) }.to raise_error(ArgumentError)
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Maxmind::ChargebackResponse do
4
+ before do
5
+ Maxmind.user_id = 'USER_ID'
6
+ Maxmind.license_key = 'LICENSE_KEY'
7
+
8
+ request = Maxmind::ChargebackRequest.new(:client_ip => '198.51.100.2')
9
+ stub_request(:post, "https://USER_ID:LICENSE_KEY@minfraud.maxmind.com/minfraud/chargeback").
10
+ to_return(:body => '', :status => 200)
11
+ @response = request.process!
12
+ end
13
+
14
+ it "requires a response" do
15
+ expect { Maxmind::ChargebackResponse.new }.to raise_exception(ArgumentError)
16
+ end
17
+
18
+ it "exposes the http response code" do
19
+ expect(@response.http_code).to eq 200
20
+ end
21
+
22
+ it "exposes the http response" do
23
+ expect(@response.response).to_not be_nil
24
+ end
25
+ end
@@ -47,4 +47,24 @@ describe Maxmind::Request do
47
47
  @request.email = 'test@test.com'
48
48
  @request.email.should == 'b642b4217b34b1e8d3bd915fc65c4452'
49
49
  end
50
- end
50
+
51
+ it "does not double convert an md5 username" do
52
+ @request.username = 'b642b4217b34b1e8d3bd915fc65c4452'
53
+ @request.username.should == 'b642b4217b34b1e8d3bd915fc65c4452'
54
+ end
55
+
56
+ it "does not double convert an md5 password" do
57
+ @request.password = 'b642b4217b34b1e8d3bd915fc65c4452'
58
+ @request.password.should == 'b642b4217b34b1e8d3bd915fc65c4452'
59
+ end
60
+
61
+ it "does not double convert an md5 email" do
62
+ @request.email = 'b642b4217b34b1e8d3bd915fc65c4452'
63
+ @request.email.should == 'b642b4217b34b1e8d3bd915fc65c4452'
64
+ end
65
+
66
+ it "exposes the query parameters" do
67
+ @request.query.should be_a Hash
68
+ end
69
+
70
+ end
@@ -1,11 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- REQUIRED_FIELDS =
4
-
5
- RECOMMENDED_FIELDS =
6
-
7
- OPTIONAL_FIELDS =
8
-
9
3
  describe Maxmind::Response do
10
4
  before do
11
5
  Maxmind.license_key = 'LICENSE_KEY'
@@ -14,10 +8,12 @@ describe Maxmind::Response do
14
8
  recommended_fields = JSON.parse(load_fixture("recommended_fields.json"))
15
9
  optional_fields = JSON.parse(load_fixture("optional_fields.json"))
16
10
  all_fields = required_fields.merge(recommended_fields).merge(optional_fields)
11
+ @response_body = load_fixture("response.txt")
12
+ @response_body.encode!("utf-8", "iso-8859-1") if @response_body.respond_to?(:encode!)
17
13
 
18
14
  request = Maxmind::Request.new(all_fields)
19
15
  stub_request(:post, "https://minfraud.maxmind.com/app/ccv2r").
20
- to_return(:body => load_fixture("response.txt"), :status => 200)
16
+ to_return(:body => @response_body, :status => 200)
21
17
  @response = request.process!
22
18
  end
23
19
 
@@ -28,6 +24,14 @@ describe Maxmind::Response do
28
24
  it "exposes its attributes" do
29
25
  @response.attributes.should be_a Hash
30
26
  end
27
+
28
+ it "exposes the raw response body" do
29
+ @response.body.should == @response_body
30
+ end
31
+
32
+ it "exposes the http response code" do
33
+ @response.http_code.should == 200
34
+ end
31
35
 
32
36
  it "has a distance" do
33
37
  @response.distance.should == 329
@@ -50,7 +54,7 @@ describe Maxmind::Response do
50
54
  end
51
55
 
52
56
  it "has an explanation" do
53
- @response.explanation.should_not == nil
57
+ @response.explanation.should be_a String
54
58
  end
55
59
 
56
60
  it "has a country match" do
@@ -69,4 +73,8 @@ describe Maxmind::Response do
69
73
  it "has a phone in billing location ? method" do
70
74
  @response.phone_in_billing_location?.should == false
71
75
  end
72
- end
76
+
77
+ it "has a high risk email" do
78
+ @response.high_risk_email.should == true
79
+ end
80
+ end
@@ -1,4 +1,7 @@
1
- require 'mocha_standalone'
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'mocha/api'
2
5
  require 'maxmind'
3
6
  require 'json'
4
7
  require 'webmock/rspec'
@@ -7,24 +10,12 @@ RSpec.configure do |config|
7
10
 
8
11
  config.before(:suite) do
9
12
  # Disable all live HTTP requests
10
- WebMock.disable_net_connect!(allow_localhost: true)
13
+ WebMock.disable_net_connect!(:allow_localhost => true)
11
14
  end
12
15
 
13
16
  config.mock_with :mocha
14
17
  end
15
18
 
16
- # Constants (classes, etc) defined within a block passed to this method
17
- # will be removed from the global namespace after the block as run.
18
- def isolate_constants
19
- existing_constants = Object.constants
20
- yield
21
- ensure
22
- (Object.constants - existing_constants).each do |constant|
23
- Object.send(:remove_const, constant)
24
- end
25
- end
26
-
27
-
28
19
  def load_fixture(*filename)
29
20
  File.open(File.join('spec', 'data', *filename)).read
30
21
  end
metadata CHANGED
@@ -1,84 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maxmind
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
5
- prerelease:
4
+ version: 0.4.5
6
5
  platform: ruby
7
6
  authors:
8
7
  - Adam Daniels
9
- - Tinu Cleatus
10
- - t.e.morgan
11
- - Sam Oliver
12
8
  autorequire:
13
9
  bindir: bin
14
10
  cert_chain: []
15
- date: 2012-01-06 00:00:00.000000000 Z
16
- dependencies:
17
- - !ruby/object:Gem::Dependency
18
- name: rspec
19
- requirement: !ruby/object:Gem::Requirement
20
- none: false
21
- requirements:
22
- - - ! '>='
23
- - !ruby/object:Gem::Version
24
- version: '0'
25
- type: :development
26
- prerelease: false
27
- version_requirements: !ruby/object:Gem::Requirement
28
- none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0'
33
- - !ruby/object:Gem::Dependency
34
- name: mocha
35
- requirement: !ruby/object:Gem::Requirement
36
- none: false
37
- requirements:
38
- - - ! '>='
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- type: :development
42
- prerelease: false
43
- version_requirements: !ruby/object:Gem::Requirement
44
- none: false
45
- requirements:
46
- - - ! '>='
47
- - !ruby/object:Gem::Version
48
- version: '0'
49
- - !ruby/object:Gem::Dependency
50
- name: webmock
51
- requirement: !ruby/object:Gem::Requirement
52
- none: false
53
- requirements:
54
- - - ! '>='
55
- - !ruby/object:Gem::Version
56
- version: '0'
57
- type: :development
58
- prerelease: false
59
- version_requirements: !ruby/object:Gem::Requirement
60
- none: false
61
- requirements:
62
- - - ! '>='
63
- - !ruby/object:Gem::Version
64
- version: '0'
65
- - !ruby/object:Gem::Dependency
66
- name: active_support
67
- requirement: !ruby/object:Gem::Requirement
68
- none: false
69
- requirements:
70
- - - ! '>='
71
- - !ruby/object:Gem::Version
72
- version: 3.0.0
73
- type: :runtime
74
- prerelease: false
75
- version_requirements: !ruby/object:Gem::Requirement
76
- none: false
77
- requirements:
78
- - - ! '>='
79
- - !ruby/object:Gem::Version
80
- version: 3.0.0
81
- description: ! "A wrapper around MaxMind's minFraud anti-fraud service. \n\nhttp://www.maxmind.com/app/ccv_overview\n"
11
+ date: 2013-09-27 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: "A wrapper around MaxMind's minFraud anti-fraud service. \n\nhttp://www.maxmind.com/app/ccv_overview\n"
82
14
  email: adam@mediadrive.ca
83
15
  executables: []
84
16
  extensions: []
@@ -87,13 +19,17 @@ extra_rdoc_files:
87
19
  - README.md
88
20
  files:
89
21
  - .gitignore
22
+ - .travis.yml
90
23
  - Gemfile
91
24
  - Guardfile
92
25
  - LICENSE
93
26
  - README.md
94
27
  - Rakefile
28
+ - examples/chargeback_example.rb
95
29
  - examples/example.rb
96
30
  - lib/maxmind.rb
31
+ - lib/maxmind/chargeback_request.rb
32
+ - lib/maxmind/chargeback_response.rb
97
33
  - lib/maxmind/request.rb
98
34
  - lib/maxmind/response.rb
99
35
  - lib/maxmind/version.rb
@@ -102,44 +38,42 @@ files:
102
38
  - spec/data/recommended_fields.json
103
39
  - spec/data/required_fields.json
104
40
  - spec/data/response.txt
41
+ - spec/maxmind/chargeback_request_spec.rb
42
+ - spec/maxmind/chargeback_response_spec.rb
105
43
  - spec/maxmind/request_spec.rb
106
44
  - spec/maxmind/response_spec.rb
107
45
  - spec/spec_helper.rb
108
46
  homepage: http://github.com/adam12/maxmind
109
- licenses: []
47
+ licenses:
48
+ - MIT
49
+ metadata: {}
110
50
  post_install_message:
111
51
  rdoc_options: []
112
52
  require_paths:
113
53
  - lib
114
54
  required_ruby_version: !ruby/object:Gem::Requirement
115
- none: false
116
55
  requirements:
117
- - - ! '>='
56
+ - - '>='
118
57
  - !ruby/object:Gem::Version
119
58
  version: '0'
120
- segments:
121
- - 0
122
- hash: -1867686245011996081
123
59
  required_rubygems_version: !ruby/object:Gem::Requirement
124
- none: false
125
60
  requirements:
126
- - - ! '>='
61
+ - - '>='
127
62
  - !ruby/object:Gem::Version
128
63
  version: '0'
129
- segments:
130
- - 0
131
- hash: -1867686245011996081
132
64
  requirements: []
133
65
  rubyforge_project:
134
- rubygems_version: 1.8.21
66
+ rubygems_version: 2.0.7
135
67
  signing_key:
136
- specification_version: 3
68
+ specification_version: 4
137
69
  summary: Wrapper for MaxMind's minFraud service
138
70
  test_files:
139
71
  - spec/data/optional_fields.json
140
72
  - spec/data/recommended_fields.json
141
73
  - spec/data/required_fields.json
142
74
  - spec/data/response.txt
75
+ - spec/maxmind/chargeback_request_spec.rb
76
+ - spec/maxmind/chargeback_response_spec.rb
143
77
  - spec/maxmind/request_spec.rb
144
78
  - spec/maxmind/response_spec.rb
145
79
  - spec/spec_helper.rb