lexer-identity 0.1.0 → 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.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/Rakefile +1 -1
- data/lib/lexer/identity/api.rb +43 -9
- data/lib/lexer/identity/version.rb +1 -1
- data/lib/lexer/identity.rb +7 -1
- data/spec/lexer/identity/api_spec.rb +144 -15
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4aa1b95c2239425aa1f672b4bf0c01b71d95c508
|
4
|
+
data.tar.gz: e6403c66dc95167a3bf47effe0010fd16809ac4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
[](http://travis-ci.org/lexerdev/identity-gem)
|
4
|
+
[](https://codeclimate.com/github/lexerdev/identity-gem)
|
5
5
|
|
6
|
-
|
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
data/lib/lexer/identity/api.rb
CHANGED
@@ -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
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
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,
|
92
|
+
fail Lexer::Identity::BadRequestError, response.body
|
59
93
|
when 401
|
60
|
-
fail Lexer::Identity::AuthenticationError,
|
94
|
+
fail Lexer::Identity::AuthenticationError, response.body
|
61
95
|
when 404
|
62
|
-
fail Lexer::Identity::NotFoundError,
|
96
|
+
fail Lexer::Identity::NotFoundError, response.body
|
63
97
|
else
|
64
|
-
fail Lexer::Identity::HttpError,
|
98
|
+
fail Lexer::Identity::HttpError, response.body
|
65
99
|
end
|
66
100
|
end
|
67
101
|
end
|
data/lib/lexer/identity.rb
CHANGED
@@ -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 '
|
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 '
|
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"},"
|
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' =>
|
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' =>
|
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' =>
|
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 = {
|
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.
|
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-
|
11
|
+
date: 2015-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|