webspicy 0.20.14 → 0.20.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/webspicy/tester/fakesendgrid/email.rb +7 -0
- data/lib/webspicy/tester/fakeses/email.rb +10 -3
- data/lib/webspicy/tester/fakesmtp/email.rb +8 -0
- data/lib/webspicy/tester.rb +3 -4
- data/lib/webspicy/version.rb +1 -1
- data/lib/webspicy/web/inferer/config.ru +8 -0
- data/lib/webspicy/web/inferer.rb +95 -0
- data/lib/webspicy/web/openapi/generator.rb +24 -4
- data/spec/unit/tester/fakesendgrid/test_email.rb +5 -1
- data/spec/unit/tester/fakeses/test_email.rb +7 -1
- data/spec/unit/tester/fakesmtp/test_email.rb +4 -0
- data/spec/unit/web/inferer/test_inferer.rb +49 -0
- metadata +20 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91e515bc7abf0feb3e3aa3eba50edba87a50e4242240aaffb67aee547038d537
|
4
|
+
data.tar.gz: 2535c3943955ee893484c49bad9cad525c7a90f29f27fb7f891ca7c0e8cd4d33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 992437acb1f193a70e47132cdb00951d0e8dcf40d761cd93194924a2849e8c92391591995ea1d07935c1f0bebb952e5bec177e6782c2b66898c5f16d7e4e843a
|
7
|
+
data.tar.gz: be6fadddc53304cf9ee2111a064f81b126f9fe1560d4a89b5bb6d60623aed88770c4fa13505d9403e811ee5e784c752ad771e401988bc85fecb411be96a2e92a
|
@@ -42,6 +42,13 @@ module Webspicy
|
|
42
42
|
@subject ||= data["subject"]
|
43
43
|
end
|
44
44
|
|
45
|
+
def headers
|
46
|
+
@headers ||= data["headers"].reduce(OpenStruct.new){|acc, (key, value)|
|
47
|
+
acc[key.downcase] = value
|
48
|
+
acc
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
45
52
|
end # class Email
|
46
53
|
end # class Fakesendgrid
|
47
54
|
end # class Tester
|
@@ -11,7 +11,7 @@ module Webspicy
|
|
11
11
|
attr_reader :data
|
12
12
|
|
13
13
|
def from
|
14
|
-
email.from
|
14
|
+
email.from[0]
|
15
15
|
end
|
16
16
|
|
17
17
|
def recipients
|
@@ -24,7 +24,7 @@ module Webspicy
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def to
|
27
|
-
email.to
|
27
|
+
email.to || []
|
28
28
|
end
|
29
29
|
|
30
30
|
def subject
|
@@ -32,13 +32,20 @@ module Webspicy
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def cc
|
35
|
-
email.cc
|
35
|
+
email.cc || []
|
36
36
|
end
|
37
37
|
|
38
38
|
def bcc
|
39
39
|
recipients - cc - to
|
40
40
|
end
|
41
41
|
|
42
|
+
def headers
|
43
|
+
@headers ||= email.header.reduce(OpenStruct.new){|acc, h|
|
44
|
+
acc[h.name.downcase] = h.unparsed_value
|
45
|
+
acc
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
42
49
|
def email
|
43
50
|
@email ||= Mail.read_from_string(raw_data)
|
44
51
|
end
|
@@ -38,6 +38,14 @@ module Webspicy
|
|
38
38
|
.first
|
39
39
|
end
|
40
40
|
|
41
|
+
def headers
|
42
|
+
@headers ||= data["headerLines"]
|
43
|
+
.reduce(OpenStruct.new){|acc, h|
|
44
|
+
acc[h["key"].downcase] = h["line"].split(': ')[1..].join(': ')
|
45
|
+
acc
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
41
49
|
end # class Email
|
42
50
|
end # class Fakesmtp
|
43
51
|
end # class Tester
|
data/lib/webspicy/tester.rb
CHANGED
@@ -118,13 +118,12 @@ module Webspicy
|
|
118
118
|
def run_service
|
119
119
|
scope.each_testcase(service) do |test_case|
|
120
120
|
@test_case = test_case
|
121
|
-
reporter.before_test_case
|
122
121
|
run_test_case
|
123
|
-
reporter.test_case_done
|
124
122
|
end
|
125
123
|
end
|
126
124
|
|
127
125
|
def run_test_case
|
126
|
+
reporter.before_test_case
|
128
127
|
hooks.fire_around(self) do
|
129
128
|
reporter.before_each
|
130
129
|
hooks.fire_before_each(self)
|
@@ -143,9 +142,9 @@ module Webspicy
|
|
143
142
|
reporter.after_each
|
144
143
|
hooks.fire_after_each(self)
|
145
144
|
reporter.after_each_done
|
146
|
-
|
147
|
-
raise FailFast if !result.success? and failfast?
|
148
145
|
end
|
146
|
+
reporter.test_case_done
|
147
|
+
raise FailFast if !result.success? && failfast?
|
149
148
|
end
|
150
149
|
|
151
150
|
def call_test_case_target
|
data/lib/webspicy/version.rb
CHANGED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'rack/proxy'
|
2
|
+
module Webspicy
|
3
|
+
module Web
|
4
|
+
class Inferer < Rack::Proxy
|
5
|
+
|
6
|
+
def initialize(config, options = nil)
|
7
|
+
@webspicy_config = config
|
8
|
+
@webspicy_options = options || options_from_env
|
9
|
+
super(proxy_options)
|
10
|
+
end
|
11
|
+
attr_reader :webspicy_config, :webspicy_options
|
12
|
+
|
13
|
+
def rewrite_env(env)
|
14
|
+
env = env.merge(static_env)
|
15
|
+
env = handle_path_info(env)
|
16
|
+
env
|
17
|
+
end
|
18
|
+
|
19
|
+
def rewrite_response(triplet)
|
20
|
+
triplet
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def options_from_env
|
26
|
+
{
|
27
|
+
target_endpoint: ENV['PROXY_TARGET_ENDPOINT'] || config.host
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def proxy_options
|
32
|
+
uri = target_uri
|
33
|
+
backend = "#{uri.scheme}://#{uri.host}"
|
34
|
+
backend = "#{backend}:#{uri.port}" if uri.port != 80 && uri.port != 443
|
35
|
+
{
|
36
|
+
streaming: false,
|
37
|
+
backend: backend
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def static_env
|
42
|
+
@static_env ||= begin
|
43
|
+
e = {}
|
44
|
+
e['HTTP_HOST'] = target_uri.host
|
45
|
+
e
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def target_uri
|
50
|
+
@target_uri ||= URI.parse(webspicy_options[:target_endpoint])
|
51
|
+
end
|
52
|
+
|
53
|
+
def handle_path_info(env)
|
54
|
+
return env if target_uri.path.nil? || target_uri.path.empty?
|
55
|
+
|
56
|
+
env['PATH_INFO'] = "#{target_uri.path}#{env['PATH_INFO']}"
|
57
|
+
env
|
58
|
+
end
|
59
|
+
|
60
|
+
def perform_request(env)
|
61
|
+
webspicy_dump_request(env)
|
62
|
+
super.tap{|triplet|
|
63
|
+
webspicy_dump_response(env, triplet)
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def webspicy_dump_request(env)
|
68
|
+
base_file = webspicy_dump_basefile(env)
|
69
|
+
env['rack.input'].rewind
|
70
|
+
input = ''
|
71
|
+
env['rack.input'].each { |s| input << s }
|
72
|
+
base_file.add_ext('.body').write(input)
|
73
|
+
env['rack.input'].rewind
|
74
|
+
end
|
75
|
+
|
76
|
+
def webspicy_dump_response(env, triplet)
|
77
|
+
base_file = webspicy_dump_basefile(env)
|
78
|
+
base_file.add_ext('.env.json').write(
|
79
|
+
JSON.pretty_generate(env)
|
80
|
+
)
|
81
|
+
base_file.add_ext('.triplet.json').write(
|
82
|
+
JSON.pretty_generate(triplet)
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
def webspicy_dump_basefile(env)
|
87
|
+
path, method = env['PATH_INFO'], env['REQUEST_METHOD'].downcase
|
88
|
+
target_folder = (webspicy_config.folder/'inferer'/'dump')/path[1..-1]
|
89
|
+
target_folder.mkdir_p
|
90
|
+
target_folder/"#{method}.#{Time.now.to_i}"
|
91
|
+
end
|
92
|
+
|
93
|
+
end # class Inferer
|
94
|
+
end # module Web
|
95
|
+
end # module Webspicy
|
@@ -36,19 +36,25 @@ module Webspicy
|
|
36
36
|
|
37
37
|
def path_for(specification)
|
38
38
|
{
|
39
|
-
specification.url => {
|
39
|
+
standardize(specification.url) => {
|
40
40
|
summary: specification.name
|
41
41
|
}.merge(verbs_for(specification))
|
42
42
|
}
|
43
43
|
end
|
44
44
|
|
45
|
+
def standardize(url)
|
46
|
+
url = url.gsub(/\/$/, '') if url =~ /\/$/
|
47
|
+
url
|
48
|
+
end
|
49
|
+
|
45
50
|
def verbs_for(specification)
|
46
51
|
specification.services.inject({}) do |verbs,service|
|
47
52
|
verb = service.method.downcase
|
48
53
|
verb_defn = {
|
49
54
|
description: service.description,
|
55
|
+
parameters: parameters_for(service),
|
50
56
|
responses: responses_for(service)
|
51
|
-
}
|
57
|
+
}.compact
|
52
58
|
unless ["get", "options", "delete", "head"].include?(verb)
|
53
59
|
verb_defn[:requestBody] = request_body_for(service)
|
54
60
|
end
|
@@ -58,15 +64,29 @@ module Webspicy
|
|
58
64
|
|
59
65
|
def request_body_for(service)
|
60
66
|
schema = actual_input_schema(service)
|
67
|
+
example = nil # catch(:unfound) { generator.call(schema, {}) }
|
61
68
|
{
|
62
69
|
required: true,
|
63
70
|
content: {
|
64
71
|
"application/json" => {
|
65
72
|
schema: schema.to_json_schema,
|
66
|
-
example:
|
67
|
-
}
|
73
|
+
example: example
|
74
|
+
}.compact
|
75
|
+
}
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def parameters_for(service)
|
80
|
+
schema = actual_input_schema(service)
|
81
|
+
params = service.specification.url_placeholders.map{|p|
|
82
|
+
{
|
83
|
+
in: 'path',
|
84
|
+
name: p,
|
85
|
+
schema: { type: "string" },
|
86
|
+
required: true
|
68
87
|
}
|
69
88
|
}
|
89
|
+
params.empty? ? nil : params
|
70
90
|
end
|
71
91
|
|
72
92
|
def responses_for(service)
|
@@ -44,7 +44,10 @@ module Webspicy
|
|
44
44
|
"value": "test <b>test</b> test",
|
45
45
|
"type": "text/html"
|
46
46
|
}
|
47
|
-
]
|
47
|
+
],
|
48
|
+
"headers": {
|
49
|
+
"x-header-key": "personalised-header-value"
|
50
|
+
}
|
48
51
|
}
|
49
52
|
J
|
50
53
|
|
@@ -58,6 +61,7 @@ module Webspicy
|
|
58
61
|
expect(subject.cc).to eql(["a-cc-recipient@world.com"])
|
59
62
|
expect(subject.bcc).to eql(["a-bcc-recipient@world.com"])
|
60
63
|
expect(subject.subject).to eql("Hello World")
|
64
|
+
expect(subject.headers['x-header-key']).to eql('personalised-header-value')
|
61
65
|
end
|
62
66
|
|
63
67
|
end
|
@@ -12,6 +12,7 @@ module Webspicy
|
|
12
12
|
To: someone@world.com, someoneelse@world.com
|
13
13
|
CC: a-cc-recipient@world.com
|
14
14
|
Subject: Hey world, hello!
|
15
|
+
X-Ses-Configuration-Set: SesConfigurationSet
|
15
16
|
Message-ID: <2421bae3-9c42-7988-23b4-b1f6168130c9@webspicy.io>
|
16
17
|
Date: Thu, 24 Jun 2021 13:45:16 +0000
|
17
18
|
MIME-Version: 1.0
|
@@ -50,11 +51,16 @@ module Webspicy
|
|
50
51
|
}
|
51
52
|
|
52
53
|
it 'works as expected' do
|
53
|
-
expect(subject.from).to eql(
|
54
|
+
expect(subject.from).to eql("noreply@webspicy.io")
|
54
55
|
expect(subject.to).to eql(["someone@world.com", "someoneelse@world.com"])
|
55
56
|
expect(subject.cc).to eql(["a-cc-recipient@world.com"])
|
56
57
|
expect(subject.bcc).to eql(["a-bcc-recipient@world.com"])
|
57
58
|
expect(subject.subject).to eql("Hey world, hello!")
|
59
|
+
expect(subject.headers[:from]).to eql("Webspicy <noreply@webspicy.io>")
|
60
|
+
expect(subject.headers[:cc]).to eql("a-cc-recipient@world.com")
|
61
|
+
expect(subject.headers["message-id"]).to eql("<2421bae3-9c42-7988-23b4-b1f6168130c9@webspicy.io>")
|
62
|
+
expect(subject.headers["mime-version"]).to eql("1.0")
|
63
|
+
expect(subject.headers["x-ses-configuration-set"]).to eql("SesConfigurationSet")
|
58
64
|
end
|
59
65
|
|
60
66
|
end
|
@@ -96,6 +96,10 @@ module Webspicy
|
|
96
96
|
expect(subject.to).to eql(["someone@world.com", "someoneelse@world.com"])
|
97
97
|
expect(subject.cc).to eql(["a-cc-recipient@world.com"])
|
98
98
|
expect(subject.subject).to eql("Hello World")
|
99
|
+
expect(subject.headers[:cc]).to eql("a-cc-recipient@world.com")
|
100
|
+
expect(subject.headers[:date]).to eql("Tue, 20 Apr 2021 14:06:13 +0000")
|
101
|
+
expect(subject.headers['message-id']).to eql("<607edfd56836e_1b0492af@1d3356d02030.mail>")
|
102
|
+
expect(subject.headers['mime-version']).to eql("1.0")
|
99
103
|
end
|
100
104
|
|
101
105
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rack/test'
|
3
|
+
require 'webspicy/web'
|
4
|
+
require 'webspicy/web/inferer'
|
5
|
+
module Webspicy
|
6
|
+
module Web
|
7
|
+
describe Inferer do
|
8
|
+
include Rack::Test::Methods
|
9
|
+
|
10
|
+
let(:config) {
|
11
|
+
Configuration.dress(restful_folder)
|
12
|
+
}
|
13
|
+
|
14
|
+
let(:options) {{
|
15
|
+
:target_endpoint => "https://reqres.in/api"
|
16
|
+
}}
|
17
|
+
|
18
|
+
let(:app) {
|
19
|
+
Inferer.new(config, options)
|
20
|
+
}
|
21
|
+
|
22
|
+
describe 'proxy_options' do
|
23
|
+
it 'works' do
|
24
|
+
expect(app.send(:proxy_options)).to eql({
|
25
|
+
:streaming => false,
|
26
|
+
:backend => "https://reqres.in"
|
27
|
+
})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'static_env' do
|
32
|
+
it 'works' do
|
33
|
+
expect(app.send(:static_env)).to eql({
|
34
|
+
"HTTP_HOST" => "reqres.in"
|
35
|
+
})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'the proxy itself' do
|
40
|
+
it 'works as expected' do
|
41
|
+
get '/users'
|
42
|
+
expect(last_response.status).to eql(200)
|
43
|
+
expect(last_response.body).not_to be_empty
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webspicy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.20.
|
4
|
+
version: 0.20.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernard Lambeau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -226,6 +226,20 @@ dependencies:
|
|
226
226
|
- - "~>"
|
227
227
|
- !ruby/object:Gem::Version
|
228
228
|
version: '2.7'
|
229
|
+
- !ruby/object:Gem::Dependency
|
230
|
+
name: rack-proxy
|
231
|
+
requirement: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - "~>"
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: 0.7.0
|
236
|
+
type: :runtime
|
237
|
+
prerelease: false
|
238
|
+
version_requirements: !ruby/object:Gem::Requirement
|
239
|
+
requirements:
|
240
|
+
- - "~>"
|
241
|
+
- !ruby/object:Gem::Version
|
242
|
+
version: 0.7.0
|
229
243
|
description: Webspicy helps testing web services as software operation black boxes
|
230
244
|
email: blambeau@gmail.com
|
231
245
|
executables:
|
@@ -310,6 +324,8 @@ files:
|
|
310
324
|
- lib/webspicy/web/client/rack_test_client.rb
|
311
325
|
- lib/webspicy/web/client/support.rb
|
312
326
|
- lib/webspicy/web/formaldoc.fio
|
327
|
+
- lib/webspicy/web/inferer.rb
|
328
|
+
- lib/webspicy/web/inferer/config.ru
|
313
329
|
- lib/webspicy/web/invocation.rb
|
314
330
|
- lib/webspicy/web/mocker.rb
|
315
331
|
- lib/webspicy/web/mocker/config.ru
|
@@ -344,6 +360,7 @@ files:
|
|
344
360
|
- spec/unit/tester/fakesmtp/test_email.rb
|
345
361
|
- spec/unit/tester/test_asserter.rb
|
346
362
|
- spec/unit/tester/test_assertions.rb
|
363
|
+
- spec/unit/web/inferer/test_inferer.rb
|
347
364
|
- spec/unit/web/mocker/test_mocker.rb
|
348
365
|
- spec/unit/web/openapi/test_generator.rb
|
349
366
|
- spec/unit/web/specification/test_instantiate_url.rb
|
@@ -369,7 +386,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
369
386
|
- !ruby/object:Gem::Version
|
370
387
|
version: '0'
|
371
388
|
requirements: []
|
372
|
-
rubygems_version: 3.2.
|
389
|
+
rubygems_version: 3.2.22
|
373
390
|
signing_key:
|
374
391
|
specification_version: 4
|
375
392
|
summary: Webspicy helps testing web services as software operation black boxes!
|