soaspec 0.2.11 → 0.2.12

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: 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