@@ -216,7 +216,7 @@ def test_post_single
216216 assert_jsonapi_response 201
217217 end
218218
219- def test_post_polymorphic
219+ def test_post_polymorphic_with_has_many_relationship
220220 post '/people' , params :
221221 {
222222 'data' => {
@@ -227,7 +227,14 @@ def test_post_polymorphic
227227 'date_joined' => 'Thu, 01 Jan 2019 00:00:00 UTC +00:00' ,
228228 } ,
229229 'relationships' => {
230- 'vehicles' => { 'data' => [ { 'type' => 'car' , 'id' => '1' } ] } ,
230+ 'vehicles' => {
231+ 'data' => [
232+ { 'type' => 'car' , 'id' => '1' } ,
233+ { 'type' => 'boat' , 'id' => '2' } ,
234+ { 'type' => 'car' , 'id' => '3' } ,
235+ { 'type' => 'car' , 'id' => '4' }
236+ ]
237+ }
231238 }
232239 }
233240 } . to_json ,
@@ -237,9 +244,19 @@ def test_post_polymorphic
237244 }
238245
239246 assert_jsonapi_response 201
247+
248+ body = JSON . parse ( response . body )
249+ person = Person . find ( body . dig ( "data" , "id" ) )
250+
251+ assert_equal "Reo" , person . name
252+ assert_equal 4 , person . vehicles . count
253+ assert_equal Car , person . vehicles . first . class
254+ assert_equal Boat , person . vehicles . second . class
255+ assert_equal Car , person . vehicles . third . class
256+ assert_equal Car , person . vehicles . fourth . class
240257 end
241258
242- def test_post_polymorphic_invalid
259+ def test_post_polymorphic_invalid_with_wrong_type
243260 post '/people' , params :
244261 {
245262 'data' => {
@@ -262,6 +279,34 @@ def test_post_polymorphic_invalid
262279 assert_jsonapi_response 400 , msg : "Submitting a thing as a vehicle should raise a type mismatch error"
263280 end
264281
282+ def test_post_polymorphic_invalid_with_not_matched_type_and_id
283+ post '/people' , params :
284+ {
285+ 'data' => {
286+ 'type' => 'people' ,
287+ 'attributes' => {
288+ 'name' => 'Reo' ,
289+ 'email' => 'reo@xyz.fake' ,
290+ 'date_joined' => 'Thu, 01 Jan 2019 00:00:00 UTC +00:00' ,
291+ } ,
292+ 'relationships' => {
293+ 'vehicles' => {
294+ 'data' => [
295+ { 'type' => 'car' , 'id' => '1' } ,
296+ { 'type' => 'car' , 'id' => '2' } #vehicle 2 is actually a boat
297+ ]
298+ }
299+ }
300+ }
301+ } . to_json ,
302+ headers : {
303+ 'CONTENT_TYPE' => JSONAPI ::MEDIA_TYPE ,
304+ 'Accept' => JSONAPI ::MEDIA_TYPE
305+ }
306+
307+ assert_jsonapi_response 404 , msg : "Submitting a thing as a vehicle should raise a record not found"
308+ end
309+
265310 def test_post_single_missing_data_contents
266311 post '/posts' , params :
267312 {
@@ -473,6 +518,96 @@ def test_patch_content_type
473518 assert_match JSONAPI ::MEDIA_TYPE , headers [ 'Content-Type' ]
474519 end
475520
521+ def test_patch_polymorphic_with_has_many_relationship
522+ patch '/people/1' , params :
523+ {
524+ 'data' => {
525+ 'id' => 1 ,
526+ 'type' => 'people' ,
527+ 'attributes' => {
528+ 'name' => 'Reo' ,
529+ 'email' => 'reo@xyz.fake' ,
530+ 'date_joined' => 'Thu, 01 Jan 2019 00:00:00 UTC +00:00' ,
531+ } ,
532+ 'relationships' => {
533+ 'vehicles' => {
534+ 'data' => [
535+ { 'type' => 'car' , 'id' => '1' } ,
536+ { 'type' => 'boat' , 'id' => '2' }
537+ ]
538+ }
539+ }
540+ }
541+ } . to_json ,
542+ headers : {
543+ 'CONTENT_TYPE' => JSONAPI ::MEDIA_TYPE ,
544+ 'Accept' => JSONAPI ::MEDIA_TYPE
545+ }
546+
547+ assert_jsonapi_response 200
548+
549+ body = JSON . parse ( response . body )
550+ person = Person . find ( body . dig ( "data" , "id" ) )
551+
552+ assert_equal "Reo" , person . name
553+ assert_equal 2 , person . vehicles . count
554+ assert_equal Car , person . vehicles . first . class
555+ assert_equal Boat , person . vehicles . second . class
556+ end
557+
558+ def test_patch_polymorphic_invalid_with_wrong_type
559+ patch '/people/1' , params :
560+ {
561+ 'data' => {
562+ 'id' => 1 ,
563+ 'type' => 'people' ,
564+ 'attributes' => {
565+ 'name' => 'Reo' ,
566+ 'email' => 'reo@xyz.fake' ,
567+ 'date_joined' => 'Thu, 01 Jan 2019 00:00:00 UTC +00:00' ,
568+ } ,
569+ 'relationships' => {
570+ 'vehicles' => { 'data' => [ { 'type' => 'author' , 'id' => '1' } ] } ,
571+ }
572+ }
573+ } . to_json ,
574+ headers : {
575+ 'CONTENT_TYPE' => JSONAPI ::MEDIA_TYPE ,
576+ 'Accept' => JSONAPI ::MEDIA_TYPE
577+ }
578+
579+ assert_jsonapi_response 400 , msg : "Submitting a thing as a vehicle should raise a type mismatch error"
580+ end
581+
582+ def test_patch_polymorphic_invalid_with_not_matched_type_and_id
583+ patch '/people/1' , params :
584+ {
585+ 'data' => {
586+ 'id' => 1 ,
587+ 'type' => 'people' ,
588+ 'attributes' => {
589+ 'name' => 'Reo' ,
590+ 'email' => 'reo@xyz.fake' ,
591+ 'date_joined' => 'Thu, 01 Jan 2019 00:00:00 UTC +00:00' ,
592+ } ,
593+ 'relationships' => {
594+ 'vehicles' => {
595+ 'data' => [
596+ { 'type' => 'car' , 'id' => '1' } ,
597+ { 'type' => 'car' , 'id' => '2' } #vehicle 2 is actually a boat
598+ ]
599+ }
600+ }
601+ }
602+ } . to_json ,
603+ headers : {
604+ 'CONTENT_TYPE' => JSONAPI ::MEDIA_TYPE ,
605+ 'Accept' => JSONAPI ::MEDIA_TYPE
606+ }
607+
608+ assert_jsonapi_response 404 , msg : "Submitting a thing as a vehicle should raise a record not found"
609+ end
610+
476611 def test_post_correct_content_type
477612 post '/posts' , params :
478613 {
@@ -1177,8 +1312,8 @@ def test_include_value_missing
11771312
11781313 def test_getting_different_resources_when_sti
11791314 assert_cacheable_jsonapi_get '/vehicles'
1180- types = json_response [ 'data' ] . map { |r | r [ 'type' ] } . sort
1181- assert_array_equals [ 'boats ', 'cars' ] , types
1315+ types = json_response [ 'data' ] . map { |r | r [ 'type' ] } . to_set
1316+ assert types == Set [ 'cars ', 'boats' ]
11821317 end
11831318
11841319 def test_getting_resource_with_correct_type_when_sti
0 commit comments