kdonovan-trufina 0.1.2 → 0.2.0

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/README.rdoc CHANGED
@@ -132,6 +132,11 @@ which is exactly the format Trufina requires to indicate we want to receive the
132
132
  * (Note that Trufina[http://www.trufina.com] itself doesn't support maxAge or timeframe yet)
133
133
  * Setting ResidenceAddress seed data isn't yet supported
134
134
 
135
+ == API Version
136
+
137
+ This is compatible with the latest Trufina API version as of the creation date: Trufina API 1.0.4
138
+
139
+
135
140
  == Compatibility
136
141
 
137
142
  The goal of this module is to be relatively framework agnostic. That being said, I've personally only tried to use it
data/TODO CHANGED
@@ -1,8 +1,5 @@
1
1
  PENDING:
2
2
  * Schema validation against the provided .xsd fails
3
- * Unable to set ResidenceAddress in seed data (e.g. Trufina.login_request(4, :seed => {:residence_address => {:state => 'CA'}}))
4
- Yields error: Attribute 'timeframe' must appear on element 'ResidenceAddress' (noted in README)
5
3
 
6
4
  UNSUPPORTED:
7
- * Setting StreetAddress seed data is unsupported (will generate extra <.> tags, and it is unclear how to set multiple lines)
8
5
  * Comparison or other request attributes (note that maxAge and timeframe are not even supported by Trufina yet)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
data/lib/elements.rb CHANGED
@@ -7,53 +7,61 @@ class Trufina
7
7
  module AllowCreationFromHash
8
8
 
9
9
  def initialize(seed_data = {})
10
- seed_data.is_a?(Array) ? create_empty_nodes(seed_data) : create_nodes(seed_data)
11
- end
10
+ create_nodes(seed_data)
12
11
 
13
- protected
14
-
15
- # e.g. Trufina::Name.new([:first, :suffix]) - no values provided, print empty nodes
16
- #
17
- # <Name>
18
- # <First/>
19
- # <Suffix/>
20
- # </Name>
21
- def create_empty_nodes(nodes)
22
- nodes.each do |node|
23
- create_node(node)
12
+ # Define attributes
13
+ self.class.attributes.each do |attr|
14
+ self.send("#{attr.method_name}=", nil) unless self.send(attr.method_name)
15
+ end
16
+
17
+ # Define elements
18
+ self.class.attributes.each do |elem|
19
+ self.send("#{elem.method_name}=", nil) unless self.send(elem.method_name)
24
20
  end
25
21
  end
26
22
 
27
- # e.g. Trufina::Name.new({:first => 'Bob', :suffix => 'III'}) - print nodes with values
28
- #
29
- # <Name>
30
- # <First>Bob</First>
31
- # <Suffix>III</Suffix>
32
- # </Name>
33
- def create_nodes(nodes)
34
- nodes.each do |node, content|
35
- create_node(node, content)
23
+ protected
24
+
25
+ def create_nodes(data)
26
+ data.each do |key, value|
27
+ create_node(key, value)
36
28
  end
37
29
  end
38
30
 
39
31
  # Handle the actual node creation
40
32
  def create_node(name, content = nil)
33
+ return create_nodes(name) if content.nil? && name.is_a?(Hash) # Handle accidentally passing in a full hash
34
+
35
+ element = self.class.elements.detect{|e| e.method_name.to_sym == name}
36
+ raise Exceptions::InvalidElement.new("No known element named '#{name}'") unless element || self.respond_to?("#{name}=")
37
+
41
38
  case name
42
- when Array then create_empty_nodes(name)
43
39
  when Hash then create_nodes(name)
40
+ when Array then create_empty_nodes(name)
44
41
  else
45
- element = self.class.elements.detect{|e| e.method_name.to_sym == name}
46
- raise Exceptions::InvalidElement.new("No known element named '#{name}'") unless element
47
-
48
- value = if HappyMapper::Item::Types.include?(element.type)
49
- content ? content : ''
50
- else
51
- content ? element.type.new(content) : element.type.new
42
+ value = if content.nil?
43
+ make_object?(element) ? element.type.new : ''
44
+ elsif content.is_a?(Array) && (element && !element.options[:single])
45
+ # If elements expects multiple instances, instantiate them all (e.g. StreetAddresses)
46
+ # Note that this assumes the object (only known case is Trufina::Elements::StreetAddress) has a :name element
47
+ out = content.collect do |local_content|
48
+ make_object?(element) ? element.type.new(:name => local_content) : local_content
49
+ end
50
+ else
51
+ make_object?(element) ? element.type.new(content) : content
52
52
  end
53
+
53
54
  self.send("#{name}=", value)
54
55
  end
55
56
  end
56
57
 
58
+ # Returns false if the given content is a simple type like a string, and we should just assign it.
59
+ # Returns true if the given content is another HappyMapper class, and we should instantiate the class
60
+ # rather than merely assigning the value.
61
+ def make_object?(element)
62
+ element && !HappyMapper::Item::Types.include?(element.type)
63
+ end
64
+
57
65
  end
58
66
 
59
67
  module Elements
@@ -93,29 +101,39 @@ class Trufina
93
101
  element :suffix, String, :tag => 'Suffix', :attributes => RESPONSE_XML_ATTRIBUTES
94
102
  end
95
103
 
96
- # Wrapper attempting to allow access to multiple StreetAddress tags per single ResidenceAddress
97
- class StreetAddress
104
+ # Encapsulates Trufina's address fields - has multiple street address fields
105
+ class ResidenceAddressResponse
98
106
  include AllowCreationFromHash
99
107
  include HappyMapper
100
108
  include EasyElementAccess
101
- tag 'StreetAddress'
102
-
103
- element :name, String, :tag => '.', :attributes => RESPONSE_XML_ATTRIBUTES
104
- end
109
+ tag 'ResidenceAddress'
110
+
111
+ has_many :street_addresses, String, :tag => 'StreetAddress', :attributes => RESPONSE_XML_ATTRIBUTES
112
+ element :city, String, :tag => 'City', :attributes => RESPONSE_XML_ATTRIBUTES
113
+ element :state, String, :tag => 'State', :attributes => RESPONSE_XML_ATTRIBUTES
114
+ element :zip, String, :tag => 'PostalCode', :attributes => RESPONSE_XML_ATTRIBUTES
115
+ attribute :timeframe, String
105
116
 
106
- # Encapsulates Trufina's address fields
107
- class ResidenceAddress
117
+ def street_address=(adr)
118
+ self.street_addresses ||= []
119
+ self.street_addresses << adr
120
+ end
121
+ end
122
+
123
+ # Encapsulates Trufina's address fields - only one street address field
124
+ class ResidenceAddressRequest
108
125
  include AllowCreationFromHash
109
126
  include HappyMapper
110
127
  include EasyElementAccess
111
128
  tag 'ResidenceAddress'
112
129
 
113
- has_many :street_addresses, StreetAddress, :tag => 'StreetAddress', :attributes => RESPONSE_XML_ATTRIBUTES
130
+ element :street_address, String, :tag => 'StreetAddress', :attributes => RESPONSE_XML_ATTRIBUTES
114
131
  element :city, String, :tag => 'City', :attributes => RESPONSE_XML_ATTRIBUTES
115
132
  element :state, String, :tag => 'State', :attributes => RESPONSE_XML_ATTRIBUTES
116
- element :postal_code, String, :tag => 'PostalCode', :attributes => RESPONSE_XML_ATTRIBUTES
133
+ element :zip, String, :tag => 'PostalCode', :attributes => RESPONSE_XML_ATTRIBUTES
117
134
  end
118
135
 
136
+
119
137
  # Encapsulates all response data Trufina may send back
120
138
  class AccessResponseGroup
121
139
  include AllowCreationFromHash
@@ -123,11 +141,11 @@ class Trufina
123
141
  include EasyElementAccess
124
142
  tag 'AccessResponse'
125
143
 
126
- element :name, Name, :single => true, :attributes => RESPONSE_XML_ATTRIBUTES
144
+ element :name, Name, :single => true
127
145
  # element :birth_date, Date, :tag => 'DateOfBirth', :attributes => RESPONSE_XML_ATTRIBUTES
128
146
  # element :birth_country, String, :tag => 'CountryOfBirth', :attributes => RESPONSE_XML_ATTRIBUTES
129
147
  element :phone, String, :tag => 'Phone', :attributes => RESPONSE_XML_ATTRIBUTES
130
- element :residence_address, ResidenceAddress, :single => true, :attributes => RESPONSE_XML_ATTRIBUTES
148
+ element :residence_address, ResidenceAddressResponse, :single => true
131
149
  element :ssn, String, :tag => 'fullSSN', :attributes => RESPONSE_XML_ATTRIBUTES
132
150
  element :last_4_ssn, String, :tag => 'Last4SSN', :attributes => RESPONSE_XML_ATTRIBUTES
133
151
  element :age, String, :tag => 'Age', :attributes => RESPONSE_XML_ATTRIBUTES
@@ -143,7 +161,7 @@ class Trufina
143
161
  element :birth_date, Date, :tag => 'DateOfBirth'
144
162
  element :birth_country, String, :tag => 'CountryOfBirth'
145
163
  element :phone, String, :tag => 'Phone' # If Trufina implemented it, could have timeframe and maxAge attributes
146
- element :residence_address, ResidenceAddress, :single => true # If Trufina implemented it, could have timeframe and maxAge attributes
164
+ element :residence_address, ResidenceAddressRequest, :single => true # If Trufina implemented it, could have timeframe and maxAge attributes
147
165
  element :ssn, String, :tag => 'fullSSN'
148
166
  element :last_4_ssn, String, :tag => 'Last4SSN'
149
167
  element :age, String, :tag => 'Age', :attributes => {:comparison => String}
@@ -156,15 +174,14 @@ class Trufina
156
174
  tag 'SeedInfo'
157
175
 
158
176
  element :name, Name, :single => true
159
- element :email, String, :single => true
160
177
  element :birth_date, Date, :tag => 'DateOfBirth'
161
178
  element :birth_country, String, :tag => 'CountryOfBirth'
162
179
  element :phone, String, :tag => 'Phone'
163
- element :residence_address, ResidenceAddress, :single => true
180
+ element :residence_address, ResidenceAddressResponse, :single => true
164
181
  element :ssn, String, :tag => 'fullSSN'
165
182
  element :last_4_ssn, String, :tag => 'Last4SSN'
166
183
  element :age, String, :tag => 'Age'
167
184
  end
168
185
 
169
186
  end
170
- end
187
+ end
data/lib/requests.rb CHANGED
@@ -126,6 +126,13 @@ class Trufina
126
126
 
127
127
  element :data, Elements::AccessRequest, :single => true
128
128
  element :seed, Elements::SeedInfoGroup, :single => true
129
+
130
+ def initialize *args
131
+ super(args)
132
+
133
+ # Trufina is brilliant, and they fail if this isn't in the request (even though they don't actually read the value)
134
+ seed.residence_address.timeframe = 'current'
135
+ end
129
136
  end
130
137
 
131
138
  end
data/lib/trufina.rb CHANGED
@@ -20,8 +20,7 @@ class Trufina
20
20
  # * seed -- Hash of seed data used to prefill the user's forms at Trufina's website
21
21
  def login_request(prt, opts = {})
22
22
  opts[:requested] ||= {:name => [:first, :last]}
23
- opts[:seed]
24
- xml = Requests::LoginRequest.new(:prt => prt, :data => opts[:requested], :seed => opts[:seed]).render
23
+ xml = Requests::LoginRequest.new(:prt => prt, :data => opts[:requested], :seed => remove_empties_from_hash(opts[:seed] || [])).render
25
24
  sendToTrufina(xml)
26
25
  end
27
26
 
@@ -137,5 +136,16 @@ class Trufina
137
136
  "http://#{domain}#{path}"
138
137
  end
139
138
 
139
+ # Removes any hash keys with empty values - seed data can't have any blanks, or Trufina gets mad
140
+ def remove_empties_from_hash(old_hash)
141
+ new_hash = {}
142
+ old_hash.each do |key, value|
143
+ next if value.nil? || value == '' || value == [] || value == {}
144
+ new_hash[key] = value.is_a?(Hash) ? remove_empties_from_hash(value) : value
145
+ end
146
+
147
+ return new_hash
148
+ end
149
+
140
150
  end
141
151
  end
data/trufina.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{trufina}
8
- s.version = "0.1.2"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kali Donovan"]
12
- s.date = %q{2009-09-03}
12
+ s.date = %q{2009-09-04}
13
13
  s.description = %q{Provides a DSL to easily interact with the XML API offered by Trufina.com, an identity verification company.}
14
14
  s.email = %q{kali.donovan@gmail.com}
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kdonovan-trufina
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kali Donovan
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-03 00:00:00 -07:00
12
+ date: 2009-09-04 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -63,6 +63,7 @@ files:
63
63
  - trufina.yml.template
64
64
  has_rdoc: false
65
65
  homepage: http://github.com/kdonovan/trufina
66
+ licenses:
66
67
  post_install_message:
67
68
  rdoc_options:
68
69
  - --charset=UTF-8
@@ -83,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
84
  requirements: []
84
85
 
85
86
  rubyforge_project:
86
- rubygems_version: 1.2.0
87
+ rubygems_version: 1.3.5
87
88
  signing_key:
88
89
  specification_version: 3
89
90
  summary: DSL to easily interact with Trufina's verification API