cucumber-api 0.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +12 -0
- data/README.md +78 -33
- data/lib/cucumber-api/response.rb +10 -9
- data/lib/cucumber-api/steps.rb +32 -1
- data/lib/cucumber-api/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55a5a265a37af8eafb9ffd06172b125a5ec25f28
|
4
|
+
data.tar.gz: 221235246f1c3156a5765467a96a324773a46ba3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0396739e1f53262ee865c3ec7d3b57cf93917d7a888ddab8308d02de6a3c1915ba14e2828470f696e14e8a51a20b2c35a9d22971215b9d889c18233716360cbc
|
7
|
+
data.tar.gz: 2bf203c41587dfd2728c5dd039897f4ff50e49fe6accfbbff5956635f6655f1a99d9302a1fe1ec2e4154500be8302f9118a6d74bf33293ddc859ff4503efc9fe
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
## [Current](https://github.com/hidroh/cucumber-api/compare/0.1...master)
|
4
|
+
|
5
|
+
* Added form request body
|
6
|
+
* Added loading request body from file (YAML/JSON)
|
7
|
+
|
8
|
+
## [0.1](https://github.com/hidroh/cucumber-api/releases/tag/0.1) (March 01, 2015)
|
9
|
+
|
10
|
+
* Initial version
|
11
|
+
* Only JSON response supported
|
12
|
+
* Only JSON POST request body supported
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
# cucumber-api
|
2
|
+
[![Build Status](https://travis-ci.org/hidroh/cucumber-api.svg?branch=master)](https://travis-ci.org/hidroh/cucumber-api) [![Gem Version](https://badge.fury.io/rb/cucumber-api.svg)](http://badge.fury.io/rb/cucumber-api) [![Dependency Status](https://gemnasium.com/hidroh/cucumber-api.svg)](https://gemnasium.com/hidroh/cucumber-api)
|
3
|
+
[![Code Climate](https://codeclimate.com/github/hidroh/cucumber-api/badges/gpa.svg)](https://codeclimate.com/github/hidroh/cucumber-api) [![Total Downloads](http://ruby-gem-downloads-badge.herokuapp.com/cucumber-api)](https://rubygems.org/gems/cucumber-api)
|
4
|
+
|
2
5
|
API validator in BBD style with [Cucumber](https://cukes.info/). **cucumber-api** lets one validate public APIs JSON response in blazingly fast time.
|
3
6
|
|
4
7
|
Inspired by [cucumber-api-steps](https://github.com/jayzes/cucumber-api-steps).
|
@@ -13,16 +16,20 @@ Add `cucumber-api` gem to your `Gemfile`:
|
|
13
16
|
|
14
17
|
Require `cucumber-api` in your Cucumber's `env.rb`:
|
15
18
|
|
16
|
-
|
19
|
+
```ruby
|
20
|
+
require 'cucumber-api'
|
21
|
+
```
|
17
22
|
|
18
23
|
## Configuration
|
19
24
|
|
20
25
|
**Verbose logging:** enable verbose logging of API calls and responses by setting `cucumber_api_verbose=true` in your `ENV`, preferably via your `cucumber.yml`
|
21
26
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
27
|
+
```yaml
|
28
|
+
# config/cucumber.yml
|
29
|
+
##YAML Template
|
30
|
+
---
|
31
|
+
verbose : cucumber_api_verbose=true
|
32
|
+
```
|
26
33
|
|
27
34
|
## Usage
|
28
35
|
|
@@ -32,46 +39,78 @@ Require `cucumber-api` in your Cucumber's `env.rb`:
|
|
32
39
|
|
33
40
|
Specify your request header's `Content-Type` and `Accept`. The only supported option for `Accept` is `application/json` at the moment.
|
34
41
|
|
35
|
-
|
36
|
-
|
37
|
-
|
42
|
+
```gherkin
|
43
|
+
Given I send and accept JSON
|
44
|
+
Given I send "(.*?)" and accept JSON
|
45
|
+
```
|
46
|
+
|
47
|
+
Specify POST body
|
48
|
+
|
49
|
+
```gherkin
|
50
|
+
When I set JSON request body to '(.*?)'
|
51
|
+
When I set form request body to:
|
52
|
+
| key1 | value1 |
|
53
|
+
| key2 | {value2} |
|
54
|
+
| key3 | file://path-to-file |
|
55
|
+
```
|
56
|
+
|
57
|
+
Or from YAML/JSON file
|
58
|
+
|
59
|
+
```gherkin
|
60
|
+
When I set request body from "(.*?).(yml|json)"
|
61
|
+
```
|
38
62
|
|
39
63
|
Example:
|
40
64
|
|
41
|
-
|
42
|
-
|
65
|
+
```Gherkin
|
66
|
+
Given I send "www-x-form-urlencoded" and accept JSON
|
67
|
+
When I set JSON request body to '{"login": "email@example.com", "password": "password"}'
|
68
|
+
When I set form request body to:
|
69
|
+
| login | email@example.com |
|
70
|
+
| password | password |
|
71
|
+
When I set request body from "data/json-data.json"
|
72
|
+
When I set request body from "data/form-data.yml"
|
73
|
+
```
|
43
74
|
|
44
75
|
**Request steps**
|
45
76
|
|
46
77
|
Specify query string parameters and send an HTTP request to given URL with parameters
|
47
78
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
79
|
+
```gherkin
|
80
|
+
When I send a (GET|POST|PATCH|PUT|DELETE) request to "(.*?)"
|
81
|
+
When I send a (GET|POST|PATCH|PUT|DELETE) request to "(.*?)" with:
|
82
|
+
| param1 | param2 | ... |
|
83
|
+
| value1 | value2 | ... |
|
84
|
+
```
|
52
85
|
|
53
86
|
Temporarily save values from the last request to use in the next request in the same scenario:
|
54
87
|
|
55
|
-
|
88
|
+
```gherkin
|
89
|
+
When I grab "(.*?)" as "(.*?)"
|
90
|
+
```
|
56
91
|
|
57
92
|
The saved value can then be used to replace `{placeholder}` in the next request.
|
58
93
|
|
59
94
|
Example:
|
60
95
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
96
|
+
```gherkin
|
97
|
+
When I send a POST request to "http://example.com/token"
|
98
|
+
And I grab "$..request_token" as "token"
|
99
|
+
And I grab "$..access_type" as "type"
|
100
|
+
And I send a GET request to "http://example.com/{token} with:
|
101
|
+
| type | pretty |
|
102
|
+
| {type} | true |
|
103
|
+
```
|
67
104
|
|
68
|
-
Assume that [http://example.com/
|
105
|
+
Assume that [http://example.com/token](http://example.com/token) have an element `{"request_token": 1, "access_type": "full"}`, **cucumber-api** will execute the followings:
|
69
106
|
|
70
|
-
*
|
71
|
-
* Extract the first `
|
72
|
-
* GET [http://example.com/1?
|
107
|
+
* POST [http://example.com/token](http://example.com/token)
|
108
|
+
* Extract the first `request_token` and `access_type` from JSON response and save it for next request
|
109
|
+
* GET [http://example.com/1?type=full&pretty=true](http://example.com/1?type=full&pretty=true)
|
73
110
|
* Clear all saved values
|
74
111
|
|
112
|
+
This will be handy when one needs to make a sequence of calls to authenticate/authorize API access.
|
113
|
+
|
75
114
|
**Assert steps**
|
76
115
|
|
77
116
|
Verify:
|
@@ -79,7 +118,7 @@ Verify:
|
|
79
118
|
* JSON response against a JSON schema conforming to [JSON Schema Draft 4](http://tools.ietf.org/html/draft-zyp-json-schema-04)
|
80
119
|
* Adhoc JSON response key-value type pair, where key is a [JSON path](http://goessner.net/articles/JsonPath/)
|
81
120
|
|
82
|
-
```
|
121
|
+
```gherkin
|
83
122
|
Then the response status should be "(\d+)"
|
84
123
|
Then the JSON response should follow "(.*?)"
|
85
124
|
Then the JSON response root should be (object|array)
|
@@ -89,13 +128,19 @@ Then the JSON response should have (required|optional) key "(.*?)" of type (nume
|
|
89
128
|
|
90
129
|
Example:
|
91
130
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
131
|
+
```gherkin
|
132
|
+
Then the response status should be "200"
|
133
|
+
Then the JSON response should follow "features/schemas/example_all.json"
|
134
|
+
Then the JSON response root should be array
|
135
|
+
Then the JSON response should have key "id"
|
136
|
+
Then the JSON response should have optional key "format" of type string or null
|
137
|
+
```
|
138
|
+
|
139
|
+
Also checkout [sample](/features/sample.feature) for real examples. Run sample with the following command:
|
97
140
|
|
98
|
-
|
141
|
+
```
|
142
|
+
cucumber -p verbose
|
143
|
+
```
|
99
144
|
|
100
145
|
### Response caching
|
101
146
|
|
@@ -107,4 +152,4 @@ Only the first request to that endpoint is made, subsequent requests will use ca
|
|
107
152
|
* [cucumber](https://github.com/cucumber/cucumber) for BDD style specs
|
108
153
|
* [jsonpath](https://github.com/joshbuddy/jsonpath) for traversal of JSON response via [JSON path](http://goessner.net/articles/JsonPath/)
|
109
154
|
* [json-schema](https://github.com/ruby-json-schema/json-schema) for JSON schema validation
|
110
|
-
* [rest-client](https://github.com/rest-client/rest-client) for HTTP REST request
|
155
|
+
* [rest-client](https://github.com/rest-client/rest-client) for HTTP REST request
|
@@ -40,7 +40,7 @@ module CucumberApi
|
|
40
40
|
end
|
41
41
|
results = JsonPath.new(json_path).on(json)
|
42
42
|
if results.empty?
|
43
|
-
raise %/Expected json path '#{json_path}' not found\n#{
|
43
|
+
raise %/Expected json path '#{json_path}' not found\n#{to_json_s}/
|
44
44
|
end
|
45
45
|
results.first
|
46
46
|
end
|
@@ -73,7 +73,7 @@ module CucumberApi
|
|
73
73
|
end
|
74
74
|
|
75
75
|
unless valid
|
76
|
-
raise %/Expect '#{json_path}' as a '#{type}' but was '#{value.class}'\n#{
|
76
|
+
raise %/Expect '#{json_path}' as a '#{type}' but was '#{value.class}'\n#{to_json_s}/
|
77
77
|
end
|
78
78
|
value
|
79
79
|
end
|
@@ -91,13 +91,14 @@ module CucumberApi
|
|
91
91
|
value.nil? ? value : get_as_type(json_path, type, json)
|
92
92
|
end
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
94
|
+
# Retrieve pretty JSON response for logging
|
95
|
+
# @return [String] pretty JSON response if verbose setting is true, empty string otherwise
|
96
|
+
def to_json_s
|
97
|
+
if ENV['cucumber_api_verbose'] == 'true'
|
98
|
+
JSON.pretty_generate(JSON.parse to_s)
|
99
|
+
else
|
100
|
+
''
|
101
101
|
end
|
102
|
+
end
|
102
103
|
end
|
103
104
|
end
|
data/lib/cucumber-api/steps.rb
CHANGED
@@ -25,6 +25,32 @@ When(/^I set JSON request body to '(.*?)'$/) do |body|
|
|
25
25
|
@body = JSON.parse body
|
26
26
|
end
|
27
27
|
|
28
|
+
When(/^I set form request body to:$/) do |params|
|
29
|
+
@body = {}
|
30
|
+
params.rows_hash.each do |key, value|
|
31
|
+
p_value = value
|
32
|
+
@grabbed.each { |k, v| p_value = v if value == %/{#{k}}/ } unless @grabbed.nil?
|
33
|
+
p_value = File.new %-#{Dir.pwd}/#{p_value.sub 'file://', ''}- if %/#{p_value}/.start_with? "file://"
|
34
|
+
@body[%/#{key}/] = p_value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
When(/^I set request body from "(.*?).(yml|json)"$/) do |filename, extension|
|
39
|
+
path = %-#{Dir.pwd}/#{filename}.#{extension}-
|
40
|
+
if File.file? path
|
41
|
+
case extension
|
42
|
+
when 'yml'
|
43
|
+
@body = YAML.load File.open(path)
|
44
|
+
when 'json'
|
45
|
+
@body = JSON.parse File.read(path)
|
46
|
+
else
|
47
|
+
raise %/Unsupported file type: '#{path}'/
|
48
|
+
end
|
49
|
+
else
|
50
|
+
raise %/File not found: '#{path}'/
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
28
54
|
When(/^I grab "(.*?)" as "(.*?)"$/) do |json_path, place_holder|
|
29
55
|
if @response.nil?
|
30
56
|
raise 'No response found, a request need to be made first before you can grab response'
|
@@ -85,7 +111,12 @@ end
|
|
85
111
|
Then(/^the JSON response should follow "(.*?)"$/) do |schema|
|
86
112
|
file_path = %-#{Dir.pwd}/#{schema}-
|
87
113
|
if File.file? file_path
|
88
|
-
|
114
|
+
begin
|
115
|
+
JSON::Validator.validate!(file_path, @response.to_s)
|
116
|
+
rescue JSON::Schema::ValidationError => e
|
117
|
+
raise JSON::Schema::ValidationError.new(%/#{$!.message}\n#{@response.to_json_s}/,
|
118
|
+
$!.fragments, $!.failed_attribute, $!.schema)
|
119
|
+
end
|
89
120
|
else
|
90
121
|
puts %/WARNING: missing schema '#{file_path}'/
|
91
122
|
pending
|
data/lib/cucumber-api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cucumber-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.2'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ha Duy Trung
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cucumber
|
@@ -75,6 +75,8 @@ extensions: []
|
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
77
|
- ".gitignore"
|
78
|
+
- ".travis.yml"
|
79
|
+
- CHANGELOG.md
|
78
80
|
- Gemfile
|
79
81
|
- LICENSE
|
80
82
|
- README.md
|