jsonapi-resources 0.7.1.beta1 → 0.7.1.beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +248 -74
- data/lib/jsonapi-resources.rb +5 -3
- data/lib/jsonapi/acts_as_resource_controller.rb +77 -14
- data/lib/jsonapi/configuration.rb +77 -16
- data/lib/jsonapi/error.rb +12 -0
- data/lib/jsonapi/error_codes.rb +2 -0
- data/lib/jsonapi/exceptions.rb +29 -9
- data/lib/jsonapi/formatter.rb +29 -4
- data/lib/jsonapi/link_builder.rb +18 -18
- data/lib/jsonapi/mime_types.rb +25 -6
- data/lib/jsonapi/naive_cache.rb +30 -0
- data/lib/jsonapi/operation.rb +10 -342
- data/lib/jsonapi/operation_dispatcher.rb +87 -0
- data/lib/jsonapi/operation_result.rb +2 -1
- data/lib/jsonapi/paginator.rb +6 -2
- data/lib/jsonapi/processor.rb +283 -0
- data/lib/jsonapi/relationship.rb +6 -4
- data/lib/jsonapi/{request.rb → request_parser.rb} +46 -35
- data/lib/jsonapi/resource.rb +88 -13
- data/lib/jsonapi/resource_controller.rb +2 -14
- data/lib/jsonapi/resource_controller_metal.rb +17 -0
- data/lib/jsonapi/resource_serializer.rb +62 -47
- data/lib/jsonapi/resources/version.rb +1 -1
- data/lib/jsonapi/response_document.rb +13 -2
- data/lib/jsonapi/routing_ext.rb +49 -11
- metadata +37 -129
- data/.gitignore +0 -22
- data/.travis.yml +0 -9
- data/Gemfile +0 -23
- data/Rakefile +0 -20
- data/jsonapi-resources.gemspec +0 -29
- data/lib/jsonapi/active_record_operations_processor.rb +0 -35
- data/lib/jsonapi/operations_processor.rb +0 -120
- data/locales/en.yml +0 -80
- data/test/config/database.yml +0 -5
- data/test/controllers/controller_test.rb +0 -3312
- data/test/fixtures/active_record.rb +0 -1486
- data/test/fixtures/author_details.yml +0 -9
- data/test/fixtures/book_authors.yml +0 -3
- data/test/fixtures/book_comments.yml +0 -12
- data/test/fixtures/books.yml +0 -7
- data/test/fixtures/categories.yml +0 -35
- data/test/fixtures/comments.yml +0 -21
- data/test/fixtures/comments_tags.yml +0 -20
- data/test/fixtures/companies.yml +0 -4
- data/test/fixtures/craters.yml +0 -9
- data/test/fixtures/customers.yml +0 -11
- data/test/fixtures/documents.yml +0 -3
- data/test/fixtures/expense_entries.yml +0 -13
- data/test/fixtures/facts.yml +0 -11
- data/test/fixtures/hair_cuts.yml +0 -3
- data/test/fixtures/iso_currencies.yml +0 -17
- data/test/fixtures/line_items.yml +0 -37
- data/test/fixtures/makes.yml +0 -2
- data/test/fixtures/moons.yml +0 -6
- data/test/fixtures/numeros_telefone.yml +0 -3
- data/test/fixtures/order_flags.yml +0 -7
- data/test/fixtures/people.yml +0 -31
- data/test/fixtures/pictures.yml +0 -15
- data/test/fixtures/planet_types.yml +0 -19
- data/test/fixtures/planets.yml +0 -47
- data/test/fixtures/posts.yml +0 -102
- data/test/fixtures/posts_tags.yml +0 -59
- data/test/fixtures/preferences.yml +0 -14
- data/test/fixtures/products.yml +0 -3
- data/test/fixtures/purchase_orders.yml +0 -23
- data/test/fixtures/sections.yml +0 -8
- data/test/fixtures/tags.yml +0 -39
- data/test/fixtures/vehicles.yml +0 -17
- data/test/fixtures/web_pages.yml +0 -3
- data/test/helpers/assertions.rb +0 -13
- data/test/helpers/functional_helpers.rb +0 -59
- data/test/helpers/value_matchers.rb +0 -60
- data/test/helpers/value_matchers_test.rb +0 -40
- data/test/integration/requests/namespaced_model_test.rb +0 -13
- data/test/integration/requests/request_test.rb +0 -932
- data/test/integration/routes/routes_test.rb +0 -218
- data/test/integration/sti_fields_test.rb +0 -18
- data/test/lib/generators/jsonapi/controller_generator_test.rb +0 -25
- data/test/lib/generators/jsonapi/resource_generator_test.rb +0 -30
- data/test/test_helper.rb +0 -342
- data/test/unit/formatters/dasherized_key_formatter_test.rb +0 -8
- data/test/unit/jsonapi_request/jsonapi_request_test.rb +0 -199
- data/test/unit/operation/operations_processor_test.rb +0 -528
- data/test/unit/pagination/offset_paginator_test.rb +0 -245
- data/test/unit/pagination/paged_paginator_test.rb +0 -242
- data/test/unit/resource/resource_test.rb +0 -560
- data/test/unit/serializer/include_directives_test.rb +0 -113
- data/test/unit/serializer/link_builder_test.rb +0 -244
- data/test/unit/serializer/polymorphic_serializer_test.rb +0 -383
- data/test/unit/serializer/response_document_test.rb +0 -61
- data/test/unit/serializer/serializer_test.rb +0 -1939
@@ -1,35 +0,0 @@
|
|
1
|
-
class ActiveRecordOperationsProcessor < JSONAPI::OperationsProcessor
|
2
|
-
private
|
3
|
-
|
4
|
-
def transaction
|
5
|
-
if @transactional
|
6
|
-
ActiveRecord::Base.transaction do
|
7
|
-
yield
|
8
|
-
end
|
9
|
-
else
|
10
|
-
yield
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def rollback
|
15
|
-
fail ActiveRecord::Rollback if @transactional
|
16
|
-
end
|
17
|
-
|
18
|
-
# Catch errors that should be handled before JSONAPI::Exceptions::Error
|
19
|
-
# and other unprocessed exceptions
|
20
|
-
def process_operation(operation)
|
21
|
-
with_default_handling do
|
22
|
-
begin
|
23
|
-
operation.apply
|
24
|
-
rescue ActiveRecord::DeleteRestrictionError => e
|
25
|
-
record_locked_error = JSONAPI::Exceptions::RecordLocked.new(e.message)
|
26
|
-
return JSONAPI::ErrorsOperationResult.new(record_locked_error.errors[0].code, record_locked_error.errors)
|
27
|
-
|
28
|
-
rescue ActiveRecord::RecordNotFound
|
29
|
-
key = operation.respond_to?(:associated_key) ? operation.associated_key : :unavailable
|
30
|
-
record_not_found = JSONAPI::Exceptions::RecordNotFound.new(key)
|
31
|
-
return JSONAPI::ErrorsOperationResult.new(record_not_found.errors[0].code, record_not_found.errors)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,120 +0,0 @@
|
|
1
|
-
module JSONAPI
|
2
|
-
class OperationsProcessor
|
3
|
-
include Callbacks
|
4
|
-
define_jsonapi_resources_callbacks :operation,
|
5
|
-
:operations,
|
6
|
-
:find_operation,
|
7
|
-
:show_operation,
|
8
|
-
:show_relationship_operation,
|
9
|
-
:show_related_resource_operation,
|
10
|
-
:show_related_resources_operation,
|
11
|
-
:create_resource_operation,
|
12
|
-
:remove_resource_operation,
|
13
|
-
:replace_fields_operation,
|
14
|
-
:replace_to_one_relationship_operation,
|
15
|
-
:replace_polymorphic_to_one_relationship_operation,
|
16
|
-
:create_to_many_relationship_operation,
|
17
|
-
:replace_to_many_relationship_operation,
|
18
|
-
:remove_to_many_relationship_operation,
|
19
|
-
:remove_to_one_relationship_operation
|
20
|
-
|
21
|
-
class << self
|
22
|
-
def operations_processor_for(operations_processor)
|
23
|
-
operations_processor_class_name = "#{operations_processor.to_s.camelize}OperationsProcessor"
|
24
|
-
operations_processor_class_name.safe_constantize
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def process(request)
|
29
|
-
@results = JSONAPI::OperationResults.new
|
30
|
-
@request = request
|
31
|
-
@operations = request.operations
|
32
|
-
|
33
|
-
# Use transactions if more than one operation and if one of the operations can be transactional
|
34
|
-
# Even if transactional transactions won't be used unless the derived OperationsProcessor supports them.
|
35
|
-
@transactional = false
|
36
|
-
@operations.each do |operation|
|
37
|
-
@transactional |= operation.transactional
|
38
|
-
end
|
39
|
-
|
40
|
-
run_callbacks :operations do
|
41
|
-
transaction do
|
42
|
-
# Links and meta data global to the set of operations
|
43
|
-
@operations_meta = {}
|
44
|
-
@operations_links = {}
|
45
|
-
@operations.each do |operation|
|
46
|
-
@operation = operation
|
47
|
-
# Links and meta data for each operation
|
48
|
-
@operation_meta = {}
|
49
|
-
@operation_links = {}
|
50
|
-
run_callbacks :operation do
|
51
|
-
@result = nil
|
52
|
-
run_callbacks @operation.class.name.demodulize.underscore.to_sym do
|
53
|
-
@result = process_operation(@operation)
|
54
|
-
end
|
55
|
-
@result.meta.merge!(@operation_meta)
|
56
|
-
@result.links.merge!(@operation_links)
|
57
|
-
@results.add_result(@result)
|
58
|
-
rollback if @results.has_errors?
|
59
|
-
end
|
60
|
-
end
|
61
|
-
@results.meta = @operations_meta
|
62
|
-
@results.links = @operations_links
|
63
|
-
end
|
64
|
-
end
|
65
|
-
@results
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
|
70
|
-
# The base OperationsProcessor provides no transaction support
|
71
|
-
# Override the transaction and rollback methods to provide transaction support.
|
72
|
-
# For ActiveRecord transactions you can use the ActiveRecordOperationsProcessor
|
73
|
-
def transaction
|
74
|
-
yield
|
75
|
-
end
|
76
|
-
|
77
|
-
def rollback
|
78
|
-
end
|
79
|
-
|
80
|
-
# If overriding in child operation processors, call operation.apply and
|
81
|
-
# catch errors that should be handled before JSONAPI::Exceptions::Error
|
82
|
-
# and other unprocessed exceptions
|
83
|
-
def process_operation(operation)
|
84
|
-
with_default_handling do
|
85
|
-
operation.apply
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def with_default_handling(&block)
|
90
|
-
yield
|
91
|
-
rescue JSONAPI::Exceptions::Error => e
|
92
|
-
raise e
|
93
|
-
|
94
|
-
rescue => e
|
95
|
-
if JSONAPI.configuration.exception_class_whitelist.any? { |k| e.class.ancestors.include?(k) }
|
96
|
-
raise e
|
97
|
-
else
|
98
|
-
@request.server_error_callbacks.each { |callback| safe_run_callback(callback, e) }
|
99
|
-
|
100
|
-
internal_server_error = JSONAPI::Exceptions::InternalServerError.new(e)
|
101
|
-
Rails.logger.error { "Internal Server Error: #{e.message} #{e.backtrace.join("\n")}" }
|
102
|
-
return JSONAPI::ErrorsOperationResult.new(internal_server_error.errors[0].code, internal_server_error.errors)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def safe_run_callback(callback, error)
|
107
|
-
begin
|
108
|
-
callback.call(error)
|
109
|
-
rescue => e
|
110
|
-
Rails.logger.error { "Error in error handling callback: #{e.message} #{e.backtrace.join("\n")}" }
|
111
|
-
internal_server_error = JSONAPI::Exceptions::InternalServerError.new(e)
|
112
|
-
return JSONAPI::ErrorsOperationResult.new(internal_server_error.errors[0].code, internal_server_error.errors)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
class BasicOperationsProcessor < JSONAPI::OperationsProcessor
|
120
|
-
end
|
data/locales/en.yml
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
en:
|
2
|
-
jsonapi-resources:
|
3
|
-
exceptions:
|
4
|
-
internal_server_error:
|
5
|
-
title: 'Internal Server Error'
|
6
|
-
detail: 'Internal Server Error'
|
7
|
-
invalid_resource:
|
8
|
-
title: 'Invalid resource'
|
9
|
-
detail: "%{resource} is not a valid resource."
|
10
|
-
record_not_found:
|
11
|
-
title: 'Record not found'
|
12
|
-
detail: "The record identified by %{id} could not be found."
|
13
|
-
unsupported_media_type:
|
14
|
-
title: 'Unsupported media type'
|
15
|
-
detail: "All requests that create or update must use the '%{needed_media_type}' Content-Type. This request specified '%{media_type}.'"
|
16
|
-
has_many_relation:
|
17
|
-
title: 'Relation exists'
|
18
|
-
detail: "The relation to %{id} already exists."
|
19
|
-
to_many_set_replacement_forbidden:
|
20
|
-
title: 'Complete replacement forbidden'
|
21
|
-
detail: 'Complete replacement forbidden for this relationship'
|
22
|
-
invalid_filter_syntax:
|
23
|
-
title: 'Invalid filters syntax'
|
24
|
-
detail: "%{filters} is not a valid syntax for filtering."
|
25
|
-
filter_not_allowed:
|
26
|
-
title: "Filter not allowed"
|
27
|
-
detail: "%{filter} is not allowed."
|
28
|
-
invalid_filter_value:
|
29
|
-
title: 'Invalid filter value'
|
30
|
-
detail: "%{value} is not a valid value for %{filter}."
|
31
|
-
invalid_field_value:
|
32
|
-
title: 'Invalid field value'
|
33
|
-
detail: "%{value} is not a valid value for %{field}."
|
34
|
-
invalid_field_format:
|
35
|
-
title: 'Invalid field format'
|
36
|
-
detail: 'Fields must specify a type.'
|
37
|
-
invalid_links_object:
|
38
|
-
title: 'Invalid Links Object'
|
39
|
-
detail: 'Data is not a valid Links Object.'
|
40
|
-
type_mismatch:
|
41
|
-
title: 'Type Mismatch'
|
42
|
-
detail: "%{type} is not a valid type for this operation."
|
43
|
-
invalid_field:
|
44
|
-
title: 'Invalid field'
|
45
|
-
detail: "%{field} is not a valid field for %{type}."
|
46
|
-
invalid_include:
|
47
|
-
title: 'Invalid field'
|
48
|
-
detail: "%{relationship} is not a valid relationship of %{resource}"
|
49
|
-
invalid_sort_criteria:
|
50
|
-
title: 'Invalid sort criteria'
|
51
|
-
detail: "%{sort_criteria} is not a valid sort criteria for %{resource}"
|
52
|
-
parameters_not_allowed:
|
53
|
-
title: 'Param not allowed'
|
54
|
-
detail: "%{param} is not allowed."
|
55
|
-
parameter_missing:
|
56
|
-
title: 'Missing Parameter'
|
57
|
-
detail: "The required parameter, %{param}, is missing."
|
58
|
-
count_mismatch:
|
59
|
-
title: 'Count to key mismatch'
|
60
|
-
detail: 'The resource collection does not contain the same number of objects as the number of keys.'
|
61
|
-
key_not_included_in_url:
|
62
|
-
title: 'Key is not included in URL'
|
63
|
-
detail: "The URL does not support the key %{key}"
|
64
|
-
missing_key:
|
65
|
-
title: 'A key is required'
|
66
|
-
detail: 'The resource object does not contain a key.'
|
67
|
-
record_locked:
|
68
|
-
title: 'Locked resource'
|
69
|
-
save_failed:
|
70
|
-
title: 'Save failed or was cancelled'
|
71
|
-
detail: 'Save failed or was cancelled'
|
72
|
-
invalid_page_object:
|
73
|
-
title: 'Invalid Page Object'
|
74
|
-
detail: 'Invalid Page Object.'
|
75
|
-
page_parameters_not_allowed:
|
76
|
-
title: 'Page parameter not allowed'
|
77
|
-
detail: "%{param} is not an allowed page parameter."
|
78
|
-
invalid_page_value:
|
79
|
-
title: 'Invalid page value'
|
80
|
-
detail: "%{value} is not a valid value for %{page} page parameter."
|
data/test/config/database.yml
DELETED
@@ -1,3312 +0,0 @@
|
|
1
|
-
require File.expand_path('../../test_helper', __FILE__)
|
2
|
-
|
3
|
-
def set_content_type_header!
|
4
|
-
@request.headers['Content-Type'] = JSONAPI::MEDIA_TYPE
|
5
|
-
end
|
6
|
-
|
7
|
-
class PostsControllerTest < ActionController::TestCase
|
8
|
-
def setup
|
9
|
-
JSONAPI.configuration.raise_if_parameters_not_allowed = true
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_index
|
13
|
-
get :index
|
14
|
-
assert_response :success
|
15
|
-
assert json_response['data'].is_a?(Array)
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_exception_class_whitelist
|
19
|
-
original_config = JSONAPI.configuration.dup
|
20
|
-
JSONAPI.configuration.operations_processor = :error_raising
|
21
|
-
# test that the operations processor rescues the error when it
|
22
|
-
# has not been added to the exception_class_whitelist
|
23
|
-
get :index
|
24
|
-
assert_response 500
|
25
|
-
# test that the operations processor does not rescue the error when it
|
26
|
-
# has been added to the exception_class_whitelist
|
27
|
-
JSONAPI.configuration.exception_class_whitelist << PostsController::SpecialError
|
28
|
-
get :index
|
29
|
-
assert_response 403
|
30
|
-
ensure
|
31
|
-
JSONAPI.configuration = original_config
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_on_server_error_block_callback_with_exception
|
35
|
-
original_config = JSONAPI.configuration.dup
|
36
|
-
JSONAPI.configuration.operations_processor = :error_raising
|
37
|
-
JSONAPI.configuration.exception_class_whitelist = []
|
38
|
-
|
39
|
-
@controller.class.instance_variable_set(:@callback_message, "none")
|
40
|
-
BaseController.on_server_error do
|
41
|
-
@controller.class.instance_variable_set(:@callback_message, "Sent from block")
|
42
|
-
end
|
43
|
-
|
44
|
-
get :index
|
45
|
-
assert_equal @controller.class.instance_variable_get(:@callback_message), "Sent from block"
|
46
|
-
|
47
|
-
# test that it renders the default server error response
|
48
|
-
assert_equal "Internal Server Error", json_response['errors'][0]['title']
|
49
|
-
assert_equal "Internal Server Error", json_response['errors'][0]['detail']
|
50
|
-
ensure
|
51
|
-
JSONAPI.configuration = original_config
|
52
|
-
end
|
53
|
-
|
54
|
-
def test_on_server_error_method_callback_with_exception
|
55
|
-
original_config = JSONAPI.configuration.dup
|
56
|
-
JSONAPI.configuration.operations_processor = :error_raising
|
57
|
-
JSONAPI.configuration.exception_class_whitelist = []
|
58
|
-
|
59
|
-
#ignores methods that don't exist
|
60
|
-
@controller.class.on_server_error :set_callback_message, :a_bogus_method
|
61
|
-
@controller.class.instance_variable_set(:@callback_message, "none")
|
62
|
-
|
63
|
-
get :index
|
64
|
-
assert_equal @controller.class.instance_variable_get(:@callback_message), "Sent from method"
|
65
|
-
|
66
|
-
# test that it renders the default server error response
|
67
|
-
assert_equal "Internal Server Error", json_response['errors'][0]['title']
|
68
|
-
ensure
|
69
|
-
JSONAPI.configuration = original_config
|
70
|
-
end
|
71
|
-
|
72
|
-
def test_on_server_error_callback_without_exception
|
73
|
-
|
74
|
-
callback = Proc.new { @controller.class.instance_variable_set(:@callback_message, "Sent from block") }
|
75
|
-
@controller.class.on_server_error callback
|
76
|
-
@controller.class.instance_variable_set(:@callback_message, "none")
|
77
|
-
|
78
|
-
get :index
|
79
|
-
assert_equal @controller.class.instance_variable_get(:@callback_message), "none"
|
80
|
-
|
81
|
-
# test that it does not render error
|
82
|
-
assert json_response.key?('data')
|
83
|
-
end
|
84
|
-
|
85
|
-
def test_index_filter_with_empty_result
|
86
|
-
get :index, {filter: {title: 'post that does not exist'}}
|
87
|
-
assert_response :success
|
88
|
-
assert json_response['data'].is_a?(Array)
|
89
|
-
assert_equal 0, json_response['data'].size
|
90
|
-
end
|
91
|
-
|
92
|
-
def test_index_filter_by_id
|
93
|
-
get :index, {filter: {id: '1'}}
|
94
|
-
assert_response :success
|
95
|
-
assert json_response['data'].is_a?(Array)
|
96
|
-
assert_equal 1, json_response['data'].size
|
97
|
-
end
|
98
|
-
|
99
|
-
def test_index_filter_by_title
|
100
|
-
get :index, {filter: {title: 'New post'}}
|
101
|
-
assert_response :success
|
102
|
-
assert json_response['data'].is_a?(Array)
|
103
|
-
assert_equal 1, json_response['data'].size
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_index_filter_by_ids
|
107
|
-
get :index, {filter: {ids: '1,2'}}
|
108
|
-
assert_response :success
|
109
|
-
assert json_response['data'].is_a?(Array)
|
110
|
-
assert_equal 2, json_response['data'].size
|
111
|
-
end
|
112
|
-
|
113
|
-
def test_index_filter_by_ids_and_include_related
|
114
|
-
get :index, {filter: {id: '2'}, include: 'comments'}
|
115
|
-
assert_response :success
|
116
|
-
assert_equal 1, json_response['data'].size
|
117
|
-
assert_equal 1, json_response['included'].size
|
118
|
-
end
|
119
|
-
|
120
|
-
def test_index_filter_by_ids_and_include_related_different_type
|
121
|
-
get :index, {filter: {id: '1,2'}, include: 'author'}
|
122
|
-
assert_response :success
|
123
|
-
assert_equal 2, json_response['data'].size
|
124
|
-
assert_equal 1, json_response['included'].size
|
125
|
-
end
|
126
|
-
|
127
|
-
def test_index_filter_not_allowed
|
128
|
-
JSONAPI.configuration.allow_filter = false
|
129
|
-
get :index, {filter: {id: '1'}}
|
130
|
-
assert_response :bad_request
|
131
|
-
ensure
|
132
|
-
JSONAPI.configuration.allow_filter = true
|
133
|
-
end
|
134
|
-
|
135
|
-
def test_index_include_one_level_query_count
|
136
|
-
count_queries do
|
137
|
-
get :index, {include: 'author'}
|
138
|
-
end
|
139
|
-
assert_response :success
|
140
|
-
assert_query_count(2)
|
141
|
-
end
|
142
|
-
|
143
|
-
def test_index_include_two_levels_query_count
|
144
|
-
count_queries do
|
145
|
-
get :index, {include: 'author,author.comments'}
|
146
|
-
end
|
147
|
-
assert_response :success
|
148
|
-
assert_query_count(3)
|
149
|
-
end
|
150
|
-
|
151
|
-
def test_index_filter_by_ids_and_fields
|
152
|
-
get :index, {filter: {id: '1,2'}, fields: {posts: 'id,title,author'}}
|
153
|
-
assert_response :success
|
154
|
-
assert_equal 2, json_response['data'].size
|
155
|
-
|
156
|
-
# type, id, links, attributes, relationships
|
157
|
-
assert_equal 5, json_response['data'][0].size
|
158
|
-
assert json_response['data'][0].key?('type')
|
159
|
-
assert json_response['data'][0].key?('id')
|
160
|
-
assert json_response['data'][0]['attributes'].key?('title')
|
161
|
-
assert json_response['data'][0].key?('links')
|
162
|
-
end
|
163
|
-
|
164
|
-
def test_index_filter_by_ids_and_fields_specify_type
|
165
|
-
get :index, {filter: {id: '1,2'}, 'fields' => {'posts' => 'id,title,author'}}
|
166
|
-
assert_response :success
|
167
|
-
assert_equal 2, json_response['data'].size
|
168
|
-
|
169
|
-
# type, id, links, attributes, relationships
|
170
|
-
assert_equal 5, json_response['data'][0].size
|
171
|
-
assert json_response['data'][0].key?('type')
|
172
|
-
assert json_response['data'][0].key?('id')
|
173
|
-
assert json_response['data'][0]['attributes'].key?('title')
|
174
|
-
assert json_response['data'][0].key?('links')
|
175
|
-
end
|
176
|
-
|
177
|
-
def test_index_filter_by_ids_and_fields_specify_unrelated_type
|
178
|
-
get :index, {filter: {id: '1,2'}, 'fields' => {'currencies' => 'code'}}
|
179
|
-
assert_response :bad_request
|
180
|
-
assert_match /currencies is not a valid resource./, json_response['errors'][0]['detail']
|
181
|
-
end
|
182
|
-
|
183
|
-
def test_index_filter_by_ids_and_fields_2
|
184
|
-
get :index, {filter: {id: '1,2'}, fields: {posts: 'author'}}
|
185
|
-
assert_response :success
|
186
|
-
assert_equal 2, json_response['data'].size
|
187
|
-
|
188
|
-
# type, id, links, relationships
|
189
|
-
assert_equal 4, json_response['data'][0].size
|
190
|
-
assert json_response['data'][0].key?('type')
|
191
|
-
assert json_response['data'][0].key?('id')
|
192
|
-
assert json_response['data'][0]['relationships'].key?('author')
|
193
|
-
end
|
194
|
-
|
195
|
-
def test_filter_relationship_single
|
196
|
-
count_queries do
|
197
|
-
get :index, {filter: {tags: '5,1'}}
|
198
|
-
end
|
199
|
-
assert_query_count(1)
|
200
|
-
assert_response :success
|
201
|
-
assert_equal 3, json_response['data'].size
|
202
|
-
assert_match /New post/, response.body
|
203
|
-
assert_match /JR Solves your serialization woes!/, response.body
|
204
|
-
assert_match /JR How To/, response.body
|
205
|
-
end
|
206
|
-
|
207
|
-
def test_filter_relationships_multiple
|
208
|
-
count_queries do
|
209
|
-
get :index, {filter: {tags: '5,1', comments: '3'}}
|
210
|
-
end
|
211
|
-
assert_query_count(1)
|
212
|
-
assert_response :success
|
213
|
-
assert_equal 1, json_response['data'].size
|
214
|
-
assert_match /JR Solves your serialization woes!/, response.body
|
215
|
-
end
|
216
|
-
|
217
|
-
def test_filter_relationships_multiple_not_found
|
218
|
-
get :index, {filter: {tags: '1', comments: '3'}}
|
219
|
-
assert_response :success
|
220
|
-
assert_equal 0, json_response['data'].size
|
221
|
-
end
|
222
|
-
|
223
|
-
def test_bad_filter
|
224
|
-
get :index, {filter: {post_ids: '1,2'}}
|
225
|
-
assert_response :bad_request
|
226
|
-
assert_match /post_ids is not allowed/, response.body
|
227
|
-
end
|
228
|
-
|
229
|
-
def test_bad_filter_value_not_integer_array
|
230
|
-
get :index, {filter: {id: 'asdfg'}}
|
231
|
-
assert_response :bad_request
|
232
|
-
assert_match /asdfg is not a valid value for id/, response.body
|
233
|
-
end
|
234
|
-
|
235
|
-
def test_bad_filter_value_not_integer
|
236
|
-
get :index, {filter: {id: 'asdfg'}}
|
237
|
-
assert_response :bad_request
|
238
|
-
assert_match /asdfg is not a valid value for id/, response.body
|
239
|
-
end
|
240
|
-
|
241
|
-
def test_bad_filter_value_not_found_array
|
242
|
-
get :index, {filter: {id: '5412333'}}
|
243
|
-
assert_response :not_found
|
244
|
-
assert_match /5412333 could not be found/, response.body
|
245
|
-
end
|
246
|
-
|
247
|
-
def test_bad_filter_value_not_found
|
248
|
-
get :index, {filter: {id: '5412333'}}
|
249
|
-
assert_response :not_found
|
250
|
-
assert_match /5412333 could not be found/, json_response['errors'][0]['detail']
|
251
|
-
end
|
252
|
-
|
253
|
-
def test_field_not_supported
|
254
|
-
get :index, {filter: {id: '1,2'}, 'fields' => {'posts' => 'id,title,rank,author'}}
|
255
|
-
assert_response :bad_request
|
256
|
-
assert_match /rank is not a valid field for posts./, json_response['errors'][0]['detail']
|
257
|
-
end
|
258
|
-
|
259
|
-
def test_resource_not_supported
|
260
|
-
get :index, {filter: {id: '1,2'}, 'fields' => {'posters' => 'id,title'}}
|
261
|
-
assert_response :bad_request
|
262
|
-
assert_match /posters is not a valid resource./, json_response['errors'][0]['detail']
|
263
|
-
end
|
264
|
-
|
265
|
-
def test_index_filter_on_relationship
|
266
|
-
get :index, {filter: {author: '1'}}
|
267
|
-
assert_response :success
|
268
|
-
assert_equal 3, json_response['data'].size
|
269
|
-
end
|
270
|
-
|
271
|
-
def test_sorting_blank
|
272
|
-
get :index, {sort: ''}
|
273
|
-
|
274
|
-
assert_response :success
|
275
|
-
end
|
276
|
-
|
277
|
-
def test_sorting_asc
|
278
|
-
get :index, {sort: 'title'}
|
279
|
-
|
280
|
-
assert_response :success
|
281
|
-
assert_equal "A First Post", json_response['data'][0]['attributes']['title']
|
282
|
-
end
|
283
|
-
|
284
|
-
def test_sorting_desc
|
285
|
-
get :index, {sort: '-title'}
|
286
|
-
|
287
|
-
assert_response :success
|
288
|
-
assert_equal "Update This Later - Multiple", json_response['data'][0]['attributes']['title']
|
289
|
-
end
|
290
|
-
|
291
|
-
def test_sorting_by_multiple_fields
|
292
|
-
get :index, {sort: 'title,body'}
|
293
|
-
|
294
|
-
assert_response :success
|
295
|
-
assert_equal '14', json_response['data'][0]['id']
|
296
|
-
end
|
297
|
-
|
298
|
-
def test_invalid_sort_param
|
299
|
-
get :index, {sort: 'asdfg'}
|
300
|
-
|
301
|
-
assert_response :bad_request
|
302
|
-
assert_match /asdfg is not a valid sort criteria for post/, response.body
|
303
|
-
end
|
304
|
-
|
305
|
-
def test_show_single_with_sort_disallowed
|
306
|
-
JSONAPI.configuration.allow_sort = false
|
307
|
-
get :index, {sort: 'title,body'}
|
308
|
-
assert_response :bad_request
|
309
|
-
ensure
|
310
|
-
JSONAPI.configuration.allow_sort = true
|
311
|
-
end
|
312
|
-
|
313
|
-
def test_excluded_sort_param
|
314
|
-
get :index, {sort: 'id'}
|
315
|
-
|
316
|
-
assert_response :bad_request
|
317
|
-
assert_match /id is not a valid sort criteria for post/, response.body
|
318
|
-
end
|
319
|
-
|
320
|
-
def test_show_single
|
321
|
-
get :show, {id: '1'}
|
322
|
-
assert_response :success
|
323
|
-
assert json_response['data'].is_a?(Hash)
|
324
|
-
assert_equal 'New post', json_response['data']['attributes']['title']
|
325
|
-
assert_equal 'A body!!!', json_response['data']['attributes']['body']
|
326
|
-
assert_nil json_response['included']
|
327
|
-
end
|
328
|
-
|
329
|
-
def test_show_does_not_include_records_count_in_meta
|
330
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
331
|
-
get :show, { id: Post.first.id }
|
332
|
-
assert_response :success
|
333
|
-
assert_equal json_response['meta'], nil
|
334
|
-
ensure
|
335
|
-
JSONAPI.configuration.top_level_meta_include_record_count = false
|
336
|
-
end
|
337
|
-
|
338
|
-
def test_show_single_with_includes
|
339
|
-
get :show, {id: '1', include: 'comments'}
|
340
|
-
assert_response :success
|
341
|
-
assert json_response['data'].is_a?(Hash)
|
342
|
-
assert_equal 'New post', json_response['data']['attributes']['title']
|
343
|
-
assert_equal 'A body!!!', json_response['data']['attributes']['body']
|
344
|
-
assert_nil json_response['data']['relationships']['tags']['data']
|
345
|
-
assert matches_array?([{'type' => 'comments', 'id' => '1'}, {'type' => 'comments', 'id' => '2'}],
|
346
|
-
json_response['data']['relationships']['comments']['data'])
|
347
|
-
assert_equal 2, json_response['included'].size
|
348
|
-
end
|
349
|
-
|
350
|
-
def test_show_single_with_include_disallowed
|
351
|
-
JSONAPI.configuration.allow_include = false
|
352
|
-
get :show, {id: '1', include: 'comments'}
|
353
|
-
assert_response :bad_request
|
354
|
-
ensure
|
355
|
-
JSONAPI.configuration.allow_include = true
|
356
|
-
end
|
357
|
-
|
358
|
-
def test_show_single_with_fields
|
359
|
-
get :show, {id: '1', fields: {posts: 'author'}}
|
360
|
-
assert_response :success
|
361
|
-
assert json_response['data'].is_a?(Hash)
|
362
|
-
assert_nil json_response['data']['attributes']
|
363
|
-
end
|
364
|
-
|
365
|
-
def test_show_single_with_fields_string
|
366
|
-
get :show, {id: '1', fields: 'author'}
|
367
|
-
assert_response :bad_request
|
368
|
-
assert_match /Fields must specify a type./, json_response['errors'][0]['detail']
|
369
|
-
end
|
370
|
-
|
371
|
-
def test_show_single_invalid_id_format
|
372
|
-
get :show, {id: 'asdfg'}
|
373
|
-
assert_response :bad_request
|
374
|
-
assert_match /asdfg is not a valid value for id/, response.body
|
375
|
-
end
|
376
|
-
|
377
|
-
def test_show_single_missing_record
|
378
|
-
get :show, {id: '5412333'}
|
379
|
-
assert_response :not_found
|
380
|
-
assert_match /record identified by 5412333 could not be found/, response.body
|
381
|
-
end
|
382
|
-
|
383
|
-
def test_show_malformed_fields_not_list
|
384
|
-
get :show, {id: '1', 'fields' => ''}
|
385
|
-
assert_response :bad_request
|
386
|
-
assert_match /Fields must specify a type./, json_response['errors'][0]['detail']
|
387
|
-
end
|
388
|
-
|
389
|
-
def test_show_malformed_fields_type_not_list
|
390
|
-
get :show, {id: '1', 'fields' => {'posts' => ''}}
|
391
|
-
assert_response :bad_request
|
392
|
-
assert_match /nil is not a valid field for posts./, json_response['errors'][0]['detail']
|
393
|
-
end
|
394
|
-
|
395
|
-
def test_create_simple
|
396
|
-
set_content_type_header!
|
397
|
-
post :create,
|
398
|
-
{
|
399
|
-
data: {
|
400
|
-
type: 'posts',
|
401
|
-
attributes: {
|
402
|
-
title: 'JR is Great',
|
403
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
404
|
-
},
|
405
|
-
relationships: {
|
406
|
-
author: {data: {type: 'people', id: '3'}}
|
407
|
-
}
|
408
|
-
}
|
409
|
-
}
|
410
|
-
|
411
|
-
assert_response :created
|
412
|
-
assert json_response['data'].is_a?(Hash)
|
413
|
-
assert_equal 'JR is Great', json_response['data']['attributes']['title']
|
414
|
-
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['attributes']['body']
|
415
|
-
end
|
416
|
-
|
417
|
-
def test_create_link_to_missing_object
|
418
|
-
set_content_type_header!
|
419
|
-
post :create,
|
420
|
-
{
|
421
|
-
data: {
|
422
|
-
type: 'posts',
|
423
|
-
attributes: {
|
424
|
-
title: 'JR is Great',
|
425
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
426
|
-
},
|
427
|
-
relationships: {
|
428
|
-
author: {data: {type: 'people', id: '304567'}}
|
429
|
-
}
|
430
|
-
}
|
431
|
-
}
|
432
|
-
|
433
|
-
assert_response :unprocessable_entity
|
434
|
-
# TODO: check if this validation is working
|
435
|
-
assert_match /author - can't be blank/, response.body
|
436
|
-
end
|
437
|
-
|
438
|
-
def test_create_extra_param
|
439
|
-
set_content_type_header!
|
440
|
-
post :create,
|
441
|
-
{
|
442
|
-
data: {
|
443
|
-
type: 'posts',
|
444
|
-
attributes: {
|
445
|
-
asdfg: 'aaaa',
|
446
|
-
title: 'JR is Great',
|
447
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
448
|
-
},
|
449
|
-
relationships: {
|
450
|
-
author: {data: {type: 'people', id: '3'}}
|
451
|
-
}
|
452
|
-
}
|
453
|
-
}
|
454
|
-
|
455
|
-
assert_response :bad_request
|
456
|
-
assert_match /asdfg is not allowed/, response.body
|
457
|
-
end
|
458
|
-
|
459
|
-
def test_create_extra_param_allow_extra_params
|
460
|
-
JSONAPI.configuration.raise_if_parameters_not_allowed = false
|
461
|
-
|
462
|
-
set_content_type_header!
|
463
|
-
post :create,
|
464
|
-
{
|
465
|
-
data: {
|
466
|
-
type: 'posts',
|
467
|
-
attributes: {
|
468
|
-
asdfg: 'aaaa',
|
469
|
-
title: 'JR is Great',
|
470
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
471
|
-
},
|
472
|
-
relationships: {
|
473
|
-
author: {data: {type: 'people', id: '3'}}
|
474
|
-
}
|
475
|
-
},
|
476
|
-
include: 'author'
|
477
|
-
}
|
478
|
-
|
479
|
-
assert_response :created
|
480
|
-
assert json_response['data'].is_a?(Hash)
|
481
|
-
assert_equal '3', json_response['data']['relationships']['author']['data']['id']
|
482
|
-
assert_equal 'JR is Great', json_response['data']['attributes']['title']
|
483
|
-
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['attributes']['body']
|
484
|
-
|
485
|
-
assert_equal 1, json_response['meta']["warnings"].count
|
486
|
-
assert_equal "Param not allowed", json_response['meta']["warnings"][0]["title"]
|
487
|
-
assert_equal "asdfg is not allowed.", json_response['meta']["warnings"][0]["detail"]
|
488
|
-
assert_equal '105', json_response['meta']["warnings"][0]["code"]
|
489
|
-
ensure
|
490
|
-
JSONAPI.configuration.raise_if_parameters_not_allowed = true
|
491
|
-
end
|
492
|
-
|
493
|
-
def test_create_with_invalid_data
|
494
|
-
set_content_type_header!
|
495
|
-
post :create,
|
496
|
-
{
|
497
|
-
data: {
|
498
|
-
type: 'posts',
|
499
|
-
attributes: {
|
500
|
-
title: 'JSONAPIResources is the greatest thing...',
|
501
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
502
|
-
},
|
503
|
-
relationships: {
|
504
|
-
author: nil
|
505
|
-
}
|
506
|
-
}
|
507
|
-
}
|
508
|
-
|
509
|
-
assert_response :unprocessable_entity
|
510
|
-
|
511
|
-
assert_equal "/data/relationships/author", json_response['errors'][0]['source']['pointer']
|
512
|
-
assert_equal "can't be blank", json_response['errors'][0]['title']
|
513
|
-
assert_equal "author - can't be blank", json_response['errors'][0]['detail']
|
514
|
-
|
515
|
-
assert_equal "/data/attributes/title", json_response['errors'][1]['source']['pointer']
|
516
|
-
assert_equal "is too long (maximum is 35 characters)", json_response['errors'][1]['title']
|
517
|
-
assert_equal "title - is too long (maximum is 35 characters)", json_response['errors'][1]['detail']
|
518
|
-
end
|
519
|
-
|
520
|
-
def test_create_multiple
|
521
|
-
set_content_type_header!
|
522
|
-
post :create,
|
523
|
-
{
|
524
|
-
data: [
|
525
|
-
{
|
526
|
-
type: 'posts',
|
527
|
-
attributes: {
|
528
|
-
title: 'JR is Great',
|
529
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
530
|
-
},
|
531
|
-
relationships: {
|
532
|
-
author: {data: {type: 'people', id: '3'}}
|
533
|
-
}
|
534
|
-
},
|
535
|
-
{
|
536
|
-
type: 'posts',
|
537
|
-
attributes: {
|
538
|
-
title: 'Ember is Great',
|
539
|
-
body: 'Ember is the greatest thing since unsliced bread.'
|
540
|
-
},
|
541
|
-
relationships: {
|
542
|
-
author: {data: {type: 'people', id: '3'}}
|
543
|
-
}
|
544
|
-
}
|
545
|
-
]
|
546
|
-
}
|
547
|
-
|
548
|
-
assert_response :created
|
549
|
-
assert json_response['data'].is_a?(Array)
|
550
|
-
assert_equal json_response['data'].size, 2
|
551
|
-
assert_nil json_response['data'][0]['relationships']['author']['data']
|
552
|
-
assert_match /JR is Great/, response.body
|
553
|
-
assert_match /Ember is Great/, response.body
|
554
|
-
end
|
555
|
-
|
556
|
-
def test_create_multiple_wrong_case
|
557
|
-
set_content_type_header!
|
558
|
-
post :create,
|
559
|
-
{
|
560
|
-
data: [
|
561
|
-
{
|
562
|
-
type: 'posts',
|
563
|
-
attributes: {
|
564
|
-
Title: 'JR is Great',
|
565
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
566
|
-
},
|
567
|
-
relationships: {
|
568
|
-
author: {data: {type: 'people', id: '3'}}
|
569
|
-
}
|
570
|
-
},
|
571
|
-
{
|
572
|
-
type: 'posts',
|
573
|
-
attributes: {
|
574
|
-
title: 'Ember is Great',
|
575
|
-
BODY: 'Ember is the greatest thing since unsliced bread.'
|
576
|
-
},
|
577
|
-
relationships: {
|
578
|
-
author: {data: {type: 'people', id: '3'}}
|
579
|
-
}
|
580
|
-
}
|
581
|
-
]
|
582
|
-
}
|
583
|
-
|
584
|
-
assert_response :bad_request
|
585
|
-
assert_match /Title/, json_response['errors'][0]['detail']
|
586
|
-
end
|
587
|
-
|
588
|
-
def test_create_simple_missing_posts
|
589
|
-
set_content_type_header!
|
590
|
-
post :create,
|
591
|
-
{
|
592
|
-
data_spelled_wrong: {
|
593
|
-
type: 'posts',
|
594
|
-
attributes: {
|
595
|
-
title: 'JR is Great',
|
596
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
597
|
-
},
|
598
|
-
relationships: {
|
599
|
-
author: {data: {type: 'people', id: '3'}}
|
600
|
-
}
|
601
|
-
}
|
602
|
-
}
|
603
|
-
|
604
|
-
assert_response :bad_request
|
605
|
-
assert_match /The required parameter, data, is missing./, json_response['errors'][0]['detail']
|
606
|
-
end
|
607
|
-
|
608
|
-
def test_create_simple_wrong_type
|
609
|
-
set_content_type_header!
|
610
|
-
post :create,
|
611
|
-
{
|
612
|
-
data: {
|
613
|
-
type: 'posts_spelled_wrong',
|
614
|
-
attributes: {
|
615
|
-
title: 'JR is Great',
|
616
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
617
|
-
},
|
618
|
-
relationships: {
|
619
|
-
author: {data: {type: 'people', id: '3'}}
|
620
|
-
}
|
621
|
-
}
|
622
|
-
}
|
623
|
-
|
624
|
-
assert_response :bad_request
|
625
|
-
assert_match /posts_spelled_wrong is not a valid resource./, json_response['errors'][0]['detail']
|
626
|
-
end
|
627
|
-
|
628
|
-
def test_create_simple_missing_type
|
629
|
-
set_content_type_header!
|
630
|
-
post :create,
|
631
|
-
{
|
632
|
-
data: {
|
633
|
-
attributes: {
|
634
|
-
title: 'JR is Great',
|
635
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
636
|
-
},
|
637
|
-
relationships: {
|
638
|
-
author: {data: {type: 'people', id: '3'}}
|
639
|
-
}
|
640
|
-
}
|
641
|
-
}
|
642
|
-
|
643
|
-
assert_response :bad_request
|
644
|
-
assert_match /The required parameter, type, is missing./, json_response['errors'][0]['detail']
|
645
|
-
end
|
646
|
-
|
647
|
-
def test_create_simple_unpermitted_attributes
|
648
|
-
set_content_type_header!
|
649
|
-
post :create,
|
650
|
-
{
|
651
|
-
data: {
|
652
|
-
type: 'posts',
|
653
|
-
attributes: {
|
654
|
-
subject: 'JR is Great',
|
655
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
656
|
-
},
|
657
|
-
relationships: {
|
658
|
-
author: {data: {type: 'people', id: '3'}}
|
659
|
-
}
|
660
|
-
}
|
661
|
-
}
|
662
|
-
|
663
|
-
assert_response :bad_request
|
664
|
-
assert_match /subject/, json_response['errors'][0]['detail']
|
665
|
-
end
|
666
|
-
|
667
|
-
def test_create_simple_unpermitted_attributes_allow_extra_params
|
668
|
-
JSONAPI.configuration.raise_if_parameters_not_allowed = false
|
669
|
-
|
670
|
-
set_content_type_header!
|
671
|
-
post :create,
|
672
|
-
{
|
673
|
-
data: {
|
674
|
-
type: 'posts',
|
675
|
-
attributes: {
|
676
|
-
title: 'JR is Great',
|
677
|
-
subject: 'JR is SUPER Great',
|
678
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
679
|
-
},
|
680
|
-
relationships: {
|
681
|
-
author: {data: {type: 'people', id: '3'}}
|
682
|
-
}
|
683
|
-
},
|
684
|
-
include: 'author'
|
685
|
-
}
|
686
|
-
|
687
|
-
assert_response :created
|
688
|
-
assert json_response['data'].is_a?(Hash)
|
689
|
-
assert_equal '3', json_response['data']['relationships']['author']['data']['id']
|
690
|
-
assert_equal 'JR is Great', json_response['data']['attributes']['title']
|
691
|
-
assert_equal 'JR is Great', json_response['data']['attributes']['subject']
|
692
|
-
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['attributes']['body']
|
693
|
-
|
694
|
-
|
695
|
-
assert_equal 1, json_response['meta']["warnings"].count
|
696
|
-
assert_equal "Param not allowed", json_response['meta']["warnings"][0]["title"]
|
697
|
-
assert_equal "subject is not allowed.", json_response['meta']["warnings"][0]["detail"]
|
698
|
-
assert_equal '105', json_response['meta']["warnings"][0]["code"]
|
699
|
-
ensure
|
700
|
-
JSONAPI.configuration.raise_if_parameters_not_allowed = true
|
701
|
-
end
|
702
|
-
|
703
|
-
def test_create_with_links_to_many_type_ids
|
704
|
-
set_content_type_header!
|
705
|
-
post :create,
|
706
|
-
{
|
707
|
-
data: {
|
708
|
-
type: 'posts',
|
709
|
-
attributes: {
|
710
|
-
title: 'JR is Great',
|
711
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
712
|
-
},
|
713
|
-
relationships: {
|
714
|
-
author: {data: {type: 'people', id: '3'}},
|
715
|
-
tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
|
716
|
-
}
|
717
|
-
},
|
718
|
-
include: 'author'
|
719
|
-
}
|
720
|
-
|
721
|
-
assert_response :created
|
722
|
-
assert json_response['data'].is_a?(Hash)
|
723
|
-
assert_equal '3', json_response['data']['relationships']['author']['data']['id']
|
724
|
-
assert_equal 'JR is Great', json_response['data']['attributes']['title']
|
725
|
-
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['attributes']['body']
|
726
|
-
end
|
727
|
-
|
728
|
-
def test_create_with_links_to_many_array
|
729
|
-
set_content_type_header!
|
730
|
-
post :create,
|
731
|
-
{
|
732
|
-
data: {
|
733
|
-
type: 'posts',
|
734
|
-
attributes: {
|
735
|
-
title: 'JR is Great',
|
736
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread.'
|
737
|
-
},
|
738
|
-
relationships: {
|
739
|
-
author: {data: {type: 'people', id: '3'}},
|
740
|
-
tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
|
741
|
-
}
|
742
|
-
},
|
743
|
-
include: 'author'
|
744
|
-
}
|
745
|
-
|
746
|
-
assert_response :created
|
747
|
-
assert json_response['data'].is_a?(Hash)
|
748
|
-
assert_equal '3', json_response['data']['relationships']['author']['data']['id']
|
749
|
-
assert_equal 'JR is Great', json_response['data']['attributes']['title']
|
750
|
-
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread.', json_response['data']['attributes']['body']
|
751
|
-
end
|
752
|
-
|
753
|
-
def test_create_with_links_include_and_fields
|
754
|
-
set_content_type_header!
|
755
|
-
post :create,
|
756
|
-
{
|
757
|
-
data: {
|
758
|
-
type: 'posts',
|
759
|
-
attributes: {
|
760
|
-
title: 'JR is Great!',
|
761
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread!'
|
762
|
-
},
|
763
|
-
relationships: {
|
764
|
-
author: {data: {type: 'people', id: '3'}},
|
765
|
-
tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
|
766
|
-
}
|
767
|
-
},
|
768
|
-
include: 'author,author.posts',
|
769
|
-
fields: {posts: 'id,title,author'}
|
770
|
-
}
|
771
|
-
|
772
|
-
assert_response :created
|
773
|
-
assert json_response['data'].is_a?(Hash)
|
774
|
-
assert_equal '3', json_response['data']['relationships']['author']['data']['id']
|
775
|
-
assert_equal 'JR is Great!', json_response['data']['attributes']['title']
|
776
|
-
assert_not_nil json_response['included'].size
|
777
|
-
end
|
778
|
-
|
779
|
-
def test_update_with_links
|
780
|
-
set_content_type_header!
|
781
|
-
javascript = Section.find_by(name: 'javascript')
|
782
|
-
|
783
|
-
put :update,
|
784
|
-
{
|
785
|
-
id: 3,
|
786
|
-
data: {
|
787
|
-
id: '3',
|
788
|
-
type: 'posts',
|
789
|
-
attributes: {
|
790
|
-
title: 'A great new Post'
|
791
|
-
},
|
792
|
-
relationships: {
|
793
|
-
section: {data: {type: 'sections', id: "#{javascript.id}"}},
|
794
|
-
tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
|
795
|
-
}
|
796
|
-
},
|
797
|
-
include: 'tags,author,section'
|
798
|
-
}
|
799
|
-
|
800
|
-
assert_response :success
|
801
|
-
assert json_response['data'].is_a?(Hash)
|
802
|
-
assert_equal '3', json_response['data']['relationships']['author']['data']['id']
|
803
|
-
assert_equal javascript.id.to_s, json_response['data']['relationships']['section']['data']['id']
|
804
|
-
assert_equal 'A great new Post', json_response['data']['attributes']['title']
|
805
|
-
assert_equal 'AAAA', json_response['data']['attributes']['body']
|
806
|
-
assert matches_array?([{'type' => 'tags', 'id' => '3'}, {'type' => 'tags', 'id' => '4'}],
|
807
|
-
json_response['data']['relationships']['tags']['data'])
|
808
|
-
end
|
809
|
-
|
810
|
-
def test_update_with_internal_server_error
|
811
|
-
set_content_type_header!
|
812
|
-
post_object = Post.find(3)
|
813
|
-
title = post_object.title
|
814
|
-
|
815
|
-
put :update,
|
816
|
-
{
|
817
|
-
id: 3,
|
818
|
-
data: {
|
819
|
-
id: '3',
|
820
|
-
type: 'posts',
|
821
|
-
attributes: {
|
822
|
-
title: 'BOOM'
|
823
|
-
}
|
824
|
-
}
|
825
|
-
}
|
826
|
-
|
827
|
-
assert_response 500
|
828
|
-
post_object = Post.find(3)
|
829
|
-
assert_equal title, post_object.title
|
830
|
-
end
|
831
|
-
|
832
|
-
def test_update_with_links_allow_extra_params
|
833
|
-
JSONAPI.configuration.raise_if_parameters_not_allowed = false
|
834
|
-
|
835
|
-
set_content_type_header!
|
836
|
-
javascript = Section.find_by(name: 'javascript')
|
837
|
-
|
838
|
-
put :update,
|
839
|
-
{
|
840
|
-
id: 3,
|
841
|
-
data: {
|
842
|
-
id: '3',
|
843
|
-
type: 'posts',
|
844
|
-
attributes: {
|
845
|
-
title: 'A great new Post',
|
846
|
-
subject: 'A great new Post',
|
847
|
-
},
|
848
|
-
relationships: {
|
849
|
-
section: {data: {type: 'sections', id: "#{javascript.id}"}},
|
850
|
-
tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
|
851
|
-
}
|
852
|
-
},
|
853
|
-
include: 'tags,author,section'
|
854
|
-
}
|
855
|
-
|
856
|
-
assert_response :success
|
857
|
-
assert json_response['data'].is_a?(Hash)
|
858
|
-
assert_equal '3', json_response['data']['relationships']['author']['data']['id']
|
859
|
-
assert_equal javascript.id.to_s, json_response['data']['relationships']['section']['data']['id']
|
860
|
-
assert_equal 'A great new Post', json_response['data']['attributes']['title']
|
861
|
-
assert_equal 'AAAA', json_response['data']['attributes']['body']
|
862
|
-
assert matches_array?([{'type' => 'tags', 'id' => '3'}, {'type' => 'tags', 'id' => '4'}],
|
863
|
-
json_response['data']['relationships']['tags']['data'])
|
864
|
-
|
865
|
-
|
866
|
-
assert_equal 1, json_response['meta']["warnings"].count
|
867
|
-
assert_equal "Param not allowed", json_response['meta']["warnings"][0]["title"]
|
868
|
-
assert_equal "subject is not allowed.", json_response['meta']["warnings"][0]["detail"]
|
869
|
-
assert_equal '105', json_response['meta']["warnings"][0]["code"]
|
870
|
-
ensure
|
871
|
-
JSONAPI.configuration.raise_if_parameters_not_allowed = true
|
872
|
-
end
|
873
|
-
|
874
|
-
def test_update_remove_links
|
875
|
-
set_content_type_header!
|
876
|
-
put :update,
|
877
|
-
{
|
878
|
-
id: 3,
|
879
|
-
data: {
|
880
|
-
id: '3',
|
881
|
-
type: 'posts',
|
882
|
-
attributes: {
|
883
|
-
title: 'A great new Post'
|
884
|
-
},
|
885
|
-
relationships: {
|
886
|
-
section: {data: {type: 'sections', id: 1}},
|
887
|
-
tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
|
888
|
-
}
|
889
|
-
},
|
890
|
-
include: 'tags'
|
891
|
-
}
|
892
|
-
|
893
|
-
assert_response :success
|
894
|
-
|
895
|
-
put :update,
|
896
|
-
{
|
897
|
-
id: 3,
|
898
|
-
data: {
|
899
|
-
type: 'posts',
|
900
|
-
id: 3,
|
901
|
-
attributes: {
|
902
|
-
title: 'A great new Post'
|
903
|
-
},
|
904
|
-
relationships: {
|
905
|
-
section: nil,
|
906
|
-
tags: []
|
907
|
-
}
|
908
|
-
},
|
909
|
-
include: 'tags,author,section'
|
910
|
-
}
|
911
|
-
|
912
|
-
assert_response :success
|
913
|
-
assert json_response['data'].is_a?(Hash)
|
914
|
-
assert_equal '3', json_response['data']['relationships']['author']['data']['id']
|
915
|
-
assert_equal nil, json_response['data']['relationships']['section']['data']
|
916
|
-
assert_equal 'A great new Post', json_response['data']['attributes']['title']
|
917
|
-
assert_equal 'AAAA', json_response['data']['attributes']['body']
|
918
|
-
assert matches_array?([],
|
919
|
-
json_response['data']['relationships']['tags']['data'])
|
920
|
-
end
|
921
|
-
|
922
|
-
def test_update_relationship_to_one
|
923
|
-
set_content_type_header!
|
924
|
-
ruby = Section.find_by(name: 'ruby')
|
925
|
-
post_object = Post.find(4)
|
926
|
-
assert_not_equal ruby.id, post_object.section_id
|
927
|
-
|
928
|
-
put :update_relationship, {post_id: 4, relationship: 'section', data: {type: 'sections', id: "#{ruby.id}"}}
|
929
|
-
|
930
|
-
assert_response :no_content
|
931
|
-
post_object = Post.find(4)
|
932
|
-
assert_equal ruby.id, post_object.section_id
|
933
|
-
end
|
934
|
-
|
935
|
-
def test_update_relationship_to_one_invalid_links_hash_keys_ids
|
936
|
-
set_content_type_header!
|
937
|
-
put :update_relationship, {post_id: 3, relationship: 'section', data: {type: 'sections', ids: 'foo'}}
|
938
|
-
|
939
|
-
assert_response :bad_request
|
940
|
-
assert_match /Invalid Links Object/, response.body
|
941
|
-
end
|
942
|
-
|
943
|
-
def test_update_relationship_to_one_invalid_links_hash_count
|
944
|
-
set_content_type_header!
|
945
|
-
put :update_relationship, {post_id: 3, relationship: 'section', data: {type: 'sections'}}
|
946
|
-
|
947
|
-
assert_response :bad_request
|
948
|
-
assert_match /Invalid Links Object/, response.body
|
949
|
-
end
|
950
|
-
|
951
|
-
def test_update_relationship_to_many_not_array
|
952
|
-
set_content_type_header!
|
953
|
-
put :update_relationship, {post_id: 3, relationship: 'tags', data: {type: 'tags', id: 2}}
|
954
|
-
|
955
|
-
assert_response :bad_request
|
956
|
-
assert_match /Invalid Links Object/, response.body
|
957
|
-
end
|
958
|
-
|
959
|
-
def test_update_relationship_to_one_invalid_links_hash_keys_type_mismatch
|
960
|
-
set_content_type_header!
|
961
|
-
put :update_relationship, {post_id: 3, relationship: 'section', data: {type: 'comment', id: '3'}}
|
962
|
-
|
963
|
-
assert_response :bad_request
|
964
|
-
assert_match /Type Mismatch/, response.body
|
965
|
-
end
|
966
|
-
|
967
|
-
def test_update_nil_to_many_links
|
968
|
-
set_content_type_header!
|
969
|
-
put :update,
|
970
|
-
{
|
971
|
-
id: 3,
|
972
|
-
data: {
|
973
|
-
type: 'posts',
|
974
|
-
id: 3,
|
975
|
-
relationships: {
|
976
|
-
tags: nil
|
977
|
-
}
|
978
|
-
}
|
979
|
-
}
|
980
|
-
|
981
|
-
assert_response :bad_request
|
982
|
-
assert_match /Invalid Links Object/, response.body
|
983
|
-
end
|
984
|
-
|
985
|
-
def test_update_bad_hash_to_many_links
|
986
|
-
set_content_type_header!
|
987
|
-
put :update,
|
988
|
-
{
|
989
|
-
id: 3,
|
990
|
-
data: {
|
991
|
-
type: 'posts',
|
992
|
-
id: 3,
|
993
|
-
relationships: {
|
994
|
-
tags: {data: {typ: 'bad link', idd: 'as'}}
|
995
|
-
}
|
996
|
-
}
|
997
|
-
}
|
998
|
-
|
999
|
-
assert_response :bad_request
|
1000
|
-
assert_match /Invalid Links Object/, response.body
|
1001
|
-
end
|
1002
|
-
|
1003
|
-
def test_update_other_to_many_links
|
1004
|
-
set_content_type_header!
|
1005
|
-
put :update,
|
1006
|
-
{
|
1007
|
-
id: 3,
|
1008
|
-
data: {
|
1009
|
-
type: 'posts',
|
1010
|
-
id: 3,
|
1011
|
-
relationships: {
|
1012
|
-
tags: 'bad link'
|
1013
|
-
}
|
1014
|
-
}
|
1015
|
-
}
|
1016
|
-
|
1017
|
-
assert_response :bad_request
|
1018
|
-
assert_match /Invalid Links Object/, response.body
|
1019
|
-
end
|
1020
|
-
|
1021
|
-
def test_update_other_to_many_links_data_nil
|
1022
|
-
set_content_type_header!
|
1023
|
-
put :update,
|
1024
|
-
{
|
1025
|
-
id: 3,
|
1026
|
-
data: {
|
1027
|
-
type: 'posts',
|
1028
|
-
id: 3,
|
1029
|
-
relationships: {
|
1030
|
-
tags: {data: nil}
|
1031
|
-
}
|
1032
|
-
}
|
1033
|
-
}
|
1034
|
-
|
1035
|
-
assert_response :bad_request
|
1036
|
-
assert_match /Invalid Links Object/, response.body
|
1037
|
-
end
|
1038
|
-
|
1039
|
-
def test_update_relationship_to_one_singular_param_id_nil
|
1040
|
-
set_content_type_header!
|
1041
|
-
ruby = Section.find_by(name: 'ruby')
|
1042
|
-
post_object = Post.find(3)
|
1043
|
-
post_object.section = ruby
|
1044
|
-
post_object.save!
|
1045
|
-
|
1046
|
-
put :update_relationship, {post_id: 3, relationship: 'section', data: {type: 'sections', id: nil}}
|
1047
|
-
|
1048
|
-
assert_response :no_content
|
1049
|
-
assert_equal nil, post_object.reload.section_id
|
1050
|
-
end
|
1051
|
-
|
1052
|
-
def test_update_relationship_to_one_data_nil
|
1053
|
-
set_content_type_header!
|
1054
|
-
ruby = Section.find_by(name: 'ruby')
|
1055
|
-
post_object = Post.find(3)
|
1056
|
-
post_object.section = ruby
|
1057
|
-
post_object.save!
|
1058
|
-
|
1059
|
-
put :update_relationship, {post_id: 3, relationship: 'section', data: nil}
|
1060
|
-
|
1061
|
-
assert_response :no_content
|
1062
|
-
assert_equal nil, post_object.reload.section_id
|
1063
|
-
end
|
1064
|
-
|
1065
|
-
def test_remove_relationship_to_one
|
1066
|
-
set_content_type_header!
|
1067
|
-
ruby = Section.find_by(name: 'ruby')
|
1068
|
-
post_object = Post.find(3)
|
1069
|
-
post_object.section_id = ruby.id
|
1070
|
-
post_object.save!
|
1071
|
-
|
1072
|
-
put :destroy_relationship, {post_id: 3, relationship: 'section'}
|
1073
|
-
|
1074
|
-
assert_response :no_content
|
1075
|
-
post_object = Post.find(3)
|
1076
|
-
assert_equal nil, post_object.section_id
|
1077
|
-
end
|
1078
|
-
|
1079
|
-
def test_update_relationship_to_one_singular_param
|
1080
|
-
set_content_type_header!
|
1081
|
-
ruby = Section.find_by(name: 'ruby')
|
1082
|
-
post_object = Post.find(3)
|
1083
|
-
post_object.section_id = nil
|
1084
|
-
post_object.save!
|
1085
|
-
|
1086
|
-
put :update_relationship, {post_id: 3, relationship: 'section', data: {type: 'sections', id: "#{ruby.id}"}}
|
1087
|
-
|
1088
|
-
assert_response :no_content
|
1089
|
-
post_object = Post.find(3)
|
1090
|
-
assert_equal ruby.id, post_object.section_id
|
1091
|
-
end
|
1092
|
-
|
1093
|
-
def test_update_relationship_to_many_join_table_single
|
1094
|
-
set_content_type_header!
|
1095
|
-
put :update_relationship, {post_id: 3, relationship: 'tags', data: []}
|
1096
|
-
assert_response :no_content
|
1097
|
-
|
1098
|
-
post_object = Post.find(3)
|
1099
|
-
assert_equal 0, post_object.tags.length
|
1100
|
-
|
1101
|
-
put :update_relationship, {post_id: 3, relationship: 'tags', data: [{type: 'tags', id: 2}]}
|
1102
|
-
|
1103
|
-
assert_response :no_content
|
1104
|
-
post_object = Post.find(3)
|
1105
|
-
assert_equal 1, post_object.tags.length
|
1106
|
-
|
1107
|
-
put :update_relationship, {post_id: 3, relationship: 'tags', data: [{type: 'tags', id: 5}]}
|
1108
|
-
|
1109
|
-
assert_response :no_content
|
1110
|
-
post_object = Post.find(3)
|
1111
|
-
tags = post_object.tags.collect { |tag| tag.id }
|
1112
|
-
assert_equal 1, tags.length
|
1113
|
-
assert matches_array? [5], tags
|
1114
|
-
end
|
1115
|
-
|
1116
|
-
def test_update_relationship_to_many
|
1117
|
-
set_content_type_header!
|
1118
|
-
put :update_relationship, {post_id: 3, relationship: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]}
|
1119
|
-
|
1120
|
-
assert_response :no_content
|
1121
|
-
post_object = Post.find(3)
|
1122
|
-
assert_equal 2, post_object.tags.collect { |tag| tag.id }.length
|
1123
|
-
assert matches_array? [2, 3], post_object.tags.collect { |tag| tag.id }
|
1124
|
-
end
|
1125
|
-
|
1126
|
-
def test_create_relationship_to_many_join_table
|
1127
|
-
set_content_type_header!
|
1128
|
-
put :update_relationship, {post_id: 3, relationship: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]}
|
1129
|
-
|
1130
|
-
assert_response :no_content
|
1131
|
-
post_object = Post.find(3)
|
1132
|
-
assert_equal 2, post_object.tags.collect { |tag| tag.id }.length
|
1133
|
-
assert matches_array? [2, 3], post_object.tags.collect { |tag| tag.id }
|
1134
|
-
|
1135
|
-
post :create_relationship, {post_id: 3, relationship: 'tags', data: [{type: 'tags', id: 5}]}
|
1136
|
-
|
1137
|
-
assert_response :no_content
|
1138
|
-
post_object = Post.find(3)
|
1139
|
-
assert_equal 3, post_object.tags.collect { |tag| tag.id }.length
|
1140
|
-
assert matches_array? [2, 3, 5], post_object.tags.collect { |tag| tag.id }
|
1141
|
-
end
|
1142
|
-
|
1143
|
-
def test_create_relationship_to_many_mismatched_type
|
1144
|
-
set_content_type_header!
|
1145
|
-
post :create_relationship, {post_id: 3, relationship: 'tags', data: [{type: 'comments', id: 5}]}
|
1146
|
-
|
1147
|
-
assert_response :bad_request
|
1148
|
-
assert_match /Type Mismatch/, response.body
|
1149
|
-
end
|
1150
|
-
|
1151
|
-
def test_create_relationship_to_many_missing_id
|
1152
|
-
set_content_type_header!
|
1153
|
-
post :create_relationship, {post_id: 3, relationship: 'tags', data: [{type: 'tags', idd: 5}]}
|
1154
|
-
|
1155
|
-
assert_response :bad_request
|
1156
|
-
assert_match /Data is not a valid Links Object./, response.body
|
1157
|
-
end
|
1158
|
-
|
1159
|
-
def test_create_relationship_to_many_not_array
|
1160
|
-
set_content_type_header!
|
1161
|
-
post :create_relationship, {post_id: 3, relationship: 'tags', data: {type: 'tags', id: 5}}
|
1162
|
-
|
1163
|
-
assert_response :bad_request
|
1164
|
-
assert_match /Data is not a valid Links Object./, response.body
|
1165
|
-
end
|
1166
|
-
|
1167
|
-
def test_create_relationship_to_many_missing_data
|
1168
|
-
set_content_type_header!
|
1169
|
-
post :create_relationship, {post_id: 3, relationship: 'tags'}
|
1170
|
-
|
1171
|
-
assert_response :bad_request
|
1172
|
-
assert_match /The required parameter, data, is missing./, response.body
|
1173
|
-
end
|
1174
|
-
|
1175
|
-
def test_create_relationship_to_many_join
|
1176
|
-
set_content_type_header!
|
1177
|
-
post :create_relationship, {post_id: 4, relationship: 'tags', data: [{type: 'tags', id: 1}, {type: 'tags', id: 2}, {type: 'tags', id: 3}]}
|
1178
|
-
assert_response :no_content
|
1179
|
-
end
|
1180
|
-
|
1181
|
-
def test_create_relationship_to_many_join_table_record_exists
|
1182
|
-
set_content_type_header!
|
1183
|
-
put :update_relationship, {post_id: 3, relationship: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]}
|
1184
|
-
|
1185
|
-
assert_response :no_content
|
1186
|
-
post_object = Post.find(3)
|
1187
|
-
assert_equal 2, post_object.tags.collect { |tag| tag.id }.length
|
1188
|
-
assert matches_array? [2, 3], post_object.tags.collect { |tag| tag.id }
|
1189
|
-
|
1190
|
-
post :create_relationship, {post_id: 3, relationship: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 5}]}
|
1191
|
-
|
1192
|
-
assert_response :bad_request
|
1193
|
-
assert_match /The relation to 2 already exists./, response.body
|
1194
|
-
end
|
1195
|
-
|
1196
|
-
def test_update_relationship_to_many_missing_tags
|
1197
|
-
set_content_type_header!
|
1198
|
-
put :update_relationship, {post_id: 3, relationship: 'tags'}
|
1199
|
-
|
1200
|
-
assert_response :bad_request
|
1201
|
-
assert_match /The required parameter, data, is missing./, response.body
|
1202
|
-
end
|
1203
|
-
|
1204
|
-
def test_delete_relationship_to_many
|
1205
|
-
set_content_type_header!
|
1206
|
-
put :update_relationship, {post_id: 14, relationship: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]}
|
1207
|
-
assert_response :no_content
|
1208
|
-
p = Post.find(14)
|
1209
|
-
assert_equal [2, 3], p.tag_ids
|
1210
|
-
|
1211
|
-
delete :destroy_relationship, {post_id: 14, relationship: 'tags', data: [{type: 'tags', id: 3}]}
|
1212
|
-
|
1213
|
-
p.reload
|
1214
|
-
assert_response :no_content
|
1215
|
-
assert_equal [2], p.tag_ids
|
1216
|
-
end
|
1217
|
-
|
1218
|
-
def test_delete_relationship_to_many_with_relationship_url_not_matching_type
|
1219
|
-
set_content_type_header!
|
1220
|
-
PostResource.has_many :special_tags, relation_name: :special_tags, class_name: "Tag"
|
1221
|
-
post :create_relationship, {post_id: 14, relationship: 'special_tags', data: [{type: 'tags', id: 2}]}
|
1222
|
-
|
1223
|
-
#check the relationship was created successfully
|
1224
|
-
assert_equal 1, Post.find(14).special_tags.count
|
1225
|
-
before_tags = Post.find(14).tags.count
|
1226
|
-
|
1227
|
-
delete :destroy_relationship, {post_id: 14, relationship: 'special_tags', data: [{type: 'tags', id: 2}]}
|
1228
|
-
assert_equal 0, Post.find(14).special_tags.count, "Relationship that matches URL relationship not destroyed"
|
1229
|
-
|
1230
|
-
#check that the tag association is not affected
|
1231
|
-
assert_equal Post.find(14).tags.count, before_tags
|
1232
|
-
ensure
|
1233
|
-
PostResource.instance_variable_get(:@_relationships).delete(:special_tags)
|
1234
|
-
end
|
1235
|
-
|
1236
|
-
def test_delete_relationship_to_many_does_not_exist
|
1237
|
-
set_content_type_header!
|
1238
|
-
put :update_relationship, {post_id: 14, relationship: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]}
|
1239
|
-
assert_response :no_content
|
1240
|
-
p = Post.find(14)
|
1241
|
-
assert_equal [2, 3], p.tag_ids
|
1242
|
-
|
1243
|
-
delete :destroy_relationship, {post_id: 14, relationship: 'tags', data: [{type: 'tags', id: 4}]}
|
1244
|
-
|
1245
|
-
p.reload
|
1246
|
-
assert_response :not_found
|
1247
|
-
assert_equal [2, 3], p.tag_ids
|
1248
|
-
end
|
1249
|
-
|
1250
|
-
def test_delete_relationship_to_many_with_empty_data
|
1251
|
-
set_content_type_header!
|
1252
|
-
put :update_relationship, {post_id: 14, relationship: 'tags', data: [{type: 'tags', id: 2}, {type: 'tags', id: 3}]}
|
1253
|
-
assert_response :no_content
|
1254
|
-
p = Post.find(14)
|
1255
|
-
assert_equal [2, 3], p.tag_ids
|
1256
|
-
|
1257
|
-
put :update_relationship, {post_id: 14, relationship: 'tags', data: [] }
|
1258
|
-
|
1259
|
-
p.reload
|
1260
|
-
assert_response :no_content
|
1261
|
-
assert_equal [], p.tag_ids
|
1262
|
-
end
|
1263
|
-
|
1264
|
-
def test_update_mismatched_keys
|
1265
|
-
set_content_type_header!
|
1266
|
-
javascript = Section.find_by(name: 'javascript')
|
1267
|
-
|
1268
|
-
put :update,
|
1269
|
-
{
|
1270
|
-
id: 3,
|
1271
|
-
data: {
|
1272
|
-
type: 'posts',
|
1273
|
-
id: 2,
|
1274
|
-
attributes: {
|
1275
|
-
title: 'A great new Post'
|
1276
|
-
},
|
1277
|
-
relationships: {
|
1278
|
-
section: {type: 'sections', id: "#{javascript.id}"},
|
1279
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1280
|
-
}
|
1281
|
-
}
|
1282
|
-
}
|
1283
|
-
|
1284
|
-
assert_response :bad_request
|
1285
|
-
assert_match /The URL does not support the key 2/, response.body
|
1286
|
-
end
|
1287
|
-
|
1288
|
-
def test_update_extra_param
|
1289
|
-
set_content_type_header!
|
1290
|
-
javascript = Section.find_by(name: 'javascript')
|
1291
|
-
|
1292
|
-
put :update,
|
1293
|
-
{
|
1294
|
-
id: 3,
|
1295
|
-
data: {
|
1296
|
-
type: 'posts',
|
1297
|
-
id: '3',
|
1298
|
-
attributes: {
|
1299
|
-
asdfg: 'aaaa',
|
1300
|
-
title: 'A great new Post'
|
1301
|
-
},
|
1302
|
-
relationships: {
|
1303
|
-
section: {type: 'sections', id: "#{javascript.id}"},
|
1304
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1305
|
-
}
|
1306
|
-
}
|
1307
|
-
}
|
1308
|
-
|
1309
|
-
assert_response :bad_request
|
1310
|
-
assert_match /asdfg is not allowed/, response.body
|
1311
|
-
end
|
1312
|
-
|
1313
|
-
def test_update_extra_param_in_links
|
1314
|
-
set_content_type_header!
|
1315
|
-
javascript = Section.find_by(name: 'javascript')
|
1316
|
-
|
1317
|
-
put :update,
|
1318
|
-
{
|
1319
|
-
id: 3,
|
1320
|
-
data: {
|
1321
|
-
type: 'posts',
|
1322
|
-
id: '3',
|
1323
|
-
attributes: {
|
1324
|
-
title: 'A great new Post'
|
1325
|
-
},
|
1326
|
-
relationships: {
|
1327
|
-
asdfg: 'aaaa',
|
1328
|
-
section: {type: 'sections', id: "#{javascript.id}"},
|
1329
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1330
|
-
}
|
1331
|
-
}
|
1332
|
-
}
|
1333
|
-
|
1334
|
-
assert_response :bad_request
|
1335
|
-
assert_match /asdfg is not allowed/, response.body
|
1336
|
-
end
|
1337
|
-
|
1338
|
-
def test_update_extra_param_in_links_allow_extra_params
|
1339
|
-
JSONAPI.configuration.raise_if_parameters_not_allowed = false
|
1340
|
-
JSONAPI.configuration.use_text_errors = true
|
1341
|
-
|
1342
|
-
set_content_type_header!
|
1343
|
-
javascript = Section.find_by(name: 'javascript')
|
1344
|
-
|
1345
|
-
put :update,
|
1346
|
-
{
|
1347
|
-
id: 3,
|
1348
|
-
data: {
|
1349
|
-
type: 'posts',
|
1350
|
-
id: '3',
|
1351
|
-
attributes: {
|
1352
|
-
title: 'A great new Post'
|
1353
|
-
},
|
1354
|
-
relationships: {
|
1355
|
-
asdfg: 'aaaa'
|
1356
|
-
}
|
1357
|
-
}
|
1358
|
-
}
|
1359
|
-
|
1360
|
-
assert_response :success
|
1361
|
-
assert_equal "A great new Post", json_response["data"]["attributes"]["title"]
|
1362
|
-
assert_equal "Param not allowed", json_response["meta"]["warnings"][0]["title"]
|
1363
|
-
assert_equal "asdfg is not allowed.", json_response["meta"]["warnings"][0]["detail"]
|
1364
|
-
assert_equal "PARAM_NOT_ALLOWED", json_response["meta"]["warnings"][0]["code"]
|
1365
|
-
ensure
|
1366
|
-
JSONAPI.configuration.raise_if_parameters_not_allowed = true
|
1367
|
-
JSONAPI.configuration.use_text_errors = false
|
1368
|
-
end
|
1369
|
-
|
1370
|
-
def test_update_missing_param
|
1371
|
-
set_content_type_header!
|
1372
|
-
javascript = Section.find_by(name: 'javascript')
|
1373
|
-
|
1374
|
-
put :update,
|
1375
|
-
{
|
1376
|
-
id: 3,
|
1377
|
-
data_spelled_wrong: {
|
1378
|
-
type: 'posts',
|
1379
|
-
attributes: {
|
1380
|
-
title: 'A great new Post'
|
1381
|
-
},
|
1382
|
-
relationships: {
|
1383
|
-
section: {type: 'sections', id: "#{javascript.id}"},
|
1384
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1385
|
-
}
|
1386
|
-
}
|
1387
|
-
}
|
1388
|
-
|
1389
|
-
assert_response :bad_request
|
1390
|
-
assert_match /The required parameter, data, is missing./, response.body
|
1391
|
-
end
|
1392
|
-
|
1393
|
-
def test_update_missing_key
|
1394
|
-
set_content_type_header!
|
1395
|
-
|
1396
|
-
put :update,
|
1397
|
-
{
|
1398
|
-
id: 3,
|
1399
|
-
data: {
|
1400
|
-
type: 'posts',
|
1401
|
-
attributes: {
|
1402
|
-
title: 'A great new Post'
|
1403
|
-
}
|
1404
|
-
}
|
1405
|
-
}
|
1406
|
-
|
1407
|
-
assert_response :bad_request
|
1408
|
-
assert_match /The resource object does not contain a key/, response.body
|
1409
|
-
end
|
1410
|
-
|
1411
|
-
def test_update_missing_type
|
1412
|
-
set_content_type_header!
|
1413
|
-
javascript = Section.find_by(name: 'javascript')
|
1414
|
-
|
1415
|
-
put :update,
|
1416
|
-
{
|
1417
|
-
id: 3,
|
1418
|
-
data: {
|
1419
|
-
id: '3',
|
1420
|
-
type_spelled_wrong: 'posts',
|
1421
|
-
attributes: {
|
1422
|
-
title: 'A great new Post'
|
1423
|
-
},
|
1424
|
-
relationships: {
|
1425
|
-
section: {type: 'sections', id: "#{javascript.id}"},
|
1426
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1427
|
-
}
|
1428
|
-
}
|
1429
|
-
}
|
1430
|
-
|
1431
|
-
assert_response :bad_request
|
1432
|
-
assert_match /The required parameter, type, is missing./, response.body
|
1433
|
-
end
|
1434
|
-
|
1435
|
-
def test_update_unknown_key
|
1436
|
-
set_content_type_header!
|
1437
|
-
javascript = Section.find_by(name: 'javascript')
|
1438
|
-
|
1439
|
-
put :update,
|
1440
|
-
{
|
1441
|
-
id: 3,
|
1442
|
-
data: {
|
1443
|
-
id: '3',
|
1444
|
-
type: 'posts',
|
1445
|
-
body: 'asdfg',
|
1446
|
-
attributes: {
|
1447
|
-
title: 'A great new Post'
|
1448
|
-
},
|
1449
|
-
relationships: {
|
1450
|
-
section: {type: 'sections', id: "#{javascript.id}"},
|
1451
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1452
|
-
}
|
1453
|
-
}
|
1454
|
-
}
|
1455
|
-
|
1456
|
-
assert_response :bad_request
|
1457
|
-
assert_match /body is not allowed/, response.body
|
1458
|
-
end
|
1459
|
-
|
1460
|
-
def test_update_multiple
|
1461
|
-
set_content_type_header!
|
1462
|
-
javascript = Section.find_by(name: 'javascript')
|
1463
|
-
|
1464
|
-
put :update,
|
1465
|
-
{
|
1466
|
-
id: [3, 16],
|
1467
|
-
data: [
|
1468
|
-
{
|
1469
|
-
type: 'posts',
|
1470
|
-
id: 3,
|
1471
|
-
attributes: {
|
1472
|
-
title: 'A great new Post QWERTY'
|
1473
|
-
},
|
1474
|
-
relationships: {
|
1475
|
-
section: {data: {type: 'sections', id: "#{javascript.id}"}},
|
1476
|
-
tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
|
1477
|
-
}
|
1478
|
-
},
|
1479
|
-
{
|
1480
|
-
type: 'posts',
|
1481
|
-
id: 16,
|
1482
|
-
attributes: {
|
1483
|
-
title: 'A great new Post ASDFG'
|
1484
|
-
},
|
1485
|
-
relationships: {
|
1486
|
-
section: {data: {type: 'sections', id: "#{javascript.id}"}},
|
1487
|
-
tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
|
1488
|
-
}
|
1489
|
-
}
|
1490
|
-
],
|
1491
|
-
include: 'tags'
|
1492
|
-
}
|
1493
|
-
|
1494
|
-
assert_response :success
|
1495
|
-
assert_equal json_response['data'].size, 2
|
1496
|
-
assert_equal json_response['data'][0]['attributes']['title'], 'A great new Post QWERTY'
|
1497
|
-
assert_equal json_response['data'][0]['attributes']['body'], 'AAAA'
|
1498
|
-
assert matches_array?([{'type' => 'tags', 'id' => '3'}, {'type' => 'tags', 'id' => '4'}],
|
1499
|
-
json_response['data'][0]['relationships']['tags']['data'])
|
1500
|
-
|
1501
|
-
assert_equal json_response['data'][1]['attributes']['title'], 'A great new Post ASDFG'
|
1502
|
-
assert_equal json_response['data'][1]['attributes']['body'], 'Not First!!!!'
|
1503
|
-
assert matches_array?([{'type' => 'tags', 'id' => '3'}, {'type' => 'tags', 'id' => '4'}],
|
1504
|
-
json_response['data'][1]['relationships']['tags']['data'])
|
1505
|
-
end
|
1506
|
-
|
1507
|
-
def test_update_multiple_missing_keys
|
1508
|
-
set_content_type_header!
|
1509
|
-
javascript = Section.find_by(name: 'javascript')
|
1510
|
-
|
1511
|
-
put :update,
|
1512
|
-
{
|
1513
|
-
id: [3, 9],
|
1514
|
-
data: [
|
1515
|
-
{
|
1516
|
-
type: 'posts',
|
1517
|
-
attributes: {
|
1518
|
-
title: 'A great new Post ASDFG'
|
1519
|
-
},
|
1520
|
-
relationships: {
|
1521
|
-
section: {type: 'sections', id: "#{javascript.id}"},
|
1522
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1523
|
-
}
|
1524
|
-
},
|
1525
|
-
{
|
1526
|
-
type: 'posts',
|
1527
|
-
attributes: {
|
1528
|
-
title: 'A great new Post QWERTY'
|
1529
|
-
},
|
1530
|
-
relationships: {
|
1531
|
-
section: {type: 'sections', id: "#{javascript.id}"},
|
1532
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1533
|
-
}
|
1534
|
-
}
|
1535
|
-
]}
|
1536
|
-
|
1537
|
-
assert_response :bad_request
|
1538
|
-
assert_match /A key is required/, response.body
|
1539
|
-
end
|
1540
|
-
|
1541
|
-
def test_update_mismatch_keys
|
1542
|
-
set_content_type_header!
|
1543
|
-
javascript = Section.find_by(name: 'javascript')
|
1544
|
-
|
1545
|
-
put :update,
|
1546
|
-
{
|
1547
|
-
id: [3, 9],
|
1548
|
-
data: [
|
1549
|
-
{
|
1550
|
-
type: 'posts',
|
1551
|
-
id: 3,
|
1552
|
-
attributes: {
|
1553
|
-
title: 'A great new Post ASDFG'
|
1554
|
-
},
|
1555
|
-
relationships: {
|
1556
|
-
section: {data: {type: 'sections', id: "#{javascript.id}"}},
|
1557
|
-
tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
|
1558
|
-
}
|
1559
|
-
},
|
1560
|
-
{
|
1561
|
-
type: 'posts',
|
1562
|
-
id: 8,
|
1563
|
-
attributes: {
|
1564
|
-
title: 'A great new Post QWERTY'
|
1565
|
-
},
|
1566
|
-
relationships: {
|
1567
|
-
section: {data: {type: 'sections', id: "#{javascript.id}"}},
|
1568
|
-
tags: {data: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]}
|
1569
|
-
}
|
1570
|
-
}
|
1571
|
-
]}
|
1572
|
-
|
1573
|
-
assert_response :bad_request
|
1574
|
-
assert_match /The URL does not support the key 8/, response.body
|
1575
|
-
end
|
1576
|
-
|
1577
|
-
def test_update_multiple_count_mismatch
|
1578
|
-
set_content_type_header!
|
1579
|
-
javascript = Section.find_by(name: 'javascript')
|
1580
|
-
|
1581
|
-
put :update,
|
1582
|
-
{
|
1583
|
-
id: [3, 9, 2],
|
1584
|
-
data: [
|
1585
|
-
{
|
1586
|
-
type: 'posts',
|
1587
|
-
id: 3,
|
1588
|
-
attributes: {
|
1589
|
-
title: 'A great new Post QWERTY'
|
1590
|
-
},
|
1591
|
-
relationships: {
|
1592
|
-
section: {type: 'sections', id: "#{javascript.id}"},
|
1593
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1594
|
-
}
|
1595
|
-
},
|
1596
|
-
{
|
1597
|
-
type: 'posts',
|
1598
|
-
id: 9,
|
1599
|
-
attributes: {
|
1600
|
-
title: 'A great new Post ASDFG'
|
1601
|
-
},
|
1602
|
-
relationships: {
|
1603
|
-
section: {type: 'sections', id: "#{javascript.id}"},
|
1604
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1605
|
-
}
|
1606
|
-
}
|
1607
|
-
]}
|
1608
|
-
|
1609
|
-
assert_response :bad_request
|
1610
|
-
assert_match /Count to key mismatch/, response.body
|
1611
|
-
end
|
1612
|
-
|
1613
|
-
def test_update_unpermitted_attributes
|
1614
|
-
set_content_type_header!
|
1615
|
-
put :update,
|
1616
|
-
{
|
1617
|
-
id: 3,
|
1618
|
-
data: {
|
1619
|
-
type: 'posts',
|
1620
|
-
id: '3',
|
1621
|
-
attributes: {
|
1622
|
-
subject: 'A great new Post'
|
1623
|
-
},
|
1624
|
-
relationships: {
|
1625
|
-
author: {type: 'people', id: '1'},
|
1626
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1627
|
-
}
|
1628
|
-
}
|
1629
|
-
}
|
1630
|
-
|
1631
|
-
assert_response :bad_request
|
1632
|
-
assert_match /author is not allowed./, response.body
|
1633
|
-
assert_match /subject is not allowed./, response.body
|
1634
|
-
end
|
1635
|
-
|
1636
|
-
def test_update_bad_attributes
|
1637
|
-
set_content_type_header!
|
1638
|
-
put :update,
|
1639
|
-
{
|
1640
|
-
id: 3,
|
1641
|
-
data: {
|
1642
|
-
type: 'posts',
|
1643
|
-
attributes: {
|
1644
|
-
subject: 'A great new Post'
|
1645
|
-
},
|
1646
|
-
linked_objects: {
|
1647
|
-
author: {type: 'people', id: '1'},
|
1648
|
-
tags: [{type: 'tags', id: 3}, {type: 'tags', id: 4}]
|
1649
|
-
}
|
1650
|
-
}
|
1651
|
-
}
|
1652
|
-
|
1653
|
-
assert_response :bad_request
|
1654
|
-
end
|
1655
|
-
|
1656
|
-
def test_delete_with_validation_error
|
1657
|
-
post = Post.create!(title: "can't destroy me", author: Person.first)
|
1658
|
-
delete :destroy, { id: post.id }
|
1659
|
-
|
1660
|
-
assert_equal "can't destroy me", json_response['errors'][0]['title']
|
1661
|
-
assert_response :unprocessable_entity
|
1662
|
-
end
|
1663
|
-
|
1664
|
-
def test_delete_single
|
1665
|
-
initial_count = Post.count
|
1666
|
-
delete :destroy, {id: '4'}
|
1667
|
-
assert_response :no_content
|
1668
|
-
assert_equal initial_count - 1, Post.count
|
1669
|
-
end
|
1670
|
-
|
1671
|
-
def test_delete_multiple
|
1672
|
-
initial_count = Post.count
|
1673
|
-
delete :destroy, {id: '5,6'}
|
1674
|
-
assert_response :no_content
|
1675
|
-
assert_equal initial_count - 2, Post.count
|
1676
|
-
end
|
1677
|
-
|
1678
|
-
def test_delete_multiple_one_does_not_exist
|
1679
|
-
initial_count = Post.count
|
1680
|
-
delete :destroy, {id: '5,6,99999'}
|
1681
|
-
assert_response :not_found
|
1682
|
-
assert_equal initial_count, Post.count
|
1683
|
-
end
|
1684
|
-
|
1685
|
-
def test_show_to_one_relationship
|
1686
|
-
get :show_relationship, {post_id: '1', relationship: 'author'}
|
1687
|
-
assert_response :success
|
1688
|
-
assert_hash_equals json_response,
|
1689
|
-
{data: {
|
1690
|
-
type: 'people',
|
1691
|
-
id: '1'
|
1692
|
-
},
|
1693
|
-
links: {
|
1694
|
-
self: 'http://test.host/posts/1/relationships/author',
|
1695
|
-
related: 'http://test.host/posts/1/author'
|
1696
|
-
}
|
1697
|
-
}
|
1698
|
-
end
|
1699
|
-
|
1700
|
-
def test_show_to_many_relationship
|
1701
|
-
get :show_relationship, {post_id: '2', relationship: 'tags'}
|
1702
|
-
assert_response :success
|
1703
|
-
assert_hash_equals json_response,
|
1704
|
-
{
|
1705
|
-
data: [
|
1706
|
-
{type: 'tags', id: '5'}
|
1707
|
-
],
|
1708
|
-
links: {
|
1709
|
-
self: 'http://test.host/posts/2/relationships/tags',
|
1710
|
-
related: 'http://test.host/posts/2/tags'
|
1711
|
-
}
|
1712
|
-
}
|
1713
|
-
end
|
1714
|
-
|
1715
|
-
def test_show_to_many_relationship_invalid_id
|
1716
|
-
get :show_relationship, {post_id: '2,1', relationship: 'tags'}
|
1717
|
-
assert_response :bad_request
|
1718
|
-
assert_match /2,1 is not a valid value for id/, response.body
|
1719
|
-
end
|
1720
|
-
|
1721
|
-
def test_show_to_one_relationship_nil
|
1722
|
-
get :show_relationship, {post_id: '17', relationship: 'author'}
|
1723
|
-
assert_response :success
|
1724
|
-
assert_hash_equals json_response,
|
1725
|
-
{
|
1726
|
-
data: nil,
|
1727
|
-
links: {
|
1728
|
-
self: 'http://test.host/posts/17/relationships/author',
|
1729
|
-
related: 'http://test.host/posts/17/author'
|
1730
|
-
}
|
1731
|
-
}
|
1732
|
-
end
|
1733
|
-
end
|
1734
|
-
|
1735
|
-
class TagsControllerTest < ActionController::TestCase
|
1736
|
-
def test_tags_index
|
1737
|
-
get :index, {filter: {id: '6,7,8,9'}, include: 'posts.tags,posts.author.posts'}
|
1738
|
-
assert_response :success
|
1739
|
-
assert_equal 4, json_response['data'].size
|
1740
|
-
assert_equal 3, json_response['included'].size
|
1741
|
-
end
|
1742
|
-
|
1743
|
-
def test_tags_show_multiple
|
1744
|
-
get :show, {id: '6,7,8,9'}
|
1745
|
-
assert_response :bad_request
|
1746
|
-
assert_match /6,7,8,9 is not a valid value for id/, response.body
|
1747
|
-
end
|
1748
|
-
|
1749
|
-
def test_tags_show_multiple_with_include
|
1750
|
-
get :show, {id: '6,7,8,9', include: 'posts.tags,posts.author.posts'}
|
1751
|
-
assert_response :bad_request
|
1752
|
-
assert_match /6,7,8,9 is not a valid value for id/, response.body
|
1753
|
-
end
|
1754
|
-
|
1755
|
-
def test_tags_show_multiple_with_nonexistent_ids
|
1756
|
-
get :show, {id: '6,99,9,100'}
|
1757
|
-
assert_response :bad_request
|
1758
|
-
assert_match /6,99,9,100 is not a valid value for id/, response.body
|
1759
|
-
end
|
1760
|
-
|
1761
|
-
def test_tags_show_multiple_with_nonexistent_ids_at_the_beginning
|
1762
|
-
get :show, {id: '99,9,100'}
|
1763
|
-
assert_response :bad_request
|
1764
|
-
assert_match /99,9,100 is not a valid value for id/, response.body
|
1765
|
-
end
|
1766
|
-
end
|
1767
|
-
|
1768
|
-
class ExpenseEntriesControllerTest < ActionController::TestCase
|
1769
|
-
def setup
|
1770
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
1771
|
-
end
|
1772
|
-
|
1773
|
-
def test_text_error
|
1774
|
-
JSONAPI.configuration.use_text_errors = true
|
1775
|
-
get :index, {sort: 'not_in_record'}
|
1776
|
-
assert_response 400
|
1777
|
-
assert_equal 'INVALID_SORT_CRITERIA', json_response['errors'][0]['code']
|
1778
|
-
ensure
|
1779
|
-
JSONAPI.configuration.use_text_errors = false
|
1780
|
-
end
|
1781
|
-
|
1782
|
-
def test_expense_entries_index
|
1783
|
-
get :index
|
1784
|
-
assert_response :success
|
1785
|
-
assert json_response['data'].is_a?(Array)
|
1786
|
-
assert_equal 2, json_response['data'].size
|
1787
|
-
end
|
1788
|
-
|
1789
|
-
def test_expense_entries_show
|
1790
|
-
get :show, {id: 1}
|
1791
|
-
assert_response :success
|
1792
|
-
assert json_response['data'].is_a?(Hash)
|
1793
|
-
end
|
1794
|
-
|
1795
|
-
def test_expense_entries_show_include
|
1796
|
-
get :show, {id: 1, include: 'isoCurrency,employee'}
|
1797
|
-
assert_response :success
|
1798
|
-
assert json_response['data'].is_a?(Hash)
|
1799
|
-
assert_equal 2, json_response['included'].size
|
1800
|
-
end
|
1801
|
-
|
1802
|
-
def test_expense_entries_show_bad_include_missing_relationship
|
1803
|
-
get :show, {id: 1, include: 'isoCurrencies,employees'}
|
1804
|
-
assert_response :bad_request
|
1805
|
-
assert_match /isoCurrencies is not a valid relationship of expenseEntries/, json_response['errors'][0]['detail']
|
1806
|
-
assert_match /employees is not a valid relationship of expenseEntries/, json_response['errors'][1]['detail']
|
1807
|
-
end
|
1808
|
-
|
1809
|
-
def test_expense_entries_show_bad_include_missing_sub_relationship
|
1810
|
-
get :show, {id: 1, include: 'isoCurrency,employee.post'}
|
1811
|
-
assert_response :bad_request
|
1812
|
-
assert_match /post is not a valid relationship of people/, json_response['errors'][0]['detail']
|
1813
|
-
end
|
1814
|
-
|
1815
|
-
def test_expense_entries_show_fields
|
1816
|
-
get :show, {id: 1, include: 'isoCurrency,employee', 'fields' => {'expenseEntries' => 'transactionDate'}}
|
1817
|
-
assert_response :success
|
1818
|
-
assert json_response['data'].is_a?(Hash)
|
1819
|
-
assert json_response['data']['attributes'].key?('transactionDate')
|
1820
|
-
assert_equal 2, json_response['included'].size
|
1821
|
-
end
|
1822
|
-
|
1823
|
-
def test_expense_entries_show_fields_type_many
|
1824
|
-
get :show, {id: 1, include: 'isoCurrency,employee', 'fields' => {'expenseEntries' => 'transactionDate',
|
1825
|
-
'isoCurrencies' => 'id,name'}}
|
1826
|
-
assert_response :success
|
1827
|
-
assert json_response['data'].is_a?(Hash)
|
1828
|
-
assert json_response['data']['attributes'].key?('transactionDate')
|
1829
|
-
assert_equal 2, json_response['included'].size
|
1830
|
-
end
|
1831
|
-
|
1832
|
-
def test_create_expense_entries_underscored
|
1833
|
-
set_content_type_header!
|
1834
|
-
original_config = JSONAPI.configuration.dup
|
1835
|
-
JSONAPI.configuration.json_key_format = :underscored_key
|
1836
|
-
|
1837
|
-
post :create,
|
1838
|
-
{
|
1839
|
-
data: {
|
1840
|
-
type: 'expense_entries',
|
1841
|
-
attributes: {
|
1842
|
-
transaction_date: '2014/04/15',
|
1843
|
-
cost: 50.58
|
1844
|
-
},
|
1845
|
-
relationships: {
|
1846
|
-
employee: {data: {type: 'people', id: '3'}},
|
1847
|
-
iso_currency: {data: {type: 'iso_currencies', id: 'USD'}}
|
1848
|
-
}
|
1849
|
-
},
|
1850
|
-
include: 'iso_currency,employee',
|
1851
|
-
fields: {expense_entries: 'id,transaction_date,iso_currency,cost,employee'}
|
1852
|
-
}
|
1853
|
-
|
1854
|
-
assert_response :created
|
1855
|
-
assert json_response['data'].is_a?(Hash)
|
1856
|
-
assert_equal '3', json_response['data']['relationships']['employee']['data']['id']
|
1857
|
-
assert_equal 'USD', json_response['data']['relationships']['iso_currency']['data']['id']
|
1858
|
-
assert_equal '50.58', json_response['data']['attributes']['cost']
|
1859
|
-
|
1860
|
-
delete :destroy, {id: json_response['data']['id']}
|
1861
|
-
assert_response :no_content
|
1862
|
-
ensure
|
1863
|
-
JSONAPI.configuration = original_config
|
1864
|
-
end
|
1865
|
-
|
1866
|
-
def test_create_expense_entries_camelized_key
|
1867
|
-
set_content_type_header!
|
1868
|
-
original_config = JSONAPI.configuration.dup
|
1869
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
1870
|
-
|
1871
|
-
post :create,
|
1872
|
-
{
|
1873
|
-
data: {
|
1874
|
-
type: 'expense_entries',
|
1875
|
-
attributes: {
|
1876
|
-
transactionDate: '2014/04/15',
|
1877
|
-
cost: 50.58
|
1878
|
-
},
|
1879
|
-
relationships: {
|
1880
|
-
employee: {data: {type: 'people', id: '3'}},
|
1881
|
-
isoCurrency: {data: {type: 'iso_currencies', id: 'USD'}}
|
1882
|
-
}
|
1883
|
-
},
|
1884
|
-
include: 'isoCurrency,employee',
|
1885
|
-
fields: {expenseEntries: 'id,transactionDate,isoCurrency,cost,employee'}
|
1886
|
-
}
|
1887
|
-
|
1888
|
-
assert_response :created
|
1889
|
-
assert json_response['data'].is_a?(Hash)
|
1890
|
-
assert_equal '3', json_response['data']['relationships']['employee']['data']['id']
|
1891
|
-
assert_equal 'USD', json_response['data']['relationships']['isoCurrency']['data']['id']
|
1892
|
-
assert_equal '50.58', json_response['data']['attributes']['cost']
|
1893
|
-
|
1894
|
-
delete :destroy, {id: json_response['data']['id']}
|
1895
|
-
assert_response :no_content
|
1896
|
-
ensure
|
1897
|
-
JSONAPI.configuration = original_config
|
1898
|
-
end
|
1899
|
-
|
1900
|
-
def test_create_expense_entries_dasherized_key
|
1901
|
-
set_content_type_header!
|
1902
|
-
original_config = JSONAPI.configuration.dup
|
1903
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
1904
|
-
|
1905
|
-
post :create,
|
1906
|
-
{
|
1907
|
-
data: {
|
1908
|
-
type: 'expense_entries',
|
1909
|
-
attributes: {
|
1910
|
-
'transaction-date' => '2014/04/15',
|
1911
|
-
cost: 50.58
|
1912
|
-
},
|
1913
|
-
relationships: {
|
1914
|
-
employee: {data: {type: 'people', id: '3'}},
|
1915
|
-
'iso-currency' => {data: {type: 'iso_currencies', id: 'USD'}}
|
1916
|
-
}
|
1917
|
-
},
|
1918
|
-
include: 'iso-currency,employee',
|
1919
|
-
fields: {'expense-entries' => 'id,transaction-date,iso-currency,cost,employee'}
|
1920
|
-
}
|
1921
|
-
|
1922
|
-
assert_response :created
|
1923
|
-
assert json_response['data'].is_a?(Hash)
|
1924
|
-
assert_equal '3', json_response['data']['relationships']['employee']['data']['id']
|
1925
|
-
assert_equal 'USD', json_response['data']['relationships']['iso-currency']['data']['id']
|
1926
|
-
assert_equal '50.58', json_response['data']['attributes']['cost']
|
1927
|
-
|
1928
|
-
delete :destroy, {id: json_response['data']['id']}
|
1929
|
-
assert_response :no_content
|
1930
|
-
ensure
|
1931
|
-
JSONAPI.configuration = original_config
|
1932
|
-
end
|
1933
|
-
end
|
1934
|
-
|
1935
|
-
class IsoCurrenciesControllerTest < ActionController::TestCase
|
1936
|
-
def after_teardown
|
1937
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
1938
|
-
end
|
1939
|
-
|
1940
|
-
def test_currencies_show
|
1941
|
-
get :show, {id: 'USD'}
|
1942
|
-
assert_response :success
|
1943
|
-
assert json_response['data'].is_a?(Hash)
|
1944
|
-
end
|
1945
|
-
|
1946
|
-
def test_create_currencies_client_generated_id
|
1947
|
-
set_content_type_header!
|
1948
|
-
original_config = JSONAPI.configuration.dup
|
1949
|
-
JSONAPI.configuration.json_key_format = :underscored_route
|
1950
|
-
|
1951
|
-
post :create,
|
1952
|
-
{
|
1953
|
-
data: {
|
1954
|
-
type: 'iso_currencies',
|
1955
|
-
id: 'BTC',
|
1956
|
-
attributes: {
|
1957
|
-
name: 'Bit Coin',
|
1958
|
-
'country_name' => 'global',
|
1959
|
-
'minor_unit' => 'satoshi'
|
1960
|
-
}
|
1961
|
-
}
|
1962
|
-
}
|
1963
|
-
|
1964
|
-
assert_response :created
|
1965
|
-
assert_equal 'BTC', json_response['data']['id']
|
1966
|
-
assert_equal 'Bit Coin', json_response['data']['attributes']['name']
|
1967
|
-
assert_equal 'global', json_response['data']['attributes']['country_name']
|
1968
|
-
assert_equal 'satoshi', json_response['data']['attributes']['minor_unit']
|
1969
|
-
|
1970
|
-
delete :destroy, {id: json_response['data']['id']}
|
1971
|
-
assert_response :no_content
|
1972
|
-
ensure
|
1973
|
-
JSONAPI.configuration = original_config
|
1974
|
-
end
|
1975
|
-
|
1976
|
-
def test_currencies_primary_key_sort
|
1977
|
-
get :index, {sort: 'id'}
|
1978
|
-
assert_response :success
|
1979
|
-
assert_equal 3, json_response['data'].size
|
1980
|
-
assert_equal 'CAD', json_response['data'][0]['id']
|
1981
|
-
assert_equal 'EUR', json_response['data'][1]['id']
|
1982
|
-
assert_equal 'USD', json_response['data'][2]['id']
|
1983
|
-
end
|
1984
|
-
|
1985
|
-
def test_currencies_code_sort
|
1986
|
-
get :index, {sort: 'code'}
|
1987
|
-
assert_response :bad_request
|
1988
|
-
end
|
1989
|
-
|
1990
|
-
def test_currencies_json_key_underscored_sort
|
1991
|
-
original_config = JSONAPI.configuration.dup
|
1992
|
-
JSONAPI.configuration.json_key_format = :underscored_key
|
1993
|
-
get :index, {sort: 'country_name'}
|
1994
|
-
assert_response :success
|
1995
|
-
assert_equal 3, json_response['data'].size
|
1996
|
-
assert_equal 'Canada', json_response['data'][0]['attributes']['country_name']
|
1997
|
-
assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['country_name']
|
1998
|
-
assert_equal 'United States', json_response['data'][2]['attributes']['country_name']
|
1999
|
-
|
2000
|
-
# reverse sort
|
2001
|
-
get :index, {sort: '-country_name'}
|
2002
|
-
assert_response :success
|
2003
|
-
assert_equal 3, json_response['data'].size
|
2004
|
-
assert_equal 'United States', json_response['data'][0]['attributes']['country_name']
|
2005
|
-
assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['country_name']
|
2006
|
-
assert_equal 'Canada', json_response['data'][2]['attributes']['country_name']
|
2007
|
-
ensure
|
2008
|
-
JSONAPI.configuration = original_config
|
2009
|
-
end
|
2010
|
-
|
2011
|
-
def test_currencies_json_key_dasherized_sort
|
2012
|
-
original_config = JSONAPI.configuration.dup
|
2013
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
2014
|
-
get :index, {sort: 'country-name'}
|
2015
|
-
assert_response :success
|
2016
|
-
assert_equal 3, json_response['data'].size
|
2017
|
-
assert_equal 'Canada', json_response['data'][0]['attributes']['country-name']
|
2018
|
-
assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['country-name']
|
2019
|
-
assert_equal 'United States', json_response['data'][2]['attributes']['country-name']
|
2020
|
-
|
2021
|
-
# reverse sort
|
2022
|
-
get :index, {sort: '-country-name'}
|
2023
|
-
assert_response :success
|
2024
|
-
assert_equal 3, json_response['data'].size
|
2025
|
-
assert_equal 'United States', json_response['data'][0]['attributes']['country-name']
|
2026
|
-
assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['country-name']
|
2027
|
-
assert_equal 'Canada', json_response['data'][2]['attributes']['country-name']
|
2028
|
-
ensure
|
2029
|
-
JSONAPI.configuration = original_config
|
2030
|
-
end
|
2031
|
-
|
2032
|
-
def test_currencies_json_key_custom_json_key_sort
|
2033
|
-
original_config = JSONAPI.configuration.dup
|
2034
|
-
JSONAPI.configuration.json_key_format = :upper_camelized_key
|
2035
|
-
get :index, {sort: 'CountryName'}
|
2036
|
-
assert_response :success
|
2037
|
-
assert_equal 3, json_response['data'].size
|
2038
|
-
assert_equal 'Canada', json_response['data'][0]['attributes']['CountryName']
|
2039
|
-
assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['CountryName']
|
2040
|
-
assert_equal 'United States', json_response['data'][2]['attributes']['CountryName']
|
2041
|
-
|
2042
|
-
# reverse sort
|
2043
|
-
get :index, {sort: '-CountryName'}
|
2044
|
-
assert_response :success
|
2045
|
-
assert_equal 3, json_response['data'].size
|
2046
|
-
assert_equal 'United States', json_response['data'][0]['attributes']['CountryName']
|
2047
|
-
assert_equal 'Euro Member Countries', json_response['data'][1]['attributes']['CountryName']
|
2048
|
-
assert_equal 'Canada', json_response['data'][2]['attributes']['CountryName']
|
2049
|
-
ensure
|
2050
|
-
JSONAPI.configuration = original_config
|
2051
|
-
end
|
2052
|
-
|
2053
|
-
def test_currencies_json_key_underscored_filter
|
2054
|
-
original_config = JSONAPI.configuration.dup
|
2055
|
-
JSONAPI.configuration.json_key_format = :underscored_key
|
2056
|
-
get :index, {filter: {country_name: 'Canada'}}
|
2057
|
-
assert_response :success
|
2058
|
-
assert_equal 1, json_response['data'].size
|
2059
|
-
assert_equal 'Canada', json_response['data'][0]['attributes']['country_name']
|
2060
|
-
ensure
|
2061
|
-
JSONAPI.configuration = original_config
|
2062
|
-
end
|
2063
|
-
|
2064
|
-
def test_currencies_json_key_camelized_key_filter
|
2065
|
-
original_config = JSONAPI.configuration.dup
|
2066
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
2067
|
-
get :index, {filter: {'countryName' => 'Canada'}}
|
2068
|
-
assert_response :success
|
2069
|
-
assert_equal 1, json_response['data'].size
|
2070
|
-
assert_equal 'Canada', json_response['data'][0]['attributes']['countryName']
|
2071
|
-
ensure
|
2072
|
-
JSONAPI.configuration = original_config
|
2073
|
-
end
|
2074
|
-
|
2075
|
-
def test_currencies_json_key_custom_json_key_filter
|
2076
|
-
original_config = JSONAPI.configuration.dup
|
2077
|
-
JSONAPI.configuration.json_key_format = :upper_camelized_key
|
2078
|
-
get :index, {filter: {'CountryName' => 'Canada'}}
|
2079
|
-
assert_response :success
|
2080
|
-
assert_equal 1, json_response['data'].size
|
2081
|
-
assert_equal 'Canada', json_response['data'][0]['attributes']['CountryName']
|
2082
|
-
ensure
|
2083
|
-
JSONAPI.configuration = original_config
|
2084
|
-
end
|
2085
|
-
end
|
2086
|
-
|
2087
|
-
class PeopleControllerTest < ActionController::TestCase
|
2088
|
-
def setup
|
2089
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
2090
|
-
end
|
2091
|
-
|
2092
|
-
def test_create_validations
|
2093
|
-
set_content_type_header!
|
2094
|
-
post :create,
|
2095
|
-
{
|
2096
|
-
data: {
|
2097
|
-
type: 'people',
|
2098
|
-
attributes: {
|
2099
|
-
name: 'Steve Jobs',
|
2100
|
-
email: 'sj@email.zzz',
|
2101
|
-
dateJoined: DateTime.parse('2014-1-30 4:20:00 UTC +00:00')
|
2102
|
-
}
|
2103
|
-
}
|
2104
|
-
}
|
2105
|
-
|
2106
|
-
assert_response :success
|
2107
|
-
end
|
2108
|
-
|
2109
|
-
def test_update_link_with_dasherized_type
|
2110
|
-
original_config = JSONAPI.configuration.dup
|
2111
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
2112
|
-
set_content_type_header!
|
2113
|
-
put :update,
|
2114
|
-
{
|
2115
|
-
id: 3,
|
2116
|
-
data: {
|
2117
|
-
id: '3',
|
2118
|
-
type: 'people',
|
2119
|
-
relationships: {
|
2120
|
-
'hair-cut' => {
|
2121
|
-
data: {
|
2122
|
-
type: 'hair-cuts',
|
2123
|
-
id: '1'
|
2124
|
-
}
|
2125
|
-
}
|
2126
|
-
}
|
2127
|
-
}
|
2128
|
-
}
|
2129
|
-
assert_response :success
|
2130
|
-
ensure
|
2131
|
-
JSONAPI.configuration = original_config
|
2132
|
-
end
|
2133
|
-
|
2134
|
-
def test_create_validations_missing_attribute
|
2135
|
-
set_content_type_header!
|
2136
|
-
post :create,
|
2137
|
-
{
|
2138
|
-
data: {
|
2139
|
-
type: 'people',
|
2140
|
-
attributes: {
|
2141
|
-
email: 'sj@email.zzz'
|
2142
|
-
}
|
2143
|
-
}
|
2144
|
-
}
|
2145
|
-
|
2146
|
-
assert_response :unprocessable_entity
|
2147
|
-
assert_equal 2, json_response['errors'].size
|
2148
|
-
assert_equal JSONAPI::VALIDATION_ERROR, json_response['errors'][0]['code']
|
2149
|
-
assert_equal JSONAPI::VALIDATION_ERROR, json_response['errors'][1]['code']
|
2150
|
-
assert_match /dateJoined - can't be blank/, response.body
|
2151
|
-
assert_match /name - can't be blank/, response.body
|
2152
|
-
end
|
2153
|
-
|
2154
|
-
def test_update_validations_missing_attribute
|
2155
|
-
set_content_type_header!
|
2156
|
-
put :update,
|
2157
|
-
{
|
2158
|
-
id: 3,
|
2159
|
-
data: {
|
2160
|
-
id: '3',
|
2161
|
-
type: 'people',
|
2162
|
-
attributes: {
|
2163
|
-
name: ''
|
2164
|
-
}
|
2165
|
-
}
|
2166
|
-
}
|
2167
|
-
|
2168
|
-
assert_response :unprocessable_entity
|
2169
|
-
assert_equal 1, json_response['errors'].size
|
2170
|
-
assert_equal JSONAPI::VALIDATION_ERROR, json_response['errors'][0]['code']
|
2171
|
-
assert_match /name - can't be blank/, response.body
|
2172
|
-
end
|
2173
|
-
|
2174
|
-
def test_delete_locked
|
2175
|
-
initial_count = Person.count
|
2176
|
-
delete :destroy, {id: '3'}
|
2177
|
-
assert_response :locked
|
2178
|
-
assert_equal initial_count, Person.count
|
2179
|
-
end
|
2180
|
-
|
2181
|
-
def test_invalid_filter_value
|
2182
|
-
get :index, {filter: {name: 'L'}}
|
2183
|
-
assert_response :bad_request
|
2184
|
-
end
|
2185
|
-
|
2186
|
-
def test_valid_filter_value
|
2187
|
-
get :index, {filter: {name: 'Joe Author'}}
|
2188
|
-
assert_response :success
|
2189
|
-
assert_equal json_response['data'].size, 1
|
2190
|
-
assert_equal json_response['data'][0]['id'], '1'
|
2191
|
-
assert_equal json_response['data'][0]['attributes']['name'], 'Joe Author'
|
2192
|
-
end
|
2193
|
-
|
2194
|
-
def test_get_related_resource_no_namespace
|
2195
|
-
original_config = JSONAPI.configuration.dup
|
2196
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
2197
|
-
JSONAPI.configuration.route_format = :underscored_key
|
2198
|
-
get :get_related_resource, {post_id: '2', relationship: 'author', source:'posts'}
|
2199
|
-
assert_response :success
|
2200
|
-
assert_hash_equals(
|
2201
|
-
{
|
2202
|
-
data: {
|
2203
|
-
id: '1',
|
2204
|
-
type: 'people',
|
2205
|
-
attributes: {
|
2206
|
-
name: 'Joe Author',
|
2207
|
-
email: 'joe@xyz.fake',
|
2208
|
-
"date-joined" => '2013-08-07 16:25:00 -0400'
|
2209
|
-
},
|
2210
|
-
links: {
|
2211
|
-
self: 'http://test.host/people/1'
|
2212
|
-
},
|
2213
|
-
relationships: {
|
2214
|
-
comments: {
|
2215
|
-
links: {
|
2216
|
-
self: 'http://test.host/people/1/relationships/comments',
|
2217
|
-
related: 'http://test.host/people/1/comments'
|
2218
|
-
}
|
2219
|
-
},
|
2220
|
-
posts: {
|
2221
|
-
links: {
|
2222
|
-
self: 'http://test.host/people/1/relationships/posts',
|
2223
|
-
related: 'http://test.host/people/1/posts'
|
2224
|
-
}
|
2225
|
-
},
|
2226
|
-
preferences: {
|
2227
|
-
links: {
|
2228
|
-
self: 'http://test.host/people/1/relationships/preferences',
|
2229
|
-
related: 'http://test.host/people/1/preferences'
|
2230
|
-
}
|
2231
|
-
},
|
2232
|
-
"hair-cut" => {
|
2233
|
-
"links" => {
|
2234
|
-
"self" => "http://test.host/people/1/relationships/hair_cut",
|
2235
|
-
"related" => "http://test.host/people/1/hair_cut"
|
2236
|
-
}
|
2237
|
-
},
|
2238
|
-
vehicles: {
|
2239
|
-
links: {
|
2240
|
-
self: "http://test.host/people/1/relationships/vehicles",
|
2241
|
-
related: "http://test.host/people/1/vehicles"
|
2242
|
-
}
|
2243
|
-
}
|
2244
|
-
}
|
2245
|
-
}
|
2246
|
-
},
|
2247
|
-
json_response
|
2248
|
-
)
|
2249
|
-
ensure
|
2250
|
-
JSONAPI.configuration = original_config
|
2251
|
-
end
|
2252
|
-
|
2253
|
-
def test_get_related_resource_nil
|
2254
|
-
get :get_related_resource, {post_id: '17', relationship: 'author', source:'posts'}
|
2255
|
-
assert_response :success
|
2256
|
-
assert_hash_equals json_response,
|
2257
|
-
{
|
2258
|
-
data: nil
|
2259
|
-
}
|
2260
|
-
|
2261
|
-
end
|
2262
|
-
end
|
2263
|
-
|
2264
|
-
class BooksControllerTest < ActionController::TestCase
|
2265
|
-
def test_books_include_correct_type
|
2266
|
-
$test_user = Person.find(1)
|
2267
|
-
get :index, {filter: {id: '1'}, include: 'authors'}
|
2268
|
-
assert_response :success
|
2269
|
-
assert_equal 'authors', json_response['included'][0]['type']
|
2270
|
-
end
|
2271
|
-
end
|
2272
|
-
|
2273
|
-
class Api::V5::AuthorsControllerTest < ActionController::TestCase
|
2274
|
-
def test_get_person_as_author
|
2275
|
-
get :index, {filter: {id: '1'}}
|
2276
|
-
assert_response :success
|
2277
|
-
assert_equal 1, json_response['data'].size
|
2278
|
-
assert_equal '1', json_response['data'][0]['id']
|
2279
|
-
assert_equal 'authors', json_response['data'][0]['type']
|
2280
|
-
assert_equal 'Joe Author', json_response['data'][0]['attributes']['name']
|
2281
|
-
assert_equal nil, json_response['data'][0]['attributes']['email']
|
2282
|
-
end
|
2283
|
-
|
2284
|
-
def test_show_person_as_author
|
2285
|
-
get :show, {id: '1'}
|
2286
|
-
assert_response :success
|
2287
|
-
assert_equal '1', json_response['data']['id']
|
2288
|
-
assert_equal 'authors', json_response['data']['type']
|
2289
|
-
assert_equal 'Joe Author', json_response['data']['attributes']['name']
|
2290
|
-
assert_equal nil, json_response['data']['attributes']['email']
|
2291
|
-
end
|
2292
|
-
|
2293
|
-
def test_get_person_as_author_by_name_filter
|
2294
|
-
get :index, {filter: {name: 'thor'}}
|
2295
|
-
assert_response :success
|
2296
|
-
assert_equal 3, json_response['data'].size
|
2297
|
-
assert_equal '1', json_response['data'][0]['id']
|
2298
|
-
assert_equal 'Joe Author', json_response['data'][0]['attributes']['name']
|
2299
|
-
end
|
2300
|
-
|
2301
|
-
def test_meta_serializer_options
|
2302
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
2303
|
-
|
2304
|
-
Api::V5::AuthorResource.class_eval do
|
2305
|
-
def meta(options)
|
2306
|
-
{
|
2307
|
-
fixed: 'Hardcoded value',
|
2308
|
-
computed: "#{self.class._type.to_s}: #{options[:serializer].link_builder.self_link(self)}",
|
2309
|
-
computed_foo: options[:serialization_options][:foo],
|
2310
|
-
options[:serializer].format_key('test_key') => 'test value'
|
2311
|
-
}
|
2312
|
-
end
|
2313
|
-
end
|
2314
|
-
|
2315
|
-
get :show, {id: '1'}
|
2316
|
-
assert_response :success
|
2317
|
-
assert_equal '1', json_response['data']['id']
|
2318
|
-
assert_equal 'Hardcoded value', json_response['data']['meta']['fixed']
|
2319
|
-
assert_equal 'authors: http://test.host/api/v5/authors/1', json_response['data']['meta']['computed']
|
2320
|
-
assert_equal 'bar', json_response['data']['meta']['computed_foo']
|
2321
|
-
assert_equal 'test value', json_response['data']['meta']['testKey']
|
2322
|
-
|
2323
|
-
ensure
|
2324
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
2325
|
-
Api::V5::AuthorResource.class_eval do
|
2326
|
-
def meta(options)
|
2327
|
-
# :nocov:
|
2328
|
-
{ }
|
2329
|
-
# :nocov:
|
2330
|
-
end
|
2331
|
-
end
|
2332
|
-
end
|
2333
|
-
|
2334
|
-
def test_meta_serializer_hash_data
|
2335
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
2336
|
-
|
2337
|
-
Api::V5::AuthorResource.class_eval do
|
2338
|
-
def meta(options)
|
2339
|
-
{
|
2340
|
-
custom_hash: {
|
2341
|
-
fixed: 'Hardcoded value',
|
2342
|
-
computed: "#{self.class._type.to_s}: #{options[:serializer].link_builder.self_link(self)}",
|
2343
|
-
computed_foo: options[:serialization_options][:foo],
|
2344
|
-
options[:serializer].format_key('test_key') => 'test value'
|
2345
|
-
}
|
2346
|
-
}
|
2347
|
-
end
|
2348
|
-
end
|
2349
|
-
|
2350
|
-
get :show, {id: '1'}
|
2351
|
-
assert_response :success
|
2352
|
-
assert_equal '1', json_response['data']['id']
|
2353
|
-
assert_equal 'Hardcoded value', json_response['data']['meta']['custom_hash']['fixed']
|
2354
|
-
assert_equal 'authors: http://test.host/api/v5/authors/1', json_response['data']['meta']['custom_hash']['computed']
|
2355
|
-
assert_equal 'bar', json_response['data']['meta']['custom_hash']['computed_foo']
|
2356
|
-
assert_equal 'test value', json_response['data']['meta']['custom_hash']['testKey']
|
2357
|
-
|
2358
|
-
ensure
|
2359
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
2360
|
-
Api::V5::AuthorResource.class_eval do
|
2361
|
-
def meta(options)
|
2362
|
-
# :nocov:
|
2363
|
-
{ }
|
2364
|
-
# :nocov:
|
2365
|
-
end
|
2366
|
-
end
|
2367
|
-
end
|
2368
|
-
end
|
2369
|
-
|
2370
|
-
class BreedsControllerTest < ActionController::TestCase
|
2371
|
-
# Note: Breed names go through the TitleValueFormatter
|
2372
|
-
|
2373
|
-
def test_poro_index
|
2374
|
-
get :index
|
2375
|
-
assert_response :success
|
2376
|
-
assert_equal '0', json_response['data'][0]['id']
|
2377
|
-
assert_equal 'Persian', json_response['data'][0]['attributes']['name']
|
2378
|
-
end
|
2379
|
-
|
2380
|
-
def test_poro_show
|
2381
|
-
get :show, {id: '0'}
|
2382
|
-
assert_response :success
|
2383
|
-
assert json_response['data'].is_a?(Hash)
|
2384
|
-
assert_equal '0', json_response['data']['id']
|
2385
|
-
assert_equal 'Persian', json_response['data']['attributes']['name']
|
2386
|
-
end
|
2387
|
-
|
2388
|
-
def test_poro_show_multiple
|
2389
|
-
get :show, {id: '0,2'}
|
2390
|
-
|
2391
|
-
assert_response :bad_request
|
2392
|
-
assert_match /0,2 is not a valid value for id/, response.body
|
2393
|
-
end
|
2394
|
-
|
2395
|
-
def test_poro_create_simple
|
2396
|
-
set_content_type_header!
|
2397
|
-
post :create,
|
2398
|
-
{
|
2399
|
-
data: {
|
2400
|
-
type: 'breeds',
|
2401
|
-
attributes: {
|
2402
|
-
name: 'tabby'
|
2403
|
-
}
|
2404
|
-
}
|
2405
|
-
}
|
2406
|
-
|
2407
|
-
assert_response :accepted
|
2408
|
-
assert json_response['data'].is_a?(Hash)
|
2409
|
-
assert_equal 'Tabby', json_response['data']['attributes']['name']
|
2410
|
-
end
|
2411
|
-
|
2412
|
-
def test_poro_create_validation_error
|
2413
|
-
set_content_type_header!
|
2414
|
-
post :create,
|
2415
|
-
{
|
2416
|
-
data: {
|
2417
|
-
type: 'breeds',
|
2418
|
-
attributes: {
|
2419
|
-
name: ''
|
2420
|
-
}
|
2421
|
-
}
|
2422
|
-
}
|
2423
|
-
|
2424
|
-
assert_equal 1, json_response['errors'].size
|
2425
|
-
assert_equal JSONAPI::VALIDATION_ERROR, json_response['errors'][0]['code']
|
2426
|
-
assert_match /name - can't be blank/, response.body
|
2427
|
-
end
|
2428
|
-
|
2429
|
-
def test_poro_create_update
|
2430
|
-
set_content_type_header!
|
2431
|
-
post :create,
|
2432
|
-
{
|
2433
|
-
data: {
|
2434
|
-
type: 'breeds',
|
2435
|
-
attributes: {
|
2436
|
-
name: 'CALIC'
|
2437
|
-
}
|
2438
|
-
}
|
2439
|
-
}
|
2440
|
-
|
2441
|
-
assert_response :accepted
|
2442
|
-
assert json_response['data'].is_a?(Hash)
|
2443
|
-
assert_equal 'Calic', json_response['data']['attributes']['name']
|
2444
|
-
|
2445
|
-
put :update,
|
2446
|
-
{
|
2447
|
-
id: json_response['data']['id'],
|
2448
|
-
data: {
|
2449
|
-
id: json_response['data']['id'],
|
2450
|
-
type: 'breeds',
|
2451
|
-
attributes: {
|
2452
|
-
name: 'calico'
|
2453
|
-
}
|
2454
|
-
}
|
2455
|
-
}
|
2456
|
-
assert_response :success
|
2457
|
-
assert json_response['data'].is_a?(Hash)
|
2458
|
-
assert_equal 'Calico', json_response['data']['attributes']['name']
|
2459
|
-
end
|
2460
|
-
|
2461
|
-
def test_poro_delete
|
2462
|
-
initial_count = $breed_data.breeds.keys.count
|
2463
|
-
delete :destroy, {id: '3'}
|
2464
|
-
assert_response :no_content
|
2465
|
-
assert_equal initial_count - 1, $breed_data.breeds.keys.count
|
2466
|
-
end
|
2467
|
-
|
2468
|
-
end
|
2469
|
-
|
2470
|
-
class Api::V2::PreferencesControllerTest < ActionController::TestCase
|
2471
|
-
def test_show_singleton_resource_without_id
|
2472
|
-
get :show
|
2473
|
-
assert_response :success
|
2474
|
-
end
|
2475
|
-
|
2476
|
-
def test_update_singleton_resource_without_id
|
2477
|
-
set_content_type_header!
|
2478
|
-
patch :update,
|
2479
|
-
data: {
|
2480
|
-
id: "1",
|
2481
|
-
type: "preferences",
|
2482
|
-
attributes: {
|
2483
|
-
}
|
2484
|
-
}
|
2485
|
-
assert_response :success
|
2486
|
-
end
|
2487
|
-
end
|
2488
|
-
|
2489
|
-
class Api::V1::PostsControllerTest < ActionController::TestCase
|
2490
|
-
def test_show_post_namespaced
|
2491
|
-
get :show, {id: '1'}
|
2492
|
-
assert_response :success
|
2493
|
-
assert_equal 'http://test.host/api/v1/posts/1/relationships/writer', json_response['data']['relationships']['writer']['links']['self']
|
2494
|
-
end
|
2495
|
-
|
2496
|
-
def test_show_post_namespaced_include
|
2497
|
-
get :show, {id: '1', include: 'writer'}
|
2498
|
-
assert_response :success
|
2499
|
-
assert_equal '1', json_response['data']['relationships']['writer']['data']['id']
|
2500
|
-
assert_nil json_response['data']['relationships']['tags']
|
2501
|
-
assert_equal '1', json_response['included'][0]['id']
|
2502
|
-
assert_equal 'writers', json_response['included'][0]['type']
|
2503
|
-
assert_equal 'joe@xyz.fake', json_response['included'][0]['attributes']['email']
|
2504
|
-
end
|
2505
|
-
|
2506
|
-
def test_index_filter_on_relationship_namespaced
|
2507
|
-
get :index, {filter: {writer: '1'}}
|
2508
|
-
assert_response :success
|
2509
|
-
assert_equal 3, json_response['data'].size
|
2510
|
-
end
|
2511
|
-
|
2512
|
-
def test_sorting_desc_namespaced
|
2513
|
-
get :index, {sort: '-title'}
|
2514
|
-
|
2515
|
-
assert_response :success
|
2516
|
-
assert_equal "Update This Later - Multiple", json_response['data'][0]['attributes']['title']
|
2517
|
-
end
|
2518
|
-
|
2519
|
-
def test_create_simple_namespaced
|
2520
|
-
set_content_type_header!
|
2521
|
-
post :create,
|
2522
|
-
{
|
2523
|
-
data: {
|
2524
|
-
type: 'posts',
|
2525
|
-
attributes: {
|
2526
|
-
title: 'JR - now with Namespacing',
|
2527
|
-
body: 'JSONAPIResources is the greatest thing since unsliced bread now that it has namespaced resources.'
|
2528
|
-
},
|
2529
|
-
relationships: {
|
2530
|
-
writer: { data: {type: 'writers', id: '3'}}
|
2531
|
-
}
|
2532
|
-
}
|
2533
|
-
}
|
2534
|
-
|
2535
|
-
assert_response :created
|
2536
|
-
assert json_response['data'].is_a?(Hash)
|
2537
|
-
assert_equal 'JR - now with Namespacing', json_response['data']['attributes']['title']
|
2538
|
-
assert_equal 'JSONAPIResources is the greatest thing since unsliced bread now that it has namespaced resources.',
|
2539
|
-
json_response['data']['attributes']['body']
|
2540
|
-
end
|
2541
|
-
|
2542
|
-
end
|
2543
|
-
|
2544
|
-
class FactsControllerTest < ActionController::TestCase
|
2545
|
-
def test_type_formatting
|
2546
|
-
original_config = JSONAPI.configuration.dup
|
2547
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
2548
|
-
get :show, {id: '1'}
|
2549
|
-
assert_response :success
|
2550
|
-
assert json_response['data'].is_a?(Hash)
|
2551
|
-
assert_equal 'Jane Author', json_response['data']['attributes']['spouseName']
|
2552
|
-
assert_equal 'First man to run across Antartica.', json_response['data']['attributes']['bio']
|
2553
|
-
assert_equal 23.89/45.6, json_response['data']['attributes']['qualityRating']
|
2554
|
-
assert_equal '47000.56', json_response['data']['attributes']['salary']
|
2555
|
-
assert_equal '2013-08-07T20:25:00Z', json_response['data']['attributes']['dateTimeJoined']
|
2556
|
-
assert_equal '1965-06-30', json_response['data']['attributes']['birthday']
|
2557
|
-
assert_equal '2000-01-01T20:00:00Z', json_response['data']['attributes']['bedtime']
|
2558
|
-
assert_equal 'abc', json_response['data']['attributes']['photo']
|
2559
|
-
assert_equal false, json_response['data']['attributes']['cool']
|
2560
|
-
ensure
|
2561
|
-
JSONAPI.configuration = original_config
|
2562
|
-
end
|
2563
|
-
|
2564
|
-
def test_create_with_invalid_data
|
2565
|
-
original_config = JSONAPI.configuration.dup
|
2566
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
2567
|
-
set_content_type_header!
|
2568
|
-
post :create,
|
2569
|
-
{
|
2570
|
-
data: {
|
2571
|
-
type: 'facts',
|
2572
|
-
attributes: {
|
2573
|
-
bio: '',
|
2574
|
-
:"quality-rating" => '',
|
2575
|
-
:"spouse-name" => '',
|
2576
|
-
salary: 100000,
|
2577
|
-
:"date-time-joined" => '',
|
2578
|
-
birthday: '',
|
2579
|
-
bedtime: '',
|
2580
|
-
photo: 'abc',
|
2581
|
-
cool: false
|
2582
|
-
},
|
2583
|
-
relationships: {
|
2584
|
-
}
|
2585
|
-
}
|
2586
|
-
}
|
2587
|
-
|
2588
|
-
assert_response :unprocessable_entity
|
2589
|
-
|
2590
|
-
assert_equal "/data/attributes/spouse-name", json_response['errors'][0]['source']['pointer']
|
2591
|
-
assert_equal "can't be blank", json_response['errors'][0]['title']
|
2592
|
-
assert_equal "spouse-name - can't be blank", json_response['errors'][0]['detail']
|
2593
|
-
|
2594
|
-
assert_equal "/data/attributes/bio", json_response['errors'][1]['source']['pointer']
|
2595
|
-
assert_equal "can't be blank", json_response['errors'][1]['title']
|
2596
|
-
assert_equal "bio - can't be blank", json_response['errors'][1]['detail']
|
2597
|
-
ensure
|
2598
|
-
JSONAPI.configuration = original_config
|
2599
|
-
end
|
2600
|
-
end
|
2601
|
-
|
2602
|
-
class Api::V2::BooksControllerTest < ActionController::TestCase
|
2603
|
-
def setup
|
2604
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
2605
|
-
$test_user = Person.find(1)
|
2606
|
-
end
|
2607
|
-
|
2608
|
-
def after_teardown
|
2609
|
-
Api::V2::BookResource.paginator :offset
|
2610
|
-
end
|
2611
|
-
|
2612
|
-
def test_books_offset_pagination_no_params
|
2613
|
-
Api::V2::BookResource.paginator :offset
|
2614
|
-
|
2615
|
-
get :index
|
2616
|
-
assert_response :success
|
2617
|
-
assert_equal 10, json_response['data'].size
|
2618
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2619
|
-
end
|
2620
|
-
|
2621
|
-
def test_books_record_count_in_meta
|
2622
|
-
Api::V2::BookResource.paginator :offset
|
2623
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
2624
|
-
get :index, {include: 'book-comments'}
|
2625
|
-
JSONAPI.configuration.top_level_meta_include_record_count = false
|
2626
|
-
|
2627
|
-
assert_response :success
|
2628
|
-
assert_equal 901, json_response['meta']['record-count']
|
2629
|
-
assert_equal 10, json_response['data'].size
|
2630
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2631
|
-
end
|
2632
|
-
|
2633
|
-
def test_books_record_count_in_meta_custom_name
|
2634
|
-
Api::V2::BookResource.paginator :offset
|
2635
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
2636
|
-
JSONAPI.configuration.top_level_meta_record_count_key = 'total_records'
|
2637
|
-
|
2638
|
-
get :index, {include: 'book-comments'}
|
2639
|
-
JSONAPI.configuration.top_level_meta_include_record_count = false
|
2640
|
-
JSONAPI.configuration.top_level_meta_record_count_key = :record_count
|
2641
|
-
|
2642
|
-
assert_response :success
|
2643
|
-
assert_equal 901, json_response['meta']['total-records']
|
2644
|
-
assert_equal 10, json_response['data'].size
|
2645
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2646
|
-
end
|
2647
|
-
|
2648
|
-
def test_books_offset_pagination_no_params_includes_query_count_one_level
|
2649
|
-
Api::V2::BookResource.paginator :offset
|
2650
|
-
|
2651
|
-
count_queries do
|
2652
|
-
get :index, {include: 'book-comments'}
|
2653
|
-
end
|
2654
|
-
assert_response :success
|
2655
|
-
assert_equal 10, json_response['data'].size
|
2656
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2657
|
-
assert_query_count(3)
|
2658
|
-
end
|
2659
|
-
|
2660
|
-
def test_books_offset_pagination_no_params_includes_query_count_two_levels
|
2661
|
-
Api::V2::BookResource.paginator :offset
|
2662
|
-
|
2663
|
-
count_queries do
|
2664
|
-
get :index, {include: 'book-comments,book-comments.author'}
|
2665
|
-
end
|
2666
|
-
assert_response :success
|
2667
|
-
assert_equal 10, json_response['data'].size
|
2668
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2669
|
-
assert_query_count(4)
|
2670
|
-
end
|
2671
|
-
|
2672
|
-
def test_books_offset_pagination
|
2673
|
-
Api::V2::BookResource.paginator :offset
|
2674
|
-
|
2675
|
-
get :index, {page: {offset: 50, limit: 12}}
|
2676
|
-
assert_response :success
|
2677
|
-
assert_equal 12, json_response['data'].size
|
2678
|
-
assert_equal 'Book 50', json_response['data'][0]['attributes']['title']
|
2679
|
-
end
|
2680
|
-
|
2681
|
-
def test_books_offset_pagination_bad_page_param
|
2682
|
-
Api::V2::BookResource.paginator :offset
|
2683
|
-
|
2684
|
-
get :index, {page: {offset_bad: 50, limit: 12}}
|
2685
|
-
assert_response :bad_request
|
2686
|
-
assert_match /offset_bad is not an allowed page parameter./, json_response['errors'][0]['detail']
|
2687
|
-
end
|
2688
|
-
|
2689
|
-
def test_books_offset_pagination_bad_param_value_limit_to_large
|
2690
|
-
Api::V2::BookResource.paginator :offset
|
2691
|
-
|
2692
|
-
get :index, {page: {offset: 50, limit: 1000}}
|
2693
|
-
assert_response :bad_request
|
2694
|
-
assert_match /Limit exceeds maximum page size of 20./, json_response['errors'][0]['detail']
|
2695
|
-
end
|
2696
|
-
|
2697
|
-
def test_books_offset_pagination_bad_param_value_limit_too_small
|
2698
|
-
Api::V2::BookResource.paginator :offset
|
2699
|
-
|
2700
|
-
get :index, {page: {offset: 50, limit: -1}}
|
2701
|
-
assert_response :bad_request
|
2702
|
-
assert_match /-1 is not a valid value for limit page parameter./, json_response['errors'][0]['detail']
|
2703
|
-
end
|
2704
|
-
|
2705
|
-
def test_books_offset_pagination_bad_param_offset_less_than_zero
|
2706
|
-
Api::V2::BookResource.paginator :offset
|
2707
|
-
|
2708
|
-
get :index, {page: {offset: -1, limit: 20}}
|
2709
|
-
assert_response :bad_request
|
2710
|
-
assert_match /-1 is not a valid value for offset page parameter./, json_response['errors'][0]['detail']
|
2711
|
-
end
|
2712
|
-
|
2713
|
-
def test_books_offset_pagination_invalid_page_format
|
2714
|
-
Api::V2::BookResource.paginator :offset
|
2715
|
-
|
2716
|
-
get :index, {page: 50}
|
2717
|
-
assert_response :bad_request
|
2718
|
-
assert_match /Invalid Page Object./, json_response['errors'][0]['detail']
|
2719
|
-
end
|
2720
|
-
|
2721
|
-
def test_books_paged_pagination_no_params
|
2722
|
-
Api::V2::BookResource.paginator :paged
|
2723
|
-
|
2724
|
-
get :index
|
2725
|
-
assert_response :success
|
2726
|
-
assert_equal 10, json_response['data'].size
|
2727
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2728
|
-
end
|
2729
|
-
|
2730
|
-
def test_books_paged_pagination_no_page
|
2731
|
-
Api::V2::BookResource.paginator :paged
|
2732
|
-
|
2733
|
-
get :index, {page: {size: 12}}
|
2734
|
-
assert_response :success
|
2735
|
-
assert_equal 12, json_response['data'].size
|
2736
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2737
|
-
end
|
2738
|
-
|
2739
|
-
def test_books_paged_pagination
|
2740
|
-
Api::V2::BookResource.paginator :paged
|
2741
|
-
|
2742
|
-
get :index, {page: {number: 3, size: 12}}
|
2743
|
-
assert_response :success
|
2744
|
-
assert_equal 12, json_response['data'].size
|
2745
|
-
assert_equal 'Book 24', json_response['data'][0]['attributes']['title']
|
2746
|
-
end
|
2747
|
-
|
2748
|
-
def test_books_paged_pagination_bad_page_param
|
2749
|
-
Api::V2::BookResource.paginator :paged
|
2750
|
-
|
2751
|
-
get :index, {page: {number_bad: 50, size: 12}}
|
2752
|
-
assert_response :bad_request
|
2753
|
-
assert_match /number_bad is not an allowed page parameter./, json_response['errors'][0]['detail']
|
2754
|
-
end
|
2755
|
-
|
2756
|
-
def test_books_paged_pagination_bad_param_value_limit_to_large
|
2757
|
-
Api::V2::BookResource.paginator :paged
|
2758
|
-
|
2759
|
-
get :index, {page: {number: 50, size: 1000}}
|
2760
|
-
assert_response :bad_request
|
2761
|
-
assert_match /size exceeds maximum page size of 20./, json_response['errors'][0]['detail']
|
2762
|
-
end
|
2763
|
-
|
2764
|
-
def test_books_paged_pagination_bad_param_value_limit_too_small
|
2765
|
-
Api::V2::BookResource.paginator :paged
|
2766
|
-
|
2767
|
-
get :index, {page: {number: 50, size: -1}}
|
2768
|
-
assert_response :bad_request
|
2769
|
-
assert_match /-1 is not a valid value for size page parameter./, json_response['errors'][0]['detail']
|
2770
|
-
end
|
2771
|
-
|
2772
|
-
def test_books_paged_pagination_invalid_page_format_incorrect
|
2773
|
-
Api::V2::BookResource.paginator :paged
|
2774
|
-
|
2775
|
-
get :index, {page: 'qwerty'}
|
2776
|
-
assert_response :bad_request
|
2777
|
-
assert_match /0 is not a valid value for number page parameter./, json_response['errors'][0]['detail']
|
2778
|
-
end
|
2779
|
-
|
2780
|
-
def test_books_paged_pagination_invalid_page_format_interpret_int
|
2781
|
-
Api::V2::BookResource.paginator :paged
|
2782
|
-
|
2783
|
-
get :index, {page: 3}
|
2784
|
-
assert_response :success
|
2785
|
-
assert_equal 10, json_response['data'].size
|
2786
|
-
assert_equal 'Book 20', json_response['data'][0]['attributes']['title']
|
2787
|
-
end
|
2788
|
-
|
2789
|
-
def test_books_included_paged
|
2790
|
-
Api::V2::BookResource.paginator :offset
|
2791
|
-
|
2792
|
-
count_queries do
|
2793
|
-
get :index, {filter: {id: '0'}, include: 'book-comments'}
|
2794
|
-
end
|
2795
|
-
assert_response :success
|
2796
|
-
assert_equal 1, json_response['data'].size
|
2797
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2798
|
-
assert_query_count(3)
|
2799
|
-
end
|
2800
|
-
|
2801
|
-
def test_books_banned_non_book_admin
|
2802
|
-
$test_user = Person.find(1)
|
2803
|
-
Api::V2::BookResource.paginator :offset
|
2804
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
2805
|
-
count_queries do
|
2806
|
-
get :index, {page: {offset: 50, limit: 12}}
|
2807
|
-
end
|
2808
|
-
assert_response :success
|
2809
|
-
assert_equal 12, json_response['data'].size
|
2810
|
-
assert_equal 'Book 50', json_response['data'][0]['attributes']['title']
|
2811
|
-
assert_equal 901, json_response['meta']['record-count']
|
2812
|
-
assert_query_count(2)
|
2813
|
-
ensure
|
2814
|
-
JSONAPI.configuration.top_level_meta_include_record_count = false
|
2815
|
-
end
|
2816
|
-
|
2817
|
-
def test_books_banned_non_book_admin_includes_switched
|
2818
|
-
$test_user = Person.find(1)
|
2819
|
-
Api::V2::BookResource.paginator :offset
|
2820
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
2821
|
-
count_queries do
|
2822
|
-
get :index, {page: {offset: 0, limit: 12}, include: 'book-comments'}
|
2823
|
-
end
|
2824
|
-
|
2825
|
-
assert_response :success
|
2826
|
-
assert_equal 12, json_response['data'].size
|
2827
|
-
assert_equal 130, json_response['included'].size
|
2828
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2829
|
-
assert_equal 26, json_response['data'][0]['relationships']['book-comments']['data'].size
|
2830
|
-
assert_equal 'book-comments', json_response['included'][0]['type']
|
2831
|
-
assert_equal 901, json_response['meta']['record-count']
|
2832
|
-
assert_query_count(3)
|
2833
|
-
ensure
|
2834
|
-
JSONAPI.configuration.top_level_meta_include_record_count = false
|
2835
|
-
end
|
2836
|
-
|
2837
|
-
def test_books_banned_non_book_admin_includes_nested_includes
|
2838
|
-
$test_user = Person.find(1)
|
2839
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
2840
|
-
Api::V2::BookResource.paginator :offset
|
2841
|
-
count_queries do
|
2842
|
-
get :index, {page: {offset: 0, limit: 12}, include: 'book-comments.author'}
|
2843
|
-
end
|
2844
|
-
assert_response :success
|
2845
|
-
assert_equal 12, json_response['data'].size
|
2846
|
-
assert_equal 131, json_response['included'].size
|
2847
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2848
|
-
assert_equal 901, json_response['meta']['record-count']
|
2849
|
-
assert_query_count(4)
|
2850
|
-
ensure
|
2851
|
-
JSONAPI.configuration.top_level_meta_include_record_count = false
|
2852
|
-
end
|
2853
|
-
|
2854
|
-
def test_books_banned_admin
|
2855
|
-
$test_user = Person.find(5)
|
2856
|
-
Api::V2::BookResource.paginator :offset
|
2857
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
2858
|
-
count_queries do
|
2859
|
-
get :index, {page: {offset: 50, limit: 12}, filter: {banned: 'true'}}
|
2860
|
-
end
|
2861
|
-
assert_response :success
|
2862
|
-
assert_equal 12, json_response['data'].size
|
2863
|
-
assert_equal 'Book 651', json_response['data'][0]['attributes']['title']
|
2864
|
-
assert_equal 99, json_response['meta']['record-count']
|
2865
|
-
assert_query_count(2)
|
2866
|
-
ensure
|
2867
|
-
JSONAPI.configuration.top_level_meta_include_record_count = false
|
2868
|
-
end
|
2869
|
-
|
2870
|
-
def test_books_not_banned_admin
|
2871
|
-
$test_user = Person.find(5)
|
2872
|
-
Api::V2::BookResource.paginator :offset
|
2873
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
2874
|
-
count_queries do
|
2875
|
-
get :index, {page: {offset: 50, limit: 12}, filter: {banned: 'false'}}
|
2876
|
-
end
|
2877
|
-
assert_response :success
|
2878
|
-
assert_equal 12, json_response['data'].size
|
2879
|
-
assert_equal 'Book 50', json_response['data'][0]['attributes']['title']
|
2880
|
-
assert_equal 901, json_response['meta']['record-count']
|
2881
|
-
assert_query_count(2)
|
2882
|
-
ensure
|
2883
|
-
JSONAPI.configuration.top_level_meta_include_record_count = false
|
2884
|
-
end
|
2885
|
-
|
2886
|
-
def test_books_banned_non_book_admin_overlapped
|
2887
|
-
$test_user = Person.find(1)
|
2888
|
-
Api::V2::BookResource.paginator :offset
|
2889
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
2890
|
-
count_queries do
|
2891
|
-
get :index, {page: {offset: 590, limit: 20}}
|
2892
|
-
end
|
2893
|
-
assert_response :success
|
2894
|
-
assert_equal 20, json_response['data'].size
|
2895
|
-
assert_equal 'Book 590', json_response['data'][0]['attributes']['title']
|
2896
|
-
assert_equal 901, json_response['meta']['record-count']
|
2897
|
-
assert_query_count(2)
|
2898
|
-
ensure
|
2899
|
-
JSONAPI.configuration.top_level_meta_include_record_count = false
|
2900
|
-
end
|
2901
|
-
|
2902
|
-
def test_books_included_exclude_unapproved
|
2903
|
-
$test_user = Person.find(1)
|
2904
|
-
Api::V2::BookResource.paginator :none
|
2905
|
-
|
2906
|
-
count_queries do
|
2907
|
-
get :index, {filter: {id: '0,1,2,3,4'}, include: 'book-comments'}
|
2908
|
-
end
|
2909
|
-
assert_response :success
|
2910
|
-
assert_equal 5, json_response['data'].size
|
2911
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2912
|
-
assert_equal 130, json_response['included'].size
|
2913
|
-
assert_equal 26, json_response['data'][0]['relationships']['book-comments']['data'].size
|
2914
|
-
assert_query_count(2)
|
2915
|
-
end
|
2916
|
-
|
2917
|
-
def test_books_included_all_comments_for_admin
|
2918
|
-
$test_user = Person.find(5)
|
2919
|
-
Api::V2::BookResource.paginator :none
|
2920
|
-
|
2921
|
-
get :index, {filter: {id: '0,1,2,3,4'}, include: 'book-comments'}
|
2922
|
-
assert_response :success
|
2923
|
-
assert_equal 5, json_response['data'].size
|
2924
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
2925
|
-
assert_equal 255, json_response['included'].size
|
2926
|
-
assert_equal 51, json_response['data'][0]['relationships']['book-comments']['data'].size
|
2927
|
-
end
|
2928
|
-
|
2929
|
-
def test_books_filter_by_book_comment_id_limited_user
|
2930
|
-
$test_user = Person.find(1)
|
2931
|
-
get :index, {filter: {book_comments: '0,52' }}
|
2932
|
-
assert_response :success
|
2933
|
-
assert_equal 1, json_response['data'].size
|
2934
|
-
end
|
2935
|
-
|
2936
|
-
def test_books_filter_by_book_comment_id_admin_user
|
2937
|
-
$test_user = Person.find(5)
|
2938
|
-
get :index, {filter: {book_comments: '0,52' }}
|
2939
|
-
assert_response :success
|
2940
|
-
assert_equal 2, json_response['data'].size
|
2941
|
-
end
|
2942
|
-
|
2943
|
-
def test_books_create_unapproved_comment_limited_user_using_relation_name
|
2944
|
-
set_content_type_header!
|
2945
|
-
$test_user = Person.find(1)
|
2946
|
-
|
2947
|
-
book_comment = BookComment.create(body: 'Not Approved dummy comment', approved: false)
|
2948
|
-
post :create_relationship, {book_id: 1, relationship: 'book_comments', data: [{type: 'book_comments', id: book_comment.id}]}
|
2949
|
-
|
2950
|
-
# Note the not_found response is coming from the BookComment's overridden records method, not the relation
|
2951
|
-
assert_response :not_found
|
2952
|
-
|
2953
|
-
ensure
|
2954
|
-
book_comment.delete
|
2955
|
-
end
|
2956
|
-
|
2957
|
-
def test_books_create_approved_comment_limited_user_using_relation_name
|
2958
|
-
set_content_type_header!
|
2959
|
-
$test_user = Person.find(1)
|
2960
|
-
|
2961
|
-
book_comment = BookComment.create(body: 'Approved dummy comment', approved: true)
|
2962
|
-
post :create_relationship, {book_id: 1, relationship: 'book_comments', data: [{type: 'book_comments', id: book_comment.id}]}
|
2963
|
-
assert_response :success
|
2964
|
-
|
2965
|
-
ensure
|
2966
|
-
book_comment.delete
|
2967
|
-
end
|
2968
|
-
|
2969
|
-
def test_books_delete_unapproved_comment_limited_user_using_relation_name
|
2970
|
-
$test_user = Person.find(1)
|
2971
|
-
|
2972
|
-
book_comment = BookComment.create(book_id: 1, body: 'Not Approved dummy comment', approved: false)
|
2973
|
-
delete :destroy_relationship, {book_id: 1, relationship: 'book_comments', data: [{type: 'book_comments', id: book_comment.id}]}
|
2974
|
-
assert_response :not_found
|
2975
|
-
|
2976
|
-
ensure
|
2977
|
-
book_comment.delete
|
2978
|
-
end
|
2979
|
-
|
2980
|
-
def test_books_delete_approved_comment_limited_user_using_relation_name
|
2981
|
-
$test_user = Person.find(1)
|
2982
|
-
|
2983
|
-
book_comment = BookComment.create(book_id: 1, body: 'Approved dummy comment', approved: true)
|
2984
|
-
delete :destroy_relationship, {book_id: 1, relationship: 'book_comments', data: [{type: 'book_comments', id: book_comment.id}]}
|
2985
|
-
assert_response :no_content
|
2986
|
-
|
2987
|
-
ensure
|
2988
|
-
book_comment.delete
|
2989
|
-
end
|
2990
|
-
end
|
2991
|
-
|
2992
|
-
class Api::V2::BookCommentsControllerTest < ActionController::TestCase
|
2993
|
-
def setup
|
2994
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
2995
|
-
Api::V2::BookCommentResource.paginator :none
|
2996
|
-
$test_user = Person.find(1)
|
2997
|
-
end
|
2998
|
-
|
2999
|
-
def test_book_comments_all_for_admin
|
3000
|
-
$test_user = Person.find(5)
|
3001
|
-
count_queries do
|
3002
|
-
get :index
|
3003
|
-
end
|
3004
|
-
assert_response :success
|
3005
|
-
assert_equal 255, json_response['data'].size
|
3006
|
-
assert_query_count(1)
|
3007
|
-
end
|
3008
|
-
|
3009
|
-
def test_book_comments_unapproved_context_based
|
3010
|
-
$test_user = Person.find(5)
|
3011
|
-
count_queries do
|
3012
|
-
get :index, {filter: {approved: 'false'}}
|
3013
|
-
end
|
3014
|
-
assert_response :success
|
3015
|
-
assert_equal 125, json_response['data'].size
|
3016
|
-
assert_query_count(1)
|
3017
|
-
end
|
3018
|
-
|
3019
|
-
def test_book_comments_exclude_unapproved_context_based
|
3020
|
-
$test_user = Person.find(1)
|
3021
|
-
count_queries do
|
3022
|
-
get :index
|
3023
|
-
end
|
3024
|
-
assert_response :success
|
3025
|
-
assert_equal 130, json_response['data'].size
|
3026
|
-
assert_query_count(1)
|
3027
|
-
end
|
3028
|
-
end
|
3029
|
-
|
3030
|
-
class Api::V4::BooksControllerTest < ActionController::TestCase
|
3031
|
-
def setup
|
3032
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
3033
|
-
end
|
3034
|
-
|
3035
|
-
def test_books_offset_pagination_meta
|
3036
|
-
original_config = JSONAPI.configuration.dup
|
3037
|
-
JSONAPI.configuration.operations_processor = :counting_active_record
|
3038
|
-
Api::V4::BookResource.paginator :offset
|
3039
|
-
get :index, {page: {offset: 50, limit: 12}}
|
3040
|
-
assert_response :success
|
3041
|
-
assert_equal 12, json_response['data'].size
|
3042
|
-
assert_equal 'Book 50', json_response['data'][0]['attributes']['title']
|
3043
|
-
assert_equal 901, json_response['meta']['totalRecords']
|
3044
|
-
ensure
|
3045
|
-
JSONAPI.configuration = original_config
|
3046
|
-
end
|
3047
|
-
|
3048
|
-
def test_books_operation_links
|
3049
|
-
original_config = JSONAPI.configuration.dup
|
3050
|
-
JSONAPI.configuration.operations_processor = :counting_active_record
|
3051
|
-
Api::V4::BookResource.paginator :offset
|
3052
|
-
get :index, {page: {offset: 50, limit: 12}}
|
3053
|
-
assert_response :success
|
3054
|
-
assert_equal 12, json_response['data'].size
|
3055
|
-
assert_equal 'Book 50', json_response['data'][0]['attributes']['title']
|
3056
|
-
assert_equal 5, json_response['links'].size
|
3057
|
-
assert_equal 'https://test_corp.com', json_response['links']['spec']
|
3058
|
-
ensure
|
3059
|
-
JSONAPI.configuration = original_config
|
3060
|
-
end
|
3061
|
-
end
|
3062
|
-
|
3063
|
-
class CategoriesControllerTest < ActionController::TestCase
|
3064
|
-
def test_index_default_filter
|
3065
|
-
get :index
|
3066
|
-
assert_response :success
|
3067
|
-
assert json_response['data'].is_a?(Array)
|
3068
|
-
assert_equal 3, json_response['data'].size
|
3069
|
-
end
|
3070
|
-
|
3071
|
-
def test_index_default_filter_override
|
3072
|
-
get :index, { filter: { status: 'inactive' } }
|
3073
|
-
assert_response :success
|
3074
|
-
assert json_response['data'].is_a?(Array)
|
3075
|
-
assert_equal 4, json_response['data'].size
|
3076
|
-
end
|
3077
|
-
end
|
3078
|
-
|
3079
|
-
class Api::V1::PlanetsControllerTest < ActionController::TestCase
|
3080
|
-
def test_save_model_callbacks
|
3081
|
-
set_content_type_header!
|
3082
|
-
post :create,
|
3083
|
-
{
|
3084
|
-
data: {
|
3085
|
-
type: 'planets',
|
3086
|
-
attributes: {
|
3087
|
-
name: 'Zeus',
|
3088
|
-
description: 'The largest planet in the solar system. Discovered in 2015.'
|
3089
|
-
}
|
3090
|
-
}
|
3091
|
-
}
|
3092
|
-
|
3093
|
-
assert_response :created
|
3094
|
-
assert json_response['data'].is_a?(Hash)
|
3095
|
-
assert_equal 'Zeus', json_response['data']['attributes']['name']
|
3096
|
-
end
|
3097
|
-
|
3098
|
-
def test_save_model_callbacks_fail
|
3099
|
-
set_content_type_header!
|
3100
|
-
post :create,
|
3101
|
-
{
|
3102
|
-
data: {
|
3103
|
-
type: 'planets',
|
3104
|
-
attributes: {
|
3105
|
-
name: 'Pluto',
|
3106
|
-
description: 'Yes, it is a planet.'
|
3107
|
-
}
|
3108
|
-
}
|
3109
|
-
}
|
3110
|
-
|
3111
|
-
assert_response :unprocessable_entity
|
3112
|
-
assert_match /Save failed or was cancelled/, json_response['errors'][0]['detail']
|
3113
|
-
end
|
3114
|
-
end
|
3115
|
-
|
3116
|
-
class Api::V1::MoonsControllerTest < ActionController::TestCase
|
3117
|
-
def test_get_related_resource
|
3118
|
-
get :get_related_resource, {crater_id: 'S56D', relationship: 'moon', source: "api/v1/craters"}
|
3119
|
-
assert_response :success
|
3120
|
-
assert_hash_equals({
|
3121
|
-
data: {
|
3122
|
-
id: "1",
|
3123
|
-
type: "moons",
|
3124
|
-
links: {self: "http://test.host/api/v1/moons/1"},
|
3125
|
-
attributes: {name: "Titan", description: "Best known of the Saturn moons."},
|
3126
|
-
relationships: {
|
3127
|
-
planet: {links: {self: "http://test.host/api/v1/moons/1/relationships/planet", related: "http://test.host/api/v1/moons/1/planet"}},
|
3128
|
-
craters: {links: {self: "http://test.host/api/v1/moons/1/relationships/craters", related: "http://test.host/api/v1/moons/1/craters"}}}
|
3129
|
-
}
|
3130
|
-
}, json_response)
|
3131
|
-
end
|
3132
|
-
|
3133
|
-
def test_get_related_resources_with_select_some_db_columns
|
3134
|
-
PlanetResource.paginator :paged
|
3135
|
-
original_config = JSONAPI.configuration.dup
|
3136
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
3137
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
3138
|
-
get :get_related_resources, {planet_id: '1', relationship: 'moons', source: 'api/v1/planets'}
|
3139
|
-
assert_response :success
|
3140
|
-
assert_equal 1, json_response['meta']['record-count']
|
3141
|
-
ensure
|
3142
|
-
JSONAPI.configuration = original_config
|
3143
|
-
end
|
3144
|
-
end
|
3145
|
-
|
3146
|
-
class Api::V1::CratersControllerTest < ActionController::TestCase
|
3147
|
-
def test_show_single
|
3148
|
-
get :show, {id: 'S56D'}
|
3149
|
-
assert_response :success
|
3150
|
-
assert json_response['data'].is_a?(Hash)
|
3151
|
-
assert_equal 'S56D', json_response['data']['attributes']['code']
|
3152
|
-
assert_equal 'Very large crater', json_response['data']['attributes']['description']
|
3153
|
-
assert_nil json_response['included']
|
3154
|
-
end
|
3155
|
-
|
3156
|
-
def test_get_related_resources
|
3157
|
-
get :get_related_resources, {moon_id: '1', relationship: 'craters', source: "api/v1/moons"}
|
3158
|
-
assert_response :success
|
3159
|
-
assert_hash_equals({
|
3160
|
-
data: [
|
3161
|
-
{
|
3162
|
-
id:"A4D3",
|
3163
|
-
type:"craters",
|
3164
|
-
links:{self: "http://test.host/api/v1/craters/A4D3"},
|
3165
|
-
attributes:{code: "A4D3", description: "Small crater"},
|
3166
|
-
relationships:{moon: {links: {self: "http://test.host/api/v1/craters/A4D3/relationships/moon", related: "http://test.host/api/v1/craters/A4D3/moon"}}}
|
3167
|
-
},
|
3168
|
-
{
|
3169
|
-
id: "S56D",
|
3170
|
-
type: "craters",
|
3171
|
-
links:{self: "http://test.host/api/v1/craters/S56D"},
|
3172
|
-
attributes:{code: "S56D", description: "Very large crater"},
|
3173
|
-
relationships:{moon: {links: {self: "http://test.host/api/v1/craters/S56D/relationships/moon", related: "http://test.host/api/v1/craters/S56D/moon"}}}
|
3174
|
-
}
|
3175
|
-
]
|
3176
|
-
}, json_response)
|
3177
|
-
end
|
3178
|
-
|
3179
|
-
def test_show_relationship
|
3180
|
-
get :show_relationship, {crater_id: 'S56D', relationship: 'moon'}
|
3181
|
-
|
3182
|
-
assert_response :success
|
3183
|
-
assert_equal "moons", json_response['data']['type']
|
3184
|
-
assert_equal "1", json_response['data']['id']
|
3185
|
-
end
|
3186
|
-
end
|
3187
|
-
|
3188
|
-
class CarsControllerTest < ActionController::TestCase
|
3189
|
-
def setup
|
3190
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
3191
|
-
end
|
3192
|
-
|
3193
|
-
def test_create_sti
|
3194
|
-
set_content_type_header!
|
3195
|
-
post :create,
|
3196
|
-
{
|
3197
|
-
data: {
|
3198
|
-
type: 'cars',
|
3199
|
-
attributes: {
|
3200
|
-
make: 'Toyota',
|
3201
|
-
model: 'Tercel',
|
3202
|
-
serialNumber: 'asasdsdadsa13544235',
|
3203
|
-
driveLayout: 'FWD'
|
3204
|
-
}
|
3205
|
-
}
|
3206
|
-
}
|
3207
|
-
|
3208
|
-
assert_response :created
|
3209
|
-
assert json_response['data'].is_a?(Hash)
|
3210
|
-
assert_equal 'cars', json_response['data']['type']
|
3211
|
-
assert_equal 'Toyota', json_response['data']['attributes']['make']
|
3212
|
-
assert_equal 'FWD', json_response['data']['attributes']['driveLayout']
|
3213
|
-
end
|
3214
|
-
end
|
3215
|
-
|
3216
|
-
class VehiclesControllerTest < ActionController::TestCase
|
3217
|
-
def setup
|
3218
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
3219
|
-
end
|
3220
|
-
|
3221
|
-
def test_immutable_create_not_supported
|
3222
|
-
set_content_type_header!
|
3223
|
-
|
3224
|
-
assert_raises ActionController::UrlGenerationError do
|
3225
|
-
post :create,
|
3226
|
-
{
|
3227
|
-
data: {
|
3228
|
-
type: 'cars',
|
3229
|
-
attributes: {
|
3230
|
-
make: 'Toyota',
|
3231
|
-
model: 'Corrola',
|
3232
|
-
serialNumber: 'dsvffsfv',
|
3233
|
-
driveLayout: 'FWD'
|
3234
|
-
}
|
3235
|
-
}
|
3236
|
-
}
|
3237
|
-
end
|
3238
|
-
end
|
3239
|
-
|
3240
|
-
def test_immutable_update_not_supported
|
3241
|
-
set_content_type_header!
|
3242
|
-
|
3243
|
-
assert_raises ActionController::UrlGenerationError do
|
3244
|
-
patch :update,
|
3245
|
-
data: {
|
3246
|
-
id: '1',
|
3247
|
-
type: 'cars',
|
3248
|
-
attributes: {
|
3249
|
-
make: 'Toyota',
|
3250
|
-
}
|
3251
|
-
}
|
3252
|
-
end
|
3253
|
-
end
|
3254
|
-
end
|
3255
|
-
|
3256
|
-
class Api::V7::ClientsControllerTest < ActionController::TestCase
|
3257
|
-
def test_get_namespaced_model_not_matching_resource_using_model_hint
|
3258
|
-
get :index
|
3259
|
-
assert_response :success
|
3260
|
-
assert_equal 'clients', json_response['data'][0]['type']
|
3261
|
-
ensure
|
3262
|
-
Api::V7::ClientResource._model_hints['api/v7/customer'] = 'clients'
|
3263
|
-
end
|
3264
|
-
|
3265
|
-
def test_get_namespaced_model_not_matching_resource_not_using_model_hint
|
3266
|
-
Api::V7::ClientResource._model_hints.delete('api/v7/customer')
|
3267
|
-
get :index
|
3268
|
-
assert_response :success
|
3269
|
-
assert_equal 'customers', json_response['data'][0]['type']
|
3270
|
-
ensure
|
3271
|
-
Api::V7::ClientResource._model_hints['api/v7/customer'] = 'clients'
|
3272
|
-
end
|
3273
|
-
end
|
3274
|
-
|
3275
|
-
class Api::V7::CustomersControllerTest < ActionController::TestCase
|
3276
|
-
def test_get_namespaced_model_matching_resource
|
3277
|
-
get :index
|
3278
|
-
assert_response :success
|
3279
|
-
assert_equal 'customers', json_response['data'][0]['type']
|
3280
|
-
end
|
3281
|
-
end
|
3282
|
-
|
3283
|
-
class Api::V7::CategoriesControllerTest < ActionController::TestCase
|
3284
|
-
def test_uncaught_error_in_controller_translated_to_internal_server_error
|
3285
|
-
|
3286
|
-
get :show, {id: '1'}
|
3287
|
-
assert_response 500
|
3288
|
-
assert_match /Internal Server Error/, json_response['errors'][0]['detail']
|
3289
|
-
end
|
3290
|
-
|
3291
|
-
def test_not_whitelisted_error_in_controller
|
3292
|
-
original_config = JSONAPI.configuration.dup
|
3293
|
-
JSONAPI.configuration.operations_processor = :error_raising
|
3294
|
-
JSONAPI.configuration.exception_class_whitelist = []
|
3295
|
-
get :show, {id: '1'}
|
3296
|
-
assert_response 500
|
3297
|
-
assert_match /Internal Server Error/, json_response['errors'][0]['detail']
|
3298
|
-
ensure
|
3299
|
-
JSONAPI.configuration = original_config
|
3300
|
-
end
|
3301
|
-
|
3302
|
-
def test_whitelisted_error_in_controller
|
3303
|
-
original_config = JSONAPI.configuration.dup
|
3304
|
-
JSONAPI.configuration.operations_processor = :error_raising
|
3305
|
-
JSONAPI.configuration.exception_class_whitelist = [PostsController::SubSpecialError]
|
3306
|
-
assert_raises PostsController::SubSpecialError do
|
3307
|
-
get :show, {id: '1'}
|
3308
|
-
end
|
3309
|
-
ensure
|
3310
|
-
JSONAPI.configuration = original_config
|
3311
|
-
end
|
3312
|
-
end
|