sinatra_resource 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/VERSION +1 -1
  2. data/examples/datacatalog/lib/resource.rb +2 -2
  3. data/examples/datacatalog/lib/roles.rb +1 -1
  4. data/examples/datacatalog/resources/categories_sources.rb +43 -0
  5. data/examples/datacatalog/test/helpers/lib/request_helpers.rb +10 -2
  6. data/examples/datacatalog/test/helpers/resource_test_helper.rb +1 -1
  7. data/examples/datacatalog/test/helpers/shared/api_keys.rb +4 -4
  8. data/examples/datacatalog/test/helpers/shared/model_counts.rb +81 -0
  9. data/examples/datacatalog/test/helpers/shared/status_codes.rb +7 -3
  10. data/examples/datacatalog/test/helpers/test_helper.rb +2 -9
  11. data/examples/datacatalog/test/resources/categories/categories_delete_test.rb +5 -17
  12. data/examples/datacatalog/test/resources/categories/categories_get_many_test.rb +5 -2
  13. data/examples/datacatalog/test/resources/categories/categories_get_one_test.rb +4 -3
  14. data/examples/datacatalog/test/resources/categories/categories_post_test.rb +27 -43
  15. data/examples/datacatalog/test/resources/categories/categories_put_test.rb +9 -15
  16. data/examples/datacatalog/test/resources/categories_sources/categories_sources_delete_test.rb +148 -0
  17. data/examples/datacatalog/test/resources/categories_sources/categories_sources_get_many_test.rb +92 -0
  18. data/examples/datacatalog/test/resources/categories_sources/categories_sources_get_one_test.rb +95 -0
  19. data/examples/datacatalog/test/resources/categories_sources/categories_sources_post_test.rb +187 -0
  20. data/examples/datacatalog/test/resources/categories_sources/categories_sources_put_test.rb +323 -0
  21. data/examples/datacatalog/test/resources/sources/sources_delete_test.rb +5 -17
  22. data/examples/datacatalog/test/resources/sources/sources_get_many_test.rb +5 -2
  23. data/examples/datacatalog/test/resources/sources/sources_get_one_test.rb +4 -3
  24. data/examples/datacatalog/test/resources/sources/sources_post_test.rb +22 -35
  25. data/examples/datacatalog/test/resources/sources/sources_put_test.rb +12 -18
  26. data/examples/datacatalog/test/resources/users/users_delete_test.rb +10 -22
  27. data/examples/datacatalog/test/resources/users/users_get_many_test.rb +5 -2
  28. data/examples/datacatalog/test/resources/users/users_get_one_test.rb +4 -3
  29. data/examples/datacatalog/test/resources/users/users_post_test.rb +15 -32
  30. data/examples/datacatalog/test/resources/users/users_put_test.rb +15 -23
  31. data/lib/builder/action_definitions.rb +60 -0
  32. data/lib/builder/helpers.rb +53 -26
  33. data/lib/builder/mongo_helpers.rb +61 -10
  34. data/lib/builder.rb +136 -38
  35. data/lib/resource.rb +99 -16
  36. data/lib/sinatra_resource.rb +6 -6
  37. data/notes/permissions.mdown +6 -6
  38. data/sinatra_resource.gemspec +17 -2
  39. metadata +17 -2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -9,11 +9,11 @@ module DataCatalog
9
9
  include SinatraResource::Resource
10
10
  end
11
11
  includee.helpers do
12
- def before_authorization(action, role)
12
+ def before_authorization(action, role, resource_config)
13
13
  unless role
14
14
  error 401, convert(body_for(:errors, ["invalid_api_key"]))
15
15
  end
16
- if role == :anonymous && minimum_role(action) != :anonymous
16
+ if role == :anonymous && minimum_role(action, resource_config) != :anonymous
17
17
  error 401, convert(body_for(:errors, ["missing_api_key"]))
18
18
  end
19
19
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../../../lib/sinatra_resource'
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../lib/sinatra_resource')
2
2
 
3
3
  module DataCatalog
4
4
 
@@ -0,0 +1,43 @@
1
+ module DataCatalog
2
+
3
+ class CategoriesSources < Base
4
+ include Resource
5
+
6
+ parent Categories
7
+ child_association :sources
8
+ model Source
9
+ path "sources"
10
+
11
+ relation :create do |parent, child|
12
+ Categorization.create(
13
+ :category_id => parent.id,
14
+ :source_id => child.id
15
+ )
16
+ end
17
+
18
+ relation :delete do |parent, child|
19
+ Categorization.find(:conditions => {
20
+ :category_id => parent.id,
21
+ :source_id => child.id
22
+ }).destroy
23
+ end
24
+
25
+ # == Permissions
26
+
27
+ roles Roles
28
+ permission :read => :basic
29
+ permission :modify => :curator
30
+
31
+ # == Properties
32
+
33
+ property :title
34
+ property :url
35
+ property :raw, :w => :admin
36
+
37
+ # == Callbacks
38
+
39
+ end
40
+
41
+ CategoriesSources.build
42
+
43
+ end
@@ -2,8 +2,6 @@ module RequestHelpers
2
2
 
3
3
  def parsed_response_body
4
4
  s = last_response.body
5
- # puts "\n== parsed_response_body"
6
- # puts "s : #{s.inspect}"
7
5
  if s == ""
8
6
  nil
9
7
  else
@@ -48,6 +46,16 @@ module RequestHelpers
48
46
  assert_include "can't be empty", parsed_response_body["errors"][s.to_s]
49
47
  end
50
48
  end
49
+
50
+ def location_header(path)
51
+ test "should set Location header correctly" do
52
+ base_uri = Config.environment_config["base_uri"]
53
+ path = %(#{path}/#{parsed_response_body["id"]})
54
+ expected = URI.join(base_uri, path).to_s
55
+ assert_equal expected, last_response.headers['Location']
56
+ end
57
+ end
58
+
51
59
  end
52
60
 
53
61
  end
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/test_helper'
2
- require File.dirname(__FILE__) + '/../../app'
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../app')
3
3
 
4
4
  BAD_API_KEY = "123400005678"
5
5
  FAKE_ID = Mongo::ObjectID.new.to_s
@@ -1,18 +1,18 @@
1
1
  class ResourceTestCase
2
2
 
3
- shared "return 400 because no parameters were given" do
3
+ shared "return 400 because no params were given" do
4
4
  use "return 400 Bad Request"
5
5
 
6
- test "body should say no parameters were given" do
6
+ test "body should say no params were given" do
7
7
  assert_include "errors", parsed_response_body
8
8
  assert_include "no_params", parsed_response_body["errors"]
9
9
  end
10
10
  end
11
11
 
12
- shared "return 400 because parameters were not empty" do
12
+ shared "return 400 because params were not empty" do
13
13
  use "return 400 Bad Request"
14
14
 
15
- test "body should say parameters were non-empty" do
15
+ test "body should say params were non-empty" do
16
16
  assert_include "errors", parsed_response_body
17
17
  assert_include "non_empty_params", parsed_response_body["errors"]
18
18
  end
@@ -0,0 +1,81 @@
1
+ class ResourceTestCase
2
+
3
+ # == categories
4
+
5
+ shared "no change in category count" do
6
+ test "should not change number of category documents in database" do
7
+ assert_equal @category_count, DataCatalog::Category.all.length
8
+ end
9
+ end
10
+
11
+ shared "one less category" do
12
+ test "should remove one category document from database" do
13
+ assert_equal @category_count - 1, DataCatalog::Category.all.length
14
+ end
15
+ end
16
+
17
+ shared "one new category" do
18
+ test "should add one category document to database" do
19
+ assert_equal @category_count + 1, DataCatalog::Category.all.length
20
+ end
21
+ end
22
+
23
+ shared "category unchanged" do
24
+ test "should not change category in database" do
25
+ assert_equal @category_copy, DataCatalog::Category.find_by_id(@category.id)
26
+ end
27
+ end
28
+
29
+ # == sources
30
+
31
+ shared "no change in source count" do
32
+ test "should not change number of source documents in database" do
33
+ assert_equal @source_count, DataCatalog::Source.all.length
34
+ end
35
+ end
36
+
37
+ shared "one less source" do
38
+ test "should remove one source document from database" do
39
+ assert_equal @source_count - 1, DataCatalog::Source.all.length
40
+ end
41
+ end
42
+
43
+ shared "one new source" do
44
+ test "should add one source document to database" do
45
+ assert_equal @source_count + 1, DataCatalog::Source.all.length
46
+ end
47
+ end
48
+
49
+ shared "source unchanged" do
50
+ test "should not change source in database" do
51
+ assert_equal @source_copy, DataCatalog::Source.find_by_id(@source.id)
52
+ end
53
+ end
54
+
55
+ # == users
56
+
57
+ shared "no change in user count" do
58
+ test "should not change number of user documents in database" do
59
+ assert_equal @user_count, DataCatalog::User.all.length
60
+ end
61
+ end
62
+
63
+ shared "one less user" do
64
+ test "should remove one user document from database" do
65
+ assert_equal @user_count - 1, DataCatalog::User.all.length
66
+ end
67
+ end
68
+
69
+ shared "one new user" do
70
+ test "should add one user document to database" do
71
+ assert_equal @user_count + 1, DataCatalog::User.all.length
72
+ end
73
+ end
74
+
75
+ shared "user unchanged" do
76
+ test "should not change user in database" do
77
+ assert_equal @user_copy, DataCatalog::User.find_by_id(@user.id)
78
+ end
79
+ end
80
+
81
+ end
@@ -23,9 +23,7 @@ class ResourceTestCase
23
23
  assert_equal 204, last_response.status
24
24
  end
25
25
 
26
- test "body should be empty" do
27
- assert_equal "", last_response.body
28
- end
26
+ use "return an empty response body"
29
27
  end
30
28
 
31
29
  shared "return 400 Bad Request" do
@@ -52,6 +50,12 @@ class ResourceTestCase
52
50
  end
53
51
  end
54
52
 
53
+ shared "return 404 Not Found with empty response body" do
54
+ use "return 404 Not Found"
55
+
56
+ use "return an empty response body"
57
+ end
58
+
55
59
  shared "return 409 Conflict" do
56
60
  test "status should be 409 Conflict" do
57
61
  assert_equal 409, last_response.status
@@ -20,17 +20,10 @@ Dir.glob(base + '/test_cases/*.rb').each { |f| require f }
20
20
  Dir.glob(base + '/assertions/*.rb').each { |f| require f }
21
21
  Dir.glob(base + '/shared/*.rb' ).each { |f| require f }
22
22
 
23
- require File.dirname(__FILE__) + '/../../config/config'
23
+ require File.expand_path(base + '/../../config/config')
24
24
  Config.environment = 'test'
25
-
26
25
  class Test::Unit::TestCase
27
26
  include RR::Adapters::TestUnit
28
27
  end
29
28
 
30
- # If you use `rake test` the database will automatically get dropped.
31
- # But if you are running inside TextMate, it is handy to automatically drop the
32
- # database here:
33
- if ENV["TM_APP_PATH"]
34
- puts "TextMate environment detected. Dropping test database..."
35
- Config.drop_database
36
- end
29
+ Config.drop_database
@@ -15,18 +15,6 @@ class CategoriesDeleteResourceTest < ResourceTestCase
15
15
  @category.destroy
16
16
  end
17
17
 
18
- shared "no change in category count" do
19
- test "should not change number of category documents in database" do
20
- assert_equal @category_count, Category.all.length
21
- end
22
- end
23
-
24
- shared "one less category" do
25
- test "should remove one category document from database" do
26
- assert_equal @category_count - 1, Category.all.length
27
- end
28
- end
29
-
30
18
  context "delete /:id" do
31
19
  context "anonymous" do
32
20
  before do
@@ -53,7 +41,7 @@ class CategoriesDeleteResourceTest < ResourceTestCase
53
41
  delete "/#{FAKE_ID}", :api_key => api_key_for(role)
54
42
  end
55
43
 
56
- use "return 401 Unauthorized"
44
+ use "return 401 because the API key is unauthorized"
57
45
  use "no change in category count"
58
46
  end
59
47
 
@@ -64,7 +52,7 @@ class CategoriesDeleteResourceTest < ResourceTestCase
64
52
  :key => "value"
65
53
  end
66
54
 
67
- use "return 401 Unauthorized"
55
+ use "return 401 because the API key is unauthorized"
68
56
  use "no change in category count"
69
57
  end
70
58
 
@@ -73,7 +61,7 @@ class CategoriesDeleteResourceTest < ResourceTestCase
73
61
  delete "/#{@category.id}", :api_key => api_key_for(role)
74
62
  end
75
63
 
76
- use "return 401 Unauthorized"
64
+ use "return 401 because the API key is unauthorized"
77
65
  use "no change in category count"
78
66
  end
79
67
  end
@@ -84,7 +72,7 @@ class CategoriesDeleteResourceTest < ResourceTestCase
84
72
  delete "/#{FAKE_ID}", :api_key => api_key_for(role)
85
73
  end
86
74
 
87
- use "return 404 Not Found"
75
+ use "return 404 Not Found with empty response body"
88
76
  use "no change in category count"
89
77
  end
90
78
 
@@ -95,7 +83,7 @@ class CategoriesDeleteResourceTest < ResourceTestCase
95
83
  :key => "value"
96
84
  end
97
85
 
98
- use "return 400 because parameters were not empty"
86
+ use "return 400 because params were not empty"
99
87
  use "no change in category count"
100
88
  end
101
89
 
@@ -2,16 +2,19 @@ require File.expand_path(File.dirname(__FILE__) + '/../../helpers/resource_test_
2
2
 
3
3
  class CategoriesGetManyResourceTest < ResourceTestCase
4
4
 
5
- def app; DataCatalog::Categories end
5
+ include DataCatalog
6
+
7
+ def app; Categories end
6
8
 
7
9
  before do
10
+ raise "Unexpected Category count" unless Category.count == 0
8
11
  @categories = 3.times.map do |i|
9
12
  create_category(:name => "Category #{i}")
10
13
  end
11
14
  end
12
15
 
13
16
  after do
14
- @categories.each { |x| x.destroy }
17
+ @categories.each { |x| x.destroy } if @categories
15
18
  end
16
19
 
17
20
  CATEGORIES = ["Category 0", "Category 1", "Category 2"].sort
@@ -2,7 +2,9 @@ require File.expand_path(File.dirname(__FILE__) + '/../../helpers/resource_test_
2
2
 
3
3
  class CategoriesGetOneResourceTest < ResourceTestCase
4
4
 
5
- def app; DataCatalog::Categories end
5
+ include DataCatalog
6
+
7
+ def app; Categories end
6
8
 
7
9
  before do
8
10
  @category = create_category
@@ -36,8 +38,7 @@ class CategoriesGetOneResourceTest < ResourceTestCase
36
38
  get "/#{FAKE_ID}", :api_key => api_key_for(role)
37
39
  end
38
40
 
39
- use "return 404 Not Found"
40
- use "return an empty response body"
41
+ use "return 404 Not Found with empty response body"
41
42
  end
42
43
 
43
44
  context "#{role} : get /:id" do
@@ -13,27 +13,6 @@ class CategoriesPostResourceTest < ResourceTestCase
13
13
  }
14
14
  end
15
15
 
16
- shared "no new categories" do
17
- test "should not change number of category documents in database" do
18
- assert_equal @category_count, Category.all.length
19
- end
20
- end
21
-
22
- shared "one new category" do
23
- test "should add one category document to database" do
24
- assert_equal @category_count + 1, Category.all.length
25
- end
26
- end
27
-
28
- shared "correct Location header" do
29
- test "should set Location header correctly" do
30
- base_uri = Config.environment_config["base_uri"]
31
- path = %(/categories/#{parsed_response_body["id"]})
32
- expected = URI.join(base_uri, path).to_s
33
- assert_equal expected, last_response.headers['Location']
34
- end
35
- end
36
-
37
16
  context "post /" do
38
17
  context "anonymous" do
39
18
  before do
@@ -41,7 +20,7 @@ class CategoriesPostResourceTest < ResourceTestCase
41
20
  end
42
21
 
43
22
  use "return 401 because the API key is missing"
44
- use "no new categories"
23
+ use "no change in category count"
45
24
  end
46
25
 
47
26
  context "incorrect API key" do
@@ -50,78 +29,83 @@ class CategoriesPostResourceTest < ResourceTestCase
50
29
  end
51
30
 
52
31
  use "return 401 because the API key is invalid"
53
- use "no new categories"
32
+ use "no change in category count"
54
33
  end
55
34
  end
56
-
35
+
57
36
  %w(basic).each do |role|
58
37
  [:name].each do |missing|
59
38
  context "#{role} : post / but missing #{missing}" do
60
39
  before do
61
40
  post "/", valid_params_for(role).delete_if { |k, v| k == missing }
62
41
  end
63
-
64
- use "return 401 Unauthorized"
65
- use "no new categories"
42
+
43
+ use "return 401 because the API key is unauthorized"
44
+ use "no change in category count"
66
45
  end
67
46
  end
68
-
47
+
69
48
  [:id, :created_at, :updated_at, :sources].each do |invalid|
70
49
  context "#{role} : post / but with #{invalid}" do
71
50
  before do
72
51
  post "/", valid_params_for(role).merge(invalid => 9)
73
52
  end
74
53
 
75
- use "return 401 Unauthorized"
76
- use "no new categories"
54
+ use "return 401 because the API key is unauthorized"
55
+ use "no change in category count"
77
56
  end
78
57
  end
79
-
58
+
80
59
  context "#{role} : post / with valid params" do
81
60
  before do
82
61
  post "/", valid_params_for(role)
83
62
  end
84
63
 
85
- use "return 401 Unauthorized"
86
- use "no new categories"
64
+ use "return 401 because the API key is unauthorized"
65
+ use "no change in category count"
87
66
  end
88
67
  end
89
68
 
90
- %w(curator admin).each do |role|
69
+ %w(curator).each do |role|
70
+ # %w(curator admin).each do |role|
91
71
  [:name].each do |missing|
92
72
  context "#{role} : post / but missing #{missing}" do
93
73
  before do
94
74
  post "/", valid_params_for(role).delete_if { |k, v| k == missing }
95
75
  end
96
-
76
+
97
77
  use "return 400 Bad Request"
98
- use "no new categories"
78
+ use "no change in category count"
99
79
  missing_param missing
100
80
  end
101
81
  end
102
-
82
+
103
83
  [:id, :created_at, :updated_at, :sources].each do |invalid|
104
84
  context "#{role} : post / but with #{invalid}" do
105
85
  before do
106
86
  post "/", valid_params_for(role).merge(invalid => 9)
107
87
  end
108
-
88
+
109
89
  use "return 400 Bad Request"
110
- use "no new categories"
90
+ use "no change in category count"
111
91
  invalid_param invalid
112
92
  end
113
93
  end
114
-
94
+
115
95
  context "#{role} : post / with valid params" do
116
96
  before do
117
97
  post "/", valid_params_for(role)
118
98
  end
119
-
99
+
100
+ after do
101
+ Category.find_by_id(parsed_response_body["id"]).destroy
102
+ end
103
+
120
104
  use "return 201 Created"
121
- use "correct Location header"
105
+ location_header "categories"
122
106
  use "one new category"
123
107
  doc_properties %w(name id created_at updated_at sources)
124
-
108
+
125
109
  test "should set all fields in database" do
126
110
  category = Category.find_by_id(parsed_response_body["id"])
127
111
  raise "Cannot find category" unless category