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,59 +0,0 @@
|
|
1
|
-
post_1_short:
|
2
|
-
post_id: 1
|
3
|
-
tag_id: 1
|
4
|
-
|
5
|
-
post_1_whiny:
|
6
|
-
post_id: 1
|
7
|
-
tag_id: 2
|
8
|
-
|
9
|
-
post_1_grumpy:
|
10
|
-
post_id: 1
|
11
|
-
tag_id: 3
|
12
|
-
|
13
|
-
post_2_jr:
|
14
|
-
post_id: 2
|
15
|
-
tag_id: 5
|
16
|
-
|
17
|
-
post_11_jr:
|
18
|
-
post_id: 11
|
19
|
-
tag_id: 5
|
20
|
-
|
21
|
-
post_12_silly:
|
22
|
-
post_id: 12
|
23
|
-
tag_id: 6
|
24
|
-
|
25
|
-
post_12_sleepy:
|
26
|
-
post_id: 12
|
27
|
-
tag_id: 7
|
28
|
-
|
29
|
-
post_12_goofy:
|
30
|
-
post_id: 12
|
31
|
-
tag_id: 8
|
32
|
-
|
33
|
-
post_12_wacky:
|
34
|
-
post_id: 12
|
35
|
-
tag_id: 9
|
36
|
-
|
37
|
-
post_13_silly:
|
38
|
-
post_id: 13
|
39
|
-
tag_id: 6
|
40
|
-
|
41
|
-
post_13_sleepy:
|
42
|
-
post_id: 13
|
43
|
-
tag_id: 7
|
44
|
-
|
45
|
-
post_13_goofy:
|
46
|
-
post_id: 13
|
47
|
-
tag_id: 8
|
48
|
-
|
49
|
-
post_13_wacky:
|
50
|
-
post_id: 13
|
51
|
-
tag_id: 9
|
52
|
-
|
53
|
-
post_14_whiny:
|
54
|
-
post_id: 14
|
55
|
-
tag_id: 2
|
56
|
-
|
57
|
-
post_14_grumpy:
|
58
|
-
post_id: 14
|
59
|
-
tag_id: 3
|
data/test/fixtures/products.yml
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
po_1:
|
2
|
-
id: 1
|
3
|
-
requested_delivery_date:
|
4
|
-
delivery_date: nil
|
5
|
-
customer_id: 1
|
6
|
-
|
7
|
-
po_2:
|
8
|
-
id: 2
|
9
|
-
requested_delivery_date:
|
10
|
-
delivery_date: nil
|
11
|
-
customer_id: 1
|
12
|
-
|
13
|
-
po_3:
|
14
|
-
id: 3
|
15
|
-
requested_delivery_date:
|
16
|
-
delivery_date: nil
|
17
|
-
customer_id: 1
|
18
|
-
|
19
|
-
po_4:
|
20
|
-
id: 4
|
21
|
-
requested_delivery_date:
|
22
|
-
delivery_date: nil
|
23
|
-
customer_id: 3
|
data/test/fixtures/sections.yml
DELETED
data/test/fixtures/tags.yml
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
short_tag:
|
2
|
-
id: 1
|
3
|
-
name: short
|
4
|
-
|
5
|
-
whiny_tag:
|
6
|
-
id: 2
|
7
|
-
name: whiny
|
8
|
-
|
9
|
-
grumpy_tag:
|
10
|
-
id: 3
|
11
|
-
name: grumpy
|
12
|
-
|
13
|
-
happy_tag:
|
14
|
-
id: 4
|
15
|
-
name: happy
|
16
|
-
|
17
|
-
jr_tag:
|
18
|
-
id: 5
|
19
|
-
name: JR
|
20
|
-
|
21
|
-
silly_tag:
|
22
|
-
id: 6
|
23
|
-
name: silly
|
24
|
-
|
25
|
-
sleepy_tag:
|
26
|
-
id: 7
|
27
|
-
name: sleepy
|
28
|
-
|
29
|
-
goofy_tag:
|
30
|
-
id: 8
|
31
|
-
name: goofy
|
32
|
-
|
33
|
-
wacky_tag:
|
34
|
-
id: 9
|
35
|
-
name: wacky
|
36
|
-
|
37
|
-
bad_tag:
|
38
|
-
id: 10
|
39
|
-
name: bad
|
data/test/fixtures/vehicles.yml
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
Miata:
|
2
|
-
id: 1
|
3
|
-
type: Car
|
4
|
-
make: Mazda
|
5
|
-
model: Miata MX5
|
6
|
-
drive_layout: Front Engine RWD
|
7
|
-
serial_number: 32432adfsfdysua
|
8
|
-
person_id: 1
|
9
|
-
|
10
|
-
Launch20:
|
11
|
-
id: 2
|
12
|
-
type: Boat
|
13
|
-
make: Chris-Craft
|
14
|
-
model: Launch 20
|
15
|
-
length_at_water_line: 15.5ft
|
16
|
-
serial_number: 434253JJJSD
|
17
|
-
person_id: 1
|
data/test/fixtures/web_pages.yml
DELETED
data/test/helpers/assertions.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
module Helpers
|
2
|
-
module Assertions
|
3
|
-
def assert_hash_equals(exp, act, msg = nil)
|
4
|
-
msg = message(msg, '') { diff exp, act }
|
5
|
-
assert(matches_hash?(exp, act, {exact: true}), msg)
|
6
|
-
end
|
7
|
-
|
8
|
-
def assert_array_equals(exp, act, msg = nil)
|
9
|
-
msg = message(msg, '') { diff exp, act }
|
10
|
-
assert(matches_array?(exp, act, {exact: true}), msg)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module Helpers
|
2
|
-
module FunctionalHelpers
|
3
|
-
# from http://jamieonsoftware.com/blog/entry/testing-restful-response-types
|
4
|
-
# def assert_response_is(type, message = '')
|
5
|
-
# case type
|
6
|
-
# when :js
|
7
|
-
# check = [
|
8
|
-
# 'text/javascript'
|
9
|
-
# ]
|
10
|
-
# when :json
|
11
|
-
# check = [
|
12
|
-
# 'application/json',
|
13
|
-
# 'text/json',
|
14
|
-
# 'application/x-javascript',
|
15
|
-
# 'text/x-javascript',
|
16
|
-
# 'text/x-json'
|
17
|
-
# ]
|
18
|
-
# when :xml
|
19
|
-
# check = [ 'application/xml', 'text/xml' ]
|
20
|
-
# when :yaml
|
21
|
-
# check = [
|
22
|
-
# 'text/yaml',
|
23
|
-
# 'text/x-yaml',
|
24
|
-
# 'application/yaml',
|
25
|
-
# 'application/x-yaml'
|
26
|
-
# ]
|
27
|
-
# else
|
28
|
-
# if methods.include?('assert_response_types')
|
29
|
-
# check = assert_response_types
|
30
|
-
# else
|
31
|
-
# check = []
|
32
|
-
# end
|
33
|
-
# end
|
34
|
-
#
|
35
|
-
# if @response.content_type
|
36
|
-
# ct = @response.content_type
|
37
|
-
# elsif methods.include?('assert_response_response')
|
38
|
-
# ct = assert_response_response
|
39
|
-
# else
|
40
|
-
# ct = ''
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# begin
|
44
|
-
# assert check.include?(ct)
|
45
|
-
# rescue Test::Unit::AssertionFailedError
|
46
|
-
# raise Test::Unit::AssertionFailedError.new(build_message(message, "The response type is not ?", type.to_s))
|
47
|
-
# end
|
48
|
-
# end
|
49
|
-
|
50
|
-
# def assert_js_redirect_to(path)
|
51
|
-
# assert_response_is :js
|
52
|
-
# assert_match /#{"window.location.href = \"" + path + "\""}/, @response.body
|
53
|
-
# end
|
54
|
-
#
|
55
|
-
def json_response
|
56
|
-
JSON.parse(@response.body)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
module Helpers
|
2
|
-
module ValueMatchers
|
3
|
-
### Matchers
|
4
|
-
def matches_value?(v1, v2, options = {})
|
5
|
-
if v1 == :any
|
6
|
-
# any value is acceptable
|
7
|
-
elsif v1 == :not_nil
|
8
|
-
return false if v2 == nil
|
9
|
-
elsif v1.kind_of?(Hash)
|
10
|
-
return false unless matches_hash?(v1, v2, options)
|
11
|
-
elsif v1.kind_of?(Array)
|
12
|
-
return false unless matches_array?(v1, v2, options)
|
13
|
-
else
|
14
|
-
return false unless v2 == v1
|
15
|
-
end
|
16
|
-
true
|
17
|
-
end
|
18
|
-
|
19
|
-
def matches_array?(array1, array2, options = {})
|
20
|
-
return false unless array1.kind_of?(Array) && array2.kind_of?(Array)
|
21
|
-
if options[:exact]
|
22
|
-
return false unless array1.size == array2.size
|
23
|
-
end
|
24
|
-
|
25
|
-
# order of items shouldn't matter:
|
26
|
-
# ['a', 'b', 'c'], ['b', 'c', 'a'] -> true
|
27
|
-
#
|
28
|
-
# matched items should only be used once:
|
29
|
-
# ['a', 'b', 'c'], ['a', 'a', 'a'] -> false
|
30
|
-
# ['a', 'a', 'a'], ['a', 'b', 'c'] -> false
|
31
|
-
matched = {}
|
32
|
-
(0..(array1.size - 1)).each do |i|
|
33
|
-
(0..(array2.size - 1)).each do |j|
|
34
|
-
if !matched.has_value?(j.to_s) && matches_value?(array1[i], array2[j], options)
|
35
|
-
matched[i.to_s] = j.to_s
|
36
|
-
break
|
37
|
-
end
|
38
|
-
end
|
39
|
-
return false unless matched.has_key?(i.to_s)
|
40
|
-
end
|
41
|
-
true
|
42
|
-
end
|
43
|
-
|
44
|
-
# options => {exact: true} # hashes must match exactly (i.e. have same number of key-value pairs that are all equal)
|
45
|
-
def matches_hash?(hash1, hash2, options = {})
|
46
|
-
return false unless hash1.kind_of?(Hash) && hash2.kind_of?(Hash)
|
47
|
-
if options[:exact]
|
48
|
-
return false unless hash1.size == hash2.size
|
49
|
-
end
|
50
|
-
|
51
|
-
hash1 = hash1.deep_symbolize_keys
|
52
|
-
hash2 = hash2.deep_symbolize_keys
|
53
|
-
|
54
|
-
hash1.each do |k1, v1|
|
55
|
-
return false unless hash2.has_key?(k1) && matches_value?(v1, hash2[k1], options)
|
56
|
-
end
|
57
|
-
true
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require File.expand_path('../../test_helper', __FILE__)
|
2
|
-
|
3
|
-
class ValueMatchersTest < ActionController::TestCase
|
4
|
-
|
5
|
-
def test_matches_value_any
|
6
|
-
assert(matches_value?(:any, 'a'))
|
7
|
-
assert(matches_value?(:any, nil))
|
8
|
-
end
|
9
|
-
|
10
|
-
def test_matches_value_not_nil
|
11
|
-
assert(matches_value?(:not_nil, 'a'))
|
12
|
-
refute(matches_value?(:not_nil, nil))
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_matches_value_array
|
16
|
-
assert(matches_value?(['a', 'b', 'c'], ['b', 'c', 'a']))
|
17
|
-
assert(matches_value?(['a', 'b', 'c'], ['a', 'b', 'c']))
|
18
|
-
refute(matches_value?(['a', 'b', 'c'], ['a', 'a']))
|
19
|
-
refute(matches_value?(['a', 'b', 'c'], ['a', 'b', 'd']))
|
20
|
-
|
21
|
-
assert(matches_value?(['a', 'b', :any], ['a', 'b', 'c']))
|
22
|
-
assert(matches_value?(['a', 'b', :not_nil], ['a', 'b', 'c']))
|
23
|
-
refute(matches_value?(['a', 'b', :not_nil], ['a', 'b', nil]))
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_matches_value_hash
|
27
|
-
assert(matches_value?({a: 'a', b: 'b', c: 'c'}, {a: 'a', b: 'b', c: 'c'}))
|
28
|
-
assert(matches_value?({a: 'a', b: 'b', c: 'c'}, {b: 'b', c: 'c', a: 'a'}))
|
29
|
-
refute(matches_value?({a: 'a', b: 'b', c: 'c'}, {b: 'a', c: 'c', a: 'b'}))
|
30
|
-
|
31
|
-
assert(matches_value?({a: 'a', b: 'b', c: {a: 'a', d: 'e'}}, {b: 'b', c: {a: 'a', d: 'e'}, a: 'a'}))
|
32
|
-
refute(matches_value?({a: 'a', b: 'b', c: {a: 'a', d: 'd'}}, {b: 'b', c: {a: 'a', d: 'e'}, a: 'a'}))
|
33
|
-
|
34
|
-
assert(matches_value?({a: 'a', b: 'b', c: {a: 'a', d: {a: :not_nil}}}, {b: 'b', c: {a: 'a', d: {a: 'b'}}, a: 'a'}))
|
35
|
-
refute(matches_value?({a: 'a', b: 'b', c: {a: 'a', d: {a: :not_nil}}}, {b: 'b', c: {a: 'a', d: {a: nil}}, a: 'a'}))
|
36
|
-
|
37
|
-
assert(matches_value?({a: 'a', b: 'b', c: {a: 'a', d: {a: :any}}}, {b: 'b', c: {a: 'a', d: {a: 'b'}}, a: 'a'}))
|
38
|
-
assert(matches_value?({a: 'a', b: 'b', c: {a: 'a', d: {a: :any}}}, {b: 'b', c: {a: 'a', d: {a: nil}}, a: 'a'}))
|
39
|
-
end
|
40
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require File.expand_path('../../../test_helper', __FILE__)
|
2
|
-
|
3
|
-
class NamedspacedModelTest < ActionDispatch::IntegrationTest
|
4
|
-
def setup
|
5
|
-
JSONAPI.configuration.json_key_format = :underscored_key
|
6
|
-
end
|
7
|
-
|
8
|
-
def test_get_flat_posts
|
9
|
-
get '/flat_posts'
|
10
|
-
assert_equal 200, status
|
11
|
-
assert_equal "flat_posts", json_response["data"].first["type"]
|
12
|
-
end
|
13
|
-
end
|
@@ -1,932 +0,0 @@
|
|
1
|
-
require File.expand_path('../../../test_helper', __FILE__)
|
2
|
-
|
3
|
-
class RequestTest < ActionDispatch::IntegrationTest
|
4
|
-
def setup
|
5
|
-
JSONAPI.configuration.json_key_format = :underscored_key
|
6
|
-
JSONAPI.configuration.route_format = :underscored_route
|
7
|
-
$test_user = Person.find(1)
|
8
|
-
end
|
9
|
-
|
10
|
-
def after_teardown
|
11
|
-
Api::V2::BookResource.paginator :offset
|
12
|
-
JSONAPI.configuration.route_format = :underscored_route
|
13
|
-
end
|
14
|
-
|
15
|
-
def assert_jsonapi_response(expected_status)
|
16
|
-
assert_equal JSONAPI::MEDIA_TYPE, response.content_type
|
17
|
-
assert_equal expected_status, status
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_get
|
21
|
-
get '/posts'
|
22
|
-
assert_jsonapi_response 200
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_get_inflected_resource
|
26
|
-
get '/api/v8/numeros_telefone'
|
27
|
-
assert_jsonapi_response 200
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_get_nested_to_one
|
31
|
-
get '/posts/1/author'
|
32
|
-
assert_jsonapi_response 200
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_get_nested_to_many
|
36
|
-
get '/posts/1/comments'
|
37
|
-
assert_jsonapi_response 200
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_get_nested_to_many_bad_param
|
41
|
-
get '/posts/1/comments?relationship=books'
|
42
|
-
assert_jsonapi_response 200
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_get_underscored_key
|
46
|
-
original_config = JSONAPI.configuration.dup
|
47
|
-
JSONAPI.configuration.json_key_format = :underscored_key
|
48
|
-
get '/iso_currencies'
|
49
|
-
assert_jsonapi_response 200
|
50
|
-
assert_equal 3, json_response['data'].size
|
51
|
-
ensure
|
52
|
-
JSONAPI.configuration = original_config
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_get_underscored_key_filtered
|
56
|
-
original_config = JSONAPI.configuration.dup
|
57
|
-
JSONAPI.configuration.json_key_format = :underscored_key
|
58
|
-
get '/iso_currencies?filter[country_name]=Canada'
|
59
|
-
assert_jsonapi_response 200
|
60
|
-
assert_equal 1, json_response['data'].size
|
61
|
-
assert_equal 'Canada', json_response['data'][0]['attributes']['country_name']
|
62
|
-
ensure
|
63
|
-
JSONAPI.configuration = original_config
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_get_camelized_key_filtered
|
67
|
-
original_config = JSONAPI.configuration.dup
|
68
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
69
|
-
get '/iso_currencies?filter[countryName]=Canada'
|
70
|
-
assert_jsonapi_response 200
|
71
|
-
assert_equal 1, json_response['data'].size
|
72
|
-
assert_equal 'Canada', json_response['data'][0]['attributes']['countryName']
|
73
|
-
ensure
|
74
|
-
JSONAPI.configuration = original_config
|
75
|
-
end
|
76
|
-
|
77
|
-
def test_get_camelized_route_and_key_filtered
|
78
|
-
original_config = JSONAPI.configuration.dup
|
79
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
80
|
-
get '/api/v4/isoCurrencies?filter[countryName]=Canada'
|
81
|
-
assert_jsonapi_response 200
|
82
|
-
assert_equal 1, json_response['data'].size
|
83
|
-
assert_equal 'Canada', json_response['data'][0]['attributes']['countryName']
|
84
|
-
ensure
|
85
|
-
JSONAPI.configuration = original_config
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_get_camelized_route_and_links
|
89
|
-
original_config = JSONAPI.configuration.dup
|
90
|
-
JSONAPI.configuration.json_key_format = :camelized_key
|
91
|
-
JSONAPI.configuration.route_format = :camelized_route
|
92
|
-
get '/api/v4/expenseEntries/1/relationships/isoCurrency'
|
93
|
-
assert_jsonapi_response 200
|
94
|
-
assert_hash_equals({'links' => {
|
95
|
-
'self' => 'http://www.example.com/api/v4/expenseEntries/1/relationships/isoCurrency',
|
96
|
-
'related' => 'http://www.example.com/api/v4/expenseEntries/1/isoCurrency'
|
97
|
-
},
|
98
|
-
'data' => {
|
99
|
-
'type' => 'isoCurrencies',
|
100
|
-
'id' => 'USD'
|
101
|
-
}
|
102
|
-
}, json_response)
|
103
|
-
ensure
|
104
|
-
JSONAPI.configuration = original_config
|
105
|
-
end
|
106
|
-
|
107
|
-
def test_put_single_without_content_type
|
108
|
-
put '/posts/3',
|
109
|
-
{
|
110
|
-
'data' => {
|
111
|
-
'linkage' => {
|
112
|
-
'type' => 'posts',
|
113
|
-
'id' => '3',
|
114
|
-
},
|
115
|
-
'attributes' => {
|
116
|
-
'title' => 'A great new Post'
|
117
|
-
},
|
118
|
-
'links' => {
|
119
|
-
'tags' => [
|
120
|
-
{type: 'tags', id: 3},
|
121
|
-
{type: 'tags', id: 4}
|
122
|
-
]
|
123
|
-
}
|
124
|
-
}
|
125
|
-
}.to_json, "CONTENT_TYPE" => "application/json"
|
126
|
-
|
127
|
-
assert_equal 415, status
|
128
|
-
end
|
129
|
-
|
130
|
-
def test_put_single
|
131
|
-
put '/posts/3',
|
132
|
-
{
|
133
|
-
'data' => {
|
134
|
-
'type' => 'posts',
|
135
|
-
'id' => '3',
|
136
|
-
'attributes' => {
|
137
|
-
'title' => 'A great new Post'
|
138
|
-
},
|
139
|
-
'relationships' => {
|
140
|
-
'tags' => {
|
141
|
-
'data' => [
|
142
|
-
{type: 'tags', id: 3},
|
143
|
-
{type: 'tags', id: 4}
|
144
|
-
]
|
145
|
-
}
|
146
|
-
}
|
147
|
-
}
|
148
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
149
|
-
|
150
|
-
assert_jsonapi_response 200
|
151
|
-
end
|
152
|
-
|
153
|
-
def test_post_single_without_content_type
|
154
|
-
post '/posts',
|
155
|
-
{
|
156
|
-
'posts' => {
|
157
|
-
'attributes' => {
|
158
|
-
'title' => 'A great new Post'
|
159
|
-
},
|
160
|
-
'relationships' => {
|
161
|
-
'tags' => {
|
162
|
-
'data' => [
|
163
|
-
{type: 'tags', id: 3},
|
164
|
-
{type: 'tags', id: 4}
|
165
|
-
]
|
166
|
-
}
|
167
|
-
}
|
168
|
-
}
|
169
|
-
}.to_json, "CONTENT_TYPE" => "application/json"
|
170
|
-
|
171
|
-
assert_equal 415, status
|
172
|
-
end
|
173
|
-
|
174
|
-
def test_post_single
|
175
|
-
post '/posts',
|
176
|
-
{
|
177
|
-
'data' => {
|
178
|
-
'type' => 'posts',
|
179
|
-
'attributes' => {
|
180
|
-
'title' => 'A great new Post',
|
181
|
-
'body' => 'JSONAPIResources is the greatest thing since unsliced bread.'
|
182
|
-
},
|
183
|
-
'relationships' => {
|
184
|
-
'author' => {'data' => {type: 'people', id: '3'}}
|
185
|
-
}
|
186
|
-
}
|
187
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
188
|
-
|
189
|
-
assert_jsonapi_response 201
|
190
|
-
end
|
191
|
-
|
192
|
-
def test_post_single_missing_data_contents
|
193
|
-
post '/posts',
|
194
|
-
{
|
195
|
-
'data' => {
|
196
|
-
}
|
197
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
198
|
-
|
199
|
-
assert_jsonapi_response 400
|
200
|
-
end
|
201
|
-
|
202
|
-
def test_post_single_minimal_valid
|
203
|
-
post '/comments',
|
204
|
-
{
|
205
|
-
'data' => {
|
206
|
-
'type' => 'comments'
|
207
|
-
}
|
208
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
209
|
-
|
210
|
-
assert_jsonapi_response 201
|
211
|
-
assert_nil json_response['data']['attributes']['body']
|
212
|
-
assert_nil json_response['data']['relationships']['post']['data']
|
213
|
-
assert_nil json_response['data']['relationships']['author']['data']
|
214
|
-
end
|
215
|
-
|
216
|
-
def test_post_single_minimal_invalid
|
217
|
-
post '/posts',
|
218
|
-
{
|
219
|
-
'data' => {
|
220
|
-
'type' => 'posts'
|
221
|
-
}
|
222
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
223
|
-
|
224
|
-
assert_jsonapi_response 422
|
225
|
-
end
|
226
|
-
|
227
|
-
def test_update_relationship_without_content_type
|
228
|
-
ruby = Section.find_by(name: 'ruby')
|
229
|
-
patch '/posts/3/relationships/section', { 'data' => {type: 'sections', id: ruby.id.to_s }}.to_json
|
230
|
-
|
231
|
-
assert_equal 415, status
|
232
|
-
end
|
233
|
-
|
234
|
-
def test_patch_update_relationship_to_one
|
235
|
-
ruby = Section.find_by(name: 'ruby')
|
236
|
-
patch '/posts/3/relationships/section', { 'data' => {type: 'sections', id: ruby.id.to_s }}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
237
|
-
|
238
|
-
assert_equal 204, status
|
239
|
-
end
|
240
|
-
|
241
|
-
def test_put_update_relationship_to_one
|
242
|
-
ruby = Section.find_by(name: 'ruby')
|
243
|
-
put '/posts/3/relationships/section', { 'data' => {type: 'sections', id: ruby.id.to_s }}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
244
|
-
|
245
|
-
assert_equal 204, status
|
246
|
-
end
|
247
|
-
|
248
|
-
def test_patch_update_relationship_to_many_acts_as_set
|
249
|
-
# Comments are acts_as_set=false so PUT/PATCH should respond with 403
|
250
|
-
|
251
|
-
rogue = Comment.find_by(body: 'Rogue Comment Here')
|
252
|
-
patch '/posts/5/relationships/comments', { 'data' => [{type: 'comments', id: rogue.id.to_s }]}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
253
|
-
|
254
|
-
assert_jsonapi_response 403
|
255
|
-
end
|
256
|
-
|
257
|
-
def test_post_update_relationship_to_many
|
258
|
-
rogue = Comment.find_by(body: 'Rogue Comment Here')
|
259
|
-
post '/posts/5/relationships/comments', { 'data' => [{type: 'comments', id: rogue.id.to_s }]}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
260
|
-
|
261
|
-
assert_equal 204, status
|
262
|
-
end
|
263
|
-
|
264
|
-
def test_put_update_relationship_to_many_acts_as_set
|
265
|
-
# Comments are acts_as_set=false so PUT/PATCH should respond with 403. Note: JR currently treats PUT and PATCH as equivalent
|
266
|
-
|
267
|
-
rogue = Comment.find_by(body: 'Rogue Comment Here')
|
268
|
-
put '/posts/5/relationships/comments', { 'data' => [{type: 'comments', id: rogue.id.to_s }]}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
269
|
-
|
270
|
-
assert_jsonapi_response 403
|
271
|
-
end
|
272
|
-
|
273
|
-
def test_index_content_type
|
274
|
-
get '/posts'
|
275
|
-
assert_match JSONAPI::MEDIA_TYPE, headers['Content-Type']
|
276
|
-
end
|
277
|
-
|
278
|
-
def test_get_content_type
|
279
|
-
get '/posts/3'
|
280
|
-
assert_match JSONAPI::MEDIA_TYPE, headers['Content-Type']
|
281
|
-
end
|
282
|
-
|
283
|
-
def test_put_content_type
|
284
|
-
put '/posts/3',
|
285
|
-
{
|
286
|
-
'data' => {
|
287
|
-
'type' => 'posts',
|
288
|
-
'id' => '3',
|
289
|
-
'attributes' => {
|
290
|
-
'title' => 'A great new Post'
|
291
|
-
},
|
292
|
-
'relationships' => {
|
293
|
-
'tags' => {
|
294
|
-
'data' => [
|
295
|
-
{type: 'tags', id: 3},
|
296
|
-
{type: 'tags', id: 4}
|
297
|
-
]
|
298
|
-
}
|
299
|
-
}
|
300
|
-
}
|
301
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
302
|
-
|
303
|
-
assert_match JSONAPI::MEDIA_TYPE, headers['Content-Type']
|
304
|
-
end
|
305
|
-
|
306
|
-
def test_patch_content_type
|
307
|
-
patch '/posts/3',
|
308
|
-
{
|
309
|
-
'data' => {
|
310
|
-
'type' => 'posts',
|
311
|
-
'id' => '3',
|
312
|
-
'attributes' => {
|
313
|
-
'title' => 'A great new Post'
|
314
|
-
},
|
315
|
-
'relationships' => {
|
316
|
-
'tags' => {
|
317
|
-
'data' => [
|
318
|
-
{type: 'tags', id: 3},
|
319
|
-
{type: 'tags', id: 4}
|
320
|
-
]
|
321
|
-
}
|
322
|
-
}
|
323
|
-
}
|
324
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
325
|
-
|
326
|
-
assert_match JSONAPI::MEDIA_TYPE, headers['Content-Type']
|
327
|
-
end
|
328
|
-
|
329
|
-
def test_post_correct_content_type
|
330
|
-
post '/posts',
|
331
|
-
{
|
332
|
-
'data' => {
|
333
|
-
'type' => 'posts',
|
334
|
-
'attributes' => {
|
335
|
-
'title' => 'A great new Post'
|
336
|
-
},
|
337
|
-
'relationships' => {
|
338
|
-
'author' => {'data' => {type: 'people', id: '3'}}
|
339
|
-
}
|
340
|
-
}
|
341
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
342
|
-
|
343
|
-
assert_match JSONAPI::MEDIA_TYPE, headers['Content-Type']
|
344
|
-
end
|
345
|
-
|
346
|
-
def test_destroy_single
|
347
|
-
delete '/posts/7'
|
348
|
-
assert_equal 204, status
|
349
|
-
assert_nil headers['Content-Type']
|
350
|
-
end
|
351
|
-
|
352
|
-
def test_destroy_multiple
|
353
|
-
delete '/posts/8,9'
|
354
|
-
assert_equal 204, status
|
355
|
-
end
|
356
|
-
|
357
|
-
def test_pagination_none
|
358
|
-
Api::V2::BookResource.paginator :none
|
359
|
-
get '/api/v2/books'
|
360
|
-
assert_jsonapi_response 200
|
361
|
-
assert_equal 901, json_response['data'].size
|
362
|
-
end
|
363
|
-
|
364
|
-
def test_pagination_offset_style
|
365
|
-
Api::V2::BookResource.paginator :offset
|
366
|
-
get '/api/v2/books'
|
367
|
-
assert_jsonapi_response 200
|
368
|
-
assert_equal JSONAPI.configuration.default_page_size, json_response['data'].size
|
369
|
-
assert_equal 'Book 0', json_response['data'][0]['attributes']['title']
|
370
|
-
end
|
371
|
-
|
372
|
-
def test_pagination_offset_style_offset
|
373
|
-
Api::V2::BookResource.paginator :offset
|
374
|
-
get '/api/v2/books?page[offset]=50'
|
375
|
-
assert_jsonapi_response 200
|
376
|
-
assert_equal JSONAPI.configuration.default_page_size, json_response['data'].size
|
377
|
-
assert_equal 'Book 50', json_response['data'][0]['attributes']['title']
|
378
|
-
end
|
379
|
-
|
380
|
-
def test_pagination_offset_style_offset_limit
|
381
|
-
Api::V2::BookResource.paginator :offset
|
382
|
-
get '/api/v2/books?page[offset]=50&page[limit]=20'
|
383
|
-
assert_jsonapi_response 200
|
384
|
-
assert_equal 20, json_response['data'].size
|
385
|
-
assert_equal 'Book 50', json_response['data'][0]['attributes']['title']
|
386
|
-
end
|
387
|
-
|
388
|
-
def test_pagination_offset_bad_param
|
389
|
-
Api::V2::BookResource.paginator :offset
|
390
|
-
get '/api/v2/books?page[irishsetter]=50&page[limit]=20'
|
391
|
-
assert_jsonapi_response 400
|
392
|
-
end
|
393
|
-
|
394
|
-
def test_pagination_related_resources_link
|
395
|
-
Api::V2::BookResource.paginator :offset
|
396
|
-
get '/api/v2/books?page[limit]=2'
|
397
|
-
assert_jsonapi_response 200
|
398
|
-
assert_equal 2, json_response['data'].size
|
399
|
-
assert_equal 'http://www.example.com/api/v2/books/1/book_comments',
|
400
|
-
json_response['data'][1]['relationships']['book_comments']['links']['related']
|
401
|
-
end
|
402
|
-
|
403
|
-
def test_pagination_related_resources_data
|
404
|
-
Api::V2::BookResource.paginator :offset
|
405
|
-
Api::V2::BookCommentResource.paginator :offset
|
406
|
-
get '/api/v2/books/1/book_comments?page[limit]=10'
|
407
|
-
assert_jsonapi_response 200
|
408
|
-
assert_equal 10, json_response['data'].size
|
409
|
-
assert_equal 'This is comment 18 on book 1.', json_response['data'][9]['attributes']['body']
|
410
|
-
end
|
411
|
-
|
412
|
-
def test_pagination_related_resources_links
|
413
|
-
Api::V2::BookResource.paginator :offset
|
414
|
-
Api::V2::BookCommentResource.paginator :offset
|
415
|
-
get '/api/v2/books/1/book_comments?page[limit]=10'
|
416
|
-
assert_equal 'http://www.example.com/api/v2/books/1/book_comments?page%5Blimit%5D=10&page%5Boffset%5D=0', json_response['links']['first']
|
417
|
-
assert_equal 'http://www.example.com/api/v2/books/1/book_comments?page%5Blimit%5D=10&page%5Boffset%5D=10', json_response['links']['next']
|
418
|
-
assert_equal 'http://www.example.com/api/v2/books/1/book_comments?page%5Blimit%5D=10&page%5Boffset%5D=16', json_response['links']['last']
|
419
|
-
end
|
420
|
-
|
421
|
-
def test_pagination_related_resources_links_meta
|
422
|
-
Api::V2::BookResource.paginator :offset
|
423
|
-
Api::V2::BookCommentResource.paginator :offset
|
424
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
425
|
-
get '/api/v2/books/1/book_comments?page[limit]=10'
|
426
|
-
assert_equal 26, json_response['meta']['record_count']
|
427
|
-
assert_equal 'http://www.example.com/api/v2/books/1/book_comments?page%5Blimit%5D=10&page%5Boffset%5D=0', json_response['links']['first']
|
428
|
-
assert_equal 'http://www.example.com/api/v2/books/1/book_comments?page%5Blimit%5D=10&page%5Boffset%5D=10', json_response['links']['next']
|
429
|
-
assert_equal 'http://www.example.com/api/v2/books/1/book_comments?page%5Blimit%5D=10&page%5Boffset%5D=16', json_response['links']['last']
|
430
|
-
ensure
|
431
|
-
JSONAPI.configuration.top_level_meta_include_record_count = false
|
432
|
-
end
|
433
|
-
|
434
|
-
def test_filter_related_resources
|
435
|
-
Api::V2::BookCommentResource.paginator :offset
|
436
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
437
|
-
get '/api/v2/books/1/book_comments?filter[book]=2'
|
438
|
-
assert_equal 0, json_response['meta']['record_count']
|
439
|
-
get '/api/v2/books/1/book_comments?filter[book]=1&page[limit]=20'
|
440
|
-
assert_equal 26, json_response['meta']['record_count']
|
441
|
-
ensure
|
442
|
-
JSONAPI.configuration.top_level_meta_include_record_count = false
|
443
|
-
end
|
444
|
-
|
445
|
-
def test_pagination_related_resources_without_related
|
446
|
-
Api::V2::BookResource.paginator :offset
|
447
|
-
Api::V2::BookCommentResource.paginator :offset
|
448
|
-
get '/api/v2/books/10/book_comments'
|
449
|
-
assert_jsonapi_response 200
|
450
|
-
assert_nil json_response['links']['next']
|
451
|
-
assert_equal 'http://www.example.com/api/v2/books/10/book_comments?page%5Blimit%5D=10&page%5Boffset%5D=0', json_response['links']['first']
|
452
|
-
assert_equal 'http://www.example.com/api/v2/books/10/book_comments?page%5Blimit%5D=10&page%5Boffset%5D=0', json_response['links']['last']
|
453
|
-
end
|
454
|
-
|
455
|
-
def test_related_resource_alternate_relation_name_record_count
|
456
|
-
original_config = JSONAPI.configuration.dup
|
457
|
-
JSONAPI.configuration.default_paginator = :paged
|
458
|
-
JSONAPI.configuration.top_level_meta_include_record_count = true
|
459
|
-
|
460
|
-
get '/api/v2/books/1/aliased_comments'
|
461
|
-
assert_jsonapi_response 200
|
462
|
-
assert_equal 26, json_response['meta']['record_count']
|
463
|
-
ensure
|
464
|
-
JSONAPI.configuration = original_config
|
465
|
-
end
|
466
|
-
|
467
|
-
def test_pagination_related_resources_data_includes
|
468
|
-
Api::V2::BookResource.paginator :offset
|
469
|
-
Api::V2::BookCommentResource.paginator :offset
|
470
|
-
get '/api/v2/books/1/book_comments?page[limit]=10&include=author,book'
|
471
|
-
assert_jsonapi_response 200
|
472
|
-
assert_equal 10, json_response['data'].size
|
473
|
-
assert_equal 'This is comment 18 on book 1.', json_response['data'][9]['attributes']['body']
|
474
|
-
end
|
475
|
-
|
476
|
-
def test_pagination_empty_results
|
477
|
-
Api::V2::BookResource.paginator :offset
|
478
|
-
Api::V2::BookCommentResource.paginator :offset
|
479
|
-
get '/api/v2/books?filter[id]=2000&page[limit]=10'
|
480
|
-
assert_jsonapi_response 200
|
481
|
-
assert_equal 0, json_response['data'].size
|
482
|
-
assert_nil json_response['links']['next']
|
483
|
-
assert_equal 'http://www.example.com/api/v2/books?filter%5Bid%5D=2000&page%5Blimit%5D=10&page%5Boffset%5D=0', json_response['links']['first']
|
484
|
-
assert_equal 'http://www.example.com/api/v2/books?filter%5Bid%5D=2000&page%5Blimit%5D=10&page%5Boffset%5D=0', json_response['links']['last']
|
485
|
-
end
|
486
|
-
|
487
|
-
# def test_pagination_related_resources_data_includes
|
488
|
-
# Api::V2::BookResource.paginator :none
|
489
|
-
# Api::V2::BookCommentResource.paginator :none
|
490
|
-
# get '/api/v2/books?filter[]'
|
491
|
-
# assert_jsonapi_response 200
|
492
|
-
# assert_equal 10, json_response['data'].size
|
493
|
-
# assert_equal 'This is comment 18 on book 1.', json_response['data'][9]['attributes']['body']
|
494
|
-
# end
|
495
|
-
|
496
|
-
|
497
|
-
def test_flow_self
|
498
|
-
get '/posts'
|
499
|
-
assert_jsonapi_response 200
|
500
|
-
post_1 = json_response['data'][0]
|
501
|
-
|
502
|
-
get post_1['links']['self']
|
503
|
-
assert_jsonapi_response 200
|
504
|
-
assert_hash_equals post_1, json_response['data']
|
505
|
-
end
|
506
|
-
|
507
|
-
def test_flow_link_to_one_self_link
|
508
|
-
get '/posts'
|
509
|
-
assert_jsonapi_response 200
|
510
|
-
post_1 = json_response['data'][0]
|
511
|
-
|
512
|
-
get post_1['relationships']['author']['links']['self']
|
513
|
-
assert_jsonapi_response 200
|
514
|
-
assert_hash_equals(json_response, {
|
515
|
-
'links' => {
|
516
|
-
'self' => 'http://www.example.com/posts/1/relationships/author',
|
517
|
-
'related' => 'http://www.example.com/posts/1/author'
|
518
|
-
},
|
519
|
-
'data' => {type: 'people', id: '1'}
|
520
|
-
})
|
521
|
-
end
|
522
|
-
|
523
|
-
def test_flow_link_to_many_self_link
|
524
|
-
get '/posts'
|
525
|
-
assert_jsonapi_response 200
|
526
|
-
post_1 = json_response['data'][0]
|
527
|
-
|
528
|
-
get post_1['relationships']['tags']['links']['self']
|
529
|
-
assert_jsonapi_response 200
|
530
|
-
assert_hash_equals(json_response,
|
531
|
-
{
|
532
|
-
'links' => {
|
533
|
-
'self' => 'http://www.example.com/posts/1/relationships/tags',
|
534
|
-
'related' => 'http://www.example.com/posts/1/tags'
|
535
|
-
},
|
536
|
-
'data' => [
|
537
|
-
{type: 'tags', id: '1'},
|
538
|
-
{type: 'tags', id: '2'},
|
539
|
-
{type: 'tags', id: '3'}
|
540
|
-
]
|
541
|
-
})
|
542
|
-
end
|
543
|
-
|
544
|
-
def test_flow_link_to_many_self_link_put
|
545
|
-
get '/posts'
|
546
|
-
assert_jsonapi_response 200
|
547
|
-
post_1 = json_response['data'][4]
|
548
|
-
|
549
|
-
post post_1['relationships']['tags']['links']['self'],
|
550
|
-
{'data' => [{'type' => 'tags', 'id' => '10'}]}.to_json,
|
551
|
-
"CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
552
|
-
|
553
|
-
assert_equal 204, status
|
554
|
-
|
555
|
-
get post_1['relationships']['tags']['links']['self']
|
556
|
-
assert_jsonapi_response 200
|
557
|
-
assert_hash_equals(json_response,
|
558
|
-
{
|
559
|
-
'links' => {
|
560
|
-
'self' => 'http://www.example.com/posts/5/relationships/tags',
|
561
|
-
'related' => 'http://www.example.com/posts/5/tags'
|
562
|
-
},
|
563
|
-
'data' => [
|
564
|
-
{type: 'tags', id: '10'}
|
565
|
-
]
|
566
|
-
})
|
567
|
-
end
|
568
|
-
|
569
|
-
def test_flow_self_formatted_route_1
|
570
|
-
original_config = JSONAPI.configuration.dup
|
571
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
572
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
573
|
-
get '/api/v6/purchase-orders'
|
574
|
-
assert_jsonapi_response 200
|
575
|
-
po_1 = json_response['data'][0]
|
576
|
-
assert_equal 'purchase-orders', json_response['data'][0]['type']
|
577
|
-
|
578
|
-
get po_1['links']['self']
|
579
|
-
assert_jsonapi_response 200
|
580
|
-
assert_hash_equals po_1, json_response['data']
|
581
|
-
ensure
|
582
|
-
JSONAPI.configuration = original_config
|
583
|
-
end
|
584
|
-
|
585
|
-
def test_flow_self_formatted_route_2
|
586
|
-
original_config = JSONAPI.configuration.dup
|
587
|
-
JSONAPI.configuration.route_format = :underscored_route
|
588
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
589
|
-
get '/api/v7/purchase_orders'
|
590
|
-
assert_jsonapi_response 200
|
591
|
-
assert_equal 'purchase-orders', json_response['data'][0]['type']
|
592
|
-
|
593
|
-
po_1 = json_response['data'][0]
|
594
|
-
|
595
|
-
get po_1['links']['self']
|
596
|
-
assert_jsonapi_response 200
|
597
|
-
assert_hash_equals po_1, json_response['data']
|
598
|
-
ensure
|
599
|
-
JSONAPI.configuration = original_config
|
600
|
-
end
|
601
|
-
|
602
|
-
def test_flow_self_formatted_route_3
|
603
|
-
original_config = JSONAPI.configuration.dup
|
604
|
-
JSONAPI.configuration.route_format = :underscored_route
|
605
|
-
JSONAPI.configuration.json_key_format = :underscored_key
|
606
|
-
get '/api/v7/purchase_orders'
|
607
|
-
assert_jsonapi_response 200
|
608
|
-
assert_equal 'purchase_orders', json_response['data'][0]['type']
|
609
|
-
|
610
|
-
po_1 = json_response['data'][0]
|
611
|
-
|
612
|
-
get po_1['links']['self']
|
613
|
-
assert_jsonapi_response 200
|
614
|
-
assert_hash_equals po_1, json_response['data']
|
615
|
-
ensure
|
616
|
-
JSONAPI.configuration = original_config
|
617
|
-
end
|
618
|
-
|
619
|
-
def test_post_formatted_keys
|
620
|
-
original_config = JSONAPI.configuration.dup
|
621
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
622
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
623
|
-
post '/api/v6/purchase-orders',
|
624
|
-
{
|
625
|
-
'data' => {
|
626
|
-
'attributes' => {
|
627
|
-
'delivery-name' => 'ASDFG Corp'
|
628
|
-
},
|
629
|
-
'type' => 'purchase-orders'
|
630
|
-
}
|
631
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
632
|
-
|
633
|
-
assert_jsonapi_response 201
|
634
|
-
ensure
|
635
|
-
JSONAPI.configuration = original_config
|
636
|
-
end
|
637
|
-
|
638
|
-
def test_post_formatted_keys_different_route_key_1
|
639
|
-
original_config = JSONAPI.configuration.dup
|
640
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
641
|
-
JSONAPI.configuration.json_key_format = :underscored_key
|
642
|
-
post '/api/v6/purchase-orders',
|
643
|
-
{
|
644
|
-
'data' => {
|
645
|
-
'attributes' => {
|
646
|
-
'delivery_name' => 'ASDFG Corp'
|
647
|
-
},
|
648
|
-
'type' => 'purchase_orders'
|
649
|
-
}
|
650
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
651
|
-
|
652
|
-
assert_jsonapi_response 201
|
653
|
-
ensure
|
654
|
-
JSONAPI.configuration = original_config
|
655
|
-
end
|
656
|
-
|
657
|
-
def test_post_formatted_keys_different_route_key_2
|
658
|
-
original_config = JSONAPI.configuration.dup
|
659
|
-
JSONAPI.configuration.route_format = :underscored_route
|
660
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
661
|
-
post '/api/v7/purchase_orders',
|
662
|
-
{
|
663
|
-
'data' => {
|
664
|
-
'attributes' => {
|
665
|
-
'delivery-name' => 'ASDFG Corp'
|
666
|
-
},
|
667
|
-
'type' => 'purchase-orders'
|
668
|
-
}
|
669
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
670
|
-
|
671
|
-
assert_jsonapi_response 201
|
672
|
-
ensure
|
673
|
-
JSONAPI.configuration = original_config
|
674
|
-
end
|
675
|
-
|
676
|
-
def test_post_formatted_keys_wrong_format
|
677
|
-
original_config = JSONAPI.configuration.dup
|
678
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
679
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
680
|
-
post '/api/v6/purchase-orders',
|
681
|
-
{
|
682
|
-
'data' => {
|
683
|
-
'attributes' => {
|
684
|
-
'delivery_name' => 'ASDFG Corp'
|
685
|
-
},
|
686
|
-
'type' => 'purchase-orders'
|
687
|
-
}
|
688
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
689
|
-
|
690
|
-
assert_jsonapi_response 400
|
691
|
-
ensure
|
692
|
-
JSONAPI.configuration = original_config
|
693
|
-
end
|
694
|
-
|
695
|
-
def test_patch_formatted_dasherized
|
696
|
-
original_config = JSONAPI.configuration.dup
|
697
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
698
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
699
|
-
patch '/api/v6/purchase-orders/1',
|
700
|
-
{
|
701
|
-
'data' => {
|
702
|
-
'id' => '1',
|
703
|
-
'attributes' => {
|
704
|
-
'delivery-name' => 'ASDFG Corp'
|
705
|
-
},
|
706
|
-
'type' => 'purchase-orders'
|
707
|
-
}
|
708
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
709
|
-
|
710
|
-
assert_jsonapi_response 200
|
711
|
-
end
|
712
|
-
|
713
|
-
def test_patch_formatted_dasherized_links
|
714
|
-
original_config = JSONAPI.configuration.dup
|
715
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
716
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
717
|
-
patch '/api/v6/line-items/1',
|
718
|
-
{
|
719
|
-
'data' => {
|
720
|
-
'id' => '1',
|
721
|
-
'type' => 'line-items',
|
722
|
-
'attributes' => {
|
723
|
-
'item-cost' => '23.57'
|
724
|
-
},
|
725
|
-
'relationships' => {
|
726
|
-
'purchase-order' => {
|
727
|
-
'data' => {'type' => 'purchase-orders', 'id' => '2'}
|
728
|
-
}
|
729
|
-
}
|
730
|
-
}
|
731
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
732
|
-
|
733
|
-
assert_jsonapi_response 200
|
734
|
-
ensure
|
735
|
-
JSONAPI.configuration = original_config
|
736
|
-
end
|
737
|
-
|
738
|
-
def test_patch_formatted_dasherized_replace_to_many
|
739
|
-
original_config = JSONAPI.configuration.dup
|
740
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
741
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
742
|
-
patch '/api/v6/purchase-orders/2?include=line-items,order-flags',
|
743
|
-
{
|
744
|
-
'data' => {
|
745
|
-
'id' => '2',
|
746
|
-
'type' => 'purchase-orders',
|
747
|
-
'relationships' => {
|
748
|
-
'line-items' => {
|
749
|
-
'data' => [
|
750
|
-
{'type' => 'line-items', 'id' => '3'},
|
751
|
-
{'type' => 'line-items', 'id' => '4'}
|
752
|
-
]
|
753
|
-
},
|
754
|
-
'order-flags' => {
|
755
|
-
'data' => [
|
756
|
-
{'type' => 'order-flags', 'id' => '1'},
|
757
|
-
{'type' => 'order-flags', 'id' => '2'}
|
758
|
-
]
|
759
|
-
}
|
760
|
-
}
|
761
|
-
}
|
762
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
763
|
-
|
764
|
-
assert_jsonapi_response 200
|
765
|
-
ensure
|
766
|
-
JSONAPI.configuration = original_config
|
767
|
-
end
|
768
|
-
|
769
|
-
def test_patch_formatted_dasherized_replace_to_many_computed_relation
|
770
|
-
$original_test_user = $test_user
|
771
|
-
$test_user = Person.find(5)
|
772
|
-
original_config = JSONAPI.configuration.dup
|
773
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
774
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
775
|
-
patch '/api/v6/purchase-orders/2?include=line-items,order-flags',
|
776
|
-
{
|
777
|
-
'data' => {
|
778
|
-
'id' => '2',
|
779
|
-
'type' => 'purchase-orders',
|
780
|
-
'relationships' => {
|
781
|
-
'line-items' => {
|
782
|
-
'data' => [
|
783
|
-
{'type' => 'line-items', 'id' => '3'},
|
784
|
-
{'type' => 'line-items', 'id' => '4'}
|
785
|
-
]
|
786
|
-
},
|
787
|
-
'order-flags' => {
|
788
|
-
'data' => [
|
789
|
-
{'type' => 'order-flags', 'id' => '1'},
|
790
|
-
{'type' => 'order-flags', 'id' => '2'}
|
791
|
-
]
|
792
|
-
}
|
793
|
-
}
|
794
|
-
}
|
795
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
796
|
-
|
797
|
-
assert_jsonapi_response 200
|
798
|
-
ensure
|
799
|
-
JSONAPI.configuration = original_config
|
800
|
-
$test_user = $original_test_user
|
801
|
-
end
|
802
|
-
|
803
|
-
def test_post_to_many_link
|
804
|
-
original_config = JSONAPI.configuration.dup
|
805
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
806
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
807
|
-
post '/api/v6/purchase-orders/3/relationships/line-items',
|
808
|
-
{
|
809
|
-
'data' => [
|
810
|
-
{'type' => 'line-items', 'id' => '3'},
|
811
|
-
{'type' => 'line-items', 'id' => '4'}
|
812
|
-
]
|
813
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
814
|
-
|
815
|
-
assert_equal 204, status
|
816
|
-
ensure
|
817
|
-
JSONAPI.configuration = original_config
|
818
|
-
end
|
819
|
-
|
820
|
-
def test_post_computed_relation_to_many
|
821
|
-
$original_test_user = $test_user
|
822
|
-
$test_user = Person.find(5)
|
823
|
-
original_config = JSONAPI.configuration.dup
|
824
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
825
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
826
|
-
post '/api/v6/purchase-orders/4/relationships/line-items',
|
827
|
-
{
|
828
|
-
'data' => [
|
829
|
-
{'type' => 'line-items', 'id' => '5'},
|
830
|
-
{'type' => 'line-items', 'id' => '6'}
|
831
|
-
]
|
832
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
833
|
-
|
834
|
-
assert_equal 204, status
|
835
|
-
ensure
|
836
|
-
JSONAPI.configuration = original_config
|
837
|
-
$test_user = $original_test_user
|
838
|
-
end
|
839
|
-
|
840
|
-
def test_patch_to_many_link
|
841
|
-
original_config = JSONAPI.configuration.dup
|
842
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
843
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
844
|
-
patch '/api/v6/purchase-orders/3/relationships/order-flags',
|
845
|
-
{
|
846
|
-
'data' => [
|
847
|
-
{'type' => 'order-flags', 'id' => '1'},
|
848
|
-
{'type' => 'order-flags', 'id' => '2'}
|
849
|
-
]
|
850
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
851
|
-
|
852
|
-
assert_equal 204, status
|
853
|
-
ensure
|
854
|
-
JSONAPI.configuration = original_config
|
855
|
-
end
|
856
|
-
|
857
|
-
def test_patch_to_many_link_computed_relation
|
858
|
-
$original_test_user = $test_user
|
859
|
-
$test_user = Person.find(5)
|
860
|
-
original_config = JSONAPI.configuration.dup
|
861
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
862
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
863
|
-
patch '/api/v6/purchase-orders/4/relationships/order-flags',
|
864
|
-
{
|
865
|
-
'data' => [
|
866
|
-
{'type' => 'order-flags', 'id' => '1'},
|
867
|
-
{'type' => 'order-flags', 'id' => '2'}
|
868
|
-
]
|
869
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
870
|
-
|
871
|
-
assert_equal 204, status
|
872
|
-
ensure
|
873
|
-
JSONAPI.configuration = original_config
|
874
|
-
$test_user = $original_test_user
|
875
|
-
end
|
876
|
-
|
877
|
-
def test_patch_to_one
|
878
|
-
original_config = JSONAPI.configuration.dup
|
879
|
-
JSONAPI.configuration.route_format = :dasherized_route
|
880
|
-
JSONAPI.configuration.json_key_format = :dasherized_key
|
881
|
-
patch '/api/v6/line-items/5/relationships/purchase-order',
|
882
|
-
{
|
883
|
-
'data' => {'type' => 'purchase-orders', 'id' => '3'}
|
884
|
-
}.to_json, "CONTENT_TYPE" => JSONAPI::MEDIA_TYPE
|
885
|
-
|
886
|
-
assert_equal 204, status
|
887
|
-
ensure
|
888
|
-
JSONAPI.configuration = original_config
|
889
|
-
end
|
890
|
-
|
891
|
-
def test_include_parameter_allowed
|
892
|
-
get '/api/v2/books/1/book_comments?include=author'
|
893
|
-
assert_jsonapi_response 200
|
894
|
-
end
|
895
|
-
|
896
|
-
def test_include_parameter_not_allowed
|
897
|
-
JSONAPI.configuration.allow_include = false
|
898
|
-
get '/api/v2/books/1/book_comments?include=author'
|
899
|
-
assert_jsonapi_response 400
|
900
|
-
ensure
|
901
|
-
JSONAPI.configuration.allow_include = true
|
902
|
-
end
|
903
|
-
|
904
|
-
def test_filter_parameter_not_allowed
|
905
|
-
JSONAPI.configuration.allow_filter = false
|
906
|
-
get '/api/v2/books?filter[author]=1'
|
907
|
-
assert_jsonapi_response 400
|
908
|
-
ensure
|
909
|
-
JSONAPI.configuration.allow_filter = true
|
910
|
-
end
|
911
|
-
|
912
|
-
def test_sort_parameter_not_allowed
|
913
|
-
JSONAPI.configuration.allow_sort = false
|
914
|
-
get '/api/v2/books?sort=title'
|
915
|
-
assert_jsonapi_response 400
|
916
|
-
ensure
|
917
|
-
JSONAPI.configuration.allow_sort = true
|
918
|
-
end
|
919
|
-
|
920
|
-
def test_getting_different_resources_when_sti
|
921
|
-
get '/vehicles'
|
922
|
-
assert_jsonapi_response 200
|
923
|
-
types = json_response['data'].map{|r| r['type']}.sort
|
924
|
-
assert_array_equals ['boats', 'cars'], types
|
925
|
-
end
|
926
|
-
|
927
|
-
def test_getting_resource_with_correct_type_when_sti
|
928
|
-
get '/vehicles/1'
|
929
|
-
assert_jsonapi_response 200
|
930
|
-
assert_equal 'cars', json_response['data']['type']
|
931
|
-
end
|
932
|
-
end
|