soaspec 0.2.8 → 0.2.9

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +0 -17
  3. data/ChangeLog +6 -0
  4. data/Gemfile +2 -2
  5. data/README.md +42 -9
  6. data/Rakefile +1 -1
  7. data/exe/soaspec +9 -14
  8. data/exe/xml_to_yaml_file +3 -3
  9. data/images/basic_demo.gif +0 -0
  10. data/lib/soaspec.rb +9 -19
  11. data/lib/soaspec/core_ext/hash.rb +10 -12
  12. data/lib/soaspec/cucumber/generic_steps.rb +1 -1
  13. data/lib/soaspec/exchange.rb +4 -1
  14. data/lib/soaspec/exchange_handlers/exchange_handler.rb +5 -4
  15. data/lib/soaspec/exchange_handlers/handler_accessors.rb +7 -3
  16. data/lib/soaspec/exchange_handlers/response_extractor.rb +55 -0
  17. data/lib/soaspec/exchange_handlers/rest_exchanger_factory.rb +1 -1
  18. data/lib/soaspec/exchange_handlers/rest_handler.rb +16 -43
  19. data/lib/soaspec/exchange_handlers/rest_methods.rb +1 -2
  20. data/lib/soaspec/exchange_handlers/rest_parameters.rb +6 -2
  21. data/lib/soaspec/exchange_handlers/rest_parameters_defaults.rb +1 -1
  22. data/lib/soaspec/exchange_handlers/soap_handler.rb +6 -10
  23. data/lib/soaspec/exchange_properties.rb +1 -2
  24. data/lib/soaspec/exe_helpers.rb +7 -9
  25. data/lib/soaspec/indifferent_hash.rb +1 -1
  26. data/lib/soaspec/interpreter.rb +1 -3
  27. data/lib/soaspec/matchers.rb +1 -2
  28. data/lib/soaspec/o_auth2.rb +2 -1
  29. data/lib/soaspec/spec_logger.rb +54 -12
  30. data/lib/soaspec/template_reader.rb +2 -1
  31. data/lib/soaspec/test_server/get_bank.rb +5 -5
  32. data/lib/soaspec/test_server/id_manager.rb +1 -3
  33. data/lib/soaspec/test_server/invoices.rb +0 -1
  34. data/lib/soaspec/test_server/puppy_service.rb +0 -1
  35. data/lib/soaspec/test_server/test_attribute.rb +0 -1
  36. data/lib/soaspec/version.rb +2 -2
  37. data/lib/soaspec/virtual_server.rb +1 -1
  38. data/lib/soaspec/wait.rb +1 -1
  39. data/lib/soaspec/wsdl_generator.rb +11 -3
  40. data/soaspec.gemspec +7 -2
  41. data/test_wsdl.rb +4 -7
  42. metadata +54 -10
@@ -1,39 +1,72 @@
1
-
2
1
  require 'logger'
3
2
  require 'fileutils'
3
+ require 'colorize'
4
4
 
5
5
  module Soaspec
6
-
7
6
  # Handles logs of API requests and responses
8
7
  class SpecLogger
9
- @traffic_folder = 'logs' # Folder to put API traffic logs
8
+ # Folder to put API traffic logs
9
+ @traffic_folder = 'logs'
10
+ # Whether to output api traffic to terminal
11
+ @output_to_terminal = false
12
+ # Whether to output API traffic to log file
13
+ @output_to_file = true
14
+ # Time test run. Will only be calculated once once called
15
+ @time_test_run = Time.now.strftime('%Y-%m-%d_%H_%M_%S')
10
16
 
11
17
  class << self
12
18
  # Folder to put API traffic logs
13
19
  attr_accessor :traffic_folder
20
+ # Readers for log parameters
21
+ attr_reader :output_to_terminal, :output_to_file, :time_test_run
22
+
23
+ # Whether to log all API traffic
24
+ def log_api_traffic=(set)
25
+ @log_api_traffic = set
26
+ RestClient.log = nil unless set
27
+ end
28
+
29
+ # @return [Boolean] Whether to log all API traffic
30
+ def log_api_traffic?
31
+ @log_api_traffic.nil? ? true : @log_api_traffic
32
+ end
33
+
34
+ # @param [Symbol, Boolean] value # Whether to output API traffic to log file
35
+ def output_to_file=(value)
36
+ @output_to_file = value
37
+ RestClient.log = Soaspec::SpecLogger.create
38
+ end
39
+
40
+ # @param [Symbol, Boolean] value # Whether to output API traffic to STDOUT
41
+ def output_to_terminal=(value)
42
+ @output_to_terminal = value
43
+ RestClient.log = Soaspec::SpecLogger.create
44
+ end
14
45
 
15
46
  # @return [String] Traffic file to create logs at
16
47
  def traffic_file
17
- filename = "traffic_#{Time.now.strftime('%Y-%m-%d_%H_%M_%S')}.log"
48
+ filename = "traffic_#{time_test_run}.log"
18
49
  File.join(traffic_folder, filename)
19
50
  end
20
51
 
21
52
  # Create new log file if necessary and setup logging level
22
53
  # @return [Logger] Logger class to record API traffic
23
54
  def create
24
- unless File.exist?(traffic_file)
25
- FileUtils.mkdir_p traffic_folder
26
- FileUtils.touch traffic_file
27
- end
55
+ create_log_file
28
56
  @logger = Logger.new(traffic_file) # Where request and responses of APIs are stored
29
- @logger.level = Logger::DEBUG
57
+ @logger.formatter = proc do |severity, datetime, _progname, msg|
58
+ message = "SpecLog, [#{datetime.strftime('%Y-%m-%d_%H:%M:%S')}] #{severity} -- : #{msg}\n"
59
+ print message.colorize(:light_blue) if @output_to_terminal
60
+ message
61
+ end
30
62
  @logger
31
63
  end
32
64
 
33
65
  # Log a message using Soaspec logger
34
66
  # @param [String] message The message to add to the logger
35
67
  def info(message)
36
- return unless Soaspec.log_api_traffic?
68
+ return unless log_api_traffic?
69
+
37
70
  if message.respond_to? :each
38
71
  message.each do |message_item|
39
72
  @logger.info(message_item)
@@ -42,7 +75,16 @@ module Soaspec
42
75
  @logger.info(message)
43
76
  end
44
77
  end
45
- end
46
78
 
79
+ private
80
+
81
+ # Create folder and file to store logs
82
+ def create_log_file
83
+ return if File.exist?(traffic_file)
84
+
85
+ FileUtils.mkdir_p traffic_folder
86
+ FileUtils.touch traffic_file
87
+ end
88
+ end
47
89
  end
48
- end
90
+ end
@@ -21,7 +21,8 @@ module Soaspec
21
21
  end
22
22
  request_body = File.read file_location
23
23
  raise "Template at #{file_location} not parsed correctly" if request_body.strip.empty?
24
+
24
25
  ERB.new(request_body).result(binding)
25
26
  end
26
27
  end
27
- end
28
+ end
@@ -1,13 +1,11 @@
1
-
2
1
  require 'erb'
3
2
 
4
3
  module Soaspec
5
4
  module TestServer
6
5
  # Representing a GetBank SOAP service
7
6
  class GetBank
8
-
9
7
  class << self
10
-
8
+ # @return [String] WSDL of mock web service
11
9
  def test_wsdl
12
10
  ERB.new(File.read(File.join(File.dirname(__FILE__), 'bank.wsdl'))).result(binding)
13
11
  end
@@ -142,20 +140,22 @@ module Soaspec
142
140
  @title = 'Deutsche Bank'
143
141
  soap_action = request.env['HTTP_SOAPACTION']
144
142
  return 500, 'Not valid SOAP' unless soap_action
143
+
145
144
  request_body = request.body
146
145
  doc = Nokogiri::XML(request_body)
147
146
  soap_action = soap_action.strip # Used in ERB
148
147
  blz_element = doc.at_xpath('//tns:blz')
149
148
  return 500, error_response_template unless blz_element
149
+
150
150
  @bank_name = blz_element.inner_text
151
151
  @bank_id = @bank_name.to_i
152
152
  return 500, ERB.new(bank_not_found).result(binding) if @bank_id.zero?
153
+
153
154
  @title = 'DAB Bank' if @bank_id == 500
154
155
  @multiple_ort = (@bank_id == 20)
155
156
  ERB.new(success_response_template).result(binding)
156
157
  end
157
-
158
158
  end
159
159
  end
160
160
  end
161
- end
161
+ end
@@ -5,7 +5,6 @@ module Soaspec
5
5
  class IdManager
6
6
  @developed = false
7
7
  class << self
8
-
9
8
  attr_accessor :developed
10
9
 
11
10
  # @return Result depending on num, id and whether '@developed' is set
@@ -25,8 +24,7 @@ module Soaspec
25
24
  'true'
26
25
  end
27
26
  end
28
-
29
27
  end
30
28
  end
31
29
  end
32
- end
30
+ end
@@ -20,7 +20,6 @@ module Soaspec
20
20
  expires_in: '86399'
21
21
  }
22
22
  end
23
-
24
23
  end
25
24
  end
26
25
  end
@@ -13,7 +13,6 @@ module Soaspec
13
13
  @current_id += 1
14
14
  @current_id - 1
15
15
  end
16
-
17
16
  end
18
17
  end
19
18
  end
@@ -1,4 +1,3 @@
1
-
2
1
  module Soaspec
3
2
  module TestServer
4
3
  # Helps tests attribute methods
@@ -1,3 +1,3 @@
1
1
  module Soaspec
2
- VERSION = '0.2.8'.freeze
3
- end
2
+ VERSION = '0.2.9'.freeze
3
+ end
@@ -147,7 +147,7 @@ module Soaspec
147
147
  ]
148
148
  }
149
149
  }
150
- BOOKS
150
+ BOOKS
151
151
  end
152
152
  end
153
153
  end
data/lib/soaspec/wait.rb CHANGED
@@ -38,4 +38,4 @@ module Soaspec
38
38
  raise Soaspec::TimeOutError, msg
39
39
  end
40
40
  end
41
- end
41
+ end
@@ -1,14 +1,15 @@
1
-
2
1
  module Soaspec
3
2
  module WsdlGenerator
4
3
  # Attempt to calculate values of enumeration by looking up type in Schema
5
4
  def try_enum_for(type)
6
5
  raise "'@wsdl_schemas' must be defined" if @wsdl_schemas.nil?
6
+
7
7
  custom_type = @wsdl_schemas.xpath("//*[@name='#{type}']")
8
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?
12
+
12
13
  @enums_values = []
13
14
  enumerations.each { |enum_value| @enums_values << "'#{enum_value['value']}'" }
14
15
  "~randomize [#{@enums_values.join(', ')}]"
@@ -21,6 +22,7 @@ module Soaspec
21
22
  # @return [Boolean] Whether WSDL type is an enumeration
22
23
  def enumeration?(type)
23
24
  return false unless type.first
25
+
24
26
  !type.xpath("*/#{type.first.namespace.prefix}:enumeration").empty?
25
27
  end
26
28
 
@@ -62,14 +64,17 @@ module Soaspec
62
64
  # @return [Nokogiri::XML::NodeSet] List of the root elements in the SOAP body
63
65
  def root_elements_for(op_details)
64
66
  raise "'@wsdl_schemas' must be defined" if @wsdl_schemas.nil?
67
+
65
68
  root_element = @wsdl_schemas.at_xpath("//*[@name='#{op_details[:input]}']")
66
69
  raise 'Operation has no input defined' if root_element.nil?
70
+
67
71
  schema_namespace = root_element.namespace.prefix
68
72
  root_type = root_element['type']
69
73
  if root_type
70
74
  @wsdl_schemas.xpath("//*[@name='#{root_type.split(':').last}']//#{schema_namespace}:element")
71
75
  else
72
76
  return [] unless complex_type? root_element # Empty Array if there are no root elements
77
+
73
78
  complex_type = root_element.children.find { |c| c.name == 'complexType' }
74
79
  sequence = complex_type.children.find { |c| c.name == 'sequence' }
75
80
  sequence.xpath("#{schema_namespace}:element")
@@ -80,6 +85,7 @@ module Soaspec
80
85
  def document_type_for(element, depth = 1)
81
86
  # raise "Too far deep for #{element}" unless depth < 6
82
87
  return unless depth < 6
88
+
83
89
  if complex_type? element
84
90
  complex_type = element.children.find { |c| c.name == 'complexType' }
85
91
  sequence = complex_type.children.find { |c| c.name == 'sequence' }
@@ -88,9 +94,10 @@ module Soaspec
88
94
  end
89
95
  else
90
96
  return "No type seen for #{element}, #{element.class}" unless element['type']
97
+
91
98
  name = element['name']
92
99
  type = value_after_namespace(element['type'])
93
- @use_camel_case = true if (/[[:upper:]]/.match(name[0]) != nil)
100
+ @use_camel_case = true unless /[[:upper:]]/.match(name[0]).nil?
94
101
  spaces = ' ' * depth
95
102
  @content += "#{spaces}#{name.snakecase}: #{fill_in_field_from_type(type)} # #{type} \n"
96
103
  end
@@ -100,6 +107,7 @@ module Soaspec
100
107
  # @param [Nokogiri::XML::NodeSet] list List
101
108
  def wsdl_to_yaml_for(list)
102
109
  raise "'@content' string must be set" if @content.nil?
110
+
103
111
  list.each do |element|
104
112
  document_type_for element
105
113
  end
@@ -142,4 +150,4 @@ User Password:
142
150
  puts
143
151
  end
144
152
  end
145
- end
153
+ end
data/soaspec.gemspec CHANGED
@@ -21,16 +21,19 @@ the same configuration. Examples designed for RSpec and Cucumber."
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ['lib']
23
23
 
24
- spec.add_development_dependency 'bundler', '~> 1.16'
24
+ spec.add_development_dependency 'bundler'
25
25
  spec.add_development_dependency 'cucumber'
26
26
  spec.add_development_dependency 'data_magic'
27
27
  spec.add_development_dependency 'factory_bot'
28
+ spec.add_development_dependency 'rack'
29
+ spec.add_development_dependency 'rack-test'
28
30
  spec.add_development_dependency 'rake', '~> 12.0'
29
31
  spec.add_development_dependency 'require_all', '1.5.0'
30
32
  spec.add_development_dependency 'rspec', '~> 3.0'
31
33
  spec.add_development_dependency 'simplecov'
32
34
  spec.add_development_dependency 'yard-cucumber'
33
35
  spec.add_dependency 'activesupport'
36
+ spec.add_dependency 'colorize'
34
37
  spec.add_dependency 'faker'
35
38
  spec.add_dependency 'hashie'
36
39
  spec.add_dependency 'jsonpath'
@@ -39,7 +42,9 @@ the same configuration. Examples designed for RSpec and Cucumber."
39
42
  spec.add_dependency 'rspec', '~> 3.0' # This framework is designed to work with RSpec
40
43
  spec.add_dependency 'rspec-its'
41
44
  spec.add_dependency 'savon', '>= 2' # SOAP
42
- spec.add_dependency 'sinatra'
45
+ # https://github.com/sinatra/sinatra/issues/1514 in 2.0.5 version of Sinatra breaks '?wsdl' a param with no
46
+ # Only affects Ruby < 2.4
47
+ spec.add_dependency 'sinatra', '2.0.4'
43
48
  spec.add_dependency 'sinatra-basic-auth'
44
49
  spec.add_dependency 'sinatra-docdsl'
45
50
  spec.add_dependency 'thor'
data/test_wsdl.rb CHANGED
@@ -1,15 +1,12 @@
1
-
2
1
  require 'wasabi'
3
2
  require 'savon'
4
3
 
5
-
6
- #document = Savon.client(wsdl: 'test.wsdl').wsdl
7
- #document = Savon.client(wsdl: 'http://www.webservicex.com/globalweather.asmx?wsdl').wsdl
8
- #document = Wasabi.document File.read('test.wsdl')
4
+ # document = Savon.client(wsdl: 'test.wsdl').wsdl
5
+ # document = Savon.client(wsdl: 'http://www.webservicex.com/globalweather.asmx?wsdl').wsdl
6
+ # document = Wasabi.document File.read('test.wsdl')
9
7
  document = Wasabi.document 'http://www.webservicex.net/ConvertTemperature.asmx?WSDL'
10
8
  parser = document.parser
11
9
 
12
-
13
10
  # TEST SCHEMA
14
11
  #
15
12
  # parser.schemas.each do |schema|
@@ -41,4 +38,4 @@ if custom_type.first
41
38
  enumerations.each do |enum_value|
42
39
  puts enum_value['value']
43
40
  end
44
- end
41
+ end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: soaspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - SamuelGarrattIQA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-03 00:00:00.000000000 Z
11
+ date: 2019-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.16'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: cucumber
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rack-test
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: rake
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +178,20 @@ dependencies:
150
178
  - - ">="
151
179
  - !ruby/object:Gem::Version
152
180
  version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: colorize
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
153
195
  - !ruby/object:Gem::Dependency
154
196
  name: faker
155
197
  requirement: !ruby/object:Gem::Requirement
@@ -266,16 +308,16 @@ dependencies:
266
308
  name: sinatra
267
309
  requirement: !ruby/object:Gem::Requirement
268
310
  requirements:
269
- - - ">="
311
+ - - '='
270
312
  - !ruby/object:Gem::Version
271
- version: '0'
313
+ version: 2.0.4
272
314
  type: :runtime
273
315
  prerelease: false
274
316
  version_requirements: !ruby/object:Gem::Requirement
275
317
  requirements:
276
- - - ">="
318
+ - - '='
277
319
  - !ruby/object:Gem::Version
278
- version: '0'
320
+ version: 2.0.4
279
321
  - !ruby/object:Gem::Dependency
280
322
  name: sinatra-basic-auth
281
323
  requirement: !ruby/object:Gem::Requirement
@@ -356,12 +398,14 @@ files:
356
398
  - Todo.md
357
399
  - exe/soaspec
358
400
  - exe/xml_to_yaml_file
401
+ - images/basic_demo.gif
359
402
  - lib/soaspec.rb
360
403
  - lib/soaspec/core_ext/hash.rb
361
404
  - lib/soaspec/cucumber/generic_steps.rb
362
405
  - lib/soaspec/exchange.rb
363
406
  - lib/soaspec/exchange_handlers/exchange_handler.rb
364
407
  - lib/soaspec/exchange_handlers/handler_accessors.rb
408
+ - lib/soaspec/exchange_handlers/response_extractor.rb
365
409
  - lib/soaspec/exchange_handlers/rest_exchanger_factory.rb
366
410
  - lib/soaspec/exchange_handlers/rest_handler.rb
367
411
  - lib/soaspec/exchange_handlers/rest_methods.rb