webspicy 0.15.8 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +76 -24
  3. data/bin/webspicy +30 -14
  4. data/examples/restful/Gemfile.lock +40 -24
  5. data/examples/restful/Rakefile +0 -1
  6. data/examples/restful/app.rb +4 -1
  7. data/examples/restful/webspicy/config.rb +9 -0
  8. data/examples/restful/webspicy/{todo/deleteTodo.yml → formaldef/todo/_one/delete.yml} +7 -1
  9. data/examples/restful/webspicy/formaldef/todo/_one/get.simpler.yml +46 -0
  10. data/examples/restful/webspicy/{todo/getTodo.yml → formaldef/todo/_one/get.yml} +0 -0
  11. data/examples/restful/webspicy/{todo/patchTodo.yml → formaldef/todo/_one/patch.yml} +3 -0
  12. data/examples/restful/webspicy/{todo/putTodo.yml → formaldef/todo/_one/put.yml} +0 -0
  13. data/examples/restful/webspicy/{todo/getTodos.yml → formaldef/todo/get.yml} +0 -0
  14. data/examples/restful/webspicy/{todo → formaldef/todo}/options.yml +1 -1
  15. data/examples/restful/webspicy/{todo/postCsv.yml → formaldef/todo/post.csv.yml} +0 -0
  16. data/examples/restful/webspicy/{todo/postFile.yml → formaldef/todo/post.file.yml} +1 -1
  17. data/examples/restful/webspicy/{todo/postTodos.yml → formaldef/todo/post.yml} +0 -0
  18. data/examples/restful/webspicy/{todo → formaldef/todo}/todos.csv +0 -0
  19. data/examples/restful/webspicy/rack.rb +1 -1
  20. data/examples/restful/webspicy/real.rb +1 -1
  21. data/examples/restful/webspicy/schema.fio +2 -2
  22. data/examples/restful/webspicy/support/must_be_authenticated.rb +2 -2
  23. data/examples/restful/webspicy/support/todo_not_removed.rb +21 -0
  24. data/examples/restful/webspicy/support/todo_removed.rb +20 -0
  25. data/examples/single_spec/spec.yml +59 -0
  26. data/examples/website/config.rb +2 -0
  27. data/examples/website/schema.fio +1 -0
  28. data/examples/website/specification/get-http.yml +30 -0
  29. data/examples/website/specification/get-https.yml +30 -0
  30. data/lib/finitio/webspicy/scalars.fio +25 -0
  31. data/lib/webspicy.rb +49 -17
  32. data/lib/webspicy/checker.rb +5 -20
  33. data/lib/webspicy/configuration.rb +79 -14
  34. data/lib/webspicy/configuration/scope.rb +154 -0
  35. data/lib/webspicy/configuration/single_url.rb +58 -0
  36. data/lib/webspicy/configuration/single_yml_file.rb +30 -0
  37. data/lib/webspicy/formaldoc.fio +25 -8
  38. data/lib/webspicy/mocker.rb +8 -8
  39. data/lib/webspicy/mocker/config.ru +5 -0
  40. data/lib/webspicy/openapi.rb +1 -0
  41. data/lib/webspicy/openapi/generator.rb +127 -0
  42. data/lib/webspicy/rspec/checker.rb +2 -0
  43. data/lib/webspicy/rspec/checker/rspec_checker.rb +24 -0
  44. data/lib/webspicy/rspec/support/rspec_runnable.rb +27 -0
  45. data/lib/webspicy/rspec/tester.rb +4 -0
  46. data/lib/webspicy/rspec/tester/rspec_asserter.rb +121 -0
  47. data/lib/webspicy/rspec/tester/rspec_matchers.rb +114 -0
  48. data/lib/webspicy/rspec/tester/rspec_tester.rb +63 -0
  49. data/lib/webspicy/{resource.rb → specification.rb} +31 -10
  50. data/lib/webspicy/specification/errcondition.rb +16 -0
  51. data/lib/webspicy/specification/file_upload.rb +37 -0
  52. data/lib/webspicy/specification/postcondition.rb +16 -0
  53. data/lib/webspicy/specification/precondition.rb +19 -0
  54. data/lib/webspicy/specification/precondition/global_request_headers.rb +35 -0
  55. data/lib/webspicy/specification/precondition/robust_to_invalid_input.rb +68 -0
  56. data/lib/webspicy/{resource → specification}/service.rb +38 -25
  57. data/lib/webspicy/specification/test_case.rb +133 -0
  58. data/lib/webspicy/support.rb +2 -0
  59. data/lib/webspicy/support/colorize.rb +28 -0
  60. data/lib/webspicy/support/data_object.rb +25 -0
  61. data/lib/webspicy/support/status_range.rb +6 -1
  62. data/lib/webspicy/tester.rb +8 -77
  63. data/lib/webspicy/tester/asserter.rb +11 -5
  64. data/lib/webspicy/tester/assertions.rb +13 -10
  65. data/lib/webspicy/tester/client.rb +63 -0
  66. data/lib/webspicy/tester/client/http_client.rb +154 -0
  67. data/lib/webspicy/tester/client/rack_test_client.rb +188 -0
  68. data/lib/webspicy/tester/client/support.rb +65 -0
  69. data/lib/webspicy/tester/failure.rb +6 -0
  70. data/lib/webspicy/tester/invocation.rb +70 -0
  71. data/lib/webspicy/version.rb +2 -2
  72. data/spec/{unit/spec_helper.rb → spec_helper.rb} +0 -0
  73. data/spec/unit/configuration/scope/test_each_service.rb +49 -0
  74. data/spec/unit/configuration/scope/test_each_specification.rb +68 -0
  75. data/spec/unit/configuration/scope/test_expand_example.rb +65 -0
  76. data/spec/unit/configuration/scope/test_to_real_url.rb +82 -0
  77. data/spec/unit/openapi/test_generator.rb +28 -0
  78. data/spec/unit/specification/precondition/test_global_request_headers.rb +42 -0
  79. data/spec/unit/{resource → specification}/service/test_dress_params.rb +2 -2
  80. data/spec/unit/specification/test_case/test_mutate.rb +24 -0
  81. data/spec/unit/{resource → specification}/test_instantiate_url.rb +5 -5
  82. data/spec/unit/{resource → specification}/test_url_placeholders.rb +4 -4
  83. data/spec/unit/test_configuration.rb +24 -7
  84. data/spec/unit/tester/client/test_around.rb +61 -0
  85. data/spec/unit/tester/test_asserter.rb +246 -0
  86. data/spec/unit/tester/test_assertions.rb +12 -10
  87. data/tasks/test.rake +3 -1
  88. metadata +106 -48
  89. data/LICENSE.md +0 -22
  90. data/lib/webspicy/client.rb +0 -61
  91. data/lib/webspicy/client/http_client.rb +0 -145
  92. data/lib/webspicy/client/rack_test_client.rb +0 -181
  93. data/lib/webspicy/client/support.rb +0 -48
  94. data/lib/webspicy/file_upload.rb +0 -35
  95. data/lib/webspicy/postcondition.rb +0 -14
  96. data/lib/webspicy/precondition.rb +0 -15
  97. data/lib/webspicy/resource/service/invocation.rb +0 -212
  98. data/lib/webspicy/resource/service/test_case.rb +0 -132
  99. data/lib/webspicy/scope.rb +0 -160
  100. data/spec/unit/client/test_around.rb +0 -59
  101. data/spec/unit/scope/test_each_resource.rb +0 -66
  102. data/spec/unit/scope/test_each_service.rb +0 -47
  103. data/spec/unit/scope/test_expand_example.rb +0 -63
  104. 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: e1d234226f15d51777e61c010557ed1691660613cd87ba11ce19844b2f7cc812
4
- data.tar.gz: 40fcd4639ce847f7f69f3471ef9676c64e8e6be489388563d5abd51ca1bf39d7
3
+ metadata.gz: 63c15addd49634a62ba637d18cfee736f405dc0e144ec688e2fda6861764a09c
4
+ data.tar.gz: 903d3a0ca2f20a5dbac1fafc4a1a89981736d527cb69668a06b41acb5ef04696
5
5
  SHA512:
6
- metadata.gz: c4d0ec9a0567955bac41c5ee887164e783799e2baf66966fabff404147376c29192a4b28090c7d816a20fd15bc7e470b20136e253b9b1a7d663ac57de4958d99
7
- data.tar.gz: 4ddccde82357c81066108133b0e5b63ea8b5a0b714556b56b4d4743ba26aaaf17a9187633061dc2f721b88833cdfb536f795d8256aa158723c4fa5a255957144
6
+ metadata.gz: d54f59f003313e38dd37104e56038b6ede06c7339718498e6dda9730de97acdd0fae5499d45463ef790f78332eb0d337a3f068e3dd08bfec901edb8125a710c2
7
+ data.tar.gz: c43077a9023045856e726c0d2dbe39abc83abbd198df4a765758e6578664bcc6ec44ec7df75e164b436ae6a89cb6fe0ee89b4fc995afd3fe068bef2e5e484144
data/README.md CHANGED
@@ -1,46 +1,98 @@
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
+
6
+ See webspicy in action and make the tutorial on https://yourbackendisbroken.dev
7
+
8
+ Have a look at `doc/*.md` for vocabulary and vision as well as `ROADMAP.md`.
5
9
 
6
10
  ## Features
7
11
 
8
- * Declarative description of RESTful web-services + their tests
12
+ * Declarative specification of HTTP web services + their tests
13
+
14
+ * Framework/language agnostic: `webspicy` is written in Ruby, but can be used
15
+ to test web services for backends written in any language / framework.
16
+
17
+ * Black box testing: `webspicy` focuses on web services seen as blackboxes. It
18
+ has no knowledge of the implementation, and focuses on HTTP and input/output
19
+ data instead. Investing in such testing makes those tests more stable and
20
+ your API design better.
21
+
22
+ * Formal and human-friendly data schema with strong data matching semantics,
23
+ thanks to [http://finitio.io](http://finitio.io)
24
+
25
+ * Test instrumentation and generation, based on PRE & POST contracts.
9
26
 
10
- * Framework/language agnostic: Webspicy is written in Ruby, but can be used to
11
- test web services in any language / framework.
27
+ * Extra goodness for Rubyists: being written in ruby, `webspicy` also supports
28
+ testing Rack applications directly (through rack/test), which boosts the
29
+ test suite.
12
30
 
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.
31
+ * Extra goodies: when a specification is written, it can also be used for
32
+ mocking the API, generating an openapi file, etc.
17
33
 
18
- * Test instrumentation and generation, based on declarative PRE & POST
19
- conditions.
34
+ ## Is this used on real-world cases?
20
35
 
21
- * Extra goodness for Rubyists: being written in ruby, Webspicy also supports
22
- testing Rack applications directly (through rack/test)
36
+ Yes, `webspicy` is currently used on a dozen production components. Our biggest specification has 324 specification files for thousands of tests, 35% of them being generated.
23
37
 
24
- ## Getting started
38
+ ## Getting started with the commandline
25
39
 
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.
40
+ To install webspicy on your developer computer, install ruby then:
29
41
 
30
- ## Executing the tests using the command line
42
+ ```
43
+ gem install webspicy
44
+ ```
31
45
 
32
- Please have a look at the examples first. Then:
46
+ Then execute webspicy help to see the options.
33
47
 
34
48
  ```
35
49
  webspicy --help
36
- webspicy path/to/your/config.rb
37
50
  ```
38
51
 
39
- ## Using the docker image
52
+ ## Using the docker image(s)
53
+
54
+ If you just want to play with the commandline tool without having to
55
+ install ruby & webspicy, you can use the docker image we provide for
56
+ the commandline:
57
+
58
+ ```
59
+ docker run enspirit/webspicy --help
60
+ ```
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
+ If you have a specification & test suite somewhere, an easy way to run the
63
+ whole suite (or integrate it in your continuous integration pipeline) is
64
+ to use our `:tester` docker image. Just mount your test suite as a volume
65
+ in `/home/app` and you are good to go:
43
66
 
44
67
  ```
45
- docker run enspirit/webspicy -v path/to/tests:/home/app
68
+ docker run -v path/to/tests:/formalspec enspirit/webspicy:tester
46
69
  ```
70
+
71
+ If your plan is to test a backend that runs on your own machine (vs.
72
+ publicly on the Internet or inside the default docker network),
73
+ you will need to add some networking option, as shown below. Please
74
+ refer to Docker documentation.
75
+
76
+ ```
77
+ docker run -v path/to/tests:/formalspec --network=host enspirit/webspicy:tester
78
+ ```
79
+
80
+ ## Contributing
81
+
82
+ Please use github issues for questions and bugs, and pull requests for
83
+ submitting improvement proposals and new features.
84
+
85
+ ## Contributors
86
+
87
+ * Bernard Lambeau (blambeau)
88
+ * Louis Lambeau (llambeau)
89
+ * Yoann Guyot (ygu)
90
+ * Felix Holmgren (@felixyz)
91
+
92
+ Enspirit (https://enspirit.be) and Klaro App (https://klaro.cards) are
93
+ both actively using, contributing and funding work on this library.
94
+ Please contact Bernard Lambeau for any question.
95
+
96
+ ## Licence
97
+
98
+ 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,15 +1,17 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- webspicy (0.15.8)
5
- finitio (>= 0.8.0)
4
+ webspicy (0.17.0)
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
- rspec (~> 3.7)
14
+ rspec (~> 3.10)
13
15
  rspec_junit_formatter (~> 0.4.1)
14
16
 
15
17
  GEM
@@ -18,14 +20,18 @@ GEM
18
20
  addressable (2.7.0)
19
21
  public_suffix (>= 2.0.2, < 5.0)
20
22
  citrus (3.0.2)
23
+ colorize (0.8.1)
24
+ commonmarker (0.21.0)
25
+ ruby-enum (~> 0.5)
26
+ concurrent-ruby (1.1.7)
21
27
  diff-lcs (1.4.4)
22
28
  domain_name (0.5.20190701)
23
29
  unf (>= 0.0.5, < 1.0.0)
24
- ffi (1.13.1)
30
+ ffi (1.14.2)
25
31
  ffi-compiler (1.0.1)
26
32
  ffi (>= 1.0.0)
27
33
  rake
28
- finitio (0.8.0)
34
+ finitio (0.9.1)
29
35
  citrus (>= 2.4, < 4.0)
30
36
  hansi (0.2.0)
31
37
  http (4.4.1)
@@ -36,42 +42,50 @@ GEM
36
42
  http-cookie (1.0.3)
37
43
  domain_name (~> 0.5)
38
44
  http-form_data (2.3.0)
39
- http-parser (1.2.1)
45
+ http-parser (1.2.3)
40
46
  ffi-compiler (>= 1.0, < 2.0)
47
+ i18n (1.8.7)
48
+ concurrent-ruby (~> 1.0)
41
49
  mustermann (1.1.1)
42
50
  ruby2_keywords (~> 0.0.1)
43
51
  mustermann-contrib (1.1.1)
44
52
  hansi (~> 0.2.0)
45
53
  mustermann (= 1.1.1)
54
+ openapi3_parser (0.8.2)
55
+ commonmarker (~> 0.17)
56
+ psych (~> 3.1)
46
57
  path (2.0.1)
47
- public_suffix (4.0.5)
58
+ psych (3.3.0)
59
+ public_suffix (4.0.6)
48
60
  rack (2.2.3)
49
- rack-protection (2.0.8.1)
61
+ rack-protection (2.1.0)
50
62
  rack
51
63
  rack-robustness (1.1.0)
52
64
  rack-test (0.6.3)
53
65
  rack (>= 1.0)
54
66
  rake (12.3.3)
55
- rspec (3.9.0)
56
- rspec-core (~> 3.9.0)
57
- rspec-expectations (~> 3.9.0)
58
- rspec-mocks (~> 3.9.0)
59
- rspec-core (3.9.2)
60
- rspec-support (~> 3.9.3)
61
- rspec-expectations (3.9.2)
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.1)
72
+ rspec-support (~> 3.10.0)
73
+ rspec-expectations (3.10.1)
62
74
  diff-lcs (>= 1.2.0, < 2.0)
63
- rspec-support (~> 3.9.0)
64
- rspec-mocks (3.9.1)
75
+ rspec-support (~> 3.10.0)
76
+ rspec-mocks (3.10.1)
65
77
  diff-lcs (>= 1.2.0, < 2.0)
66
- rspec-support (~> 3.9.0)
67
- rspec-support (3.9.3)
78
+ rspec-support (~> 3.10.0)
79
+ rspec-support (3.10.1)
68
80
  rspec_junit_formatter (0.4.1)
69
81
  rspec-core (>= 2, < 4, != 2.12.0)
82
+ ruby-enum (0.8.0)
83
+ i18n
70
84
  ruby2_keywords (0.0.2)
71
- sinatra (2.0.8.1)
85
+ sinatra (2.1.0)
72
86
  mustermann (~> 1.0)
73
- rack (~> 2.0)
74
- rack-protection (= 2.0.8.1)
87
+ rack (~> 2.2)
88
+ rack-protection (= 2.1.0)
75
89
  tilt (~> 2.0)
76
90
  tilt (2.0.10)
77
91
  unf (0.1.4)
@@ -80,6 +94,8 @@ GEM
80
94
 
81
95
  PLATFORMS
82
96
  ruby
97
+ x86_64-darwin-15
98
+ x86_64-darwin-18
83
99
 
84
100
  DEPENDENCIES
85
101
  rake (~> 12)
@@ -87,4 +103,4 @@ DEPENDENCIES
87
103
  webspicy!
88
104
 
89
105
  BUNDLED WITH
90
- 2.0.2
106
+ 2.2.2
@@ -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,15 @@ 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
+ c.errcondition TodoNotRemoved
15
+
7
16
  c.instrument do |tc, client|
8
17
  role = tc.metadata[:role]
9
18
  tc.headers['Authorization'] = "Bearer #{role}" if role
@@ -15,13 +15,19 @@ services:
15
15
  preconditions:
16
16
  - Must be an admin
17
17
 
18
+ postconditions:
19
+ - The todo has been removed
20
+
21
+ errconditions:
22
+ - If it existed, the todo has not been removed
23
+
18
24
  input_schema: |-
19
25
  {
20
26
  id: Integer
21
27
  }
22
28
 
23
29
  output_schema: |-
24
- .
30
+ Any
25
31
 
26
32
  error_schema: |-
27
33
  ErrorSchema
@@ -0,0 +1,46 @@
1
+ ---
2
+ url: |-
3
+ /todo/{id}
4
+
5
+ method: |-
6
+ GET
7
+
8
+ description: |-
9
+ Returns a single todo item
10
+
11
+ input_schema: |-
12
+ {
13
+ id: Integer
14
+ }
15
+
16
+ output_schema: |-
17
+ Todo
18
+
19
+ error_schema: |-
20
+ ErrorSchema
21
+
22
+ examples:
23
+
24
+ - description: |-
25
+ when requested on an existing TODO
26
+ params:
27
+ id: 1
28
+ expected:
29
+ content_type: application/json
30
+ status: 200
31
+ assert:
32
+ - "pathFD('', id: 1)"
33
+ - "match('description', /Refactor/)"
34
+ - "notMatch('description', /Foo/)"
35
+
36
+ counterexamples:
37
+
38
+ - description: |-
39
+ when requested on an unexisting TODO
40
+ params:
41
+ id: 999254654
42
+ expected:
43
+ content_type: application/json
44
+ status: 404
45
+ assert:
46
+ - "pathFD('', error: 'No such todo')"