api-tester 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +56 -47
- data/changelog.txt +6 -0
- data/lib/tester/api_tester.rb +4 -2
- data/lib/tester/definition/api_contract.rb +13 -0
- data/lib/tester/definition/api_method.rb +11 -0
- data/lib/tester/definition/endpoint.rb +36 -5
- data/lib/tester/definition/response.rb +3 -3
- data/lib/tester/method_case_test.rb +8 -8
- data/lib/tester/modules/extra_verbs.rb +25 -0
- data/lib/tester/modules/format.rb +1 -1
- data/lib/tester/modules/good_case.rb +5 -5
- data/lib/tester/modules/module.rb +0 -19
- data/lib/tester/modules/typo.rb +14 -41
- data/lib/tester/test_helper.rb +3 -0
- data/lib/tester/util/response_evaluator.rb +3 -3
- data/lib/tester/util/supported_verbs.rb +0 -36
- data/lib/tester/version.rb +1 -1
- metadata +5 -18
- data/lib/tester/definition/methods/api_copy.rb +0 -13
- data/lib/tester/definition/methods/api_delete.rb +0 -13
- data/lib/tester/definition/methods/api_get.rb +0 -16
- data/lib/tester/definition/methods/api_head.rb +0 -16
- data/lib/tester/definition/methods/api_lock.rb +0 -13
- data/lib/tester/definition/methods/api_method.rb +0 -21
- data/lib/tester/definition/methods/api_mkcol.rb +0 -13
- data/lib/tester/definition/methods/api_move.rb +0 -13
- data/lib/tester/definition/methods/api_options.rb +0 -16
- data/lib/tester/definition/methods/api_patch.rb +0 -18
- data/lib/tester/definition/methods/api_post.rb +0 -18
- data/lib/tester/definition/methods/api_propfind.rb +0 -13
- data/lib/tester/definition/methods/api_proppatch.rb +0 -13
- data/lib/tester/definition/methods/api_put.rb +0 -18
- data/lib/tester/definition/methods/api_trace.rb +0 -13
- data/lib/tester/definition/methods/api_unlock.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41988c02130d7463e08e3d41c50f17a60fc3e562
|
4
|
+
data.tar.gz: 19dc7c39a0156c600029ba34d2f533ffe0934bde
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e7d21836ff7dc8928b68f50b3d6e117f3823bd24fff3e2145dbaee0a0f0367fc7b317bf365a2ae41657ab636b214e9a73b909023f88a8f471c6ed8a6b11140b
|
7
|
+
data.tar.gz: d2b4ccb62ee4907c327a45a5bde32fbc8e6f8a0afe7d1d936725a77e6acbcb39c4911ea480240d933986399d23bff43d1cc3ad262dfe4227f34b3eaa8328168f
|
data/README.md
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/api-tester.svg)](https://badge.fury.io/rb/api-tester)
|
3
3
|
[![Build Status](https://travis-ci.org/araneforseti/api-tester.svg?branch=master)](https://travis-ci.org/araneforseti/api-tester)
|
4
4
|
|
5
|
-
Work in Progress! Use at own risk, definitely not ready
|
5
|
+
Work in Progress! Use at own risk, definitely not ready
|
6
6
|
for prime time! To isolate your project from the changes, be sure to specify which gem version you use.
|
7
7
|
|
8
|
-
This gem is intended to enable easy creation of tests for
|
8
|
+
This gem is intended to enable easy creation of tests for
|
9
9
|
RESTful API services when given a contract.
|
10
10
|
|
11
11
|
Check out [API Tester Example](https://github.com/araneforseti/example_api-tester) for an example in action
|
@@ -15,22 +15,24 @@ Check out [API Tester Example](https://github.com/araneforseti/example_api-teste
|
|
15
15
|
Check out our [Trello Board](https://trello.com/b/R3RtsJ2A/api-tester) to see progress and where we are headed!
|
16
16
|
Feel free to leave feedback through github's issue tracker
|
17
17
|
|
18
|
-
- Format module:
|
19
|
-
- Checks syntax problems with the request and
|
18
|
+
- Format module:
|
19
|
+
- Checks syntax problems with the request and
|
20
20
|
ensuring a consistent response
|
21
21
|
- Typo module:
|
22
|
-
- Tests
|
23
|
-
-
|
24
|
-
- Checks
|
25
|
-
|
22
|
+
- Tests simulates typos in the url
|
23
|
+
- Extra Verbs module:
|
24
|
+
- Checks all the supported verbs to ensure no vulnerabilities are exposed
|
25
|
+
- Good Case (name pending) module:
|
26
|
+
- Checks expected good requests will work
|
27
|
+
(eg, number field should accept integers
|
26
28
|
between 1 - 100)
|
27
29
|
- Unused Fields module:
|
28
30
|
- A module which runs after all the others and reports on any response fields which were never returned
|
29
|
-
|
31
|
+
|
30
32
|
## Intended Features Before "Release"
|
31
33
|
|
32
34
|
- Other Param Testing
|
33
|
-
- Path
|
35
|
+
- Path params
|
34
36
|
- Query
|
35
37
|
- Headers
|
36
38
|
- Endpoint Testing
|
@@ -40,10 +42,10 @@ Feel free to leave feedback through github's issue tracker
|
|
40
42
|
- Documentation
|
41
43
|
- Generate Swagger-compliant documentation
|
42
44
|
- Generate definitions from Swagger documentation
|
43
|
-
|
45
|
+
|
44
46
|
## What is this not intended for?
|
45
47
|
|
46
|
-
- Logic testing (eg, if X is between A and B, then Y is
|
48
|
+
- Logic testing (eg, if X is between A and B, then Y is
|
47
49
|
required)
|
48
50
|
|
49
51
|
# Usage
|
@@ -65,29 +67,30 @@ Or install it yourself as:
|
|
65
67
|
|
66
68
|
## Usage in Code
|
67
69
|
|
68
|
-
Warning: This gem is still in alpha stage. Use at own risk
|
69
|
-
understanding the contract will change until the first
|
70
|
+
Warning: This gem is still in alpha stage. Use at own risk
|
71
|
+
understanding the contract will change until the first
|
70
72
|
stable release
|
71
73
|
|
72
|
-
Define your endpoints using
|
74
|
+
Define your contract and endpoints using
|
73
75
|
```ruby
|
76
|
+
require 'tester/definition/api_contract'
|
77
|
+
require 'tester/definition/endpoint'
|
78
|
+
contract = ApiContract.new "API Name"
|
74
79
|
endpoint = Endpoint.new "Some name which is currently unused", "http://yourbase.com/api/endpoint"
|
75
80
|
```
|
76
81
|
|
77
82
|
Define methods on endpoints
|
78
83
|
|
79
84
|
```ruby
|
80
|
-
|
85
|
+
endpoint.add_method SupportedVerbs::GET, expected_response, expected_request
|
81
86
|
```
|
82
|
-
Note:
|
83
|
-
you can make your own so long as it has `call` and `verb` methods
|
84
|
-
which will execute the method given parameters
|
87
|
+
Note: While an extensive list of verbs exists in SupportedVerbs, you can define your own (with the caveat they have to be supported by RestClient)
|
85
88
|
|
86
89
|
Define fields used by the method (both Request and Response)
|
87
90
|
```ruby
|
88
|
-
|
91
|
+
expected_request = Request.new.add_field(Field.new "fieldName")
|
89
92
|
```
|
90
|
-
Note: Similar to methods, you can create your own fields.
|
93
|
+
Note: Similar to methods, you can create your own fields.
|
91
94
|
They need to repond to:
|
92
95
|
```ruby
|
93
96
|
field.has_subfields?
|
@@ -98,19 +101,18 @@ Put them together and call go and off you go!
|
|
98
101
|
```ruby
|
99
102
|
request = Request.new.add_field(Field.new "fieldName")
|
100
103
|
expected_response = Response.new(200).add_field(Field.new "fieldName")
|
101
|
-
get_method = ApiGet.new
|
102
|
-
get_method.request = request
|
103
|
-
get_method.expected_response = expected_response
|
104
104
|
endpoint = Endpoint.new "Unused Name", "http://yourbase.com/api/endpoint"
|
105
|
-
endpoint.add_method
|
106
|
-
|
105
|
+
endpoint.add_method SupportedVerbs::GET, expected_response, request
|
106
|
+
contract = ApiContract.new "API Name"
|
107
|
+
contract.add_endpoint endpoint
|
108
|
+
tester = ApiTester.new(contract).with_module(Format.new)
|
107
109
|
expect(tester.go).to be true
|
108
110
|
|
109
111
|
```
|
110
112
|
|
111
113
|
## Dependencies
|
112
114
|
|
113
|
-
If your API
|
115
|
+
If any of your API endpoints have some setup which needs to happen before or after each call (eg, path param represents resource which needs to be created), you can use the TestHelper interface:
|
114
116
|
|
115
117
|
```ruby
|
116
118
|
class InfoCreator < TestHelper
|
@@ -118,6 +120,10 @@ class InfoCreator < TestHelper
|
|
118
120
|
puts "This code runs before every call"
|
119
121
|
end
|
120
122
|
|
123
|
+
def retrieve_param key
|
124
|
+
puts "If any created data needs to be accessed (eg, a path param), allow it to be retrieved here"
|
125
|
+
end
|
126
|
+
|
121
127
|
def after
|
122
128
|
puts "This code runs after every call"
|
123
129
|
end
|
@@ -130,31 +136,35 @@ expect(tester.go).to be true
|
|
130
136
|
|
131
137
|
# Modules
|
132
138
|
## Boundary
|
133
|
-
This module will test out various edge cases and
|
139
|
+
This module will test out various edge cases and
|
134
140
|
ensure error handling is consistent
|
135
141
|
|
136
142
|
## Good Case
|
137
|
-
This module ensures your 'default request' works
|
143
|
+
This module ensures your 'default request' works
|
138
144
|
appropriately
|
139
145
|
|
140
146
|
## Typo
|
141
|
-
This module checks for common integration issues when an
|
142
|
-
API is first being worked against such as urls which don't
|
143
|
-
exist
|
147
|
+
This module checks for common integration issues when an
|
148
|
+
API is first being worked against such as urls which don't
|
149
|
+
exist
|
150
|
+
|
151
|
+
## Extra Verbs
|
152
|
+
This module checks to ensure consistency in response when
|
153
|
+
the api receives verbs it doesn't explicitly support
|
144
154
|
|
145
155
|
## Unused Fields
|
146
156
|
If any response fields are not returned during tests run
|
147
|
-
by previous modules, this will fail with a report
|
148
|
-
detailing unreturned response fields. When using this
|
149
|
-
module, it is recommended the good case module is also
|
157
|
+
by previous modules, this will fail with a report
|
158
|
+
detailing unreturned response fields. When using this
|
159
|
+
module, it is recommended the good case module is also
|
150
160
|
used.
|
151
161
|
|
152
162
|
# Reporting
|
153
|
-
Right now the default reporting mechanism prints out to
|
154
|
-
the console all the issues which were found. You can
|
155
|
-
create your own reporting class (so long as it responds
|
156
|
-
to the same methods) or just extend the current one and
|
157
|
-
override the print method. Then set the tester's report
|
163
|
+
Right now the default reporting mechanism prints out to
|
164
|
+
the console all the issues which were found. You can
|
165
|
+
create your own reporting class (so long as it responds
|
166
|
+
to the same methods) or just extend the current one and
|
167
|
+
override the print method. Then set the tester's report
|
158
168
|
tool:
|
159
169
|
```ruby
|
160
170
|
tester.with_reporter(new_reporter)
|
@@ -162,22 +172,21 @@ tester.with_reporter(new_reporter)
|
|
162
172
|
|
163
173
|
# Development
|
164
174
|
|
165
|
-
After checking out the repo, run `bin/setup` to install
|
166
|
-
dependencies. Then, run `rake spec` to run the tests.
|
167
|
-
You can also run `bin/console` for an interactive prompt
|
175
|
+
After checking out the repo, run `bin/setup` to install
|
176
|
+
dependencies. Then, run `rake spec` to run the tests.
|
177
|
+
You can also run `bin/console` for an interactive prompt
|
168
178
|
that will allow you to experiment.
|
169
179
|
|
170
|
-
To install this gem onto your local machine,
|
180
|
+
To install this gem onto your local machine,
|
171
181
|
run `bundle exec rake install`.
|
172
182
|
|
173
183
|
## Contributing
|
174
184
|
|
175
|
-
Bug reports and pull requests are welcome on GitHub at
|
185
|
+
Bug reports and pull requests are welcome on GitHub at
|
176
186
|
https://github.com/araneforseti/api-tester.
|
177
187
|
|
178
188
|
|
179
189
|
# License
|
180
190
|
|
181
|
-
The gem is available as open source under the terms
|
191
|
+
The gem is available as open source under the terms
|
182
192
|
of the [MIT License](http://opensource.org/licenses/MIT).
|
183
|
-
|
data/changelog.txt
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
0.1.0
|
2
|
+
|
3
|
+
- Moving call to endpoint for path param support
|
4
|
+
- Adding top level Contract to bind endpoints together
|
5
|
+
- Moved extra verbs check out of typo to its own module
|
6
|
+
|
1
7
|
0.0.5
|
2
8
|
|
3
9
|
- Adding support for delete, put, head, options, copy, mkcol, move, propfind, proppatch, trace, lock, unlock, and patch verbs
|
data/lib/tester/api_tester.rb
CHANGED
@@ -38,8 +38,10 @@ class ApiTester
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def go
|
41
|
-
self.
|
42
|
-
mod.
|
41
|
+
self.definition.endpoints.each do |endpoint|
|
42
|
+
self.modules.sort_by{ |mod| mod.order }.each do |mod|
|
43
|
+
mod.go endpoint, self.report
|
44
|
+
end
|
43
45
|
end
|
44
46
|
|
45
47
|
self.report.print
|
@@ -1,26 +1,57 @@
|
|
1
1
|
require 'tester/definition/response'
|
2
|
+
require 'tester/definition/api_method'
|
2
3
|
|
3
4
|
class Endpoint
|
4
|
-
attr_accessor :url
|
5
|
-
attr_accessor :methods
|
6
5
|
attr_accessor :name
|
6
|
+
attr_accessor :base_url
|
7
|
+
attr_accessor :path_params
|
8
|
+
attr_accessor :methods
|
7
9
|
attr_accessor :test_helper
|
8
10
|
attr_accessor :bad_request_response
|
9
11
|
attr_accessor :not_allowed_response
|
10
12
|
attr_accessor :not_found_response
|
11
13
|
|
12
14
|
def initialize name, url
|
13
|
-
self.
|
15
|
+
self.base_url = url
|
14
16
|
self.name = name
|
15
17
|
self.methods = []
|
18
|
+
self.path_params = []
|
16
19
|
self.test_helper = TestHelper.new
|
17
20
|
self.bad_request_response = Response.new 400
|
18
21
|
self.not_allowed_response = Response.new 415
|
19
22
|
self.not_found_response = Response.new 404
|
20
23
|
end
|
21
24
|
|
22
|
-
def
|
23
|
-
self.
|
25
|
+
def url
|
26
|
+
temp_url = self.base_url
|
27
|
+
self.path_params.each do |param|
|
28
|
+
temp_url.sub! "{#{param}}", self.test_helper.retrieve_param(param)
|
29
|
+
end
|
30
|
+
temp_url
|
31
|
+
end
|
32
|
+
|
33
|
+
def call method, payload={}, headers={}
|
34
|
+
self.test_helper.before
|
35
|
+
begin
|
36
|
+
response = RestClient::Request.execute(method: method.verb, url: self.url, payload: payload, headers: headers)
|
37
|
+
rescue RestClient::ExceptionWithResponse => e
|
38
|
+
response = e.response
|
39
|
+
end
|
40
|
+
self.test_helper.after
|
41
|
+
response
|
42
|
+
end
|
43
|
+
|
44
|
+
def add_method verb, response, request=Request.new()
|
45
|
+
self.methods << ApiMethod.new(verb, response, request)
|
24
46
|
self
|
25
47
|
end
|
48
|
+
|
49
|
+
def add_path_param param
|
50
|
+
self.path_params << param
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def verbs
|
55
|
+
self.methods.map(&:verb)
|
56
|
+
end
|
26
57
|
end
|
@@ -2,7 +2,7 @@ class Response
|
|
2
2
|
attr_accessor :code
|
3
3
|
attr_accessor :body
|
4
4
|
|
5
|
-
def initialize(status_code)
|
5
|
+
def initialize(status_code=200)
|
6
6
|
self.code = status_code
|
7
7
|
self.body = []
|
8
8
|
end
|
@@ -14,7 +14,7 @@ class Response
|
|
14
14
|
|
15
15
|
def to_s
|
16
16
|
des = {}
|
17
|
-
|
17
|
+
self.body.map do |f|
|
18
18
|
des[f.name] = field_display f
|
19
19
|
end
|
20
20
|
des.to_json
|
@@ -24,7 +24,7 @@ class Response
|
|
24
24
|
des = field.display_class
|
25
25
|
if field.has_subfields?
|
26
26
|
des = {}
|
27
|
-
|
27
|
+
field.fields.map do |f|
|
28
28
|
des[f.name] = field_display f
|
29
29
|
end
|
30
30
|
des.to_json
|
@@ -16,25 +16,25 @@ class MethodCaseTest
|
|
16
16
|
self.url = "#{verb} #{url}"
|
17
17
|
self.module_name = module_name
|
18
18
|
end
|
19
|
-
|
20
|
-
def response_code_report
|
19
|
+
|
20
|
+
def response_code_report
|
21
21
|
report = StatusCodeReport.new "#{module_name} - Incorrect response code", self.url, self.payload, self.expected_response.code, self.response.code
|
22
22
|
self.reports << report
|
23
23
|
nil
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def missing_field_report field
|
27
27
|
report = Report.new "#{module_name} - Missing field #{field}", self.url, self.payload, self.expected_response, self.response
|
28
28
|
self.reports << report
|
29
29
|
nil
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def extra_field_report field
|
33
33
|
report = Report.new "#{module_name} - Found extra field #{field}", self.url, self.payload, self.expected_response, self.response
|
34
34
|
self.reports << report
|
35
35
|
nil
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def check
|
39
39
|
if check_response_code
|
40
40
|
evaluator = ResponseEvaluator.new json_parse(self.response.body), self.expected_response
|
@@ -44,7 +44,7 @@ class MethodCaseTest
|
|
44
44
|
end
|
45
45
|
return self.reports
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def check_response_code
|
49
49
|
if response.code != expected_response.code
|
50
50
|
response_code_report
|
@@ -52,13 +52,13 @@ class MethodCaseTest
|
|
52
52
|
end
|
53
53
|
return true
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
def increment_fields seen_fields
|
57
57
|
seen_fields.each do |field|
|
58
58
|
field.seen
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
def json_parse body
|
63
63
|
JSON.parse!(body)
|
64
64
|
rescue JSON::ParserError
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'tester/modules/module'
|
2
|
+
require 'tester/util/supported_verbs'
|
3
|
+
|
4
|
+
class ExtraVerbs < Module
|
5
|
+
def go(endpoint, report)
|
6
|
+
super
|
7
|
+
|
8
|
+
extras = SupportedVerbs.all - endpoint.verbs
|
9
|
+
extras.each do |verb|
|
10
|
+
verb_case = BoundaryCase.new("Verb check with #{verb} for #{endpoint.name}", {}, {})
|
11
|
+
method = ApiMethod.new verb, Response.new, Request.new
|
12
|
+
response = endpoint.call method, verb_case.payload, verb_case.headers
|
13
|
+
test = VerbClass.new response, verb_case.payload, endpoint.not_allowed_response, endpoint.url, verb
|
14
|
+
reports = test.check
|
15
|
+
self.report.reports.concat reports
|
16
|
+
end
|
17
|
+
self.report.reports == []
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class VerbClass < MethodCaseTest
|
22
|
+
def initialize response, payload, expected_response, url, verb
|
23
|
+
super response, payload, expected_response, url, verb, "VerbModule"
|
24
|
+
end
|
25
|
+
end
|
@@ -9,7 +9,7 @@ class Format < Module
|
|
9
9
|
definition.methods.each do |method|
|
10
10
|
cases = method.request.cases
|
11
11
|
cases.each do |format_case|
|
12
|
-
response =
|
12
|
+
response = definition.call method, format_case.payload, format_case.headers
|
13
13
|
test = FormatTest.new response, format_case.payload, definition.bad_request_response, definition.url, method.verb
|
14
14
|
self.report.reports.concat test.check
|
15
15
|
end
|
@@ -3,13 +3,13 @@ require 'tester/modules/module'
|
|
3
3
|
require 'tester/method_case_test'
|
4
4
|
|
5
5
|
class GoodCase < Module
|
6
|
-
def go
|
6
|
+
def go endpoint, report
|
7
7
|
super
|
8
8
|
|
9
|
-
|
10
|
-
default_case = BoundaryCase.new
|
11
|
-
response =
|
12
|
-
test = GoodCaseTest.new response,
|
9
|
+
endpoint.methods.each do |method|
|
10
|
+
default_case = BoundaryCase.new endpoint.url, method.request.default_payload, method.request.default_headers
|
11
|
+
response = endpoint.call method, default_case.payload, default_case.headers
|
12
|
+
test = GoodCaseTest.new response, endpoint.url, method
|
13
13
|
self.report.reports.concat test.check
|
14
14
|
end
|
15
15
|
|
@@ -15,23 +15,4 @@ class Module
|
|
15
15
|
def order
|
16
16
|
5
|
17
17
|
end
|
18
|
-
|
19
|
-
def before definition
|
20
|
-
definition.test_helper.before
|
21
|
-
end
|
22
|
-
|
23
|
-
def after definition
|
24
|
-
definition.test_helper.after
|
25
|
-
end
|
26
|
-
|
27
|
-
def call method, definition, format_case
|
28
|
-
self.before definition
|
29
|
-
begin
|
30
|
-
response = method.call definition.url, format_case.payload, format_case.headers
|
31
|
-
rescue RestClient::ExceptionWithResponse => e
|
32
|
-
response = e.response
|
33
|
-
end
|
34
|
-
self.after definition
|
35
|
-
response
|
36
|
-
end
|
37
18
|
end
|
data/lib/tester/modules/typo.rb
CHANGED
@@ -3,61 +3,34 @@ require 'tester/modules/module'
|
|
3
3
|
require 'tester/util/supported_verbs'
|
4
4
|
|
5
5
|
class Typo < Module
|
6
|
-
def go(
|
6
|
+
def go(endpoint, report)
|
7
7
|
super
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
contract.each do |url, verbs|
|
12
|
-
check_verbs definition, url, verbs
|
13
|
-
|
14
|
-
check_typo_url definition, url
|
9
|
+
allowances(endpoint).each do |verbs|
|
10
|
+
check_typo_url endpoint
|
15
11
|
end
|
16
12
|
|
17
13
|
report.reports == []
|
18
14
|
end
|
19
15
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
check_method = create_api_method verb
|
24
|
-
typo_case = BoundaryCase.new("Typo verb check #{verb}", {}, {})
|
25
|
-
response = self.call check_method, definition, typo_case
|
26
|
-
|
27
|
-
test = TypoClass.new response, typo_case.payload, definition.not_allowed_response, url, verb
|
28
|
-
reports = test.check
|
29
|
-
self.report.reports.concat reports
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def check_typo_url definition, url
|
34
|
-
bad_url = "#{url}gibberishadsfasdf"
|
35
|
-
bad_definition = Endpoint.new "Bad URL", bad_url
|
16
|
+
def check_typo_url endpoint
|
17
|
+
bad_url = "#{endpoint.url}gibberishadsfasdf"
|
18
|
+
bad_endpoint = Endpoint.new "Bad URL", bad_url
|
36
19
|
typo_case = BoundaryCase.new("Typo URL check", {}, {})
|
37
|
-
|
38
|
-
response =
|
20
|
+
method = ApiMethod.new SupportedVerbs::GET, Response.new(200), Request.new
|
21
|
+
response = bad_endpoint.call method, typo_case.payload, typo_case.headers
|
39
22
|
|
40
|
-
test = TypoClass.new response, typo_case.payload,
|
23
|
+
test = TypoClass.new response, typo_case.payload, endpoint.not_found_response, bad_url, SupportedVerbs::GET
|
41
24
|
reports = test.check
|
42
25
|
self.report.reports.concat reports
|
43
26
|
end
|
44
27
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
def allowances(definition)
|
51
|
-
allowances = {}
|
52
|
-
definition.methods.each do |method|
|
53
|
-
url = definition.url
|
54
|
-
if allowances[url]
|
55
|
-
allowances[url] << method.verb
|
56
|
-
else
|
57
|
-
allowances[url] = [method.verb]
|
58
|
-
end
|
28
|
+
def allowances(endpoint)
|
29
|
+
allowances = []
|
30
|
+
endpoint.methods.each do |method|
|
31
|
+
allowances << method.verb
|
59
32
|
end
|
60
|
-
allowances
|
33
|
+
allowances.uniq
|
61
34
|
end
|
62
35
|
end
|
63
36
|
|
data/lib/tester/test_helper.rb
CHANGED
@@ -19,7 +19,7 @@ class ResponseEvaluator
|
|
19
19
|
seen = []
|
20
20
|
fields = response_field_array - extra_fields
|
21
21
|
expected = expected_fields_hash
|
22
|
-
fields.each do |field_key|
|
22
|
+
fields.each do |field_key|
|
23
23
|
seen << expected[field_key]
|
24
24
|
end
|
25
25
|
seen
|
@@ -64,10 +64,10 @@ class ResponseEvaluator
|
|
64
64
|
fields.concat(field_array(value).map{|i| "#{key}.#{i}"})
|
65
65
|
else
|
66
66
|
fields.concat(field_array(key))
|
67
|
-
end
|
67
|
+
end
|
68
68
|
end
|
69
69
|
fields
|
70
|
-
rescue NoMethodError
|
70
|
+
rescue NoMethodError
|
71
71
|
fields
|
72
72
|
end
|
73
73
|
end
|
@@ -1,19 +1,3 @@
|
|
1
|
-
require 'tester/definition/methods/api_copy'
|
2
|
-
require 'tester/definition/methods/api_delete'
|
3
|
-
require 'tester/definition/methods/api_get'
|
4
|
-
require 'tester/definition/methods/api_head'
|
5
|
-
require 'tester/definition/methods/api_lock'
|
6
|
-
require 'tester/definition/methods/api_mkcol'
|
7
|
-
require 'tester/definition/methods/api_move'
|
8
|
-
require 'tester/definition/methods/api_options'
|
9
|
-
require 'tester/definition/methods/api_patch'
|
10
|
-
require 'tester/definition/methods/api_post'
|
11
|
-
require 'tester/definition/methods/api_propfind'
|
12
|
-
require 'tester/definition/methods/api_proppatch'
|
13
|
-
require 'tester/definition/methods/api_put'
|
14
|
-
require 'tester/definition/methods/api_trace'
|
15
|
-
require 'tester/definition/methods/api_unlock'
|
16
|
-
|
17
1
|
class SupportedVerbs
|
18
2
|
def SupportedVerbs.add_item(key, value)
|
19
3
|
@hash ||= {}
|
@@ -32,26 +16,6 @@ class SupportedVerbs
|
|
32
16
|
@hash.values
|
33
17
|
end
|
34
18
|
|
35
|
-
def SupportedVerbs.get_method_for(verb)
|
36
|
-
{
|
37
|
-
:copy => ApiCopy,
|
38
|
-
:delete => ApiDelete,
|
39
|
-
:get => ApiGet,
|
40
|
-
:head => ApiHead,
|
41
|
-
:lock => ApiLock,
|
42
|
-
:mkcol => ApiMkcol,
|
43
|
-
:move => ApiMove,
|
44
|
-
:options => ApiOptions,
|
45
|
-
:patch => ApiPatch,
|
46
|
-
:post => ApiPost,
|
47
|
-
:propfind => ApiPropfind,
|
48
|
-
:proppatch => ApiProppatch,
|
49
|
-
:put => ApiPut,
|
50
|
-
:unlock => ApiUnlock,
|
51
|
-
:trace => ApiTrace
|
52
|
-
}[verb]
|
53
|
-
end
|
54
|
-
|
55
19
|
SupportedVerbs.add_item :COPY, :copy
|
56
20
|
SupportedVerbs.add_item :DELETE, :delete
|
57
21
|
SupportedVerbs.add_item :GET, :get
|
data/lib/tester/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api-tester
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- arane
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -101,6 +101,8 @@ files:
|
|
101
101
|
- changelog.txt
|
102
102
|
- lib/tester.rb
|
103
103
|
- lib/tester/api_tester.rb
|
104
|
+
- lib/tester/definition/api_contract.rb
|
105
|
+
- lib/tester/definition/api_method.rb
|
104
106
|
- lib/tester/definition/boundary_case.rb
|
105
107
|
- lib/tester/definition/endpoint.rb
|
106
108
|
- lib/tester/definition/fields/array_field.rb
|
@@ -110,25 +112,10 @@ files:
|
|
110
112
|
- lib/tester/definition/fields/field.rb
|
111
113
|
- lib/tester/definition/fields/number_field.rb
|
112
114
|
- lib/tester/definition/fields/object_field.rb
|
113
|
-
- lib/tester/definition/methods/api_copy.rb
|
114
|
-
- lib/tester/definition/methods/api_delete.rb
|
115
|
-
- lib/tester/definition/methods/api_get.rb
|
116
|
-
- lib/tester/definition/methods/api_head.rb
|
117
|
-
- lib/tester/definition/methods/api_lock.rb
|
118
|
-
- lib/tester/definition/methods/api_method.rb
|
119
|
-
- lib/tester/definition/methods/api_mkcol.rb
|
120
|
-
- lib/tester/definition/methods/api_move.rb
|
121
|
-
- lib/tester/definition/methods/api_options.rb
|
122
|
-
- lib/tester/definition/methods/api_patch.rb
|
123
|
-
- lib/tester/definition/methods/api_post.rb
|
124
|
-
- lib/tester/definition/methods/api_propfind.rb
|
125
|
-
- lib/tester/definition/methods/api_proppatch.rb
|
126
|
-
- lib/tester/definition/methods/api_put.rb
|
127
|
-
- lib/tester/definition/methods/api_trace.rb
|
128
|
-
- lib/tester/definition/methods/api_unlock.rb
|
129
115
|
- lib/tester/definition/request.rb
|
130
116
|
- lib/tester/definition/response.rb
|
131
117
|
- lib/tester/method_case_test.rb
|
118
|
+
- lib/tester/modules/extra_verbs.rb
|
132
119
|
- lib/tester/modules/format.rb
|
133
120
|
- lib/tester/modules/good_case.rb
|
134
121
|
- lib/tester/modules/module.rb
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'tester/util/supported_verbs'
|
2
|
-
require 'rest-client'
|
3
|
-
require 'tester/definition/methods/api_method'
|
4
|
-
|
5
|
-
class ApiCopy < ApiMethod
|
6
|
-
def call url, params={}, headers={}
|
7
|
-
RestClient::Request.execute(method: :copy, url: url, headers: headers)
|
8
|
-
end
|
9
|
-
|
10
|
-
def verb
|
11
|
-
SupportedVerbs::COPY
|
12
|
-
end
|
13
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'tester/util/supported_verbs'
|
2
|
-
require 'rest-client'
|
3
|
-
require 'tester/definition/methods/api_method'
|
4
|
-
|
5
|
-
class ApiDelete < ApiMethod
|
6
|
-
def call url, params={}, headers={}
|
7
|
-
RestClient::Request.execute(method: :delete, url: url, headers: headers)
|
8
|
-
end
|
9
|
-
|
10
|
-
def verb
|
11
|
-
SupportedVerbs::DELETE
|
12
|
-
end
|
13
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'rest-client'
|
2
|
-
require 'tester/definition/methods/api_method'
|
3
|
-
|
4
|
-
class ApiGet < ApiMethod
|
5
|
-
def call url, params={}, headers={}
|
6
|
-
headers[:params] = params
|
7
|
-
|
8
|
-
RestClient.get(url, headers) { |real_response, request, result|
|
9
|
-
real_response
|
10
|
-
}
|
11
|
-
end
|
12
|
-
|
13
|
-
def verb
|
14
|
-
SupportedVerbs::GET
|
15
|
-
end
|
16
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'rest-client'
|
2
|
-
require 'tester/definition/methods/api_method'
|
3
|
-
|
4
|
-
class ApiHead < ApiMethod
|
5
|
-
def call url, params={}, headers={}
|
6
|
-
headers[:params] = params
|
7
|
-
|
8
|
-
RestClient.head(url, headers) { |real_response, request, result|
|
9
|
-
real_response
|
10
|
-
}
|
11
|
-
end
|
12
|
-
|
13
|
-
def verb
|
14
|
-
SupportedVerbs::HEAD
|
15
|
-
end
|
16
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'tester/util/supported_verbs'
|
2
|
-
require 'rest-client'
|
3
|
-
require 'tester/definition/methods/api_method'
|
4
|
-
|
5
|
-
class ApiLock < ApiMethod
|
6
|
-
def call url, params={}, headers={}
|
7
|
-
RestClient::Request.execute(method: :lock, url: url, headers: headers)
|
8
|
-
end
|
9
|
-
|
10
|
-
def verb
|
11
|
-
SupportedVerbs::LOCK
|
12
|
-
end
|
13
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'tester/definition/request'
|
2
|
-
require 'tester/definition/response'
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
class ApiMethod
|
6
|
-
attr_accessor :request
|
7
|
-
attr_accessor :expected_response
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
self.request = Request.new
|
11
|
-
self.expected_response = Response.new 200
|
12
|
-
end
|
13
|
-
|
14
|
-
def call
|
15
|
-
throw "Not implemented"
|
16
|
-
end
|
17
|
-
|
18
|
-
def verb
|
19
|
-
"None"
|
20
|
-
end
|
21
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'tester/util/supported_verbs'
|
2
|
-
require 'rest-client'
|
3
|
-
require 'tester/definition/methods/api_method'
|
4
|
-
|
5
|
-
class ApiMkcol < ApiMethod
|
6
|
-
def call url, params={}, headers={}
|
7
|
-
RestClient::Request.execute(method: :mkcol, url: url, headers: headers)
|
8
|
-
end
|
9
|
-
|
10
|
-
def verb
|
11
|
-
SupportedVerbs::MKCOL
|
12
|
-
end
|
13
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'tester/util/supported_verbs'
|
2
|
-
require 'rest-client'
|
3
|
-
require 'tester/definition/methods/api_method'
|
4
|
-
|
5
|
-
class ApiMove < ApiMethod
|
6
|
-
def call url, params={}, headers={}
|
7
|
-
RestClient::Request.execute(method: :move, url: url, headers: headers)
|
8
|
-
end
|
9
|
-
|
10
|
-
def verb
|
11
|
-
SupportedVerbs::MOVE
|
12
|
-
end
|
13
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'rest-client'
|
2
|
-
require 'tester/definition/methods/api_method'
|
3
|
-
|
4
|
-
class ApiOptions < ApiMethod
|
5
|
-
def call url, params={}, headers={}
|
6
|
-
headers[:params] = params
|
7
|
-
|
8
|
-
RestClient.options(url, headers) { |real_response, request, result|
|
9
|
-
real_response
|
10
|
-
}
|
11
|
-
end
|
12
|
-
|
13
|
-
def verb
|
14
|
-
SupportedVerbs::OPTIONS
|
15
|
-
end
|
16
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'rest-client'
|
2
|
-
require 'tester/definition/methods/api_method'
|
3
|
-
|
4
|
-
class ApiPatch < ApiMethod
|
5
|
-
def patch url, json_payload, headers
|
6
|
-
RestClient.patch(url, json_payload, headers) { |real_response, request, result|
|
7
|
-
real_response
|
8
|
-
}
|
9
|
-
end
|
10
|
-
|
11
|
-
def call url, body_params={}, request_params={}
|
12
|
-
patch url, body_params.to_json, request_params
|
13
|
-
end
|
14
|
-
|
15
|
-
def verb
|
16
|
-
SupportedVerbs::PATCH
|
17
|
-
end
|
18
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'rest-client'
|
2
|
-
require 'tester/definition/methods/api_method'
|
3
|
-
|
4
|
-
class ApiPost < ApiMethod
|
5
|
-
def post url, json_payload, headers
|
6
|
-
RestClient.post(url, json_payload, headers) { |real_response, request, result|
|
7
|
-
real_response
|
8
|
-
}
|
9
|
-
end
|
10
|
-
|
11
|
-
def call url, body_params={}, request_params={}
|
12
|
-
post url, body_params.to_json, request_params
|
13
|
-
end
|
14
|
-
|
15
|
-
def verb
|
16
|
-
SupportedVerbs::POST
|
17
|
-
end
|
18
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'tester/util/supported_verbs'
|
2
|
-
require 'rest-client'
|
3
|
-
require 'tester/definition/methods/api_method'
|
4
|
-
|
5
|
-
class ApiPropfind < ApiMethod
|
6
|
-
def call url, params={}, headers={}
|
7
|
-
RestClient::Request.execute(method: :propfind, url: url, headers: headers)
|
8
|
-
end
|
9
|
-
|
10
|
-
def verb
|
11
|
-
SupportedVerbs::PROPFIND
|
12
|
-
end
|
13
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'tester/util/supported_verbs'
|
2
|
-
require 'rest-client'
|
3
|
-
require 'tester/definition/methods/api_method'
|
4
|
-
|
5
|
-
class ApiProppatch < ApiMethod
|
6
|
-
def call url, params={}, headers={}
|
7
|
-
RestClient::Request.execute(method: :proppatch, url: url, headers: headers)
|
8
|
-
end
|
9
|
-
|
10
|
-
def verb
|
11
|
-
SupportedVerbs::PROPPATCH
|
12
|
-
end
|
13
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'rest-client'
|
2
|
-
require 'tester/definition/methods/api_method'
|
3
|
-
|
4
|
-
class ApiPut < ApiMethod
|
5
|
-
def put url, json_payload, headers
|
6
|
-
RestClient.put(url, json_payload, headers) { |real_response, request, result|
|
7
|
-
real_response
|
8
|
-
}
|
9
|
-
end
|
10
|
-
|
11
|
-
def call url, body_params={}, request_params={}
|
12
|
-
self.put url, body_params.to_json, request_params
|
13
|
-
end
|
14
|
-
|
15
|
-
def verb
|
16
|
-
SupportedVerbs::PUT
|
17
|
-
end
|
18
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'tester/util/supported_verbs'
|
2
|
-
require 'rest-client'
|
3
|
-
require 'tester/definition/methods/api_method'
|
4
|
-
|
5
|
-
class ApiTrace < ApiMethod
|
6
|
-
def call url, params={}, headers={}
|
7
|
-
RestClient::Request.execute(method: :trace, url: url, headers: headers)
|
8
|
-
end
|
9
|
-
|
10
|
-
def verb
|
11
|
-
SupportedVerbs::TRACE
|
12
|
-
end
|
13
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'tester/util/supported_verbs'
|
2
|
-
require 'rest-client'
|
3
|
-
require 'tester/definition/methods/api_method'
|
4
|
-
|
5
|
-
class ApiUnlock < ApiMethod
|
6
|
-
def call url, params={}, headers={}
|
7
|
-
RestClient::Request.execute(method: :unlock, url: url, headers: headers)
|
8
|
-
end
|
9
|
-
|
10
|
-
def verb
|
11
|
-
SupportedVerbs::UNLOCK
|
12
|
-
end
|
13
|
-
end
|