linkedin-build 1.1.14
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 +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
|