marty 1.0.42 → 1.0.43
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/app/controllers/marty/rpc_controller.rb +20 -1
- data/lib/marty/migrations.rb +3 -1
- data/lib/marty/schema_helper.rb +42 -0
- data/lib/marty/version.rb +1 -1
- data/spec/controllers/rpc_controller_spec.rb +139 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b66276891458efd498648be59d402697d007be05
|
4
|
+
data.tar.gz: 6fd5ee9414488b17042c87bb1439ca1021d371b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acff2e6a1842b34ed8ec5c17e8d15bd314723eae74cc11e043ca8f4f23bee95da6c0a46a56dca72bec7e248878f2849b517fb8f8397f3f1873ffd3658bd6c0d5
|
7
|
+
data.tar.gz: b596a59fd785a72531318a652dc9f20c71944df9a433e5b8db183316d4434015c974cc0276940ca7c3d418f94e49fbd07d6fbc228447c2fd63172f03bab0ff4c
|
data/Gemfile.lock
CHANGED
@@ -34,6 +34,24 @@ class Marty::RpcController < ActionController::Base
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
def _get_errors(errs)
|
38
|
+
if errs.is_a?(Array)
|
39
|
+
errs.map { |err| _get_errors(err) }
|
40
|
+
elsif errs.is_a?(Hash)
|
41
|
+
if !errs.include?(:failed_attribute)
|
42
|
+
errs.map { |k, v| _get_errors(v) }
|
43
|
+
else
|
44
|
+
fa, message, errors = errs.values_at(:failed_attribute,
|
45
|
+
:message, :errors)
|
46
|
+
(['AllOf','AnyOf','Not'].include?(fa) ? [] : [message]) +
|
47
|
+
_get_errors(errors || {})
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
def get_errors(errs)
|
52
|
+
_get_errors(errs).flatten
|
53
|
+
end
|
54
|
+
|
37
55
|
def do_eval(sname, tag, node, attrs, params, api_key, background)
|
38
56
|
return {error: "Malformed attrs"} unless attrs.is_a?(String)
|
39
57
|
|
@@ -95,7 +113,8 @@ class Marty::RpcController < ActionController::Base
|
|
95
113
|
rescue => ex
|
96
114
|
return {error: "#{attr}: #{ex.message}"}
|
97
115
|
end
|
98
|
-
|
116
|
+
|
117
|
+
validation_error[attr] = get_errors(er) if er.size > 0
|
99
118
|
err_count += er.size
|
100
119
|
end
|
101
120
|
end
|
data/lib/marty/migrations.rb
CHANGED
@@ -187,6 +187,7 @@ EOSQL
|
|
187
187
|
encode(line.encoding, :crlf_newline => true)
|
188
188
|
end
|
189
189
|
end
|
190
|
+
|
190
191
|
def self.generate_sql_migrations(migrations_dir, sql_files_dir)
|
191
192
|
sd = Rails.root.join(sql_files_dir)
|
192
193
|
md = Rails.root.join(migrations_dir)
|
@@ -218,7 +219,8 @@ EOSQL
|
|
218
219
|
newbase = "#{timestamp}_#{klass}"
|
219
220
|
mig_name = File.join(md, "#{newbase}.rb")
|
220
221
|
sql_snap_literal = Rails.root.join(md, 'sql', "#{newbase}.sql")
|
221
|
-
sql_snap_call =
|
222
|
+
sql_snap_call =
|
223
|
+
"Rails.root.join('#{migrations_dir}', 'sql', '#{newbase}.sql')"
|
222
224
|
|
223
225
|
File.open(sql_snap_literal, "w") do |f|
|
224
226
|
f.print sql_lines.join
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class Marty::SchemaHelper
|
2
|
+
include Delorean::Model
|
3
|
+
delorean_fn :enum_is, sig: 2 do
|
4
|
+
|var, value|
|
5
|
+
{"properties"=> {var => { "enum"=> value}}}
|
6
|
+
end
|
7
|
+
delorean_fn :bool_is, sig: 2 do
|
8
|
+
|var, value|
|
9
|
+
{"properties"=> {var => { "type"=> "boolean", "enum"=> [value]}}}
|
10
|
+
end
|
11
|
+
|
12
|
+
delorean_fn :or, sig: [1, 20] do
|
13
|
+
|*args|
|
14
|
+
{"anyOf"=>args}
|
15
|
+
end
|
16
|
+
|
17
|
+
delorean_fn :and, sig: [1, 20] do
|
18
|
+
|*args|
|
19
|
+
{"allOf"=>args}
|
20
|
+
end
|
21
|
+
|
22
|
+
delorean_fn :not, sig: 1 do
|
23
|
+
|arg|
|
24
|
+
{"not"=>{"allOf"=>[arg]}}
|
25
|
+
end
|
26
|
+
|
27
|
+
# if conds is true, var_array columns we be required
|
28
|
+
delorean_fn :required_if, sig: [2, 20] do
|
29
|
+
|var_array, *conds_array|
|
30
|
+
{"anyOf"=>[{"not"=>{"allOf"=> conds_array}},
|
31
|
+
{"required"=>var_array}]}
|
32
|
+
end
|
33
|
+
|
34
|
+
# if dep_column is present, checks must pass
|
35
|
+
delorean_fn :dep_check, sig: [2, 20] do
|
36
|
+
|dep_column, *checks|
|
37
|
+
{"dependencies"=> {dep_column =>
|
38
|
+
{"type"=>"object",
|
39
|
+
"allOf"=> checks}}}
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/lib/marty/version.rb
CHANGED
@@ -89,6 +89,35 @@ A:
|
|
89
89
|
result = [{"a": 1, "b": res}, {"a": 789, "b": res}]
|
90
90
|
eof
|
91
91
|
|
92
|
+
sample_script10 = <<eof
|
93
|
+
A:
|
94
|
+
opt1 =?
|
95
|
+
optn =?
|
96
|
+
opttf =?
|
97
|
+
opttrue =?
|
98
|
+
optfalse =?
|
99
|
+
req1 =?
|
100
|
+
req2 =?
|
101
|
+
req3 =?
|
102
|
+
|
103
|
+
optif = if opttf == true
|
104
|
+
then opttrue
|
105
|
+
else if opttf == false
|
106
|
+
then optfalse
|
107
|
+
else nil
|
108
|
+
|
109
|
+
v1 = if req1 == 'no opts'
|
110
|
+
then req2
|
111
|
+
else if req1 == "opt1"
|
112
|
+
then opt1
|
113
|
+
else if req2 != 'no opts'
|
114
|
+
then optn
|
115
|
+
else if req3 == "opttf"
|
116
|
+
then optif
|
117
|
+
else 'req3'
|
118
|
+
|
119
|
+
eof
|
120
|
+
|
92
121
|
script3_schema = <<eof
|
93
122
|
A:
|
94
123
|
pc = { "properties : {
|
@@ -227,6 +256,56 @@ A:
|
|
227
256
|
}
|
228
257
|
eof
|
229
258
|
|
259
|
+
script10_schema = <<eof
|
260
|
+
A:
|
261
|
+
properties = {
|
262
|
+
"opt1" : { "type" : "string" },
|
263
|
+
"opttf" : { "type" : "boolean" },
|
264
|
+
"opttrue" : { "type" : "string" },
|
265
|
+
"optfalse" : { "type" : "string" },
|
266
|
+
"req1" : { "pg_enum" : "CondEnum" },
|
267
|
+
"req2" : { "pg_enum" : "CondEnum" }
|
268
|
+
}
|
269
|
+
|
270
|
+
req1_is_opt1 = Marty::SchemaHelper.enum_is('req1', ['opt1'])
|
271
|
+
req2_is_not_no_opts = Marty::SchemaHelper.not(
|
272
|
+
Marty::SchemaHelper.enum_is('req2', ['no opts']))
|
273
|
+
req3_is_opttf = Marty::SchemaHelper.enum_is('req3', ['opttf'])
|
274
|
+
opttf_is_true = Marty::SchemaHelper.bool_is('opttf', true)
|
275
|
+
opttf_is_false = Marty::SchemaHelper.bool_is('opttf', false)
|
276
|
+
|
277
|
+
# opt1 is required if req1 == 'opt1'
|
278
|
+
opt1_check = Marty::SchemaHelper.required_if(['opt1'], req1_is_opt1)
|
279
|
+
|
280
|
+
# optn is required if req2 != 'no opts'
|
281
|
+
optn_check = Marty::SchemaHelper.required_if(['optn'], req2_is_not_no_opts)
|
282
|
+
|
283
|
+
# opttf is required if req3 == 'opttf'
|
284
|
+
opttf_check = Marty::SchemaHelper.required_if(['opttf'], req3_is_opttf)
|
285
|
+
|
286
|
+
# opttrue is required if opttf is true
|
287
|
+
opttrue_check = Marty::SchemaHelper.required_if(['opttrue'], opttf_is_true)
|
288
|
+
|
289
|
+
# optfalse is required if opttf is false
|
290
|
+
optfalse_check = Marty::SchemaHelper.required_if(['optfalse'],
|
291
|
+
opttf_is_false)
|
292
|
+
|
293
|
+
# opttf is optional (contingent on req3) so eval of opttrue_check
|
294
|
+
# and optfalse_check is dependent upon opttf existing
|
295
|
+
opttruefalse_check = Marty::SchemaHelper.dep_check('opttf',
|
296
|
+
opttrue_check,
|
297
|
+
optfalse_check)
|
298
|
+
|
299
|
+
v1 = { "properties": properties,
|
300
|
+
"required": ["req1", "req2", "req3"],
|
301
|
+
"allOf": [
|
302
|
+
opt1_check,
|
303
|
+
optn_check,
|
304
|
+
opttf_check,
|
305
|
+
opttruefalse_check
|
306
|
+
] }
|
307
|
+
eof
|
308
|
+
|
230
309
|
describe Marty::RpcController do
|
231
310
|
before(:each) {
|
232
311
|
@routes = Marty::Engine.routes
|
@@ -250,6 +329,7 @@ describe Marty::RpcController do
|
|
250
329
|
"M7" => sample_script7,
|
251
330
|
"M8" => sample_script8,
|
252
331
|
"M9" => sample_script9,
|
332
|
+
"M10" => sample_script10,
|
253
333
|
"M3Schemas" => script3_schema,
|
254
334
|
"M4Schemas" => script4_schema,
|
255
335
|
"M5Schemas" => script5_schema,
|
@@ -257,6 +337,7 @@ describe Marty::RpcController do
|
|
257
337
|
"M7Schemas" => script7_schema,
|
258
338
|
"M8Schemas" => script8_schema,
|
259
339
|
"M9Schemas" => script9_schema,
|
340
|
+
"M10Schemas" => script10_schema,
|
260
341
|
}, Date.today + 1.minute)
|
261
342
|
|
262
343
|
@p1 = Marty::Posting.do_create("BASE", Date.today + 2.minute, 'a comment')
|
@@ -792,6 +873,9 @@ describe Marty::RpcController do
|
|
792
873
|
class FruitsEnum
|
793
874
|
VALUES=Set['Apple', 'Banana', 'Orange']
|
794
875
|
end
|
876
|
+
class CondEnum
|
877
|
+
VALUES=Set['no opts','opt1','opt2','opttf']
|
878
|
+
end
|
795
879
|
|
796
880
|
it "validates schema with a pg_enum (Positive)" do
|
797
881
|
Marty::ApiConfig.create!(script: "M5",
|
@@ -1033,6 +1117,61 @@ describe Marty::RpcController do
|
|
1033
1117
|
expect(response.body).to match(/"error":"Permission denied"/)
|
1034
1118
|
end
|
1035
1119
|
|
1120
|
+
context "conditional validation" do
|
1121
|
+
before(:all) do
|
1122
|
+
Marty::ApiConfig.create!(script: "M10",
|
1123
|
+
node: "A",
|
1124
|
+
attr: nil,
|
1125
|
+
logged: false,
|
1126
|
+
input_validated: true,
|
1127
|
+
output_validated: false,
|
1128
|
+
strict_validate: false)
|
1129
|
+
end
|
1130
|
+
def do_call(req1, req2, req3, optionals={})
|
1131
|
+
attrs = ["v1"].to_json
|
1132
|
+
params = optionals.merge({"req1" => req1,
|
1133
|
+
"req2"=> req2,
|
1134
|
+
"req3"=> req3}).to_json
|
1135
|
+
get 'evaluate', {
|
1136
|
+
format: :json,
|
1137
|
+
script: "M10",
|
1138
|
+
node: "A",
|
1139
|
+
attrs: attrs,
|
1140
|
+
params: params
|
1141
|
+
}
|
1142
|
+
end
|
1143
|
+
|
1144
|
+
it "does conditional" do
|
1145
|
+
aggregate_failures "conditionals" do
|
1146
|
+
[# first group has all required fields
|
1147
|
+
[['opt1', 'no opts', 'no opts', opt1: 'hi mom'], "hi mom"],
|
1148
|
+
[['no opts', 'no opts', 'no opts', opt1: 'hi mom'], "no opts"],
|
1149
|
+
[['opt2', 'opt2', 'no opts', optn: 'foo'], 'foo'],
|
1150
|
+
[['opt2', 'no opts', 'opt2'], 'req3'],
|
1151
|
+
[['opt2', 'no opts', 'opttf', opttf: true, opttrue: 'bar'], 'bar'],
|
1152
|
+
[['opt2', 'no opts', 'opttf', opttf: false, optfalse: 'baz'], 'baz'],
|
1153
|
+
# second group is missing fields
|
1154
|
+
[['opt1', 'no opts', 'no opts'],
|
1155
|
+
"did not contain a required property of 'opt1'"],
|
1156
|
+
[['opt2', 'opt2', 'no opts',],
|
1157
|
+
"did not contain a required property of 'optn'"],
|
1158
|
+
[['opt2', 'no opts', 'opttf'],
|
1159
|
+
"did not contain a required property of 'opttf'"],
|
1160
|
+
[['opt2', 'no opts', 'opttf', opttf: true],
|
1161
|
+
"did not contain a required property of 'opttrue'"],
|
1162
|
+
[['opt2', 'no opts', 'opttf', opttf: false],
|
1163
|
+
"did not contain a required property of 'optfalse'"],
|
1164
|
+
].each do
|
1165
|
+
|a, exp|
|
1166
|
+
do_call(*a)
|
1167
|
+
res_hash = JSON.parse(response.body)
|
1168
|
+
got = res_hash.is_a?(Array) ? res_hash[0] : res_hash["error"]
|
1169
|
+
expect(got).to include(exp)
|
1170
|
+
end
|
1171
|
+
end
|
1172
|
+
end
|
1173
|
+
end
|
1174
|
+
|
1036
1175
|
context "error handling" do
|
1037
1176
|
it 'returns bad attrs if attrs is not a string' do
|
1038
1177
|
get :evaluate, format: :json, attrs: 0
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.43
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arman Bostani
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2017-10-
|
17
|
+
date: 2017-10-09 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: pg
|
@@ -499,6 +499,7 @@ files:
|
|
499
499
|
- lib/marty/railtie.rb
|
500
500
|
- lib/marty/relation.rb
|
501
501
|
- lib/marty/rpc_call.rb
|
502
|
+
- lib/marty/schema_helper.rb
|
502
503
|
- lib/marty/util.rb
|
503
504
|
- lib/marty/version.rb
|
504
505
|
- lib/marty/xl.rb
|