soaspec 0.2.11 → 0.2.12

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f4316417650edcdef9d66fb391ff90736a400dc2
4
- data.tar.gz: 163b3ca2c9a547915693d33a7e7147dbc079cea6
3
+ metadata.gz: 70554212f6b7e667767a9d38f2c3b9c2f0bfec96
4
+ data.tar.gz: 3eaae9121a99e8b9a48b4f25ecb5a17178158e7c
5
5
  SHA512:
6
- metadata.gz: 2a58886e537a7e063f4977a184cac67d32ffe4827d4331315475d780450d0025bf86a000978457a0d5b52f1361e54496d1661f70904f6aa84f9ada7a8d300f12
7
- data.tar.gz: 41c07147d1db749aab3b3c4dfbfa638b46e46297ddbdc39c9f8eef0eb27bc9ad47dc347920c960fa1069236641aa2acd58d4619c6f46f0d775783b933b8dcbfb
6
+ metadata.gz: 6c7f0b3de2c2c31778410004db25705e3a561617be0e227be1c913e7b22e741b471fea0ce5ce2e575ea8f134dc39db5e28f9bbc61d7a0ccb17bace96e94a7500
7
+ data.tar.gz: 5deb9f12a6b63ec3e0077ca84c79ff625ee90e0cd86a7fadc60924ea0b3e98b8b85fd6274304ac2b54c930c960ec229dc9c3dbd0c2595de17a3fecea62541535
data/ChangeLog CHANGED
@@ -1,3 +1,7 @@
1
+ Version 0.2.12
2
+ * Enhancements
3
+ * Make it easier to set 'traffic_file' location with `Soaspec::SpecLogger.traffic_file = ''`
4
+
1
5
  Version 0.2.11
2
6
  * Bug Fix
3
7
  * Cache 'Soaspec::OAuth2.instance_url' so Access token server not called everytime it's needed
data/README.md CHANGED
@@ -175,6 +175,15 @@ expect(@exchange['message']).to include 'success'
175
175
  expect(@exchange.status_code).to eq 200
176
176
  ```
177
177
 
178
+ ## Logging
179
+
180
+ By default traffic is logged to a file in the `logs` folder called `traffic_DATETIME.log`.
181
+
182
+ The `SpecLogger` class is responsible for handling all the logs.
183
+
184
+ To change the output file location to 'custom.log':
185
+ `Soaspec::SpecLogger.traffic_file = 'custom.log'`
186
+
178
187
  ## Development
179
188
 
180
189
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/Rakefile CHANGED
@@ -28,3 +28,11 @@ end
28
28
  YARD::Rake::YardocTask.new do |t|
29
29
  t.files = %w[features/**/*.feature features/**/*.rb lib/soaspec/cucumber/*.rb] # lib/soaspec/cucumber/*.rb]
30
30
  end
31
+
32
+ desc 'Ensure system has all docs'
33
+ task :must_have_docs do
34
+ yard = `yard`
35
+ puts yard
36
+ percentage = yard.lines.last.strip.split('%').first.to_f
37
+ raise 'Must be fully documented' unless percentage == 100.00
38
+ end
data/Todo.md CHANGED
@@ -1,6 +1,8 @@
1
- * Get initial `soaspec new` working with TODOs as placeholders for how to get started
1
+ * `yard` should show everything documented
2
+ * Rubocop should have 0 offenses
2
3
  * Unit tests
3
4
  * OAuth class, etc
5
+ * Get initial `soaspec new` working with TODOs as placeholders for how to get started
4
6
  * Request method from within exchange
5
7
  * Use this in tests
6
8
  * Basic service generator
@@ -1,6 +1,7 @@
1
- # Override Hash class with convience methods
1
+ # Override Hash class with convenience methods
2
2
  class Hash
3
3
  # Transform each key in Hash to a symbol. Privately used by non-self method
4
+ # @param [Object] value Value inside hash to transform keys under
4
5
  def self.transform_keys_to_symbols(value)
5
6
  return value unless value.is_a?(Hash)
6
7
 
@@ -13,28 +14,8 @@ class Hash
13
14
  each_with_object({}) { |(k, v), memo| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); }
14
15
  end
15
16
 
16
- # Returns all keys that have a particular value within a nested Hash
17
- def find_all_values_for(key)
18
- result = []
19
- result << self[key]
20
- values.each do |hash_value|
21
- # next if hash_value.is_a? Array
22
- #
23
- if hash_value.is_a?(Array)
24
- hash_value.each do |array_element|
25
- result += array_element.find_all_values_for(key) if array_element.is_a? Hash
26
- end
27
- end
28
-
29
- values = [hash_value]
30
- values.each do |value|
31
- result += value.find_all_values_for(key) if value.is_a? Hash
32
- end
33
- end
34
- result.compact
35
- end
36
-
37
17
  # Value present in nested Hash.
18
+ # @return [Boolean] Whether value is included in nested Hash
38
19
  def include_value?(value)
39
20
  each_value do |v|
40
21
  return true if v == value
@@ -51,31 +32,4 @@ class Hash
51
32
  end
52
33
  false
53
34
  end
54
-
55
- # # Whether key is present at least once
56
- # def include_key?(key)
57
- # result = find_all_values_for key
58
- # result != []
59
- # end
60
-
61
- # Loop through each item within a key within a Hash if the key exists
62
- # @param [Key] key Key within hash to iterate through
63
- def each_if_not_null(key)
64
- case key.class.to_s
65
- when 'String'
66
- if self[key]
67
- self[key].each do |list_item|
68
- yield(list_item)
69
- end
70
- end
71
- when 'Array', 'Hash'
72
- if self[key[0]]
73
- if self[key[0]][key[1]]
74
- self[key[0]][key[1]].each do |list_item|
75
- yield(list_item)
76
- end
77
- end
78
- end
79
- end
80
- end
81
35
  end
@@ -43,6 +43,8 @@ class Exchange
43
43
  nil
44
44
  end
45
45
 
46
+ # Create new Exchange according to parameters set. A response will be made if called
47
+ # explicitly with 'response' method or through other methods that use it like 'status_code'
46
48
  # @param [Symbol, String] name Name shown in RSpec run
47
49
  # @param [Hash] override_parameters Parameters to override for default params
48
50
  def initialize(name = self.class.to_s, override_parameters = {})
@@ -17,6 +17,7 @@ module Soaspec
17
17
  end
18
18
 
19
19
  # Set retry_for_success to true, retrying response until a successful status code is returned
20
+ # @param [Integer] retry_count Times to retry to get a positive response
20
21
  def expect_positive_status(retry_count: 3)
21
22
  define_method('retry_count') do
22
23
  retry_count
@@ -16,6 +16,12 @@ module Soaspec
16
16
  # Set a parameter request in the request body.
17
17
  # Can be used to build a request over several steps (e.g Cucumber)
18
18
  # Will be used with FactoryBot
19
+ #
20
+ # @example
21
+ # exchange['name'] = 'tester'
22
+ # # Will set { name: tester } in the response, formatting as JSON or XML depending on REST / SOAP
23
+ # @param [String, Symbol] key Name of request element to set
24
+ # @param [String] value Value to set request element to
19
25
  def []=(key, value)
20
26
  @override_parameters[:body] ||= {}
21
27
  @override_parameters[:body][key] = value
@@ -24,7 +30,7 @@ module Soaspec
24
30
  # Implement undefined setter with []= for FactoryBot to use without needing to define params to set
25
31
  # @param [Object] method_name Name of method not defined
26
32
  # @param [Object] args Arguments passed to method
27
- # @param [Object] block
33
+ # @param [Object] block Block passed to method
28
34
  def method_missing(method_name, *args, &block)
29
35
  set_value = args.first
30
36
  if method_name[-1] == '=' # A setter method
@@ -41,13 +47,15 @@ module Soaspec
41
47
  end
42
48
 
43
49
  # Used for setters that are not defined
50
+ # @param [String] method_name Name of method
51
+ # @param [Array] args List of arguments to method
44
52
  def respond_to_missing?(method_name, *args)
45
53
  method_name[-1] == '=' || super
46
54
  end
47
55
 
48
56
  # Makes request, caching the response and returning self
49
57
  # Used by FactoryBot
50
- # @return [Self]
58
+ # @return [Self] Return itself so methods can be called on itself afterwards
51
59
  def save!
52
60
  @retry_for_success = @fail_factory ? false : true
53
61
  call
@@ -16,7 +16,7 @@ module Soaspec
16
16
 
17
17
  # Set instance variable name
18
18
  # @param [String, Symbol] name Name used when describing API test
19
- # @param [Hash] options Parameters defining handler. Used in descendants
19
+ # @param [Hash] _options Parameters defining handler. Used in descendants
20
20
  def initialize(name = self.class.to_s, _options = {})
21
21
  use
22
22
  @request_option = :hash
@@ -86,9 +86,7 @@ module Soaspec
86
86
  # @param [Symbol] name Name of method to use to access this value within handler
87
87
  # @param [String] value Value to store
88
88
  def store(name, value)
89
- define_singleton_method('__stored_val__' + name.to_s) do
90
- value
91
- end
89
+ define_singleton_method('__stored_val__' + name.to_s) { value }
92
90
  end
93
91
 
94
92
  # Set instance variable for each key in hash remove it from Hash
@@ -99,6 +97,8 @@ module Soaspec
99
97
  end
100
98
 
101
99
  # Set instance variable and remove it from Hash
100
+ # @param [Hash] hash Hash to remove/retrieve keys from
101
+ # @param [String,Symbol] key Key to remove and to set instance variable for
102
102
  def set_remove_key(hash, key)
103
103
  return unless hash.key? key
104
104
 
@@ -112,6 +112,7 @@ module Soaspec
112
112
  end
113
113
 
114
114
  # Request of API call. Either intended request or actual request
115
+ # @param [Object] response Response from calling exchange
115
116
  def request(response)
116
117
  return "Request not yet sent Request option is #{@request_option}" unless response
117
118
 
@@ -31,11 +31,13 @@ module Soaspec
31
31
  # @example Inside class
32
32
  # mandatory_xpath_values '//xmlns:GetWeatherResult' => 'Data Not Found'
33
33
  #
34
- # In test
35
- # describe Exchange(:name) do
36
- # it_behaves_like 'success scenario' # Includes xpath pair validation
37
- # end
34
+ # @example In test
35
+ # describe Exchange(:name) do
36
+ # it_behaves_like 'success scenario' # Includes xpath pair validation
37
+ # end
38
38
  #
39
+ # @param [Hash] xpath_value_pairs Hash of element => expected value that must appear
40
+ # in a successful response body
39
41
  def mandatory_xpath_values(xpath_value_pairs)
40
42
  raise ArgumentError('Hash of {xpath => expected values} expected ') unless xpath_value_pairs.is_a? Hash
41
43
 
@@ -47,11 +49,13 @@ module Soaspec
47
49
  # @example Inside class
48
50
  # mandatory_json_values '$..GetWeatherResult' => 'Found'
49
51
  #
50
- # In test
51
- # describe Exchange(:name) do
52
- # it_behaves_like 'success scenario' # Includes json pair validation
53
- # end
52
+ # @example In test
53
+ # describe Exchange(:name) do
54
+ # it_behaves_like 'success scenario' # Includes json pair validation
55
+ # end
54
56
  #
57
+ # @param [Hash] json_value_pairs Hash of element => expected value that must appear
58
+ # in a successful response body
55
59
  def mandatory_json_values(json_value_pairs)
56
60
  raise ArgumentError("Hash of {'jsonpath' => expected values} expected") unless json_value_pairs.is_a? Hash
57
61
 
@@ -84,6 +88,7 @@ module Soaspec
84
88
 
85
89
  # All xpath will be done with XML that is converted to lower case
86
90
  # You must then use lower case in the xpath's to obtain the desired values
91
+ # @param [Boolean] set Whether to convert all xml in response to lower case before performing XPath
87
92
  def convert_to_lower(set)
88
93
  return unless set
89
94
 
@@ -94,6 +99,7 @@ module Soaspec
94
99
  # For why this may not be a good thing in general see
95
100
  # http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html
96
101
  # This will be overridden if xpath has a ':' in it
102
+ # @param [Boolean] set Whether to strip namespaces form XML response
97
103
  def strip_namespaces(set)
98
104
  return unless set
99
105
 
@@ -20,6 +20,7 @@ module Soaspec
20
20
  end
21
21
  end
22
22
 
23
+ # @param [Object] response Response object
23
24
  # @return [Hash] Hash representing response body
24
25
  def to_hash(response)
25
26
  case Interpreter.response_type_for(response)
@@ -145,7 +145,7 @@ module Soaspec
145
145
  end
146
146
 
147
147
  # Convert all XML nodes to lowercase
148
- # @param [Nokogiri::XML::Document]
148
+ # @param [Nokogiri::XML::Document] xml_doc Xml document to convert
149
149
  def convert_to_lower_case(xml_doc)
150
150
  xml_doc.traverse do |node|
151
151
  node.name = node.name.downcase if node.is_a?(Nokogiri::XML::Element)
@@ -48,7 +48,6 @@ module Soaspec
48
48
  params[:security_token] = ERB.new(params[:security_token]).result(binding) if params[:security_token]
49
49
  params[:token_url] = ERB.new(params[:token_url]).result(binding) if params[:token_url]
50
50
  params[:password] = ERB.new(params[:password]).result(binding) if params[:password]
51
- Soaspec::SpecLogger.info request_message
52
51
  end
53
52
 
54
53
  # Retrieve instance_url according to access token response.
@@ -61,6 +60,7 @@ module Soaspec
61
60
 
62
61
  # @return [String] Existing or new access token, dependent on refresh_token attribute
63
62
  def access_token
63
+ Soaspec::SpecLogger.info request_message
64
64
  case Soaspec::OAuth2.refresh_token
65
65
  when :once
66
66
  Soaspec::OAuth2.access_tokens[params] ||= response['access_token']
@@ -23,12 +23,15 @@ module Soaspec
23
23
  @output_to_file = true
24
24
  # Time test run. Will only be calculated once once called
25
25
  @time_test_run = Time.now.strftime('%Y-%m-%d_%H_%M_%S')
26
-
26
+ # By default file is based on time
27
+ @traffic_file = nil
27
28
  class << self
28
29
  # Folder to put API traffic logs
29
30
  attr_accessor :traffic_folder
30
31
  # Readers for log parameters
31
32
  attr_reader :output_to_terminal, :output_to_file, :time_test_run
33
+ # Set file to log traffic to
34
+ attr_writer :traffic_file
32
35
 
33
36
  # Whether to log all API traffic
34
37
  def log_api_traffic=(set)
@@ -55,6 +58,8 @@ module Soaspec
55
58
 
56
59
  # @return [String] Traffic file to create logs at
57
60
  def traffic_file
61
+ return File.join(traffic_folder, @traffic_file) if @traffic_file
62
+
58
63
  filename = "traffic_#{time_test_run}.log"
59
64
  File.join(traffic_folder, filename)
60
65
  end
@@ -1,3 +1,3 @@
1
1
  module Soaspec
2
- VERSION = '0.2.11'.freeze
2
+ VERSION = '0.2.12'.freeze
3
3
  end
@@ -1,6 +1,8 @@
1
1
  module Soaspec
2
+ # Produce test content from a WSDL
2
3
  module WsdlGenerator
3
4
  # Attempt to calculate values of enumeration by looking up type in Schema
5
+ # @param [String] type Try out filling enumeration for type. Return Custom Type if can't be done
4
6
  def try_enum_for(type)
5
7
  raise "'@wsdl_schemas' must be defined" if @wsdl_schemas.nil?
6
8
 
@@ -28,34 +30,33 @@ module Soaspec
28
30
 
29
31
  # Return value of string after a namespace
30
32
  # @param [String] string String to parse for part after namespace
33
+ # @return [String] Part after the namespace, demonstrated by ':'
31
34
  def value_after_namespace(string)
32
35
  string.split(':').last
33
36
  end
34
37
 
35
38
  # Based on WSDL type return a valid value
36
39
  # @param [String] type Type without the WSDL
40
+ # @return [Object] Value representing type to fill in
37
41
  def fill_in_field_from_type(type)
38
42
  case type
39
- when 'string'
40
- options[:string_default] # 'test string'
41
- when 'int'
42
- 2
43
- when 'boolean'
44
- true
45
- when 'double'
46
- '1.5'
43
+ when 'string' then options[:string_default] # 'test string'
44
+ when 'int' then 2
45
+ when 'boolean' then true
46
+ when 'double' then '1.5'
47
47
  else
48
48
  try_enum_for type
49
49
  end
50
50
  end
51
51
 
52
52
  # @param [Nokogiri::XML::Element]
53
- # @return [Boolean] True if nokogori element is a complex type, that is, has a complexType element underneath itself
53
+ # @return [Boolean] True if Nokogiri element is a complex type, that is, has a complexType element underneath itself
54
54
  def complex_type?(element)
55
55
  element.children.any? { |child| child.name == 'complexType' }
56
56
  end
57
57
 
58
58
  # @param [String, Symbol] underscore_separated Snakecase value to be converted to camel case
59
+ # @return [String] CamelCased value
59
60
  def camel_case(underscore_separated)
60
61
  underscore_separated.to_s.split('_').collect(&:capitalize).join
61
62
  end
@@ -81,7 +82,9 @@ module Soaspec
81
82
  end
82
83
  end
83
84
 
84
- # @param [Nokogiri::XML::Element]
85
+ # Adds documentation content for all children of XML element
86
+ # @param [Nokogiri::XML::Element] element Type to document for
87
+ # @param [Integer] depth How many times to iterate depth for
85
88
  def document_type_for(element, depth = 1)
86
89
  # raise "Too far deep for #{element}" unless depth < 6
87
90
  return unless depth < 6
@@ -104,20 +107,18 @@ module Soaspec
104
107
  end
105
108
 
106
109
  # Makes a yaml string in a '@content' instance variable
107
- # @param [Nokogiri::XML::NodeSet] list List
110
+ # @param [Nokogiri::XML::NodeSet] list List to convert to YAML
108
111
  def wsdl_to_yaml_for(list)
109
112
  raise "'@content' string must be set" if @content.nil?
110
113
 
111
- list.each do |element|
112
- document_type_for element
113
- end
114
+ list.each { |element| document_type_for element }
114
115
  end
115
116
 
116
117
  # Prompt user for wsdl
117
118
  def ask_wsdl
118
- prompt = <<-EOF
119
- Enter WSDL:
120
- EOF
119
+ prompt = <<-WSDL_LOC
120
+ Enter WSDL:
121
+ WSDL_LOC
121
122
  print prompt.chop
122
123
  @wsdl = $stdin.gets.strip
123
124
  puts
@@ -125,9 +126,9 @@ Enter WSDL:
125
126
 
126
127
  # Prompt user for Service name for wsdl
127
128
  def name_of_wsdl
128
- prompt = <<-EOF
129
- Enter what you would like to name WSDL (CamelCase):
130
- EOF
129
+ prompt = <<-WSDL_NAME
130
+ Enter what you would like to name WSDL (CamelCase):
131
+ WSDL_NAME
131
132
  print prompt.chop
132
133
  @name = $stdin.gets.strip
133
134
  puts
@@ -135,16 +136,16 @@ Enter what you would like to name WSDL (CamelCase):
135
136
 
136
137
  # Prompt user to enter basic auth details
137
138
  def enter_auth_details
138
- prompt = <<-EOF
139
- User Name:
140
- EOF
139
+ prompt = <<-AUTH_PROMPT
140
+ User Name:
141
+ AUTH_PROMPT
141
142
  print prompt.chop
142
143
  @auth_name = $stdin.gets.strip
143
144
  puts
144
145
 
145
- prompt = <<-EOF
146
- User Password:
147
- EOF
146
+ prompt = <<-PASSWORD
147
+ User Password:
148
+ PASSWORD
148
149
  print prompt.chop
149
150
  @auth_password = $stdin.gets.strip
150
151
  puts
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.2.11
4
+ version: 0.2.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - SamuelGarrattIQA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-06 00:00:00.000000000 Z
11
+ date: 2019-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler