sinatra_resource 0.1.0 → 0.2.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.
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