leadspend 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/.autotest +23 -0
- data/.gemtest +0 -0
- data/History.txt +14 -0
- data/Manifest.txt +14 -0
- data/README.txt +59 -0
- data/Rakefile +17 -0
- data/lib/leadspend.rb +18 -0
- data/lib/leadspend/client.rb +138 -0
- data/lib/leadspend/exceptions.rb +13 -0
- data/lib/leadspend/parser/json_parser.rb +12 -0
- data/lib/leadspend/parser/rails_parser.rb +15 -0
- data/lib/leadspend/parser/yajl_parser.rb +14 -0
- data/lib/leadspend/result.rb +89 -0
- data/test/mocks/leadspend/server.rb +82 -0
- data/test/unit/test_leadspend_client.rb +100 -0
- metadata +133 -0
- metadata.gz.sig +4 -0
data.tar.gz.sig
ADDED
Binary file
|
data/.autotest
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'autotest/restart'
|
4
|
+
|
5
|
+
# Autotest.add_hook :initialize do |at|
|
6
|
+
# at.extra_files << "../some/external/dependency.rb"
|
7
|
+
#
|
8
|
+
# at.libs << ":../some/external"
|
9
|
+
#
|
10
|
+
# at.add_exception 'vendor'
|
11
|
+
#
|
12
|
+
# at.add_mapping(/dependency.rb/) do |f, _|
|
13
|
+
# at.files_matching(/test_.*rb$/)
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# %w(TestA TestB).each do |klass|
|
17
|
+
# at.extra_class_map[klass] = "test/test_misc.rb"
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
# Autotest.add_hook :run_command do |at|
|
22
|
+
# system "rake build"
|
23
|
+
# end
|
data/.gemtest
ADDED
File without changes
|
data/History.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
=== 1.0.2 / 2012-08-23
|
2
|
+
* Moved username and password into options for client initialization
|
3
|
+
|
4
|
+
=== 1.0.1 / 2012-08-23
|
5
|
+
* Added configurable JSON backends with reasonable defaults
|
6
|
+
* to use a particular backend, the supporting gem(s) must be installed (Yajl, JSON, Rails)
|
7
|
+
* Added support for the "role", "timeout", "retry" extended attributes on results
|
8
|
+
* Now using Hoe for gemspec
|
9
|
+
* Added MIT-LICENSE
|
10
|
+
|
11
|
+
=== 1.0.0 / 2012-08-22
|
12
|
+
* Support for Leadspend API according to their spec documentation.
|
13
|
+
* unit tests require the fakeweb gem.
|
14
|
+
|
data/Manifest.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
.autotest
|
2
|
+
History.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
lib/leadspend.rb
|
7
|
+
lib/leadspend/exceptions.rb
|
8
|
+
lib/leadspend/result.rb
|
9
|
+
lib/leadspend/client.rb
|
10
|
+
lib/leadspend/parser/json_parser.rb
|
11
|
+
lib/leadspend/parser/yajl_parser.rb
|
12
|
+
lib/leadspend/parser/rails_parser.rb
|
13
|
+
test/unit/test_leadspend_client.rb
|
14
|
+
test/mocks/leadspend/server.rb
|
data/README.txt
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
= leadspend
|
2
|
+
|
3
|
+
* http://www.github.com/justindossey/leadspend
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
Leadspend client access library.
|
7
|
+
|
8
|
+
== SYNOPSIS:
|
9
|
+
|
10
|
+
client = Leadspend::Client.new(:username => LEADSPEND_USERNAME,
|
11
|
+
:password => LEADSPEND_PASSWORD,
|
12
|
+
:ca_file => CA_FILE,
|
13
|
+
:timeout => 5)
|
14
|
+
is_valid_email = client.validate(params[:email]) # true if verified or unknown, false otherwise
|
15
|
+
|
16
|
+
== REQUIREMENTS:
|
17
|
+
|
18
|
+
* Ruby (of course) with OpenSSL support
|
19
|
+
* Your preferred JSON gem (json, yajl), or ActiveSupport if you use Rails
|
20
|
+
* FakeWeb for testing: https://github.com/chrisk/fakeweb
|
21
|
+
* Hoe for building the gem
|
22
|
+
|
23
|
+
== INSTALL:
|
24
|
+
|
25
|
+
* sudo gem install leadspend
|
26
|
+
|
27
|
+
== DEVELOPERS
|
28
|
+
|
29
|
+
Read the source!
|
30
|
+
After checking out the source, run:
|
31
|
+
|
32
|
+
$ rake newb
|
33
|
+
|
34
|
+
This task will install any missing dependencies, run the tests/specs,
|
35
|
+
and generate the RDoc.
|
36
|
+
|
37
|
+
(The MIT License)
|
38
|
+
|
39
|
+
Copyright (c) 2012 Justin Dossey.
|
40
|
+
|
41
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
42
|
+
a copy of this software and associated documentation files (the
|
43
|
+
'Software'), to deal in the Software without restriction, including
|
44
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
45
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
46
|
+
permit persons to whom the Software is furnished to do so, subject to
|
47
|
+
the following conditions:
|
48
|
+
|
49
|
+
The above copyright notice and this permission notice shall be
|
50
|
+
included in all copies or substantial portions of the Software.
|
51
|
+
|
52
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
53
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
54
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
55
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
56
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
57
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
58
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
59
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
|
6
|
+
# Hoe.plugin :compiler
|
7
|
+
# Hoe.plugin :gem_prelude_sucks
|
8
|
+
# Hoe.plugin :inline
|
9
|
+
# Hoe.plugin :racc
|
10
|
+
# Hoe.plugin :rcov
|
11
|
+
# Hoe.plugin :rubyforge
|
12
|
+
|
13
|
+
Hoe.spec 'leadspend' do
|
14
|
+
developer('Justin Dossey', 'jbd@podomatic.com')
|
15
|
+
end
|
16
|
+
|
17
|
+
# vim: syntax=ruby
|
data/lib/leadspend.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
##
|
2
|
+
# Leadspend API implementation for Ruby
|
3
|
+
# = Leadspend
|
4
|
+
# This (top-level) module contains constants based on the API specification.
|
5
|
+
module Leadspend
|
6
|
+
VERSION = '1.0.2'
|
7
|
+
DEFAULT_SERVERS = %w{primary.api.leadspend.com secondary.api.leadspend.com}
|
8
|
+
DEFAULT_VERSION = "v2"
|
9
|
+
MIN_TIMEOUT = 3
|
10
|
+
MAX_TIMEOUT = 15
|
11
|
+
RESULT_STATUSES = ['unknown','verified','disposable', 'unreachable', 'undeliverable', 'illegitimate']
|
12
|
+
end
|
13
|
+
require "#{File.dirname(__FILE__)}/leadspend/exceptions"
|
14
|
+
require "#{File.dirname(__FILE__)}/leadspend/parser"
|
15
|
+
require "#{File.dirname(__FILE__)}/leadspend/result"
|
16
|
+
require "#{File.dirname(__FILE__)}/leadspend/client"
|
17
|
+
|
18
|
+
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
##
|
3
|
+
# = Leadspend Client
|
4
|
+
# The primary interface to Leadspend.
|
5
|
+
# Use it like so:
|
6
|
+
# client = Leadspend::Client.new(LEADSPEND_USERNAME, LEADSPEND_PASSWORD, :ca_file => CA_FILE, :timeout => 5)
|
7
|
+
# is_valid_email = client.validate(params[:email) # true if verified or unknown, false otherwise
|
8
|
+
# If you want more information about the response, use something like
|
9
|
+
# leadspend_result = client.fetch_result(params[:email])
|
10
|
+
# This will return a Leadspend::Result object representing the JSON response,
|
11
|
+
# with convenience methods like unreachable? and illegitimate?.
|
12
|
+
|
13
|
+
class Leadspend::Client
|
14
|
+
# Instantiate a client.
|
15
|
+
# Recommended options: :ca_file is the full path to a CA Cert file.
|
16
|
+
# :timeout is the server-side timeout in seconds, between 3 and 15. If a
|
17
|
+
# result is not available within the timeout, the response will be an
|
18
|
+
# "unknown" result.
|
19
|
+
def initialize(opts={})
|
20
|
+
options = opts
|
21
|
+
if defined?(HashWithIndifferentAccess)
|
22
|
+
options = HashWithIndifferentAccess.new(opts)
|
23
|
+
end
|
24
|
+
@username = options[:username]
|
25
|
+
@password = options[:password]
|
26
|
+
if @username.nil? or @password.nil?
|
27
|
+
raise Leadspend::Exceptions::LeadspendException, "No username or password specified!"
|
28
|
+
end
|
29
|
+
@servers = options[:servers] || Leadspend::DEFAULT_SERVERS
|
30
|
+
@api_version = options[:version] || Leadspend::DEFAULT_VERSION
|
31
|
+
# path to the CA file: download http://curl.haxx.se/ca/cacert.pem and put
|
32
|
+
# it someplace on your server.
|
33
|
+
@ca_file = options[:ca_file]
|
34
|
+
|
35
|
+
# set the JSON parser to use. Use the one specified, or choose a reasonable default.
|
36
|
+
case options[:json_parser]
|
37
|
+
when 'yajl'
|
38
|
+
require "#{File.dirname(__FILE__)}/parser/yajl_parser"
|
39
|
+
Leadspend::Result.json_parser=Leadspend::Parser::YajlParser
|
40
|
+
when 'rails'
|
41
|
+
require "#{File.dirname(__FILE__)}/parser/rails_parser"
|
42
|
+
Leadspend::Result.json_parser=Leadspend::Parser::RailsParser
|
43
|
+
when 'json'
|
44
|
+
require "#{File.dirname(__FILE__)}/parser/json_parser"
|
45
|
+
Leadspend::Result.json_parser=Leadspend::Parser::JSONParser
|
46
|
+
else
|
47
|
+
if defined? Rails
|
48
|
+
require "#{File.dirname(__FILE__)}/parser/rails_parser"
|
49
|
+
Leadspend::Result.json_parser=Leadspend::Parser::RailsParser
|
50
|
+
else
|
51
|
+
require "#{File.dirname(__FILE__)}/parser/json_parser"
|
52
|
+
Leadspend::Result.json_parser=Leadspend::Parser::JSONParser
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
@server_index = 0
|
57
|
+
|
58
|
+
@request_options = {}
|
59
|
+
# optional: allow a server timeout. Minimum is 3, max is 15
|
60
|
+
if options[:timeout]
|
61
|
+
@request_options[:timeout] = options[:timeout].to_i
|
62
|
+
if @request_options[:timeout] < Leadspend::MIN_TIMEOUT
|
63
|
+
@request_options[:timeout] = Leadspend::MIN_TIMEOUT
|
64
|
+
elsif @request_options[:timeout] > Leadspend::MAX_TIMEOUT
|
65
|
+
@request_options[:timeout] = Leadspend::MAX_TIMEOUT
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Return a boolean based on whether an address is valid or not.
|
71
|
+
# Valid statuses: unknown, validated.
|
72
|
+
# Invalid statuses: anything else.
|
73
|
+
def validate(address)
|
74
|
+
result = fetch_result(address)
|
75
|
+
return result.verified? || result.unknown?
|
76
|
+
end
|
77
|
+
|
78
|
+
# fetch a result from Leadspend, doing failover if necessary. R
|
79
|
+
# Returns a Leadspend::Result object if successful, or an exception if there was a failure.
|
80
|
+
def fetch_result(address)
|
81
|
+
retry_once = true
|
82
|
+
begin
|
83
|
+
result = query("/#{@api_version}/validity", address, @request_options)
|
84
|
+
rescue Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::ECONNRESET, IOError,
|
85
|
+
Leadspend::Exceptions::ServerException, Leadspend::Exceptions::ServerBusyException
|
86
|
+
if retry_once
|
87
|
+
retry_once = false
|
88
|
+
@server_index = (@server_index + 1) % @servers.length
|
89
|
+
retry
|
90
|
+
else
|
91
|
+
raise $!
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
# do a full uri escape on a value for HTTP
|
98
|
+
def escape_param(param) # :nodoc:
|
99
|
+
URI::escape(param.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
100
|
+
end
|
101
|
+
|
102
|
+
# Do a request to Leadspend and return a Leadspend::Result or exception.
|
103
|
+
def query(base, address, param_hash) # :nodoc:
|
104
|
+
http = Net::HTTP.new(@servers[@server_index], 443)
|
105
|
+
http.use_ssl = true
|
106
|
+
if @ca_file
|
107
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
108
|
+
http.ca_file = @ca_file
|
109
|
+
end
|
110
|
+
if param_hash.empty?
|
111
|
+
request_path = [base, escape_param(address)].join('/')
|
112
|
+
else
|
113
|
+
param_str = param_hash.map{|k,v| [k.to_s, escape_param(v)].join('=')}.join('&')
|
114
|
+
request_path = [[base, escape_param(address)].join('/'), param_str].join('?')
|
115
|
+
end
|
116
|
+
http.start do
|
117
|
+
request = Net::HTTP::Get.new(request_path)
|
118
|
+
request.basic_auth @username, @password
|
119
|
+
response = http.request(request)
|
120
|
+
case response.code.to_i
|
121
|
+
when 200
|
122
|
+
return Leadspend::Result.new(response.body)
|
123
|
+
when 202
|
124
|
+
return Leadspend::Result.unknown(address)
|
125
|
+
when 400
|
126
|
+
raise Leadspend::Exceptions::BadRequestException, response.body
|
127
|
+
when 401
|
128
|
+
raise Leadspend::Exceptions::UnauthorizedRequestException, response.body
|
129
|
+
when 500
|
130
|
+
raise Leadspend::Exceptions::ServerException, response.body
|
131
|
+
when 503
|
132
|
+
raise Leadspend::Exceptions::ServerBusyException, response.body
|
133
|
+
else
|
134
|
+
raise Leadspend::Exceptions::UnknownResponseException, response.body
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
##
|
2
|
+
# = Leadspend Exceptions.
|
3
|
+
# The status code from the Leadspend server determines which exception is raised by the client.
|
4
|
+
module Leadspend
|
5
|
+
module Exceptions
|
6
|
+
class LeadspendException < Exception; end
|
7
|
+
class BadRequestException < LeadspendException ; end
|
8
|
+
class UnknownResponseException < LeadspendException ; end
|
9
|
+
class UnauthorizedRequestException < LeadspendException ; end
|
10
|
+
class ServerException < LeadspendException; end
|
11
|
+
class ServerBusyException < LeadspendException ; end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Leadspend::Result
|
4
|
+
@@json_parser=nil
|
5
|
+
def initialize(json_string)
|
6
|
+
@raw = json_string
|
7
|
+
@result = self.class.decode_json(json_string)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.json_parser=(p)
|
11
|
+
@@json_parser = p
|
12
|
+
end
|
13
|
+
|
14
|
+
def raw
|
15
|
+
@raw
|
16
|
+
end
|
17
|
+
|
18
|
+
def result
|
19
|
+
@result['result']
|
20
|
+
end
|
21
|
+
|
22
|
+
Leadspend::RESULT_STATUSES.each do |status|
|
23
|
+
define_method("#{status}?") { result == status }
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.method_missing(meth, *args, &block)
|
27
|
+
if Leadspend::RESULT_STATUSES.index(meth.to_s)
|
28
|
+
generate_result(meth.to_s, *args)
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.respond_to?(meth)
|
35
|
+
Leadspend::RESULT_STATUSES.include?(meth.to_s) || super
|
36
|
+
end
|
37
|
+
|
38
|
+
def ==(other)
|
39
|
+
other.is_a?(Leadspend::Result) and other.address == self.address and other.result == self.result
|
40
|
+
end
|
41
|
+
|
42
|
+
def address
|
43
|
+
@result['address']
|
44
|
+
end
|
45
|
+
|
46
|
+
# extended attributes
|
47
|
+
|
48
|
+
def role?
|
49
|
+
result['role']
|
50
|
+
end
|
51
|
+
|
52
|
+
def full?
|
53
|
+
undeliverable? and result['full']
|
54
|
+
end
|
55
|
+
|
56
|
+
def timeout?
|
57
|
+
unknown? and result['timeout']
|
58
|
+
end
|
59
|
+
|
60
|
+
def retry_seconds
|
61
|
+
unknown? and result['retry']
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
private
|
66
|
+
def self.generate_result(status, address, opts={})
|
67
|
+
new(encode_json({'result' => status, 'address' => address}.merge(opts)))
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.decode_json(json_string)
|
71
|
+
json_parser.decode(json_string)
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.encode_json(object)
|
75
|
+
json_parser.encode(object)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.json_parser
|
79
|
+
if @@json_parser.nil?
|
80
|
+
unless defined?(Leadspend::Parser::JSONParser)
|
81
|
+
require "#{File.dirname(__FILE__)}/parser/json_parser"
|
82
|
+
end
|
83
|
+
@@json_parser = Leadspend::Parser::JSONParser
|
84
|
+
end
|
85
|
+
@@json_parser
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'fakeweb'
|
3
|
+
require "#{File.dirname(__FILE__)}/../../../init"
|
4
|
+
class Leadspend::Server
|
5
|
+
def initialize(opts={})
|
6
|
+
@username = opts[:username]
|
7
|
+
@password = opts[:password]
|
8
|
+
options = opts
|
9
|
+
@servers = options[:servers] || Leadspend::DEFAULT_SERVERS
|
10
|
+
@api_version = options[:version] || Leadspend::DEFAULT_VERSION
|
11
|
+
FakeWeb.allow_net_connect = false
|
12
|
+
register_all_urls
|
13
|
+
end
|
14
|
+
|
15
|
+
def unregister_all_urls
|
16
|
+
FakeWeb.clean_registry
|
17
|
+
end
|
18
|
+
|
19
|
+
def register_all_urls
|
20
|
+
@servers.each do |server|
|
21
|
+
Leadspend::RESULT_STATUSES.each do |status|
|
22
|
+
|
23
|
+
http_status = [200, 'OK']
|
24
|
+
email = "#{status}-#{http_status.first}@example.com"
|
25
|
+
#$stderr.puts("Registering #{url_for(server, email)}")
|
26
|
+
FakeWeb.register_uri(:get, url_for(server, email),
|
27
|
+
:body => Leadspend::Result.send(status, email).raw,
|
28
|
+
:status => http_status)
|
29
|
+
[Leadspend::MIN_TIMEOUT, Leadspend::MAX_TIMEOUT, (Leadspend::MIN_TIMEOUT-1), (Leadspend::MAX_TIMEOUT+1)].each do |timeout|
|
30
|
+
#$stderr.puts("Registering #{url_for(server, email, :timeout => timeout)}")
|
31
|
+
FakeWeb.register_uri(:get, url_for(server, email, :timeout => timeout),
|
32
|
+
:body => Leadspend::Result.send(status, email).raw,
|
33
|
+
:status => http_status)
|
34
|
+
end
|
35
|
+
|
36
|
+
# non-200 statuses
|
37
|
+
|
38
|
+
# for 202, have it be "unknown".
|
39
|
+
http_status = [202, 'Accepted']
|
40
|
+
email = "#{status}-#{http_status.first}@example.com"
|
41
|
+
FakeWeb.register_uri(:get, url_for(server, email),
|
42
|
+
:body => Leadspend::Result.unknown(email).raw,
|
43
|
+
:status => http_status)
|
44
|
+
|
45
|
+
|
46
|
+
# 401 and 400 should cause the client to raise an exception
|
47
|
+
[[400, 'Bad Request'], [401, 'Unauthorized']].each do |http_status|
|
48
|
+
email = "verified-#{http_status.first}@example.com"
|
49
|
+
FakeWeb.register_uri(:get, url_for(server, email), :body => 'Error!', :status => http_status)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# for 500 and 503, make this work on secondary, but not primary-- this means we can test failover
|
55
|
+
[[500, 'Internal Server Error'],[503, 'Service Unavailable']].each do |http_status|
|
56
|
+
email = "verified-#{http_status.first}@example.com"
|
57
|
+
FakeWeb.register_uri(:get, url_for(@servers.first, email), :body => 'Error!', :status => http_status)
|
58
|
+
new_http_status = [200, 'OK']
|
59
|
+
FakeWeb.register_uri(:get, url_for(@servers.last, email),
|
60
|
+
:body => Leadspend::Result.verified(email).raw,
|
61
|
+
:status => new_http_status )
|
62
|
+
|
63
|
+
# also register an "alwaysfail" address to see that the proper exception is raised
|
64
|
+
email = "alwaysfail-#{http_status.first}@example.com"
|
65
|
+
@servers.each do |server|
|
66
|
+
FakeWeb.register_uri(:get, url_for(server, email), :body => 'Error!', :status => http_status)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def url_for(server, email, opts={})
|
72
|
+
opts_str = ''
|
73
|
+
unless opts.empty?
|
74
|
+
opts_str += '?' + opts.map { |k,v| "#{k.to_s}=#{escape_param(v)}"}.join('&')
|
75
|
+
end
|
76
|
+
"https://#{@username}:#{@password}@#{server}/#{@api_version}/validity/#{escape_param email}#{opts_str}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def escape_param(param)
|
80
|
+
URI::escape(param.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../mocks/leadspend/server"
|
2
|
+
require 'test/unit'
|
3
|
+
class Leadspend::TestLeadspendClient < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@server = Leadspend::Server.new(:username => 'test', :password => 'test')
|
6
|
+
@client = Leadspend::Client.new(:username => 'test', :password => 'test')
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_yajl_backend
|
10
|
+
@client = Leadspend::Client.new(:username => 'test', :password => 'test', :json_parser => 'yajl')
|
11
|
+
verified_email="verified-200@example.com"
|
12
|
+
unknown_email="unknown-200@example.com"
|
13
|
+
assert @client.validate(verified_email)
|
14
|
+
assert @client.validate(unknown_email)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_rails_backend
|
18
|
+
@client = Leadspend::Client.new(:username => 'test', :password => 'test', :json_parser => 'rails')
|
19
|
+
verified_email="verified-200@example.com"
|
20
|
+
unknown_email="unknown-200@example.com"
|
21
|
+
assert @client.validate(verified_email)
|
22
|
+
assert @client.validate(unknown_email)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_result_consistency
|
26
|
+
verified_email="verified-200@example.com"
|
27
|
+
unknown_email="unknown-200@example.com"
|
28
|
+
assert Leadspend::Result.verified(verified_email).verified?
|
29
|
+
assert Leadspend::Result.unknown(unknown_email).unknown?
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_validate
|
33
|
+
verified_email="verified-200@example.com"
|
34
|
+
unknown_email="unknown-200@example.com"
|
35
|
+
assert @client.validate(verified_email)
|
36
|
+
assert @client.validate(unknown_email)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_ok_results
|
40
|
+
Leadspend::RESULT_STATUSES.each do |status|
|
41
|
+
email = "#{status}-200@example.com"
|
42
|
+
assert_equal Leadspend::Result.send(status, email), @client.fetch_result(email)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_accepted_results
|
47
|
+
Leadspend::RESULT_STATUSES.each do |status|
|
48
|
+
email = "#{status}-202@example.com"
|
49
|
+
assert_equal Leadspend::Result.unknown(email), @client.fetch_result(email)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_400_results
|
54
|
+
status='verified'
|
55
|
+
email = "#{status}-400@example.com"
|
56
|
+
assert_raise(Leadspend::Exceptions::BadRequestException) do
|
57
|
+
@client.fetch_result(email)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_401_results
|
62
|
+
status='verified'
|
63
|
+
email = "#{status}-401@example.com"
|
64
|
+
assert_raise(Leadspend::Exceptions::UnauthorizedRequestException) do
|
65
|
+
@client.fetch_result(email)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_500_failover_results
|
70
|
+
status='verified'
|
71
|
+
email = "#{status}-500@example.com"
|
72
|
+
assert_equal Leadspend::Result.send(status, email), @client.fetch_result(email)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_500_everywhere
|
76
|
+
status='alwaysfail'
|
77
|
+
email = "#{status}-500@example.com"
|
78
|
+
assert_raise(Leadspend::Exceptions::ServerException) do
|
79
|
+
@client.fetch_result(email)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_503_failover_results
|
84
|
+
status='verified'
|
85
|
+
email = "#{status}-503@example.com"
|
86
|
+
assert_equal Leadspend::Result.send(status, email), @client.fetch_result(email)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_503_everywhere
|
90
|
+
status='alwaysfail'
|
91
|
+
email = "#{status}-503@example.com"
|
92
|
+
assert_raise(Leadspend::Exceptions::ServerBusyException) do
|
93
|
+
@client.fetch_result(email)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def teardown
|
98
|
+
@server.unregister_all_urls unless @server.nil?
|
99
|
+
end
|
100
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: leadspend
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 1.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Justin Dossey
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain:
|
17
|
+
- |
|
18
|
+
-----BEGIN CERTIFICATE-----
|
19
|
+
MIIDMDCCAhigAwIBAgIBADANBgkqhkiG9w0BAQUFADA+MQwwCgYDVQQDDANqYmQx
|
20
|
+
GTAXBgoJkiaJk/IsZAEZFglwb2RvbWF0aWMxEzARBgoJkiaJk/IsZAEZFgNjb20w
|
21
|
+
HhcNMTIwODIzMTc1NjI2WhcNMTMwODIzMTc1NjI2WjA+MQwwCgYDVQQDDANqYmQx
|
22
|
+
GTAXBgoJkiaJk/IsZAEZFglwb2RvbWF0aWMxEzARBgoJkiaJk/IsZAEZFgNjb20w
|
23
|
+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5RGjRB6bqQgjXJJGqgsnP
|
24
|
+
o+eYygOuuJiteU8x5KEAj9VgM7GdOkBszpwDxRfBuZo8yrCmtDowD+yvTdNochOD
|
25
|
+
PTXcDaEshBsRr8j8ZW8LKUE8uFwwHGH1eeUSIzt2DytosC/MAvUbDQCD/2aqWshW
|
26
|
+
wvO2I08bSRyusrxAGILYcB3CWx0WTU/Gr5aVBaHBRRi3Ebmu2pFzRYQuDnJx7Xiq
|
27
|
+
kB9yGx8cBwRqT8YEu+vRiM+2t77xXN6mVYoP4hsNafOURHCJuW3R8r5rkbq2OP+y
|
28
|
+
EDIGIUnQS7oTndT1Xw7o2czQud2+uWAl+TMCCaN3sX10c4L05i3vKiIcioiqIzON
|
29
|
+
AgMBAAGjOTA3MB0GA1UdDgQWBBTwCGTQ7oaGQqyQXzsTDrgeDwlglTALBgNVHQ8E
|
30
|
+
BAMCBLAwCQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAQo4JD6kU2Jf2+Qk0
|
31
|
+
1/bcV1i/x2W/NBY0U3GGMg9hpVZ0U5iUM3hyEfH6fFI36qL+SeQN3OZWefdoKT1W
|
32
|
+
B9deFyS4nG4u3KX5I8StJDN1TVm/6pd2oFadkhBeOJohiYspa5XjTxdn47zZOTIU
|
33
|
+
LI+e36qne3wsTZRNw3xtp3cHgXSOKvAW8GVmJHk/2fvvzP3M14xjLSecu9gz3leB
|
34
|
+
CCypHKDQ9StNcMuvHsRyFOoojb2iJygucIcOXBy0bQEOzUVFDzwaLYNAciAUlOPs
|
35
|
+
es1G1v2drcgWtxkPCQNzgqw2rOq6B5UHqxBh9IB3xEXZ1YYaU4Si6jDLtEWy76Fa
|
36
|
+
DHOLCQ==
|
37
|
+
-----END CERTIFICATE-----
|
38
|
+
|
39
|
+
date: 2012-08-23 00:00:00 Z
|
40
|
+
dependencies:
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rdoc
|
43
|
+
prerelease: false
|
44
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ~>
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
hash: 19
|
50
|
+
segments:
|
51
|
+
- 3
|
52
|
+
- 10
|
53
|
+
version: "3.10"
|
54
|
+
type: :development
|
55
|
+
version_requirements: *id001
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: hoe
|
58
|
+
prerelease: false
|
59
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ~>
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
hash: 7
|
65
|
+
segments:
|
66
|
+
- 3
|
67
|
+
- 0
|
68
|
+
version: "3.0"
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id002
|
71
|
+
description: Leadspend client access library.
|
72
|
+
email:
|
73
|
+
- jbd@podomatic.com
|
74
|
+
executables: []
|
75
|
+
|
76
|
+
extensions: []
|
77
|
+
|
78
|
+
extra_rdoc_files:
|
79
|
+
- History.txt
|
80
|
+
- Manifest.txt
|
81
|
+
- README.txt
|
82
|
+
files:
|
83
|
+
- .autotest
|
84
|
+
- History.txt
|
85
|
+
- Manifest.txt
|
86
|
+
- README.txt
|
87
|
+
- Rakefile
|
88
|
+
- lib/leadspend.rb
|
89
|
+
- lib/leadspend/exceptions.rb
|
90
|
+
- lib/leadspend/result.rb
|
91
|
+
- lib/leadspend/client.rb
|
92
|
+
- lib/leadspend/parser/json_parser.rb
|
93
|
+
- lib/leadspend/parser/yajl_parser.rb
|
94
|
+
- lib/leadspend/parser/rails_parser.rb
|
95
|
+
- test/unit/test_leadspend_client.rb
|
96
|
+
- test/mocks/leadspend/server.rb
|
97
|
+
- .gemtest
|
98
|
+
homepage: http://www.github.com/justindossey/leadspend
|
99
|
+
licenses: []
|
100
|
+
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options:
|
103
|
+
- --main
|
104
|
+
- README.txt
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
hash: 3
|
113
|
+
segments:
|
114
|
+
- 0
|
115
|
+
version: "0"
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
hash: 3
|
122
|
+
segments:
|
123
|
+
- 0
|
124
|
+
version: "0"
|
125
|
+
requirements: []
|
126
|
+
|
127
|
+
rubyforge_project: leadspend
|
128
|
+
rubygems_version: 1.8.15
|
129
|
+
signing_key:
|
130
|
+
specification_version: 3
|
131
|
+
summary: Leadspend client access library.
|
132
|
+
test_files:
|
133
|
+
- test/unit/test_leadspend_client.rb
|
metadata.gz.sig
ADDED