sinatra_resource 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
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