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.
- data/VERSION +1 -1
- data/examples/datacatalog/lib/resource.rb +2 -2
- data/examples/datacatalog/lib/roles.rb +1 -1
- data/examples/datacatalog/resources/categories_sources.rb +43 -0
- data/examples/datacatalog/test/helpers/lib/request_helpers.rb +10 -2
- data/examples/datacatalog/test/helpers/resource_test_helper.rb +1 -1
- data/examples/datacatalog/test/helpers/shared/api_keys.rb +4 -4
- data/examples/datacatalog/test/helpers/shared/model_counts.rb +81 -0
- data/examples/datacatalog/test/helpers/shared/status_codes.rb +7 -3
- data/examples/datacatalog/test/helpers/test_helper.rb +2 -9
- data/examples/datacatalog/test/resources/categories/categories_delete_test.rb +5 -17
- data/examples/datacatalog/test/resources/categories/categories_get_many_test.rb +5 -2
- data/examples/datacatalog/test/resources/categories/categories_get_one_test.rb +4 -3
- data/examples/datacatalog/test/resources/categories/categories_post_test.rb +27 -43
- data/examples/datacatalog/test/resources/categories/categories_put_test.rb +9 -15
- data/examples/datacatalog/test/resources/categories_sources/categories_sources_delete_test.rb +148 -0
- data/examples/datacatalog/test/resources/categories_sources/categories_sources_get_many_test.rb +92 -0
- data/examples/datacatalog/test/resources/categories_sources/categories_sources_get_one_test.rb +95 -0
- data/examples/datacatalog/test/resources/categories_sources/categories_sources_post_test.rb +187 -0
- data/examples/datacatalog/test/resources/categories_sources/categories_sources_put_test.rb +323 -0
- data/examples/datacatalog/test/resources/sources/sources_delete_test.rb +5 -17
- data/examples/datacatalog/test/resources/sources/sources_get_many_test.rb +5 -2
- data/examples/datacatalog/test/resources/sources/sources_get_one_test.rb +4 -3
- data/examples/datacatalog/test/resources/sources/sources_post_test.rb +22 -35
- data/examples/datacatalog/test/resources/sources/sources_put_test.rb +12 -18
- data/examples/datacatalog/test/resources/users/users_delete_test.rb +10 -22
- data/examples/datacatalog/test/resources/users/users_get_many_test.rb +5 -2
- data/examples/datacatalog/test/resources/users/users_get_one_test.rb +4 -3
- data/examples/datacatalog/test/resources/users/users_post_test.rb +15 -32
- data/examples/datacatalog/test/resources/users/users_put_test.rb +15 -23
- data/lib/builder/action_definitions.rb +60 -0
- data/lib/builder/helpers.rb +53 -26
- data/lib/builder/mongo_helpers.rb +61 -10
- data/lib/builder.rb +136 -38
- data/lib/resource.rb +99 -16
- data/lib/sinatra_resource.rb +6 -6
- data/notes/permissions.mdown +6 -6
- data/sinatra_resource.gemspec +17 -2
- metadata +17 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
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
|
@@ -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,18 +1,18 @@
|
|
1
1
|
class ResourceTestCase
|
2
2
|
|
3
|
-
shared "return 400 because no
|
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
|
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
|
12
|
+
shared "return 400 because params were not empty" do
|
13
13
|
use "return 400 Bad Request"
|
14
14
|
|
15
|
-
test "body should say
|
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
|
-
|
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.
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
65
|
-
use "no
|
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
|
76
|
-
use "no
|
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
|
86
|
-
use "no
|
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
|
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
|
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
|
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
|
-
|
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
|