arest 0.9.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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
@@ -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