aggcat 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.
- data/Gemfile +3 -5
- data/README.md +6 -0
- data/lib/aggcat/base.rb +3 -5
- data/lib/aggcat/version.rb +1 -1
- data/test/aggcat/aggcat_test.rb +54 -0
- data/test/aggcat/client_test.rb +131 -4
- data/test/fixtures/challenge.xml +5 -0
- data/test/test_helper.rb +8 -0
- metadata +6 -2
data/Gemfile
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'oauth', '~> 0.4'
|
4
|
-
gem 'nori', '~> 2.0'
|
5
|
-
gem 'nokogiri', '~> 1.5'
|
6
|
-
gem 'active_support', '~> 3.0'
|
7
|
-
gem 'builder', '~> 3.2'
|
8
3
|
gem 'rake'
|
9
4
|
|
10
5
|
group :test do
|
11
6
|
gem 'minitest'
|
12
7
|
gem 'test-unit'
|
13
8
|
gem 'simplecov', :require => false
|
9
|
+
gem 'coveralls', :require => false
|
14
10
|
gem 'webmock'
|
15
11
|
end
|
12
|
+
|
13
|
+
gemspec
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Aggcat
|
2
2
|
[](https://travis-ci.org/cloocher/aggcat)
|
3
|
+
[](https://coveralls.io/r/cloocher/aggcat)
|
4
|
+
[](http://badge.fury.io/rb/aggcat)
|
3
5
|
|
4
6
|
Intuit Customer Account Data API client
|
5
7
|
|
@@ -78,6 +80,10 @@ Aggcat.delete_customer
|
|
78
80
|
|
79
81
|
Please make sure to read Intuit's [Account Data API](http://docs.developer.intuit.com/0020_Aggregation_Categorization_Apps/AggCat_API/0020_API_Documentation) docs.
|
80
82
|
|
83
|
+
## Requirements
|
84
|
+
|
85
|
+
* Ruby 1.9.2 or higher
|
86
|
+
|
81
87
|
## Copyright
|
82
88
|
Copyright (c) 2013 Gene Drabkin.
|
83
89
|
See [LICENSE][] for details.
|
data/lib/aggcat/base.rb
CHANGED
@@ -23,8 +23,6 @@ module Aggcat
|
|
23
23
|
|
24
24
|
TIMEOUT = 120
|
25
25
|
|
26
|
-
IGNORE_KEYS = Set.new([:'@xmlns', :'@xmlns:ns2', :'@xmlns:ns3', :'@xmlns:ns4', :'@xmlns:ns5', :'@xmlns:ns6', :'@xmlns:ns7', :'@xmlns:ns8', :'@xmlns:ns9'])
|
27
|
-
|
28
26
|
protected
|
29
27
|
|
30
28
|
def oauth_client
|
@@ -61,7 +59,7 @@ module Aggcat
|
|
61
59
|
def saml_message(user_id)
|
62
60
|
now = Time.now.utc
|
63
61
|
reference_id = SecureRandom.uuid.gsub('-', '')
|
64
|
-
assertion = %[<?xml version="1.0" encoding="UTF-8"?><saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_#{reference_id}" IssueInstant="#{iso8601(now)}" Version="2.0"><saml2:Issuer>#{@issuer_id}</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference URI="#_#{reference_id}"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue
|
62
|
+
assertion = %[<?xml version="1.0" encoding="UTF-8"?><saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_#{reference_id}" IssueInstant="#{iso8601(now)}" Version="2.0"><saml2:Issuer>#{@issuer_id}</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference URI="#_#{reference_id}"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>%s</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>%s</ds:SignatureValue></ds:Signature><saml2:Subject><saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">#{user_id}</saml2:NameID><saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"/></saml2:Subject><saml2:Conditions NotBefore="#{iso8601(now-5*60)}" NotOnOrAfter="#{iso8601(now+10*60)}"><saml2:AudienceRestriction><saml2:Audience>#{@issuer_id}</saml2:Audience></saml2:AudienceRestriction></saml2:Conditions><saml2:AuthnStatement AuthnInstant="#{iso8601(now)}" SessionIndex="_#{reference_id}"><saml2:AuthnContext><saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml2:AuthnContextClassRef></saml2:AuthnContext></saml2:AuthnStatement></saml2:Assertion>]
|
65
63
|
doc = Nokogiri::XML(assertion)
|
66
64
|
doc.xpath('//ds:Signature', 'ds' => 'http://www.w3.org/2000/09/xmldsig#').remove
|
67
65
|
doc.xpath('//text()[not(normalize-space())]').remove
|
@@ -71,7 +69,7 @@ module Aggcat
|
|
71
69
|
signature_value = Nokogiri::XML(signed_info).canonicalize
|
72
70
|
key = OpenSSL::PKey::RSA.new(File.read(@certificate_path))
|
73
71
|
encoded_signature_value = Base64.encode64(key.sign(OpenSSL::Digest::SHA1.new, signature_value)).gsub!(/\n/, '')
|
74
|
-
Base64.encode64(assertion
|
72
|
+
Base64.encode64(assertion % [encoded_digest, encoded_signature_value])
|
75
73
|
end
|
76
74
|
|
77
75
|
def iso8601(time)
|
@@ -88,7 +86,7 @@ module Aggcat
|
|
88
86
|
|
89
87
|
def cleanup(hash)
|
90
88
|
hash.each do |k, v|
|
91
|
-
if
|
89
|
+
if k.to_s[/^@xmlns/]
|
92
90
|
hash.delete(k)
|
93
91
|
elsif v.respond_to?(:keys)
|
94
92
|
cleanup(v)
|
data/lib/aggcat/version.rb
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AggcatTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
Aggcat.configure do |config|
|
6
|
+
config.issuer_id = 'issuer_id'
|
7
|
+
config.consumer_key = 'consumer_key'
|
8
|
+
config.consumer_secret = 'consumer_secret'
|
9
|
+
config.certificate_path = "#{fixture_path}/cert.key"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_configure
|
14
|
+
configurable = Aggcat.configure do |config|
|
15
|
+
config.issuer_id = 'issuer_id'
|
16
|
+
config.consumer_key = 'consumer_key'
|
17
|
+
config.consumer_secret = 'consumer_secret'
|
18
|
+
config.certificate_path = "#{fixture_path}/cert.key"
|
19
|
+
end
|
20
|
+
assert_equal 'issuer_id', configurable.instance_variable_get(:'@issuer_id')
|
21
|
+
assert_equal 'consumer_key', configurable.instance_variable_get(:'@consumer_key')
|
22
|
+
assert_equal 'consumer_secret', configurable.instance_variable_get(:'@consumer_secret')
|
23
|
+
assert_equal "#{fixture_path}/cert.key", configurable.instance_variable_get(:'@certificate_path')
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_scope
|
27
|
+
client1 = Aggcat.scope('1')
|
28
|
+
assert_true client1.is_a?(Aggcat::Client)
|
29
|
+
assert_equal 'issuer_id', client1.instance_variable_get(:'@issuer_id')
|
30
|
+
assert_equal 'consumer_key', client1.instance_variable_get(:'@consumer_key')
|
31
|
+
assert_equal 'consumer_secret', client1.instance_variable_get(:'@consumer_secret')
|
32
|
+
assert_equal "#{fixture_path}/cert.key", client1.instance_variable_get(:'@certificate_path')
|
33
|
+
assert_equal '1', client1.instance_variable_get(:'@customer_id')
|
34
|
+
client2 = Aggcat.client
|
35
|
+
assert_equal client1, client2
|
36
|
+
client3 = Aggcat.scope('1')
|
37
|
+
assert_equal client1, client3
|
38
|
+
client4 = Aggcat.scope('2')
|
39
|
+
assert_not_equal client1, client4
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_no_scope
|
43
|
+
exception = assert_raise(ArgumentError) { Aggcat.scope(nil) }
|
44
|
+
assert_equal('customer_id is required for scoping all requests', exception.message)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_client_api
|
48
|
+
stub_request(:post, Aggcat::Base::SAML_URL).to_return(:status => 200, :body => fixture('oauth_token.txt'))
|
49
|
+
Aggcat.scope('1')
|
50
|
+
stub_get('/institutions').to_return(:body => fixture('institutions.xml'), :headers => {:content_type => 'application/xml; charset=utf-8'})
|
51
|
+
response = Aggcat.institutions
|
52
|
+
assert_equal response[:response][:institutions][:institution][0][:institution_id].to_i, 100000
|
53
|
+
end
|
54
|
+
end
|
data/test/aggcat/client_test.rb
CHANGED
@@ -27,9 +27,10 @@ class ClientTest < Test::Unit::TestCase
|
|
27
27
|
assert_equal institution_id, response[:response][:institution_detail][:institution_id]
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
30
|
+
def test_institution_with_bad_args
|
31
|
+
exception = assert_raise(ArgumentError) { @client.institution(nil) }
|
32
|
+
assert_equal('institution_id is required', exception.message)
|
33
|
+
|
33
34
|
exception = assert_raise(ArgumentError) { @client.institution('') }
|
34
35
|
assert_equal('institution_id is required', exception.message)
|
35
36
|
end
|
@@ -43,6 +44,35 @@ class ClientTest < Test::Unit::TestCase
|
|
43
44
|
assert_equal '000000000001', response[:response][:account_list][:banking_account][:account_id]
|
44
45
|
end
|
45
46
|
|
47
|
+
def test_discover_and_add_accounts_with_challenge
|
48
|
+
institution_id = '100000'
|
49
|
+
stub_get("/institutions/#{institution_id}").to_return(:body => fixture('institution.xml'), :headers => {:content_type => 'application/xml; charset=utf-8'})
|
50
|
+
stub_post("/institutions/#{institution_id}/logins").to_return(:code => 401, :body => fixture('account.xml'), :headers => {:content_type => 'application/xml; charset=utf-8'})
|
51
|
+
response = @client.discover_and_add_accounts(institution_id, 'username', 'password')
|
52
|
+
assert_equal institution_id, response[:response][:account_list][:banking_account][:institution_id]
|
53
|
+
assert_equal '000000000001', response[:response][:account_list][:banking_account][:account_id]
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_discover_and_add_accounts_bad_args
|
57
|
+
exception = assert_raise(ArgumentError) { @client.discover_and_add_accounts(nil, 'username', 'password') }
|
58
|
+
assert_equal('institution_id is required', exception.message)
|
59
|
+
|
60
|
+
exception = assert_raise(ArgumentError) { @client.discover_and_add_accounts('', 'username', 'password') }
|
61
|
+
assert_equal('institution_id is required', exception.message)
|
62
|
+
|
63
|
+
exception = assert_raise(ArgumentError) { @client.discover_and_add_accounts(1, nil, 'password') }
|
64
|
+
assert_equal('username is required', exception.message)
|
65
|
+
|
66
|
+
exception = assert_raise(ArgumentError) { @client.discover_and_add_accounts(1, '', 'password') }
|
67
|
+
assert_equal('username is required', exception.message)
|
68
|
+
|
69
|
+
exception = assert_raise(ArgumentError) { @client.discover_and_add_accounts(1, 'username', nil) }
|
70
|
+
assert_equal('password is required', exception.message)
|
71
|
+
|
72
|
+
exception = assert_raise(ArgumentError) { @client.discover_and_add_accounts(1, 'username', '') }
|
73
|
+
assert_equal('password is required', exception.message)
|
74
|
+
end
|
75
|
+
|
46
76
|
def test_account
|
47
77
|
account_id = '000000000001'
|
48
78
|
stub_get("/accounts/#{account_id}").to_return(:body => fixture('account.xml'), :headers => {:content_type => 'application/xml; charset=utf-8'})
|
@@ -50,6 +80,14 @@ class ClientTest < Test::Unit::TestCase
|
|
50
80
|
assert_equal account_id, response[:response][:account_list][:banking_account][:account_id]
|
51
81
|
end
|
52
82
|
|
83
|
+
def test_account_bad_args
|
84
|
+
exception = assert_raise(ArgumentError) { @client.account(nil) }
|
85
|
+
assert_equal('account_id is required', exception.message)
|
86
|
+
|
87
|
+
exception = assert_raise(ArgumentError) { @client.account('') }
|
88
|
+
assert_equal('account_id is required', exception.message)
|
89
|
+
end
|
90
|
+
|
53
91
|
def test_accounts
|
54
92
|
stub_get('/accounts').to_return(:body => fixture('accounts.xml'), :headers => {:content_type => 'application/xml; charset=utf-8'})
|
55
93
|
response = @client.accounts
|
@@ -62,8 +100,36 @@ class ClientTest < Test::Unit::TestCase
|
|
62
100
|
start_date = Date.today - 30
|
63
101
|
uri = "/accounts/#{account_id}/transactions?txnStartDate=#{start_date.strftime(Aggcat::Base::DATE_FORMAT)}"
|
64
102
|
stub_get(uri).to_return(:body => fixture('transactions.xml'), :headers => {:content_type => 'application/xml; charset=utf-8'})
|
65
|
-
response = @client.account_transactions(account_id,
|
103
|
+
response = @client.account_transactions(account_id, start_date)
|
104
|
+
assert_equal '75000088503', response[:response][:transaction_list][:credit_card_transaction][:id]
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_account_transactions_with_dates
|
108
|
+
account_id = '000000000001'
|
109
|
+
end_date = Date.today
|
110
|
+
start_date = end_date - 30
|
111
|
+
challenge_session_id = '1234'
|
112
|
+
challenge_node_id = '4321'
|
113
|
+
uri = "/accounts/#{account_id}/transactions?txnStartDate=#{start_date.strftime(Aggcat::Base::DATE_FORMAT)}&txnEndDate=#{end_date.strftime(Aggcat::Base::DATE_FORMAT)}"
|
114
|
+
stub_get(uri).to_return(:body => fixture('transactions.xml'), :headers => {:content_type => 'application/xml; charset=utf-8', :challengeSessionId => challenge_session_id, :challengeNodeId => challenge_node_id})
|
115
|
+
response = @client.account_transactions(account_id, start_date, end_date)
|
66
116
|
assert_equal '75000088503', response[:response][:transaction_list][:credit_card_transaction][:id]
|
117
|
+
assert_equal response[:challenge_session_id], challenge_session_id
|
118
|
+
assert_equal response[:challenge_node_id], challenge_node_id
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_account_transactions_bad_args
|
122
|
+
exception = assert_raise(ArgumentError) { @client.account_transactions(nil, Date.today) }
|
123
|
+
assert_equal('account_id is required', exception.message)
|
124
|
+
|
125
|
+
exception = assert_raise(ArgumentError) { @client.account_transactions('', Date.today) }
|
126
|
+
assert_equal('account_id is required', exception.message)
|
127
|
+
|
128
|
+
exception = assert_raise(ArgumentError) { @client.account_transactions(1, nil) }
|
129
|
+
assert_equal('start_date is required', exception.message)
|
130
|
+
|
131
|
+
exception = assert_raise(ArgumentError) { @client.account_transactions(1, '') }
|
132
|
+
assert_equal('start_date is required', exception.message)
|
67
133
|
end
|
68
134
|
|
69
135
|
def test_delete_account
|
@@ -73,6 +139,14 @@ class ClientTest < Test::Unit::TestCase
|
|
73
139
|
assert_equal '200', response[:response_code]
|
74
140
|
end
|
75
141
|
|
142
|
+
def test_delete_account_bad_args
|
143
|
+
exception = assert_raise(ArgumentError) { @client.delete_account(nil) }
|
144
|
+
assert_equal('account_id is required', exception.message)
|
145
|
+
|
146
|
+
exception = assert_raise(ArgumentError) { @client.delete_account('') }
|
147
|
+
assert_equal('account_id is required', exception.message)
|
148
|
+
end
|
149
|
+
|
76
150
|
def test_delete_customer
|
77
151
|
stub_delete('/customers').to_return(:status => 200)
|
78
152
|
response = @client.delete_customer
|
@@ -88,4 +162,57 @@ class ClientTest < Test::Unit::TestCase
|
|
88
162
|
assert_equal '200', response[:response_code]
|
89
163
|
end
|
90
164
|
|
165
|
+
def test_update_login_bad_args
|
166
|
+
exception = assert_raise(ArgumentError) { @client.update_login(nil, 1, 'username', 'password') }
|
167
|
+
assert_equal('institution_id is required', exception.message)
|
168
|
+
|
169
|
+
exception = assert_raise(ArgumentError) { @client.update_login('', 1, 'username', 'password') }
|
170
|
+
assert_equal('institution_id is required', exception.message)
|
171
|
+
|
172
|
+
exception = assert_raise(ArgumentError) { @client.update_login(1, nil, 'username', 'password') }
|
173
|
+
assert_equal('login_id is required', exception.message)
|
174
|
+
|
175
|
+
exception = assert_raise(ArgumentError) { @client.update_login(1, '', 'username', 'password') }
|
176
|
+
assert_equal('login_id is required', exception.message)
|
177
|
+
|
178
|
+
exception = assert_raise(ArgumentError) { @client.update_login(1, 1, nil, 'password') }
|
179
|
+
assert_equal('username is required', exception.message)
|
180
|
+
|
181
|
+
exception = assert_raise(ArgumentError) { @client.update_login(1, 1, '', 'password') }
|
182
|
+
assert_equal('username is required', exception.message)
|
183
|
+
|
184
|
+
exception = assert_raise(ArgumentError) { @client.update_login(1, 1, 'username', nil) }
|
185
|
+
assert_equal('password is required', exception.message)
|
186
|
+
|
187
|
+
exception = assert_raise(ArgumentError) { @client.update_login(1, 1, 'username', '') }
|
188
|
+
assert_equal('password is required', exception.message)
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
def test_account_confirmation
|
193
|
+
institution_id = '100000'
|
194
|
+
challenge_session_id = '1234'
|
195
|
+
challenge_node_id = '4321'
|
196
|
+
answer = 'answer'
|
197
|
+
parser = Nori.new(:parser => :nokogiri, :strip_namespaces => true, :convert_tags_to => lambda { |tag| tag.snakecase.to_sym })
|
198
|
+
stub_get("/institutions/#{institution_id}").to_return(:body => fixture('institution.xml'), :headers => {:content_type => 'application/xml; charset=utf-8'})
|
199
|
+
stub_post("/institutions/#{institution_id}/logins").to_return(:body => lambda { |request| assert_equal(parser.parse(fixture('challenge.xml').read), parser.parse(request.body)) })
|
200
|
+
@client.account_confirmation(institution_id, challenge_session_id, challenge_node_id, answer)
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_update_login_confirmation
|
204
|
+
login_id = '1234567890'
|
205
|
+
challenge_session_id = '1234'
|
206
|
+
challenge_node_id = '4321'
|
207
|
+
answer = 'answer'
|
208
|
+
validator = lambda do |request|
|
209
|
+
parser = Nori.new(:parser => :nokogiri, :strip_namespaces => true, :convert_tags_to => lambda { |tag| tag.snakecase.to_sym })
|
210
|
+
assert_equal(parser.parse(fixture('challenge.xml').read), parser.parse(request.body))
|
211
|
+
assert_equal(challenge_session_id, request.headers['Challengesessionid'])
|
212
|
+
assert_equal(challenge_node_id, request.headers['Challengenodeid'])
|
213
|
+
end
|
214
|
+
stub_put("/logins/#{login_id}?refresh=true").to_return(:body => validator)
|
215
|
+
@client.update_login_confirmation(login_id, challenge_session_id, challenge_node_id, answer)
|
216
|
+
end
|
217
|
+
|
91
218
|
end
|
data/test/test_helper.rb
CHANGED
@@ -2,12 +2,20 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
2
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
3
|
|
4
4
|
require 'simplecov'
|
5
|
+
require 'coveralls'
|
6
|
+
|
7
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
8
|
+
SimpleCov::Formatter::HTMLFormatter,
|
9
|
+
Coveralls::SimpleCov::Formatter
|
10
|
+
]
|
5
11
|
SimpleCov.start
|
6
12
|
|
7
13
|
require 'webmock/test_unit'
|
8
14
|
require 'test/unit'
|
9
15
|
require 'aggcat'
|
10
16
|
|
17
|
+
WebMock.disable_net_connect!(:allow => 'coveralls.io')
|
18
|
+
|
11
19
|
def stub_delete(path)
|
12
20
|
stub_request(:delete, Aggcat::Client::BASE_URL + path)
|
13
21
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aggcat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: oauth
|
@@ -142,10 +142,12 @@ files:
|
|
142
142
|
- lib/aggcat/client.rb
|
143
143
|
- lib/aggcat/configurable.rb
|
144
144
|
- lib/aggcat/version.rb
|
145
|
+
- test/aggcat/aggcat_test.rb
|
145
146
|
- test/aggcat/client_test.rb
|
146
147
|
- test/fixtures/account.xml
|
147
148
|
- test/fixtures/accounts.xml
|
148
149
|
- test/fixtures/cert.key
|
150
|
+
- test/fixtures/challenge.xml
|
149
151
|
- test/fixtures/institution.xml
|
150
152
|
- test/fixtures/institutions.xml
|
151
153
|
- test/fixtures/login.xml
|
@@ -178,10 +180,12 @@ signing_key:
|
|
178
180
|
specification_version: 3
|
179
181
|
summary: Intuit Customer Account Data API client
|
180
182
|
test_files:
|
183
|
+
- test/aggcat/aggcat_test.rb
|
181
184
|
- test/aggcat/client_test.rb
|
182
185
|
- test/fixtures/account.xml
|
183
186
|
- test/fixtures/accounts.xml
|
184
187
|
- test/fixtures/cert.key
|
188
|
+
- test/fixtures/challenge.xml
|
185
189
|
- test/fixtures/institution.xml
|
186
190
|
- test/fixtures/institutions.xml
|
187
191
|
- test/fixtures/login.xml
|