soaspec 0.0.89 → 0.1.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: 0fbb853656c1ac3fa5e3f8cf9deb35d3ffd2094b
4
- data.tar.gz: 4af040f838d170b0248adcddbee6adffee89d978
3
+ metadata.gz: 47048ecb768673e682744c8ed3064450530ed0de
4
+ data.tar.gz: 4f4137848f7a656914205ad76a3ae800a065c969
5
5
  SHA512:
6
- metadata.gz: 72d6dcbf54043591c26c8e0951e68a56c331a26f7d8d05bc9acd76ae512bda463bddc5be2d96de322e4041c64c51b972f879aaf227f1e3465c436821bba2692a
7
- data.tar.gz: d25a4e7f6ab09ed7657a886fcf2b24aefd15da539fc9ad18fa1ed70a17c278a750a098e771603dd7e571d5cb6a9bfc2749525ae37e96dd3eff34ddb01d2a81e8
6
+ metadata.gz: dd35e76ceae861c08bcad153b0e124643c83b856071e486116f40d1a7c210f92b4d0854172bcf14a5d1a462e42f5ad197fd8853bdd8a252bbfc469948c52a1d9
7
+ data.tar.gz: 167dbbf4db1b4a61def28a6c4bfea8810c192a922f03495ae727fc754b9086a0658e8e5b1c4a0265a7d5c2ae322207f65889d65d4096a3061b7a7cb20e6886fb
data/ChangeLog CHANGED
@@ -1,3 +1,9 @@
1
+ Version 0.1.0
2
+ * Enhancements
3
+ * Cleaned up unit tests for WSDL generator. Won't bother for SOAP ComplexType for now as I'm not needing this and it looks like Savon 3 will create example requests anyway
4
+ * Put SOAP Basic Auth in Example
5
+ * Added template handling for REST handler
6
+
1
7
  Version 0.0.89
2
8
  * Enhancements
3
9
  * Move more functionality out of soaspec exe and into WsdlGenerator. Started unit tests for it
data/README.md CHANGED
@@ -31,7 +31,7 @@ Example:
31
31
  ```
32
32
  mkdir 'api_test'
33
33
  cd 'api_test'
34
- soaspec-init
34
+ soaspec new
35
35
  bundle install
36
36
  ```
37
37
 
@@ -41,7 +41,7 @@ Then you can run the tests with:
41
41
  rake spec
42
42
  ```
43
43
 
44
- You can also use `soaspec-generate` to generate a set of tests from a WSDL. This is still in trial period
44
+ You can also use `soaspec generate` to generate a set of tests from a WSDL. This is still in trial period and will be finished probably after Savon 3 is more stable.
45
45
 
46
46
  ## Usage
47
47
 
data/Todo.md CHANGED
@@ -1,7 +1,6 @@
1
1
  * Give examples and convenience methods for building classes for each SOAP or REST operation
2
2
  * For SOAP give example of basic_auth
3
- * Handle REST template (similar way to SOAP)
4
- * Get wsdl generator working for non complex gems
5
3
  * Potentially have in built use of 'vcr' and 'http_stub' gems
6
4
  * Handle proxies to record traffic for MiddleWare testing
7
- * Much more - please raise an issue for suggestion
5
+ * Get wsdl generator working for non complex gems (Put on hold til new Savon version)
6
+ * Much more - please raise an issue for suggestion
@@ -26,14 +26,9 @@ class SoaspecVirtualServer < Sinatra::Application
26
26
  Soaspec::TestServer::TestNamespace.food
27
27
  end
28
28
 
29
- # This is the one being hit by SOAP actions
30
- post '/BLZService' do
31
- Soaspec::TestServer::GetBank.response_for request
32
- end
33
-
34
- # This is returned when a query for the WSDL is made
35
- get '/BLZService' do
36
- [200, { 'Content-Type' => 'text/xml' }, Soaspec::TestServer::GetBank.test_wsdl]
29
+ # Used for simple testing of posing
30
+ post '/echoer' do
31
+ request.body
37
32
  end
38
33
 
39
34
  # Simulate retrieving an ouath token. Passed to '/invoices'
@@ -46,6 +41,11 @@ class SoaspecVirtualServer < Sinatra::Application
46
41
  JSON.generate(customer_id: id, oauth: request.env['HTTP_AUTHORIZATION'], user: Soaspec::TestServer::Invoices.user_used)
47
42
  end
48
43
 
44
+ # This is returned when a query for the WSDL is made
45
+ get '/BLZService' do
46
+ [200, { 'Content-Type' => 'text/xml' }, Soaspec::TestServer::GetBank.test_wsdl]
47
+ end
48
+
49
49
  authorize do |username, password|
50
50
  username == 'admin' && password == 'secret'
51
51
  end
@@ -54,6 +54,11 @@ class SoaspecVirtualServer < Sinatra::Application
54
54
  get '/basic_secrets' do
55
55
  'Secret data'
56
56
  end
57
+
58
+ # This is the one being hit by SOAP actions
59
+ post '/BLZService' do
60
+ Soaspec::TestServer::GetBank.response_for request
61
+ end
57
62
  end
58
63
 
59
64
  # Used for testing storage of data
@@ -55,6 +55,7 @@ module Soaspec
55
55
  super
56
56
  set_remove_key(options, :api_username)
57
57
  set_remove_key(options, :default_hash)
58
+ set_remove_key(options, :template_name)
58
59
  @init_options = options
59
60
  end
60
61
 
@@ -71,16 +72,6 @@ module Soaspec
71
72
  false
72
73
  end
73
74
 
74
- # @return [Hash]
75
- def hash_used_in_request(override_hash)
76
- request = @default_hash.merge(override_hash)
77
- if pascal_keys?
78
- request.map { |k, v| [convert_to_pascal_case(k.to_s), v] }.to_h
79
- else
80
- request
81
- end
82
- end
83
-
84
75
  # Initialize value of merged options
85
76
  def init_merge_options
86
77
  options = rest_resource_options
@@ -93,6 +84,7 @@ module Soaspec
93
84
  # @param [Hash] override_parameters Params to characterize REST request
94
85
  # @param_value [params] Extra parameters (E.g. headers)
95
86
  # @param_value [suburl] URL appended to base_url of class
87
+ # @param_value [q] Query for REST
96
88
  # @param_value [method] REST method (:get, :post, etc)
97
89
  def make_request(override_parameters)
98
90
  @merged_options ||= init_merge_options
@@ -101,7 +93,6 @@ module Soaspec
101
93
  test_values[:method] ||= :post
102
94
  test_values[:suburl] = test_values[:suburl].to_s if test_values[:suburl]
103
95
  test_values[:params][:params] = test_values[:q] if test_values[:q] # Use q for query parameters. Nested :params is ugly and long
104
-
105
96
  # In order for ERB to be calculated at correct time, the first time request is made, the resource should be created
106
97
  @resource ||= RestClient::Resource.new(ERB.new(base_url_value).result(binding), @merged_options)
107
98
 
@@ -110,11 +101,9 @@ module Soaspec
110
101
  begin
111
102
  response = case test_values[:method]
112
103
  when :post, :patch, :put
113
- unless test_values[:payload]
114
- test_values[:payload] = JSON.generate(hash_used_in_request(test_values[:body])).to_s if test_values[:body]
115
- end
116
- @resource_used.send(test_values[:method].to_s, test_values[:payload], test_values[:params])
117
- else
104
+ Soaspec::SpecLogger.info("request body: #{post_data(test_values)}")
105
+ @resource_used.send(test_values[:method].to_s, post_data(test_values), test_values[:params])
106
+ else # :get, :delete
118
107
  @resource_used.send(test_values[:method].to_s, test_values[:params])
119
108
  end
120
109
  rescue RestClient::ExceptionWithResponse => e
@@ -131,11 +120,12 @@ module Soaspec
131
120
  extract_hash response
132
121
  end
133
122
 
123
+ # @return [Boolean] Whether response body includes String
134
124
  def include_in_body?(response, expected)
135
125
  response.body.include? expected
136
126
  end
137
127
 
138
- # Whether the request found the desired value or not
128
+ # @@return [Boolean] Whether the request found the desired value or not
139
129
  def found?(response)
140
130
  status_code_for(response) != 404
141
131
  end
@@ -275,6 +265,31 @@ module Soaspec
275
265
  end
276
266
  end
277
267
 
268
+ private
269
+
270
+ # Work out data to send based upon payload, template_name
271
+ # @return [String] Payload to send in REST request
272
+ def post_data(test_values)
273
+ if test_values[:body]
274
+ test_values[:payload] = JSON.generate(hash_used_in_request(test_values[:body])).to_s
275
+ elsif @request_option == :template
276
+ request_body = File.read('template/' + template_name)
277
+ ERB.new(request_body).result(binding)
278
+ else
279
+ test_values[:payload]
280
+ end
281
+ end
282
+
283
+ # @return [Hash] Hash used in REST request based on data conversion
284
+ def hash_used_in_request(override_hash)
285
+ request = @default_hash.merge(override_hash)
286
+ if pascal_keys?
287
+ request.map { |k, v| [convert_to_pascal_case(k.to_s), v] }.to_h
288
+ else
289
+ request
290
+ end
291
+ end
292
+
278
293
  # Convenience methods for once off usage of a REST request
279
294
  class << self
280
295
 
@@ -101,11 +101,11 @@ module Soaspec
101
101
  test_values = request_body_params request_parameters
102
102
  begin
103
103
  if @request_option == :template
104
- request_body = File.read('template/' + template_name + '.xml')
104
+ request_body = File.read('template/' + template_name)
105
105
  render_body = ERB.new(request_body).result(binding)
106
- @client.call(operation, xml: render_body) # Call the SOAP operation with the request XML provided
106
+ client.call(operation, xml: render_body) # Call the SOAP operation with the request XML provided
107
107
  elsif @request_option == :hash
108
- @client.call(operation, message: @default_hash.merge(test_values), attributes: request_root_attributes)
108
+ client.call(operation, message: @default_hash.merge(test_values), attributes: request_root_attributes)
109
109
  end
110
110
  rescue Savon::HTTPError => e
111
111
  e
@@ -1,3 +1,3 @@
1
1
  module Soaspec
2
- VERSION = '0.0.89'.freeze
2
+ VERSION = '0.1.0'.freeze
3
3
  end
@@ -5,7 +5,7 @@ module Soaspec
5
5
  def try_enum_for(type)
6
6
  raise "'@wsdl_schemas' must be defined" if @wsdl_schemas.nil?
7
7
  custom_type = @wsdl_schemas.xpath("//*[@name='#{type}']")
8
- if custom_type.first
8
+ if enumeration? custom_type
9
9
  prefix = custom_type.first.namespace.prefix
10
10
  enumerations = custom_type.xpath("//#{prefix}:enumeration")
11
11
  return 'Custom Type' if enumerations.empty?
@@ -17,6 +17,13 @@ module Soaspec
17
17
  end
18
18
  end
19
19
 
20
+ # @param [Nokogiri::XML::NodeSet]
21
+ # @return [Boolean] Whether WSDL type is an enumeration
22
+ def enumeration?(type)
23
+ return false unless type.first
24
+ !type.xpath("*/#{type.first.namespace.prefix}:enumeration").empty?
25
+ end
26
+
20
27
  # Return value of string after a namespace
21
28
  # @param [String] string String to parse for part after namespace
22
29
  def value_after_namespace(string)
@@ -40,6 +47,12 @@ module Soaspec
40
47
  end
41
48
  end
42
49
 
50
+ # @param [Nokogiri::XML::Element]
51
+ # @return [Boolean] True if nokogori element is a complex type, that is, has a complexType element underneath itself
52
+ def complex_type?(element)
53
+ element.children.any? { |child| child.name == 'complexType' }
54
+ end
55
+
43
56
  # @param [String, Symbol] underscore_separated Snakecase value to be converted to camel case
44
57
  def camel_case(underscore_separated)
45
58
  underscore_separated.to_s.split('_').collect(&:capitalize).join
@@ -52,27 +65,43 @@ module Soaspec
52
65
  root_element = @wsdl_schemas.at_xpath("//*[@name='#{op_details[:input]}']")
53
66
  raise 'Operation has no input defined' if root_element.nil?
54
67
  schema_namespace = root_element.namespace.prefix
55
-
56
68
  root_type = root_element['type']
57
69
  if root_type
58
70
  @wsdl_schemas.xpath("//*[@name='#{root_type.split(':').last}']//#{schema_namespace}:element")
59
71
  else
60
- return [] unless root_element.children.any? { |child| child.name == 'complexType' } # Empty Array if there are no root elements
61
- root_element.xpath("//#{schema_namespace}:element")
72
+ return [] unless complex_type? root_element # Empty Array if there are no root elements
73
+ complex_type = root_element.children.find { |c| c.name == 'complexType' }
74
+ sequence = complex_type.children.find { |c| c.name == 'sequence' }
75
+ sequence.xpath("#{schema_namespace}:element")
62
76
  end
63
77
  end
64
78
 
65
- # @param [Nokogiri::NodeSet] list List
66
- def wsdl_to_yaml_for(list)
67
- raise "'@content' string must be set" if @content.nil?
68
- puts list
69
- list.each do |element|
79
+ # @param [Nokogiri::XML::Element]
80
+ def document_type_for(element, depth = 1)
81
+ # raise "Too far deep for #{element}" unless depth < 6
82
+ return unless depth < 6
83
+ if complex_type? element
84
+ complex_type = element.children.find { |c| c.name == 'complexType' }
85
+ sequence = complex_type.children.find { |c| c.name == 'sequence' }
86
+ sequence.children.select { |node| node.class == Nokogiri::XML::Element }.each do |sub_element|
87
+ document_type_for sub_element, depth += 1
88
+ end
89
+ else
90
+ return "No type seen for #{element}, #{element.class}" unless element['type']
70
91
  name = element['name']
71
92
  type = value_after_namespace(element['type'])
72
- puts 'Name ' + name + ' type ' + type
73
93
  @use_camel_case = true if (/[[:upper:]]/.match(name[0]) != nil)
74
- @content += " #{name.snakecase}: #{fill_in_field_from_type(type)} # #{type} \n"
75
- # TODO: If it is nested need to loop again
94
+ spaces = ' ' * depth
95
+ @content += "#{spaces}#{name.snakecase}: #{fill_in_field_from_type(type)} # #{type} \n"
96
+ end
97
+ end
98
+
99
+ # Makes a yaml string in a '@content' instance variable
100
+ # @param [Nokogiri::XML::NodeSet] list List
101
+ def wsdl_to_yaml_for(list)
102
+ raise "'@content' string must be set" if @content.nil?
103
+ list.each do |element|
104
+ document_type_for element
76
105
  end
77
106
  end
78
107
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: soaspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.89
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SamuelGarrattIQA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-06 00:00:00.000000000 Z
11
+ date: 2018-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler