test/controllers/controller_test.rb in jsonapi-resources-0.3.3 vs test/controllers/controller_test.rb in jsonapi-resources-0.4.0
- old
+ new
@@ -2,14 +2,10 @@
def set_content_type_header!
@request.headers['Content-Type'] = JSONAPI::MEDIA_TYPE
end
-class ConfigControllerTest < ActionController::TestCase
-
-end
-
class PostsControllerTest < ActionController::TestCase
def test_index
get :index
assert_response :success
assert json_response['data'].is_a?(Array)
@@ -55,33 +51,49 @@
assert_response :success
assert_equal 2, json_response['data'].size
assert_equal 1, json_response['included'].size
end
+ def test_index_include_one_level_query_count
+ query_count = count_queries do
+ get :index, {include: 'author'}
+ end
+ assert_response :success
+ assert_equal 2, query_count
+ end
+
+ def test_index_include_two_levels_query_count
+ query_count = count_queries do
+ get :index, {include: 'author,author.comments'}
+ end
+ assert_response :success
+ assert_equal 3, query_count
+ end
+
def test_index_filter_by_ids_and_fields
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
+ # type, id, links, attributes, relationships
+ assert_equal 5, json_response['data'][0].size
assert json_response['data'][0].has_key?('type')
assert json_response['data'][0].has_key?('id')
- assert json_response['data'][0].has_key?('title')
+ assert json_response['data'][0]['attributes'].has_key?('title')
assert json_response['data'][0].has_key?('links')
end
def test_index_filter_by_ids_and_fields_specify_type
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
+ # type, id, links, attributes, relationships
+ assert_equal 5, json_response['data'][0].size
assert json_response['data'][0].has_key?('type')
assert json_response['data'][0].has_key?('id')
- assert json_response['data'][0].has_key?('title')
+ assert json_response['data'][0]['attributes'].has_key?('title')
assert json_response['data'][0].has_key?('links')
end
def test_index_filter_by_ids_and_fields_specify_unrelated_type
get :index, {filter: {id: '1,2'}, 'fields' => {'currencies' => 'code'}}
@@ -92,15 +104,15 @@
def test_index_filter_by_ids_and_fields_2
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
+ # type, id, links, relationships
+ assert_equal 4, json_response['data'][0].size
assert json_response['data'][0].has_key?('type')
assert json_response['data'][0].has_key?('id')
- assert json_response['data'][0]['links'].has_key?('author')
+ assert json_response['data'][0]['relationships'].has_key?('author')
end
def test_filter_association_single
get :index, {filter: {tags: '5,1'}}
assert_response :success
@@ -170,95 +182,71 @@
assert_response :success
assert_equal 3, json_response['data'].size
end
def test_sorting_asc
- get :index, {sort: '+title'}
+ get :index, {sort: 'title'}
assert_response :success
- assert_equal "A First Post", json_response['data'][0]['title']
+ assert_equal "A First Post", json_response['data'][0]['attributes']['title']
end
- # Plus symbol may be replaced by a space
- def test_sorting_asc_with_space
- get :index, {sort: ' title'}
-
- assert_response :success
- assert_equal "A First Post", json_response['data'][0]['title']
- end
-
- # Plus symbol may be sent uriencoded ('%2b')
- def test_sorting_asc_with_encoded_plus
- get :index, {sort: '%2btitle'}
-
- assert_response :success
- assert_equal "A First Post", json_response['data'][0]['title']
- end
-
def test_sorting_desc
get :index, {sort: '-title'}
assert_response :success
- assert_equal "Update This Later - Multiple", json_response['data'][0]['title']
+ assert_equal "Update This Later - Multiple", json_response['data'][0]['attributes']['title']
end
def test_sorting_by_multiple_fields
- get :index, {sort: '+title,+body'}
+ get :index, {sort: 'title,body'}
assert_response :success
assert_equal '14', json_response['data'][0]['id']
end
def test_invalid_sort_param
- get :index, {sort: '+asdfg'}
+ get :index, {sort: 'asdfg'}
assert_response :bad_request
assert_match /asdfg is not a valid sort criteria for post/, response.body
end
- def test_invalid_sort_param_missing_direction
- get :index, {sort: 'title'}
-
- assert_response :bad_request
- assert_match /title must start with a direction/, response.body
- end
-
def test_excluded_sort_param
- get :index, {sort: '+id'}
+ get :index, {sort: 'id'}
assert_response :bad_request
assert_match /id is not a valid sort criteria for post/, response.body
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_equal 'New post', json_response['data']['attributes']['title']
+ assert_equal 'A body!!!', json_response['data']['attributes']['body']
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']['linkage']
+ assert_equal 'New post', json_response['data']['attributes']['title']
+ assert_equal 'A body!!!', json_response['data']['attributes']['body']
+ assert_nil json_response['data']['relationships']['tags']['data']
assert matches_array?([{'type' => 'comments', 'id' => '1'}, {'type' => 'comments', 'id' => '2'}],
- json_response['data']['links']['comments']['linkage'])
+ json_response['data']['relationships']['comments']['data'])
assert_equal 2, json_response['included'].size
end
def test_show_single_with_fields
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']['linkage']['id']
+ assert_nil json_response['data']['attributes']
+ assert_equal '1', json_response['data']['relationships']['author']['data']['id']
end
def test_show_single_with_fields_string
get :show, {id: '1', fields: 'author'}
assert_response :bad_request
@@ -293,35 +281,39 @@
set_content_type_header!
post :create,
{
data: {
type: 'posts',
- title: 'JR is Great',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}}
+ attributes: {
+ title: 'JR is Great',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}}
}
}
}
assert_response :created
assert json_response['data'].is_a?(Hash)
- 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']
+ assert_equal '3', json_response['data']['relationships']['author']['data']['id']
+ assert_equal 'JR is Great', json_response['data']['attributes']['title']
+ assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['attributes']['body']
end
def test_create_link_to_missing_object
set_content_type_header!
post :create,
{
data: {
type: 'posts',
- title: 'JR is Great',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '304567'}}
+ attributes: {
+ title: 'JR is Great',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '304567'}}
}
}
}
assert_response :unprocessable_entity
@@ -333,15 +325,17 @@
set_content_type_header!
post :create,
{
data: {
type: 'posts',
- asdfg: 'aaaa',
- title: 'JR is Great',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}}
+ attributes: {
+ asdfg: 'aaaa',
+ title: 'JR is Great',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}}
}
}
}
assert_response :bad_request
@@ -352,13 +346,15 @@
set_content_type_header!
post :create,
{
data: {
type: 'posts',
- title: 'JSONAPIResources is the greatest thing...',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
+ attributes: {
+ title: 'JSONAPIResources is the greatest thing...',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
author: nil
}
}
}
@@ -378,31 +374,35 @@
post :create,
{
data: [
{
type: 'posts',
- title: 'JR is Great',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}}
+ attributes: {
+ title: 'JR is Great',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}}
}
},
{
type: 'posts',
- title: 'Ember is Great',
- body: 'Ember is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}}
+ attributes: {
+ title: 'Ember is Great',
+ body: 'Ember is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}}
}
}
]
}
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']['linkage']['id'], '3'
+ assert_equal json_response['data'][0]['relationships']['author']['data']['id'], '3'
assert_match /JR is Great/, response.body
assert_match /Ember is Great/, response.body
end
def test_create_multiple_wrong_case
@@ -410,22 +410,26 @@
post :create,
{
data: [
{
type: 'posts',
- Title: 'JR is Great',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}}
+ attributes: {
+ Title: 'JR is Great',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}}
}
},
{
type: 'posts',
- title: 'Ember is Great',
- BODY: 'Ember is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}}
+ attributes: {
+ title: 'Ember is Great',
+ BODY: 'Ember is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}}
}
}
]
}
@@ -437,14 +441,16 @@
set_content_type_header!
post :create,
{
data_spelled_wrong: {
type: 'posts',
- title: 'JR is Great',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}}
+ attributes: {
+ title: 'JR is Great',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}}
}
}
}
assert_response :bad_request
@@ -455,14 +461,16 @@
set_content_type_header!
post :create,
{
data: {
type: 'posts_spelled_wrong',
- title: 'JR is Great',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}}
+ attributes: {
+ title: 'JR is Great',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}}
}
}
}
assert_response :bad_request
@@ -472,14 +480,16 @@
def test_create_simple_missing_type
set_content_type_header!
post :create,
{
data: {
- title: 'JR is Great',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}}
+ attributes: {
+ title: 'JR is Great',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}}
}
}
}
assert_response :bad_request
@@ -490,14 +500,16 @@
set_content_type_header!
post :create,
{
data: {
type: 'posts',
- subject: 'JR is Great',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}}
+ attributes: {
+ subject: 'JR is Great',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}}
}
}
}
assert_response :bad_request
@@ -508,69 +520,75 @@
set_content_type_header!
post :create,
{
data: {
type: 'posts',
- title: 'JR is Great',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}},
- tags: {linkage: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
+ attributes: {
+ title: 'JR is Great',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}},
+ tags: {data: [{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']['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']
+ assert_equal '3', json_response['data']['relationships']['author']['data']['id']
+ assert_equal 'JR is Great', json_response['data']['attributes']['title']
+ assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['attributes']['body']
end
def test_create_with_links_has_many_array
set_content_type_header!
post :create,
{
data: {
type: 'posts',
- title: 'JR is Great',
- body: 'JSONAPIResources is the greatest thing since unsliced bread.',
- links: {
- author: {linkage: {type: 'people', id: '3'}},
- tags: {linkage: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
+ attributes: {
+ title: 'JR is Great',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread.'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}},
+ tags: {data: [{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']['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']
+ assert_equal '3', json_response['data']['relationships']['author']['data']['id']
+ assert_equal 'JR is Great', json_response['data']['attributes']['title']
+ assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['attributes']['body']
end
def test_create_with_links_include_and_fields
set_content_type_header!
post :create,
{
data: {
type: 'posts',
- title: 'JR is Great!',
- body: 'JSONAPIResources is the greatest thing since unsliced bread!',
- links: {
- author: {linkage: {type: 'people', id: '3'}},
- tags: {linkage: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
+ attributes: {
+ title: 'JR is Great!',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread!'
+ },
+ relationships: {
+ author: {data: {type: 'people', id: '3'}},
+ tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
}
},
include: 'author,author.posts',
fields: {posts: 'id,title,author'}
}
assert_response :created
assert json_response['data'].is_a?(Hash)
- assert_equal '3', json_response['data']['links']['author']['linkage']['id']
- assert_equal 'JR is Great!', json_response['data']['title']
+ assert_equal '3', json_response['data']['relationships']['author']['data']['id']
+ assert_equal 'JR is Great!', json_response['data']['attributes']['title']
assert_not_nil json_response['included'].size
end
def test_update_with_links
set_content_type_header!
@@ -580,41 +598,45 @@
{
id: 3,
data: {
id: '3',
type: 'posts',
- title: 'A great new Post',
- links: {
- section: {linkage: {type: 'sections', id: "#{javascript.id}"}},
- tags: {linkage: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
+ attributes: {
+ title: 'A great new Post'
+ },
+ relationships: {
+ section: {data: {type: 'sections', id: "#{javascript.id}"}},
+ tags: {data: [{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']['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_equal '3', json_response['data']['relationships']['author']['data']['id']
+ assert_equal javascript.id.to_s, json_response['data']['relationships']['section']['data']['id']
+ assert_equal 'A great new Post', json_response['data']['attributes']['title']
+ assert_equal 'AAAA', json_response['data']['attributes']['body']
assert matches_array?([{'type' => 'tags', 'id' => '3'}, {'type' => 'tags', 'id' => '4'}],
- json_response['data']['links']['tags']['linkage'])
+ json_response['data']['relationships']['tags']['data'])
end
def test_update_remove_links
set_content_type_header!
put :update,
{
id: 3,
data: {
id: '3',
type: 'posts',
- title: 'A great new Post',
- links: {
- section: {linkage: {type: 'sections', id: 1}},
- tags: {linkage: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
+ attributes: {
+ title: 'A great new Post'
+ },
+ relationships: {
+ section: {data: {type: 'sections', id: 1}},
+ tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
}
},
include: 'tags'
}
@@ -624,27 +646,29 @@
{
id: 3,
data: {
type: 'posts',
id: 3,
- title: 'A great new Post',
- links: {
+ attributes: {
+ title: 'A great new Post'
+ },
+ relationships: {
section: nil,
tags: []
}
},
include: 'tags'
}
assert_response :success
assert json_response['data'].is_a?(Hash)
- assert_equal '3', json_response['data']['links']['author']['linkage']['id']
- assert_equal nil, json_response['data']['links']['section']['linkage']
- assert_equal 'A great new Post', json_response['data']['title']
- assert_equal 'AAAA', json_response['data']['body']
+ assert_equal '3', json_response['data']['relationships']['author']['data']['id']
+ assert_equal nil, json_response['data']['relationships']['section']['data']
+ assert_equal 'A great new Post', json_response['data']['attributes']['title']
+ assert_equal 'AAAA', json_response['data']['attributes']['body']
assert matches_array?([],
- json_response['data']['links']['tags']['linkage'])
+ json_response['data']['relationships']['tags']['data'])
end
def test_update_relationship_has_one
set_content_type_header!
ruby = Section.find_by(name: 'ruby')
@@ -696,11 +720,11 @@
{
id: 3,
data: {
type: 'posts',
id: 3,
- links: {
+ relationships: {
tags: nil
}
}
}
@@ -714,12 +738,12 @@
{
id: 3,
data: {
type: 'posts',
id: 3,
- links: {
- tags: {linkage: {typ: 'bad link', idd: 'as'}}
+ relationships: {
+ tags: {data: {typ: 'bad link', idd: 'as'}}
}
}
}
assert_response :bad_request
@@ -732,30 +756,30 @@
{
id: 3,
data: {
type: 'posts',
id: 3,
- links: {
+ relationships: {
tags: 'bad link'
}
}
}
assert_response :bad_request
assert_match /Invalid Links Object/, response.body
end
- def test_update_other_has_many_links_linkage_nil
+ def test_update_other_has_many_links_data_nil
set_content_type_header!
put :update,
{
id: 3,
data: {
type: 'posts',
id: 3,
- links: {
- tags: {linkage: nil}
+ relationships: {
+ tags: {data: nil}
}
}
}
assert_response :bad_request
@@ -977,12 +1001,14 @@
{
id: 3,
data: {
type: 'posts',
id: 2,
- title: 'A great new Post',
- links: {
+ attributes: {
+ title: 'A great new Post'
+ },
+ relationships: {
section: {type: 'sections', id: "#{javascript.id}"},
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
}
}
}
@@ -999,13 +1025,15 @@
{
id: 3,
data: {
type: 'posts',
id: '3',
- asdfg: 'aaaa',
- title: 'A great new Post',
- links: {
+ attributes: {
+ asdfg: 'aaaa',
+ title: 'A great new Post'
+ },
+ relationships: {
section: {type: 'sections', id: "#{javascript.id}"},
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
}
}
}
@@ -1022,12 +1050,14 @@
{
id: 3,
data: {
type: 'posts',
id: '3',
- title: 'A great new Post',
- links: {
+ attributes: {
+ title: 'A great new Post'
+ },
+ relationships: {
asdfg: 'aaaa',
section: {type: 'sections', id: "#{javascript.id}"},
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
}
}
@@ -1044,12 +1074,14 @@
put :update,
{
id: 3,
data_spelled_wrong: {
type: 'posts',
- title: 'A great new Post',
- links: {
+ attributes: {
+ title: 'A great new Post'
+ },
+ relationships: {
section: {type: 'sections', id: "#{javascript.id}"},
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
}
}
}
@@ -1064,11 +1096,13 @@
put :update,
{
id: 3,
data: {
type: 'posts',
- title: 'A great new Post'
+ attributes: {
+ title: 'A great new Post'
+ }
}
}
assert_response :bad_request
assert_match /The resource object does not contain a key/, response.body
@@ -1082,22 +1116,49 @@
{
id: 3,
data: {
id: '3',
type_spelled_wrong: 'posts',
- title: 'A great new Post',
- links: {
+ attributes: {
+ title: 'A great new Post'
+ },
+ relationships: {
section: {type: 'sections', id: "#{javascript.id}"},
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
}
}
}
assert_response :bad_request
assert_match /The required parameter, type, is missing./, response.body
end
+ def test_update_unknown_key
+ set_content_type_header!
+ javascript = Section.find_by(name: 'javascript')
+
+ put :update,
+ {
+ id: 3,
+ data: {
+ id: '3',
+ type: 'posts',
+ body: 'asdfg',
+ attributes: {
+ title: 'A great new Post'
+ },
+ relationships: {
+ section: {type: 'sections', id: "#{javascript.id}"},
+ tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
+ }
+ }
+ }
+
+ assert_response :bad_request
+ assert_match /body is not allowed/, response.body
+ end
+
def test_update_multiple
set_content_type_header!
javascript = Section.find_by(name: 'javascript')
put :update,
@@ -1105,44 +1166,48 @@
id: [3, 16],
data: [
{
type: 'posts',
id: 3,
- title: 'A great new Post QWERTY',
- links: {
- section: {linkage: {type: 'sections', id: "#{javascript.id}"}},
- tags: {linkage: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
+ attributes: {
+ title: 'A great new Post QWERTY'
+ },
+ relationships: {
+ section: {data: {type: 'sections', id: "#{javascript.id}"}},
+ tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
}
},
{
type: 'posts',
id: 16,
- title: 'A great new Post ASDFG',
- links: {
- section: {linkage: {type: 'sections', id: "#{javascript.id}"}},
- tags: {linkage: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
+ attributes: {
+ title: 'A great new Post ASDFG'
+ },
+ relationships: {
+ section: {data: {type: 'sections', id: "#{javascript.id}"}},
+ tags: {data: [{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']['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]['relationships']['author']['data']['id'], '3'
+ assert_equal json_response['data'][0]['relationships']['section']['data']['id'], javascript.id.to_s
+ assert_equal json_response['data'][0]['attributes']['title'], 'A great new Post QWERTY'
+ assert_equal json_response['data'][0]['attributes']['body'], 'AAAA'
assert matches_array?([{'type' => 'tags', 'id' => '3'}, {'type' => 'tags', 'id' => '4'}],
- json_response['data'][0]['links']['tags']['linkage'])
+ json_response['data'][0]['relationships']['tags']['data'])
- 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'], 'Not First!!!!'
+ assert_equal json_response['data'][1]['relationships']['author']['data']['id'], '3'
+ assert_equal json_response['data'][1]['relationships']['section']['data']['id'], javascript.id.to_s
+ assert_equal json_response['data'][1]['attributes']['title'], 'A great new Post ASDFG'
+ assert_equal json_response['data'][1]['attributes']['body'], 'Not First!!!!'
assert matches_array?([{'type' => 'tags', 'id' => '3'}, {'type' => 'tags', 'id' => '4'}],
- json_response['data'][1]['links']['tags']['linkage'])
+ json_response['data'][1]['relationships']['tags']['data'])
end
def test_update_multiple_missing_keys
set_content_type_header!
javascript = Section.find_by(name: 'javascript')
@@ -1151,20 +1216,24 @@
{
id: [3, 9],
data: [
{
type: 'posts',
- title: 'A great new Post ASDFG',
- links: {
+ attributes: {
+ title: 'A great new Post ASDFG'
+ },
+ relationships: {
section: {type: 'sections', id: "#{javascript.id}"},
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
}
},
{
type: 'posts',
- title: 'A great new Post QWERTY',
- links: {
+ attributes: {
+ title: 'A great new Post QWERTY'
+ },
+ relationships: {
section: {type: 'sections', id: "#{javascript.id}"},
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
}
}
]}
@@ -1182,23 +1251,27 @@
id: [3, 9],
data: [
{
type: 'posts',
id: 3,
- title: 'A great new Post ASDFG',
- links: {
- section: {linkage: {type: 'sections', id: "#{javascript.id}"}},
- tags: {linkage: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
+ attributes: {
+ title: 'A great new Post ASDFG'
+ },
+ relationships: {
+ section: {data: {type: 'sections', id: "#{javascript.id}"}},
+ tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
}
},
{
type: 'posts',
id: 8,
- title: 'A great new Post QWERTY',
- links: {
- section: {linkage: {type: 'sections', id: "#{javascript.id}"}},
- tags: {linkage: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
+ attributes: {
+ title: 'A great new Post QWERTY'
+ },
+ relationships: {
+ section: {data: {type: 'sections', id: "#{javascript.id}"}},
+ tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
}
}
]}
assert_response :bad_request
@@ -1214,21 +1287,25 @@
id: [3, 9, 2],
data: [
{
type: 'posts',
id: 3,
- title: 'A great new Post QWERTY',
- links: {
+ attributes: {
+ title: 'A great new Post QWERTY'
+ },
+ relationships: {
section: {type: 'sections', id: "#{javascript.id}"},
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
}
},
{
type: 'posts',
id: 9,
- title: 'A great new Post ASDFG',
- links: {
+ attributes: {
+ title: 'A great new Post ASDFG'
+ },
+ relationships: {
section: {type: 'sections', id: "#{javascript.id}"},
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
}
}
]}
@@ -1243,12 +1320,14 @@
{
id: 3,
data: {
type: 'posts',
id: '3',
- subject: 'A great new Post',
- links: {
+ attributes: {
+ subject: 'A great new Post'
+ },
+ relationships: {
author: {type: 'people', id: '1'},
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
}
}
}
@@ -1263,11 +1342,13 @@
put :update,
{
id: 3,
data: {
type: 'posts',
- subject: 'A great new Post',
+ attributes: {
+ subject: 'A great new Post'
+ },
linked_objects: {
author: {type: 'people', id: '1'},
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
}
}
@@ -1311,11 +1392,11 @@
{data: {
type: 'people',
id: '1'
},
links: {
- self: 'http://test.host/posts/1/links/author',
+ self: 'http://test.host/posts/1/relationships/author',
related: 'http://test.host/posts/1/author'
}
}
end
@@ -1326,11 +1407,11 @@
{
data: [
{type: 'tags', id: '5'}
],
links: {
- self: 'http://test.host/posts/2/links/tags',
+ self: 'http://test.host/posts/2/relationships/tags',
related: 'http://test.host/posts/2/tags'
}
}
end
@@ -1345,33 +1426,33 @@
assert_response :success
assert_hash_equals json_response,
{
data: nil,
links: {
- self: 'http://test.host/posts/17/links/author',
+ self: 'http://test.host/posts/17/relationships/author',
related: 'http://test.host/posts/17/author'
}
}
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'}
+ get :index, {filter: {id: '6,7,8,9'}, include: 'posts.tags,posts.author.posts'}
assert_response :success
assert_equal 4, json_response['data'].size
- assert_equal 2, json_response['included'].size
+ assert_equal 3, json_response['included'].size
end
def test_tags_show_multiple
get :show, {id: '6,7,8,9'}
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'}
+ get :show, {id: '6,7,8,9', include: 'posts.tags,posts.author.posts'}
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
@@ -1394,11 +1475,11 @@
def test_text_error
JSONAPI.configuration.use_text_errors = true
get :index, {sort: 'not_in_record'}
assert_response 400
- assert_equal 'INVALID_SORT_FORMAT', json_response['errors'][0]['code']
+ assert_equal 'INVALID_SORT_CRITERIA', json_response['errors'][0]['code']
JSONAPI.configuration.use_text_errors = false
end
def test_expense_entries_index
get :index
@@ -1435,20 +1516,20 @@
def test_expense_entries_show_fields
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 json_response['data']['attributes'].has_key?('transactionDate')
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 json_response['data']['attributes'].has_key?('transactionDate')
assert_equal 2, json_response['included'].size
end
def test_create_expense_entries_underscored
set_content_type_header!
@@ -1456,26 +1537,28 @@
post :create,
{
data: {
type: 'expense_entries',
- transaction_date: '2014/04/15',
- cost: 50.58,
- links: {
- employee: {linkage: {type: 'people', id: '3'}},
- iso_currency: {linkage: {type: 'iso_currencies', id: 'USD'}}
+ attributes: {
+ transaction_date: '2014/04/15',
+ cost: 50.58
+ },
+ relationships: {
+ employee: {data: {type: 'people', id: '3'}},
+ iso_currency: {data: {type: 'iso_currencies', id: 'USD'}}
}
},
include: 'iso_currency',
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']['linkage']['id']
- assert_equal 'USD', json_response['data']['links']['iso_currency']['linkage']['id']
- assert_equal '50.58', json_response['data']['cost']
+ assert_equal '3', json_response['data']['relationships']['employee']['data']['id']
+ assert_equal 'USD', json_response['data']['relationships']['iso_currency']['data']['id']
+ assert_equal '50.58', json_response['data']['attributes']['cost']
delete :destroy, {id: json_response['data']['id']}
assert_response :no_content
end
@@ -1485,26 +1568,28 @@
post :create,
{
data: {
type: 'expense_entries',
- transactionDate: '2014/04/15',
- cost: 50.58,
- links: {
- employee: {linkage: {type: 'people', id: '3'}},
- isoCurrency: {linkage: {type: 'iso_currencies', id: 'USD'}}
+ attributes: {
+ transactionDate: '2014/04/15',
+ cost: 50.58
+ },
+ relationships: {
+ employee: {data: {type: 'people', id: '3'}},
+ isoCurrency: {data: {type: 'iso_currencies', id: 'USD'}}
}
},
include: 'isoCurrency',
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']['linkage']['id']
- assert_equal 'USD', json_response['data']['links']['isoCurrency']['linkage']['id']
- assert_equal '50.58', json_response['data']['cost']
+ assert_equal '3', json_response['data']['relationships']['employee']['data']['id']
+ assert_equal 'USD', json_response['data']['relationships']['isoCurrency']['data']['id']
+ assert_equal '50.58', json_response['data']['attributes']['cost']
delete :destroy, {id: json_response['data']['id']}
assert_response :no_content
end
@@ -1514,26 +1599,28 @@
post :create,
{
data: {
type: 'expense_entries',
- 'transaction-date' => '2014/04/15',
- cost: 50.58,
- links: {
- employee: {linkage: {type: 'people', id: '3'}},
- 'iso-currency' => {linkage: {type: 'iso_currencies', id: 'USD'}}
+ attributes: {
+ 'transaction-date' => '2014/04/15',
+ cost: 50.58
+ },
+ relationships: {
+ employee: {data: {type: 'people', id: '3'}},
+ 'iso-currency' => {data: {type: 'iso_currencies', id: 'USD'}}
}
},
include: 'iso-currency',
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']['linkage']['id']
- assert_equal 'USD', json_response['data']['links']['iso-currency']['linkage']['id']
- assert_equal '50.58', json_response['data']['cost']
+ assert_equal '3', json_response['data']['relationships']['employee']['data']['id']
+ assert_equal 'USD', json_response['data']['relationships']['iso-currency']['data']['id']
+ assert_equal '50.58', json_response['data']['attributes']['cost']
delete :destroy, {id: json_response['data']['id']}
assert_response :no_content
end
end
@@ -1542,91 +1629,132 @@
def after_teardown
JSONAPI.configuration.json_key_format = :camelized_key
end
def test_currencies_show
- get :show, {code: 'USD'}
+ get :show, {id: 'USD'}
assert_response :success
assert json_response['data'].is_a?(Hash)
end
+ def test_create_currencies_client_generated_id
+ set_content_type_header!
+ JSONAPI.configuration.json_key_format = :underscored_route
+
+ post :create,
+ {
+ data: {
+ type: 'iso_currencies',
+ id: 'BTC',
+ attributes: {
+ name: 'Bit Coin',
+ 'country_name' => 'global',
+ 'minor_unit' => 'satoshi'
+ }
+ }
+ }
+
+ assert_response :created
+ assert_equal 'BTC', json_response['data']['id']
+ assert_equal 'Bit Coin', json_response['data']['attributes']['name']
+ assert_equal 'global', json_response['data']['attributes']['country_name']
+ assert_equal 'satoshi', json_response['data']['attributes']['minor_unit']
+
+ delete :destroy, {id: json_response['data']['id']}
+ assert_response :no_content
+ end
+
+ def test_currencies_primary_key_sort
+ get :index, {sort: 'id'}
+ assert_response :success
+ assert_equal 3, json_response['data'].size
+ assert_equal 'CAD', json_response['data'][0]['id']
+ assert_equal 'EUR', json_response['data'][1]['id']
+ assert_equal 'USD', json_response['data'][2]['id']
+ end
+
+ def test_currencies_code_sort
+ get :index, {sort: 'code'}
+ assert_response :bad_request
+ end
+
def test_currencies_json_key_underscored_sort
JSONAPI.configuration.json_key_format = :underscored_key
- get :index, {sort: '+country_name'}
+ get :index, {sort: 'country_name'}
assert_response :success
assert_equal 3, json_response['data'].size
- assert_equal 'Canada', json_response['data'][0]['country_name']
- assert_equal 'Euro Member Countries', json_response['data'][1]['country_name']
- assert_equal 'United States', json_response['data'][2]['country_name']
+ assert_equal 'Canada', json_response['data'][0]['attributes']['country_name']
+ assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['country_name']
+ assert_equal 'United States', json_response['data'][2]['attributes']['country_name']
# reverse sort
get :index, {sort: '-country_name'}
assert_response :success
assert_equal 3, json_response['data'].size
- assert_equal 'United States', json_response['data'][0]['country_name']
- assert_equal 'Euro Member Countries', json_response['data'][1]['country_name']
- assert_equal 'Canada', json_response['data'][2]['country_name']
+ assert_equal 'United States', json_response['data'][0]['attributes']['country_name']
+ assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['country_name']
+ assert_equal 'Canada', json_response['data'][2]['attributes']['country_name']
end
def test_currencies_json_key_dasherized_sort
JSONAPI.configuration.json_key_format = :dasherized_key
- get :index, {sort: '+country-name'}
+ get :index, {sort: 'country-name'}
assert_response :success
assert_equal 3, json_response['data'].size
- assert_equal 'Canada', json_response['data'][0]['country-name']
- assert_equal 'Euro Member Countries', json_response['data'][1]['country-name']
- assert_equal 'United States', json_response['data'][2]['country-name']
+ assert_equal 'Canada', json_response['data'][0]['attributes']['country-name']
+ assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['country-name']
+ assert_equal 'United States', json_response['data'][2]['attributes']['country-name']
# reverse sort
get :index, {sort: '-country-name'}
assert_response :success
assert_equal 3, json_response['data'].size
- assert_equal 'United States', json_response['data'][0]['country-name']
- assert_equal 'Euro Member Countries', json_response['data'][1]['country-name']
- assert_equal 'Canada', json_response['data'][2]['country-name']
+ assert_equal 'United States', json_response['data'][0]['attributes']['country-name']
+ assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['country-name']
+ assert_equal 'Canada', json_response['data'][2]['attributes']['country-name']
end
def test_currencies_json_key_custom_json_key_sort
JSONAPI.configuration.json_key_format = :upper_camelized_key
- get :index, {sort: '+CountryName'}
+ get :index, {sort: 'CountryName'}
assert_response :success
assert_equal 3, json_response['data'].size
- assert_equal 'Canada', json_response['data'][0]['CountryName']
- assert_equal 'Euro Member Countries', json_response['data'][1]['CountryName']
- assert_equal 'United States', json_response['data'][2]['CountryName']
+ assert_equal 'Canada', json_response['data'][0]['attributes']['CountryName']
+ assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['CountryName']
+ assert_equal 'United States', json_response['data'][2]['attributes']['CountryName']
# reverse sort
get :index, {sort: '-CountryName'}
assert_response :success
assert_equal 3, json_response['data'].size
- assert_equal 'United States', json_response['data'][0]['CountryName']
- assert_equal 'Euro Member Countries', json_response['data'][1]['CountryName']
- assert_equal 'Canada', json_response['data'][2]['CountryName']
+ assert_equal 'United States', json_response['data'][0]['attributes']['CountryName']
+ assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['CountryName']
+ assert_equal 'Canada', json_response['data'][2]['attributes']['CountryName']
end
def test_currencies_json_key_underscored_filter
JSONAPI.configuration.json_key_format = :underscored_key
get :index, {filter: {country_name: 'Canada'}}
assert_response :success
assert_equal 1, json_response['data'].size
- assert_equal 'Canada', json_response['data'][0]['country_name']
+ assert_equal 'Canada', json_response['data'][0]['attributes']['country_name']
end
def test_currencies_json_key_camelized_key_filter
JSONAPI.configuration.json_key_format = :camelized_key
get :index, {filter: {'countryName' => 'Canada'}}
assert_response :success
assert_equal 1, json_response['data'].size
- assert_equal 'Canada', json_response['data'][0]['countryName']
+ assert_equal 'Canada', json_response['data'][0]['attributes']['countryName']
end
def test_currencies_json_key_custom_json_key_filter
JSONAPI.configuration.json_key_format = :upper_camelized_key
get :index, {filter: {'CountryName' => 'Canada'}}
assert_response :success
assert_equal 1, json_response['data'].size
- assert_equal 'Canada', json_response['data'][0]['CountryName']
+ assert_equal 'Canada', json_response['data'][0]['attributes']['CountryName']
end
end
class PeopleControllerTest < ActionController::TestCase
def setup
@@ -1637,13 +1765,15 @@
set_content_type_header!
post :create,
{
data: {
type: 'people',
- name: 'Steve Jobs',
- email: 'sj@email.zzz',
- dateJoined: DateTime.parse('2014-1-30 4:20:00 UTC +00:00')
+ attributes: {
+ name: 'Steve Jobs',
+ email: 'sj@email.zzz',
+ dateJoined: DateTime.parse('2014-1-30 4:20:00 UTC +00:00')
+ }
}
}
assert_response :success
end
@@ -1655,13 +1785,13 @@
{
id: 3,
data: {
id: '3',
type: 'people',
- links: {
+ relationships: {
'hair-cut' => {
- linkage: {
+ data: {
type: 'hair-cuts',
id: '1'
}
}
}
@@ -1674,11 +1804,13 @@
set_content_type_header!
post :create,
{
data: {
type: 'people',
- email: 'sj@email.zzz'
+ attributes: {
+ email: 'sj@email.zzz'
+ }
}
}
assert_response :unprocessable_entity
assert_equal 2, json_response['errors'].size
@@ -1694,11 +1826,13 @@
{
id: 3,
data: {
id: '3',
type: 'people',
- name: ''
+ attributes: {
+ name: ''
+ }
}
}
assert_response :unprocessable_entity
assert_equal 1, json_response['errors'].size
@@ -1721,11 +1855,11 @@
def test_valid_filter_value
get :index, {filter: {name: 'Joe Author'}}
assert_response :success
assert_equal json_response['data'].size, 1
assert_equal json_response['data'][0]['id'], '1'
- assert_equal json_response['data'][0]['name'], 'Joe Author'
+ assert_equal json_response['data'][0]['attributes']['name'], 'Joe Author'
end
def test_get_related_resource
JSONAPI.configuration.json_key_format = :dasherized_key
JSONAPI.configuration.route_format = :underscored_key
@@ -1734,35 +1868,47 @@
assert_hash_equals(
{
data: {
id: '1',
type: 'people',
- name: 'Joe Author',
- email: 'joe@xyz.fake',
- "date-joined" => '2013-08-07 16:25:00 -0400',
+ attributes: {
+ name: 'Joe Author',
+ email: 'joe@xyz.fake',
+ "date-joined" => '2013-08-07 16:25:00 -0400'
+ },
links: {
- self: 'http://test.host/people/1',
+ self: 'http://test.host/people/1'
+ },
+ relationships: {
comments: {
- self: 'http://test.host/people/1/links/comments',
- related: 'http://test.host/people/1/comments'
+ links: {
+ self: 'http://test.host/people/1/relationships/comments',
+ related: 'http://test.host/people/1/comments'
+ }
},
posts: {
- self: 'http://test.host/people/1/links/posts',
- related: 'http://test.host/people/1/posts'
+ links: {
+ self: 'http://test.host/people/1/relationships/posts',
+ related: 'http://test.host/people/1/posts'
+ }
},
preferences: {
- self: 'http://test.host/people/1/links/preferences',
- related: 'http://test.host/people/1/preferences',
- linkage: {
+ links: {
+ self: 'http://test.host/people/1/relationships/preferences',
+ related: 'http://test.host/people/1/preferences'
+ },
+ data: {
type: 'preferences',
id: '1'
}
},
"hair-cut" => {
- "self" => "http://test.host/people/1/links/hair_cut",
- "related" => "http://test.host/people/1/hair_cut",
- "linkage" => nil
+ "links" => {
+ "self" => "http://test.host/people/1/relationships/hair_cut",
+ "related" => "http://test.host/people/1/hair_cut"
+ },
+ "data" => nil
}
}
}
},
json_response
@@ -1785,39 +1931,39 @@
get :index, {filter: {id: '1'}}
assert_response :success
assert_equal 1, json_response['data'].size
assert_equal '1', json_response['data'][0]['id']
assert_equal 'authors', json_response['data'][0]['type']
- assert_equal 'Joe Author', json_response['data'][0]['name']
- assert_equal nil, json_response['data'][0]['email']
+ assert_equal 'Joe Author', json_response['data'][0]['attributes']['name']
+ assert_equal nil, json_response['data'][0]['attributes']['email']
end
def test_get_person_as_author_by_name_filter
get :index, {filter: {name: 'thor'}}
assert_response :success
assert_equal 3, json_response['data'].size
assert_equal '1', json_response['data'][0]['id']
- assert_equal 'Joe Author', json_response['data'][0]['name']
+ assert_equal 'Joe Author', json_response['data'][0]['attributes']['name']
end
end
class BreedsControllerTest < ActionController::TestCase
# Note: Breed names go through the TitleValueFormatter
def test_poro_index
get :index
assert_response :success
assert_equal '0', json_response['data'][0]['id']
- assert_equal 'Persian', json_response['data'][0]['name']
+ assert_equal 'Persian', json_response['data'][0]['attributes']['name']
end
def test_poro_show
get :show, {id: '0'}
assert_response :success
assert json_response['data'].is_a?(Hash)
assert_equal '0', json_response['data']['id']
- assert_equal 'Persian', json_response['data']['name']
+ assert_equal 'Persian', json_response['data']['attributes']['name']
end
def test_poro_show_multiple
get :show, {id: '0,2'}
@@ -1829,45 +1975,68 @@
set_content_type_header!
post :create,
{
data: {
type: 'breeds',
- name: 'tabby'
+ attributes: {
+ name: 'tabby'
+ }
}
}
- assert_response :created
+ assert_response :accepted
assert json_response['data'].is_a?(Hash)
- assert_equal 'Tabby', json_response['data']['name']
+ assert_equal 'Tabby', json_response['data']['attributes']['name']
end
+ def test_poro_create_validation_error
+ set_content_type_header!
+ post :create,
+ {
+ data: {
+ type: 'breeds',
+ attributes: {
+ name: ''
+ }
+ }
+ }
+
+ assert_equal 1, json_response['errors'].size
+ assert_equal JSONAPI::VALIDATION_ERROR, json_response['errors'][0]['code']
+ assert_match /name - can't be blank/, response.body
+ end
+
def test_poro_create_update
set_content_type_header!
post :create,
{
data: {
type: 'breeds',
- name: 'CALIC'
+ attributes: {
+ name: 'CALIC'
+ }
}
}
- assert_response :created
+ assert_response :accepted
assert json_response['data'].is_a?(Hash)
- assert_equal 'Calic', json_response['data']['name']
+ assert_equal 'Calic', json_response['data']['attributes']['name']
put :update,
{
id: json_response['data']['id'],
data: {
id: json_response['data']['id'],
type: 'breeds',
- name: 'calico'
+ attributes: {
+ name: 'calico'
+ }
}
}
assert_response :success
assert json_response['data'].is_a?(Hash)
- assert_equal 'Calico', json_response['data']['name']
+ assert_equal 'Calico', json_response['data']['attributes']['name']
end
def test_poro_delete
initial_count = $breed_data.breeds.keys.count
delete :destroy, {id: '3'}
@@ -1886,21 +2055,21 @@
class Api::V1::PostsControllerTest < ActionController::TestCase
def test_show_post_namespaced
get :show, {id: '1'}
assert_response :success
- assert_equal 'http://test.host/api/v1/posts/1/links/writer', json_response['data']['links']['writer']['self']
+ assert_equal 'http://test.host/api/v1/posts/1/relationships/writer', json_response['data']['relationships']['writer']['links']['self']
end
def test_show_post_namespaced_include
get :show, {id: '1', include: 'writer'}
assert_response :success
- assert_equal '1', json_response['data']['links']['writer']['linkage']['id']
- assert_nil json_response['data']['links']['tags']
+ assert_equal '1', json_response['data']['relationships']['writer']['data']['id']
+ assert_nil json_response['data']['relationships']['tags']
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']
+ assert_equal 'joe@xyz.fake', json_response['included'][0]['attributes']['email']
end
def test_index_filter_on_association_namespaced
get :index, {filter: {writer: '1'}}
assert_response :success
@@ -1909,33 +2078,35 @@
def test_sorting_desc_namespaced
get :index, {sort: '-title'}
assert_response :success
- assert_equal "Update This Later - Multiple", json_response['data'][0]['title']
+ assert_equal "Update This Later - Multiple", json_response['data'][0]['attributes']['title']
end
def test_create_simple_namespaced
set_content_type_header!
post :create,
{
data: {
type: 'posts',
- title: 'JR - now with Namespacing',
- body: 'JSONAPIResources is the greatest thing since unsliced bread now that it has namespaced resources.',
- links: {
- writer: { linkage: {type: 'writers', id: '3'}}
+ attributes: {
+ title: 'JR - now with Namespacing',
+ body: 'JSONAPIResources is the greatest thing since unsliced bread now that it has namespaced resources.'
+ },
+ relationships: {
+ writer: { data: {type: 'writers', id: '3'}}
}
}
}
assert_response :created
assert json_response['data'].is_a?(Hash)
- assert_equal '3', json_response['data']['links']['writer']['linkage']['id']
- assert_equal 'JR - now with Namespacing', json_response['data']['title']
+ assert_equal '3', json_response['data']['relationships']['writer']['data']['id']
+ assert_equal 'JR - now with Namespacing', json_response['data']['attributes']['title']
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread now that it has namespaced resources.',
- json_response['data']['body']
+ json_response['data']['attributes']['body']
end
end
class FactsControllerTest < ActionController::TestCase
@@ -1945,43 +2116,71 @@
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: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']
+ assert_equal 'Jane Author', json_response['data']['attributes']['spouseName']
+ assert_equal 'First man to run across Antartica.', json_response['data']['attributes']['bio']
+ assert_equal 23.89/45.6, json_response['data']['attributes']['qualityRating']
+ assert_equal '47000.56', json_response['data']['attributes']['salary']
+ assert_equal '2013-08-07T20:25:00Z', json_response['data']['attributes']['dateTimeJoined']
+ assert_equal '1965-06-30', json_response['data']['attributes']['birthday']
+ assert_equal '2000-01-01T20:00:00Z', json_response['data']['attributes']['bedtime']
+ assert_equal 'abc', json_response['data']['attributes']['photo']
+ assert_equal false, json_response['data']['attributes']['cool']
end
end
class Api::V2::BooksControllerTest < ActionController::TestCase
+ def setup
+ JSONAPI.configuration.json_key_format = :dasherized_key
+ end
+
def after_teardown
Api::V2::BookResource.paginator :offset
end
def test_books_offset_pagination_no_params
Api::V2::BookResource.paginator :offset
get :index
assert_response :success
assert_equal 10, json_response['data'].size
- assert_equal 'Book 0', json_response['data'][0]['title']
+ assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
end
+ def test_books_offset_pagination_no_params_includes_query_count_one_level
+ Api::V2::BookResource.paginator :offset
+
+ query_count = count_queries do
+ get :index, {include: 'book-comments'}
+ end
+ assert_response :success
+ assert_equal 10, json_response['data'].size
+ assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
+ assert_equal 2, query_count
+ end
+
+ def test_books_offset_pagination_no_params_includes_query_count_two_levels
+ Api::V2::BookResource.paginator :offset
+
+ query_count = count_queries do
+ get :index, {include: 'book-comments,book-comments.author'}
+ end
+ assert_response :success
+ assert_equal 10, json_response['data'].size
+ assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
+ assert_equal 3, query_count
+ end
+
def test_books_offset_pagination
Api::V2::BookResource.paginator :offset
get :index, {page: {offset: 50, limit: 12}}
assert_response :success
assert_equal 12, json_response['data'].size
- assert_equal 'Book 50', json_response['data'][0]['title']
+ assert_equal 'Book 50', json_response['data'][0]['attributes']['title']
end
def test_books_offset_pagination_bad_page_param
Api::V2::BookResource.paginator :offset
@@ -2004,10 +2203,18 @@
get :index, {page: {offset: 50, limit: -1}}
assert_response :bad_request
assert_match /-1 is not a valid value for limit page parameter./, json_response['errors'][0]['detail']
end
+ def test_books_offset_pagination_bad_param_offset_less_than_zero
+ Api::V2::BookResource.paginator :offset
+
+ get :index, {page: {offset: -1, limit: 20}}
+ assert_response :bad_request
+ assert_match /-1 is not a valid value for offset page parameter./, json_response['errors'][0]['detail']
+ end
+
def test_books_offset_pagination_invalid_page_format
Api::V2::BookResource.paginator :offset
get :index, {page: 50}
assert_response :bad_request
@@ -2018,29 +2225,29 @@
Api::V2::BookResource.paginator :paged
get :index
assert_response :success
assert_equal 10, json_response['data'].size
- assert_equal 'Book 0', json_response['data'][0]['title']
+ assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
end
def test_books_paged_pagination_no_page
Api::V2::BookResource.paginator :paged
get :index, {page: {size: 12}}
assert_response :success
assert_equal 12, json_response['data'].size
- assert_equal 'Book 0', json_response['data'][0]['title']
+ assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
end
def test_books_paged_pagination
Api::V2::BookResource.paginator :paged
get :index, {page: {number: 3, size: 12}}
assert_response :success
assert_equal 12, json_response['data'].size
- assert_equal 'Book 24', json_response['data'][0]['title']
+ assert_equal 'Book 24', json_response['data'][0]['attributes']['title']
end
def test_books_paged_pagination_bad_page_param
Api::V2::BookResource.paginator :paged
@@ -2063,23 +2270,92 @@
get :index, {page: {number: 50, size: -1}}
assert_response :bad_request
assert_match /-1 is not a valid value for size page parameter./, json_response['errors'][0]['detail']
end
- def test_books_paged_pagination_invalid_page_format_interpret_int_text
+ def test_books_paged_pagination_invalid_page_format_incorrect
Api::V2::BookResource.paginator :paged
get :index, {page: 'qwerty'}
- assert_response :success
- assert_equal 10, json_response['data'].size
- assert_equal 'Book 0', json_response['data'][0]['title']
+ assert_response :bad_request
+ assert_match /0 is not a valid value for number page parameter./, json_response['errors'][0]['detail']
end
def test_books_paged_pagination_invalid_page_format_interpret_int
Api::V2::BookResource.paginator :paged
get :index, {page: 3}
assert_response :success
assert_equal 10, json_response['data'].size
- assert_equal 'Book 20', json_response['data'][0]['title']
+ assert_equal 'Book 20', json_response['data'][0]['attributes']['title']
end
end
+
+class Api::V4::BooksControllerTest < ActionController::TestCase
+ def setup
+ JSONAPI.configuration.json_key_format = :camelized_key
+ end
+
+ def test_books_offset_pagination_meta
+ JSONAPI.configuration.operations_processor = :counting_active_record
+ Api::V4::BookResource.paginator :offset
+ get :index, {page: {offset: 50, limit: 12}}
+ assert_response :success
+ assert_equal 12, json_response['data'].size
+ assert_equal 'Book 50', json_response['data'][0]['attributes']['title']
+ assert_equal 1000, json_response['meta']['totalRecords']
+ JSONAPI.configuration.operations_processor = :active_record
+ end
+end
+
+class CategoriesControllerTest < ActionController::TestCase
+ def test_index_default_filter
+ get :index
+ assert_response :success
+ assert json_response['data'].is_a?(Array)
+ assert_equal 3, json_response['data'].size
+ end
+
+ def test_index_default_filter_override
+ get :index, { filter: { status: 'inactive' } }
+ assert_response :success
+ assert json_response['data'].is_a?(Array)
+ assert_equal 4, json_response['data'].size
+ end
+end
+
+class Api::V1::PlanetsControllerTest < ActionController::TestCase
+ def test_save_model_callbacks
+ set_content_type_header!
+ post :create,
+ {
+ data: {
+ type: 'planets',
+ attributes: {
+ name: 'Zeus',
+ description: 'The largest planet in the solar system. Discovered in 2015.'
+ }
+ }
+ }
+
+ assert_response :created
+ assert json_response['data'].is_a?(Hash)
+ assert_equal 'Zeus', json_response['data']['attributes']['name']
+ end
+
+ def test_save_model_callbacks_fail
+ set_content_type_header!
+ post :create,
+ {
+ data: {
+ type: 'planets',
+ attributes: {
+ name: 'Pluto',
+ description: 'Yes, it is a planet.'
+ }
+ }
+ }
+
+ assert_response :unprocessable_entity
+ assert_match /Save failed or was cancelled/, json_response['errors'][0]['detail']
+ end
+end
\ No newline at end of file