usps-imis-api 0.8.1 → 0.9.0
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/Gemfile.lock +1 -1
- data/Readme.md +21 -1
- data/lib/usps/imis/api.rb +6 -32
- data/lib/usps/imis/config.rb +6 -3
- data/lib/usps/imis/data.rb +16 -5
- data/lib/usps/imis/mapper.rb +6 -8
- data/lib/usps/imis/query.rb +88 -0
- data/lib/usps/imis/requests.rb +15 -1
- data/lib/usps/imis/version.rb +1 -1
- data/lib/usps/imis.rb +6 -0
- data/spec/lib/usps/imis/api_spec.rb +6 -8
- data/spec/lib/usps/imis/data_spec.rb +16 -2
- data/spec/spec_helper.rb +2 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e94dcde6abaf560148b72523c9defe96cd30f6980631f11b79cf8b35f52a1dcc
|
|
4
|
+
data.tar.gz: a94d8ce631656ff48bf6c3b905e3e06bf130a5a658dfad737afec2be21ac1957
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1c155ff3c3e0801c4cb1d738c736e7da9833b651ba56cafb5983439d8e7708f15a266f688d40672917270745b198cac6a38e86b735932c447a631b1c5922b17d
|
|
7
|
+
data.tar.gz: e99827b9bb433d673c6d76558c209f23a12aba1dbe22a674d4972f8ff97b0122374cb4ef2955c0b903ebcf5f7d20721c15b800b79cba17c304113436ea8c66a9
|
data/Gemfile.lock
CHANGED
data/Readme.md
CHANGED
|
@@ -32,6 +32,10 @@ Usps::Imis.configure do |config|
|
|
|
32
32
|
config.imis_id_query_name = ENV['IMIS_ID_QUERY_NAME']
|
|
33
33
|
config.username = ENV['IMIS_USERNAME']
|
|
34
34
|
config.password = ENV['IMIS_PASSWORD']
|
|
35
|
+
|
|
36
|
+
# These options will use these defaults
|
|
37
|
+
config.logger = Logger.new($stdout)
|
|
38
|
+
config.logger.level = :info
|
|
35
39
|
end
|
|
36
40
|
```
|
|
37
41
|
|
|
@@ -195,7 +199,15 @@ Run an IQA Query
|
|
|
195
199
|
`query_params` is a hash of shape: `{ param_name => param_value }`
|
|
196
200
|
|
|
197
201
|
```ruby
|
|
198
|
-
api.query(query_name, query_params)
|
|
202
|
+
query = api.query(query_name, query_params)
|
|
203
|
+
|
|
204
|
+
query.each do |item|
|
|
205
|
+
# Download all pages of the query, then iterate on the results
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
query.find_each do |item|
|
|
209
|
+
# Iterate one page at a time, fetching new pages automatically
|
|
210
|
+
end
|
|
199
211
|
```
|
|
200
212
|
|
|
201
213
|
### Field Mapper
|
|
@@ -314,6 +326,14 @@ end
|
|
|
314
326
|
api.with(31092).on('ABC_ASC_Individual_Demog').get_field('TotMMS')
|
|
315
327
|
```
|
|
316
328
|
|
|
329
|
+
### Data Methods
|
|
330
|
+
|
|
331
|
+
Data responses from the API can be handled as a standard Hash using the `raw` method.
|
|
332
|
+
|
|
333
|
+
If you need to access all of the property values, you can use the `properties` method.
|
|
334
|
+
By default, this will exclude the `ID` and `Ordinal` properties; they can be included with
|
|
335
|
+
`properties(include_ids: true)`.
|
|
336
|
+
|
|
317
337
|
## Test Data Mocking
|
|
318
338
|
|
|
319
339
|
You can use the provided Business Object Mock to generate stub data for rspec:
|
data/lib/usps/imis/api.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative 'requests'
|
|
4
4
|
require_relative 'business_object'
|
|
5
5
|
require_relative 'mapper'
|
|
6
|
+
require_relative 'query'
|
|
6
7
|
|
|
7
8
|
module Usps
|
|
8
9
|
module Imis
|
|
@@ -15,10 +16,6 @@ module Usps
|
|
|
15
16
|
#
|
|
16
17
|
AUTHENTICATION_PATH = 'Token'
|
|
17
18
|
|
|
18
|
-
# Endpoint for IQA query requests
|
|
19
|
-
#
|
|
20
|
-
QUERY_PATH = 'api/Query'
|
|
21
|
-
|
|
22
19
|
# API bearer token
|
|
23
20
|
#
|
|
24
21
|
attr_reader :token
|
|
@@ -67,8 +64,7 @@ module Usps
|
|
|
67
64
|
raise Errors::LockedIdError if lock_imis_id
|
|
68
65
|
|
|
69
66
|
begin
|
|
70
|
-
|
|
71
|
-
@imis_id = result['Items']['$values'][0]['ID'].to_i
|
|
67
|
+
self.imis_id = query(Imis.configuration.imis_id_query_name, { certificate: }).first['ID'].to_i
|
|
72
68
|
rescue StandardError
|
|
73
69
|
raise Errors::NotFoundError, 'Member not found'
|
|
74
70
|
end
|
|
@@ -101,7 +97,7 @@ module Usps
|
|
|
101
97
|
end
|
|
102
98
|
end
|
|
103
99
|
|
|
104
|
-
#
|
|
100
|
+
# Build an IQA Query interface
|
|
105
101
|
#
|
|
106
102
|
# @param query_name [String] Full path of the query in IQA, e.g. +$/_ABC/Fiander/iMIS_ID+
|
|
107
103
|
# @query_params [Hash] Conforms to pattern +{ param_name => param_value }+
|
|
@@ -109,31 +105,7 @@ module Usps
|
|
|
109
105
|
# @return [Hash] Response data from the API
|
|
110
106
|
#
|
|
111
107
|
def query(query_name, query_params = {})
|
|
112
|
-
|
|
113
|
-
path = "#{QUERY_PATH}?#{query_params.to_query}"
|
|
114
|
-
uri = URI(File.join(Imis.configuration.hostname, path))
|
|
115
|
-
request = Net::HTTP::Get.new(uri)
|
|
116
|
-
result = submit(uri, authorize(request))
|
|
117
|
-
JSON.parse(result.body)
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# Run an IQA Query, paging through all responses
|
|
121
|
-
#
|
|
122
|
-
# @param query_name [String] Full path of the query in IQA, e.g. +$/_ABC/Fiander/iMIS_ID+
|
|
123
|
-
# @query_params [Hash] Conforms to pattern +{ param_name => param_value }+
|
|
124
|
-
#
|
|
125
|
-
# @return [Array<Hash>] Collected response item values from the API
|
|
126
|
-
#
|
|
127
|
-
def query_all(query_name, query_params = {})
|
|
128
|
-
response = query(query_name, **query_params)
|
|
129
|
-
results = response['Items']['$values']
|
|
130
|
-
|
|
131
|
-
while response['HasNext']
|
|
132
|
-
response = query(query_name, **query_params, Offset: response['NextOffset'])
|
|
133
|
-
results += response['Items']['$values']
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
results
|
|
108
|
+
Query.new(self, query_name, query_params)
|
|
137
109
|
end
|
|
138
110
|
|
|
139
111
|
# Run requests as DSL, with specific +BusinessObject+ only maintained for this scope
|
|
@@ -178,6 +150,8 @@ module Usps
|
|
|
178
150
|
# Authenticate to the iMIS API, and store the access token and expiration time
|
|
179
151
|
#
|
|
180
152
|
def authenticate
|
|
153
|
+
Imis.logger.debug 'Authenticating with iMIS'
|
|
154
|
+
|
|
181
155
|
uri = URI(File.join(Imis.configuration.hostname, AUTHENTICATION_PATH))
|
|
182
156
|
req = Net::HTTP::Post.new(uri)
|
|
183
157
|
authentication_data = {
|
data/lib/usps/imis/config.rb
CHANGED
|
@@ -8,16 +8,19 @@ module Usps
|
|
|
8
8
|
IMIS_ROOT_URL_PROD = 'https://portal.americasboatingclub.org'
|
|
9
9
|
IMIS_ROOT_URL_DEV = 'https://abcdev.imiscloud.com'
|
|
10
10
|
|
|
11
|
-
attr_accessor :imis_id_query_name, :username, :password
|
|
12
|
-
attr_reader :environment
|
|
11
|
+
attr_accessor :imis_id_query_name, :username, :password, :logger
|
|
12
|
+
attr_reader :environment, :logger_level
|
|
13
13
|
|
|
14
14
|
def initialize
|
|
15
15
|
@environment = defined?(Rails) ? Rails.env : ActiveSupport::StringInquirer.new('development')
|
|
16
16
|
@imis_id_query_name = ENV.fetch('IMIS_ID_QUERY_NAME', nil)
|
|
17
17
|
@username = ENV.fetch('IMIS_USERNAME', nil)
|
|
18
18
|
@password = ENV.fetch('IMIS_PASSWORD', nil)
|
|
19
|
+
@logger = Logger.new($stdout, level: :info)
|
|
19
20
|
|
|
20
21
|
yield self if block_given?
|
|
22
|
+
|
|
23
|
+
@logger_level = logger.class::SEV_LABEL[logger.level].downcase.to_sym
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
def environment=(env)
|
|
@@ -37,7 +40,7 @@ module Usps
|
|
|
37
40
|
|
|
38
41
|
# Ruby 3.5 instance variable filter
|
|
39
42
|
#
|
|
40
|
-
def instance_variables_to_inspect = %i[@environment @imis_id_query_name @username]
|
|
43
|
+
def instance_variables_to_inspect = %i[@environment @imis_id_query_name @username @logger_level]
|
|
41
44
|
end
|
|
42
45
|
end
|
|
43
46
|
end
|
data/lib/usps/imis/data.rb
CHANGED
|
@@ -16,6 +16,10 @@ module Usps
|
|
|
16
16
|
|
|
17
17
|
alias raw to_h
|
|
18
18
|
|
|
19
|
+
# The Business Object or Panel name
|
|
20
|
+
#
|
|
21
|
+
def entity = raw['EntityTypeName']
|
|
22
|
+
|
|
19
23
|
# Access the iMIS ID property
|
|
20
24
|
#
|
|
21
25
|
def imis_id = self['ID'].to_i
|
|
@@ -35,6 +39,17 @@ module Usps
|
|
|
35
39
|
value.is_a?(String) ? value : value['$value']
|
|
36
40
|
end
|
|
37
41
|
|
|
42
|
+
# Hash of all property names to values
|
|
43
|
+
#
|
|
44
|
+
# @param include_ids [Boolean] Whether to include the iMIS ID and Ordinal
|
|
45
|
+
#
|
|
46
|
+
def properties(include_ids: false)
|
|
47
|
+
raw['Properties']['$values']
|
|
48
|
+
.map { it['Name'] }
|
|
49
|
+
.select { include_ids || !%w[ID Ordinal].include?(it) }
|
|
50
|
+
.index_with { self[it] }
|
|
51
|
+
end
|
|
52
|
+
|
|
38
53
|
def inspect
|
|
39
54
|
stringio = StringIO.new
|
|
40
55
|
PP.pp(self, stringio)
|
|
@@ -42,11 +57,7 @@ module Usps
|
|
|
42
57
|
end
|
|
43
58
|
|
|
44
59
|
def pretty_print(pp)
|
|
45
|
-
data = {
|
|
46
|
-
entity_type_name: raw['EntityTypeName'],
|
|
47
|
-
imis_id:,
|
|
48
|
-
ordinal:
|
|
49
|
-
}.compact
|
|
60
|
+
data = { entity:, imis_id:, ordinal: }.compact
|
|
50
61
|
|
|
51
62
|
pp.group(1, "#<#{self.class}", '>') do
|
|
52
63
|
data.each do |key, value|
|
data/lib/usps/imis/mapper.rb
CHANGED
|
@@ -36,7 +36,7 @@ module Usps
|
|
|
36
36
|
#
|
|
37
37
|
# @param data [Hash] Conforms to pattern +{ field_key => value }+
|
|
38
38
|
#
|
|
39
|
-
# @return [Array<
|
|
39
|
+
# @return [Array<Usps::Imis::Data>] Response data from the API for each internal update request
|
|
40
40
|
#
|
|
41
41
|
def update(data)
|
|
42
42
|
updates = data.each_with_object({}) do |(field_key, value), hash|
|
|
@@ -54,15 +54,13 @@ module Usps
|
|
|
54
54
|
private
|
|
55
55
|
|
|
56
56
|
def map_update(field_name)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
missing_mapping(field_name)
|
|
62
|
-
end
|
|
57
|
+
missing_mapping!(field_name) unless FIELD_MAPPING.key?(field_name.to_sym)
|
|
58
|
+
|
|
59
|
+
business_object_name, field = FIELD_MAPPING[field_name.to_sym]
|
|
60
|
+
yield(business_object_name, field)
|
|
63
61
|
end
|
|
64
62
|
|
|
65
|
-
def missing_mapping(field_name)
|
|
63
|
+
def missing_mapping!(field_name)
|
|
66
64
|
unless ENV['TESTING']
|
|
67
65
|
# :nocov:
|
|
68
66
|
warn(
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Usps
|
|
4
|
+
module Imis
|
|
5
|
+
# API wrapper for IQA Queries
|
|
6
|
+
#
|
|
7
|
+
class Query
|
|
8
|
+
include Enumerable
|
|
9
|
+
include Requests
|
|
10
|
+
|
|
11
|
+
# Endpoint for IQA query requests
|
|
12
|
+
#
|
|
13
|
+
QUERY_PATH = 'api/Query'
|
|
14
|
+
|
|
15
|
+
# The parent +Api+ object
|
|
16
|
+
#
|
|
17
|
+
attr_reader :api
|
|
18
|
+
|
|
19
|
+
# Name of the Query to run
|
|
20
|
+
#
|
|
21
|
+
attr_reader :query_name
|
|
22
|
+
|
|
23
|
+
# Parameters for the Query
|
|
24
|
+
#
|
|
25
|
+
attr_reader :query_params
|
|
26
|
+
|
|
27
|
+
# Current offset for paging through the Query
|
|
28
|
+
#
|
|
29
|
+
attr_reader :offset
|
|
30
|
+
|
|
31
|
+
# A new instance of +Query+
|
|
32
|
+
#
|
|
33
|
+
# @param api [Api] Parent to use for making requests
|
|
34
|
+
# @param query_name [String] Full path of the query in IQA, e.g. +$/_ABC/Fiander/iMIS_ID+
|
|
35
|
+
# @query_params [Hash] Conforms to pattern +{ param_name => param_value }+
|
|
36
|
+
#
|
|
37
|
+
def initialize(api, query_name, query_params)
|
|
38
|
+
@api = api
|
|
39
|
+
@query_name = query_name
|
|
40
|
+
@query_params = query_params
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Iterate through all results from the query
|
|
44
|
+
#
|
|
45
|
+
def each(&)
|
|
46
|
+
Imis.logger.info 'Running IQA Query on iMIS'
|
|
47
|
+
|
|
48
|
+
items = []
|
|
49
|
+
find_each { items << it }
|
|
50
|
+
items.each(&)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Iterate through all results from the query, fetching one page at a time
|
|
54
|
+
#
|
|
55
|
+
def find_each(&)
|
|
56
|
+
result = { 'HasNext' => true }
|
|
57
|
+
count = 0
|
|
58
|
+
|
|
59
|
+
while result['HasNext']
|
|
60
|
+
Imis.logger.info 'Fetching IQA Query page'
|
|
61
|
+
|
|
62
|
+
result = fetch
|
|
63
|
+
|
|
64
|
+
count += result['Count'] || 0
|
|
65
|
+
Imis.logger.info " -> #{count} / #{result['TotalCount']} #{'item'.pluralize(count)}"
|
|
66
|
+
Imis.logger.debug ' -> Query page data:'
|
|
67
|
+
JSON.pretty_generate(result).split("\n").each { Imis.logger.debug " -> #{it}" }
|
|
68
|
+
|
|
69
|
+
items = result['Items']['$values'].map { it.except('$type') }
|
|
70
|
+
@offset = result['NextOffset']
|
|
71
|
+
|
|
72
|
+
items.each(&)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
nil
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def token = api.token
|
|
81
|
+
def token_expiration = api.token_expiration
|
|
82
|
+
|
|
83
|
+
def path = "#{QUERY_PATH}?#{query_params.merge(QueryName: query_name, Offset: offset).to_query}"
|
|
84
|
+
def uri = URI(File.join(Imis.configuration.hostname, path))
|
|
85
|
+
def fetch = JSON.parse(submit(uri, authorize(Net::HTTP::Get.new(uri))).body)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
data/lib/usps/imis/requests.rb
CHANGED
|
@@ -19,15 +19,29 @@ module Usps
|
|
|
19
19
|
# If the current token is missing/expired, request a new one
|
|
20
20
|
#
|
|
21
21
|
def authorize(request)
|
|
22
|
-
|
|
22
|
+
if token_expiration < Time.now
|
|
23
|
+
Imis.logger.debug 'Token expired: re-authenticating with iMIS'
|
|
24
|
+
authenticate
|
|
25
|
+
end
|
|
23
26
|
request.tap { it.add_field('Authorization', "Bearer #{token}") }
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
def submit(uri, request)
|
|
30
|
+
Imis.logger.info 'Submitting request to iMIS'
|
|
31
|
+
Imis.logger.debug " -> #{uri}"
|
|
32
|
+
sanitized_request_body(request).split("\n").each { Imis.logger.debug " -> #{it}" }
|
|
27
33
|
client(uri).request(request).tap do |result|
|
|
28
34
|
raise Errors::ResponseError.from(result) unless result.is_a?(Net::HTTPSuccess)
|
|
35
|
+
|
|
36
|
+
Imis.logger.info 'Request succeeded'
|
|
29
37
|
end
|
|
30
38
|
end
|
|
39
|
+
|
|
40
|
+
def sanitized_request_body(request)
|
|
41
|
+
return 'grant_type=password&username=[filtered]&password=[filtered]' if request.body&.include?('password=')
|
|
42
|
+
|
|
43
|
+
request.body.nil? ? '*** empty request body ***' : JSON.pretty_generate(JSON.parse(request.body))
|
|
44
|
+
end
|
|
31
45
|
end
|
|
32
46
|
end
|
|
33
47
|
end
|
data/lib/usps/imis/version.rb
CHANGED
data/lib/usps/imis.rb
CHANGED
|
@@ -8,7 +8,9 @@ require 'cgi'
|
|
|
8
8
|
|
|
9
9
|
require 'active_support/core_ext/string/inflections'
|
|
10
10
|
require 'active_support/core_ext/object/to_query'
|
|
11
|
+
require 'active_support/core_ext/enumerable'
|
|
11
12
|
require 'active_support/string_inquirer'
|
|
13
|
+
require 'logger'
|
|
12
14
|
|
|
13
15
|
# Internal requires
|
|
14
16
|
require_relative 'imis/config'
|
|
@@ -39,6 +41,10 @@ module Usps
|
|
|
39
41
|
yield(configuration) if block_given?
|
|
40
42
|
configuration
|
|
41
43
|
end
|
|
44
|
+
|
|
45
|
+
# Logger instance to write to
|
|
46
|
+
#
|
|
47
|
+
def logger = configuration.logger
|
|
42
48
|
end
|
|
43
49
|
end
|
|
44
50
|
end
|
|
@@ -37,18 +37,18 @@ describe Usps::Imis::Api do
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
describe '#
|
|
40
|
+
describe '#query' do
|
|
41
|
+
let(:query) { api.query('$/ABC/ExampleQueryAll', {}) }
|
|
42
|
+
|
|
41
43
|
before do
|
|
42
|
-
allow(
|
|
44
|
+
allow(query).to receive(:fetch).and_return(
|
|
43
45
|
{ 'Items' => { '$values' => [{ 'key1' => 'value1' }] }, 'HasNext' => true, 'NextOffset' => 1 },
|
|
44
46
|
{ 'Items' => { '$values' => [{ 'key1' => 'value2' }] }, 'HasNext' => false, 'NextOffset' => 0 }
|
|
45
47
|
)
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
it 'collects all query results' do
|
|
49
|
-
expect(
|
|
50
|
-
[{ 'key1' => 'value1' }, { 'key1' => 'value2' }]
|
|
51
|
-
)
|
|
51
|
+
expect(query.to_a).to eq([{ 'key1' => 'value1' }, { 'key1' => 'value2' }])
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
@@ -56,9 +56,7 @@ describe Usps::Imis::Api do
|
|
|
56
56
|
before { api.imis_id = 31092 }
|
|
57
57
|
|
|
58
58
|
it 'sends an update' do
|
|
59
|
-
expect(api.on('ABC_ASC_Individual_Demog').put_fields('TotMMS' => 15)).to(
|
|
60
|
-
be_a(Hash)
|
|
61
|
-
)
|
|
59
|
+
expect(api.on('ABC_ASC_Individual_Demog').put_fields('TotMMS' => 15)).to be_a(Hash)
|
|
62
60
|
end
|
|
63
61
|
|
|
64
62
|
context 'when receiving a response error' do
|
|
@@ -22,9 +22,23 @@ describe Usps::Imis::Data do
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
describe '#properties' do
|
|
26
|
+
it 'iterates over the properties, excluding IDs' do
|
|
27
|
+
expect(data.properties.map { |field, value| "#{field}: #{value}" }).to eq(
|
|
28
|
+
['Stub Integer: 42', 'Stub String: something']
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'iterates over the properties, including IDs' do
|
|
33
|
+
expect(data.properties(include_ids: true).map { |field, value| "#{field}: #{value}" }).to eq(
|
|
34
|
+
['ID: 31092', 'Stub Integer: 42', 'Stub String: something']
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
25
39
|
describe '#inspect' do
|
|
26
40
|
it 'generates the correct inspect string' do
|
|
27
|
-
expect(data.inspect).to eq('#<Usps::Imis::Data
|
|
41
|
+
expect(data.inspect).to eq('#<Usps::Imis::Data entity="ABC_ASC_Individual_Demog" imis_id=31092>')
|
|
28
42
|
end
|
|
29
43
|
|
|
30
44
|
context 'with data from a Panel' do
|
|
@@ -44,7 +58,7 @@ describe Usps::Imis::Data do
|
|
|
44
58
|
|
|
45
59
|
it 'generates the correct inspect string with an ordinal' do
|
|
46
60
|
expect(data.inspect).to eq(
|
|
47
|
-
'#<Usps::Imis::Data
|
|
61
|
+
'#<Usps::Imis::Data entity="ABC_ASC_Individual_Demog" imis_id=31092 ordinal=99>'
|
|
48
62
|
)
|
|
49
63
|
end
|
|
50
64
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: usps-imis-api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Julian Fiander
|
|
@@ -63,6 +63,7 @@ files:
|
|
|
63
63
|
- lib/usps/imis/panels/education.rb
|
|
64
64
|
- lib/usps/imis/panels/vsc.rb
|
|
65
65
|
- lib/usps/imis/properties.rb
|
|
66
|
+
- lib/usps/imis/query.rb
|
|
66
67
|
- lib/usps/imis/requests.rb
|
|
67
68
|
- lib/usps/imis/version.rb
|
|
68
69
|
- spec/lib/usps/imis/api_spec.rb
|