runapi-core 0.3.1 → 0.3.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb5369d4bc3ec00ba92341e7151b7e1d62b6972ef3e84fd35474638da86a9926
4
- data.tar.gz: ed1fe305dba138db597e86e31421312bf0a017d9c3ed1564b0e44044a9a537a0
3
+ metadata.gz: ed0b6cfd9c5bdf13cf3eefa0908ca4daffe4eae9d73c2f57a42676bfacfb4106
4
+ data.tar.gz: 35666b5f7e5d4196e04d27c35b6c434a155781d9a54dfa489aa5f17fea9037ee
5
5
  SHA512:
6
- metadata.gz: 7c885608b3f52f9e5ab11937e032149a164a781c8f413e19d394484a7b6576b622afd82c2c152ed52ca5ff67c389f9ee40d28aef174f7553947fd888c204a1cb
7
- data.tar.gz: b0af7a1272a3f69003bb4fa80ca4848511f847dcd7a5a1e1c5678b358c90313962312ddc4f7a0f870a32de801cf2e5af94e33879fec14084ecf1b36e920be8ed
6
+ metadata.gz: e2126afb383fc59dd861c8ff3e08fc248b05ddbb0d205b0f9f26e67c2a10db51022d1c0f07f19f2bb85b58dd366d9a8ed5b8be7f44116321d60b6a22dbe8cb79
7
+ data.tar.gz: f335af67d8763ea0cd6a02f31e0278b6edef4628e7d1d7e3c7c2962cdc39b285b064f36ec38439db659bc7c7c2860bde08bad28a0483a1a48a0bae0812b43115
@@ -127,7 +127,9 @@ module RunApi
127
127
 
128
128
  def multipart_parts(body)
129
129
  opened_files = []
130
- field_parts = body.fields.map { |key, value| [key, value.to_s] }
130
+ field_parts = body.fields.flat_map do |key, value|
131
+ Array(value).map { |item| [key, item.to_s] }
132
+ end
131
133
  file_parts = body.files.map do |key, file|
132
134
  options = {filename: file.filename}
133
135
  options[:content_type] = file.content_type if file.content_type
@@ -149,7 +149,9 @@ module RunApi
149
149
 
150
150
  def enum_value_allowed?(enum, value)
151
151
  enum.any? do |allowed|
152
- if allowed.is_a?(Numeric)
152
+ if allowed == true || allowed == false
153
+ value == allowed
154
+ elsif allowed.is_a?(Numeric)
153
155
  value.is_a?(Numeric) && value == allowed
154
156
  elsif value.is_a?(Numeric)
155
157
  allowed == value
@@ -161,25 +163,57 @@ module RunApi
161
163
 
162
164
  def enforce_contract_rule!(params, rule)
163
165
  conditions = rule["when"] || {}
164
- return unless conditions.all? { |field, value| rule_condition_met?(params, field, value) }
166
+ return unless conditions.all? { |field, condition| rule_condition_met?(params, field, condition) }
167
+
168
+ context = conditions.map { |field, condition| rule_condition_label(field, condition) }.join(" and ")
169
+ qualifier = context.empty? ? "" : " when #{context}"
165
170
 
166
- context = conditions.map { |field, value| "#{field} is #{value}" }.join(" and ")
167
171
  Array(rule["required"]).each do |field|
168
172
  next if field_present?(params, field)
169
173
 
170
- raise Core::ValidationError, "#{field} is required when #{context}"
174
+ raise Core::ValidationError, "#{field} is required#{qualifier}"
175
+ end
176
+
177
+ required_any = Array(rule["required_any"])
178
+ if required_any.any? && required_any.none? { |field| field_present?(params, field) }
179
+ raise Core::ValidationError, "one of #{required_any.join(", ")} is required#{qualifier}"
171
180
  end
181
+
172
182
  Array(rule["forbidden"]).each do |field|
173
183
  next unless field_present?(params, field)
174
184
 
175
- raise Core::ValidationError, "#{field} is not allowed when #{context}"
185
+ raise Core::ValidationError, "#{field} is not allowed#{qualifier}"
186
+ end
187
+
188
+ (rule["enum"] || {}).each do |field, allowed|
189
+ next unless field_present?(params, field)
190
+
191
+ value = param_value(params, field)
192
+ next if Array(allowed).any? { |candidate| candidate.to_s == value.to_s }
193
+
194
+ raise Core::ValidationError, "#{field} must be one of: #{Array(allowed).join(", ")}#{qualifier}"
176
195
  end
177
196
  end
178
197
 
179
- def rule_condition_met?(params, field, value)
198
+ # A `when` entry is either `{present: true|false}` or a scalar the
199
+ # supplied value must equal. Rules never resolve declared defaults.
200
+ def rule_condition_met?(params, field, condition)
201
+ if condition.is_a?(Hash) && (condition.key?("present") || condition.key?(:present))
202
+ expected = condition["present"].nil? ? condition[:present] : condition["present"]
203
+ return field_present?(params, field) == (expected == true)
204
+ end
180
205
  return false unless param_key?(params, field)
181
206
 
182
- param_value(params, field).to_s == value.to_s
207
+ param_value(params, field).to_s == condition.to_s
208
+ end
209
+
210
+ def rule_condition_label(field, condition)
211
+ if condition.is_a?(Hash) && (condition.key?("present") || condition.key?(:present))
212
+ expected = condition["present"].nil? ? condition[:present] : condition["present"]
213
+ return (expected == true) ? "#{field} is present" : "#{field} is absent"
214
+ end
215
+
216
+ "#{field} is #{condition}"
183
217
  end
184
218
 
185
219
  def field_present?(params, field)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RunApi
4
4
  module Core
5
- VERSION = "0.3.1"
5
+ VERSION = "0.3.3"
6
6
  end
7
7
 
8
8
  VERSION = Core::VERSION
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runapi-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - RunAPI