name_dot_com_api 0.0.1
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 +6 -0
- data/Gemfile +10 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +16 -0
- data/Rakefile +20 -0
- data/lib/name_dot_com_api/client.rb +151 -0
- data/lib/name_dot_com_api/connection.rb +141 -0
- data/lib/name_dot_com_api/response.rb +34 -0
- data/lib/name_dot_com_api/version.rb +3 -0
- data/lib/name_dot_com_api.rb +17 -0
- data/name_dot_com_api.gemspec +22 -0
- data/spec/client_spec.rb +174 -0
- data/spec/connection_spec.rb +123 -0
- data/spec/name_dot_com_api_spec.rb +18 -0
- data/spec/response_spec.rb +25 -0
- data/spec/spec_helper.rb +25 -0
- data/spec.opts +3 -0
- metadata +94 -0
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Nicholas Barthelemy
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
= NameDotComApi
|
2
|
+
|
3
|
+
This gem allows you to interact with the name.com api via ruby.
|
4
|
+
|
5
|
+
== Basic Usage
|
6
|
+
|
7
|
+
client = NameDotComApi::Client.new('< username >','< api_token >', < test_mode >)
|
8
|
+
response = client.check_domain('< domain_name >')
|
9
|
+
|
10
|
+
* Please see lib/name_dot_com_api/client.rb and specs for additional details on usage
|
11
|
+
|
12
|
+
== TODOS
|
13
|
+
|
14
|
+
* MORE DOCUMENTAION
|
15
|
+
* Add Contact model for contact creation and possible validation
|
16
|
+
* Include expected responses in mocks
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler::GemHelper.install_tasks
|
4
|
+
|
5
|
+
# Added to get the specs working
|
6
|
+
require 'spec/rake/spectask'
|
7
|
+
Spec::Rake::SpecTask.new(:spec)
|
8
|
+
|
9
|
+
task :default => :spec
|
10
|
+
task :specs => :spec
|
11
|
+
|
12
|
+
# Generate documentation
|
13
|
+
require 'rake/rdoctask'
|
14
|
+
desc "Generate Documentation"
|
15
|
+
Rake::RDocTask.new do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'doc'
|
17
|
+
rdoc.title = 'Name.com API'
|
18
|
+
rdoc.options << '--line-numbers' << '--inline-source' << '--main' << 'Name.com API'
|
19
|
+
rdoc.rdoc_files.include(FileList[ 'lib/**/*.rb', 'README.rdoc', 'LICENSE'])
|
20
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module NameDotComApi
|
2
|
+
|
3
|
+
class Client
|
4
|
+
|
5
|
+
attr_reader :connection
|
6
|
+
|
7
|
+
def initialize(username, api_token, test_mode = false)
|
8
|
+
@connection ||= Connection.new
|
9
|
+
@connection.test_mode = test_mode
|
10
|
+
login username, api_token
|
11
|
+
end
|
12
|
+
|
13
|
+
# response = client.login(username, api_token)
|
14
|
+
def login(username, api_token)
|
15
|
+
raise "You are already logged in" if @connection.logged_in?
|
16
|
+
|
17
|
+
@connection.username ||= username
|
18
|
+
@connection.api_token ||= api_token
|
19
|
+
|
20
|
+
connection.post '/login', {
|
21
|
+
:username => @connection.username, :api_token => @connection.api_token
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
# response = client.logout
|
26
|
+
def logout
|
27
|
+
connection.get '/logout'
|
28
|
+
end
|
29
|
+
|
30
|
+
# response = client.hello
|
31
|
+
def hello
|
32
|
+
connection.get '/hello'
|
33
|
+
end
|
34
|
+
|
35
|
+
# response = client.get_account
|
36
|
+
def get_account
|
37
|
+
connection.get '/account/get'
|
38
|
+
end
|
39
|
+
|
40
|
+
# response = client.list_domains
|
41
|
+
def list_domains
|
42
|
+
connection.get "/domain/list/#{connection.username}"
|
43
|
+
end
|
44
|
+
|
45
|
+
# response = client.update_domain_nameservers('example.com', [
|
46
|
+
# 'ns1.name.com', 'ns2.name.com', 'ns3.name.com'
|
47
|
+
# ])
|
48
|
+
def update_domain_nameservers(domain, nameservers = {})
|
49
|
+
connection.post "/domain/update_nameservers/#{domain}", { :nameservers => nameservers }
|
50
|
+
end
|
51
|
+
|
52
|
+
# response = client.update_domain_contacts('mynewdomain.com', [
|
53
|
+
# { 'type' => [ 'registrant','administrative','technical','billing' ],
|
54
|
+
# 'first_name' => 'John',
|
55
|
+
# 'last_name' => 'Doe',
|
56
|
+
# 'organization' => 'Name.com',
|
57
|
+
# 'address_1' => '125 Main St',
|
58
|
+
# 'address_2' => 'Suite 300',
|
59
|
+
# 'city' => 'Denver',
|
60
|
+
# 'state' => 'CO',
|
61
|
+
# 'zip' => '80230',
|
62
|
+
# 'country' => 'US',
|
63
|
+
# 'phone' => '+1.3035555555',
|
64
|
+
# 'fax' => '+1.3035555556',
|
65
|
+
# 'email' => 'john@example.net'
|
66
|
+
# }
|
67
|
+
# ])
|
68
|
+
def update_domain_contacts(domain, contacts = [])
|
69
|
+
connection.post "/domain/update_contacts/#{domain}", { :contacts => contacts }
|
70
|
+
end
|
71
|
+
|
72
|
+
# response = client.lock_domain('example.com')
|
73
|
+
def lock_domain(domain)
|
74
|
+
connection.get "/domain/lock/#{domain}"
|
75
|
+
end
|
76
|
+
|
77
|
+
# response = client.unlock_domain('example.com')
|
78
|
+
def unlock_domain(domain)
|
79
|
+
connection.get "/domain/unlock/#{domain}"
|
80
|
+
end
|
81
|
+
|
82
|
+
# response = client.list_dns_records('example.com')
|
83
|
+
def list_dns_records(domain)
|
84
|
+
connection.get "/dns/list/#{domain}"
|
85
|
+
end
|
86
|
+
|
87
|
+
# response = client.create_dns_record('example.com', 'www', 'A', '127.0.0.1', 300)
|
88
|
+
# response = client.create_dns_record('example.com', 'mail', 'MX', 'mx3.name.com', 300, 10)
|
89
|
+
def create_dns_record(domain, hostname, type, content, ttl, priority = nil)
|
90
|
+
body = {
|
91
|
+
'hostname' => hostname,
|
92
|
+
'type' => type,
|
93
|
+
'content' => content,
|
94
|
+
'ttl' => ttl
|
95
|
+
}
|
96
|
+
body.update!(:priority => priority) if priority
|
97
|
+
connection.post "/dns/create/#{domain}", body
|
98
|
+
end
|
99
|
+
alias :add_dns_record :create_dns_record
|
100
|
+
|
101
|
+
# response = client.delete_dns_record('example.com', 1234)
|
102
|
+
def delete_dns_record(domain, record_id)
|
103
|
+
connection.post "/dns/delete/#{domain}", { :record_id => record_id }
|
104
|
+
end
|
105
|
+
alias :remove_dns_record :delete_dns_record
|
106
|
+
|
107
|
+
# response = client.check_domain('example')
|
108
|
+
# response = client.check_domain('example', [ 'com', 'net', 'org' ], [ 'availability','suggested' ])
|
109
|
+
def check_domain(keyword, tlds = nil, services = nil)
|
110
|
+
connection.post '/domain/power_check', {
|
111
|
+
'keyword' => keyword,
|
112
|
+
'tlds' => tlds || [ 'com' ], # ,'net','org','info','us','biz','tel' ],
|
113
|
+
'services' => services || [ 'availability' ] # ,'suggested' ]
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
# ns = [ 'ns1.name.com', 'ns2.name.com', 'ns3.name.com' ]
|
118
|
+
# response = client.create_domain('example.com', 1, ns, [
|
119
|
+
# { 'type' => [ 'registrant','administrative','technical','billing' ],
|
120
|
+
# 'first_name' => 'John',
|
121
|
+
# 'last_name' => 'Doe',
|
122
|
+
# 'organization' => 'Name.com',
|
123
|
+
# 'address_1' => '125 Main St',
|
124
|
+
# 'address_2' => 'Suite 300',
|
125
|
+
# 'city' => 'Denver',
|
126
|
+
# 'state' => 'CO',
|
127
|
+
# 'zip' => '80230',
|
128
|
+
# 'country' => 'US',
|
129
|
+
# 'phone' => '+1.3035555555',
|
130
|
+
# 'fax' => '+1.3035555556',
|
131
|
+
# 'email' => 'john@example.net'
|
132
|
+
# }
|
133
|
+
# ])
|
134
|
+
def create_domain(domain, period, nameservers, contacts)
|
135
|
+
connection.post '/domain/create', {
|
136
|
+
'domain' => domain,
|
137
|
+
'period' => period,
|
138
|
+
'nameservers' => nameservers,
|
139
|
+
'contacts' => contacts,
|
140
|
+
'username' => connection.username
|
141
|
+
}
|
142
|
+
end
|
143
|
+
|
144
|
+
# response = client.get_domain('example.com')
|
145
|
+
def get_domain(domain)
|
146
|
+
connection.get "/domain/get/#{domain}"
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'net/https'
|
3
|
+
require 'uri'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module NameDotComApi
|
7
|
+
|
8
|
+
class ConnectionError < StandardError
|
9
|
+
attr_reader :response
|
10
|
+
|
11
|
+
def initialize(response, message = nil)
|
12
|
+
@response = response
|
13
|
+
@message = message
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
"Failed with #{response.code} #{response.message if response.respond_to?(:message)}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Connection
|
22
|
+
HTTP_FORMAT_HEADER_NAMES = {
|
23
|
+
:get => 'Accept',
|
24
|
+
:post => 'Content-Type'
|
25
|
+
}
|
26
|
+
|
27
|
+
JSON_MIME_TYPE = 'text/json; charset=utf-8'
|
28
|
+
|
29
|
+
def initialize(test_mode = false)
|
30
|
+
@headers ||= {}
|
31
|
+
@cookies ||= {}
|
32
|
+
@test_mode = test_mode
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_accessor :username, :api_token, :session_token
|
36
|
+
attr_accessor :url, :cookies, :timeout, :test_mode
|
37
|
+
|
38
|
+
def logged_in?; !!session_token; end
|
39
|
+
|
40
|
+
# Set URI for remote service.
|
41
|
+
def url=(url)
|
42
|
+
@url = url.is_a?(URI) ? url : URI.parse(url)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Creates new Net::HTTP instance for communication with remote service and resources.
|
46
|
+
def http
|
47
|
+
http = Net::HTTP.new(url.host, url.port)
|
48
|
+
http.use_ssl = url.is_a?(URI::HTTPS)
|
49
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl
|
50
|
+
http.read_timeout = timeout || 60 # Net::HTTP default 60 seconds
|
51
|
+
http.set_debug_output $stderr if test_mode
|
52
|
+
http
|
53
|
+
end
|
54
|
+
|
55
|
+
def get(path, params = {}); request(:get, path, params); end
|
56
|
+
def post(path, params = {}); request(:post, path, params); end
|
57
|
+
|
58
|
+
def logger
|
59
|
+
defined?(ActiveRecord) ? ActiveRecord::Base.logger : nil
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# Makes request to remote service. # Be sure to handle Timeout::Error
|
65
|
+
def request(method, path, params = {})
|
66
|
+
# ensure the user is logged in or logging in
|
67
|
+
raise "You must first login" unless path =~ /^\/login/ || logged_in?
|
68
|
+
|
69
|
+
self.url = "#{NameDotComApi.base_url(test_mode)}#{path}"
|
70
|
+
|
71
|
+
logger.info "#{method.to_s.upcase} #{url.to_s}" if logger
|
72
|
+
logger.info "with body: #{params.inspect}" if logger
|
73
|
+
|
74
|
+
result = case method
|
75
|
+
when :get then http.send(method, url.to_s, build_request_headers(method))
|
76
|
+
when :post then http.send(method, url.to_s, params.to_json, build_request_headers(method))
|
77
|
+
end
|
78
|
+
|
79
|
+
logger.info "--> %d %s (%d)" % [ result.code, result.message, result.body ? result.body.length : 0 ] if logger
|
80
|
+
|
81
|
+
handle_response(result)
|
82
|
+
rescue Timeout::Error => e
|
83
|
+
raise TimeoutError.new(e.message)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Builds headers for request to remote service.
|
87
|
+
def build_request_headers(http_method = nil)
|
88
|
+
headers = {}
|
89
|
+
|
90
|
+
if session_token
|
91
|
+
logger.info "SessionToken: #{session_token}" if logger
|
92
|
+
headers['Api-Session-Token'] = session_token
|
93
|
+
end
|
94
|
+
|
95
|
+
if username && api_token
|
96
|
+
logger.info "Username: #{username}" if logger
|
97
|
+
headers['Api-Username'] = username
|
98
|
+
|
99
|
+
logger.info "SessionToken: #{api_token}" if logger
|
100
|
+
headers['Api-Token'] = api_token
|
101
|
+
end
|
102
|
+
|
103
|
+
http_format_header(http_method).update(cookie_header).update(headers)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Builds the cookie header according to what's stored in @cookies
|
107
|
+
# Encodes correctly for cookies, e.g. key1=value1; key2=value2
|
108
|
+
def cookie_header
|
109
|
+
unless cookies.nil? || cookies.empty?
|
110
|
+
pairs = @cookies.inject([]) do |a, p|
|
111
|
+
a << "#{CGI::escape(p[0].to_s)}=#{CGI::escape(p[1].to_s)}"; a
|
112
|
+
end
|
113
|
+
{ 'Cookie' => pairs.join('; ') }
|
114
|
+
else
|
115
|
+
{}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def http_format_header(http_method)
|
120
|
+
{ HTTP_FORMAT_HEADER_NAMES[http_method] => JSON_MIME_TYPE }
|
121
|
+
end
|
122
|
+
|
123
|
+
# Handles response and error codes from remote service.
|
124
|
+
def handle_response(response)
|
125
|
+
case response.code.to_i
|
126
|
+
when 200
|
127
|
+
response = ::NameDotComApi::Response.new(response.body)
|
128
|
+
unless response['session_token'].nil?
|
129
|
+
self.session_token = response['session_token']
|
130
|
+
end
|
131
|
+
response
|
132
|
+
when 301, 302
|
133
|
+
raise ConnectionError.new(response, "Redirection response code: #{response.code}")
|
134
|
+
else
|
135
|
+
raise ConnectionError.new(response, "Connection response code: #{response.code}")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module NameDotComApi
|
4
|
+
class Response < Hash
|
5
|
+
|
6
|
+
def initialize(json)
|
7
|
+
self.update JSON.parse(json)
|
8
|
+
end
|
9
|
+
|
10
|
+
module EigenMethodDefiner # :nodoc:
|
11
|
+
def method_missing(name, *args, &block)
|
12
|
+
if key?(name.to_s)
|
13
|
+
define_eigen_method(name.to_s)
|
14
|
+
value = self[name.to_s]
|
15
|
+
value.extend(EigenMethodDefiner) if value.is_a?(Hash)
|
16
|
+
value
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def define_eigen_method(name)
|
25
|
+
eigen_class = class << self; self; end
|
26
|
+
eigen_class.send(:define_method, name){ self[name] }
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
include EigenMethodDefiner
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# client = NameDotComApi::Client.new('< username >','< api_token >', < test mode >)
|
2
|
+
# response = client.check_domain('< domain_name >')
|
3
|
+
|
4
|
+
require 'name_dot_com_api/client'
|
5
|
+
require 'name_dot_com_api/connection'
|
6
|
+
require 'name_dot_com_api/response'
|
7
|
+
|
8
|
+
module NameDotComApi
|
9
|
+
|
10
|
+
TEST_API_HOST = 'https://api.dev.name.com/api'
|
11
|
+
PRODUCTION_API_HOST = 'https://api.name.com/api'
|
12
|
+
|
13
|
+
def self.base_url(test_mode = false)
|
14
|
+
test_mode ? TEST_API_HOST : PRODUCTION_API_HOST
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/name_dot_com_api/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "name_dot_com_api"
|
6
|
+
s.version = NameDotComApi::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = [ 'Nicholas Barthelemy' ]
|
9
|
+
s.email = [ 'nicholas.barthelemy@gmail.com' ]
|
10
|
+
s.homepage = "https://github.com/nbarthelemy/name_dot_com_api"
|
11
|
+
s.summary = "An easy to use unterface for the name.com api"
|
12
|
+
s.description = "This gem allows you to interact with the name.com api via ruby."
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
s.rubyforge_project = "name_dot_com_api"
|
16
|
+
|
17
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
21
|
+
s.require_path = 'lib'
|
22
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe NameDotComApi do
|
4
|
+
|
5
|
+
describe "::Client" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@username = 'spec_user'
|
9
|
+
@api_key = 'ds98fusdfjsdklfjk832934d9sa0d9auda8s7df8'
|
10
|
+
@session_token = '34d9sa0d9auda8' # fake logged in
|
11
|
+
|
12
|
+
@base_url = NameDotComApi.base_url
|
13
|
+
|
14
|
+
@domain = 'example.com'
|
15
|
+
@nameservers = [ 'ns1.name.com', 'ns2.name.com', 'ns3.name.com' ]
|
16
|
+
@contact = {
|
17
|
+
'type' => [ 'registrant','administrative','technical','billing' ],
|
18
|
+
'first_name' => 'John',
|
19
|
+
'last_name' => 'Doe',
|
20
|
+
'organization' => 'Name.com',
|
21
|
+
'address_1' => '125 Main St',
|
22
|
+
'address_2' => 'Suite 300',
|
23
|
+
'city' => 'Denver',
|
24
|
+
'state' => 'CO',
|
25
|
+
'zip' => '80230',
|
26
|
+
'country' => 'US',
|
27
|
+
'phone' => '+1.3035555555',
|
28
|
+
'fax' => '+1.3035555556',
|
29
|
+
'email' => 'john@example.net'
|
30
|
+
}
|
31
|
+
|
32
|
+
stub_request(:post, "#{@base_url}/login").
|
33
|
+
to_return(successful_json_response(:session_token => @session_token))
|
34
|
+
|
35
|
+
@client = NameDotComApi::Client.new(@username, @api_key)
|
36
|
+
end
|
37
|
+
|
38
|
+
def check_for_successful_response(response)
|
39
|
+
response.result['code'].should == 100
|
40
|
+
response.result['message'].should == "Command Successful"
|
41
|
+
end
|
42
|
+
|
43
|
+
def successful_json_response(body = {})
|
44
|
+
{ :status => 200, :body => {
|
45
|
+
:result => { :code => 100, :message => "Command Successful" }
|
46
|
+
}.merge(body).to_json }
|
47
|
+
end
|
48
|
+
|
49
|
+
it "can login" do
|
50
|
+
@client.connection.logged_in?.should == true
|
51
|
+
end
|
52
|
+
|
53
|
+
it "can logoout" do
|
54
|
+
stub_request(:get, "#{@base_url}/logout").to_return(successful_json_response)
|
55
|
+
|
56
|
+
response = @client.logout
|
57
|
+
check_for_successful_response(response)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "can get hello response" do
|
61
|
+
stub_request(:get, "#{@base_url}/hello").to_return(successful_json_response)
|
62
|
+
|
63
|
+
response = @client.hello
|
64
|
+
check_for_successful_response(response)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "can get account information" do
|
68
|
+
stub_request(:get, "#{@base_url}/account/get").
|
69
|
+
to_return(successful_json_response(:username => @username))
|
70
|
+
|
71
|
+
response = @client.get_account
|
72
|
+
check_for_successful_response(response)
|
73
|
+
response.username.should == @username
|
74
|
+
end
|
75
|
+
|
76
|
+
it "can list domains" do
|
77
|
+
stub_request(:get, "#{@base_url}/domain/list/spec_user").
|
78
|
+
to_return(successful_json_response(:domains => []))
|
79
|
+
|
80
|
+
response = @client.list_domains
|
81
|
+
check_for_successful_response(response)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "can create a domain" do
|
85
|
+
stub_request(:post, "#{@base_url}/domain/create").
|
86
|
+
to_return(successful_json_response)
|
87
|
+
|
88
|
+
response = @client.create_domain(@domain, 1, @nameservers, [ @contact ])
|
89
|
+
check_for_successful_response(response)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "can update nameservers for domain" do
|
93
|
+
stub_request(:post, "#{@base_url}/domain/update_nameservers/#{@domain}").
|
94
|
+
to_return(successful_json_response)
|
95
|
+
|
96
|
+
response = @client.update_domain_nameservers(@domain, @nameservers)
|
97
|
+
check_for_successful_response(response)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "can update contacts for domain" do
|
101
|
+
stub_request(:post, "#{@base_url}/domain/update_contacts/#{@domain}").
|
102
|
+
to_return(successful_json_response)
|
103
|
+
|
104
|
+
response = @client.update_domain_contacts(@domain, [ @contact ])
|
105
|
+
check_for_successful_response(response)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "can lock a domain" do
|
109
|
+
stub_request(:get, "#{@base_url}/domain/lock/#{@domain}").
|
110
|
+
to_return(successful_json_response)
|
111
|
+
|
112
|
+
response = @client.lock_domain(@domain)
|
113
|
+
check_for_successful_response(response)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "can unlock a domain" do
|
117
|
+
stub_request(:get, "#{@base_url}/domain/unlock/#{@domain}").
|
118
|
+
to_return(successful_json_response)
|
119
|
+
|
120
|
+
response = @client.unlock_domain(@domain)
|
121
|
+
check_for_successful_response(response)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "can list dns records" do
|
125
|
+
stub_request(:get, "#{@base_url}/dns/list/#{@domain}").
|
126
|
+
to_return(successful_json_response)
|
127
|
+
|
128
|
+
response = @client.list_dns_records(@domain)
|
129
|
+
check_for_successful_response(response)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "can create a dns record" do
|
133
|
+
stub_request(:post, "#{@base_url}/dns/create/#{@domain}").
|
134
|
+
to_return(successful_json_response)
|
135
|
+
|
136
|
+
response = @client.create_dns_record(@domain, 'www', 'A', '127.0.0.1', 300)
|
137
|
+
check_for_successful_response(response)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "can delete a dns record" do
|
141
|
+
stub_request(:post, "#{@base_url}/dns/delete/#{@domain}").
|
142
|
+
to_return(successful_json_response)
|
143
|
+
|
144
|
+
response = @client.delete_dns_record(@domain, 1234)
|
145
|
+
check_for_successful_response(response)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "can check a domain" do
|
149
|
+
stub_request(:post, "#{@base_url}/domain/power_check").
|
150
|
+
to_return(successful_json_response)
|
151
|
+
|
152
|
+
response = @client.check_domain('example', [ 'com' ])
|
153
|
+
check_for_successful_response(response)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "can create a domain" do
|
157
|
+
stub_request(:post, "#{@base_url}/domain/create").
|
158
|
+
to_return(successful_json_response)
|
159
|
+
|
160
|
+
response = @client.create_domain(@domain, 1, @nameservers, [ @contact ])
|
161
|
+
check_for_successful_response(response)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "can get a domain" do
|
165
|
+
stub_request(:get, "#{@base_url}/domain/get/#{@domain}").
|
166
|
+
to_return(successful_json_response)
|
167
|
+
|
168
|
+
response = @client.get_domain(@domain)
|
169
|
+
check_for_successful_response(response)
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
# test the private methods; see spec/spec_helper.rb
|
4
|
+
describe_internally NameDotComApi::Connection do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@connection = NameDotComApi::Connection.new
|
8
|
+
@connection.username = 'spec_user'
|
9
|
+
@connection.api_token = 'ds98fusdfjsdklfjk832934d9sa0d9auda8s7df8'
|
10
|
+
@connection.session_token = '34d9sa0d9auda8' # fake logged in
|
11
|
+
|
12
|
+
@test_path = '/hello'
|
13
|
+
@test_url = "#{NameDotComApi.base_url(@connection.test_mode)}#{@test_path}"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "can represent both login states" do
|
17
|
+
@connection.logged_in?.should == true
|
18
|
+
|
19
|
+
@connection.session_token = nil
|
20
|
+
@connection.logged_in?.should == false
|
21
|
+
end
|
22
|
+
|
23
|
+
it "can build cookie headers" do
|
24
|
+
# no cookies
|
25
|
+
@connection.cookie_header.should == {}
|
26
|
+
|
27
|
+
# cookies
|
28
|
+
@connection.cookies = { 'test' => 'cookie' }
|
29
|
+
@connection.cookie_header.should == { 'Cookie' => 'test=cookie' }
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can retrieve the correct http format header (get/post)" do
|
33
|
+
@connection.http_format_header(:get).should == { "Accept" => "text/json; charset=utf-8" }
|
34
|
+
@connection.http_format_header(:post).should == { "Content-Type" => "text/json; charset=utf-8" }
|
35
|
+
end
|
36
|
+
|
37
|
+
it "can build request headers (get/post)" do
|
38
|
+
# get
|
39
|
+
@connection.build_request_headers(:get).should == {
|
40
|
+
"Api-Username" => @connection.username,
|
41
|
+
"Api-Token" => @connection.api_token,
|
42
|
+
"Api-Session-Token" => @connection.session_token,
|
43
|
+
"Accept" => NameDotComApi::Connection::JSON_MIME_TYPE
|
44
|
+
}
|
45
|
+
|
46
|
+
# post
|
47
|
+
@connection.build_request_headers(:post).should == {
|
48
|
+
"Api-Username" => @connection.username,
|
49
|
+
"Api-Token" => @connection.api_token,
|
50
|
+
"Api-Session-Token" => @connection.session_token,
|
51
|
+
"Content-Type" => NameDotComApi::Connection::JSON_MIME_TYPE
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
it "can make a request (get/post)" do
|
56
|
+
# get
|
57
|
+
stub_request(:get, @test_url).to_return(:status => 200, :body => "{}")
|
58
|
+
@connection.request(:get, @test_path).should == {}
|
59
|
+
|
60
|
+
# post
|
61
|
+
stub_request(:post, @test_url).with(:body => "{}").to_return(:status => 200, :body => '{}')
|
62
|
+
@connection.request(:post, @test_path).should == {}
|
63
|
+
end
|
64
|
+
|
65
|
+
it "can handle a 200 response" do
|
66
|
+
@mock = mock('Net::HTTPResponse')
|
67
|
+
@mock.stub(:code => '200', :message => "OK", :content_type => "text/json", :body => '{}')
|
68
|
+
@connection.handle_response(@mock).should == {}
|
69
|
+
end
|
70
|
+
|
71
|
+
it "can handle a 30X response" do
|
72
|
+
@mock = mock('Net::HTTPResponse')
|
73
|
+
@mock.stub(:code => '301', :message => "PERMANENTLY MOVED", :content_type => "text/json", :body => '')
|
74
|
+
lambda{ @connection.handle_response(@mock) }.should raise_error(NameDotComApi::ConnectionError)
|
75
|
+
|
76
|
+
@mock = mock('Net::HTTPResponse')
|
77
|
+
@mock.stub(:code => '302', :message => "TEMPORARILY MOVED", :content_type => "text/json", :body => '')
|
78
|
+
lambda{ @connection.handle_response(@mock) }.should raise_error(NameDotComApi::ConnectionError)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "can handle any other response" do
|
82
|
+
@mock = mock('Net::HTTPResponse')
|
83
|
+
@mock.stub(:code => '400', :message => "NOT FOUND", :content_type => "text/json", :body => '')
|
84
|
+
lambda{ @connection.handle_response(@mock) }.should raise_error(NameDotComApi::ConnectionError)
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
describe NameDotComApi::Connection do
|
90
|
+
|
91
|
+
before(:each) do
|
92
|
+
@connection = NameDotComApi::Connection.new
|
93
|
+
@connection.username = 'spec_user'
|
94
|
+
@connection.api_token = 'ds98fusdfjsdklfjk832934d9sa0d9auda8s7df8'
|
95
|
+
@connection.session_token = '34d9sa0d9auda8' # fake logged in
|
96
|
+
|
97
|
+
@test_path = '/hello'
|
98
|
+
@test_url = "#{NameDotComApi.base_url(@connection.test_mode)}#{@test_path}"
|
99
|
+
end
|
100
|
+
|
101
|
+
it "can set test mode" do
|
102
|
+
@connection.test_mode = true
|
103
|
+
@connection.test_mode.should == true
|
104
|
+
@connection.test_mode = false
|
105
|
+
@connection.test_mode.should == false
|
106
|
+
end
|
107
|
+
|
108
|
+
it "can create an http object" do
|
109
|
+
@connection.url = @test_url
|
110
|
+
@connection.http.is_a?(Net::HTTP).should == true
|
111
|
+
end
|
112
|
+
|
113
|
+
it "can make a get request" do
|
114
|
+
stub_request(:get, @test_url).to_return(:status => 200, :body => "{}")
|
115
|
+
@connection.get(@test_path).should == {}
|
116
|
+
end
|
117
|
+
|
118
|
+
it "can make a post request" do
|
119
|
+
stub_request(:post, @test_url).with(:body => "{}").to_return(:status => 200, :body => '{}')
|
120
|
+
@connection.post(@test_path).should == {}
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe NameDotComApi do
|
4
|
+
|
5
|
+
describe "#base_url" do
|
6
|
+
|
7
|
+
it "returns test url" do
|
8
|
+
NameDotComApi.base_url(true).should == 'https://api.dev.name.com/api'
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns production url" do
|
12
|
+
NameDotComApi.base_url.should == 'https://api.name.com/api'
|
13
|
+
NameDotComApi.base_url(false).should == 'https://api.name.com/api'
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe NameDotComApi do
|
4
|
+
|
5
|
+
describe "::Response" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@response = NameDotComApi::Response.new("{\"a\":1,\"b\":2,\"c\":[1,2]}")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "parses a json object" do
|
12
|
+
@response['a'].should == 1
|
13
|
+
@response['b'].should == 2
|
14
|
+
@response['c'].should == [1,2]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "allows top level hash keys to be called as methods" do
|
18
|
+
@response.a.should == 1
|
19
|
+
@response.b.should == 2
|
20
|
+
@response.c.should == [1,2]
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
RAILS_ENV = 'test' if ENV['RAILS_ENV'] == 'development' || !ENV.key?('RAILS_ENV')
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'spec'
|
6
|
+
require 'webmock/rspec'
|
7
|
+
require 'name_dot_com_api'
|
8
|
+
|
9
|
+
# http://kailuowang.blogspot.com/2010/08/testing-private-methods-in-rspec.html
|
10
|
+
def describe_internally *args, &block
|
11
|
+
example = describe *args, &block
|
12
|
+
klass = args[0]
|
13
|
+
if klass.is_a? Class
|
14
|
+
saved_private_instance_methods = klass.private_instance_methods
|
15
|
+
example.before do
|
16
|
+
klass.class_eval { public *saved_private_instance_methods }
|
17
|
+
end
|
18
|
+
example.after do
|
19
|
+
klass.class_eval { private *saved_private_instance_methods }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Spec::Runner.configure do |config|
|
25
|
+
end
|
data/spec.opts
ADDED
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: name_dot_com_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Nicholas Barthelemy
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-01-06 00:00:00 -06:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: bundler
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 0
|
30
|
+
- 0
|
31
|
+
version: 1.0.0
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
description: This gem allows you to interact with the name.com api via ruby.
|
35
|
+
email:
|
36
|
+
- nicholas.barthelemy@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- Gemfile
|
46
|
+
- MIT-LICENSE
|
47
|
+
- README.rdoc
|
48
|
+
- Rakefile
|
49
|
+
- lib/name_dot_com_api.rb
|
50
|
+
- lib/name_dot_com_api/client.rb
|
51
|
+
- lib/name_dot_com_api/connection.rb
|
52
|
+
- lib/name_dot_com_api/response.rb
|
53
|
+
- lib/name_dot_com_api/version.rb
|
54
|
+
- name_dot_com_api.gemspec
|
55
|
+
- spec.opts
|
56
|
+
- spec/client_spec.rb
|
57
|
+
- spec/connection_spec.rb
|
58
|
+
- spec/name_dot_com_api_spec.rb
|
59
|
+
- spec/response_spec.rb
|
60
|
+
- spec/spec_helper.rb
|
61
|
+
has_rdoc: true
|
62
|
+
homepage: https://github.com/nbarthelemy/name_dot_com_api
|
63
|
+
licenses: []
|
64
|
+
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 1
|
83
|
+
- 3
|
84
|
+
- 6
|
85
|
+
version: 1.3.6
|
86
|
+
requirements: []
|
87
|
+
|
88
|
+
rubyforge_project: name_dot_com_api
|
89
|
+
rubygems_version: 1.3.6
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: An easy to use unterface for the name.com api
|
93
|
+
test_files: []
|
94
|
+
|