restfulness 0.2.0 → 0.2.1

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: 656fc9b27618b6b00f0cdc31dff51fc59081881b
4
- data.tar.gz: eed7ea6153eb14c67d0888643287ed911bfb477a
3
+ metadata.gz: 6461108ff8796134694c51592c8ccefc8053647e
4
+ data.tar.gz: 22405556949ce5d69f7192f2c402038ca8b08802
5
5
  SHA512:
6
- metadata.gz: d06a2ee69944bfd705f22516c246ec49293488e69bc7bc5f7357cbe3830ac1b283e5e5046063c4e22e427d5ddf2541811c2d49b0e285eb742c63c0f132b64564
7
- data.tar.gz: b297d63290e7df33142641c2c8d072d97bb4494ece946b8ec6f2ddb4c44e10ac6cd997729689ede5fefb299f492c77b74e82b9646f04793ca49f77c473a99e70
6
+ metadata.gz: 9bebef2fdf368de74cfb3f63e4acb15c087575fe76e34f24be3e62e47718f9f02c7b82b57993e81778483eaf3289244338620848e49027feb316504c0cffa743
7
+ data.tar.gz: 867d7656b3e93b340ecd362ca7965b65741fb53af3a45e714eb770f9cef879214786bd472605d221a9258cc8d8d2d33305075dda37e410cc145d6c94e3f03af7
data/README.md CHANGED
@@ -422,9 +422,16 @@ Restfulness was created by Sam Lown <me@samlown.com> as a solution for building
422
422
 
423
423
  ## History
424
424
 
425
+ ### 0.2.1 - October 22, 2013
426
+
427
+ * Removing some unnecessary logging and using Rack::CommonLogger.
428
+ * Improving some test coverage.
429
+ * Supporting user agent in requests.
430
+ * Supporting PATCH method in resources.
431
+
425
432
  ### 0.2.0 - October 17, 2013
426
433
 
427
- Refactoring error handling and reporting so that it is easier to use and simpler.
434
+ * Refactoring error handling and reporting so that it is easier to use and simpler.
428
435
 
429
436
  ### 0.1.0 - October 16, 2013
430
437
 
data/lib/restfulness.rb CHANGED
@@ -5,6 +5,7 @@ require 'mono_logger'
5
5
  require 'active_support/core_ext'
6
6
  require 'active_support/dependencies'
7
7
  require 'rack/utils'
8
+ require 'rack/commonlogger'
8
9
  require 'rack/showexceptions'
9
10
  require 'rack/builder'
10
11
 
@@ -10,7 +10,7 @@ module Restfulness
10
10
  # class MyApp < Restfulness::Application
11
11
  #
12
12
  # routes do
13
- # scope 'api' do
13
+ # scope 'api' do # scope not supported yet!
14
14
  # add 'journey', JourneyResource
15
15
  # add 'journeys', JourneyCollectionResource
16
16
  # end
@@ -63,6 +63,7 @@ module Restfulness
63
63
  #
64
64
  def middlewares
65
65
  @middlewares ||= [
66
+ Rack::CommonLogger,
66
67
  Rack::ShowExceptions
67
68
  ]
68
69
  end
@@ -5,59 +5,45 @@ module Restfulness
5
5
  class Rack < Dispatcher
6
6
 
7
7
  def call(env)
8
- rack_req = ::Rack::Request.new(env)
9
-
10
8
  # Make sure we understand the request
11
- request = Request.new(app)
12
- prepare_request(env, rack_req, request)
9
+ request = prepare_request(env)
13
10
 
14
11
  # Prepare a suitable response
15
12
  response = Response.new(request)
16
13
  response.run
17
14
 
18
- log_response(response.status)
19
15
  [response.status, response.headers, [response.payload || ""]]
20
16
  end
21
17
 
22
18
  protected
23
19
 
24
- def prepare_request(env, rack_req, request)
25
- request.uri = rack_req.url
26
- request.action = parse_action(rack_req.request_method)
27
- request.query = rack_req.GET
28
- request.body = rack_req.body
29
- request.remote_ip = rack_req.ip
30
- request.headers = prepare_headers(env)
20
+ def prepare_request(env)
21
+ rack_req = ::Rack::Request.new(env)
22
+ request = Request.new(app)
23
+ request.uri = rack_req.url
24
+ request.action = parse_action(rack_req.request_method)
25
+ request.query = rack_req.GET
26
+ request.body = rack_req.body
27
+ request.headers = prepare_headers(env)
28
+
29
+ request.remote_ip = rack_req.ip
30
+ request.user_agent = rack_req.user_agent
31
31
 
32
32
  # Sometimes rack removes content type from headers
33
33
  request.headers[:content_type] ||= rack_req.content_type
34
+
35
+ request
34
36
  end
35
37
 
36
38
  def parse_action(action)
37
39
  case action
38
- when 'DELETE'
39
- :delete
40
- when 'GET'
41
- :get
42
- when 'HEAD'
43
- :head
44
- when 'POST'
45
- :post
46
- when 'PUT'
47
- :put
48
- when 'PATCH'
49
- :patch
50
- when 'OPTIONS'
51
- :options
40
+ when 'DELETE', 'GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'OPTIONS'
41
+ action.downcase.to_sym
52
42
  else
53
43
  raise HTTPException.new(501)
54
44
  end
55
45
  end
56
46
 
57
- def log_response(status)
58
- logger.info("Completed #{status} #{STATUSES[status]}")
59
- end
60
-
61
47
  def prepare_headers(env)
62
48
  res = {}
63
49
  env.each do |k,v|
@@ -67,10 +53,6 @@ module Restfulness
67
53
  res
68
54
  end
69
55
 
70
- def logger
71
- Restfulness.logger
72
- end
73
-
74
56
  end
75
57
 
76
58
  end
@@ -30,8 +30,8 @@ module Restfulness
30
30
  # Raw HTTP body, for POST and PUT requests.
31
31
  attr_accessor :body
32
32
 
33
- # IP address of requester
34
- attr_accessor :remote_ip
33
+ # Additional useful fields
34
+ attr_accessor :remote_ip, :user_agent
35
35
 
36
36
  def initialize(app)
37
37
  @app = app
@@ -57,8 +57,7 @@ module Restfulness
57
57
  forbidden! unless allowed?
58
58
 
59
59
  # The following callbacks only make sense for certain methods
60
- if [:head, :get, :put, :delete].include?(request.action)
61
-
60
+ if [:head, :get, :put, :patch, :delete].include?(request.action)
62
61
  resource_not_found! unless exists?
63
62
 
64
63
  if [:get, :head].include?(request.action)
@@ -15,11 +15,8 @@ module Restfulness
15
15
  end
16
16
 
17
17
  def run
18
- logger.info("Responding to #{request.action.to_s.upcase} #{request.uri.to_s} from #{request.remote_ip}")
19
-
20
18
  route = request.route
21
19
  if route
22
- logger.info("Using resource: #{route.resource_name}")
23
20
  resource = route.build_resource(request, self)
24
21
 
25
22
  # run callbacks, if any fail, they'll raise an error
@@ -34,15 +31,10 @@ module Restfulness
34
31
  end
35
32
 
36
33
  rescue HTTPException => e # Deal with HTTP exceptions
37
- logger.error(e.message)
38
34
  headers.update(e.headers)
39
35
  update_status_and_payload(e.status, e.payload)
40
36
  end
41
37
 
42
- def logger
43
- Restfulness.logger
44
- end
45
-
46
38
  protected
47
39
 
48
40
  def update_status_and_payload(status, payload = "")
@@ -1,3 +1,3 @@
1
1
  module Restfulness
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -3,12 +3,22 @@ require 'spec_helper'
3
3
 
4
4
  describe Restfulness::Dispatchers::Rack do
5
5
 
6
+ class RackExampleResource < Restfulness::Resource
7
+ def get
8
+ 'rack_example_result'
9
+ end
10
+ end
11
+
6
12
  let :klass do
7
13
  Restfulness::Dispatchers::Rack
8
14
  end
9
15
 
10
16
  let :app do
11
- Class.new(Restfulness::Application).new
17
+ Class.new(Restfulness::Application) {
18
+ routes do
19
+ add 'projects', RackExampleResource
20
+ end
21
+ }.new
12
22
  end
13
23
 
14
24
  let :obj do
@@ -17,17 +27,75 @@ describe Restfulness::Dispatchers::Rack do
17
27
 
18
28
  let :env do
19
29
  {
20
- 'REQUEST_METHOD' => 'GET',
21
- 'SCRIPT_NAME' => 'projects',
22
- 'PATH_INFO' => 'projects',
23
- 'QUERY_STRING' => '',
24
- 'SERVER_NAME' => 'localhost',
25
- 'SERVER_PORT' => '3000',
26
- 'HTTP_CONTENT_TYPE' => 'application/json'
30
+ 'REQUEST_METHOD' => 'GET',
31
+ 'SCRIPT_NAME' => '',
32
+ 'PATH_INFO' => '/projects',
33
+ 'QUERY_STRING' => '',
34
+ 'SERVER_NAME' => 'localhost',
35
+ 'SERVER_PORT' => '3000',
36
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
37
+ 'rack.url_scheme' => 'http',
38
+ 'REMOTE_ADDR' => '192.168.1.23',
39
+ 'HTTP_CONTENT_TYPE' => 'application/json',
40
+ 'HTTP_X_AUTH_TOKEN' => 'foobartoken',
41
+ 'HTTP_USER_AGENT' => 'Some Navigator',
27
42
  }
28
43
  end
29
44
 
30
- describe "#" do
45
+ describe "#call" do
46
+
47
+ it "should handle basic call and return response" do
48
+ res = obj.call(env)
49
+ res[0].should eql(200)
50
+ res[1].should be_a(Hash)
51
+ res[2].first.should eql('rack_example_result')
52
+ end
53
+
54
+
55
+ end
56
+
57
+ describe "#parse_action (protected)" do
58
+
59
+ it "should convert main actions to symbols" do
60
+ actions = ['DELETE', 'GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'OPTIONS']
61
+ actions.each do |action|
62
+ val = obj.send(:parse_action, action)
63
+ val.should eql(action.downcase.to_sym)
64
+ end
65
+ end
66
+
67
+ it "should raise error if action unrecognised" do
68
+ expect {
69
+ obj.send(:parse_action, 'FOOO')
70
+ }.to raise_error(Restfulness::HTTPException)
71
+ end
72
+
73
+ end
74
+
75
+ describe "#prepare_headers (protected)" do
76
+
77
+ it "should parse headers from environment" do
78
+ res = obj.send(:prepare_headers, env)
79
+ res[:content_type].should eql('application/json')
80
+ res[:x_auth_token].should eql('foobartoken')
81
+ end
82
+ end
83
+
84
+ describe "#prepare_request (protected)" do
85
+
86
+ it "should prepare request object with main fields" do
87
+ req = obj.send(:prepare_request, env)
88
+
89
+ req.uri.should be_a(URI)
90
+ req.action.should eql(:get)
91
+ req.query.should be_empty
92
+ req.body.should be_nil
93
+ req.headers.keys.should include(:x_auth_token)
94
+ req.remote_ip.should eql('192.168.1.23')
95
+ req.user_agent.should eql('Some Navigator')
96
+
97
+ req.headers[:content_type].should eql('application/json')
98
+ end
31
99
 
32
100
  end
33
101
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restfulness
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Lown
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-17 00:00:00.000000000 Z
11
+ date: 2013-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack