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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +248 -74
  3. data/lib/jsonapi-resources.rb +5 -3
  4. data/lib/jsonapi/acts_as_resource_controller.rb +77 -14
  5. data/lib/jsonapi/configuration.rb +77 -16
  6. data/lib/jsonapi/error.rb +12 -0
  7. data/lib/jsonapi/error_codes.rb +2 -0
  8. data/lib/jsonapi/exceptions.rb +29 -9
  9. data/lib/jsonapi/formatter.rb +29 -4
  10. data/lib/jsonapi/link_builder.rb +18 -18
  11. data/lib/jsonapi/mime_types.rb +25 -6
  12. data/lib/jsonapi/naive_cache.rb +30 -0
  13. data/lib/jsonapi/operation.rb +10 -342
  14. data/lib/jsonapi/operation_dispatcher.rb +87 -0
  15. data/lib/jsonapi/operation_result.rb +2 -1
  16. data/lib/jsonapi/paginator.rb +6 -2
  17. data/lib/jsonapi/processor.rb +283 -0
  18. data/lib/jsonapi/relationship.rb +6 -4
  19. data/lib/jsonapi/{request.rb → request_parser.rb} +46 -35
  20. data/lib/jsonapi/resource.rb +88 -13
  21. data/lib/jsonapi/resource_controller.rb +2 -14
  22. data/lib/jsonapi/resource_controller_metal.rb +17 -0
  23. data/lib/jsonapi/resource_serializer.rb +62 -47
  24. data/lib/jsonapi/resources/version.rb +1 -1
  25. data/lib/jsonapi/response_document.rb +13 -2
  26. data/lib/jsonapi/routing_ext.rb +49 -11
  27. metadata +37 -129
  28. data/.gitignore +0 -22
  29. data/.travis.yml +0 -9
  30. data/Gemfile +0 -23
  31. data/Rakefile +0 -20
  32. data/jsonapi-resources.gemspec +0 -29
  33. data/lib/jsonapi/active_record_operations_processor.rb +0 -35
  34. data/lib/jsonapi/operations_processor.rb +0 -120
  35. data/locales/en.yml +0 -80
  36. data/test/config/database.yml +0 -5
  37. data/test/controllers/controller_test.rb +0 -3312
  38. data/test/fixtures/active_record.rb +0 -1486
  39. data/test/fixtures/author_details.yml +0 -9
  40. data/test/fixtures/book_authors.yml +0 -3
  41. data/test/fixtures/book_comments.yml +0 -12
  42. data/test/fixtures/books.yml +0 -7
  43. data/test/fixtures/categories.yml +0 -35
  44. data/test/fixtures/comments.yml +0 -21
  45. data/test/fixtures/comments_tags.yml +0 -20
  46. data/test/fixtures/companies.yml +0 -4
  47. data/test/fixtures/craters.yml +0 -9
  48. data/test/fixtures/customers.yml +0 -11
  49. data/test/fixtures/documents.yml +0 -3
  50. data/test/fixtures/expense_entries.yml +0 -13
  51. data/test/fixtures/facts.yml +0 -11
  52. data/test/fixtures/hair_cuts.yml +0 -3
  53. data/test/fixtures/iso_currencies.yml +0 -17
  54. data/test/fixtures/line_items.yml +0 -37
  55. data/test/fixtures/makes.yml +0 -2
  56. data/test/fixtures/moons.yml +0 -6
  57. data/test/fixtures/numeros_telefone.yml +0 -3
  58. data/test/fixtures/order_flags.yml +0 -7
  59. data/test/fixtures/people.yml +0 -31
  60. data/test/fixtures/pictures.yml +0 -15
  61. data/test/fixtures/planet_types.yml +0 -19
  62. data/test/fixtures/planets.yml +0 -47
  63. data/test/fixtures/posts.yml +0 -102
  64. data/test/fixtures/posts_tags.yml +0 -59
  65. data/test/fixtures/preferences.yml +0 -14
  66. data/test/fixtures/products.yml +0 -3
  67. data/test/fixtures/purchase_orders.yml +0 -23
  68. data/test/fixtures/sections.yml +0 -8
  69. data/test/fixtures/tags.yml +0 -39
  70. data/test/fixtures/vehicles.yml +0 -17
  71. data/test/fixtures/web_pages.yml +0 -3
  72. data/test/helpers/assertions.rb +0 -13
  73. data/test/helpers/functional_helpers.rb +0 -59
  74. data/test/helpers/value_matchers.rb +0 -60
  75. data/test/helpers/value_matchers_test.rb +0 -40
  76. data/test/integration/requests/namespaced_model_test.rb +0 -13
  77. data/test/integration/requests/request_test.rb +0 -932
  78. data/test/integration/routes/routes_test.rb +0 -218
  79. data/test/integration/sti_fields_test.rb +0 -18
  80. data/test/lib/generators/jsonapi/controller_generator_test.rb +0 -25
  81. data/test/lib/generators/jsonapi/resource_generator_test.rb +0 -30
  82. data/test/test_helper.rb +0 -342
  83. data/test/unit/formatters/dasherized_key_formatter_test.rb +0 -8
  84. data/test/unit/jsonapi_request/jsonapi_request_test.rb +0 -199
  85. data/test/unit/operation/operations_processor_test.rb +0 -528
  86. data/test/unit/pagination/offset_paginator_test.rb +0 -245
  87. data/test/unit/pagination/paged_paginator_test.rb +0 -242
  88. data/test/unit/resource/resource_test.rb +0 -560
  89. data/test/unit/serializer/include_directives_test.rb +0 -113
  90. data/test/unit/serializer/link_builder_test.rb +0 -244
  91. data/test/unit/serializer/polymorphic_serializer_test.rb +0 -383
  92. data/test/unit/serializer/response_document_test.rb +0 -61
  93. 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
@@ -1,14 +0,0 @@
1
- a:
2
- id: 1
3
- advanced_mode: false
4
-
5
- b:
6
- id: 2
7
- advanced_mode: false
8
- c:
9
- id: 3
10
- advanced_mode: false
11
-
12
- d:
13
- id: 4
14
- advanced_mode: false
@@ -1,3 +0,0 @@
1
- product_1:
2
- id: 1
3
- name: Enterprise Gizmo
@@ -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
@@ -1,8 +0,0 @@
1
- javascript:
2
- id: 1
3
- name: javascript
4
-
5
- ruby:
6
- id: 2
7
- name: ruby
8
-
@@ -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
@@ -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
@@ -1,3 +0,0 @@
1
- web_page1:
2
- href: http://example.com
3
- link: http://link.example.com
@@ -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