rest-assured 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +23 -3
- data/db/migrate/20170818001158_add_pathpattern_to_doubles.rb +9 -0
- data/features/rest_api/doubles.feature +44 -0
- data/features/ruby_api/create_double.feature +16 -0
- data/features/step_definitions/doubles_steps.rb +21 -2
- data/features/web_ui/doubles.feature +24 -10
- data/lib/rest-assured/models/double.rb +25 -1
- data/lib/rest-assured/routes/double.rb +1 -1
- data/lib/rest-assured/routes/response.rb +9 -2
- data/lib/rest-assured/version.rb +1 -1
- data/spec/functional/double_routes_spec.rb +3 -3
- data/spec/functional/response_spec.rb +48 -23
- data/spec/models/double_spec.rb +25 -1
- data/views/doubles/_form.haml +5 -1
- data/views/doubles/index.haml +3 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 370e594e8946de24f24b8469929fbc069fe5235f
|
4
|
+
data.tar.gz: 9e1e1621fa5b64411827d967dfd6705cf1872e5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4652bf11923b101cdbd09e61c6e3f45a01c9756d81a3816bbe7330fbee9a60d1dee4e0d4338dcbafe18ec51e314c947d6c548a6762ba7b5e7de40bea1ec1039e
|
7
|
+
data.tar.gz: 886b1e670a667bfb494d30535a5e275f8c3dedcd892be3d5c6edb7fad5c04b7fa7321052a6f10ca433c644dd73cb01b3bee3ab486cea238cf23847fdfcd23eb7
|
data/README.markdown
CHANGED
@@ -89,7 +89,16 @@ Create double:
|
|
89
89
|
RestAssured::Double.create(fullpath: '/products', content: 'this is content')
|
90
90
|
```
|
91
91
|
|
92
|
-
|
92
|
+
Alternatively using a regular expression for the path
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
RestAssured::Double.create(pathpattern: /products\/[a-z]{10}\/?param=.*/, content: 'this is more content')
|
96
|
+
```
|
97
|
+
|
98
|
+
Now GET `http://localhost:4578/products` will be returning `this is content` and a GET to
|
99
|
+
`http://localhost:4578/products/coolprod22?param=foo` will be returning `this is more content`.
|
100
|
+
|
101
|
+
The pathpattern parameter must be a ruby Regexp object or a string containing a valid regular expression.
|
93
102
|
|
94
103
|
You can also verify what requests happen on a double (spy on it). Say this is a Given part of a test:
|
95
104
|
|
@@ -146,14 +155,24 @@ For using REST-assured from non-ruby environments.
|
|
146
155
|
Example:
|
147
156
|
|
148
157
|
```
|
149
|
-
$ curl -d 'fullpath
|
158
|
+
$ curl -d 'fullpath=%2Fapi%2Fsomething%5C%3Fparam%3D.*&content=awesome&response_headers%5BContent-Type%5D=text%2Fhtml' http://localhost:4578/doubles
|
150
159
|
{"double":{"active":true,"content":"awesome","description":null,"fullpath":"/api/something","id":1,"response_headers":{"Content-Type":"text/html"},"status":200,"verb":"GET"}}
|
151
160
|
|
152
161
|
$ curl http://localhost:4578/api/something
|
153
162
|
awesome
|
154
163
|
```
|
164
|
+
Example using a regular expression for the path:
|
165
|
+
```
|
166
|
+
$ curl -d 'pathpattern=/api/something\?param=.*&content=awesome&response_headers%5BContent-Type%5D=text%2Fhtml' http://localhost:4578/doubles
|
167
|
+
{"double":{"active":true,"content":"awesome","description":null,"pathpattern":"/api/something\?param=.*","id":1,"response_headers":{"Content-Type":"text/html"},"status":200,"verb":"GET"}}
|
168
|
+
|
169
|
+
$ curl http://localhost:4578/api/something?param=foo
|
170
|
+
awesome
|
171
|
+
```
|
155
172
|
|
156
|
-
If there is more than one double for the same fullpath and verb, the last created one gets served.
|
173
|
+
If there is more than one double for the same fullpath and verb, the last created one gets served.
|
174
|
+
Doubles with `fullpath`'s are served in preference to `pathpattern`'s.
|
175
|
+
In UI you can manually control which double is 'active' (gets served).
|
157
176
|
|
158
177
|
#### Get double state
|
159
178
|
|
@@ -166,6 +185,7 @@ For using REST-assured from non-ruby environments.
|
|
166
185
|
"double": {
|
167
186
|
"verb": "GET",
|
168
187
|
"fullpath": "/api/something",
|
188
|
+
"pathpattern" : null,
|
169
189
|
"response_headers": {
|
170
190
|
"Content-Type": "text/html"
|
171
191
|
},
|
@@ -18,6 +18,15 @@ Feature: use doubles via api
|
|
18
18
|
| /api/file | | HEAD | HEAD | | 200 | 5 | 5 |
|
19
19
|
| /api/file | | PATCH | PATCH | | 200 | 6 | 6 |
|
20
20
|
|
21
|
+
Scenario Outline: create a double with a url pattern
|
22
|
+
When I create a double with "<pathpattern>" as pathpattern, "<content>" as response content, "<verb>" as request verb, status as "<status>" and delay as "<delay>"
|
23
|
+
Then there should be 1 double with "<pathpattern>" as pathpattern, "<content>" as response content, "<result_verb>" as request verb, status as "<result_status>" and delay as "<result_delay>"
|
24
|
+
Examples:
|
25
|
+
| pathpattern | content | verb | result_verb | status | result_status | delay | result_delay |
|
26
|
+
| ^\/api\/.*$ | created | POST | POST | 200 | 200 | | 0 |
|
27
|
+
| ^.*\/\?nocache=\d+$ | changed | PUT | PUT | 201 | 201 | 0 | 0 |
|
28
|
+
| ^[a-zA-Z]\/123$ | removed | DELETE | DELETE | 300 | 300 | 1 | 1 |
|
29
|
+
|
21
30
|
Scenario: view created double details
|
22
31
|
When I create a double
|
23
32
|
Then I should be able to get json representation of that double from response
|
@@ -36,6 +45,17 @@ Feature: use doubles via api
|
|
36
45
|
| /other/api | | GET | 303 |
|
37
46
|
| /patch/api | | PATCH | 200 |
|
38
47
|
|
48
|
+
Scenario Outline: request a path that matches double a path pattern
|
49
|
+
Given there is double with "<pathpattern>" as pathpattern, "<content>" as response content, "<verb>" as request verb and "<status>" as status
|
50
|
+
When I "<verb>" "<fullpath>"
|
51
|
+
Then I should get "<status>" as response status and "<content>" in response content
|
52
|
+
|
53
|
+
Examples:
|
54
|
+
| pathpattern | fullpath | content | verb | status |
|
55
|
+
| ^.*$ | /api/something | created | POST | 200 |
|
56
|
+
| ^/api/.*$ | /api/sss | changed | PUT | 201 |
|
57
|
+
| ^\/api\/some\?a=\d&b=[a-z]{2}$ | /api/some?a=3&b=dd | more content | GET | 203 |
|
58
|
+
|
39
59
|
# current rule: last added double gets picked
|
40
60
|
Scenario Outline: request fullpath that matches multiple doubles
|
41
61
|
Given there is double with "<fullpath>" as fullpath and "<content>" as response content
|
@@ -48,6 +68,30 @@ Feature: use doubles via api
|
|
48
68
|
| /api/something | test content | another content |
|
49
69
|
| /api/some?a=3&b=dd | more content | some text |
|
50
70
|
|
71
|
+
# current rule: full path matches over pattern
|
72
|
+
Scenario Outline: request fullpath that matches the full path of a double and a url pattern of another double
|
73
|
+
Given there is double with "<fullpath>" as fullpath and "<content>" as response content
|
74
|
+
Given there is double with "<pathpattern>" as pathpattern and "<content2>" as response content
|
75
|
+
When I "GET" "<fullpath>"
|
76
|
+
Then I should get "<content>" in response content
|
77
|
+
|
78
|
+
Examples:
|
79
|
+
| fullpath | content | pathpattern | content2 |
|
80
|
+
| /api/something | test content | ^/api/.*$ | more content |
|
81
|
+
| /api/some?a=3&b=dd | test content | ^\/api\/some?a=\d+&b=d[a-z]$ | more content |
|
82
|
+
|
83
|
+
# current rule: last added double gets picked
|
84
|
+
Scenario Outline: request full path that matches more than one path pattern
|
85
|
+
Given there is double with "<pathpattern>" as pathpattern and "<content>" as response content
|
86
|
+
Given there is double with "<pathpattern2>" as pathpattern and "<content2>" as response content
|
87
|
+
When I "GET" "<fullpath>"
|
88
|
+
Then I should get "<content2>" in response content
|
89
|
+
|
90
|
+
Examples:
|
91
|
+
| fullpath | pathpattern | content | pathpattern2 | content2 |
|
92
|
+
| /api/sam | ^.*$ | test content | ^\/api\/.*$ | more content |
|
93
|
+
| /api/some?a=123&b=dd | ^\/api\/some\?a=\d+&b=d[a-z]$ | test content | ^\/api\/some\?a=\d+&b=d[a-z]$ | more content |
|
94
|
+
|
51
95
|
Scenario: request fullpath that does not match any double
|
52
96
|
Given there are no doubles
|
53
97
|
When I "GET" "/api/something"
|
@@ -20,6 +20,22 @@ Feature: create double
|
|
20
20
|
last_response.should be_ok
|
21
21
|
"""
|
22
22
|
|
23
|
+
Scenario: use a path pattern
|
24
|
+
When I create a double:
|
25
|
+
"""
|
26
|
+
@double = RestAssured::Double.create(:pathpattern => /^\/some\/api\?nocache=\d+$/)
|
27
|
+
"""
|
28
|
+
Then the following should be true:
|
29
|
+
"""
|
30
|
+
@double.verb.should == 'GET'
|
31
|
+
@double.response_headers.should == {}
|
32
|
+
@double.status.should == 200
|
33
|
+
@double.content.should == nil
|
34
|
+
|
35
|
+
get '/some/api?nocache=1234'
|
36
|
+
last_response.should be_ok
|
37
|
+
"""
|
38
|
+
|
23
39
|
Scenario: specify response headers
|
24
40
|
When I create a double:
|
25
41
|
"""
|
@@ -9,6 +9,11 @@ When /^I create a double with "([^""]*)" as fullpath, "([^""]*)" as response con
|
|
9
9
|
last_response.should be_ok
|
10
10
|
end
|
11
11
|
|
12
|
+
When /^I create a double with "([^""]*)" as pathpattern, "([^""]*)" as response content, "([^""]*)" as request verb, status as "([^""]*)" and delay as "([^""]*)"$/ do |pathpattern, content, verb, status, delay|
|
13
|
+
post '/doubles.json', { :pathpattern => pathpattern, :content => content, :verb => verb, :status => status, :delay => delay}
|
14
|
+
last_response.should be_ok
|
15
|
+
end
|
16
|
+
|
12
17
|
When /^I create a double$/ do
|
13
18
|
post '/doubles.json', { :fullpath => '/api/something' }
|
14
19
|
@create_a_double_response = last_response.body
|
@@ -27,14 +32,26 @@ Then /^there should be (#{CAPTURE_A_NUMBER}) double with "([^""]*)" as fullpath,
|
|
27
32
|
RestAssured::Models::Double.where(:fullpath => fullpath, :content => content, :verb => verb, :status => status, :delay => delay).count.should == n
|
28
33
|
end
|
29
34
|
|
35
|
+
Then /^there should be (#{CAPTURE_A_NUMBER}) double with "([^""]*)" as pathpattern, "([^""]*)" as response content, "([^""]*)" as request verb, status as "(#{CAPTURE_A_NUMBER})" and delay as "(#{CAPTURE_A_NUMBER})"$/ do |n, pathpattern, content, verb, status, delay|
|
36
|
+
RestAssured::Models::Double.where(:pathpattern => pathpattern, :content => content, :verb => verb, :status => status, :delay => delay).count.should == n
|
37
|
+
end
|
38
|
+
|
30
39
|
Given /^there is double with "([^"]*)" as fullpath and "([^"]*)" as response content$/ do |fullpath, content|
|
31
40
|
RestAssured::Models::Double.create(:fullpath => fullpath, :content => content)
|
32
41
|
end
|
33
42
|
|
43
|
+
Given /^there is double with "([^"]*)" as pathpattern and "([^"]*)" as response content$/ do |pathpattern, content|
|
44
|
+
RestAssured::Models::Double.create(:pathpattern => pathpattern, :content => content)
|
45
|
+
end
|
46
|
+
|
34
47
|
Given /^there is double with "([^"]*)" as fullpath, "([^"]*)" as response content, "([^"]*)" as request verb and "([^"]*)" as status$/ do |fullpath, content, verb, status|
|
35
48
|
RestAssured::Models::Double.create(:fullpath => fullpath, :content => content, :verb => verb, :status => status)
|
36
49
|
end
|
37
50
|
|
51
|
+
Given /there is double with "([^"]*)" as pathpattern, "([^"]*)" as response content, "([^"]*)" as request verb and "([^"]*)" as status$/ do |pathpattern, content, verb, status|
|
52
|
+
RestAssured::Models::Double.create(:pathpattern => pathpattern, :content => content, :verb => verb, :status => status)
|
53
|
+
end
|
54
|
+
|
38
55
|
When /^I request "([^"]*)"$/ do |fullpath|
|
39
56
|
get fullpath
|
40
57
|
end
|
@@ -73,6 +90,7 @@ Given /^the following doubles exist:$/ do |doubles|
|
|
73
90
|
doubles.hashes.each do |row|
|
74
91
|
RestAssured::Models::Double.create(
|
75
92
|
:fullpath => row['fullpath'],
|
93
|
+
:pathpattern => row['pathpattern'],
|
76
94
|
:description => row['description'],
|
77
95
|
:content => row['content'],
|
78
96
|
:verb => row['verb'],
|
@@ -83,7 +101,8 @@ end
|
|
83
101
|
|
84
102
|
Then /^I should see existing doubles:$/ do |doubles|
|
85
103
|
doubles.hashes.each do |row|
|
86
|
-
page.should have_content(row[:fullpath])
|
104
|
+
page.should have_content(row[:fullpath]) unless row[:fullpath].blank?
|
105
|
+
page.should have_content(row[:pathpattern]) unless row[:pathpattern].blank?
|
87
106
|
page.should have_content(row[:description])
|
88
107
|
page.should have_content(row[:verb])
|
89
108
|
page.should have_content(row[:status])
|
@@ -100,8 +119,8 @@ end
|
|
100
119
|
|
101
120
|
When /^I enter double details:$/ do |details|
|
102
121
|
double = details.hashes.first
|
103
|
-
|
104
122
|
fill_in 'Request fullpath', :with => double['fullpath']
|
123
|
+
fill_in 'Request path pattern', :with => double['pathpattern']
|
105
124
|
fill_in 'Content', :with => double['content']
|
106
125
|
select double['verb'], :from => 'Verb'
|
107
126
|
fill_in 'Description', :with => double['description']
|
@@ -6,29 +6,43 @@ Feature: manage doubles via ui
|
|
6
6
|
|
7
7
|
Scenario: view existing doubles
|
8
8
|
Given the following doubles exist:
|
9
|
-
| fullpath | description | content
|
10
|
-
| /url1/aaa | twitter | test content
|
11
|
-
| /url2/bbb | geo location | more content
|
12
|
-
| /u/b?c=1 | wikipedia | article
|
9
|
+
| fullpath | pathpattern | description | content | verb | delay |
|
10
|
+
| /url1/aaa | | twitter | test content | GET | 0 |
|
11
|
+
| /url2/bbb | | geo location | more content | POST | 1 |
|
12
|
+
| /u/b?c=1 | | wikipedia | article | PUT | 2 |
|
13
|
+
| | ^/api/foo\?nocache=123$ | pattern | pattern content | GET | 0 |
|
13
14
|
When I visit "doubles" page
|
14
15
|
Then I should see existing doubles:
|
15
|
-
| fullpath | description | verb | delay |
|
16
|
-
| /url1/aaa | twitter | GET | 0 |
|
17
|
-
| /url2/bbb | geo location | POST | 1 |
|
18
|
-
| /u/b?c=1 | wikipedia | PUT | 2 |
|
16
|
+
| fullpath | pathpattern | description | verb | delay |
|
17
|
+
| /url1/aaa | | twitter | GET | 0 |
|
18
|
+
| /url2/bbb | | geo location | POST | 1 |
|
19
|
+
| /u/b?c=1 | | wikipedia | PUT | 2 |
|
20
|
+
| | ^/api/foo\?nocache=123$ | pattern | GET | 0 |
|
19
21
|
|
20
22
|
Scenario: add new double
|
21
23
|
Given I am on "doubles" page
|
22
24
|
When I choose to create a double
|
23
25
|
And I enter double details:
|
24
|
-
| fullpath | description | content | verb | status | delay |
|
25
|
-
| /url2/bb?a=b5 | google api | test content | POST | 200 | 1 |
|
26
|
+
| fullpath | pathpattern | description | content | verb | status | delay |
|
27
|
+
| /url2/bb?a=b5 | | google api | test content | POST | 200 | 1 |
|
26
28
|
And I save it
|
27
29
|
Then I should see "Double created"
|
28
30
|
And I should see existing doubles:
|
29
31
|
| fullpath | description | verb | status | delay |
|
30
32
|
| /url2/bb?a=b5 | google api | POST | 200 | 1 |
|
31
33
|
|
34
|
+
Scenario: add a new double with a path pattern
|
35
|
+
Given I am on "doubles" page
|
36
|
+
When I choose to create a double
|
37
|
+
And I enter double details:
|
38
|
+
| fullpath | pathpattern | description | content | verb | status | delay |
|
39
|
+
| | ^\/api\/.*$ | pattern api | test content 1 | GET | 200 | 0 |
|
40
|
+
And I save it
|
41
|
+
Then I should see "Double created"
|
42
|
+
And I should see existing doubles:
|
43
|
+
| pathpattern | description | verb | status | delay |
|
44
|
+
| ^\/api\/.*$ | pattern api | GET | 200 | 1 |
|
45
|
+
|
32
46
|
@javascript
|
33
47
|
Scenario: choose active double
|
34
48
|
Given there are two doubles for the same fullpath
|
@@ -10,7 +10,8 @@ module RestAssured
|
|
10
10
|
STATUSES = Net::HTTPResponse::CODE_TO_OBJ.keys.map(&:to_i)
|
11
11
|
MAX_DELAY = 30
|
12
12
|
|
13
|
-
|
13
|
+
validate :fullpath_or_pattern
|
14
|
+
validate :pattern_is_regex
|
14
15
|
validates_inclusion_of :verb, :in => VERBS
|
15
16
|
validates_inclusion_of :status, :in => STATUSES
|
16
17
|
|
@@ -18,6 +19,7 @@ module RestAssured
|
|
18
19
|
after_initialize :set_verb
|
19
20
|
after_initialize :set_response_headers
|
20
21
|
after_initialize :set_delay
|
22
|
+
after_initialize :stringify_regexp
|
21
23
|
|
22
24
|
before_save :toggle_active
|
23
25
|
after_destroy :set_active
|
@@ -59,7 +61,29 @@ module RestAssured
|
|
59
61
|
puts "delay #{self.delay} exceeds maxmium. Defaulting to #{MAX_DELAY}"
|
60
62
|
self.delay = MAX_DELAY
|
61
63
|
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def fullpath_or_pattern
|
67
|
+
unless self.fullpath.blank? ^ self.pathpattern.blank?
|
68
|
+
errors.add(:path, "Exactly one of fullpath or pathpattern must be present")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def pattern_is_regex
|
73
|
+
unless self.pathpattern.blank?
|
74
|
+
begin
|
75
|
+
Regexp.new(self.pathpattern)
|
76
|
+
rescue RegexpError
|
77
|
+
errors.add(:pathpattern, "not a valid regular expression")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def stringify_regexp
|
83
|
+
unless self.pathpattern.blank?
|
84
|
+
self.pathpattern = self.pathpattern.to_s
|
62
85
|
end
|
86
|
+
end
|
63
87
|
end
|
64
88
|
end
|
65
89
|
end
|
@@ -51,7 +51,7 @@ module RestAssured
|
|
51
51
|
end
|
52
52
|
rescue
|
53
53
|
d = params['double'] ||
|
54
|
-
params.slice(*%w[fullpath content description verb status response_headers delay])
|
54
|
+
params.slice(*%w[fullpath pathpattern content description verb status response_headers delay])
|
55
55
|
end
|
56
56
|
|
57
57
|
@double = Models::Double.create(d)
|
@@ -3,10 +3,10 @@ module RestAssured
|
|
3
3
|
|
4
4
|
def self.perform(app)
|
5
5
|
request = app.request
|
6
|
-
if d =
|
6
|
+
if d = find_matching_double(request.request_method, request.fullpath)
|
7
7
|
return_double app, d
|
8
8
|
elsif redirect_url = Models::Redirect.find_redirect_url_for(request.fullpath)
|
9
|
-
if d =
|
9
|
+
if d = find_matching_double(request.request_method, redirect_url)
|
10
10
|
return_double app, d
|
11
11
|
else
|
12
12
|
app.redirect redirect_url
|
@@ -16,6 +16,13 @@ module RestAssured
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
def self.find_matching_double(method, fullpath)
|
20
|
+
active_doubles_for_verb = Models::Double.where(:active => true, :verb => method)
|
21
|
+
|
22
|
+
active_doubles_for_verb.select {|d| !d.fullpath.blank? && d.fullpath == fullpath}.sort_by { |d| d[:id] }.last ||
|
23
|
+
active_doubles_for_verb.select {|d| !d.pathpattern.blank? && Regexp.new(d.pathpattern).match(fullpath)}.sort_by { |d| d[:id] }.last
|
24
|
+
end
|
25
|
+
|
19
26
|
def self.return_double(app, d)
|
20
27
|
request = app.request
|
21
28
|
request.body.rewind
|
data/lib/rest-assured/version.rb
CHANGED
@@ -75,7 +75,7 @@ module RestAssured
|
|
75
75
|
post '/doubles', invalid_params
|
76
76
|
|
77
77
|
expect(last_response).to be_ok
|
78
|
-
expect(last_response.body).to match(/Crumps!.*
|
78
|
+
expect(last_response.body).to match(/Crumps!.*Exactly one of fullpath or pathpattern must be present/)
|
79
79
|
end
|
80
80
|
|
81
81
|
it "renders double edit form" do
|
@@ -137,7 +137,7 @@ module RestAssured
|
|
137
137
|
post '/doubles.json', test_double.except(:fullpath)
|
138
138
|
|
139
139
|
expect(last_response).not_to be_ok
|
140
|
-
expect(last_response.body).to match(
|
140
|
+
expect(last_response.body).to match(/[\"Exactly one of fullpath or pathpattern must be present\"]/)
|
141
141
|
end
|
142
142
|
|
143
143
|
it "deletes double" do
|
@@ -187,7 +187,7 @@ module RestAssured
|
|
187
187
|
post '/doubles.json', test_double.except(:fullpath).to_json, 'CONTENT_TYPE' => 'Application/json'
|
188
188
|
|
189
189
|
expect(last_response).not_to be_ok
|
190
|
-
expect(last_response.body).to match(
|
190
|
+
expect(last_response.body).to match("{\"path\":[\"Exactly one of fullpath or pathpattern must be present\"]}")
|
191
191
|
end
|
192
192
|
|
193
193
|
it 'loads double as AR resource' do
|
@@ -11,30 +11,21 @@ module RestAssured
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
let(:env) {
|
14
|
+
let(:env) {double(:to_json => 'env').as_null_object}
|
15
|
+
|
15
16
|
let(:request) {
|
16
17
|
double('Request',
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
:request_method => 'GET',
|
19
|
+
:fullpath => '/api',
|
20
|
+
:env => env,
|
21
|
+
:body => double(:read => 'body').as_null_object,
|
22
|
+
:params => double(:to_json => 'params')
|
22
23
|
)
|
23
24
|
}
|
24
|
-
let(:rest_assured_app) { double('App', :request => request).as_null_object }
|
25
|
-
|
26
|
-
context 'when double matches request' do
|
27
|
-
before do
|
28
|
-
@double = Models::Double.create \
|
29
|
-
:fullpath => '/some/path',
|
30
|
-
:content => 'content',
|
31
|
-
:response_headers => { 'ACCEPT' => 'text/html' },
|
32
|
-
:status => 201,
|
33
|
-
:delay => 0
|
34
25
|
|
35
|
-
|
36
|
-
end
|
26
|
+
let(:rest_assured_app) {double('App', :request => request).as_null_object}
|
37
27
|
|
28
|
+
shared_examples "double_matches" do |path|
|
38
29
|
it "returns double content" do
|
39
30
|
expect(rest_assured_app).to receive(:body).with(@double.content)
|
40
31
|
|
@@ -55,17 +46,19 @@ module RestAssured
|
|
55
46
|
|
56
47
|
it 'records request' do
|
57
48
|
requests = double
|
58
|
-
allow(Models::Double).to
|
49
|
+
allow(Models::Double).to receive(:where).and_return(double(:requests => requests, :delay => 0).as_null_object)
|
59
50
|
|
60
51
|
expect(requests).to receive(:create!).with(:rack_env => 'env', :body => 'body', :params => 'params')
|
61
52
|
|
62
53
|
Response.perform(rest_assured_app)
|
63
54
|
end
|
64
|
-
|
55
|
+
|
65
56
|
it "returns double when redirect matches double" do
|
66
57
|
fullpath = '/some/other/path'
|
67
58
|
allow(request).to receive(:fullpath).and_return(fullpath)
|
68
|
-
allow(Models::Redirect).to receive(:find_redirect_url_for).with(fullpath).and_return(
|
59
|
+
allow(Models::Redirect).to receive(:find_redirect_url_for).with(fullpath).and_return(path)
|
60
|
+
puts "PATH"
|
61
|
+
puts path
|
69
62
|
|
70
63
|
expect(rest_assured_app).to receive(:body).with(@double.content)
|
71
64
|
expect(rest_assured_app).to receive(:status).with(@double.status)
|
@@ -73,7 +66,39 @@ module RestAssured
|
|
73
66
|
|
74
67
|
Response.perform(rest_assured_app)
|
75
68
|
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when double matches request' do
|
72
|
+
path = '/some/path'
|
73
|
+
before do
|
74
|
+
@double = Models::Double.create \
|
75
|
+
:fullpath => path,
|
76
|
+
:content => 'content',
|
77
|
+
:response_headers => {'ACCEPT' => 'text/html'},
|
78
|
+
:status => 201,
|
79
|
+
:delay => 0
|
80
|
+
|
81
|
+
allow(request).to receive(:fullpath).and_return(@double.fullpath)
|
82
|
+
end
|
83
|
+
|
84
|
+
include_examples "double_matches", path
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when double matches request pattern' do
|
88
|
+
path = '/api?someparam=something'
|
89
|
+
|
90
|
+
before do
|
91
|
+
@double = Models::Double.create \
|
92
|
+
:pathpattern => '\/api\?someparam=.*',
|
93
|
+
:content => 'content',
|
94
|
+
:response_headers => {'ACCEPT' => 'text/html'},
|
95
|
+
:status => 201,
|
96
|
+
:delay => 0
|
97
|
+
|
98
|
+
allow(request).to receive(:fullpath).and_return(path)
|
99
|
+
end
|
76
100
|
|
101
|
+
include_examples "double_matches", path
|
77
102
|
end
|
78
103
|
|
79
104
|
it "redirects if double not hit but there is redirect that matches request" do
|
@@ -97,7 +122,7 @@ module RestAssured
|
|
97
122
|
# TODO change to instead exclude anything that does not respond_to?(:to_s)
|
98
123
|
it 'excludes "rack.input" and "rack.errors" as they break with "IOError - not opened for reading:" on consequent #to_json (as they are IO and StringIO)' do
|
99
124
|
requests = double.as_null_object
|
100
|
-
allow(Models::Double).to
|
125
|
+
allow(Models::Double).to receive(:where).and_return(double(:requests => requests, :delay => 0).as_null_object)
|
101
126
|
|
102
127
|
expect(env).to receive(:except).with('rack.input', 'rack.errors', 'rack.logger')
|
103
128
|
|
@@ -106,7 +131,7 @@ module RestAssured
|
|
106
131
|
|
107
132
|
it 'it sleeps for delay seconds' do
|
108
133
|
requests = double.as_null_object
|
109
|
-
allow(Models::Double).to
|
134
|
+
allow(Models::Double).to receive(:where).and_return(double(:requests => requests, :delay => 10).as_null_object)
|
110
135
|
|
111
136
|
Response.stub(:sleep)
|
112
137
|
expect(Response).to receive(:sleep).with(10)
|
data/spec/models/double_spec.rb
CHANGED
@@ -13,17 +13,41 @@ module RestAssured::Models
|
|
13
13
|
}
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
let :valid_params_with_pattern do
|
17
|
+
valid_params.except(:fullpath).merge(:pathpattern => /^\/api\/.*\/[a-zA-Z]\?nocache=true/)
|
18
|
+
end
|
19
|
+
|
17
20
|
it { is_expected.to validate_inclusion_of(:verb).in_array Double::VERBS }
|
18
21
|
it { is_expected.to validate_inclusion_of(:status).in_array Double::STATUSES }
|
19
22
|
|
20
23
|
it { is_expected.to have_many(:requests) }
|
21
24
|
|
25
|
+
it 'rejects double with neither fullpath or pathpattern' do
|
26
|
+
d = Double.new valid_params.except(:fullpath)
|
27
|
+
expect(d).to_not be_valid
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'rejects double with both fullpath or pathpattern' do
|
31
|
+
d = Double.new valid_params.merge(valid_params_with_pattern)
|
32
|
+
expect(d).to_not be_valid
|
33
|
+
end
|
34
|
+
|
22
35
|
it 'creates double with valid params' do
|
23
36
|
d = Double.new valid_params
|
24
37
|
expect(d).to be_valid
|
25
38
|
end
|
26
39
|
|
40
|
+
it 'creates double with pathpattern' do
|
41
|
+
d = Double.new valid_params_with_pattern
|
42
|
+
expect(d).to be_valid
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'rejects double with invalid pathpattern regex string' do
|
46
|
+
# Probably a common mistake - not escaping forward slashes
|
47
|
+
d = Double.new valid_params_with_pattern.merge(:pathpattern => '**')
|
48
|
+
expect(d).to_not be_valid
|
49
|
+
end
|
50
|
+
|
27
51
|
it "defaults verb to GET" do
|
28
52
|
f = Double.create valid_params.except(:verb)
|
29
53
|
expect(f.verb).to eq('GET')
|
data/views/doubles/_form.haml
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
%p
|
2
|
-
|
2
|
+
Specify either a fullpath or a path pattern
|
3
|
+
%label{:for => 'double_fullpath'} Request fullpath
|
3
4
|
%input.wide#double_fullpath{:type => 'text', :name => 'double[fullpath]', :value => @double.fullpath}
|
4
5
|
|
6
|
+
%label{:for => 'double_pathpattern'} Request path pattern
|
7
|
+
%input.wide#double_pathpattern{:type => 'text', :name => 'double[pathpattern]', :value => @double.pathpattern}
|
8
|
+
|
5
9
|
%p
|
6
10
|
%label{:for => 'double_content'} Content
|
7
11
|
%textarea.wide#double_content{:name => 'double[content]', :rows => 10}= @double.content
|
data/views/doubles/index.haml
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
%thead
|
5
5
|
%tr
|
6
6
|
%th Request fullpath
|
7
|
+
%th Request path pattern
|
7
8
|
%th Description
|
8
9
|
%th Verb
|
9
10
|
%th Status
|
@@ -11,7 +12,7 @@
|
|
11
12
|
%th Active?
|
12
13
|
%th
|
13
14
|
%tbody
|
14
|
-
- @doubles.group_by {|f| f.fullpath + f.verb }.each do |group, fs|
|
15
|
+
- @doubles.group_by {|f| (f.fullpath || f.pathpattern) + f.verb }.each do |group, fs|
|
15
16
|
- fs.each_with_index do |f, i|
|
16
17
|
%tr{:id => "double_row_#{f.id}"}
|
17
18
|
- if i == 0
|
@@ -20,6 +21,7 @@
|
|
20
21
|
%a{:href => f.fullpath, :target => '_blank'}= f.fullpath
|
21
22
|
- else
|
22
23
|
= f.fullpath
|
24
|
+
%td= f.pathpattern
|
23
25
|
%td= f.description
|
24
26
|
%td= f.verb
|
25
27
|
%td= f.status
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-assured
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Artem Avetisyan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -134,6 +134,7 @@ files:
|
|
134
134
|
- db/migrate/20111208155906_add_response_headers_to_doubles.rb
|
135
135
|
- db/migrate/20120320200820_change_fullpath_to_text.rb
|
136
136
|
- db/migrate/20170713000515_add_delay_to_doubles.rb
|
137
|
+
- db/migrate/20170818001158_add_pathpattern_to_doubles.rb
|
137
138
|
- db/test.db
|
138
139
|
- features/command_line_options.feature
|
139
140
|
- features/rest_api/doubles.feature
|