test/controllers/controller_test.rb in jsonapi-resources-0.2.0 vs test/controllers/controller_test.rb in jsonapi-resources-0.3.0.pre1

- old
+ new

@@ -1,7 +1,6 @@ require File.expand_path('../../test_helper', __FILE__) -require File.expand_path('../../fixtures/active_record', __FILE__) def set_content_type_header! @request.headers['Content-Type'] = JSONAPI::MEDIA_TYPE end @@ -42,22 +41,22 @@ def test_index_filter_by_ids_and_include_related get :index, {filter: {id: '2'}, include: 'comments'} assert_response :success assert_equal 1, json_response['data'].size - assert_equal 1, json_response['linked'].size + assert_equal 1, json_response['included'].size end def test_index_filter_by_ids_and_include_related_different_type get :index, {filter: {id: '1,2'}, include: 'author'} assert_response :success assert_equal 2, json_response['data'].size - assert_equal 1, json_response['linked'].size + assert_equal 1, json_response['included'].size end def test_index_filter_by_ids_and_fields - get :index, {filter: {id: '1,2'}, 'fields' => 'id,title,author'} + get :index, {filter: {id: '1,2'}, fields: {posts: 'id,title,author'}} assert_response :success assert_equal 2, json_response['data'].size # type, id, title, links assert_equal 4, json_response['data'][0].size @@ -85,11 +84,11 @@ assert_response :bad_request assert_match /currencies is not a valid resource./, json_response['errors'][0]['detail'] end def test_index_filter_by_ids_and_fields_2 - get :index, {filter: {id: '1,2'}, 'fields' => 'author'} + get :index, {filter: {id: '1,2'}, fields: {posts: 'author'}} assert_response :success assert_equal 2, json_response['data'].size # links, id, type assert_equal 3, json_response['data'][0].size @@ -148,16 +147,10 @@ get :index, {filter: {id: '5412333'}} assert_response :not_found assert_match /5412333 could not be found/, json_response['errors'][0]['detail'] end - def test_index_malformed_fields - get :index, {filter: {id: '1,2'}, 'fields' => 'posts'} - assert_response :bad_request - assert_match /posts is not a valid field for posts./, json_response['errors'][0]['detail'] - end - def test_field_not_supported get :index, {filter: {id: '1,2'}, 'fields' => {'posts' => 'id,title,rank,author'}} assert_response :bad_request assert_match /rank is not a valid field for posts./, json_response['errors'][0]['detail'] end @@ -176,11 +169,11 @@ def test_sorting_asc get :index, {sort: '+title'} assert_response :success - assert_equal "Delete This Later - Multiple2-1", json_response['data'][0]['title'] + assert_equal "A First Post", json_response['data'][0]['title'] end def test_sorting_desc get :index, {sort: '-title'} @@ -190,11 +183,11 @@ def test_sorting_by_multiple_fields get :index, {sort: '+title,+body'} assert_response :success - assert_equal '8', json_response['data'][0]['id'] + assert_equal '14', json_response['data'][0]['id'] end def test_invalid_sort_param get :index, {sort: '+asdfg'} @@ -214,45 +207,46 @@ assert_response :bad_request assert_match /id is not a valid sort criteria for post/, response.body end - # ToDo: test validating the parameter values - # def test_index_invalid_filter_value - # get :index, {ids: [1,'asdfg1']} - # assert_response :bad_request - # end - def test_show_single get :show, {id: '1'} assert_response :success assert json_response['data'].is_a?(Hash) assert_equal 'New post', json_response['data']['title'] assert_equal 'A body!!!', json_response['data']['body'] - assert_nil json_response['linked'] + assert_nil json_response['included'] end def test_show_single_with_includes get :show, {id: '1', include: 'comments'} assert_response :success assert json_response['data'].is_a?(Hash) assert_equal 'New post', json_response['data']['title'] assert_equal 'A body!!!', json_response['data']['body'] - assert_nil json_response['data']['links']['tags']['ids'] - assert_equal ['1', '2'], json_response['data']['links']['comments']['ids'] - assert_equal 2, json_response['linked'].size + assert_nil json_response['data']['links']['tags']['linkage'] + assert matches_array?([{'type' => 'comments', 'id' => '1'}, {'type' => 'comments', 'id' => '2'}], + json_response['data']['links']['comments']['linkage']) + assert_equal 2, json_response['included'].size end def test_show_single_with_fields - get :show, {id: '1', fields: 'author'} + get :show, {id: '1', fields: {posts: 'author'}} assert_response :success assert json_response['data'].is_a?(Hash) assert_nil json_response['data']['title'] assert_nil json_response['data']['body'] - assert_equal '1', json_response['data']['links']['author']['id'] + assert_equal '1', json_response['data']['links']['author']['linkage']['id'] end + def test_show_single_with_fields_string + get :show, {id: '1', fields: 'author'} + assert_response :bad_request + assert_match /Fields must specify a type./, json_response['errors'][0]['detail'] + end + def test_show_single_invalid_id_format get :show, {id: 'asdfg'} assert_response :bad_request assert_match /asdfg is not a valid value for id/, response.body end @@ -264,11 +258,11 @@ end def test_show_malformed_fields_not_list get :show, {id: '1', 'fields' => ''} assert_response :bad_request - assert_match /nil is not a valid field for posts./, json_response['errors'][0]['detail'] + assert_match /Fields must specify a type./, json_response['errors'][0]['detail'] end def test_show_malformed_fields_type_not_list get :show, {id: '1', 'fields' => {'posts' => ''}} assert_response :bad_request @@ -289,11 +283,11 @@ } } assert_response :created assert json_response['data'].is_a?(Hash) - assert_equal '3', json_response['data']['links']['author']['id'] + assert_equal '3', json_response['data']['links']['author']['linkage']['id'] assert_equal 'JR is Great', json_response['data']['title'] assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['body'] end def test_create_link_to_missing_object @@ -384,11 +378,11 @@ } assert_response :created assert json_response['data'].is_a?(Array) assert_equal json_response['data'].size, 2 - assert_equal json_response['data'][0]['links']['author']['id'], '3' + assert_equal json_response['data'][0]['links']['author']['linkage']['id'], '3' assert_match /JR is Great/, response.body assert_match /Ember is Great/, response.body end def test_create_multiple_wrong_case @@ -498,18 +492,18 @@ type: 'posts', title: 'JR is Great', body: 'JSONAPIResources is the greatest thing since unsliced bread.', links: { author: {type: 'people', id: '3'}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } } assert_response :created assert json_response['data'].is_a?(Hash) - assert_equal '3', json_response['data']['links']['author']['id'] + assert_equal '3', json_response['data']['links']['author']['linkage']['id'] assert_equal 'JR is Great', json_response['data']['title'] assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['body'] end def test_create_with_links_has_many_array @@ -527,11 +521,11 @@ } } assert_response :created assert json_response['data'].is_a?(Hash) - assert_equal '3', json_response['data']['links']['author']['id'] + assert_equal '3', json_response['data']['links']['author']['linkage']['id'] assert_equal 'JR is Great', json_response['data']['title'] assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['body'] end def test_create_with_links_include_and_fields @@ -542,22 +536,22 @@ type: 'posts', title: 'JR is Great!', body: 'JSONAPIResources is the greatest thing since unsliced bread!', links: { author: {type: 'people', id: '3'}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } }, include: 'author,author.posts', - fields: 'id,title,author' + fields: {posts: 'id,title,author'} } assert_response :created assert json_response['data'].is_a?(Hash) - assert_equal '3', json_response['data']['links']['author']['id'] + assert_equal '3', json_response['data']['links']['author']['linkage']['id'] assert_equal 'JR is Great!', json_response['data']['title'] - assert_not_nil json_response['linked'].size + assert_not_nil json_response['included'].size end def test_update_with_links set_content_type_header! javascript = Section.find_by(name: 'javascript') @@ -569,23 +563,24 @@ id: '3', type: 'posts', title: 'A great new Post', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } }, include: 'tags' } assert_response :success assert json_response['data'].is_a?(Hash) - assert_equal '3', json_response['data']['links']['author']['id'] - assert_equal javascript.id.to_s, json_response['data']['links']['section']['id'] + assert_equal '3', json_response['data']['links']['author']['linkage']['id'] + assert_equal javascript.id.to_s, json_response['data']['links']['section']['linkage']['id'] assert_equal 'A great new Post', json_response['data']['title'] assert_equal 'AAAA', json_response['data']['body'] - assert matches_array?(['3', '4'], json_response['data']['links']['tags']['ids']) + assert matches_array?([{'type' => 'tags', 'id' => '3'}, {'type' => 'tags', 'id' => '4'}], + json_response['data']['links']['tags']['linkage']) end def test_update_remove_links set_content_type_header! put :update, @@ -603,46 +598,55 @@ include: 'tags' } assert_response :success assert json_response['data'].is_a?(Hash) - assert_equal '3', json_response['data']['links']['author']['id'] - assert_equal nil, json_response['data']['links']['section']['id'] + assert_equal '3', json_response['data']['links']['author']['linkage']['id'] + assert_equal nil, json_response['data']['links']['section']['linkage']['id'] assert_equal 'A great new Post', json_response['data']['title'] assert_equal 'AAAA', json_response['data']['body'] - assert matches_array?([], json_response['data']['links']['tags']['ids']) + assert matches_array?([], + json_response['data']['links']['tags']['linkage']) end def test_update_relationship_has_one set_content_type_header! ruby = Section.find_by(name: 'ruby') - post_object = Post.find(3) + post_object = Post.find(4) assert_not_equal ruby.id, post_object.section_id - put :update_association, {post_id: 3, association: 'section', data: {type: 'sections', id: "#{ruby.id}"}} + put :update_association, {post_id: 4, association: 'section', data: {type: 'sections', id: "#{ruby.id}"}} assert_response :no_content - post_object = Post.find(3) + post_object = Post.find(4) assert_equal ruby.id, post_object.section_id end def test_update_relationship_has_one_invalid_links_hash_keys_ids set_content_type_header! - put :update_association, {post_id: 3, association: 'section', data: {types: 'sections', ids: 'foo'}} + put :update_association, {post_id: 3, association: 'section', data: {type: 'sections', ids: 'foo'}} assert_response :bad_request assert_match /Invalid Links Object/, response.body end def test_update_relationship_has_one_invalid_links_hash_count set_content_type_header! - put :update_association, {post_id: 3, association: 'section', data: {types: 'sections'}} + put :update_association, {post_id: 3, association: 'section', data: {type: 'sections'}} assert_response :bad_request assert_match /Invalid Links Object/, response.body end + def test_update_relationship_has_many_not_array + set_content_type_header! + put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', id: 2}} + + assert_response :bad_request + assert_match /Invalid Links Object/, response.body + end + def test_update_relationship_has_one_invalid_links_hash_keys_type_mismatch set_content_type_header! put :update_association, {post_id: 3, association: 'section', data: {type: 'comment', id: '3'}} assert_response :bad_request @@ -705,18 +709,30 @@ def test_update_relationship_has_one_singular_param_id_nil set_content_type_header! ruby = Section.find_by(name: 'ruby') post_object = Post.find(3) - post_object.section_id = ruby.id + post_object.section = ruby post_object.save! put :update_association, {post_id: 3, association: 'section', data: {type: 'sections', id: nil}} assert_response :no_content + assert_equal nil, post_object.reload.section_id + end + + def test_update_relationship_has_one_data_nil + set_content_type_header! + ruby = Section.find_by(name: 'ruby') post_object = Post.find(3) - assert_equal nil, post_object.section_id + post_object.section = ruby + post_object.save! + + put :update_association, {post_id: 3, association: 'section', data: nil} + + assert_response :no_content + assert_equal nil, post_object.reload.section_id end def test_remove_relationship_has_one set_content_type_header! ruby = Section.find_by(name: 'ruby') @@ -745,108 +761,106 @@ assert_equal ruby.id, post_object.section_id end def test_update_relationship_has_many_join_table_single set_content_type_header! - put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: []}} + put :update_association, {post_id: 3, association: 'tags', data: []} assert_response :no_content post_object = Post.find(3) assert_equal 0, post_object.tags.length - put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [2]}} + put :update_association, {post_id: 3, association: 'tags', data: [{type: 'tags', id: 2}]} assert_response :no_content post_object = Post.find(3) assert_equal 1, post_object.tags.length - put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [5]}} + put :update_association, {post_id: 3, association: 'tags', data: [{type: 'tags', id: 5}]} assert_response :no_content post_object = Post.find(3) tags = post_object.tags.collect { |tag| tag.id } assert_equal 1, tags.length assert matches_array? [5], tags end - def test_update_relationship_has_many_join_table_homogenous + def test_update_relationship_has_many set_content_type_header! - put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [2, 3]}} - - assert_response :no_content - post_object = Post.find(3) - assert_equal 2, post_object.tags.collect { |tag| tag.id }.length - assert matches_array? [2, 3], post_object.tags.collect { |tag| tag.id } - end - - def test_update_relationship_has_many_join_table_heterogenous - set_content_type_header! put :update_association, {post_id: 3, association: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]} assert_response :no_content post_object = Post.find(3) assert_equal 2, post_object.tags.collect { |tag| tag.id }.length assert matches_array? [2, 3], post_object.tags.collect { |tag| tag.id } end def test_create_relationship_has_many_join_table set_content_type_header! - put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [2, 3]}} + put :update_association, {post_id: 3, association: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]} assert_response :no_content post_object = Post.find(3) assert_equal 2, post_object.tags.collect { |tag| tag.id }.length assert matches_array? [2, 3], post_object.tags.collect { |tag| tag.id } - post :create_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [5]}} + post :create_association, {post_id: 3, association: 'tags', data: [{type: 'tags', id: 5}]} assert_response :no_content post_object = Post.find(3) assert_equal 3, post_object.tags.collect { |tag| tag.id }.length assert matches_array? [2, 3, 5], post_object.tags.collect { |tag| tag.id } end def test_create_relationship_has_many_mismatched_type set_content_type_header! - post :create_association, {post_id: 3, association: 'tags', data: {type: 'comments', ids: [5]}} + post :create_association, {post_id: 3, association: 'tags', data: [{type: 'comments', id: 5}]} assert_response :bad_request assert_match /Type Mismatch/, response.body end def test_create_relationship_has_many_missing_id set_content_type_header! - post :create_association, {post_id: 3, association: 'tags', data: {type: 'tags', idds: [5]}} + post :create_association, {post_id: 3, association: 'tags', data: [{type: 'tags', idd: 5}]} assert_response :bad_request - assert_match /The required parameter, ids, is missing/, response.body + assert_match /Data is not a valid Links Object./, response.body end + def test_create_relationship_has_many_not_array + set_content_type_header! + post :create_association, {post_id: 3, association: 'tags', data: {type: 'tags', id: 5}} + + assert_response :bad_request + assert_match /Data is not a valid Links Object./, response.body + end + def test_create_relationship_has_many_missing_data set_content_type_header! post :create_association, {post_id: 3, association: 'tags'} assert_response :bad_request assert_match /The required parameter, data, is missing./, response.body end def test_create_relationship_has_many_join set_content_type_header! - post :create_association, {post_id: 4, association: 'tags', data: {type: 'tags', ids: [1, 2, 3]}} + post :create_association, {post_id: 4, association: 'tags', data: [{type: 'tags', id: 1}, {type: 'tags', id: 2}, {type: 'tags', id: 3}]} assert_response :no_content end def test_create_relationship_has_many_join_table_record_exists set_content_type_header! - put :update_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [2, 3]}} + put :update_association, {post_id: 3, association: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]} assert_response :no_content post_object = Post.find(3) assert_equal 2, post_object.tags.collect { |tag| tag.id }.length assert matches_array? [2, 3], post_object.tags.collect { |tag| tag.id } - post :create_association, {post_id: 3, association: 'tags', data: {type: 'tags', ids: [5, 2]}} + post :create_association, {post_id: 3, association: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 5}]} assert_response :bad_request assert_match /The relation to 2 already exists./, response.body end @@ -858,36 +872,50 @@ assert_match /The required parameter, data, is missing./, response.body end def test_delete_relationship_has_many set_content_type_header! - put :update_association, {post_id: 9, association: 'tags', data: {type: 'tags', ids: [2, 3]}} + put :update_association, {post_id: 14, association: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]} assert_response :no_content - p = Post.find(9) + p = Post.find(14) assert_equal [2, 3], p.tag_ids - delete :destroy_association, {post_id: 9, association: 'tags', keys: '3'} + delete :destroy_association, {post_id: 14, association: 'tags', keys: '3'} p.reload assert_response :no_content assert_equal [2], p.tag_ids end def test_delete_relationship_has_many_does_not_exist set_content_type_header! - put :update_association, {post_id: 9, association: 'tags', data: {type: 'tags', ids: [2, 3]}} + put :update_association, {post_id: 14, association: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]} assert_response :no_content - p = Post.find(9) + p = Post.find(14) assert_equal [2, 3], p.tag_ids - delete :destroy_association, {post_id: 9, association: 'tags', keys: '4'} + delete :destroy_association, {post_id: 14, association: 'tags', keys: '4'} p.reload assert_response :not_found assert_equal [2, 3], p.tag_ids end + def test_delete_relationship_has_many_with_empty_data + set_content_type_header! + put :update_association, {post_id: 14, association: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]} + assert_response :no_content + p = Post.find(14) + assert_equal [2, 3], p.tag_ids + + put :update_association, {post_id: 14, association: 'tags', data: [] } + + p.reload + assert_response :no_content + assert_equal [], p.tag_ids + end + def test_update_mismatched_keys set_content_type_header! javascript = Section.find_by(name: 'javascript') put :update, @@ -897,11 +925,11 @@ type: 'posts', id: 2, title: 'A great new Post', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } } assert_response :bad_request @@ -920,11 +948,11 @@ id: '3', asdfg: 'aaaa', title: 'A great new Post', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } } assert_response :bad_request @@ -943,11 +971,11 @@ id: '3', title: 'A great new Post', links: { asdfg: 'aaaa', section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } } assert_response :bad_request @@ -964,11 +992,11 @@ data_spelled_wrong: { type: 'posts', title: 'A great new Post', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } } assert_response :bad_request @@ -1002,11 +1030,11 @@ id: '3', type_spelled_wrong: 'posts', title: 'A great new Post', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } } assert_response :bad_request @@ -1017,47 +1045,49 @@ set_content_type_header! javascript = Section.find_by(name: 'javascript') put :update, { - id: [3, 9], + id: [3, 16], data: [ { type: 'posts', id: 3, title: 'A great new Post QWERTY', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } }, { type: 'posts', - id: 9, + id: 16, title: 'A great new Post ASDFG', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } ], include: 'tags' } assert_response :success assert_equal json_response['data'].size, 2 - assert_equal json_response['data'][0]['links']['author']['id'], '3' - assert_equal json_response['data'][0]['links']['section']['id'], javascript.id.to_s + assert_equal json_response['data'][0]['links']['author']['linkage']['id'], '3' + assert_equal json_response['data'][0]['links']['section']['linkage']['id'], javascript.id.to_s assert_equal json_response['data'][0]['title'], 'A great new Post QWERTY' assert_equal json_response['data'][0]['body'], 'AAAA' - assert_equal json_response['data'][0]['links']['tags']['ids'], ['3', '4'] + assert matches_array?([{'type' => 'tags', 'id' => '3'}, {'type' => 'tags', 'id' => '4'}], + json_response['data'][0]['links']['tags']['linkage']) - assert_equal json_response['data'][1]['links']['author']['id'], '3' - assert_equal json_response['data'][1]['links']['section']['id'], javascript.id.to_s + assert_equal json_response['data'][1]['links']['author']['linkage']['id'], '3' + assert_equal json_response['data'][1]['links']['section']['linkage']['id'], javascript.id.to_s assert_equal json_response['data'][1]['title'], 'A great new Post ASDFG' - assert_equal json_response['data'][1]['body'], 'AAAA' - assert_equal json_response['data'][1]['links']['tags']['ids'], ['3', '4'] + assert_equal json_response['data'][1]['body'], 'Not First!!!!' + assert matches_array?([{'type' => 'tags', 'id' => '3'}, {'type' => 'tags', 'id' => '4'}], + json_response['data'][1]['links']['tags']['linkage']) end def test_update_multiple_missing_keys set_content_type_header! javascript = Section.find_by(name: 'javascript') @@ -1069,19 +1099,19 @@ { type: 'posts', title: 'A great new Post ASDFG', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } }, { type: 'posts', title: 'A great new Post QWERTY', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } ]} assert_response :bad_request @@ -1100,20 +1130,20 @@ type: 'posts', id: 3, title: 'A great new Post ASDFG', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } }, { type: 'posts', id: 8, title: 'A great new Post QWERTY', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } ]} assert_response :bad_request @@ -1132,20 +1162,20 @@ type: 'posts', id: 3, title: 'A great new Post QWERTY', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } }, { type: 'posts', id: 9, title: 'A great new Post ASDFG', links: { section: {type: 'sections', id: "#{javascript.id}"}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } ]} assert_response :bad_request @@ -1161,11 +1191,11 @@ type: 'posts', id: '3', subject: 'A great new Post', links: { author: {type: 'people', id: '1'}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } } assert_response :bad_request @@ -1181,11 +1211,11 @@ data: { type: 'posts', subject: 'A great new Post', linked_objects: { author: {type: 'people', id: '1'}, - tags: {type: 'tags', ids: [3, 4]} + tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}] } } } assert_response :bad_request @@ -1222,64 +1252,77 @@ def test_show_has_one_relationship get :show_association, {post_id: '1', association: 'author'} assert_response :success assert_hash_equals json_response, {data: { - type: 'people', - id: '1', - self: 'http://test.host/posts/1/links/author', - resource: 'http://test.host/posts/1/author' - } + type: 'people', + id: '1' + }, + links: { + self: 'http://test.host/posts/1/links/author', + related: 'http://test.host/posts/1/author' + } } end def test_show_has_many_relationship - get :show_association, {post_id: '1', association: 'tags'} + get :show_association, {post_id: '2', association: 'tags'} assert_response :success assert_hash_equals json_response, - {data: { - type: 'tags', - ids: ['1', '2', '3'], - self: 'http://test.host/posts/1/links/tags', - resource: 'http://test.host/posts/1/tags' + { + data: [ + {type: 'tags', id: '5'} + ], + links: { + self: 'http://test.host/posts/2/links/tags', + related: 'http://test.host/posts/2/tags' } } end + + def test_show_has_many_relationship_invalid_id + get :show_association, {post_id: '2,1', association: 'tags'} + assert_response :bad_request + assert_match /2,1 is not a valid value for id/, response.body + end end class TagsControllerTest < ActionController::TestCase def test_tags_index get :index, {filter: {id: '6,7,8,9'}, include: 'posts,posts.tags,posts.author.posts'} assert_response :success assert_equal 4, json_response['data'].size - assert_equal 2, json_response['linked'].size + assert_equal 2, json_response['included'].size end def test_tags_show_multiple get :show, {id: '6,7,8,9'} - assert_response :success - assert json_response['data'].is_a?(Array) - assert_equal 4, json_response['data'].size + assert_response :bad_request + assert_match /6,7,8,9 is not a valid value for id/, response.body end def test_tags_show_multiple_with_include get :show, {id: '6,7,8,9', include: 'posts,posts.tags,posts.author.posts'} - assert_response :success - assert json_response['data'].is_a?(Array) - assert_equal 4, json_response['data'].size - assert_equal 2, json_response['linked'].size + assert_response :bad_request + assert_match /6,7,8,9 is not a valid value for id/, response.body end def test_tags_show_multiple_with_nonexistent_ids get :show, {id: '6,99,9,100'} - assert_response :not_found - assert_match /The record identified by 99 could not be found./, json_response['errors'][0]['detail'] + assert_response :bad_request + assert_match /6,99,9,100 is not a valid value for id/, response.body end + + def test_tags_show_multiple_with_nonexistent_ids_at_the_beginning + get :show, {id: '99,9,100'} + assert_response :bad_request + assert_match /99,9,100 is not a valid value for id/, response.body + end end class ExpenseEntriesControllerTest < ActionController::TestCase - def after_teardown + def setup JSONAPI.configuration.json_key_format = :camelized_key end def test_expense_entries_index get :index @@ -1296,11 +1339,11 @@ def test_expense_entries_show_include get :show, {id: 1, include: 'isoCurrency,employee'} assert_response :success assert json_response['data'].is_a?(Hash) - assert_equal 2, json_response['linked'].size + assert_equal 2, json_response['included'].size end def test_expense_entries_show_bad_include_missing_association get :show, {id: 1, include: 'isoCurrencies,employees'} assert_response :bad_request @@ -1313,31 +1356,24 @@ assert_response :bad_request assert_match /post is not a valid association of people/, json_response['errors'][0]['detail'] end def test_expense_entries_show_fields - get :show, {id: 1, include: 'isoCurrency,employee', 'fields' => 'transactionDate'} - assert_response :success - assert json_response['data'].is_a?(Hash) - assert json_response['data'].has_key?('transactionDate') - end - - def test_expense_entries_show_fields_type get :show, {id: 1, include: 'isoCurrency,employee', 'fields' => {'expenseEntries' => 'transactionDate'}} assert_response :success assert json_response['data'].is_a?(Hash) assert json_response['data'].has_key?('transactionDate') - assert_equal 2, json_response['linked'].size + assert_equal 2, json_response['included'].size end def test_expense_entries_show_fields_type_many get :show, {id: 1, include: 'isoCurrency,employee', 'fields' => {'expenseEntries' => 'transactionDate', 'isoCurrencies' => 'id,name'}} assert_response :success assert json_response['data'].is_a?(Hash) assert json_response['data'].has_key?('transactionDate') - assert_equal 2, json_response['linked'].size + assert_equal 2, json_response['included'].size end def test_create_expense_entries_underscored set_content_type_header! JSONAPI.configuration.json_key_format = :underscored_key @@ -1352,18 +1388,18 @@ employee: {type: 'people', id: '3'}, iso_currency: {type: 'iso_currencies', id: 'USD'} } }, include: 'iso_currency', - fields: 'id,transaction_date,iso_currency,cost,employee' + fields: {expense_entries: 'id,transaction_date,iso_currency,cost,employee'} } assert_response :created assert json_response['data'].is_a?(Hash) - assert_equal '3', json_response['data']['links']['employee']['id'] - assert_equal 'USD', json_response['data']['links']['iso_currency']['id'] - assert_equal 50.58, json_response['data']['cost'] + assert_equal '3', json_response['data']['links']['employee']['linkage']['id'] + assert_equal 'USD', json_response['data']['links']['iso_currency']['linkage']['id'] + assert_equal '50.58', json_response['data']['cost'] delete :destroy, {id: json_response['data']['id']} assert_response :no_content end @@ -1381,18 +1417,18 @@ employee: {type: 'people', id: '3'}, isoCurrency: {type: 'iso_currencies', id: 'USD'} } }, include: 'isoCurrency', - fields: 'id,transactionDate,isoCurrency,cost,employee' + fields: {expenseEntries: 'id,transactionDate,isoCurrency,cost,employee'} } assert_response :created assert json_response['data'].is_a?(Hash) - assert_equal '3', json_response['data']['links']['employee']['id'] - assert_equal 'USD', json_response['data']['links']['isoCurrency']['id'] - assert_equal 50.58, json_response['data']['cost'] + assert_equal '3', json_response['data']['links']['employee']['linkage']['id'] + assert_equal 'USD', json_response['data']['links']['isoCurrency']['linkage']['id'] + assert_equal '50.58', json_response['data']['cost'] delete :destroy, {id: json_response['data']['id']} assert_response :no_content end @@ -1410,18 +1446,18 @@ employee: {type: 'people', id: '3'}, 'iso-currency' => {type: 'iso_currencies', id: 'USD'} } }, include: 'iso-currency', - fields: 'id,transaction-date,iso-currency,cost,employee' + fields: {'expense-entries' => 'id,transaction-date,iso-currency,cost,employee'} } assert_response :created assert json_response['data'].is_a?(Hash) - assert_equal '3', json_response['data']['links']['employee']['id'] - assert_equal 'USD', json_response['data']['links']['iso-currency']['id'] - assert_equal 50.58, json_response['data']['cost'] + assert_equal '3', json_response['data']['links']['employee']['linkage']['id'] + assert_equal 'USD', json_response['data']['links']['iso-currency']['linkage']['id'] + assert_equal '50.58', json_response['data']['cost'] delete :destroy, {id: json_response['data']['id']} assert_response :no_content end end @@ -1515,10 +1551,14 @@ assert_equal 'Canada', json_response['data'][0]['CountryName'] end end class PeopleControllerTest < ActionController::TestCase + def setup + JSONAPI.configuration.json_key_format = :camelized_key + end + def test_create_validations set_content_type_header! post :create, { data: { @@ -1587,11 +1627,11 @@ assert_equal json_response['data'][0]['id'], '1' assert_equal json_response['data'][0]['name'], 'Joe Author' end end -class AuthorsControllerTest < ActionController::TestCase +class Api::V5::AuthorsControllerTest < ActionController::TestCase def test_get_person_as_author get :index, {filter: {id: '1'}} assert_response :success assert_equal 1, json_response['data'].size assert_equal '1', json_response['data'][0]['id'] @@ -1627,17 +1667,13 @@ assert_equal 'Persian', json_response['data']['name'] end def test_poro_show_multiple get :show, {id: '0,2'} - assert_response :success - assert json_response['data'].is_a?(Array) - assert_equal 2, json_response['data'].size - assert_equal '0', json_response['data'][0]['id'] - assert_equal 'Persian', json_response['data'][0]['name'] - assert_equal '2', json_response['data'][1]['id'] - assert_equal 'Sphinx', json_response['data'][1]['name'] + + assert_response :bad_request + assert_match /0,2 is not a valid value for id/, response.body end def test_poro_create_simple set_content_type_header! post :create, @@ -1705,15 +1741,15 @@ end def test_show_post_namespaced_include get :show, {id: '1', include: 'writer'} assert_response :success - assert_equal '1', json_response['data']['links']['writer']['id'] + assert_equal '1', json_response['data']['links']['writer']['linkage']['id'] assert_nil json_response['data']['links']['tags'] - assert_equal '1', json_response['linked'][0]['id'] - assert_equal 'writers', json_response['linked'][0]['type'] - assert_equal 'joe@xyz.fake', json_response['linked'][0]['email'] + assert_equal '1', json_response['included'][0]['id'] + assert_equal 'writers', json_response['included'][0]['type'] + assert_equal 'joe@xyz.fake', json_response['included'][0]['email'] end def test_index_filter_on_association_namespaced get :index, {filter: {writer: '1'}} assert_response :success @@ -1741,27 +1777,31 @@ } } assert_response :created assert json_response['data'].is_a?(Hash) - assert_equal '3', json_response['data']['links']['writer']['id'] + assert_equal '3', json_response['data']['links']['writer']['linkage']['id'] assert_equal 'JR - now with Namespacing', json_response['data']['title'] assert_equal 'JSONAPIResources is the greatest thing since unsliced bread now that it has namespaced resources.', json_response['data']['body'] end end class FactsControllerTest < ActionController::TestCase + def setup + JSONAPI.configuration.json_key_format = :camelized_key + end + def test_type_formatting get :show, {id: '1'} assert_response :success assert json_response['data'].is_a?(Hash) assert_equal 'Jane Author', json_response['data']['spouseName'] assert_equal 'First man to run across Antartica.', json_response['data']['bio'] assert_equal 23.89/45.6, json_response['data']['qualityRating'] - assert_equal 47000.56, json_response['data']['salary'] - assert_equal '2013-08-07T20:25:00.000Z', json_response['data']['dateTimeJoined'] + assert_equal '47000.56', json_response['data']['salary'] + assert_equal '2013-08-07T20:25:00Z', json_response['data']['dateTimeJoined'] assert_equal '1965-06-30', json_response['data']['birthday'] assert_equal '2000-01-01T20:00:00Z', json_response['data']['bedtime'] assert_equal 'abc', json_response['data']['photo'] assert_equal false, json_response['data']['cool'] end