graphiti_scaffold_generator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []