soaspec 0.0.19 → 0.0.20
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 +4 -4
- data/.gitignore +13 -13
- data/.rspec +3 -3
- data/.travis.yml +5 -5
- data/CODE_OF_CONDUCT.md +74 -74
- data/ChangeLog +61 -55
- data/Gemfile +16 -16
- data/Gemfile.lock +115 -115
- data/LICENSE.txt +21 -21
- data/README.md +85 -66
- data/Rakefile +20 -20
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/config/data/default.yml +2 -2
- data/exe/soaspec-init +254 -252
- data/exe/xml_to_yaml_file +63 -63
- data/lib/soaspec.rb +61 -48
- data/lib/soaspec/basic_soap_handler.rb +132 -122
- data/lib/soaspec/exchange.rb +56 -56
- data/lib/soaspec/hash_methods.rb +71 -71
- data/lib/soaspec/matchers.rb +40 -39
- data/lib/soaspec/soaspec_shared_examples.rb +18 -18
- data/lib/soaspec/spec_logger.rb +17 -17
- data/lib/soaspec/tester.rb +30 -30
- data/lib/soaspec/version.rb +3 -3
- data/lib/soaspec/xpath_not_found.rb +7 -0
- data/soaspec.gemspec +34 -34
- data/template/soap_template.xml +9 -9
- metadata +4 -3
data/LICENSE.txt
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
The MIT License (MIT)
|
2
|
-
|
3
|
-
Copyright (c) 2018 Samuel Garratt
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in
|
13
|
-
all copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
THE SOFTWARE.
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Samuel Garratt
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,66 +1,85 @@
|
|
1
|
-
# Soaspec
|
2
|
-
|
3
|
-
This gem helps to represent multiple API tests against a backend briefly, concisely and clearly. It is essentially a wrapper around the Savon and RestClient gems. Note it is still in early stages of development.
|
4
|
-
|
5
|
-
|
6
|
-
## Installation
|
7
|
-
|
8
|
-
Add this line to your application's Gemfile:
|
9
|
-
|
10
|
-
```ruby
|
11
|
-
gem 'soaspec'
|
12
|
-
```
|
13
|
-
|
14
|
-
And then execute:
|
15
|
-
|
16
|
-
$ bundle
|
17
|
-
|
18
|
-
Or install it yourself as:
|
19
|
-
|
20
|
-
$ gem install soaspec
|
21
|
-
|
22
|
-
## Todo
|
23
|
-
|
24
|
-
Handle REST
|
25
|
-
Give examples and convenience methods for building classes for each SOAP or REST operation
|
26
|
-
Potentially have in built use of 'vcr' and 'http_stub' gems
|
27
|
-
|
28
|
-
##
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
1
|
+
# Soaspec
|
2
|
+
|
3
|
+
This gem helps to represent multiple API tests against a backend briefly, concisely and clearly. It is essentially a wrapper around the Savon and RestClient gems. Note it is still in early stages of development.
|
4
|
+
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'soaspec'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install soaspec
|
21
|
+
|
22
|
+
## Todo
|
23
|
+
|
24
|
+
Handle REST
|
25
|
+
Give examples and convenience methods for building classes for each SOAP or REST operation
|
26
|
+
Potentially have in built use of 'vcr' and 'http_stub' gems
|
27
|
+
|
28
|
+
## Getting Started
|
29
|
+
|
30
|
+
To create a new test suite using this you can use the 'soaspec-init' binary.
|
31
|
+
|
32
|
+
Example:
|
33
|
+
|
34
|
+
```
|
35
|
+
mkdir 'api_test'
|
36
|
+
cd 'api_test'
|
37
|
+
soaspec-init
|
38
|
+
bundle install
|
39
|
+
```
|
40
|
+
|
41
|
+
Then you can run the tests with:
|
42
|
+
|
43
|
+
```
|
44
|
+
rake spec
|
45
|
+
```
|
46
|
+
|
47
|
+
## Usage
|
48
|
+
|
49
|
+
* SOAP - this uses Savon behind the scenes. Some defaults are overridden. Please see 'basic_soap_handler.rb'-'default_options' method
|
50
|
+
for such defaults. When describing an API override this in 'savon_options' method
|
51
|
+
|
52
|
+
See specs for example of usage. This will be added to later.
|
53
|
+
|
54
|
+
### Recommended
|
55
|
+
|
56
|
+
It is recommended that a class be created representing a Web Service Operation or REST call. Then tests refer back to
|
57
|
+
that class. See 'weather_web_service.rb' class in spec/soaspec/soap folder for example.
|
58
|
+
|
59
|
+
If you find having a large backtrace on errors or RSpec shared examples such as 'success scenarios' this can shorten the
|
60
|
+
backtrace.
|
61
|
+
|
62
|
+
RSpec.configure do |config|
|
63
|
+
|
64
|
+
config.backtrace_exclusion_patterns = [
|
65
|
+
/rspec/
|
66
|
+
]
|
67
|
+
end
|
68
|
+
|
69
|
+
## Development
|
70
|
+
|
71
|
+
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.
|
72
|
+
|
73
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
74
|
+
|
75
|
+
## Contributing
|
76
|
+
|
77
|
+
Bug reports and pull requests are welcome on GitLab at https://gitlab.com/samuel-garratt/soaspec. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
78
|
+
|
79
|
+
## License
|
80
|
+
|
81
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
82
|
+
|
83
|
+
## Code of Conduct
|
84
|
+
|
85
|
+
Everyone interacting in the Soaspec project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://gitlab.com/samuel-garratt/soaspec/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
|
-
require 'rspec/core/rake_task'
|
3
|
-
require 'rake/clean'
|
4
|
-
|
5
|
-
RSpec::Core::RakeTask.new(:run_spec) do |t|
|
6
|
-
t.pattern = "spec/*/*/*_spec.rb"
|
7
|
-
end
|
8
|
-
|
9
|
-
desc 'Prepare log files'
|
10
|
-
task :logs do
|
11
|
-
mkdir_p 'logs'
|
12
|
-
touch 'logs/traffic.log'
|
13
|
-
end
|
14
|
-
|
15
|
-
desc 'Run tests'
|
16
|
-
task :spec => %w[logs run_spec]
|
17
|
-
|
18
|
-
task :default => :spec
|
19
|
-
|
20
|
-
CLOBBER.include 'logs/*'
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rake/clean'
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new(:run_spec) do |t|
|
6
|
+
t.pattern = "spec/*/*/*_spec.rb"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc 'Prepare log files'
|
10
|
+
task :logs do
|
11
|
+
mkdir_p 'logs'
|
12
|
+
touch 'logs/traffic.log'
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Run tests'
|
16
|
+
task :spec => %w[logs run_spec]
|
17
|
+
|
18
|
+
task :default => :spec
|
19
|
+
|
20
|
+
CLOBBER.include 'logs/*'
|
data/bin/console
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "bundler/setup"
|
4
|
-
require "soaspec"
|
5
|
-
|
6
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start(__FILE__)
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "soaspec"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
set -euo pipefail
|
3
|
-
IFS=$'\n\t'
|
4
|
-
set -vx
|
5
|
-
|
6
|
-
bundle install
|
7
|
-
|
8
|
-
# Do any other automated setup that you need to do here
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
set -euo pipefail
|
3
|
+
IFS=$'\n\t'
|
4
|
+
set -vx
|
5
|
+
|
6
|
+
bundle install
|
7
|
+
|
8
|
+
# Do any other automated setup that you need to do here
|
data/config/data/default.yml
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
japan:
|
2
|
-
city_name: 'Tokyo'
|
1
|
+
japan:
|
2
|
+
city_name: 'Tokyo'
|
3
3
|
country_name: 'Japan'
|
data/exe/soaspec-init
CHANGED
@@ -1,252 +1,254 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'soaspec'
|
4
|
-
require 'fileutils'
|
5
|
-
|
6
|
-
def create_file(options)
|
7
|
-
filename = options[:filename]
|
8
|
-
raise 'Need to pass filename' unless filename
|
9
|
-
content = options[:content]
|
10
|
-
raise 'Need to pass contents to insert into file' unless content
|
11
|
-
if File.exist? filename
|
12
|
-
old_content = File.read(filename)
|
13
|
-
if old_content != content
|
14
|
-
warn "!! #{filename} already exists and differs from template"
|
15
|
-
end
|
16
|
-
else
|
17
|
-
File.open(filename, 'w') do |f|
|
18
|
-
f.puts content
|
19
|
-
end
|
20
|
-
puts 'Created: ' + filename
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def create_folder(folder)
|
25
|
-
if File.exists? folder
|
26
|
-
unless File.directory? folder
|
27
|
-
$stderr.puts "!! #{folder} already exists and is not a directory"
|
28
|
-
end
|
29
|
-
else
|
30
|
-
FileUtils.mkdir folder
|
31
|
-
puts "Created folder: #{folder}/"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
puts 'Creating files for soaspec'
|
36
|
-
|
37
|
-
gem_content = <<-EOF
|
38
|
-
|
39
|
-
source 'https://rubygems.org'
|
40
|
-
|
41
|
-
gem 'data_magic'
|
42
|
-
gem 'require_all'
|
43
|
-
gem 'rspec_junit_formatter'
|
44
|
-
gem 'rake'
|
45
|
-
gem 'soaspec'
|
46
|
-
|
47
|
-
EOF
|
48
|
-
|
49
|
-
rake_content = <<-EOF
|
50
|
-
# The list of task for a Rake file can be seen with `rake -T`
|
51
|
-
require 'rspec/core/rake_task' # See See https://relishapp.com/rspec/rspec-core/docs/command-line/rake-task for details
|
52
|
-
|
53
|
-
# This runs `rspec` command with the following options. Type `rake spec` to run this task
|
54
|
-
RSpec::Core::RakeTask.new(:spec) do |t, task_args|
|
55
|
-
t.pattern = "spec/*_spec.rb" # Run all specs in 'spec' folder ending in '_spec'
|
56
|
-
# Next line shows output on the screen, Junit xml report and an HTML report
|
57
|
-
t.rspec_opts = "--format documentation --format RspecJunitFormatter --out logs/spec.xml --format html --out logs/spec.html"
|
58
|
-
t.fail_on_error = false
|
59
|
-
end
|
60
|
-
|
61
|
-
task :default => :spec # This runs the 'spec' task by default when no task is mentioned. E.g., if only `rake` is typed
|
62
|
-
EOF
|
63
|
-
|
64
|
-
|
65
|
-
spec_helper_content = <<-EOF
|
66
|
-
|
67
|
-
require 'soaspec'
|
68
|
-
require 'require_all'
|
69
|
-
require_all 'lib'
|
70
|
-
require 'data_magic'
|
71
|
-
|
72
|
-
include DataMagic # Used as example of loading data smartly. Use 'data_for' method to load yml data
|
73
|
-
|
74
|
-
RSpec.configure do |config|
|
75
|
-
# This will make backtrace much shorter by removing many lines from rspec failure message
|
76
|
-
config.backtrace_exclusion_patterns = [
|
77
|
-
/rspec/
|
78
|
-
]
|
79
|
-
end
|
80
|
-
|
81
|
-
EOF
|
82
|
-
|
83
|
-
weather_web_service = <<-EOF
|
84
|
-
|
85
|
-
require 'soaspec'
|
86
|
-
|
87
|
-
# This class is not part of the gem. It's an example of a class you can make
|
88
|
-
# to describe your APIs. Usually this would exist in the 'lib' directory
|
89
|
-
# Common configuration for the Savon client should go here
|
90
|
-
class WeatherWebService < Soaspec::BasicSoapHandler
|
91
|
-
# Add to or override default Savon client options
|
92
|
-
def savon_options
|
93
|
-
{
|
94
|
-
wsdl: 'http://www.webservicex.com/globalweather.asmx?wsdl',
|
95
|
-
convert_request_keys_to: :camelcase
|
96
|
-
}
|
97
|
-
end
|
98
|
-
|
99
|
-
# Specifying that get_weather_result must be present in the SOAP response
|
100
|
-
def mandatory_elements
|
101
|
-
[:get_weather_result]
|
102
|
-
end
|
103
|
-
|
104
|
-
# Example of xpath value that must be true for all success scenarios
|
105
|
-
def mandatory_xpath_values
|
106
|
-
{
|
107
|
-
'//xmlns:GetWeatherResult' => 'Data Not Found'
|
108
|
-
}
|
109
|
-
end
|
110
|
-
|
111
|
-
# Example of setting an attribute on the root XML element
|
112
|
-
def root_attributes
|
113
|
-
{
|
114
|
-
'Version' => '1'
|
115
|
-
}
|
116
|
-
end
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
EOF
|
121
|
-
|
122
|
-
soap_spec_content = <<-EOF
|
123
|
-
|
124
|
-
require 'spec_helper'
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
soap_example
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
it { is_expected.to
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
end
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
<!-- optional -->
|
185
|
-
<ns1:
|
186
|
-
|
187
|
-
|
188
|
-
</
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
create_file(filename: '
|
238
|
-
|
239
|
-
create_file(filename: '
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
create_folder '
|
245
|
-
create_file(filename: '
|
246
|
-
|
247
|
-
|
248
|
-
create_file(filename: '
|
249
|
-
create_folder '
|
250
|
-
|
251
|
-
|
252
|
-
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'soaspec'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
def create_file(options)
|
7
|
+
filename = options[:filename]
|
8
|
+
raise 'Need to pass filename' unless filename
|
9
|
+
content = options[:content]
|
10
|
+
raise 'Need to pass contents to insert into file' unless content
|
11
|
+
if File.exist? filename
|
12
|
+
old_content = File.read(filename)
|
13
|
+
if old_content != content
|
14
|
+
warn "!! #{filename} already exists and differs from template"
|
15
|
+
end
|
16
|
+
else
|
17
|
+
File.open(filename, 'w') do |f|
|
18
|
+
f.puts content
|
19
|
+
end
|
20
|
+
puts 'Created: ' + filename
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_folder(folder)
|
25
|
+
if File.exists? folder
|
26
|
+
unless File.directory? folder
|
27
|
+
$stderr.puts "!! #{folder} already exists and is not a directory"
|
28
|
+
end
|
29
|
+
else
|
30
|
+
FileUtils.mkdir folder
|
31
|
+
puts "Created folder: #{folder}/"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
puts 'Creating files for soaspec'
|
36
|
+
|
37
|
+
gem_content = <<-EOF
|
38
|
+
|
39
|
+
source 'https://rubygems.org'
|
40
|
+
|
41
|
+
gem 'data_magic'
|
42
|
+
gem 'require_all'
|
43
|
+
gem 'rspec_junit_formatter'
|
44
|
+
gem 'rake'
|
45
|
+
gem 'soaspec'
|
46
|
+
|
47
|
+
EOF
|
48
|
+
|
49
|
+
rake_content = <<-EOF
|
50
|
+
# The list of task for a Rake file can be seen with `rake -T`
|
51
|
+
require 'rspec/core/rake_task' # See See https://relishapp.com/rspec/rspec-core/docs/command-line/rake-task for details
|
52
|
+
|
53
|
+
# This runs `rspec` command with the following options. Type `rake spec` to run this task
|
54
|
+
RSpec::Core::RakeTask.new(:spec) do |t, task_args|
|
55
|
+
t.pattern = "spec/*_spec.rb" # Run all specs in 'spec' folder ending in '_spec'
|
56
|
+
# Next line shows output on the screen, Junit xml report and an HTML report
|
57
|
+
t.rspec_opts = "--format documentation --format RspecJunitFormatter --out logs/spec.xml --format html --out logs/spec.html"
|
58
|
+
t.fail_on_error = false
|
59
|
+
end
|
60
|
+
|
61
|
+
task :default => :spec # This runs the 'spec' task by default when no task is mentioned. E.g., if only `rake` is typed
|
62
|
+
EOF
|
63
|
+
|
64
|
+
|
65
|
+
spec_helper_content = <<-EOF
|
66
|
+
|
67
|
+
require 'soaspec'
|
68
|
+
require 'require_all'
|
69
|
+
require_all 'lib'
|
70
|
+
require 'data_magic'
|
71
|
+
|
72
|
+
include DataMagic # Used as example of loading data smartly. Use 'data_for' method to load yml data
|
73
|
+
|
74
|
+
RSpec.configure do |config|
|
75
|
+
# This will make backtrace much shorter by removing many lines from rspec failure message
|
76
|
+
config.backtrace_exclusion_patterns = [
|
77
|
+
/rspec/
|
78
|
+
]
|
79
|
+
end
|
80
|
+
|
81
|
+
EOF
|
82
|
+
|
83
|
+
weather_web_service = <<-EOF
|
84
|
+
|
85
|
+
require 'soaspec'
|
86
|
+
|
87
|
+
# This class is not part of the gem. It's an example of a class you can make
|
88
|
+
# to describe your APIs. Usually this would exist in the 'lib' directory
|
89
|
+
# Common configuration for the Savon client should go here
|
90
|
+
class WeatherWebService < Soaspec::BasicSoapHandler
|
91
|
+
# Add to or override default Savon client options
|
92
|
+
def savon_options
|
93
|
+
{
|
94
|
+
wsdl: 'http://www.webservicex.com/globalweather.asmx?wsdl',
|
95
|
+
convert_request_keys_to: :camelcase
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
# Specifying that get_weather_result must be present in the SOAP response
|
100
|
+
def mandatory_elements
|
101
|
+
[:get_weather_result]
|
102
|
+
end
|
103
|
+
|
104
|
+
# Example of xpath value that must be true for all success scenarios
|
105
|
+
def mandatory_xpath_values
|
106
|
+
{
|
107
|
+
'//xmlns:GetWeatherResult' => 'Data Not Found'
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
# Example of setting an attribute on the root XML element
|
112
|
+
def root_attributes
|
113
|
+
{
|
114
|
+
'Version' => '1'
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
EOF
|
121
|
+
|
122
|
+
soap_spec_content = <<-EOF
|
123
|
+
|
124
|
+
require 'spec_helper'
|
125
|
+
|
126
|
+
Soaspec::Environment.strip_namespaces = true # This allows namespace not to be used. Be careful with this
|
127
|
+
|
128
|
+
soap_example = WeatherWebService.new('Get Weather')
|
129
|
+
soap_example.operation = :get_weather
|
130
|
+
soap_example.default_hash = { city_name: 'Sydney', country_name: 'Australia' }
|
131
|
+
# soap_example.template_name = 'soap_template' # Use this if you'd rather use template file and comment out previous line
|
132
|
+
|
133
|
+
|
134
|
+
context soap_example do
|
135
|
+
describe Exchange.new(:default) do
|
136
|
+
it { is_expected.to contain_value 'Data Not Found' }
|
137
|
+
it_behaves_like 'success scenario'
|
138
|
+
end
|
139
|
+
|
140
|
+
describe Exchange.new(:china, city_name: 'Shanghai', country_name: 'China') do
|
141
|
+
it_behaves_like 'success scenario'
|
142
|
+
context 'handle xpath' do
|
143
|
+
its(['GetWeatherResult']) { is_expected.to eq 'Data Not Found' } # Don't need to use namespace
|
144
|
+
it { is_expected.to have_element_at_xpath '//xmlns:GetWeatherResult' }
|
145
|
+
it { is_expected.to have_xpath_value '//xmlns:GetWeatherResult' => 'Data Not Found' }
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe Exchange.new(:japan, data_for(:japan)) do
|
150
|
+
it_behaves_like 'success scenario'
|
151
|
+
its(['//xmlns:GetWeatherResult']) { is_expected.to eq 'Data Not Found' } # Can specify namespace if wanted
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
soap_example.default_hash = { city_name: 'Washington' }
|
157
|
+
context 'error scenarios' do
|
158
|
+
context soap_example do
|
159
|
+
describe Exchange.new(:error) do
|
160
|
+
it_behaves_like 'error scenario'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
EOF
|
167
|
+
|
168
|
+
shared_examples_content = <<-EOF
|
169
|
+
|
170
|
+
require 'rspec'
|
171
|
+
|
172
|
+
shared_examples_for 'error scenario' do
|
173
|
+
it 'does not have status code of 200' do
|
174
|
+
expect(described_class.status_code).not_to eq 200
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
EOF
|
179
|
+
|
180
|
+
soap_template_content = <<-EOF
|
181
|
+
<s12:Envelope xmlns:s12='http://www.w3.org/2003/05/soap-envelope'>
|
182
|
+
<s12:Body>
|
183
|
+
<ns1:GetWeather xmlns:ns1='http://www.webserviceX.NET'>
|
184
|
+
<!-- optional -->
|
185
|
+
<ns1:CityName><%= test_values[:city_name] || 'Wellington' %></ns1:CityName>
|
186
|
+
<!-- optional -->
|
187
|
+
<ns1:CountryName><%= test_values[:country] || 'New Zealand' %></ns1:CountryName>
|
188
|
+
</ns1:GetWeather>
|
189
|
+
</s12:Body>
|
190
|
+
</s12:Envelope>
|
191
|
+
EOF
|
192
|
+
|
193
|
+
default_yaml_content = <<-EOF
|
194
|
+
japan:
|
195
|
+
city_name: 'Tokyo'
|
196
|
+
country_name: 'Japan'
|
197
|
+
|
198
|
+
EOF
|
199
|
+
|
200
|
+
readme_content = <<-EOF
|
201
|
+
|
202
|
+
# Prerequisites
|
203
|
+
This creates files within an existing folder. It could add onto an existing project.
|
204
|
+
For a new project create a folder and be at it's location on the command line
|
205
|
+
|
206
|
+
```
|
207
|
+
mkdir soaspec_test
|
208
|
+
cd soaspec_test
|
209
|
+
```
|
210
|
+
|
211
|
+
Run `bundle install` to install the gems mentioned in the Gemfile.
|
212
|
+
|
213
|
+
To avoid conflict with gems on the machine globally it may be better to specify gem location with:
|
214
|
+
|
215
|
+
`bundle install --path ~/.gem`
|
216
|
+
|
217
|
+
# Running tests
|
218
|
+
On the command line type:
|
219
|
+
`bundle exec rake spec` or simply `bundle exec rake`
|
220
|
+
|
221
|
+
# Structure
|
222
|
+
|
223
|
+
## Tests
|
224
|
+
Tests are within the 'spec' folder and end in '_spec'. Setup and teardown for tests is in 'spec/spec_helper'
|
225
|
+
|
226
|
+
## Templates
|
227
|
+
These are the base requests with ERB inside them to create smartly changing requests accoring to the test.yml
|
228
|
+
|
229
|
+
## Libaries
|
230
|
+
Libaries to be installed are in 'Gemfile'. Specific gem versions can be specified here and enforeced with `bundle exec rake`
|
231
|
+
|
232
|
+
## Reports
|
233
|
+
Reports are shown in the 'logs' folder. By default Rake produces a junit, an html report, and a traffic.log file with the API request and responses in it
|
234
|
+
|
235
|
+
EOF
|
236
|
+
|
237
|
+
create_file(filename: 'Gemfile', content: gem_content)
|
238
|
+
create_file(filename: 'Rakefile', content: rake_content)
|
239
|
+
create_file(filename: 'README.md', content: readme_content)
|
240
|
+
create_folder 'lib'
|
241
|
+
create_file(filename: 'lib/weather_web_service.rb', content: weather_web_service)
|
242
|
+
create_file filename: 'lib/shared_example.rb', content: shared_examples_content
|
243
|
+
create_folder 'config'
|
244
|
+
create_folder 'config/data'
|
245
|
+
create_file(filename: 'config/data/default.yml', content: default_yaml_content)
|
246
|
+
create_folder 'spec'
|
247
|
+
create_file(filename: 'spec/spec_helper.rb', content: spec_helper_content)
|
248
|
+
create_file(filename: 'spec/soap_spec.rb', content: soap_spec_content)
|
249
|
+
create_folder 'template'
|
250
|
+
create_file(filename: 'template/soap_template.xml', content: soap_template_content)
|
251
|
+
create_folder 'logs'
|
252
|
+
|
253
|
+
puts "Run 'bundle install' to install necessary gems"
|
254
|
+
puts "Run 'rake spec' to run the tests"
|