linkedin-build 1.1.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.autotest +14 -0
- data/.gemtest +0 -0
- data/.gitignore +49 -0
- data/.rspec +1 -0
- data/.travis.yml +6 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +99 -0
- data/EXAMPLES.md +202 -0
- data/Gemfile +11 -0
- data/LICENSE +22 -0
- data/README.md +43 -0
- data/Rakefile +15 -0
- data/lib/linked_in/api.rb +38 -0
- data/lib/linked_in/api/communications.rb +44 -0
- data/lib/linked_in/api/companies.rb +129 -0
- data/lib/linked_in/api/groups.rb +115 -0
- data/lib/linked_in/api/jobs.rb +64 -0
- data/lib/linked_in/api/people.rb +73 -0
- data/lib/linked_in/api/query_helpers.rb +86 -0
- data/lib/linked_in/api/share_and_social_stream.rb +137 -0
- data/lib/linked_in/client.rb +51 -0
- data/lib/linked_in/errors.rb +29 -0
- data/lib/linked_in/helpers.rb +6 -0
- data/lib/linked_in/helpers/authorization.rb +69 -0
- data/lib/linked_in/helpers/request.rb +85 -0
- data/lib/linked_in/mash.rb +95 -0
- data/lib/linked_in/search.rb +71 -0
- data/lib/linked_in/version.rb +11 -0
- data/lib/linkedin.rb +35 -0
- data/linkedin-build.gemspec +28 -0
- data/spec/cases/api_spec.rb +308 -0
- data/spec/cases/linkedin_spec.rb +37 -0
- data/spec/cases/mash_spec.rb +113 -0
- data/spec/cases/oauth_spec.rb +178 -0
- data/spec/cases/search_spec.rb +234 -0
- data/spec/fixtures/cassette_library/LinkedIn_Api/Company_API.yml +81 -0
- data/spec/fixtures/cassette_library/LinkedIn_Api/Company_API/should_load_correct_company_data.yml +81 -0
- data/spec/fixtures/cassette_library/LinkedIn_Client/_authorize_from_request/should_return_a_valid_access_token.yml +37 -0
- data/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_a_callback_url/should_return_a_valid_access_token.yml +37 -0
- data/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_default_options/should_return_a_valid_request_token.yml +37 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_company_name_option/should_perform_a_search.yml +92 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_email_address/should_perform_a_people_search.yml +57 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options/should_perform_a_search.yml +100 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options_with_fields/should_perform_a_search.yml +114 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_keywords_string_parameter/should_perform_a_search.yml +52 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_multiple_email_address/should_perform_a_multi-email_search.yml +59 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option/should_perform_a_search.yml +52 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option_with_pagination/should_perform_a_search.yml +43 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search/email_search_returns_unauthorized/should_raise_an_unauthorized_error.yml +59 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_options_with_fields/should_perform_a_search.yml +43 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_string_parameter/should_perform_a_company_search.yml +80 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option/should_perform_a_company_search.yml +80 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_facets_to_return/should_return_a_facet.yml +80 -0
- data/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_pagination/should_perform_a_search.yml +74 -0
- data/spec/helper.rb +34 -0
- metadata +282 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
module LinkedIn
|
5
|
+
|
6
|
+
# The generalized pseudo-object that is returned for all query
|
7
|
+
# requests.
|
8
|
+
class Mash < ::Hashie::Mash
|
9
|
+
|
10
|
+
# Convert a json string to a Mash
|
11
|
+
#
|
12
|
+
# @param [String] json_string
|
13
|
+
# @return [LinkedIn::Mash]
|
14
|
+
def self.from_json(json_string)
|
15
|
+
result_hash = ::MultiJson.decode(json_string)
|
16
|
+
new(result_hash)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns a Date if we have year, month and day, and no conflicting key
|
20
|
+
#
|
21
|
+
# @return [Date]
|
22
|
+
def to_date
|
23
|
+
if !self.has_key?('to_date') && contains_date_fields?
|
24
|
+
Date.civil(self.year, self.month, self.day)
|
25
|
+
else
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns the id of the object from LinkedIn
|
31
|
+
#
|
32
|
+
# @return [String]
|
33
|
+
def id
|
34
|
+
if self['id']
|
35
|
+
self['id']
|
36
|
+
else
|
37
|
+
self['_key']
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Convert the 'timestamp' field from a string to a Time object
|
42
|
+
#
|
43
|
+
# @return [Time]
|
44
|
+
def timestamp
|
45
|
+
value = self['timestamp']
|
46
|
+
if value.kind_of? Integer
|
47
|
+
value = value / 1000 if value > 9999999999
|
48
|
+
Time.at(value)
|
49
|
+
else
|
50
|
+
value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return the results array from the query
|
55
|
+
#
|
56
|
+
# @return [Array]
|
57
|
+
def all
|
58
|
+
super || []
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
def contains_date_fields?
|
64
|
+
self.year? && self.month? && self.day?
|
65
|
+
end
|
66
|
+
|
67
|
+
# overload the convert_key mash method so that the LinkedIn
|
68
|
+
# keys are made a little more ruby-ish
|
69
|
+
def convert_key(key)
|
70
|
+
case key.to_s
|
71
|
+
when '_total'
|
72
|
+
'total'
|
73
|
+
when 'values'
|
74
|
+
'all'
|
75
|
+
when 'numResults'
|
76
|
+
'total_results'
|
77
|
+
else
|
78
|
+
underscore(key)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# borrowed from ActiveSupport
|
83
|
+
# no need require an entire lib when we only need one method
|
84
|
+
def underscore(camel_cased_word)
|
85
|
+
word = camel_cased_word.to_s.dup
|
86
|
+
word.gsub!(/::/, '/')
|
87
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
88
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
89
|
+
word.tr!("-", "_")
|
90
|
+
word.downcase!
|
91
|
+
word
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
|
3
|
+
module Search
|
4
|
+
|
5
|
+
# Retrieve search results of the given object type
|
6
|
+
#
|
7
|
+
# Permissions: (for people search only) r_network
|
8
|
+
#
|
9
|
+
# @note People Search API is a part of the Vetted API Access Program. You
|
10
|
+
# must apply and get approval before using this API
|
11
|
+
#
|
12
|
+
# @see http://developer.linkedin.com/documents/people-search-api People Search
|
13
|
+
# @see http://developer.linkedin.com/documents/job-search-api Job Search
|
14
|
+
# @see http://developer.linkedin.com/documents/company-search Company Search
|
15
|
+
#
|
16
|
+
# @param [Hash] options search input fields
|
17
|
+
# @param [String] type type of object to return ('people', 'job' or 'company')
|
18
|
+
# @return [LinkedIn::Mash]
|
19
|
+
def search(options={}, type='people')
|
20
|
+
|
21
|
+
path = "/#{type.to_s}-search"
|
22
|
+
|
23
|
+
if options.is_a?(Hash)
|
24
|
+
fields = options.delete(:fields)
|
25
|
+
path += field_selector(fields) if fields
|
26
|
+
end
|
27
|
+
|
28
|
+
options = { :keywords => options } if options.is_a?(String)
|
29
|
+
options = format_options_for_query(options)
|
30
|
+
|
31
|
+
result_json = get(to_uri(path, options))
|
32
|
+
|
33
|
+
Mash.from_json(result_json)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def format_options_for_query(opts)
|
39
|
+
opts.inject({}) do |list, kv|
|
40
|
+
key, value = kv.first.to_s.gsub("_","-"), kv.last
|
41
|
+
list[key] = sanitize_value(value)
|
42
|
+
list
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def sanitize_value(value)
|
47
|
+
value = value.join("+") if value.is_a?(Array)
|
48
|
+
value = value.gsub(" ", "+") if value.is_a?(String)
|
49
|
+
value
|
50
|
+
end
|
51
|
+
|
52
|
+
def field_selector(fields)
|
53
|
+
result = ":("
|
54
|
+
fields = fields.to_a.map do |field|
|
55
|
+
if field.is_a?(Hash)
|
56
|
+
innerFields = []
|
57
|
+
field.each do |key, value|
|
58
|
+
innerFields << key.to_s.gsub("_","-") + field_selector(value)
|
59
|
+
end
|
60
|
+
innerFields.join(',')
|
61
|
+
else
|
62
|
+
field.to_s.gsub("_","-")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
result += fields.join(',')
|
66
|
+
result += ")"
|
67
|
+
result
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
data/lib/linkedin.rb
ADDED
@@ -0,0 +1,35 @@
|
|
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
|
+
# ```ruby
|
11
|
+
# LinkedIn.configure do |config|
|
12
|
+
# config.token = 'consumer_token'
|
13
|
+
# config.secret = 'consumer_secret'
|
14
|
+
# config.default_profile_fields = ['educations', 'positions']
|
15
|
+
# end
|
16
|
+
# ```
|
17
|
+
# elsewhere
|
18
|
+
#
|
19
|
+
# ```ruby
|
20
|
+
# client = LinkedIn::Client.new
|
21
|
+
# ```
|
22
|
+
def configure
|
23
|
+
yield self
|
24
|
+
true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
autoload :Api, "linked_in/api"
|
29
|
+
autoload :Client, "linked_in/client"
|
30
|
+
autoload :Mash, "linked_in/mash"
|
31
|
+
autoload :Errors, "linked_in/errors"
|
32
|
+
autoload :Helpers, "linked_in/helpers"
|
33
|
+
autoload :Search, "linked_in/search"
|
34
|
+
autoload :Version, "linked_in/version"
|
35
|
+
end
|
@@ -0,0 +1,28 @@
|
|
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', '3.5.6' #'~> 3.0'
|
6
|
+
gem.add_dependency 'multi_json', '~> 1.0'
|
7
|
+
gem.add_dependency 'oauth', '0.5.1' # '~> 0.4'
|
8
|
+
gem.add_dependency 'oauth2', '1.4.0'
|
9
|
+
# gem.add_development_dependency 'json', '~> 1.6'
|
10
|
+
gem.add_development_dependency 'rake', '~> 10'
|
11
|
+
gem.add_development_dependency 'yard'
|
12
|
+
gem.add_development_dependency 'kramdown'
|
13
|
+
gem.add_development_dependency 'rspec', '~> 2.13'
|
14
|
+
gem.add_development_dependency 'simplecov', '~> 0.7'
|
15
|
+
gem.add_development_dependency 'vcr', '~> 2.5'
|
16
|
+
gem.add_development_dependency 'webmock', '~> 1.11'
|
17
|
+
gem.authors = ['Matthew Kirk', 'Wynn Netherland', 'Josh Kalderimis']
|
18
|
+
gem.description = 'Ruby wrapper for the LinkedIn API'
|
19
|
+
gem.email = ['meteor.kirk@gmail.com', 'wynn.netherland@gmail.com', 'josh.kalderimis@gmail.com']
|
20
|
+
gem.files = `git ls-files`.split("\n")
|
21
|
+
gem.homepage = 'http://github.com/hexgnu/linkedin'
|
22
|
+
gem.name = 'linkedin-build'
|
23
|
+
gem.licenses = %w[MIT]
|
24
|
+
gem.require_paths = ['lib']
|
25
|
+
gem.summary = 'This gem interfaces with the Linkedin XML and JSON APis'
|
26
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
27
|
+
gem.version = LinkedIn::VERSION::STRING
|
28
|
+
end
|
@@ -0,0 +1,308 @@
|
|
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 the picture urls" do
|
24
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/picture-urls::(original)").to_return(:body => "{}")
|
25
|
+
client.picture_urls.should be_an_instance_of(LinkedIn::Mash)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be able to view connections" do
|
29
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/connections").to_return(:body => "{}")
|
30
|
+
client.connections.should be_an_instance_of(LinkedIn::Mash)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should be able to view new connections" do
|
34
|
+
modified_since = Time.now.to_i * 1000
|
35
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/connections?modified=new&modified-since=#{modified_since}").to_return(:body => "{}")
|
36
|
+
client.new_connections(modified_since).should be_an_instance_of(LinkedIn::Mash)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be able to view network_updates" do
|
40
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates").to_return(:body => "{}")
|
41
|
+
client.network_updates.should be_an_instance_of(LinkedIn::Mash)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should be able to view network_update's comments" do
|
45
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates/key=network_update_key/update-comments").to_return(:body => "{}")
|
46
|
+
client.share_comments("network_update_key").should be_an_instance_of(LinkedIn::Mash)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should be able to view network_update's likes" do
|
50
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates/key=network_update_key/likes").to_return(:body => "{}")
|
51
|
+
client.share_likes("network_update_key").should be_an_instance_of(LinkedIn::Mash)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should be able to search with a keyword if given a String" do
|
55
|
+
stub_request(:get, "https://api.linkedin.com/v1/people-search?keywords=business").to_return(:body => "{}")
|
56
|
+
client.search("business").should be_an_instance_of(LinkedIn::Mash)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should be able to search with an option" do
|
60
|
+
stub_request(:get, "https://api.linkedin.com/v1/people-search?first-name=Javan").to_return(:body => "{}")
|
61
|
+
client.search(:first_name => "Javan").should be_an_instance_of(LinkedIn::Mash)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should be able to search with an option and fetch specific fields" do
|
65
|
+
stub_request(:get, "https://api.linkedin.com/v1/people-search:(num-results,total)?first-name=Javan").to_return(
|
66
|
+
:body => "{}")
|
67
|
+
client.search(:first_name => "Javan", :fields => ["num_results", "total"]).should be_an_instance_of(LinkedIn::Mash)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should be able to share a new status" do
|
71
|
+
stub_request(:post, "https://api.linkedin.com/v1/people/~/shares").to_return(:body => "", :status => 201)
|
72
|
+
response = client.add_share(:comment => "Testing, 1, 2, 3")
|
73
|
+
response.body.should == nil
|
74
|
+
response.status.should == "201"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should be able to share a new company status" do
|
78
|
+
stub_request(:post, "https://api.linkedin.com/v1/companies/123456/shares").to_return(:body => "", :status => 201)
|
79
|
+
response = client.add_company_share("123456", { :comment => "Testing, 1, 2, 3" })
|
80
|
+
response.body.should == nil
|
81
|
+
response.status.should == "201"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "returns the shares for a person" do
|
85
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates?type=SHAR&scope=self&after=1234&count=35").to_return(
|
86
|
+
:body => "{}")
|
87
|
+
client.shares(:after => 1234, :count => 35)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be able to fetch a single share" do
|
91
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates/key=network_update_key").to_return(:body => "{}")
|
92
|
+
client.share("network_update_key").should be_an_instance_of(LinkedIn::Mash)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should be able to comment on network update" do
|
96
|
+
stub_request(:post, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/update-comments").to_return(
|
97
|
+
:body => "", :status => 201)
|
98
|
+
response = client.update_comment('SOMEKEY', "Testing, 1, 2, 3")
|
99
|
+
response.body.should == nil
|
100
|
+
response.status.should == "201"
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should be able to like a network update" do
|
104
|
+
stub_request(:put, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/is-liked").
|
105
|
+
with(:body => "true").to_return(:body => "", :status => 201)
|
106
|
+
response = client.like_share('SOMEKEY')
|
107
|
+
response.body.should == nil
|
108
|
+
response.status.should == "201"
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should be able to unlike a network update" do
|
112
|
+
stub_request(:put, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/is-liked").
|
113
|
+
with(:body => "false").to_return(:body => "", :status => 201)
|
114
|
+
response = client.unlike_share('SOMEKEY')
|
115
|
+
response.body.should == nil
|
116
|
+
response.status.should == "201"
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should be able to pass down the additional arguments to OAuth's get_request_token" do
|
120
|
+
consumer.should_receive(:get_request_token).with(
|
121
|
+
{:oauth_callback => "http://localhost:3000/auth/callback"}, :scope => "rw_nus").and_return("request_token")
|
122
|
+
|
123
|
+
request_token = client.request_token(
|
124
|
+
{:oauth_callback => "http://localhost:3000/auth/callback"}, :scope => "rw_nus"
|
125
|
+
)
|
126
|
+
|
127
|
+
request_token.should == "request_token"
|
128
|
+
end
|
129
|
+
|
130
|
+
context "Company API", :vcr do
|
131
|
+
|
132
|
+
it "should be able to view a company profile" do
|
133
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies/id=1586").to_return(:body => "{}")
|
134
|
+
client.company(:id => 1586).should be_an_instance_of(LinkedIn::Mash)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should be able to view a company by universal name" do
|
138
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies/universal-name=acme").to_return(:body => "{}")
|
139
|
+
client.company(:name => 'acme').should be_an_instance_of(LinkedIn::Mash)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should be able to view a company by e-mail domain" do
|
143
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies?email-domain=acme.com").to_return(:body => "{}")
|
144
|
+
client.company(:domain => 'acme.com').should be_an_instance_of(LinkedIn::Mash)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should be able to view a user's company pages" do
|
148
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies?is-company-admin=true").to_return(:body => "{}")
|
149
|
+
client.company(:is_admin => 'true').should be_an_instance_of(LinkedIn::Mash)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should be able to page a user's company pages" do
|
153
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies?is-company-admin=true&count=10&start=0").to_return(:body => "{}")
|
154
|
+
client.company(:is_admin => 'true', :count => 10, :start => 0).should be_an_instance_of(LinkedIn::Mash)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should load correct company data" do
|
158
|
+
client.company(:id => 1586).name.should == "Amazon"
|
159
|
+
|
160
|
+
data = client.company(:id => 1586, :fields => %w{ id name industry locations:(address:(city state country-code) is-headquarters) employee-count-range })
|
161
|
+
data.id.should == 1586
|
162
|
+
data.name.should == "Amazon"
|
163
|
+
data.employee_count_range.name.should == "10001+"
|
164
|
+
data.industry.should == "Internet"
|
165
|
+
data.locations.all[0].address.city.should == "Seattle"
|
166
|
+
data.locations.all[0].is_headquarters.should == true
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should be able to view company_updates" do
|
170
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies/id=1586/updates").to_return(:body => "{}")
|
171
|
+
client.company_updates(:id => 1586).should be_an_instance_of(LinkedIn::Mash)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should be able to view company_statistic" do
|
175
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies/id=1586/company-statistics").to_return(:body => "{}")
|
176
|
+
client.company_statistics(:id => 1586).should be_an_instance_of(LinkedIn::Mash)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should be able to view company updates comments" do
|
180
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies/id=1586/updates/key=company_update_key/update-comments").to_return(:body => "{}")
|
181
|
+
client.company_updates_comments("company_update_key", :id => 1586).should be_an_instance_of(LinkedIn::Mash)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should be able to view company updates likes" do
|
185
|
+
stub_request(:get, "https://api.linkedin.com/v1/companies/id=1586/updates/key=company_update_key/likes").to_return(:body => "{}")
|
186
|
+
client.company_updates_likes("company_update_key", :id => 1586).should be_an_instance_of(LinkedIn::Mash)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should be able to follow a company" do
|
190
|
+
stub_request(:post, "https://api.linkedin.com/v1/people/~/following/companies").to_return(:body => "", :status => 201)
|
191
|
+
|
192
|
+
response = client.follow_company(1586)
|
193
|
+
response.body.should == nil
|
194
|
+
response.status.should == "201"
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should be able to unfollow a company" do
|
198
|
+
stub_request(:delete, "https://api.linkedin.com/v1/people/~/following/companies/id=1586").to_return(:body => "", :status => 201)
|
199
|
+
|
200
|
+
response = client.unfollow_company(1586)
|
201
|
+
response.body.should == nil
|
202
|
+
response.status.should == "201"
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
context "Job API", :vcr do
|
208
|
+
|
209
|
+
it "should be able to view a job listing" do
|
210
|
+
stub_request(:get, "https://api.linkedin.com/v1/jobs/id=1586").to_return(:body => "{}")
|
211
|
+
client.job(:id => 1586).should be_an_instance_of(LinkedIn::Mash)
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should be able to view its job bookmarks" do
|
215
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/job-bookmarks").to_return(:body => "{}")
|
216
|
+
client.job_bookmarks.should be_an_instance_of(LinkedIn::Mash)
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should be able to view its job suggestion" do
|
220
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/suggestions/job-suggestions").to_return(:body => "{}")
|
221
|
+
client.job_suggestions.should be_an_instance_of(LinkedIn::Mash)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should be able to add a bookmark" do
|
225
|
+
stub_request(:post, "https://api.linkedin.com/v1/people/~/job-bookmarks").to_return(:body => "", :status => 201)
|
226
|
+
response = client.add_job_bookmark(:id => 1452577)
|
227
|
+
response.body.should == nil
|
228
|
+
response.status.should == "201"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context "Group API" do
|
233
|
+
|
234
|
+
it "should be able to list group memberships for a profile" do
|
235
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/group-memberships").to_return(:body => "{}")
|
236
|
+
client.group_memberships.should be_an_instance_of(LinkedIn::Mash)
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should be able to list suggested groups for a profile" do
|
240
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/suggestions/groups").to_return(:body => '{"id": "123"}')
|
241
|
+
response = client.group_suggestions
|
242
|
+
response.id.should == '123'
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should be able to parse nested fields" do
|
246
|
+
stub_request(:get, "https://api.linkedin.com/v1/people/~/group-memberships:(group:(id,name,small-logo-url,short-description))").to_return(:body => "{}")
|
247
|
+
client.group_memberships(:fields => [{:group => ['id', 'name', 'small-logo-url', 'short-description']}]).should be_an_instance_of(LinkedIn::Mash)
|
248
|
+
end
|
249
|
+
|
250
|
+
it "should be able to join a group" do
|
251
|
+
stub_request(:put, "https://api.linkedin.com/v1/people/~/group-memberships/123").to_return(:body => "", :status => 201)
|
252
|
+
|
253
|
+
response = client.join_group(123)
|
254
|
+
response.body.should == nil
|
255
|
+
response.status.should == "201"
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should be able to list a group profile" do
|
259
|
+
stub_request(:get, "https://api.linkedin.com/v1/groups/123").to_return(:body => '{"id": "123"}')
|
260
|
+
response = client.group_profile(:id => 123)
|
261
|
+
response.id.should == '123'
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should be able to list group posts" do
|
265
|
+
stub_request(:get, "https://api.linkedin.com/v1/groups/123/posts").to_return(:body => '{"id": "123"}')
|
266
|
+
response = client.group_posts(:id => 123)
|
267
|
+
response.id.should == '123'
|
268
|
+
end
|
269
|
+
|
270
|
+
it 'should be able to post a discussion to a group' do
|
271
|
+
expected = {
|
272
|
+
'title' => 'New Discussion',
|
273
|
+
'summary' => 'New Summary',
|
274
|
+
'content' => {
|
275
|
+
"submitted-url" => "http://www.google.com"
|
276
|
+
}
|
277
|
+
}
|
278
|
+
|
279
|
+
stub_request(:post, "https://api.linkedin.com/v1/groups/123/posts").with(:body => expected).to_return(:body => "", :status => 201)
|
280
|
+
response = client.post_group_discussion(123, expected)
|
281
|
+
response.body.should == nil
|
282
|
+
response.status.should == '201'
|
283
|
+
end
|
284
|
+
|
285
|
+
it "should be able to share a new group status" do
|
286
|
+
stub_request(:post, "https://api.linkedin.com/v1/groups/1/posts").to_return(:body => "", :status => 201)
|
287
|
+
response = client.add_group_share(1, :comment => "Testing, 1, 2, 3")
|
288
|
+
response.body.should == nil
|
289
|
+
response.status.should == "201"
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
context "Communication API" do
|
294
|
+
it "should be able to send a message" do
|
295
|
+
stub_request(:post, "https://api.linkedin.com/v1/people/~/mailbox").to_return(:body => "", :status => 201)
|
296
|
+
response = client.send_message("subject", "body", ["recip1", "recip2"])
|
297
|
+
response.body.should == nil
|
298
|
+
response.status.should == "201"
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
context "Errors" do
|
303
|
+
it "should raise AccessDeniedError when LinkedIn returns 403 status code" do
|
304
|
+
stub_request(:get, "https://api.linkedin.com/v1/people-search?first-name=Javan").to_return(:body => "{}", :status => 403)
|
305
|
+
expect{ client.search(:first_name => "Javan") }.to raise_error(LinkedIn::Errors::AccessDeniedError)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|