soaspec 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
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