enom 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,102 @@
1
+ # Enom
2
+
3
+ A ruby wrapper for the Enom Domain Registrar's API for checking domain name
4
+ availability, domain contact information, name server settings, etc.
5
+
6
+ ```
7
+ gem install enom
8
+ ```
9
+
10
+ [![Build Status](https://secure.travis-ci.org/bensie/enom.png)](http://travis-ci.org/bensie/enom)
11
+
12
+ Enom provides an API for all of their services, unfortunately it's got hundreds of commands and it's pretty tough to test. This library aims to make calls to their API trivial and also makes it simple to continually add API commands without much effort.
13
+
14
+ Here are the basics that it covers so far:
15
+
16
+ ## Account Operations
17
+
18
+ ```ruby
19
+ # Set some initial values to allow connections to your account
20
+ Enom::Client.username = "foo"
21
+ Enom::Client.password = "bar"
22
+ Enom::Client.test = true
23
+ # Declaring test mode is optional, defaults to false (production)
24
+ # Test mode will run commands on Enom's reseller test platform
25
+ ```
26
+
27
+ Once these are set, subsequent commands will make calls to the API using your credentials (HTTPS). Any methods in the library that charge or refund the account in any way end with a bang (!).
28
+
29
+ ```ruby
30
+ # Get account balance
31
+ Enom::Account.balance
32
+ # => 12.34
33
+
34
+ # Find a domain in your account
35
+ d = Enom::Domain.find("example.com")
36
+ # => #<Enom::Domain:0x1019f3b78...
37
+
38
+ # Check domain availability
39
+ Enom::Domain.check("example.com")
40
+ # => 'available'
41
+ Enom::Domain.check("google.com")
42
+ # => 'unavailable'
43
+
44
+ # Another way to check availability (boolean)
45
+ Enom::Domain.available?("example.com")
46
+ # => true
47
+
48
+ # Register a domain
49
+ d = Enom::Domain.register!("example.com")
50
+ # => #<Enom::Domain:0x1019f3b78...
51
+ ```
52
+
53
+ ## Domain Operations
54
+
55
+ ```ruby
56
+ # Return the domain name
57
+ d.name
58
+ # => 'example.com'
59
+
60
+ # Check if domain is locked
61
+ d.locked?
62
+ # => true
63
+
64
+ # Check if domain is unlocked
65
+ d.unlocked?
66
+ # => false
67
+
68
+ # Unlock the domain for transfer
69
+ d.unlock
70
+
71
+ # Lock the domain to the registrar
72
+ d.lock
73
+
74
+ # Get name servers
75
+ d.nameservers
76
+ # => ['ns1.example.com', 'ns2.example.com', 'ns3.example.com']
77
+
78
+ # Update name servers
79
+ d.update_nameservers(['ns1.example.com', 'ns2.example.com', 'ns3.example.com'])
80
+
81
+ # Get expiration date
82
+ d.expiration_date
83
+ # => Returns a Date object
84
+
85
+ # Check if domain is expired
86
+ d.expired?
87
+ # => true
88
+
89
+ # Get registration status
90
+ d.registration_status
91
+ # => 'Registered' or 'Expired'
92
+
93
+ # Renew domain (defaults to 1 year)
94
+ d.renew!
95
+
96
+ # Renew domain for specific number of years
97
+ d.renew!(:years => 3)
98
+ ```
99
+
100
+ ## Copyright
101
+
102
+ Copyright (c) 2011 James Miller
data/Rakefile CHANGED
@@ -1,15 +1,13 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'rake/rdoctask'
1
+ require "rake"
2
+ require "rake/testtask"
4
3
 
5
- desc 'Default: run unit tests.'
4
+ desc "Default: run unit tests."
6
5
  task :default => :test
7
6
 
8
- desc 'Test the enom_api plugin.'
7
+ desc "Test the enom gem"
9
8
  Rake::TestTask.new(:test) do |t|
10
- t.libs << 'lib'
11
- t.libs << 'test'
12
- t.pattern = 'test/**/*_test.rb'
13
- t.verbose = true
9
+ t.libs << "lib"
10
+ t.libs << "test"
11
+ t.test_files = FileList['test/*_test.rb']
12
+ t.verbose = true
14
13
  end
15
-
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:.unshift(File.dirname(__FILE__) + '/../lib')
4
- require 'enom'
5
- require 'enom/cli'
3
+ $:.unshift(File.dirname(__FILE__) + "/../lib")
4
+ require "enom"
5
+ require "enom/cli"
6
6
 
7
- require 'optparse'
7
+ require "optparse"
8
8
 
9
9
  def usage
10
10
  $stderr.puts <<-EOF
@@ -35,9 +35,10 @@ help # Show this usage
35
35
 
36
36
  list # List all domains
37
37
  check domain.com # Check if a domain is available (for registration)
38
- describe domain.com # Describe the given domain
39
- register domain.com # Register the given domain with Enom
40
- renew domain.com # Renew the given domain with Enom
38
+ describe domain.com # Describe a domain
39
+ register domain.com # Register a domain with Enom
40
+ renew domain.com # Renew a domain with Enom
41
+ transfer domain.com 867e5926e93 # Transfer a domain to Enom (requires auth/EPP code)
41
42
 
42
43
  EOF
43
44
  end
@@ -59,7 +60,7 @@ end
59
60
  global.order!
60
61
  command = ARGV.shift
61
62
 
62
- if command.nil? || command == 'help'
63
+ if command.nil? || command == "help"
63
64
  usage
64
65
  else
65
66
  begin
@@ -2,8 +2,8 @@ module Enom
2
2
  class Account
3
3
 
4
4
  def self.balance
5
- Client.request('Command' => 'GetBalance')['interface_response']['AvailableBalance'].gsub(',', '').to_f
5
+ Client.request("Command" => "GetBalance")["interface_response"]["AvailableBalance"].gsub(",", "").to_f
6
6
  end
7
7
 
8
8
  end
9
- end
9
+ end
@@ -1,4 +1,4 @@
1
- require 'yaml'
1
+ require "yaml"
2
2
  module Enom
3
3
 
4
4
  class CLI
@@ -9,8 +9,8 @@ module Enom
9
9
  file = File.expand_path("~/.enomconfig")
10
10
  if File.exists?(file)
11
11
  credentials = YAML.load(File.new(file))
12
- Enom::Client.username = credentials['username']
13
- Enom::Client.password = credentials['password']
12
+ Enom::Client.username = credentials["username"]
13
+ Enom::Client.password = credentials["password"]
14
14
  else
15
15
  raise InvalidCredentials, "Please provide a username/password as arguments create a config file with credentials in ~/.enomconfig"
16
16
  end
@@ -34,18 +34,20 @@ module Enom
34
34
 
35
35
  def commands
36
36
  {
37
- 'list' => Enom::Commands::ListDomains,
38
- 'check' => Enom::Commands::CheckDomain,
39
- 'register' => Enom::Commands::RegisterDomain,
40
- 'renew' => Enom::Commands::RenewDomain,
41
- 'describe' => Enom::Commands::DescribeDomain
37
+ "list" => Enom::Commands::ListDomains,
38
+ "check" => Enom::Commands::CheckDomain,
39
+ "register" => Enom::Commands::RegisterDomain,
40
+ "renew" => Enom::Commands::RenewDomain,
41
+ "describe" => Enom::Commands::DescribeDomain,
42
+ "transfer" => Enom::Commands::TransferDomain
42
43
  }
43
44
  end
44
45
 
45
46
  end
46
47
  end
47
- require 'enom/commands/list_domains'
48
- require 'enom/commands/check_domain'
49
- require 'enom/commands/register_domain'
50
- require 'enom/commands/renew_domain'
51
- require 'enom/commands/describe_domain'
48
+ require "enom/commands/list_domains"
49
+ require "enom/commands/check_domain"
50
+ require "enom/commands/register_domain"
51
+ require "enom/commands/renew_domain"
52
+ require "enom/commands/describe_domain"
53
+ require "enom/commands/transfer_domain"
@@ -9,17 +9,17 @@ module Enom
9
9
 
10
10
  # All requests must contain the UID, PW, and ResponseType query parameters
11
11
  def default_params
12
- { 'UID' => self.username, 'PW' => self.password, 'ResponseType' => 'xml'}
12
+ { "UID" => self.username, "PW" => self.password, "ResponseType" => "xml"}
13
13
  end
14
14
 
15
15
  # Enom has a test platform and a production platform. Both are configured to use
16
- # HTTPS at all times. Don't forget to configure permitted IPs (in both environments)
17
- # or you'll get InterfaceErrors.
16
+ # HTTPS at all times. Don"t forget to configure permitted IPs (in both environments)
17
+ # or you"ll get InterfaceErrors.
18
18
  def base_uri
19
19
  @base_uri = test? ? "https://resellertest.enom.com/interface.asp" : "https://reseller.enom.com/interface.asp"
20
20
  end
21
21
 
22
- # All requests to Enom are GET requests, even when we're changing data. Unfortunately,
22
+ # All requests to Enom are GET requests, even when we"re changing data. Unfortunately,
23
23
  # Enom also does not provide HTTP status codes to alert for authentication failures
24
24
  # or other helpful statuses -- everything comes back as a 200.
25
25
  def request(params = {})
@@ -27,10 +27,10 @@ module Enom
27
27
  response = get(base_uri, :query => params)
28
28
  case response.code
29
29
  when 200
30
- if response['interface_response']['ErrCount'] == '0'
30
+ if response["interface_response"]["ErrCount"] == "0"
31
31
  return response
32
32
  else
33
- raise InterfaceError, response['interface_response']['errors'].values.join(", ")
33
+ raise InterfaceError, response["interface_response"]["errors"].values.join(", ")
34
34
  end
35
35
  end
36
36
  end
@@ -0,0 +1,14 @@
1
+ module Enom
2
+ module Commands
3
+ class TransferDomain
4
+ def execute(args, options={})
5
+ name = args.shift
6
+ auth_code = args.shift
7
+ Domain.transfer!(name, auth_code)
8
+ output = "Transferred #{name}"
9
+ puts output
10
+ return output
11
+ end
12
+ end
13
+ end
14
+ end
@@ -25,7 +25,7 @@ module Enom
25
25
  # ...
26
26
  # end
27
27
  define_method "#{contact_type.downcase}_contact_info" do
28
- Client.request('Command' => 'GetContacts', 'SLD' => sld, 'TLD' => tld)["interface_response"]["GetContacts"][contact_type]
28
+ Client.request("Command" => "GetContacts", "SLD" => sld, "TLD" => tld)["interface_response"]["GetContacts"][contact_type]
29
29
  end
30
30
 
31
31
  # Define setter methods for each contact type
@@ -34,7 +34,7 @@ module Enom
34
34
  # end
35
35
  define_method "update_#{contact_type.downcase}_contact_info" do |contact_data|
36
36
 
37
- # Remove attributes that are not in Enom's list of available fields
37
+ # Remove attributes that are not in Enom"s list of available fields
38
38
  contact_data.select!{|k| FIELDS.map{|f| f[:name] }.include?(k)}
39
39
 
40
40
  # Write the initial options hash containing the current ContactType
@@ -55,14 +55,14 @@ module Enom
55
55
  end
56
56
 
57
57
  # Send the new contact details to Enom
58
- Client.request({'Command' => 'Contacts', 'SLD' => sld, 'TLD' => tld}.merge(opts))
58
+ Client.request({"Command" => "Contacts", "SLD" => sld, "TLD" => tld}.merge(opts))
59
59
 
60
60
  # Fetch the new contact info and return it
61
61
  send("#{contact_type.downcase}_contact_info")
62
62
  end
63
63
 
64
64
  def all_contact_info
65
- Client.request('Command' => 'GetContacts', 'SLD' => sld, 'TLD' => tld)["interface_response"]["GetContacts"].select{|k| CONTACT_TYPES.include?(k)}
65
+ Client.request("Command" => "GetContacts", "SLD" => sld, "TLD" => tld)["interface_response"]["GetContacts"].select{|k| CONTACT_TYPES.include?(k)}
66
66
  end
67
67
 
68
68
  # Update all contact types with the same data
@@ -16,10 +16,10 @@ module Enom
16
16
 
17
17
  def initialize(attributes)
18
18
  @name = attributes["DomainName"] || attributes["domainname"]
19
- @sld, @tld = @name.split('.')
19
+ @sld, @tld = @name.split(".")
20
20
 
21
21
  expiration_date_string = attributes["expiration_date"] || attributes["status"]["expiration"]
22
- @expiration_date = Date.strptime(expiration_date_string.split(' ').first, "%m/%d/%Y")
22
+ @expiration_date = Date.strptime(expiration_date_string.split(" ").first, "%m/%d/%Y")
23
23
 
24
24
  # If we have more attributes for the domain from running GetDomainInfo
25
25
  # (as opposed to GetAllDomains), we should save it to the instance to
@@ -31,21 +31,56 @@ module Enom
31
31
 
32
32
  # Find the domain (must be in your account) on Enom
33
33
  def self.find(name)
34
- sld, tld = name.split('.')
35
- response = Client.request('Command' => 'GetDomainInfo', 'SLD' => sld, 'TLD' => tld)["interface_response"]["GetDomainInfo"]
34
+ sld, tld = name.split(".")
35
+ response = Client.request("Command" => "GetDomainInfo", "SLD" => sld, "TLD" => tld)["interface_response"]["GetDomainInfo"]
36
36
  Domain.new(response)
37
37
  end
38
38
 
39
39
  # Determine if the domain is available for purchase
40
40
  def self.check(name)
41
- sld, tld = name.split('.')
41
+ available?(name) ? "available" : "unavailable"
42
+ end
43
+
44
+ # Boolean helper method to determine if the domain is available for purchase
45
+ def self.available?(name)
46
+ sld, tld = name.split(".")
42
47
  response = Client.request("Command" => "Check", "SLD" => sld, "TLD" => tld)["interface_response"]["RRPCode"]
48
+ response == "210"
49
+ end
43
50
 
44
- if response == "210"
45
- "available"
46
- else
47
- "unavailable"
51
+ # Determine if a list of domains are available for purchase
52
+ # Returns an array of available domain names given
53
+
54
+ # Default TLD check lists
55
+ # * com, net, org, info, biz, us, ws, cc, tv, bz, nu
56
+ # *1 com, net, org, info, biz, us, ws
57
+ # *2 com, net, org, info, biz, us
58
+ # @ com, net, org
59
+
60
+ # You can provide one of the default check lists or provide an array of strings
61
+ # to check a custom set of TLDs. Enom currently chokes when specifying a custom
62
+ # list, so this will raise a NotImplementedError until Enom fixes this
63
+ def self.check_multiple_tlds(sld, tlds = "*")
64
+ if tlds.kind_of?(Array)
65
+ # list = tlds.join(",")
66
+ # tld = nil
67
+ raise NotImplementedError
68
+ elsif %w(* *1 *2 @).include?(tlds)
69
+ list = nil
70
+ tld = tlds
48
71
  end
72
+
73
+ response = Client.request("Command" => "Check", "SLD" => sld, "TLD" => tld, "TLDList" => list)
74
+
75
+ result = []
76
+ response["interface_response"].each do |k, v|
77
+ if v == "210" #&& k[0,6] == "RRPCode"
78
+ pos = k[7..k.size]
79
+ result << response["interface_response"]["Domain#{pos}"] unless k.blank?
80
+ end
81
+ end
82
+
83
+ return result
49
84
  end
50
85
 
51
86
  # Find and return all domains in the account
@@ -59,7 +94,7 @@ module Enom
59
94
 
60
95
  # Purchase the domain
61
96
  def self.register!(name, options = {})
62
- sld, tld = name.split('.')
97
+ sld, tld = name.split(".")
63
98
  opts = {}
64
99
  if options[:nameservers]
65
100
  count = 1
@@ -70,30 +105,71 @@ module Enom
70
105
  else
71
106
  opts.merge!("UseDNS" => "default")
72
107
  end
73
- opts.merge!('NumYears' => options[:years]) if options[:years]
74
- response = Client.request({'Command' => 'Purchase', 'SLD' => sld, 'TLD' => tld}.merge(opts))
108
+ opts.merge!("NumYears" => options[:years]) if options[:years]
109
+ response = Client.request({"Command" => "Purchase", "SLD" => sld, "TLD" => tld}.merge(opts))
75
110
  Domain.find(name)
76
111
  end
77
112
 
113
+
114
+ # Transfer domain from another registrar to Enom, charges the account when successful
115
+ # Returns true if successful, false if failed
116
+ def self.transfer!(name, auth, options = {})
117
+ sld, tld = name.split(".")
118
+
119
+ # Default options
120
+ opts = {
121
+ "OrderType" => "AutoVerification",
122
+ "DomainCount" => 1,
123
+ "SLD1" => sld,
124
+ "TLD1" => tld,
125
+ "AuthInfo1" => auth, # Authorization (EPP) key from the
126
+ "UseContacts" => 1 # Set UseContacts=1 to transfer existing Whois contacts with a domain that does not require extended attributes.
127
+ }
128
+
129
+ opts.merge!("Renew" => 1) if options[:renew]
130
+
131
+ response = Client.request({"Command" => "TP_CreateOrder"}.merge(opts))["ErrCount"]
132
+
133
+ response.to_i == 0
134
+ end
135
+
136
+
78
137
  # Renew the domain
79
138
  def self.renew!(name, options = {})
80
- sld, tld = name.split('.')
139
+ sld, tld = name.split(".")
81
140
  opts = {}
82
- opts.merge!('NumYears' => options[:years]) if options[:years]
83
- response = Client.request({'Command' => 'Extend', 'SLD' => sld, 'TLD' => tld}.merge(opts))
141
+ opts.merge!("NumYears" => options[:years]) if options[:years]
142
+ response = Client.request({"Command" => "Extend", "SLD" => sld, "TLD" => tld}.merge(opts))
84
143
  Domain.find(name)
85
144
  end
86
145
 
87
- # Lock the domain at the registrar so it can't be transferred
146
+ # Suggest available domains using the namespinner
147
+ # Returns an array of available domain names that match
148
+ def self.suggest(name, options ={})
149
+ sld, tld = name.split(".")
150
+ opts = {}
151
+ opts.merge!("MaxResults" => options[:max_results] || 8, "Similar" => options[:similar] || "High")
152
+ response = Client.request({"Command" => "namespinner", "SLD" => sld, "TLD" => tld}.merge(opts))
153
+
154
+ suggestions = []
155
+ response["interface_response"]["namespin"]["domains"]["domain"].map do |d|
156
+ %w(com net tv cc).each do |toplevel|
157
+ suggestions << [d["name"].downcase, toplevel].join(".") if d[toplevel] == "y"
158
+ end
159
+ end
160
+ return suggestions
161
+ end
162
+
163
+ # Lock the domain at the registrar so it can"t be transferred
88
164
  def lock
89
- Client.request('Command' => 'SetRegLock', 'SLD' => sld, 'TLD' => tld, 'UnlockRegistrar' => '0')
165
+ Client.request("Command" => "SetRegLock", "SLD" => sld, "TLD" => tld, "UnlockRegistrar" => "0")
90
166
  @locked = true
91
167
  return self
92
168
  end
93
169
 
94
170
  # Unlock the domain at the registrar to permit transfers
95
171
  def unlock
96
- Client.request('Command' => 'SetRegLock', 'SLD' => sld, 'TLD' => tld, 'UnlockRegistrar' => '1')
172
+ Client.request("Command" => "SetRegLock", "SLD" => sld, "TLD" => tld, "UnlockRegistrar" => "1")
97
173
  @locked = false
98
174
  return self
99
175
  end
@@ -101,8 +177,8 @@ module Enom
101
177
  # Check if the domain is currently locked. locked? helper method also available
102
178
  def locked
103
179
  unless defined?(@locked)
104
- response = Client.request('Command' => 'GetRegLock', 'SLD' => sld, 'TLD' => tld)['interface_response']['reg_lock']
105
- @locked = response == '1'
180
+ response = Client.request("Command" => "GetRegLock", "SLD" => sld, "TLD" => tld)["interface_response"]["reg_lock"]
181
+ @locked = response == "1"
106
182
  end
107
183
  return @locked
108
184
  end
@@ -128,7 +204,7 @@ module Enom
128
204
  ns.merge!("NS#{count}" => nameserver)
129
205
  count += 1
130
206
  end
131
- Client.request({'Command' => 'ModifyNS', 'SLD' => sld, 'TLD' => tld}.merge(ns))
207
+ Client.request({"Command" => "ModifyNS", "SLD" => sld, "TLD" => tld}.merge(ns))
132
208
  @nameservers = ns.values
133
209
  return self
134
210
  else
@@ -138,8 +214,8 @@ module Enom
138
214
 
139
215
  def expiration_date
140
216
  unless defined?(@expiration_date)
141
- date_string = @domain_payload['interface_response']['GetDomainInfo']['status']['expiration']
142
- @expiration_date = Date.strptime(date_string.split(' ').first, "%m/%d/%Y")
217
+ date_string = @domain_payload["interface_response"]["GetDomainInfo"]["status"]["expiration"]
218
+ @expiration_date = Date.strptime(date_string.split(" ").first, "%m/%d/%Y")
143
219
  end
144
220
  @expiration_date
145
221
  end
@@ -166,15 +242,15 @@ module Enom
166
242
  # Make another API call to get all domain info. Often necessary when domains are
167
243
  # found using Domain.all instead of Domain.find.
168
244
  def get_extended_domain_attributes
169
- sld, tld = name.split('.')
170
- attributes = Client.request('Command' => 'GetDomainInfo', 'SLD' => sld, 'TLD' => tld)["interface_response"]["GetDomainInfo"]
245
+ sld, tld = name.split(".")
246
+ attributes = Client.request("Command" => "GetDomainInfo", "SLD" => sld, "TLD" => tld)["interface_response"]["GetDomainInfo"]
171
247
  set_extended_domain_attributes(attributes)
172
248
  end
173
249
 
174
250
  # Set any more attributes that we have to work with to instance variables
175
251
  def set_extended_domain_attributes(attributes)
176
- @nameservers = attributes['services']['entry'].first['configuration']['dns']
177
- @registration_status = attributes['status']['registrationstatus']
252
+ @nameservers = attributes["services"]["entry"].first["configuration"]["dns"]
253
+ @registration_status = attributes["status"]["registrationstatus"]
178
254
  return self
179
255
  end
180
256
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class AccountTest < Test::Unit::TestCase
4
4
 
@@ -1,5 +1,5 @@
1
- require 'test_helper'
2
- require File.expand_path('../../lib/enom/cli', __FILE__)
1
+ require "test_helper"
2
+ require File.expand_path("../../lib/enom/cli", __FILE__)
3
3
 
4
4
  class CliTest < Test::Unit::TestCase
5
5
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class ClientTest < Test::Unit::TestCase
4
4
 
@@ -13,7 +13,7 @@ class ClientTest < Test::Unit::TestCase
13
13
  assert_equal "resellidtest", Enom::Client.username
14
14
  assert_equal "resellpwtest", Enom::Client.password
15
15
  assert_equal "https://resellertest.enom.com/interface.asp", Enom::Client.base_uri
16
- assert_equal Hash['UID' => 'resellidtest', 'PW' => 'resellpwtest', 'ResponseType' => 'xml'], Enom::Client.default_params
16
+ assert_equal Hash["UID" => "resellidtest", "PW" => "resellpwtest", "ResponseType" => "xml"], Enom::Client.default_params
17
17
  end
18
18
  end
19
19
 
@@ -27,7 +27,7 @@ class ClientTest < Test::Unit::TestCase
27
27
  assert_equal "resellid", Enom::Client.username
28
28
  assert_equal "resellpw", Enom::Client.password
29
29
  assert_equal "https://reseller.enom.com/interface.asp", Enom::Client.base_uri
30
- assert_equal Hash['UID' => 'resellid', 'PW' => 'resellpw', 'ResponseType' => 'xml'], Enom::Client.default_params
30
+ assert_equal Hash["UID" => "resellid", "PW" => "resellpw", "ResponseType" => "xml"], Enom::Client.default_params
31
31
  end
32
32
  end
33
33
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class ContactInfoTest < Test::Unit::TestCase
4
4
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class DomainTest < Test::Unit::TestCase
4
4
 
@@ -26,9 +26,71 @@ class DomainTest < Test::Unit::TestCase
26
26
  context "checking for available domains" do
27
27
  should "return 'available' for an available domain" do
28
28
  assert_equal "available", Enom::Domain.check("test123456test123456.com")
29
+ assert Enom::Domain.available?("test123456test123456.com")
29
30
  end
30
31
  should "return 'unavailable' for an unavailable domain" do
31
32
  assert_equal "unavailable", Enom::Domain.check("google.com")
33
+ assert !Enom::Domain.available?("google.com")
34
+ end
35
+ end
36
+
37
+ context "checking multiple TLDs for a single domain" do
38
+ should "return an array of available domains with the provided TLD" do
39
+ wildcard_tld_domains = %w(
40
+ test123456test123456.com
41
+ test123456test123456.net
42
+ test123456test123456.org
43
+ test123456test123456.info
44
+ test123456test123456.biz
45
+ test123456test123456.ws
46
+ test123456test123456.us
47
+ test123456test123456.cc
48
+ test123456test123456.tv
49
+ test123456test123456.bz
50
+ test123456test123456.nu
51
+ test123456test123456.mobi
52
+ test123456test123456.eu
53
+ test123456test123456.ca
54
+ )
55
+ assert_equal wildcard_tld_domains.sort, Enom::Domain.check_multiple_tlds("test123456test123456","*").sort
56
+ #assert_equal ["test123456test123456.us", "test123456test123456.ca", "test123456test123456.com"], Enom::Domain.check_multiple_tlds("test123456test123456", ["us", "ca", "com"])
57
+ end
58
+ end
59
+
60
+ context "checking for suggested domains" do
61
+ setup do
62
+ @suggestions = Enom::Domain.suggest("hand.com")
63
+ end
64
+ should "return an array of suggestions matching the supplied term" do
65
+ assert !@suggestions.empty?
66
+ suggestions = %w(
67
+ handsewncurtains.net
68
+ handsewncurtains.tv
69
+ handsewncurtains.cc
70
+ handicappingclub.net
71
+ handicappingclub.tv
72
+ handicappingclub.cc
73
+ handingok.com
74
+ handingok.net
75
+ handingok.tv
76
+ handingok.cc
77
+ handsofjustice.tv
78
+ handsofjustice.cc
79
+ handoki.net
80
+ handoki.tv
81
+ handoki.cc
82
+ handinghand.com
83
+ handinghand.net
84
+ handinghand.tv
85
+ handinghand.cc
86
+ handcrafthouselogs.com
87
+ handcrafthouselogs.net
88
+ handcrafthouselogs.tv
89
+ handcrafthouselogs.cc
90
+ handloser.tv
91
+ handloser.cc
92
+ )
93
+ assert_equal suggestions, @suggestions
32
94
  end
33
95
  end
34
96
 
@@ -42,6 +104,15 @@ class DomainTest < Test::Unit::TestCase
42
104
  end
43
105
  end
44
106
 
107
+ context "transfer a domain" do
108
+ setup do
109
+ @result = Enom::Domain.transfer!("resellerdocs2.net", "ros8enQi")
110
+ end
111
+ should "transfer the domain and return true if successful" do
112
+ assert @result
113
+ end
114
+ end
115
+
45
116
  context "renewing a domain" do
46
117
  setup do
47
118
  @domain = Enom::Domain.renew!("test123456test123456.com")
@@ -1,9 +1,9 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
4
- require 'fakeweb'
1
+ require "rubygems"
2
+ require "test/unit"
3
+ require "shoulda"
4
+ require "fakeweb"
5
5
 
6
- require File.expand_path('../../lib/enom', __FILE__)
6
+ require File.expand_path("../../lib/enom", __FILE__)
7
7
 
8
8
  class Test::Unit::TestCase
9
9
 
@@ -94,6 +94,113 @@ class Test::Unit::TestCase
94
94
  </interface-response>
95
95
  EOF
96
96
  },
97
+ {
98
+ :command => "Check Many with default (*) TLD list (Success)",
99
+ :request => "https://reseller.enom.com/interface.asp?Command=Check&SLD=test123456test123456&TLD=*&TLDList=&UID=resellid&PW=resellpw&ResponseType=xml",
100
+ :response => <<-EOF
101
+ <?xml version="1.0"?>
102
+ <interface-response>
103
+ <Domain1>test123456test123456.com</Domain1>
104
+ <RRPCode1>210</RRPCode1>
105
+ <RRPText1>Domain available</RRPText1>
106
+ <Domain2>test123456test123456.net</Domain2>
107
+ <RRPCode2>210</RRPCode2>
108
+ <RRPText2>Domain available</RRPText2>
109
+ <Domain3>test123456test123456.org</Domain3>
110
+ <RRPCode3>210</RRPCode3>
111
+ <RRPText3>Domain available</RRPText3>
112
+ <Domain4>test123456test123456.info</Domain4>
113
+ <RRPCode4>210</RRPCode4>
114
+ <RRPText4>Domain available</RRPText4>
115
+ <Domain5>test123456test123456.biz</Domain5>
116
+ <RRPCode5>210</RRPCode5>
117
+ <RRPText5>Domain available</RRPText5>
118
+ <Domain6>test123456test123456.ws</Domain6>
119
+ <RRPCode6>210</RRPCode6>
120
+ <RRPText6>Domain available</RRPText6>
121
+ <Domain7>test123456test123456.us</Domain7>
122
+ <RRPCode7>210</RRPCode7>
123
+ <RRPText7>Domain available</RRPText7>
124
+ <Domain8>test123456test123456.cc</Domain8>
125
+ <RRPCode8>210</RRPCode8>
126
+ <RRPText8>Domain available</RRPText8>
127
+ <Domain9>test123456test123456.tv</Domain9>
128
+ <PremiumName>
129
+ <IsPremiumName>False</IsPremiumName>
130
+ <PremiumPrice/>
131
+ <PremiumAboveThresholdPrice>False</PremiumAboveThresholdPrice>
132
+ <PremiumCategory>False</PremiumCategory>
133
+ </PremiumName>
134
+ <RRPCode9>210</RRPCode9>
135
+ <RRPText9>Domain available</RRPText9>
136
+ <Domain10>test123456test123456.bz</Domain10>
137
+ <RRPCode10>210</RRPCode10>
138
+ <RRPText10>Domain available</RRPText10>
139
+ <Domain11>test123456test123456.nu</Domain11>
140
+ <RRPCode11>210</RRPCode11>
141
+ <RRPText11>Domain available</RRPText11>
142
+ <Domain12>test123456test123456.mobi</Domain12>
143
+ <RRPCode12>210</RRPCode12>
144
+ <RRPText12>Domain available</RRPText12>
145
+ <Domain13>test123456test123456.eu</Domain13>
146
+ <RRPCode13>210</RRPCode13>
147
+ <RRPText13>Domain available</RRPText13>
148
+ <Domain14>test123456test123456.ca</Domain14>
149
+ <RRPCode14>210</RRPCode14>
150
+ <RRPText14>Domain available</RRPText14>
151
+ <DomainCount>14</DomainCount>
152
+ <Command>CHECK</Command>
153
+ <Language>eng</Language>
154
+ <ErrCount>0</ErrCount>
155
+ <ResponseCount>0</ResponseCount>
156
+ <MinPeriod>1</MinPeriod>
157
+ <MaxPeriod>10</MaxPeriod>
158
+ <Server>SJL01WRESELL15</Server>
159
+ <Site>eNom</Site>
160
+ <IsLockable>True</IsLockable>
161
+ <IsRealTimeTLD>True</IsRealTimeTLD>
162
+ <TimeDifference>+00.00</TimeDifference>
163
+ <ExecTime>2.156</ExecTime>
164
+ <Done>true</Done>
165
+ <debug><![CDATA[]]></debug>
166
+ </interface-response>
167
+ EOF
168
+ },
169
+ {
170
+ :command => "Check Many with custom array TLD list (Success)",
171
+ :request => "https://reseller.enom.com/interface.asp?Command=Check&SLD=test123456test123456&TLD=&TLDList=us%2Cca%2Ccom&UID=resellid&PW=resellpw&ResponseType=xml",
172
+ :response => <<-EOF
173
+ <?xml version="1.0"?>
174
+ <interface-response>
175
+ <Domain>test123456test123456.us</Domain>
176
+ <RRPCode>210</RRPCode>
177
+ <RRPText>Domain available</RRPText>
178
+ <Domain>test123456test123456.ca</Domain>
179
+ <RRPCode>210</RRPCode>
180
+ <RRPText>Domain available</RRPText>
181
+ <Domain>test123456test123456.com</Domain>
182
+ <RRPCode>210</RRPCode>
183
+ <RRPText>Domain available</RRPText>
184
+ <DomainCount>3</DomainCount>
185
+ <AuctionDate/>
186
+ <AuctionID/>
187
+ <Command>CHECK</Command>
188
+ <Language>eng</Language>
189
+ <ErrCount>0</ErrCount>
190
+ <ResponseCount>0</ResponseCount>
191
+ <MinPeriod/>
192
+ <MaxPeriod>10</MaxPeriod>
193
+ <Server>SJL01WRESELL06</Server>
194
+ <Site>eNom</Site>
195
+ <IsLockable/>
196
+ <IsRealTimeTLD/>
197
+ <TimeDifference>+0.00</TimeDifference>
198
+ <ExecTime>0.344</ExecTime>
199
+ <Done>true</Done>
200
+ <debug><![CDATA[]]></debug>
201
+ </interface-response>
202
+ EOF
203
+ },
97
204
  {
98
205
  :command => "GetDomainInfo (Success)",
99
206
  :request => "https://reseller.enom.com/interface.asp?Command=GetDomainInfo&SLD=test123456test123456&TLD=com&UID=resellid&PW=resellpw&ResponseType=xml",
@@ -328,6 +435,53 @@ class Test::Unit::TestCase
328
435
  </interface-response>
329
436
  EOF
330
437
  },
438
+ {
439
+ :command => "Transfer domain",
440
+ :request => "https://reseller.enom.com/interface.asp?Command=TP_CreateOrder&OrderType=AutoVerification&DomainCount=1&SLD1=resellerdocs2&TLD1=net&AuthInfo1=ros8enQi&UseContacts=1&UID=resellid&PW=resellpw&ResponseType=xml",
441
+ :response => <<-EOF
442
+ <?xml version="1.0"?>
443
+ <interface-response>
444
+ <success>True</success>
445
+ <transferorder>
446
+ <transferorderid>175614452</transferorderid>
447
+ <orderdate>9/7/2011 10:59:21 AM</orderdate>
448
+ <ordertypeid>1</ordertypeid>
449
+ <ordertypedesc>Auto Verification</ordertypedesc>
450
+ <statusid>4</statusid>
451
+ <statusdesc>Processing</statusdesc>
452
+ <authamount>8.95</authamount>
453
+ <version>1</version>
454
+ <transferorderdetail>
455
+ <transferorderdetailid>77455163</transferorderdetailid>
456
+ <sld>resellerdocs2</sld>
457
+ <tld>net</tld>
458
+ <statusid>9</statusid>
459
+ <statusdesc>Awaiting auto verification of transfer request</statusdesc>
460
+ <price>8.95</price>
461
+ <usecontacts>1</usecontacts>
462
+ </transferorderdetail>
463
+ <transferorderdetailcount>1</transferorderdetailcount>
464
+ </transferorder>
465
+ <success>True</success>
466
+ <Command>TP_CREATEORDER</Command>
467
+ <Language>eng</Language>
468
+ <ErrCount>0</ErrCount>
469
+ <ResponseCount>0</ResponseCount>
470
+ <MinPeriod>1</MinPeriod>
471
+ <MaxPeriod>10</MaxPeriod>
472
+ <Server>SJL21WRESELLT01</Server>
473
+ <Site>eNom</Site>
474
+ <IsLockable>True</IsLockable>
475
+ <IsRealTimeTLD>True</IsRealTimeTLD>
476
+ <TimeDifference>+08.00</TimeDifference>
477
+ <ExecTime>0.563</ExecTime>
478
+ <Done>true</Done>
479
+ <debug>
480
+ <![CDATA[ ]]>
481
+ </debug>
482
+ </interface-response>
483
+ EOF
484
+ },
331
485
  {
332
486
  :command => "GetAllDomains",
333
487
  :request => "https://reseller.enom.com/interface.asp?Command=GetAllDomains&UID=resellid&PW=resellpw&ResponseType=xml",
@@ -368,6 +522,46 @@ class Test::Unit::TestCase
368
522
  <debug><![CDATA[]]></debug>
369
523
  </interface-response>
370
524
  EOF
525
+ },
526
+ {
527
+ :command => "NameSpinner",
528
+ :request => "https://reseller.enom.com/interface.asp?Command=namespinner&SLD=hand&TLD=com&MaxResults=8&Similar=High&UID=resellid&PW=resellpw&ResponseType=xml",
529
+ :response => <<-EOF
530
+ <?xml version="1.0"?>
531
+ <interface-response>
532
+ <namespin>
533
+ <spincount>8</spincount>
534
+ <TLDList />
535
+ <domains>
536
+ <domain name="Handsewncurtains" com="n" comscore="835" net="y" netscore="864" tv="y" tvscore="797" cc="y" ccscore="762" />
537
+ <domain name="Handicappingclub" com="n" comscore="821" net="y" netscore="851" tv="y" tvscore="784" cc="y" ccscore="749" />
538
+ <domain name="Handingok" com="y" comscore="837" net="y" netscore="810" tv="y" tvscore="783" cc="y" ccscore="757" />
539
+ <domain name="Handsofjustice" com="n" comscore="870" net="n" netscore="844" tv="y" tvscore="834" cc="y" ccscore="799" />
540
+ <domain name="Handoki" com="n" comscore="794" net="y" netscore="824" tv="y" tvscore="757" cc="y" ccscore="722" />
541
+ <domain name="Handinghand" com="y" comscore="820" net="y" netscore="793" tv="y" tvscore="767" cc="y" ccscore="740" />
542
+ <domain name="Handcrafthouselogs" com="y" comscore="810" net="y" netscore="783" tv="y" tvscore="757" cc="y" ccscore="730" />
543
+ <domain name="Handloser" com="n" comscore="844" net="n" netscore="817" tv="y" tvscore="807" cc="y" ccscore="773" />
544
+ </domains>
545
+ </namespin>
546
+ <originalsld>hand</originalsld>
547
+ <Command>NAMESPINNER</Command>
548
+ <Language>eng</Language>
549
+ <ErrCount>0</ErrCount>
550
+ <ResponseCount>0</ResponseCount>
551
+ <MinPeriod>1</MinPeriod>
552
+ <MaxPeriod>10</MaxPeriod>
553
+ <Server>RESELLER1-STG</Server>
554
+ <Site>enom</Site>
555
+ <IsLockable>True</IsLockable>
556
+ <IsRealTimeTLD>True</IsRealTimeTLD>
557
+ <TimeDifference>+03.00</TimeDifference>
558
+ <ExecTime>0.719</ExecTime>
559
+ <Done>true</Done>
560
+ <debug>
561
+ <![CDATA[ ]]>
562
+ </debug>
563
+ </interface-response>
564
+ EOF
371
565
  }
372
566
  ]
373
567
 
metadata CHANGED
@@ -1,73 +1,69 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: enom
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 1
7
- - 0
8
- - 0
9
- version: 1.0.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - James Miller
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-01-30 00:00:00 -08:00
18
- default_executable: enom
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2011-09-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: httparty
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70314757598780 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
18
+ requirements:
26
19
  - - ~>
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
- - 7
31
- - 3
32
- version: 0.7.3
20
+ - !ruby/object:Gem::Version
21
+ version: 0.7.8
33
22
  type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: shoulda
37
23
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70314757598780
25
+ - !ruby/object:Gem::Dependency
26
+ name: shoulda
27
+ requirement: &70314757598380 !ruby/object:Gem::Requirement
39
28
  none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- segments:
44
- - 0
45
- version: "0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
46
33
  type: :development
47
- version_requirements: *id002
48
- - !ruby/object:Gem::Dependency
34
+ prerelease: false
35
+ version_requirements: *70314757598380
36
+ - !ruby/object:Gem::Dependency
49
37
  name: fakeweb
38
+ requirement: &70314757597920 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
50
45
  prerelease: false
51
- requirement: &id003 !ruby/object:Gem::Requirement
46
+ version_requirements: *70314757597920
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &70314757597420 !ruby/object:Gem::Requirement
52
50
  none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- segments:
57
- - 0
58
- version: "0"
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0.9'
59
55
  type: :development
60
- version_requirements: *id003
61
- description: Enom is a Ruby wrapper and command line interface for portions of the Enom domain reseller API.
56
+ prerelease: false
57
+ version_requirements: *70314757597420
58
+ description: Enom is a Ruby wrapper and command line interface for portions of the
59
+ Enom domain reseller API.
62
60
  email: bensie@gmail.com
63
- executables:
61
+ executables:
64
62
  - enom
65
63
  extensions: []
66
-
67
64
  extra_rdoc_files: []
68
-
69
- files:
70
- - README.rdoc
65
+ files:
66
+ - README.md
71
67
  - Rakefile
72
68
  - LICENSE
73
69
  - lib/enom.rb
@@ -82,6 +78,7 @@ files:
82
78
  - lib/enom/commands/list_domains.rb
83
79
  - lib/enom/commands/register_domain.rb
84
80
  - lib/enom/commands/renew_domain.rb
81
+ - lib/enom/commands/transfer_domain.rb
85
82
  - test/account_test.rb
86
83
  - test/cli_test.rb
87
84
  - test/client_test.rb
@@ -90,37 +87,28 @@ files:
90
87
  - test/test_helper.rb
91
88
  - bin/enom
92
89
  - bin/enom.rb
93
- has_rdoc: true
94
90
  homepage: http://github.com/bensie/enom
95
91
  licenses: []
96
-
97
92
  post_install_message:
98
93
  rdoc_options: []
99
-
100
- require_paths:
94
+ require_paths:
101
95
  - lib
102
- required_ruby_version: !ruby/object:Gem::Requirement
96
+ required_ruby_version: !ruby/object:Gem::Requirement
103
97
  none: false
104
- requirements:
105
- - - ">="
106
- - !ruby/object:Gem::Version
107
- segments:
108
- - 0
109
- version: "0"
110
- required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
103
  none: false
112
- requirements:
113
- - - ">="
114
- - !ruby/object:Gem::Version
115
- segments:
116
- - 0
117
- version: "0"
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
118
108
  requirements: []
119
-
120
109
  rubyforge_project:
121
- rubygems_version: 1.3.7
110
+ rubygems_version: 1.8.6
122
111
  signing_key:
123
112
  specification_version: 3
124
113
  summary: Ruby wrapper for the Enom API
125
114
  test_files: []
126
-
@@ -1,12 +0,0 @@
1
- = Enom
2
-
3
- A ruby wrapper for the Enom Domain Registrar's API for checking domain name
4
- availability, domain contact information, name server settings, etc.
5
-
6
- gem install enom
7
-
8
- See the Wiki (https://github.com/bensie/enom/wiki) for usage instructions.
9
-
10
- = Copyright
11
-
12
- Copyright (c) 2011 James Miller