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 +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
|
-
[![Build Status](https://travis-ci.org/lexerdev/
|
4
|
-
[![Code Climate](https://codeclimate.com/github/lexerdev/
|
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
|
-
|
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
|