standardapi 6.1.0 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +80 -58
  3. data/lib/standard_api/access_control_list.rb +40 -6
  4. data/lib/standard_api/controller.rb +96 -28
  5. data/lib/standard_api/helpers.rb +13 -7
  6. data/lib/standard_api/middleware.rb +5 -0
  7. data/lib/standard_api/railtie.rb +17 -0
  8. data/lib/standard_api/route_helpers.rb +59 -9
  9. data/lib/standard_api/test_case/calculate_tests.rb +7 -6
  10. data/lib/standard_api/test_case/destroy_tests.rb +19 -7
  11. data/lib/standard_api/test_case/index_tests.rb +7 -13
  12. data/lib/standard_api/test_case/show_tests.rb +7 -7
  13. data/lib/standard_api/test_case/update_tests.rb +7 -6
  14. data/lib/standard_api/version.rb +1 -1
  15. data/lib/standard_api/views/application/_record.json.jbuilder +4 -3
  16. data/lib/standard_api/views/application/_record.streamer +4 -3
  17. data/lib/standard_api/views/application/_schema.json.jbuilder +20 -8
  18. data/lib/standard_api/views/application/_schema.streamer +22 -8
  19. data/lib/standard_api.rb +1 -0
  20. data/test/standard_api/caching_test.rb +2 -2
  21. data/test/standard_api/controller/include_test.rb +107 -0
  22. data/test/standard_api/controller/subresource_test.rb +157 -0
  23. data/test/standard_api/helpers_test.rb +9 -8
  24. data/test/standard_api/nested_attributes/belongs_to_test.rb +71 -0
  25. data/test/standard_api/nested_attributes/has_and_belongs_to_many_test.rb +70 -0
  26. data/test/standard_api/nested_attributes/has_many_test.rb +85 -0
  27. data/test/standard_api/nested_attributes/has_one_test.rb +71 -0
  28. data/test/standard_api/route_helpers_test.rb +56 -0
  29. data/test/standard_api/standard_api_test.rb +80 -50
  30. data/test/standard_api/test_app/app/controllers/acl/camera_acl.rb +7 -0
  31. data/test/standard_api/test_app/app/controllers/acl/photo_acl.rb +13 -0
  32. data/test/standard_api/test_app/app/controllers/acl/property_acl.rb +7 -1
  33. data/test/standard_api/test_app/controllers.rb +17 -0
  34. data/test/standard_api/test_app/models.rb +59 -2
  35. data/test/standard_api/test_app/test/factories.rb +3 -0
  36. data/test/standard_api/test_app/views/sessions/create.json.jbuilder +1 -0
  37. data/test/standard_api/test_app/views/sessions/create.streamer +3 -0
  38. data/test/standard_api/test_app.rb +12 -1
  39. data/test/standard_api/test_helper.rb +9 -0
  40. metadata +52 -13
@@ -0,0 +1,71 @@
1
+ require 'standard_api/test_helper'
2
+
3
+ module NestedAttributes
4
+ class BelongsToTest < ActionDispatch::IntegrationTest
5
+ # include StandardAPI::TestCase
6
+ include StandardAPI::Helpers
7
+
8
+
9
+ # = Create Test
10
+
11
+ test 'create record and create nested record' do
12
+ @controller = PhotosController.new
13
+ post photos_path, params: { photo: { account: {name: 'Big Ben'}} }, as: :json
14
+
15
+ assert_response :created
16
+ photo = Photo.last
17
+ assert_equal 'Big Ben', photo.account.name
18
+ end
19
+
20
+ test 'create record and update nested record' do
21
+ account = create(:account, name: 'Big Ben')
22
+
23
+ @controller = PhotosController.new
24
+ post photos_path, params: { photo: { account: {id: account.id, name: 'Little Jimmie'}} }, as: :json
25
+
26
+
27
+ assert_response :created
28
+ photo = Photo.last
29
+ assert_equal account.id, photo.account_id
30
+ assert_equal 'Little Jimmie', photo.account.name
31
+ end
32
+
33
+ # = Update Test
34
+
35
+ test 'update record and create nested record' do
36
+ photo = create(:photo)
37
+
38
+ @controller = PhotosController.new
39
+ put photo_path(photo), params: { photo: { account: {name: 'Big Ben'}} }, as: :json
40
+
41
+ assert_response :ok
42
+ photo.reload
43
+ assert_equal 'Big Ben', photo.account.name
44
+ end
45
+
46
+ test 'update record and update nested record' do
47
+ account = create(:account, name: 'Big Ben')
48
+ photo = create(:photo, account: account)
49
+
50
+ @controller = PhotosController.new
51
+ put photo_path(photo), params: { photo: { account: {name: 'Little Jimmie'}} }, as: :json
52
+
53
+ assert_response :ok
54
+ photo.reload
55
+ assert_equal 'Little Jimmie', photo.account.name
56
+ end
57
+
58
+ test 'update record and set relation to nil' do
59
+ account = create(:account, name: 'Big Ben')
60
+ photo = create(:photo, account: account)
61
+
62
+ @controller = PhotosController.new
63
+ put photo_path(photo), params: { photo: { account: nil} }, as: :json
64
+
65
+ assert_response :ok
66
+ photo.reload
67
+ assert_nil photo.account
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,70 @@
1
+ require 'standard_api/test_helper'
2
+
3
+ module NestedAttributes
4
+ class HasAndBelongsToManyTest < ActionDispatch::IntegrationTest
5
+ # include StandardAPI::TestCase
6
+ include StandardAPI::Helpers
7
+
8
+
9
+ # = Create Test
10
+
11
+ test 'create record and create nested record' do
12
+ @controller = PropertiesController.new
13
+ post properties_path, params: { property: { name: 'Beach House', photos: [{format: 'image/jpeg'}]} }, as: :json
14
+
15
+ assert_response :created
16
+ property = Property.last
17
+ assert_equal 'Beach House', property.name
18
+ assert_equal ['image/jpeg'], property.photos.map(&:format)
19
+ end
20
+
21
+ test 'create record and update nested record' do
22
+ photo = create(:photo, format: 'image/png')
23
+
24
+ @controller = PropertiesController.new
25
+ post properties_path, params: { property: { name: 'Beach House', photos: [{id: photo.id, format: 'image/jpeg'}] } }, as: :json
26
+
27
+ assert_response :created
28
+ property = Property.last
29
+ assert_equal 'Beach House', property.name
30
+ assert_equal [photo.id], property.photos.map(&:id)
31
+ assert_equal ['image/jpeg'], property.photos.map(&:format)
32
+ assert_equal 'image/jpeg', photo.reload.format
33
+ end
34
+
35
+ # = Update Test
36
+
37
+ test 'update record and create nested record' do
38
+ property = create(:property)
39
+
40
+ @controller = PropertiesController.new
41
+ put property_path(property), params: { property: { photos: [{format: "image/tiff"}]} }, as: :json
42
+
43
+ assert_response :ok
44
+ assert_equal ["image/tiff"], property.reload.photos.map(&:format)
45
+ end
46
+
47
+ test 'update record and update nested record' do
48
+ photo = create(:photo, format: 'image/gif')
49
+ property = create(:property, photos: [photo])
50
+
51
+ @controller = PropertiesController.new
52
+ put property_path(property), params: { property: { photos: [{id: photo.id, format: "image/heic"}]} }, as: :json
53
+
54
+ assert_response :ok
55
+ assert_equal ['image/heic'], property.reload.photos.map(&:format)
56
+ end
57
+
58
+ test 'update record and set relation to an empty array' do
59
+ photo = create(:photo, format: 'image/gif')
60
+ property = create(:property, photos: [photo])
61
+
62
+ @controller = PropertiesController.new
63
+ put property_path(property), params: { property: { photos: [] } }, as: :json
64
+
65
+ assert_response :ok
66
+ assert_equal [], property.reload.photos
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,85 @@
1
+ require 'standard_api/test_helper'
2
+
3
+ module NestedAttributes
4
+ class HasManyTest < ActionDispatch::IntegrationTest
5
+ # include StandardAPI::TestCase
6
+ include StandardAPI::Helpers
7
+
8
+
9
+ # = Create Test
10
+
11
+ test 'create record and create nested record' do
12
+ @controller = PropertiesController.new
13
+ post properties_path, params: { property: { name: 'Beach House', accounts: [{name: 'Billabong'}]} }, as: :json
14
+
15
+ assert_response :created
16
+ property = Property.last
17
+ assert_equal 'Beach House', property.name
18
+ assert_equal ['Billabong'], property.accounts.map(&:name)
19
+ end
20
+
21
+ test 'create record and update nested record' do
22
+ account = create(:account, name: 'Coco Chanel')
23
+
24
+ @controller = PropertiesController.new
25
+ post properties_path, params: { property: { name: 'Beach House', accounts: [{id: account.id, name: 'Crazy Chanel'}]} }, as: :json
26
+
27
+ assert_response :created
28
+ property = Property.last
29
+ assert_equal [account.id], property.accounts.map(&:id)
30
+ assert_equal ['Crazy Chanel'], property.accounts.map(&:name)
31
+ assert_equal 'Crazy Chanel', account.reload.name
32
+ end
33
+
34
+ # = Update Test
35
+
36
+ test 'update record and create nested record' do
37
+ property = create(:property)
38
+
39
+ @controller = PropertiesController.new
40
+ put property_path(property), params: { property: { accounts: [{name: "Hersey's"}]} }, as: :json
41
+
42
+ assert_response :ok
43
+ assert_equal ["Hersey's"], property.accounts.map(&:name)
44
+ end
45
+
46
+ test 'update record and update nested record' do
47
+ account = create(:account, name: 'A Co.')
48
+ property = create(:property, name: 'Empire State Building', accounts: [account])
49
+
50
+ @controller = PropertiesController.new
51
+ put property_path(property), params: { property: { name: 'John Hancock Center', accounts: [{id: account.id, name: "B Co."}]} }, as: :json
52
+
53
+ assert_response :ok
54
+ property.reload
55
+ assert_equal 'John Hancock Center', property.name
56
+ assert_equal ['B Co.'], property.accounts.map(&:name)
57
+ end
58
+
59
+ test 'update record and set relation to an empty array' do
60
+ account = create(:account, name: 'A Co.')
61
+ property = create(:property, name: 'Empire State Building', accounts: [account])
62
+
63
+ @controller = PropertiesController.new
64
+ put property_path(property), params: { property: { accounts: [] } }, as: :json
65
+
66
+ assert_response :ok
67
+ property.reload
68
+ assert_equal [], property.accounts
69
+ end
70
+
71
+ test 'update record and include nested record in response' do
72
+ account = create(:account, name: 'A Co.')
73
+ property = create(:property, name: 'Empire State Building', accounts: [account])
74
+
75
+ @controller = PropertiesController.new
76
+ put property_path(property), params: { property: { name: 'John Hancock Center', accounts: [{id: account.id, name: "B Co."}]} }, as: :json
77
+
78
+ attributes = JSON.parse(response.body)
79
+ assert_response :ok
80
+ assert_equal account.id, attributes["accounts"][0]["id"]
81
+ assert_equal "B Co.", attributes["accounts"][0]["name"]
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,71 @@
1
+ require 'standard_api/test_helper'
2
+
3
+ module NestedAttributes
4
+ class HasOneTest < ActionDispatch::IntegrationTest
5
+ # include StandardAPI::TestCase
6
+ include StandardAPI::Helpers
7
+
8
+
9
+ # = Create Test
10
+
11
+ test 'create record and create nested record' do
12
+ @controller = PhotosController.new
13
+
14
+ post photos_path, params: { photo: { camera: {make: 'Sony'}} }, as: :json
15
+
16
+ photo = Photo.last
17
+ assert_equal photo.id, photo.camera.photo_id
18
+ assert_equal 'Sony', photo.camera.make
19
+ end
20
+
21
+ test 'create record and update nested record' do
22
+ camera = create(:camera, make: 'Sony')
23
+
24
+ @controller = PhotosController.new
25
+ post photos_path, params: { photo: { camera: {id: camera.id, make: 'Nokia'} } }, as: :json
26
+
27
+ assert_response :created
28
+ photo = Photo.last
29
+ assert_equal photo.id, photo.camera.photo_id
30
+ assert_equal 'Nokia', photo.camera.make
31
+ end
32
+
33
+ # = Update Test
34
+
35
+ test 'update record and create nested record' do
36
+ photo = create(:photo)
37
+
38
+ @controller = PhotosController.new
39
+ put photo_path(photo), params: { photo: { camera: {make: 'Canon'}} }, as: :json
40
+
41
+ assert_response :ok
42
+ photo.reload
43
+ assert_equal 'Canon', photo.camera.make
44
+ end
45
+
46
+ test 'update record and update nested record' do
47
+ camera = create(:camera, make: 'Leica')
48
+ photo = create(:photo, camera: camera)
49
+
50
+ @controller = PhotosController.new
51
+ put photo_path(photo), params: { photo: { camera: {make: 'Nokia'}} }, as: :json
52
+
53
+ assert_response :ok
54
+ photo.reload
55
+ assert_equal 'Nokia', photo.camera.make
56
+ end
57
+
58
+ test 'update record and set relation to nil' do
59
+ camera = create(:camera, make: 'Leica')
60
+ photo = create(:photo, camera: camera)
61
+
62
+ @controller = PhotosController.new
63
+ put photo_path(photo), params: { photo: { camera: nil} }, as: :json
64
+
65
+ assert_response :ok
66
+ photo.reload
67
+ assert_nil photo.camera
68
+ end
69
+
70
+ end
71
+ end
@@ -30,4 +30,60 @@ class RouteHelpersTest < ActionDispatch::IntegrationTest
30
30
  assert_routing({ path: '/photos/1/properties/1', method: :delete }, { controller: 'photos', action: 'remove_resource', id: '1', relationship: 'properties', resource_id: '1' })
31
31
  end
32
32
 
33
+ test "standard_resources with only option" do
34
+ with_routing do |set|
35
+ set.draw do
36
+ standard_resources :photos, only: [ :index, :show ]
37
+ end
38
+ assert_routing({ path: '/photos', method: :get }, { controller: 'photos', action: 'index' })
39
+ assert_routing({ path: '/photos/1', method: :get }, { controller: 'photos', action: 'show', id: '1' })
40
+ assert_equal 2, set.routes.size
41
+ end
42
+ end
43
+
44
+ test "standard_resources with except option" do
45
+ with_routing do |set|
46
+ set.draw do
47
+ standard_resources :photos, except: [ :destroy ]
48
+ end
49
+ assert_routing({ path: '/photos', method: :get }, { controller: 'photos', action: 'index' })
50
+ assert_routing({ path: '/photos/1', method: :get }, { controller: 'photos', action: 'show', id: '1' })
51
+ assert_routing({ path: '/photos/new', method: :get }, { controller: 'photos', action: 'new' })
52
+ assert_routing({ path: '/photos', method: :post }, { controller: 'photos', action: 'create' })
53
+ assert_routing({ path: '/photos/1', method: :put }, { controller: 'photos', action: 'update', id: '1' })
54
+ assert_routing({ path: '/photos/1', method: :patch }, { controller: 'photos', action: 'update', id: '1' })
55
+ assert_routing({ path: '/photos/schema', method: :get }, { controller: 'photos', action: 'schema' })
56
+ assert_routing({ path: '/photos/calculate', method: :get }, { controller: 'photos', action: 'calculate' })
57
+ assert_routing({ path: '/photos/1/properties/1', method: :post }, { controller: 'photos', action: 'add_resource', id: '1', relationship: 'properties', resource_id: '1' })
58
+ assert_routing({ path: '/photos/1/properties/1', method: :delete }, { controller: 'photos', action: 'remove_resource', id: '1', relationship: 'properties', resource_id: '1' })
59
+ assert_routing({ path: '/photos/1/properties', method: :post }, { controller: 'photos', action: 'create_resource', id: '1', relationship: 'properties' })
60
+ assert_equal 12, set.routes.size
61
+ end
62
+ end
63
+
64
+ test "standard_resource with only option" do
65
+ with_routing do |set|
66
+ set.draw do
67
+ standard_resource :accounts, only: :show
68
+ end
69
+ assert_routing({ path: '/accounts', method: :get }, { controller: 'accounts', action: 'show' })
70
+ assert_equal 1, set.routes.size
71
+ end
72
+ end
73
+
74
+ test "standard_resource with except option" do
75
+ with_routing do |set|
76
+ set.draw do
77
+ standard_resource :accounts, except: [ :destroy ]
78
+ end
79
+ assert_routing({ path: '/accounts', method: :get }, { controller: 'accounts', action: 'show' })
80
+ assert_routing({ path: '/accounts/new', method: :get }, { controller: 'accounts', action: 'new' })
81
+ assert_routing({ path: '/accounts', method: :post }, { controller: 'accounts', action: 'create' })
82
+ assert_routing({ path: '/accounts', method: :put }, { controller: 'accounts', action: 'update' })
83
+ assert_routing({ path: '/accounts', method: :patch }, { controller: 'accounts', action: 'update' })
84
+ assert_routing({ path: '/accounts/schema', method: :get }, { controller: 'accounts', action: 'schema' })
85
+ assert_routing({ path: '/accounts/calculate', method: :get }, { controller: 'accounts', action: 'calculate' })
86
+ assert_equal 10, set.routes.size
87
+ end
88
+ end
33
89
  end
@@ -92,18 +92,33 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
92
92
  assert_equal @controller.send(:model_includes), []
93
93
  end
94
94
 
95
- test 'Controller#model_params defaults to []' do
95
+ test 'Controller#model_params defaults to ActionController::Parameters' do
96
+ @controller = DocumentsController.new
97
+ @controller.params = ActionController::Parameters.new
98
+ assert_equal @controller.send(:model_params), ActionController::Parameters.new
99
+ end
100
+
101
+ test 'Controller#model_params defaults to ActionController::Parameters when no resource_attributes' do
96
102
  @controller = ReferencesController.new
97
- @controller.params = {}
103
+ @controller.params = ActionController::Parameters.new
98
104
  assert_equal @controller.send(:model_params), ActionController::Parameters.new
99
105
  end
100
106
 
101
- test 'Controller#current_mask' do
107
+ test 'Controller#mask' do
102
108
  @controller = ReferencesController.new
103
- @controller.instance_variable_set('@current_mask', { 'references' => { 'subject_id' => 1 }})
109
+ @controller.define_singleton_method(:mask_for) do |table_name|
110
+ {subject_id: 1}
111
+ end
104
112
  @controller.params = {}
105
113
  assert_equal 'SELECT "references".* FROM "references" WHERE "references"."subject_id" = 1', @controller.send(:resources).to_sql
106
114
  end
115
+
116
+ test "Auto includes on a controller without a model" do
117
+ @controller = SessionsController.new
118
+ assert_nil @controller.send(:model)
119
+ post sessions_path(format: :json), params: {session: {user: 'user', pass: 'pass'}}
120
+ assert_response :ok
121
+ end
107
122
 
108
123
  test 'ApplicationController#schema.json' do
109
124
  get schema_path(format: 'json')
@@ -112,7 +127,7 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
112
127
  controllers = ApplicationController.descendants
113
128
  controllers.select! { |c| c.ancestors.include?(StandardAPI::Controller) && c != StandardAPI::Controller }
114
129
 
115
- @controller.send(:models).reject { |x| x.name == 'Photo' }.each do |model|
130
+ @controller.send(:models).reject { |x| %w(Photo Document).include?(x.name) }.each do |model|
116
131
  assert_equal true, schema['models'].has_key?(model.name)
117
132
 
118
133
  model_comment = model.connection.table_comment(model.table_name)
@@ -125,7 +140,7 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
125
140
  model.columns.each do |column|
126
141
  assert_equal json_column_type(column.sql_type), schema.dig('models', model.name, 'attributes', column.name, 'type')
127
142
  default = column.default
128
- if default then
143
+ if default
129
144
  default = model.connection.lookup_cast_type_from_column(column).deserialize(default)
130
145
  assert_equal default, schema.dig('models', model.name, 'attributes', column.name, 'default')
131
146
  else
@@ -134,11 +149,15 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
134
149
  assert_equal column.name == model.primary_key, schema.dig('models', model.name, 'attributes', column.name, 'primary_key')
135
150
  assert_equal column.null, schema.dig('models', model.name, 'attributes', column.name, 'null')
136
151
  assert_equal column.array, schema.dig('models', model.name, 'attributes', column.name, 'array')
137
- if column.comment then
152
+ if column.comment
138
153
  assert_equal column.comment, schema.dig('models', model.name, 'attributes', column.name, 'comment')
139
154
  else
140
155
  assert_nil schema.dig('models', model.name, 'attributes', column.name, 'comment')
141
156
  end
157
+
158
+ if column.respond_to?(:auto_populated?)
159
+ assert_equal !!column.auto_populated?, schema.dig('models', model.name, 'attributes', column.name, 'auto_populated')
160
+ end
142
161
  end
143
162
  end
144
163
 
@@ -163,6 +182,26 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
163
182
  assert_nil schema['limit']
164
183
  end
165
184
 
185
+ test 'Controller#schema.json for an enum with default' do
186
+ get schema_documents_path(format: 'json')
187
+
188
+ schema = JSON(response.body)
189
+
190
+ assert_equal true, schema.has_key?('attributes')
191
+ assert_equal 'string', schema['attributes']['level']['type']
192
+ assert_equal 'public', schema['attributes']['level']['default']
193
+ end
194
+
195
+ test 'Controller#schema.json for an enum without default' do
196
+ get schema_documents_path(format: 'json')
197
+
198
+ schema = JSON(response.body)
199
+
200
+ assert_equal true, schema.has_key?('attributes')
201
+ assert_equal 'string', schema['attributes']['rating']['type']
202
+ assert_nil schema['attributes']['rating']['default']
203
+ end
204
+
166
205
  test 'Controller#index w/o limit' do
167
206
  account = create(:account)
168
207
  get unlimited_index_path(format: 'json')
@@ -188,47 +227,6 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
188
227
  assert_redirected_to document_path(pdf)
189
228
  end
190
229
 
191
- test 'Controller#add_resource' do
192
- property = create(:property, photos: [])
193
- photo = create(:photo)
194
-
195
- post "/properties/#{property.id}/photos/#{photo.id}"
196
- assert_equal property.photos.reload.map(&:id), [photo.id]
197
- assert_response :created
198
-
199
- post "/properties/#{property.id}/photos/9999999"
200
- assert_response :not_found
201
- end
202
-
203
- test 'Controller#add_resource with has_one' do
204
- photo = create(:document)
205
- property = create(:property)
206
- post "/properties/#{property.id}/document/#{photo.id}"
207
- assert_equal property.reload.document, photo
208
- assert_response :created
209
- end
210
-
211
- test 'Controller#remove_resource' do
212
- photo = create(:photo)
213
- property = create(:property, photos: [photo])
214
- assert_equal property.photos.reload, [photo]
215
- delete "/properties/#{property.id}/photos/#{photo.id}"
216
- assert_equal property.photos.reload, []
217
- assert_response :no_content
218
-
219
- delete "/properties/#{property.id}/photos/9999999"
220
- assert_response :not_found
221
- end
222
-
223
- test 'Controller#remove_resource with has_one' do
224
- photo = create(:document)
225
- property = create(:property, document: photo)
226
- assert_equal property.document, photo
227
- delete "/properties/#{property.id}/document/#{photo.id}"
228
- assert_nil property.reload.document
229
- assert_response :no_content
230
- end
231
-
232
230
  # = View Tests
233
231
 
234
232
  test 'rendering tables' do
@@ -236,7 +234,7 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
236
234
  assert_response :ok
237
235
  # assert_equal ['properties', 'accounts', 'photos', 'references', 'sessions', 'unlimited'], response.parsed_body
238
236
  # Multiple 'accounts' because multiple controllers with that model for testing.
239
- assert_equal ["properties", "accounts", "documents", "photos", "references", "accounts", 'accounts'].sort, response.parsed_body.sort
237
+ assert_equal ["properties", "accounts", "documents", "photos", "references", "accounts", 'accounts', 'uuid_models'].sort, response.parsed_body.sort
240
238
  end
241
239
 
242
240
  test 'rendering null attribute' do
@@ -246,13 +244,45 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
246
244
  assert_nil JSON(response.body)['landlord']
247
245
  end
248
246
 
247
+ test 'rendering binary attribute' do
248
+ reference = create(:reference, sha: "Hello World")
249
+ get reference_path(reference, format: 'json'), params: { id: reference.id }
250
+ assert_equal "48656c6c6f20576f726c64", JSON(response.body)['sha']
251
+ end
252
+
253
+ test 'rendering a custom binary attribute' do
254
+ reference = create(:reference, custom_binary: 2)
255
+ get reference_path(reference, format: 'json'), params: { id: reference.id }
256
+ assert_equal 2, JSON(response.body)['custom_binary']
257
+ assert_equal "\\x00000002".b,reference.custom_binary_before_type_cast
258
+ end
259
+
249
260
  test 'rendering null attribute for has_one through' do
250
261
  property = create(:property)
251
262
  get property_path(property, format: 'json'), params: { id: property.id, include: [:document] }
252
263
  assert JSON(response.body).has_key?('document')
253
264
  assert_nil JSON(response.body)['document']
254
265
  end
266
+
267
+ test 'rendering serialize_attribute' do
268
+ property = create(:property, description: 'This text will magically change')
269
+ get property_path(property, format: 'json'), params: { id: property.id, magic: true }
255
270
 
271
+ body = JSON(response.body)
272
+ assert_equal body['description'], 'See it changed!'
273
+ end
274
+
275
+ test 'rendering an enum' do
276
+ public_document = create(:document, level: 'public')
277
+
278
+ get documents_path(format: 'json'), params: { limit: 1 }
279
+ assert_equal JSON(response.body)[0]['level'], 'public'
280
+
281
+ secret_document = create(:document, level: 'secret')
282
+ get document_path(secret_document, format: 'json')
283
+ assert_equal JSON(response.body)['level'], 'secret'
284
+ end
285
+
256
286
  test '#index.json uses overridden partial' do
257
287
  create(:property, photos: [create(:photo)])
258
288
  get properties_path(format: 'json'), params: { limit: 100, include: [{:photos => { order: :id }}] }
@@ -444,7 +474,7 @@ class PropertiesControllerTest < ActionDispatch::IntegrationTest
444
474
  },
445
475
  format: 'json')
446
476
 
447
- assert_equal [photos.first.id], JSON(response.body)['photos'].map { |x| x['id'] }
477
+ assert_equal [photos.map(&:id).sort.first], JSON(response.body)['photos'].map { |x| x['id'] }
448
478
 
449
479
  get property_path(property,
450
480
  include: {
@@ -0,0 +1,7 @@
1
+ module CameraACL
2
+
3
+ def attributes
4
+ [ :make ]
5
+ end
6
+
7
+ end
@@ -0,0 +1,13 @@
1
+ module PhotoACL
2
+
3
+ def attributes
4
+ [
5
+ :format
6
+ ]
7
+ end
8
+
9
+ def nested
10
+ [ :account, :camera ]
11
+ end
12
+
13
+ end
@@ -1,5 +1,6 @@
1
1
  module PropertyACL
2
2
 
3
+ # Attributes allowed to be updated
3
4
  def attributes
4
5
  [ :name,
5
6
  :aliases,
@@ -12,16 +13,21 @@ module PropertyACL
12
13
  ]
13
14
  end
14
15
 
16
+ # Orderings allowed
15
17
  def orders
16
18
  ["id", "name", "aliases", "description", "constructed", "size", "created_at", "active"]
17
19
  end
18
20
 
21
+ # Sub resources allowed to be included in the response
19
22
  def includes
20
23
  [ :photos, :landlord, :english_name, :document ]
21
24
  end
22
25
 
26
+ # Sub resourced allowed to be set during create / update / delete if a user is
27
+ # allowed to ....
28
+ # only add to and from the relation, can also create or update the subresource
23
29
  def nested
24
- [ :photos ]
30
+ [ :photos, :accounts ]
25
31
  end
26
32
 
27
33
  end
@@ -2,6 +2,18 @@ class ApplicationController < ActionController::Base
2
2
  include StandardAPI::Controller
3
3
  include StandardAPI::AccessControlList
4
4
  prepend_view_path File.join(File.dirname(__FILE__), 'views')
5
+
6
+ helper_method :serialize_attribute
7
+
8
+ def serialize_attribute(json, record, attribute, type)
9
+ value = if attribute == 'description' && params["magic"] === "true"
10
+ 'See it changed!'
11
+ else
12
+ record.send(attribute)
13
+ end
14
+
15
+ json.set! attribute, type == :binary ? value&.unpack1('H*') : value
16
+ end
5
17
 
6
18
  end
7
19
 
@@ -48,6 +60,8 @@ class ReferencesController < ApplicationController
48
60
  end
49
61
 
50
62
  class SessionsController < ApplicationController
63
+ def create
64
+ end
51
65
  end
52
66
 
53
67
  class UnlimitedController < ApplicationController
@@ -73,3 +87,6 @@ class DefaultLimitController < ApplicationController
73
87
  end
74
88
 
75
89
  end
90
+
91
+ class UuidModelController < ApplicationController
92
+ end