marty 1.0.27 → 1.0.28
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 +4 -4
- data/app/components/marty/api_config_view.rb +72 -0
- data/app/components/marty/api_log_view.rb +73 -0
- data/app/components/marty/main_auth_app.rb +35 -3
- data/app/controllers/marty/rpc_controller.rb +84 -35
- data/app/models/marty/api_auth.rb +2 -1
- data/app/models/marty/api_config.rb +16 -0
- data/app/models/marty/api_log.rb +5 -0
- data/app/models/marty/data_grid.rb +1 -1
- data/db/migrate/300_create_marty_api_configs.rb +13 -0
- data/db/migrate/301_create_marty_api_log.rb +16 -0
- data/lib/marty.rb +1 -0
- data/lib/marty/json_schema.rb +52 -0
- data/lib/marty/monkey.rb +15 -0
- data/lib/marty/version.rb +1 -1
- data/marty.gemspec +1 -0
- data/spec/controllers/rpc_controller_spec.rb +342 -1
- data/spec/lib/json_schema_spec.rb +619 -0
- data/spec/models/api_auth_spec.rb +14 -14
- metadata +24 -2
@@ -0,0 +1,619 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class MammalEnum
|
4
|
+
VALUES=Set['Dog','Cat','Human','Cow','Bear']
|
5
|
+
end
|
6
|
+
|
7
|
+
class ElectronicsEnum
|
8
|
+
VALUES=Set['Phone','Keyboard','Terminator']
|
9
|
+
end
|
10
|
+
|
11
|
+
module Marty
|
12
|
+
|
13
|
+
describe JsonSchema do
|
14
|
+
|
15
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
16
|
+
### Generic, simple data ###
|
17
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
18
|
+
|
19
|
+
simple_schema = {
|
20
|
+
"$schema" => "http://json-schema.org/marty-draft/schema#",
|
21
|
+
"properties" => {
|
22
|
+
"a" => {
|
23
|
+
"type" => "integer"
|
24
|
+
},
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
it "returns true on correct simple data" do
|
29
|
+
data = {"a" => 5}
|
30
|
+
expect(JSON::Validator.validate(simple_schema, data)).to be true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns false on incorrect simple data -- 1" do
|
34
|
+
data = {"a" => 5.2}
|
35
|
+
expect(JSON::Validator.validate(simple_schema, data)).to be false
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns false on incorrect simple data -- 2" do
|
39
|
+
data = {"a" => "Kangaroo"}
|
40
|
+
expect(JSON::Validator.validate(simple_schema, data)).to be false
|
41
|
+
end
|
42
|
+
|
43
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
44
|
+
### PgEnum ###
|
45
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
46
|
+
|
47
|
+
pg_schema_opt = {
|
48
|
+
"$schema" => "http://json-schema.org/marty-draft/schema#",
|
49
|
+
"properties" => {
|
50
|
+
"a" => {
|
51
|
+
"pg_enum" => "MammalEnum"
|
52
|
+
},
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
it "returns true on correct existing enums" do
|
57
|
+
data = {"a" => 'Dog'}
|
58
|
+
expect(JSON::Validator.validate(pg_schema_opt, data)).to be true
|
59
|
+
end
|
60
|
+
|
61
|
+
it "vacuously returns true on a field not validated" do
|
62
|
+
data = {"b" => 'Dawg'}
|
63
|
+
expect(JSON::Validator.validate(pg_schema_opt, data)).to be true
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns false on non-existant enums" do
|
67
|
+
data = {"a" => 'Beer'}
|
68
|
+
expect(JSON::Validator.validate(pg_schema_opt, data)).to be false
|
69
|
+
end
|
70
|
+
|
71
|
+
it "returns true when a optional field is not suppplied" do
|
72
|
+
data = {}
|
73
|
+
expect(JSON::Validator.validate(pg_schema_opt, data)).to be true
|
74
|
+
end
|
75
|
+
|
76
|
+
it "returns false when a nil enum is passed even when enum is optional" do
|
77
|
+
data = {"a" => nil}
|
78
|
+
expect(JSON::Validator.validate(pg_schema_opt, data)).to be false
|
79
|
+
end
|
80
|
+
|
81
|
+
pg_schema_req = {
|
82
|
+
"$schema" => "http://json-schema.org/marty-draft/schema#",
|
83
|
+
"required" => ["a"],
|
84
|
+
"properties" => {
|
85
|
+
"a" => {
|
86
|
+
"pg_enum" => "MammalEnum"
|
87
|
+
},
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
it "returns false when a required field is not supplied" do
|
92
|
+
data = {}
|
93
|
+
expect(JSON::Validator.validate(pg_schema_req, data)).to be false
|
94
|
+
end
|
95
|
+
|
96
|
+
it "returns false when a nil enum is passed when enum is required" do
|
97
|
+
data = {"a" => nil}
|
98
|
+
expect(JSON::Validator.validate(pg_schema_req, data)).to be false
|
99
|
+
end
|
100
|
+
|
101
|
+
dt_schema_opt = {
|
102
|
+
"$schema" => "http://json-schema.org/marty-draft/schema#",
|
103
|
+
"properties" => {
|
104
|
+
"a" => {
|
105
|
+
"datetime_format" => ""
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
111
|
+
### DateTime Format ###
|
112
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
113
|
+
|
114
|
+
it "returns true on a properly formatted datetime" do
|
115
|
+
data = {"a" => '2017-05-22T14:51:44Z'}
|
116
|
+
expect(JSON::Validator.validate(dt_schema_opt, data)).to be true
|
117
|
+
end
|
118
|
+
|
119
|
+
it "vacuously returns true on a field not validated" do
|
120
|
+
data = {"b" => 'Today is May 22nd'}
|
121
|
+
expect(JSON::Validator.validate(dt_schema_opt, data)).to be true
|
122
|
+
end
|
123
|
+
|
124
|
+
it "returns false on an improperly formatted datetime" do
|
125
|
+
data = {"a" => '2017-30-22T14:51:44Z'}
|
126
|
+
expect(JSON::Validator.validate(dt_schema_opt, data)).to be false
|
127
|
+
end
|
128
|
+
|
129
|
+
it "returns true when an opt field is not supplied" do
|
130
|
+
data = {}
|
131
|
+
expect(JSON::Validator.validate(dt_schema_opt, data)).to be true
|
132
|
+
end
|
133
|
+
|
134
|
+
it "returns false when a nil dt is passed even when dt is opt" do
|
135
|
+
data = {"a" => nil}
|
136
|
+
expect(JSON::Validator.validate(dt_schema_opt, data)).to be false
|
137
|
+
end
|
138
|
+
|
139
|
+
dt_schema_req = {
|
140
|
+
"$schema" => "http://json-schema.org/marty-draft/schema#",
|
141
|
+
"required" => ["a"],
|
142
|
+
"properties" => {
|
143
|
+
"a" => {
|
144
|
+
"datetime_format" => ""
|
145
|
+
}
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
it "returns false when a required field is not supplied" do
|
150
|
+
data = {}
|
151
|
+
expect(JSON::Validator.validate(dt_schema_req, data)).to be false
|
152
|
+
end
|
153
|
+
|
154
|
+
it "returns false when a nil dt is passed when dt is required" do
|
155
|
+
data = {"a" => nil}
|
156
|
+
expect(JSON::Validator.validate(dt_schema_req, data)).to be false
|
157
|
+
end
|
158
|
+
|
159
|
+
pg_dt_schema = {
|
160
|
+
"$schema" => "http://json-schema.org/marty-draft/schema#",
|
161
|
+
"properties" => {
|
162
|
+
"a" => {
|
163
|
+
"pg_enum" => "MammalEnum"
|
164
|
+
},
|
165
|
+
"b" => {
|
166
|
+
"datetime_format" => ""
|
167
|
+
},
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
172
|
+
### PgEnum & DateTime Format ###
|
173
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
174
|
+
|
175
|
+
it "validates both pg_enum and dt format when both are correct" do
|
176
|
+
data = {"a" => 'Dog', "b" => '2017-05-22T14:51:44Z'}
|
177
|
+
expect(JSON::Validator.validate(pg_dt_schema, data)).to be true
|
178
|
+
end
|
179
|
+
|
180
|
+
it "validates both pg_enum and dt format when only enum is correct" do
|
181
|
+
data = {"a" => 'Dog', "b" => '2017-55-22T14:51:44Z'}
|
182
|
+
expect(JSON::Validator.validate(pg_dt_schema, data)).to be false
|
183
|
+
end
|
184
|
+
|
185
|
+
it "validates both pg_enum and dt format when only dt is correct" do
|
186
|
+
data = {"a" => 'Dogg', "b" => '2017-05-22T14:51:44Z'}
|
187
|
+
expect(JSON::Validator.validate(pg_dt_schema, data)).to be false
|
188
|
+
end
|
189
|
+
|
190
|
+
it "validates both pg_enum and dt format when neither is correct" do
|
191
|
+
data = {"a" => 'Dogg', "b" => '2017-55-22T14:51:44Z'}
|
192
|
+
expect(JSON::Validator.validate(pg_dt_schema, data)).to be false
|
193
|
+
end
|
194
|
+
|
195
|
+
pg_dt_int_schema = {
|
196
|
+
"$schema" => "http://json-schema.org/marty-draft/schema#",
|
197
|
+
"properties" => {
|
198
|
+
"a" => {
|
199
|
+
"pg_enum" => "MammalEnum"
|
200
|
+
},
|
201
|
+
"b" => {
|
202
|
+
"datetime_format" => ""
|
203
|
+
},
|
204
|
+
"c" => {
|
205
|
+
"type" => "integer"
|
206
|
+
},
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
it "validates pg_enum, dt format and int when they are correct" do
|
211
|
+
data = {"a" => 'Dog', "b" => '2017-05-22T14:51:44Z', "c" => 5}
|
212
|
+
expect(JSON::Validator.validate(pg_dt_int_schema, data)).to be true
|
213
|
+
end
|
214
|
+
|
215
|
+
it "validates pg_enum, dt format and int when one is incorrect" do
|
216
|
+
data = {"a" => 'Chair', "b" => '2017-05-22T14:51:44Z', "c" => 5}
|
217
|
+
expect(JSON::Validator.validate(pg_dt_int_schema, data)).to be false
|
218
|
+
end
|
219
|
+
|
220
|
+
pg_dt_int_schema_req = {
|
221
|
+
"$schema" => "http://json-schema.org/marty-draft/schema#",
|
222
|
+
"required" => ["b"],
|
223
|
+
"properties" => {
|
224
|
+
"a" => {
|
225
|
+
"pg_enum" => "MammalEnum"
|
226
|
+
},
|
227
|
+
"b" => {
|
228
|
+
"datetime_format" => ""
|
229
|
+
},
|
230
|
+
"c" => {
|
231
|
+
"type" => "integer"
|
232
|
+
},
|
233
|
+
}
|
234
|
+
}
|
235
|
+
|
236
|
+
it "validates pg_enum, dt format and int when dt is required" do
|
237
|
+
data = {"a" => 'Dog', "d" => '2017-05-22T14:51:44Z', "c" => 5}
|
238
|
+
expect(JSON::Validator.validate(pg_dt_int_schema_req, data)).to be false
|
239
|
+
end
|
240
|
+
|
241
|
+
pg_dt_pg_int_schema = {
|
242
|
+
"$schema" => "http://json-schema.org/marty-draft/schema#",
|
243
|
+
"required" => ["c"],
|
244
|
+
"properties" => {
|
245
|
+
"a" => {
|
246
|
+
"pg_enum" => "MammalEnum"
|
247
|
+
},
|
248
|
+
"b" => {
|
249
|
+
"datetime_format" => ""
|
250
|
+
},
|
251
|
+
"c" => {
|
252
|
+
"pg_enum" => "ElectronicsEnum"
|
253
|
+
},
|
254
|
+
"d" => {
|
255
|
+
"type" => "integer"
|
256
|
+
},
|
257
|
+
}
|
258
|
+
}
|
259
|
+
|
260
|
+
it "validates a schema containing 2 pg_enums, one that is required" do
|
261
|
+
data = { "a" => 'Dog',
|
262
|
+
"b" => '2017-05-22T14:51:44Z',
|
263
|
+
"c" => 'Phone',
|
264
|
+
"d" => 5 }
|
265
|
+
expect(JSON::Validator.validate(pg_dt_pg_int_schema, data)).to be true
|
266
|
+
end
|
267
|
+
|
268
|
+
it "validates a schema containing 2 pg_enums, one that is required" do
|
269
|
+
data = { "a" => 'Dog',
|
270
|
+
"b" => '2017-05-22T14:51:44Z',
|
271
|
+
"e" => 'Phone',
|
272
|
+
"d" => 5 }
|
273
|
+
expect(JSON::Validator.validate(pg_dt_pg_int_schema, data)).to be false
|
274
|
+
end
|
275
|
+
|
276
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
277
|
+
### Nested Schemas ###
|
278
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
279
|
+
|
280
|
+
nested_schema = {
|
281
|
+
"$schema" => "http://json-schema.org/marty-draft/schema#",
|
282
|
+
"required" => ["a", "b", "c", "d", "root1", "root2"],
|
283
|
+
"properties" => {
|
284
|
+
"a" => {
|
285
|
+
"pg_enum" => "MammalEnum"
|
286
|
+
},
|
287
|
+
"b" => {
|
288
|
+
"datetime_format" => ""
|
289
|
+
},
|
290
|
+
"c" => {
|
291
|
+
"pg_enum" => "ElectronicsEnum"
|
292
|
+
},
|
293
|
+
"d" => {
|
294
|
+
"type" => "integer"
|
295
|
+
},
|
296
|
+
"root1" => {
|
297
|
+
"type" => "array",
|
298
|
+
"minItems" => 3,
|
299
|
+
"items" => {
|
300
|
+
"required" => ["x", "y"],
|
301
|
+
"properties" => {
|
302
|
+
"x" => { "type" => "object",
|
303
|
+
"required" => ["w", "t", "f"],
|
304
|
+
"properties" => { "w" => { "type" => "integer",
|
305
|
+
"minimum" => 0,
|
306
|
+
"maximum" => 3 },
|
307
|
+
"t" => { "pg_enum" => "MammalEnum"},
|
308
|
+
"f" => { "type" => ["number"],
|
309
|
+
"minimum" => 0,
|
310
|
+
"maximum" => 100,
|
311
|
+
"multipleOf"=> 5.0 }}
|
312
|
+
},
|
313
|
+
"y" => { "pg_enum" => "ElectronicsEnum" }
|
314
|
+
}
|
315
|
+
}
|
316
|
+
},
|
317
|
+
"root2" => {
|
318
|
+
"type" => "array",
|
319
|
+
"minItems" => 2,
|
320
|
+
"items" => {
|
321
|
+
"required" => ["m1", "e", "m2"],
|
322
|
+
"properties" => {
|
323
|
+
"m1" => { "pg_enum" => "MammalEnum" },
|
324
|
+
"e" => { "pg_enum" => "ElectronicsEnum" },
|
325
|
+
"m2" => { "pg_enum" => "MammalEnum" },
|
326
|
+
}
|
327
|
+
},
|
328
|
+
},
|
329
|
+
}
|
330
|
+
}
|
331
|
+
|
332
|
+
it "validates a complex nested schema when correct" do
|
333
|
+
data = { "a" => 'Dog',
|
334
|
+
"b" => '2017-05-22T14:51:44Z',
|
335
|
+
"root1" => [ { "x" => {"w" => 0, "t" => 'Bear', "f" => 0.0},
|
336
|
+
"y" => 'Phone' },
|
337
|
+
{ "x" => {"w" => 1, "t" => 'Human', "f" => 5.0},
|
338
|
+
"y" => 'Terminator' },
|
339
|
+
{ "x" => {"w" => 2, "t" => 'Dog', "f" => 65.0},
|
340
|
+
"y" => 'Phone' } ],
|
341
|
+
"root2" => [ {"m1" => 'Cat', "e" => 'Keyboard', "m2" => 'Dog' },
|
342
|
+
{"m1" => 'Dog', "e" => 'Phone', "m2" => 'Cow' }],
|
343
|
+
"c" => 'Terminator',
|
344
|
+
"d" => 5
|
345
|
+
}
|
346
|
+
expect(JSON::Validator.validate(nested_schema, data)).to be true
|
347
|
+
end
|
348
|
+
|
349
|
+
it "validates a complex nested schema when incorrect -- 1" do
|
350
|
+
data = { "a" => 'Dog',
|
351
|
+
"b" => '2017-05-32T14:51:44Z', #
|
352
|
+
"root1" => [ { "x" => {"w" => 0, "t" => 'Bear', "f" => 0.0},
|
353
|
+
"y" => 'Phone' },
|
354
|
+
{ "x" => {"w" => 1, "t" => 'Human', "f" => 5.0},
|
355
|
+
"y" => 'Terminator' },
|
356
|
+
{ "x" => {"w" => 2, "t" => 'Dog', "f" => 65.0},
|
357
|
+
"y" => 'Phone' } ],
|
358
|
+
"root2" => [ {"m1" => 'Cat', "e" => 'Keyboard', "m2" => 'Dog' },
|
359
|
+
{"m1" => 'Dog', "e" => 'Phone', "m2" => 'Cow' }],
|
360
|
+
"c" => 'Terminator',
|
361
|
+
"d" => 5
|
362
|
+
}
|
363
|
+
expect(JSON::Validator.validate(nested_schema, data)).to be false
|
364
|
+
end
|
365
|
+
|
366
|
+
it "validates a complex nested schema when incorrect -- 2" do
|
367
|
+
data = { "a" => 'Dog',
|
368
|
+
"b" => '2017-05-22T14:51:44Z',
|
369
|
+
"root1" => [ { "x" => {"w" => 0, "t" => 'Bar', "f" => 0.0}, #
|
370
|
+
"y" => 'Phone' },
|
371
|
+
{ "x" => {"w" => 1, "t" => 'Human', "f" => 5},
|
372
|
+
"y" => 'Terminator' },
|
373
|
+
{ "x" => {"w" => 2, "t" => 'Dog', "f" => 65.0},
|
374
|
+
"y" => 'Phone' } ],
|
375
|
+
"root2" => [ {"m1" => 'Cat', "e" => 'Keyboard', "m2" => 'Dog' },
|
376
|
+
{"m1" => 'Dog', "e" => 'Phone', "m2" => 'Cow' }],
|
377
|
+
"c" => 'Terminator',
|
378
|
+
"d" => 5
|
379
|
+
}
|
380
|
+
expect(JSON::Validator.validate(nested_schema, data)).to be false
|
381
|
+
end
|
382
|
+
|
383
|
+
it "validates a complex nested schema when incorrect -- 3" do
|
384
|
+
data = { "a" => 'Dog',
|
385
|
+
"b" => '2017-05-22T14:51:44Z',
|
386
|
+
"root1" => [ { "x" => {"w" => 0, "t" => 'Bear', "f" => 0.0},
|
387
|
+
"y" => 'Phone' },
|
388
|
+
{ "x" => {"w" => 1, "t" => 'Human', "f" => 6.0}, #
|
389
|
+
"y" => 'Terminator' },
|
390
|
+
{ "x" => {"w" => 2, "t" => 'Dog', "f" => 65.0},
|
391
|
+
"y" => 'Phone' } ],
|
392
|
+
"root2" => [ {"m1" => 'Cat', "e" => 'Keyboard', "m2" => 'Dog' },
|
393
|
+
{"m1" => 'Dog', "e" => 'Phone', "m2" => 'Cow' }],
|
394
|
+
"c" => 'Terminator',
|
395
|
+
"d" => 5
|
396
|
+
}
|
397
|
+
expect(JSON::Validator.validate(nested_schema, data)).to be false
|
398
|
+
end
|
399
|
+
|
400
|
+
it "validates a complex nested schema when incorrect -- 4" do
|
401
|
+
data = { "a" => 'Dog',
|
402
|
+
"b" => '2017-05-22T14:51:44Z',
|
403
|
+
"root1" => [ { "x" => {"w" => 0, "t" => 'Bear', "f" => 0.0},
|
404
|
+
"y" => 'Phone' },
|
405
|
+
{ "x" => {"w" => 1, "t" => 'Human', "f" => 5.0},
|
406
|
+
"y" => 'Trminator' }, #
|
407
|
+
{ "x" => {"w" => 2, "t" => 'Dog', "f" => 65.0},
|
408
|
+
"y" => 'Phone' } ],
|
409
|
+
"root2" => [ {"m1" => 'Cat', "e" => 'Keyboard', "m2" => 'Dog' },
|
410
|
+
{"m1" => 'Dog', "e" => 'Phone', "m2" => 'Cow' }],
|
411
|
+
"c" => 'Terminator',
|
412
|
+
"d" => 5
|
413
|
+
}
|
414
|
+
expect(JSON::Validator.validate(nested_schema, data)).to be false
|
415
|
+
end
|
416
|
+
|
417
|
+
it "validates a complex nested schema when incorrect -- 5" do
|
418
|
+
data = { "a" => 'Dog',
|
419
|
+
"b" => '2017-05-22T14:51:44Z',
|
420
|
+
"root1" => [ { "x" => {"w" => 0, "t" => 'Bear', "f" => 0.0},
|
421
|
+
"y" => 'Phone' },
|
422
|
+
{ "x" => {"w" => 1, "t" => 'Human', "f" => 5.0},
|
423
|
+
"y" => 'Terminator' },
|
424
|
+
{ "x" => {"w" => 5, "t" => 'Dog', "f" => 65.0}, #
|
425
|
+
"y" => 'Phone' } ],
|
426
|
+
"root2" => [ {"m1" => 'Cat', "e" => 'Keyboard', "m2" => 'Dog' },
|
427
|
+
{"m1" => 'Dog', "e" => 'Phone', "m2" => 'Cow' }],
|
428
|
+
"c" => 'Terminator',
|
429
|
+
"d" => 5
|
430
|
+
}
|
431
|
+
expect(JSON::Validator.validate(nested_schema, data)).to be false
|
432
|
+
end
|
433
|
+
|
434
|
+
it "validates a complex nested schema when incorrect -- 6" do
|
435
|
+
data = { "a" => 'Dog',
|
436
|
+
"b" => '2017-05-22T14:51:44Z',
|
437
|
+
"root1" => [ { "x" => {"w" => 0, "t" => 'Bear', "f" => 0.0},
|
438
|
+
"y" => 'Phone' },
|
439
|
+
{ "x" => {"w" => 1, "t" => 'Human', "f" => 5.0},
|
440
|
+
"y" => 'Terminator' },
|
441
|
+
{ "x" => {"w" => 5, "t" => 'Dog', "f" => 65.0}, #
|
442
|
+
"y" => 'Phone' } ],
|
443
|
+
"root2" => [ {"m1" => 'Cat', "e" => 'Keyboard', "m2" => 'Dog' },
|
444
|
+
{"m1" => 'Dog', "e" => 'Phone', "m2" => 'Cow' }],
|
445
|
+
"c" => 'Terminator',
|
446
|
+
"d" => 5
|
447
|
+
}
|
448
|
+
expect(JSON::Validator.validate(nested_schema, data)).to be false
|
449
|
+
end
|
450
|
+
|
451
|
+
it "validates a complex nested schema when incorrect -- 7" do
|
452
|
+
data = { "a" => 'Dog',
|
453
|
+
"b" => '2017-05-22T14:51:44Z',
|
454
|
+
"root1" => [ { "x" => {"w" => 0, "t" => 'Bear', "f" => 0.0},
|
455
|
+
"y" => 'Phone' },
|
456
|
+
{ "x" => {"w" => 1, "t" => 'Human', "f" => 5.0},
|
457
|
+
"y" => 'Terminator' },
|
458
|
+
{ "x" => {"w" => 2, "t" => 'Dog', "f" => 65.0},
|
459
|
+
"y" => 'Phone' } ],
|
460
|
+
"root2" => [ {"m1" => 'Cat', "e" => 'Keyboard', "m2" => 'Dog' },
|
461
|
+
{"m1" => 'Dog', "e" => 'Dog', "m2" => 'Cow' }], #
|
462
|
+
"c" => 'Terminator',
|
463
|
+
"d" => 5
|
464
|
+
}
|
465
|
+
expect(JSON::Validator.validate(nested_schema, data)).to be false
|
466
|
+
end
|
467
|
+
|
468
|
+
end
|
469
|
+
|
470
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
471
|
+
### URI ###
|
472
|
+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
|
473
|
+
|
474
|
+
class FloorOf8 < JSON::Schema::Attribute
|
475
|
+
def self.validate(curr_schema, data, frag, processor, validator, opt)
|
476
|
+
if data < 8
|
477
|
+
msg = "Error at FloorOf8: Value is below 8"
|
478
|
+
validation_error(processor,
|
479
|
+
msg,
|
480
|
+
frag,
|
481
|
+
curr_schema,
|
482
|
+
self,
|
483
|
+
opt[:record_errors])
|
484
|
+
end
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
class CeilingOf20 < JSON::Schema::Attribute
|
489
|
+
def self.validate(curr_schema, data, frag, processor, validator, opt)
|
490
|
+
if data > 20
|
491
|
+
msg = "Error at CeilingOf20: Value exceeds 20"
|
492
|
+
validation_error(processor,
|
493
|
+
msg,
|
494
|
+
frag,
|
495
|
+
curr_schema,
|
496
|
+
self,
|
497
|
+
opt[:record_errors])
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
|
503
|
+
describe "how @uri behaves as a key to a set of attributes" do
|
504
|
+
|
505
|
+
class BoundSchema < JSON::Schema::Draft4
|
506
|
+
def initialize
|
507
|
+
super
|
508
|
+
@attributes["bound"] = CeilingOf20
|
509
|
+
uri = "http://json-schema.org/bound-draft/schema#"
|
510
|
+
@uri = JSON::Util::URI.parse(uri)
|
511
|
+
end
|
512
|
+
|
513
|
+
JSON::Validator.register_validator(self.new)
|
514
|
+
end
|
515
|
+
|
516
|
+
marty_uri = {
|
517
|
+
"$schema" => "http://json-schema.org/marty-draft/schema#",
|
518
|
+
"required" => ["a"],
|
519
|
+
"properties" => {
|
520
|
+
"a" => {
|
521
|
+
"pg_enum" => "MammalEnum",
|
522
|
+
},
|
523
|
+
}
|
524
|
+
}
|
525
|
+
|
526
|
+
bound_uri = {
|
527
|
+
"$schema" => "http://json-schema.org/bound-draft/schema#",
|
528
|
+
"required" => ["a"],
|
529
|
+
"properties" => {
|
530
|
+
"a" => {
|
531
|
+
"pg_enum" => "MammalEnum",
|
532
|
+
},
|
533
|
+
}
|
534
|
+
}
|
535
|
+
|
536
|
+
it "validates an attribute dictated by its uri (Positive)" do
|
537
|
+
data = {"a" => 'Dog'}
|
538
|
+
expect(JSON::Validator.validate(marty_uri, data)).to be true
|
539
|
+
end
|
540
|
+
|
541
|
+
it "validates an attribute dictated by its uri (Negative)" do
|
542
|
+
data = {"a" => 'Table'}
|
543
|
+
expect(JSON::Validator.validate(marty_uri, data)).to be false
|
544
|
+
end
|
545
|
+
|
546
|
+
it "incorrectly validates an attribute not part of its uri" do
|
547
|
+
data = {"a" => 'Table'}
|
548
|
+
expect(JSON::Validator.validate(bound_uri, data)).to be true
|
549
|
+
end
|
550
|
+
|
551
|
+
end
|
552
|
+
|
553
|
+
describe "how @uri also behaves as namespace" do
|
554
|
+
|
555
|
+
class BoundFloorSchema < JSON::Schema::Draft4
|
556
|
+
def initialize
|
557
|
+
super
|
558
|
+
@attributes["bound"] = FloorOf8
|
559
|
+
uri = "http://json-schema.org/bound-floor-draft/schema#"
|
560
|
+
@uri = JSON::Util::URI.parse(uri)
|
561
|
+
end
|
562
|
+
|
563
|
+
JSON::Validator.register_validator(self.new)
|
564
|
+
end
|
565
|
+
|
566
|
+
class BoundCeilingSchema < JSON::Schema::Draft4
|
567
|
+
def initialize
|
568
|
+
super
|
569
|
+
@attributes["bound"] = CeilingOf20
|
570
|
+
uri = "http://json-schema.org/bound-ceiling-draft/schema#"
|
571
|
+
@uri = JSON::Util::URI.parse(uri)
|
572
|
+
end
|
573
|
+
|
574
|
+
JSON::Validator.register_validator(self.new)
|
575
|
+
end
|
576
|
+
|
577
|
+
bound_floor_schema = {
|
578
|
+
"$schema" => "http://json-schema.org/bound-floor-draft/schema#",
|
579
|
+
"required" => ["a"],
|
580
|
+
"properties" => {
|
581
|
+
"a" => {
|
582
|
+
"bound" => "",
|
583
|
+
},
|
584
|
+
}
|
585
|
+
}
|
586
|
+
|
587
|
+
bound_ceiling_schema = {
|
588
|
+
"$schema" => "http://json-schema.org/bound-ceiling-draft/schema#",
|
589
|
+
"required" => ["a"],
|
590
|
+
"properties" => {
|
591
|
+
"a" => {
|
592
|
+
"bound" => "",
|
593
|
+
},
|
594
|
+
}
|
595
|
+
}
|
596
|
+
|
597
|
+
it "validates BoundFloorSchema when called with its uri (Positive)" do
|
598
|
+
data = {"a" => 9}
|
599
|
+
expect(JSON::Validator.validate(bound_floor_schema, data)).to be true
|
600
|
+
end
|
601
|
+
|
602
|
+
it "validates BoundFloorSchema when called with its uri (Negative)" do
|
603
|
+
data = {"a" => 7}
|
604
|
+
expect(JSON::Validator.validate(bound_floor_schema, data)).to be false
|
605
|
+
end
|
606
|
+
|
607
|
+
it "validates BoundCeilingSchema when called with its uri (Positive)" do
|
608
|
+
data = {"a" => 19}
|
609
|
+
expect(JSON::Validator.validate(bound_ceiling_schema, data)).to be true
|
610
|
+
end
|
611
|
+
|
612
|
+
it "validates BoundCielingSchema when called with its uri (Negative)" do
|
613
|
+
data = {"a" => 21}
|
614
|
+
expect(JSON::Validator.validate(bound_ceiling_schema, data)).to be false
|
615
|
+
end
|
616
|
+
|
617
|
+
end
|
618
|
+
|
619
|
+
end
|