sinatra_resource 0.3.2 → 0.3.3

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 CHANGED
@@ -1 +1 @@
1
- 0.3.2
1
+ 0.3.3
@@ -17,6 +17,7 @@ module DataCatalog
17
17
 
18
18
  # == Associations
19
19
 
20
+ many :usages
20
21
  many :categorizations
21
22
 
22
23
  def categories
@@ -0,0 +1,31 @@
1
+ module DataCatalog
2
+
3
+ class Usage
4
+
5
+ include MongoMapper::EmbeddedDocument
6
+
7
+ # == Attributes
8
+
9
+ key :title, String
10
+ key :url, String
11
+ key :description, String
12
+
13
+ # == Indices
14
+
15
+ # == Associations
16
+
17
+ # == Validations
18
+
19
+ # TODO: As of 2009-10-29, MongoMapper does not support validations on
20
+ # EmbeddedDocuments.
21
+ #
22
+ # validates_presence_of :title
23
+ # validates_presence_of :url
24
+
25
+ # == Class Methods
26
+
27
+ # == Various Instance Methods
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,32 @@
1
+ module DataCatalog
2
+
3
+ class SourcesUsages < Base
4
+ include Resource
5
+
6
+ parent Sources
7
+ child_association :usages
8
+ model Usage
9
+ path "usages"
10
+
11
+ # == Permissions
12
+
13
+ roles Roles
14
+ permission :list => :basic
15
+ permission :read => :basic
16
+ permission :create => :curator
17
+ permission :update => :curator
18
+ permission :delete => :curator
19
+
20
+ # == Properties
21
+
22
+ property :title
23
+ property :url
24
+ property :description
25
+
26
+ # == Callbacks
27
+
28
+ end
29
+
30
+ SourcesUsages.build
31
+
32
+ end
@@ -34,6 +34,16 @@ module ModelFactories
34
34
  :role => "basic",
35
35
  })
36
36
  end
37
+
38
+ # -----
39
+
40
+ def new_usage(custom={})
41
+ new_model!(DataCatalog::Usage, custom, {
42
+ :title => "Sample Usage",
43
+ :url => "http://inter.net/article/100",
44
+ :description => "Citation from the internet",
45
+ })
46
+ end
37
47
 
38
48
  protected
39
49
 
@@ -55,6 +55,19 @@ module RequestHelpers
55
55
  assert_equal expected, last_response.headers['Location']
56
56
  end
57
57
  end
58
+
59
+ def nested_location_header(parent_path, parent_ivar, child_path)
60
+ test "should set Location header correctly" do
61
+ base_uri = Config.environment_config["base_uri"]
62
+ parent = instance_variable_get("@#{parent_ivar}")
63
+ raise Error unless parent
64
+ path = parent_path + '/' + parent.id + '/' + child_path + '/' +
65
+ parsed_response_body["id"]
66
+ expected = URI.join(base_uri, path).to_s
67
+ assert_equal expected, last_response.headers['Location']
68
+ end
69
+ end
70
+
58
71
 
59
72
  end
60
73
 
@@ -78,6 +78,38 @@ class ResourceTestCase
78
78
  end
79
79
  end
80
80
 
81
+ # == usages
82
+
83
+ shared "no change in usage count" do
84
+ test "should not change number of user documents in database" do
85
+ source = DataCatalog::Source.find_by_id(@source.id)
86
+ assert_equal @usage_count, source.usages.length
87
+ end
88
+ end
89
+
90
+ shared "one less usage" do
91
+ test "should remove one user document from database" do
92
+ source = DataCatalog::Source.find_by_id(@source.id)
93
+ assert_equal @usage_count - 1, source.usages.length
94
+ end
95
+ end
96
+
97
+ shared "one new usage" do
98
+ test "should add one user document to database" do
99
+ source = DataCatalog::Source.find_by_id(@source.id)
100
+ assert_equal @usage_count + 1, source.usages.length
101
+ end
102
+ end
103
+
104
+ shared "usage unchanged" do
105
+ test "should not change usage in database" do
106
+ source = DataCatalog::Source.find_by_id(@source.id)
107
+ usage = source.usages.detect { |x| x.id == @usage_id }
108
+ assert @usage_copy
109
+ assert_equal @usage_copy, usage
110
+ end
111
+ end
112
+
81
113
  # == users
82
114
 
83
115
  shared "no change in user count" do
@@ -43,10 +43,10 @@ class CategoriesSourcesGetManyResourceTest < ResourceTestCase
43
43
  @category.destroy
44
44
  end
45
45
 
46
- context "get /:id/sources/" do
46
+ context "get /:id/sources" do
47
47
  context "anonymous" do
48
48
  before do
49
- get "/#{@category.id}/sources/"
49
+ get "/#{@category.id}/sources"
50
50
  end
51
51
 
52
52
  use "return 401 because the API key is missing"
@@ -54,7 +54,7 @@ class CategoriesSourcesGetManyResourceTest < ResourceTestCase
54
54
 
55
55
  context "incorrect API key" do
56
56
  before do
57
- get "/#{@category.id}/sources/", :api_key => BAD_API_KEY
57
+ get "/#{@category.id}/sources", :api_key => BAD_API_KEY
58
58
  end
59
59
 
60
60
  use "return 401 because the API key is invalid"
@@ -64,7 +64,7 @@ class CategoriesSourcesGetManyResourceTest < ResourceTestCase
64
64
  %w(basic curator admin).each do |role|
65
65
  context "#{role} : get /:fake_id/sources" do
66
66
  before do
67
- get "/#{FAKE_ID}/sources/", :api_key => api_key_for(role)
67
+ get "/#{FAKE_ID}/sources", :api_key => api_key_for(role)
68
68
  end
69
69
 
70
70
  use "return 404 Not Found with empty response body"
@@ -72,7 +72,7 @@ class CategoriesSourcesGetManyResourceTest < ResourceTestCase
72
72
 
73
73
  context "#{role} : get /:id/sources" do
74
74
  before do
75
- get "/#{@category.id}/sources/", :api_key => api_key_for(role)
75
+ get "/#{@category.id}/sources", :api_key => api_key_for(role)
76
76
  end
77
77
 
78
78
  use "return 200 Ok"
@@ -30,7 +30,7 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
30
30
  context "post /:id/sources" do
31
31
  context "anonymous" do
32
32
  before do
33
- post "/#{@category.id}/sources/"
33
+ post "/#{@category.id}/sources"
34
34
  end
35
35
 
36
36
  use "return 401 because the API key is missing"
@@ -39,7 +39,7 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
39
39
 
40
40
  context "incorrect API key" do
41
41
  before do
42
- post "/#{@category.id}/sources/", :api_key => BAD_API_KEY
42
+ post "/#{@category.id}/sources", :api_key => BAD_API_KEY
43
43
  end
44
44
 
45
45
  use "return 401 because the API key is invalid"
@@ -50,7 +50,7 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
50
50
  %w(basic).each do |role|
51
51
  context "#{role} : post /:fake_id/sources" do
52
52
  before do
53
- post "/#{FAKE_ID}/sources/", :api_key => api_key_for(role)
53
+ post "/#{FAKE_ID}/sources", :api_key => api_key_for(role)
54
54
  end
55
55
 
56
56
  use "return 404 Not Found with empty response body"
@@ -59,7 +59,7 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
59
59
 
60
60
  context "#{role} : post /:id/sources" do
61
61
  before do
62
- post "/#{@category.id}/sources/", :api_key => api_key_for(role)
62
+ post "/#{@category.id}/sources", :api_key => api_key_for(role)
63
63
  end
64
64
 
65
65
  use "return 401 because the API key is unauthorized"
@@ -70,7 +70,7 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
70
70
  %w(curator).each do |role|
71
71
  context "#{role} : post /:fake_id/sources" do
72
72
  before do
73
- post "/#{FAKE_ID}/sources/", :api_key => api_key_for(role)
73
+ post "/#{FAKE_ID}/sources", :api_key => api_key_for(role)
74
74
  end
75
75
 
76
76
  use "return 404 Not Found with empty response body"
@@ -78,9 +78,9 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
78
78
  end
79
79
 
80
80
  [:title, :url].each do |missing|
81
- context "#{role} : post /:id/sources/ but missing #{missing}" do
81
+ context "#{role} : post /:id/sources but missing #{missing}" do
82
82
  before do
83
- post "/#{@category.id}/sources/",
83
+ post "/#{@category.id}/sources",
84
84
  valid_params_for(role).delete_if { |k, v| k == missing }
85
85
  end
86
86
 
@@ -91,9 +91,9 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
91
91
  end
92
92
 
93
93
  [:raw, :id, :created_at, :updated_at, :junk].each do |invalid|
94
- context "#{role} : post /:id/sources/ but with #{invalid}" do
94
+ context "#{role} : post /:id/sources but with #{invalid}" do
95
95
  before do
96
- post "/#{@category.id}/sources/", valid_params_for(role).
96
+ post "/#{@category.id}/sources", valid_params_for(role).
97
97
  merge(invalid => 9)
98
98
  end
99
99
 
@@ -105,7 +105,7 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
105
105
 
106
106
  context "#{role} : post /:id/sources with valid params" do
107
107
  before do
108
- post "/#{@category.id}/sources/", valid_params_for(role)
108
+ post "/#{@category.id}/sources", valid_params_for(role)
109
109
  end
110
110
 
111
111
  after do
@@ -113,7 +113,7 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
113
113
  end
114
114
 
115
115
  use "return 201 Created"
116
- location_header "sources"
116
+ nested_location_header "categories", :category, "sources"
117
117
  use "one new source"
118
118
  doc_properties %w(title url raw id created_at updated_at)
119
119
 
@@ -127,7 +127,7 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
127
127
  %w(admin).each do |role|
128
128
  context "#{role} : post /:fake_id/sources" do
129
129
  before do
130
- post "/#{FAKE_ID}/sources/",
130
+ post "/#{FAKE_ID}/sources",
131
131
  valid_params_for(role).merge(@extra_admin_params)
132
132
  end
133
133
 
@@ -136,9 +136,9 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
136
136
  end
137
137
 
138
138
  [:title, :url].each do |missing|
139
- context "#{role} : post /:id/sources/ but missing #{missing}" do
139
+ context "#{role} : post /:id/sources but missing #{missing}" do
140
140
  before do
141
- post "/#{@category.id}/sources/",
141
+ post "/#{@category.id}/sources",
142
142
  valid_params_for(role).merge(@extra_admin_params).
143
143
  delete_if { |k, v| k == missing }
144
144
  end
@@ -150,9 +150,9 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
150
150
  end
151
151
 
152
152
  [:id, :created_at, :updated_at, :junk].each do |invalid|
153
- context "#{role} : post /:id/sources/ but with #{invalid}" do
153
+ context "#{role} : post /:id/sources but with #{invalid}" do
154
154
  before do
155
- post "/#{@category.id}/sources/", valid_params_for(role).
155
+ post "/#{@category.id}/sources", valid_params_for(role).
156
156
  merge(@extra_admin_params).merge(invalid => 9)
157
157
  end
158
158
 
@@ -164,7 +164,7 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
164
164
 
165
165
  context "#{role} : post /:id/sources with valid params" do
166
166
  before do
167
- post "/#{@category.id}/sources/",
167
+ post "/#{@category.id}/sources",
168
168
  valid_params_for(role).merge(@extra_admin_params)
169
169
  end
170
170
 
@@ -173,7 +173,7 @@ class CategoriesSourcesPostResourceTest < ResourceTestCase
173
173
  end
174
174
 
175
175
  use "return 201 Created"
176
- location_header "sources"
176
+ nested_location_header "categories", :category, "sources"
177
177
  use "one new source"
178
178
  doc_properties %w(title url raw id created_at updated_at)
179
179
 
@@ -245,32 +245,6 @@ class CategoriesSourcesPutResourceTest < ResourceTestCase
245
245
  use "return 404 Not Found with empty response body"
246
246
  use "source unchanged"
247
247
  end
248
-
249
- [:created_at, :updated_at, :junk].each do |invalid|
250
- context "#{role} : put /:id/sources/:id but with #{invalid}" do
251
- before do
252
- put "/#{@category.id}/sources/#{@source.id}",
253
- valid_params_for(role).merge(@extra_admin_params).merge(invalid => 9)
254
- end
255
-
256
- use "return 400 Bad Request"
257
- use "source unchanged"
258
- invalid_param invalid
259
- end
260
- end
261
-
262
- [:title, :url].each do |erase|
263
- context "#{role} : put /:id/sources/:id but blanking out #{erase}" do
264
- before do
265
- put "/#{@category.id}/sources/#{@source.id}",
266
- valid_params_for(role).merge(@extra_admin_params).merge(erase => "")
267
- end
268
-
269
- use "return 400 Bad Request"
270
- use "source unchanged"
271
- missing_param erase
272
- end
273
- end
274
248
 
275
249
  context "#{role} : put /:id/sources/:id with no params" do
276
250
  before do
@@ -281,7 +255,7 @@ class CategoriesSourcesPutResourceTest < ResourceTestCase
281
255
  use "return 400 because no params were given"
282
256
  use "source unchanged"
283
257
  end
284
-
258
+
285
259
  [:title, :url].each do |missing|
286
260
  context "#{role} : put /:id/sources/:id without #{missing}" do
287
261
  before do
@@ -302,6 +276,32 @@ class CategoriesSourcesPutResourceTest < ResourceTestCase
302
276
  end
303
277
  end
304
278
 
279
+ [:title, :url].each do |erase|
280
+ context "#{role} : put /:id/sources/:id but blanking out #{erase}" do
281
+ before do
282
+ put "/#{@category.id}/sources/#{@source.id}",
283
+ valid_params_for(role).merge(@extra_admin_params).merge(erase => "")
284
+ end
285
+
286
+ use "return 400 Bad Request"
287
+ use "source unchanged"
288
+ missing_param erase
289
+ end
290
+ end
291
+
292
+ [:created_at, :updated_at, :junk].each do |invalid|
293
+ context "#{role} : put /:id/sources/:id but with #{invalid}" do
294
+ before do
295
+ put "/#{@category.id}/sources/#{@source.id}",
296
+ valid_params_for(role).merge(@extra_admin_params).merge(invalid => 9)
297
+ end
298
+
299
+ use "return 400 Bad Request"
300
+ use "source unchanged"
301
+ invalid_param invalid
302
+ end
303
+ end
304
+
305
305
  context "#{role} : put /:id/sources/:id" do
306
306
  before do
307
307
  put "/#{@category.id}/sources/#{@source.id}",
@@ -0,0 +1,145 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../helpers/resource_test_helper')
2
+
3
+ class SourcesUsagesDeleteResourceTest < ResourceTestCase
4
+
5
+ include DataCatalog
6
+
7
+ def app; Sources end
8
+
9
+ before do
10
+ @source = create_source
11
+ @source.usages << new_usage
12
+ @source.save
13
+ @usage_id = @source.usages[0].id
14
+ @usage_count = @source.usages.length
15
+
16
+ @other_source = create_source
17
+ @other_source.usages << new_usage
18
+ @other_source.save
19
+ @other_usage_id = @other_source.usages[0].id
20
+ end
21
+
22
+ context "delete /:id/usages/:id" do
23
+ context "anonymous" do
24
+ before do
25
+ delete "/#{@source.id}/usages/#{@usage_id}"
26
+ end
27
+
28
+ use "return 401 because the API key is missing"
29
+ end
30
+
31
+ context "incorrect API key" do
32
+ before do
33
+ delete "/#{@source.id}/usages/#{@usage_id}",
34
+ :api_key => BAD_API_KEY
35
+ end
36
+
37
+ use "return 401 because the API key is invalid"
38
+ end
39
+ end
40
+
41
+ %w(basic).each do |role|
42
+ context "#{role} : delete /:fake_id/usages/:fake_id" do
43
+ before do
44
+ delete "/#{FAKE_ID}/usages/#{FAKE_ID}",
45
+ :api_key => api_key_for(role)
46
+ end
47
+
48
+ use "return 404 Not Found with empty response body"
49
+ use "no change in usage count"
50
+ end
51
+
52
+ context "#{role} : delete /:fake_id/usages/:id" do
53
+ before do
54
+ delete "/#{FAKE_ID}/usages/#{@usage_id}",
55
+ :api_key => api_key_for(role)
56
+ end
57
+
58
+ use "return 404 Not Found with empty response body"
59
+ use "no change in usage count"
60
+ end
61
+
62
+ context "#{role} : delete /:id/usages/:fake_id" do
63
+ before do
64
+ delete "/#{@source.id}/usages/#{FAKE_ID}", :api_key => api_key_for(role)
65
+ end
66
+
67
+ use "return 401 because the API key is unauthorized"
68
+ use "no change in usage count"
69
+ end
70
+
71
+ context "#{role} : delete /:id/usages/:not_related_id" do
72
+ before do
73
+ delete "/#{@source.id}/usages/#{@other_usage_id}",
74
+ :api_key => api_key_for(role)
75
+ end
76
+
77
+ use "return 401 because the API key is unauthorized"
78
+ use "no change in usage count"
79
+ end
80
+
81
+ context "#{role} : delete /:id/usages/:id" do
82
+ before do
83
+ delete "/#{@source.id}/usages/#{@usage_id}",
84
+ :api_key => api_key_for(role)
85
+ end
86
+
87
+ use "return 401 because the API key is unauthorized"
88
+ use "no change in usage count"
89
+ end
90
+ end
91
+
92
+ %w(curator).each do |role|
93
+ # %w(curator admin).each do |role|
94
+ context "#{role} : delete /:fake_id/usages/:fake_id" do
95
+ before do
96
+ delete "/#{FAKE_ID}/usages/#{FAKE_ID}",
97
+ :api_key => api_key_for(role)
98
+ end
99
+
100
+ use "return 404 Not Found with empty response body"
101
+ use "no change in usage count"
102
+ end
103
+
104
+ context "#{role} : delete /:fake_id/usages/:id" do
105
+ before do
106
+ delete "/#{FAKE_ID}/usages/#{@usage_id}",
107
+ :api_key => api_key_for(role)
108
+ end
109
+
110
+ use "return 404 Not Found with empty response body"
111
+ use "no change in usage count"
112
+ end
113
+
114
+ context "#{role} : delete /:id/usages/:fake_id" do
115
+ before do
116
+ delete "/#{@source.id}/usages/#{FAKE_ID}",
117
+ :api_key => api_key_for(role)
118
+ end
119
+
120
+ use "return 404 Not Found with empty response body"
121
+ use "no change in usage count"
122
+ end
123
+
124
+ context "#{role} : delete /:id/usages/:not_related_id" do
125
+ before do
126
+ delete "/#{@source.id}/usages/#{@other_usage_id}",
127
+ :api_key => api_key_for(role)
128
+ end
129
+
130
+ use "return 404 Not Found with empty response body"
131
+ use "no change in usage count"
132
+ end
133
+
134
+ context "#{role} : delete /:id/usages/:id" do
135
+ before do
136
+ delete "/#{@source.id}/usages/#{@usage_id}",
137
+ :api_key => api_key_for(role)
138
+ end
139
+
140
+ use "return 204 No Content"
141
+ use "one less usage"
142
+ end
143
+ end
144
+
145
+ end
@@ -0,0 +1,76 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../helpers/resource_test_helper')
2
+
3
+ class SourcesUsagesGetManyResourceTest < ResourceTestCase
4
+
5
+ include DataCatalog
6
+
7
+ def app; Sources end
8
+
9
+ before do
10
+ @source = create_source(:title => "Source A")
11
+ 3.times do |i|
12
+ @source.usages << new_usage(:title => "Usage #{i}A")
13
+ end
14
+ @source.save
15
+ @usage_titles = ["Usage 0A", "Usage 1A", "Usage 2A"].sort
16
+
17
+ @other_source = create_source(:title => "Source B")
18
+ 3.times do |i|
19
+ @other_source.usages << new_usage(:title => "Usage #{i}B")
20
+ end
21
+ @other_source.save
22
+ end
23
+
24
+ after do
25
+ @other_source.destroy
26
+ @source.destroy
27
+ end
28
+
29
+ context "get /:id/usages" do
30
+ context "anonymous" do
31
+ before do
32
+ get "/#{@source.id}/usages"
33
+ end
34
+
35
+ use "return 401 because the API key is missing"
36
+ end
37
+
38
+ context "incorrect API key" do
39
+ before do
40
+ get "/#{@source.id}/usages", :api_key => BAD_API_KEY
41
+ end
42
+
43
+ use "return 401 because the API key is invalid"
44
+ end
45
+ end
46
+
47
+ %w(basic curator admin).each do |role|
48
+ context "#{role} : get /:fake_id/usages" do
49
+ before do
50
+ get "/#{FAKE_ID}/usages", :api_key => api_key_for(role)
51
+ end
52
+
53
+ use "return 404 Not Found with empty response body"
54
+ end
55
+
56
+ context "#{role} : get /:id/usages" do
57
+ before do
58
+ get "/#{@source.id}/usages", :api_key => api_key_for(role)
59
+ end
60
+
61
+ use "return 200 Ok"
62
+
63
+ test "body should have 3 sources" do
64
+ assert_equal 3, parsed_response_body.length
65
+ end
66
+
67
+ test "body should have correct source titles" do
68
+ actual = parsed_response_body.map { |e| e["title"] }
69
+ assert_equal @usage_titles, actual.sort
70
+ end
71
+
72
+ docs_properties %w(title url description id)
73
+ end
74
+ end
75
+
76
+ end