epp-client 1.0.0 → 2.0.0

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