linkedin-drspin 0.3.6
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/.autotest +14 -0
- data/.document +5 -0
- data/.gemtest +0 -0
- data/.gitignore +41 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +7 -0
- data/LICENSE +20 -0
- data/README.markdown +78 -0
- data/Rakefile +19 -0
- data/changelog.markdown +71 -0
- data/examples/authenticate.rb +21 -0
- data/examples/network.rb +12 -0
- data/examples/profile.rb +18 -0
- data/examples/sinatra.rb +77 -0
- data/examples/status.rb +6 -0
- data/lib/linked_in/api.rb +11 -0
- data/lib/linked_in/api/comment_methods.rb +33 -0
- data/lib/linked_in/api/company_search_methods.rb +65 -0
- data/lib/linked_in/api/group_methods.rb +18 -0
- data/lib/linked_in/api/people_search_methods.rb +112 -0
- data/lib/linked_in/api/post_methods.rb +33 -0
- data/lib/linked_in/api/query_methods.rb +81 -0
- data/lib/linked_in/api/update_methods.rb +55 -0
- data/lib/linked_in/client.rb +51 -0
- data/lib/linked_in/errors.rb +19 -0
- data/lib/linked_in/helpers.rb +6 -0
- data/lib/linked_in/helpers/authorization.rb +68 -0
- data/lib/linked_in/helpers/request.rb +80 -0
- data/lib/linked_in/mash.rb +68 -0
- data/lib/linked_in/search.rb +56 -0
- data/lib/linked_in/version.rb +11 -0
- data/lib/linkedin.rb +32 -0
- data/linkedin.gemspec +25 -0
- data/spec/cases/api_spec.rb +92 -0
- data/spec/cases/linkedin_spec.rb +37 -0
- data/spec/cases/mash_spec.rb +85 -0
- data/spec/cases/oauth_spec.rb +166 -0
- data/spec/cases/search_spec.rb +206 -0
- data/spec/fixtures/cassette_library/LinkedIn_Api/Company_API.yml +73 -0
- data/spec/fixtures/cassette_library/LinkedIn_Client/_authorize_from_request.yml +28 -0
- data/spec/fixtures/cassette_library/LinkedIn_Client/_request_token.yml +28 -0
- data/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_a_callback_url.yml +28 -0
- data/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_default_options.yml +28 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_company_name_option.yml +135 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options.yml +122 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options_with_fields.yml +72 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_keywords_string_parameter.yml +136 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option.yml +136 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option_with_pagination.yml +128 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_options_with_fields.yml +252 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_string_parameter.yml +73 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option.yml +71 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_a_facet.yml +111 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_facets_to_return.yml +71 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_pagination.yml +66 -0
- data/spec/helper.rb +30 -0
- metadata +237 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
module Helpers
|
3
|
+
|
4
|
+
module Authorization
|
5
|
+
|
6
|
+
DEFAULT_OAUTH_OPTIONS = {
|
7
|
+
:request_token_path => "/uas/oauth/requestToken",
|
8
|
+
:access_token_path => "/uas/oauth/accessToken",
|
9
|
+
:authorize_path => "/uas/oauth/authorize",
|
10
|
+
:api_host => "https://api.linkedin.com",
|
11
|
+
:auth_host => "https://www.linkedin.com"
|
12
|
+
}
|
13
|
+
|
14
|
+
def consumer
|
15
|
+
@consumer ||= ::OAuth::Consumer.new(@consumer_token, @consumer_secret, parse_oauth_options)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Note: If using oauth with a web app, be sure to provide :oauth_callback.
|
19
|
+
# Options:
|
20
|
+
# :oauth_callback => String, url that LinkedIn should redirect to
|
21
|
+
def request_token(options={})
|
22
|
+
@request_token ||= consumer.get_request_token(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
# For web apps use params[:oauth_verifier], for desktop apps,
|
26
|
+
# use the verifier is the pin that LinkedIn gives users.
|
27
|
+
def authorize_from_request(request_token, request_secret, verifier_or_pin)
|
28
|
+
request_token = ::OAuth::RequestToken.new(consumer, request_token, request_secret)
|
29
|
+
access_token = request_token.get_access_token(:oauth_verifier => verifier_or_pin)
|
30
|
+
@auth_token, @auth_secret = access_token.token, access_token.secret
|
31
|
+
end
|
32
|
+
|
33
|
+
def access_token
|
34
|
+
@access_token ||= ::OAuth::AccessToken.new(consumer, @auth_token, @auth_secret)
|
35
|
+
end
|
36
|
+
|
37
|
+
def authorize_from_access(atoken, asecret)
|
38
|
+
@auth_token, @auth_secret = atoken, asecret
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# since LinkedIn uses api.linkedin.com for request and access token exchanges,
|
44
|
+
# but www.linkedin.com for authorize/authenticate, we have to take care
|
45
|
+
# of the url creation ourselves.
|
46
|
+
def parse_oauth_options
|
47
|
+
{
|
48
|
+
:request_token_url => full_oauth_url_for(:request_token, :api_host),
|
49
|
+
:access_token_url => full_oauth_url_for(:access_token, :api_host),
|
50
|
+
:authorize_url => full_oauth_url_for(:authorize, :auth_host),
|
51
|
+
:site => @consumer_options[:site] || @consumer_options[:api_host] || DEFAULT_OAUTH_OPTIONS[:api_host]
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def full_oauth_url_for(url_type, host_type)
|
56
|
+
if @consumer_options["#{url_type}_url".to_sym]
|
57
|
+
@consumer_options["#{url_type}_url".to_sym]
|
58
|
+
else
|
59
|
+
host = @consumer_options[:site] || @consumer_options[host_type] || DEFAULT_OAUTH_OPTIONS[host_type]
|
60
|
+
path = @consumer_options[:"#{url_type}_path".to_sym] || DEFAULT_OAUTH_OPTIONS["#{url_type}_path".to_sym]
|
61
|
+
"#{host}#{path}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
module Helpers
|
3
|
+
|
4
|
+
module Request
|
5
|
+
|
6
|
+
DEFAULT_HEADERS = {
|
7
|
+
'x-li-format' => 'json'
|
8
|
+
}
|
9
|
+
|
10
|
+
API_PATH = '/v1'
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def get(path, options={})
|
15
|
+
response = access_token.get("#{API_PATH}#{path}", DEFAULT_HEADERS.merge(options))
|
16
|
+
raise_errors(response)
|
17
|
+
response.body
|
18
|
+
end
|
19
|
+
|
20
|
+
def post(path, body='', options={})
|
21
|
+
response = access_token.post("#{API_PATH}#{path}", body, DEFAULT_HEADERS.merge(options))
|
22
|
+
raise_errors(response)
|
23
|
+
response
|
24
|
+
end
|
25
|
+
|
26
|
+
def put(path, body, options={})
|
27
|
+
response = access_token.put("#{API_PATH}#{path}", body, DEFAULT_HEADERS.merge(options))
|
28
|
+
raise_errors(response)
|
29
|
+
response
|
30
|
+
end
|
31
|
+
|
32
|
+
def delete(path, options={})
|
33
|
+
response = access_token.delete("#{API_PATH}#{path}", DEFAULT_HEADERS.merge(options))
|
34
|
+
raise_errors(response)
|
35
|
+
response
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def raise_errors(response)
|
41
|
+
# Even if the json answer contains the HTTP status code, LinkedIn also sets this code
|
42
|
+
# in the HTTP answer (thankfully).
|
43
|
+
case response.code.to_i
|
44
|
+
when 401
|
45
|
+
data = Mash.from_json(response.body)
|
46
|
+
raise LinkedIn::Errors::UnauthorizedError.new(data), "(#{data.status}): #{data.message}"
|
47
|
+
when 400
|
48
|
+
data = Mash.from_json(response.body)
|
49
|
+
raise LinkedIn::Errors::GeneralError.new(data), "(#{data.status}): #{data.message}"
|
50
|
+
when 403
|
51
|
+
data = Mash.from_json(response.body)
|
52
|
+
raise LinkedIn::Errors::AccessDeniedError.new(data), "(#{data.status}): #{data.message}"
|
53
|
+
when 404
|
54
|
+
raise LinkedIn::Errors::NotFoundError, "(#{response.code}): #{response.message}"
|
55
|
+
when 500
|
56
|
+
raise LinkedIn::Errors::InformLinkedInError, "LinkedIn had an internal error. Please let them know in the forum. (#{response.code}): #{response.message}"
|
57
|
+
when 502..503
|
58
|
+
raise LinkedIn::Errors::UnavailableError, "(#{response.code}): #{response.message}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_query(options)
|
63
|
+
options.inject([]) do |collection, opt|
|
64
|
+
collection << "#{opt[0]}=#{opt[1]}"
|
65
|
+
collection
|
66
|
+
end * '&'
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_uri(path, options)
|
70
|
+
uri = URI.parse(path)
|
71
|
+
|
72
|
+
if options && options != {}
|
73
|
+
uri.query = to_query(options)
|
74
|
+
end
|
75
|
+
uri.to_s
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
module LinkedIn
|
5
|
+
class Mash < ::Hashie::Mash
|
6
|
+
|
7
|
+
# a simple helper to convert a json string to a Mash
|
8
|
+
def self.from_json(json_string)
|
9
|
+
result_hash = ::MultiJson.decode(json_string)
|
10
|
+
new(result_hash)
|
11
|
+
end
|
12
|
+
|
13
|
+
# returns a Date if we have year, month and day, and no conflicting key
|
14
|
+
def to_date
|
15
|
+
if !self.has_key?('to_date') && contains_date_fields?
|
16
|
+
Date.civil(self.year, self.month, self.day)
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def timestamp
|
23
|
+
value = self['timestamp']
|
24
|
+
if value.kind_of? Integer
|
25
|
+
value = value / 1000 if value > 9999999999
|
26
|
+
Time.at(value)
|
27
|
+
else
|
28
|
+
value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def contains_date_fields?
|
35
|
+
self.year? && self.month? && self.day?
|
36
|
+
end
|
37
|
+
|
38
|
+
# overload the convert_key mash method so that the LinkedIn
|
39
|
+
# keys are made a little more ruby-ish
|
40
|
+
def convert_key(key)
|
41
|
+
case key.to_s
|
42
|
+
when '_key'
|
43
|
+
'id'
|
44
|
+
when '_total'
|
45
|
+
'total'
|
46
|
+
when 'values'
|
47
|
+
'all'
|
48
|
+
when 'numResults'
|
49
|
+
'total_results'
|
50
|
+
else
|
51
|
+
underscore(key)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# borrowed from ActiveSupport
|
56
|
+
# no need require an entire lib when we only need one method
|
57
|
+
def underscore(camel_cased_word)
|
58
|
+
word = camel_cased_word.to_s.dup
|
59
|
+
word.gsub!(/::/, '/')
|
60
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
61
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
62
|
+
word.tr!("-", "_")
|
63
|
+
word.downcase!
|
64
|
+
word
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
|
3
|
+
module Search
|
4
|
+
def search(options={}, type='people')
|
5
|
+
|
6
|
+
path = "/#{type.to_s}-search"
|
7
|
+
|
8
|
+
if options.is_a?(Hash)
|
9
|
+
fields = options.delete(:fields)
|
10
|
+
path += field_selector(fields) if fields
|
11
|
+
end
|
12
|
+
|
13
|
+
options = { :keywords => options } if options.is_a?(String)
|
14
|
+
options = format_options_for_query(options)
|
15
|
+
|
16
|
+
result_json = get(to_uri(path, options))
|
17
|
+
|
18
|
+
Mash.from_json(result_json)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def format_options_for_query(opts)
|
24
|
+
opts.inject({}) do |list, kv|
|
25
|
+
key, value = kv.first.to_s.gsub("_","-"), kv.last
|
26
|
+
list[key] = sanitize_value(value)
|
27
|
+
list
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def sanitize_value(value)
|
32
|
+
value = value.join("+") if value.is_a?(Array)
|
33
|
+
value = value.gsub(" ", "+") if value.is_a?(String)
|
34
|
+
value
|
35
|
+
end
|
36
|
+
|
37
|
+
def field_selector(fields)
|
38
|
+
result = ":("
|
39
|
+
fields = fields.to_a.map do |field|
|
40
|
+
if field.is_a?(Hash)
|
41
|
+
innerFields = []
|
42
|
+
field.each do |key, value|
|
43
|
+
innerFields << key.to_s.gsub("_","-") + field_selector(value)
|
44
|
+
end
|
45
|
+
innerFields.join(',')
|
46
|
+
else
|
47
|
+
field.to_s.gsub("_","-")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
result += fields.join(',')
|
51
|
+
result += ")"
|
52
|
+
result
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/lib/linkedin.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
|
3
|
+
module LinkedIn
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_accessor :token, :secret, :default_profile_fields
|
7
|
+
|
8
|
+
# config/initializers/linkedin.rb (for instance)
|
9
|
+
#
|
10
|
+
# LinkedIn.configure do |config|
|
11
|
+
# config.token = 'consumer_token'
|
12
|
+
# config.secret = 'consumer_secret'
|
13
|
+
# config.default_profile_fields = ['education', 'positions']
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# elsewhere
|
17
|
+
#
|
18
|
+
# client = LinkedIn::Client.new
|
19
|
+
def configure
|
20
|
+
yield self
|
21
|
+
true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
autoload :Api, "linked_in/api"
|
26
|
+
autoload :Client, "linked_in/client"
|
27
|
+
autoload :Mash, "linked_in/mash"
|
28
|
+
autoload :Errors, "linked_in/errors"
|
29
|
+
autoload :Helpers, "linked_in/helpers"
|
30
|
+
autoload :Search, "linked_in/search"
|
31
|
+
autoload :Version, "linked_in/version"
|
32
|
+
end
|
data/linkedin.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path('../lib/linked_in/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.add_dependency 'hashie', '~> 1.2.0'
|
6
|
+
gem.add_dependency 'multi_json', '~> 1.0.3'
|
7
|
+
gem.add_dependency 'oauth', '~> 0.4.5'
|
8
|
+
gem.add_development_dependency 'json', '~> 1.6'
|
9
|
+
gem.add_development_dependency 'rake', '~> 0.9'
|
10
|
+
gem.add_development_dependency 'rdoc', '~> 3.8'
|
11
|
+
gem.add_development_dependency 'rspec', '~> 2.6'
|
12
|
+
gem.add_development_dependency 'simplecov', '~> 0.5'
|
13
|
+
gem.add_development_dependency 'vcr', '~> 1.10'
|
14
|
+
gem.add_development_dependency 'webmock', '~> 1.7'
|
15
|
+
gem.authors = ["Wynn Netherland", "Josh Kalderimis"]
|
16
|
+
gem.description = %q{Ruby wrapper for the LinkedIn API}
|
17
|
+
gem.email = ['wynn.netherland@gmail.com', 'josh.kalderimis@gmail.com']
|
18
|
+
gem.files = `git ls-files`.split("\n")
|
19
|
+
gem.homepage = 'http://github.com/pengwynn/linkedin'
|
20
|
+
gem.name = 'linkedin-drspin'
|
21
|
+
gem.require_paths = ['lib']
|
22
|
+
gem.summary = gem.description
|
23
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
+
gem.version = LinkedIn::VERSION::STRING
|
25
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe LinkedIn::Api do
|
4
|
+
before do
|
5
|
+
LinkedIn.default_profile_fields = nil
|
6
|
+
client.stub(:consumer).and_return(consumer)
|
7
|
+
client.authorize_from_access('atoken', 'asecret')
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:client){LinkedIn::Client.new('token', 'secret')}
|
11
|
+
let(:consumer){OAuth::Consumer.new('token', 'secret', {:site => 'https://api.linkedin.com'})}
|
12
|
+
|
13
|
+
it "should be able to view the account profile" do
|
14
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~").to_return(:body => "{}")
|
15
|
+
client.profile.should be_an_instance_of(LinkedIn::Mash)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be able to view public profiles" do
|
19
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/id=123").to_return(:body => "{}")
|
20
|
+
client.profile(:id => 123).should be_an_instance_of(LinkedIn::Mash)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be able to view connections" do
|
24
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/connections").to_return(:body => "{}")
|
25
|
+
client.connections.should be_an_instance_of(LinkedIn::Mash)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be able to view network_updates" do
|
29
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates").to_return(:body => "{}")
|
30
|
+
client.network_updates.should be_an_instance_of(LinkedIn::Mash)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should be able to search with a keyword if given a String" do
|
34
|
+
stub_request(:get, "https://api.linkedin.com/v1/people-search?keywords=business").to_return(:body => "{}")
|
35
|
+
client.search("business").should be_an_instance_of(LinkedIn::Mash)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be able to search with an option" do
|
39
|
+
stub_request(:get, "https://api.linkedin.com/v1/people-search?first-name=Javan").to_return(:body => "{}")
|
40
|
+
client.search(:first_name => "Javan").should be_an_instance_of(LinkedIn::Mash)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be able to search with an option and fetch specific fields" do
|
44
|
+
stub_request(:get, "https://api.linkedin.com/v1/people-search:(num-results,total)?first-name=Javan").to_return(:body => "{}")
|
45
|
+
client.search(:first_name => "Javan", :fields => ["num_results", "total"]).should be_an_instance_of(LinkedIn::Mash)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should be able to share a new status" do
|
49
|
+
stub_request(:post, "https://api.linkedin.com/v1/people/~/shares").to_return(:body => "", :status => 201)
|
50
|
+
response = client.add_share(:comment => "Testing, 1, 2, 3")
|
51
|
+
response.body.should == ""
|
52
|
+
response.code.should == "201"
|
53
|
+
end
|
54
|
+
|
55
|
+
context "Company API" do
|
56
|
+
use_vcr_cassette
|
57
|
+
|
58
|
+
it "should be able to view a company profile" do
|
59
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies/id=1586").to_return(:body => "{}")
|
60
|
+
client.company(:id => 1586).should be_an_instance_of(LinkedIn::Mash)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should be able to view a company by universal name" do
|
64
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies/universal-name=acme").to_return(:body => "{}")
|
65
|
+
client.company(:name => 'acme').should be_an_instance_of(LinkedIn::Mash)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should be able to view a company by e-mail domain" do
|
69
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies/email-domain=acme.com").to_return(:body => "{}")
|
70
|
+
client.company(:domain => 'acme.com').should be_an_instance_of(LinkedIn::Mash)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should load correct company data" do
|
74
|
+
client.company(:id => 1586).name.should == "Amazon"
|
75
|
+
|
76
|
+
data = client.company(:id => 1586, :fields => %w{ id name industry locations:(address:(city state country-code) is-headquarters) employee-count-range })
|
77
|
+
data.id.should == 1586
|
78
|
+
data.name.should == "Amazon"
|
79
|
+
data.employee_count_range.name.should == "10001+"
|
80
|
+
data.industry.should == "Internet"
|
81
|
+
data.locations.all[0].address.city.should == "Seattle"
|
82
|
+
data.locations.all[0].is_headquarters.should == true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "Errors" do
|
87
|
+
it "should raise AccessDeniedError when LinkedIn returns 403 status code" do
|
88
|
+
stub_request(:get, "https://api.linkedin.com/v1/people-search?first-name=Javan").to_return(:body => "{}", :status => 403)
|
89
|
+
expect{ client.search(:first_name => "Javan") }.to raise_error(LinkedIn::Errors::AccessDeniedError)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe LinkedIn do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
LinkedIn.token = nil
|
7
|
+
LinkedIn.secret = nil
|
8
|
+
LinkedIn.default_profile_fields = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be able to set the consumer token and consumer secret" do
|
12
|
+
LinkedIn.token = 'consumer_token'
|
13
|
+
LinkedIn.secret = 'consumer_secret'
|
14
|
+
|
15
|
+
LinkedIn.token.should == 'consumer_token'
|
16
|
+
LinkedIn.secret.should == 'consumer_secret'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be able to set the default profile fields" do
|
20
|
+
LinkedIn.default_profile_fields = ['education', 'positions']
|
21
|
+
|
22
|
+
LinkedIn.default_profile_fields.should == ['education', 'positions']
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be able to set the consumer token and consumer secret via a configure block" do
|
26
|
+
LinkedIn.configure do |config|
|
27
|
+
config.token = 'consumer_token'
|
28
|
+
config.secret = 'consumer_secret'
|
29
|
+
config.default_profile_fields = ['education', 'positions']
|
30
|
+
end
|
31
|
+
|
32
|
+
LinkedIn.token.should == 'consumer_token'
|
33
|
+
LinkedIn.secret.should == 'consumer_secret'
|
34
|
+
LinkedIn.default_profile_fields.should == ['education', 'positions']
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|