mx-platform-ruby 0.1.0 → 0.1.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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +20 -0
  3. data/.gitignore +13 -0
  4. data/.rubocop.yml +44 -0
  5. data/Gemfile +5 -0
  6. data/LICENSE +21 -0
  7. data/README.md +60 -0
  8. data/Rakefile +11 -0
  9. data/lib/mx-platform-ruby.rb +44 -0
  10. data/lib/mx-platform-ruby/account.rb +107 -0
  11. data/lib/mx-platform-ruby/account_number.rb +57 -0
  12. data/lib/mx-platform-ruby/account_owner.rb +42 -0
  13. data/lib/mx-platform-ruby/category.rb +127 -0
  14. data/lib/mx-platform-ruby/challenge.rb +37 -0
  15. data/lib/mx-platform-ruby/client.rb +59 -0
  16. data/lib/mx-platform-ruby/connect_widget.rb +43 -0
  17. data/lib/mx-platform-ruby/credential.rb +54 -0
  18. data/lib/mx-platform-ruby/enhanced_transaction.rb +44 -0
  19. data/lib/mx-platform-ruby/error.rb +6 -0
  20. data/lib/mx-platform-ruby/holding.rb +87 -0
  21. data/lib/mx-platform-ruby/institution.rb +78 -0
  22. data/lib/mx-platform-ruby/member.rb +242 -0
  23. data/lib/mx-platform-ruby/member_status.rb +35 -0
  24. data/lib/mx-platform-ruby/merchant.rb +52 -0
  25. data/lib/mx-platform-ruby/oauth_window.rb +32 -0
  26. data/lib/mx-platform-ruby/pageable.rb +29 -0
  27. data/lib/mx-platform-ruby/statement.rb +70 -0
  28. data/lib/mx-platform-ruby/tag.rb +104 -0
  29. data/lib/mx-platform-ruby/tagging.rb +107 -0
  30. data/lib/mx-platform-ruby/transaction.rb +162 -0
  31. data/lib/mx-platform-ruby/transaction_rule.rb +112 -0
  32. data/lib/mx-platform-ruby/user.rb +112 -0
  33. data/lib/mx-platform-ruby/version.rb +5 -0
  34. data/lib/mx-platform-ruby/widget.rb +49 -0
  35. data/mx-platform-ruby.gemspec +31 -0
  36. data/spec/lib/mx-platform-ruby/account_number_spec.rb +100 -0
  37. data/spec/lib/mx-platform-ruby/account_owner_spec.rb +71 -0
  38. data/spec/lib/mx-platform-ruby/account_spec.rb +267 -0
  39. data/spec/lib/mx-platform-ruby/category_spec.rb +244 -0
  40. data/spec/lib/mx-platform-ruby/challenge_spec.rb +72 -0
  41. data/spec/lib/mx-platform-ruby/client_spec.rb +101 -0
  42. data/spec/lib/mx-platform-ruby/connect_widget_spec.rb +66 -0
  43. data/spec/lib/mx-platform-ruby/credential_spec.rb +90 -0
  44. data/spec/lib/mx-platform-ruby/enhanced_transaction_spec.rb +89 -0
  45. data/spec/lib/mx-platform-ruby/holding_spec.rb +178 -0
  46. data/spec/lib/mx-platform-ruby/institution_spec.rb +141 -0
  47. data/spec/lib/mx-platform-ruby/member_spec.rb +557 -0
  48. data/spec/lib/mx-platform-ruby/member_status_spec.rb +76 -0
  49. data/spec/lib/mx-platform-ruby/merchant_spec.rb +89 -0
  50. data/spec/lib/mx-platform-ruby/oauth_window_spec.rb +47 -0
  51. data/spec/lib/mx-platform-ruby/pageable_spec.rb +75 -0
  52. data/spec/lib/mx-platform-ruby/statement_spec.rb +130 -0
  53. data/spec/lib/mx-platform-ruby/tag_spec.rb +179 -0
  54. data/spec/lib/mx-platform-ruby/tagging_spec.rb +191 -0
  55. data/spec/lib/mx-platform-ruby/transaction_rule_spec.rb +207 -0
  56. data/spec/lib/mx-platform-ruby/transaction_spec.rb +449 -0
  57. data/spec/lib/mx-platform-ruby/user_spec.rb +196 -0
  58. data/spec/lib/mx-platform-ruby/widget_spec.rb +76 -0
  59. data/spec/lib/mx-platform-ruby_spec.rb +15 -0
  60. data/spec/sample.pdf +0 -0
  61. data/spec/spec_helper.rb +24 -0
  62. metadata +63 -3
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MXPlatformRuby
4
+ class Category
5
+ extend ::MXPlatformRuby::Pageable
6
+ include ::ActiveAttr::Model
7
+
8
+ attribute :created_at
9
+ attribute :guid
10
+ attribute :is_default
11
+ attribute :is_income
12
+ attribute :metadata
13
+ attribute :name
14
+ attribute :parent_guid
15
+ attribute :updated_at
16
+
17
+ def self.create_category(options = {})
18
+ create_category_options = create_category_options(options)
19
+ response = ::MXPlatformRuby.client.make_request(create_category_options)
20
+
21
+ category_params = response['category']
22
+ ::MXPlatformRuby::Category.new(category_params)
23
+ end
24
+
25
+ def self.delete_category(options = {})
26
+ delete_category_options = delete_category_options(options)
27
+ ::MXPlatformRuby.client.make_request(delete_category_options)
28
+ end
29
+
30
+ def self.list_categories(options = {})
31
+ options = list_categories_options(options)
32
+
33
+ paginate(options)
34
+ end
35
+
36
+ def self.list_default_categories(options = {})
37
+ options = list_default_categories_options(options)
38
+
39
+ paginate(options)
40
+ end
41
+
42
+ def self.read_category(options = {})
43
+ read_category_options = read_category_options(options)
44
+ response = ::MXPlatformRuby.client.make_request(read_category_options)
45
+
46
+ category_params = response['category']
47
+ ::MXPlatformRuby::Category.new(category_params)
48
+ end
49
+
50
+ def self.update_category(options = {})
51
+ update_category_options = update_category_options(options)
52
+ response = ::MXPlatformRuby.client.make_request(update_category_options)
53
+
54
+ category_params = response['category']
55
+ ::MXPlatformRuby::Category.new(category_params)
56
+ end
57
+
58
+ # Private class methods
59
+
60
+ def self.create_category_options(options)
61
+ {
62
+ endpoint: "/users/#{options[:user_guid]}/categories",
63
+ http_method: :post,
64
+ request_body: {
65
+ category: {
66
+ metadata: options[:metadata],
67
+ name: options[:name],
68
+ parent_guid: options[:parent_guid]
69
+ }.compact
70
+ }
71
+ }
72
+ end
73
+ private_class_method :create_category_options
74
+
75
+ def self.delete_category_options(options)
76
+ {
77
+ endpoint: "/users/#{options[:user_guid]}/categories/#{options[:category_guid]}",
78
+ http_method: :delete
79
+ }
80
+ end
81
+ private_class_method :delete_category_options
82
+
83
+ def self.list_categories_options(options)
84
+ {
85
+ endpoint: "/users/#{options[:user_guid]}/categories",
86
+ http_method: :get,
87
+ query_params: {
88
+ page: options[:page],
89
+ records_per_page: options[:records_per_page]
90
+ }.compact,
91
+ resource: 'categories'
92
+ }
93
+ end
94
+ private_class_method :list_categories_options
95
+
96
+ def self.list_default_categories_options(options)
97
+ {
98
+ endpoint: "/users/#{options[:user_guid]}/categories/default",
99
+ http_method: :get,
100
+ resource: 'categories'
101
+ }
102
+ end
103
+ private_class_method :list_default_categories_options
104
+
105
+ def self.read_category_options(options)
106
+ {
107
+ endpoint: "/users/#{options[:user_guid]}/categories/#{options[:category_guid]}",
108
+ http_method: :get
109
+ }
110
+ end
111
+ private_class_method :read_category_options
112
+
113
+ def self.update_category_options(options)
114
+ {
115
+ endpoint: "/users/#{options[:user_guid]}/categories/#{options[:category_guid]}",
116
+ http_method: :put,
117
+ request_body: {
118
+ category: {
119
+ metadata: options[:metadata],
120
+ name: options[:name]
121
+ }.compact
122
+ }
123
+ }
124
+ end
125
+ private_class_method :update_category_options
126
+ end
127
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MXPlatformRuby
4
+ class Challenge
5
+ extend ::MXPlatformRuby::Pageable
6
+ include ::ActiveAttr::Model
7
+
8
+ attribute :field_name
9
+ attribute :guid
10
+ attribute :image_data
11
+ attribute :image_options
12
+ attribute :label
13
+ attribute :options
14
+ attribute :type
15
+
16
+ def self.list_member_challenges(options = {})
17
+ options = list_member_challenges_options(options)
18
+
19
+ paginate(options)
20
+ end
21
+
22
+ # Private class methods
23
+
24
+ def self.list_member_challenges_options(options)
25
+ {
26
+ endpoint: "/users/#{options[:user_guid]}/members/#{options[:member_guid]}/challenges",
27
+ http_method: :get,
28
+ query_params: {
29
+ page: options[:page],
30
+ records_per_page: options[:records_per_page]
31
+ }.compact,
32
+ resource: 'challenges'
33
+ }
34
+ end
35
+ private_class_method :list_member_challenges_options
36
+ end
37
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MXPlatformRuby
4
+ class Client
5
+ BASE_URL = 'https://int-api.mx.com'
6
+
7
+ attr_accessor :base_url, :password, :username
8
+
9
+ def initialize(base_url = BASE_URL, password = nil, username = nil)
10
+ @base_url = base_url
11
+ @password = password
12
+ @username = username
13
+ end
14
+
15
+ def http_client
16
+ @http_client ||= ::HTTPClient.new
17
+ end
18
+
19
+ def make_request(options = {})
20
+ body = ::JSON.dump(options[:request_body]) if options[:request_body]
21
+ headers = default_headers.merge(options[:headers] || {})
22
+ url = "#{base_url}#{options[:endpoint]}"
23
+ url = "#{url}?#{::URI.encode_www_form(options[:query_params])}" if options[:query_params]
24
+ method = options[:http_method]
25
+
26
+ response = http_client.public_send(method, url, body, headers)
27
+
28
+ handle_response(response)
29
+ end
30
+
31
+ private
32
+
33
+ def default_headers
34
+ {
35
+ 'Accept': 'application/vnd.mx.api.v1+json',
36
+ 'Authorization': "Basic #{::Base64.urlsafe_encode64("#{username}:#{password}")}",
37
+ 'Content-Type': 'application/json'
38
+ }
39
+ end
40
+
41
+ def format_response_body(body)
42
+ ::JSON.parse(body)
43
+ rescue JSON::ParserError
44
+ file = ::Tempfile.new
45
+ file.write(body)
46
+ file.close
47
+ file
48
+ end
49
+
50
+ def handle_response(response)
51
+ # Handle 200-206 responses as acceptable
52
+ raise ::MXPlatformRuby::Error, "#{response.status}: #{response.body}" unless response.status.between?(200, 206)
53
+
54
+ return if response.body.empty?
55
+
56
+ format_response_body(response.body)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MXPlatformRuby
4
+ class ConnectWidget
5
+ include ::ActiveAttr::Model
6
+
7
+ attribute :connect_widget_url
8
+ attribute :guid
9
+
10
+ def self.request_connect_widget_url(options = {})
11
+ request_connect_widget_url_options = request_connect_widget_url_options(options)
12
+ response = ::MXPlatformRuby.client.make_request(request_connect_widget_url_options)
13
+
14
+ user_params = response['user']
15
+ ::MXPlatformRuby::ConnectWidget.new(user_params)
16
+ end
17
+
18
+ # Private class methods
19
+
20
+ def self.request_connect_widget_url_options(options)
21
+ {
22
+ endpoint: "/users/#{options[:user_guid]}/connect_widget_url",
23
+ http_method: :post,
24
+ request_body: {
25
+ config: {
26
+ color_scheme: options[:color_scheme],
27
+ current_institution_code: options[:current_institution_code],
28
+ current_member_guid: options[:current_member_guid],
29
+ disable_institution_search: options[:disable_institution_search],
30
+ include_transactions: options[:include_transactions],
31
+ is_mobile_webview: options[:is_mobile_webview],
32
+ mode: options[:mode],
33
+ ui_message_version: options[:ui_message_version],
34
+ ui_message_webview_url_scheme: options[:ui_message_webview_url_scheme],
35
+ update_credentials: options[:update_credentials],
36
+ wait_for_full_aggregation: options[:wait_for_full_aggregation]
37
+ }.compact
38
+ }
39
+ }
40
+ end
41
+ private_class_method :request_connect_widget_url_options
42
+ end
43
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MXPlatformRuby
4
+ class Credential
5
+ extend ::MXPlatformRuby::Pageable
6
+ include ::ActiveAttr::Model
7
+
8
+ attribute :display_order
9
+ attribute :field_name
10
+ attribute :field_type
11
+ attribute :guid
12
+ attribute :label
13
+
14
+ def self.list_institution_required_credentials(options = {})
15
+ options = list_institution_required_credentials_options(options)
16
+
17
+ paginate(options)
18
+ end
19
+
20
+ def self.list_member_credentials(options = {})
21
+ options = list_member_credentials_options(options)
22
+
23
+ paginate(options)
24
+ end
25
+
26
+ # Private class methods
27
+
28
+ def self.list_institution_required_credentials_options(options)
29
+ {
30
+ endpoint: "/institutions/#{options[:institution_code]}/credentials",
31
+ http_method: :get,
32
+ query_params: {
33
+ page: options[:page],
34
+ records_per_page: options[:records_per_page]
35
+ }.compact,
36
+ resource: 'credentials'
37
+ }
38
+ end
39
+ private_class_method :list_institution_required_credentials_options
40
+
41
+ def self.list_member_credentials_options(options)
42
+ {
43
+ endpoint: "/users/#{options[:user_guid]}/members/#{options[:member_guid]}/credentials",
44
+ http_method: :get,
45
+ query_params: {
46
+ page: options[:page],
47
+ records_per_page: options[:records_per_page]
48
+ }.compact,
49
+ resource: 'credentials'
50
+ }
51
+ end
52
+ private_class_method :list_member_credentials_options
53
+ end
54
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MXPlatformRuby
4
+ class EnhancedTransaction
5
+ include ::ActiveAttr::Model
6
+
7
+ attribute :amount
8
+ attribute :category
9
+ attribute :description
10
+ attribute :id
11
+ attribute :is_bill_pay
12
+ attribute :is_direct_deposit
13
+ attribute :is_expense
14
+ attribute :is_fee
15
+ attribute :is_income
16
+ attribute :is_international
17
+ attribute :is_overdraft_fee
18
+ attribute :is_payroll_advance
19
+ attribute :merchant_category_code
20
+ attribute :merchant_guid
21
+ attribute :original_description
22
+ attribute :type
23
+
24
+ def self.enhance_transactions(options = {})
25
+ enhance_transactions_options = enhance_transactions_options(options)
26
+ response = ::MXPlatformRuby.client.make_request(enhance_transactions_options)
27
+
28
+ response['transactions'].map { |attributes| ::MXPlatformRuby::EnhancedTransaction.new(attributes) }
29
+ end
30
+
31
+ # Private class methods
32
+
33
+ def self.enhance_transactions_options(options)
34
+ {
35
+ endpoint: '/transactions/enhance',
36
+ http_method: :post,
37
+ request_body: {
38
+ transactions: options[:transactions]
39
+ }.compact
40
+ }
41
+ end
42
+ private_class_method :enhance_transactions_options
43
+ end
44
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MXPlatformRuby
4
+ class Error < StandardError
5
+ end
6
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MXPlatformRuby
4
+ class Holding
5
+ extend ::MXPlatformRuby::Pageable
6
+ include ::ActiveAttr::Model
7
+
8
+ attribute :account_guid
9
+ attribute :cost_basis
10
+ attribute :created_at
11
+ attribute :currency_code
12
+ attribute :cusip
13
+ attribute :daily_change
14
+ attribute :description
15
+ attribute :guid
16
+ attribute :holding_type
17
+ attribute :id
18
+ attribute :market_value
19
+ attribute :member_guid
20
+ attribute :metadata
21
+ attribute :purchase_price
22
+ attribute :shares
23
+ attribute :symbol
24
+ attribute :updated_at
25
+ attribute :user_guid
26
+
27
+ def self.list_holdings_by_member(options = {})
28
+ options = list_holdings_by_member_options(options)
29
+
30
+ paginate(options)
31
+ end
32
+
33
+ def self.list_holdings_by_user(options = {})
34
+ options = list_holdings_by_user_options(options)
35
+
36
+ paginate(options)
37
+ end
38
+
39
+ def self.read_holding(options = {})
40
+ read_holding_options = read_holding_options(options)
41
+ response = ::MXPlatformRuby.client.make_request(read_holding_options)
42
+
43
+ holding_params = response['holding']
44
+ ::MXPlatformRuby::Holding.new(holding_params)
45
+ end
46
+
47
+ # Private class methods
48
+
49
+ def self.list_holdings_by_member_options(options)
50
+ {
51
+ endpoint: "/users/#{options[:user_guid]}/members/#{options[:member_guid]}/holdings",
52
+ http_method: :get,
53
+ query_params: {
54
+ from_date: options[:from_date],
55
+ page: options[:page],
56
+ records_per_page: options[:records_per_page],
57
+ to_date: options[:to_date]
58
+ }.compact,
59
+ resource: 'holdings'
60
+ }
61
+ end
62
+ private_class_method :list_holdings_by_member_options
63
+
64
+ def self.list_holdings_by_user_options(options)
65
+ {
66
+ endpoint: "/users/#{options[:user_guid]}/holdings",
67
+ http_method: :get,
68
+ query_params: {
69
+ from_date: options[:from_date],
70
+ page: options[:page],
71
+ records_per_page: options[:records_per_page],
72
+ to_date: options[:to_date]
73
+ }.compact,
74
+ resource: 'holdings'
75
+ }
76
+ end
77
+ private_class_method :list_holdings_by_user_options
78
+
79
+ def self.read_holding_options(options)
80
+ {
81
+ endpoint: "/users/#{options[:user_guid]}/holdings/#{options[:holding_guid]}",
82
+ http_method: :get
83
+ }
84
+ end
85
+ private_class_method :read_holding_options
86
+ end
87
+ end