graphiti_scaffold_generator 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e8d0c144c7d84bee66406b31d5e2922c83ad4f9cbc4196360d3cf206ea8cade5
4
+ data.tar.gz: bc589e4db463e07ffbb4f6f22823e2f630d901e56999a390aee8ba7306b84982
5
+ SHA512:
6
+ metadata.gz: 4a8790f79b7c7c0d4fae2a96412e32d72148c11303b52a338be98d7b49227b393ba085158fce28f91a9747ec5493d2a594a1c2f451b0716ec2e3529e518dc5e3
7
+ data.tar.gz: 3154e7591493660c86586a81ca4d40337ae82234f2c80ec6f2eb27218a2eac7bcacf03b8469b5f7e90ca41182b2cb825c0ef3373b50cd8cc1e30b6b4acadf795
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in graphiti_scaffold_generator.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rspec", "~> 3.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,34 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ graphiti_scaffold_generator (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.5.0)
10
+ rake (13.1.0)
11
+ rspec (3.12.0)
12
+ rspec-core (~> 3.12.0)
13
+ rspec-expectations (~> 3.12.0)
14
+ rspec-mocks (~> 3.12.0)
15
+ rspec-core (3.12.2)
16
+ rspec-support (~> 3.12.0)
17
+ rspec-expectations (3.12.3)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.12.0)
20
+ rspec-mocks (3.12.6)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.12.0)
23
+ rspec-support (3.12.1)
24
+
25
+ PLATFORMS
26
+ x86_64-linux
27
+
28
+ DEPENDENCIES
29
+ graphiti_scaffold_generator!
30
+ rake (~> 13.0)
31
+ rspec (~> 3.0)
32
+
33
+ BUNDLED WITH
34
+ 2.3.9
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Dmitry Kulikov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # GraphitiScaffoldGenerator
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/graphiti_scaffold_generator`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Install the gem and add to the application's Gemfile by executing:
10
+
11
+ $ bundle add graphiti_scaffold_generator
12
+
13
+ If bundler is not being used to manage dependencies, install the gem by executing:
14
+
15
+ $ gem install graphiti_scaffold_generator
16
+
17
+ ## Usage
18
+
19
+ TODO: Write usage instructions here
20
+
21
+ ## Development
22
+
23
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
24
+
25
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
26
+
27
+ ## Contributing
28
+
29
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dima4p/graphiti_scaffold_generator.
30
+
31
+ ## License
32
+
33
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/graphiti_scaffold_generator/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "graphiti_scaffold_generator"
7
+ spec.version = GraphitiScaffoldGenerator::VERSION
8
+ spec.authors = ["Dmitry Kulikov"]
9
+ spec.email = ["dima@koulikoff.ru"]
10
+
11
+ spec.summary = "When gem 'graphiti' is in use generates code for app/resources and /spec/resources for scaffold"
12
+ spec.description = <<-DESCRIPTION
13
+ The graphiti gem has no support for scaffold generator.
14
+ This gem fiexes the problem. When you generate scaffold for a model
15
+ you'll get the correct controller, specs for the request and, of course,
16
+ the code for /app/resources and /spec/resources
17
+ DESCRIPTION
18
+ spec.homepage = "https://github.com/dima4p/graphiti_scaffold_generator"
19
+ spec.license = "MIT"
20
+ spec.required_ruby_version = ">= 2.6.0"
21
+
22
+ #spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
23
+
24
+ spec.metadata["homepage_uri"] = spec.homepage
25
+ #spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
26
+ #spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
27
+
28
+ # Specify which files should be added to the gem when it is released.
29
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
30
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
31
+ `git ls-files -z`.split("\x0").reject do |f|
32
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
33
+ end
34
+ end
35
+ spec.bindir = "exe"
36
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
37
+ spec.require_paths = ["lib"]
38
+
39
+ # Uncomment to register a new dependency of your gem
40
+ # spec.add_dependency "example-gem", "~> 1.0"
41
+
42
+ # For more information and examples about making a new gem, check out our
43
+ # guide at: https://bundler.io/guides/creating_gem.html
44
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rspec
4
+ class ResourceGenerator < ::Rails::Generators::NamedBase
5
+ argument :attributes, type: :array, default: [], banner: "field:type field:type"
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ def create_resource_spec
9
+ template "resource_spec.rb", File.join("spec/resources", class_path, "#{file_name}_resource_spec.rb")
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,122 @@
1
+ <%
2
+ primary_key_type = Rails.application.config.generators
3
+ .options[:active_record][:primary_key_type]
4
+ belongs_to = []
5
+ id_attr = []; id_attr << ['id', primary_key_type.inspect] if primary_key_type
6
+ all_attributes = attributes.map do |attribute|
7
+ name = attribute.name
8
+ type = attribute.type
9
+ unless Graphiti::Types.map.keys.include? type
10
+ type = case type
11
+ when :belongs_to, :references
12
+ belongs_to << name
13
+ type = name.camelcase.constantize.columns_hash["id"].type rescue nil
14
+ type ||= primary_key_type || :integer
15
+ name += '_id'
16
+ type
17
+ when :text
18
+ type = :string
19
+ end
20
+ end
21
+ [name, type.inspect]
22
+ end
23
+ all_attributes = id_attr + all_attributes
24
+ -%>
25
+
26
+ <% if File.exist?(File.join %w[spec rails_helper.rb]) -%>
27
+ require 'rails_helper'
28
+ <% else -%>
29
+ require 'spec_helper'
30
+ <% end -%>
31
+
32
+ describe '<%= class_name %>Resource', type: :resource do
33
+ subject(:config) { <%= class_name %>Resource.config }
34
+
35
+ describe 'attributes' do
36
+ subject(:attributes) { config[:attributes] }
37
+
38
+ it 'equal to [<%= all_attributes.map{|a| ":#{a.first}"}.join ", " %>]' do
39
+ expect(attributes.keys)
40
+ .to eq %i[
41
+ <%= all_attributes.map(&:first).join "\n " %>
42
+ ]
43
+ end
44
+ <% all_attributes.each do |name, type| -%>
45
+
46
+ describe ':<%= name %>' do
47
+ subject(:attr_<%= name %>) { attributes[:<%= name %>] }
48
+
49
+ it 'has type <%= type %>' do
50
+ expect(attr_<%= name %>[:type]).to be <%= type %>
51
+ end
52
+
53
+ it 'is <%= name == 'id' ? '' : 'not ' %>filterable' do
54
+ expect(attr_<%= name %>[:filterable]).to be <%= name == 'id' %>
55
+ end
56
+
57
+ it 'is readable' do
58
+ expect(attr_<%= name %>[:readable]).to be true
59
+ end
60
+
61
+ it 'is not writable' do
62
+ expect(attr_<%= name %>[:writable]).to be false
63
+ end
64
+
65
+ it 'is not sortable' do
66
+ expect(attr_<%= name %>[:sortable]).to be false
67
+ end
68
+ end
69
+ <% end -%>
70
+ end
71
+
72
+ describe 'relation' do
73
+ subject(:relations) do
74
+ config[:sideloads].each_with_object({}) do |(name, sideload), hash|
75
+ hash[sideload.type] ||= []
76
+ hash[sideload.type] << sideload.name
77
+ end
78
+ end
79
+
80
+ describe '::belongs_to' do
81
+ subject(:list) { relations[:belongs_to] }
82
+
83
+ <% if belongs_to.blank? -%>
84
+ it 'does not exist' do
85
+ is_expected.to be_blank
86
+ end
87
+ <% else -%>
88
+ <% belongs_to.each_with_index do |name, n| -%>
89
+ <% if n > 0 -%>
90
+
91
+ <% end -%>
92
+ it 'is defined for :<%= name %>' do
93
+ expect(list).to include :<%= name %>
94
+ end
95
+ <% end -%>
96
+ <% end -%>
97
+ end
98
+ <%
99
+ %w[
100
+ has_many
101
+ has_one
102
+ many_to_many
103
+ polymorphic_belongs_to
104
+ polymorphic_has_many
105
+ ].each do |relation_name|
106
+ -%>
107
+
108
+ describe '::<%= relation_name %>' do
109
+ subject(:list) { relations[:<%= relation_name %>] }
110
+
111
+ it 'does not exist' do
112
+ is_expected.to be_blank
113
+ end
114
+
115
+ it 'is defined for :the_name_of_the_relation' do
116
+ skip 'edit this Spec and add more if required or remove it completely'
117
+ expect(list).to include :the_name_of_the_relation
118
+ end
119
+ end
120
+ <% end -%>
121
+ end
122
+ end
@@ -0,0 +1,14 @@
1
+ module ResourceGenerator
2
+ module Generators
3
+ class GraphitiScaffoldGenerator < Rails::Generators::NamedBase
4
+ source_root File.expand_path('../templates', __FILE__)
5
+ puts "ResourceGenerator::Generators::GraphitiScaffoldGenerator"
6
+
7
+ def create_resource
8
+ template "resource.rb", File.join("app/resources", class_path, "#{file_name}_resource.rb")
9
+ end
10
+
11
+ hook_for :test_framework, as: :resource
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ module GraphitiResourceGenerator
2
+ module Generators
3
+ class ScaffoldControllerGenerator < Rails::Generators::NamedBase
4
+ argument :attributes, type: :array, default: [], banner: "field:type field:type"
5
+
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ def create_resource
9
+ template "resource.rb", File.join("app/resources", class_path, "#{file_name}_resource.rb")
10
+ end
11
+
12
+ hook_for :test_framework, as: :resource
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ <% primary_key_type = Rails.application.config.generators.options[:active_record][:primary_key_type] -%>
2
+ <% belongs_to = [] -%>
3
+ class <%= class_name %>Resource < ApplicationResource
4
+ <% if primary_key_type -%>
5
+ attribute :id, :<%= primary_key_type %>, readable: true, writable: false, filterable: true
6
+
7
+ <% end -%>
8
+ <%
9
+ attributes.each do |attribute|
10
+ name = attribute.name
11
+ type = attribute.type
12
+ unless Graphiti::Types.map.keys.include? type
13
+ type = case type
14
+ when :belongs_to, :references
15
+ belongs_to << name
16
+ type = name.camelcase.constantize.columns_hash["id"].type rescue nil
17
+ type ||= primary_key_type || :integer
18
+ name += '_id'
19
+ type
20
+ when :text
21
+ type = :string
22
+ end
23
+ end
24
+ -%>
25
+ attribute :<%= name %>, :<%= type %>, readable: true, writable: false
26
+ <% end -%>
27
+ <% if belongs_to.present? -%>
28
+
29
+ <% belongs_to.each do |name| -%>
30
+ belongs_to :<%= name %>
31
+ <% end -%>
32
+ <% end -%>
33
+ end
@@ -0,0 +1,23 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
3
+
4
+ module Rails
5
+ module Generators
6
+ class ScaffoldControllerGenerator < NamedBase
7
+ source_paths.unshift File.expand_path('../templates', __FILE__)
8
+
9
+ class_option :graphiti_resource_generator,
10
+ desc: 'Generates the graphiti resource',
11
+ default: 'graphiti_resource_generator'
12
+ hook_for :graphiti_resource_generator, required: true
13
+ end
14
+ end
15
+ end
16
+
17
+ module Rspec
18
+ module Generators
19
+ class ScaffoldGenerator < Base
20
+ source_paths.unshift File.expand_path('../templates', __FILE__)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,70 @@
1
+ <% resource = class_name + 'Resource' -%>
2
+ <% pundit = defined?(Pundit) -%>
3
+ # resource = <%= resource %>
4
+ # pundit = <%= pundit %>
5
+ <% module_namespacing do -%>
6
+ class <%= controller_class_name %>Controller < ApplicationController
7
+ before_action :set_<%= pundit ? 'and_authorise_' : '' %><%= singular_table_name %>, only: %i[ show update destroy ]
8
+
9
+ # GET <%= route_url %>
10
+ def index
11
+ authorize <%= class_name %>
12
+ respond_with <%= resource %>.all(params)
13
+ end
14
+
15
+ # GET <%= route_url %>/1
16
+ def show
17
+ respond_with @<%= singular_table_name %>
18
+ end
19
+
20
+ # POST <%= route_url %>
21
+ def create
22
+ @<%= singular_table_name %> = <%= resource %>.build params
23
+ <% if pundit -%>
24
+ authorize <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
25
+ <% end -%>
26
+
27
+ if @<%= singular_table_name %>.save
28
+ render jsonapi: <%= singular_table_name %>, status: :created
29
+ else
30
+ render jsonapi_errors: <%= singular_table_name %>
31
+ end
32
+ end
33
+
34
+ # PATCH/PUT <%= route_url %>/1
35
+ def update
36
+ if @<%= singular_table_name %>.update_attributes
37
+ render jsonapi: <%= singular_table_name %>
38
+ else
39
+ render jsonapi_errors: <%= singular_table_name %>
40
+ end
41
+ end
42
+
43
+ # DELETE <%= route_url %>/1
44
+ def destroy
45
+ @<%= orm_instance.destroy %>
46
+ end
47
+
48
+ private
49
+
50
+ # Use callbacks to share common setup or constraints between actions.
51
+ def set_<%= pundit ? 'and_authorise_' : '' %><%= singular_table_name %>
52
+ @<%= singular_table_name %> = <%= resource %>.find(params)
53
+ <% if pundit -%>
54
+ authorize @<%= singular_table_name %>
55
+ <% end -%>
56
+ end
57
+
58
+ # Never trust parameters from the scary internet, only allow the white list through.
59
+ def <%= "#{singular_table_name}_params" %>
60
+ <%- if attributes_names.empty? -%>
61
+ params.fetch(:<%= singular_table_name %>, {})
62
+ <%- else -%>
63
+ list = %i[
64
+ <%= attributes_names.join(' ') %>
65
+ ]
66
+ params.require(:<%= singular_table_name %>).permit(*list)
67
+ <%- end -%>
68
+ end
69
+ end
70
+ <% end -%>
@@ -0,0 +1,233 @@
1
+ <% pundit = defined? Pundit -%>
2
+ <% fbot = defined? FactoryBot -%>
3
+ <% if File.exist?(File.join %w[spec rails_helper.rb]) -%>
4
+ require 'rails_helper'
5
+ <% else -%>
6
+ require 'spec_helper'
7
+ <% end -%>
8
+
9
+ <% module_namespacing do -%>
10
+ describe "Request /<%= name.underscore.pluralize %>", <%= type_metatag(:request) %> do
11
+ <% if fbot -%>
12
+ let(:<%= file_name %>) { create :<%= file_name %> }
13
+ <% if pundit -%>
14
+ let(:user) { create :user }
15
+ <% end -%>
16
+ <% else -%>
17
+ let(:<%= file_name %>) { <%= class_name %>.create! valid_attributes }
18
+ <% end -%>
19
+
20
+ # This should return the minimal set of attributes required to create a valid
21
+ # <%= class_name %>. As you add validations to <%= class_name %>, be sure to
22
+ # adjust the attributes here as well.
23
+ <% attributes.map{|a| [a.name, a.type]} -%>
24
+ <% if fbot -%>
25
+ <% links = attributes.select{|a| [:belongs_to, :references].include? a.type} -%>
26
+ <% attribute = (attributes - links).detect{|a| a.name == 'name' || a.name == 'title' || a.name == 'code' || a.name =~ /name/ || a.name =~ /title/} || attributes.detect{|a| %i[string text].include? a.type} || attributes.last -%>
27
+ <% attribute_name = attribute.respond_to?(:column_name) ? attribute.column_name : attribute.name -%>
28
+ <% if links.present? -%>
29
+ let(:valid_attributes) do
30
+ attributes_for(:<%=file_name%>)
31
+ .slice(*%i[<%= attribute_name %>])
32
+ .merge(
33
+ <% links.each do |relation| -%>
34
+ <%= relation.name %>_id: create(:<%= relation.name %>).id,
35
+ <% end -%>
36
+ )
37
+ end
38
+ <% else -%>
39
+ let(:valid_attributes) {attributes_for(:<%=file_name%>).slice *%i[<%= attribute_name %>]}
40
+ <% end -%>
41
+ <% else -%>
42
+ let(:valid_attributes) {
43
+ skip("Add a hash of attributes valid for your model")
44
+ }
45
+ <% end -%>
46
+
47
+ let(:invalid_attributes) do
48
+ skip("Add a hash of attributes invalid for your model")
49
+ { <%= attribute_name %>: '' }
50
+ end
51
+
52
+ # This should return the minimal set of values that should be in the headers
53
+ # in order to pass any filters (e.g. authentication) defined in
54
+ # <%= controller_class_name %>Controller, or in your router and rack
55
+ # middleware. Be sure to keep this updated too.
56
+ let(:valid_headers) {
57
+ {}
58
+ }
59
+
60
+ <% unless options[:singleton] -%>
61
+ describe 'GET /index' do
62
+ it "renders a successful response" do
63
+ <%= class_name %>.create! valid_attributes
64
+ get <%= index_helper %>_url, headers: valid_headers, as: :json
65
+ expect(response).to be_successful
66
+ end
67
+ end
68
+ <% end -%>
69
+
70
+ describe 'GET /show' do
71
+ subject(:get_show) { get <%= show_helper %> }
72
+
73
+ it "renders a successful response" do
74
+ get_show
75
+ expect(response).to be_successful
76
+ end
77
+ end
78
+
79
+ describe 'POST /create' do
80
+ subject(:post_create) do
81
+ post <%= index_helper %>_url,
82
+ params: { data: data },
83
+ headers: valid_headers,
84
+ as: :json
85
+ end
86
+ let(:data) do
87
+ {
88
+ type: '<%= table_name %>',
89
+ attributes: attributes,
90
+ }
91
+ end
92
+ let(:attributes) { valid_attributes }
93
+
94
+ context 'with valid parameters' do
95
+ it "creates a new <%= class_name %>" do
96
+ expect { post_create }.to change(<%= class_name %>, :count).by(1)
97
+ end
98
+
99
+ it 'returns :created' do
100
+ post_create
101
+ expect(response).to have_http_status(:created)
102
+ end
103
+
104
+ it 'renders content_type "application/vnd.api+json; charset=utf-8"' do
105
+ post_create
106
+ expect(response.content_type).to eq("application/vnd.api+json; charset=utf-8")
107
+ end
108
+
109
+ it "renders a JSON response with the new <%= file_name %>" do
110
+ post_create
111
+ expect(JSON.parse(response.body)['data']['id'])
112
+ .to eq <%= class_name %>.order(:created_at).last.id
113
+ end
114
+ end
115
+
116
+ context 'with invalid parameters' do
117
+ let(:attributes) { invalid_attributes }
118
+
119
+ it "does not create a new <%= class_name %>" do
120
+ expect { post_create }.not_to change <%= class_name %>, :count
121
+ end
122
+
123
+ it 'returns :unprocessable_entity' do
124
+ post_create
125
+ expect(response).to have_http_status(:unprocessable_entity)
126
+ end
127
+
128
+ it 'renders content_type "application/vnd.api+json; charset=utf-8"' do
129
+ post_create
130
+ expect(response.content_type).to eq("application/vnd.api+json; charset=utf-8")
131
+ end
132
+
133
+ it 'renders a JSON response with errors for the new <%= file_name %>' do
134
+ post_create
135
+ expect(JSON.parse(response.body).dig 'errors', 0, 'meta', 'attribute')
136
+ .to be_present
137
+ end
138
+ end
139
+ end
140
+
141
+ describe 'PATCH /update' do
142
+ subject(:patch_update) do
143
+ patch <%= file_name %>_url(<%= file_name %>),
144
+ params: { data: data },
145
+ headers: valid_headers,
146
+ as: :json
147
+ end
148
+ let(:data) do
149
+ {
150
+ id: <%= file_name %>.id.to_s,
151
+ type: '<%= file_name %>s',
152
+ attributes: new_attributes,
153
+ }
154
+ end
155
+ let(:new_attributes) {
156
+ skip("Add a hash of attributes valid for <%= class_name %>")
157
+ { <%= attribute_name %>: 'New <%= attribute_name %>' }
158
+ }
159
+
160
+ context "with valid parameters" do
161
+ it "updates the requested <%= file_name %>" do
162
+ patch_update
163
+ <%= file_name %>.reload
164
+ skip("Add assertions for updated state")
165
+ <%= file_name %>.<%= attribute_name %> == 'New <%= attribute_name %>'
166
+ end
167
+
168
+ it 'returns :ok' do
169
+ patch_update
170
+ expect(response).to have_http_status :ok
171
+ end
172
+
173
+ it 'renders content_type "application/vnd.api+json; charset=utf-8"' do
174
+ patch_update
175
+ expect(response.content_type).to eq("application/vnd.api+json; charset=utf-8")
176
+ end
177
+
178
+ it "renders a JSON response with the <%= file_name %>" do
179
+ patch_update
180
+ expect(JSON.parse(response.body)['data']['id']).to eq <%= file_name %>.id
181
+ end
182
+ end
183
+
184
+ context "with invalid parameters" do
185
+ let(:new_attributes) { invalid_attributes }
186
+
187
+ it "does not update the requested <%= file_name %>" do
188
+ expect { patch_update }.not_to change <%= file_name %>, :reload
189
+ end
190
+
191
+ it 'returns :unprocessable_entity' do
192
+ patch_update
193
+ expect(response).to have_http_status(:unprocessable_entity)
194
+ end
195
+
196
+ it 'renders content_type "application/vnd.api+json; charset=utf-8"' do
197
+ patch_update
198
+ expect(response.content_type).to eq("application/vnd.api+json; charset=utf-8")
199
+ end
200
+
201
+ it "renders a JSON response with errors for the new <%= file_name %>" do
202
+ patch_update
203
+ expect(JSON.parse(response.body).dig 'errors', 0, 'meta', 'attribute')
204
+ .to be_present
205
+ end
206
+ end
207
+ end
208
+
209
+ describe "DELETE /destroy" do
210
+ subject(:delete_destroy) do
211
+ delete <%= file_name %>_url(id: <%= file_name %>.to_param)
212
+ end
213
+
214
+ before do
215
+ <%= file_name %> # we need something to destroy
216
+ end
217
+
218
+ it "destroys the requested <%= file_name %>" do
219
+ expect { delete_destroy }.to change(<%= class_name %>, :count).by -1
220
+ end
221
+
222
+ it 'returns :no_content' do
223
+ delete_destroy
224
+ expect(response).to have_http_status(:no_content)
225
+ end
226
+
227
+ it "renders empty response" do
228
+ delete_destroy
229
+ expect(response.body).to be_empty
230
+ end
231
+ end
232
+ end
233
+ <% end -%>
@@ -0,0 +1,11 @@
1
+ require 'rails/railtie'
2
+
3
+ module GraphitiScaffoldGenerator
4
+ class Railtie < ::Rails::Railtie
5
+ generators do |app|
6
+ Rails::Generators.configure! app.config.generators
7
+ Rails::Generators.hidden_namespaces.uniq!
8
+ require 'graphiti_scaffold_generator/generators/rails/scaffold_controller_generator'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphitiScaffoldGenerator
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "graphiti_scaffold_generator/version"
4
+ require 'graphiti_scaffold_generator/railtie'
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: graphiti_scaffold_generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Dmitry Kulikov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-11-21 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: |
14
+ The graphiti gem has no support for scaffold generator.
15
+ This gem fiexes the problem. When you generate scaffold for a model
16
+ you'll get the correct controller, specs for the request and, of course,
17
+ the code for /app/resources and /spec/resources
18
+ email:
19
+ - dima@koulikoff.ru
20
+ executables: []
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - ".rspec"
25
+ - Gemfile
26
+ - Gemfile.lock
27
+ - LICENSE.txt
28
+ - README.md
29
+ - Rakefile
30
+ - graphiti_scaffold_generator.gemspec
31
+ - lib/generators/graphiti_resource_generator/rspec/rspec_generator.rb
32
+ - lib/generators/graphiti_resource_generator/rspec/templates/resource_spec.rb
33
+ - lib/generators/graphiti_resource_generator/scaffold_controller_generator.rb
34
+ - lib/generators/graphiti_resource_generator/scaffold_controller_generator/scaffold_controller.rb
35
+ - lib/generators/graphiti_resource_generator/templates/resource.rb
36
+ - lib/graphiti_scaffold_generator.rb
37
+ - lib/graphiti_scaffold_generator/generators/rails/scaffold_controller_generator.rb
38
+ - lib/graphiti_scaffold_generator/generators/rails/templates/api_controller.rb
39
+ - lib/graphiti_scaffold_generator/generators/rails/templates/api_request_spec.rb
40
+ - lib/graphiti_scaffold_generator/railtie.rb
41
+ - lib/graphiti_scaffold_generator/version.rb
42
+ homepage: https://github.com/dima4p/graphiti_scaffold_generator
43
+ licenses:
44
+ - MIT
45
+ metadata:
46
+ homepage_uri: https://github.com/dima4p/graphiti_scaffold_generator
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 2.6.0
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubygems_version: 3.1.4
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: When gem 'graphiti' is in use generates code for app/resources and /spec/resources
66
+ for scaffold
67
+ test_files: []