brienw-linkedin 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
- 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 +9 -0
- data/lib/linked_in/api.rb +6 -0
- data/lib/linked_in/api/query_methods.rb +73 -0
- data/lib/linked_in/api/update_methods.rb +55 -0
- data/lib/linked_in/client.rb +46 -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 +295 -0
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 = 'brienw-linkedin'
|
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
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe LinkedIn::Mash do
|
4
|
+
|
5
|
+
describe ".from_json" do
|
6
|
+
it "should convert a json string to a Mash" do
|
7
|
+
json_string = "{\"name\":\"Josh Kalderimis\"}"
|
8
|
+
mash = LinkedIn::Mash.from_json(json_string)
|
9
|
+
|
10
|
+
mash.should have_key('name')
|
11
|
+
mash.name.should == 'Josh Kalderimis'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#convert_keys" do
|
16
|
+
let(:mash) do
|
17
|
+
LinkedIn::Mash.new({
|
18
|
+
'firstName' => 'Josh',
|
19
|
+
'LastName' => 'Kalderimis',
|
20
|
+
'_key' => 1234,
|
21
|
+
'_total' => 1234,
|
22
|
+
'values' => {},
|
23
|
+
'numResults' => 'total_results'
|
24
|
+
})
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should convert camal cased hash keys to underscores" do
|
28
|
+
mash.should have_key('first_name')
|
29
|
+
mash.should have_key('last_name')
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should convert the key _key to id" do
|
33
|
+
mash.should have_key('id')
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should convert the key _total to total" do
|
37
|
+
mash.should have_key('total')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should convert the key values to all" do
|
41
|
+
mash.should have_key('all')
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should convert the key numResults to total_results" do
|
45
|
+
mash.should have_key('total_results')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#timestamp' do
|
50
|
+
it "should return a valid Time if a key of timestamp exists and the value is an int" do
|
51
|
+
time_mash = LinkedIn::Mash.new({ 'timestamp' => 1297083249 })
|
52
|
+
|
53
|
+
time_mash.timestamp.should be_a_kind_of(Time)
|
54
|
+
time_mash.timestamp.to_i.should == 1297083249
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return a valid Time if a key of timestamp exists and the value is an int which is greater than 9999999999" do
|
58
|
+
time_mash = LinkedIn::Mash.new({ 'timestamp' => 1297083249 * 1000 })
|
59
|
+
|
60
|
+
time_mash.timestamp.should be_a_kind_of(Time)
|
61
|
+
time_mash.timestamp.to_i.should == 1297083249
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should not try to convert to a Time object if the value isn't an Integer" do
|
65
|
+
time_mash = LinkedIn::Mash.new({ 'timestamp' => 'Foo' })
|
66
|
+
|
67
|
+
time_mash.timestamp.class.should be String
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#to_date" do
|
72
|
+
let(:date_mash) do
|
73
|
+
LinkedIn::Mash.new({
|
74
|
+
'year' => 2010,
|
75
|
+
'month' => 06,
|
76
|
+
'day' => 23
|
77
|
+
})
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should return a valid Date if the keys year, month, day all exist" do
|
81
|
+
date_mash.to_date.should == Date.civil(2010, 06, 23)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe "LinkedIn::Client" do
|
4
|
+
|
5
|
+
let(:client) do
|
6
|
+
key = ENV['LINKED_IN_CONSUMER_KEY'] || '1234'
|
7
|
+
secret = ENV['LINKED_IN_CONSUMER_SECRET'] || '1234'
|
8
|
+
LinkedIn::Client.new(key, secret)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#consumer" do
|
12
|
+
describe "default oauth options" do
|
13
|
+
let(:consumer) { client.consumer }
|
14
|
+
|
15
|
+
it "should return a configured OAuth consumer" do
|
16
|
+
consumer.site.should == 'https://api.linkedin.com'
|
17
|
+
consumer.request_token_url.should == 'https://api.linkedin.com/uas/oauth/requestToken'
|
18
|
+
consumer.access_token_url.should == 'https://api.linkedin.com/uas/oauth/accessToken'
|
19
|
+
consumer.authorize_url.should == 'https://www.linkedin.com/uas/oauth/authorize'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "different api and auth hosts options" do
|
24
|
+
let(:consumer) do
|
25
|
+
LinkedIn::Client.new('1234', '1234', {
|
26
|
+
:api_host => 'https://api.josh.com',
|
27
|
+
:auth_host => 'https://www.josh.com'
|
28
|
+
}).consumer
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return a configured OAuth consumer" do
|
32
|
+
consumer.site.should == 'https://api.josh.com'
|
33
|
+
consumer.request_token_url.should == 'https://api.josh.com/uas/oauth/requestToken'
|
34
|
+
consumer.access_token_url.should == 'https://api.josh.com/uas/oauth/accessToken'
|
35
|
+
consumer.authorize_url.should == 'https://www.josh.com/uas/oauth/authorize'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "different oauth paths" do
|
40
|
+
let(:consumer) do
|
41
|
+
LinkedIn::Client.new('1234', '1234', {
|
42
|
+
:request_token_path => "/secure/oauth/requestToken",
|
43
|
+
:access_token_path => "/secure/oauth/accessToken",
|
44
|
+
:authorize_path => "/secure/oauth/authorize",
|
45
|
+
}).consumer
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should return a configured OAuth consumer" do
|
49
|
+
consumer.site.should == 'https://api.linkedin.com'
|
50
|
+
consumer.request_token_url.should == 'https://api.linkedin.com/secure/oauth/requestToken'
|
51
|
+
consumer.access_token_url.should == 'https://api.linkedin.com/secure/oauth/accessToken'
|
52
|
+
consumer.authorize_url.should == 'https://www.linkedin.com/secure/oauth/authorize'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "specify oauth urls" do
|
57
|
+
let(:consumer) do
|
58
|
+
LinkedIn::Client.new('1234', '1234', {
|
59
|
+
:request_token_url => "https://api.josh.com/secure/oauth/requestToken",
|
60
|
+
:access_token_url => "https://api.josh.com/secure/oauth/accessToken",
|
61
|
+
:authorize_url => "https://www.josh.com/secure/oauth/authorize",
|
62
|
+
}).consumer
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should return a configured OAuth consumer" do
|
66
|
+
consumer.site.should == 'https://api.linkedin.com'
|
67
|
+
consumer.request_token_url.should == 'https://api.josh.com/secure/oauth/requestToken'
|
68
|
+
consumer.access_token_url.should == 'https://api.josh.com/secure/oauth/accessToken'
|
69
|
+
consumer.authorize_url.should == 'https://www.josh.com/secure/oauth/authorize'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "use the :site option to specify the host of all oauth urls" do
|
74
|
+
let(:consumer) do
|
75
|
+
LinkedIn::Client.new('1234', '1234', {
|
76
|
+
:site => "https://api.josh.com"
|
77
|
+
}).consumer
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should return a configured OAuth consumer" do
|
81
|
+
consumer.site.should == 'https://api.josh.com'
|
82
|
+
consumer.request_token_url.should == 'https://api.josh.com/uas/oauth/requestToken'
|
83
|
+
consumer.access_token_url.should == 'https://api.josh.com/uas/oauth/accessToken'
|
84
|
+
consumer.authorize_url.should == 'https://api.josh.com/uas/oauth/authorize'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#request_token" do
|
90
|
+
describe "with default options" do
|
91
|
+
use_vcr_cassette :record => :new_episodes
|
92
|
+
|
93
|
+
it "should return a valid request token" do
|
94
|
+
request_token = client.request_token
|
95
|
+
|
96
|
+
request_token.should be_a_kind_of OAuth::RequestToken
|
97
|
+
request_token.authorize_url.should include("https://www.linkedin.com/uas/oauth/authorize?oauth_token=")
|
98
|
+
|
99
|
+
a_request(:post, "https://api.linkedin.com/uas/oauth/requestToken").should have_been_made.once
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "with a callback url" do
|
104
|
+
use_vcr_cassette :record => :new_episodes
|
105
|
+
|
106
|
+
it "should return a valid access token" do
|
107
|
+
request_token = client.request_token(:oauth_callback => 'http://www.josh.com')
|
108
|
+
|
109
|
+
request_token.should be_a_kind_of OAuth::RequestToken
|
110
|
+
request_token.authorize_url.should include("https://www.linkedin.com/uas/oauth/authorize?oauth_token=")
|
111
|
+
request_token.callback_confirmed?.should == true
|
112
|
+
|
113
|
+
a_request(:post, "https://api.linkedin.com/uas/oauth/requestToken").should have_been_made.once
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "#authorize_from_request" do
|
119
|
+
let(:access_token) do
|
120
|
+
# if you remove the related casssette you will need to do the following
|
121
|
+
# authorize_from_request request manually
|
122
|
+
#
|
123
|
+
# request_token = client.request_token
|
124
|
+
# puts "token : #{request_token.token} - secret #{request_token.secret}"
|
125
|
+
# puts "auth url : #{request_token.authorize_url}"
|
126
|
+
# raise 'keep note of the token and secret'
|
127
|
+
#
|
128
|
+
client.authorize_from_request('dummy-token', 'dummy-secret', 'dummy-pin')
|
129
|
+
end
|
130
|
+
|
131
|
+
use_vcr_cassette :record => :new_episodes, :match_requests_on => [:uri, :method]
|
132
|
+
|
133
|
+
it "should return a valid access token" do
|
134
|
+
access_token.should be_a_kind_of Array
|
135
|
+
access_token[0].should be_a_kind_of String
|
136
|
+
access_token[1].should be_a_kind_of String
|
137
|
+
|
138
|
+
a_request(:post, "https://api.linkedin.com/uas/oauth/accessToken").should have_been_made.once
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "#access_token" do
|
143
|
+
let(:access_token) do
|
144
|
+
client.authorize_from_access('dummy-token', 'dummy-secret')
|
145
|
+
client.access_token
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should return a valid auth token" do
|
149
|
+
access_token.should be_a_kind_of OAuth::AccessToken
|
150
|
+
access_token.token.should be_a_kind_of String
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "#authorize_from_access" do
|
155
|
+
let(:auth_token) do
|
156
|
+
client.authorize_from_access('dummy-token', 'dummy-secret')
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should return a valid auth token" do
|
160
|
+
auth_token.should be_a_kind_of Array
|
161
|
+
auth_token[0].should be_a_kind_of String
|
162
|
+
auth_token[1].should be_a_kind_of String
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe LinkedIn::Search do
|
4
|
+
|
5
|
+
# if you remove the related cassettes you will need to inform valid
|
6
|
+
# tokens and secrets to regenerate them
|
7
|
+
#
|
8
|
+
let(:client) do
|
9
|
+
consumer_token = ENV['LINKED_IN_CONSUMER_KEY'] || 'key'
|
10
|
+
consumer_secret = ENV['LINKED_IN_CONSUMER_SECRET'] || 'secret'
|
11
|
+
client = LinkedIn::Client.new(consumer_token, consumer_secret)
|
12
|
+
|
13
|
+
auth_token = ENV['LINKED_IN_AUTH_KEY'] || 'key'
|
14
|
+
auth_secret = ENV['LINKED_IN_AUTH_SECRET'] || 'secret'
|
15
|
+
client.authorize_from_access(auth_token, auth_secret)
|
16
|
+
client
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#search_company" do
|
20
|
+
|
21
|
+
describe "by keywords string parameter" do
|
22
|
+
use_vcr_cassette :record => :new_episodes
|
23
|
+
|
24
|
+
let(:results) do
|
25
|
+
client.search('apple', :company)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should perform a company search" do
|
29
|
+
results.companies.all.size.should == 10
|
30
|
+
results.companies.all.first.name.should == 'Apple'
|
31
|
+
results.companies.all.first.id.should == 162479
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "by single keywords option" do
|
36
|
+
use_vcr_cassette :record => :new_episodes
|
37
|
+
|
38
|
+
let(:results) do
|
39
|
+
options = {:keywords => 'apple'}
|
40
|
+
client.search(options, :company)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should perform a company search" do
|
44
|
+
results.companies.all.size.should == 10
|
45
|
+
results.companies.all.first.name.should == 'Apple'
|
46
|
+
results.companies.all.first.id.should == 162479
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "by single keywords option with facets to return" do
|
51
|
+
use_vcr_cassette :record => :new_episodes
|
52
|
+
|
53
|
+
let(:results) do
|
54
|
+
options = {:keywords => 'apple', :facets => [:industry]}
|
55
|
+
client.search(options, :company)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return a facet" do
|
59
|
+
results.facets.all.first.buckets.all.first.name.should == 'Information Technology and Services'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "by single keywords option with pagination" do
|
64
|
+
use_vcr_cassette :record => :new_episodes
|
65
|
+
|
66
|
+
let(:results) do
|
67
|
+
options = {:keywords => 'apple', :start => 5, :count => 5}
|
68
|
+
client.search(options, :company)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should perform a search" do
|
72
|
+
results.companies.all.size.should == 5
|
73
|
+
results.companies.all.first.name.should == 'Apple Vacations'
|
74
|
+
results.companies.all.first.id.should == 19271
|
75
|
+
results.companies.all.last.name.should == 'Micro Center'
|
76
|
+
results.companies.all.last.id.should == 15552
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "by keywords options with fields" do
|
81
|
+
use_vcr_cassette :record => :new_episodes
|
82
|
+
|
83
|
+
let(:results) do
|
84
|
+
fields = [{:companies => [:id, :name, :industries, :description, :specialties]}, :num_results]
|
85
|
+
client.search({:keywords => 'apple', :fields => fields}, 'company')
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should perform a search" do
|
89
|
+
results.companies.all.first.name.should == 'Apple'
|
90
|
+
results.companies.all.first.description.should == 'Apple designs Macs, the best personal computers in the world, along with Mac OS X, iLife, iWork, and professional software. Apple leads the digital music revolution with its iPods and iTunes online store. Apple is reinventing the mobile phone with its revolutionary iPhone and App Store, and has recently introduced its magical iPad which is defining the future of mobile media and computing devices.'
|
91
|
+
results.companies.all.first.id.should == 162479
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#search" do
|
98
|
+
|
99
|
+
describe "by keywords string parameter" do
|
100
|
+
use_vcr_cassette :record => :new_episodes
|
101
|
+
|
102
|
+
let(:results) do
|
103
|
+
client.search('github')
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should perform a search" do
|
107
|
+
results.people.all.size.should == 10
|
108
|
+
results.people.all.first.first_name.should == 'Giliardi'
|
109
|
+
results.people.all.first.last_name.should == 'Pires'
|
110
|
+
results.people.all.first.id.should == 'YkdnFl04s_'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "by single keywords option" do
|
115
|
+
use_vcr_cassette :record => :new_episodes
|
116
|
+
|
117
|
+
let(:results) do
|
118
|
+
client.search(:keywords => 'github')
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should perform a search" do
|
122
|
+
results.people.all.size.should == 10
|
123
|
+
results.people.all.first.first_name.should == 'Giliardi'
|
124
|
+
results.people.all.first.last_name.should == 'Pires'
|
125
|
+
results.people.all.first.id.should == 'YkdnFl04s_'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "by single keywords option with pagination" do
|
130
|
+
use_vcr_cassette :record => :new_episodes
|
131
|
+
|
132
|
+
let(:results) do
|
133
|
+
client.search(:keywords => 'github', :start => 5, :count => 5)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should perform a search" do
|
137
|
+
results.people.all.size.should == 5
|
138
|
+
results.people.all.first.first_name.should == 'Stephen'
|
139
|
+
results.people.all.first.last_name.should == 'M.'
|
140
|
+
results.people.all.first.id.should == 'z2XMcxa_dR'
|
141
|
+
results.people.all.last.first_name.should == 'Pablo'
|
142
|
+
results.people.all.last.last_name.should == 'C.'
|
143
|
+
results.people.all.last.id.should == 'pdzrGpyP0h'
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "by first_name and last_name options" do
|
148
|
+
use_vcr_cassette :record => :new_episodes
|
149
|
+
|
150
|
+
let(:results) do
|
151
|
+
client.search(:first_name => 'Giliardi', :last_name => 'Pires')
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should perform a search" do
|
155
|
+
results.people.all.size.should == 1
|
156
|
+
results.people.all.first.first_name.should == 'Giliardi'
|
157
|
+
results.people.all.first.last_name.should == 'Pires'
|
158
|
+
results.people.all.first.id.should == 'YkdnFl04s_'
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "by first_name and last_name options with fields" do
|
163
|
+
use_vcr_cassette :record => :new_episodes
|
164
|
+
|
165
|
+
let(:results) do
|
166
|
+
fields = [{:people => [:id, :first_name, :last_name, :public_profile_url, :picture_url]}, :num_results]
|
167
|
+
client.search(:first_name => 'Giliardi', :last_name => 'Pires', :fields => fields)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should perform a search" do
|
171
|
+
results.people.all.size.should == 1
|
172
|
+
results.people.all.first.first_name.should == 'Giliardi'
|
173
|
+
results.people.all.first.last_name.should == 'Pires'
|
174
|
+
results.people.all.first.id.should == 'YkdnFl04s_'
|
175
|
+
results.people.all.first.picture_url == 'http://media.linkedin.com/mpr/mprx/0_Oz05kn9xkWziAEOUKtOVkqzjXd8Clf7UyqIVkqchR2NtmwZRt1fWoN_aobhg-HmB09jUwPLKrAhU'
|
176
|
+
results.people.all.first.public_profile_url == 'http://www.linkedin.com/in/gibanet'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "by company_name option" do
|
181
|
+
use_vcr_cassette :record => :new_episodes
|
182
|
+
|
183
|
+
let(:results) do
|
184
|
+
client.search(:company_name => 'linkedin')
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should perform a search" do
|
188
|
+
results.people.all.size.should == 10
|
189
|
+
results.people.all.first.first_name.should == 'Donald'
|
190
|
+
results.people.all.first.last_name.should == 'Denker'
|
191
|
+
results.people.all.first.id.should == 'VQcsz5Hp_h'
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe "#field_selector" do
|
196
|
+
it "should not modify the parameter object" do
|
197
|
+
fields = [{:people => [:id, :first_name]}]
|
198
|
+
fields_dup = fields.dup
|
199
|
+
client.send(:field_selector, fields)
|
200
|
+
fields.should eq fields_dup
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|