usps-imis-api 1.0.0.pre.rc.5 → 1.0.0.pre.rc.8

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/Gemfile.lock +36 -30
  4. data/Readme.md +149 -33
  5. data/lib/usps/imis/api.rb +32 -39
  6. data/lib/usps/imis/business_object.rb +97 -47
  7. data/lib/usps/imis/config.rb +14 -3
  8. data/lib/usps/imis/data.rb +72 -0
  9. data/lib/usps/imis/error.rb +53 -0
  10. data/lib/usps/imis/errors/api_error.rb +11 -0
  11. data/lib/usps/imis/errors/config_error.rb +11 -0
  12. data/lib/usps/imis/errors/locked_id_error.rb +15 -0
  13. data/lib/usps/imis/errors/mapper_error.rb +29 -0
  14. data/lib/usps/imis/errors/not_found_error.rb +11 -0
  15. data/lib/usps/imis/errors/panel_unimplemented_error.rb +34 -0
  16. data/lib/usps/imis/{error → errors}/response_error.rb +5 -8
  17. data/lib/usps/imis/errors/unexpected_property_type_error.rb +31 -0
  18. data/lib/usps/imis/mapper.rb +51 -20
  19. data/lib/usps/imis/mocks/business_object.rb +47 -0
  20. data/lib/usps/imis/mocks.rb +11 -0
  21. data/lib/usps/imis/panels/base_panel.rb +154 -0
  22. data/lib/usps/imis/{panel → panels}/education.rb +2 -2
  23. data/lib/usps/imis/{panel → panels}/vsc.rb +2 -2
  24. data/lib/usps/imis/panels.rb +25 -0
  25. data/lib/usps/imis/properties.rb +50 -0
  26. data/lib/usps/imis/query.rb +94 -0
  27. data/lib/usps/imis/requests.rb +27 -3
  28. data/lib/usps/imis/version.rb +1 -1
  29. data/lib/usps/imis.rb +20 -15
  30. data/spec/lib/usps/imis/api_spec.rb +26 -13
  31. data/spec/lib/usps/imis/business_object_spec.rb +70 -33
  32. data/spec/lib/usps/imis/config_spec.rb +2 -2
  33. data/spec/lib/usps/imis/data_spec.rb +66 -0
  34. data/spec/lib/usps/imis/{error/api_error_spec.rb → error_spec.rb} +1 -1
  35. data/spec/lib/usps/imis/{error → errors}/response_error_spec.rb +4 -4
  36. data/spec/lib/usps/imis/mapper_spec.rb +27 -3
  37. data/spec/lib/usps/imis/mocks/business_object_spec.rb +65 -0
  38. data/spec/lib/usps/imis/panels/base_panel_spec.rb +33 -0
  39. data/spec/lib/usps/imis/panels/education_spec.rb +70 -0
  40. data/spec/lib/usps/imis/{panel → panels}/vsc_spec.rb +6 -7
  41. data/spec/lib/usps/imis/properties_spec.rb +19 -0
  42. data/spec/spec_helper.rb +2 -0
  43. data/usps-imis-api.gemspec +1 -1
  44. metadata +28 -16
  45. data/lib/ext/hash.rb +0 -10
  46. data/lib/usps/imis/error/api_error.rb +0 -44
  47. data/lib/usps/imis/error/mapper_error.rb +0 -11
  48. data/lib/usps/imis/panel/base_panel.rb +0 -101
  49. data/lib/usps/imis/panel/panel_properties.rb +0 -52
  50. data/spec/lib/usps/imis/panel/base_panel_spec.rb +0 -32
  51. data/spec/lib/usps/imis/panel/education_spec.rb +0 -55
  52. data/spec/lib/usps/imis/panel/panel_properties_spec.rb +0 -19
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: 1.0.0.pre.rc.5
4
+ version: 1.0.0.pre.rc.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Fiander
@@ -41,35 +41,47 @@ files:
41
41
  - Readme.md
42
42
  - bin/console
43
43
  - bin/setup
44
- - lib/ext/hash.rb
45
44
  - lib/usps/imis.rb
46
45
  - lib/usps/imis/api.rb
47
46
  - lib/usps/imis/business_object.rb
48
47
  - lib/usps/imis/config.rb
49
- - lib/usps/imis/error/api_error.rb
50
- - lib/usps/imis/error/mapper_error.rb
51
- - lib/usps/imis/error/response_error.rb
48
+ - lib/usps/imis/data.rb
49
+ - lib/usps/imis/error.rb
50
+ - lib/usps/imis/errors/api_error.rb
51
+ - lib/usps/imis/errors/config_error.rb
52
+ - lib/usps/imis/errors/locked_id_error.rb
53
+ - lib/usps/imis/errors/mapper_error.rb
54
+ - lib/usps/imis/errors/not_found_error.rb
55
+ - lib/usps/imis/errors/panel_unimplemented_error.rb
56
+ - lib/usps/imis/errors/response_error.rb
57
+ - lib/usps/imis/errors/unexpected_property_type_error.rb
52
58
  - lib/usps/imis/mapper.rb
53
- - lib/usps/imis/panel/base_panel.rb
54
- - lib/usps/imis/panel/education.rb
55
- - lib/usps/imis/panel/panel_properties.rb
56
- - lib/usps/imis/panel/vsc.rb
59
+ - lib/usps/imis/mocks.rb
60
+ - lib/usps/imis/mocks/business_object.rb
61
+ - lib/usps/imis/panels.rb
62
+ - lib/usps/imis/panels/base_panel.rb
63
+ - lib/usps/imis/panels/education.rb
64
+ - lib/usps/imis/panels/vsc.rb
65
+ - lib/usps/imis/properties.rb
66
+ - lib/usps/imis/query.rb
57
67
  - lib/usps/imis/requests.rb
58
68
  - lib/usps/imis/version.rb
59
69
  - spec/lib/usps/imis/api_spec.rb
60
70
  - spec/lib/usps/imis/business_object_spec.rb
61
71
  - spec/lib/usps/imis/config_spec.rb
62
- - spec/lib/usps/imis/error/api_error_spec.rb
63
- - spec/lib/usps/imis/error/response_error_spec.rb
72
+ - spec/lib/usps/imis/data_spec.rb
73
+ - spec/lib/usps/imis/error_spec.rb
74
+ - spec/lib/usps/imis/errors/response_error_spec.rb
64
75
  - spec/lib/usps/imis/mapper_spec.rb
65
- - spec/lib/usps/imis/panel/base_panel_spec.rb
66
- - spec/lib/usps/imis/panel/education_spec.rb
67
- - spec/lib/usps/imis/panel/panel_properties_spec.rb
68
- - spec/lib/usps/imis/panel/vsc_spec.rb
76
+ - spec/lib/usps/imis/mocks/business_object_spec.rb
77
+ - spec/lib/usps/imis/panels/base_panel_spec.rb
78
+ - spec/lib/usps/imis/panels/education_spec.rb
79
+ - spec/lib/usps/imis/panels/vsc_spec.rb
80
+ - spec/lib/usps/imis/properties_spec.rb
69
81
  - spec/lib/usps/imis_spec.rb
70
82
  - spec/spec_helper.rb
71
83
  - usps-imis-api.gemspec
72
- homepage: http://rubygems.org/gems/usps-imis-api
84
+ homepage: https://github.com/unitedstatespowersquadrons/imis-api-ruby
73
85
  licenses: []
74
86
  metadata:
75
87
  rubygems_mfa_required: 'true'
data/lib/ext/hash.rb DELETED
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Import a simplified version of to_query from Rails if not already defined
4
- class Hash
5
- def to_query
6
- map do |key, value|
7
- "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
8
- end.sort * '&'
9
- end
10
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Usps
4
- module Imis
5
- module Error
6
- # Base error class for all internal exceptions
7
- #
8
- class ApiError < StandardError
9
- # Additional call-specific metadata to pass through to Bugsnag
10
- #
11
- attr_accessor :metadata
12
-
13
- # A new instance of +ApiError+
14
- #
15
- # @param message [String] The base exception message
16
- # @param metadata [Hash] Additional call-specific metadata to pass through to Bugsnag
17
- #
18
- def initialize(message, metadata = {})
19
- super(message)
20
- @metadata = metadata
21
- end
22
-
23
- # Additional metadata to include in Bugsnag reports
24
- #
25
- # Can include fields at the top level, which will be shows on the custom tab
26
- #
27
- # Can include fields nested under a top-level key, which will be shown on a tab with the
28
- # top-level key as its name
29
- #
30
- # @return [Hash]
31
- #
32
- def bugsnag_meta_data
33
- metadata == {} ? {} : base_metadata
34
- end
35
-
36
- private
37
-
38
- def base_metadata
39
- { api: metadata }
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Usps
4
- module Imis
5
- module Error
6
- # Exception raised by a +Mapper+
7
- #
8
- class MapperError < ApiError; end
9
- end
10
- end
11
- end
@@ -1,101 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Usps
4
- module Imis
5
- module Panel
6
- # Base class for configuring Panels
7
- #
8
- class BasePanel
9
- # The parent +Api+ object
10
- #
11
- attr_reader :api
12
-
13
- def initialize(api = nil, imis_id: nil)
14
- @api = api || Api.new
15
- @api.imis_id = imis_id if imis_id
16
- end
17
-
18
- # Get a specific object from the Panel
19
- #
20
- # @param ordinal [Integer] The ordinal identifier for the desired object
21
- #
22
- def get(ordinal)
23
- api.business_object(business_object, url_id: "~#{api.imis_id}|#{ordinal}").get
24
- end
25
-
26
- # Create a new object in the Panel
27
- #
28
- # @param data [Hash] The record data for the desired object
29
- #
30
- def create(data)
31
- api.business_object(business_object, url_id: '').post(payload(data))
32
- end
33
-
34
- # Update an existing object in the Panel
35
- #
36
- # @param data [Hash] The record data for the desired object -- including the required
37
- # +ordinal+ identifier
38
- #
39
- def update(data)
40
- api
41
- .business_object(business_object, url_id: "~#{api.imis_id}|#{data[:ordinal]}")
42
- .put(payload(data))
43
- end
44
-
45
- # Remove a specific object from the Panel
46
- #
47
- # @param ordinal [Integer] The ordinal identifier for the desired object
48
- #
49
- def destroy(ordinal)
50
- api.business_object(business_object, url_id: "~#{api.imis_id}|#{ordinal}").delete
51
- end
52
-
53
- private
54
-
55
- def business_object
56
- raise Error::ApiError, "#{self.class.name} must implement #business_object"
57
- end
58
-
59
- def payload(_data)
60
- raise Error::ApiError, "#{self.class.name} must implement #payload(data)"
61
- end
62
-
63
- def payload_header(data)
64
- {
65
- '$type' => 'Asi.Soa.Core.DataContracts.GenericEntityData, Asi.Contracts',
66
- 'EntityTypeName' => business_object,
67
- 'PrimaryParentEntityTypeName' => 'Party',
68
- 'Identity' => identity(data[:ordinal]),
69
- 'PrimaryParentIdentity' => primary_parent_identity
70
- }
71
- end
72
-
73
- def identity(ordinal = nil)
74
- {
75
- '$type' => 'Asi.Soa.Core.DataContracts.IdentityData, Asi.Contracts',
76
- 'EntityTypeName' => business_object,
77
- 'IdentityElements' => {
78
- '$type' => identity_type,
79
- '$values' => [api.imis_id, ordinal&.to_s].compact
80
- }
81
- }
82
- end
83
-
84
- def primary_parent_identity
85
- {
86
- '$type' => 'Asi.Soa.Core.DataContracts.IdentityData, Asi.Contracts',
87
- 'EntityTypeName' => 'Party',
88
- 'IdentityElements' => {
89
- '$type' => identity_type,
90
- '$values' => [api.imis_id]
91
- }
92
- }
93
- end
94
-
95
- def identity_type = 'System.Collections.ObjectModel.Collection`1[[System.String, mscorlib]], mscorlib'
96
-
97
- def build_payload(data, &) = payload_header(data).merge(PanelProperties.build(&))
98
- end
99
- end
100
- end
101
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Usps
4
- module Imis
5
- module Panel
6
- # Constructor for the Properties field for Panel requests
7
- #
8
- class PanelProperties
9
- # Build a new Properties field
10
- #
11
- def self.build(&) = new.build(&)
12
-
13
- # Build the Properties field
14
- #
15
- def build
16
- yield(self)
17
-
18
- {
19
- 'Properties' => {
20
- '$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyDataCollection, Asi.Contracts',
21
- '$values' => @properties
22
- }
23
- }
24
- end
25
-
26
- # Add an individual property to the field
27
- #
28
- def add(name, value)
29
- @properties ||= []
30
- @properties << {
31
- '$type' => 'Asi.Soa.Core.DataContracts.GenericPropertyData, Asi.Contracts',
32
- 'Name' => name,
33
- 'Value' => property_value(value)
34
- }
35
- end
36
-
37
- private
38
-
39
- def property_value(value)
40
- case value
41
- when String then value
42
- when Time, DateTime then value.strftime('%Y-%m-%dT%H:%I:%S')
43
- when Integer then { '$type' => 'System.Int32', '$value' => value }
44
- when true, false then { '$type' => 'System.Boolean', '$value' => value }
45
- else
46
- raise Error::ApiError, "Unexpected property type: #{value.inspect}"
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,32 +0,0 @@
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::ApiError, '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::ApiError,
29
- 'Usps::Imis::Panel::InvalidPanelWithBusinessObject must implement #payload(data)'
30
- )
31
- end
32
- end
@@ -1,55 +0,0 @@
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
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Usps::Imis::Panel::PanelProperties do
6
- let(:builder) { described_class.new }
7
-
8
- it 'handles boolean property values' do
9
- expect(builder.send(:property_value, true)).to eq(
10
- '$type' => 'System.Boolean', '$value' => true
11
- )
12
- end
13
-
14
- it 'raises an error for unexpected property types' do
15
- expect { builder.send(:property_value, {}) }.to raise_error(
16
- Usps::Imis::Error::ApiError, 'Unexpected property type: {}'
17
- )
18
- end
19
- end