synergy_wholesale 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +19 -0
  5. data/CHANGELOG.md +2 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +20 -0
  8. data/README.md +59 -0
  9. data/Rakefile +19 -0
  10. data/lib/synergy_wholesale.rb +17 -0
  11. data/lib/synergy_wholesale/adapter.rb +41 -0
  12. data/lib/synergy_wholesale/api.rb +29 -0
  13. data/lib/synergy_wholesale/base_response.rb +55 -0
  14. data/lib/synergy_wholesale/configuration.rb +22 -0
  15. data/lib/synergy_wholesale/errors.rb +3 -0
  16. data/lib/synergy_wholesale/errors/bad_data_error.rb +6 -0
  17. data/lib/synergy_wholesale/errors/error.rb +15 -0
  18. data/lib/synergy_wholesale/errors/response_error.rb +16 -0
  19. data/lib/synergy_wholesale/inflector.rb +67 -0
  20. data/lib/synergy_wholesale/operation.rb +21 -0
  21. data/lib/synergy_wholesale/operations/check_domain.rb +34 -0
  22. data/lib/synergy_wholesale/operations/disable_auto_renewal.rb +27 -0
  23. data/lib/synergy_wholesale/operations/domain_register.rb +51 -0
  24. data/lib/synergy_wholesale/operations/domain_register_au.rb +46 -0
  25. data/lib/synergy_wholesale/operations/enable_auto_renewal.rb +27 -0
  26. data/lib/synergy_wholesale/response_generator.rb +18 -0
  27. data/lib/synergy_wholesale/types.rb +22 -0
  28. data/lib/synergy_wholesale/types/au_contact.rb +61 -0
  29. data/lib/synergy_wholesale/types/au_domain.rb +17 -0
  30. data/lib/synergy_wholesale/types/au_id_type.rb +28 -0
  31. data/lib/synergy_wholesale/types/au_organisation_type.rb +33 -0
  32. data/lib/synergy_wholesale/types/au_postcode.rb +13 -0
  33. data/lib/synergy_wholesale/types/au_registrant.rb +41 -0
  34. data/lib/synergy_wholesale/types/au_state.rb +15 -0
  35. data/lib/synergy_wholesale/types/contact.rb +61 -0
  36. data/lib/synergy_wholesale/types/country.rb +263 -0
  37. data/lib/synergy_wholesale/types/domain.rb +17 -0
  38. data/lib/synergy_wholesale/types/domain_list.rb +21 -0
  39. data/lib/synergy_wholesale/types/email.rb +31 -0
  40. data/lib/synergy_wholesale/types/phone.rb +13 -0
  41. data/lib/synergy_wholesale/types/registration_years.rb +12 -0
  42. data/lib/synergy_wholesale/version.rb +3 -0
  43. data/spec/fixtures/synergy/domain/autorenew/disable/failure.xml +14 -0
  44. data/spec/fixtures/synergy/domain/autorenew/disable/success.xml +14 -0
  45. data/spec/fixtures/synergy/domain/autorenew/enable/failure.xml +14 -0
  46. data/spec/fixtures/synergy/domain/autorenew/enable/success.xml +14 -0
  47. data/spec/fixtures/synergy/domain/available/example.com.xml +14 -0
  48. data/spec/fixtures/synergy/domain/available/ljsdlksdlfkmsldlskmlskmdlfkjlskjdlmlknlks.com.xml +1 -0
  49. data/spec/fixtures/synergy/domain/register/au/failure.xml +14 -0
  50. data/spec/fixtures/synergy/domain/register/au/success.xml +15 -0
  51. data/spec/fixtures/synergy/domain/register/failure.xml +14 -0
  52. data/spec/fixtures/synergy/domain/register/success.xml +15 -0
  53. data/spec/integration/check_domain_spec.rb +50 -0
  54. data/spec/integration/disable_auto_renewal_spec.rb +52 -0
  55. data/spec/integration/domain_register_au_spec.rb +225 -0
  56. data/spec/integration/domain_register_spec.rb +215 -0
  57. data/spec/integration/enable_auto_renewal_spec.rb +52 -0
  58. data/spec/spec_helper.rb +37 -0
  59. data/spec/unit/adapter_spec.rb +97 -0
  60. data/spec/unit/api_spec.rb +42 -0
  61. data/spec/unit/configuration_spec.rb +44 -0
  62. data/spec/unit/response_generator_spec.rb +35 -0
  63. data/synergy_wholesale.gemspec +26 -0
  64. metadata +210 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 16546c116e3f5953fc7907e148e50dffd9acd0b0
4
+ data.tar.gz: a39e4a136c65fbb1ffc23378d781e6c99b1c830e
5
+ SHA512:
6
+ metadata.gz: db2a1a5fde0f1c9be6b397808990517df772c69b05933bc7455947f072ccf661027af1d2436ba3904da45172ad9fe7ac176ec93225fa3d2dcfec9d9c80de0eff
7
+ data.tar.gz: 35490a221d48958a47dc98b61d9d75d7e49fd0c07f938a1258b4b120b9dfba818312a7bf391c3f4695af887fd5610f17d9c9a19b659aaa22a7ca0b3b581b317c
@@ -0,0 +1,11 @@
1
+ .DS_Store
2
+ coverage
3
+ /.bundle
4
+ vendor/bundle
5
+ bin/
6
+ !bin/console
7
+ tmp/
8
+ .idea/
9
+ Gemfile.lock
10
+ .ruby-version
11
+ .ruby-gemset
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --order random
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ dist: trusty
3
+ sudo: required
4
+ cache: bundler
5
+ script:
6
+ - bundle exec rake
7
+ rvm:
8
+ - 2.2
9
+ - 2.3
10
+ - 2.4.0
11
+ - jruby-9.1.5.0
12
+ - rbx-3
13
+ env:
14
+ global:
15
+ - COVERAGE=true
16
+ - JRUBY_OPTS='--dev -J-Xmx1024M'
17
+ matrix:
18
+ allow_failures:
19
+ - rvm: rbx-3
@@ -0,0 +1,2 @@
1
+ # 0.0.0
2
+ * Initialize gem
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Rob Jacoby
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,59 @@
1
+ # synergy_wholesale
2
+
3
+ ## Installation
4
+
5
+ Synergy Wholesale is available through [Rubygems](http://rubygems.org/gems/synergy_wholesale) and can be installed via:
6
+
7
+ ```
8
+ $ gem install synergy_wholesale
9
+ ```
10
+
11
+ or add it to your Gemfile like this:
12
+
13
+ ```
14
+ gem 'synergy_wholesale'
15
+ ```
16
+
17
+ ## Usage example
18
+
19
+ ``` ruby
20
+ require 'synergy_wholesale'
21
+
22
+ # configure Synergy Wholesale
23
+ SynergyWholesale.setup do |config|
24
+ config.reseller_id = '12345'
25
+ config.api_key = 'abc123'
26
+ end
27
+
28
+ # call an operation
29
+ response = SynergyWholesale::CheckDomain.call(domain: { name: 'example.com'})
30
+
31
+ response.body
32
+ # => { status: 'UNAVAILABLE', available: '0' }
33
+
34
+ response.is_available?
35
+ # => false
36
+
37
+ # Or do things manually
38
+ # create an instance of the api adapter
39
+ api = SynergyWholesale::API.new
40
+
41
+ # create a command
42
+ command = SynergyWholesale::CheckDomain::Command.new(SynergyWholesale::Types::Domain.new(name: 'example.com'))
43
+
44
+ command.to_param
45
+ # => { domain_name: 'example.com' }
46
+
47
+ # call the 'checkDomain' command
48
+ response = api.call(command)
49
+
50
+ response.body
51
+ # => { status: 'UNAVAILABLE', available: '0' }
52
+
53
+ response.is_available?
54
+ # => false
55
+ ```
56
+
57
+ ## License
58
+
59
+ See `LICENSE` file.
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
5
+
6
+ require 'rspec/core'
7
+ require 'rspec/core/rake_task'
8
+
9
+ desc 'Run all specs in spec directory'
10
+ task :run_specs do
11
+
12
+ RSpec::Core::Runner.run(['spec/integration', 'spec/unit'])
13
+ RSpec.clear_examples
14
+ Dir[SPEC_ROOT.join('shared/**/*.rb')].each(&method(:load))
15
+
16
+ RSpec::Core::Runner.run(['spec'])
17
+ end
18
+
19
+ task default: :run_specs
@@ -0,0 +1,17 @@
1
+ require 'synergy_wholesale/configuration'
2
+
3
+ module SynergyWholesale
4
+ extend Configuration
5
+
6
+ def self.configure
7
+ yield self if block_given?
8
+ end
9
+ end
10
+
11
+ require 'dry-validation'
12
+ require 'dry-struct'
13
+ require 'synergy_wholesale/api'
14
+ require 'synergy_wholesale/errors'
15
+ require 'synergy_wholesale/types'
16
+ require 'synergy_wholesale/base_response'
17
+ require 'synergy_wholesale/operation'
@@ -0,0 +1,41 @@
1
+ require 'savon'
2
+
3
+ module SynergyWholesale
4
+ class Adapter
5
+
6
+ attr_reader :client
7
+
8
+ def initialize
9
+ @client = Savon.client(
10
+ wsdl: SynergyWholesale.wsdl_path,
11
+ namespaces: { 'xmlns:enc' => 'http://schemas.xmlsoap.org/soap/encoding/' }
12
+ )
13
+ end
14
+
15
+ def add_param(key, value)
16
+ params[key] = value
17
+ end
18
+
19
+ def add_params(*params)
20
+ return if params.blank?
21
+
22
+ if params.size == 1 && params.first.is_a?(Hash)
23
+ params.first.each { |key, value| add_param key, value }
24
+ else
25
+ raise 'params are required to be key/value combinations'
26
+ end
27
+ end
28
+
29
+ def params
30
+ @params ||= {
31
+ 'resellerID' => SynergyWholesale.reseller_id,
32
+ 'apiKey' => SynergyWholesale.api_key
33
+ }
34
+ end
35
+
36
+ def call(action)
37
+ client.call(action, message: { request: params })
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'adapter'
2
+ require_relative 'response_generator'
3
+ require_relative 'inflector'
4
+
5
+ module SynergyWholesale
6
+ class API
7
+
8
+ attr_writer :adapter, :response_generator
9
+
10
+ def adapter
11
+ @adapter ||= Adapter.new
12
+ end
13
+
14
+ def response_generator
15
+ @response_generator ||= ResponseGenerator.new
16
+ end
17
+
18
+ def call(command)
19
+ adapter.add_params(command.to_param)
20
+ command_name = command.class.name
21
+ soap_command = command.operation
22
+
23
+ savon_response = adapter.call(soap_command)
24
+ response = savon_response.body["#{soap_command}_response".to_sym][:return]
25
+ response_generator.build_response(command_name, response, soap_command)
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,55 @@
1
+ module SynergyWholesale
2
+ class BaseResponse
3
+
4
+ attr_reader :response, :command
5
+
6
+ def initialize(response, command)
7
+ @response = response
8
+ @command = command
9
+
10
+ validate_status
11
+ validate_expected_fields
12
+ validate_data
13
+ end
14
+
15
+ def successful?
16
+ [*success_statuses].include?(response[:status])
17
+ end
18
+
19
+ def message
20
+ response[:error_message]
21
+ end
22
+
23
+ def body
24
+ response
25
+ end
26
+
27
+ protected
28
+
29
+ def validate_status
30
+ raise Errors::BadDataError.new("No status found in response to Soap command [#{command}]", command, response) unless response[:status]
31
+ raise Errors::ResponseError.new(command, response) unless successful?
32
+ end
33
+
34
+ def validate_expected_fields
35
+ return if expected_fields.empty?
36
+ [*expected_fields].each do |expected|
37
+ message = "Expected property [#{expected}] missing from response data"
38
+ raise Errors::BadDataError.new(message, command, response) unless response.has_key?(expected.to_sym)
39
+ end
40
+ end
41
+
42
+ def validate_data
43
+ # NO-OP - let subclasses provide their own implementation if they choose
44
+ end
45
+
46
+ def success_statuses
47
+ %w(OK ok)
48
+ end
49
+
50
+ def expected_fields
51
+ []
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,22 @@
1
+ module SynergyWholesale
2
+ module Configuration
3
+
4
+ attr_writer :reseller_id,
5
+ :api_key
6
+
7
+ def wsdl_path
8
+ 'https://api.synergywholesale.com/server.php?wsdl'
9
+ end
10
+
11
+ def reseller_id
12
+ raise 'You need to provide a reseller ID to use the Synergy Wholesale API' unless @reseller_id
13
+ @reseller_id
14
+ end
15
+
16
+ def api_key
17
+ raise 'You need to provide an API Key to use the Synergy Wholesale API' unless @api_key
18
+ @api_key
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ require_relative 'errors/error'
2
+ require_relative 'errors/bad_data_error'
3
+ require_relative 'errors/response_error'
@@ -0,0 +1,6 @@
1
+ module SynergyWholesale
2
+ module Errors
3
+ class BadDataError < Error
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,15 @@
1
+ module SynergyWholesale
2
+ module Errors
3
+ class Error < StandardError
4
+
5
+ attr_reader :command, :response
6
+
7
+ def self.new(message, command, response)
8
+ @command = command
9
+ @response = response
10
+ super(message)
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module SynergyWholesale
2
+ module Errors
3
+ class ResponseError < Error
4
+
5
+ attr_reader :status
6
+
7
+ def self.new(command, response)
8
+ @status = response[:status]
9
+ message = response[:error_message] || @status
10
+
11
+ super(message, command, response)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,67 @@
1
+ module SynergyWholesale
2
+ class Inflector
3
+
4
+ class << self
5
+
6
+ # File activesupport/lib/active_support/inflector/methods.rb, line 89
7
+ def underscore(camel_cased_word)
8
+ return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
9
+ word = camel_cased_word.to_s.gsub('::'.freeze, '/'.freeze)
10
+ word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{/(?=a)b/})(?=\b|[^a-z])/) { "#{$1 && '_'.freeze }#{$2.downcase}" }
11
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
12
+ word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
13
+ word.tr!('-'.freeze, '_'.freeze)
14
+ word.downcase!
15
+ word
16
+ end
17
+
18
+ # File activesupport/lib/active_support/inflector/methods.rb, line 206
19
+ def demodulize(path)
20
+ path = path.to_s
21
+ if i = path.rindex('::')
22
+ path[(i+2)..-1]
23
+ else
24
+ path
25
+ end
26
+ end
27
+
28
+ # File activesupport/lib/active_support/inflector/methods.rb, line 257
29
+ def constantize(camel_cased_word)
30
+ names = camel_cased_word.split('::'.freeze)
31
+
32
+ # Trigger a built-in NameError exception including the ill-formed constant in the message.
33
+ Object.const_get(camel_cased_word) if names.empty?
34
+
35
+ # Remove the first blank element in case of '::ClassName' notation.
36
+ names.shift if names.size > 1 && names.first.empty?
37
+
38
+ names.inject(Object) do |constant, name|
39
+ if constant == Object
40
+ constant.const_get(name)
41
+ else
42
+ candidate = constant.const_get(name)
43
+ next candidate if constant.const_defined?(name, false)
44
+ next candidate unless Object.const_defined?(name)
45
+
46
+ # Go down the ancestors to check if it is owned directly. The check
47
+ # stops when we reach Object or the end of ancestors tree.
48
+ constant = constant.ancestors.inject do |const, ancestor|
49
+ break const if ancestor == Object
50
+ break ancestor if ancestor.const_defined?(name, false)
51
+ const
52
+ end
53
+
54
+ # owner is in Object, so raise
55
+ constant.const_get(name, false)
56
+ end
57
+ end
58
+ end
59
+
60
+ def is_numeric?(string)
61
+ !!Float(string.to_s) rescue false
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,21 @@
1
+ module SynergyWholesale
2
+ class Operation
3
+
4
+ def self.call(attrs)
5
+ new.call(attrs)
6
+ end
7
+
8
+ protected
9
+
10
+ def api
11
+ @api ||= API.new
12
+ end
13
+
14
+ end
15
+ end
16
+
17
+ require_relative 'operations/check_domain'
18
+ require_relative 'operations/enable_auto_renewal'
19
+ require_relative 'operations/disable_auto_renewal'
20
+ require_relative 'operations/domain_register_au'
21
+ require_relative 'operations/domain_register'