grape_fast_jsonapi 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ed838d297ef0c44b39588e77a204a37a8c8b4b4f
4
- data.tar.gz: 0e57addeb1bfeac8b6ff3e5c54ceb85d20f9cddb
2
+ SHA256:
3
+ metadata.gz: 38ad3fb865f43aa0c089abf0136617191d3dbf8fa10d3dff3798537312026851
4
+ data.tar.gz: 44f09504170ee1b3ec39be3d11784adaf5255b867693c77850d5089b2b2cecf5
5
5
  SHA512:
6
- metadata.gz: f65646281a1da90c7fb6e4d38918f67fe50c1467c3a54546b3a7a7d39e50189c907bf851c02b8bac01723196f038a842336e8f972a0772fd05d0b7b618fc9fa0
7
- data.tar.gz: 62e22336e61cec1388e2980dac12e045facf7fd77c7bb0a8c3ee94b9e1a7735904bfa21d2fa819425af9669758ef6f7e23003e712abf27a03f70c553d2d55cc9
6
+ metadata.gz: c6d628fe38e31362949ee2c9e7fbf9d866fe5e99ee910aa16f8dc533da1ee54ec5e8af949d688b194fbe783d258fe5ac09e20ee5a23d60ba8b1aa61335f4d1f7
7
+ data.tar.gz: c6f7ec14e0e3d67e9dd707dd99b563408d62526f4188c114198c53a8b053a0075c2c7f98bea028cf1baa797a613465ba7b0b8be16e431624bc961ae6dd00804c
@@ -0,0 +1,57 @@
1
+ # Ruby CircleCI 2.0 configuration file
2
+ #
3
+ # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
+ #
5
+ version: 2
6
+ jobs:
7
+ build:
8
+ docker:
9
+ # specify the version you desire here
10
+ - image: circleci/ruby:2.5.3-node-browsers
11
+ environment:
12
+ RAILS_ENV: test
13
+
14
+ # Specify service dependencies here if necessary
15
+ # CircleCI maintains a library of pre-built images
16
+ # documented at https://circleci.com/docs/2.0/circleci-images/
17
+
18
+ working_directory: ~/repo
19
+
20
+ steps:
21
+ - checkout
22
+
23
+ # Download and cache dependencies
24
+ - restore_cache:
25
+ keys:
26
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
27
+ # fallback to using the latest cache if no exact match is found
28
+ - v1-dependencies-
29
+
30
+ - run:
31
+ name: install gems
32
+ command: |
33
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
34
+
35
+ - save_cache:
36
+ paths:
37
+ - ./vendor/bundle
38
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
39
+
40
+ # run tests!
41
+ - run:
42
+ name: run tests
43
+ command: |
44
+ mkdir /tmp/test-results
45
+ TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
46
+
47
+ bundle exec rspec --format progress \
48
+ --out /tmp/test-results/rspec.xml \
49
+ --format progress \
50
+ $TEST_FILES
51
+
52
+ # collect reports
53
+ - store_test_results:
54
+ path: /tmp/test-results
55
+ - store_artifacts:
56
+ path: /tmp/test-results
57
+ destination: test-results
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
data/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ ## Changelog
2
+
3
+ ### 0.2.1 (Next)
4
+
5
+ * Your contribution here.
6
+
7
+ ### v0.2.0 (February 8, 2019)
8
+
9
+ * [#5](https://github.com/EmCousin/grape_fast_jsonapi/pull/5): Provide custom Grape Swagger parser for fast_jsonapi object serializers, as well as unit test coverage - [@EmCousin](https://github.com/EmCousin)
10
+ * [#6](https://github.com/EmCousin/grape_fast_jsonapi/pull/6) - Fix to make the parser compatible with latest version of fast_jsonapi (1.5 at date) - @rromanchuk](https://github.com/rromanchuk).
11
+
12
+ ### v0.1.0
13
+
14
+ * Initial public release - [@EmCousin](https://github.com/EmCousin).
data/Gemfile.lock ADDED
@@ -0,0 +1,173 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ grape_fast_jsonapi (0.2.0)
5
+ fast_jsonapi (>= 1.5)
6
+ grape
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actioncable (5.2.2)
12
+ actionpack (= 5.2.2)
13
+ nio4r (~> 2.0)
14
+ websocket-driver (>= 0.6.1)
15
+ actionmailer (5.2.2)
16
+ actionpack (= 5.2.2)
17
+ actionview (= 5.2.2)
18
+ activejob (= 5.2.2)
19
+ mail (~> 2.5, >= 2.5.4)
20
+ rails-dom-testing (~> 2.0)
21
+ actionpack (5.2.2)
22
+ actionview (= 5.2.2)
23
+ activesupport (= 5.2.2)
24
+ rack (~> 2.0)
25
+ rack-test (>= 0.6.3)
26
+ rails-dom-testing (~> 2.0)
27
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
28
+ actionview (5.2.2)
29
+ activesupport (= 5.2.2)
30
+ builder (~> 3.1)
31
+ erubi (~> 1.4)
32
+ rails-dom-testing (~> 2.0)
33
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
34
+ activejob (5.2.2)
35
+ activesupport (= 5.2.2)
36
+ globalid (>= 0.3.6)
37
+ activemodel (5.2.2)
38
+ activesupport (= 5.2.2)
39
+ activerecord (5.2.2)
40
+ activemodel (= 5.2.2)
41
+ activesupport (= 5.2.2)
42
+ arel (>= 9.0)
43
+ activestorage (5.2.2)
44
+ actionpack (= 5.2.2)
45
+ activerecord (= 5.2.2)
46
+ marcel (~> 0.3.1)
47
+ activesupport (5.2.2)
48
+ concurrent-ruby (~> 1.0, >= 1.0.2)
49
+ i18n (>= 0.7, < 2)
50
+ minitest (~> 5.1)
51
+ tzinfo (~> 1.1)
52
+ arel (9.0.0)
53
+ axiom-types (0.1.1)
54
+ descendants_tracker (~> 0.0.4)
55
+ ice_nine (~> 0.11.0)
56
+ thread_safe (~> 0.3, >= 0.3.1)
57
+ builder (3.2.3)
58
+ coercible (1.0.0)
59
+ descendants_tracker (~> 0.0.1)
60
+ concurrent-ruby (1.1.4)
61
+ crass (1.0.4)
62
+ descendants_tracker (0.0.4)
63
+ thread_safe (~> 0.3, >= 0.3.1)
64
+ diff-lcs (1.3)
65
+ equalizer (0.0.11)
66
+ erubi (1.8.0)
67
+ fast_jsonapi (1.5)
68
+ activesupport (>= 4.2)
69
+ globalid (0.4.2)
70
+ activesupport (>= 4.2.0)
71
+ grape (1.2.3)
72
+ activesupport
73
+ builder
74
+ mustermann-grape (~> 1.0.0)
75
+ rack (>= 1.3.0)
76
+ rack-accept
77
+ virtus (>= 1.0.0)
78
+ i18n (1.5.3)
79
+ concurrent-ruby (~> 1.0)
80
+ ice_nine (0.11.2)
81
+ loofah (2.2.3)
82
+ crass (~> 1.0.2)
83
+ nokogiri (>= 1.5.9)
84
+ mail (2.7.1)
85
+ mini_mime (>= 0.1.1)
86
+ marcel (0.3.3)
87
+ mimemagic (~> 0.3.2)
88
+ method_source (0.9.2)
89
+ mimemagic (0.3.3)
90
+ mini_mime (1.0.1)
91
+ mini_portile2 (2.4.0)
92
+ minitest (5.11.3)
93
+ mustermann (1.0.3)
94
+ mustermann-grape (1.0.0)
95
+ mustermann (~> 1.0.0)
96
+ nio4r (2.3.1)
97
+ nokogiri (1.10.1)
98
+ mini_portile2 (~> 2.4.0)
99
+ rack (2.0.6)
100
+ rack-accept (0.4.5)
101
+ rack (>= 0.4)
102
+ rack-test (1.1.0)
103
+ rack (>= 1.0, < 3)
104
+ rails (5.2.2)
105
+ actioncable (= 5.2.2)
106
+ actionmailer (= 5.2.2)
107
+ actionpack (= 5.2.2)
108
+ actionview (= 5.2.2)
109
+ activejob (= 5.2.2)
110
+ activemodel (= 5.2.2)
111
+ activerecord (= 5.2.2)
112
+ activestorage (= 5.2.2)
113
+ activesupport (= 5.2.2)
114
+ bundler (>= 1.3.0)
115
+ railties (= 5.2.2)
116
+ sprockets-rails (>= 2.0.0)
117
+ rails-dom-testing (2.0.3)
118
+ activesupport (>= 4.2.0)
119
+ nokogiri (>= 1.6)
120
+ rails-html-sanitizer (1.0.4)
121
+ loofah (~> 2.2, >= 2.2.2)
122
+ railties (5.2.2)
123
+ actionpack (= 5.2.2)
124
+ activesupport (= 5.2.2)
125
+ method_source
126
+ rake (>= 0.8.7)
127
+ thor (>= 0.19.0, < 2.0)
128
+ rake (12.3.2)
129
+ rspec (3.8.0)
130
+ rspec-core (~> 3.8.0)
131
+ rspec-expectations (~> 3.8.0)
132
+ rspec-mocks (~> 3.8.0)
133
+ rspec-core (3.8.0)
134
+ rspec-support (~> 3.8.0)
135
+ rspec-expectations (3.8.2)
136
+ diff-lcs (>= 1.2.0, < 2.0)
137
+ rspec-support (~> 3.8.0)
138
+ rspec-mocks (3.8.0)
139
+ diff-lcs (>= 1.2.0, < 2.0)
140
+ rspec-support (~> 3.8.0)
141
+ rspec-support (3.8.0)
142
+ sprockets (3.7.2)
143
+ concurrent-ruby (~> 1.0)
144
+ rack (> 1, < 3)
145
+ sprockets-rails (3.2.1)
146
+ actionpack (>= 4.0)
147
+ activesupport (>= 4.0)
148
+ sprockets (>= 3.0.0)
149
+ thor (0.20.3)
150
+ thread_safe (0.3.6)
151
+ tzinfo (1.2.5)
152
+ thread_safe (~> 0.1)
153
+ virtus (1.0.5)
154
+ axiom-types (~> 0.1)
155
+ coercible (~> 1.0)
156
+ descendants_tracker (~> 0.0, >= 0.0.3)
157
+ equalizer (~> 0.0, >= 0.0.9)
158
+ websocket-driver (0.7.0)
159
+ websocket-extensions (>= 0.1.0)
160
+ websocket-extensions (0.1.3)
161
+
162
+ PLATFORMS
163
+ ruby
164
+
165
+ DEPENDENCIES
166
+ fast_jsonapi
167
+ grape
168
+ grape_fast_jsonapi!
169
+ rails (>= 4.2.0)
170
+ rspec (~> 3.7)
171
+
172
+ BUNDLED WITH
173
+ 1.16.6
data/README.md CHANGED
@@ -8,14 +8,11 @@ Add the `grape` and `grape_fast_jsonapi` gems to Gemfile.
8
8
 
9
9
  ```ruby
10
10
  gem 'grape'
11
- # gem is not published to rubygems yet
12
- gem 'grape_fast_jsonapi', git: 'git@github.com:EmCousin/grape_fast_jsonapi.git'
11
+ gem 'grape_fast_jsonapi'
13
12
  ```
14
13
 
15
14
  ## Usage
16
15
 
17
- ### Require grape_fast_jsonapi
18
-
19
16
  ### Tell your API to use Grape::Formatter::FastJsonapi
20
17
 
21
18
  ```ruby
@@ -34,6 +31,33 @@ get "/" do
34
31
  end
35
32
  ```
36
33
 
34
+ ### Model parser for response documentation
35
+
36
+ When using Grape with Swagger via [grape-swagger](https://github.com/ruby-grape/grape-swagger), you can generate response documentation automatically via the provided following model parser:
37
+
38
+ ```ruby
39
+ # FastJsonapi serializer example
40
+ # app/serializers/user_serializer.rb
41
+ class UserSerializer
42
+ include FastJsonapi::ObjectSerializer
43
+
44
+ set_type :user
45
+ has_many :orders
46
+
47
+ attributes :name, :email
48
+ end
49
+
50
+ # config/initializers/grape_swagger.rb
51
+ GrapeSwagger.model_parsers.register(GrapeSwagger::FastJsonapi::Parser, UserSerializer)
52
+
53
+ # Your grape API endpoint
54
+ desc 'Get current user',
55
+ success: { code: 200, model: UserSerializer, message: 'The current user' }
56
+ # [...]
57
+ ```
58
+
59
+ Note that you **need** the `grape-swagger` gem for this to work, otherwise it will throw an error.
60
+
37
61
  ## Credit
38
62
 
39
63
  Code adapted from [grape-jsonapi-resources](https://github.com/cdunn/grape-jsonapi-resources)
@@ -19,10 +19,8 @@ Gem::Specification.new do |gem|
19
19
  gem.licenses = ['MIT']
20
20
 
21
21
  gem.add_dependency 'grape'
22
- gem.add_dependency 'fast_jsonapi'
22
+ gem.add_dependency 'fast_jsonapi', '>= 1.5'
23
23
 
24
- gem.add_development_dependency 'rails', '>= 5.0.0'
25
- gem.add_development_dependency 'rspec'
26
- gem.add_development_dependency 'rack-test'
27
- gem.add_development_dependency 'rake'
24
+ gem.add_development_dependency 'rails', '>= 4.2.0'
25
+ gem.add_development_dependency 'rspec', '~> 3.7'
28
26
  end
@@ -14,6 +14,8 @@ module Grape
14
14
  private
15
15
 
16
16
  def serializable?(object)
17
+ return false if object.nil?
18
+
17
19
  object.respond_to?(:serializable_hash) || object.respond_to?(:to_a) && object.all? { |o| o.respond_to? :serializable_hash } || object.is_a?(Hash)
18
20
  end
19
21
 
@@ -21,7 +23,7 @@ module Grape
21
23
  if object.respond_to? :serializable_hash
22
24
  serializable_object(object, fast_jsonapi_options(env)).serializable_hash
23
25
  elsif object.respond_to?(:to_a) && object.all? { |o| o.respond_to? :serializable_hash }
24
- fast_jsonapi_serializable(object, fast_jsonapi_options(env)).serializable_hash || object.map(&:serializable_hash)
26
+ serializable_collection(object, fast_jsonapi_options(env))
25
27
  elsif object.is_a?(Hash)
26
28
  serialize_each_pair(object, env)
27
29
  else
@@ -37,7 +39,18 @@ module Grape
37
39
  serializable_class(object)&.new(object, options)
38
40
  end
39
41
 
42
+ def serializable_collection(collection, options)
43
+ if collection.map(&:model_name).uniq.count > 1
44
+ collection.map do |o|
45
+ fast_jsonapi_serializable(o, options).serializable_hash || o.map(&:serializable_hash)
46
+ end
47
+ else
48
+ fast_jsonapi_serializable(collection, options).serializable_hash || collection.map(&:serializable_hash)
49
+ end
50
+ end
51
+
40
52
  def serializable_class(object)
53
+ object = object.first if object.is_a?(Array)
41
54
  (object.model_name.name + 'Serializer').safe_constantize
42
55
  end
43
56
 
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GrapeSwagger
4
+ module FastJsonapi
5
+ class Parser
6
+ attr_reader :model
7
+ attr_reader :endpoint
8
+
9
+ def initialize(model, endpoint)
10
+ @model = model
11
+ @endpoint = endpoint
12
+ end
13
+
14
+ def call
15
+ schema = default_schema
16
+
17
+ attributes_hash = if (defined? ActiveRecord)
18
+ map_active_record_columns_to_attributes
19
+ else
20
+ map_model_attributes
21
+ end
22
+
23
+ attributes_hash.each do |attribute, type|
24
+ schema[:data][:properties][:attributes][:properties][attribute] = { type: type }
25
+ schema[:data][:example][:attributes][attribute] = send "#{type}_example"
26
+ end
27
+
28
+ relationships_hash = model.relationships_to_serialize || []
29
+
30
+ relationships_hash.each do |model_type, relationship_data|
31
+ relationships_attributes = relationship_data.instance_values.symbolize_keys
32
+ schema[:data][:properties][:relationships][:properties][model_type] = {
33
+ type: :object,
34
+ properties: relationships_properties(relationships_attributes)
35
+ }
36
+ schema[:data][:example][:relationships][model_type] = relationships_example(relationships_attributes)
37
+ end
38
+
39
+ schema
40
+ end
41
+
42
+ private
43
+
44
+ def default_schema
45
+ {
46
+ data: {
47
+ type: :object,
48
+ properties: {
49
+ id: { type: :integer },
50
+ type: { type: :string },
51
+ attributes: default_schema_object,
52
+ relationships: default_schema_object
53
+ },
54
+ example: {
55
+ id: 1,
56
+ type: model.record_type,
57
+ attributes: {},
58
+ relationships: {}
59
+ }
60
+ }
61
+ }
62
+ end
63
+
64
+ def default_schema_object
65
+ { type: :object, properties: {} }
66
+ end
67
+
68
+ def map_active_record_columns_to_attributes
69
+ activerecord_model = model.record_type.to_s.camelize.safe_constantize
70
+ return map_model_attributes unless activerecord_model&.is_a?(ActiveRecord::Base)
71
+
72
+ columns = activerecord_model.columns.select do |c|
73
+ c.name.to_sym.in?(model.attributes_to_serialize.keys)
74
+ end
75
+
76
+ attributes = {}
77
+ columns.each do |column|
78
+ attributes[column.name] = column.type
79
+ end
80
+
81
+ attributes
82
+ end
83
+
84
+ def map_model_attributes
85
+ attributes = {}
86
+ model.attributes_to_serialize.each do |attribute, _|
87
+ attributes[attribute] = :string
88
+ end
89
+ attributes
90
+ end
91
+
92
+ def relationships_properties(relationship_data)
93
+ if relationship_data[:relationship_type] == :has_many
94
+ {
95
+ data: {
96
+ type: :array,
97
+ items: relationship_default_item
98
+ }
99
+ }
100
+ else
101
+ {
102
+ data: relationship_default_item
103
+ }
104
+ end
105
+ end
106
+
107
+ def relationship_default_item
108
+ {
109
+ type: :object,
110
+ properties: {
111
+ id: { type: :integer },
112
+ type: { type: :string }
113
+ }
114
+ }
115
+ end
116
+
117
+ def relationships_example(relationship_data)
118
+ data = { id: 1, type: relationship_data[:record_type] }
119
+ if relationship_data[:relationship_type] == :has_many
120
+ { data: [data] }
121
+ else
122
+ { data: data }
123
+ end
124
+ end
125
+
126
+ def integer_example
127
+ if defined? Faker
128
+ Faker::Number.number.to_i
129
+ else
130
+ rand(1..9999)
131
+ end
132
+ end
133
+
134
+ def string_example
135
+ if defined? Faker
136
+ Faker::Lorem.word
137
+ else
138
+ "Example string"
139
+ end
140
+ end
141
+
142
+ def text_example
143
+ if defined? Faker
144
+ Faker::Lorem.paragraph
145
+ else
146
+ "Example string"
147
+ end
148
+ end
149
+
150
+ def date_example
151
+ Date.today.to_s
152
+ end
153
+
154
+ def datetime_example
155
+ Time.current.to_s
156
+ end
157
+ alias :time_example :datetime_example
158
+
159
+ def object_example
160
+ if defined? Faker
161
+ {
162
+ string_example.parameterize.underscore.to_sym => string_example.parameterize.underscore.to_sym
163
+ }
164
+ else
165
+ { example: :object }
166
+ end
167
+ end
168
+
169
+ def array_example
170
+ [string_example]
171
+ end
172
+
173
+ def boolean_example
174
+ [true, false].sample
175
+ end
176
+ end
177
+ end
178
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Grape
4
4
  module FastJsonapi
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'.freeze
6
6
  end
7
7
  end
@@ -1,5 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
1
4
  require 'fast_jsonapi'
2
5
  require 'grape'
3
6
  require 'grape_fast_jsonapi/endpoint_extension'
4
7
  require 'grape_fast_jsonapi/formatter'
8
+ require 'grape_fast_jsonapi/parser'
5
9
  require 'grape_fast_jsonapi/version'
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Grape::Formatter::FastJsonapi do
4
+ describe 'class methods' do
5
+ let(:user) do
6
+ User.new(id: 1, first_name: 'Chuck', last_name: 'Norris', password: 'supersecretpassword', email: 'chuck@norris.com')
7
+ end
8
+ let(:another_user) do
9
+ User.new(id: 2, first_name: 'Bruce', last_name: 'Lee', password: 'supersecretpassword', email: 'bruce@lee.com')
10
+ end
11
+ let(:blog_post) do
12
+ BlogPost.new(id: 1, title: "Blog Post title", body: "Blog post body")
13
+ end
14
+
15
+ describe '.call' do
16
+ subject { described_class.call(object, env) }
17
+ let(:env) { {} }
18
+
19
+ context 'when the object is a string' do
20
+ let(:object) { "I am a string" }
21
+
22
+ it { is_expected.to eq object }
23
+ end
24
+
25
+ context 'when the object is serializable' do
26
+ let(:user_serializer) { UserSerializer.new(object, {}) }
27
+ let(:blog_post_serializer) { BlogPostSerializer.new(object, {}) }
28
+
29
+ context 'when the object is a active serializable model instance' do
30
+ let(:object) { user }
31
+
32
+ it { is_expected.to eq ::Grape::Json.dump(user_serializer.serializable_hash) }
33
+ end
34
+
35
+ context 'when the object is an array of active serializable model instances' do
36
+ let(:object) { [user, another_user] }
37
+
38
+ it { is_expected.to eq ::Grape::Json.dump(user_serializer.serializable_hash) }
39
+
40
+ context "when the array contains instances of different models" do
41
+ let(:object) { [user, blog_post] }
42
+
43
+ it 'returns an array of jsonapi serialialized objects' do
44
+ expect(subject).to eq(::Grape::Json.dump([
45
+ UserSerializer.new(user, {}).serializable_hash,
46
+ BlogPostSerializer.new(blog_post, {}).serializable_hash
47
+ ]))
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'when the object is a Hash of plain values' do
53
+ let(:object) { user.as_json }
54
+
55
+ it { is_expected.to eq ::Grape::Json.dump(object) }
56
+ end
57
+
58
+ context 'when the object is a Hash with serializable object values' do
59
+ let(:object) do
60
+ {
61
+ user: user,
62
+ blog_post: blog_post
63
+ }
64
+ end
65
+
66
+ it 'returns an hash of with jsonapi serialialized objects values' do
67
+ expect(subject).to eq(::Grape::Json.dump({
68
+ user: UserSerializer.new(user, {}).serializable_hash,
69
+ blog_post: BlogPostSerializer.new(blog_post, {}).serializable_hash
70
+ }))
71
+ end
72
+ end
73
+
74
+ context 'when the object is nil' do
75
+ let(:object) { nil }
76
+
77
+ it { is_expected.to eq 'null' }
78
+ end
79
+
80
+ context 'when the object is a number' do
81
+ let(:object) { 42 }
82
+
83
+ it { is_expected.to eq '42' }
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GrapeSwagger::FastJsonapi::Parser do
4
+ let(:model) { BlogPostSerializer }
5
+ let(:endpoint) { '/' }
6
+
7
+ describe 'attr_readers' do
8
+ subject { described_class.new(model, endpoint) }
9
+
10
+ it { expect(subject.model).to eq model }
11
+ it { expect(subject.endpoint).to eq endpoint }
12
+ end
13
+
14
+ describe 'instance methods' do
15
+ describe '#call' do
16
+ subject { described_class.new(model, endpoint).call }
17
+
18
+ it 'return a hash defining the schema' do
19
+ expect(subject).to eq({
20
+ data: {
21
+ type: :object,
22
+ properties: {
23
+ id: { type: :integer },
24
+ type: { type: :string },
25
+ attributes: {
26
+ type: :object,
27
+ properties: {
28
+ title: { type: :string },
29
+ body: { type: :string }
30
+ }
31
+ },
32
+ relationships: {
33
+ type: :object,
34
+ properties: {
35
+ user: {
36
+ type: :object,
37
+ properties: {
38
+ data: {
39
+ type: :object,
40
+ properties: {
41
+ id: { type: :integer },
42
+ type: { type: :string }
43
+ }
44
+ }
45
+ }
46
+ }
47
+ }
48
+ }
49
+ },
50
+ example: {
51
+ id: 1,
52
+ type: :blog_post,
53
+ attributes: {
54
+ title: "Example string",
55
+ body: "Example string",
56
+ },
57
+ relationships: {
58
+ user: {
59
+ data: {
60
+ id: 1,
61
+ type: :user
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
67
+ })
68
+ end
69
+
70
+ context 'when the serializer contains sensitive information' do
71
+ let(:model) { UserSerializer } # contains :password attribute
72
+
73
+ it 'return a hash defining the schema filtering the sensitive attributes' do
74
+ expect(subject).to eq({
75
+ data: {
76
+ type: :object,
77
+ properties: {
78
+ id: { type: :integer },
79
+ type: { type: :string },
80
+ attributes: {
81
+ type: :object,
82
+ properties: {
83
+ first_name: { type: :string },
84
+ last_name: { type: :string },
85
+ email: { type: :string },
86
+ # password: { type: :string }, FILTERED
87
+ }
88
+ },
89
+ relationships: {
90
+ type: :object,
91
+ properties: {
92
+ blog_posts: {
93
+ type: :object,
94
+ properties: {
95
+ data: {
96
+ type: :array,
97
+ items: {
98
+ type: :object,
99
+ properties: {
100
+ id: { type: :integer },
101
+ type: { type: :string }
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
109
+ },
110
+ example: {
111
+ id: 1,
112
+ type: :user,
113
+ attributes: {
114
+ first_name: "Example string",
115
+ last_name: "Example string",
116
+ email: "Example string",
117
+ # password: "Example string", FILTERED
118
+ },
119
+ relationships: {
120
+ blog_posts: {
121
+ data: [{ id: 1, type: :blog_post }]
122
+ }
123
+ }
124
+ }
125
+ }
126
+ })
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Grape::FastJsonapi::VERSION do
4
+ it { is_expected.to eq '0.2.0' }
5
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model'
4
+ require 'grape_fast_jsonapi'
5
+
6
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BlogPost
4
+ extend ActiveModel::Naming
5
+ include ActiveModel::Serialization
6
+
7
+ attr_accessor :id, :title, :body
8
+
9
+ def initialize(params = {})
10
+ params.each do |k, v|
11
+ instance_variable_set("@#{k}", v) unless v.nil?
12
+ end
13
+ end
14
+
15
+ def user_id
16
+ nil
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class User
4
+ extend ActiveModel::Naming
5
+ include ActiveModel::Serialization
6
+
7
+ attr_accessor :id, :first_name, :last_name, :password, :email
8
+
9
+ def initialize(params = {})
10
+ params.each do |k, v|
11
+ instance_variable_set("@#{k}", v) unless v.nil?
12
+ end
13
+ end
14
+
15
+ def attributes
16
+ {
17
+ 'id' => nil,
18
+ 'first_name' => nil,
19
+ 'last_name' => nil,
20
+ 'password' => nil,
21
+ 'email' => nil
22
+ }
23
+ end
24
+
25
+ def blog_post_ids
26
+ []
27
+ end
28
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BlogPostSerializer
4
+ include FastJsonapi::ObjectSerializer
5
+
6
+ belongs_to :user
7
+
8
+ attributes :title, :body
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UserSerializer
4
+ include FastJsonapi::ObjectSerializer
5
+
6
+ has_many :blog_posts
7
+
8
+ attributes :first_name, :last_name, :email
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape_fast_jsonapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emmanuel Cousin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-06 00:00:00.000000000 Z
11
+ date: 2019-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grape
@@ -30,70 +30,42 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '1.5'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '1.5'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rails
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 5.0.0
47
+ version: 4.2.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 5.0.0
54
+ version: 4.2.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rack-test
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
59
+ - - "~>"
88
60
  - !ruby/object:Gem::Version
89
- version: '0'
61
+ version: '3.7'
90
62
  type: :development
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
- - - ">="
66
+ - - "~>"
95
67
  - !ruby/object:Gem::Version
96
- version: '0'
68
+ version: '3.7'
97
69
  description: Provides a Formatter for the Grape API DSL to emit objects serialized
98
70
  with fast_jsonapi.
99
71
  email:
@@ -102,7 +74,11 @@ executables: []
102
74
  extensions: []
103
75
  extra_rdoc_files: []
104
76
  files:
77
+ - ".circleci/config.yml"
78
+ - ".rspec"
79
+ - CHANGELOG.md
105
80
  - Gemfile
81
+ - Gemfile.lock
106
82
  - LICENSE
107
83
  - README.md
108
84
  - Rakefile
@@ -110,7 +86,16 @@ files:
110
86
  - lib/grape_fast_jsonapi.rb
111
87
  - lib/grape_fast_jsonapi/endpoint_extension.rb
112
88
  - lib/grape_fast_jsonapi/formatter.rb
89
+ - lib/grape_fast_jsonapi/parser.rb
113
90
  - lib/grape_fast_jsonapi/version.rb
91
+ - spec/lib/grape_fast_jsonapi/formatter_spec.rb
92
+ - spec/lib/grape_fast_jsonapi/parser_spec.rb
93
+ - spec/lib/grape_fast_jsonapi/version_spec.rb
94
+ - spec/spec_helper.rb
95
+ - spec/support/models/blog_post.rb
96
+ - spec/support/models/user.rb
97
+ - spec/support/serializers/blog_post_serializer.rb
98
+ - spec/support/serializers/user_serializer.rb
114
99
  homepage: https://github.com/EmCousin/grape_fast_jsonapi
115
100
  licenses:
116
101
  - MIT
@@ -130,9 +115,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
115
  - !ruby/object:Gem::Version
131
116
  version: '0'
132
117
  requirements: []
133
- rubyforge_project:
134
- rubygems_version: 2.5.2
118
+ rubygems_version: 3.0.1
135
119
  signing_key:
136
120
  specification_version: 4
137
121
  summary: Use fast_jsonapi in grape
138
- test_files: []
122
+ test_files:
123
+ - spec/lib/grape_fast_jsonapi/formatter_spec.rb
124
+ - spec/lib/grape_fast_jsonapi/parser_spec.rb
125
+ - spec/lib/grape_fast_jsonapi/version_spec.rb
126
+ - spec/spec_helper.rb
127
+ - spec/support/models/blog_post.rb
128
+ - spec/support/models/user.rb
129
+ - spec/support/serializers/blog_post_serializer.rb
130
+ - spec/support/serializers/user_serializer.rb