callcredit 0.3.8 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +41 -0
- data/.rubocop_todo.yml +154 -0
- data/CHANGELOG.md +8 -1
- data/LICENSE +1 -1
- data/README.md +25 -6
- data/callcredit.gemspec +2 -2
- data/lib/callcredit.rb +10 -1
- data/lib/callcredit/checks/bank_enhanced.rb +49 -0
- data/lib/callcredit/checks/bank_standard.rb +28 -0
- data/lib/callcredit/checks/id_enhanced.rb +1 -1
- data/lib/callcredit/client.rb +11 -1
- data/lib/callcredit/config.rb +3 -3
- data/lib/callcredit/constants.rb +6 -1
- data/lib/callcredit/errors/callcredit_error.rb +7 -3
- data/lib/callcredit/errors/invalid_request_error.rb +3 -3
- data/lib/callcredit/middleware/check_response.rb +9 -5
- data/lib/callcredit/request.rb +19 -5
- data/lib/callcredit/response.rb +8 -1
- data/lib/callcredit/util.rb +3 -3
- data/lib/callcredit/validations.rb +34 -17
- data/lib/callcredit/version.rb +1 -1
- data/spec/callcredit_spec.rb +23 -1
- data/spec/checks/bank_enhanced_spec.rb +71 -0
- data/spec/checks/bank_standard_spec.rb +44 -0
- data/spec/checks/id_enhanced_spec.rb +1 -1
- data/spec/client_spec.rb +18 -2
- data/spec/request_spec.rb +35 -1
- data/spec/validations_spec.rb +66 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a36f71d745577cbb7014548b3bfb274aaf08daec
|
4
|
+
data.tar.gz: 54086f749c30f37c3055298450d4ec4988f5f1e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: adf512665d1906b25a37cb658b39875d680360a6465f9e7f256e4a7e6f6ec568ed2d7841734c0874db2ba355f3330f866aa7facdcb856382e08f6d291c9e535b
|
7
|
+
data.tar.gz: 8a597828c0501da6782c48813f59abaddf82f66da96d2897059fef7a640ebf01cb7354389f43feb1a1b5784d512e92466a50861ac2cd07ddde199a00f938f9f3
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# For all options see https://github.com/bbatsov/rubocop/tree/master/config
|
2
|
+
|
3
|
+
inherit_from: .rubocop_todo.yml
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
Exclude:
|
7
|
+
- bin/*
|
8
|
+
|
9
|
+
LineLength:
|
10
|
+
Max: 80
|
11
|
+
|
12
|
+
ClassLength:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
# Avoid methods longer than 30 lines of code
|
16
|
+
MethodLength:
|
17
|
+
CountComments: false # count full line comments?
|
18
|
+
Max: 87
|
19
|
+
|
20
|
+
# Avoid single-line methods.
|
21
|
+
SingleLineMethods:
|
22
|
+
AllowIfMethodIsEmpty: true
|
23
|
+
|
24
|
+
StringLiterals:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
GlobalVars:
|
28
|
+
Enabled: false
|
29
|
+
|
30
|
+
# Wants underscores in all large numbers. Pain in the ass for things like
|
31
|
+
# unix timestamps.
|
32
|
+
NumericLiterals:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
# Wants you to use the same argument names for every reduce. This seems kinda
|
36
|
+
# naff compared to naming them semantically
|
37
|
+
SingleLineBlockParams:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Style/SignalException:
|
41
|
+
EnforcedStyle: 'only_raise'
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
+
# on 2014-10-30 22:45:17 +0000 using RuboCop version 0.27.0.
|
3
|
+
# The point is for the user to remove these configuration records
|
4
|
+
# one by one as the offenses are removed from the code base.
|
5
|
+
# Note that changes in the inspected code, or installation of new
|
6
|
+
# versions of RuboCop, may require this file to be generated again.
|
7
|
+
|
8
|
+
# Offense count: 27
|
9
|
+
# Cop supports --auto-correct.
|
10
|
+
Lint/UnusedBlockArgument:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
# Offense count: 128
|
14
|
+
Metrics/AbcSize:
|
15
|
+
Max: 64
|
16
|
+
|
17
|
+
# Offense count: 9
|
18
|
+
Metrics/CyclomaticComplexity:
|
19
|
+
Max: 10
|
20
|
+
|
21
|
+
# Offense count: 5
|
22
|
+
Metrics/PerceivedComplexity:
|
23
|
+
Max: 10
|
24
|
+
|
25
|
+
# Offense count: 17
|
26
|
+
Style/AccessorMethodName:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
# Offense count: 64
|
30
|
+
# Cop supports --auto-correct.
|
31
|
+
# Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle, SupportedLastArgumentHashStyles.
|
32
|
+
Style/AlignHash:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
# Offense count: 72
|
36
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
37
|
+
Style/ClassAndModuleChildren:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
# Offense count: 16
|
41
|
+
# Configuration parameters: Keywords.
|
42
|
+
Style/CommentAnnotation:
|
43
|
+
Enabled: false
|
44
|
+
|
45
|
+
# Offense count: 336
|
46
|
+
Style/Documentation:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
# Offense count: 1285
|
50
|
+
# Cop supports --auto-correct.
|
51
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
52
|
+
Style/DotPosition:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
# Offense count: 6
|
56
|
+
Style/DoubleNegation:
|
57
|
+
Enabled: false
|
58
|
+
|
59
|
+
# Offense count: 11
|
60
|
+
Style/EachWithObject:
|
61
|
+
Enabled: false
|
62
|
+
|
63
|
+
# Offense count: 92
|
64
|
+
# Configuration parameters: MinBodyLength.
|
65
|
+
Style/GuardClause:
|
66
|
+
Enabled: false
|
67
|
+
|
68
|
+
# Offense count: 24
|
69
|
+
# Cop supports --auto-correct.
|
70
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
71
|
+
Style/IndentHash:
|
72
|
+
Enabled: false
|
73
|
+
|
74
|
+
# Offense count: 60
|
75
|
+
Style/Lambda:
|
76
|
+
Enabled: false
|
77
|
+
|
78
|
+
# Offense count: 141
|
79
|
+
# Cop supports --auto-correct.
|
80
|
+
Style/LineEndConcatenation:
|
81
|
+
Enabled: false
|
82
|
+
|
83
|
+
# Offense count: 3
|
84
|
+
# Cop supports --auto-correct.
|
85
|
+
Style/MethodCallParentheses:
|
86
|
+
Enabled: false
|
87
|
+
|
88
|
+
Style/ModuleFunction:
|
89
|
+
Enabled: false
|
90
|
+
|
91
|
+
# Offense count: 449
|
92
|
+
# Cop supports --auto-correct.
|
93
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
94
|
+
Style/MultilineOperationIndentation:
|
95
|
+
Enabled: false
|
96
|
+
|
97
|
+
# Offense count: 4
|
98
|
+
# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
|
99
|
+
Style/Next:
|
100
|
+
Enabled: false
|
101
|
+
|
102
|
+
# Offense count: 11
|
103
|
+
# Configuration parameters: NamePrefix, NamePrefixBlacklist.
|
104
|
+
Style/PredicateName:
|
105
|
+
Enabled: false
|
106
|
+
|
107
|
+
# Offense count: 5
|
108
|
+
# Cop supports --auto-correct.
|
109
|
+
Style/Proc:
|
110
|
+
Enabled: false
|
111
|
+
|
112
|
+
# Offense count: 9
|
113
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
114
|
+
Style/RaiseArgs:
|
115
|
+
Enabled: false
|
116
|
+
|
117
|
+
# Offense count: 5
|
118
|
+
# Cop supports --auto-correct.
|
119
|
+
# Configuration parameters: AllowMultipleReturnValues.
|
120
|
+
Style/RedundantReturn:
|
121
|
+
Enabled: false
|
122
|
+
|
123
|
+
# Offense count: 177
|
124
|
+
# Cop supports --auto-correct.
|
125
|
+
Style/RedundantSelf:
|
126
|
+
Enabled: false
|
127
|
+
|
128
|
+
# Offense count: 17
|
129
|
+
# Cop supports --auto-correct.
|
130
|
+
Style/SingleSpaceBeforeFirstArg:
|
131
|
+
Enabled: false
|
132
|
+
|
133
|
+
# Offense count: 87
|
134
|
+
# Cop supports --auto-correct.
|
135
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
136
|
+
Style/StringLiteralsInInterpolation:
|
137
|
+
Enabled: false
|
138
|
+
|
139
|
+
# Offense count: 53
|
140
|
+
# Cop supports --auto-correct.
|
141
|
+
# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
|
142
|
+
Style/TrailingComma:
|
143
|
+
Enabled: false
|
144
|
+
|
145
|
+
# Offense count: 8
|
146
|
+
# Cop supports --auto-correct.
|
147
|
+
# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, Whitelist.
|
148
|
+
Style/TrivialAccessors:
|
149
|
+
Enabled: false
|
150
|
+
|
151
|
+
# Offense count: 1
|
152
|
+
# Cop supports --auto-correct.
|
153
|
+
Style/WhileUntilDo:
|
154
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
+
## 0.4.0 - December 31, 2014
|
2
|
+
|
3
|
+
- Add support for BankStandard and BankEnhanced checks
|
4
|
+
- Tweak `Callcredit::Response#result` to support multiple kinds of check (i.e. not just
|
5
|
+
identity checks)
|
6
|
+
- Enforce code style with Rubocop
|
7
|
+
|
1
8
|
## 0.3.8 - July 16, 2014
|
2
9
|
|
3
|
-
- Include
|
10
|
+
- Include request ID (RID) on all requests
|
4
11
|
|
5
12
|
## 0.3.7 - June 3, 2014
|
6
13
|
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -45,7 +45,30 @@ The library will raise an error if you're missing any of the required
|
|
45
45
|
parameters (first_name, last_name, date_of_birth, building_number and
|
46
46
|
postcode).
|
47
47
|
|
48
|
+
#### BankStandard check
|
49
|
+
|
50
|
+
To perform a BankStandard check use:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
Callcredit.bank_standard_check(account_number: "44779911", sort_code: "200000")
|
54
|
+
```
|
55
|
+
|
56
|
+
The library will raise an error unless you provide both account_number and sort_code.
|
57
|
+
|
58
|
+
#### BankEnhanced check
|
59
|
+
|
60
|
+
To perform a BankEnhanced check use:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
Callcredit.bank_enhanced_check(first_name: "Tim", last_name: "Rogers", postcode: "EC1V 7LQ", account_number: "44779911", sort_code: "200000", building_number: "338-346")
|
64
|
+
```
|
65
|
+
|
66
|
+
The library will raise an error if you're missing any of the required
|
67
|
+
parameters (first_name, last_name, building_number, postcode, account_number
|
68
|
+
and sort_code).
|
69
|
+
|
48
70
|
#### Other checks
|
71
|
+
|
49
72
|
For any other check, simply pass the name of the check you'd like to perform
|
50
73
|
into the `perform_check` method, along with details of the individual you're
|
51
74
|
checking.
|
@@ -63,11 +86,6 @@ data_hash = { personal_data: { first_name: "Grey", last_name: "Baker" } }
|
|
63
86
|
Callcredit.perform_check([:id_enhanced, :credit_score], data_hash)
|
64
87
|
```
|
65
88
|
|
66
|
-
NOTE: Currently, this gem only supports checks on the payer's personal
|
67
|
-
information (other information won't be passed through to Callcredit).
|
68
|
-
Extending the gem should be trivial if Callcredit have given you access to
|
69
|
-
other checks.
|
70
|
-
|
71
89
|
### Parsing responses
|
72
90
|
|
73
91
|
Unless you've set the "raw" argument to true in your config, checks called by
|
@@ -80,7 +98,8 @@ Callcredit.id_enhanced_check(...) # => Callcredit::Response
|
|
80
98
|
Callcredit.id_enhanced_check(...).input # => Hash of input params, as
|
81
99
|
# returned by Callcredit
|
82
100
|
|
83
|
-
Callcredit.id_enhanced_check(...).result # => Hash of results
|
101
|
+
Callcredit.id_enhanced_check(...).result # => Hash of results, mapping
|
102
|
+
# a check type to its results
|
84
103
|
|
85
104
|
Callcredit.id_enhanced_check(...).full_result # => Hash of the full XML body
|
86
105
|
# returned by Callcredit
|
data/callcredit.gemspec
CHANGED
@@ -10,13 +10,13 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.add_development_dependency 'webmock', '~> 1.18.0'
|
11
11
|
|
12
12
|
gem.authors = ['Grey Baker']
|
13
|
-
gem.description =
|
13
|
+
gem.description = "Ruby wrapper for Callcredit's CallValidate API"
|
14
14
|
gem.email = ['grey@gocardless.com']
|
15
15
|
gem.files = `git ls-files`.split("\n")
|
16
16
|
gem.homepage = 'https://github.com/gocardless/callcredit-ruby'
|
17
17
|
gem.name = 'callcredit'
|
18
18
|
gem.require_paths = ['lib']
|
19
|
-
gem.summary =
|
19
|
+
gem.summary = "Ruby wrapper for Callcredit's CallValidate API"
|
20
20
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
21
|
gem.version = Callcredit::VERSION.dup
|
22
22
|
end
|
data/lib/callcredit.rb
CHANGED
@@ -11,6 +11,8 @@ require 'callcredit/validations'
|
|
11
11
|
require 'callcredit/client'
|
12
12
|
require 'callcredit/response'
|
13
13
|
require 'callcredit/checks/id_enhanced'
|
14
|
+
require 'callcredit/checks/bank_standard'
|
15
|
+
require 'callcredit/checks/bank_enhanced'
|
14
16
|
require 'callcredit/middleware/check_response'
|
15
17
|
|
16
18
|
# Errors
|
@@ -28,6 +30,14 @@ module Callcredit
|
|
28
30
|
client.id_enhanced_check(*args)
|
29
31
|
end
|
30
32
|
|
33
|
+
def self.bank_standard_check(*args)
|
34
|
+
client.bank_standard_check(*args)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.bank_enhanced_check(*args)
|
38
|
+
client.bank_enhanced_check(*args)
|
39
|
+
end
|
40
|
+
|
31
41
|
def self.perform_check(*args)
|
32
42
|
client.perform_check(*args)
|
33
43
|
end
|
@@ -49,4 +59,3 @@ module Callcredit
|
|
49
59
|
end
|
50
60
|
private_class_method :client
|
51
61
|
end
|
52
|
-
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Callcredit
|
2
|
+
module Checks
|
3
|
+
class BankEnhanced
|
4
|
+
REQUIRED_INPUTS = [:first_name, :last_name, :postcode, :account_number,
|
5
|
+
:sort_code, :account_number, :sort_code]
|
6
|
+
|
7
|
+
PERSONAL_DATA_KEYS = [:first_name, :last_name, :postcode,
|
8
|
+
:building_name, :building_number]
|
9
|
+
|
10
|
+
BANK_DATA_KEYS = [:account_number, :sort_code]
|
11
|
+
|
12
|
+
def initialize(client)
|
13
|
+
@client = client
|
14
|
+
end
|
15
|
+
|
16
|
+
def perform(data = {})
|
17
|
+
check_params(data)
|
18
|
+
response = @client.perform_check([:bank_standard, :bank_enhanced],
|
19
|
+
build_params(data))
|
20
|
+
|
21
|
+
@client.config[:raw] ? response : Response.new(response)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def build_params(data)
|
27
|
+
{
|
28
|
+
personal_data: data.select { |k, v| PERSONAL_DATA_KEYS.include?(k) },
|
29
|
+
bank_data: data.select { |k, v| BANK_DATA_KEYS.include?(k) }
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def check_params(data)
|
34
|
+
REQUIRED_INPUTS.each do |param|
|
35
|
+
if data[param].nil?
|
36
|
+
msg = "An BankEnhanced check requires a #{param}"
|
37
|
+
raise InvalidRequestError.new(msg, param)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# For a BankEnhanced check, we also need a building name or number
|
42
|
+
unless data[:building_number] || data[:building_name]
|
43
|
+
msg = "A BankEnhanced check requires a building number or name"
|
44
|
+
raise InvalidRequestError.new(msg, :building_number)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Callcredit
|
2
|
+
module Checks
|
3
|
+
class BankStandard
|
4
|
+
REQUIRED_INPUTS = [:account_number, :sort_code]
|
5
|
+
|
6
|
+
def initialize(client)
|
7
|
+
@client = client
|
8
|
+
end
|
9
|
+
|
10
|
+
def perform(data = {})
|
11
|
+
check_params(data)
|
12
|
+
response = @client.perform_check(:bank_standard, bank_data: data)
|
13
|
+
@client.config[:raw] ? response : Response.new(response)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def check_params(data)
|
19
|
+
REQUIRED_INPUTS.each do |param|
|
20
|
+
if data[param].nil?
|
21
|
+
msg = "An BankStandard check requires a #{param}"
|
22
|
+
raise InvalidRequestError.new(msg, param)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -23,7 +23,7 @@ module Callcredit
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
# For
|
26
|
+
# For an ID Enhanced check, we also need a building name or number
|
27
27
|
unless data[:building_number] || data[:building_name]
|
28
28
|
msg = "An IDEnhanced check requires a building number or name"
|
29
29
|
raise InvalidRequestError.new(msg, :building_number)
|
data/lib/callcredit/client.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
1
|
module Callcredit
|
2
2
|
class Client
|
3
|
-
def initialize(config=nil)
|
3
|
+
def initialize(config = nil)
|
4
4
|
@config = (config || Callcredit.config).clone
|
5
5
|
end
|
6
6
|
|
7
|
+
def bank_standard_check(check_data)
|
8
|
+
check = Checks::BankStandard.new(self)
|
9
|
+
check.perform(check_data)
|
10
|
+
end
|
11
|
+
|
12
|
+
def bank_enhanced_check(check_data)
|
13
|
+
check = Checks::BankEnhanced.new(self)
|
14
|
+
check.perform(check_data)
|
15
|
+
end
|
16
|
+
|
7
17
|
def id_enhanced_check(check_data)
|
8
18
|
check = Checks::IDEnhanced.new(self)
|
9
19
|
check.perform(check_data)
|
data/lib/callcredit/config.rb
CHANGED
@@ -7,7 +7,8 @@ module Callcredit
|
|
7
7
|
password: nil,
|
8
8
|
application_name: nil,
|
9
9
|
raw: false,
|
10
|
-
api_endpoint: "https://ct.callcreditsecure.co.uk/callvalidateapi/
|
10
|
+
api_endpoint: "https://ct.callcreditsecure.co.uk/callvalidateapi/" \
|
11
|
+
"incomingserver.php",
|
11
12
|
user_agent: "Callcredit Ruby Gem #{Callcredit::VERSION}".freeze
|
12
13
|
}.freeze
|
13
14
|
|
@@ -25,8 +26,7 @@ module Callcredit
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def clone
|
28
|
-
Config.new { |config| @config.each { |k,v| config[k] = v } }
|
29
|
+
Config.new { |config| @config.each { |k, v| config[k] = v } }
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
32
|
-
|
data/lib/callcredit/constants.rb
CHANGED
@@ -2,12 +2,16 @@ module Callcredit
|
|
2
2
|
class CallcreditError < StandardError
|
3
3
|
attr_reader :message
|
4
4
|
attr_reader :status
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :response
|
6
6
|
|
7
|
-
def initialize(message=nil, status=nil, response=nil)
|
7
|
+
def initialize(message = nil, status = nil, response = nil)
|
8
8
|
@message = message
|
9
9
|
@status = status
|
10
|
-
@
|
10
|
+
@response = response
|
11
|
+
end
|
12
|
+
|
13
|
+
def response_body
|
14
|
+
response.fetch(:body, nil) if response.responds_to?(:fetch)
|
11
15
|
end
|
12
16
|
|
13
17
|
def to_s
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module Callcredit
|
2
2
|
class InvalidRequestError < CallcreditError
|
3
|
-
|
3
|
+
attr_reader :param
|
4
4
|
|
5
|
-
def initialize(message, param, status=nil,
|
6
|
-
super(message, status,
|
5
|
+
def initialize(message, param, status = nil, response = nil)
|
6
|
+
super(message, status, response)
|
7
7
|
@param = param
|
8
8
|
end
|
9
9
|
end
|
@@ -2,18 +2,22 @@ module Callcredit
|
|
2
2
|
module Middleware
|
3
3
|
class CheckResponse < Faraday::Middleware
|
4
4
|
def call(env)
|
5
|
-
@app.call(env).on_complete do |
|
6
|
-
|
5
|
+
@app.call(env).on_complete do |completed_env|
|
6
|
+
results = completed_env[:body]["Results"]
|
7
|
+
|
8
|
+
unless results
|
7
9
|
raise InvalidResponseError.new(
|
8
|
-
"Invalid response",
|
10
|
+
"Invalid response", completed_env[:status], completed_env)
|
9
11
|
end
|
10
12
|
|
11
13
|
if results["Errors"]
|
12
14
|
errors = results["Errors"].values.flatten
|
13
15
|
messages = errors.map { |e| e.is_a?(Hash) ? e["__content__"] : e }
|
14
|
-
|
16
|
+
|
17
|
+
raise APIError.new(messages.join(" | "), completed_env[:status],
|
18
|
+
completed_env)
|
15
19
|
end
|
16
|
-
response_values(
|
20
|
+
response_values(completed_env)
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
data/lib/callcredit/request.rb
CHANGED
@@ -22,7 +22,7 @@ module Callcredit
|
|
22
22
|
end
|
23
23
|
|
24
24
|
# Compile the complete XML request to send to Callcredit
|
25
|
-
def build_request_xml(checks, check_data={})
|
25
|
+
def build_request_xml(checks, check_data = {})
|
26
26
|
builder = Nokogiri::XML::Builder.new do |xml|
|
27
27
|
xml.callvalidate do
|
28
28
|
authentication(xml)
|
@@ -66,9 +66,11 @@ module Callcredit
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def personal_data(xml, data)
|
69
|
+
return unless data
|
70
|
+
|
69
71
|
unless data.is_a? Hash
|
70
72
|
raise InvalidRequestError.new(
|
71
|
-
"
|
73
|
+
"Personal data must be a hash (if provided)", :personal_data)
|
72
74
|
end
|
73
75
|
|
74
76
|
xml.Personalinformation do
|
@@ -87,15 +89,27 @@ module Callcredit
|
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
90
|
-
def card_data(
|
92
|
+
def card_data(_xml, _data)
|
91
93
|
# Not implemented
|
92
94
|
end
|
93
95
|
|
94
96
|
def bank_data(xml, data)
|
95
|
-
|
97
|
+
return unless data
|
98
|
+
|
99
|
+
unless data.is_a? Hash
|
100
|
+
raise InvalidRequestError.new(
|
101
|
+
"Bank data must be a hash (if provided)", :bank_data)
|
102
|
+
end
|
103
|
+
|
104
|
+
xml.Bankinformation do
|
105
|
+
Constants::BANK_DETAILS.each do |param, element_name|
|
106
|
+
value = Validations.clean_param(param, data[param])
|
107
|
+
xml.send(element_name, value) if value
|
108
|
+
end
|
109
|
+
end
|
96
110
|
end
|
97
111
|
|
98
|
-
def income_data(
|
112
|
+
def income_data(_xml, _data)
|
99
113
|
# Not implemented
|
100
114
|
end
|
101
115
|
end
|
data/lib/callcredit/response.rb
CHANGED
@@ -17,7 +17,8 @@ module Callcredit
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def result
|
20
|
-
@response_data["Results"]["Result"]["Displays"]
|
20
|
+
@response_data["Results"]["Result"]["Displays"].
|
21
|
+
reject { |k, v| displays_excluded_from_results.include?(k) }
|
21
22
|
end
|
22
23
|
|
23
24
|
def warnings
|
@@ -27,5 +28,11 @@ module Callcredit
|
|
27
28
|
def full_result
|
28
29
|
@response_data
|
29
30
|
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def displays_excluded_from_results
|
35
|
+
%w(ChecksCompleted InputData Warnings InternalUse)
|
36
|
+
end
|
30
37
|
end
|
31
38
|
end
|
data/lib/callcredit/util.rb
CHANGED
@@ -7,10 +7,10 @@ module Callcredit
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def underscore(str)
|
10
|
-
str.to_s.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
11
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
10
|
+
str.to_s.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
11
|
+
gsub(/([a-z\d])([A-Z])/, '\1_\2').
|
12
12
|
tr("-", "_").
|
13
13
|
downcase
|
14
14
|
end
|
15
15
|
end
|
16
|
-
end
|
16
|
+
end
|
@@ -1,19 +1,19 @@
|
|
1
1
|
module Callcredit
|
2
2
|
module Validations
|
3
|
-
|
4
3
|
VALIDATIONS = {
|
5
|
-
date_of_birth:
|
6
|
-
title:
|
7
|
-
first_name:
|
8
|
-
last_name:
|
9
|
-
middle_names:
|
10
|
-
postcode:
|
11
|
-
previous_postcode:
|
12
|
-
|
4
|
+
date_of_birth: ->(val) { clean_date_of_birth(val) },
|
5
|
+
title: ->(val) { val || "Unknown" },
|
6
|
+
first_name: ->(val) { clean_name(val, :first_name) },
|
7
|
+
last_name: ->(val) { clean_name(val, :last_name) },
|
8
|
+
middle_names: ->(val) { clean_name(val, :middle_names) },
|
9
|
+
postcode: ->(val) { clean_postcode(val, :postcode) },
|
10
|
+
previous_postcode: ->(val) { clean_postcode(val, :previous_postcode) },
|
11
|
+
account_number: ->(val) { clean_account_number(val) },
|
12
|
+
sort_code: ->(val) { clean_sort_code(val) },
|
13
13
|
}
|
14
14
|
|
15
15
|
def self.clean_param(key, value)
|
16
|
-
validator = VALIDATIONS.fetch(key, ->(
|
16
|
+
validator = VALIDATIONS.fetch(key, ->(val) { val })
|
17
17
|
validator.call(value)
|
18
18
|
end
|
19
19
|
|
@@ -28,7 +28,7 @@ module Callcredit
|
|
28
28
|
def self.clean_name(name, param)
|
29
29
|
return unless name
|
30
30
|
# Convert name to ASCII characters only
|
31
|
-
name = UnicodeUtils.nfkd(name).gsub(/(\p{Letter})\p{Mark}+/,'\\1')
|
31
|
+
name = UnicodeUtils.nfkd(name).gsub(/(\p{Letter})\p{Mark}+/, '\\1')
|
32
32
|
input_error(param, name) unless name =~ /\A[a-z A-Z'-]{1,30}\z/
|
33
33
|
name
|
34
34
|
end
|
@@ -40,13 +40,30 @@ module Callcredit
|
|
40
40
|
postcode
|
41
41
|
end
|
42
42
|
|
43
|
-
def self.
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
def self.clean_account_number(account_number)
|
44
|
+
return unless account_number
|
45
|
+
cleaned_value = account_number.to_s.gsub(/[-\s]/, '')
|
46
|
+
unless cleaned_value =~ /\A\d{6,8}\z/
|
47
|
+
input_error(:account_number, account_number)
|
48
48
|
end
|
49
|
+
cleaned_value
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.clean_sort_code(sort_code)
|
53
|
+
return unless sort_code
|
54
|
+
cleaned_value = sort_code.to_s.gsub(/[-\s]/, '')
|
55
|
+
input_error(:sort_code, sort_code) unless cleaned_value =~ /\A\d{6}\z/
|
56
|
+
cleaned_value
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.input_error(param, value = nil)
|
60
|
+
msg = if value.nil?
|
61
|
+
"#{param} is a required param"
|
62
|
+
else
|
63
|
+
"Invalid value \"#{value}\" for #{param}"
|
64
|
+
end
|
65
|
+
|
49
66
|
raise InvalidRequestError.new(msg, param)
|
50
67
|
end
|
51
68
|
end
|
52
|
-
end
|
69
|
+
end
|
data/lib/callcredit/version.rb
CHANGED
data/spec/callcredit_spec.rb
CHANGED
@@ -10,7 +10,7 @@ describe Callcredit do
|
|
10
10
|
before { Callcredit.configure { |config| config[key] = key } }
|
11
11
|
|
12
12
|
describe [key] do
|
13
|
-
subject {
|
13
|
+
subject { Callcredit.config[key] }
|
14
14
|
it { should == key }
|
15
15
|
end
|
16
16
|
end
|
@@ -36,6 +36,28 @@ describe Callcredit do
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
describe '#bank_standard_check' do
|
40
|
+
before { configure_callcredit }
|
41
|
+
let(:data) { { account_number: "44779911", sort_code: "200000" } }
|
42
|
+
|
43
|
+
it "delegates to the client" do
|
44
|
+
expect_any_instance_of(Callcredit::Client).
|
45
|
+
to receive(:bank_standard_check).with(data)
|
46
|
+
Callcredit.bank_standard_check(data)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#bank_enhanced_check' do
|
51
|
+
before { configure_callcredit }
|
52
|
+
let(:data) { { first_name: "Grey", last_name: "Baker" } }
|
53
|
+
|
54
|
+
it "delegates to the client" do
|
55
|
+
expect_any_instance_of(Callcredit::Client).
|
56
|
+
to receive(:bank_enhanced_check).with(data)
|
57
|
+
Callcredit.bank_enhanced_check(data)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
39
61
|
describe '#perform_check' do
|
40
62
|
before { configure_callcredit }
|
41
63
|
let(:data) do
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Callcredit::Checks::BankEnhanced do
|
4
|
+
let(:bank_enhanced_check) { Callcredit::Checks::BankEnhanced.new(client) }
|
5
|
+
let(:client) { Callcredit::Client.new(config) }
|
6
|
+
let(:config) { Callcredit::Config.new }
|
7
|
+
|
8
|
+
let(:response_hash) { { status: status, body: body } }
|
9
|
+
let(:status) { 200 }
|
10
|
+
let(:body) { response_xml }
|
11
|
+
let(:response_xml) { load_fixture('response.xml') }
|
12
|
+
before { stub_request(:get, config[:api_endpoint]).to_return(response_hash) }
|
13
|
+
|
14
|
+
describe "#perform" do
|
15
|
+
subject(:perform_check) { bank_enhanced_check.perform(check_data) }
|
16
|
+
|
17
|
+
let(:check_data) do
|
18
|
+
{ first_name: "Grey",
|
19
|
+
last_name: "Baker",
|
20
|
+
postcode: "EC2A 1DX",
|
21
|
+
building_number: "22-25",
|
22
|
+
sort_code: "200000",
|
23
|
+
account_number: "44779911" }
|
24
|
+
end
|
25
|
+
|
26
|
+
it "separates the supplied data into personal and bank details" do
|
27
|
+
expect(client).to receive(:perform_check) do |check_types, data|
|
28
|
+
expect(data[:personal_data][:postcode]).to eq(check_data[:postcode])
|
29
|
+
expect(data[:bank_data][:sort_code]).to eq(check_data[:sort_code])
|
30
|
+
end
|
31
|
+
|
32
|
+
perform_check
|
33
|
+
end
|
34
|
+
|
35
|
+
it "makes a get request" do
|
36
|
+
perform_check
|
37
|
+
expect(a_request(:get, config[:api_endpoint])).to have_been_made
|
38
|
+
end
|
39
|
+
|
40
|
+
it { is_expected.to be_a Callcredit::Response }
|
41
|
+
|
42
|
+
context "when the config[:raw] is true" do
|
43
|
+
before { config[:raw] = true }
|
44
|
+
it { is_expected.to be_a Faraday::Response }
|
45
|
+
|
46
|
+
describe '#body' do
|
47
|
+
subject { perform_check.body }
|
48
|
+
it { should be_a String }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "validates inputs" do
|
53
|
+
it_behaves_like "it validates presence", :first_name
|
54
|
+
it_behaves_like "it validates presence", :last_name
|
55
|
+
it_behaves_like "it validates presence", :postcode
|
56
|
+
it_behaves_like "it validates presence", :building_number
|
57
|
+
it_behaves_like "it validates presence", :account_number
|
58
|
+
it_behaves_like "it validates presence", :sort_code
|
59
|
+
|
60
|
+
context "with a building_name instead of building number" do
|
61
|
+
before { check_data.delete(:building_number) }
|
62
|
+
before { check_data[:building_name] = "The Mill" }
|
63
|
+
|
64
|
+
it "makes a get request" do
|
65
|
+
perform_check
|
66
|
+
expect(a_request(:get, config[:api_endpoint])).to have_been_made
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Callcredit::Checks::BankStandard do
|
4
|
+
let(:bank_standard_check) { Callcredit::Checks::BankStandard.new(client) }
|
5
|
+
let(:client) { Callcredit::Client.new(config) }
|
6
|
+
let(:config) { Callcredit::Config.new }
|
7
|
+
|
8
|
+
let(:response_hash) { { status: status, body: body } }
|
9
|
+
let(:status) { 200 }
|
10
|
+
let(:body) { response_xml }
|
11
|
+
let(:response_xml) { load_fixture('response.xml') }
|
12
|
+
before { stub_request(:get, config[:api_endpoint]).to_return(response_hash) }
|
13
|
+
|
14
|
+
describe "#perform" do
|
15
|
+
subject(:perform_check) { bank_standard_check.perform(check_data) }
|
16
|
+
|
17
|
+
let(:check_data) do
|
18
|
+
{ account_number: "44779911",
|
19
|
+
sort_code: "200000" }
|
20
|
+
end
|
21
|
+
|
22
|
+
it "makes a get request" do
|
23
|
+
perform_check
|
24
|
+
expect(a_request(:get, config[:api_endpoint])).to have_been_made
|
25
|
+
end
|
26
|
+
|
27
|
+
it { is_expected.to be_a Callcredit::Response }
|
28
|
+
|
29
|
+
context "when the config[:raw] is true" do
|
30
|
+
before { config[:raw] = true }
|
31
|
+
it { is_expected.to be_a Faraday::Response }
|
32
|
+
|
33
|
+
describe '#body' do
|
34
|
+
subject { perform_check.body }
|
35
|
+
it { should be_a String }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "validates inputs" do
|
40
|
+
it_behaves_like "it validates presence", :account_number
|
41
|
+
it_behaves_like "it validates presence", :sort_code
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/spec/client_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe Callcredit::Client do
|
|
11
11
|
subject(:new_client) { Callcredit::Client.new }
|
12
12
|
|
13
13
|
describe '#config' do
|
14
|
-
subject {
|
14
|
+
subject { new_client.config }
|
15
15
|
it { should_not == Callcredit.config }
|
16
16
|
end
|
17
17
|
it "has the attributes of the global config" do
|
@@ -24,7 +24,7 @@ describe Callcredit::Client do
|
|
24
24
|
subject(:new_client) { Callcredit::Client.new(config) }
|
25
25
|
|
26
26
|
describe '#config' do
|
27
|
-
subject {
|
27
|
+
subject { new_client.config }
|
28
28
|
it { should_not == config }
|
29
29
|
end
|
30
30
|
it "has the attributes of the passed in config" do
|
@@ -41,6 +41,22 @@ describe Callcredit::Client do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
describe "#bank_standard_check" do
|
45
|
+
it "delegates to an instance of BankStandard" do
|
46
|
+
expect_any_instance_of(Callcredit::Checks::BankStandard).
|
47
|
+
to receive(:perform).once
|
48
|
+
client.bank_standard_check(check_data)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#bank_enhanced_check" do
|
53
|
+
it "delegates to an instance of BankEnhanced" do
|
54
|
+
expect_any_instance_of(Callcredit::Checks::BankEnhanced).
|
55
|
+
to receive(:perform).once
|
56
|
+
client.bank_enhanced_check(check_data)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
44
60
|
describe "#perform_check" do
|
45
61
|
subject(:perform_check) { client.perform_check(:check_type, check_data) }
|
46
62
|
|
data/spec/request_spec.rb
CHANGED
@@ -41,6 +41,40 @@ describe Callcredit::Request do
|
|
41
41
|
expect(xsd.validate(request_xml)).to eq([])
|
42
42
|
end
|
43
43
|
end
|
44
|
+
|
45
|
+
context "for a BankStandard check" do
|
46
|
+
before do
|
47
|
+
check_data.merge!(
|
48
|
+
bank_data: { account_number: 55779911, sort_code: 200000 }
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
subject(:request_xml) do
|
53
|
+
request.build_request_xml(:bank_standard, check_data)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "generates a valid XML request" do
|
57
|
+
expect(xsd.validate(request_xml)).to eq([])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "for a BankEnhanced check" do
|
62
|
+
before do
|
63
|
+
check_data.merge!(
|
64
|
+
bank_data: { account_number: 55779911, sort_code: 200000 },
|
65
|
+
personal_data: { first_name: "Tim", last_name: "Rogers",
|
66
|
+
postcode: "EC1V 7LQ", building_number: "338-346" }
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
subject(:request_xml) do
|
71
|
+
request.build_request_xml(:bank_enhanced, check_data)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "generates a valid XML request" do
|
75
|
+
expect(xsd.validate(request_xml)).to eq([])
|
76
|
+
end
|
77
|
+
end
|
44
78
|
end
|
45
79
|
|
46
80
|
describe "#perform" do
|
@@ -56,7 +90,7 @@ describe Callcredit::Request do
|
|
56
90
|
it { is_expected.to be_a Faraday::Response }
|
57
91
|
|
58
92
|
describe '#body' do
|
59
|
-
subject {
|
93
|
+
subject { perform_check.body }
|
60
94
|
it { should be_a String }
|
61
95
|
end
|
62
96
|
end
|
data/spec/validations_spec.rb
CHANGED
@@ -85,4 +85,70 @@ describe Callcredit::Validations do
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
88
|
+
|
89
|
+
describe '#clean_account_number' do
|
90
|
+
subject { Callcredit::Validations.clean_account_number(account_number) }
|
91
|
+
|
92
|
+
context "without an account_number" do
|
93
|
+
let(:account_number) { nil }
|
94
|
+
it { is_expected.to eq(nil) }
|
95
|
+
end
|
96
|
+
|
97
|
+
context "with a correct account_number" do
|
98
|
+
let(:account_number) { "12345678" }
|
99
|
+
it { is_expected.to eq(account_number) }
|
100
|
+
end
|
101
|
+
|
102
|
+
context "with a padded account_number" do
|
103
|
+
let(:account_number) { " 1234 5678 " }
|
104
|
+
it { is_expected.to eq("12345678") }
|
105
|
+
end
|
106
|
+
|
107
|
+
context "with an account_number with letters" do
|
108
|
+
let(:account_number) { "N1234567" }
|
109
|
+
it "raises an error" do
|
110
|
+
expect { subject }.to raise_error Callcredit::InvalidRequestError
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "with an account_number with too many numbers" do
|
115
|
+
let(:account_number) { "123456789" }
|
116
|
+
it "raises an error" do
|
117
|
+
expect { subject }.to raise_error Callcredit::InvalidRequestError
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe '#clean_sort_code' do
|
123
|
+
subject { Callcredit::Validations.clean_sort_code(sort_code) }
|
124
|
+
|
125
|
+
context "without a sort_code" do
|
126
|
+
let(:sort_code) { nil }
|
127
|
+
it { is_expected.to eq(nil) }
|
128
|
+
end
|
129
|
+
|
130
|
+
context "with a correct sort_code" do
|
131
|
+
let(:sort_code) { "123456" }
|
132
|
+
it { is_expected.to eq(sort_code) }
|
133
|
+
end
|
134
|
+
|
135
|
+
context "with a padded sort_code" do
|
136
|
+
let(:sort_code) { " 1234 56 " }
|
137
|
+
it { is_expected.to eq("123456") }
|
138
|
+
end
|
139
|
+
|
140
|
+
context "with a sort_code with letters" do
|
141
|
+
let(:sort_code) { "N12345" }
|
142
|
+
it "raises an error" do
|
143
|
+
expect { subject }.to raise_error Callcredit::InvalidRequestError
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "with a sort_code with too many numbers" do
|
148
|
+
let(:sort_code) { "1234567" }
|
149
|
+
it "raises an error" do
|
150
|
+
expect { subject }.to raise_error Callcredit::InvalidRequestError
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
88
154
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: callcredit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grey Baker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday_middleware
|
@@ -108,6 +108,8 @@ extensions: []
|
|
108
108
|
extra_rdoc_files: []
|
109
109
|
files:
|
110
110
|
- .gitignore
|
111
|
+
- .rubocop.yml
|
112
|
+
- .rubocop_todo.yml
|
111
113
|
- .travis.yml
|
112
114
|
- CHANGELOG.md
|
113
115
|
- Gemfile
|
@@ -115,6 +117,8 @@ files:
|
|
115
117
|
- README.md
|
116
118
|
- callcredit.gemspec
|
117
119
|
- lib/callcredit.rb
|
120
|
+
- lib/callcredit/checks/bank_enhanced.rb
|
121
|
+
- lib/callcredit/checks/bank_standard.rb
|
118
122
|
- lib/callcredit/checks/id_enhanced.rb
|
119
123
|
- lib/callcredit/client.rb
|
120
124
|
- lib/callcredit/config.rb
|
@@ -130,6 +134,8 @@ files:
|
|
130
134
|
- lib/callcredit/validations.rb
|
131
135
|
- lib/callcredit/version.rb
|
132
136
|
- spec/callcredit_spec.rb
|
137
|
+
- spec/checks/bank_enhanced_spec.rb
|
138
|
+
- spec/checks/bank_standard_spec.rb
|
133
139
|
- spec/checks/id_enhanced_spec.rb
|
134
140
|
- spec/client_spec.rb
|
135
141
|
- spec/fixtures/access_denied.xml
|
@@ -166,6 +172,8 @@ specification_version: 4
|
|
166
172
|
summary: Ruby wrapper for Callcredit's CallValidate API
|
167
173
|
test_files:
|
168
174
|
- spec/callcredit_spec.rb
|
175
|
+
- spec/checks/bank_enhanced_spec.rb
|
176
|
+
- spec/checks/bank_standard_spec.rb
|
169
177
|
- spec/checks/id_enhanced_spec.rb
|
170
178
|
- spec/client_spec.rb
|
171
179
|
- spec/fixtures/access_denied.xml
|