jsonapi-resources 0.4.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -18,6 +18,11 @@ ActiveRecord::Schema.define do
18
18
  t.timestamps null: false
19
19
  end
20
20
 
21
+ create_table :author_details, force: true do |t|
22
+ t.integer :person_id
23
+ t.string :author_stuff
24
+ end
25
+
21
26
  create_table :posts, force: true do |t|
22
27
  t.string :title
23
28
  t.text :body
@@ -190,6 +195,11 @@ ActiveRecord::Schema.define do
190
195
 
191
196
  create_table :vehicles, force: true do |t|
192
197
  t.string :type
198
+ t.string :make
199
+ t.string :vehicle_model
200
+ t.string :length_at_water_line
201
+ t.string :drive_layout
202
+ t.string :serial_number
193
203
  t.integer :person_id
194
204
  end
195
205
  end
@@ -202,12 +212,17 @@ class Person < ActiveRecord::Base
202
212
  has_many :vehicles
203
213
  belongs_to :preferences
204
214
  belongs_to :hair_cut
215
+ has_one :author_detail
205
216
 
206
217
  ### Validations
207
218
  validates :name, presence: true
208
219
  validates :date_joined, presence: true
209
220
  end
210
221
 
222
+ class AuthorDetail < ActiveRecord::Base
223
+ belongs_to :author, class_name: 'Person', foreign_key: 'person_id'
224
+ end
225
+
211
226
  class Post < ActiveRecord::Base
212
227
  belongs_to :author, class_name: 'Person', foreign_key: 'author_id'
213
228
  belongs_to :writer, class_name: 'Person', foreign_key: 'author_id'
@@ -634,12 +649,15 @@ end
634
649
 
635
650
  class VehicleResource < JSONAPI::Resource
636
651
  has_one :person
652
+ attributes :make, :vehicle_model, :serial_number
637
653
  end
638
654
 
639
655
  class CarResource < VehicleResource
656
+ attributes :drive_layout
640
657
  end
641
658
 
642
659
  class BoatResource < VehicleResource
660
+ attributes :length_at_water_line
643
661
  end
644
662
 
645
663
  class CommentResource < JSONAPI::Resource
@@ -655,7 +673,7 @@ class TagResource < JSONAPI::Resource
655
673
  attributes :name
656
674
 
657
675
  has_many :posts
658
- # Not including the planets association so they don't get output
676
+ # Not including the planets relationship so they don't get output
659
677
  #has_many :planets
660
678
  end
661
679
 
@@ -673,6 +691,9 @@ class PostResource < JSONAPI::Resource
673
691
  has_many :tags, acts_as_set: true
674
692
  has_many :comments, acts_as_set: false
675
693
 
694
+ # Not needed - just for testing
695
+ primary_key :id
696
+
676
697
  before_save do
677
698
  msg = "Before save"
678
699
  end
@@ -763,7 +784,6 @@ class HairCutResource < JSONAPI::Resource
763
784
  end
764
785
 
765
786
  class IsoCurrencyResource < JSONAPI::Resource
766
- primary_key :code
767
787
  attributes :name, :country_name, :minor_unit
768
788
 
769
789
  filter :country_name
@@ -881,7 +901,7 @@ end
881
901
 
882
902
  class ProductResource < JSONAPI::Resource
883
903
  attribute :name
884
- has_one :picture
904
+ has_one :picture, always_include_linkage_data: true
885
905
 
886
906
  def picture_id
887
907
  model.picture.id
@@ -1080,7 +1100,8 @@ module Api
1080
1100
  class AuthorResource < JSONAPI::Resource
1081
1101
  attributes :name, :email
1082
1102
  model_name 'Person'
1083
- has_many :posts
1103
+ relationship :posts, to: :many
1104
+ relationship :author_detail, to: :one, foreign_key_on: :related
1084
1105
 
1085
1106
  filter :name
1086
1107
 
@@ -1100,6 +1121,10 @@ module Api
1100
1121
  end
1101
1122
  end
1102
1123
 
1124
+ class AuthorDetailResource < JSONAPI::Resource
1125
+ attributes :author_stuff
1126
+ end
1127
+
1103
1128
  PersonResource = PersonResource.dup
1104
1129
  PostResource = PostResource.dup
1105
1130
  ExpenseEntryResource = ExpenseEntryResource.dup
@@ -1164,11 +1189,19 @@ module Api
1164
1189
  end
1165
1190
  end
1166
1191
 
1192
+ module MyEngine
1193
+ module Api
1194
+ module V1
1195
+ class PersonResource < JSONAPI::Resource
1196
+ end
1197
+ end
1198
+ end
1199
+ end
1200
+
1167
1201
  warn 'start testing Name Collisions'
1168
1202
  # The name collisions only emmit warnings. Exceptions would change the flow of the tests
1169
1203
 
1170
1204
  class LinksResource < JSONAPI::Resource
1171
-
1172
1205
  end
1173
1206
 
1174
1207
  class BadlyNamedAttributesResource < JSONAPI::Resource
@@ -0,0 +1,9 @@
1
+ a:
2
+ id: 1
3
+ person_id: 1
4
+ author_stuff: blah blah
5
+
6
+ b:
7
+ id: 2
8
+ person_id: 2
9
+ author_stuff: blah blah blah
@@ -1,8 +1,16 @@
1
- car:
1
+ Miata:
2
2
  id: 1
3
3
  type: Car
4
+ make: Mazda
5
+ vehicle_model: Miata MX5
6
+ drive_layout: Front Engine RWD
7
+ serial_number: 32432adfsfdysua
4
8
  person_id: 1
5
- boat:
9
+ Launch20:
6
10
  id: 2
7
11
  type: Boat
12
+ make: Chris-Craft
13
+ vehicle_model: Launch 20
14
+ length_at_water_line: 15.5ft
15
+ serial_number: 434253JJJSD
8
16
  person_id: 1
@@ -22,18 +22,18 @@ class RequestTest < ActionDispatch::IntegrationTest
22
22
  assert_equal 200, status
23
23
  end
24
24
 
25
- def test_get_nested_has_one
25
+ def test_get_nested_to_one
26
26
  get '/posts/1/author'
27
27
  assert_equal 200, status
28
28
  end
29
29
 
30
- def test_get_nested_has_many
30
+ def test_get_nested_to_many
31
31
  get '/posts/1/comments'
32
32
  assert_equal 200, status
33
33
  end
34
34
 
35
- def test_get_nested_has_many_bad_param
36
- get '/posts/1/comments?association=books'
35
+ def test_get_nested_to_many_bad_param
36
+ get '/posts/1/comments?relationship=books'
37
37
  assert_equal 200, status
38
38
  end
39
39
 
@@ -204,28 +204,28 @@ class RequestTest < ActionDispatch::IntegrationTest
204
204
  assert_equal 422, status
205
205
  end
206
206
 
207
- def test_update_association_without_content_type
207
+ def test_update_relationship_without_content_type
208
208
  ruby = Section.find_by(name: 'ruby')
209
209
  patch '/posts/3/relationships/section', { 'data' => {type: 'sections', id: ruby.id.to_s }}.to_json
210
210
 
211
211
  assert_equal 415, status
212
212
  end
213
213
 
214
- def test_patch_update_association_has_one
214
+ def test_patch_update_relationship_to_one
215
215
  ruby = Section.find_by(name: 'ruby')
216
216
  patch '/posts/3/relationships/section', { 'data' => {type: 'sections', id: ruby.id.to_s }}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
217
217
 
218
218
  assert_equal 204, status
219
219
  end
220
220
 
221
- def test_put_update_association_has_one
221
+ def test_put_update_relationship_to_one
222
222
  ruby = Section.find_by(name: 'ruby')
223
223
  put '/posts/3/relationships/section', { 'data' => {type: 'sections', id: ruby.id.to_s }}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
224
224
 
225
225
  assert_equal 204, status
226
226
  end
227
227
 
228
- def test_patch_update_association_has_many_acts_as_set
228
+ def test_patch_update_relationship_to_many_acts_as_set
229
229
  # Comments are acts_as_set=false so PUT/PATCH should respond with 403
230
230
 
231
231
  rogue = Comment.find_by(body: 'Rogue Comment Here')
@@ -234,14 +234,14 @@ class RequestTest < ActionDispatch::IntegrationTest
234
234
  assert_equal 403, status
235
235
  end
236
236
 
237
- def test_post_update_association_has_many
237
+ def test_post_update_relationship_to_many
238
238
  rogue = Comment.find_by(body: 'Rogue Comment Here')
239
239
  post '/posts/5/relationships/comments', { 'data' => [{type: 'comments', id: rogue.id.to_s }]}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
240
240
 
241
241
  assert_equal 204, status
242
242
  end
243
243
 
244
- def test_put_update_association_has_many_acts_as_set
244
+ def test_put_update_relationship_to_many_acts_as_set
245
245
  # Comments are acts_as_set=false so PUT/PATCH should respond with 403. Note: JR currently treats PUT and PATCH as equivalent
246
246
 
247
247
  rogue = Comment.find_by(body: 'Rogue Comment Here')
@@ -418,7 +418,7 @@ class RequestTest < ActionDispatch::IntegrationTest
418
418
  assert_hash_equals post_1, json_response['data']
419
419
  end
420
420
 
421
- def test_flow_link_has_one_self_link
421
+ def test_flow_link_to_one_self_link
422
422
  get '/posts'
423
423
  assert_equal 200, status
424
424
  post_1 = json_response['data'][0]
@@ -434,7 +434,7 @@ class RequestTest < ActionDispatch::IntegrationTest
434
434
  })
435
435
  end
436
436
 
437
- def test_flow_link_has_many_self_link
437
+ def test_flow_link_to_many_self_link
438
438
  get '/posts'
439
439
  assert_equal 200, status
440
440
  post_1 = json_response['data'][0]
@@ -455,7 +455,7 @@ class RequestTest < ActionDispatch::IntegrationTest
455
455
  })
456
456
  end
457
457
 
458
- def test_flow_link_has_many_self_link_put
458
+ def test_flow_link_to_many_self_link_put
459
459
  get '/posts'
460
460
  assert_equal 200, status
461
461
  post_1 = json_response['data'][4]
@@ -624,7 +624,7 @@ class RequestTest < ActionDispatch::IntegrationTest
624
624
  assert_equal 200, status
625
625
  end
626
626
 
627
- def test_patch_formatted_dasherized_replace_has_many
627
+ def test_patch_formatted_dasherized_replace_to_many
628
628
  JSONAPI.configuration.route_format = :dasherized_route
629
629
  JSONAPI.configuration.json_key_format = :dasherized_key
630
630
  patch '/api/v6/purchase-orders/2?include=line-items,order-flags',
@@ -652,7 +652,7 @@ class RequestTest < ActionDispatch::IntegrationTest
652
652
  assert_equal 200, status
653
653
  end
654
654
 
655
- def test_post_has_many_link
655
+ def test_post_to_many_link
656
656
  JSONAPI.configuration.route_format = :dasherized_route
657
657
  JSONAPI.configuration.json_key_format = :dasherized_key
658
658
  post '/api/v6/purchase-orders/3/relationships/line-items',
@@ -666,7 +666,7 @@ class RequestTest < ActionDispatch::IntegrationTest
666
666
  assert_equal 204, status
667
667
  end
668
668
 
669
- def test_patch_has_many_link
669
+ def test_patch_to_many_link
670
670
  JSONAPI.configuration.route_format = :dasherized_route
671
671
  JSONAPI.configuration.json_key_format = :dasherized_key
672
672
  patch '/api/v6/purchase-orders/3/relationships/order-flags',
@@ -680,7 +680,7 @@ class RequestTest < ActionDispatch::IntegrationTest
680
680
  assert_equal 204, status
681
681
  end
682
682
 
683
- def test_patch_has_one
683
+ def test_patch_to_one
684
684
  JSONAPI.configuration.route_format = :dasherized_route
685
685
  JSONAPI.configuration.json_key_format = :dasherized_key
686
686
  patch '/api/v6/line-items/5/relationships/purchase-order',
@@ -19,37 +19,37 @@ class RoutesTest < ActionDispatch::IntegrationTest
19
19
 
20
20
  def test_routing_posts_links_author_show
21
21
  assert_routing({path: '/posts/1/relationships/author', method: :get},
22
- {controller: 'posts', action: 'show_association', post_id: '1', association: 'author'})
22
+ {controller: 'posts', action: 'show_relationship', post_id: '1', relationship: 'author'})
23
23
  end
24
24
 
25
25
  def test_routing_posts_links_author_destroy
26
26
  assert_routing({path: '/posts/1/relationships/author', method: :delete},
27
- {controller: 'posts', action: 'destroy_association', post_id: '1', association: 'author'})
27
+ {controller: 'posts', action: 'destroy_relationship', post_id: '1', relationship: 'author'})
28
28
  end
29
29
 
30
30
  def test_routing_posts_links_author_update
31
31
  assert_routing({path: '/posts/1/relationships/author', method: :patch},
32
- {controller: 'posts', action: 'update_association', post_id: '1', association: 'author'})
32
+ {controller: 'posts', action: 'update_relationship', post_id: '1', relationship: 'author'})
33
33
  end
34
34
 
35
35
  def test_routing_posts_links_tags_show
36
36
  assert_routing({path: '/posts/1/relationships/tags', method: :get},
37
- {controller: 'posts', action: 'show_association', post_id: '1', association: 'tags'})
37
+ {controller: 'posts', action: 'show_relationship', post_id: '1', relationship: 'tags'})
38
38
  end
39
39
 
40
40
  def test_routing_posts_links_tags_destroy
41
41
  assert_routing({path: '/posts/1/relationships/tags/1,2', method: :delete},
42
- {controller: 'posts', action: 'destroy_association', post_id: '1', keys: '1,2', association: 'tags'})
42
+ {controller: 'posts', action: 'destroy_relationship', post_id: '1', keys: '1,2', relationship: 'tags'})
43
43
  end
44
44
 
45
45
  def test_routing_posts_links_tags_create
46
46
  assert_routing({path: '/posts/1/relationships/tags', method: :post},
47
- {controller: 'posts', action: 'create_association', post_id: '1', association: 'tags'})
47
+ {controller: 'posts', action: 'create_relationship', post_id: '1', relationship: 'tags'})
48
48
  end
49
49
 
50
50
  def test_routing_posts_links_tags_update_acts_as_set
51
51
  assert_routing({path: '/posts/1/relationships/tags', method: :patch},
52
- {controller: 'posts', action: 'update_association', post_id: '1', association: 'tags'})
52
+ {controller: 'posts', action: 'update_relationship', post_id: '1', relationship: 'tags'})
53
53
  end
54
54
 
55
55
  # Polymorphic
@@ -60,7 +60,7 @@ class RoutesTest < ActionDispatch::IntegrationTest
60
60
  method: :get
61
61
  },
62
62
  {
63
- association: 'imageable',
63
+ relationship: 'imageable',
64
64
  source: 'pictures',
65
65
  controller: 'imageables',
66
66
  action: 'get_related_resource',
@@ -76,9 +76,9 @@ class RoutesTest < ActionDispatch::IntegrationTest
76
76
  method: :patch
77
77
  },
78
78
  {
79
- association: 'imageable',
79
+ relationship: 'imageable',
80
80
  controller: 'pictures',
81
- action: 'update_association',
81
+ action: 'update_relationship',
82
82
  picture_id: '1'
83
83
  }
84
84
  )
@@ -91,9 +91,9 @@ class RoutesTest < ActionDispatch::IntegrationTest
91
91
  method: :delete
92
92
  },
93
93
  {
94
- association: 'imageable',
94
+ relationship: 'imageable',
95
95
  controller: 'pictures',
96
- action: 'destroy_association',
96
+ action: 'destroy_relationship',
97
97
  picture_id: '1'
98
98
  }
99
99
  )
@@ -112,13 +112,13 @@ class RoutesTest < ActionDispatch::IntegrationTest
112
112
 
113
113
  def test_routing_v1_posts_links_writer_show
114
114
  assert_routing({path: '/api/v1/posts/1/relationships/writer', method: :get},
115
- {controller: 'api/v1/posts', action: 'show_association', post_id: '1', association: 'writer'})
115
+ {controller: 'api/v1/posts', action: 'show_relationship', post_id: '1', relationship: 'writer'})
116
116
  end
117
117
 
118
118
  # V2
119
119
  def test_routing_v2_posts_links_author_show
120
120
  assert_routing({path: '/api/v2/posts/1/relationships/author', method: :get},
121
- {controller: 'api/v2/posts', action: 'show_association', post_id: '1', association: 'author'})
121
+ {controller: 'api/v2/posts', action: 'show_relationship', post_id: '1', relationship: 'author'})
122
122
  end
123
123
 
124
124
  def test_routing_v2_preferences_show
@@ -148,7 +148,7 @@ class RoutesTest < ActionDispatch::IntegrationTest
148
148
  {action: 'show', controller: 'api/v4/expense_entries', id: '1'})
149
149
 
150
150
  assert_routing({path: '/api/v4/expenseEntries/1/relationships/isoCurrency', method: :get},
151
- {controller: 'api/v4/expense_entries', action: 'show_association', expense_entry_id: '1', association: 'iso_currency'})
151
+ {controller: 'api/v4/expense_entries', action: 'show_relationship', expense_entry_id: '1', relationship: 'iso_currency'})
152
152
  end
153
153
 
154
154
  # V5 dasherized
@@ -167,7 +167,7 @@ class RoutesTest < ActionDispatch::IntegrationTest
167
167
  {action: 'show', controller: 'api/v5/expense_entries', id: '1'})
168
168
 
169
169
  assert_routing({path: '/api/v5/expense-entries/1/relationships/iso-currency', method: :get},
170
- {controller: 'api/v5/expense_entries', action: 'show_association', expense_entry_id: '1', association: 'iso_currency'})
170
+ {controller: 'api/v5/expense_entries', action: 'show_relationship', expense_entry_id: '1', relationship: 'iso_currency'})
171
171
  end
172
172
 
173
173
  def test_routing_authors_show
@@ -177,7 +177,7 @@ class RoutesTest < ActionDispatch::IntegrationTest
177
177
 
178
178
  def test_routing_author_links_posts_create_not_acts_as_set
179
179
  assert_routing({path: '/api/v5/authors/1/relationships/posts', method: :post},
180
- {controller: 'api/v5/authors', action: 'create_association', author_id: '1', association: 'posts'})
180
+ {controller: 'api/v5/authors', action: 'create_relationship', author_id: '1', relationship: 'posts'})
181
181
  end
182
182
 
183
183
  #primary_key
@@ -194,14 +194,14 @@ class RoutesTest < ActionDispatch::IntegrationTest
194
194
 
195
195
  # def test_routing_posts_links_author_except_destroy
196
196
  # assert_routing({ path: '/api/v3/posts/1/relationships/author', method: :delete },
197
- # { controller: 'api/v3/posts', action: 'destroy_association', post_id: '1', association: 'author' })
197
+ # { controller: 'api/v3/posts', action: 'destroy_relationship', post_id: '1', relationship: 'author' })
198
198
  # end
199
199
  #
200
200
  # def test_routing_posts_links_tags_only_create_show
201
201
  # assert_routing({ path: '/api/v3/posts/1/relationships/tags/1,2', method: :delete },
202
- # { controller: 'api/v3/posts', action: 'destroy_association', post_id: '1', keys: '1,2', association: 'tags' })
202
+ # { controller: 'api/v3/posts', action: 'destroy_relationship', post_id: '1', keys: '1,2', relationship: 'tags' })
203
203
  # end
204
204
 
205
- # Test that non acts as set has_many association update route is not created
205
+ # Test that non acts as set to_many relationship update route is not created
206
206
 
207
207
  end
data/test/test_helper.rb CHANGED
@@ -14,6 +14,7 @@ require 'rails/all'
14
14
  require 'rails/test_help'
15
15
  require 'minitest/mock'
16
16
  require 'jsonapi-resources'
17
+ require 'pry'
17
18
 
18
19
  require File.expand_path('../helpers/value_matchers', __FILE__)
19
20
  require File.expand_path('../helpers/assertions', __FILE__)
@@ -43,6 +44,12 @@ class TestApp < Rails::Application
43
44
  ActiveSupport::JSON::Encoding.time_precision = 0 if Rails::VERSION::MAJOR >= 4 && Rails::VERSION::MINOR >= 1
44
45
  end
45
46
 
47
+ module MyEngine
48
+ class Engine < ::Rails::Engine
49
+ isolate_namespace MyEngine
50
+ end
51
+ end
52
+
46
53
  # Patch RAILS 4.0 to not use millisecond precision
47
54
  if Rails::VERSION::MAJOR >= 4 && Rails::VERSION::MINOR < 1
48
55
  module ActiveSupport
@@ -141,7 +148,7 @@ TestApp.routes.draw do
141
148
 
142
149
  namespace :v3 do
143
150
  jsonapi_resource :preferences do
144
- # Intentionally empty block to skip association urls
151
+ # Intentionally empty block to skip relationship urls
145
152
  end
146
153
 
147
154
  jsonapi_resources :posts, except: [:destroy] do
@@ -198,6 +205,16 @@ TestApp.routes.draw do
198
205
  jsonapi_resources :numeros_telefone
199
206
  end
200
207
  end
208
+
209
+ mount MyEngine::Engine => "/boomshaka", as: :my_engine
210
+ end
211
+
212
+ MyEngine::Engine.routes.draw do
213
+ namespace :api do
214
+ namespace :v1 do
215
+ jsonapi_resources :people
216
+ end
217
+ end
201
218
  end
202
219
 
203
220
  # Ensure backward compatibility with Minitest 4