rest-assured 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|