instant_quote 1.0.5

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4ef875cefed1539965a4ae7b1887b6f8566b59afa05645da6c4c870d21d47cdf
4
+ data.tar.gz: 6f6b168b51dd4c945f18772e2baf3ef1712af0a28737929d50f9abd9d9da5ec6
5
+ SHA512:
6
+ metadata.gz: 50be577e7e0c420de314a096d792462391bcb71d4d13e0bdaeb64db4611cd03231e2e394b7c50be6d9523344a9c86fdf174f0b04d45880238eaabfd452680627
7
+ data.tar.gz: 85d5e1ae438101c3e699e289632098ef9530efacae59a31d5f60d08db173d780a371573bb534f2fbb98de8918e6df509c7b161986e6c0907722ebe3a71e08573
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ .DS_Store
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ Layout/LineLength:
2
+ Max: 100
3
+
4
+ Style/Documentation:
5
+ Enabled: false
6
+
7
+ Metrics/ClassLength:
8
+ Max: 250
9
+
10
+ Metrics/MethodLength:
11
+ Max: 25
12
+
13
+ Metrics/BlockLength:
14
+ Max: 200
15
+
16
+ Naming/AccessorMethodName:
17
+ Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.6.3
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.3
7
+ before_install: gem install bundler -v 2.0.2
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # When developing new features in the gems this might be handy
6
+ #
7
+ # gem 'capital_on_tap', path: '../capital-on-tap'
8
+ # gem 'iwoca', path: '../iwoca'
9
+
10
+ # Specify your gem's dependencies in instant-quotes.gemspec
11
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,110 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ instant_quote (1.0.5)
5
+ activesupport
6
+ capital_on_tap
7
+ iwoca
8
+ money
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ activesupport (6.0.2.1)
14
+ concurrent-ruby (~> 1.0, >= 1.0.2)
15
+ i18n (>= 0.7, < 2)
16
+ minitest (~> 5.1)
17
+ tzinfo (~> 1.1)
18
+ zeitwerk (~> 2.2)
19
+ addressable (2.7.0)
20
+ public_suffix (>= 2.0.2, < 5.0)
21
+ ast (2.4.0)
22
+ byebug (11.1.1)
23
+ capital_on_tap (1.0.0)
24
+ addressable
25
+ faraday
26
+ faraday_middleware
27
+ multi_json
28
+ rainbow
29
+ coderay (1.1.2)
30
+ concurrent-ruby (1.1.5)
31
+ diff-lcs (1.3)
32
+ docile (1.3.2)
33
+ dotenv (2.7.5)
34
+ faraday (0.17.3)
35
+ multipart-post (>= 1.2, < 3)
36
+ faraday_middleware (0.14.0)
37
+ faraday (>= 0.7.4, < 1.0)
38
+ i18n (1.8.2)
39
+ concurrent-ruby (~> 1.0)
40
+ iwoca (1.0.0)
41
+ addressable
42
+ faraday
43
+ faraday_middleware
44
+ multi_json
45
+ rainbow
46
+ jaro_winkler (1.5.4)
47
+ method_source (0.9.2)
48
+ minitest (5.14.0)
49
+ money (6.13.7)
50
+ i18n (>= 0.6.4, <= 2)
51
+ multi_json (1.14.1)
52
+ multipart-post (2.1.1)
53
+ parallel (1.19.1)
54
+ parser (2.7.0.2)
55
+ ast (~> 2.4.0)
56
+ pry (0.12.2)
57
+ coderay (~> 1.1.0)
58
+ method_source (~> 0.9.0)
59
+ pry-byebug (3.8.0)
60
+ byebug (~> 11.0)
61
+ pry (~> 0.10)
62
+ public_suffix (4.0.3)
63
+ rainbow (3.0.0)
64
+ rake (10.5.0)
65
+ rspec (3.9.0)
66
+ rspec-core (~> 3.9.0)
67
+ rspec-expectations (~> 3.9.0)
68
+ rspec-mocks (~> 3.9.0)
69
+ rspec-core (3.9.1)
70
+ rspec-support (~> 3.9.1)
71
+ rspec-expectations (3.9.0)
72
+ diff-lcs (>= 1.2.0, < 2.0)
73
+ rspec-support (~> 3.9.0)
74
+ rspec-mocks (3.9.1)
75
+ diff-lcs (>= 1.2.0, < 2.0)
76
+ rspec-support (~> 3.9.0)
77
+ rspec-support (3.9.2)
78
+ rubocop (0.79.0)
79
+ jaro_winkler (~> 1.5.1)
80
+ parallel (~> 1.10)
81
+ parser (>= 2.7.0.1)
82
+ rainbow (>= 2.2.2, < 4.0)
83
+ ruby-progressbar (~> 1.7)
84
+ unicode-display_width (>= 1.4.0, < 1.7)
85
+ ruby-progressbar (1.10.1)
86
+ simplecov (0.18.1)
87
+ docile (~> 1.1)
88
+ simplecov-html (~> 0.11.0)
89
+ simplecov-html (0.11.0)
90
+ thread_safe (0.3.6)
91
+ tzinfo (1.2.6)
92
+ thread_safe (~> 0.1)
93
+ unicode-display_width (1.6.1)
94
+ zeitwerk (2.2.2)
95
+
96
+ PLATFORMS
97
+ ruby
98
+
99
+ DEPENDENCIES
100
+ bundler (~> 2.0)
101
+ dotenv
102
+ instant_quote!
103
+ pry-byebug
104
+ rake (~> 10.0)
105
+ rspec (~> 3.0)
106
+ rubocop
107
+ simplecov
108
+
109
+ BUNDLED WITH
110
+ 2.0.2
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Instant Quote
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/instant/quotes`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'instant_quote'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install instant-quotes
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require 'bundler/setup'
6
+ require 'instant_quote'
7
+ require 'dotenv'
8
+
9
+ Dotenv.load
10
+
11
+ require 'capital_on_tap'
12
+ require 'iwoca'
13
+
14
+ CapitalOnTap.configure do |config|
15
+ config.client_id = ENV['CAPITAL_ON_TAP_CLIENT_ID']
16
+ config.client_secret = ENV['CAPITAL_ON_TAP_CLIENT_SECRET']
17
+ config.username = ENV['CAPITAL_ON_TAP_USERNAME']
18
+ config.password = ENV['CAPITAL_ON_TAP_PASSWORD']
19
+ config.debug = true
20
+ end
21
+
22
+ Iwoca.configure do |config|
23
+ config.api_key = ENV['IWOCA_API_KEY']
24
+ config.webhook_signature = ENV['IWOCA_WEBHOOK_SIGNATURE']
25
+ end
26
+
27
+ send(:include, InstantQuote)
28
+
29
+ require 'pry'
30
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # frozen_string_literal: true
4
+
5
+ set -euo pipefail
6
+ IFS=$'\n\t'
7
+ set -vx
8
+
9
+ bundle install
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'instant_quote/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'instant_quote'
10
+ spec.version = InstantQuote::VERSION
11
+ spec.authors = ['rikas']
12
+ spec.email = ['oterosantos@gmail.com']
13
+
14
+ spec.summary = 'Instant quote providers gem.'
15
+ spec.description = spec.summary
16
+ spec.homepage = 'https://finpoint.co.uk'
17
+
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^((test|spec|features)/|.env)}) }
24
+ end
25
+ spec.bindir = 'exe'
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_development_dependency 'bundler', '~> 2.0'
30
+ spec.add_development_dependency 'dotenv'
31
+ spec.add_development_dependency 'pry-byebug'
32
+ spec.add_development_dependency 'rake', '~> 10.0'
33
+ spec.add_development_dependency 'rspec', '~> 3.0'
34
+ spec.add_development_dependency 'rubocop'
35
+ spec.add_development_dependency 'simplecov'
36
+
37
+ spec.add_dependency 'activesupport'
38
+ spec.add_dependency 'capital_on_tap'
39
+ spec.add_dependency 'iwoca'
40
+ spec.add_dependency 'money'
41
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InstantQuote
4
+ class Adapter
5
+ def self.additional_fields(fields = [])
6
+ return (@additional_fields || []) if fields.empty?
7
+
8
+ @additional_fields = fields
9
+ end
10
+
11
+ def self.get_link(application_id)
12
+ new.get_link(application_id)
13
+ end
14
+
15
+ def self.get_quote(params)
16
+ new.get_quote(params)
17
+ end
18
+
19
+ def self.get_status(application_id)
20
+ new.get_status(application_id)
21
+ end
22
+
23
+ def self.get_approval(application_id)
24
+ new.get_approval(application_id)
25
+ end
26
+
27
+ def get_link(_application_id)
28
+ raise NotImplementedError, "You must implement '#{self.class.name}#get_link'"
29
+ end
30
+
31
+ def get_quote(_params)
32
+ raise NotImplementedError, "You must implement '#{self.class.name}#get_quote'"
33
+ end
34
+
35
+ def get_status(_application_id)
36
+ raise NotImplementedError, "You must implement '#{self.class.name}#get_status'"
37
+ end
38
+
39
+ def get_approval(_application_id)
40
+ raise NotImplementedError, "You must implement '#{self.class.name}#get_approval"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Require all the connection translators
4
+ translators = Dir.children(File.expand_path('connection_translators', __dir__))
5
+ translators.each { |translator| require "instant_quote/connection_translators/#{translator}" }
6
+
7
+ # Require all the decision parsers
8
+ parsers = Dir.children(File.expand_path('decision_parsers', __dir__))
9
+ parsers.each { |parser| require "instant_quote/decision_parsers/#{parser}" }
10
+
11
+ # Require all the adapters
12
+ adapters = Dir.children(File.expand_path('adapters', __dir__))
13
+ adapters.each { |adapter| require "instant_quote/adapters/#{adapter}" }
14
+
15
+ module InstantQuote
16
+ class AdapterFinder
17
+ attr_reader :connection, :adapter, :translator, :decision_parser
18
+
19
+ def initialize(connection)
20
+ @connection = connection
21
+ @adapter_name = connection.adapter
22
+
23
+ validate_adapter_name!
24
+
25
+ @adapter = Object.const_get("InstantQuote::Adapters::#{adapter_class}")
26
+ @translator = Object.const_get("InstantQuote::ConnectionTranslators::#{adapter_class}")
27
+ @decision_parser = Object.const_get("InstantQuote::DecisionParsers::#{adapter_class}")
28
+ end
29
+
30
+ def get_link
31
+ adapter.get_link(connection.external_id)
32
+ end
33
+
34
+ def get_quote
35
+ params = translator.translate(connection)
36
+
37
+ adapter.get_quote(params)
38
+ end
39
+
40
+ def get_status
41
+ adapter.get_status(connection.external_id)
42
+ end
43
+
44
+ def get_approval
45
+ adapter.get_approval(connection.external_id)
46
+ end
47
+
48
+ def additional_fields
49
+ adapter.additional_fields
50
+ end
51
+
52
+ def parse_decision
53
+ decision_parser.new(connection.approval_decision_info)
54
+ end
55
+
56
+ private
57
+
58
+ def adapter_class
59
+ @adapter_name.to_s.split('_').map(&:capitalize).join
60
+ end
61
+
62
+ def available_adapters
63
+ adapters = Dir.children(File.expand_path('adapters', __dir__))
64
+ adapters.map { |adapter| adapter.tr('.rb', '') }
65
+ end
66
+
67
+ def validate_adapter_name!
68
+ return true if available_adapters.include?(@adapter_name)
69
+
70
+ message = "Unknown adapter '#{@adapter_name}'. Available names: #{available_adapters}"
71
+
72
+ raise InstantQuote::AdapterError, message
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'capital_on_tap'
4
+ require 'instant_quote/decision_parsers/capital_on_tap'
5
+
6
+ module InstantQuote
7
+ module Adapters
8
+ class CapitalOnTap < Adapter
9
+ additional_fields [
10
+ {
11
+ name: 'date_of_birth',
12
+ label: 'Date of birth',
13
+ type: 'date',
14
+ required: true
15
+ },
16
+ {
17
+ name: 'business_landline',
18
+ label: 'Business landline',
19
+ required: true
20
+ },
21
+ {
22
+ name: 'applicant_phone_number',
23
+ label: 'Applicant mobile phone',
24
+ required: true
25
+ },
26
+ {
27
+ name: 'applicant_consent',
28
+ label: 'Yes, I give my consent for my data to be shared',
29
+ required: true,
30
+ type: 'checkbox'
31
+ }
32
+ ]
33
+
34
+ # Creates the quote with the information from instant connection
35
+ def get_quote(params)
36
+ response = ::CapitalOnTap::Application.create(params)
37
+
38
+ # CoT responses can be 200 OK but still have an error!
39
+ unless response.success? && !response.error
40
+ raise ApiError.new(data: response.body, error: response.error || 'Unknown API error')
41
+ end
42
+
43
+ response.body.dig(:result)
44
+ end
45
+
46
+ # Get the status for a given application ID
47
+ # {:applicationStatus=>
48
+ # {:locatorId=>"B247T62",
49
+ # :applicationStage=>"AppSubmitted",
50
+ # :creditDecision=>
51
+ # {:status=>"Pending",
52
+ # :starRating=>0.0,
53
+ # :approvalAmount=>0.0,
54
+ # :monthlyInterestRate=>0.0,
55
+ # :monthlyCardInterestRate=>0.0,
56
+ # :decisionDate=>"2020-01-28T01:44:29.241",
57
+ # :creditDecisionReason=>"None"}},
58
+ # :links=>{:self=>"/api/v1/Applications/B247T62", :parent=>nil},
59
+ # :metaData=>{}
60
+ # }
61
+ def get_status(application_id)
62
+ response = ::CapitalOnTap::Application.status(application_id)
63
+
64
+ raise ApiError.new(data: response.body, error: response.error) unless response.success?
65
+
66
+ DecisionParsers::CapitalOnTap.new(response.body[:applicationStatus])
67
+ end
68
+
69
+ # The link is always the same for Capital On Tap
70
+ def get_link(_application_id)
71
+ 'https://account.capitalontap.com/apps/portal/login/'
72
+ end
73
+
74
+ # Capital On Tap doesn't need an approval request
75
+ def get_approval(_application_id)
76
+ true
77
+ end
78
+ end
79
+ end
80
+ end