rest_baby 0.5 → 0.6
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/.rubocop.yml +20 -0
- data/ChangeLog +4 -0
- data/Gemfile +1 -0
- data/Rakefile +4 -4
- data/cucumber.yml +4 -4
- data/features/{headers/header_options.feature → header_options.feature} +8 -4
- data/features/print_response.feature +6 -6
- data/features/rest_client.feature +2 -2
- data/features/step_definitions/header_steps.rb +23 -13
- data/features/step_definitions/rest_client_steps.rb +50 -47
- data/features/support/env.rb +3 -2
- data/features/support/mock_rest_service.rb +30 -23
- data/features/support/utility.rb +2 -2
- data/lib/rest_baby/version.rb +2 -1
- data/lib/rest_baby.rb +161 -194
- data/rest_baby.gemspec +12 -13
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86630eb56f0b1daee5aa7f2e7a28776a1e38d3b6
|
4
|
+
data.tar.gz: 6a44e6984e440e831bd7eb9f1ade1dc7834504bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7be630a9887bcbbcc1b9130f3886d9beeb42ead8e1809bedd390a73d0fc0b83447a59a2a80b145dbe7cc35adc2752afac0fb8d3918ded85185656a258c527d6e
|
7
|
+
data.tar.gz: ac1c5a81bc2e75166a60ad9a1a7cc1bc69bd96bea059e2d4329006ebd845b3fc10fe958ce637cb0e2b86112729d56cb90f6262d3944395b34542c63ebf736008
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
AllCops:
|
2
|
+
Include:
|
3
|
+
- '**/Rakefile'
|
4
|
+
- '**/config.ru'
|
5
|
+
- 'lib/**/*'
|
6
|
+
- 'bin/**/*'
|
7
|
+
Exclude:
|
8
|
+
- 'features/**/*'
|
9
|
+
|
10
|
+
# Configuration parameters: AllowURI, URISchemes.
|
11
|
+
Metrics/LineLength:
|
12
|
+
Max: 81
|
13
|
+
|
14
|
+
# Configuration parameters: CountComments.
|
15
|
+
Metrics/MethodLength:
|
16
|
+
Max: 14
|
17
|
+
|
18
|
+
# Configuration parameters: CountKeywordArgs.
|
19
|
+
Metrics/ParameterLists:
|
20
|
+
Max: 6
|
data/ChangeLog
CHANGED
@@ -21,3 +21,7 @@
|
|
21
21
|
=== Version 0.5 / 2014-07-27
|
22
22
|
* Enabled use of query parameters on GET calls
|
23
23
|
* Revised tests to replace expect with should
|
24
|
+
=== Version 0.5 / 2014-07-27
|
25
|
+
* Fixed reference to nokogiri' (~> 0)
|
26
|
+
* Fixed all cukes, no more @wip
|
27
|
+
* Added rubocop style-checker/lint compliance
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
2
|
require 'rubygems'
|
3
3
|
require 'cucumber'
|
4
4
|
require 'cucumber/rake/task'
|
@@ -9,9 +9,9 @@ Cucumber::Rake::Task.new(:features) do |t|
|
|
9
9
|
t.profile = 'default'
|
10
10
|
end
|
11
11
|
|
12
|
-
task :
|
12
|
+
task default: :features
|
13
13
|
|
14
14
|
YARD::Rake::YardocTask.new do |t|
|
15
|
-
|
16
|
-
|
15
|
+
t.files = ['features/**/*.feature', 'features/**/*.rb']
|
16
|
+
t.options = ['--any', '--extra', '--opts'] # optional
|
17
17
|
end
|
data/cucumber.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
default: FIG_NEWTON_FILE=mock.yml --tags ~@wip --no-source --color --format pretty
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
default: FIG_NEWTON_FILE=mock.yml DEBUG_HTTP=false --tags ~@wip --no-source --color --format pretty
|
2
|
+
debug: FIG_NEWTON_FILE=mock.yml DEBUG_HTTP=true --no-source --color --format pretty
|
3
|
+
report: FIG_NEWTON_FILE=mock.yml DEBUG_HTTP=false --no-source --color --format progress --format html --out='features_<%= Time.new.strftime('%Y-%m-%d_%H_%M_%S') %>.html'
|
4
|
+
wip: FIG_NEWTON_FILE=mock.yml DEBUG_HTTP=true --tags @wip --color --format pretty
|
@@ -1,6 +1,7 @@
|
|
1
1
|
Feature: Create a basic rest client that can get, put, post, and delete
|
2
2
|
|
3
|
-
@extended @get @
|
3
|
+
@extended @get @header
|
4
|
+
@header.S1
|
4
5
|
Scenario: client uses an Accept header for a GET
|
5
6
|
Given I have a web service
|
6
7
|
And I have "GET" service for "/test" with the following headers
|
@@ -11,7 +12,8 @@ Scenario: client uses an Accept header for a GET
|
|
11
12
|
And I "GET" from the web service
|
12
13
|
Then I receive the expected message
|
13
14
|
|
14
|
-
@extended @post @headers
|
15
|
+
@extended @post @headers
|
16
|
+
@header.S2
|
15
17
|
Scenario: client uses an Accept and a Content-Type header for a POST
|
16
18
|
Given I have a web service
|
17
19
|
And I have "POST" service for "/test" with the following headers
|
@@ -27,7 +29,8 @@ Scenario: client uses an Accept and a Content-Type header for a POST
|
|
27
29
|
"""
|
28
30
|
Then I receive the expected message
|
29
31
|
|
30
|
-
@extended @post @authentication
|
32
|
+
@extended @post @authentication
|
33
|
+
@header.S3
|
31
34
|
Scenario: client uses basic authentication
|
32
35
|
Given I have a web service
|
33
36
|
And I have "GET" service for "/test" for user "test" and password "rest"
|
@@ -36,7 +39,8 @@ Scenario: client uses basic authentication
|
|
36
39
|
And I "GET" from the web service
|
37
40
|
Then I receive the expected message
|
38
41
|
|
39
|
-
@extended @post @authentication
|
42
|
+
@extended @post @authentication
|
43
|
+
@header.S4
|
40
44
|
Scenario: client uses a secure web server
|
41
45
|
Given I have a secure web service
|
42
46
|
And I have "GET" service for "/test" for user "test" and password "rest"
|
@@ -6,7 +6,7 @@ Scenario: client rest Get
|
|
6
6
|
Given I have a web service
|
7
7
|
And I have "GET" service for "/test" as follows
|
8
8
|
"""
|
9
|
-
{
|
9
|
+
{"Answer": "What did you expect?"}
|
10
10
|
"""
|
11
11
|
And I am a rest client
|
12
12
|
When I "GET" from the web service
|
@@ -18,12 +18,12 @@ Scenario: client rest Put
|
|
18
18
|
Given I have a web service
|
19
19
|
And I have "PUT" service for "/test" as follows
|
20
20
|
"""
|
21
|
-
{
|
21
|
+
{"Answer": "What did you expect?"}
|
22
22
|
"""
|
23
23
|
And I am a rest client
|
24
24
|
When I "PUT" to the web service with the following
|
25
25
|
"""
|
26
|
-
{
|
26
|
+
{"Answer": "What did you expect?"}
|
27
27
|
"""
|
28
28
|
Then I receive the expected message
|
29
29
|
|
@@ -33,12 +33,12 @@ Scenario: client rest Post
|
|
33
33
|
Given I have a web service
|
34
34
|
And I have "POST" service for "/test" as follows
|
35
35
|
"""
|
36
|
-
{
|
36
|
+
{"Answer": "What did you expect?"}
|
37
37
|
"""
|
38
38
|
And I am a rest client
|
39
39
|
When I "POST" to the web service with the following
|
40
40
|
"""
|
41
|
-
{
|
41
|
+
{"Answer": "What did you expect?"}
|
42
42
|
"""
|
43
43
|
Then I receive the expected message
|
44
44
|
|
@@ -48,7 +48,7 @@ Scenario: client rest Delete
|
|
48
48
|
Given I have a web service
|
49
49
|
And I have "DELETE" service for "/test" as follows
|
50
50
|
"""
|
51
|
-
{
|
51
|
+
{"Answer": "What did you expect?"}
|
52
52
|
"""
|
53
53
|
And I am a rest client
|
54
54
|
When I "DELETE" from the web service
|
@@ -17,7 +17,7 @@ Scenario: client rest PUT
|
|
17
17
|
And I am a rest client
|
18
18
|
When I "PUT" to the web service with the following
|
19
19
|
"""
|
20
|
-
{
|
20
|
+
{"Question": "What is the meaning of life?"}
|
21
21
|
"""
|
22
22
|
Then I receive the expected message
|
23
23
|
|
@@ -29,7 +29,7 @@ Scenario: client rest POST
|
|
29
29
|
And I am a rest client
|
30
30
|
When I "POST" to the web service with the following
|
31
31
|
"""
|
32
|
-
{
|
32
|
+
{"Question": "What is the meaning of life?"}
|
33
33
|
"""
|
34
34
|
Then I receive the expected message
|
35
35
|
|
@@ -1,24 +1,34 @@
|
|
1
1
|
Given(/^I have a secure web service$/) do
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
@protocol = 'https'
|
3
|
+
@server = FigNewton.server
|
4
|
+
@port = FigNewton.port
|
5
|
+
@mockservice = MockRestService.new(@server, @port, @protocol)
|
6
6
|
end
|
7
7
|
|
8
|
-
Given(/^I have "(GET|PUT|POST|DELETE)" service for "([^"]*)
|
9
|
-
|
10
|
-
|
8
|
+
Given(/^I have "(GET|PUT|POST|DELETE)" service for "([^"]*)" \
|
9
|
+
with the following headers$/) do |type, path, table|
|
10
|
+
@path = path
|
11
|
+
@mockservice.store_msg(type, path, DEFAULT_MSG, table.rows_hash)
|
11
12
|
end
|
12
13
|
|
13
|
-
Given(/^I have "(GET|
|
14
|
-
|
15
|
-
|
14
|
+
Given(/^I have "(GET|DELETE)" service for "([^"]*)" for \
|
15
|
+
user "([^"]*)" and password "([^"]*)"$/) do |type, path, user, password|
|
16
|
+
@path = path
|
17
|
+
@mockservice.store_msg(type, path, DEFAULT_MSG, {}, user, password)
|
18
|
+
end
|
19
|
+
|
20
|
+
Given(/^I have "(PUT|POST)" service for "([^"]*)" for \
|
21
|
+
user "([^"]*)" and password "([^"]*)"$/) do |type, path, user, password, table|
|
22
|
+
@path = path
|
23
|
+
@headers = table.rows_hash
|
24
|
+
@mockservice.store_msg(type, path, DEFAULT_MSG, @headers, user, password)
|
16
25
|
end
|
17
26
|
|
18
27
|
When(/^I have the following headers?$/) do |table|
|
19
|
-
|
28
|
+
@restbaby.add_headers(table.rows_hash)
|
20
29
|
end
|
21
30
|
|
22
|
-
Given(/^I have basic auth for user "(
|
23
|
-
|
31
|
+
Given(/^I have basic auth for user "([^"]*)" \
|
32
|
+
and password "(.*?)"$/) do |user, password|
|
33
|
+
@restbaby.set_auth(user, password)
|
24
34
|
end
|
@@ -1,72 +1,75 @@
|
|
1
|
-
|
1
|
+
DEFAULT_MSG = "{\"Answer\": \"What did you expect?\"}"
|
2
2
|
|
3
3
|
Given(/^I have a web service$/) do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
@protocol = 'http'
|
5
|
+
@server = FigNewton.server
|
6
|
+
@port = FigNewton.port
|
7
|
+
@mockservice = MockRestService.new(@server, @port, @protocol)
|
8
8
|
end
|
9
9
|
|
10
|
-
Given(/^I have "(GET|PUT|POST|DELETE)" service for "(
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
Given(/^I have "(GET|PUT|POST|DELETE)" service for "([^"]*)"$/) do |type, path|
|
11
|
+
if type == 'GET'
|
12
|
+
create_get(type, path)
|
13
|
+
else
|
14
|
+
@path = path
|
15
|
+
@mockservice.store_msg(type, path, DEFAULT_MSG)
|
16
|
+
end
|
17
17
|
end
|
18
18
|
|
19
|
-
Given(/^I have "(GET|PUT|POST|DELETE)" service for "(
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
19
|
+
Given(/^I have "(GET|PUT|POST|DELETE)" service for "([^"]*)" as follows$/) \
|
20
|
+
do |type, path, message|
|
21
|
+
if type == 'GET'
|
22
|
+
create_get(type, path, message)
|
23
|
+
else
|
24
|
+
@path = path
|
25
|
+
@mockservice.store_msg(type, path, message)
|
26
|
+
end
|
26
27
|
end
|
27
28
|
|
28
|
-
def create_get(
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
def create_get(_type, path, message = DEFAULT_MSG)
|
30
|
+
@path = path.split('?')[0]
|
31
|
+
if path.split('?').length == 1
|
32
|
+
@mockservice.store_msg('GET', @path, message)
|
33
|
+
else
|
34
|
+
@mockservice.store_get_query(path)
|
35
|
+
end
|
35
36
|
end
|
36
37
|
|
37
38
|
Given(/^I am a rest client$/) do
|
38
|
-
|
39
|
+
@restbaby = Client.new("#{@protocol}://#{@server}:#{@port}#{@path}")
|
39
40
|
end
|
40
41
|
|
41
42
|
When(/^I "(GET|DELETE)" from the web service$/) do |type|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
case type.downcase
|
44
|
+
when 'get'
|
45
|
+
@response = @restbaby.get
|
46
|
+
when 'delete'
|
47
|
+
@response = @restbaby.delete
|
48
|
+
end
|
48
49
|
end
|
49
50
|
|
50
|
-
When(/^I "(PUT|POST)" to the web service with the following$/)
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
When(/^I "(PUT|POST)" to the web service with the following$/) \
|
52
|
+
do |type, message|
|
53
|
+
@message = JSON(message)
|
54
|
+
case type.downcase
|
55
|
+
when 'put'
|
56
|
+
@response = @restbaby.put(@message)
|
57
|
+
when 'post'
|
58
|
+
@response = @restbaby.post(@message)
|
59
|
+
end
|
57
60
|
end
|
58
61
|
|
59
62
|
When(/^I "GET" from the web service with the parameters$/) do |table|
|
60
|
-
|
63
|
+
@response = @restbaby.get({}, nil, table.rows_hash)
|
61
64
|
end
|
62
65
|
|
63
66
|
When(/^I pause$/) do
|
64
|
-
pause
|
67
|
+
pause
|
65
68
|
end
|
66
69
|
|
67
70
|
Then(/^I receive the expected message$/) do
|
68
|
-
|
69
|
-
|
71
|
+
@response.code.should eq('200')
|
72
|
+
expect(@response.body).to eq(DEFAULT_MSG)
|
70
73
|
end
|
71
74
|
|
72
75
|
# Then(/^I receive the following$/) do |message|
|
@@ -74,7 +77,7 @@ end
|
|
74
77
|
# @response.body.should eq(message)
|
75
78
|
# end
|
76
79
|
|
77
|
-
Then(/^I receive a message with "(
|
78
|
-
|
79
|
-
|
80
|
+
Then(/^I receive a message with "([^"]*)"$/) do |message|
|
81
|
+
@response.code.should eq('200')
|
82
|
+
@response.body.should eq(message)
|
80
83
|
end
|
data/features/support/env.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
require 'rspec
|
1
|
+
require 'rspec/expectations'
|
2
2
|
require 'fig_newton'
|
3
3
|
require 'cucumber/rspec/doubles'
|
4
4
|
require 'rubygems'
|
5
5
|
require 'webmock/cucumber'
|
6
|
-
require File.expand_path(File.join(File.dirname(__FILE__),
|
6
|
+
require File.expand_path(File.join(File.dirname(__FILE__),
|
7
|
+
'..', '..', 'lib', 'rest_baby.rb'))
|
7
8
|
|
8
9
|
include RestBaby
|
9
10
|
|
@@ -2,44 +2,51 @@ require 'webmock/cucumber'
|
|
2
2
|
|
3
3
|
include WebMock::API
|
4
4
|
|
5
|
+
# Mocking Service for testing rest calls
|
5
6
|
class MockRestService
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
STANDARD = "http"
|
10
|
-
SECURE = "https"
|
7
|
+
STANDARD_HEADERS = { 'Accept' => '*/*', 'User-Agent' => 'Ruby' }
|
8
|
+
STANDARD = 'http'
|
9
|
+
SECURE = 'https'
|
11
10
|
|
12
11
|
def initialize(host, port, protocol = STANDARD)
|
13
12
|
@protocol = protocol
|
14
13
|
@host = host
|
15
14
|
@port = port
|
16
15
|
@messages = {}
|
17
|
-
end
|
16
|
+
end
|
18
17
|
|
19
18
|
def store_msg(type, path, message, headers = {}, user = nil, password = nil)
|
20
|
-
|
21
|
-
auth_string = "#{user}:#{password}@" unless (user.nil? || password.nil?)
|
19
|
+
url = "#{@protocol}://#{auth_string(user, password)}#{@host}:#{@port}#{path}"
|
22
20
|
case type.downcase
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
21
|
+
when 'get', 'delete'
|
22
|
+
WebMock.stub_request(type.downcase.to_sym, url)
|
23
|
+
.with(headers: merge_headers(headers))
|
24
|
+
.to_return({ status: 200, body: "#{message}" }, headers: {})
|
25
|
+
when 'put', 'post'
|
26
|
+
WebMock.stub_request(:put, url)
|
27
|
+
.with(body: body,
|
28
|
+
headers: merge_headers(headers))
|
29
|
+
.to_return({ status: 200, body: "#{message}" }, headers: {})
|
30
|
+
else
|
31
|
+
fail "Unsupported type: #{type}"
|
33
32
|
end
|
34
33
|
end
|
35
34
|
|
35
|
+
def merge_headers(headers)
|
36
|
+
STANDARD_HEADERS.merge(headers)
|
37
|
+
end
|
38
|
+
|
39
|
+
def auth_string(user, password)
|
40
|
+
"#{user}:#{password}@" unless user.nil? || password.nil?
|
41
|
+
end
|
42
|
+
|
36
43
|
def store_get_query(path, headers = {}, user = nil, password = nil)
|
37
44
|
new_headers = STANDARD_HEADERS.merge(headers)
|
38
|
-
params = Hash.new
|
39
45
|
message = path.split('?').last
|
40
|
-
auth_string = "#{user}:#{password}@" unless
|
41
|
-
WebMock.stub_request(:get,
|
42
|
-
|
43
|
-
|
46
|
+
auth_string = "#{user}:#{password}@" unless user.nil? || password.nil?
|
47
|
+
WebMock.stub_request(:get,
|
48
|
+
"#{@protocol}://#{auth_string}#{@host}:#{@port}#{path}")
|
49
|
+
.with(headers: new_headers)
|
50
|
+
.to_return({ body: "#{message}", status: 200 }, headers: {})
|
44
51
|
end
|
45
52
|
end
|
data/features/support/utility.rb
CHANGED
data/lib/rest_baby/version.rb
CHANGED
data/lib/rest_baby.rb
CHANGED
@@ -9,200 +9,167 @@ require 'json'
|
|
9
9
|
require 'nokogiri'
|
10
10
|
require 'rest_baby/version'
|
11
11
|
|
12
|
-
# RestBaby is a small rest client. It encapsulates some of the details for
|
12
|
+
# RestBaby is a small rest client. It encapsulates some of the details for
|
13
|
+
# creating and using the rest service.
|
13
14
|
# @private
|
14
15
|
module RestBaby
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
puts request.body
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
# Pretty print the web services last response
|
180
|
-
def print_response(response)
|
181
|
-
if @verbose
|
182
|
-
puts "<< RESPONSE"
|
183
|
-
puts " < CODE = #{response.code}"
|
184
|
-
puts " < MESSAGE = #{response.message}"
|
185
|
-
response.each { |key, value| puts " < #{key} = #{value}\n"}
|
186
|
-
puts " < BODY = "
|
187
|
-
if response.header['Content-Type']=='application/json'
|
188
|
-
jj JSON(response.body)
|
189
|
-
elsif response.header['Content-Type']=='text/csv'
|
190
|
-
puts response.body
|
191
|
-
elsif response.header['Content-Type']=='application/xml'
|
192
|
-
puts pretty_xml(body)
|
193
|
-
elsif response.body.nil?
|
194
|
-
puts "[Empty]"
|
195
|
-
else
|
196
|
-
puts "#{response.body}\n<"
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
def pretty_xml(xml)
|
202
|
-
doc = Nokogiri.XML(xml) do |config|
|
203
|
-
config.default_xml.noblanks
|
204
|
-
end
|
205
|
-
return doc.to_xml(:indent => 2)
|
206
|
-
end
|
207
|
-
end
|
16
|
+
# Sends and receives data to a restful web service
|
17
|
+
class Client
|
18
|
+
PARAM_STARTER = '?'
|
19
|
+
PARAM_SEPARATOR = '&'
|
20
|
+
|
21
|
+
# The WebService Response from the last call
|
22
|
+
attr_reader :wsresponse
|
23
|
+
# The user (for authentication)
|
24
|
+
attr_reader :user
|
25
|
+
# The password for the user (for authentication)
|
26
|
+
attr_reader :password
|
27
|
+
# Response Code
|
28
|
+
attr_reader :code
|
29
|
+
|
30
|
+
# Creates a new rest client
|
31
|
+
#
|
32
|
+
# @param url [String] url of the rest service
|
33
|
+
# eg. http://myrestservice.com:80/time
|
34
|
+
# @param headers [Hash] default headers to use.
|
35
|
+
# eg. '{ \"Content-Type\" => \"application/json\"}'
|
36
|
+
# Can be multiple headers separated by commas inside the brackets.
|
37
|
+
def initialize(url, headers = {}, user = nil, password = nil)
|
38
|
+
@url = url
|
39
|
+
@headers = headers
|
40
|
+
@user = user
|
41
|
+
@password = password
|
42
|
+
@verbose = (ENV['DEBUG_HTTP'] != 'false')
|
43
|
+
end
|
44
|
+
|
45
|
+
# Adds user/password to the rest client
|
46
|
+
#
|
47
|
+
# @param user [String] user that has authorization
|
48
|
+
# @param password [String] authorized user's password
|
49
|
+
def set_auth(user, password)
|
50
|
+
@user = user
|
51
|
+
@password = password
|
52
|
+
end
|
53
|
+
|
54
|
+
# Modifies the headers by merging new headers with current headers.
|
55
|
+
#
|
56
|
+
# @param headers [Hash] new headers to merge with current headers
|
57
|
+
def add_headers(headers)
|
58
|
+
@headers = @headers.merge(headers)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Basic web services Get command
|
62
|
+
#
|
63
|
+
# @param headers [Hash] header parameters including authorization
|
64
|
+
# and Content-Type
|
65
|
+
# @param path [String] Path of service to send the command to
|
66
|
+
# @param parameters [Hash] query string that added as part of the URL
|
67
|
+
# @return The response from the rest server is returned
|
68
|
+
def get(headers = {}, path = '', parameters = {})
|
69
|
+
full_path = [path, URI.encode_www_form(parameters)].join(PARAM_STARTER)
|
70
|
+
uri = URI.parse("#{@url}#{full_path}")
|
71
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
72
|
+
request.body = nil
|
73
|
+
send_request(uri, request, headers)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Basic web services Post command
|
77
|
+
#
|
78
|
+
# @param path [String] Path of service to send the command to
|
79
|
+
# @param body [Any type of string] Data to put in the
|
80
|
+
# body such as json or xml
|
81
|
+
# @param headers [Hash] header parameters including authorization
|
82
|
+
# and Content-Type
|
83
|
+
# @return The response from the rest server is returned
|
84
|
+
def post(body = nil, headers = {}, path = '')
|
85
|
+
uri = URI.parse("#{@url}#{path}")
|
86
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
87
|
+
request.body = body unless body.nil?
|
88
|
+
send_request(uri, request, headers)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Basic web services Delete command
|
92
|
+
#
|
93
|
+
# @param path [String] Path of service to send the command to
|
94
|
+
# @param headers [Hash] header parameters including
|
95
|
+
# authorization and Content-Type
|
96
|
+
# @return The response from the rest server is returned
|
97
|
+
def delete(headers = {}, path = '', parameters = {})
|
98
|
+
full_path = [path, URI.encode_www_form(parameters)].join(PARAM_STARTER)
|
99
|
+
uri = URI.parse("#{@url}#{full_path}")
|
100
|
+
request = Net::HTTP::Delete.new(uri.request_uri)
|
101
|
+
request.body = nil
|
102
|
+
send_request(uri, request, headers)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Basic web services Put command
|
106
|
+
#
|
107
|
+
# @param path [String] Path of service to send the command to
|
108
|
+
# @param body [String] data to put in the body
|
109
|
+
# @param headers [Hash] header parameters including authorization
|
110
|
+
# and Content-Type
|
111
|
+
# @return Response from the rest server is returned
|
112
|
+
def put(body = nil, headers = {}, path = '')
|
113
|
+
uri = URI.parse("#{@url}#{path}")
|
114
|
+
request = Net::HTTP::Put.new(uri.request_uri)
|
115
|
+
request.body = body unless body.nil?
|
116
|
+
send_request(uri, request, headers)
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def send_request(uri, request, headers)
|
122
|
+
@headers.merge(headers).each { |key, value| request[key] = value }
|
123
|
+
request.basic_auth(@user, @password) unless @user.nil?
|
124
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
125
|
+
http.use_ssl = true if uri.scheme == 'https'
|
126
|
+
print_request(request, uri)
|
127
|
+
@wsresponse = http.request(request)
|
128
|
+
print_response(@wsresponse)
|
129
|
+
@wsresponse
|
130
|
+
end
|
131
|
+
|
132
|
+
def print_request(request, uri)
|
133
|
+
return nil unless @verbose
|
134
|
+
query = ((uri.query == '') ? '' : "?#{uri.query}")
|
135
|
+
puts ">> REQUEST\n"\
|
136
|
+
"> URL: #{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}#{query}\n"\
|
137
|
+
"> Headers:\n"\
|
138
|
+
"#{header_text(request, '> ')}\n"\
|
139
|
+
"> BODY =\n"\
|
140
|
+
"> BODY =\n#{body_text(request['Content-Type'], request.body)}"
|
141
|
+
end
|
142
|
+
|
143
|
+
def print_response(response)
|
144
|
+
return nil unless @verbose
|
145
|
+
puts "<< RESPONSE\n"\
|
146
|
+
"< CODE = #{response.code}\n"\
|
147
|
+
"< MESSAGE = #{response.message}\n"\
|
148
|
+
"#{header_text(response, ' <')}\n"\
|
149
|
+
"< BODY =\n#{body_text(response['Content-Type'], response.body)}"
|
150
|
+
end
|
151
|
+
|
152
|
+
def header_text(message, pointer)
|
153
|
+
headers = ''
|
154
|
+
message.each { |key, value| headers << "#{pointer} #{key} = #{value}\n" }
|
155
|
+
headers
|
156
|
+
end
|
157
|
+
|
158
|
+
def body_text(type, response_body)
|
159
|
+
return '[Empty]' if response_body.nil?
|
160
|
+
case type
|
161
|
+
when 'application/json'
|
162
|
+
JSON.pretty_generate(response_body)
|
163
|
+
when 'application/xml'
|
164
|
+
pretty_xml(response_body)
|
165
|
+
else
|
166
|
+
"#{response_body}\n<"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def pretty_xml(xml)
|
171
|
+
doc = Nokogiri.XML(xml) { |config| config.default_xml.noblanks }
|
172
|
+
doc.to_xml(indent: 2)
|
173
|
+
end
|
174
|
+
end
|
208
175
|
end
|
data/rest_baby.gemspec
CHANGED
@@ -4,21 +4,21 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'rest_baby/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'rest_baby'
|
8
8
|
spec.version = RestBaby::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.description =
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
9
|
+
spec.authors = ['Dave McNulla']
|
10
|
+
spec.email = ['mcnulla@gmail.com']
|
11
|
+
spec.description = 'Rest client'
|
12
|
+
spec.summary = 'Small rest client developed to testing rest services.'
|
13
|
+
spec.homepage = 'https://github.com/dmcnulla/rest_baby'
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
|
-
spec.files = `git ls-files`.split(
|
17
|
-
spec.executables = spec.files.grep(
|
18
|
-
spec.test_files = spec.files.grep(
|
19
|
-
spec.require_paths = [
|
16
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
|
+
spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(/^(test|spec|features)/)
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_dependency 'nokogiri', '~>
|
21
|
+
spec.add_dependency 'nokogiri', '~> 1.6'
|
22
22
|
spec.add_dependency 'json', '~> 1.8', '>= 1.8.0'
|
23
23
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
24
24
|
spec.add_development_dependency 'rake', '~> 0'
|
@@ -26,5 +26,4 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_development_dependency 'fig_newton', '~> 0.9'
|
27
27
|
spec.add_development_dependency 'rspec', '~> 2.14', '>= 2.14.1'
|
28
28
|
spec.add_development_dependency 'webmock', '~> 1.13', '>= 1.13.0'
|
29
|
-
|
30
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest_baby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.6'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dave McNulla
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1.6'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '1.6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: json
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -153,6 +153,7 @@ executables: []
|
|
153
153
|
extensions: []
|
154
154
|
extra_rdoc_files: []
|
155
155
|
files:
|
156
|
+
- ".rubocop.yml"
|
156
157
|
- ChangeLog
|
157
158
|
- Gemfile
|
158
159
|
- LICENSE.txt
|
@@ -202,7 +203,7 @@ files:
|
|
202
203
|
- doc/stepdefinition_list.html
|
203
204
|
- doc/tag_list.html
|
204
205
|
- doc/top-level-namespace.html
|
205
|
-
- features/
|
206
|
+
- features/header_options.feature
|
206
207
|
- features/print_response.feature
|
207
208
|
- features/rest_client.feature
|
208
209
|
- features/step_definitions/header_steps.rb
|
@@ -234,12 +235,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
234
235
|
version: '0'
|
235
236
|
requirements: []
|
236
237
|
rubyforge_project:
|
237
|
-
rubygems_version: 2.
|
238
|
+
rubygems_version: 2.4.5
|
238
239
|
signing_key:
|
239
240
|
specification_version: 4
|
240
|
-
summary:
|
241
|
+
summary: Small rest client developed to testing rest services.
|
241
242
|
test_files:
|
242
|
-
- features/
|
243
|
+
- features/header_options.feature
|
243
244
|
- features/print_response.feature
|
244
245
|
- features/rest_client.feature
|
245
246
|
- features/step_definitions/header_steps.rb
|