usps-imis-api 0.9.3 → 0.9.5

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: e19af888058a7e7b952269cf44ca87dcd50c733e5ad4c97760c80fee73e713b6
4
- data.tar.gz: 85c743311d63b29d85ebab874e174446d452a4e0679bdc7c8191d5cdb1557a22
3
+ metadata.gz: 0e2478447353e616e857b13ac4b3c87d62c8f8d9a499a1ef8610355d91181539
4
+ data.tar.gz: f00d8b31112b0295834eca9a74176318d5e51f7596d9fa2082267671763255e6
5
5
  SHA512:
6
- metadata.gz: eebcd44785ae1a0d021ff01a7205b2fe9db7546c73dd3f47e3e4c34db90c1344bc2dee97283f67a484764b87b1b8ade9e04811a848caece4bd7287df3297e55c
7
- data.tar.gz: 52dc9356735c0d972096fefe3de91c5acb2f3cf4698f5fe2a4ac711e655b15f384c7a815a9c4eff7ac12db09f9e425f03de2f318df2d45b99bc14b84e49ce7e7
6
+ metadata.gz: 8dda7fe4ff5daab7fc34df6ca508005f38295987f626cc73762fbb6f641404e5f9ad9f4108815362f98333e806c2366b7143c94cf3a861d6729cdc77034b2a09
7
+ data.tar.gz: d9b0f87d187cdb1e10d66ee439a750d659e87ae033fe3c7848d87dc96f211895041ff7196fa88d1f60b27fdfb8a7e39ce03b34a5e74e4be8c88445cb16b01540
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- usps-imis-api (0.9.3)
4
+ usps-imis-api (0.9.5)
5
5
  activesupport (~> 8.0)
6
6
 
7
7
  GEM
data/Readme.md CHANGED
@@ -34,7 +34,7 @@ Usps::Imis.configure do |config|
34
34
  config.password = ENV['IMIS_PASSWORD']
35
35
 
36
36
  # These options will use these defaults
37
- config.logger = Logger.new($stdout)
37
+ config.logger = ActiveSupport::TaggedLogging.new(Logger.new($stdout))
38
38
  config.logger.level = :info
39
39
  end
40
40
  ```
@@ -213,13 +213,24 @@ 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 update interface:
216
+ Mapper class to further simplify the fetch / update interfaces:
217
+
218
+ ```ruby
219
+ mm = api.mapper.fetch(:mm)
220
+ mm = api.mapper[:mm]
221
+ ```
217
222
 
218
223
  ```ruby
219
224
  api.mapper.update(mm: 15)
220
225
  ```
221
226
 
222
- For simplicity, you can also call `update` on the `Api` class directly:
227
+ For simplicity, you can also call `fetch` (or simply use Hash access syntax) and `update` on the
228
+ `Api` class directly:
229
+
230
+ ```ruby
231
+ api.fetch(:mm)
232
+ api[:mm]
233
+ ```
223
234
 
224
235
  ```ruby
225
236
  api.update(mm: 15)
data/lib/usps/imis/api.rb CHANGED
@@ -128,11 +128,14 @@ module Usps
128
128
  @mapper ||= Mapper.new(self)
129
129
  end
130
130
 
131
+ # Convenience alias for reading mapped fields
132
+ #
133
+ def fetch(field_key) = mapper.fetch(field_key)
134
+ alias [] fetch
135
+
131
136
  # Convenience alias for updating mapped fields
132
137
  #
133
- def update(data)
134
- mapper.update(data)
135
- end
138
+ def update(data) = mapper.update(data)
136
139
 
137
140
  # Convenience accessor for available Panel objects, each using this instance as its parent
138
141
  # +Api+
@@ -147,10 +150,12 @@ module Usps
147
150
 
148
151
  private
149
152
 
153
+ def logger = Imis.logger('Api')
154
+
150
155
  # Authenticate to the iMIS API, and store the access token and expiration time
151
156
  #
152
157
  def authenticate
153
- Imis.logger.debug 'Authenticating with iMIS'
158
+ logger.debug 'Authenticating with iMIS'
154
159
 
155
160
  uri = URI(File.join(Imis.configuration.hostname, AUTHENTICATION_PATH))
156
161
  req = Net::HTTP::Post.new(uri)
@@ -111,6 +111,8 @@ module Usps
111
111
  def token = api.token
112
112
  def token_expiration = api.token_expiration
113
113
 
114
+ def logger = Imis.logger('BusinessObject')
115
+
114
116
  # Construct a business object API endpoint address
115
117
  #
116
118
  def uri(id: nil)
@@ -164,7 +166,7 @@ module Usps
164
166
  request = Net::HTTP::Get.new(uri)
165
167
  result = submit(uri, authorize(request))
166
168
  result = Data.from_json(result.body)
167
- JSON.pretty_generate(result).split("\n").each { Imis.logger.debug " -> #{it}" }
169
+ JSON.pretty_generate(result).split("\n").each { logger.debug " -> #{it}" }
168
170
  result
169
171
  end
170
172
 
@@ -174,7 +176,7 @@ module Usps
174
176
  request.body = JSON.dump(body)
175
177
  result = submit(uri, authorize(request))
176
178
  result = Data.from_json(result.body)
177
- JSON.pretty_generate(result).split("\n").each { Imis.logger.debug " -> #{it}" }
179
+ JSON.pretty_generate(result).split("\n").each { logger.debug " -> #{it}" }
178
180
  result
179
181
  end
180
182
  end
@@ -8,15 +8,15 @@ 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, :logger
12
- attr_reader :environment, :logger_level
11
+ attr_accessor :imis_id_query_name, :username, :password
12
+ attr_reader :environment, :logger, :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
+ @logger = ActiveSupport::TaggedLogging.new(Logger.new($stdout, level: :info))
20
20
 
21
21
  yield self if block_given?
22
22
 
@@ -27,6 +27,10 @@ module Usps
27
27
  @environment = ActiveSupport::StringInquirer.new(env.to_s)
28
28
  end
29
29
 
30
+ def logger=(logger)
31
+ @logger = ActiveSupport::TaggedLogging.new(logger)
32
+ end
33
+
30
34
  # Environment-specific API endpoint hostname
31
35
  #
32
36
  # @return The API hostname for the current environment
@@ -19,7 +19,7 @@ module Usps
19
19
  #
20
20
  def message
21
21
  <<~MESSAGE.chomp
22
- Mapper does not recognize field: "#{metadata[:field_name]}".
22
+ Mapper does not recognize field: "#{metadata[:field_key]}".
23
23
  Please report what data you are attempting to work with to ITCom leadership.
24
24
  MESSAGE
25
25
  end
@@ -28,6 +28,14 @@ module Usps
28
28
  @api.imis_id = imis_id if imis_id
29
29
  end
30
30
 
31
+ def fetch(field_key)
32
+ missing_mapping!(field_key) unless FIELD_MAPPING.key?(field_key.to_sym)
33
+
34
+ business_object_name, field = FIELD_MAPPING[field_key]
35
+ api.on(business_object_name)[field]
36
+ end
37
+ alias [] fetch
38
+
31
39
  # Update a member's data on multiple affected business objects by arbitrary field names
32
40
  #
33
41
  # Does not require knowing which business object / iMIS-specific field name to use
@@ -57,25 +65,27 @@ module Usps
57
65
 
58
66
  private
59
67
 
60
- def map_update(field_name)
61
- missing_mapping!(field_name) unless FIELD_MAPPING.key?(field_name.to_sym)
68
+ def logger = Imis.logger('Mapper')
69
+
70
+ def map_update(field_key)
71
+ missing_mapping!(field_key) unless FIELD_MAPPING.key?(field_key.to_sym)
62
72
 
63
- business_object_name, field = FIELD_MAPPING[field_name.to_sym]
73
+ business_object_name, field = FIELD_MAPPING[field_key.to_sym]
64
74
  yield(business_object_name, field)
65
75
  end
66
76
 
67
- def missing_mapping!(field_name)
77
+ def missing_mapping!(field_key)
68
78
  unless ENV['TESTING']
69
79
  # :nocov:
70
- warn(
71
- "Mapper does not know how to handle field \"#{field_name}\".\n\n" \
72
- 'You can use api.put_fields(business_object_name, { field_name => value }) ' \
73
- "if you know the business object and iMIS-specific field name.\n\n"
74
- )
80
+ "Mapper does not know how to handle field \"#{field_key}\".\n\n" \
81
+ 'You can use api.put_fields(business_object_name, { field_name => value }) ' \
82
+ "if you know the business object and iMIS-specific field name.\n\n"
83
+ .split("\n")
84
+ .each { logger.warn(it) }
75
85
  # :nocov:
76
86
  end
77
87
 
78
- raise Errors::MapperError.new({ field_name: })
88
+ raise Errors::MapperError.new({ field_key: })
79
89
  end
80
90
  end
81
91
  end
@@ -93,6 +93,8 @@ module Usps
93
93
 
94
94
  private
95
95
 
96
+ def logger = Imis.logger('Panel')
97
+
96
98
  def business_object
97
99
  raise Errors::PanelUnimplementedError.from(self.class.name, 'business_object')
98
100
  end
@@ -43,7 +43,7 @@ module Usps
43
43
  # Iterate through all results from the query
44
44
  #
45
45
  def each(&)
46
- Imis.logger.info 'Running IQA Query on iMIS'
46
+ logger.info 'Running IQA Query on iMIS'
47
47
 
48
48
  items = []
49
49
  find_each { items << it }
@@ -57,14 +57,14 @@ module Usps
57
57
  count = 0
58
58
 
59
59
  while result['HasNext']
60
- Imis.logger.info 'Fetching IQA Query page'
60
+ logger.info 'Fetching IQA Query page'
61
61
 
62
62
  result = fetch
63
63
 
64
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}" }
65
+ logger.info " -> #{count} / #{result['TotalCount']} #{'item'.pluralize(count)}"
66
+ logger.debug ' -> Query page data:'
67
+ JSON.pretty_generate(result).split("\n").each { logger.debug " -> #{it}" }
68
68
 
69
69
  items = result['Items']['$values'].map { it.except('$type') }
70
70
  @offset = result['NextOffset']
@@ -87,6 +87,8 @@ module Usps
87
87
  def path = "#{QUERY_PATH}?#{query_params.merge(QueryName: query_name, Offset: offset).to_query}"
88
88
  def uri = URI(File.join(Imis.configuration.hostname, path))
89
89
  def fetch = JSON.parse(submit(uri, authorize(Net::HTTP::Get.new(uri))).body)
90
+
91
+ def logger = Imis.logger('Query')
90
92
  end
91
93
  end
92
94
  end
@@ -7,6 +7,8 @@ module Usps
7
7
  module Requests
8
8
  private
9
9
 
10
+ def logger = Imis.logger
11
+
10
12
  def client(uri)
11
13
  Net::HTTP.new(uri.host, uri.port).tap do |http|
12
14
  http.use_ssl = true
@@ -20,20 +22,20 @@ module Usps
20
22
  #
21
23
  def authorize(request)
22
24
  if token_expiration < Time.now
23
- Imis.logger.debug 'Token expired: re-authenticating with iMIS'
25
+ logger.debug 'Token expired: re-authenticating with iMIS'
24
26
  authenticate
25
27
  end
26
28
  request.tap { it.add_field('Authorization', "Bearer #{token}") }
27
29
  end
28
30
 
29
31
  def submit(uri, request)
30
- Imis.logger.info 'Submitting request to iMIS'
31
- Imis.logger.debug " -> #{request.class.name.demodulize.upcase} #{uri}"
32
- sanitized_request_body(request).split("\n").each { Imis.logger.debug " -> #{it}" }
32
+ logger.info 'Submitting request to iMIS'
33
+ logger.debug " -> #{request.class.name.demodulize.upcase} #{uri}"
34
+ sanitized_request_body(request).split("\n").each { logger.debug " -> #{it}" }
33
35
  client(uri).request(request).tap do |result|
34
36
  raise Errors::ResponseError.from(result) unless result.is_a?(Net::HTTPSuccess)
35
37
 
36
- Imis.logger.info 'Request succeeded'
38
+ logger.info 'Request succeeded'
37
39
  end
38
40
  end
39
41
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Usps
4
4
  module Imis
5
- VERSION = '0.9.3'
5
+ VERSION = '0.9.5'
6
6
  end
7
7
  end
data/lib/usps/imis.rb CHANGED
@@ -11,6 +11,8 @@ require 'active_support/core_ext/object/to_query'
11
11
  require 'active_support/core_ext/enumerable'
12
12
  require 'active_support/string_inquirer'
13
13
  require 'logger'
14
+ require 'active_support/isolated_execution_state' # Fix costant loading issue with TaggedLogging
15
+ require 'active_support/tagged_logging'
14
16
 
15
17
  # Internal requires
16
18
  require_relative 'imis/config'
@@ -43,9 +45,9 @@ module Usps
43
45
  configuration
44
46
  end
45
47
 
46
- # Logger instance to write to
48
+ # Logger (with optional nested tags) to write to
47
49
  #
48
- def logger = configuration.logger
50
+ def logger(*tags) = configuration.logger.tagged('iMIS', *tags)
49
51
  end
50
52
  end
51
53
  end
@@ -13,6 +13,30 @@ describe Usps::Imis::Mapper do
13
13
  end
14
14
  end
15
15
 
16
+ describe '#fetch' do
17
+ before { api.imis_id = 31092 }
18
+
19
+ it 'fetches a mapped field' do
20
+ expect(api.mapper.fetch(:mm)).to be_a(Integer)
21
+ end
22
+
23
+ it 'supports Hash access syntax' do
24
+ expect(api.mapper[:mm]).to be_a(Integer)
25
+ end
26
+
27
+ it 'supports Hash access syntax on the Api directly' do
28
+ expect(api[:mm]).to be_a(Integer)
29
+ end
30
+
31
+ it 'raises for unmapped updates' do
32
+ expect { api.mapper.fetch(:another) }.to raise_error(
33
+ Usps::Imis::Errors::MapperError,
34
+ %(Mapper does not recognize field: "another".\n) \
35
+ 'Please report what data you are attempting to work with to ITCom leadership.'
36
+ )
37
+ end
38
+ end
39
+
16
40
  describe '#update' do
17
41
  before { api.imis_id = 31092 }
18
42
 
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.9.3
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Fiander