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 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