souls 0.18.2 → 0.20.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,56 @@
1
+ module Souls
2
+ module Generate
3
+ class << self
4
+ ## Generate Query / Queries
5
+ def create_queries class_name: "souls"
6
+ file_path = "./app/graphql/queries/#{class_name.pluralize}.rb"
7
+ File.open(file_path, "w") do |f|
8
+ f.write <<~EOS
9
+ module Queries
10
+ class #{class_name.camelize.pluralize} < Queries::BaseQuery
11
+ type [Types::#{class_name.camelize}Type], null: false
12
+
13
+ def resolve
14
+ ::#{class_name.camelize}.all
15
+ rescue StandardError => error
16
+ GraphQL::ExecutionError.new error
17
+ end
18
+ end
19
+ end
20
+ EOS
21
+ end
22
+ file_path
23
+ end
24
+
25
+ def create_query class_name: "souls"
26
+ file_path = "./app/graphql/queries/#{class_name}.rb"
27
+ File.open(file_path, "w") do |f|
28
+ f.write <<~EOS
29
+ module Queries
30
+ class #{class_name.camelize} < Queries::BaseQuery
31
+ type Types::#{class_name.camelize}Type, null: false
32
+ argument :id, String, required: true
33
+
34
+ def resolve **args
35
+ _, data_id = SoulsApiSchema.from_global_id args[:id]
36
+ ::#{class_name.camelize}.find(data_id)
37
+ rescue StandardError => error
38
+ GraphQL::ExecutionError.new error
39
+ end
40
+ end
41
+ end
42
+ EOS
43
+ file_path
44
+ end
45
+ end
46
+
47
+ def query class_name: "souls"
48
+ singularized_class_name = class_name.singularize
49
+ [
50
+ create_query(class_name: singularized_class_name),
51
+ create_queries(class_name: singularized_class_name)
52
+ ]
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,153 @@
1
+ module Souls
2
+ module Generate
3
+ class << self
4
+ ## Generate Resolver
5
+ def resolver_head class_name: "souls"
6
+ FileUtils.mkdir_p "./app/graphql/resolvers" unless Dir.exist? "./app/graphql/resolvers"
7
+ file_path = "./app/graphql/resolvers/#{class_name.singularize}_search.rb"
8
+ @relation_params = []
9
+ return ["Resolver already exist! #{file_path}"] if File.exist? file_path
10
+ File.open(file_path, "w") do |f|
11
+ f.write <<~EOS
12
+ module Resolvers
13
+ class #{class_name.camelize}Search < Base
14
+ include SearchObject.module(:graphql)
15
+ scope { ::#{class_name.camelize}.all }
16
+ type Types::#{class_name.camelize}Type.connection_type, null: false
17
+ description "Search #{class_name.camelize}"
18
+
19
+ class #{class_name.camelize}Filter < ::Types::BaseInputObject
20
+ argument :OR, [self], required: false
21
+ EOS
22
+ end
23
+ end
24
+
25
+ def resolver_params class_name: "souls"
26
+ file_path = "./app/graphql/resolvers/#{class_name.singularize}_search.rb"
27
+ path = "./db/schema.rb"
28
+ @on = false
29
+ @user_exist = false
30
+ @relation_params = []
31
+ File.open(file_path, "a") do |new_line|
32
+ File.open(path, "r") do |f|
33
+ f.each_line.with_index do |line, i|
34
+ if @on
35
+ if line.include?("end") || line.include?("t.index")
36
+ break
37
+ end
38
+ field = "[String]" if line.include?("array: true")
39
+ type, name = get_type_and_name(line)
40
+ field ||= type_check type
41
+ case name
42
+ when "user_id"
43
+ @user_exist = true
44
+ when /$*_id\z/
45
+ @relation_params << name
46
+ new_line.write " argument :#{name}, String, required: false\n"
47
+ when "created_at", "updated_at"
48
+ next
49
+ else
50
+ new_line.write " argument :#{name}, #{field}, required: false\n"
51
+ end
52
+ end
53
+ @on = true if table_check(line: line, class_name: class_name)
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ def resolver_after_params class_name: "souls"
60
+ file_path = "./app/graphql/resolvers/#{class_name.singularize}_search.rb"
61
+ File.open(file_path, "a") do |f|
62
+ f.write <<-EOS
63
+ argument :start_date, String, required: false
64
+ argument :end_date, String, required: false
65
+ end
66
+
67
+ option :filter, type: #{class_name.camelize}Filter, with: :apply_filter
68
+ option :first, type: types.Int, with: :apply_first
69
+ option :skip, type: types.Int, with: :apply_skip
70
+
71
+ def apply_filter(scope, value)
72
+ branches = normalize_filters(value).inject { |a, b| a.or(b) }
73
+ scope.merge branches
74
+ end
75
+
76
+ def normalize_filters(value, branches = [])
77
+ scope = ::#{class_name.camelize}.all
78
+ EOS
79
+ end
80
+ end
81
+
82
+ def resolver_before_end class_name: "souls"
83
+ file_path = "./app/graphql/resolvers/#{class_name.singularize}_search.rb"
84
+ path = "./db/schema.rb"
85
+ @on = false
86
+ @user_exist = false
87
+ @relation_params = []
88
+ File.open(file_path, "a") do |new_line|
89
+ File.open(path, "r") do |f|
90
+ f.each_line.with_index do |line, i|
91
+ if @on
92
+ if line.include?("end") || line.include?("t.index")
93
+ break
94
+ end
95
+ type, name = get_type_and_name(line)
96
+ if line.include?("array: true")
97
+ new_line.write " scope = scope.where(\"#{name} @> ARRAY[?]::text[]\", value[:#{name}]) if value[:#{name}]\n"
98
+ next
99
+ end
100
+ case name
101
+ when "user_id"
102
+ @user_exist = true
103
+ when /$*_id\z/
104
+ @relation_params << name
105
+ new_line.write " scope = scope.where(#{name}: decode_global_key(value[:#{name}])) if value[:#{name}]\n"
106
+ when "created_at", "updated_at"
107
+ next
108
+ else
109
+ case type
110
+ when "boolean"
111
+ new_line.write " scope = scope.where(#{name}: value[:#{name}]) unless value[:#{name}].nil?\n"
112
+ else
113
+ new_line.write " scope = scope.where(#{name}: value[:#{name}]) if value[:#{name}]\n"
114
+ end
115
+ end
116
+ end
117
+ @on = true if table_check(line: line, class_name: class_name)
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ def resolver_end class_name: "souls"
124
+ file_path = "./app/graphql/resolvers/#{class_name.singularize}_search.rb"
125
+ File.open(file_path, "a") do |f|
126
+ f.write <<~EOS
127
+ scope = scope.where("created_at >= ?", value[:start_date]) if value[:start_date]
128
+ scope = scope.where("created_at <= ?", value[:end_date]) if value[:end_date]
129
+ #{' '}
130
+ branches << scope
131
+ #{' '}
132
+ value[:OR].inject(branches) { |s, v| normalize_filters(v, s) } if value[:OR].present?
133
+ #{' '}
134
+ branches
135
+ end
136
+ end
137
+ end
138
+ EOS
139
+ end
140
+ file_path
141
+ end
142
+
143
+ def resolver class_name: "souls"
144
+ singularized_class_name = class_name.singularize.underscore
145
+ resolver_head class_name: singularized_class_name
146
+ resolver_params class_name: singularized_class_name
147
+ resolver_after_params class_name: singularized_class_name
148
+ resolver_before_end class_name: singularized_class_name
149
+ resolver_end class_name: singularized_class_name
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,63 @@
1
+ module Souls
2
+ module Generate
3
+ class << self
4
+ ## Generate Rspec Factory
5
+ def rspec_factory_head class_name: "souls"
6
+ file_path = "./spec/factories/#{class_name.pluralize}.rb"
7
+ File.open(file_path, "w") do |f|
8
+ f.write <<~EOS
9
+ FactoryBot.define do
10
+ factory :#{class_name} do
11
+ EOS
12
+ end
13
+ end
14
+
15
+ def rspec_factory_params class_name: "souls"
16
+ file_path = "./spec/factories/#{class_name.pluralize}.rb"
17
+ path = "./db/schema.rb"
18
+ @on = false
19
+ File.open(file_path, "a") do |new_line|
20
+ File.open(path, "r") do |f|
21
+ f.each_line.with_index do |line, i|
22
+ if @on
23
+ new_line.write "\n" && break if line.include?("end") || line.include?("t.index")
24
+ field = '["tag1", "tag2", "tag3"]' if line.include?("array: true")
25
+ type, name = line.split(",")[0].gsub("\"", "").scan(/((?<=t\.).+(?=\s)) (.+)/)[0]
26
+ field ||= get_test_type type
27
+ if type == "bigint" && name.include?("_id")
28
+ id_name = name.gsub("_id", "")
29
+ new_line.write " association :#{id_name}, factory: :#{id_name}\n"
30
+ else
31
+ new_line.write " #{name} { #{field} }\n"
32
+ end
33
+ end
34
+ if table_check(line: line, class_name: class_name)
35
+ @on = true
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ def rspec_factory_end class_name: "souls"
43
+ file_path = "./spec/factories/#{class_name.pluralize}.rb"
44
+ File.open(file_path, "a") do |f|
45
+ f.write <<~EOS
46
+ end
47
+ end
48
+ EOS
49
+ end
50
+ file_path
51
+ end
52
+
53
+ def rspec_factory class_name: "souls"
54
+ file_path = "./spec/factories/#{class_name.pluralize}.rb"
55
+ return ["Factory aleady exist! #{file_path}"] if File.exist? file_path
56
+ singularized_class_name = class_name.singularize
57
+ rspec_factory_head class_name: singularized_class_name
58
+ rspec_factory_params class_name: singularized_class_name
59
+ rspec_factory_end class_name: singularized_class_name
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,23 @@
1
+ module Souls
2
+ module Generate
3
+ class << self
4
+ ## Generate Rspec Model
5
+ def rspec_model class_name: "souls"
6
+ file_path = "./spec/models/#{class_name}_spec.rb"
7
+ return ["Aleady Exist!"] if File.exist? file_path
8
+ File.open(file_path, "w") do |f|
9
+ f.write <<~EOS
10
+ RSpec.describe "#{class_name.camelize} Model テスト", type: :model do
11
+ describe "#{class_name.camelize} データを書き込む" do
12
+ it "valid #{class_name.camelize} Model" do
13
+ expect(FactoryBot.build(:#{class_name.singularize})).to be_valid
14
+ end
15
+ end
16
+ end
17
+ EOS
18
+ end
19
+ file_path
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,247 @@
1
+ module Souls
2
+ module Generate
3
+ class << self
4
+ ## Generate Rspec Mutation
5
+ def rspec_mutation_head class_name: "souls"
6
+ file_path = "./spec/mutations/#{class_name.singularize}_spec.rb"
7
+ File.open(file_path, "w") do |f|
8
+ f.write <<~EOS
9
+ RSpec.describe \"#{class_name.camelize} Mutation テスト\" do
10
+ describe "#{class_name.camelize} データを登録する" do
11
+ EOS
12
+ end
13
+ end
14
+
15
+ def rspec_mutation_after_head class_name: "souls"
16
+ file_path = "./spec/mutations/#{class_name.singularize}_spec.rb"
17
+ path = "./db/schema.rb"
18
+ @on = false
19
+ @user_exist = false
20
+ @relation_params = []
21
+ File.open(file_path, "a") do |new_line|
22
+ File.open(path, "r") do |f|
23
+ f.each_line.with_index do |line, i|
24
+ if @on
25
+ if line.include?("end") || line.include?("t.index")
26
+ if @relation_params.empty?
27
+ new_line.write <<-EOS
28
+ let(:#{class_name}) { FactoryBot.attributes_for(:#{class_name}) }
29
+
30
+ let(:mutation) do
31
+ %(mutation {
32
+ create#{class_name.camelize}(input: {
33
+ EOS
34
+ else
35
+ new_line.write <<-EOS
36
+ let(:#{class_name}) { FactoryBot.attributes_for(:#{class_name}, #{@relation_params.join(", ")}) }
37
+
38
+ let(:mutation) do
39
+ %(mutation {
40
+ create#{class_name.camelize}(input: {
41
+ EOS
42
+ end
43
+ break
44
+ end
45
+ _, name = line.split(",")[0].gsub("\"", "").scan(/((?<=t\.).+(?=\s)) (.+)/)[0]
46
+ case name
47
+ when "user_id"
48
+ relation_col = name.gsub("_id", "")
49
+ new_line.write " let(:#{relation_col}) { FactoryBot.create(:#{relation_col}) }\n"
50
+ when /$*_id\z/
51
+ relation_col = name.gsub("_id", "")
52
+ @relation_params << "#{name}: get_global_key(\"#{name.singularize.camelize.gsub("Id", "")}\", #{relation_col}.id)"
53
+ new_line.write " let(:#{relation_col}) { FactoryBot.create(:#{relation_col}) }\n"
54
+ end
55
+ end
56
+ if table_check(line: line, class_name: class_name)
57
+ @on = true
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def rspec_mutation_params class_name: "souls"
65
+ file_path = "./spec/mutations/#{class_name.singularize}_spec.rb"
66
+ path = "./db/schema.rb"
67
+ @on = false
68
+ @user_exist = false
69
+ File.open(file_path, "a") do |new_line|
70
+ File.open(path, "r") do |f|
71
+ f.each_line.with_index do |line, i|
72
+ if @on
73
+ if line.include?("end") || line.include?("t.index")
74
+ new_line.write " }) {\n #{class_name.singularize.camelize(:lower)}Edge {\n node {\n"
75
+ new_line.write " id\n"
76
+ break
77
+ end
78
+ type, name = line.split(",")[0].gsub("\"", "").scan(/((?<=t\.).+(?=\s)) (.+)/)[0]
79
+ array_true = line.include?("array: true")
80
+ case name
81
+ when "created_at", "updated_at"
82
+ next
83
+ when "user_id"
84
+ @user_exist = true
85
+ when /$*_id\z/
86
+ new_line.write " #{name.singularize.camelize(:lower)}: \"\#{#{class_name.singularize}[:#{name.singularize.underscore}]}\"\n"
87
+ else
88
+ case type
89
+ when "string", "text", "date", "datetime"
90
+ if array_true
91
+ new_line.write " #{name.pluralize.camelize(:lower)}: \#{#{class_name.singularize}[:#{name.pluralize.underscore}]}\n"
92
+ else
93
+ new_line.write " #{name.singularize.camelize(:lower)}: \"\#{#{class_name.singularize}[:#{name.singularize.underscore}]}\"\n"
94
+ end
95
+ when "bigint", "integer", "float", "boolean"
96
+ new_line.write " #{name.singularize.camelize(:lower)}: \#{#{class_name.singularize}[:#{name.singularize.underscore}]}\n"
97
+ end
98
+ end
99
+ end
100
+ if table_check(line: line, class_name: class_name)
101
+ @on = true
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def rspec_mutation_params_response class_name: "souls"
109
+ file_path = "./spec/mutations/#{class_name.singularize}_spec.rb"
110
+ path = "./db/schema.rb"
111
+ @on = false
112
+ File.open(file_path, "a") do |new_line|
113
+ File.open(path, "r") do |f|
114
+ f.each_line.with_index do |line, i|
115
+ if @on
116
+ if line.include?("end") || line.include?("t.index")
117
+ if @user_exist
118
+ new_line.write <<-EOS
119
+ }
120
+ }
121
+ }
122
+ }
123
+ )
124
+ end
125
+
126
+ subject(:result) do
127
+ context = {
128
+ user: user
129
+ }
130
+ SoulsApiSchema.execute(mutation, context: context).as_json
131
+ end
132
+
133
+ it "return #{class_name.camelize} Data" do
134
+ begin
135
+ a1 = result.dig("data", "create#{class_name.singularize.camelize}", "#{class_name.singularize.camelize(:lower)}Edge", "node")
136
+ raise unless a1.present?
137
+ rescue
138
+ raise StandardError, result
139
+ end
140
+ expect(a1).to include(
141
+ "id" => be_a(String),
142
+ EOS
143
+ else
144
+ new_line.write <<-EOS
145
+ }
146
+ }
147
+ }
148
+ }
149
+ )
150
+ end
151
+
152
+ subject(:result) do
153
+ SoulsApiSchema.execute(mutation).as_json
154
+ end
155
+
156
+ it "return #{class_name.camelize} Data" do
157
+ begin
158
+ a1 = result.dig("data", "create#{class_name.singularize.camelize}", "#{class_name.singularize.camelize(:lower)}Edge", "node")
159
+ raise unless a1.present?
160
+ rescue
161
+ raise StandardError, result
162
+ end
163
+ expect(a1).to include(
164
+ "id" => be_a(String),
165
+ EOS
166
+ end
167
+ break
168
+ end
169
+ _, name = line.split(",")[0].gsub("\"", "").scan(/((?<=t\.).+(?=\s)) (.+)/)[0]
170
+ array_true = line.include?("array: true")
171
+ case name
172
+ when "user_id", "created_at", "updated_at", /$*_id\z/
173
+ next
174
+ else
175
+ if array_true
176
+ new_line.write " #{name.pluralize.camelize(:lower)}\n"
177
+ else
178
+ new_line.write " #{name.singularize.camelize(:lower)}\n"
179
+ end
180
+ end
181
+ end
182
+ if table_check(line: line, class_name: class_name)
183
+ @on = true
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+ def rspec_mutation_end class_name: "souls"
191
+ file_path = "./spec/mutations/#{class_name.singularize}_spec.rb"
192
+ path = "./db/schema.rb"
193
+ @on = false
194
+ File.open(file_path, "a") do |new_line|
195
+ File.open(path, "r") do |f|
196
+ f.each_line.with_index do |line, i|
197
+ if @on
198
+ if line.include?("end") || line.include?("t.index")
199
+ new_line.write <<~EOS
200
+ )
201
+ end
202
+ end
203
+ end
204
+ EOS
205
+ break
206
+ end
207
+ type, name = line.split(",")[0].gsub("\"", "").scan(/((?<=t\.).+(?=\s)) (.+)/)[0]
208
+ field ||= type_check type
209
+ array_true = line.include?("array: true")
210
+ case name
211
+ when "user_id", "created_at", "updated_at", /$*_id\z/
212
+ next
213
+ else
214
+ case type
215
+ when "text", "date", "datetime"
216
+ if array_true
217
+ new_line.write " \"#{name.pluralize.camelize(:lower)}\" => be_all(String),\n"
218
+ else
219
+ new_line.write " \"#{name.singularize.camelize(:lower)}\" => be_a(String),\n"
220
+ end
221
+ when "boolean"
222
+ new_line.write " \"#{name.singularize.camelize(:lower)}\" => be_in([true, false]),\n"
223
+ when "string", "bigint", "integer", "float"
224
+ new_line.write " \"#{name.singularize.camelize(:lower)}\" => be_a(#{field}),\n"
225
+ end
226
+ end
227
+ end
228
+ if table_check(line: line, class_name: class_name)
229
+ @on = true
230
+ end
231
+ end
232
+ end
233
+ end
234
+ file_path
235
+ end
236
+
237
+ def rspec_mutation class_name: "souls"
238
+ singularized_class_name = class_name.singularize
239
+ rspec_mutation_head class_name: singularized_class_name
240
+ rspec_mutation_after_head class_name: singularized_class_name
241
+ rspec_mutation_params class_name: singularized_class_name
242
+ rspec_mutation_params_response class_name: singularized_class_name
243
+ rspec_mutation_end class_name: singularized_class_name
244
+ end
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,50 @@
1
+ module Souls
2
+ module Generate
3
+ class << self
4
+ ## Generate Rspec Policy
5
+ def rspec_policy class_name: "souls"
6
+ dir_name = "./spec/policies"
7
+ FileUtils.mkdir_p dir_name unless Dir.exist? dir_name
8
+ file_path = "./spec/policies/#{class_name}_policy_spec.rb"
9
+ File.open(file_path, "w") do |new_line|
10
+ new_line.write <<~EOS
11
+ describe #{class_name.camelize}Policy do
12
+ subject { described_class.new(user, #{class_name.underscore}) }
13
+
14
+ let(:#{class_name.underscore}) { FactoryBot.create(:#{class_name.underscore}) }
15
+
16
+ context "being a visitor" do
17
+ let(:user) { FactoryBot.create(:user) }
18
+
19
+ it { is_expected.to permit_action(:index) }
20
+ it { is_expected.to permit_action(:show) }
21
+ it { is_expected.to forbid_actions([:create, :update, :delete]) }
22
+ end
23
+
24
+ context "being a retailer" do
25
+ let(:user) { FactoryBot.create(:user, user_role: 1) }
26
+
27
+ it { is_expected.to permit_action(:index) }
28
+ it { is_expected.to permit_action(:show) }
29
+ it { is_expected.to forbid_actions([:create, :update, :delete]) }
30
+ end
31
+
32
+ context "being a staff" do
33
+ let(:user) { FactoryBot.create(:user, user_role: 3) }
34
+
35
+ it { is_expected.to permit_actions([:create, :update, :delete]) }
36
+ end
37
+
38
+ context "being an administrator" do
39
+ let(:user) { FactoryBot.create(:user, user_role: 4) }
40
+
41
+ it { is_expected.to permit_actions([:create, :update, :delete]) }
42
+ end
43
+ end
44
+ EOS
45
+ end
46
+ file_path
47
+ end
48
+ end
49
+ end
50
+ end