skeleton 0.3.3 → 0.4.1

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +140 -65
  4. data/Rakefile +10 -3
  5. data/lib/skeleton.rb +6 -10
  6. data/lib/skeleton/contact.rb +1 -13
  7. data/lib/skeleton/error.rb +4 -0
  8. data/lib/skeleton/graph.rb +56 -0
  9. data/lib/skeleton/header.rb +2 -63
  10. data/lib/skeleton/items.rb +34 -0
  11. data/lib/skeleton/license.rb +1 -12
  12. data/lib/skeleton/model.rb +13 -17
  13. data/lib/skeleton/operation.rb +50 -121
  14. data/lib/skeleton/parameter.rb +31 -88
  15. data/lib/skeleton/parameters.rb +40 -0
  16. data/lib/skeleton/path.rb +42 -80
  17. data/lib/skeleton/presenter.rb +19 -0
  18. data/lib/skeleton/property.rb +6 -0
  19. data/lib/skeleton/response.rb +24 -45
  20. data/lib/skeleton/schema.rb +80 -63
  21. data/lib/skeleton/scope.rb +18 -0
  22. data/lib/skeleton/security_scheme.rb +19 -37
  23. data/lib/skeleton/serializers/options.rb +215 -0
  24. data/lib/skeleton/serializers/swagger.rb +197 -0
  25. data/lib/skeleton/structure.rb +92 -138
  26. data/lib/skeleton/swagger.rb +9 -0
  27. data/lib/skeleton/tag.rb +11 -16
  28. data/lib/skeleton/version.rb +1 -1
  29. data/skeleton.gemspec +2 -0
  30. data/test/fixtures/json-schema-draft-04.json +150 -0
  31. data/test/fixtures/schema.json +1482 -0
  32. data/test/integrations/validate_complex_schema_spec.rb +42 -0
  33. data/test/skeleton/graph_test.rb +22 -0
  34. data/test/skeleton/mapper_test.rb +84 -0
  35. data/test/skeleton/operation_test.rb +11 -0
  36. data/test/skeleton/parameter_test.rb +34 -0
  37. data/test/skeleton/parameters_test.rb +9 -0
  38. data/test/skeleton/path_test.rb +46 -0
  39. data/test/skeleton/property_test.rb +8 -0
  40. data/test/skeleton/serializers/options_test.rb +68 -0
  41. data/test/skeleton/serializers/swagger_test.rb +30 -0
  42. data/test/support/factories/structure_factory.rb +86 -0
  43. data/test/support/fixtures.rb +6 -0
  44. data/test/support/kissmetrics/core_api.rb +542 -0
  45. data/{spec/spec_helper.rb → test/test_helper.rb} +7 -1
  46. metadata +73 -25
  47. data/lib/skeleton/config.rb +0 -37
  48. data/lib/skeleton/documentation.rb +0 -17
  49. data/lib/skeleton/example.rb +0 -31
  50. data/lib/skeleton/headers.rb +0 -50
  51. data/lib/skeleton/helpers/controller_helpers.rb +0 -25
  52. data/lib/skeleton/info.rb +0 -40
  53. data/lib/skeleton/item.rb +0 -99
  54. data/lib/skeleton/responses.rb +0 -59
  55. data/lib/skeleton/scopes.rb +0 -24
  56. data/lib/skeleton/security_definitions.rb +0 -46
  57. data/lib/skeleton/security_requirement.rb +0 -29
  58. data/spec/integrations/use_case_spec.rb +0 -131
  59. data/spec/skeleton/operation_spec.rb +0 -113
  60. data/spec/skeleton/serializers/contact_spec.rb +0 -30
  61. data/spec/skeleton/serializers/documentation_spec.rb +0 -23
  62. data/spec/skeleton/serializers/header_spec.rb +0 -57
@@ -0,0 +1,6 @@
1
+ module Fixtures
2
+ def self.read(file)
3
+ path = File.expand_path(File.join('..', '..', 'fixtures', file), __FILE__)
4
+ File.read(path)
5
+ end
6
+ end
@@ -0,0 +1,542 @@
1
+ require 'skeleton'
2
+
3
+ module KISSmetrics
4
+ module CoreAPI
5
+ def self.structure
6
+ skeleton = Skeleton.build do |s|
7
+ s.title = 'KISSmetrics API'
8
+ s.version = '1.0.0'
9
+ s.description = 'A simply complex skeleton'
10
+
11
+ s.terms = 'https://www.kissmetrics.com/terms'
12
+
13
+ s.contact.name = 'KISSmetrics'
14
+ s.contact.email = 'support@kissmetrics.com'
15
+ s.contact.url = 'https://support.kissmetrics.com'
16
+
17
+ s.license.name = 'KISSmetrics'
18
+ s.license.url = 'https://www.kissmetrics.com'
19
+
20
+ s.host = 'api.kissmetrics.com'
21
+ s.base_path = '/core'
22
+ s.scheme(:https)
23
+ s.consume('application/json')
24
+ s.produce('application/json')
25
+ end
26
+
27
+ skeleton.define_tag('products') do
28
+ describe('The product')
29
+ end
30
+
31
+ skeleton.define_model('Link') do
32
+ describe('The link object used for api discovery')
33
+ required(:href, type: 'string')
34
+ required(:rel, type: 'string')
35
+ optional(:templated, type: 'boolean')
36
+ optional(:name, type: 'string')
37
+ end
38
+
39
+ skeleton.define_model('Error') do
40
+ describe('Represents an error')
41
+ required(:message, type: 'string')
42
+ optional(:field, type: 'string')
43
+ optional(:errors, type: 'array', items: { ref: 'Error' })
44
+ end
45
+
46
+ skeleton.define_model('Meta') do
47
+ describe('The meta information regarding the request')
48
+ required(:status, type: 'integer')
49
+ optional(:message, type: 'string')
50
+ optional(:errors, type: 'array', items: { ref: 'Error' })
51
+ end
52
+
53
+ skeleton.define_model('ErrorResponse') do
54
+ describe('The information when there is an issue with a request')
55
+ required(:meta, ref: 'Meta')
56
+ required(:links, type: 'array', items: { ref: 'Link' })
57
+ end
58
+
59
+ skeleton.define_model('WizardProperty') do
60
+ required(:name, type: 'string')
61
+ required(:value, type: 'string')
62
+ end
63
+
64
+ skeleton.define_model('WizardRules') do
65
+ required(:meta, ref: 'Meta')
66
+ required(:data, type: 'array', items: { ref: 'WizardRuleData' })
67
+ required(:links, type: 'array', items: { ref: 'Link' })
68
+ end
69
+
70
+ skeleton.define_model('WizardRuleData') do
71
+ required(:type, type: 'string')
72
+ required(:name, type: 'string')
73
+ optional(:display_name, type: 'string')
74
+ required(:visible, type: 'boolean')
75
+ end
76
+
77
+ skeleton.define_model('WizardRule') do
78
+ required(:meta, ref: 'Meta')
79
+ required(:data, type: 'array', items: { ref: 'WizardRuleData' })
80
+ required(:links, type: 'array', items: { ref: 'Link' })
81
+ end
82
+
83
+ skeleton.define_model('WizardUrlRule') do
84
+ describe('The wizard url rule')
85
+ extends('WizardRuleData')
86
+ required(:url, type: 'string')
87
+ optional(:properties, type: 'array', items: { ref: 'WizardProperty' })
88
+ end
89
+
90
+ skeleton.define_model('WizardClickRule') do
91
+ describe('The wizard click rule')
92
+ extends('WizardRuleData')
93
+ required(:data, type: 'string')
94
+ optional(:properties, type: 'array', items: { ref: 'WizardProperty' })
95
+ end
96
+
97
+ skeleton.define_model('WizardSubmitRule') do
98
+ describe('The wizard submit rule')
99
+ extends('WizardRuleData')
100
+ required(:data, type: 'string')
101
+ optional(:properties, type: 'array', items: { ref: 'WizardProperty' })
102
+ end
103
+
104
+ skeleton.define_model('WizardRegexRule') do
105
+ describe('The wizard regex rule')
106
+ extends('WizardRuleData')
107
+ required(:data, type: 'string')
108
+ optional(:properties, type: 'array', items: { ref: 'WizardProperty' })
109
+ end
110
+
111
+ skeleton.define_model('OptionsResponse') do
112
+ describe('The subset of swagger options')
113
+ end
114
+
115
+ skeleton.define_model('NewProduct') do
116
+ describe('The model required to build a product')
117
+ required(:name, type: 'string')
118
+ required(:account_id, type: 'string', format: 'uuid')
119
+ end
120
+
121
+ skeleton.define_model('ProductData') do
122
+ describe('The persisted product data')
123
+ required(:id, type: 'string', format: 'uuid')
124
+ required(:name, type: 'string')
125
+ end
126
+
127
+ skeleton.define_model('Product') do
128
+ describe('The product')
129
+ required(:meta, ref: 'Meta')
130
+ required(:data, ref: 'ProductData')
131
+ required(:links, type: 'array', items: { ref: 'Link' })
132
+ end
133
+
134
+ skeleton.define_model('UserData') do
135
+ describe('The persisted user data')
136
+ required(:id, type: 'string', format: 'uuid')
137
+ required(:login, type: 'string', format: 'email')
138
+ end
139
+
140
+ skeleton.define_model('User') do
141
+ describe('The user')
142
+ required(:meta, ref: 'Meta')
143
+ required(:data, ref: 'UserData')
144
+ required(:links, type: 'array', items: { ref: 'Link' })
145
+ end
146
+
147
+ skeleton.define_model('AccountData') do
148
+ describe('The persisted account data')
149
+ required(:id, type: 'string', format: 'uuid')
150
+ required(:name, type: 'string')
151
+ end
152
+
153
+ skeleton.define_model('Account') do
154
+ describe('The account')
155
+ required(:meta, ref: 'Meta')
156
+ required(:data, ref: 'AccountData')
157
+ required(:links, type: 'array', items: { ref: 'Link' })
158
+ end
159
+
160
+ # ##############################################################################
161
+ # ##############################################################################
162
+ skeleton.define_path('/products') do
163
+ get do
164
+ identify('list-products')
165
+ tag('product')
166
+ summarize('List products')
167
+ describe('List all of the products')
168
+
169
+ parameters(:query) do
170
+ optional(:limit, type: 'integer', format: 'int32', default: 20, maximum: 50, minimum: 0)
171
+ optional(:offset, type: 'integer', format: 'int32', default: 0)
172
+ end
173
+
174
+ response(200, default: true) do
175
+ describe('Product list')
176
+ header('Link', type: 'string', description: 'The list of links for the resource')
177
+ schema(ref: 'Product')
178
+ end
179
+
180
+ response(403) do
181
+ describe('Unauthorized')
182
+ header('Link', type: 'string', description: 'The list of links for the resource')
183
+ schema(ref: 'ErrorResponse')
184
+ end
185
+ end
186
+
187
+ head do
188
+ tag('product')
189
+ summarize('List products headers')
190
+ describe('List the headers for the products action')
191
+
192
+ parameters(:query) do
193
+ optional(:limit, type: 'integer', format: 'int32', default: 20, maximum: 50, minimum: 0)
194
+ optional(:offset, type: 'integer', format: 'int32', default: 0)
195
+ end
196
+
197
+ response(200, default: true) do
198
+ describe('Product list')
199
+ header('Link', type: 'string', description: 'The list of links for the resource')
200
+ end
201
+
202
+ response(403) do
203
+ describe('Unauthorized')
204
+ header('Link', type: 'string', description: 'The list of links for the resource')
205
+ end
206
+ end
207
+
208
+ post do
209
+ tag('product')
210
+ summarize('Create product')
211
+ describe('Create a product')
212
+
213
+ parameters(:body) do
214
+ required(:body, schema: { ref: 'NewProduct' })
215
+ end
216
+
217
+ response(201) do
218
+ describe('Product created')
219
+ header('Link', type: 'string', description: 'The list of links for the resource')
220
+ schema(ref: 'Product')
221
+ end
222
+
223
+ response(400) do
224
+ describe('Client error')
225
+ header('Link', type: 'string', description: 'The list of links for the resource')
226
+ schema(ref: 'ErrorResponse')
227
+ end
228
+
229
+ response(403) do
230
+ describe('Unauthorized')
231
+ header('Link', type: 'string', description: 'The list of links for the resource')
232
+ schema(ref: 'ErrorResponse')
233
+ end
234
+ end
235
+
236
+ options do
237
+ tag('product')
238
+ summarize('List actions for a product')
239
+ describe('List actions for a product')
240
+
241
+ parameters(:query) do
242
+ optional(:limit, type: 'integer', format: 'int32', default: 20, maximum: 50, minimum: 0)
243
+ optional(:offset, type: 'integer', format: 'int32', default: 0)
244
+ end
245
+
246
+ response(200, default: true) do
247
+ describe('Product action list')
248
+ header('Allow', type: 'array', items: { type: 'string' }, collection_format: 'csv')
249
+ header('Link', type: 'string', description: 'The list of links for the resource')
250
+ schema(ref: 'OptionsResponse')
251
+ end
252
+
253
+ response(400) do
254
+ describe('Client error')
255
+ header('Link', type: 'string', description: 'The list of links for the resource')
256
+ schema(ref: 'ErrorResponse')
257
+ end
258
+
259
+ response(403) do
260
+ describe('Unauthorized')
261
+ header('Link', type: 'string', description: 'The list of links for the resource')
262
+ schema(ref: 'ErrorResponse')
263
+ end
264
+ end
265
+ end
266
+
267
+ # ##############################################################################
268
+ # ##############################################################################
269
+ skeleton.define_path('/products/{product_id}') do
270
+ get do
271
+ tag('product')
272
+ summarize('Get product')
273
+ describe('Get product')
274
+
275
+ parameters(:path) do
276
+ required(:product_id, type: 'string', format: 'uuid', description: 'The product id')
277
+ end
278
+
279
+ response(200) do
280
+ describe('Product found')
281
+ header('Link', type: 'string', description: 'The list of links for the resource')
282
+ schema(ref: 'Product')
283
+ end
284
+
285
+ response(403) do
286
+ describe('Unauthorized')
287
+ header('Link', type: 'string', description: 'The list of links for the resource')
288
+ schema(ref: 'ErrorResponse')
289
+ end
290
+
291
+ response(404) do
292
+ describe('Not Found')
293
+ header('Link', type: 'string', description: 'The list of links for the resource')
294
+ schema(ref: 'ErrorResponse')
295
+ end
296
+ end
297
+
298
+ head do
299
+ tag('product')
300
+ summarize('Get product')
301
+ describe('Get product')
302
+
303
+ parameters(:path) do
304
+ required(:product_id, type: 'string', format: 'uuid', description: 'The product id')
305
+ end
306
+
307
+ response(200) do
308
+ describe('Product found')
309
+ header('Link', type: 'string', description: 'The list of links for the resource')
310
+ end
311
+
312
+ response(403) do
313
+ describe('Unauthorized')
314
+ header('Link', type: 'string', description: 'The list of links for the resource')
315
+ end
316
+
317
+ response(404) do
318
+ describe('Not Found')
319
+ header('Link', type: 'string', description: 'The list of links for the resource')
320
+ end
321
+ end
322
+
323
+ options do
324
+ tag('product')
325
+ summarize('Get resource actions')
326
+ describe('Get resource action')
327
+
328
+ parameters(:path) do
329
+ required(:product_id, type: 'string', format: 'uuid', description: 'The product id')
330
+ end
331
+
332
+ response(200, default: true) do
333
+ describe('Product actions')
334
+ header('Allow', type: 'array', items: { type: 'string' }, collection_format: 'csv')
335
+ header('Link', type: 'string', description: 'The list of links for the resource')
336
+ schema(ref: 'OptionsResponse')
337
+ end
338
+
339
+ response(400) do
340
+ describe('Client error')
341
+ header('Link', type: 'string', description: 'The list of links for the resource')
342
+ schema(ref: 'ErrorResponse')
343
+ end
344
+
345
+ response(403) do
346
+ describe('Unauthorized')
347
+ header('Link', type: 'string', description: 'The list of links for the resource')
348
+ schema(ref: 'ErrorResponse')
349
+ end
350
+ end
351
+ end
352
+
353
+ # ##############################################################################
354
+ # ##############################################################################
355
+ skeleton.define_path('/products/{product_id}/wizard/rules') do
356
+ get do
357
+ tag('product')
358
+ tag('event-library')
359
+ summarize('List rules for a given product')
360
+ describe('List rules for a given product')
361
+
362
+ parameters(:path) do
363
+ required(:product_id, type: 'string', format: 'uuid', description: 'The product id')
364
+ end
365
+
366
+ response(200) do
367
+ describe('Product found')
368
+ header('Link', type: 'string', description: 'The list of links for the resource')
369
+ schema(ref: 'WizardRules')
370
+ end
371
+
372
+ response(403) do
373
+ describe('Unauthorized')
374
+ header('Link', type: 'string', description: 'The list of links for the resource')
375
+ schema(ref: 'ErrorResponse')
376
+ end
377
+
378
+ response(404) do
379
+ describe('Product not found')
380
+ header('Link', type: 'string', description: 'The list of links for the resource')
381
+ schema(ref: 'ErrorResponse')
382
+ end
383
+ end
384
+
385
+ head do
386
+ tag('product')
387
+ tag('event-library')
388
+ summarize('List rules for a given product')
389
+ describe('List rules for a given product')
390
+
391
+ parameters(:path) do
392
+ required(:product_id, type: 'string', format: 'uuid', description: 'The product id')
393
+ end
394
+
395
+ response(200, default: true) do
396
+ describe('Product found')
397
+ header('Link', type: 'string', description: 'The list of links for the resource')
398
+ end
399
+
400
+ response(403) do
401
+ describe('Unauthorized')
402
+ header('Link', type: 'string', description: 'The list of links for the resource')
403
+ end
404
+
405
+ response(404) do
406
+ describe('Product not found')
407
+ header('Link', type: 'string', description: 'The list of links for the resource')
408
+ end
409
+ end
410
+
411
+ options do
412
+ tag('product')
413
+ tag('event-library')
414
+ summarize('List actions for the given product')
415
+ describe('List actions for the given product')
416
+
417
+ parameters(:path) do
418
+ required(:product_id, type: 'string', format: 'uuid', description: 'The product id')
419
+ end
420
+
421
+ response(200, default: true) do
422
+ describe('Product actions')
423
+ header('Allow', type: 'array', items: { type: 'string' }, collection_format: 'csv')
424
+ header('Link', type: 'string', description: 'The list of links for the resource')
425
+ schema(ref: 'OptionsResponse')
426
+ end
427
+
428
+ response(403) do
429
+ describe('Unauthorized')
430
+ header('Link', type: 'string', description: 'The list of links for the resource')
431
+ schema(ref: 'ErrorResponse')
432
+ end
433
+
434
+ response(404) do
435
+ describe('Product not found')
436
+ header('Link', type: 'string', description: 'The list of links for the resource')
437
+ schema(ref: 'ErrorResponse')
438
+ end
439
+ end
440
+
441
+ post do
442
+ tag('product')
443
+ tag('event-library')
444
+ summarize('Create rule for the product')
445
+ describe('Create rule for the product')
446
+ parameters(:path) do
447
+ required(:product_id, type: 'string', format: 'uuid', description: 'The product id')
448
+ end
449
+
450
+ response(201) do
451
+ describe('Rule created')
452
+ header('Link', type: 'string', description: 'The list of links for the resource')
453
+ schema(ref: 'WizardRule')
454
+ end
455
+
456
+ response(400) do
457
+ describe('Client error')
458
+ header('Link', type: 'string', description: 'The list of links for the resource')
459
+ schema(ref: 'ErrorResponse')
460
+ end
461
+
462
+ response(403) do
463
+ describe('Unauthorized')
464
+ header('Link', type: 'string', description: 'The list of links for the resource')
465
+ schema(ref: 'ErrorResponse')
466
+ end
467
+
468
+ response(404) do
469
+ describe('Product not found')
470
+ header('Link', type: 'string', description: 'The list of links for the resource')
471
+ schema(ref: 'ErrorResponse')
472
+ end
473
+ end
474
+
475
+ put do
476
+ tag('product')
477
+ tag('event-library')
478
+ summarize('Update rule for the product')
479
+ describe('Update rule for the product')
480
+ parameters(:path) do
481
+ required(:product_id, type: 'string', format: 'uuid', description: 'The product id')
482
+ end
483
+
484
+ response(200) do
485
+ describe('Rule updated')
486
+ header('Link', type: 'string', description: 'The list of links for the resource')
487
+ schema(ref: 'WizardRule')
488
+ end
489
+
490
+ response(400) do
491
+ describe('Client error')
492
+ header('Link', type: 'string', description: 'The list of links for the resource')
493
+ schema(ref: 'ErrorResponse')
494
+ end
495
+
496
+ response(403) do
497
+ describe('Unauthorized')
498
+ header('Link', type: 'string', description: 'The list of links for the resource')
499
+ schema(ref: 'ErrorResponse')
500
+ end
501
+
502
+ response(404) do
503
+ describe('Product not found')
504
+ header('Link', type: 'string', description: 'The list of links for the resource')
505
+ schema(ref: 'ErrorResponse')
506
+ end
507
+ end
508
+
509
+ delete do
510
+ identify('delete-wizard-rule')
511
+ tag('product')
512
+ tag('event-library')
513
+ summarize('Delete rule for the product')
514
+ describe('Delete rule for the product')
515
+
516
+ parameters(:path) do
517
+ required(:product_id, type: 'string', format: 'uuid', description: 'The product id')
518
+ end
519
+
520
+ response(204) do
521
+ describe('Rule deleted')
522
+ header('Link', type: 'string', description: 'The list of links for the resource')
523
+ end
524
+
525
+ response(403) do
526
+ describe('Unauthorized')
527
+ header('Link', type: 'string', description: 'The list of links for the resource')
528
+ schema(ref: 'ErrorResponse')
529
+ end
530
+
531
+ response(404) do
532
+ describe('Product not found')
533
+ header('Link', type: 'string', description: 'The list of links for the resource')
534
+ schema(ref: 'ErrorResponse')
535
+ end
536
+ end
537
+ end
538
+
539
+ skeleton
540
+ end # end #structure
541
+ end
542
+ end