rest-assured 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c35115ced77a2089492a155ef70c877a7f79155
4
- data.tar.gz: 3d0869cf86b0874e797e40054776213c87d7c145
3
+ metadata.gz: 7f22fb40a5da375669712d668d450c79397ddd9a
4
+ data.tar.gz: ee5916c4ee0dac3b82230c24bb606c90205091ab
5
5
  SHA512:
6
- metadata.gz: db3e43f69330695ba514f99c3851e78020828700aab04104e000149799941ac7d83b74ac147712a6355269c807ab5afa585f5acffae7215c9994289853fb7556
7
- data.tar.gz: 0c9b77fe69ea6dbf572130f7e998557ef0a89ed2c76b1bcad92bb5f8b2fa1f08a402726185bafa82bcb5a90f83cb44ac956f4d5f77a742787c210dbfed721d3b
6
+ metadata.gz: 5333399d35149cd78f6fbb8a2c404a2535fcb75845a77b8352de6955bbbfe332ce429bc4ada5044c0ef8146e986e13385642c4cbbf09ec8c61f72c61ba926721
7
+ data.tar.gz: 5e90dbf790b43165c31efc5ae29094ae2af86e9ef5acfd3be0ba5a4a1d98fa215f62ddbeb570044375e84d68a196c3bd9945ef5f710034d309ef4ec4e0c26d19
@@ -111,6 +111,15 @@ JSON.parse(req.params).should == expected_params_hash
111
111
  JSON.parse(req.rack_env)['HTTP_ACCEPT'].should == 'text/html'
112
112
  ```
113
113
 
114
+ If you want to simulate a delayed time to first byte to test how your application handles latency or time outs you can
115
+ use the delay property when you create the double.
116
+
117
+ ```ruby
118
+ @double = RestAssured::Double.create(fullpath: '/slow-products', delay: 5)
119
+ ```
120
+
121
+ Now, when a request is made to `http://localhost:4578/slow-products`, then the server will pause for 5 seconds before responding.
122
+
114
123
  Use REST api to clear doubles/redirects between tests:
115
124
 
116
125
  ```ruby
@@ -132,6 +141,7 @@ For using REST-assured from non-ruby environments.
132
141
  - __verb__ - one of http the following http verbs: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`. Optional. `GET` is default.
133
142
  - __status__ - status returned when double is requested. Optional. `200` is default.
134
143
  - __response_headers__ - key/value map of headers. Optional.
144
+ - __delay__ - the length of time in seconds the server should pause before sending the response. Optional.
135
145
 
136
146
  Example:
137
147
 
@@ -173,7 +183,8 @@ For using REST-assured from non-ruby environments.
173
183
  "content": "awesome",
174
184
  "description": null,
175
185
  "status": 200,
176
- "active": true
186
+ "active": true,
187
+ "delay" : 0
177
188
  }
178
189
  }
179
190
 
@@ -219,7 +230,7 @@ Here is the rest API for managing redirects:
219
230
 
220
231
  ## Running tests
221
232
 
222
- Tests require sqlite. Cucumber tests also need Chrome.
233
+ Tests require postgres. Connection params are read from environment variables `DB_HOST`, `DB_PORT` and `DB_USER` (defaults are `localhost`, `5432` and `postgres`). Cucumber tests also need Chrome.
223
234
 
224
235
  $ git clone git://github.com/artemave/REST-assured.git
225
236
  $ cd rest-assured && bundle install
@@ -19,7 +19,7 @@ OptionParser.new do |opts|
19
19
  end
20
20
 
21
21
  opts.on('-u', '--dbuser DBUSER', "Db username (mysql, postgresql only)") do |user|
22
- user_opts[:user] = user
22
+ user_opts[:dbuser] = user
23
23
  end
24
24
 
25
25
  opts.on('--dbpass DBPASSWORD', 'Db password (mysql, postgresql only). Defaults to empty') do |password|
@@ -0,0 +1,9 @@
1
+ class AddDelayToDoubles < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :doubles, :delay, :integer
4
+ end
5
+
6
+ def self.down
7
+ remove_column :doubles, :delay
8
+ end
9
+ end
data/db/test.db CHANGED
Binary file
@@ -4,19 +4,19 @@ Feature: use doubles via api
4
4
  I want to mock rest services my app is consuming from
5
5
 
6
6
  Scenario Outline: create double
7
- When I create a double with "<fullpath>" as fullpath, "<content>" as response content, "<verb>" as request verb and status as "<status>"
8
- Then there should be 1 double with "<fullpath>" as fullpath, "<content>" as response content, "<result_verb>" as request verb and status as "<result_status>"
7
+ When I create a double with "<fullpath>" as fullpath, "<content>" as response content, "<verb>" as request verb, status as "<status>" and delay as "<delay>"
8
+ Then there should be 1 double with "<fullpath>" as fullpath, "<content>" as response content, "<result_verb>" as request verb, status as "<result_status>" and delay as "<result_delay>"
9
9
 
10
10
  Examples:
11
- | fullpath | content | verb | result_verb | status | result_status |
12
- | /api/something | created | POST | POST | 200 | 200 |
13
- | /api/sss | changed | PUT | PUT | 201 | 201 |
14
- | /api/asdfsf | removed | DELETE | DELETE | 300 | 300 |
15
- | /api/some | text content | GET | GET | 303 | 303 |
16
- | /api/some?a=3&b=dd | more content | | GET | | 200 |
17
- | /api/empty | | POST | POST | | 200 |
18
- | /api/file | | HEAD | HEAD | | 200 |
19
- | /api/file | | PATCH | PATCH | | 200 |
11
+ | fullpath | content | verb | result_verb | status | result_status | delay | result_delay |
12
+ | /api/something | created | POST | POST | 200 | 200 | | 0 |
13
+ | /api/sss | changed | PUT | PUT | 201 | 201 | 0 | 0 |
14
+ | /api/asdfsf | removed | DELETE | DELETE | 300 | 300 | 1 | 1 |
15
+ | /api/some | text content | GET | GET | 303 | 303 | 2 | 2 |
16
+ | /api/some?a=3&b=dd | more content | | GET | | 200 | 3 | 3 |
17
+ | /api/empty | | POST | POST | | 200 | 4 | 4 |
18
+ | /api/file | | HEAD | HEAD | | 200 | 5 | 5 |
19
+ | /api/file | | PATCH | PATCH | | 200 | 6 | 6 |
20
20
 
21
21
  Scenario: view created double details
22
22
  When I create a double
@@ -74,3 +74,22 @@ Feature: create double
74
74
  get @double.fullpath
75
75
  last_response.status == 302
76
76
  """
77
+
78
+ Scenario: specify a delay
79
+ When I create a double:
80
+ """
81
+ @double = RestAssured::Double.create(:fullpath => '/some/api', :delay => 4)
82
+ """
83
+ Then the following should be true:
84
+ """
85
+ start_time = Time.now
86
+
87
+ get @double.fullpath
88
+
89
+ end_time = Time.now
90
+
91
+ time_elapsed = end_time - start_time
92
+
93
+ expect(time_elapsed).to be > 3
94
+
95
+ """
@@ -4,8 +4,8 @@ Given /^there are no doubles$/ do
4
4
  RestAssured::Models::Double.destroy_all
5
5
  end
6
6
 
7
- When /^I create a double with "([^""]*)" as fullpath, "([^""]*)" as response content, "([^""]*)" as request verb and status as "([^""]*)"$/ do |fullpath, content, verb, status|
8
- post '/doubles.json', { :fullpath => fullpath, :content => content, :verb => verb, :status => status }
7
+ When /^I create a double with "([^""]*)" as fullpath, "([^""]*)" as response content, "([^""]*)" as request verb, status as "([^""]*)" and delay as "([^""]*)"$/ do |fullpath, content, verb, status, delay|
8
+ post '/doubles.json', { :fullpath => fullpath, :content => content, :verb => verb, :status => status, :delay => delay}
9
9
  last_response.should be_ok
10
10
  end
11
11
 
@@ -23,8 +23,8 @@ Then /^I should get (#{CAPTURE_A_NUMBER}) in response status$/ do |status|
23
23
  last_response.status.should == status
24
24
  end
25
25
 
26
- Then /^there should be (#{CAPTURE_A_NUMBER}) double with "([^""]*)" as fullpath, "([^""]*)" as response content, "([^""]*)" as request verb and status as "(#{CAPTURE_A_NUMBER})"$/ do |n, fullpath, content, verb, status|
27
- RestAssured::Models::Double.where(:fullpath => fullpath, :content => content, :verb => verb, :status => status).count.should == n
26
+ Then /^there should be (#{CAPTURE_A_NUMBER}) double with "([^""]*)" as fullpath, "([^""]*)" as response content, "([^""]*)" as request verb, status as "(#{CAPTURE_A_NUMBER})" and delay as "(#{CAPTURE_A_NUMBER})"$/ do |n, fullpath, content, verb, status, delay|
27
+ RestAssured::Models::Double.where(:fullpath => fullpath, :content => content, :verb => verb, :status => status, :delay => delay).count.should == n
28
28
  end
29
29
 
30
30
  Given /^there is double with "([^"]*)" as fullpath and "([^"]*)" as response content$/ do |fullpath, content|
@@ -152,7 +152,7 @@ Given /^I choose to delete double with fullpath "([^"]*)"$/ do |fullpath|
152
152
  end
153
153
 
154
154
  Then /^I should be asked to confirm delete$/ do
155
- page.driver.browser.switch_to.alert.accept
155
+ js_confirm
156
156
  end
157
157
 
158
158
  Given /^there are the following doubles:$/ do |table|
@@ -5,6 +5,7 @@ require 'rspec'
5
5
  require 'rack/test'
6
6
  require 'capybara'
7
7
  require 'capybara/cucumber'
8
+ require 'capybara/poltergeist'
8
9
  require 'database_cleaner'
9
10
  require 'anticipate'
10
11
  require 'awesome_print'
@@ -29,11 +30,17 @@ end
29
30
  Capybara.register_driver :selenium do |app|
30
31
  Capybara::Selenium::Driver.new(app, :browser => :chrome)
31
32
  end
33
+ Capybara.javascript_driver = ENV['FF'] ? :selenium : :poltergeist
32
34
 
33
35
  World(Capybara, Rack::Test::Methods, RackHeaderHack, WorldHelpers, Anticipate)
34
36
 
35
37
  require 'rest-assured/config'
36
- db_opts = { :adapter => 'sqlite' }
38
+ db_opts = {
39
+ adapter: 'postgres',
40
+ dbhost: ENV.fetch('DB_HOST', 'localhost'),
41
+ dbport: ENV.fetch('DB_PORT', 5432),
42
+ dbuser: ENV.fetch('DB_USER', 'postgres')
43
+ }
37
44
  RestAssured::Config.build(db_opts)
38
45
 
39
46
  require 'rest-assured'
@@ -22,4 +22,10 @@ module WorldHelpers
22
22
 
23
23
  YAML.load(config_yaml)
24
24
  end
25
+
26
+ def js_confirm
27
+ if Capybara.current_driver == :selenium
28
+ page.driver.browser.switch_to.alert.accept
29
+ end
30
+ end
25
31
  end
@@ -6,28 +6,28 @@ Feature: manage doubles via ui
6
6
 
7
7
  Scenario: view existing doubles
8
8
  Given the following doubles exist:
9
- | fullpath | description | content | verb |
10
- | /url1/aaa | twitter | test content | GET |
11
- | /url2/bbb | geo location | more content | POST |
12
- | /u/b?c=1 | wikipedia | article | PUT |
9
+ | fullpath | 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
13
  When I visit "doubles" page
14
14
  Then I should see existing doubles:
15
- | fullpath | description | verb |
16
- | /url1/aaa | twitter | GET |
17
- | /url2/bbb | geo location | POST |
18
- | /u/b?c=1 | wikipedia | PUT |
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 |
19
19
 
20
20
  Scenario: add new double
21
21
  Given I am on "doubles" page
22
22
  When I choose to create a double
23
23
  And I enter double details:
24
- | fullpath | description | content | verb | status |
25
- | /url2/bb?a=b5 | google api | test content | POST | 200 |
24
+ | fullpath | description | content | verb | status | delay |
25
+ | /url2/bb?a=b5 | google api | test content | POST | 200 | 1 |
26
26
  And I save it
27
27
  Then I should see "Double created"
28
28
  And I should see existing doubles:
29
- | fullpath | description | verb | status |
30
- | /url2/bb?a=b5 | google api | POST | 200 |
29
+ | fullpath | description | verb | status | delay |
30
+ | /url2/bb?a=b5 | google api | POST | 200 | 1 |
31
31
 
32
32
  @javascript
33
33
  Scenario: choose active double
@@ -40,22 +40,22 @@ Feature: manage doubles via ui
40
40
 
41
41
  Scenario: edit double
42
42
  Given the following doubles exist:
43
- | fullpath | description | content | verb | status |
44
- | /url1/aaa | twitter | test content | POST | 404 |
43
+ | fullpath | description | content | verb | status | delay |
44
+ | /url1/aaa | twitter | test content | POST | 404 | 0 |
45
45
  And I visit "doubles" page
46
46
  And I choose to edit double
47
47
  When I change "double" "description" to "google"
48
48
  And I save it
49
49
  Then I should see existing doubles:
50
- | fullpath | description | verb | status |
51
- | /url1/aaa | google | POST | 404 |
50
+ | fullpath | description | verb | status | delay |
51
+ | /url1/aaa | google | POST | 404 | 0 |
52
52
 
53
53
  @javascript
54
54
  Scenario: delete double
55
55
  Given the following doubles exist:
56
- | fullpath | description | content |
57
- | /url1/aaa | twitter | test content |
58
- | /url/cc/bb | google | other content |
56
+ | fullpath | description | content | delay |
57
+ | /url1/aaa | twitter | test content | 0 |
58
+ | /url/cc/bb | google | other content | 1 |
59
59
  And I visit "doubles" page
60
60
  And I choose to delete double with fullpath "/url1/aaa"
61
61
  Then I should be asked to confirm delete
@@ -139,7 +139,7 @@ module RestAssured
139
139
 
140
140
  opts = {
141
141
  :adapter => 'postgresql',
142
- :username => AppConfig.user || 'root',
142
+ :username => AppConfig.dbuser || 'root',
143
143
  :database => AppConfig.database || default_database,
144
144
  :pool => 20
145
145
  }
@@ -8,6 +8,7 @@ module RestAssured
8
8
 
9
9
  VERBS = %w{GET POST PUT DELETE HEAD PATCH}
10
10
  STATUSES = Net::HTTPResponse::CODE_TO_OBJ.keys.map(&:to_i)
11
+ MAX_DELAY = 30
11
12
 
12
13
  validates_presence_of :fullpath
13
14
  validates_inclusion_of :verb, :in => VERBS
@@ -16,6 +17,7 @@ module RestAssured
16
17
  after_initialize :set_status
17
18
  after_initialize :set_verb
18
19
  after_initialize :set_response_headers
20
+ after_initialize :set_delay
19
21
 
20
22
  before_save :toggle_active
21
23
  after_destroy :set_active
@@ -50,6 +52,14 @@ module RestAssured
50
52
  f.save
51
53
  end
52
54
  end
55
+
56
+ def set_delay
57
+ self.delay = 0 unless delay.present?
58
+ if self.delay > MAX_DELAY
59
+ puts "delay #{self.delay} exceeds maxmium. Defaulting to #{MAX_DELAY}"
60
+ self.delay = MAX_DELAY
61
+ end
62
+ end
53
63
  end
54
64
  end
55
65
  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])
54
+ params.slice(*%w[fullpath content description verb status response_headers delay])
55
55
  end
56
56
 
57
57
  @double = Models::Double.create(d)
@@ -24,6 +24,8 @@ module RestAssured
24
24
 
25
25
  d.requests.create!(:rack_env => env.to_json, :body => body, :params => request.params.to_json)
26
26
 
27
+ sleep d.delay
28
+
27
29
  app.headers d.response_headers
28
30
  app.body d.content
29
31
  app.status d.status
@@ -1,3 +1,3 @@
1
1
  module RestAssured
2
- VERSION = '2.0.2'
2
+ VERSION = '2.1.0'
3
3
  end
@@ -29,7 +29,8 @@ module RestAssured
29
29
  :fullpath => '/some/path',
30
30
  :content => 'content',
31
31
  :response_headers => { 'ACCEPT' => 'text/html' },
32
- :status => 201
32
+ :status => 201,
33
+ :delay => 0
33
34
 
34
35
  allow(request).to receive(:fullpath).and_return(@double.fullpath)
35
36
  end
@@ -54,7 +55,7 @@ module RestAssured
54
55
 
55
56
  it 'records request' do
56
57
  requests = double
57
- allow(Models::Double).to receive_message_chain('where.first').and_return(double(:requests => requests).as_null_object)
58
+ allow(Models::Double).to receive_message_chain('where.first').and_return(double(:requests => requests, :delay => 0).as_null_object)
58
59
 
59
60
  expect(requests).to receive(:create!).with(:rack_env => 'env', :body => 'body', :params => 'params')
60
61
 
@@ -96,12 +97,22 @@ module RestAssured
96
97
  # TODO change to instead exclude anything that does not respond_to?(:to_s)
97
98
  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
98
99
  requests = double.as_null_object
99
- allow(Models::Double).to receive_message_chain('where.first').and_return(double(:requests => requests).as_null_object)
100
+ allow(Models::Double).to receive_message_chain('where.first').and_return(double(:requests => requests, :delay => 0).as_null_object)
100
101
 
101
102
  expect(env).to receive(:except).with('rack.input', 'rack.errors', 'rack.logger')
102
103
 
103
104
  Response.perform(rest_assured_app)
104
105
  end
105
106
 
107
+ it 'it sleeps for delay seconds' do
108
+ requests = double.as_null_object
109
+ allow(Models::Double).to receive_message_chain('where.first').and_return(double(:requests => requests, :delay => 10).as_null_object)
110
+
111
+ Response.stub(:sleep)
112
+ expect(Response).to receive(:sleep).with(10)
113
+
114
+ Response.perform(rest_assured_app)
115
+ end
116
+
106
117
  end
107
118
  end
@@ -8,7 +8,8 @@ module RestAssured::Models
8
8
  :content => 'some content',
9
9
  :verb => 'GET',
10
10
  :status => '303',
11
- :response_headers => { 'ACCEPT' => 'text/html' }
11
+ :response_headers => { 'ACCEPT' => 'text/html' },
12
+ :delay => 5
12
13
  }
13
14
  end
14
15
 
@@ -38,6 +39,16 @@ module RestAssured::Models
38
39
  expect(f.active).to be true
39
40
  end
40
41
 
42
+ it "defaults delay to 0" do
43
+ f = Double.create valid_params.except(:delay)
44
+ expect(f.delay).to be 0
45
+ end
46
+
47
+ it "defaults delay of greater than 30 seconds to 30 seconds" do
48
+ f = Double.create valid_params.merge(:delay => 99)
49
+ expect(f.delay).to be 30
50
+ end
51
+
41
52
  describe 'when created' do
42
53
  it "toggles active double for the same fullpath and verb" do
43
54
  f1 = Double.create valid_params
@@ -20,7 +20,12 @@ require 'rack/test'
20
20
  require 'awesome_print'
21
21
  require 'rest-assured/config'
22
22
 
23
- DB_OPTS = { :adapter => 'sqlite' }
23
+ DB_OPTS = {
24
+ adapter: 'postgres',
25
+ dbhost: ENV.fetch('DB_HOST', 'localhost'),
26
+ dbport: ENV.fetch('DB_PORT', 5432),
27
+ dbuser: ENV.fetch('DB_USER', 'postgres')
28
+ }
24
29
  RestAssured::Config.build(DB_OPTS)
25
30
 
26
31
  require 'rest-assured'
@@ -18,6 +18,10 @@
18
18
  - statuses.each do |s|
19
19
  %option{:name => s, :selected => (@double.status == s)}= s
20
20
 
21
+ %p
22
+ %label{:for => 'double_delay'} Delay
23
+ %input.wide#double_delay{:type => 'text', :name => 'double[delay]', :value => @double.delay}
24
+
21
25
  %p
22
26
  %label{:for => 'double_description'} Description
23
27
  %textarea.wide#double_description{:name => 'double[description]', :rows => 3}= @double.description
@@ -7,6 +7,7 @@
7
7
  %th Description
8
8
  %th Verb
9
9
  %th Status
10
+ %th Delay
10
11
  %th Active?
11
12
  %th &nbsp;
12
13
  %tbody
@@ -22,6 +23,7 @@
22
23
  %td= f.description
23
24
  %td= f.verb
24
25
  %td= f.status
26
+ %td= f.delay
25
27
  %td.label.text-center
26
28
  - if fs.size > 1
27
29
  %input.active-double-toggle{:type => 'radio', :name => group, :checked => f.active, :data => { 'double-id' => f.id }}
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.0.2
4
+ version: 2.1.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: 2016-05-24 00:00:00.000000000 Z
11
+ date: 2017-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -133,6 +133,7 @@ files:
133
133
  - db/migrate/20111021113953_add_status_to_doubles.rb
134
134
  - db/migrate/20111208155906_add_response_headers_to_doubles.rb
135
135
  - db/migrate/20120320200820_change_fullpath_to_text.rb
136
+ - db/migrate/20170713000515_add_delay_to_doubles.rb
136
137
  - db/test.db
137
138
  - features/command_line_options.feature
138
139
  - features/rest_api/doubles.feature
@@ -229,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
229
230
  version: '0'
230
231
  requirements: []
231
232
  rubyforge_project: rest-assured
232
- rubygems_version: 2.5.1
233
+ rubygems_version: 2.6.11
233
234
  signing_key:
234
235
  specification_version: 4
235
236
  summary: Real stubs and spies for HTTP(S) services