webspicy 0.15.7 → 0.16.3
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/README.md +71 -24
- data/bin/webspicy +30 -14
- data/examples/restful/Gemfile +2 -2
- data/examples/restful/Gemfile.lock +53 -33
- data/examples/restful/Rakefile +0 -1
- data/examples/restful/app.rb +4 -1
- data/examples/restful/webspicy/config.rb +8 -0
- data/examples/restful/webspicy/rack.rb +1 -1
- data/examples/restful/webspicy/real.rb +1 -1
- data/examples/restful/webspicy/schema.fio +2 -2
- data/examples/restful/webspicy/support/must_be_authenticated.rb +2 -2
- data/examples/restful/webspicy/support/todo_removed.rb +18 -0
- data/examples/restful/webspicy/todo/deleteTodo.yml +4 -1
- data/examples/restful/webspicy/todo/getTodoSingleServiceFormat.yml +46 -0
- data/examples/restful/webspicy/todo/options.yml +1 -1
- data/examples/restful/webspicy/todo/patchTodo.yml +3 -0
- data/examples/restful/webspicy/todo/postFile.yml +1 -1
- data/examples/single_spec/spec.yml +59 -0
- data/examples/website/config.rb +2 -0
- data/examples/website/schema.fio +1 -0
- data/examples/website/specification/get-http.yml +30 -0
- data/examples/website/specification/get-https.yml +30 -0
- data/lib/finitio/webspicy/scalars.fio +25 -0
- data/lib/webspicy.rb +48 -17
- data/lib/webspicy/checker.rb +2 -2
- data/lib/webspicy/configuration.rb +70 -14
- data/lib/webspicy/configuration/scope.rb +162 -0
- data/lib/webspicy/configuration/single_url.rb +58 -0
- data/lib/webspicy/configuration/single_yml_file.rb +30 -0
- data/lib/webspicy/formaldoc.fio +23 -8
- data/lib/webspicy/mocker.rb +8 -8
- data/lib/webspicy/mocker/config.ru +5 -0
- data/lib/webspicy/openapi.rb +1 -0
- data/lib/webspicy/openapi/generator.rb +127 -0
- data/lib/webspicy/{resource.rb → specification.rb} +28 -5
- data/lib/webspicy/specification/file_upload.rb +37 -0
- data/lib/webspicy/specification/postcondition.rb +16 -0
- data/lib/webspicy/specification/precondition.rb +19 -0
- data/lib/webspicy/specification/precondition/global_request_headers.rb +35 -0
- data/lib/webspicy/specification/precondition/robust_to_invalid_input.rb +68 -0
- data/lib/webspicy/{resource → specification}/service.rb +11 -6
- data/lib/webspicy/specification/test_case.rb +139 -0
- data/lib/webspicy/support.rb +1 -0
- data/lib/webspicy/support/colorize.rb +28 -0
- data/lib/webspicy/support/status_range.rb +6 -1
- data/lib/webspicy/tester.rb +16 -11
- data/lib/webspicy/tester/asserter.rb +3 -2
- data/lib/webspicy/tester/assertions.rb +5 -1
- data/lib/webspicy/tester/client.rb +63 -0
- data/lib/webspicy/tester/client/http_client.rb +154 -0
- data/lib/webspicy/tester/client/rack_test_client.rb +188 -0
- data/lib/webspicy/tester/client/support.rb +65 -0
- data/lib/webspicy/tester/invocation.rb +218 -0
- data/lib/webspicy/tester/rspec_asserter.rb +108 -0
- data/lib/webspicy/tester/rspec_matchers.rb +104 -0
- data/lib/webspicy/version.rb +2 -2
- data/spec/{unit/spec_helper.rb → spec_helper.rb} +0 -0
- data/spec/unit/configuration/scope/test_each_service.rb +49 -0
- data/spec/unit/configuration/scope/test_each_specification.rb +68 -0
- data/spec/unit/configuration/scope/test_expand_example.rb +65 -0
- data/spec/unit/configuration/scope/test_to_real_url.rb +82 -0
- data/spec/unit/openapi/test_generator.rb +28 -0
- data/spec/unit/specification/precondition/test_global_request_headers.rb +42 -0
- data/spec/unit/{resource → specification}/service/test_dress_params.rb +2 -2
- data/spec/unit/specification/test_case/test_mutate.rb +24 -0
- data/spec/unit/{resource → specification}/test_instantiate_url.rb +5 -5
- data/spec/unit/{resource → specification}/test_url_placeholders.rb +4 -4
- data/spec/unit/test_configuration.rb +24 -7
- data/spec/unit/tester/client/test_around.rb +61 -0
- data/spec/unit/tester/test_asserter.rb +51 -0
- data/spec/unit/tester/test_assertions.rb +4 -4
- data/tasks/test.rake +3 -1
- metadata +88 -45
- data/LICENSE.md +0 -22
- data/lib/webspicy/client.rb +0 -61
- data/lib/webspicy/client/http_client.rb +0 -145
- data/lib/webspicy/client/rack_test_client.rb +0 -181
- data/lib/webspicy/client/support.rb +0 -48
- data/lib/webspicy/file_upload.rb +0 -35
- data/lib/webspicy/postcondition.rb +0 -14
- data/lib/webspicy/precondition.rb +0 -15
- data/lib/webspicy/resource/service/invocation.rb +0 -212
- data/lib/webspicy/resource/service/test_case.rb +0 -132
- data/lib/webspicy/scope.rb +0 -160
- data/spec/unit/client/test_around.rb +0 -59
- data/spec/unit/scope/test_each_resource.rb +0 -66
- data/spec/unit/scope/test_each_service.rb +0 -47
- data/spec/unit/scope/test_expand_example.rb +0 -63
- data/spec/unit/scope/test_to_real_url.rb +0 -80
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cbfb644d2ae34f2e2e87aa2d69b50b762299770b9c0109fbc5281fdd3b80d22
|
4
|
+
data.tar.gz: 6bf17b7423bb6ff33b53d8f12dc761094e613961487c146c66a87ce84b792bc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 403ddeb22ffccd059d8450a6290f7f190d97bc45ef12a04a43a97059d733085ce4fe2865f31a5452d43c18e4244a53129ac280cd37db09b8a6ce50e76506f8f6
|
7
|
+
data.tar.gz: '095210fda4e1b4e903c1803a2cd75420a905894b06d4403e8f1019df0c43eeec10eb3952b8d06397bdb0d8a753361c01f1577f85f09ca34258386020276dcdaa'
|
data/README.md
CHANGED
@@ -1,46 +1,93 @@
|
|
1
1
|
# Webspicy
|
2
2
|
|
3
|
-
A
|
4
|
-
|
3
|
+
A specification and test framework for web services seen as black-box software
|
4
|
+
operations. Webspicy yields a better test coverage for a smaller testing effort,
|
5
|
+
because software quality matters.
|
6
|
+
|
7
|
+
See webspicy in action and make the tutorial on https://yourbackendisbroken.dev
|
5
8
|
|
6
9
|
## Features
|
7
10
|
|
8
|
-
* Declarative
|
11
|
+
* Declarative specification of HTTP web services + their tests
|
12
|
+
|
13
|
+
* Framework/language agnostic: `webspicy` is written in Ruby, but can be used
|
14
|
+
to test web services for backends written in any language / framework.
|
15
|
+
|
16
|
+
* Black box testing: `webspicy` focuses on web services seen as blackboxes. It
|
17
|
+
has no knowledge of the implementation, and focuses on HTTP and input/output
|
18
|
+
data instead. Investing in such testing makes those tests more stable and
|
19
|
+
your API design better.
|
9
20
|
|
10
|
-
*
|
11
|
-
|
21
|
+
* Formal and human-friendly data schema with strong data matching semantics,
|
22
|
+
thanks to finitio.io
|
12
23
|
|
13
|
-
*
|
14
|
-
no knowledge of the implementation, and focuses on HTTP and input/output data
|
15
|
-
instead. Investing in such testing makes those tests more stable and your API
|
16
|
-
better.
|
24
|
+
* Test instrumentation and generation, based on PRE & POST contracts.
|
17
25
|
|
18
|
-
*
|
19
|
-
|
26
|
+
* Extra goodness for Rubyists: being written in ruby, `webspicy` also supports
|
27
|
+
testing Rack applications directly (through rack/test), which boosts the
|
28
|
+
test suite.
|
20
29
|
|
21
|
-
* Extra
|
22
|
-
|
30
|
+
* Extra goodies: when a specification is written, it can also be used for
|
31
|
+
mocking the API, generating an openapi file, etc.
|
23
32
|
|
24
|
-
## Getting started
|
33
|
+
## Getting started with the commandline
|
25
34
|
|
26
|
-
|
27
|
-
with GET and POST restful services tested with the framework. The Rakefile contains
|
28
|
-
the necessary tasks to run those tests.
|
35
|
+
To install webspicy on your developer computer, install ruby then:
|
29
36
|
|
30
|
-
|
37
|
+
```
|
38
|
+
gem install webspicy
|
39
|
+
```
|
31
40
|
|
32
|
-
|
41
|
+
Then execute webspicy help to see the options.
|
33
42
|
|
34
43
|
```
|
35
44
|
webspicy --help
|
36
|
-
webspicy path/to/your/config.rb
|
37
45
|
```
|
38
46
|
|
39
|
-
## Using the docker image
|
47
|
+
## Using the docker image(s)
|
48
|
+
|
49
|
+
If you just want to play with the commandline tool without having to
|
50
|
+
install ruby & webspicy, you can use the docker image we provide for
|
51
|
+
the commandline:
|
52
|
+
|
53
|
+
```
|
54
|
+
docker run enspirit/webspicy --help
|
55
|
+
```
|
56
|
+
|
57
|
+
If you have a specification & test suite somewhere, an easy way to run the
|
58
|
+
whole suite (or integrate it in your continuous integration pipeline) is
|
59
|
+
to use our `:tester` docker image. Just mount your test suite as a volume
|
60
|
+
in `/home/app` and you are good to go:
|
40
61
|
|
41
|
-
|
42
|
-
|
62
|
+
```
|
63
|
+
docker run -v path/to/tests:/formalspec enspirit/webspicy:tester
|
64
|
+
```
|
65
|
+
|
66
|
+
If your plan is to test a backend that runs on your own machine (vs.
|
67
|
+
publicly on the Internet or inside the default docker network),
|
68
|
+
you will need to add some networking option, as shown below. Please
|
69
|
+
refer to Docker documentation.
|
43
70
|
|
44
71
|
```
|
45
|
-
docker run
|
72
|
+
docker run -v path/to/tests:/formalspec --network=host enspirit/webspicy:tester
|
46
73
|
```
|
74
|
+
|
75
|
+
## Contributing
|
76
|
+
|
77
|
+
Please use github issues for questions and bugs, and pull requests for
|
78
|
+
submitting improvement proposals and new features.
|
79
|
+
|
80
|
+
## Contributors
|
81
|
+
|
82
|
+
* Bernard Lambeau (blambeau)
|
83
|
+
* Louis Lambeau (llambeau)
|
84
|
+
* Yoann Guyot (ygu)
|
85
|
+
* Felix Holmgren (@felixyz)
|
86
|
+
|
87
|
+
Enspirit (https://enspirit.be) and Klaro App (https://klaro.cards) are
|
88
|
+
both actively using, contributing and funding work on this library.
|
89
|
+
Please contact Bernard Lambeau for any question.
|
90
|
+
|
91
|
+
## Licence
|
92
|
+
|
93
|
+
Webspicy is distributed under a MIT Licence, by Enspirit SRL.
|
data/bin/webspicy
CHANGED
@@ -1,15 +1,25 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#/
|
3
|
-
#/
|
4
|
-
#/
|
2
|
+
#/
|
3
|
+
#/ Document & test web services as black-box operations.
|
4
|
+
#/ (c) Enspirit SRL. Distributed under MIT licence.
|
5
|
+
#/
|
6
|
+
#/ Usage: webspicy [options] URL # run default test againt url
|
7
|
+
#/ Usage: webspicy [options] path/to/config.rb # run whole test suite
|
8
|
+
#/ Usage: webspicy [options] path/to/spec.yml # run a single test
|
9
|
+
#/
|
10
|
+
#/ Options:
|
11
|
+
#/ -h, --help Show this help message
|
12
|
+
#/ -v, --version Show webspicy version
|
13
|
+
#/ --debug Same as LOG_LEVEL=DEBUG, takes precedence
|
5
14
|
#/
|
6
15
|
#/ Recognized env vars:
|
7
|
-
#/ - ROBUST=no
|
16
|
+
#/ - ROBUST=no|only|generated execute no counterexamples (only them, only generated ones)
|
8
17
|
#/ - LOG_LEVEL=INFO|DEBUG|... set log level to the appropriate level
|
9
18
|
#/ - RESOURCE=... restrict to .yml test files matching the pattern
|
10
|
-
#/ - METHOD=GET|POST|DELETE... execute only tests matching the verb
|
19
|
+
#/ - METHOD=GET|POST|DELETE... execute only tests matching the HTTP verb
|
11
20
|
#/ - TAG=... execute only tests matching the given tag
|
12
21
|
#/ - FAILFAST=yes|no stop executing tests on first failure
|
22
|
+
#/
|
13
23
|
require 'webspicy'
|
14
24
|
require 'webspicy/tester'
|
15
25
|
require 'optparse'
|
@@ -20,19 +30,25 @@ def showhelp
|
|
20
30
|
end
|
21
31
|
|
22
32
|
ARGV.options do |opts|
|
23
|
-
opts.on_tail("-h", "--help"){
|
33
|
+
opts.on_tail("-h", "--help"){
|
34
|
+
showhelp
|
35
|
+
}
|
36
|
+
opts.on("-v", "--version"){
|
37
|
+
puts "webspicy v#{Webspicy::VERSION}, (c) Enspirit SRL"
|
38
|
+
exit(0)
|
39
|
+
}
|
40
|
+
opts.on("--debug") {
|
41
|
+
ENV['LOG_LEVEL'] = 'DEBUG'
|
42
|
+
Webspicy::LOGGER.level = Logger.const_get(ENV['LOG_LEVEL'])
|
43
|
+
}
|
24
44
|
opts.parse!
|
25
45
|
end
|
26
46
|
|
27
47
|
if ARGV.size != 1
|
28
48
|
showhelp
|
29
49
|
exit(-1)
|
30
|
-
elsif (p = Path(ARGV.first)).exists?
|
31
|
-
config = Webspicy::Configuration.dress(p)
|
32
|
-
res = Webspicy::Tester.new(config).call
|
33
|
-
abort("Some tests failed") unless res == 0
|
34
|
-
else
|
35
|
-
puts "No such file or directory `#{ARGV.first}`"
|
36
|
-
showhelp
|
37
|
-
exit(-1)
|
38
50
|
end
|
51
|
+
|
52
|
+
config = Webspicy::Configuration.dress(ARGV[0])
|
53
|
+
res = Webspicy::Tester.new(config).call
|
54
|
+
abort("Some tests failed") unless res == 0
|
data/examples/restful/Gemfile
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../..
|
3
3
|
specs:
|
4
|
-
webspicy (0.
|
5
|
-
|
4
|
+
webspicy (0.16.3)
|
5
|
+
colorize (~> 0.8.1)
|
6
|
+
finitio (~> 0.9.0)
|
6
7
|
http (>= 2)
|
7
8
|
mustermann (~> 1.0)
|
8
9
|
mustermann-contrib
|
9
|
-
|
10
|
+
openapi3_parser (~> 0.8.2)
|
11
|
+
path (~> 2.0)
|
10
12
|
rack-robustness (~> 1.1, >= 1.1.0)
|
11
13
|
rack-test (~> 0.6.3)
|
12
14
|
rspec (~> 3.7)
|
@@ -18,68 +20,86 @@ GEM
|
|
18
20
|
addressable (2.7.0)
|
19
21
|
public_suffix (>= 2.0.2, < 5.0)
|
20
22
|
citrus (3.0.2)
|
21
|
-
|
23
|
+
colorize (0.8.1)
|
24
|
+
commonmarker (0.21.0)
|
25
|
+
ruby-enum (~> 0.5)
|
26
|
+
concurrent-ruby (1.1.7)
|
27
|
+
diff-lcs (1.4.4)
|
22
28
|
domain_name (0.5.20190701)
|
23
29
|
unf (>= 0.0.5, < 1.0.0)
|
24
|
-
|
30
|
+
ffi (1.13.1)
|
31
|
+
ffi-compiler (1.0.1)
|
32
|
+
ffi (>= 1.0.0)
|
33
|
+
rake
|
34
|
+
finitio (0.9.0)
|
25
35
|
citrus (>= 2.4, < 4.0)
|
26
36
|
hansi (0.2.0)
|
27
|
-
http (
|
37
|
+
http (4.4.1)
|
28
38
|
addressable (~> 2.3)
|
29
39
|
http-cookie (~> 1.0)
|
30
|
-
http-form_data (~>
|
31
|
-
|
40
|
+
http-form_data (~> 2.2)
|
41
|
+
http-parser (~> 1.2.0)
|
32
42
|
http-cookie (1.0.3)
|
33
43
|
domain_name (~> 0.5)
|
34
|
-
http-form_data (
|
35
|
-
|
44
|
+
http-form_data (2.3.0)
|
45
|
+
http-parser (1.2.2)
|
46
|
+
ffi-compiler
|
47
|
+
i18n (1.8.5)
|
48
|
+
concurrent-ruby (~> 1.0)
|
36
49
|
mustermann (1.1.1)
|
37
50
|
ruby2_keywords (~> 0.0.1)
|
38
51
|
mustermann-contrib (1.1.1)
|
39
52
|
hansi (~> 0.2.0)
|
40
53
|
mustermann (= 1.1.1)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
54
|
+
openapi3_parser (0.8.2)
|
55
|
+
commonmarker (~> 0.17)
|
56
|
+
psych (~> 3.1)
|
57
|
+
path (2.0.1)
|
58
|
+
psych (3.2.1)
|
59
|
+
public_suffix (4.0.6)
|
60
|
+
rack (2.2.3)
|
61
|
+
rack-protection (2.1.0)
|
45
62
|
rack
|
46
63
|
rack-robustness (1.1.0)
|
47
64
|
rack-test (0.6.3)
|
48
65
|
rack (>= 1.0)
|
49
|
-
rake (
|
50
|
-
rspec (3.
|
51
|
-
rspec-core (~> 3.
|
52
|
-
rspec-expectations (~> 3.
|
53
|
-
rspec-mocks (~> 3.
|
54
|
-
rspec-core (3.
|
55
|
-
rspec-support (~> 3.
|
56
|
-
rspec-expectations (3.
|
66
|
+
rake (12.3.3)
|
67
|
+
rspec (3.10.0)
|
68
|
+
rspec-core (~> 3.10.0)
|
69
|
+
rspec-expectations (~> 3.10.0)
|
70
|
+
rspec-mocks (~> 3.10.0)
|
71
|
+
rspec-core (3.10.0)
|
72
|
+
rspec-support (~> 3.10.0)
|
73
|
+
rspec-expectations (3.10.0)
|
57
74
|
diff-lcs (>= 1.2.0, < 2.0)
|
58
|
-
rspec-support (~> 3.
|
59
|
-
rspec-mocks (3.
|
75
|
+
rspec-support (~> 3.10.0)
|
76
|
+
rspec-mocks (3.10.0)
|
60
77
|
diff-lcs (>= 1.2.0, < 2.0)
|
61
|
-
rspec-support (~> 3.
|
62
|
-
rspec-support (3.
|
78
|
+
rspec-support (~> 3.10.0)
|
79
|
+
rspec-support (3.10.0)
|
63
80
|
rspec_junit_formatter (0.4.1)
|
64
81
|
rspec-core (>= 2, < 4, != 2.12.0)
|
82
|
+
ruby-enum (0.8.0)
|
83
|
+
i18n
|
65
84
|
ruby2_keywords (0.0.2)
|
66
|
-
sinatra (2.0
|
85
|
+
sinatra (2.1.0)
|
67
86
|
mustermann (~> 1.0)
|
68
|
-
rack (~> 2.
|
69
|
-
rack-protection (= 2.0
|
87
|
+
rack (~> 2.2)
|
88
|
+
rack-protection (= 2.1.0)
|
70
89
|
tilt (~> 2.0)
|
71
90
|
tilt (2.0.10)
|
72
91
|
unf (0.1.4)
|
73
92
|
unf_ext
|
74
|
-
unf_ext (0.0.7.
|
93
|
+
unf_ext (0.0.7.7)
|
75
94
|
|
76
95
|
PLATFORMS
|
77
96
|
ruby
|
97
|
+
x86_64-darwin-15
|
78
98
|
|
79
99
|
DEPENDENCIES
|
80
|
-
rake (~>
|
81
|
-
sinatra (~> 2
|
100
|
+
rake (~> 12)
|
101
|
+
sinatra (~> 2)
|
82
102
|
webspicy!
|
83
103
|
|
84
104
|
BUNDLED WITH
|
85
|
-
2.
|
105
|
+
2.2.1
|
data/examples/restful/Rakefile
CHANGED
data/examples/restful/app.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'webspicy'
|
1
2
|
require 'sinatra'
|
2
3
|
require 'json'
|
3
4
|
require 'path'
|
@@ -65,6 +66,7 @@ post '/reset' do
|
|
65
66
|
end
|
66
67
|
|
67
68
|
get '/todo/' do
|
69
|
+
raise unless request.env['HTTP_ACCEPT'] == 'application/json'
|
68
70
|
content_type :json
|
69
71
|
settings.todolist.to_json
|
70
72
|
end
|
@@ -94,6 +96,7 @@ post '/todo/', :auth => :user do
|
|
94
96
|
end
|
95
97
|
|
96
98
|
get '/todo/:id' do |id|
|
99
|
+
raise unless request.env['HTTP_ACCEPT'] == 'application/json'
|
97
100
|
content_type :json
|
98
101
|
todo = settings.todolist.find{|todo| todo[:id] == Integer(id) }
|
99
102
|
if todo.nil?
|
@@ -111,7 +114,7 @@ patch '/todo/:id', :auth => :user do |id|
|
|
111
114
|
status 404
|
112
115
|
{error: "No such todo"}.to_json
|
113
116
|
else
|
114
|
-
patch = SCHEMA["TodoPatch"].dress(loaded_body)
|
117
|
+
patch = SCHEMA["TodoPatch"].dress(loaded_body.merge("id" => Integer(id)))
|
115
118
|
patched = todo.merge(patch)
|
116
119
|
settings.todolist = settings.todolist.reject{|todo| todo[:id] == Integer(id) }
|
117
120
|
settings.todolist << patched
|
@@ -4,6 +4,14 @@ def webspicy_config(&bl)
|
|
4
4
|
c.precondition MustBeAuthenticated
|
5
5
|
c.precondition MustBeAnAdmin
|
6
6
|
|
7
|
+
c.precondition Webspicy::Specification::Precondition::GlobalRequestHeaders.new({
|
8
|
+
'Accept' => 'application/json'
|
9
|
+
}){|service| service.method == "GET" }
|
10
|
+
|
11
|
+
c.precondition Webspicy::Specification::Precondition::RobustToInvalidInput.new
|
12
|
+
|
13
|
+
c.postcondition TodoRemoved
|
14
|
+
|
7
15
|
c.instrument do |tc, client|
|
8
16
|
role = tc.metadata[:role]
|
9
17
|
tc.headers['Authorization'] = "Bearer #{role}" if role
|
@@ -30,7 +30,7 @@ class MustBeAuthenticated
|
|
30
30
|
def counterexample(description, role, expected, status = 401)
|
31
31
|
YAML.load <<-YML.gsub(/^\s+[#][ ]/, "")
|
32
32
|
# description: |-
|
33
|
-
# (#{self.class.name})
|
33
|
+
# #{description} (#{self.class.name} PRE)
|
34
34
|
# params:
|
35
35
|
# id: 1
|
36
36
|
# dress_params:
|
@@ -41,7 +41,7 @@ class MustBeAuthenticated
|
|
41
41
|
# content_type: application/json
|
42
42
|
# status: #{status}
|
43
43
|
# assert:
|
44
|
-
# - "pathFD('', error: '#{expected}')"
|
44
|
+
# - "pathFD('', error: '#{expected}')"
|
45
45
|
YML
|
46
46
|
end
|
47
47
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class TodoRemoved
|
2
|
+
include Webspicy::Specification::Postcondition
|
3
|
+
|
4
|
+
def self.match(service, descr)
|
5
|
+
return TodoRemoved.new if descr =~ /The todo has been removed/
|
6
|
+
end
|
7
|
+
|
8
|
+
def check(invocation)
|
9
|
+
client = invocation.client
|
10
|
+
id = invocation.test_case.params['id']
|
11
|
+
url = "/todo/#{id}"
|
12
|
+
response = client.api.get(url, {}, {
|
13
|
+
"Accept" => "application/json"
|
14
|
+
})
|
15
|
+
return nil if response.status == 404
|
16
|
+
"Todo `#{id}` was not deleted, it has been found"
|
17
|
+
end
|
18
|
+
end
|