leadspend 1.0.2
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.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