rackjson 0.2.1 → 0.3.0

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.
@@ -12,114 +12,131 @@ RackJSON uses MongoDB for persistence so you also need to install MongoDB.
12
12
 
13
13
  In your rackup file:
14
14
 
15
- `require mongo
16
- require rackjson`
17
-
18
- `use Rack::JSON::Resource, :collections => [:notes], :db => Mongo::Connection.new.db("mydb")`
19
-
20
- `run lambda { |env|
21
- [404, {'Content-Length' => '9', 'Content-Type' => 'text/plain'}, "Not Found"]
22
- }`
15
+ require mongo
16
+ require rackjson
17
+
18
+ expose_resource :collections => [:notes], :db => Mongo::Connection.new.db("mydb")
19
+
20
+ run lambda { |env|
21
+ [404, {'Content-Length' => '9', 'Content-Type' => 'text/plain'}, "Not Found"]
22
+ }
23
23
 
24
24
  This will set up a RESTful resource called 'notes' at /notes which will store any JSON document.
25
25
 
26
- ### REST API
26
+ ### Restricting Access
27
27
 
28
- To see what actions are available on the notes resource:
28
+ There are three ways of mounting a restful resource with rackjson:
29
29
 
30
- `curl -i -XOPTIONS http://localhost:9292/notes`
30
+ `expose_resource :collections => [:notes], :db => Mongo::Connection.new.db("mydb")`
31
31
 
32
- `HTTP/1.1 200 OK`
33
- `Connection: close`
34
- `Date: Sun, 11 Apr 2010 11:09:40 GMT`
35
- `Content-Type: text/plain`
36
- `Content-Length: 0`
37
- `Allow: GET, POST`
32
+ Using `expose_resource` won't restrict access to the resource at all, all requests by anyone will succeed.
38
33
 
39
- Listing the existing notes:
34
+ `public_resource :collections => [:notes], :filters => [:user_id], :db => Mongo::Connection.new.db("mydb")`
40
35
 
41
- `curl -i http://localhost:9292/notes`
36
+ Using `public_resource` will allow everyone to perform GET requests against the resource, however to make POST, PUT or DELETE requests the requester must have a specific session param, and will only be able to make requests to documents which match this session param. In the above example this session param is set to user_id and could be set when logging in.
42
37
 
43
- `HTTP/1.1 200 OK
44
- Connection: close
45
- Date: Sun, 11 Apr 2010 11:12:04 GMT
46
- Content-Type: application/json
47
- Content-Length: 2`
38
+ `public_resource :collections => [:notes], :filters => [:user_id], :db => Mongo::Connection.new.db("mydb")`
48
39
 
49
- `[]`
40
+ Private resource is very similar except that all requests, including GET requests must also satisfy the pre-condition of having a specific session param.
50
41
 
51
- Currently there are no notes, create one with a post request:
42
+ When creating resources with either the public or private resources the specified session param will be included in the document automatically.
52
43
 
53
- `curl -i -XPOST -d'{"title":"hello world!"}' http://localhost:9292/notes`
44
+ ### REST API
54
45
 
55
- `HTTP/1.1 201 Created
56
- Connection: close
57
- Date: Sun, 11 Apr 2010 11:14:17 GMT
58
- Content-Type: application/json
59
- Content-Length: 149`
46
+ To see what actions are available on the notes resource:
60
47
 
61
- `{"updated_at":"Sun Apr 11 12:14:17 +0100 2010","title":"hello world!","_id":"4bc1af0934701204fd000001","created_at":"Sun Apr 11 12:14:17 +0100 2010"}`
48
+ curl -i -XOPTIONS http://localhost:9292/notes
49
+
50
+ HTTP/1.1 200 OK
51
+ Connection: close
52
+ Date: Sun, 11 Apr 2010 11:09:40 GMT
53
+ Content-Type: text/plain
54
+ Content-Length: 0
55
+ Allow: GET, POST
62
56
 
63
- RackJSON will assign an id to this resource as _id. This can be used to access this resource directly
57
+ Listing the existing notes:
64
58
 
65
- `curl -i http://localhost:9292/notes/4bc1af0934701204fd000001`
59
+ curl -i http://localhost:9292/notes
60
+
61
+ HTTP/1.1 200 OK
62
+ Connection: close
63
+ Date: Sun, 11 Apr 2010 11:12:04 GMT
64
+ Content-Type: application/json
65
+ Content-Length: 2
66
+
67
+ []
66
68
 
67
- `HTTP/1.1 200 OK
68
- Connection: close
69
- Date: Sun, 11 Apr 2010 11:16:30 GMT
70
- Content-Type: application/json
71
- Content-Length: 147`
69
+ Currently there are no notes, create one with a post request:
72
70
 
73
- `[{"updated_at":"Sun Apr 11 11:14:17 UTC 2010","title":"hello world!","_id":"4bc1af0934701204fd000001","created_at":"Sun Apr 11 11:14:17 UTC 2010"}]`
71
+ curl -i -XPOST -d'{"title":"hello world!"}' http://localhost:9292/notes
72
+
73
+ HTTP/1.1 201 Created
74
+ Connection: close
75
+ Date: Sun, 11 Apr 2010 11:14:17 GMT
76
+ Content-Type: application/json
77
+ Content-Length: 149
78
+
79
+ {"updated_at":"Sun Apr 11 12:14:17 +0100 2010","title":"hello world!","_id":"4bc1af0934701204fd000001","created_at":"Sun Apr 11 12:14:17 +0100 2010"}
74
80
 
75
- This resource will also appear in the index of notes resources
81
+ RackJSON will assign an id to this resource as _id. This can be used to access this resource directly
76
82
 
77
- `curl -i http://localhost:9292/notes`
83
+ curl -i http://localhost:9292/notes/4bc1af0934701204fd000001
84
+
85
+ HTTP/1.1 200 OK
86
+ Connection: close
87
+ Date: Sun, 11 Apr 2010 11:16:30 GMT
88
+ Content-Type: application/json
89
+ Content-Length: 147
90
+
91
+ [{"updated_at":"Sun Apr 11 11:14:17 UTC 2010","title":"hello world!","_id":"4bc1af0934701204fd000001","created_at":"Sun Apr 11 11:14:17 UTC 2010"}]
78
92
 
79
- `HTTP/1.1 200 OK
80
- Connection: close
81
- Date: Sun, 11 Apr 2010 11:17:27 GMT
82
- Content-Type: application/json
83
- Content-Length: 147`
93
+ This resource will also appear in the index of notes resources
84
94
 
85
- `[{"updated_at":"Sun Apr 11 11:14:17 UTC 2010","title":"hello world!","_id":"4bc1af0934701204fd000001","created_at":"Sun Apr 11 11:14:17 UTC 2010"}]`
95
+ curl -i http://localhost:9292/notes
96
+
97
+ HTTP/1.1 200 OK
98
+ Connection: close
99
+ Date: Sun, 11 Apr 2010 11:17:27 GMT
100
+ Content-Type: application/json
101
+ Content-Length: 147
102
+
103
+ [{"updated_at":"Sun Apr 11 11:14:17 UTC 2010","title":"hello world!","_id":"4bc1af0934701204fd000001","created_at":"Sun Apr 11 11:14:17 UTC 2010"}]
86
104
 
87
105
  Update a resource using a PUT request
88
106
 
89
- `curl -i -XPUT -d'{"title":"updated"}' http://localhost:9292/notes/4bc1af0934701204fd000001`
90
-
91
- `HTTP/1.1 200 OK
92
- Connection: close
93
- Date: Sun, 11 Apr 2010 11:25:04 GMT
94
- Content-Type: application/json
95
- Content-Length: 144`
96
-
97
- `{"updated_at":"Sun Apr 11 12:25:04 +0100 2010","title":"updated","_id":"4bc1af0934701204fd000001","created_at":"Sun Apr 11 12:25:04 +0100 2010"}`
107
+ curl -i -XPUT -d'{"title":"updated"}' http://localhost:9292/notes/4bc1af0934701204fd000001
108
+
109
+ HTTP/1.1 200 OK
110
+ Connection: close
111
+ Date: Sun, 11 Apr 2010 11:25:04 GMT
112
+ Content-Type: application/json
113
+ Content-Length: 144
114
+
115
+ {"updated_at":"Sun Apr 11 12:25:04 +0100 2010","title":"updated","_id":"4bc1af0934701204fd000001","created_at":"Sun Apr 11 12:25:04 +0100 2010"}
98
116
 
99
117
  A PUT request can also be used to create a resource at the given location:
100
118
 
101
- `curl -i -XPUT -d'{"foo":"bar"}' http://localhost:9292/notes/1`
102
-
103
- `HTTP/1.1 200 OK
104
- Connection: close
105
- Date: Sun, 11 Apr 2010 11:27:13 GMT
106
- Content-Type: application/json
107
- Content-Length: 113`
108
-
109
- `{"updated_at":"Sun Apr 11 12:27:13 +0100 2010","_id":1,"foo":"bar","created_at":"Sun Apr 11 12:27:13 +0100 2010"}`
119
+ curl -i -XPUT -d'{"foo":"bar"}' http://localhost:9292/notes/1
120
+
121
+ HTTP/1.1 200 OK
122
+ Connection: close
123
+ Date: Sun, 11 Apr 2010 11:27:13 GMT
124
+ Content-Type: application/json
125
+ Content-Length: 113
126
+
127
+ {"updated_at":"Sun Apr 11 12:27:13 +0100 2010","_id":1,"foo":"bar","created_at":"Sun Apr 11 12:27:13 +0100 2010"}
110
128
 
111
129
  Finally a resource can be deleted using a DELETE request
112
130
 
113
- `curl -i -XDELETE http://localhost:9292/notes/1`
114
-
115
- `HTTP/1.1 200 OK
116
- Connection: close
117
- Date: Sun, 11 Apr 2010 11:29:14 GMT
118
- Content-Type: application/json
119
- Content-Length: 12
120
- `
121
-
122
- `{"ok": "true"}`
131
+ curl -i -XDELETE http://localhost:9292/notes/1
132
+
133
+ HTTP/1.1 200 OK
134
+ Connection: close
135
+ Date: Sun, 11 Apr 2010 11:29:14 GMT
136
+ Content-Type: application/json
137
+ Content-Length: 12
138
+
139
+ {"ok": "true"}
123
140
 
124
141
  ### JSON Query
125
142
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
@@ -3,9 +3,12 @@ require 'json'
3
3
  require 'rack'
4
4
  require 'mongo'
5
5
  require 'time'
6
+ require 'rackjson/rack/builder'
6
7
 
7
8
  module Rack::JSON
8
9
 
10
+ autoload :BaseDocument, 'rackjson/base_document'
11
+ autoload :Builder, 'rackjson/rack/builder'
9
12
  autoload :EndPoint, 'rackjson/end_point'
10
13
  autoload :Collection, 'rackjson/collection'
11
14
  autoload :Filter, 'rackjson/filter'
@@ -0,0 +1,18 @@
1
+ module Rack::JSON
2
+ module BaseDocument
3
+
4
+ private
5
+
6
+ def set_attribute_created_at
7
+ @attributes["created_at"] = Time.now unless @attributes["created_at"]
8
+ end
9
+
10
+ def set_attributes
11
+ private_methods.each do |method|
12
+ if method.match /^set_attribute_\w*$/
13
+ send method
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -15,6 +15,10 @@ module Rack::JSON
15
15
  !@methods.include?(request.request_method.downcase.to_sym)
16
16
  end
17
17
 
18
+ def invalid_json error
19
+ render (error.class.to_s + " :" + error.message), :status => 422
20
+ end
21
+
18
22
  def render body, options={}
19
23
  Rack::JSON::Response.new(body, options).to_a
20
24
  end
@@ -33,6 +33,8 @@ module Rack::JSON
33
33
  end
34
34
  append_filters_to_document_in request if request.post? || request.put?
35
35
  @app.call(request.env)
36
+ rescue JSON::ParserError => error
37
+ return invalid_json error
36
38
  end
37
39
 
38
40
  def pre_condition_not_met
@@ -1,5 +1,6 @@
1
1
  module Rack::JSON
2
2
  class JSONDocument
3
+ include Rack::JSON::BaseDocument
3
4
 
4
5
  attr_reader :attributes
5
6
 
@@ -14,10 +15,6 @@ module Rack::JSON
14
15
 
15
16
  private
16
17
 
17
- def set_attribute_created_at
18
- @attributes["created_at"] = Time.now unless @attributes["created_at"]
19
- end
20
-
21
18
  def set_attribute_dates
22
19
  @attributes.each_pair do |key, value|
23
20
  if value.class == String && value.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/)
@@ -35,13 +32,5 @@ module Rack::JSON
35
32
  def set_attribute_updated_at
36
33
  @attributes["updated_at"] = Time.now
37
34
  end
38
-
39
- def set_attributes
40
- private_methods.each do |method|
41
- if method.match /^set_attribute_\w*$/
42
- send method
43
- end
44
- end
45
- end
46
35
  end
47
36
  end
@@ -1,11 +1,11 @@
1
1
  module Rack::JSON
2
2
  class MongoDocument
3
+ include Rack::JSON::BaseDocument
3
4
 
4
5
  attr_accessor :attributes
5
6
 
6
7
  def initialize(row)
7
8
  @attributes = row
8
- set_created_at
9
9
  set_attributes
10
10
  end
11
11
 
@@ -14,19 +14,5 @@ module Rack::JSON
14
14
  def set_attribute_ids
15
15
  @attributes["_id"] = @attributes["_id"].to_s if (@attributes["_id"].is_a? BSON::ObjectID)
16
16
  end
17
-
18
- def set_created_at
19
- if @attributes["_id"].is_a? BSON::ObjectID
20
- @attributes["created_at"] = @attributes["_id"].generation_time unless @attributes["created_at"]
21
- end
22
- end
23
-
24
- def set_attributes
25
- private_methods.each do |method|
26
- if method.match /^set_attribute_\w*$/
27
- send method
28
- end
29
- end
30
- end
31
17
  end
32
18
  end
@@ -0,0 +1,44 @@
1
+ module Rack
2
+ class Builder
3
+ # Setup resource collections without authentication.
4
+ #
5
+ # ===Example
6
+ # expose_resource :collections => [:notes, :projects], :db => @mongo_db
7
+ #
8
+ def expose_resource options
9
+ @ins << lambda do |app|
10
+ Rack::JSON::Resource.new app, options
11
+ end
12
+ end
13
+
14
+ # Setup resource collections with public read access but write access only
15
+ # given to the owner of the document, determened from the session var passed
16
+ # as filter.
17
+ #
18
+ # ===Example
19
+ # public_resource :collections => [:notes, :projects], :db => @mongo_db, :filters => [:user_id]
20
+ #
21
+ def public_resource options
22
+ @ins << lambda do |app|
23
+ Rack::JSON::Filter.new(
24
+ Rack::JSON::Resource.new(app, options),
25
+ options.merge(:methods => [:post, :put, :delete]))
26
+ end
27
+ end
28
+
29
+ # Setup resource collections with no public access. Read and write access only
30
+ # given to the owner of the document, determened from the session vars passed
31
+ # as filters.
32
+ #
33
+ # ===Example
34
+ # private_resource :collections => [:notes, :projects], :db => @mongo_db, :filters => [:user_id]
35
+ #
36
+ def private_resource options
37
+ @ins << lambda do |app|
38
+ Rack::JSON::Filter.new(
39
+ Rack::JSON::Resource.new(app, options),
40
+ options.merge(:methods => [:get, :post, :put, :delete]))
41
+ end
42
+ end
43
+ end
44
+ end
@@ -44,7 +44,7 @@ module Rack::JSON
44
44
  end
45
45
 
46
46
  def session
47
- @env['rack.session']
47
+ @env['rack.session'] || {}
48
48
  end
49
49
 
50
50
  def set_body json
@@ -57,13 +57,13 @@ module Rack::JSON
57
57
  @collection.create(document.attributes)
58
58
  render document.to_json, :status => 201
59
59
  rescue JSON::ParserError => error
60
- render (error.class.to_s + " :" + error.message), :status => 422
60
+ invalid_json error
61
61
  end
62
62
 
63
63
  def put(request)
64
64
  @collection.exists?(request.resource_id) ? update(request) : upsert(request)
65
65
  rescue JSON::ParserError => error
66
- render (error.class.to_s + " :" + error.message), :status => 422
66
+ invalid_json error
67
67
  end
68
68
 
69
69
  def update(request)
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rackjson}
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Oliver Nightingale"]
12
- s.date = %q{2010-04-29}
12
+ s.date = %q{2010-05-06}
13
13
  s.description = %q{A rack end point for storing json documents.}
14
14
  s.email = %q{oliver.n@new-bamboo.co.uk}
15
15
  s.extra_rdoc_files = [
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  "Rakefile",
25
25
  "VERSION",
26
26
  "lib/rackjson.rb",
27
+ "lib/rackjson/base_document.rb",
27
28
  "lib/rackjson/collection.rb",
28
29
  "lib/rackjson/document.rb",
29
30
  "lib/rackjson/end_point.rb",
@@ -31,6 +32,7 @@ Gem::Specification.new do |s|
31
32
  "lib/rackjson/json_document.rb",
32
33
  "lib/rackjson/json_query.rb",
33
34
  "lib/rackjson/mongo_document.rb",
35
+ "lib/rackjson/rack/builder.rb",
34
36
  "lib/rackjson/request.rb",
35
37
  "lib/rackjson/resource.rb",
36
38
  "lib/rackjson/response.rb",
@@ -43,6 +45,7 @@ Gem::Specification.new do |s|
43
45
  "test/test_json_document.rb",
44
46
  "test/test_json_query.rb",
45
47
  "test/test_mongo_document.rb",
48
+ "test/test_rack_builder.rb",
46
49
  "test/test_resource.rb",
47
50
  "test/test_response.rb"
48
51
  ]
@@ -60,6 +63,7 @@ Gem::Specification.new do |s|
60
63
  "test/test_json_document.rb",
61
64
  "test/test_json_query.rb",
62
65
  "test/test_mongo_document.rb",
66
+ "test/test_rack_builder.rb",
63
67
  "test/test_resource.rb",
64
68
  "test/test_response.rb"
65
69
  ]
@@ -13,7 +13,9 @@ class CollectionTest < Test::Unit::TestCase
13
13
 
14
14
  test "finding a single document by id" do
15
15
  mongo_document = @mongo_collection.save({:testing => true, :rating => 5, :title => 'testing', :_id => 1})
16
- assert_equal @collection.find(1).attributes, @mongo_collection.find_one(:_id => 1)
16
+ assert_equal @collection.find(1).attributes['testing'], @mongo_collection.find_one(:_id => 1)['testing']
17
+ assert_equal @collection.find(1).attributes['rating'], @mongo_collection.find_one(:_id => 1)['rating']
18
+ assert_equal @collection.find(1).attributes['title'], @mongo_collection.find_one(:_id => 1)['title']
17
19
  assert_kind_of Rack::JSON::Document, @collection.find(1)
18
20
  end
19
21
 
@@ -21,7 +23,7 @@ class CollectionTest < Test::Unit::TestCase
21
23
  mongo_document = @mongo_collection.save({:testing => true, :rating => 5, :title => 'testing', :_id => 1})
22
24
  mongo_results = []
23
25
  @mongo_collection.find(:testing => true).each { |row| mongo_results << row }
24
- assert_equal @collection.find(:testing => true).first.attributes, mongo_results.first
26
+ assert_equal @collection.find(:testing => true, :rating => 5).first.attributes['testing'], mongo_results.first['testing']
25
27
  assert_kind_of Rack::JSON::Document, @collection.find(:testing => true).first
26
28
  end
27
29
 
@@ -30,7 +32,7 @@ class CollectionTest < Test::Unit::TestCase
30
32
  mongo_results = []
31
33
  @mongo_collection.find(:testing => true, :rating => 5).each { |row| mongo_results << row }
32
34
  assert_equal @collection.find(:testing => true, :rating => 5).length, mongo_results.length
33
- assert_equal @collection.find(:testing => true, :rating => 5).first.attributes, mongo_results.first
35
+ assert_equal @collection.find(:testing => true, :rating => 5).first.attributes['testing'], mongo_results.first['testing']
34
36
  end
35
37
 
36
38
  def test_finding_no_documents_using_search_conditions
@@ -44,6 +44,21 @@ class DocumentTest < Test::Unit::TestCase
44
44
  assert_equal(Time.now.to_s, document.attributes["updated_at"].to_s)
45
45
  end
46
46
 
47
+ test "creating from json with single nested document" do
48
+ json = '{"test":"hello", "nested":{"foo":"bar"}}'
49
+ document = Rack::JSON::Document.new(json)
50
+ assert document.attributes['nested'].is_a?(Hash)
51
+ assert_equal 'bar', document.attributes['nested']['foo']
52
+ end
53
+
54
+ test "creating from json with multiple nested documents" do
55
+ json = '{"test":"hello", "nested":[{"foo":"bar"}, {"boo":"far"}]}'
56
+ document = Rack::JSON::Document.new(json)
57
+ assert document.attributes['nested'].is_a?(Array)
58
+ assert_equal({'foo' => 'bar'}, document.attributes['nested'][0])
59
+ assert_equal 'far', document.attributes['nested'][1]['boo']
60
+ end
61
+
47
62
  def test_adding_id
48
63
  json = '{"test":"hello"}'
49
64
  document = Rack::JSON::Document.new(json)
@@ -69,4 +69,10 @@ class FilterTest < Test::Unit::TestCase
69
69
  post '/testing', '{ "title": "hello!" }'
70
70
  assert_match /"user_id":1/, last_response.body
71
71
  end
72
+
73
+ test "handling invalid json" do
74
+ get '/login'
75
+ post '/testing', 'invalid json'
76
+ assert_equal 422, last_response.status
77
+ end
72
78
  end
@@ -3,7 +3,7 @@ require 'helper'
3
3
  class MongoDocumentTest < Test::Unit::TestCase
4
4
 
5
5
  def test_stringifying_mongo_object_ids
6
- hash = { "_id" => BSON::ObjectID.from_string("4ba7e82ca04014011c000001") }
6
+ hash = {"_id" => BSON::ObjectID.from_string("4ba7e82ca04014011c000001")}
7
7
  doc = Rack::JSON::MongoDocument.new(hash).attributes
8
8
  assert_equal("4ba7e82ca04014011c000001", doc["_id"])
9
9
  end
@@ -11,14 +11,6 @@ class MongoDocumentTest < Test::Unit::TestCase
11
11
  def test_not_stringifying_non_mongo_object_ids
12
12
  hash = { "_id" => 1 }
13
13
  doc = Rack::JSON::MongoDocument.new(hash).attributes
14
- assert_equal({ "_id" => 1 }, doc)
15
- end
16
-
17
- def test_setting_the_created_at_stamp
18
- hash = { "_id" => BSON::ObjectID.from_string("4ba7e82ca04014011c000001") }
19
- doc = Rack::JSON::MongoDocument.new(hash).attributes
20
- assert_equal({ "_id" => "4ba7e82ca04014011c000001",
21
- "created_at" => BSON::ObjectID.from_string("4ba7e82ca04014011c000001").generation_time
22
- }, doc)
14
+ assert_equal(1, doc["_id"])
23
15
  end
24
16
  end
@@ -0,0 +1,124 @@
1
+ require 'helper'
2
+
3
+ class BuilderTest < Test::Unit::TestCase
4
+ include Rack::Test::Methods
5
+ include Rack::Utils
6
+
7
+ def setup
8
+ @db = Mongo::Connection.new.db("test")
9
+ @collection = @db['testing']
10
+ end
11
+
12
+ def teardown
13
+ @collection.drop
14
+ end
15
+
16
+ def public_resource_app
17
+ Rack::Builder.app do
18
+ use Rack::Session::Cookie
19
+ public_resource :collections => [:testing], :filters => [:user_id], :db => Mongo::Connection.new.db("test")
20
+ run lambda { |env|
21
+ # this is doing some pretend login by simply setting a session var
22
+ request = Rack::JSON::Request.new(env)
23
+ env['rack.session'] = {}
24
+ env['rack.session']['user_id'] = 1
25
+ [200, {'Content-Length' => "6", 'Content-Type' => 'text/plain'}, ["Hello!"]]
26
+ }
27
+ end
28
+ end
29
+
30
+ def private_resource_app
31
+ Rack::Builder.app do
32
+ use Rack::Session::Cookie
33
+ private_resource :collections => [:testing], :filters => [:user_id], :db => Mongo::Connection.new.db("test")
34
+ run lambda { |env|
35
+ # this is doing some pretend login by simply setting a session var
36
+ request = Rack::JSON::Request.new(env)
37
+ env['rack.session'] = {}
38
+ env['rack.session']['user_id'] = 1
39
+ [200, {'Content-Length' => "6", 'Content-Type' => 'text/plain'}, ["Hello!"]]
40
+ }
41
+ end
42
+ end
43
+
44
+ def expose_resource_app
45
+ Rack::Builder.app do
46
+ expose_resource :collections => [:testing], :db => Mongo::Connection.new.db("test")
47
+ run lambda { |env| [404, {'Content-Length' => '9', 'Content-Type' => 'text/plain'}, ["Not Found"]] }
48
+ end
49
+ end
50
+
51
+ def use_expose_resource
52
+ BuilderTest.class_eval { def app; expose_resource_app; end }
53
+ end
54
+
55
+ def use_public_resource
56
+ BuilderTest.class_eval { def app; public_resource_app; end }
57
+ end
58
+
59
+ def use_private_resource
60
+ BuilderTest.class_eval { def app; private_resource_app; end }
61
+ end
62
+
63
+ test "using expose_resource we can still bypass rack json" do
64
+ BuilderTest.class_eval { def app; expose_resource_app; end }
65
+
66
+ get '/blah'
67
+ assert_equal 404, last_response.status
68
+ end
69
+
70
+ test "using expose_resource still gives access to Rack::JSON::Resource" do
71
+ use_expose_resource
72
+
73
+ @collection.save({:testing => true})
74
+ get '/testing'
75
+ assert last_response.ok?
76
+ assert_match /"testing":true/, last_response.body
77
+ end
78
+
79
+ test "using public_resource still can bypass Rack::JSON" do
80
+ use_public_resource
81
+
82
+ get '/blah'
83
+ assert_equal 200, last_response.status
84
+ end
85
+
86
+ test "using public_resource still gives access to Rack::JSON::Resource" do
87
+ use_public_resource
88
+
89
+ @collection.save({:testing => true})
90
+ get '/testing'
91
+ assert last_response.ok?
92
+ assert_match /"testing":true/, last_response.body
93
+ end
94
+
95
+ test "using public_resource should restrict non get requests to the resources" do
96
+ use_public_resource
97
+
98
+ post '/testing', '{"test":"yes"}'
99
+ assert_equal 412, last_response.status
100
+ end
101
+
102
+ test "using public resource should not restrict requests when the pre-conditions are met" do
103
+ use_public_resource
104
+
105
+ get '/login' # pretend to login
106
+ post '/testing', '{"test":"yes"}'
107
+ assert_equal 201, last_response.status
108
+ end
109
+
110
+ test "using private resource should restrict all requests to the resource" do
111
+ use_private_resource
112
+
113
+ get '/testing'
114
+ assert_equal 412, last_response.status
115
+ end
116
+
117
+ test "using private resource should not restrict requests when the pre-conditions are met" do
118
+ use_private_resource
119
+
120
+ get '/login' # pretend to login
121
+ get '/testing'
122
+ assert last_response.ok?
123
+ end
124
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rackjson
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Nightingale
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-04-29 00:00:00 +01:00
12
+ date: 2010-05-06 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -69,6 +69,7 @@ files:
69
69
  - Rakefile
70
70
  - VERSION
71
71
  - lib/rackjson.rb
72
+ - lib/rackjson/base_document.rb
72
73
  - lib/rackjson/collection.rb
73
74
  - lib/rackjson/document.rb
74
75
  - lib/rackjson/end_point.rb
@@ -76,6 +77,7 @@ files:
76
77
  - lib/rackjson/json_document.rb
77
78
  - lib/rackjson/json_query.rb
78
79
  - lib/rackjson/mongo_document.rb
80
+ - lib/rackjson/rack/builder.rb
79
81
  - lib/rackjson/request.rb
80
82
  - lib/rackjson/resource.rb
81
83
  - lib/rackjson/response.rb
@@ -88,6 +90,7 @@ files:
88
90
  - test/test_json_document.rb
89
91
  - test/test_json_query.rb
90
92
  - test/test_mongo_document.rb
93
+ - test/test_rack_builder.rb
91
94
  - test/test_resource.rb
92
95
  - test/test_response.rb
93
96
  has_rdoc: true
@@ -127,5 +130,6 @@ test_files:
127
130
  - test/test_json_document.rb
128
131
  - test/test_json_query.rb
129
132
  - test/test_mongo_document.rb
133
+ - test/test_rack_builder.rb
130
134
  - test/test_resource.rb
131
135
  - test/test_response.rb