sinatra_resource 0.4.4 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.4
1
+ 0.4.5
@@ -43,20 +43,26 @@ class CategoriesGetManyResourceTest < ResourceTestCase
43
43
  context "#{role} : get /" do
44
44
  before do
45
45
  get "/", :api_key => api_key_for(role)
46
+ @members = parsed_response_body['members']
46
47
  end
47
48
 
48
49
  use "return 200 Ok"
49
50
 
50
51
  test "body should have 3 categories" do
51
- assert_equal 3, parsed_response_body.length
52
+ assert_equal 3, @members.length
52
53
  end
53
54
 
54
55
  test "body should have correct category names" do
55
- actual = parsed_response_body.map { |e| e["name"] }
56
+ actual = @members.map { |e| e["name"] }
56
57
  assert_equal CATEGORIES, actual.sort
57
58
  end
58
59
 
59
- docs_properties %w(name log sources id created_at updated_at)
60
+ test "members should only have correct attributes" do
61
+ correct = %w(name log sources id created_at updated_at)
62
+ @members.each do |member|
63
+ assert_properties(correct, member)
64
+ end
65
+ end
60
66
  end
61
67
  end
62
68
 
@@ -73,20 +73,26 @@ class CategoriesSourcesGetManyResourceTest < ResourceTestCase
73
73
  context "#{role} : get /:id/sources" do
74
74
  before do
75
75
  get "/#{@category.id}/sources", :api_key => api_key_for(role)
76
+ @members = parsed_response_body['members']
76
77
  end
77
78
 
78
79
  use "return 200 Ok"
79
80
 
80
81
  test "body should have 3 sources" do
81
- assert_equal 3, parsed_response_body.length
82
+ assert_equal 3, @members.length
82
83
  end
83
84
 
84
85
  test "body should have correct source titles" do
85
- actual = parsed_response_body.map { |e| e["title"] }
86
+ actual = @members.map { |e| e["title"] }
86
87
  assert_equal @source_titles, actual.sort
87
88
  end
88
-
89
- docs_properties %w(title url raw id created_at updated_at)
89
+
90
+ test "members should only have correct attributes" do
91
+ correct = %w(title url raw id created_at updated_at)
92
+ @members.each do |member|
93
+ assert_properties(correct, member)
94
+ end
95
+ end
90
96
  end
91
97
  end
92
98
 
@@ -49,12 +49,13 @@ class NotesGetManyResourceTest < ResourceTestCase
49
49
  context "#{role} : get /" do
50
50
  before do
51
51
  get "/", :api_key => api_key_for(role)
52
+ @members = parsed_response_body['members']
52
53
  end
53
54
 
54
55
  use "return 200 Ok"
55
56
 
56
57
  test "body should have an empty list" do
57
- assert_equal [], parsed_response_body
58
+ assert_equal [], @members
58
59
  end
59
60
  end
60
61
  end
@@ -62,40 +63,52 @@ class NotesGetManyResourceTest < ResourceTestCase
62
63
  context "owner : get /" do
63
64
  before do
64
65
  get "/", :api_key => @users[0]._api_key
66
+ @members = parsed_response_body['members']
65
67
  end
66
68
 
67
69
  use "return 200 Ok"
68
70
 
69
71
  test "body should have 1 note" do
70
- assert_equal 1, parsed_response_body.length
72
+ assert_equal 1, @members.length
71
73
  end
72
74
 
73
75
  test "body should have correct note text" do
74
- actual = parsed_response_body.map { |e| e["text"] }
76
+ actual = @members.map { |e| e["text"] }
75
77
  assert_equal ["Note 0"], actual.sort
76
78
  end
77
79
 
78
- docs_properties %w(text user_id id created_at updated_at)
80
+ test "members should only have correct attributes" do
81
+ correct = %w(text user_id id created_at updated_at)
82
+ @members.each do |member|
83
+ assert_properties(correct, member)
84
+ end
85
+ end
79
86
  end
80
87
 
81
88
  %w(admin).each do |role|
82
89
  context "#{role} : get /" do
83
90
  before do
84
91
  get "/", :api_key => api_key_for(role)
92
+ @members = parsed_response_body['members']
85
93
  end
86
94
 
87
95
  use "return 200 Ok"
88
96
 
89
97
  test "body should have 3 notes" do
90
- assert_equal 3, parsed_response_body.length
98
+ assert_equal 3, @members.length
91
99
  end
92
100
 
93
101
  test "body should have correct note text" do
94
- actual = parsed_response_body.map { |e| e["text"] }
102
+ actual = @members.map { |e| e["text"] }
95
103
  assert_equal @note_texts, actual.sort
96
104
  end
97
-
98
- docs_properties %w(text user_id id created_at updated_at)
105
+
106
+ test "notes should only have correct attributes" do
107
+ correct = %w(text user_id id created_at updated_at)
108
+ @members.each do |member|
109
+ assert_properties(correct, member)
110
+ end
111
+ end
99
112
  end
100
113
  end
101
114
 
@@ -45,19 +45,25 @@ class SourcesGetManyFilterResourceTest < ResourceTestCase
45
45
  context "#{role} : get /" do
46
46
  before do
47
47
  get "/", @search_params.merge(:api_key => api_key_for(role))
48
+ @members = parsed_response_body['members']
48
49
  end
49
50
 
50
51
  use "return 200 Ok"
51
52
 
52
53
  test "body should have 1 source" do
53
- assert_equal 1, parsed_response_body.length
54
+ assert_equal 1, @members.length
54
55
  end
55
56
 
56
57
  test "body should have correct source" do
57
- assert_equal 'Source 2', parsed_response_body[0]['title']
58
+ assert_equal 'Source 2', @members[0]['title']
58
59
  end
59
60
 
60
- docs_properties %w(title url raw categories id created_at updated_at)
61
+ test "members should only have correct attributes" do
62
+ correct = %w(title url raw categories id created_at updated_at)
63
+ @members.each do |member|
64
+ assert_properties(correct, member)
65
+ end
66
+ end
61
67
  end
62
68
  end
63
69
  end
@@ -71,20 +77,26 @@ class SourcesGetManyFilterResourceTest < ResourceTestCase
71
77
  context "#{role} : get /" do
72
78
  before do
73
79
  get "/", @search_params.merge(:api_key => api_key_for(role))
80
+ @members = parsed_response_body['members']
74
81
  end
75
82
 
76
83
  use "return 200 Ok"
77
84
 
78
85
  test "body should have 3 sources" do
79
- assert_equal 3, parsed_response_body.length
86
+ assert_equal 3, @members.length
80
87
  end
81
88
 
82
89
  test "body should have correct source titles" do
83
- actual = parsed_response_body.map { |e| e["title"] }
90
+ actual = @members.map { |e| e["title"] }
84
91
  assert_equal @source_titles, actual.sort
85
92
  end
86
93
 
87
- docs_properties %w(title url raw categories id created_at updated_at)
94
+ test "members should only have correct attributes" do
95
+ correct = %w(title url raw categories id created_at updated_at)
96
+ @members.each do |member|
97
+ assert_properties(correct, member)
98
+ end
99
+ end
88
100
  end
89
101
  end
90
102
  end
@@ -73,20 +73,26 @@ class SourcesGetManySearchResourceTest < ResourceTestCase
73
73
  context "#{role} : get /" do
74
74
  before do
75
75
  get "/", @search_params.merge(:api_key => api_key_for(role))
76
+ @members = parsed_response_body['members']
76
77
  end
77
78
 
78
79
  use "return 200 Ok"
79
80
 
80
81
  test "body should have 1 source" do
81
- assert_equal 1, parsed_response_body.length
82
+ assert_equal 1, @members.length
82
83
  end
83
84
 
84
85
  test "body should have correct source" do
85
86
  assert_equal %{2007 Crime in the United States},
86
- parsed_response_body[0]['title']
87
+ @members[0]['title']
87
88
  end
88
89
 
89
- docs_properties %w(title url raw categories id created_at updated_at)
90
+ test "members should only have correct attributes" do
91
+ correct = %w(title url raw categories id created_at updated_at)
92
+ @members.each do |member|
93
+ assert_properties(correct, member)
94
+ end
95
+ end
90
96
  end
91
97
  end
92
98
  end
@@ -100,12 +106,13 @@ class SourcesGetManySearchResourceTest < ResourceTestCase
100
106
  context "#{role} : get /" do
101
107
  before do
102
108
  get "/", @search_params.merge(:api_key => api_key_for(role))
109
+ @members = parsed_response_body['members']
103
110
  end
104
111
 
105
112
  use "return 200 Ok"
106
113
 
107
114
  test "body should have correct sources" do
108
- titles = parsed_response_body.map { |x| x['title'] }
115
+ titles = @members.map { |x| x['title'] }
109
116
  assert_equal 2, titles.length
110
117
  assert_include %{Interest Rate Statistics - Daily Treasury Yield Curve Rates (1998)}, titles
111
118
  assert_include %{Interest Rate Statistics - Daily Treasury Bills Rates (Current month)}, titles
@@ -40,20 +40,26 @@ class SourcesGetManyResourceTest < ResourceTestCase
40
40
  context "#{role} : get /" do
41
41
  before do
42
42
  get "/", :api_key => api_key_for(role)
43
+ @members = parsed_response_body['members']
43
44
  end
44
45
 
45
46
  use "return 200 Ok"
46
47
 
47
48
  test "body should have 3 sources" do
48
- assert_equal 3, parsed_response_body.length
49
+ assert_equal 3, @members.length
49
50
  end
50
51
 
51
52
  test "body should have correct source titles" do
52
- actual = parsed_response_body.map { |e| e["title"] }
53
+ actual = @members.map { |e| e["title"] }
53
54
  assert_equal @source_titles, actual.sort
54
55
  end
55
-
56
- docs_properties %w(title url raw categories id created_at updated_at)
56
+
57
+ test "members should only have correct attributes" do
58
+ correct = %w(title url raw categories id created_at updated_at)
59
+ @members.each do |member|
60
+ assert_properties(correct, member)
61
+ end
62
+ end
57
63
  end
58
64
  end
59
65
 
@@ -66,20 +66,26 @@ class SourcesUsagesGetManyFilterResourceTest < ResourceTestCase
66
66
  before do
67
67
  get "/#{@source.id}/usages", search.merge(
68
68
  :api_key => api_key_for(role))
69
+ @members = parsed_response_body['members']
69
70
  end
70
71
 
71
72
  use "return 200 Ok"
72
73
 
73
74
  test "body should have 2 sources" do
74
- assert_equal 2, parsed_response_body.length
75
+ assert_equal 2, @members.length
75
76
  end
76
77
 
77
78
  test "body should have correct source titles" do
78
- actual = parsed_response_body.map { |e| e["title"] }
79
+ actual = @members.map { |e| e["title"] }
79
80
  assert_equal ["Usage 0", "Usage 2"], actual.sort
80
81
  end
81
-
82
- docs_properties %w(title url description id)
82
+
83
+ test "members should only have correct attributes" do
84
+ correct = %w(title url description id)
85
+ @members.each do |member|
86
+ assert_properties(correct, member)
87
+ end
88
+ end
83
89
  end
84
90
  end
85
91
  end
@@ -56,20 +56,26 @@ class SourcesUsagesGetManyResourceTest < ResourceTestCase
56
56
  context "#{role} : get /:id/usages" do
57
57
  before do
58
58
  get "/#{@source.id}/usages", :api_key => api_key_for(role)
59
+ @members = parsed_response_body['members']
59
60
  end
60
61
 
61
62
  use "return 200 Ok"
62
63
 
63
64
  test "body should have 3 sources" do
64
- assert_equal 3, parsed_response_body.length
65
+ assert_equal 3, @members.length
65
66
  end
66
67
 
67
68
  test "body should have correct source titles" do
68
- actual = parsed_response_body.map { |e| e["title"] }
69
+ actual = @members.map { |e| e["title"] }
69
70
  assert_equal @usage_titles, actual.sort
70
71
  end
71
-
72
- docs_properties %w(title url description id)
72
+
73
+ test "members should only have correct attributes" do
74
+ correct = %w(title url description id)
75
+ @members.each do |member|
76
+ assert_properties(correct, member)
77
+ end
78
+ end
73
79
  end
74
80
  end
75
81
 
@@ -62,21 +62,22 @@ class UsersGetManyResourceTest < ResourceTestCase
62
62
  context "#{role} : get /" do
63
63
  before do
64
64
  get "/", :api_key => api_key_for(role)
65
+ @members = parsed_response_body['members']
65
66
  end
66
67
 
67
68
  use "return 200 Ok"
68
69
 
69
70
  test "body should have 6 users" do
70
- assert_equal 6, parsed_response_body.length
71
+ assert_equal 6, @members.length
71
72
  end
72
73
 
73
74
  test "body should have correct names" do
74
- actual = parsed_response_body.map { |e| e["name"] }
75
+ actual = @members.map { |e| e["name"] }
75
76
  assert_equal NAMES, actual.sort
76
77
  end
77
78
 
78
79
  test "body elements should be correct" do
79
- parsed_response_body.each do |element|
80
+ @members.each do |element|
80
81
  if element["id"] == user_for(role).id
81
82
  assert_properties(%w(name email role _api_key token
82
83
  id created_at updated_at), element)
@@ -92,25 +93,31 @@ class UsersGetManyResourceTest < ResourceTestCase
92
93
  context "#{role} : get /" do
93
94
  before do
94
95
  get "/", :api_key => api_key_for(role)
96
+ @members = parsed_response_body['members']
95
97
  end
96
98
 
97
99
  use "return 200 Ok"
98
100
 
99
101
  test "body should have 6 users" do
100
- assert_equal 6, parsed_response_body.length
102
+ assert_equal 6, @members.length
101
103
  end
102
104
 
103
105
  test "body should have correct names" do
104
- actual = parsed_response_body.map { |e| e["name"] }
106
+ actual = @members.map { |e| e["name"] }
105
107
  assert_equal NAMES, actual.sort
106
108
  end
107
109
 
108
110
  test "body should have correct emails" do
109
- actual = parsed_response_body.map { |e| e["email"] }
111
+ actual = @members.map { |e| e["email"] }
110
112
  assert_equal EMAILS, actual.sort
111
113
  end
112
-
113
- docs_properties %w(name email role _api_key token id created_at updated_at)
114
+
115
+ test "members should only have correct attributes" do
116
+ correct = %w(name email role _api_key token id created_at updated_at)
117
+ @members.each do |member|
118
+ assert_properties(correct, member)
119
+ end
120
+ end
114
121
  end
115
122
  end
116
123
 
@@ -17,13 +17,21 @@ module SinatraResource
17
17
  end
18
18
  end
19
19
 
20
- def documents_for_get_many(role, model, resource_config, leaf, parent_document, child_assoc)
20
+ def document_count_for_get_many(model, resource_config, parent_document, child_assoc)
21
+ if resource_config[:parent]
22
+ count_nested_documents(parent_document, child_assoc, model)
23
+ else
24
+ count_documents(model)
25
+ end
26
+ end
27
+
28
+ def documents_for_get_many(role, model, resource_config, page, items_per_page, leaf, parent_document, child_assoc)
21
29
  check_permission(:list, role, resource_config)
22
30
  check_params(:list, role, resource_config, leaf)
23
31
  documents = if resource_config[:parent]
24
- find_nested_documents!(parent_document, child_assoc, model)
32
+ find_nested_documents!(parent_document, child_assoc, model, page, items_per_page)
25
33
  else
26
- find_documents!(model)
34
+ find_documents!(model, page, items_per_page)
27
35
  end
28
36
  documents.select do |doc|
29
37
  authorized?(:read, lookup_role(doc), resource_config)
@@ -33,11 +33,28 @@ module SinatraResource
33
33
  #
34
34
  # @param [Hash] resource_config
35
35
  #
36
+ # @param [Integer] page
37
+ #
38
+ # @param [Integer] page_count
39
+ #
36
40
  # @return [Array<Hash<String => Object>>]
37
- def build_resources(documents, resource_config)
38
- documents.map do |document|
39
- build_resource(lookup_role(document), document, resource_config)
41
+ def build_resources(documents, resource_config, page, page_count)
42
+ if page_count > 0 && page > page_count
43
+ error 400, convert(body_for(:errors,
44
+ "page (#{page}) must be <= page_count (#{page_count})"))
40
45
  end
46
+ {
47
+ 'previous' => page > 1 ? link_to_page(page - 1) : nil,
48
+ 'next' => page < page_count ? link_to_page(page + 1) : nil,
49
+ 'page_count' => page_count,
50
+ 'members' => documents.map do |document|
51
+ build_resource(lookup_role(document), document, resource_config)
52
+ end,
53
+ }
54
+ end
55
+
56
+ def calculate_page_count(document_count, items_per_page)
57
+ (document_count.to_f / items_per_page).ceil
41
58
  end
42
59
 
43
60
  # Halt unless the current params are ok for +action+ and +role+.
@@ -160,6 +177,33 @@ module SinatraResource
160
177
  raise NotImplementedError
161
178
  end
162
179
 
180
+ # Get the page parameter.
181
+ #
182
+ # @param [Hash] params
183
+ #
184
+ # @return [Integer]
185
+ def get_page(params)
186
+ raw = params.delete('page')
187
+ return 1 unless raw
188
+ page = raw.to_i
189
+ if page < 1
190
+ error 400, convert(body_for(:errors, "page must be >= 1"))
191
+ end
192
+ page
193
+ end
194
+
195
+ # Build a hash that contains a URL to +page_number+.
196
+ #
197
+ # @param [Integer] page
198
+ #
199
+ # @return [Hash]
200
+ def link_to_page(page_number)
201
+ q = Rack::Utils.parse_query(request.query_string)
202
+ q['page'] = page_number
203
+ query_string = Rack::Utils.build_query(q)
204
+ { 'href' => "#{request.path}?#{query_string}" }
205
+ end
206
+
163
207
  # Get role, using +model+ and +id+. Delegates to +lookup_role+.
164
208
  #
165
209
  # When +id+ is present, it can help determine 'relative' roles such
@@ -22,6 +22,41 @@ module SinatraResource
22
22
  find_child!(children, child_id)
23
23
  true
24
24
  end
25
+
26
+ # Find +model+ documents: find all documents if no params, otherwise
27
+ # find selected documents.
28
+ #
29
+ # @param [Class] model
30
+ # a class that includes MongoMapper::Document
31
+ #
32
+ # @return [Integer]
33
+ def count_documents(model)
34
+ conditions = params.empty? ? {} : make_conditions(params, model)
35
+ model.count(conditions)
36
+ end
37
+
38
+ def count_nested_documents(parent, child_assoc, child_model)
39
+ #
40
+ # This code needs significant improvement.
41
+ # It is copy and pasted from find_nested_documents!
42
+ #
43
+ documents = if child_model.embeddable?
44
+ children = parent.send(child_assoc)
45
+ if params.empty?
46
+ children
47
+ else
48
+ select_by(children, make_conditions(params, child_model))
49
+ end
50
+ else
51
+ children = if params.empty?
52
+ child_model.all
53
+ else
54
+ child_model.all(make_conditions(params, child_model))
55
+ end
56
+ select_related(parent, child_assoc, children)
57
+ end
58
+ documents.length
59
+ end
25
60
 
26
61
  # Create a document from params. If not valid, returns 400.
27
62
  #
@@ -199,7 +234,7 @@ module SinatraResource
199
234
  end
200
235
  document
201
236
  end
202
-
237
+
203
238
  # Find +model+ documents: find all documents if no params, otherwise
204
239
  # find selected documents.
205
240
  #
@@ -207,9 +242,12 @@ module SinatraResource
207
242
  # a class that includes MongoMapper::Document
208
243
  #
209
244
  # @return [Array<MongoMapper::Document>]
210
- def find_documents!(model)
211
- return(model.all) if params.empty?
212
- model.all(make_conditions(params, model))
245
+ def find_documents!(model, page, items_per_page)
246
+ conditions = params.empty? ? {} : make_conditions(params, model)
247
+ model.all(conditions.merge({
248
+ :skip => items_per_page * (page - 1),
249
+ :limit => items_per_page
250
+ }))
213
251
  end
214
252
 
215
253
  # Find nested +child_model+ documents: find all documents if no
@@ -226,7 +264,11 @@ module SinatraResource
226
264
  # * MongoMapper::EmbeddedDocument
227
265
  #
228
266
  # @return [Array<MongoMapper::Document>]
229
- def find_nested_documents!(parent, child_assoc, child_model)
267
+ def find_nested_documents!(parent, child_assoc, child_model, page, items_per_page)
268
+ #
269
+ # TODO: handle page parameter
270
+ # TODO: handle items_per_page parameter
271
+ #
230
272
  documents = if child_model.embeddable?
231
273
  children = parent.send(child_assoc)
232
274
  if params.empty?
@@ -244,7 +286,7 @@ module SinatraResource
244
286
  end
245
287
  end
246
288
 
247
- # Delegates to application, who should use custom logic to related
289
+ # Delegates to application, who should use custom logic to relate
248
290
  # +parent+ and +child+.
249
291
  #
250
292
  # @param [MongoMapper::Document] parent
data/lib/builder.rb CHANGED
@@ -4,6 +4,8 @@ module SinatraResource
4
4
 
5
5
  FILTER_KEY = "filter"
6
6
  SEARCH_KEY = "search"
7
+
8
+ ITEMS_PER_PAGE = 20
7
9
 
8
10
  def initialize(klass)
9
11
  @klass = klass
@@ -64,8 +66,11 @@ module SinatraResource
64
66
  if !@parent
65
67
  @klass.get '/?' do
66
68
  role = lookup_role(nil)
67
- documents = documents_for_get_many(role, model, resource_config, true, nil, nil)
68
- resources = build_resources(documents, resource_config)
69
+ page = get_page(params)
70
+ documents = documents_for_get_many(role, model, resource_config, page, ITEMS_PER_PAGE, true, nil, nil)
71
+ document_count = document_count_for_get_many(model, resource_config, nil, nil)
72
+ page_count = calculate_page_count(document_count, ITEMS_PER_PAGE)
73
+ resources = build_resources(documents, resource_config, page, page_count)
69
74
  display(:list, resources, resource_config)
70
75
  end
71
76
  else
@@ -79,8 +84,11 @@ module SinatraResource
79
84
  parent_document = document_for_get_one(parent_role, parent_model, parent_resource_config, false, parent_id, nil, nil)
80
85
  # ------
81
86
  role = lookup_role(nil)
82
- documents = documents_for_get_many(role, model, resource_config, true, parent_document, child_assoc)
83
- resources = build_resources(documents, resource_config)
87
+ page = get_page(params)
88
+ documents = documents_for_get_many(role, model, resource_config, page, ITEMS_PER_PAGE, true, parent_document, child_assoc)
89
+ document_count = document_count_for_get_many(model, resource_config, parent_document, child_assoc)
90
+ page_count = calculate_page_count(document_count, ITEMS_PER_PAGE)
91
+ resources = build_resources(documents, resource_config, page, page_count)
84
92
  display(:list, resources, resource_config, parent_id)
85
93
  end
86
94
  end
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sinatra_resource}
8
- s.version = "0.4.4"
8
+ s.version = "0.4.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David James"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra_resource
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - David James