arest 0.9.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/arest.rb +123 -0
- data/spec/arest_spec.rb +85 -0
- data/spec/spec_helper.rb +97 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 486926dcce7e504ad5fd10ddc6eb66495681fad1
|
4
|
+
data.tar.gz: 42a53c28a548b74d049f4cfa9c0fafb32b0de8cb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5ce9be9ec6c7302033c4b04e9e5ddf3ec815258d0b11a7607833089eeae91e78e790bb89e01b2b27e6543ac6bf2c704f67d41140be8a3a37023036c0e7f934a8
|
7
|
+
data.tar.gz: 92b431e715d1c731dbc42b84c0d551b83ee50dcd15cc83bbef49242b283757c5945062cc0f394e263802ce0577c8048f317697c3481c97528904bcebc5641f06
|
data/lib/arest.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
require 'active_support/core_ext/hash/conversions'
|
4
|
+
|
5
|
+
# Extensions to standard HTTPResponse
|
6
|
+
class Net::HTTPResponse
|
7
|
+
# Find out the content type of the response and convert it the proper object
|
8
|
+
def deserialize
|
9
|
+
case content_type
|
10
|
+
when "application/xml"
|
11
|
+
Hash.from_xml body
|
12
|
+
when "application/json"
|
13
|
+
JSON.parse body
|
14
|
+
else
|
15
|
+
body
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# True if response is HTTP OK
|
20
|
+
def ok?
|
21
|
+
Net::HTTPSuccess === self || Net::HTTPRedirection === self
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class ARestException < Exception; end
|
26
|
+
|
27
|
+
class ARest
|
28
|
+
# Input:
|
29
|
+
# * base_url - the base URL for REST API
|
30
|
+
#
|
31
|
+
# Options:
|
32
|
+
# * headers (Hash) to set up headers
|
33
|
+
# c = ARest.new "http://localhost:3000/_api/v1", headers: {"Authentication" => "Token token=AHDIUHSBC...."}
|
34
|
+
#
|
35
|
+
# * username and password for basic http authentication
|
36
|
+
# c = ARest.new "http://localhost:3000/_api/v1", username: "user1", password: "password.8"
|
37
|
+
#
|
38
|
+
# * Authentication token
|
39
|
+
# c = ARest.new "http://localhost:3000/_api/v1", token: 'AdbsuUDhwb3hqhj...'
|
40
|
+
def initialize(base_url, **options)
|
41
|
+
@base_url = base_url
|
42
|
+
@headers = options[:headers]
|
43
|
+
@auth_user = options[:username]
|
44
|
+
@auth_password = options[:password]
|
45
|
+
@auth_token = options[:token]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Perform a HTTP GET request. Requires a path to current operation
|
49
|
+
# See #execute for details
|
50
|
+
def get(path, **options)
|
51
|
+
execute :get, path, options
|
52
|
+
end
|
53
|
+
|
54
|
+
# Perform a HTTP POST request. Requires a path to current operation
|
55
|
+
# See #execute for details
|
56
|
+
def post(path, **options)
|
57
|
+
execute :post, path, options
|
58
|
+
end
|
59
|
+
|
60
|
+
# Perform a HTTP PUT request. Requires a path to current operation
|
61
|
+
# See #execute for details
|
62
|
+
def put(path, **options)
|
63
|
+
execute :put, path, options
|
64
|
+
end
|
65
|
+
|
66
|
+
# Perform a HTTP DELETE request. Requires a path to current operation
|
67
|
+
# See #execute for details
|
68
|
+
def delete(path, **options)
|
69
|
+
execute :delete, path, options
|
70
|
+
end
|
71
|
+
|
72
|
+
def inspect
|
73
|
+
"<ARest #{@base_url}#{if @headers then ', with headers' else '' end}#{if @auth_user && @auth_password then ', authenticating as '+@auth_user else '' end}>"
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
# Perform a HTTP request. Requires method name a path to current operation.
|
78
|
+
# If given, headers and http authentication can be override
|
79
|
+
#
|
80
|
+
# Input
|
81
|
+
# * method - HTTP method, :get, :post, :delete, :header, :update
|
82
|
+
# * path - relative to URI given in constructor
|
83
|
+
# Options Hash
|
84
|
+
# * headers - overrides the header given in constructor
|
85
|
+
# * username, password - overrides the http authentication
|
86
|
+
# * token - overrides authorization token
|
87
|
+
# * form_data - hash with HTML form data
|
88
|
+
def execute(method, path, **options)
|
89
|
+
uri = URI("#{@base_url}/#{path}")
|
90
|
+
|
91
|
+
case method.to_sym
|
92
|
+
when :get
|
93
|
+
req = Net::HTTP::Get.new(uri)
|
94
|
+
when :post
|
95
|
+
req = Net::HTTP::Post.new(uri)
|
96
|
+
when :put
|
97
|
+
req = Net::HTTP::Put.new(uri)
|
98
|
+
when :delete
|
99
|
+
req = Net::HTTP::Delete.new(uri)
|
100
|
+
else
|
101
|
+
raise ARestException, "Unknown method: #{method}"
|
102
|
+
end
|
103
|
+
|
104
|
+
req.form_data = options[:form_data] if options[:form_data]
|
105
|
+
|
106
|
+
headers = options[:headers] || @headers
|
107
|
+
headers.each { |k,v| req[k] = v } if headers
|
108
|
+
|
109
|
+
auth_user = options[:auth_user] || @auth_user
|
110
|
+
auth_password = options[:auth_password] || @auth_password
|
111
|
+
req.basic_auth auth_user, auth_password if auth_user && auth_password
|
112
|
+
|
113
|
+
token = options[:token] || @auth_token
|
114
|
+
if token
|
115
|
+
req["Authorization"] = "Token token=#{token}"
|
116
|
+
end
|
117
|
+
|
118
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
119
|
+
http.request(req)
|
120
|
+
end
|
121
|
+
res
|
122
|
+
end
|
123
|
+
end
|
data/spec/arest_spec.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe ARest do
|
3
|
+
describe "JSON request" do
|
4
|
+
describe "without authentication" do
|
5
|
+
before do
|
6
|
+
@client = ARest.new 'http://jsonplaceholder.typicode.com'
|
7
|
+
end
|
8
|
+
it "should be able to get fake users list" do
|
9
|
+
users_res = @client.get 'users'
|
10
|
+
expect(users_res).to be_ok
|
11
|
+
users = users_res.deserialize
|
12
|
+
expect(users.count).to eq 10
|
13
|
+
end
|
14
|
+
it "should be able to GET fake user" do
|
15
|
+
user = @client.get('users/1').deserialize
|
16
|
+
expect(user["name"]).to eq "Leanne Graham"
|
17
|
+
end
|
18
|
+
it "should be able to POST fake post" do
|
19
|
+
posts_res = @client.post('posts', form_data: { title: 'foo', body: 'bar', userId: 1 })
|
20
|
+
expect(posts_res).to be_ok
|
21
|
+
post = posts_res.deserialize
|
22
|
+
expect(post['title']).to eq 'foo'
|
23
|
+
end
|
24
|
+
it "should be able to PUT fake post" do
|
25
|
+
posts_res = @client.put('posts/1', form_data: { id: 1, title: 'foo', body: 'bar', userId: 1 })
|
26
|
+
expect(posts_res).to be_ok
|
27
|
+
post = posts_res.deserialize
|
28
|
+
expect(post['title']).to eq 'foo'
|
29
|
+
end
|
30
|
+
it "should be able to DELETE fake post" do
|
31
|
+
posts_res = @client.delete('posts/1')
|
32
|
+
expect(posts_res).to be_ok
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "with HTTP authentication" do
|
37
|
+
# to test authentication I use the demo of Tarkin, The Team Password Manager
|
38
|
+
before do
|
39
|
+
@arest = ARest.new 'http://tarkin.tg.pl/_api/v1', username: 'user@example.com', password: 'password0'
|
40
|
+
end
|
41
|
+
it "should be able to login with http authentication" do
|
42
|
+
res = @arest.get '_authorize.json'
|
43
|
+
expect(res).to be_ok
|
44
|
+
end
|
45
|
+
it "should be able to get password" do
|
46
|
+
pass = @arest.get('/db/prod/oracle/scott').deserialize
|
47
|
+
expect(pass).to eq 't1ger'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "with form authentication" do
|
52
|
+
before do
|
53
|
+
@arest = ARest.new 'http://tarkin.tg.pl/_api/v1'
|
54
|
+
end
|
55
|
+
it "should be able to get password with form authentication" do
|
56
|
+
pass = @arest.post('/db/prod/oracle/scott.json', form_data: { email: 'user@example.com', password: 'password0'}).deserialize
|
57
|
+
expect(pass['password']).to eq 't1ger'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "with token authentication" do
|
62
|
+
before do
|
63
|
+
auth = ARest.new 'http://tarkin.tg.pl/_api/v1', username: 'user@example.com', password: 'password0'
|
64
|
+
token = auth.get('_authorize').deserialize
|
65
|
+
@arest = ARest.new 'http://tarkin.tg.pl/_api/v1', token: token
|
66
|
+
end
|
67
|
+
it "should be able to get password" do
|
68
|
+
pass = @arest.get('/db/prod/oracle/scott').deserialize
|
69
|
+
expect(pass).to eq 't1ger'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "XML request" do
|
75
|
+
describe "without authentication" do
|
76
|
+
before do
|
77
|
+
@client = ARest.new 'http://www.thomas-bayer.com/sqlrest'
|
78
|
+
end
|
79
|
+
it "should be able to get the fake customer" do
|
80
|
+
customer = @client.get('CUSTOMER/3').deserialize['CUSTOMER']
|
81
|
+
expect(customer['FIRSTNAME']).to eq "Michael"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
4
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
5
|
+
# files.
|
6
|
+
#
|
7
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
8
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
9
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
10
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
11
|
+
# a separate helper file that requires the additional dependencies and performs
|
12
|
+
# the additional setup, and require it from the spec files that actually need
|
13
|
+
# it.
|
14
|
+
#
|
15
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
16
|
+
# users commonly want.
|
17
|
+
#
|
18
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
19
|
+
|
20
|
+
require 'bundler/setup'
|
21
|
+
Bundler.setup
|
22
|
+
|
23
|
+
require 'arest'
|
24
|
+
|
25
|
+
RSpec.configure do |config|
|
26
|
+
# rspec-expectations config goes here. You can use an alternate
|
27
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
28
|
+
# assertions if you prefer.
|
29
|
+
config.expect_with :rspec do |expectations|
|
30
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
31
|
+
# and `failure_message` of custom matchers include text for helper methods
|
32
|
+
# defined using `chain`, e.g.:
|
33
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
34
|
+
# # => "be bigger than 2 and smaller than 4"
|
35
|
+
# ...rather than:
|
36
|
+
# # => "be bigger than 2"
|
37
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
38
|
+
end
|
39
|
+
|
40
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
41
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
42
|
+
config.mock_with :rspec do |mocks|
|
43
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
44
|
+
# a real object. This is generally recommended, and will default to
|
45
|
+
# `true` in RSpec 4.
|
46
|
+
mocks.verify_partial_doubles = true
|
47
|
+
end
|
48
|
+
|
49
|
+
# The settings below are suggested to provide a good initial experience
|
50
|
+
# with RSpec, but feel free to customize to your heart's content.
|
51
|
+
=begin
|
52
|
+
# These two settings work together to allow you to limit a spec run
|
53
|
+
# to individual examples or groups you care about by tagging them with
|
54
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
55
|
+
# get run.
|
56
|
+
config.filter_run :focus
|
57
|
+
config.run_all_when_everything_filtered = true
|
58
|
+
|
59
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
60
|
+
# recommended. For more details, see:
|
61
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
62
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
63
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
64
|
+
config.disable_monkey_patching!
|
65
|
+
|
66
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
67
|
+
# be too noisy due to issues in dependencies.
|
68
|
+
config.warnings = true
|
69
|
+
|
70
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
71
|
+
# file, and it's useful to allow more verbose output when running an
|
72
|
+
# individual spec file.
|
73
|
+
if config.files_to_run.one?
|
74
|
+
# Use the documentation formatter for detailed output,
|
75
|
+
# unless a formatter has already been configured
|
76
|
+
# (e.g. via a command-line flag).
|
77
|
+
config.default_formatter = 'doc'
|
78
|
+
end
|
79
|
+
|
80
|
+
# Print the 10 slowest examples and example groups at the
|
81
|
+
# end of the spec run, to help surface which specs are running
|
82
|
+
# particularly slow.
|
83
|
+
config.profile_examples = 10
|
84
|
+
|
85
|
+
# Run specs in random order to surface order dependencies. If you find an
|
86
|
+
# order dependency and want to debug it, you can fix the order by providing
|
87
|
+
# the seed, which is printed after each run.
|
88
|
+
# --seed 1234
|
89
|
+
config.order = :random
|
90
|
+
|
91
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
92
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
93
|
+
# test failures related to randomization by passing the same `--seed` value
|
94
|
+
# as the one that triggered the failure.
|
95
|
+
Kernel.srand config.seed
|
96
|
+
=end
|
97
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: arest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tomek Gryszkiewicz
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: json
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.8.3
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.8'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.8.3
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: activesupport
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '4.2'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 4.2.1
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '4.2'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 4.2.1
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rspec
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '3.2'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 3.2.0
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.2'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 3.2.0
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: bundler
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '1.8'
|
80
|
+
type: :development
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '1.8'
|
87
|
+
description: A Very Simple REST client
|
88
|
+
email: grych@tg.pl
|
89
|
+
executables: []
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files: []
|
92
|
+
files:
|
93
|
+
- lib/arest.rb
|
94
|
+
- spec/arest_spec.rb
|
95
|
+
- spec/spec_helper.rb
|
96
|
+
homepage: https://github.com/grych/arest
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
metadata: {}
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 2.4.5
|
117
|
+
signing_key:
|
118
|
+
specification_version: 4
|
119
|
+
summary: A REST client
|
120
|
+
test_files:
|
121
|
+
- spec/arest_spec.rb
|
122
|
+
- spec/spec_helper.rb
|