usps-imis-api 0.11.23 → 1.0.0.pre.rc.1

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +57 -0
  3. data/.gitignore +4 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +88 -0
  6. data/.ruby-version +1 -0
  7. data/.simplecov +8 -0
  8. data/Gemfile +12 -0
  9. data/Gemfile.lock +95 -0
  10. data/Rakefile +12 -0
  11. data/Readme.md +191 -19
  12. data/bin/console +21 -0
  13. data/bin/setup +8 -0
  14. data/lib/ext/hash.rb +10 -0
  15. data/lib/usps/imis/api.rb +138 -177
  16. data/lib/usps/imis/config.rb +10 -68
  17. data/lib/usps/imis/error/api.rb +26 -0
  18. data/lib/usps/imis/error/mapper.rb +9 -0
  19. data/lib/usps/imis/{errors/response_error.rb → error/response.rb} +7 -34
  20. data/lib/usps/imis/mapper.rb +21 -90
  21. data/lib/usps/imis/panel/base_panel.rb +42 -0
  22. data/lib/usps/imis/panel/education.rb +111 -0
  23. data/lib/usps/imis/panel/vsc.rb +109 -0
  24. data/lib/usps/imis/version.rb +1 -1
  25. data/lib/usps/imis.rb +17 -32
  26. data/spec/lib/usps/imis/api_spec.rb +143 -0
  27. data/spec/lib/usps/imis/config_spec.rb +33 -0
  28. data/spec/lib/usps/imis/error/api_spec.rb +17 -0
  29. data/spec/lib/usps/imis/error/response_spec.rb +107 -0
  30. data/spec/lib/usps/imis/mapper_spec.rb +31 -0
  31. data/spec/lib/usps/imis/panel/base_panel_spec.rb +32 -0
  32. data/spec/lib/usps/imis/panel/education_spec.rb +55 -0
  33. data/spec/lib/usps/imis/panel/vsc_spec.rb +38 -0
  34. data/spec/lib/usps/imis_spec.rb +11 -0
  35. data/spec/spec_helper.rb +35 -0
  36. data/usps-imis-api.gemspec +18 -0
  37. metadata +33 -94
  38. data/bin/imis +0 -8
  39. data/lib/usps/imis/business_object.rb +0 -209
  40. data/lib/usps/imis/command_line/interface.rb +0 -204
  41. data/lib/usps/imis/command_line/options_parser.rb +0 -136
  42. data/lib/usps/imis/command_line.rb +0 -15
  43. data/lib/usps/imis/data.rb +0 -76
  44. data/lib/usps/imis/error.rb +0 -55
  45. data/lib/usps/imis/errors/api_error.rb +0 -11
  46. data/lib/usps/imis/errors/command_line_error.rb +0 -11
  47. data/lib/usps/imis/errors/config_error.rb +0 -11
  48. data/lib/usps/imis/errors/locked_id_error.rb +0 -15
  49. data/lib/usps/imis/errors/mapper_error.rb +0 -29
  50. data/lib/usps/imis/errors/missing_id_error.rb +0 -15
  51. data/lib/usps/imis/errors/not_found_error.rb +0 -11
  52. data/lib/usps/imis/errors/panel_unimplemented_error.rb +0 -34
  53. data/lib/usps/imis/errors/unexpected_property_type_error.rb +0 -31
  54. data/lib/usps/imis/logger.rb +0 -19
  55. data/lib/usps/imis/logger_formatter.rb +0 -32
  56. data/lib/usps/imis/logger_helpers.rb +0 -17
  57. data/lib/usps/imis/mocks/business_object.rb +0 -47
  58. data/lib/usps/imis/mocks.rb +0 -11
  59. data/lib/usps/imis/panels/base_panel.rb +0 -158
  60. data/lib/usps/imis/panels/education.rb +0 -33
  61. data/lib/usps/imis/panels/vsc.rb +0 -32
  62. data/lib/usps/imis/panels.rb +0 -25
  63. data/lib/usps/imis/properties.rb +0 -50
  64. data/lib/usps/imis/query.rb +0 -153
  65. data/lib/usps/imis/requests.rb +0 -68
  66. data/spec/support/usps/vcr/config.rb +0 -47
  67. data/spec/support/usps/vcr/filters.rb +0 -89
  68. data/spec/support/usps/vcr.rb +0 -8
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Usps::Imis::Error::Api do
6
+ it 'builds Bugsnag metadata' do
7
+ error = described_class.new('Example', something: :else)
8
+
9
+ expect(error.bugsnag_meta_data).to eq(api: { something: :else })
10
+ end
11
+
12
+ it 'ignores Bugsnag metadata with none provided' do
13
+ error = described_class.new('Example')
14
+
15
+ expect(error.bugsnag_meta_data).to eq({})
16
+ end
17
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ ApiResponseStub = Struct.new(:code, :body)
6
+
7
+ describe Usps::Imis::Error::Response do
8
+ let(:error) { described_class.from(response) }
9
+
10
+ describe 'error codes' do
11
+ context 'with a 400' do
12
+ let(:response) { ApiResponseStub.new('400', 'body') }
13
+
14
+ it 'builds the Bugsnag metadata correctly' do
15
+ expect(error.bugsnag_meta_data).to eq(api: { status: :bad_request, body: 'body' })
16
+ end
17
+ end
18
+
19
+ context 'with a 401' do
20
+ let(:response) { ApiResponseStub.new('401', 'body') }
21
+
22
+ it 'builds the Bugsnag metadata correctly' do
23
+ expect(error.bugsnag_meta_data).to eq(api: { status: :unauthorized, body: 'body' })
24
+ end
25
+ end
26
+
27
+ context 'with a 404' do
28
+ let(:response) { ApiResponseStub.new('404', 'body') }
29
+
30
+ it 'builds the Bugsnag metadata correctly' do
31
+ expect(error.bugsnag_meta_data).to eq(api: { status: :not_found, body: 'body' })
32
+ end
33
+ end
34
+
35
+ context 'with a 422' do
36
+ let(:response) { ApiResponseStub.new('422', 'body') }
37
+
38
+ it 'builds the Bugsnag metadata correctly' do
39
+ expect(error.bugsnag_meta_data).to eq(api: { status: :unprocessable_entity, body: 'body' })
40
+ end
41
+ end
42
+
43
+ context 'with a 500' do
44
+ let(:response) { ApiResponseStub.new('500', 'body') }
45
+
46
+ it 'builds the Bugsnag metadata correctly' do
47
+ expect(error.bugsnag_meta_data).to eq(api: { status: :internal_server_error, body: 'body' })
48
+ end
49
+ end
50
+
51
+ context 'with a 429' do
52
+ let(:response) { ApiResponseStub.new('429', 'body') }
53
+
54
+ it 'builds the Bugsnag metadata correctly' do
55
+ expect(error.bugsnag_meta_data).to eq(api: { status: '429', body: 'body' })
56
+ end
57
+ end
58
+ end
59
+
60
+ context 'with a string response body' do
61
+ let(:response) { ApiResponseStub.new('500', 'Body of the API response error') }
62
+ let(:warning_text) do
63
+ <<~WARNING.chomp
64
+ Usps::Imis::Error::Response: [INTERNAL_SERVER_ERROR] The iMIS API returned an error.
65
+ Body of the API response error
66
+ WARNING
67
+ end
68
+
69
+ it 'builds the correct message' do
70
+ expect(error.message).to eq(warning_text)
71
+ end
72
+ end
73
+
74
+ context 'with an invalid_grant hash response body' do
75
+ let(:response_body) do
76
+ { 'error' => 'invalid_grant', 'error_description' => 'description' }
77
+ end
78
+ let(:response) { ApiResponseStub.new('500', response_body) }
79
+ let(:warning_text) do
80
+ <<~WARNING.chomp
81
+ Usps::Imis::Error::Response: [INTERNAL_SERVER_ERROR] The iMIS API returned an error.
82
+ description
83
+ WARNING
84
+ end
85
+
86
+ it 'builds the correct message' do
87
+ expect(error.message).to eq(warning_text)
88
+ end
89
+ end
90
+
91
+ context 'with a generic hash response body' do
92
+ let(:response_body) do
93
+ { 'error' => 'summary', 'error_description' => 'description' }
94
+ end
95
+ let(:response) { ApiResponseStub.new('500', response_body) }
96
+ let(:warning_text) do
97
+ <<~WARNING.chomp
98
+ Usps::Imis::Error::Response: [INTERNAL_SERVER_ERROR] The iMIS API returned an error.
99
+ #{response_body}
100
+ WARNING
101
+ end
102
+
103
+ it 'builds the correct message' do
104
+ expect(error.message).to eq(warning_text)
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Usps::Imis::Mapper do
6
+ let(:api) { described_class.new.api }
7
+
8
+ describe 'initialize with imis_id' do
9
+ it 'stores the initial imis_id' do
10
+ mapper = described_class.new(imis_id: 42)
11
+
12
+ expect(mapper.api.imis_id).to eq('42')
13
+ end
14
+ end
15
+
16
+ describe '#update' do
17
+ before { api.imis_id = 31092 }
18
+
19
+ it 'sends a mapped update' do
20
+ expect(api.mapper.update(mm: 15).first).to be_a(Hash)
21
+ end
22
+
23
+ it 'raises for unmapped updates' do
24
+ expect { api.mapper.update(something: 'anything') }.to raise_error(
25
+ Usps::Imis::Error::Mapper,
26
+ 'Unrecognized field: "something". ' \
27
+ 'Please report what data you are attempting to work with to ITCom leadership.'
28
+ )
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ module Usps
6
+ module Imis
7
+ module Panel
8
+ class InvalidPanel < BasePanel; end
9
+
10
+ class InvalidPanelWithBusinessObject < BasePanel
11
+ private
12
+
13
+ def business_object = 'Something'
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ describe Usps::Imis::Panel::BasePanel do
20
+ it 'requires #business_object to be defined' do
21
+ expect { Usps::Imis::Panel::InvalidPanel.new.get(1) }.to raise_error(
22
+ Usps::Imis::Error::Api, 'Usps::Imis::Panel::InvalidPanel must implement #business_object'
23
+ )
24
+ end
25
+
26
+ it 'requires #payload(data) to be defined' do
27
+ expect { Usps::Imis::Panel::InvalidPanelWithBusinessObject.new.create({}) }.to raise_error(
28
+ Usps::Imis::Error::Api,
29
+ 'Usps::Imis::Panel::InvalidPanelWithBusinessObject must implement #payload(data)'
30
+ )
31
+ end
32
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Usps::Imis::Panel::Education do
6
+ describe 'api example' do
7
+ let(:education) { described_class.new }
8
+
9
+ let(:details) do
10
+ {
11
+ certificate: 'E136924',
12
+ description: 'Marine Navigation',
13
+ effective_date: Time.now.strftime('%Y-%m-%dT00:00:00'),
14
+ source: 'Online Exams System',
15
+ code: 'MN',
16
+ type_code: 'CRS'
17
+
18
+ }
19
+ end
20
+
21
+ before { education.api.imis_id = 6374 }
22
+
23
+ describe '#get' do
24
+ it 'loads a specific object' do
25
+ expect(education.get(90737)).to be_a(Hash)
26
+ end
27
+ end
28
+
29
+ # rubocop:disable RSpec/ExampleLength
30
+ it 'handles new records correctly', :aggregate_failures do
31
+ new_record = education.create(details)
32
+ expect(new_record).to be_a(Hash)
33
+
34
+ ordinal = new_record['Identity']['IdentityElements']['$values'][1]
35
+
36
+ update_result =
37
+ education.update(details.merge(source: 'Online Exams System - Modified', ordinal:))
38
+ updated = update_result['Properties']['$values'].find do |v|
39
+ v['Name'] == 'ABC_Educ_Source_System'
40
+ end
41
+ expect(updated['Value']).to eq('Online Exams System - Modified')
42
+
43
+ expect(education.destroy(ordinal)).to eq('')
44
+ end
45
+ # rubocop:enable RSpec/ExampleLength
46
+ end
47
+
48
+ describe 'initialization with ID' do
49
+ it 'can initialize with an iMIS ID' do
50
+ panel = described_class.new(imis_id: 6374)
51
+
52
+ expect(panel.api.imis_id).to eq('6374')
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Usps::Imis::Panel::Vsc do
6
+ let(:vsc) { described_class.new }
7
+
8
+ let(:details) do
9
+ {
10
+ certificate: 'E136924',
11
+ year: 2024,
12
+ count: 42
13
+ }
14
+ end
15
+
16
+ before { vsc.api.imis_id = 6374 }
17
+
18
+ describe '#get' do
19
+ it 'loads a specific object' do
20
+ expect(vsc.get(1433)).to be_a(Hash)
21
+ end
22
+ end
23
+
24
+ # rubocop:disable RSpec/ExampleLength
25
+ it 'handles new records correctly', :aggregate_failures do
26
+ new_record = vsc.create(details)
27
+ expect(new_record).to be_a(Hash)
28
+
29
+ ordinal = new_record['Identity']['IdentityElements']['$values'][1]
30
+
31
+ update_result = vsc.update(details.merge(count: 43, ordinal:))
32
+ updated = update_result['Properties']['$values'].find { |v| v['Name'] == 'Quantity' }
33
+ expect(updated['Value']['$value']).to eq(43)
34
+
35
+ expect(vsc.destroy(ordinal)).to eq('')
36
+ end
37
+ # rubocop:enable RSpec/ExampleLength
38
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Usps::Imis do
6
+ it 'returns configuration from configure without a block' do
7
+ described_class.configuration.environment = 'development'
8
+
9
+ expect(described_class.configure.environment).to eq('development')
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ Bundler.setup
5
+ require 'simplecov'
6
+ SimpleCov.minimum_coverage(line: 100, branch: 100)
7
+
8
+ require 'dotenv/load'
9
+ require 'usps/imis'
10
+
11
+ ENV['TESTING'] = 'true'
12
+
13
+ RSpec.configure do |config|
14
+ # Enable flags like --only-failures and --next-failure
15
+ config.example_status_persistence_file_path = 'tmp/.rspec_status'
16
+
17
+ # Disable RSpec exposing methods globally on `Module` and `main`
18
+ config.disable_monkey_patching!
19
+
20
+ config.expose_dsl_globally = true
21
+
22
+ config.expect_with :rspec do |c|
23
+ c.syntax = :expect
24
+ end
25
+
26
+ config.before(:suite) do
27
+ Usps::Imis.configure do |imis_config|
28
+ imis_config.environment = :development
29
+ imis_config.imis_id_query_name = ENV.fetch('IMIS_ID_QUERY_NAME', '')
30
+
31
+ imis_config.username = ENV.fetch('IMIS_USERNAME', '')
32
+ imis_config.password = ENV.fetch('IMIS_PASSWORD', '')
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/usps/imis/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'usps-imis-api'
7
+ s.version = Usps::Imis::VERSION
8
+ s.summary = 'iMIS API Wrapper'
9
+ s.description = 'A wrapper for the iMIS API.'
10
+ s.homepage = 'http://rubygems.org/gems/usps-imis-api'
11
+ s.authors = ['Julian Fiander']
12
+ s.email = 'jsfiander@gmail.com'
13
+ s.require_paths = %w[lib]
14
+ s.files = `git ls-files`.split("\n")
15
+ s.metadata['rubygems_mfa_required'] = 'true'
16
+
17
+ s.required_ruby_version = '>= 3.4'
18
+ end
metadata CHANGED
@@ -1,123 +1,62 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: usps-imis-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.23
4
+ version: 1.0.0.pre.rc.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Fiander
8
8
  bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
- dependencies:
12
- - !ruby/object:Gem::Dependency
13
- name: activesupport
14
- requirement: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - "~>"
17
- - !ruby/object:Gem::Version
18
- version: '8.0'
19
- type: :runtime
20
- prerelease: false
21
- version_requirements: !ruby/object:Gem::Requirement
22
- requirements:
23
- - - "~>"
24
- - !ruby/object:Gem::Version
25
- version: '8.0'
26
- - !ruby/object:Gem::Dependency
27
- name: dotenv
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: 3.1.4
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: 3.1.4
40
- - !ruby/object:Gem::Dependency
41
- name: colorize
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: 1.1.0
47
- type: :runtime
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: 1.1.0
54
- - !ruby/object:Gem::Dependency
55
- name: optimist
56
- requirement: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: 3.2.1
61
- type: :runtime
62
- prerelease: false
63
- version_requirements: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: 3.2.1
11
+ dependencies: []
68
12
  description: A wrapper for the iMIS API.
69
13
  email: jsfiander@gmail.com
70
- executables:
71
- - imis
14
+ executables: []
72
15
  extensions: []
73
16
  extra_rdoc_files: []
74
17
  files:
18
+ - ".github/workflows/main.yml"
19
+ - ".gitignore"
20
+ - ".rspec"
21
+ - ".rubocop.yml"
22
+ - ".ruby-version"
23
+ - ".simplecov"
24
+ - Gemfile
25
+ - Gemfile.lock
26
+ - Rakefile
75
27
  - Readme.md
76
- - bin/imis
28
+ - bin/console
29
+ - bin/setup
30
+ - lib/ext/hash.rb
77
31
  - lib/usps/imis.rb
78
32
  - lib/usps/imis/api.rb
79
- - lib/usps/imis/business_object.rb
80
- - lib/usps/imis/command_line.rb
81
- - lib/usps/imis/command_line/interface.rb
82
- - lib/usps/imis/command_line/options_parser.rb
83
33
  - lib/usps/imis/config.rb
84
- - lib/usps/imis/data.rb
85
- - lib/usps/imis/error.rb
86
- - lib/usps/imis/errors/api_error.rb
87
- - lib/usps/imis/errors/command_line_error.rb
88
- - lib/usps/imis/errors/config_error.rb
89
- - lib/usps/imis/errors/locked_id_error.rb
90
- - lib/usps/imis/errors/mapper_error.rb
91
- - lib/usps/imis/errors/missing_id_error.rb
92
- - lib/usps/imis/errors/not_found_error.rb
93
- - lib/usps/imis/errors/panel_unimplemented_error.rb
94
- - lib/usps/imis/errors/response_error.rb
95
- - lib/usps/imis/errors/unexpected_property_type_error.rb
96
- - lib/usps/imis/logger.rb
97
- - lib/usps/imis/logger_formatter.rb
98
- - lib/usps/imis/logger_helpers.rb
34
+ - lib/usps/imis/error/api.rb
35
+ - lib/usps/imis/error/mapper.rb
36
+ - lib/usps/imis/error/response.rb
99
37
  - lib/usps/imis/mapper.rb
100
- - lib/usps/imis/mocks.rb
101
- - lib/usps/imis/mocks/business_object.rb
102
- - lib/usps/imis/panels.rb
103
- - lib/usps/imis/panels/base_panel.rb
104
- - lib/usps/imis/panels/education.rb
105
- - lib/usps/imis/panels/vsc.rb
106
- - lib/usps/imis/properties.rb
107
- - lib/usps/imis/query.rb
108
- - lib/usps/imis/requests.rb
38
+ - lib/usps/imis/panel/base_panel.rb
39
+ - lib/usps/imis/panel/education.rb
40
+ - lib/usps/imis/panel/vsc.rb
109
41
  - lib/usps/imis/version.rb
110
- - spec/support/usps/vcr.rb
111
- - spec/support/usps/vcr/config.rb
112
- - spec/support/usps/vcr/filters.rb
113
- homepage: https://github.com/unitedstatespowersquadrons/imis-api-ruby
42
+ - spec/lib/usps/imis/api_spec.rb
43
+ - spec/lib/usps/imis/config_spec.rb
44
+ - spec/lib/usps/imis/error/api_spec.rb
45
+ - spec/lib/usps/imis/error/response_spec.rb
46
+ - spec/lib/usps/imis/mapper_spec.rb
47
+ - spec/lib/usps/imis/panel/base_panel_spec.rb
48
+ - spec/lib/usps/imis/panel/education_spec.rb
49
+ - spec/lib/usps/imis/panel/vsc_spec.rb
50
+ - spec/lib/usps/imis_spec.rb
51
+ - spec/spec_helper.rb
52
+ - usps-imis-api.gemspec
53
+ homepage: http://rubygems.org/gems/usps-imis-api
114
54
  licenses: []
115
55
  metadata:
116
56
  rubygems_mfa_required: 'true'
117
57
  rdoc_options: []
118
58
  require_paths:
119
59
  - lib
120
- - spec/support
121
60
  required_ruby_version: !ruby/object:Gem::Requirement
122
61
  requirements:
123
62
  - - ">="
data/bin/imis DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require_relative '../lib/usps/imis'
4
- require_relative '../lib/usps/imis/command_line'
5
-
6
- # Invoke CLI
7
- #
8
- Usps::Imis::CommandLine::Interface.run