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.
- 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
|