finapps 4.0.6 → 4.0.7

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/lib/finapps.rb +8 -0
  4. data/lib/finapps/rest/alert_definitions.rb +24 -0
  5. data/lib/finapps/rest/alert_occurrences.rb +25 -0
  6. data/lib/finapps/rest/client.rb +8 -0
  7. data/lib/finapps/rest/consumers_portfolios.rb +20 -0
  8. data/lib/finapps/rest/portfolio_reports.rb +18 -0
  9. data/lib/finapps/rest/portfolios.rb +43 -0
  10. data/lib/finapps/rest/portfolios_alerts.rb +34 -0
  11. data/lib/finapps/rest/portfolios_available_consumers.rb +20 -0
  12. data/lib/finapps/rest/portfolios_consumers.rb +45 -0
  13. data/lib/finapps/utils/query_builder.rb +5 -0
  14. data/lib/finapps/version.rb +1 -1
  15. data/spec/rest/alert_definitions_spec.rb +78 -0
  16. data/spec/rest/alert_occurrences_spec.rb +44 -0
  17. data/spec/rest/client_spec.rb +34 -0
  18. data/spec/rest/consumers_portfolios_spec.rb +54 -0
  19. data/spec/rest/portfolio_reports_spec.rb +44 -0
  20. data/spec/rest/portfolios_alerts_spec.rb +125 -0
  21. data/spec/rest/portfolios_available_consumers_spec.rb +54 -0
  22. data/spec/rest/portfolios_consumers_spec.rb +183 -0
  23. data/spec/rest/portfolios_spec.rb +181 -0
  24. data/spec/support/fake_api.rb +54 -0
  25. data/spec/support/fixtures/alert_definition.json +17 -0
  26. data/spec/support/fixtures/alert_definitions.json +24 -0
  27. data/spec/support/fixtures/alert_occurrences.json +32 -0
  28. data/spec/support/fixtures/multiple_consumer_subscribe_error.json +7 -0
  29. data/spec/support/fixtures/portfolio.json +9 -0
  30. data/spec/support/fixtures/portfolio_reports.json +38 -0
  31. data/spec/support/fixtures/portfolios.json +16 -0
  32. data/spec/support/fixtures/portfolios_alerts.json +19 -0
  33. data/spec/support/fixtures/portfolios_available_consumers.json +20 -0
  34. data/spec/support/fixtures/portfolios_consumers.json +14 -0
  35. data/spec/support/fixtures/single_consumer_subscribe_error.json +5 -0
  36. metadata +58 -23
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helpers/client'
4
+
5
+ RSpec.describe FinApps::REST::Portfolios do
6
+ include SpecHelpers::Client
7
+ subject { FinApps::REST::Portfolios.new(client) }
8
+
9
+ describe '#list' do
10
+ let(:list) { subject.list(params) }
11
+ let(:results) { list[RESULTS] }
12
+ let(:errors) { list[ERROR_MESSAGES] }
13
+
14
+ context 'when missing params' do
15
+ let(:params) { nil }
16
+
17
+ it { expect { list }.not_to raise_error }
18
+ it('returns an array') { expect(list).to be_a(Array) }
19
+ it('performs a get and returns the response') { expect(results).to respond_to(:records) }
20
+ it('returns no error messages') { expect(errors).to be_empty }
21
+ end
22
+
23
+ context 'when invalid params are provided' do
24
+ let(:params) { %w[this is an array] }
25
+
26
+ it { expect { list }.to raise_error(FinAppsCore::InvalidArgumentsError) }
27
+ end
28
+
29
+ context 'when including valid params' do
30
+ let(:params) { { page: 2, sort: '-created_date', requested: 25 } }
31
+
32
+ it { expect { list }.not_to raise_error }
33
+ it('returns an array') { expect(list).to be_a(Array) }
34
+ it('performs a get and returns the response') { expect(results).to respond_to(:records) }
35
+ it('returns no error messages') { expect(errors).to be_empty }
36
+ it 'builds query and sends proper request' do
37
+ list
38
+ url = "#{FinAppsCore::REST::Defaults::DEFAULTS[:host]}/v3/portfolios?page=2&requested=25&sort=-created_date"
39
+ expect(WebMock).to have_requested(:get, url)
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '#show' do
45
+ let(:show) { subject.show(id) }
46
+ let(:results) { show[RESULTS] }
47
+ let(:errors) { show[ERROR_MESSAGES] }
48
+
49
+ context 'when missing params' do
50
+ let(:id) { nil }
51
+
52
+ it { expect { show }.to raise_error(FinAppsCore::MissingArgumentsError) }
53
+ end
54
+
55
+ context 'when valid id is provided' do
56
+ let(:id) { 'valid_id' }
57
+
58
+ it { expect { show }.not_to raise_error(FinAppsCore::MissingArgumentsError) }
59
+ it('returns an array') { expect(show).to be_a(Array) }
60
+ it('performs a get and returns the response') do
61
+ expect(results).to respond_to(:_id)
62
+ expect(results).to respond_to(:product)
63
+ end
64
+ it('returns no error messages') { expect(errors).to be_empty }
65
+ end
66
+
67
+ context 'when invalid id is provided' do
68
+ let(:id) { 'invalid_id' }
69
+
70
+ it { expect { show }.not_to raise_error }
71
+ it('results is nil') { expect(results).to be_nil }
72
+ it('error messages array is populated') do
73
+ expect(errors.first.downcase).to eq('resource not found')
74
+ end
75
+ end
76
+ end
77
+
78
+ describe '#create' do
79
+ let(:create) { subject.create(params) }
80
+ let(:results) { create[RESULTS] }
81
+ let(:errors) { create[ERROR_MESSAGES] }
82
+
83
+ context 'when missing params' do
84
+ let(:params) { nil }
85
+
86
+ it { expect { create }.to raise_error(FinAppsCore::MissingArgumentsError) }
87
+ end
88
+
89
+ context 'when valid params are provided' do
90
+ let(:params) { { name: 'Account Checks', description: 'Some Check Stuff', product: 'valid' } }
91
+
92
+ it { expect { create }.not_to raise_error(FinAppsCore::MissingArgumentsError) }
93
+ it('returns an array') { expect(create).to be_a(Array) }
94
+ it('performs a get and returns the response') do
95
+ expect(results).to respond_to(:_id)
96
+ expect(results).to respond_to(:product)
97
+ end
98
+ it('returns no error messages') { expect(errors).to be_empty }
99
+ end
100
+
101
+ context 'when invalid params are provided' do
102
+ let(:params) { { name: 'Account Checks', description: 'Some Check Stuff', product: 'invalid' } }
103
+
104
+ it { expect { create }.not_to raise_error(FinAppsCore::MissingArgumentsError) }
105
+ it('results is nil') { expect(results).to be_nil }
106
+ it('error messages array is populated') do
107
+ expect(errors.first.downcase).to eq('invalid request body')
108
+ end
109
+ end
110
+ end
111
+
112
+ describe '#update' do
113
+ let(:update) { subject.update(id, params) }
114
+ let(:results) { update[RESULTS] }
115
+ let(:errors) { update[ERROR_MESSAGES] }
116
+
117
+ context 'when missing id' do
118
+ let(:id) { nil }
119
+ let(:params) { { fake: 'data' } }
120
+
121
+ it { expect { update }.to raise_error(FinAppsCore::MissingArgumentsError) }
122
+ end
123
+
124
+ context 'when missing params' do
125
+ let(:id) { 'valid_id' }
126
+ let(:params) { nil }
127
+
128
+ it { expect { update }.to raise_error(FinAppsCore::MissingArgumentsError) }
129
+ end
130
+
131
+ context 'when invalid id or params are provided' do
132
+ let(:id) { 'invalid_id' }
133
+ let(:params) { { fake: 'data' } }
134
+
135
+ it { expect { update }.not_to raise_error(FinAppsCore::MissingArgumentsError) }
136
+ it('results is nil') { expect(results).to be_nil }
137
+ it('error messages array is populated') { expect(errors.first.downcase).to eq('resource not found') }
138
+ end
139
+
140
+ context 'when valid id and params are provided' do
141
+ let(:id) { 'valid_id' }
142
+ let(:params) { { fake: 'data' } }
143
+
144
+ it { expect { update }.not_to raise_error(FinAppsCore::MissingArgumentsError) }
145
+ it('returns an array') { expect(update).to be_a(Array) }
146
+ it('performs a get and returns the response') do
147
+ expect(results).to respond_to(:_id)
148
+ expect(results).to respond_to(:product)
149
+ end
150
+ it('returns no error messages') { expect(errors).to be_empty }
151
+ end
152
+ end
153
+
154
+ describe '#destroy' do
155
+ let(:destroy) { subject.destroy(id) }
156
+ let(:results) { destroy[RESULTS] }
157
+ let(:errors) { destroy[ERROR_MESSAGES] }
158
+
159
+ context 'when missing id' do
160
+ let(:id) { nil }
161
+
162
+ it { expect { destroy }.to raise_error(FinAppsCore::MissingArgumentsError) }
163
+ end
164
+
165
+ context 'when invalid id is provided' do
166
+ let(:id) { 'invalid_id' }
167
+
168
+ it { expect { destroy }.not_to raise_error }
169
+ it('results is nil') { expect(results).to be_nil }
170
+ it('error messages array is populated') { expect(errors.first.downcase).to eq('resource not found') }
171
+ end
172
+
173
+ context 'when valid id is provided' do
174
+ let(:id) { 'valid_id' }
175
+
176
+ it { expect { destroy }.not_to raise_error }
177
+ it('results is nil') { expect(results).to be_nil }
178
+ it('error messages array is empty') { expect(errors).to be_empty }
179
+ end
180
+ end
181
+ end
@@ -180,6 +180,60 @@ class FakeApi < Sinatra::Base
180
180
  # products
181
181
  get('/v3/products') { json_response 200, 'products.json' }
182
182
 
183
+ # portfolios
184
+ get('/v3/portfolios') { json_response 200, 'portfolios.json' }
185
+ get('/v3/portfolios/valid_id') { json_response 200, 'portfolio.json' }
186
+ get('/v3/portfolios/invalid_id') { json_response 404, 'resource_not_found.json' }
187
+ post('/v3/portfolios') do
188
+ request.body.rewind
189
+ request_payload = JSON.parse request.body.read
190
+ if request_payload['product'] == 'invalid'
191
+ json_response(400, 'invalid_request_body.json')
192
+ else
193
+ json_response(200, 'portfolio.json')
194
+ end
195
+ end
196
+ put('/v3/portfolios/valid_id') { json_response 200, 'portfolio.json' }
197
+ put('/v3/portfolios/invalid_id') { json_response 404, 'resource_not_found.json' }
198
+ delete('/v3/portfolios/valid_id') { status 204 }
199
+ delete('/v3/portfolios/invalid_id') { json_response 404, 'resource_not_found.json' }
200
+
201
+ # alert definitions
202
+ get('/v3/portfolio/alerts/definitions') { json_response 200, 'alert_definitions.json' }
203
+ get('/v3/portfolio/alerts/definitions/valid_id') { json_response 200, 'alert_definition.json' }
204
+ get('/v3/portfolio/alerts/definitions/invalid_id') { json_response 404, 'resource_not_found.json' }
205
+
206
+ # alert occurrences
207
+ get('/v3/portfolio/alerts/occurrences') { json_response 200, 'alert_occurrences.json' }
208
+
209
+ # portfolios alerts
210
+ get('/v3/portfolios/valid_id/alerts') { json_response 200, 'portfolios_alerts.json' }
211
+ get('/v3/portfolios/invalid_id/alerts') { json_response 404, 'resource_not_found.json' }
212
+ put('/v3/portfolios/valid_id/alerts/valid_id') { status 204 }
213
+ put('/v3/portfolios/invalid_id/alerts/invalid_id') { json_response 404, 'resource_not_found.json' }
214
+ delete('/v3/portfolios/valid_id/alerts/valid_id') { status 204 }
215
+ delete('/v3/portfolios/invalid_id/alerts/invalid_id') { json_response 404, 'resource_not_found.json' }
216
+
217
+ # portfolios consumers
218
+ get('/v3/portfolios/valid_id/consumers') { json_response 200, 'portfolios_consumers.json' }
219
+ get('/v3/portfolios/invalid_id/consumers') { json_response 404, 'resource_not_found.json' }
220
+ post('/v3/portfolios/valid_id/consumers') { status 204 }
221
+ post('/v3/portfolios/invalid_id/consumers') { json_response 400, 'multiple_consumer_subscribe_error.json' }
222
+ post('/v3/portfolios/valid_id/consumers/valid_id') { status 204 }
223
+ post('/v3/portfolios/invalid_id/consumers/invalid_id') { json_response 400, 'single_consumer_subscribe_error.json' }
224
+ delete('/v3/portfolios/valid_id/consumers/valid_id') { status 204 }
225
+ delete('/v3/portfolios/invalid_id/consumers/invalid_id') { json_response 404, 'resource_not_found.json' }
226
+
227
+ # portfolios available consumers
228
+ get('/v3/portfolios/:id/consumers/available') { json_response 200, 'portfolios_available_consumers.json' }
229
+
230
+ # consumers portfolios
231
+ get('/v3/consumers/valid_id/portfolios') { json_response 200, 'portfolios.json' }
232
+ get('/v3/consumers/invalid_id/portfolios') { json_response 404, 'resource_not_found.json' }
233
+
234
+ # portfolio reports
235
+ get('/v3/portfolio/reports') { json_response 200, 'portfolio_reports.json' }
236
+
183
237
  # relevance
184
238
  get('/v3/relevance/ruleset/names') { json_response 200, 'relevance_ruleset_names.json' }
185
239
 
@@ -0,0 +1,17 @@
1
+ {
2
+ "_id": "7d48e535-6405-4c9c-adc2-be94e19cf94e",
3
+ "name": "Low Balance Alert",
4
+ "rule_name": "min_balance",
5
+ "description": "Checks a consumer's account balance",
6
+ "params": [
7
+ {
8
+ "name": "minimum",
9
+ "display": "Minimum Balance",
10
+ "type": "float",
11
+ "message": "Account balance is too low.",
12
+ "value": 200.00
13
+ }
14
+ ],
15
+ "created_date": "2018-09-18T17:23:36.272Z",
16
+ "modified_date": "2018-09-18T17:23:36.272Z"
17
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "total_records": 1,
3
+ "page": 1,
4
+ "total_pages": 1,
5
+ "records": [
6
+ {
7
+ "_id": "7d48e535-6405-4c9c-adc2-be94e19cf94e",
8
+ "name": "Low Balance Alert",
9
+ "rule_name": "min_balance",
10
+ "description": "Checks a consumer's account balance",
11
+ "params": [
12
+ {
13
+ "name": "minimum",
14
+ "display": "Minimum Balance",
15
+ "type": "float",
16
+ "message": "Account balance is too low.",
17
+ "value": 200.00
18
+ }
19
+ ],
20
+ "created_date": "2018-09-18T17:23:36.272Z",
21
+ "modified_date": "2018-09-18T17:23:36.272Z"
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "total_records": 1,
3
+ "page": 1,
4
+ "total_pages": 1,
5
+ "records": [
6
+ {
7
+ "_id": "8847b703-dfd5-4bb8-8c06-35b64d6a6a54",
8
+ "portfolio": {
9
+ "_id": "c75283f7-0dea-4bf0-b5a2-4a648bdc5d95",
10
+ "name": "Account Checks",
11
+ "description": "Checks accounts for various thresholds.",
12
+ "enabled": true,
13
+ "product": "PROD3",
14
+ "created_date": "2018-09-18T17:38:10.353Z",
15
+ "modified_date": "2018-09-18T17:38:10.353Z"
16
+ },
17
+ "consumer": {
18
+ "first_name": "test",
19
+ "last_name": "consumer",
20
+ "email": "testconsumer@finapps.com",
21
+ "memo": "test memo",
22
+ "postal_code": "33032"
23
+ },
24
+ "alert_id": "7d48e535-6405-4c9c-adc2-be94e19cf94e",
25
+ "alert_name": "Low Balance Alert",
26
+ "results": [
27
+ {}
28
+ ],
29
+ "date": "2018-09-18T17:38:10.353Z"
30
+ }
31
+ ]
32
+ }
@@ -0,0 +1,7 @@
1
+ [
2
+ {"consumer_id": "a031137a-4c4b-4b8e-5be5-3747a7953e83", "message": "Consumer not eligible, no completed orders."},
3
+ {"consumer_id": "b2fbc913-c7c0-452a-5a10-09e4b34ab6a9", "message": "Consumer not found."},
4
+ {"consumer_id": "b2fbc913-c7c0-452a-5a10-09e4b34ab6a1", "message": "Application error"},
5
+ {"consumer_id": "c63fa6e8-0494-4ee1-5e96-c26fa31fc62a", "message": "Consumer not processed."},
6
+ {"consumer_id": "b5d03e74-92c9-462f-455f-827a77b8082d", "message": "Consumer not processed."}
7
+ ]
@@ -0,0 +1,9 @@
1
+ {
2
+ "_id": "c75283f7-0dea-4bf0-b5a2-4a648bdc5d95",
3
+ "name": "Account Checks",
4
+ "description": "Checks accounts for various thresholds.",
5
+ "enabled": true,
6
+ "product": "PROD3",
7
+ "created_date": "2018-09-18T17:38:10.353Z",
8
+ "modified_date": "2018-09-18T17:38:10.353Z"
9
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "total_records": 1,
3
+ "page": 1,
4
+ "total_pages": 1,
5
+ "records": [
6
+ {
7
+ "_id": "56aac2ff-d746-4095-aaca-3b71caf3b6cb",
8
+ "portfolio": {
9
+ "_id": "c75283f7-0dea-4bf0-b5a2-4a648bdc5d95",
10
+ "name": "Account Checks",
11
+ "description": "Checks accounts for various thresholds.",
12
+ "enabled": true,
13
+ "product": "PROD3",
14
+ "created_date": "2018-09-18T17:38:10.353Z",
15
+ "modified_date": "2018-09-18T17:38:10.353Z"
16
+ },
17
+ "consumer": {
18
+ "first_name": "test",
19
+ "last_name": "consumer",
20
+ "email": "testconsumer@finapps.com",
21
+ "memo": "test memo",
22
+ "postal_code": "33032"
23
+ },
24
+ "occurrences": [
25
+ {
26
+ "_id": "429bca0a-e557-43af-a3d0-777a09e903c0",
27
+ "alert_id": "7d48e535-6405-4c9c-adc2-be94e19cf94e",
28
+ "alert_name": "Low Balance Alert",
29
+ "results": [
30
+ {}
31
+ ],
32
+ "date": "2018-09-18T18:16:35.962Z"
33
+ }
34
+ ],
35
+ "date": "2018-09-18T18:16:35.962Z"
36
+ }
37
+ ]
38
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "total_records": 1,
3
+ "page": 1,
4
+ "total_pages": 1,
5
+ "records": [
6
+ {
7
+ "_id": "c75283f7-0dea-4bf0-b5a2-4a648bdc5d95",
8
+ "name": "Account Checks",
9
+ "description": "Checks accounts for various thresholds.",
10
+ "enabled": true,
11
+ "product": "PROD3",
12
+ "created_date": "2018-09-18T17:38:10.353Z",
13
+ "modified_date": "2018-09-18T17:38:10.353Z"
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,19 @@
1
+ [
2
+ {
3
+ "_id": "7d48e535-6405-4c9c-adc2-be94e19cf94e",
4
+ "name": "Low Balance Alert",
5
+ "rule_name": "min_balance",
6
+ "description": "Checks a consumer's account balance",
7
+ "params": [
8
+ {
9
+ "name": "minimum",
10
+ "display": "Minimum Balance",
11
+ "type": "float",
12
+ "message": "Account balance is too low.",
13
+ "value": 200.00
14
+ }
15
+ ],
16
+ "created_date": "2018-09-18T17:23:36.272Z",
17
+ "modified_date": "2018-09-18T17:23:36.272Z"
18
+ }
19
+ ]
@@ -0,0 +1,20 @@
1
+ {
2
+ "total_records": 1,
3
+ "page": 1,
4
+ "total_pages": 1,
5
+ "records": [
6
+ {
7
+ "public_id": "b242cc06-2ca7-4158-6197-7f7af08f1b41",
8
+ "email": "testconsumer@finapps.com",
9
+ "first_name": "Ed",
10
+ "last_name": "Smith",
11
+ "memo": "",
12
+ "tenant_id": "49fb918d-7e71-44dd-7378-58f19606df2a",
13
+ "language": 1,
14
+ "currency": 1,
15
+ "date_modified": "2018-09-24T22:05:57.607-04:00",
16
+ "date_created": "2018-09-24T22:05:57.607-04:00",
17
+ "postal_code": ""
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "page": 1,
3
+ "total_pages": 1,
4
+ "total_records": 1,
5
+ "records": [
6
+ {
7
+ "first_name": "test",
8
+ "last_name": "consumer",
9
+ "email": "testconsumer@finapps.com",
10
+ "memo": "test memo",
11
+ "postal_code": "33032"
12
+ }
13
+ ]
14
+ }