finapps 1.0.8 → 2.0.2

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rspec +1 -2
  4. data/.rubocop.yml +102 -0
  5. data/.ruby-gemset +1 -1
  6. data/.ruby-version +1 -1
  7. data/Rakefile +1 -1
  8. data/finapps.gemspec +10 -10
  9. data/lib/finapps/core_extensions/hash/compact.rb +22 -0
  10. data/lib/finapps/core_extensions/integerable.rb +14 -0
  11. data/lib/finapps/core_extensions/object/blank.rb +145 -0
  12. data/lib/finapps/error.rb +7 -0
  13. data/lib/finapps/hash_constructable.rb +9 -0
  14. data/lib/finapps/middleware/raise_error.rb +46 -0
  15. data/lib/finapps/middleware/tenant_authentication.rb +19 -0
  16. data/lib/finapps/rest/base_client.rb +96 -0
  17. data/lib/finapps/rest/client.rb +11 -199
  18. data/lib/finapps/rest/configuration.rb +55 -0
  19. data/lib/finapps/rest/connection.rb +14 -33
  20. data/lib/finapps/rest/defaults.rb +55 -64
  21. data/lib/finapps/rest/resource.rb +3 -6
  22. data/lib/finapps/rest/resources.rb +11 -6
  23. data/lib/finapps/rest/users.rb +17 -57
  24. data/lib/finapps/utils/loggeable.rb +13 -0
  25. data/lib/finapps/version.rb +1 -1
  26. data/lib/finapps.rb +11 -23
  27. data/lib/tasks/releaser.rake +2 -2
  28. data/spec/middleware/tenant_authentication_spec.rb +29 -0
  29. data/spec/rest/base_client_spec.rb +89 -0
  30. data/spec/rest/client_spec.rb +16 -102
  31. data/spec/rest/configuration_spec.rb +75 -0
  32. data/spec/spec_helper.rb +10 -7
  33. data/spec/support/fake_api.rb +9 -2
  34. data/spec/support/fixtures/error.json +5 -0
  35. data/spec/support/fixtures/relevance_ruleset_names.json +47 -0
  36. metadata +49 -57
  37. data/lib/finapps/middleware/api_token.rb +0 -26
  38. data/lib/finapps/middleware/raise_http_exceptions.rb +0 -92
  39. data/lib/finapps/middleware/response_logger.rb +0 -37
  40. data/lib/finapps/rest/alert.rb +0 -62
  41. data/lib/finapps/rest/alert_definition.rb +0 -40
  42. data/lib/finapps/rest/alert_preferences.rb +0 -40
  43. data/lib/finapps/rest/alert_settings.rb +0 -40
  44. data/lib/finapps/rest/budget_calculation.rb +0 -45
  45. data/lib/finapps/rest/budget_models.rb +0 -42
  46. data/lib/finapps/rest/budgets.rb +0 -103
  47. data/lib/finapps/rest/cashflows.rb +0 -87
  48. data/lib/finapps/rest/categories.rb +0 -21
  49. data/lib/finapps/rest/errors.rb +0 -155
  50. data/lib/finapps/rest/institutions.rb +0 -47
  51. data/lib/finapps/rest/relevance/rulesets.rb +0 -64
  52. data/lib/finapps/rest/transactions.rb +0 -45
  53. data/lib/finapps/rest/user_institutions.rb +0 -138
  54. data/lib/finapps/utils/logging.rb +0 -95
  55. data/lib/finapps/utils/utils.rb +0 -57
  56. data/spec/middleware/api_token_spec.rb +0 -32
  57. data/spec/rest/connection_spec.rb +0 -40
  58. data/spec/rest/users_spec.rb +0 -24
  59. data/spec/utils/logging_spec.rb +0 -28
data/lib/finapps.rb CHANGED
@@ -1,39 +1,27 @@
1
1
  require 'finapps/version' unless defined?(FinApps::VERSION)
2
- require 'logger' unless defined?(::Logger)
3
- require 'pp'
4
2
 
5
3
  require 'faraday'
6
4
  require 'faraday_middleware'
7
5
  require 'typhoeus'
8
6
  require 'typhoeus/adapters/faraday'
9
7
 
10
- require 'finapps/utils/logging'
11
- require 'finapps/utils/utils'
12
- require 'finapps/middleware/api_token'
13
- require 'finapps/middleware/raise_http_exceptions'
14
- require 'finapps/middleware/response_logger'
8
+ require 'finapps/core_extensions/object/blank'
9
+ require 'finapps/core_extensions/hash/compact'
10
+ require 'finapps/core_extensions/integerable'
11
+ require 'finapps/hash_constructable'
12
+ require 'finapps/utils/loggeable'
13
+ require 'finapps/error'
15
14
 
16
- require 'finapps/rest/defaults'
17
- require 'finapps/rest/errors'
15
+ require 'finapps/middleware/tenant_authentication'
16
+ require 'finapps/middleware/raise_error'
18
17
 
18
+ require 'finapps/rest/defaults'
19
19
  require 'finapps/rest/resource'
20
20
  require 'finapps/rest/resources'
21
21
 
22
22
  require 'finapps/rest/users'
23
- require 'finapps/rest/institutions'
24
- require 'finapps/rest/user_institutions'
25
- require 'finapps/rest/transactions'
26
- require 'finapps/rest/categories'
27
- require 'finapps/rest/budget_models'
28
- require 'finapps/rest/budget_calculation'
29
- require 'finapps/rest/budgets'
30
- require 'finapps/rest/cashflows'
31
- require 'finapps/rest/alert'
32
- require 'finapps/rest/alert_definition'
33
- require 'finapps/rest/alert_settings'
34
- require 'finapps/rest/alert_preferences'
35
-
36
- require 'finapps/rest/relevance/rulesets'
37
23
 
24
+ require 'finapps/rest/configuration'
38
25
  require 'finapps/rest/connection'
26
+ require 'finapps/rest/base_client'
39
27
  require 'finapps/rest/client'
@@ -1,5 +1,5 @@
1
1
  desc 'Bumps the version to the next patch level, tags and pushes the code to
2
2
  origin repository and releases the gem. BOOM!'
3
3
  task :release do
4
- system "gem bump --tag --release"
5
- end
4
+ system 'gem bump --tag --release'
5
+ end
@@ -0,0 +1,29 @@
1
+ RSpec.describe FinApps::Middleware::TenantAuthentication do
2
+ let(:valid_tenant_options) { VALID_CREDENTIALS }
3
+ let(:key) { FinApps::Middleware::TenantAuthentication::KEY }
4
+
5
+ describe '#call' do
6
+ fake_app = proc {|env| env }
7
+
8
+ context 'when company credentials were provided' do
9
+ let(:middleware) { FinApps::Middleware::TenantAuthentication.new fake_app, valid_tenant_options }
10
+ let(:expected_header) { "#{valid_tenant_options[:identifier]}=#{valid_tenant_options[:token]}" }
11
+
12
+ context 'when header was not previously set' do
13
+ let(:request_env) { {request_headers: {}} }
14
+ subject(:actual_header) { middleware.call(request_env)[:request_headers][key] }
15
+
16
+ it('generates a Tenant Authentication header') { expect(actual_header).to eq(expected_header) }
17
+ end
18
+
19
+ context 'when header was previously set' do
20
+ let(:existing_header) { {FinApps::Middleware::TenantAuthentication::KEY => 'foo'} }
21
+ let(:request_env) { {request_headers: existing_header} }
22
+ subject(:actual_header) { middleware.call(request_env)[:request_headers][key] }
23
+
24
+ it('does not override existing Tenant Authentication header') { expect(actual_header).to eq('foo') }
25
+ it('does not generate a Tenant Authentication header') { expect(actual_header).to_not eq(expected_header) }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,89 @@
1
+ RSpec.describe FinApps::REST::BaseClient do
2
+ let(:valid_tenant_options) { {tenant_credentials: VALID_CREDENTIALS} }
3
+ subject { FinApps::REST::BaseClient.new(valid_tenant_options) }
4
+
5
+ RESPONSE = 0
6
+ ERROR_MESSAGES = 1
7
+ let(:return_array) { %i(RESPONSE ERROR_MESSAGES) }
8
+
9
+ describe '#new' do
10
+ it 'assigns @config' do
11
+ expect(subject.config).to be_a(FinApps::REST::Configuration)
12
+ end
13
+ end
14
+
15
+ describe '#connection' do
16
+ it 'created a Faraday connection object' do
17
+ expect(subject.connection).to be_a(Faraday::Connection)
18
+ end
19
+
20
+ it 'memoizes the results' do
21
+ first = subject.connection
22
+ second = subject.connection
23
+ expect(first.object_id).to eq(second.object_id)
24
+ end
25
+ end
26
+
27
+ describe '#send_request' do
28
+ it 'should raise FinApps::MissingArgumentsError if method is NOT provided' do
29
+ expect { subject.send_request(nil, :get) }.to raise_error(FinApps::MissingArgumentsError)
30
+ end
31
+
32
+ it 'should raise FinApps::MissingArgumentsError if path is NOT provided' do
33
+ expect { subject.send_request('fake_path', nil) }.to raise_error(FinApps::MissingArgumentsError)
34
+ end
35
+
36
+ context 'when method and path are provided' do
37
+ subject { FinApps::REST::BaseClient.new(valid_tenant_options).send_request('relevance/ruleset/names', :get) }
38
+ let(:return_array) { %i(RESPONSE ERROR_MESSAGES) }
39
+
40
+ it('returns an array of 2 items') do
41
+ expect(subject).to be_a(Array)
42
+ expect(subject.size).to eq(return_array.length)
43
+ end
44
+
45
+ context 'for unsupported methods' do
46
+ subject { FinApps::REST::BaseClient.new(valid_tenant_options).send_request('users', :options) }
47
+
48
+ it do
49
+ expect { subject.send_request(nil, :get) }
50
+ .to raise_error(FinApps::InvalidArgumentsError, 'Method not supported: options.')
51
+ end
52
+ end
53
+
54
+ context 'for client errors' do
55
+ subject { FinApps::REST::BaseClient.new(valid_tenant_options).send_request('client_error', :get) }
56
+
57
+ it('the result should be nil') { expect(subject[RESPONSE]).to be_nil }
58
+ it { expect(subject[ERROR_MESSAGES]).not_to be_nil }
59
+ it { expect(subject[ERROR_MESSAGES]).to be_a(Array) }
60
+ it { expect(subject[ERROR_MESSAGES].length).to be > 0 }
61
+ end
62
+
63
+ context 'for server errors' do
64
+ subject { FinApps::REST::BaseClient.new(valid_tenant_options).send_request('server_error', :get) }
65
+
66
+ it('the result should be nil') { expect(subject[RESPONSE]).to be_nil }
67
+ it { expect(subject[ERROR_MESSAGES]).not_to be_nil }
68
+ it { expect(subject[ERROR_MESSAGES]).to be_a(Array) }
69
+ it { expect(subject[ERROR_MESSAGES].first).to eq 'the server responded with status 500' }
70
+ end
71
+
72
+ context 'for proxy errors' do
73
+ subject { FinApps::REST::BaseClient.new(valid_tenant_options).send_request('proxy_error', :get) }
74
+
75
+ it do
76
+ expect { subject.send_request(nil, :get) }
77
+ .to raise_error(Faraday::ConnectionFailed, '407 "Proxy Authentication Required"')
78
+ end
79
+ end
80
+ end
81
+
82
+ context 'if a block is provided' do
83
+ it('gets executed on the response') do
84
+ expect(subject.send_request('relevance/ruleset/names', :get, &:status)[RESPONSE]).to eq(200)
85
+ expect(subject.send_request('relevance/ruleset/names', :get) {|r| r.body.length }[RESPONSE]).to eq(45)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -1,122 +1,36 @@
1
1
  RSpec.describe FinApps::REST::Client do
2
-
3
2
  describe '#new' do
4
-
5
- context 'when company_identifier is NOT provided' do
6
- it { expect { FinApps::REST::Client.new nil, :company_token }.to raise_error(FinApps::REST::MissingArgumentsError) }
7
- end
8
-
9
- context 'when company_token is NOT provided' do
10
- it { expect { FinApps::REST::Client.new :company_identifier, nil }.to raise_error(FinApps::REST::MissingArgumentsError) }
11
- end
12
-
13
- context 'when company_identifier is not string or symbol' do
14
- it { expect { FinApps::REST::Client.new 1, :company_token }.to raise_error(FinApps::REST::InvalidArgumentsError) }
3
+ it 'raises for missing company_identifier' do
4
+ expect { FinApps::REST::Client.new nil, :company_token }.to raise_error(FinApps::MissingArgumentsError)
15
5
  end
16
6
 
17
- context 'when company_token is not string or symbol' do
18
- it { expect { FinApps::REST::Client.new :company_identifier, 1 }.to raise_error(FinApps::REST::InvalidArgumentsError) }
7
+ it 'raises for missing company_token' do
8
+ expect { FinApps::REST::Client.new :company_identifier, nil }.to raise_error(FinApps::MissingArgumentsError)
19
9
  end
20
-
21
- context 'when options are not provided' do
22
- it { expect { FinApps::REST::Client.new :company_identifier, :company_token }.not_to raise_error }
23
- end
24
-
25
10
  end
26
11
 
27
- context 'after initialized' do
12
+ context 'an instance of Client' do
13
+ subject { FinApps::REST::Client.new(:company_identifier, :company_token) }
28
14
 
29
- let(:client) { FinApps::REST::Client.new(:company_identifier, :company_token) }
30
-
31
- [:send_request, :connection, :users, :institutions, :user_institutions, :transactions,
32
- :categories, :budget_models, :budget_calculation, :budgets, :cashflows, :alert,
33
- :alert_definition, :alert_preferences, :alert_settings, :rule_sets, :user_credentials!].each do |method|
15
+ %i(users).each do |method|
34
16
  it "responds to #{method}" do
35
- expect(client).to respond_to(method)
17
+ expect(subject).to respond_to(method)
36
18
  end
37
19
  end
38
20
 
39
21
  describe '#users' do
40
- it { expect(client.users).to be_an_instance_of(FinApps::REST::Users) }
41
- end
42
-
43
- describe '#institutions' do
44
- it { expect(client.institutions).to be_an_instance_of(FinApps::REST::Institutions) }
45
- end
46
-
47
- describe '#user_institutions' do
48
- it { expect(client.user_institutions).to be_an_instance_of(FinApps::REST::UserInstitutions) }
49
- end
50
-
51
- describe '#categories' do
52
- it { expect(client.categories).to be_an_instance_of(FinApps::REST::Categories) }
53
- end
54
-
55
- describe '#budget_models' do
56
- it { expect(client.budget_models).to be_an_instance_of(FinApps::REST::BudgetModels) }
57
- end
58
-
59
- describe '#budget_calculation' do
60
- it { expect(client.budget_calculation).to be_an_instance_of(FinApps::REST::BudgetCalculation) }
61
- end
62
-
63
- describe '#budgets' do
64
- it { expect(client.budgets).to be_an_instance_of(FinApps::REST::Budgets) }
65
- end
66
-
67
- describe '#cashflows' do
68
- it { expect(client.cashflows).to be_an_instance_of(FinApps::REST::Cashflows) }
22
+ it { expect(subject.users).to be_an_instance_of(FinApps::REST::Users) }
69
23
  end
70
24
 
71
- describe '#alert' do
72
- it { expect(client.alert).to be_an_instance_of(FinApps::REST::Alert) }
73
- end
74
-
75
- describe '#alert_definition' do
76
- it { expect(client.alert_definition).to be_an_instance_of(FinApps::REST::AlertDefinition) }
77
- end
78
-
79
- describe '#alert_preferences' do
80
- it { expect(client.alert_preferences).to be_an_instance_of(FinApps::REST::AlertPreferences) }
81
- end
82
-
83
- describe '#alert_settings' do
84
- it { expect(client.alert_settings).to be_an_instance_of(FinApps::REST::AlertSettings) }
85
- end
86
-
87
- describe '#rule_sets' do
88
- it { expect(client.rule_sets).to be_an_instance_of(FinApps::REST::Relevance::Rulesets) }
89
- end
90
-
91
- describe '#connection' do
92
- it { expect(client.connection).to be_an_instance_of(Faraday::Connection) }
93
- end
94
-
95
- [:connection, :users, :institutions, :user_institutions, :transactions,
96
- :categories, :budget_models, :budget_calculation, :budgets, :cashflows, :alert,
97
- :alert_definition, :alert_preferences, :alert_settings, :rule_sets].each do |method|
25
+ # [:users, :institutions, :user_institutions, :transactions, :categories,
26
+ # :budget_models, :budget_calculation, :budgets, :cashflows,
27
+ # :alert, :alert_definition, :alert_preferences, :alert_settings, :rule_sets]
28
+ [:users].each do |method|
98
29
  it "memoizes the result of #{method}" do
99
- first, second = client.send(method), client.send(method)
30
+ first = subject.send(method)
31
+ second = subject.send(method)
100
32
  expect(first.object_id).to eq(second.object_id)
101
33
  end
102
34
  end
103
-
104
- describe '#send_request' do
105
-
106
- context 'when path is NOT provided' do
107
- it { expect { client.send_request(nil, :post) }.to raise_error(FinApps::REST::MissingArgumentsError) }
108
- end
109
-
110
- context 'when method is NOT provided' do
111
- it { expect { client.send_request(:path, nil) }.to raise_error(FinApps::REST::MissingArgumentsError) }
112
- end
113
-
114
- context 'when method is NOT supported' do
115
- it { expect { client.send_request(:path, :unsupported_method) }.to raise_error(FinApps::REST::InvalidArgumentsError) }
116
- end
117
-
118
- end
119
-
120
35
  end
121
-
122
- end
36
+ end
@@ -0,0 +1,75 @@
1
+ RSpec.describe FinApps::REST::Configuration do
2
+ describe '#new' do
3
+ it 'raises for missing tenant credentials' do
4
+ expect { FinApps::REST::Configuration.new({}) }
5
+ .to raise_error(FinApps::MissingArgumentsError, 'Missing tenant_credentials.')
6
+ end
7
+
8
+ it 'raises for invalid tenant credentials (identifier)' do
9
+ expect { FinApps::REST::Configuration.new(tenant_credentials: {token: :token}) }
10
+ .to raise_error(FinApps::MissingArgumentsError, 'Missing tenant_credentials.')
11
+ end
12
+
13
+ it 'raises for invalid tenant credentials (token)' do
14
+ expect { FinApps::REST::Configuration.new(tenant_credentials: {identifier: :identifier}) }
15
+ .to raise_error(FinApps::MissingArgumentsError, 'Missing tenant_credentials.')
16
+ end
17
+
18
+ context 'for valid tenant credentials' do
19
+ let(:valid_tenant_options) { {tenant_credentials: VALID_CREDENTIALS} }
20
+
21
+ context 'when valid user credentials were provided' do
22
+ let(:valid_creds) { valid_tenant_options.merge(user_credentials: VALID_CREDENTIALS) }
23
+ subject { FinApps::REST::Configuration.new(valid_creds) }
24
+ it('should have user_credentials') { expect(subject.user_credentials).to eq(VALID_CREDENTIALS) }
25
+ it('user_credentials are valid') { expect(subject.valid_user_credentials?).to eq true }
26
+ end
27
+
28
+ context 'for missing user credentials' do
29
+ subject { FinApps::REST::Configuration.new(valid_tenant_options) }
30
+ it('user_credentials are not valid') { expect(subject.valid_user_credentials?).to eq false }
31
+ end
32
+
33
+ context 'for invalid user credentials (token)' do
34
+ let(:invalid_user_creds) { {identifier: :identifier, token: ''} }
35
+ subject { FinApps::REST::Configuration.new(valid_tenant_options.merge(user_credentials: invalid_user_creds)) }
36
+
37
+ it('user_credentials are not valid') { expect(subject.valid_user_credentials?).to eq false }
38
+ end
39
+
40
+ context 'for invalid user credentials (identifier)' do
41
+ let(:invalid_user_creds) { {identifier: '', token: :token} }
42
+ subject { FinApps::REST::Configuration.new(valid_tenant_options.merge(user_credentials: invalid_user_creds)) }
43
+
44
+ it('user_credentials are not valid') { expect(subject.valid_user_credentials?).to eq false }
45
+ end
46
+
47
+ it 'raises for invalid timeout values' do
48
+ expect { FinApps::REST::Configuration.new(valid_tenant_options.merge(timeout: 'whatever')) }
49
+ .to raise_error(FinApps::InvalidArgumentsError, 'Invalid argument. {timeout: whatever}')
50
+ end
51
+
52
+ context 'for valid timeout' do
53
+ subject { FinApps::REST::Configuration.new(valid_tenant_options.merge(timeout: nil)) }
54
+ it 'should have a default timeout value' do
55
+ config = FinApps::REST::Configuration.new(valid_tenant_options.merge(timeout: nil))
56
+ expect(config.timeout).to eq(FinApps::REST::Defaults::DEFAULTS[:timeout])
57
+ end
58
+ end
59
+
60
+ it 'raises for invalid host values' do
61
+ expect { FinApps::REST::Configuration.new(valid_tenant_options.merge(host: 'whatever')) }
62
+ .to raise_error(FinApps::InvalidArgumentsError, 'Invalid argument. {host: whatever}')
63
+ end
64
+
65
+ context 'for valid host' do
66
+ subject { FinApps::REST::Configuration.new(valid_tenant_options.merge(host: nil)) }
67
+
68
+ it('should have a default host') { expect(subject.host).to eq(FinApps::REST::Defaults::DEFAULTS[:host]) }
69
+ it('url should include version') do
70
+ expect(subject.url).to eq("#{subject.host}/v#{FinApps::REST::Defaults::API_VERSION}/")
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
data/spec/spec_helper.rb CHANGED
@@ -3,25 +3,28 @@ Bundler.setup
3
3
 
4
4
  require 'finapps'
5
5
  require 'webmock/rspec'
6
- require File.join(File.dirname(__dir__), 'spec/support/fake_api')
6
+
7
+ # noinspection RubyResolve
8
+ require File.join(File.dirname(__dir__), 'spec/support/fake_api')
7
9
 
8
10
  RSpec.configure do |config|
9
11
  config.expect_with(:rspec) do |expectations|
10
12
  expectations.include_chain_clauses_in_custom_matcher_descriptions = true
11
13
  expectations.syntax = :expect
12
14
  end
13
- config.mock_with(:rspec) { |mocks| mocks.verify_partial_doubles = true }
14
- config.filter_run :focus
15
- config.run_all_when_everything_filtered = true
15
+ config.mock_with(:rspec) {|mocks| mocks.verify_partial_doubles = true }
16
+ # config.filter_run_including :focus => true
16
17
  config.default_formatter = 'doc' if config.files_to_run.one?
17
18
  config.order = :random
18
19
  config.example_status_persistence_file_path = 'spec/examples.txt'
19
- #config.disable_monkey_patching!
20
20
  config.warnings = true
21
- config.profile_examples = 5
22
21
  Kernel.srand config.seed
23
22
 
24
23
  config.before(:each) do
25
- stub_request(:any, /api.financialapps.com/).to_rack(::FakeApi )
24
+ base_url = "#{FinApps::REST::Defaults::DEFAULTS[:host]}/v#{FinApps::REST::Defaults::API_VERSION}/"
25
+ stub_request(:any, /#{base_url}/).to_rack(::FakeApi)
26
26
  end
27
27
  end
28
+
29
+ VALID_CREDENTIALS = {identifier: '49fb918d-7e71-44dd-7378-58f19606df2a',
30
+ token: 'hohoho='}.freeze
@@ -2,7 +2,14 @@ require 'sinatra/base'
2
2
 
3
3
  class FakeApi < Sinatra::Base
4
4
  # users
5
- get('/v1/users/:id') { json_response 200, 'user.json' }
5
+ get('/users/:id') { json_response 200, 'user.json' }
6
+
7
+ # relevance
8
+ get('/v2/relevance/ruleset/names') { json_response 200, 'relevance_ruleset_names.json' }
9
+
10
+ get('/v2/client_error') { json_response 400, 'error.json' }
11
+ get('/v2/server_error') { status 500 }
12
+ get('/v2/proxy_error') { status 407 }
6
13
 
7
14
  private
8
15
 
@@ -11,4 +18,4 @@ class FakeApi < Sinatra::Base
11
18
  status response_code
12
19
  File.open(File.dirname(__FILE__) + '/fixtures/' + file_name, 'rb').read
13
20
  end
14
- end
21
+ end
@@ -0,0 +1,5 @@
1
+ {
2
+ "messages": [
3
+ "Password Minimum size is 8"
4
+ ]
5
+ }
@@ -0,0 +1,47 @@
1
+ [
2
+ "accounts_overview",
3
+ "alert_cash_withdrawal",
4
+ "alert_deposits",
5
+ "alert_low_avg_balance",
6
+ "alert_low_cash_flow",
7
+ "alert_merchant_breach",
8
+ "budet_wip03",
9
+ "budget",
10
+ "budget_wip",
11
+ "budget_wip02",
12
+ "budget_wip03",
13
+ "budget_wip04",
14
+ "budget_wip05",
15
+ "budget_wip06",
16
+ "budget_wip07",
17
+ "budget_wip08",
18
+ "bug_test",
19
+ "cashflow",
20
+ "cashflow_02",
21
+ "cashflow_detail",
22
+ "cashflow_old",
23
+ "demo",
24
+ "formfree_structure",
25
+ "fraud",
26
+ "fraud_alert_cash_withdrawal",
27
+ "fraud_alert_double_charge",
28
+ "hello_dom_breakpoint",
29
+ "hello_jira",
30
+ "hello_temp",
31
+ "iav_avg_dep_velocity",
32
+ "iav_avg_dly_bal",
33
+ "iav_avg_income",
34
+ "iav_avg_spend",
35
+ "iav_balance_summary",
36
+ "iav_cash_flow",
37
+ "iav_eod_balance",
38
+ "iav_low_bal_trends",
39
+ "iav_nsf",
40
+ "iav_payroll",
41
+ "iav_report_summary",
42
+ "iav_risk_score",
43
+ "inventory_testing",
44
+ "loopWIP",
45
+ "mysql",
46
+ "simple_rule_data"
47
+ ]