usps-imis-api 0.9.7 → 0.9.9
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/.rubocop.yml +3 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +20 -2
- data/Readme.md +12 -2
- data/lib/usps/imis/api.rb +16 -12
- data/lib/usps/imis/business_object.rb +17 -8
- data/lib/usps/imis/data.rb +4 -0
- data/lib/usps/imis/error.rb +2 -0
- data/lib/usps/imis/mapper.rb +23 -0
- data/lib/usps/imis/panels/base_panel.rb +10 -0
- data/lib/usps/imis/query.rb +50 -18
- data/lib/usps/imis/requests.rb +7 -3
- data/lib/usps/imis/version.rb +1 -1
- data/spec/fixtures/vcr_cassettes/.keep +0 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_authorize/automatically_refreshes_an_expired_token.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_imis_id_for/gets_the_iMIS_ID.yml +131 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_imis_id_for/with_a_query_error/wraps_errors.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_inspect/does_not_show_the_token_instance_variable.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_inspect/is_configured_to_exclude_the_token_instance_variable.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_on/chains_with_on_to_a_single_block.yml +256 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_on/nests_on_and_with.yml +256 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_on/returns_a_BusinessObject_without_a_block.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_on/sends_an_update_from_put.yml +256 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_put/sends_an_update.yml +256 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_put/when_receiving_a_response_error/wraps_the_error.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_query/collects_all_query_results.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_with/blocks_calling_imis_id_.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_with/blocks_calling_imis_id_for.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_with/sends_an_update_from_put.yml +256 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_with/sends_an_update_from_update.yml +256 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/_with/uses_a_panel_correctly.yml +145 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Api/stores_the_initial_imis_id.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_BusinessObject/_put_field/submits_the_correct_update_request.yml +627 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_BusinessObject/with_stubbed_data/_filter_fields/formats_fields_correctly.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_BusinessObject/with_stubbed_data/_get/delegation_to_get_fields/delegates_to_get_fields.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_BusinessObject/with_stubbed_data/_get/returns_multiple_values.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_BusinessObject/with_stubbed_data/_get_field/returns_a_string_value.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_BusinessObject/with_stubbed_data/_get_field/returns_an_integer_value.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_BusinessObject/with_stubbed_data/_get_fields/returns_multiple_values.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Mapper/_fetch/fetches_a_mapped_field.yml +158 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Mapper/_fetch/raises_for_unmapped_updates.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Mapper/_fetch/supports_Hash_access_syntax.yml +158 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Mapper/_fetch/supports_Hash_access_syntax_on_the_Api_directly.yml +158 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Mapper/_update/raises_for_unmapped_updates.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Mapper/_update/sends_a_mapped_update.yml +256 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Mapper/initialize_with_imis_id/stores_the_initial_imis_id.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Panels_BasePanel/requires_business_object_to_be_defined.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Panels_BasePanel/requires_payload_data_to_be_defined.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Panels_Education/api_example/_get/loads_a_specific_object.yml +146 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Panels_Education/api_example/_get/returns_specific_fields.yml +146 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Panels_Education/api_example/_get_field/returns_a_specific_field.yml +146 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Panels_Education/api_example/_get_fields/returns_specific_fields.yml +146 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Panels_Education/api_example/interacts_with_records_correctly.yml +495 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Panels_Education/initialization_with_ID/can_initialize_with_an_iMIS_ID.yml +67 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Panels_Vsc/_get/loads_a_specific_object.yml +145 -0
- data/spec/fixtures/vcr_cassettes/Usps_Imis_Panels_Vsc/handles_new_records_correctly.yml +319 -0
- data/spec/lib/usps/imis/api_spec.rb +4 -14
- data/spec/lib/usps/imis/business_object_spec.rb +63 -50
- data/spec/lib/usps/imis/data_spec.rb +9 -0
- data/spec/lib/usps/imis/mapper_spec.rb +1 -1
- data/spec/lib/usps/imis/panels/base_panel_spec.rb +1 -1
- data/spec/lib/usps/imis/panels/education_spec.rb +1 -1
- data/spec/lib/usps/imis/panels/vsc_spec.rb +1 -1
- data/spec/spec_helper.rb +40 -0
- metadata +44 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cc0ebcfc78fa3368d5901ad0e9bf03b6149ec0b2e84fecbb25e2449ba866fe09
|
|
4
|
+
data.tar.gz: 04a02698dd0936b051086fc57714a00d6fe90150f82002f3a944a47189ecd120
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 60cb55c6754bf92f8ddb804726d6dc0272bfd09c09afb912dc9e5d0fd6e0b7b4984cfe1ea9761b22c38e3a855f0b7675c492c9cb811b9afc2a1e742ebdf2fe49
|
|
7
|
+
data.tar.gz: f7824ff8fae0a47456811457ead9f91d2bd8c6a481f9b70342bb76cb66b29f93b60ce03980ea339f56baf5099e0b250f10b9f7990be0f0bc30535be3e109d76c
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
usps-imis-api (0.9.
|
|
4
|
+
usps-imis-api (0.9.9)
|
|
5
5
|
activesupport (~> 8.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -20,17 +20,24 @@ GEM
|
|
|
20
20
|
securerandom (>= 0.3)
|
|
21
21
|
tzinfo (~> 2.0, >= 2.0.5)
|
|
22
22
|
uri (>= 0.13.1)
|
|
23
|
+
addressable (2.8.7)
|
|
24
|
+
public_suffix (>= 2.0.2, < 7.0)
|
|
23
25
|
ast (2.4.3)
|
|
24
26
|
base64 (0.3.0)
|
|
25
27
|
bigdecimal (3.3.1)
|
|
28
|
+
cgi (0.5.0)
|
|
26
29
|
concurrent-ruby (1.3.5)
|
|
27
30
|
connection_pool (2.5.4)
|
|
31
|
+
crack (1.0.1)
|
|
32
|
+
bigdecimal
|
|
33
|
+
rexml
|
|
28
34
|
date (3.4.1)
|
|
29
35
|
diff-lcs (1.6.2)
|
|
30
36
|
docile (1.4.1)
|
|
31
37
|
dotenv (3.1.8)
|
|
32
38
|
drb (2.2.3)
|
|
33
39
|
erb (5.1.1)
|
|
40
|
+
hashdiff (1.2.1)
|
|
34
41
|
i18n (1.14.7)
|
|
35
42
|
concurrent-ruby (~> 1.0)
|
|
36
43
|
io-console (0.8.1)
|
|
@@ -38,7 +45,7 @@ GEM
|
|
|
38
45
|
pp (>= 0.6.0)
|
|
39
46
|
rdoc (>= 4.0.0)
|
|
40
47
|
reline (>= 0.4.2)
|
|
41
|
-
json (2.15.
|
|
48
|
+
json (2.15.2)
|
|
42
49
|
language_server-protocol (3.17.0.5)
|
|
43
50
|
lint_roller (1.1.0)
|
|
44
51
|
logger (1.7.0)
|
|
@@ -54,6 +61,7 @@ GEM
|
|
|
54
61
|
psych (5.2.6)
|
|
55
62
|
date
|
|
56
63
|
stringio
|
|
64
|
+
public_suffix (6.0.2)
|
|
57
65
|
racc (1.8.1)
|
|
58
66
|
rainbow (3.1.1)
|
|
59
67
|
rake (13.3.0)
|
|
@@ -64,6 +72,7 @@ GEM
|
|
|
64
72
|
regexp_parser (2.11.3)
|
|
65
73
|
reline (0.6.2)
|
|
66
74
|
io-console (~> 0.5)
|
|
75
|
+
rexml (3.4.4)
|
|
67
76
|
rspec (3.13.2)
|
|
68
77
|
rspec-core (~> 3.13.0)
|
|
69
78
|
rspec-expectations (~> 3.13.0)
|
|
@@ -110,12 +119,19 @@ GEM
|
|
|
110
119
|
unicode-emoji (~> 4.1)
|
|
111
120
|
unicode-emoji (4.1.0)
|
|
112
121
|
uri (1.0.4)
|
|
122
|
+
vcr (6.3.1)
|
|
123
|
+
base64
|
|
124
|
+
webmock (3.25.2)
|
|
125
|
+
addressable (>= 2.8.0)
|
|
126
|
+
crack (>= 0.3.2)
|
|
127
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
|
113
128
|
|
|
114
129
|
PLATFORMS
|
|
115
130
|
arm64-darwin-23
|
|
116
131
|
ruby
|
|
117
132
|
|
|
118
133
|
DEPENDENCIES
|
|
134
|
+
cgi (>= 0.5.0)
|
|
119
135
|
dotenv (>= 3.1.4)
|
|
120
136
|
irb (>= 1.15.2)
|
|
121
137
|
rake (>= 13.2.1)
|
|
@@ -124,6 +140,8 @@ DEPENDENCIES
|
|
|
124
140
|
rubocop-rspec (>= 3.1.0)
|
|
125
141
|
simplecov (>= 0.22.0)
|
|
126
142
|
usps-imis-api!
|
|
143
|
+
vcr (>= 6.3.1)
|
|
144
|
+
webmock (>= 3.25.2)
|
|
127
145
|
|
|
128
146
|
BUNDLED WITH
|
|
129
147
|
2.5.6
|
data/Readme.md
CHANGED
|
@@ -213,7 +213,7 @@ end
|
|
|
213
213
|
### Field Mapper
|
|
214
214
|
|
|
215
215
|
For fields that have already been mapped between the ITCom database and iMIS, you can use the
|
|
216
|
-
Mapper class to further simplify the fetch / update interfaces:
|
|
216
|
+
Mapper class to further simplify the `fetch` / `update` interfaces:
|
|
217
217
|
|
|
218
218
|
```ruby
|
|
219
219
|
mm = api.mapper.fetch(:mm)
|
|
@@ -234,6 +234,7 @@ api[:mm]
|
|
|
234
234
|
|
|
235
235
|
```ruby
|
|
236
236
|
api.update(mm: 15)
|
|
237
|
+
api[:mm] = 15
|
|
237
238
|
```
|
|
238
239
|
|
|
239
240
|
If there is no known mapping for the requested field, the Mapper will give up, but will provide
|
|
@@ -272,6 +273,7 @@ ordinal = created.raw['Identity']['IdentityElements']['$values'][1].to_i # Value
|
|
|
272
273
|
vsc.update(certificate: 'E136924', year: 2024, count: 43, ordinal: ordinal)
|
|
273
274
|
|
|
274
275
|
vsc.put_fields(ordinal, 'Quantity' => 44)
|
|
276
|
+
vsc['Quantity'] = 44
|
|
275
277
|
|
|
276
278
|
vsc.destroy(ordinal)
|
|
277
279
|
```
|
|
@@ -305,7 +307,12 @@ api.with(31092) do
|
|
|
305
307
|
mapper.update(mm: 15)
|
|
306
308
|
|
|
307
309
|
update(mm: 15)
|
|
310
|
+
|
|
311
|
+
mapper[:mm] = 15
|
|
308
312
|
end
|
|
313
|
+
|
|
314
|
+
# This request fetches the same data, but leaves the iMIS ID selected
|
|
315
|
+
api.with(31092)[:mm] = 15
|
|
309
316
|
```
|
|
310
317
|
|
|
311
318
|
```ruby
|
|
@@ -333,8 +340,9 @@ api.with(31092) do
|
|
|
333
340
|
on('ABC_ASC_Individual_Demog')['TotMMS']
|
|
334
341
|
end
|
|
335
342
|
|
|
336
|
-
#
|
|
343
|
+
# These requests fetch the same data, but leave the iMIS ID selected
|
|
337
344
|
api.with(31092).on('ABC_ASC_Individual_Demog').get_field('TotMMS')
|
|
345
|
+
api.with(31092).on('ABC_ASC_Individual_Demog')['TotMMS']
|
|
338
346
|
```
|
|
339
347
|
|
|
340
348
|
### Data Methods
|
|
@@ -369,6 +377,8 @@ Testing is available by running:
|
|
|
369
377
|
bundle exec rspec
|
|
370
378
|
```
|
|
371
379
|
|
|
380
|
+
API web requests are sanitized and recorded using VCR.
|
|
381
|
+
|
|
372
382
|
Linting is available by running:
|
|
373
383
|
|
|
374
384
|
```ruby
|
data/lib/usps/imis/api.rb
CHANGED
|
@@ -36,11 +36,10 @@ module Usps
|
|
|
36
36
|
|
|
37
37
|
# A new instance of +Api+
|
|
38
38
|
#
|
|
39
|
-
# @param skip_authentication [bool] Skip authentication on initialization (used for tests)
|
|
40
39
|
# @param imis_id [Integer, String] iMIS ID to select immediately on initialization
|
|
41
40
|
#
|
|
42
|
-
def initialize(
|
|
43
|
-
authenticate
|
|
41
|
+
def initialize(imis_id: nil)
|
|
42
|
+
authenticate
|
|
44
43
|
self.imis_id = imis_id if imis_id
|
|
45
44
|
end
|
|
46
45
|
|
|
@@ -104,9 +103,7 @@ module Usps
|
|
|
104
103
|
#
|
|
105
104
|
# @return [Hash] Response data from the API
|
|
106
105
|
#
|
|
107
|
-
def query(query_name, query_params = {})
|
|
108
|
-
Query.new(self, query_name, query_params)
|
|
109
|
-
end
|
|
106
|
+
def query(query_name, query_params = {}) = Query.new(self, query_name, **query_params)
|
|
110
107
|
|
|
111
108
|
# Run requests as DSL, with specific +BusinessObject+ only maintained for this scope
|
|
112
109
|
#
|
|
@@ -133,6 +130,11 @@ module Usps
|
|
|
133
130
|
def fetch(field_key) = mapper.fetch(field_key)
|
|
134
131
|
alias [] fetch
|
|
135
132
|
|
|
133
|
+
# Convenience alias for updating mapped fields
|
|
134
|
+
#
|
|
135
|
+
def put_field(field_key, value) = update(field_key => value)
|
|
136
|
+
alias []= put_field
|
|
137
|
+
|
|
136
138
|
# Convenience alias for updating mapped fields
|
|
137
139
|
#
|
|
138
140
|
def update(data) = mapper.update(data)
|
|
@@ -157,20 +159,22 @@ module Usps
|
|
|
157
159
|
def authenticate
|
|
158
160
|
logger.debug 'Authenticating with iMIS'
|
|
159
161
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
authentication_data = {
|
|
162
|
+
request = http_post
|
|
163
|
+
request.body = URI.encode_www_form(
|
|
163
164
|
grant_type: 'password',
|
|
164
165
|
username: Imis.configuration.username,
|
|
165
166
|
password: Imis.configuration.password
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
result = submit(uri, req)
|
|
167
|
+
)
|
|
168
|
+
result = submit(uri, request)
|
|
169
169
|
json = JSON.parse(result.body)
|
|
170
170
|
|
|
171
171
|
@token = json['access_token']
|
|
172
172
|
@token_expiration = Time.parse(json['.expires'])
|
|
173
173
|
end
|
|
174
|
+
|
|
175
|
+
# URI for the authentication endpoint
|
|
176
|
+
#
|
|
177
|
+
def uri(...) = URI(File.join(Imis.configuration.hostname, AUTHENTICATION_PATH))
|
|
174
178
|
end
|
|
175
179
|
end
|
|
176
180
|
end
|
|
@@ -66,6 +66,16 @@ module Usps
|
|
|
66
66
|
end
|
|
67
67
|
alias fetch_all get_fields
|
|
68
68
|
|
|
69
|
+
# Update a single named field on a business object for the current member
|
|
70
|
+
#
|
|
71
|
+
# @param field [String] Name of the field
|
|
72
|
+
# @param value Value of the field
|
|
73
|
+
#
|
|
74
|
+
# @return [Usps::Imis::Data] Response data from the API
|
|
75
|
+
#
|
|
76
|
+
def put_field(field, value) = put(filter_fields(field => value))
|
|
77
|
+
alias []= put_field
|
|
78
|
+
|
|
69
79
|
# Update only specific fields on a business object for the current member
|
|
70
80
|
#
|
|
71
81
|
# @param fields [Hash] Conforms to pattern +{ field_key => value }+
|
|
@@ -83,7 +93,7 @@ module Usps
|
|
|
83
93
|
#
|
|
84
94
|
# @return [Usps::Imis::Data] Response data from the API
|
|
85
95
|
#
|
|
86
|
-
def put(body) = put_object(
|
|
96
|
+
def put(body) = put_object(http_put, body)
|
|
87
97
|
alias update put
|
|
88
98
|
|
|
89
99
|
# Create a business object for the current member
|
|
@@ -92,14 +102,14 @@ module Usps
|
|
|
92
102
|
#
|
|
93
103
|
# @return [Usps::Imis::Data] Response data from the API
|
|
94
104
|
#
|
|
95
|
-
def post(body) = put_object(
|
|
105
|
+
def post(body) = put_object(http_post, body)
|
|
96
106
|
alias create post
|
|
97
107
|
|
|
98
108
|
# Remove a business object for the current member
|
|
99
109
|
#
|
|
100
110
|
# @return [true] Only on success response (i.e. blank string from the API)
|
|
101
111
|
#
|
|
102
|
-
def delete = submit(uri, authorize(
|
|
112
|
+
def delete = submit(uri, authorize(http_delete)).body == '' # rubocop:disable Naming/PredicateMethod
|
|
103
113
|
alias destroy delete
|
|
104
114
|
|
|
105
115
|
# Ruby 3.5 instance variable filter
|
|
@@ -163,9 +173,8 @@ module Usps
|
|
|
163
173
|
# Useful for stubbing data in tests
|
|
164
174
|
#
|
|
165
175
|
def raw_object
|
|
166
|
-
|
|
167
|
-
result =
|
|
168
|
-
result = Data.from_json(result.body)
|
|
176
|
+
response = submit(uri, authorize(http_get))
|
|
177
|
+
result = Data.from_json(response.body)
|
|
169
178
|
JSON.pretty_generate(result).split("\n").each { logger.debug " -> #{it}" }
|
|
170
179
|
result
|
|
171
180
|
end
|
|
@@ -174,8 +183,8 @@ module Usps
|
|
|
174
183
|
#
|
|
175
184
|
def put_object(request, body)
|
|
176
185
|
request.body = JSON.dump(body)
|
|
177
|
-
|
|
178
|
-
result = Data.from_json(
|
|
186
|
+
response = submit(uri, authorize(request))
|
|
187
|
+
result = Data.from_json(response.body)
|
|
179
188
|
JSON.pretty_generate(result).split("\n").each { logger.debug " -> #{it}" }
|
|
180
189
|
result
|
|
181
190
|
end
|
data/lib/usps/imis/data.rb
CHANGED
|
@@ -50,6 +50,10 @@ module Usps
|
|
|
50
50
|
.index_with { self[it] }
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
def []=(...)
|
|
54
|
+
raise Errors::ApiError, '`Data` does not support setting values. If you need to modify it, call `.raw` on it.'
|
|
55
|
+
end
|
|
56
|
+
|
|
53
57
|
def inspect
|
|
54
58
|
stringio = StringIO.new
|
|
55
59
|
PP.pp(self, stringio)
|
data/lib/usps/imis/error.rb
CHANGED
data/lib/usps/imis/mapper.rb
CHANGED
|
@@ -28,6 +28,16 @@ module Usps
|
|
|
28
28
|
@api.imis_id = imis_id if imis_id
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# Get a member's data for a specific field by arbitrary field name
|
|
32
|
+
#
|
|
33
|
+
# Does not require knowing which business object / iMIS-specific field name to use
|
|
34
|
+
#
|
|
35
|
+
# Only available for fields defined in +FIELD_MAPPING+
|
|
36
|
+
#
|
|
37
|
+
# @param field_key [Symbol] Internal name of the field
|
|
38
|
+
#
|
|
39
|
+
# @return Value of the field
|
|
40
|
+
#
|
|
31
41
|
def fetch(field_key)
|
|
32
42
|
missing_mapping!(field_key) unless FIELD_MAPPING.key?(field_key.to_sym)
|
|
33
43
|
|
|
@@ -36,6 +46,19 @@ module Usps
|
|
|
36
46
|
end
|
|
37
47
|
alias [] fetch
|
|
38
48
|
|
|
49
|
+
# Update a member's data for a specific field by arbitrary field name
|
|
50
|
+
#
|
|
51
|
+
# Does not require knowing which business object / iMIS-specific field name to use
|
|
52
|
+
#
|
|
53
|
+
# Only available for fields defined in +FIELD_MAPPING+
|
|
54
|
+
#
|
|
55
|
+
# @param field_key [Symbol] Internal name of the field
|
|
56
|
+
#
|
|
57
|
+
# @return Value of the field
|
|
58
|
+
#
|
|
59
|
+
def put_field(field_key, value) = update(field_key => value)
|
|
60
|
+
alias []= put_field
|
|
61
|
+
|
|
39
62
|
# Update a member's data on multiple affected business objects by arbitrary field names
|
|
40
63
|
#
|
|
41
64
|
# Does not require knowing which business object / iMIS-specific field name to use
|
|
@@ -49,6 +49,16 @@ module Usps
|
|
|
49
49
|
def get_fields(ordinal, *fields) = api.on(business_object, ordinal:).get_fields(*fields)
|
|
50
50
|
alias fetch_all get_fields
|
|
51
51
|
|
|
52
|
+
# Update a single named field on a business object for the current member
|
|
53
|
+
#
|
|
54
|
+
# @param field [String] Name of the field
|
|
55
|
+
# @param value Value of the field
|
|
56
|
+
#
|
|
57
|
+
# @return [Usps::Imis::Data] Response data from the API
|
|
58
|
+
#
|
|
59
|
+
def put_field(field, value) = api.on(business_object, ordinal:).put_field(field, value)
|
|
60
|
+
alias []= put_field
|
|
61
|
+
|
|
52
62
|
# Update only specific fields on a Panel for the current member
|
|
53
63
|
#
|
|
54
64
|
# @param ordinal [Integer] The ordinal identifier for the desired object
|
data/lib/usps/imis/query.rb
CHANGED
|
@@ -24,20 +24,32 @@ module Usps
|
|
|
24
24
|
#
|
|
25
25
|
attr_reader :query_params
|
|
26
26
|
|
|
27
|
+
# Current page size for paging through the Query
|
|
28
|
+
#
|
|
29
|
+
attr_accessor :page_size
|
|
30
|
+
|
|
27
31
|
# Current offset for paging through the Query
|
|
28
32
|
#
|
|
29
|
-
|
|
33
|
+
attr_accessor :offset
|
|
34
|
+
|
|
35
|
+
# Count of records processed
|
|
36
|
+
#
|
|
37
|
+
attr_reader :count
|
|
30
38
|
|
|
31
39
|
# A new instance of +Query+
|
|
32
40
|
#
|
|
33
41
|
# @param api [Api] Parent to use for making requests
|
|
34
42
|
# @param query_name [String] Full path of the query in IQA, e.g. +$/_ABC/Fiander/iMIS_ID+
|
|
35
|
-
# @
|
|
43
|
+
# @param page_size [Integer] Number of records to return on each request page
|
|
44
|
+
# @param offset [Integer] Offset index of records to return on next request page
|
|
45
|
+
# @param query_params [Hash] Conforms to pattern +{ param_name => param_value }+
|
|
36
46
|
#
|
|
37
|
-
def initialize(api, query_name, query_params)
|
|
47
|
+
def initialize(api, query_name, page_size: 100, offset: nil, **query_params)
|
|
38
48
|
@api = api
|
|
39
49
|
@query_name = query_name
|
|
40
50
|
@query_params = query_params
|
|
51
|
+
@page_size = page_size
|
|
52
|
+
@offset = offset
|
|
41
53
|
end
|
|
42
54
|
|
|
43
55
|
# Iterate through all results from the query
|
|
@@ -53,26 +65,37 @@ module Usps
|
|
|
53
65
|
# Iterate through all results from the query, fetching one page at a time
|
|
54
66
|
#
|
|
55
67
|
def find_each(&)
|
|
56
|
-
result =
|
|
57
|
-
count = 0
|
|
68
|
+
result = reset!
|
|
58
69
|
|
|
59
70
|
while result['HasNext']
|
|
60
|
-
|
|
71
|
+
result = fetch_next.tap do |result_page|
|
|
72
|
+
result_page['Items']['$values'].map { it.except('$type') }.each(&)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
61
75
|
|
|
62
|
-
|
|
76
|
+
nil
|
|
77
|
+
end
|
|
63
78
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
JSON.pretty_generate(result).split("\n").each { logger.debug " -> #{it}" }
|
|
79
|
+
# Fetch a raw query page
|
|
80
|
+
#
|
|
81
|
+
def fetch = JSON.parse(submit(uri, authorize(http_get)).body)
|
|
68
82
|
|
|
69
|
-
|
|
70
|
-
|
|
83
|
+
# Fetch the next raw query page, and update the current offset
|
|
84
|
+
#
|
|
85
|
+
def fetch_next
|
|
86
|
+
logger.info 'Fetching IQA Query page'
|
|
71
87
|
|
|
72
|
-
|
|
73
|
-
end
|
|
88
|
+
result = fetch
|
|
74
89
|
|
|
75
|
-
|
|
90
|
+
@count += result['Count'] || 0
|
|
91
|
+
total = result['TotalCount']
|
|
92
|
+
logger.info " -> #{@count} / #{total} #{'item'.pluralize(total)}"
|
|
93
|
+
logger.debug ' -> Query page data:'
|
|
94
|
+
JSON.pretty_generate(result).split("\n").each { logger.debug " -> #{it}" }
|
|
95
|
+
|
|
96
|
+
@offset = result['NextOffset']
|
|
97
|
+
|
|
98
|
+
result
|
|
76
99
|
end
|
|
77
100
|
|
|
78
101
|
# Ruby 3.5 instance variable filter
|
|
@@ -84,11 +107,20 @@ module Usps
|
|
|
84
107
|
def token = api.token
|
|
85
108
|
def token_expiration = api.token_expiration
|
|
86
109
|
|
|
87
|
-
def
|
|
110
|
+
def path_params = query_params.merge(QueryName: query_name).merge({ Offset: offset, Limit: page_size }.compact)
|
|
111
|
+
def path = "#{QUERY_PATH}?#{path_params.to_query}"
|
|
88
112
|
def uri = URI(File.join(Imis.configuration.hostname, path))
|
|
89
|
-
def fetch = JSON.parse(submit(uri, authorize(Net::HTTP::Get.new(uri))).body)
|
|
90
113
|
|
|
91
114
|
def logger = Imis.logger('Query')
|
|
115
|
+
|
|
116
|
+
def reset!
|
|
117
|
+
logger.debug 'Resetting Query progress'
|
|
118
|
+
|
|
119
|
+
@count = 0
|
|
120
|
+
@offset = 0
|
|
121
|
+
|
|
122
|
+
{ 'HasNext' => true }
|
|
123
|
+
end
|
|
92
124
|
end
|
|
93
125
|
end
|
|
94
126
|
end
|
data/lib/usps/imis/requests.rb
CHANGED
|
@@ -9,6 +9,11 @@ module Usps
|
|
|
9
9
|
|
|
10
10
|
def logger = Imis.logger
|
|
11
11
|
|
|
12
|
+
def http_get = Net::HTTP::Get.new(uri)
|
|
13
|
+
def http_put = Net::HTTP::Put.new(uri)
|
|
14
|
+
def http_post = Net::HTTP::Post.new(uri(id: ''))
|
|
15
|
+
def http_delete = Net::HTTP::Delete.new(uri)
|
|
16
|
+
|
|
12
17
|
def client(uri)
|
|
13
18
|
Net::HTTP.new(uri.host, uri.port).tap do |http|
|
|
14
19
|
http.use_ssl = true
|
|
@@ -45,9 +50,8 @@ module Usps
|
|
|
45
50
|
body = request.body.dup
|
|
46
51
|
|
|
47
52
|
Imis.config.filtered_parameters.each do |parameter|
|
|
48
|
-
body
|
|
49
|
-
|
|
50
|
-
.gsub(CGI.escape(Imis.config.public_send(parameter)), '[FILTERED]')
|
|
53
|
+
body.gsub!(Imis.config.public_send(parameter), '[FILTERED]')
|
|
54
|
+
body.gsub!(CGI.escape(Imis.config.public_send(parameter)), '[FILTERED]')
|
|
51
55
|
end
|
|
52
56
|
|
|
53
57
|
body
|
data/lib/usps/imis/version.rb
CHANGED
|
File without changes
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
http_interactions:
|
|
3
|
+
- request:
|
|
4
|
+
method: post
|
|
5
|
+
uri: https://abcdev.imiscloud.com/Token
|
|
6
|
+
body:
|
|
7
|
+
encoding: US-ASCII
|
|
8
|
+
string: grant_type=password&username=<USERNAME>&password=<PASSWORD>
|
|
9
|
+
headers:
|
|
10
|
+
Accept-Encoding:
|
|
11
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
|
12
|
+
Accept:
|
|
13
|
+
- "*/*"
|
|
14
|
+
User-Agent:
|
|
15
|
+
- Ruby
|
|
16
|
+
Host:
|
|
17
|
+
- abcdev.imiscloud.com
|
|
18
|
+
response:
|
|
19
|
+
status:
|
|
20
|
+
code: 200
|
|
21
|
+
message: OK
|
|
22
|
+
headers:
|
|
23
|
+
Date:
|
|
24
|
+
- Sun, 26 Oct 2025 01:24:38 GMT
|
|
25
|
+
Content-Type:
|
|
26
|
+
- application/json; charset=UTF-8
|
|
27
|
+
Transfer-Encoding:
|
|
28
|
+
- chunked
|
|
29
|
+
Connection:
|
|
30
|
+
- keep-alive
|
|
31
|
+
Server:
|
|
32
|
+
- cloudflare
|
|
33
|
+
Cf-Ray:
|
|
34
|
+
- 994627bdc9e8e822-ORD
|
|
35
|
+
Cf-Cache-Status:
|
|
36
|
+
- DYNAMIC
|
|
37
|
+
Access-Control-Allow-Origin:
|
|
38
|
+
- "*"
|
|
39
|
+
Cache-Control:
|
|
40
|
+
- no-cache
|
|
41
|
+
Expires:
|
|
42
|
+
- "-1"
|
|
43
|
+
Strict-Transport-Security:
|
|
44
|
+
- max-age=31536000
|
|
45
|
+
Vary:
|
|
46
|
+
- Accept-Encoding,Accept-Encoding
|
|
47
|
+
Pragma:
|
|
48
|
+
- no-cache
|
|
49
|
+
Access-Control-Expose-Headers:
|
|
50
|
+
- Request-Context
|
|
51
|
+
Request-Context:
|
|
52
|
+
- appId=cid-v1:9c05b5dd-9acf-4a59-aabb-1775785c005f
|
|
53
|
+
X-Aspnet-Version:
|
|
54
|
+
- 4.0.30319
|
|
55
|
+
X-Content-Type-Options:
|
|
56
|
+
- nosniff
|
|
57
|
+
- nosniff
|
|
58
|
+
Set-Cookie:
|
|
59
|
+
- __cf_bm=WthwCIYBGJjeQcPIuJteHBCsffR9_YnIswA1GxBsAY0-1761441878-1.0.1.1-PDKN99A_uKww6R0a3o7xNsGHGxn2nOOhCXcaMzV_6LgrHJ1GEYNmKklmEtAghMWUP4IGpM9INbgu7tFJP1_AlEsAbYw0VOZD80N9_B0VvwU;
|
|
60
|
+
path=/; expires=Sun, 26-Oct-25 01:54:38 GMT; domain=.abcdev.imiscloud.com;
|
|
61
|
+
HttpOnly; Secure; SameSite=None
|
|
62
|
+
body:
|
|
63
|
+
encoding: ASCII-8BIT
|
|
64
|
+
string: '{"access_token":"<ACCESS_TOKEN>","token_type":"bearer","expires_in":3599,"userName":"J.S.FIANDER@GMAIL.COM",".issued":"Sun,
|
|
65
|
+
26 Oct 2025 01:24:38 GMT",".expires":"Sun, 26 Oct 2025 02:24:38 GMT"}'
|
|
66
|
+
recorded_at: Sun, 26 Oct 2025 01:24:38 GMT
|
|
67
|
+
recorded_with: VCR 6.3.1
|