haveapi 0.27.1 → 0.27.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 +4 -4
- data/haveapi.gemspec +1 -1
- data/lib/haveapi/model_adapters/active_record.rb +10 -3
- data/lib/haveapi/parameters/resource.rb +15 -3
- data/lib/haveapi/parameters/typed.rb +16 -3
- data/lib/haveapi/resources/action_state.rb +5 -4
- data/lib/haveapi/version.rb +1 -1
- data/spec/model_adapters/active_record_spec.rb +2 -2
- data/spec/parameters/typed_spec.rb +41 -3
- data/test_support/client_test_api.rb +49 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ec45b62af7fa8653e5f1a304b57746a9a2858db8b75c6a1d8a3deb5536cc7946
|
|
4
|
+
data.tar.gz: 0a991e394ccf4a4629f8d755fcfdfa9fd76af6fe37c696d361c1d9340ea8763c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 693eb912e8215aa93c1c7b009475d91a752bfee1a2d4faeb33d59728168def03128dc7738c264e52f6cef3a87b7e7e11362a4da2f227deb057a9a89e50813705
|
|
7
|
+
data.tar.gz: e11fd922568a2ed631a702ec71e8e4631759bee27ecd122029e50af3fb389cde4f7167a0c26876b79b1db220d434b4c3117cb338e1a1fb3f529d85675fa91f1d
|
data/haveapi.gemspec
CHANGED
|
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
|
15
15
|
s.required_ruby_version = ">= #{File.read('../../.ruby-version').strip}"
|
|
16
16
|
|
|
17
17
|
s.add_dependency 'activesupport', '>= 7.1'
|
|
18
|
-
s.add_dependency 'haveapi-client', '~> 0.27.
|
|
18
|
+
s.add_dependency 'haveapi-client', '~> 0.27.3'
|
|
19
19
|
s.add_dependency 'json'
|
|
20
20
|
s.add_dependency 'mail'
|
|
21
21
|
s.add_dependency 'nesty', '~> 1.0'
|
|
@@ -142,15 +142,22 @@ module HaveAPI::ModelAdapters
|
|
|
142
142
|
|
|
143
143
|
class Input < ::HaveAPI::ModelAdapter::Input
|
|
144
144
|
def self.clean(model, raw, extra)
|
|
145
|
-
return nil if raw.nil?
|
|
146
|
-
|
|
147
145
|
original = raw
|
|
146
|
+
allow_null = if extra
|
|
147
|
+
extra.has_key?(:nullable) ? extra[:nullable] : extra[:optional]
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
if raw.nil?
|
|
151
|
+
return nil if allow_null
|
|
152
|
+
|
|
153
|
+
raise HaveAPI::ValidationError, "not a valid id #{original.inspect}"
|
|
154
|
+
end
|
|
148
155
|
|
|
149
156
|
if raw.is_a?(String)
|
|
150
157
|
stripped = raw.strip
|
|
151
158
|
|
|
152
159
|
if stripped.empty?
|
|
153
|
-
return nil if
|
|
160
|
+
return nil if allow_null
|
|
154
161
|
|
|
155
162
|
raise HaveAPI::ValidationError, "not a valid id #{original.inspect}"
|
|
156
163
|
end
|
|
@@ -5,7 +5,7 @@ module HaveAPI::Parameters
|
|
|
5
5
|
|
|
6
6
|
def initialize(resource, name: nil, label: nil, desc: nil,
|
|
7
7
|
choices: nil, value_id: :id, value_label: :label, required: nil,
|
|
8
|
-
db_name: nil, fetch: nil)
|
|
8
|
+
db_name: nil, fetch: nil, nullable: nil)
|
|
9
9
|
@resource = resource
|
|
10
10
|
@resource_path = build_resource_path(resource)
|
|
11
11
|
@name = name || resource.resource_name.underscore.to_sym
|
|
@@ -15,6 +15,7 @@ module HaveAPI::Parameters
|
|
|
15
15
|
@value_id = value_id
|
|
16
16
|
@value_label = value_label
|
|
17
17
|
@required = required
|
|
18
|
+
@nullable = nullable
|
|
18
19
|
@db_name = db_name
|
|
19
20
|
@extra = {
|
|
20
21
|
fetch:
|
|
@@ -33,6 +34,10 @@ module HaveAPI::Parameters
|
|
|
33
34
|
!@required
|
|
34
35
|
end
|
|
35
36
|
|
|
37
|
+
def nullable?
|
|
38
|
+
@nullable == true && optional?
|
|
39
|
+
end
|
|
40
|
+
|
|
36
41
|
def show_action
|
|
37
42
|
@resource::Show
|
|
38
43
|
end
|
|
@@ -56,6 +61,7 @@ module HaveAPI::Parameters
|
|
|
56
61
|
|
|
57
62
|
{
|
|
58
63
|
required: required?,
|
|
64
|
+
nullable: nullable?,
|
|
59
65
|
label: @label,
|
|
60
66
|
description: @desc,
|
|
61
67
|
type: 'Resource',
|
|
@@ -92,12 +98,18 @@ module HaveAPI::Parameters
|
|
|
92
98
|
end
|
|
93
99
|
|
|
94
100
|
def clean(raw)
|
|
101
|
+
if raw.nil?
|
|
102
|
+
return nil if nullable?
|
|
103
|
+
|
|
104
|
+
raise HaveAPI::ValidationError, 'cannot be null'
|
|
105
|
+
end
|
|
106
|
+
|
|
95
107
|
if raw.is_a?(String)
|
|
96
108
|
stripped = raw.strip
|
|
97
|
-
return nil if stripped.empty? &&
|
|
109
|
+
return nil if stripped.empty? && nullable?
|
|
98
110
|
end
|
|
99
111
|
|
|
100
|
-
extra = @extra.merge(optional: optional?)
|
|
112
|
+
extra = @extra.merge(optional: optional?, nullable: nullable?)
|
|
101
113
|
|
|
102
114
|
::HaveAPI::ModelAdapter.for(
|
|
103
115
|
show_action.input.layout, @resource.model
|
|
@@ -2,7 +2,7 @@ require 'date'
|
|
|
2
2
|
|
|
3
3
|
module HaveAPI::Parameters
|
|
4
4
|
class Typed
|
|
5
|
-
ATTRIBUTES = %i[label desc type db_name default fill clean protected load_validators].freeze
|
|
5
|
+
ATTRIBUTES = %i[label desc type db_name default fill clean protected load_validators nullable].freeze
|
|
6
6
|
|
|
7
7
|
attr_reader :name, :label, :desc, :type, :default
|
|
8
8
|
|
|
@@ -36,6 +36,10 @@ module HaveAPI::Parameters
|
|
|
36
36
|
!required?
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
def nullable?
|
|
40
|
+
@nullable == true && optional?
|
|
41
|
+
end
|
|
42
|
+
|
|
39
43
|
def fill?
|
|
40
44
|
@fill
|
|
41
45
|
end
|
|
@@ -47,6 +51,7 @@ module HaveAPI::Parameters
|
|
|
47
51
|
def describe(context)
|
|
48
52
|
{
|
|
49
53
|
required: required?,
|
|
54
|
+
nullable: nullable?,
|
|
50
55
|
label: @label,
|
|
51
56
|
description: @desc,
|
|
52
57
|
type: @type ? @type.to_s : String.to_s,
|
|
@@ -76,9 +81,17 @@ module HaveAPI::Parameters
|
|
|
76
81
|
return instance_exec(raw, &@clean) if @clean
|
|
77
82
|
|
|
78
83
|
if raw.nil?
|
|
79
|
-
|
|
84
|
+
return nil if nullable?
|
|
85
|
+
|
|
86
|
+
raise HaveAPI::ValidationError, 'cannot be null'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
if raw.is_a?(String)
|
|
90
|
+
stripped = raw.strip
|
|
91
|
+
return nil if stripped.empty? && nullable?
|
|
92
|
+
end
|
|
80
93
|
|
|
81
|
-
|
|
94
|
+
if @type.nil?
|
|
82
95
|
nil
|
|
83
96
|
|
|
84
97
|
elsif @type == Integer
|
|
@@ -85,10 +85,11 @@ module HaveAPI::Resources
|
|
|
85
85
|
float :timeout, label: 'Timeout', desc: 'in seconds', default: 15, fill: true
|
|
86
86
|
float :update_in, label: 'Progress',
|
|
87
87
|
desc: 'number of seconds after which the state is returned if the progress ' \
|
|
88
|
-
'has changed'
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
integer :
|
|
88
|
+
'has changed',
|
|
89
|
+
nullable: true
|
|
90
|
+
bool :status, desc: 'status to check with if update_in is set', nullable: true
|
|
91
|
+
integer :current, desc: 'progress to check with if update_in is set', nullable: true
|
|
92
|
+
integer :total, desc: 'progress to check with if update_in is set', nullable: true
|
|
92
93
|
end
|
|
93
94
|
|
|
94
95
|
output(:hash) do
|
data/lib/haveapi/version.rb
CHANGED
|
@@ -343,8 +343,8 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
343
343
|
expect(described_class::Input.clean(ARAdapterSpec::Environment, 1, {})).to eq(environment)
|
|
344
344
|
expect(described_class::Input.clean(ARAdapterSpec::Environment, '1', {})).to eq(environment)
|
|
345
345
|
expect(described_class::Input.clean(ARAdapterSpec::Environment, 1.0, {})).to eq(environment)
|
|
346
|
-
expect(described_class::Input.clean(ARAdapterSpec::Environment, '', {
|
|
347
|
-
expect(described_class::Input.clean(ARAdapterSpec::Environment, ' ', {
|
|
346
|
+
expect(described_class::Input.clean(ARAdapterSpec::Environment, '', { nullable: true })).to be_nil
|
|
347
|
+
expect(described_class::Input.clean(ARAdapterSpec::Environment, ' ', { nullable: true })).to be_nil
|
|
348
348
|
|
|
349
349
|
expect do
|
|
350
350
|
described_class::Input.clean(ARAdapterSpec::Environment, 'abc', {})
|
|
@@ -79,10 +79,14 @@ describe 'Parameters::Typed' do
|
|
|
79
79
|
expect { p.clean('abc') }.to raise_error(HaveAPI::ValidationError)
|
|
80
80
|
expect { p.clean('12abc') }.to raise_error(HaveAPI::ValidationError)
|
|
81
81
|
expect { p.clean('') }.to raise_error(HaveAPI::ValidationError)
|
|
82
|
+
expect { p.clean(nil) }.to raise_error(HaveAPI::ValidationError)
|
|
82
83
|
expect { p.clean('12.0') }.to raise_error(HaveAPI::ValidationError)
|
|
83
84
|
expect { p.clean(12.3) }.to raise_error(HaveAPI::ValidationError)
|
|
84
85
|
expect { p.clean(true) }.to raise_error(HaveAPI::ValidationError)
|
|
85
86
|
|
|
87
|
+
p = p_arg(type: Integer, required: true)
|
|
88
|
+
expect { p.clean('') }.to raise_error(HaveAPI::ValidationError)
|
|
89
|
+
|
|
86
90
|
# Float
|
|
87
91
|
p = p_type(Float)
|
|
88
92
|
expect(p.clean('3.1456')).to eq(3.1456)
|
|
@@ -90,10 +94,14 @@ describe 'Parameters::Typed' do
|
|
|
90
94
|
expect(p.clean(3)).to eq(3.0)
|
|
91
95
|
expect { p.clean('abc') }.to raise_error(HaveAPI::ValidationError)
|
|
92
96
|
expect { p.clean('') }.to raise_error(HaveAPI::ValidationError)
|
|
97
|
+
expect { p.clean(nil) }.to raise_error(HaveAPI::ValidationError)
|
|
93
98
|
expect { p.clean('NaN') }.to raise_error(HaveAPI::ValidationError)
|
|
94
99
|
expect { p.clean(Float::NAN) }.to raise_error(HaveAPI::ValidationError)
|
|
95
100
|
expect { p.clean(Float::INFINITY) }.to raise_error(HaveAPI::ValidationError)
|
|
96
101
|
|
|
102
|
+
p = p_arg(type: Float, required: true)
|
|
103
|
+
expect { p.clean('') }.to raise_error(HaveAPI::ValidationError)
|
|
104
|
+
|
|
97
105
|
# Boolean
|
|
98
106
|
p = p_type(Boolean)
|
|
99
107
|
|
|
@@ -110,8 +118,12 @@ describe 'Parameters::Typed' do
|
|
|
110
118
|
expect(p.clean(' YES ')).to be true
|
|
111
119
|
expect { p.clean('maybe') }.to raise_error(HaveAPI::ValidationError)
|
|
112
120
|
expect { p.clean('') }.to raise_error(HaveAPI::ValidationError)
|
|
121
|
+
expect { p.clean(nil) }.to raise_error(HaveAPI::ValidationError)
|
|
113
122
|
expect { p.clean(2) }.to raise_error(HaveAPI::ValidationError)
|
|
114
123
|
|
|
124
|
+
p = p_arg(type: Boolean, required: true)
|
|
125
|
+
expect { p.clean('') }.to raise_error(HaveAPI::ValidationError)
|
|
126
|
+
|
|
115
127
|
# Datetime
|
|
116
128
|
p = p_type(Datetime)
|
|
117
129
|
t = Time.now
|
|
@@ -120,10 +132,15 @@ describe 'Parameters::Typed' do
|
|
|
120
132
|
expect(p.clean(t.iso8601)).to eq(t2)
|
|
121
133
|
expect { p.clean('bzz') }.to raise_error(HaveAPI::ValidationError)
|
|
122
134
|
expect { p.clean('') }.to raise_error(HaveAPI::ValidationError)
|
|
135
|
+
expect { p.clean(nil) }.to raise_error(HaveAPI::ValidationError)
|
|
136
|
+
|
|
137
|
+
p = p_arg(type: Datetime, required: true)
|
|
138
|
+
expect { p.clean('') }.to raise_error(HaveAPI::ValidationError)
|
|
123
139
|
|
|
124
140
|
# String, Text
|
|
125
141
|
p = p_type(String)
|
|
126
142
|
expect(p.clean('bzz')).to eq('bzz')
|
|
143
|
+
expect(p.clean('')).to eq('')
|
|
127
144
|
expect(p.clean(123)).to eq('123')
|
|
128
145
|
expect(p.clean(true)).to eq('true')
|
|
129
146
|
expect { p.clean([]) }.to raise_error(HaveAPI::ValidationError)
|
|
@@ -131,17 +148,38 @@ describe 'Parameters::Typed' do
|
|
|
131
148
|
|
|
132
149
|
p = p_type(Text)
|
|
133
150
|
expect(p.clean('bzz')).to eq('bzz')
|
|
151
|
+
expect(p.clean('')).to eq('')
|
|
134
152
|
expect(p.clean(123)).to eq('123')
|
|
135
153
|
expect(p.clean(true)).to eq('true')
|
|
136
154
|
expect { p.clean([]) }.to raise_error(HaveAPI::ValidationError)
|
|
137
155
|
expect { p.clean({}) }.to raise_error(HaveAPI::ValidationError)
|
|
138
156
|
|
|
139
|
-
#
|
|
140
|
-
p =
|
|
157
|
+
# Nullable
|
|
158
|
+
p = p_arg(type: Integer, nullable: true)
|
|
159
|
+
expect(p.clean('')).to be_nil
|
|
141
160
|
expect(p.clean(nil)).to be_nil
|
|
142
161
|
|
|
162
|
+
p = p_arg(type: Float, nullable: true)
|
|
163
|
+
expect(p.clean('')).to be_nil
|
|
164
|
+
expect(p.clean(nil)).to be_nil
|
|
165
|
+
|
|
166
|
+
p = p_arg(type: Boolean, nullable: true)
|
|
167
|
+
expect(p.clean('')).to be_nil
|
|
168
|
+
expect(p.clean(nil)).to be_nil
|
|
169
|
+
|
|
170
|
+
p = p_arg(type: Datetime, nullable: true)
|
|
171
|
+
expect(p.clean('')).to be_nil
|
|
172
|
+
expect(p.clean(nil)).to be_nil
|
|
173
|
+
|
|
174
|
+
p = p_arg(type: String, nullable: true)
|
|
175
|
+
expect(p.clean('')).to be_nil
|
|
176
|
+
expect(p.clean(nil)).to be_nil
|
|
143
177
|
p.patch(default: 'bazinga')
|
|
144
|
-
expect(p.clean(nil)).to
|
|
178
|
+
expect(p.clean(nil)).to be_nil
|
|
179
|
+
|
|
180
|
+
p = p_arg(type: Text, nullable: true)
|
|
181
|
+
expect(p.clean('')).to be_nil
|
|
182
|
+
expect(p.clean(nil)).to be_nil
|
|
145
183
|
end
|
|
146
184
|
|
|
147
185
|
it 'can be protected' do
|
|
@@ -457,6 +457,54 @@ module HaveAPI
|
|
|
457
457
|
end
|
|
458
458
|
end
|
|
459
459
|
|
|
460
|
+
define_action(:EchoOptional) do
|
|
461
|
+
extend DocFilter
|
|
462
|
+
route 'echo_optional'
|
|
463
|
+
http_method :post
|
|
464
|
+
input(:hash) do
|
|
465
|
+
datetime :dt, required: false, nullable: true
|
|
466
|
+
end
|
|
467
|
+
output(:hash) do
|
|
468
|
+
bool :dt_provided, required: true
|
|
469
|
+
bool :dt_nil, required: true
|
|
470
|
+
datetime :dt
|
|
471
|
+
end
|
|
472
|
+
authorize { allow }
|
|
473
|
+
|
|
474
|
+
def exec
|
|
475
|
+
ret = {
|
|
476
|
+
dt_provided: input.has_key?(:dt),
|
|
477
|
+
dt_nil: input[:dt].nil?
|
|
478
|
+
}
|
|
479
|
+
ret[:dt] = input[:dt] unless input[:dt].nil?
|
|
480
|
+
ret
|
|
481
|
+
end
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
define_action(:EchoOptionalGet) do
|
|
485
|
+
extend DocFilter
|
|
486
|
+
route 'echo_optional_get'
|
|
487
|
+
http_method :get
|
|
488
|
+
input(:hash) do
|
|
489
|
+
datetime :dt, required: false, nullable: true
|
|
490
|
+
end
|
|
491
|
+
output(:hash) do
|
|
492
|
+
bool :dt_provided, required: true
|
|
493
|
+
bool :dt_nil, required: true
|
|
494
|
+
datetime :dt
|
|
495
|
+
end
|
|
496
|
+
authorize { allow }
|
|
497
|
+
|
|
498
|
+
def exec
|
|
499
|
+
ret = {
|
|
500
|
+
dt_provided: input.has_key?(:dt),
|
|
501
|
+
dt_nil: input[:dt].nil?
|
|
502
|
+
}
|
|
503
|
+
ret[:dt] = input[:dt] unless input[:dt].nil?
|
|
504
|
+
ret
|
|
505
|
+
end
|
|
506
|
+
end
|
|
507
|
+
|
|
460
508
|
define_action(:EchoResource) do
|
|
461
509
|
extend DocFilter
|
|
462
510
|
route 'echo_resource'
|
|
@@ -479,7 +527,7 @@ module HaveAPI
|
|
|
479
527
|
route 'echo_resource_optional'
|
|
480
528
|
http_method :get
|
|
481
529
|
input(:hash) do
|
|
482
|
-
resource HaveAPI::ClientTestAPI::Resources::Project, required: false
|
|
530
|
+
resource HaveAPI::ClientTestAPI::Resources::Project, required: false, nullable: true
|
|
483
531
|
end
|
|
484
532
|
output(:hash) do
|
|
485
533
|
bool :project_provided, required: true
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: haveapi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.27.
|
|
4
|
+
version: 0.27.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jakub Skokan
|
|
@@ -29,14 +29,14 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.27.
|
|
32
|
+
version: 0.27.3
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 0.27.
|
|
39
|
+
version: 0.27.3
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: json
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|