lexer-identity 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a395e6932b3a744d3a9e85f22a14842139afa5dd
4
- data.tar.gz: c1772af7cfaae2a992d2ddbc599edd3481913d70
3
+ metadata.gz: 4aa1b95c2239425aa1f672b4bf0c01b71d95c508
4
+ data.tar.gz: e6403c66dc95167a3bf47effe0010fd16809ac4b
5
5
  SHA512:
6
- metadata.gz: dfd879f57b3a28d98d54033966dc35f6089a5df8d08f11935d78c1d6dbbb8fffa64cd27a2f4ad7d51a7092277129a36432bc4cf5773727d8ebb84755bf0c2ab4
7
- data.tar.gz: 13284a564344bfc9220ec37a9d048d3f59b84761674bc8086858b9be3150dc5c42ce3588b0d5bc786019227b86d65208695e310e2523124ee1ebf07d5050399c
6
+ metadata.gz: 08ffdfa2c86c03f7a306f534dfea816ab4652d3bbe51c001c457dbe76a0f9da79a69aabe3171688f1d7adaa0436287275fc1f5677c371bc3ba4078bb7cafa753
7
+ data.tar.gz: b376a1ab3a4d4e661a826cc350e4da0cc7d2d201f77a356d99dc5ea54f2d6d8b8f7275df178cfdfe0043a0d2a1f2c85af4df9d563a9523f196b1bbb644028655
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Lexer Identities Official Ruby Client Library
2
2
 
3
- [![Build Status](https://travis-ci.org/lexerdev/lexer-identity-gem.svg)](http://travis-ci.org/lexerdev/lexer-identity-gem)
4
- [![Code Climate](https://codeclimate.com/github/lexerdev/lexer-identity-gem/badges/gpa.svg)](https://codeclimate.com/github/lexerdev/lexer-identity-gem)
3
+ [![Build Status](https://travis-ci.org/lexerdev/identity-gem.svg)](http://travis-ci.org/lexerdev/identity-gem)
4
+ [![Code Climate](https://codeclimate.com/github/lexerdev/identity-gem/badges/gpa.svg)](https://codeclimate.com/github/lexerdev/identity-gem)
5
5
 
6
- lexer-identity-gem is the official Ruby Client for the [Lexer Identity](https://lexer.io/) API. The
6
+ Lexer Identity Gem is the official Ruby Client for the [Lexer Identity](https://lexer.io/) API. The
7
7
  Lexer Identity API lets brands contribute and consume from Lexer's Identity database directly from their apps.
8
8
 
9
9
  ## Installation
data/Rakefile CHANGED
@@ -8,4 +8,4 @@ Rake::TestTask.new do |t|
8
8
  t.libs.push 'spec'
9
9
  end
10
10
 
11
- task :default => [:test]
11
+ task default: [:test]
@@ -5,28 +5,51 @@ require 'multi_json'
5
5
  module Lexer
6
6
  # :nordoc:
7
7
  module Identity
8
+ # Constants for attribute confidence
9
+ CONFIDENCE_PROVIDED = 2
10
+ CONFIDENCE_CALCULATED = 1
11
+ CONFIDENCE_INFERRED = 0
12
+
8
13
  # The backbone of the Identity API.
9
14
  # Enrich accepts links and attributes as per the
10
15
  # API Documentation hosted at http://developer.lexer.io/
11
16
  #
12
17
  # Options:
13
18
  #
19
+ # +id+ - A string of the Lexer Identity ID to lookup
14
20
  # +links+ - A hash of links to search for and link to the identity. Default: {}.
15
21
  # +attributes+ - A hash of attributes where keys are valid namespaces. Default: {}.
16
22
  #
23
+ # An +id+ or +links+ is required for a valid request.
24
+ #
17
25
  # Response:
18
26
  #
19
27
  # A hash containing the Lexer Identity ID and any attributes on the identity
20
28
  #
21
- def self.enrich(links: {}, attributes: {})
29
+ def self.enrich(id: nil, links: {}, attributes: {})
30
+ body = {}
31
+
22
32
  # ensure the module is configured
23
33
  fail Lexer::Identity::ConfigurationError, 'Module has not been configured.' if configuration.nil?
24
34
  configuration.validate
25
35
 
26
- # produce the request body
27
- body = {}
28
- body[:links] = links
29
- body[:attributes] = attributes unless configuration.contributor_token.nil?
36
+ # use the id if provided
37
+ if id.nil?
38
+ if links.keys.size == 0
39
+ fail Lexer::Identity::MissingLinksError, 'An ID or Link is required'
40
+ else
41
+ body[:links] = links
42
+ end
43
+ else
44
+ body[:id] = id
45
+ end
46
+
47
+ # only include attributes if contributing
48
+ if !configuration.contributor_token.nil? && attributes.keys.size > 0
49
+ self.validate_attributes attributes
50
+ body[:attributes] = attributes
51
+ end
52
+
30
53
  body[:api_token] = configuration.api_token unless configuration.api_token.nil?
31
54
  body[:contributor_token] = configuration.contributor_token unless configuration.contributor_token.nil?
32
55
  body[:consumer_token] = configuration.consumer_token unless configuration.consumer_token.nil?
@@ -36,6 +59,17 @@ module Lexer
36
59
 
37
60
  private
38
61
 
62
+ def self.validate_attributes attributes
63
+ attributes.each { |k, v|
64
+ unless v.is_a? Hash
65
+ fail Lexer::Identity::AttributePayloadError, "#{k} is not a hash"
66
+ end
67
+ unless v.has_key?(:value) && v.has_key?(:confidence)
68
+ fail Lexer::Identity::AttributePayloadError, "#{k} has an invalid payload"
69
+ end
70
+ }
71
+ end
72
+
39
73
  def self.post_request(body)
40
74
  uri = URI(configuration.api_url)
41
75
  header = { 'Content-Type' => 'application/json' }
@@ -55,13 +89,13 @@ module Lexer
55
89
  when 200..204
56
90
  Lexer::Identity::EnrichedResult.from_json response.body
57
91
  when 400
58
- fail Lexer::Identity::BadRequestError, response_body
92
+ fail Lexer::Identity::BadRequestError, response.body
59
93
  when 401
60
- fail Lexer::Identity::AuthenticationError, response_body
94
+ fail Lexer::Identity::AuthenticationError, response.body
61
95
  when 404
62
- fail Lexer::Identity::NotFoundError, response_body
96
+ fail Lexer::Identity::NotFoundError, response.body
63
97
  else
64
- fail Lexer::Identity::HttpError, response_body
98
+ fail Lexer::Identity::HttpError, response.body
65
99
  end
66
100
  end
67
101
  end
@@ -4,6 +4,6 @@
4
4
  module Lexer
5
5
  # :nordoc:
6
6
  module Identity
7
- VERSION = '0.1.0'
7
+ VERSION = '0.2.0'
8
8
  end
9
9
  end
@@ -22,7 +22,7 @@ module Lexer
22
22
  # config.consumer_token = "..."
23
23
  # end
24
24
  #
25
- # Lexer::Identity.enrich( links: { email: "...", ... }, attributes: { "com.mybrand.name": "...", ... } )
25
+ # Lexer::Identity.enrich( id: "...", links: { email: "...", ... }, attributes: { "com.mybrand.name": "...", ... } )
26
26
  #
27
27
  # See the +Lexer::Identity.enrich+ documentation for more details.
28
28
  module Identity
@@ -44,6 +44,12 @@ module Lexer
44
44
  # Will be thrown when there is an error with the Module's configuration
45
45
  class ConfigurationError < Error; end
46
46
 
47
+ # Thrown when the attribute payload is not valid
48
+ class AttributePayloadError < Error; end
49
+
50
+ # Thrown when a request does not contain an ID or Link
51
+ class MissingLinksError < Error; end
52
+
47
53
  # Will be thrown when there is an error communicating with the API
48
54
  # Also inherited by other errors
49
55
  class HttpError < Error; end
@@ -2,43 +2,149 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  describe Lexer::Identity do
5
- describe 'contributions' do
5
+ describe 'constants' do
6
+ it 'has required constants' do
7
+ Lexer::Identity::CONFIDENCE_PROVIDED.wont_be_nil
8
+ Lexer::Identity::CONFIDENCE_CALCULATED.wont_be_nil
9
+ Lexer::Identity::CONFIDENCE_INFERRED.wont_be_nil
10
+ end
11
+ end
12
+
13
+ describe 'use of links and ids' do
6
14
  before do
7
15
  Lexer::Identity.configuration = nil
8
16
  Lexer::Identity.configure do |config|
9
17
  config.api_token = 'abc-123'
10
18
  config.contributor_token = 'bcd-234'
19
+ config.consumer_token = 'cde-345'
11
20
  end
12
21
  end
13
- it 'produces a valid request' do
22
+ it 'requires either a link or id' do
23
+ proc do
24
+ Lexer::Identity.enrich
25
+ end.must_raise Lexer::Identity::MissingLinksError
26
+ end
27
+ it 'requires at least one link' do
28
+ proc do
29
+ Lexer::Identity.enrich(
30
+ links: {}
31
+ )
32
+ end.must_raise Lexer::Identity::MissingLinksError
33
+ end
34
+ it 'produces a valid request with links' do
14
35
  stub_request(:post, 'https://identity.lexer.io/identity').
15
- with(body: '{"links":{"email":["user1@brand.com","usera@brand.com"],"mobile":"61440000000"},"attributes":{"com.brand.car":"Tesla","com.brand.code":10,"com.brand.products":["a","b","c"],"com.brand.detail":{"make":"cake"}},"api_token":"abc-123","contributor_token":"bcd-234"}', headers: { 'Content-Type' => 'application/json' }).
36
+ with(body: '{"links":{"email":["user1@brand.com","usera@brand.com"],"mobile":"61440000000"},"api_token":"abc-123","contributor_token":"bcd-234","consumer_token":"cde-345"}', headers: { 'Content-Type' => 'application/json' }).
16
37
  to_return(status: 200, body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04"}')
17
38
 
18
39
  Lexer::Identity.enrich(
19
40
  links: {
20
41
  email: %w(user1@brand.com usera@brand.com),
21
42
  mobile: '61440000000'
22
- }, attributes: {
23
- 'com.brand.car' => 'Tesla',
24
- 'com.brand.code' => 10,
25
- 'com.brand.products' => %w(a b c),
26
- 'com.brand.detail' => { make: 'cake' }
27
43
  }
28
44
  )
29
45
 
30
46
  assert_requested(:post, 'https://identity.lexer.io/identity', times: 1)
31
47
  end
48
+ it 'produces a valid request with an ID' do
49
+ stub_request(:post, 'https://identity.lexer.io/identity').
50
+ with(body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04","api_token":"abc-123","contributor_token":"bcd-234","consumer_token":"cde-345"}', headers: { 'Content-Type' => 'application/json' }).
51
+ to_return(status: 200, body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04"}')
52
+
53
+ Lexer::Identity.enrich(
54
+ id: '0a224111-ac64-4142-9198-adf8bf2c1a04'
55
+ )
56
+
57
+ assert_requested(:post, 'https://identity.lexer.io/identity', times: 1)
58
+ end
59
+ it 'ignores links when an ID is present' do
60
+ stub_request(:post, 'https://identity.lexer.io/identity').
61
+ with(body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04","api_token":"abc-123","contributor_token":"bcd-234","consumer_token":"cde-345"}', headers: { 'Content-Type' => 'application/json' }).
62
+ to_return(status: 200, body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04"}')
63
+
64
+ Lexer::Identity.enrich(
65
+ id: '0a224111-ac64-4142-9198-adf8bf2c1a04',
66
+ links: {
67
+ email: %w(user1@brand.com usera@brand.com),
68
+ mobile: '61440000000'
69
+ }
70
+ )
71
+
72
+ assert_requested(:post, 'https://identity.lexer.io/identity', times: 1)
73
+ end
74
+ end
75
+
76
+ describe 'contributions' do
77
+ before do
78
+ Lexer::Identity.configuration = nil
79
+ Lexer::Identity.configure do |config|
80
+ config.api_token = 'abc-123'
81
+ config.contributor_token = 'bcd-234'
82
+ end
83
+ end
84
+ describe 'attribute payloads' do
85
+ it 'requires a complete payload' do
86
+ proc do
87
+ Lexer::Identity.enrich(
88
+ id: 'abc-123',
89
+ attributes: {
90
+ 'com.brand.car' => 'Tesla'
91
+ }
92
+ )
93
+ end.must_raise Lexer::Identity::AttributePayloadError
94
+
95
+ proc do
96
+ Lexer::Identity.enrich(
97
+ id: 'abc-123',
98
+ attributes: {
99
+ 'com.brand.car' => {
100
+ value: 'attribute value'
101
+ }
102
+ }
103
+ )
104
+ end.must_raise Lexer::Identity::AttributePayloadError
105
+
106
+ proc do
107
+ Lexer::Identity.enrich(
108
+ id: 'abc-123',
109
+ attributes: {
110
+ 'com.brand.car' => {
111
+ confidence: Lexer::Identity::CONFIDENCE_PROVIDED
112
+ }
113
+ }
114
+ )
115
+ end.must_raise Lexer::Identity::AttributePayloadError
116
+ end
117
+ it 'allows a complete payload' do
118
+ stub_request(:post, 'https://identity.lexer.io/identity').
119
+ with(body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04","attributes":{"com.brand.car":{"value":"Tesla","confidence":2}},"api_token":"abc-123","contributor_token":"bcd-234"}', headers: { 'Content-Type' => 'application/json' }).
120
+ to_return(status: 200, body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04"}')
121
+
122
+ Lexer::Identity.enrich(
123
+ id: '0a224111-ac64-4142-9198-adf8bf2c1a04',
124
+ attributes: {
125
+ 'com.brand.car' => {
126
+ value: 'Tesla',
127
+ confidence: Lexer::Identity::CONFIDENCE_PROVIDED
128
+ }
129
+ }
130
+ )
131
+
132
+ assert_requested(:post, 'https://identity.lexer.io/identity', times: 1)
133
+ end
134
+ end
32
135
  it 'returns an EnrichedResult' do
33
136
  stub_request(:post, 'https://identity.lexer.io/identity').
34
- with(body: '{"links":{"email":"user1@brand.com"},"attributes":{"com.brand.car":"Tesla"},"api_token":"abc-123","contributor_token":"bcd-234"}', headers: { 'Content-Type' => 'application/json' }).
137
+ with(body: '{"links":{"email":"user1@brand.com"},"attributes":{"com.brand.car":{"value":"Tesla","confidence":2}},"api_token":"abc-123","contributor_token":"bcd-234"}', headers: { 'Content-Type' => 'application/json' }).
35
138
  to_return(status: 200, body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04"}')
36
139
 
37
140
  result = Lexer::Identity.enrich(
38
141
  links: {
39
142
  email: 'user1@brand.com'
40
143
  }, attributes: {
41
- 'com.brand.car' => 'Tesla'
144
+ 'com.brand.car' => {
145
+ value: 'Tesla',
146
+ confidence: Lexer::Identity::CONFIDENCE_PROVIDED
147
+ }
42
148
  }
43
149
  )
44
150
 
@@ -59,14 +165,17 @@ describe Lexer::Identity do
59
165
  it 'produces a valid request' do
60
166
  stub_request(:post, 'https://identity.lexer.io/identity').
61
167
  with(body: '{"links":{"email":["user1@brand.com","usera@brand.com"],"mobile":"61440000000"},"api_token":"abc-123","consumer_token":"bcd-234"}', headers: { 'Content-Type' => 'application/json' }).
62
- to_return(status: 200, body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04","attributes":{"com.brand.car":"Tesla","com.brand.code":10,"com.brand.products":["a","b","c"],"com.brand.detail":{"make":"cake"}}}')
168
+ to_return(status: 200, body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04","attributes":{"com.brand.car":{"value":"Tesla","confidence":2},"com.brand.code":{"value":10,"confidence":2},"com.brand.products":{"value":["a","b","c"],"confidence":1},"com.brand.detail":{"value":{"make":"cake"},"confidence":0}}}')
63
169
 
64
170
  Lexer::Identity.enrich(
65
171
  links: {
66
172
  email: %w(user1@brand.com usera@brand.com),
67
173
  mobile: '61440000000'
68
174
  }, attributes: {
69
- 'com.brand.car' => 'Tesla' # note: this will be discarded as consumers can't contribute
175
+ 'com.brand.car' => {
176
+ value: 'Tesla',
177
+ confidence: Lexer::Identity::CONFIDENCE_PROVIDED
178
+ }
70
179
  }
71
180
  )
72
181
 
@@ -75,20 +184,40 @@ describe Lexer::Identity do
75
184
  it 'returns an EnrichedResult' do
76
185
  stub_request(:post, 'https://identity.lexer.io/identity').
77
186
  with(body: '{"links":{"email":["user1@brand.com","usera@brand.com"],"mobile":"61440000000"},"api_token":"abc-123","consumer_token":"bcd-234"}', headers: { 'Content-Type' => 'application/json' }).
78
- to_return(status: 200, body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04","attributes":{"com.brand.car":"Tesla","com.brand.code":10,"com.brand.products":["a","b","c"],"com.brand.detail":{"make":"cake"}}}')
187
+ to_return(status: 200, body: '{"id":"0a224111-ac64-4142-9198-adf8bf2c1a04","attributes":{"com.brand.car":{"value":"Tesla","confidence":2},"com.brand.code":{"value":10,"confidence":2},"com.brand.products":{"value":["a","b","c"],"confidence":1},"com.brand.detail":{"value":{"make":"cake"},"confidence":0}}}')
79
188
 
80
189
  result = Lexer::Identity.enrich(
81
190
  links: {
82
191
  email: %w(user1@brand.com usera@brand.com),
83
192
  mobile: '61440000000'
84
193
  }, attributes: {
85
- 'com.brand.car' => 'Tesla' # note: this will be discarded as consumers can't contribute
194
+ 'com.brand.car' => {
195
+ value: 'Tesla',
196
+ confidence: Lexer::Identity::CONFIDENCE_PROVIDED
197
+ }
86
198
  }
87
199
  )
88
200
 
89
201
  result.must_be_instance_of Lexer::Identity::EnrichedResult
90
202
  result.id.must_be_kind_of String
91
- hash = { 'com.brand.car' => 'Tesla', 'com.brand.code' => 10, 'com.brand.products' => %w(a b c), 'com.brand.detail' => { 'make' => 'cake' } }
203
+ hash = {
204
+ 'com.brand.car' => {
205
+ 'value' => 'Tesla',
206
+ 'confidence' => 2
207
+ },
208
+ 'com.brand.code' => {
209
+ 'value' => 10,
210
+ 'confidence' => 2
211
+ },
212
+ 'com.brand.products' => {
213
+ 'value' => %w(a b c),
214
+ 'confidence' => 1
215
+ },
216
+ 'com.brand.detail' => {
217
+ 'value' => { 'make' => 'cake' },
218
+ 'confidence' => 0
219
+ }
220
+ }
92
221
  result.attributes.must_equal hash
93
222
  end
94
223
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lexer-identity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Wallis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-07 00:00:00.000000000 Z
11
+ date: 2015-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json