standardapi 6.1.0 → 7.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) 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 +22 -22
  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 +17 -6
  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 +110 -50
  30. data/test/standard_api/test_app/app/controllers/acl/account_acl.rb +5 -1
  31. data/test/standard_api/test_app/app/controllers/acl/camera_acl.rb +7 -0
  32. data/test/standard_api/test_app/app/controllers/acl/photo_acl.rb +13 -0
  33. data/test/standard_api/test_app/app/controllers/acl/property_acl.rb +7 -1
  34. data/test/standard_api/test_app/controllers.rb +17 -0
  35. data/test/standard_api/test_app/models.rb +59 -2
  36. data/test/standard_api/test_app/test/factories.rb +3 -0
  37. data/test/standard_api/test_app/views/sessions/create.json.jbuilder +1 -0
  38. data/test/standard_api/test_app/views/sessions/create.streamer +3 -0
  39. data/test/standard_api/test_app.rb +13 -1
  40. data/test/standard_api/test_helper.rb +100 -7
  41. metadata +52 -13
@@ -80,7 +80,7 @@ class HelpersTest < ActionView::TestCase
80
80
  account.expects(:photos_cached_at).returns(t1)
81
81
 
82
82
  assert_equal(
83
- "accounts/#{account.id}/photos-#{t1.utc.to_s(ActiveRecord::Base.cache_timestamp_format)}",
83
+ "accounts/#{account.id}/photos-#{t1.utc.to_fs(ActiveRecord::Base.cache_timestamp_format)}",
84
84
  association_cache_key(account, :photos, {})
85
85
  )
86
86
 
@@ -88,7 +88,7 @@ class HelpersTest < ActionView::TestCase
88
88
  account.expects(:photos_cached_at).returns(t1)
89
89
  account.expects(:photos_property_cached_at).returns(t2)
90
90
  assert_equal(
91
- "accounts/#{account.id}/photos-2ea683a694a33359514c41435f8f0646-#{t2.utc.to_s(ActiveRecord::Base.cache_timestamp_format)}",
91
+ "accounts/#{account.id}/photos-2ea683a694a33359514c41435f8f0646-#{t2.utc.to_fs(ActiveRecord::Base.cache_timestamp_format)}",
92
92
  association_cache_key(account, :photos, {property: {}})
93
93
  )
94
94
 
@@ -96,7 +96,7 @@ class HelpersTest < ActionView::TestCase
96
96
  account.expects(:photos_cached_at).returns(t1)
97
97
  account.expects(:photos_property_cached_at).returns(t2)
98
98
  assert_equal(
99
- "accounts/#{account.id}/photos-779c17ef027655fd8c06c3083d2df64b-#{t2.utc.to_s(ActiveRecord::Base.cache_timestamp_format)}",
99
+ "accounts/#{account.id}/photos-779c17ef027655fd8c06c3083d2df64b-#{t2.utc.to_fs(ActiveRecord::Base.cache_timestamp_format)}",
100
100
  association_cache_key(account, :photos, { "property" => { "order" => { "x" => "desc" }}})
101
101
  )
102
102
 
@@ -105,7 +105,7 @@ class HelpersTest < ActionView::TestCase
105
105
  account.expects(:photos_property_cached_at).returns(t2)
106
106
  account.expects(:photos_agents_cached_at).returns(t3)
107
107
  assert_equal(
108
- "accounts/#{account.id}/photos-abbee2d4535400c162c8dbf14bbef6d5-#{t3.utc.to_s(ActiveRecord::Base.cache_timestamp_format)}",
108
+ "accounts/#{account.id}/photos-abbee2d4535400c162c8dbf14bbef6d5-#{t3.utc.to_fs(ActiveRecord::Base.cache_timestamp_format)}",
109
109
  association_cache_key(account, :photos, {property: {}, agents: {}})
110
110
  )
111
111
 
@@ -114,7 +114,7 @@ class HelpersTest < ActionView::TestCase
114
114
  account.expects(:photos_property_cached_at).returns(t2)
115
115
  account.expects(:photos_property_agents_cached_at).returns(t3)
116
116
  assert_equal(
117
- "accounts/#{account.id}/photos-0962ae73347c5c605d329eaa25e2be49-#{t3.utc.to_s(ActiveRecord::Base.cache_timestamp_format)}",
117
+ "accounts/#{account.id}/photos-0962ae73347c5c605d329eaa25e2be49-#{t3.utc.to_fs(ActiveRecord::Base.cache_timestamp_format)}",
118
118
  association_cache_key(account, :photos, {property: {agents: {}}})
119
119
  )
120
120
 
@@ -124,7 +124,7 @@ class HelpersTest < ActionView::TestCase
124
124
  account.expects(:photos_agents_cached_at).returns(t2)
125
125
  account.expects(:photos_property_addresses_cached_at).returns(t3)
126
126
  assert_equal(
127
- "accounts/#{account.id}/photos-00ea6afe3ff68037f8b4dcdb275e2a24-#{t3.utc.to_s(ActiveRecord::Base.cache_timestamp_format)}",
127
+ "accounts/#{account.id}/photos-00ea6afe3ff68037f8b4dcdb275e2a24-#{t3.utc.to_fs(ActiveRecord::Base.cache_timestamp_format)}",
128
128
  association_cache_key(account, :photos, {property: {addresses: {}}, agents: {}})
129
129
  )
130
130
 
@@ -132,7 +132,7 @@ class HelpersTest < ActionView::TestCase
132
132
  Photo.expects(:column_names).returns(['id', 'cached_at', 'account_cached_at'])
133
133
  photo.expects(:account_cached_at).returns(t1)
134
134
  assert_equal(
135
- "accounts/#{account.id}-#{t1.utc.to_s(ActiveRecord::Base.cache_timestamp_format)}",
135
+ "accounts/#{account.id}-#{t1.utc.to_fs(ActiveRecord::Base.cache_timestamp_format)}",
136
136
  association_cache_key(photo, :account, {})
137
137
  )
138
138
 
@@ -140,7 +140,7 @@ class HelpersTest < ActionView::TestCase
140
140
  photo.expects(:account_cached_at).returns(t1)
141
141
  photo.expects(:account_photos_cached_at).returns(t2)
142
142
  assert_equal(
143
- "accounts/#{account.id}/07437ce3863467f4cd715ae1ef930f08-#{t2.utc.to_s(ActiveRecord::Base.cache_timestamp_format)}",
143
+ "accounts/#{account.id}/07437ce3863467f4cd715ae1ef930f08-#{t2.utc.to_fs(ActiveRecord::Base.cache_timestamp_format)}",
144
144
  association_cache_key(photo, :account, {photos: {}})
145
145
  )
146
146
  end
@@ -150,6 +150,7 @@ class HelpersTest < ActionView::TestCase
150
150
  assert_equal 'string', json_column_type('character varying(2)')
151
151
  assert_equal 'string', json_column_type('character varying(255)')
152
152
  assert_equal 'datetime', json_column_type('timestamp without time zone')
153
+ assert_equal 'datetime', json_column_type('timestamp(6) without time zone')
153
154
  assert_equal 'datetime', json_column_type('time without time zone')
154
155
  assert_equal 'string', json_column_type('text')
155
156
  assert_equal 'hash', json_column_type('json')
@@ -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