jsonapi-resources 0.4.4 → 0.5.0

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