sinatra_resource 0.4.4 → 0.4.5

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