webspicy 0.15.7 → 0.16.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +71 -24
  3. data/bin/webspicy +30 -14
  4. data/examples/restful/Gemfile +2 -2
  5. data/examples/restful/Gemfile.lock +53 -33
  6. data/examples/restful/Rakefile +0 -1
  7. data/examples/restful/app.rb +4 -1
  8. data/examples/restful/webspicy/config.rb +8 -0
  9. data/examples/restful/webspicy/rack.rb +1 -1
  10. data/examples/restful/webspicy/real.rb +1 -1
  11. data/examples/restful/webspicy/schema.fio +2 -2
  12. data/examples/restful/webspicy/support/must_be_authenticated.rb +2 -2
  13. data/examples/restful/webspicy/support/todo_removed.rb +18 -0
  14. data/examples/restful/webspicy/todo/deleteTodo.yml +4 -1
  15. data/examples/restful/webspicy/todo/getTodoSingleServiceFormat.yml +46 -0
  16. data/examples/restful/webspicy/todo/options.yml +1 -1
  17. data/examples/restful/webspicy/todo/patchTodo.yml +3 -0
  18. data/examples/restful/webspicy/todo/postFile.yml +1 -1
  19. data/examples/single_spec/spec.yml +59 -0
  20. data/examples/website/config.rb +2 -0
  21. data/examples/website/schema.fio +1 -0
  22. data/examples/website/specification/get-http.yml +30 -0
  23. data/examples/website/specification/get-https.yml +30 -0
  24. data/lib/finitio/webspicy/scalars.fio +25 -0
  25. data/lib/webspicy.rb +48 -17
  26. data/lib/webspicy/checker.rb +2 -2
  27. data/lib/webspicy/configuration.rb +70 -14
  28. data/lib/webspicy/configuration/scope.rb +162 -0
  29. data/lib/webspicy/configuration/single_url.rb +58 -0
  30. data/lib/webspicy/configuration/single_yml_file.rb +30 -0
  31. data/lib/webspicy/formaldoc.fio +23 -8
  32. data/lib/webspicy/mocker.rb +8 -8
  33. data/lib/webspicy/mocker/config.ru +5 -0
  34. data/lib/webspicy/openapi.rb +1 -0
  35. data/lib/webspicy/openapi/generator.rb +127 -0
  36. data/lib/webspicy/{resource.rb → specification.rb} +28 -5
  37. data/lib/webspicy/specification/file_upload.rb +37 -0
  38. data/lib/webspicy/specification/postcondition.rb +16 -0
  39. data/lib/webspicy/specification/precondition.rb +19 -0
  40. data/lib/webspicy/specification/precondition/global_request_headers.rb +35 -0
  41. data/lib/webspicy/specification/precondition/robust_to_invalid_input.rb +68 -0
  42. data/lib/webspicy/{resource → specification}/service.rb +11 -6
  43. data/lib/webspicy/specification/test_case.rb +139 -0
  44. data/lib/webspicy/support.rb +1 -0
  45. data/lib/webspicy/support/colorize.rb +28 -0
  46. data/lib/webspicy/support/status_range.rb +6 -1
  47. data/lib/webspicy/tester.rb +16 -11
  48. data/lib/webspicy/tester/asserter.rb +3 -2
  49. data/lib/webspicy/tester/assertions.rb +5 -1
  50. data/lib/webspicy/tester/client.rb +63 -0
  51. data/lib/webspicy/tester/client/http_client.rb +154 -0
  52. data/lib/webspicy/tester/client/rack_test_client.rb +188 -0
  53. data/lib/webspicy/tester/client/support.rb +65 -0
  54. data/lib/webspicy/tester/invocation.rb +218 -0
  55. data/lib/webspicy/tester/rspec_asserter.rb +108 -0
  56. data/lib/webspicy/tester/rspec_matchers.rb +104 -0
  57. data/lib/webspicy/version.rb +2 -2
  58. data/spec/{unit/spec_helper.rb → spec_helper.rb} +0 -0
  59. data/spec/unit/configuration/scope/test_each_service.rb +49 -0
  60. data/spec/unit/configuration/scope/test_each_specification.rb +68 -0
  61. data/spec/unit/configuration/scope/test_expand_example.rb +65 -0
  62. data/spec/unit/configuration/scope/test_to_real_url.rb +82 -0
  63. data/spec/unit/openapi/test_generator.rb +28 -0
  64. data/spec/unit/specification/precondition/test_global_request_headers.rb +42 -0
  65. data/spec/unit/{resource → specification}/service/test_dress_params.rb +2 -2
  66. data/spec/unit/specification/test_case/test_mutate.rb +24 -0
  67. data/spec/unit/{resource → specification}/test_instantiate_url.rb +5 -5
  68. data/spec/unit/{resource → specification}/test_url_placeholders.rb +4 -4
  69. data/spec/unit/test_configuration.rb +24 -7
  70. data/spec/unit/tester/client/test_around.rb +61 -0
  71. data/spec/unit/tester/test_asserter.rb +51 -0
  72. data/spec/unit/tester/test_assertions.rb +4 -4
  73. data/tasks/test.rake +3 -1
  74. metadata +88 -45
  75. data/LICENSE.md +0 -22
  76. data/lib/webspicy/client.rb +0 -61
  77. data/lib/webspicy/client/http_client.rb +0 -145
  78. data/lib/webspicy/client/rack_test_client.rb +0 -181
  79. data/lib/webspicy/client/support.rb +0 -48
  80. data/lib/webspicy/file_upload.rb +0 -35
  81. data/lib/webspicy/postcondition.rb +0 -14
  82. data/lib/webspicy/precondition.rb +0 -15
  83. data/lib/webspicy/resource/service/invocation.rb +0 -212
  84. data/lib/webspicy/resource/service/test_case.rb +0 -132
  85. data/lib/webspicy/scope.rb +0 -160
  86. data/spec/unit/client/test_around.rb +0 -59
  87. data/spec/unit/scope/test_each_resource.rb +0 -66
  88. data/spec/unit/scope/test_each_service.rb +0 -47
  89. data/spec/unit/scope/test_expand_example.rb +0 -63
  90. 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: f4a2e0e1d1ccfacade6173f0ebe8119a71438aeb5403af05bdf08373f98630d7
4
- data.tar.gz: 063a4f40b5e8244adc654bb0e60b2dccb67b930b0ec4fa18045e3b005392004d
3
+ metadata.gz: 7cbfb644d2ae34f2e2e87aa2d69b50b762299770b9c0109fbc5281fdd3b80d22
4
+ data.tar.gz: 6bf17b7423bb6ff33b53d8f12dc761094e613961487c146c66a87ce84b792bc7
5
5
  SHA512:
6
- metadata.gz: bdaaf1d7e90215b5f2f4d30ab0efd42ddf08f490dcaa77cba84a822b333020d63c34980420d9b9872c2db423635cf0d0fd0193a578826a31ad950795fa8a806e
7
- data.tar.gz: 21a7cf4e9b0bbb8835284132edd029fd7221933d2cc0d044c8ca6f5fb81bfc406621cbefdd33422da1a3ce68a703a030965fd15b7da8e678693e25a78c1526e7
6
+ metadata.gz: 403ddeb22ffccd059d8450a6290f7f190d97bc45ef12a04a43a97059d733085ce4fe2865f31a5452d43c18e4244a53129ac280cd37db09b8a6ce50e76506f8f6
7
+ data.tar.gz: '095210fda4e1b4e903c1803a2cd75420a905894b06d4403e8f1019df0c43eeec10eb3952b8d06397bdb0d8a753361c01f1577f85f09ca34258386020276dcdaa'
data/README.md CHANGED
@@ -1,46 +1,93 @@
1
1
  # Webspicy
2
2
 
3
- A description, specification and test framework for web services seen as black
4
- box software operations.
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 description of RESTful web-services + their tests
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
- * Framework/language agnostic: Webspicy is written in Ruby, but can be used to
11
- test web services in any language / framework.
21
+ * Formal and human-friendly data schema with strong data matching semantics,
22
+ thanks to finitio.io
12
23
 
13
- * Black box testing: Webspicy focuses on web services seen as blackboxes. It has
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
- * Test instrumentation and generation, based on declarative PRE & POST
19
- conditions.
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 goodness for Rubyists: being written in ruby, Webspicy also supports
22
- testing Rack applications directly (through rack/test)
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
- Please have a look at the example first. It contains a simple Sinatra application
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
- ## Executing the tests using the command line
37
+ ```
38
+ gem install webspicy
39
+ ```
31
40
 
32
- Please have a look at the examples first. Then:
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
- A docker image running your tests is provided. It expects a volume with the
42
- tests to run put in `/home/app`.
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 enspirit/webspicy -v path/to/tests:/home/app
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.
@@ -1,15 +1,25 @@
1
1
  #!/usr/bin/env ruby
2
- #/ Document and test RESTful webservices
3
- #/ (c) Enspirit SPRL. Distributed under MIT licence.
4
- #/ Usage: webspicy [options] path/to/config.rb
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 do not execute counterexamples
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"){ showhelp }
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
@@ -1,5 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "rake", "~> 10"
4
- gem 'sinatra', "~> 2.0", ">= 2.0.2"
3
+ gem "rake", "~> 12"
4
+ gem 'sinatra', "~> 2"
5
5
  gem "webspicy", path: "../.."
@@ -1,12 +1,14 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- webspicy (0.15.7)
5
- finitio (>= 0.8.0)
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
- path (>= 1.3)
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
- diff-lcs (1.3)
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
- finitio (0.8.0)
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 (2.2.2)
37
+ http (4.4.1)
28
38
  addressable (~> 2.3)
29
39
  http-cookie (~> 1.0)
30
- http-form_data (~> 1.0.1)
31
- http_parser.rb (~> 0.6.0)
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 (1.0.3)
35
- http_parser.rb (0.6.0)
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
- path (1.3.3)
42
- public_suffix (4.0.3)
43
- rack (2.2.2)
44
- rack-protection (2.0.8.1)
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 (10.5.0)
50
- rspec (3.9.0)
51
- rspec-core (~> 3.9.0)
52
- rspec-expectations (~> 3.9.0)
53
- rspec-mocks (~> 3.9.0)
54
- rspec-core (3.9.1)
55
- rspec-support (~> 3.9.1)
56
- rspec-expectations (3.9.1)
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.9.0)
59
- rspec-mocks (3.9.1)
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.9.0)
62
- rspec-support (3.9.2)
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.8.1)
85
+ sinatra (2.1.0)
67
86
  mustermann (~> 1.0)
68
- rack (~> 2.0)
69
- rack-protection (= 2.0.8.1)
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.6)
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 (~> 10)
81
- sinatra (~> 2.0, >= 2.0.2)
100
+ rake (~> 12)
101
+ sinatra (~> 2)
82
102
  webspicy!
83
103
 
84
104
  BUNDLED WITH
85
- 2.0.2
105
+ 2.2.1
@@ -1,6 +1,5 @@
1
1
  $LOAD_PATH.unshift File.expand_path("..", __FILE__)
2
2
  require 'app'
3
- require 'webspicy'
4
3
 
5
4
  desc "Checks all .yml definition files"
6
5
  task :check do
@@ -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
@@ -1,6 +1,6 @@
1
1
  require_relative 'config'
2
2
  webspicy_config do |c|
3
- c.client = Webspicy::RackTestClient.for(::Sinatra::Application)
3
+ c.client = Webspicy::Tester::RackTestClient.for(::Sinatra::Application)
4
4
  c.before_each do |_,client|
5
5
  client.api.post "/reset"
6
6
  end
@@ -1,7 +1,7 @@
1
1
  require_relative 'config'
2
2
  webspicy_config do |c|
3
3
  c.host = "http://127.0.0.1:4567"
4
- c.client = Webspicy::HttpClient
4
+ c.client = Webspicy::Tester::HttpClient
5
5
  c.before_each do |_,client|
6
6
  client.api.post "http://127.0.0.1:4567/reset"
7
7
  end
@@ -1,4 +1,4 @@
1
- @import finitio/data
1
+ @import webspicy/scalars
2
2
 
3
3
  Todo = {
4
4
  id : Integer
@@ -6,7 +6,7 @@ Todo = {
6
6
  }
7
7
 
8
8
  TodoPatch = {
9
- id :? Integer
9
+ id : Integer
10
10
  description :? String
11
11
  }
12
12
 
@@ -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}) #{description}
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