epp-client 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 80878ef18fa5460776840d8c1c512a36cf48e8e6
4
- data.tar.gz: bf787e1cf786d17c0f226e69d067e83c1c1867ff
3
+ metadata.gz: 593b7e211a6bc863d15336709228708ce22368d2
4
+ data.tar.gz: 8cacbdd420ff80c12238956fba39510219f66a82
5
5
  SHA512:
6
- metadata.gz: bed66d9db6da5af4ea69f2690446707358f945975c0b0ff970a8892cf64185488e1f94768d14e4d7b1957db090d221cf9f79b5cd8b500e0a9a9de626f41e6f30
7
- data.tar.gz: 04fa093a95aa55c84e3094e64681788c44de675895ac36361b46a729d9941638d9e16eab7b62ff5f164d6b4969fbecd4bd52ce2aabea8ab5bdffeddc974d3697
6
+ metadata.gz: d7df5c50e3af2f3db322e3c8ec211ac64c191cb4641e8774c8a089bc16da3ca1820a76357eb05095581a127546ba1b18090a3c1616ed854154cd4c39cbc37905
7
+ data.tar.gz: b698287a84811a9305236a1113bd74d553280512c4baa920fb6a7548566807de6efa42ec4cf7c34b81110153792f0dcdbd9170ebdb9feaef008b8b41caac6f84
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- epp-client (1.0.0)
4
+ epp-client (2.0.0)
5
5
  libxml-ruby
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # EPP Client
2
2
 
3
+ [![Build Status](https://travis-ci.org/m247/epp-client.svg?branch=master)](https://travis-ci.org/m247/epp-client)
4
+
3
5
  Client for communicating with EPP services
4
6
 
5
7
  ## Installation
@@ -16,55 +18,60 @@ Or install it yourself as:
16
18
 
17
19
  $ gem install epp-client
18
20
 
19
- ## Usage
20
-
21
- client = EPP::Client.new('username', 'password', 'epp.server.com')
22
- client.hello
23
- puts client._last_request.inspect
24
- puts client._last_response.inspect
25
-
26
- Any other methods called on `client` will be passed through to an
27
- authenticated EPP server connection. As a quick example, either a
28
- string of XML, an XML::Node or XML::Document can be passed or a
29
- block may be used
30
-
31
- ### domain:check using string payload
32
-
33
- client.check <<-EOXML
34
- <domain:check
35
- xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
36
- <domain:name>example.com</domain:name>
37
- <domain:name>example.net</domain:name>
38
- <domain:name>example.org</domain:name>
39
- </domain:check>
40
- EOXML
21
+ ## Version 2.0.0
41
22
 
42
- ### domain:check using XML::Node payload
23
+ The version has been bumped to 2.0.0 due to the introduction of a backwards incompatible change.
43
24
 
44
- xml = XML::Node.new('check')
45
- ns = XML::Namespace.new(xml, 'domain', 'urn:ietf:params:xml:ns:domain-1.0')
46
- xml.namespaces.namespace = ns
25
+ * `EPP::Domain::InfoResponse#status` now returns an array of statuses as part of m247/epp-client#7.
47
26
 
48
- %w(example.com example.net example.org).each do |name|
49
- xml << XML::Node.new('name', name, ns)
50
- end
51
-
52
- client.check xml
53
-
54
- ### domain:check using block
55
-
56
- client.check do |xml|
57
- xml << (check = XML::Node.new('check'))
58
- ns = XML::Namespace.new(check, 'domain', 'urn:ietf:params:xml:ns:domain-1.0')
59
- check.namespaces.namespace = ns
60
-
61
- %w(example.com example.net example.org).each do |name|
62
- check << XML::Node.new('name', name, ns)
63
- end
64
- end
27
+ ## Usage
65
28
 
66
- If you leave off the block parameter then the return value of the block will be
67
- inserted into the `xml`.
29
+ client = EPP::Client.new('username', 'password', 'epp.server.com')
30
+ client.hello
31
+ puts client.last_request.to_s(:indent => 2)
32
+ puts client.last_response.to_s(:indent => 2)
33
+
34
+ The old `method_missing` behaviour has been removed and replaced with defined
35
+ methods for handling each of the distinct EPP commands.
36
+
37
+ * `check`
38
+ * `create`
39
+ * `delete`
40
+ * `info`
41
+ * `renew`
42
+ * `transfer`
43
+ * `update`
44
+ * `poll`
45
+ * `ack`
46
+
47
+ each of these methods, with the exception of `poll` and `ack`, accept two arguments.
48
+ Those arguments are a `payload` and an optional `extension`. The majority of the
49
+ common `domain`, `contact` and `host` payloads have been defined already.
50
+
51
+ ### Domain Check Example
52
+
53
+ resp = client.check EPP::Domain::Check.new('example.com', 'example.net', 'example.org')
54
+ check = EPP::Domain::CheckResponse.new(resp)
55
+ check.available?('example.com') #=> true
56
+ check.available?('example.net') #=> false
57
+ check.available?('example.org') #=> false
58
+
59
+ ### Domain Information Example
60
+
61
+ resp = client.info EPP::Domain::Info.new('example.com')
62
+ info = EPP::Domain::InfoResponse.new(resp)
63
+ info.name #=> "example.com"
64
+ info.nameservers #=> [{"name"=>"ns1.example.net"},{"name"=>"ns2.example.net"}]
65
+
66
+ ### Payload an Extension API
67
+
68
+ The objects which are passed to the `client` methods need to adhere to the following
69
+ API in order to be successfully marshalled by the `client` into the required XML
70
+ document.
71
+
72
+ * `name` to specify the EPP command name. Required.
73
+ * `to_xml` returns an `XML::Document`. Required.
74
+ * `set_namespaces` to receive `XML::Namespace` objects from the parent. Optional.
68
75
 
69
76
  ## Contributing
70
77
 
@@ -21,6 +21,7 @@ module EPP
21
21
  # @param [String] host EPP Host address
22
22
  # @param [Hash] options Options
23
23
  # @option options [Integer] :port EPP Port number, default 700
24
+ # @option options [OpenSSL::SSL::SSLContext] :ssl_context For client certificate auth
24
25
  # @option options [Boolean] :compatibility Compatibility mode, default false
25
26
  # @option options [String] :lang EPP Language code, default 'en'
26
27
  # @option options [String] :version EPP protocol version, default '1.0'
@@ -29,6 +30,7 @@ module EPP
29
30
  # @option options [String] :address_family 'AF_INET' or 'AF_INET6' or either of the
30
31
  # appropriate socket constants. Will cause connections to be
31
32
  # limited to this address family. Default try all addresses.
33
+
32
34
  def initialize(tag, passwd, host, options = {})
33
35
  @tag, @passwd, @host, @options = tag, passwd, host, options
34
36
  @conn = if options.delete(:compatibility) == true
@@ -3,13 +3,32 @@ require File.expand_path('../response', __FILE__)
3
3
  module EPP
4
4
  module Contact
5
5
  class CheckResponse < Response
6
- def available?(id)
7
- availability[id]
6
+ def available?(id = nil)
7
+ return availability[id] if id
8
+
9
+ if id.nil? && availability.count == 1
10
+ return availability.values.first
11
+ end
12
+
13
+ raise ArgumentError, "id must be specified if more than one contact checked"
8
14
  end
9
- def unavailable?(id)
15
+ def unavailable?(id = nil)
10
16
  !available?(id)
11
17
  end
12
18
 
19
+ def ids
20
+ availability.keys
21
+ end
22
+
23
+ def id
24
+ raise "id unavailable when more than one contact checked, use #ids" if count != 1
25
+ ids.first
26
+ end
27
+
28
+ def count
29
+ availability.count
30
+ end
31
+
13
32
  protected
14
33
  def availability
15
34
  @availability ||= nodes_for_xpath('//contact:id').inject({}) do |hash, node|
@@ -5,6 +5,15 @@ module EPP
5
5
  attr_reader :namespaces
6
6
 
7
7
  DISCLOSE_ORDER = ['name', 'org', 'addr', 'voice', 'fax', 'email']
8
+ MAX_STREETS = 3
9
+
10
+ class TooManyStreetLines < RuntimeError
11
+ attr_reader :streets
12
+ def initialize(streets)
13
+ super("too many streets, #{streets[MAX_STREETS..-1]} would be excluded")
14
+ @streets = streets
15
+ end
16
+ end
8
17
 
9
18
  def set_namespaces(namespaces)
10
19
  @namespaces = namespaces
@@ -48,7 +57,17 @@ module EPP
48
57
  def addr_to_xml(addr)
49
58
  node = contact_node('addr')
50
59
 
51
- node << contact_node('street', addr[:street]) if addr[:street]
60
+ if addr[:street]
61
+ streets = addr[:street].split("\n")
62
+ if streets.count > MAX_STREETS
63
+ raise TooManyStreetLines.new(streets)
64
+ end
65
+
66
+ streets.each do |street|
67
+ node << contact_node('street', street)
68
+ end
69
+ end
70
+
52
71
  node << contact_node('city', addr[:city])
53
72
  node << contact_node('sp', addr[:sp]) if addr[:sp]
54
73
  node << contact_node('pc', addr[:pc]) if addr[:pc]
@@ -3,13 +3,32 @@ require File.expand_path('../response', __FILE__)
3
3
  module EPP
4
4
  module Domain
5
5
  class CheckResponse < Response
6
- def available?(name)
7
- availability[name]
6
+ def available?(name = nil)
7
+ return availability[name] if name
8
+
9
+ if name.nil? && availability.count == 1
10
+ return availability.values.first
11
+ end
12
+
13
+ raise ArgumentError, "name must be specified if more than one domain checked"
8
14
  end
9
- def unavailable?(name)
15
+ def unavailable?(name = nil)
10
16
  !available?(name)
11
17
  end
12
-
18
+
19
+ def names
20
+ availability.keys
21
+ end
22
+
23
+ def name
24
+ raise "name unavailable when more than one domain checked, use #names" if count != 1
25
+ names.first
26
+ end
27
+
28
+ def count
29
+ availability.count
30
+ end
31
+
13
32
  protected
14
33
  def availability
15
34
  @availability ||= nodes_for_xpath('//domain:name').inject({}) do |hash, node|
@@ -17,7 +17,7 @@ module EPP
17
17
  def initialize(name, options = {})
18
18
  @name = name
19
19
  @period = options.delete(:period) || '1y'
20
- @nameservers = Array(options.delete(:nameservers))
20
+ @nameservers = Array(options.delete(:nameservers))
21
21
  @registrant = options.delete(:registrant)
22
22
  @contacts = options.delete(:contacts)
23
23
  @auth_info = options.delete(:auth_info)
@@ -41,7 +41,7 @@ module EPP
41
41
  contacts_to_xml(node, @contacts)
42
42
 
43
43
  node << auth_info_to_xml(@auth_info) unless @auth_info.empty?
44
-
44
+
45
45
  node
46
46
  end
47
47
  end
@@ -10,7 +10,7 @@ module EPP
10
10
  @roid ||= value_for_xpath('//domain:roid')
11
11
  end
12
12
  def status
13
- @status ||= value_for_xpath('//domain:status/@s')
13
+ @status ||= values_for_xpath('//domain:status/@s')
14
14
  end
15
15
  def registrant
16
16
  @registrant ||= value_for_xpath('//domain:registrant')
@@ -24,9 +24,15 @@ module EPP
24
24
  def nameservers
25
25
  @nameservers ||= nodes_for_xpath('//domain:ns').map do |ns_node|
26
26
  ns = ns_node.find('domain:hostAttr', namespaces).map do |hostAttr|
27
- { 'name' => hostAttr.find('domain:name').first.content.strip,
28
- 'ipv4' => hostAttr.find('domain:addr[@ip="v4"]').first.content.strip,
29
- 'ipv6' => hostAttr.find('domain:addr[@ip="v6"]').first.content.strip }
27
+ name_node = hostAttr.find('domain:hostName').first
28
+ ipv4_node = hostAttr.find('domain:hostAddr[@ip="v4"]').first
29
+ ipv6_node = hostAttr.find('domain:hostAddr[@ip="v6"]').first
30
+
31
+ {}.tap do |result|
32
+ result['name']= name_node.content.strip if name_node
33
+ result['ipv4']= ipv4_node.content.strip if ipv4_node
34
+ result['ipv6']= ipv6_node.content.strip if ipv6_node
35
+ end
30
36
  end
31
37
 
32
38
  ns + ns_node.find('domain:hostObj').map { |n| { 'name' => n.content.strip } }
@@ -3,13 +3,32 @@ require File.expand_path('../response', __FILE__)
3
3
  module EPP
4
4
  module Host
5
5
  class CheckResponse < Response
6
- def available?(name)
7
- availability[name]
6
+ def available?(name = nil)
7
+ return availability[name] if name
8
+
9
+ if name.nil? && availability.count == 1
10
+ return availability.values.first
11
+ end
12
+
13
+ raise ArgumentError, "name must be specified if more than one host checked"
8
14
  end
9
- def unavailable?(name)
15
+ def unavailable?(name = nil)
10
16
  !available?(name)
11
17
  end
12
-
18
+
19
+ def names
20
+ availability.keys
21
+ end
22
+
23
+ def name
24
+ raise "name unavailable when more than one host checked, use #names" if count != 1
25
+ names.first
26
+ end
27
+
28
+ def count
29
+ availability.count
30
+ end
31
+
13
32
  protected
14
33
  def availability
15
34
  @availability ||= nodes_for_xpath('//host:name').inject({}) do |hash, node|
@@ -52,6 +52,7 @@ module EPP
52
52
  # @param [String] host EPP Server address
53
53
  # @param [Hash] options configuration options
54
54
  # @option options [Integer] :port EPP Port number, default 700
55
+ # @option options [OpenSSL::SSL::SSLContext] :ssl_context For client certificate auth
55
56
  # @option options [Boolean] :compatibility Compatibility mode, default false
56
57
  # @option options [String] :lang EPP Language code, default 'en'
57
58
  # @option options [String] :version EPP protocol version, default '1.0'
@@ -60,6 +61,7 @@ module EPP
60
61
  # @option options [String] :address_family 'AF_INET' or 'AF_INET6' or either of the
61
62
  # appropriate socket constants. Will cause connections to be
62
63
  # limited to this address family. Default try all addresses.
64
+
63
65
  def initialize(tag, passwd, host, options = {})
64
66
  @tag, @passwd, @host = tag, passwd, host
65
67
  @options = DEFAULTS.merge(options)
@@ -192,7 +194,9 @@ module EPP
192
194
  retry
193
195
  end
194
196
 
195
- @sock = OpenSSL::SSL::SSLSocket.new(@conn)
197
+ args = [@conn]
198
+ args << options[:ssl_context] if options[:ssl_context]
199
+ @sock = OpenSSL::SSL::SSLSocket.new(*args)
196
200
  @sock.sync_close = true
197
201
 
198
202
  begin
@@ -317,7 +321,7 @@ module EPP
317
321
  len = header.unpack('N')[0]
318
322
 
319
323
  raise ServerError, "Bad frame header from server, should be greater than #{HEADER_LEN}" unless len > HEADER_LEN
320
- response = @sock.read(len - HEADER_LEN)
324
+ @sock.read(len - HEADER_LEN)
321
325
  end
322
326
  end
323
327
  end
@@ -1,3 +1,3 @@
1
1
  module EPP
2
- VERSION = '1.0.0'
2
+ VERSION = '2.0.0'
3
3
  end
@@ -20,6 +20,15 @@ class TestEppContactCheckResponse < Test::Unit::TestCase
20
20
  assert_equal 'Command completed successfully', @check_response.message
21
21
  end
22
22
 
23
+ should 'have ids' do
24
+ expected = ['sh8013', 'sah8013', '8013sah'].sort
25
+ assert_equal expected, @check_response.ids.sort
26
+ end
27
+
28
+ should 'have count' do
29
+ assert_equal 3, @check_response.count
30
+ end
31
+
23
32
  should 'list sh8013 as available' do
24
33
  assert @check_response.available?('sh8013')
25
34
  assert !@check_response.unavailable?('sh8013')
@@ -34,5 +43,46 @@ class TestEppContactCheckResponse < Test::Unit::TestCase
34
43
  assert @check_response.available?('8013sah')
35
44
  assert !@check_response.unavailable?('8013sah')
36
45
  end
46
+
47
+ should 'raise ArgumentError if available with no argument for count > 1' do
48
+ assert_raise ArgumentError do
49
+ @check_response.available?
50
+ end
51
+ end
52
+
53
+ should 'raise RuntimeError if id called with count > 1' do
54
+ assert_raise RuntimeError do
55
+ @check_response.id
56
+ end
57
+ end
58
+ end
59
+
60
+ context 'EPP::Contact::CheckResponse Single Query' do
61
+ setup do
62
+ @response = EPP::Response.new(load_xml('contact/check-single'))
63
+ @check_response = EPP::Contact::CheckResponse.new(@response)
64
+ end
65
+
66
+ should 'have names' do
67
+ assert_equal ['sh8013'], @check_response.ids
68
+ end
69
+
70
+ should 'have name' do
71
+ assert_equal 'sh8013', @check_response.id
72
+ end
73
+
74
+ should 'have count' do
75
+ assert_equal 1, @check_response.count
76
+ end
77
+
78
+ should 'list sh8013 as available' do
79
+ assert @check_response.available?('sh8013')
80
+ assert !@check_response.unavailable?('sh8013')
81
+ end
82
+
83
+ should 'be available? with no argument' do
84
+ assert @check_response.available?
85
+ assert !@check_response.unavailable?
86
+ end
37
87
  end
38
88
  end
@@ -10,7 +10,7 @@ class TestEppContactCreateCommand < Test::Unit::TestCase
10
10
  :org => "Epiphyte",
11
11
  :name => "Enoch Root",
12
12
  :addr => {
13
- :street => "1 Test Avenue",
13
+ :street => "Test Suite\n1 Test Avenue",
14
14
  :city => "Testington",
15
15
  :sp => "Testshire",
16
16
  :pc => "TE57 1NG",
@@ -51,7 +51,8 @@ class TestEppContactCreateCommand < Test::Unit::TestCase
51
51
  assert_equal "Enoch Root", xpath_find('//contact:postalInfo[@type="loc"]/contact:name')
52
52
  end
53
53
  should 'set address' do
54
- assert_equal "1 Test Avenue", xpath_find('//contact:postalInfo[@type="loc"]/contact:addr/contact:street')
54
+ assert_equal "Test Suite", xpath_find('//contact:postalInfo[@type="loc"]/contact:addr/contact:street[1]')
55
+ assert_equal "1 Test Avenue", xpath_find('//contact:postalInfo[@type="loc"]/contact:addr/contact:street[2]')
55
56
  assert_equal "Testington", xpath_find('//contact:postalInfo[@type="loc"]/contact:addr/contact:city')
56
57
  assert_equal "Testshire", xpath_find('//contact:postalInfo[@type="loc"]/contact:addr/contact:sp')
57
58
  assert_equal "TE57 1NG", xpath_find('//contact:postalInfo[@type="loc"]/contact:addr/contact:pc')
@@ -13,7 +13,7 @@ class TestEppContactUpdateCommand < Test::Unit::TestCase
13
13
  :org => "Epiphyte",
14
14
  :name => "Enoch Root",
15
15
  :addr => {
16
- :street => "1 Test Avenue",
16
+ :street => "Test Suite\n1 Test Avenue",
17
17
  :city => "Testington",
18
18
  :sp => "Testshire",
19
19
  :pc => "TE57 1NG",
@@ -65,7 +65,8 @@ class TestEppContactUpdateCommand < Test::Unit::TestCase
65
65
  assert_equal "Enoch Root", xpath_find('//contact:chg/contact:postalInfo[@type="loc"]/contact:name')
66
66
  end
67
67
  should 'set address for change' do
68
- assert_equal "1 Test Avenue", xpath_find('//contact:chg/contact:postalInfo[@type="loc"]/contact:addr/contact:street')
68
+ assert_equal "Test Suite", xpath_find('//contact:chg/contact:postalInfo[@type="loc"]/contact:addr/contact:street[1]')
69
+ assert_equal "1 Test Avenue", xpath_find('//contact:chg/contact:postalInfo[@type="loc"]/contact:addr/contact:street[2]')
69
70
  assert_equal "Testington", xpath_find('//contact:chg/contact:postalInfo[@type="loc"]/contact:addr/contact:city')
70
71
  assert_equal "Testshire", xpath_find('//contact:chg/contact:postalInfo[@type="loc"]/contact:addr/contact:sp')
71
72
  assert_equal "TE57 1NG", xpath_find('//contact:chg/contact:postalInfo[@type="loc"]/contact:addr/contact:pc')
@@ -20,6 +20,15 @@ class TestEppDomainCheckResponse < Test::Unit::TestCase
20
20
  assert_equal 'Command completed successfully', @check_response.message
21
21
  end
22
22
 
23
+ should 'have names' do
24
+ expected = ['example.com', 'example.net', 'example.org'].sort
25
+ assert_equal expected, @check_response.names.sort
26
+ end
27
+
28
+ should 'have count' do
29
+ assert_equal 3, @check_response.count
30
+ end
31
+
23
32
  should 'list example.com as available' do
24
33
  assert @check_response.available?('example.com')
25
34
  assert !@check_response.unavailable?('example.com')
@@ -34,5 +43,46 @@ class TestEppDomainCheckResponse < Test::Unit::TestCase
34
43
  assert @check_response.available?('example.org')
35
44
  assert !@check_response.unavailable?('example.org')
36
45
  end
46
+
47
+ should 'raise ArgumentError if available with no argument for count > 1' do
48
+ assert_raise ArgumentError do
49
+ @check_response.available?
50
+ end
51
+ end
52
+
53
+ should 'raise RuntimeError if name called with count > 1' do
54
+ assert_raise RuntimeError do
55
+ @check_response.name
56
+ end
57
+ end
58
+ end
59
+
60
+ context 'EPP::Domain::CheckResponse Single Query' do
61
+ setup do
62
+ @response = EPP::Response.new(load_xml('domain/check-single'))
63
+ @check_response = EPP::Domain::CheckResponse.new(@response)
64
+ end
65
+
66
+ should 'have names' do
67
+ assert_equal ['example.com'], @check_response.names
68
+ end
69
+
70
+ should 'have name' do
71
+ assert_equal 'example.com', @check_response.name
72
+ end
73
+
74
+ should 'have count' do
75
+ assert_equal 1, @check_response.count
76
+ end
77
+
78
+ should 'list example.com as available' do
79
+ assert @check_response.available?('example.com')
80
+ assert !@check_response.unavailable?('example.com')
81
+ end
82
+
83
+ should 'be available? with no argument' do
84
+ assert @check_response.available?
85
+ assert !@check_response.unavailable?
86
+ end
37
87
  end
38
88
  end
@@ -23,71 +23,71 @@ class TestEppDomainInfoResponse < Test::Unit::TestCase
23
23
  should 'have name' do
24
24
  assert_equal 'example.com', @info_response.name
25
25
  end
26
-
26
+
27
27
  should 'have roid' do
28
28
  assert_equal 'EXAMPLE1-REP', @info_response.roid
29
29
  end
30
30
 
31
31
  should 'have status' do
32
- assert_equal 'ok', @info_response.status
32
+ assert_equal ['ok', 'clientTransferProhibited'], @info_response.status
33
33
  end
34
-
34
+
35
35
  should 'have registrant' do
36
36
  assert_equal 'jd1234', @info_response.registrant
37
37
  end
38
-
38
+
39
39
  should 'have contacts' do
40
40
  expected = { 'admin' => 'sh8013', 'tech' => 'sh8013' }
41
41
  assert_equal expected, @info_response.contacts
42
42
  end
43
-
43
+
44
44
  should 'have nameservers' do
45
45
  expected = [ {'name' => 'ns1.example.com'},
46
46
  {'name' => 'ns1.example.net'} ]
47
47
  assert_equal expected, @info_response.nameservers
48
48
  end
49
-
49
+
50
50
  should 'have hosts' do
51
51
  expected = %w(ns1.example.com ns2.example.com)
52
52
  assert_equal expected, @info_response.hosts
53
53
  end
54
-
54
+
55
55
  should 'have client_id' do
56
56
  assert_equal 'ClientX', @info_response.client_id
57
57
  end
58
-
58
+
59
59
  should 'have creator_id' do
60
60
  assert_equal 'ClientY', @info_response.creator_id
61
61
  end
62
-
62
+
63
63
  should 'have created_date' do
64
64
  # 1999-04-03T22:00:00.0Z
65
65
  expected = Time.gm(1999,4,3,22,00,00)
66
66
  assert_equal expected, @info_response.created_date
67
67
  end
68
-
68
+
69
69
  should 'have updator_id' do
70
70
  assert_equal 'ClientX', @info_response.updator_id
71
71
  end
72
-
72
+
73
73
  should 'have updated_date' do
74
74
  # 1999-12-03T09:00:00.0Z
75
75
  expected = Time.gm(1999,12,3,9,00,00)
76
76
  assert_equal expected, @info_response.updated_date
77
77
  end
78
-
78
+
79
79
  should 'have expiration_date' do
80
80
  # 2005-04-03T22:00:00.0Z
81
81
  expected = Time.gm(2005,4,3,22,00,00)
82
82
  assert_equal expected, @info_response.expiration_date
83
83
  end
84
-
84
+
85
85
  should 'have transfer_date' do
86
86
  # 2000-04-08T09:00:00.0Z
87
87
  expected = Time.gm(2000,4,8,9,00,00)
88
88
  assert_equal expected, @info_response.transfer_date
89
89
  end
90
-
90
+
91
91
  should 'have authInfo' do
92
92
  expected = { 'pw' => '2fooBAR' }
93
93
  assert_equal expected, @info_response.auth_info
@@ -103,5 +103,44 @@ class TestEppDomainInfoResponse < Test::Unit::TestCase
103
103
  assert_nil @info_response.expiration_date
104
104
  end
105
105
  end
106
+
107
+ context 'nameserver data specified inside <hostAttr>' do
108
+ context 'with name, ipv4 and ipv6' do
109
+ setup do
110
+ @response = EPP::Response.new(load_xml('domain/info-ns-hostAttr'))
111
+ @info_response = EPP::Domain::InfoResponse.new(@response)
112
+ end
113
+
114
+ should 'have nameservers' do
115
+ expected = [
116
+ {
117
+ 'name' => 'ns1.example.com',
118
+ 'ipv4' => '192.0.2.1',
119
+ 'ipv6' => '2002:0:0:0:0:0:C000:201'
120
+ },
121
+ {
122
+ 'name' => 'ns2.example.com',
123
+ 'ipv4' => '192.0.2.2',
124
+ 'ipv6' => '1080:0:0:0:8:800:200C:417A'
125
+ }
126
+ ]
127
+ assert_equal expected, @info_response.nameservers
128
+ end
129
+ end
130
+
131
+ context 'with name only' do
132
+ setup do
133
+ @response = EPP::Response.new(load_xml('domain/info-ns-hostAttr-name-only'))
134
+ @info_response = EPP::Domain::InfoResponse.new(@response)
135
+ end
136
+
137
+ should 'have nameservers' do
138
+ expected = [ { 'name' => 'ns1.example.com' },
139
+ { 'name' => 'ns2.example.com' }
140
+ ]
141
+ assert_equal expected, @info_response.nameservers
142
+ end
143
+ end
144
+ end
106
145
  end
107
146
  end
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
3
+ <response>
4
+ <result code="1000">
5
+ <msg>Command completed successfully</msg>
6
+ </result>
7
+ <resData>
8
+ <contact:chkData
9
+ xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
10
+ <contact:cd>
11
+ <contact:id avail="1">sh8013</contact:id>
12
+ </contact:cd>
13
+ </contact:chkData>
14
+ </resData>
15
+ <trID>
16
+ <clTRID>ABC-12345</clTRID>
17
+ <svTRID>54322-XYZ</svTRID>
18
+ </trID>
19
+ </response>
20
+ </epp>
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
3
+ <response>
4
+ <result code="1000">
5
+ <msg>Command completed successfully</msg>
6
+ </result>
7
+ <resData>
8
+ <domain:chkData
9
+ xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
10
+ <domain:cd>
11
+ <domain:name avail="1">example.com</domain:name>
12
+ </domain:cd>
13
+ </domain:chkData>
14
+ </resData>
15
+ <trID>
16
+ <clTRID>ABC-12345</clTRID>
17
+ <svTRID>54322-XYZ</svTRID>
18
+ </trID>
19
+ </response>
20
+ </epp>
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
3
+ <response>
4
+ <result code="1000">
5
+ <msg>Command completed successfully</msg>
6
+ </result>
7
+ <resData>
8
+ <domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
9
+ <domain:name>example-1409820378.io</domain:name>
10
+ <domain:roid>DOM-123456</domain:roid>
11
+ <domain:status s="ok"/>
12
+ <domain:registrant>T-qZtDtfraZ0Z</domain:registrant>
13
+ <domain:contact type="admin">T-qZtDtfraZ0Z</domain:contact>
14
+ <domain:contact type="tech">T-qZtDtfraZ0Z</domain:contact>
15
+ <domain:contact type="billing">T-qZtDtfraZ0Z</domain:contact>
16
+ <domain:ns>
17
+ <domain:hostAttr>
18
+ <domain:hostName>ns1.example.com</domain:hostName>
19
+ </domain:hostAttr>
20
+ <domain:hostAttr>
21
+ <domain:hostName>ns2.example.com</domain:hostName>
22
+ </domain:hostAttr>
23
+ </domain:ns>
24
+ <domain:clID>NIC-1234</domain:clID>
25
+ <domain:crDate>2014-09-04T08:46:22.0Z</domain:crDate>
26
+ <domain:exDate>2015-09-04T08:46:22.0Z</domain:exDate>
27
+ </domain:infData>
28
+ </resData>
29
+ <trID>
30
+ <clTRID>NIC-1234-20140904000001</clTRID>
31
+ <svTRID>EPP-00A1.000000E1.2</svTRID>
32
+ </trID>
33
+ </response>
34
+ </epp>
@@ -0,0 +1,38 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
3
+ <response>
4
+ <result code="1000">
5
+ <msg>Command completed successfully</msg>
6
+ </result>
7
+ <resData>
8
+ <domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
9
+ <domain:name>example-1409820378.io</domain:name>
10
+ <domain:roid>DOM-123456</domain:roid>
11
+ <domain:status s="ok"/>
12
+ <domain:registrant>T-qZtDtfraZ0Z</domain:registrant>
13
+ <domain:contact type="admin">T-qZtDtfraZ0Z</domain:contact>
14
+ <domain:contact type="tech">T-qZtDtfraZ0Z</domain:contact>
15
+ <domain:contact type="billing">T-qZtDtfraZ0Z</domain:contact>
16
+ <domain:ns>
17
+ <domain:hostAttr>
18
+ <domain:hostName>ns1.example.com</domain:hostName>
19
+ <domain:hostAddr ip="v4">192.0.2.1</domain:hostAddr>
20
+ <domain:hostAddr ip="v6">2002:0:0:0:0:0:C000:201</domain:hostAddr>
21
+ </domain:hostAttr>
22
+ <domain:hostAttr>
23
+ <domain:hostName>ns2.example.com</domain:hostName>
24
+ <domain:hostAddr ip="v4">192.0.2.2</domain:hostAddr>
25
+ <domain:hostAddr ip="v6">1080:0:0:0:8:800:200C:417A</domain:hostAddr>
26
+ </domain:hostAttr>
27
+ </domain:ns>
28
+ <domain:clID>NIC-1234</domain:clID>
29
+ <domain:crDate>2014-09-04T08:46:22.0Z</domain:crDate>
30
+ <domain:exDate>2015-09-04T08:46:22.0Z</domain:exDate>
31
+ </domain:infData>
32
+ </resData>
33
+ <trID>
34
+ <clTRID>NIC-1234-20140904000001</clTRID>
35
+ <svTRID>EPP-00A1.000000E1.2</svTRID>
36
+ </trID>
37
+ </response>
38
+ </epp>
@@ -10,6 +10,7 @@
10
10
  <domain:name>example.com</domain:name>
11
11
  <domain:roid>EXAMPLE1-REP</domain:roid>
12
12
  <domain:status s="ok"/>
13
+ <domain:status s="clientTransferProhibited"/>
13
14
  <domain:registrant>jd1234</domain:registrant>
14
15
  <domain:contact type="admin">sh8013</domain:contact>
15
16
  <domain:contact type="tech">sh8013</domain:contact>
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
3
+ <response>
4
+ <result code="1000">
5
+ <msg>Command completed successfully</msg>
6
+ </result>
7
+ <resData>
8
+ <host:chkData
9
+ xmlns:host="urn:ietf:params:xml:ns:host-1.0">
10
+ <host:cd>
11
+ <host:name avail="1">ns1.example.com</host:name>
12
+ </host:cd>
13
+ </host:chkData>
14
+ </resData>
15
+ <trID>
16
+ <clTRID>ABC-12345</clTRID>
17
+ <svTRID>54322-XYZ</svTRID>
18
+ </trID>
19
+ </response>
20
+ </epp>
@@ -1,7 +1,4 @@
1
1
  require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
4
- require 'mocha/setup'
5
2
 
6
3
  if RUBY_VERSION >= '1.9'
7
4
  begin
@@ -11,6 +8,10 @@ if RUBY_VERSION >= '1.9'
11
8
  end
12
9
  end
13
10
 
11
+ require 'test/unit'
12
+ require 'shoulda'
13
+ require 'mocha/setup'
14
+
14
15
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
15
16
  $LOAD_PATH.unshift(File.dirname(__FILE__))
16
17
  require 'epp-client'
@@ -66,7 +67,7 @@ class Test::Unit::TestCase
66
67
  def namespaces_from_request(request = @request)
67
68
  @namespaces = Hash[*request.namespaces.map { |k,ns| [k, ns.href] }.flatten]
68
69
  end
69
-
70
+
70
71
  unless RUBY_VERSION >= "1.9"
71
72
  def assert_output stdout = nil, stderr = nil
72
73
  out, err = capture_io do
@@ -20,6 +20,15 @@ class TestEppHostCheckResponse < Test::Unit::TestCase
20
20
  assert_equal 'Command completed successfully', @check_response.message
21
21
  end
22
22
 
23
+ should 'have names' do
24
+ expected = ['ns1.example.com', 'ns2.example2.com', 'ns3.example3.com'].sort
25
+ assert_equal expected, @check_response.names.sort
26
+ end
27
+
28
+ should 'have count' do
29
+ assert_equal 3, @check_response.count
30
+ end
31
+
23
32
  should 'list ns1.example.com as available' do
24
33
  assert @check_response.available?('ns1.example.com')
25
34
  assert !@check_response.unavailable?('ns1.example.com')
@@ -34,5 +43,46 @@ class TestEppHostCheckResponse < Test::Unit::TestCase
34
43
  assert @check_response.available?('ns3.example3.com')
35
44
  assert !@check_response.unavailable?('ns3.example3.com')
36
45
  end
46
+
47
+ should 'raise ArgumentError if available with no argument for count > 1' do
48
+ assert_raise ArgumentError do
49
+ @check_response.available?
50
+ end
51
+ end
52
+
53
+ should 'raise RuntimeError if name called with count > 1' do
54
+ assert_raise RuntimeError do
55
+ @check_response.name
56
+ end
57
+ end
58
+ end
59
+
60
+ context 'EPP::Host::CheckResponse Single Query' do
61
+ setup do
62
+ @response = EPP::Response.new(load_xml('host/check-single'))
63
+ @check_response = EPP::Host::CheckResponse.new(@response)
64
+ end
65
+
66
+ should 'have names' do
67
+ assert_equal ['ns1.example.com'], @check_response.names
68
+ end
69
+
70
+ should 'have name' do
71
+ assert_equal 'ns1.example.com', @check_response.name
72
+ end
73
+
74
+ should 'have count' do
75
+ assert_equal 1, @check_response.count
76
+ end
77
+
78
+ should 'list ns1.example.com as available' do
79
+ assert @check_response.available?('ns1.example.com')
80
+ assert !@check_response.unavailable?('ns1.example.com')
81
+ end
82
+
83
+ should 'be available? with no argument' do
84
+ assert @check_response.available?
85
+ assert !@check_response.unavailable?
86
+ end
37
87
  end
38
88
  end
@@ -18,6 +18,16 @@ class TestEppClient < Test::Unit::TestCase
18
18
 
19
19
  assert_equal 7001, client.options[:port]
20
20
  end
21
+
22
+ should 'allow configuration of SSL context' do
23
+ client = nil
24
+ ctx = OpenSSL::SSL::SSLContext.new
25
+ assert_nothing_raised do
26
+ client = EPP::Client.new('TEST', 'test', 'epp.test.host', :ssl_context => ctx)
27
+ end
28
+
29
+ assert_equal ctx, client.options[:ssl_context]
30
+ end
21
31
 
22
32
  should 'allow configuration of language' do
23
33
  client = EPP::Client.new('TEST', 'test', 'epp.test.host', :lang => 'no')
@@ -26,6 +26,16 @@ class TestEppServer < Test::Unit::TestCase
26
26
 
27
27
  assert_equal 7001, server.options[:port]
28
28
  end
29
+
30
+ should 'allow configuration of SSL context' do
31
+ server = nil
32
+ ctx = OpenSSL::SSL::SSLContext.new
33
+ assert_nothing_raised do
34
+ server = EPP::Server.new('TEST', 'test', 'epp.test.host', :ssl_context => ctx)
35
+ end
36
+
37
+ assert_equal ctx, server.options[:ssl_context]
38
+ end
29
39
 
30
40
  should 'allow configuration of language' do
31
41
  server = EPP::Server.new('TEST', 'test', 'epp.test.host', :lang => 'no')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epp-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoff Garside
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-02 00:00:00.000000000 Z
11
+ date: 2014-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: libxml-ruby
@@ -149,6 +149,7 @@ files:
149
149
  - test/domain/test_domain_transfer_response.rb
150
150
  - test/domain/test_domain_update.rb
151
151
  - test/domain/test_domain_update_response.rb
152
+ - test/fixtures/responses/contact/check-single.xml
152
153
  - test/fixtures/responses/contact/check.xml
153
154
  - test/fixtures/responses/contact/create.xml
154
155
  - test/fixtures/responses/contact/delete.xml
@@ -156,16 +157,20 @@ files:
156
157
  - test/fixtures/responses/contact/transfer-query.xml
157
158
  - test/fixtures/responses/contact/transfer-request.xml
158
159
  - test/fixtures/responses/contact/update.xml
160
+ - test/fixtures/responses/domain/check-single.xml
159
161
  - test/fixtures/responses/domain/check.xml
160
162
  - test/fixtures/responses/domain/create.xml
161
163
  - test/fixtures/responses/domain/delete.xml
162
164
  - test/fixtures/responses/domain/info-no-exDate.xml
165
+ - test/fixtures/responses/domain/info-ns-hostAttr-name-only.xml
166
+ - test/fixtures/responses/domain/info-ns-hostAttr.xml
163
167
  - test/fixtures/responses/domain/info.xml
164
168
  - test/fixtures/responses/domain/renew.xml
165
169
  - test/fixtures/responses/domain/transfer-query.xml
166
170
  - test/fixtures/responses/domain/transfer-request.xml
167
171
  - test/fixtures/responses/domain/update.xml
168
172
  - test/fixtures/responses/greeting.xml
173
+ - test/fixtures/responses/host/check-single.xml
169
174
  - test/fixtures/responses/host/check.xml
170
175
  - test/fixtures/responses/host/create.xml
171
176
  - test/fixtures/responses/host/delete.xml
@@ -254,6 +259,7 @@ test_files:
254
259
  - test/domain/test_domain_transfer_response.rb
255
260
  - test/domain/test_domain_update.rb
256
261
  - test/domain/test_domain_update_response.rb
262
+ - test/fixtures/responses/contact/check-single.xml
257
263
  - test/fixtures/responses/contact/check.xml
258
264
  - test/fixtures/responses/contact/create.xml
259
265
  - test/fixtures/responses/contact/delete.xml
@@ -261,16 +267,20 @@ test_files:
261
267
  - test/fixtures/responses/contact/transfer-query.xml
262
268
  - test/fixtures/responses/contact/transfer-request.xml
263
269
  - test/fixtures/responses/contact/update.xml
270
+ - test/fixtures/responses/domain/check-single.xml
264
271
  - test/fixtures/responses/domain/check.xml
265
272
  - test/fixtures/responses/domain/create.xml
266
273
  - test/fixtures/responses/domain/delete.xml
267
274
  - test/fixtures/responses/domain/info-no-exDate.xml
275
+ - test/fixtures/responses/domain/info-ns-hostAttr-name-only.xml
276
+ - test/fixtures/responses/domain/info-ns-hostAttr.xml
268
277
  - test/fixtures/responses/domain/info.xml
269
278
  - test/fixtures/responses/domain/renew.xml
270
279
  - test/fixtures/responses/domain/transfer-query.xml
271
280
  - test/fixtures/responses/domain/transfer-request.xml
272
281
  - test/fixtures/responses/domain/update.xml
273
282
  - test/fixtures/responses/greeting.xml
283
+ - test/fixtures/responses/host/check-single.xml
274
284
  - test/fixtures/responses/host/check.xml
275
285
  - test/fixtures/responses/host/create.xml
276
286
  - test/fixtures/responses/host/delete.xml