apipie-bindings 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9e2b6c74e6f5eabc3b2c279de947f3d8249fd978
4
- data.tar.gz: bac12a5d7f2d0c2bf25ca97fc1430c5767dd3aba
3
+ metadata.gz: ff423fb9cfff64a08d97f4a3709b25e03efa1289
4
+ data.tar.gz: 589750c97d73e14a76480b7f286652706fcb2871
5
5
  SHA512:
6
- metadata.gz: 6c6cc3e9a3bbacc815c2d775bc72face007584478f80e245102edd325617699e48963632471be919d5a81d44d3b422bfcbc002f92a4129134c82711121ed64e5
7
- data.tar.gz: 4149592d5f3f8424080881f0cd124caf2d3bbe506c6e13daf986eca4f362e2746f148e575400ed8c2b268917b454f0590b2eca0c9aa26a7494587d67a6c4ce44
6
+ metadata.gz: d98b130b8d4bfc3d0f8b8b55da47491ab310d0a3bc5a9bfc6486863d02153bcff05656584225a164e7b746b4f32dcf998fb5f38faf6e1d0faae3884878abd7f9
7
+ data.tar.gz: eefe52e4281fde2e644eb2be132d2f4045d9803966f8ab4016a8f2fb1b9adb158d75ac0e29c9e35ea24e803870ee694f433c16570726aa4add3f23b2fd075522
data/doc/release_notes.md CHANGED
@@ -1,6 +1,9 @@
1
1
  Release notes
2
2
  =============
3
3
 
4
+ ### 0.0.10 (2014-09-18)
5
+ * apipie-bindings should enforce required params, BZ 1116803 ([#6820](http://projects.theforeman.org/issues/6820))
6
+
4
7
  ### 0.0.9 (2014-08-29)
5
8
  * Fixes RHBZ#1134954 - Log API errors that are re-risen with debug verbosity
6
9
  * Add apidoc_cache_base_dir option to move all caches to another dir
@@ -1,3 +1,5 @@
1
+ require 'apipie_bindings/utilities'
2
+
1
3
  module ApipieBindings
2
4
 
3
5
  class Action
@@ -56,16 +58,34 @@ module ApipieBindings
56
58
  end
57
59
 
58
60
  def validate!(params)
59
- # return unless params.is_a?(Hash)
61
+ missing_params = missing_params(api_params_tree { |par| par.required? }, params_tree(params))
62
+ raise ApipieBindings::MissingArgumentsError.new(missing_params) unless missing_params.empty?
63
+ end
64
+
65
+ def api_params_tree(&block)
66
+ ApipieBindings::Utilities.params_hash_tree(self.params, &block)
67
+ end
60
68
 
61
- # invalid_keys = params.keys.map(&:to_s) - (rules.is_a?(Hash) ? rules.keys : rules)
62
- # raise ArgumentError, "Invalid keys: #{invalid_keys.join(", ")}" unless invalid_keys.empty?
69
+ def params_tree(params)
70
+ params.inject([]) do |tree, (key, val)|
71
+ subtree = val.is_a?(Hash) ? { key.to_s => params_tree(val) } : key.to_s
72
+ tree << subtree
73
+ tree
74
+ end
75
+ end
63
76
 
64
- # if rules.is_a? Hash
65
- # rules.each do |key, sub_keys|
66
- # validate_params!(params[key], sub_keys) if params[key]
67
- # end
68
- # end
77
+ def missing_params(master, slave)
78
+ missing = []
79
+ master.each do |required_param|
80
+ if required_param.is_a?(Hash)
81
+ key = required_param.keys.first
82
+ slave_hash = slave.select { |p| p.is_a?(Hash) && p[key] }
83
+ missing << missing_params(required_param[key], slave_hash.first ? slave_hash.first[key] : [])
84
+ else
85
+ missing << required_param unless slave.include?(required_param)
86
+ end
87
+ end
88
+ missing.flatten.sort
69
89
  end
70
90
 
71
91
  def to_s
@@ -148,7 +148,7 @@ module ApipieBindings
148
148
  resource = resource(resource_name)
149
149
  action = resource.action(action_name)
150
150
  route = action.find_route(params)
151
- #action.validate(params)
151
+ action.validate!(params)
152
152
  options[:fake_response] = find_match(fake_responses, resource_name, action_name, params) || action.examples.first if dry_run?
153
153
  return http_call(
154
154
  route.method,
@@ -3,4 +3,13 @@ module ApipieBindings
3
3
  class ConfigurationError < StandardError; end
4
4
  class DocLoadingError < StandardError; end
5
5
 
6
+ class MissingArgumentsError < StandardError
7
+ attr_reader :params
8
+
9
+ def initialize(params)
10
+ @params = params
11
+ end
12
+
13
+ end
14
+
6
15
  end
@@ -1,3 +1,5 @@
1
+ require 'apipie_bindings/utilities'
2
+
1
3
  module ApipieBindings
2
4
 
3
5
  class Param
@@ -11,10 +13,14 @@ module ApipieBindings
11
13
  @params = params.map { |p| ApipieBindings::Param.new(p) }
12
14
  @expected_type = param[:expected_type].to_sym
13
15
  @description = param[:description].gsub(/<\/?[^>]+?>/, "")
14
- @required = param[:required]
16
+ @required = param[:required] || @params.inject(false) { |req, par| req ||= par.required? }
15
17
  @validator = param[:validator]
16
18
  end
17
19
 
20
+ def tree(&block)
21
+ ApipieBindings::Utilities.params_hash_tree(@params, &block)
22
+ end
23
+
18
24
  def required?
19
25
  @required
20
26
  end
@@ -0,0 +1,18 @@
1
+ module ApipieBindings
2
+
3
+ module Utilities
4
+
5
+ def self.params_hash_tree(params_hash, &block)
6
+ block ||= lambda { |_| true }
7
+ params_hash.inject([]) do |tree, par|
8
+ if block.call(par)
9
+ subtree = par.expected_type == :hash ? { par.name => par.tree(&block) } : par.name
10
+ tree << subtree
11
+ end
12
+ tree
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -1,5 +1,5 @@
1
1
  module ApipieBindings
2
2
  def self.version
3
- @version ||= Gem::Version.new '0.0.9'
3
+ @version ||= Gem::Version.new '0.0.10'
4
4
  end
5
5
  end
@@ -41,8 +41,20 @@ describe ApipieBindings::Action do
41
41
  # incuded params in alphanumeric order.
42
42
 
43
43
 
44
- it "should validate the params" do
45
- resource.action(:create).validate!({ :architecture => { :name => 'i386' } })
44
+ it "should validate incorrect params" do
45
+ proc do
46
+ resource.action(:create).validate!({ :architecture => { :foo => "foo" } })
47
+ end.must_raise(ApipieBindings::MissingArgumentsError)
48
+
49
+ proc do
50
+ # completely different sub-hash; should still fail
51
+ resource.action(:create).validate!({ :organization => { :name => "acme" } })
52
+ end.must_raise(ApipieBindings::MissingArgumentsError)
53
+ end
54
+
55
+ it "should accept correct params" do
56
+ resource.action(:create).validate!({:architecture => { :name => 'i386' } })
57
+ resource.action(:create_unnested).validate!(:name => "i386")
46
58
  end
47
59
 
48
60
  it "should have name visible in puts" do
@@ -145,6 +145,44 @@
145
145
  }
146
146
  ],
147
147
  "see": []
148
+ },
149
+ {
150
+ "apis": [
151
+ {
152
+ "api_url": "/api/architectures",
153
+ "http_method": "POST",
154
+ "short_description": "create an architecture."
155
+ }
156
+ ],
157
+ "doc_url": "/apidoc/v2/architectures/create",
158
+ "errors": [],
159
+ "examples" : [
160
+ "same as nested create"
161
+ ],
162
+ "formats": null,
163
+ "full_description": "",
164
+ "name": "create_unnested",
165
+ "params":[
166
+ {
167
+ "allow_nil": false,
168
+ "description": "",
169
+ "expected_type": "string",
170
+ "full_name": "architecture[name]",
171
+ "name": "name",
172
+ "required": true,
173
+ "validator": "Must be String"
174
+ },
175
+ {
176
+ "allow_nil": false,
177
+ "description": "\n<p>Operatingsystem ID\u2019s</p>\n",
178
+ "expected_type": "array",
179
+ "full_name": "architecture[operatingsystem_ids]",
180
+ "name": "operatingsystem_ids",
181
+ "required": false,
182
+ "validator": "Must be Array"
183
+ }
184
+ ],
185
+ "see": []
148
186
  }
149
187
  ]
150
188
  }
@@ -6,7 +6,7 @@ describe ApipieBindings::Resource do
6
6
  :apidoc_cache_name => 'architecture'}).resource(:architectures) }
7
7
 
8
8
  it "should list actions" do
9
- resource.actions.map(&:name).must_equal [:index, :show, :create]
9
+ resource.actions.map(&:name).must_equal [:index, :show, :create, :create_unnested]
10
10
  end
11
11
 
12
12
  it "should test action existence" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apipie-bindings
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Bačovský
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-29 00:00:00.000000000 Z
11
+ date: 2014-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -214,6 +214,7 @@ files:
214
214
  - lib/apipie_bindings/resource.rb
215
215
  - lib/apipie_bindings/rest_client_oauth.rb
216
216
  - lib/apipie_bindings/route.rb
217
+ - lib/apipie_bindings/utilities.rb
217
218
  - lib/apipie_bindings/version.rb
218
219
  - test/unit/action_test.rb
219
220
  - test/unit/api_test.rb