soaspec 0.0.19 → 0.0.20

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.
@@ -1,64 +1,64 @@
1
-
2
- require 'xmlsimple'
3
- require 'yaml'
4
- require 'fileutils'
5
-
6
- default_output_file = 'output.yml'
7
-
8
- # Create file if not present. If present but different give warning
9
- def create_file(options)
10
- filename = options[:filename]
11
- raise 'Need to pass filename' unless filename
12
- content = options[:content]
13
- raise 'Need to pass contents to insert into file' unless content
14
- if File.exist? filename
15
- old_content = File.read(filename)
16
- if old_content != content
17
- warn "!! #{filename} already exists and differs from template"
18
- end
19
- else
20
- File.open(filename, 'w') do |f|
21
- f.puts content
22
- end
23
- puts 'Created: ' + filename
24
- end
25
- end
26
-
27
- # Convert key in camelcase to underscore separated (snakecase)
28
- def underscore_key(key)
29
- key.to_s.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
30
- .gsub(/([a-z\d])([A-Z])/,'\1_\2')
31
- .tr('-', '_')
32
- .gsub(/\s/, '_')
33
- .gsub(/__+/, '_')
34
- .downcase
35
- end
36
-
37
- # For all keys in a Hash, convert Camelcase to underscore separated
38
- def convert_hash_keys(value)
39
- case value
40
- when Array
41
- value.map { |v| convert_hash_keys(v) }
42
- when Hash
43
- Hash[value.map { |k, v| [underscore_key(k), convert_hash_keys(v)] }]
44
- else
45
- value
46
- end
47
- end
48
-
49
- # Remove arrays created as another string
50
- def clean_up_yaml(yaml_string)
51
- yaml_string = yaml_string.gsub(/\R+(\s*)-/, '').gsub(/{}/, "''") # Remove arrays, {} -> ''
52
- # Insert new line where there are 2 ':' on 1 line. Issue from first gsub
53
- yaml_string.gsub(/:(\s)(\w*):/){|s| s.insert(1, "\n")}
54
- end
55
-
56
- if ARGV[0]
57
- warn "Using '#{default_output_file}' as default output file since no 2nd argument passed" unless ARGV[1]
58
- hash = XmlSimple.xml_in(ARGV[0])
59
- converted = convert_hash_keys hash
60
- yaml_file = clean_up_yaml(converted.to_yaml)
61
- create_file(filename: ARGV[1] || default_output_file, content: yaml_file)
62
- else
63
- puts 'usage: xml_to_yaml_file [input.xml] [output.yml] '
1
+
2
+ require 'xmlsimple'
3
+ require 'yaml'
4
+ require 'fileutils'
5
+
6
+ default_output_file = 'output.yml'
7
+
8
+ # Create file if not present. If present but different give warning
9
+ def create_file(options)
10
+ filename = options[:filename]
11
+ raise 'Need to pass filename' unless filename
12
+ content = options[:content]
13
+ raise 'Need to pass contents to insert into file' unless content
14
+ if File.exist? filename
15
+ old_content = File.read(filename)
16
+ if old_content != content
17
+ warn "!! #{filename} already exists and differs from template"
18
+ end
19
+ else
20
+ File.open(filename, 'w') do |f|
21
+ f.puts content
22
+ end
23
+ puts 'Created: ' + filename
24
+ end
25
+ end
26
+
27
+ # Convert key in camelcase to underscore separated (snakecase)
28
+ def underscore_key(key)
29
+ key.to_s.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
30
+ .gsub(/([a-z\d])([A-Z])/,'\1_\2')
31
+ .tr('-', '_')
32
+ .gsub(/\s/, '_')
33
+ .gsub(/__+/, '_')
34
+ .downcase
35
+ end
36
+
37
+ # For all keys in a Hash, convert Camelcase to underscore separated
38
+ def convert_hash_keys(value)
39
+ case value
40
+ when Array
41
+ value.map { |v| convert_hash_keys(v) }
42
+ when Hash
43
+ Hash[value.map { |k, v| [underscore_key(k), convert_hash_keys(v)] }]
44
+ else
45
+ value
46
+ end
47
+ end
48
+
49
+ # Remove arrays created as another string
50
+ def clean_up_yaml(yaml_string)
51
+ yaml_string = yaml_string.gsub(/\R+(\s*)-/, '').gsub(/{}/, "''") # Remove arrays, {} -> ''
52
+ # Insert new line where there are 2 ':' on 1 line. Issue from first gsub
53
+ yaml_string.gsub(/:(\s)(\w*):/){|s| s.insert(1, "\n")}
54
+ end
55
+
56
+ if ARGV[0]
57
+ warn "Using '#{default_output_file}' as default output file since no 2nd argument passed" unless ARGV[1]
58
+ hash = XmlSimple.xml_in(ARGV[0])
59
+ converted = convert_hash_keys hash
60
+ yaml_file = clean_up_yaml(converted.to_yaml)
61
+ create_file(filename: ARGV[1] || default_output_file, content: yaml_file)
62
+ else
63
+ puts 'usage: xml_to_yaml_file [input.xml] [output.yml] '
64
64
  end
@@ -1,48 +1,61 @@
1
- require 'rest-client' # REST
2
- require 'erb' # Embedded ruby
3
- require 'yaml' # Reading yaml
4
- require 'rspec' # Testing framework
5
- require 'rspec/its'
6
- require 'savon' # SOAP
7
- require 'nokogiri' # XPath
8
- require 'date'
9
-
10
- require 'soaspec/version'
11
- require 'soaspec/basic_soap_handler'
12
- require 'soaspec/tester'
13
- require 'soaspec/exchange'
14
- require 'soaspec/matchers'
15
- require 'soaspec/soaspec_shared_examples'
16
- require 'soaspec/hash_methods'
17
- require 'soaspec/spec_logger'
18
-
19
- # Gem for handling SOAP and REST api tests
20
- module Soaspec
21
-
22
- def self.hi
23
- puts 'Hello world!'
24
- end
25
-
26
- # Represents Environment parameters used in Soaspec tests
27
- module Environment
28
-
29
- # Used so that exchange class knows what context it's in
30
- def self.api_handler=(handler)
31
- @api_handler = handler
32
- end
33
-
34
- def self.api_handler
35
- @api_handler
36
- end
37
-
38
- # Whether to transform strings to keys automatically
39
- def self.always_use_keys=(use_keys)
40
- @always_use_keys = use_keys
41
- end
42
-
43
- def self.always_use_keys?
44
- @always_use_keys || true
45
- end
46
-
47
- end
48
- end
1
+ require 'rest-client' # REST
2
+ require 'erb' # Embedded ruby
3
+ require 'yaml' # Reading yaml
4
+ require 'rspec' # Testing framework
5
+ require 'rspec/its'
6
+ require 'savon' # SOAP
7
+ require 'nokogiri' # XPath
8
+ require 'date'
9
+
10
+ require 'soaspec/version'
11
+ require 'soaspec/basic_soap_handler'
12
+ require 'soaspec/tester'
13
+ require 'soaspec/exchange'
14
+ require 'soaspec/matchers'
15
+ require 'soaspec/soaspec_shared_examples'
16
+ require 'soaspec/hash_methods'
17
+ require 'soaspec/spec_logger'
18
+
19
+ # Gem for handling SOAP and REST api tests
20
+ module Soaspec
21
+
22
+ def self.hi
23
+ puts 'Hello world!'
24
+ end
25
+
26
+ # Represents Environment parameters used in Soaspec tests
27
+ module Environment
28
+
29
+ # Used so that exchange class knows what context it's in
30
+ def self.api_handler=(handler)
31
+ @api_handler = handler
32
+ end
33
+
34
+ def self.api_handler
35
+ @api_handler
36
+ end
37
+
38
+ # Whether to transform strings to keys automatically
39
+ def self.always_use_keys=(use_keys)
40
+ @always_use_keys = use_keys
41
+ end
42
+
43
+ def self.always_use_keys?
44
+ @always_use_keys || true
45
+ end
46
+
47
+ # Whether to remove namespaces from response in Xpath assertion automatically
48
+ # For why this may not be a good thing in general see
49
+ # http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html
50
+ # This will be overridden if xpath has a ':' in it
51
+ def self.strip_namespaces=(remove_namespaces_from_response)
52
+ @strip_namespaces = remove_namespaces_from_response
53
+ end
54
+
55
+ # Whether to remove namespaces in xpath assertion automatically
56
+ def self.strip_namespaces?
57
+ @strip_namespaces || false
58
+ end
59
+
60
+ end
61
+ end
@@ -1,123 +1,133 @@
1
-
2
- require_relative 'tester'
3
- require_relative 'hash_methods'
4
-
5
- module Soaspec
6
- # Wraps around Savon client defining default values dependent on the soap request
7
- class BasicSoapHandler < Tester
8
- # Savon client used to make SOAP calls
9
- attr_accessor :client
10
- # SOAP Operation to use by default
11
- attr_accessor :operation
12
-
13
- # Options to log xml request and response
14
- def logging_options
15
- {
16
- log: true, # See request and response. (Put this in traffic file)
17
- log_level: :debug,
18
- logger: Soaspec::SpecLogger.create,
19
- pretty_print_xml: true # Prints XML pretty
20
- }
21
- end
22
-
23
- # Default Savon options. See http://savonrb.com/version2/globals.html for details
24
- # @return [Hash] Default Savon options for all BasicSoapHandler
25
- def default_options
26
- {
27
- ssl_verify_mode: :none, # Easier for testing. Not so secure
28
- follow_redirects: true, # Necessary for many API calls
29
- soap_version: 2, # use SOAP 1.2. You will get 415 error if this is incorrect
30
- raise_errors: false # HTTP errors not cause failure as often negative test scenarios expect not 200 response
31
- # Things could go wrong if not set properly
32
- # env_namespace: :soap, # Change environment namespace
33
- # namespace_identifier: :tst, # Change namespace element
34
- # element_form_default: :qualified # Populate each element with namespace
35
- # namespace: 'http://Extended_namespace.xsd' change root namespace
36
- # basic_auth: 'user', 'password'
37
- }
38
- end
39
-
40
- # Add values to here when extending this class to have default Savon options.
41
- # See http://savonrb.com/version2/globals.html for details
42
- # @return [Hash] Savon options adding to & overriding defaults
43
- def savon_options
44
- {
45
- }
46
- end
47
-
48
- # Setup object to handle communicating with a particular SOAP WSDL
49
- # @param [Hash] specific_options Options defining SOAP request. WSDL, authentication, see http://savonrb.com/version2/globals.html for list of options
50
- def initialize(name, specific_options = {})
51
- options = default_options.merge logging_options
52
- options.merge! savon_options
53
- options.merge!(specific_options)
54
- @client = Savon.client(options)
55
- super
56
- end
57
-
58
- def name(name)
59
- @test_values = {}
60
- @test_name = name
61
- self
62
- end
63
-
64
- def override(request_parameters)
65
- @test_values = request_parameters
66
- self
67
- end
68
-
69
- # Used in together with Exchange request that passes such override parameters
70
- def make_request(override_parameters)
71
- test_values = override_parameters # Used in Erb
72
- # Erb parses template file, executing Ruby code in `<% %>` blocks to work out final request
73
- test_values = test_values.transform_keys_to_symbols if Soaspec::Environment.always_use_keys?
74
- if @request_option == :template
75
- request_body = File.read('template/' + template_name + '.xml')
76
- render_body = ERB.new(request_body).result(binding)
77
- @client.call(operation, xml: render_body) # Call the SOAP operation with the request XML provided
78
- elsif @request_option == :hash
79
- @client.call(operation, message: @default_hash.merge(test_values), attributes: root_attributes)
80
- end
81
- end
82
-
83
- def default_hash=(hash)
84
- @request_option = :hash
85
- @default_hash = Soaspec::Environment.always_use_keys? ? hash.transform_keys_to_symbols : hash
86
- end
87
-
88
- def status_code_for(response)
89
- response.http.code
90
- end
91
-
92
- # Override this to specify elements that must be present in the response
93
- # Will be used in 'success_scenarios' shared examples
94
- # @return [Array] Array of symbols specifying element names
95
- def mandatory_elements
96
- []
97
- end
98
-
99
- # Override this to specify xpath results that must be present in the response
100
- # Will be used in 'success_scenarios' shared examples
101
- # @return [Hash] Hash of 'xpath' => 'expected value' pairs
102
- def mandatory_xpath_values
103
- {}
104
- end
105
-
106
- # Attributes set at the root XML element of SOAP request
107
- def root_attributes
108
- nil
109
- end
110
-
111
- def xpath_value_for(param)
112
- result = param[:exchange].response.xpath(param[:xpath]).first
113
- raise 'No value at Xpath' unless result
114
- result.inner_text
115
- end
116
-
117
- def value_from_path(exchange, path)
118
- path = '//' + path if path[0] != '/'
119
- xpath_value_for(exchange: exchange, xpath: path)
120
- end
121
-
122
- end
1
+
2
+ require_relative 'tester'
3
+ require_relative 'hash_methods'
4
+ require_relative 'xpath_not_found'
5
+
6
+ module Soaspec
7
+ # Wraps around Savon client defining default values dependent on the soap request
8
+ class BasicSoapHandler < Tester
9
+ # Savon client used to make SOAP calls
10
+ attr_accessor :client
11
+ # SOAP Operation to use by default
12
+ attr_accessor :operation
13
+
14
+ # Options to log xml request and response
15
+ def logging_options
16
+ {
17
+ log: true, # See request and response. (Put this in traffic file)
18
+ log_level: :debug,
19
+ logger: Soaspec::SpecLogger.create,
20
+ pretty_print_xml: true # Prints XML pretty
21
+ }
22
+ end
23
+
24
+ # Default Savon options. See http://savonrb.com/version2/globals.html for details
25
+ # @return [Hash] Default Savon options for all BasicSoapHandler
26
+ def default_options
27
+ {
28
+ ssl_verify_mode: :none, # Easier for testing. Not so secure
29
+ follow_redirects: true, # Necessary for many API calls
30
+ soap_version: 2, # use SOAP 1.2. You will get 415 error if this is incorrect
31
+ raise_errors: false # HTTP errors not cause failure as often negative test scenarios expect not 200 response
32
+ # Things could go wrong if not set properly
33
+ # env_namespace: :soap, # Change environment namespace
34
+ # namespace_identifier: :tst, # Change namespace element
35
+ # element_form_default: :qualified # Populate each element with namespace
36
+ # namespace: 'http://Extended_namespace.xsd' change root namespace
37
+ # basic_auth: 'user', 'password'
38
+ }
39
+ end
40
+
41
+ # Add values to here when extending this class to have default Savon options.
42
+ # See http://savonrb.com/version2/globals.html for details
43
+ # @return [Hash] Savon options adding to & overriding defaults
44
+ def savon_options
45
+ {
46
+ }
47
+ end
48
+
49
+ # Setup object to handle communicating with a particular SOAP WSDL
50
+ # @param [Hash] specific_options Options defining SOAP request. WSDL, authentication, see http://savonrb.com/version2/globals.html for list of options
51
+ def initialize(name, specific_options = {})
52
+ options = default_options.merge logging_options
53
+ options.merge! savon_options
54
+ options.merge!(specific_options)
55
+ @client = Savon.client(options)
56
+ super
57
+ end
58
+
59
+ def name(name)
60
+ @test_values = {}
61
+ @test_name = name
62
+ self
63
+ end
64
+
65
+ def override(request_parameters)
66
+ @test_values = request_parameters
67
+ self
68
+ end
69
+
70
+ # Used in together with Exchange request that passes such override parameters
71
+ def make_request(override_parameters)
72
+ test_values = override_parameters # Used in Erb
73
+ # Erb parses template file, executing Ruby code in `<% %>` blocks to work out final request
74
+ test_values = test_values.transform_keys_to_symbols if Soaspec::Environment.always_use_keys?
75
+ if @request_option == :template
76
+ request_body = File.read('template/' + template_name + '.xml')
77
+ render_body = ERB.new(request_body).result(binding)
78
+ @client.call(operation, xml: render_body) # Call the SOAP operation with the request XML provided
79
+ elsif @request_option == :hash
80
+ @client.call(operation, message: @default_hash.merge(test_values), attributes: root_attributes)
81
+ end
82
+ end
83
+
84
+ def default_hash=(hash)
85
+ @request_option = :hash
86
+ @default_hash = Soaspec::Environment.always_use_keys? ? hash.transform_keys_to_symbols : hash
87
+ end
88
+
89
+ def status_code_for(response)
90
+ response.http.code
91
+ end
92
+
93
+ # Override this to specify elements that must be present in the response
94
+ # Will be used in 'success_scenarios' shared examples
95
+ # @return [Array] Array of symbols specifying element names
96
+ def mandatory_elements
97
+ []
98
+ end
99
+
100
+ # Override this to specify xpath results that must be present in the response
101
+ # Will be used in 'success_scenarios' shared examples
102
+ # @return [Hash] Hash of 'xpath' => 'expected value' pairs
103
+ def mandatory_xpath_values
104
+ {}
105
+ end
106
+
107
+ # Attributes set at the root XML element of SOAP request
108
+ def root_attributes
109
+ nil
110
+ end
111
+
112
+ # Returns the value at the provided xpath
113
+ def xpath_value_for(param)
114
+ result =
115
+ if Soaspec::Environment.strip_namespaces? && !param[:xpath].include?(':')
116
+ temp_doc = param[:exchange].response.doc
117
+ temp_doc.remove_namespaces!
118
+ temp_doc.xpath(param[:xpath]).first
119
+ else
120
+ puts 'no strip' + param[:xpath]
121
+ param[:exchange].response.xpath(param[:xpath]).first
122
+ end
123
+ raise NoElementAtXpath, "No value at Xpath '#{param[:xpath]}'" unless result
124
+ result.inner_text
125
+ end
126
+
127
+ def value_from_path(exchange, path)
128
+ path = '//' + path if path[0] != '/'
129
+ xpath_value_for(exchange: exchange, xpath: path)
130
+ end
131
+
132
+ end
123
133
  end