haveapi 0.20.0 → 0.21.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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Rakefile +6 -6
  4. data/haveapi.gemspec +13 -13
  5. data/lib/haveapi/action.rb +153 -167
  6. data/lib/haveapi/action_state.rb +2 -6
  7. data/lib/haveapi/actions/default.rb +8 -10
  8. data/lib/haveapi/api.rb +2 -1
  9. data/lib/haveapi/authentication/base.rb +5 -8
  10. data/lib/haveapi/authentication/basic/provider.rb +4 -5
  11. data/lib/haveapi/authentication/chain.rb +19 -17
  12. data/lib/haveapi/authentication/oauth2/config.rb +12 -32
  13. data/lib/haveapi/authentication/oauth2/provider.rb +20 -30
  14. data/lib/haveapi/authentication/oauth2/revoke_endpoint.rb +1 -2
  15. data/lib/haveapi/authentication/token/action_config.rb +5 -3
  16. data/lib/haveapi/authentication/token/config.rb +5 -5
  17. data/lib/haveapi/authentication/token/provider.rb +33 -37
  18. data/lib/haveapi/authorization.rb +10 -4
  19. data/lib/haveapi/client_example.rb +11 -14
  20. data/lib/haveapi/client_examples/curl.rb +37 -37
  21. data/lib/haveapi/client_examples/fs_client.rb +29 -31
  22. data/lib/haveapi/client_examples/http.rb +35 -36
  23. data/lib/haveapi/client_examples/js_client.rb +62 -63
  24. data/lib/haveapi/client_examples/php_client.rb +77 -76
  25. data/lib/haveapi/client_examples/ruby_cli.rb +30 -30
  26. data/lib/haveapi/client_examples/ruby_client.rb +26 -26
  27. data/lib/haveapi/common.rb +3 -4
  28. data/lib/haveapi/context.rb +11 -10
  29. data/lib/haveapi/example.rb +9 -4
  30. data/lib/haveapi/example_list.rb +2 -2
  31. data/lib/haveapi/exceptions.rb +1 -1
  32. data/lib/haveapi/extensions/action_exceptions.rb +2 -2
  33. data/lib/haveapi/extensions/base.rb +1 -3
  34. data/lib/haveapi/extensions/exception_mailer.rb +260 -257
  35. data/lib/haveapi/hooks.rb +40 -39
  36. data/lib/haveapi/metadata.rb +1 -1
  37. data/lib/haveapi/model_adapter.rb +16 -27
  38. data/lib/haveapi/model_adapters/active_record.rb +59 -69
  39. data/lib/haveapi/output_formatter.rb +7 -7
  40. data/lib/haveapi/output_formatters/base.rb +2 -4
  41. data/lib/haveapi/parameters/resource.rb +7 -7
  42. data/lib/haveapi/parameters/typed.rb +6 -9
  43. data/lib/haveapi/params.rb +38 -45
  44. data/lib/haveapi/resource.rb +8 -8
  45. data/lib/haveapi/resources/action_state.rb +11 -19
  46. data/lib/haveapi/server.rb +102 -107
  47. data/lib/haveapi/spec/api_response.rb +1 -1
  48. data/lib/haveapi/spec/helpers.rb +1 -1
  49. data/lib/haveapi/spec/mock_action.rb +11 -10
  50. data/lib/haveapi/spec/spec_methods.rb +9 -8
  51. data/lib/haveapi/tasks/yard.rb +2 -2
  52. data/lib/haveapi/types.rb +0 -3
  53. data/lib/haveapi/validator.rb +6 -3
  54. data/lib/haveapi/validator_chain.rb +9 -8
  55. data/lib/haveapi/validators/acceptance.rb +6 -6
  56. data/lib/haveapi/validators/confirmation.rb +2 -3
  57. data/lib/haveapi/validators/exclusion.rb +1 -1
  58. data/lib/haveapi/validators/format.rb +1 -1
  59. data/lib/haveapi/validators/inclusion.rb +1 -1
  60. data/lib/haveapi/validators/length.rb +12 -11
  61. data/lib/haveapi/validators/numericality.rb +14 -13
  62. data/lib/haveapi/validators/presence.rb +4 -3
  63. data/lib/haveapi/version.rb +2 -2
  64. data/lib/haveapi.rb +2 -3
  65. data/spec/.rubocop.yml +4 -0
  66. data/spec/action/dsl_spec.rb +18 -18
  67. data/spec/authorization_spec.rb +8 -8
  68. data/spec/common_spec.rb +2 -1
  69. data/spec/documentation_spec.rb +2 -9
  70. data/spec/envelope_spec.rb +2 -2
  71. data/spec/hooks_spec.rb +12 -12
  72. data/spec/parameters/typed_spec.rb +6 -6
  73. data/spec/params_spec.rb +22 -24
  74. data/spec/resource_spec.rb +5 -7
  75. data/spec/spec_helper.rb +0 -1
  76. data/spec/validators/acceptance_spec.rb +1 -1
  77. data/spec/validators/confirmation_spec.rb +5 -5
  78. data/spec/validators/exclusion_spec.rb +3 -3
  79. data/spec/validators/format_spec.rb +2 -2
  80. data/spec/validators/inclusion_spec.rb +4 -4
  81. data/spec/validators/length_spec.rb +23 -23
  82. data/spec/validators/numericality_spec.rb +13 -13
  83. data/spec/validators/presence_spec.rb +3 -3
  84. metadata +49 -48
@@ -1,18 +1,13 @@
1
1
  module HaveAPI
2
2
  module Parameters
3
-
4
3
  end
5
4
 
6
- class ValidationError < Exception
5
+ class ValidationError < StandardError
7
6
  def initialize(msg, errors = {})
8
- @msg = msg
7
+ super(msg)
9
8
  @errors = errors
10
9
  end
11
10
 
12
- def message
13
- @msg
14
- end
15
-
16
11
  def to_hash
17
12
  @errors
18
13
  end
@@ -57,7 +52,7 @@ module HaveAPI
57
52
  def layout
58
53
  return @cache[:layout] if @cache[:layout]
59
54
 
60
- @cache[:layout] = @layout ? @layout : :object
55
+ @cache[:layout] = @layout || :object
61
56
  end
62
57
 
63
58
  def layout=(l)
@@ -69,7 +64,7 @@ module HaveAPI
69
64
  return @cache[:namespace] = @namespace unless @namespace.nil?
70
65
 
71
66
  n = @action.resource.resource_name.underscore
72
- n = n.pluralize if %i(object_list hash_list).include?(layout)
67
+ n = n.pluralize if %i[object_list hash_list].include?(layout)
73
68
  @cache[:namespace] = n.to_sym
74
69
  end
75
70
 
@@ -106,8 +101,8 @@ module HaveAPI
106
101
  add_param(name, apply(kwargs, type: Integer))
107
102
  end
108
103
 
109
- alias_method :id, :integer
110
- alias_method :foreign_key, :integer
104
+ alias id integer
105
+ alias foreign_key integer
111
106
 
112
107
  def float(name, **kwargs)
113
108
  add_param(name, apply(kwargs, type: Float))
@@ -127,33 +122,33 @@ module HaveAPI
127
122
 
128
123
  block = @action.resource.params(name)
129
124
 
130
- if block
131
- @include_back << @include.clone if @include
132
- @exclude_back << @exclude.clone if @exclude
125
+ return unless block
133
126
 
134
- if include
135
- @include ||= []
136
- @include.concat(include)
137
- end
127
+ @include_back << @include.clone if @include
128
+ @exclude_back << @exclude.clone if @exclude
138
129
 
139
- if exclude
140
- @exclude ||= []
141
- @exclude.concat(exclude)
142
- end
143
-
144
- instance_eval(&block)
130
+ if include
131
+ @include ||= []
132
+ @include.concat(include)
133
+ end
145
134
 
146
- @include = @include_back.pop if @include
147
- @exclude = @exclude_back.pop if @exclude
135
+ if exclude
136
+ @exclude ||= []
137
+ @exclude.concat(exclude)
148
138
  end
139
+
140
+ instance_eval(&block)
141
+
142
+ @include = @include_back.pop if @include
143
+ @exclude = @exclude_back.pop if @exclude
149
144
  end
150
145
 
151
146
  def resource(name, **kwargs)
152
147
  add_resource(name, kwargs)
153
148
  end
154
149
 
155
- alias_method :references, :resource
156
- alias_method :belongs_to, :resource
150
+ alias references resource
151
+ alias belongs_to resource
157
152
 
158
153
  def patch(name, **changes)
159
154
  @params.detect { |p| p.name == name }.patch(changes)
@@ -167,7 +162,7 @@ module HaveAPI
167
162
  def describe(context)
168
163
  context.layout = layout
169
164
 
170
- ret = {parameters: {}}
165
+ ret = { parameters: {} }
171
166
  ret[:layout] = layout
172
167
  ret[:namespace] = namespace
173
168
  ret[:format] = @structure if @structure
@@ -176,17 +171,17 @@ module HaveAPI
176
171
  ret[:parameters][p.name] = p.describe(context)
177
172
  end
178
173
 
179
- if @direction == :input
180
- ret[:parameters] = context.authorization.filter_input(
181
- @params,
182
- ModelAdapters::Hash.output(context, ret[:parameters])
183
- )
184
- else
185
- ret[:parameters] = context.authorization.filter_output(
186
- @params,
187
- ModelAdapters::Hash.output(context, ret[:parameters])
188
- )
189
- end
174
+ ret[:parameters] = if @direction == :input
175
+ context.authorization.filter_input(
176
+ @params,
177
+ ModelAdapters::Hash.output(context, ret[:parameters])
178
+ )
179
+ else
180
+ context.authorization.filter_output(
181
+ @params,
182
+ ModelAdapters::Hash.output(context, ret[:parameters])
183
+ )
184
+ end
190
185
 
191
186
  ret
192
187
  end
@@ -235,7 +230,6 @@ module HaveAPI
235
230
 
236
231
  begin
237
232
  cleaned = p.clean(input[p.name])
238
-
239
233
  rescue ValidationError => e
240
234
  errors[p.name] ||= []
241
235
  errors[p.name] << e.message
@@ -271,6 +265,7 @@ module HaveAPI
271
265
  end
272
266
 
273
267
  private
268
+
274
269
  def add_param(name, kwargs)
275
270
  p = Parameters::Typed.new(name, kwargs)
276
271
 
@@ -311,7 +306,7 @@ module HaveAPI
311
306
  end
312
307
  end
313
308
 
314
- def layout_aware(params)
309
+ def layout_aware(params, &)
315
310
  ns = namespace
316
311
 
317
312
  case layout
@@ -319,9 +314,7 @@ module HaveAPI
319
314
  yield(ns ? params[namespace] : params)
320
315
 
321
316
  when :object_list, :hash_list
322
- (ns ? params[namespace] : params).each do |object|
323
- yield(object)
324
- end
317
+ (ns ? params[namespace] : params).each(&)
325
318
 
326
319
  else
327
320
  false
@@ -11,6 +11,7 @@ module HaveAPI
11
11
  has_attr :singular, false
12
12
 
13
13
  def self.inherited(subclass)
14
+ super
14
15
  subclass.instance_variable_set(:@obj_type, obj_type)
15
16
  end
16
17
 
@@ -28,8 +29,8 @@ module HaveAPI
28
29
  end
29
30
  end
30
31
 
31
- def self.actions(&block)
32
- (@actions || []).each(&block)
32
+ def self.actions(&)
33
+ (@actions || []).each(&)
33
34
  end
34
35
 
35
36
  def self.resources
@@ -40,7 +41,6 @@ module HaveAPI
40
41
  if obj.obj_type == :resource
41
42
  yield obj
42
43
  end
43
-
44
44
  rescue NoMethodError
45
45
  next
46
46
  end
@@ -51,15 +51,15 @@ module HaveAPI
51
51
  (@resource_name ? @resource_name.to_s : to_s).demodulize
52
52
  end
53
53
 
54
- def self.resource_name=(name)
55
- @resource_name = name
54
+ class << self
55
+ attr_writer :resource_name
56
56
  end
57
57
 
58
58
  def self.rest_name
59
59
  singular ? resource_name.singularize.underscore : resource_name.tableize
60
60
  end
61
61
 
62
- def self.routes(prefix='/', resource_path: [])
62
+ def self.routes(prefix = '/', resource_path: [])
63
63
  ret = []
64
64
  prefix = "#{prefix}#{@route || rest_name}/"
65
65
  new_resource_path = resource_path + [resource_name.underscore]
@@ -73,14 +73,14 @@ module HaveAPI
73
73
  end
74
74
 
75
75
  resources do |r|
76
- ret << {r => r.routes(prefix, resource_path: new_resource_path)}
76
+ ret << { r => r.routes(prefix, resource_path: new_resource_path) }
77
77
  end
78
78
 
79
79
  ret
80
80
  end
81
81
 
82
82
  def self.describe(hash, context)
83
- ret = {description: self.desc, actions: {}, resources: {}}
83
+ ret = { description: desc, actions: {}, resources: {} }
84
84
 
85
85
  context.resource = self
86
86
 
@@ -11,16 +11,16 @@ module HaveAPI::Resources
11
11
  string :label, label: 'Label'
12
12
  bool :finished, label: 'Finished'
13
13
  bool :status, label: 'Status',
14
- desc: 'Determines whether the action is proceeding or failing'
14
+ desc: 'Determines whether the action is proceeding or failing'
15
15
  integer :current, label: 'Current progress'
16
16
  integer :total, label: 'Total',
17
- desc: 'The action is finished when current equals to total'
17
+ desc: 'The action is finished when current equals to total'
18
18
  string :unit, label: 'Unit', desc: 'Unit of current and total'
19
19
  bool :can_cancel, label: 'Can cancel',
20
- desc: 'When true, execution of this action can be cancelled'
20
+ desc: 'When true, execution of this action can be cancelled'
21
21
  datetime :created_at, label: 'Created at'
22
22
  datetime :updated_at, label: 'Updated at',
23
- desc: 'When was the progress last updated'
23
+ desc: 'When was the progress last updated'
24
24
  end
25
25
 
26
26
  module Mixin
@@ -31,15 +31,10 @@ module HaveAPI::Resources
31
31
  status: state.status,
32
32
  created_at: state.created_at,
33
33
  updated_at: state.updated_at,
34
- can_cancel: state.can_cancel?,
34
+ can_cancel: state.can_cancel?
35
35
  }
36
36
 
37
- if state.finished?
38
- hash[:finished] = true
39
-
40
- else
41
- hash[:finished] = false
42
- end
37
+ hash[:finished] = state.finished?
43
38
 
44
39
  progress = state.progress
45
40
  hash[:current] = progress[:current] || 0
@@ -56,7 +51,7 @@ module HaveAPI::Resources
56
51
  desc 'List states of pending actions'
57
52
 
58
53
  input(:hash) do
59
- string :order, choices: %w(newest oldest), default: 'newest', fill: true
54
+ string :order, choices: %w[newest oldest], default: 'newest', fill: true
60
55
  end
61
56
 
62
57
  output(:hash_list) do
@@ -92,8 +87,8 @@ module HaveAPI::Resources
92
87
  input(:hash) do
93
88
  float :timeout, label: 'Timeout', desc: 'in seconds', default: 15, fill: true
94
89
  float :update_in, label: 'Progress',
95
- desc: 'number of seconds after which the state is returned if the progress '+
96
- 'has changed'
90
+ desc: 'number of seconds after which the state is returned if the progress ' \
91
+ 'has changed'
97
92
  bool :status, desc: 'status to check with if update_in is set'
98
93
  integer :current, desc: 'progress to check with if update_in is set'
99
94
  integer :total, desc: 'progress to check with if update_in is set'
@@ -122,7 +117,7 @@ module HaveAPI::Resources
122
117
  elsif input[:update_in]
123
118
  new_state = state_to_hash(state)
124
119
 
125
- %i(status current total).each do |v|
120
+ %i[status current total].each do |v|
126
121
  return new_state if input[v] != new_state[v]
127
122
  end
128
123
  end
@@ -185,14 +180,11 @@ module HaveAPI::Resources
185
180
  else
186
181
  error('cancellation failed')
187
182
  end
188
-
189
183
  rescue RuntimeError, NotImplementedError => e
190
184
  error(e.message)
191
185
  end
192
186
 
193
- def state_id
194
- @state_id
195
- end
187
+ attr_reader :state_id
196
188
  end
197
189
  end
198
190
  end