linkedin 0.2.2 → 0.3.1

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.
Files changed (74) hide show
  1. data/{spec/fixtures/blank.xml → .gemtest} +0 -0
  2. data/.gitignore +36 -21
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +6 -2
  6. data/Rakefile +9 -31
  7. data/changelog.markdown +1 -1
  8. data/lib/linked_in/api/query_methods.rb +49 -0
  9. data/lib/linked_in/api/update_methods.rb +54 -0
  10. data/lib/linked_in/client.rb +44 -147
  11. data/lib/linked_in/errors.rb +20 -0
  12. data/lib/linked_in/helpers/authorization.rb +67 -0
  13. data/lib/linked_in/helpers/request.rb +77 -0
  14. data/lib/linked_in/mash.rb +68 -0
  15. data/lib/linked_in/search.rb +34 -0
  16. data/lib/linked_in/version.rb +11 -0
  17. data/lib/linkedin.rb +4 -55
  18. data/linkedin.gemspec +26 -47
  19. data/spec/cases/client_spec.rb +260 -276
  20. data/spec/cases/linkedin_spec.rb +6 -6
  21. data/spec/cases/mash_spec.rb +85 -0
  22. data/spec/cases/oauth_spec.rb +146 -92
  23. data/spec/fixtures/cassette_library/LinkedIn_Client/_authorize_from_request.yml +28 -0
  24. data/spec/fixtures/cassette_library/LinkedIn_Client/_request_token.yml +28 -0
  25. data/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_a_callback_url.yml +28 -0
  26. data/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_default_options.yml +28 -0
  27. data/spec/helper.rb +30 -0
  28. metadata +139 -169
  29. data/VERSION +0 -1
  30. data/lib/linked_in/api_standard_profile_request.rb +0 -17
  31. data/lib/linked_in/authorization_helpers.rb +0 -48
  32. data/lib/linked_in/base.rb +0 -13
  33. data/lib/linked_in/birthdate.rb +0 -21
  34. data/lib/linked_in/company.rb +0 -11
  35. data/lib/linked_in/connections.rb +0 -16
  36. data/lib/linked_in/country.rb +0 -9
  37. data/lib/linked_in/current_share.rb +0 -56
  38. data/lib/linked_in/education.rb +0 -41
  39. data/lib/linked_in/error.rb +0 -21
  40. data/lib/linked_in/group.rb +0 -32
  41. data/lib/linked_in/languages.rb +0 -28
  42. data/lib/linked_in/likes.rb +0 -23
  43. data/lib/linked_in/location.rb +0 -13
  44. data/lib/linked_in/message.rb +0 -20
  45. data/lib/linked_in/network.rb +0 -12
  46. data/lib/linked_in/patents.rb +0 -42
  47. data/lib/linked_in/people.rb +0 -18
  48. data/lib/linked_in/person.rb +0 -7
  49. data/lib/linked_in/phone_number.rb +0 -29
  50. data/lib/linked_in/position.rb +0 -46
  51. data/lib/linked_in/profile.rb +0 -85
  52. data/lib/linked_in/publications.rb +0 -40
  53. data/lib/linked_in/recipient.rb +0 -7
  54. data/lib/linked_in/recipients.rb +0 -18
  55. data/lib/linked_in/recommendations.rb +0 -30
  56. data/lib/linked_in/short_profile.rb +0 -13
  57. data/lib/linked_in/skill.rb +0 -33
  58. data/lib/linked_in/to_xml_helpers.rb +0 -53
  59. data/lib/linked_in/update.rb +0 -23
  60. data/lib/linked_in/url_resource.rb +0 -26
  61. data/spec/fixtures/connections.xml +0 -3733
  62. data/spec/fixtures/error.xml +0 -7
  63. data/spec/fixtures/likes.xml +0 -18
  64. data/spec/fixtures/mailbox_items.xml +0 -16
  65. data/spec/fixtures/network_status_with_group.xml +0 -44
  66. data/spec/fixtures/network_statuses.xml +0 -317
  67. data/spec/fixtures/picture_updates.xml +0 -117
  68. data/spec/fixtures/profile.xml +0 -9
  69. data/spec/fixtures/profile_full.xml +0 -3906
  70. data/spec/fixtures/profile_with_positions.xml +0 -79
  71. data/spec/fixtures/search.xml +0 -538
  72. data/spec/fixtures/shares.xml +0 -12
  73. data/spec/fixtures/status.xml +0 -2
  74. data/spec/spec_helper.rb +0 -49
@@ -0,0 +1,20 @@
1
+ module LinkedIn
2
+
3
+ class LinkedInError < StandardError
4
+ attr_reader :data
5
+
6
+ def initialize(data)
7
+ @data = data
8
+ super
9
+ end
10
+ end
11
+
12
+ class RateLimitExceededError < LinkedInError; end
13
+ class UnauthorizedError < LinkedInError; end
14
+ class GeneralError < LinkedInError; end
15
+
16
+ class UnavailableError < StandardError; end
17
+ class InformLinkedInError < StandardError; end
18
+ class NotFoundError < StandardError; end
19
+
20
+ end
@@ -0,0 +1,67 @@
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
+ }
52
+ end
53
+
54
+ def full_oauth_url_for(url_type, host_type)
55
+ if @consumer_options["#{url_type}_url".to_sym]
56
+ @consumer_options["#{url_type}_url".to_sym]
57
+ else
58
+ host = @consumer_options[:site] || @consumer_options[host_type] || DEFAULT_OAUTH_OPTIONS[host_type]
59
+ path = @consumer_options[:"#{url_type}_path".to_sym] || DEFAULT_OAUTH_OPTIONS["#{url_type}_path".to_sym]
60
+ "#{host}#{path}"
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,77 @@
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 UnauthorizedError.new(data), "(#{data.status}): #{data.message}"
47
+ when 400, 403
48
+ data = Mash.from_json(response.body)
49
+ raise GeneralError.new(data), "(#{data.status}): #{data.message}"
50
+ when 404
51
+ raise NotFoundError, "(#{response.code}): #{response.message}"
52
+ when 500
53
+ raise InformLinkedInError, "LinkedIn had an internal error. Please let them know in the forum. (#{response.code}): #{response.message}"
54
+ when 502..503
55
+ raise UnavailableError, "(#{response.code}): #{response.message}"
56
+ end
57
+ end
58
+
59
+ def to_query(options)
60
+ options.inject([]) do |collection, opt|
61
+ collection << "#{opt[0]}=#{opt[1]}"
62
+ collection
63
+ end * '&'
64
+ end
65
+
66
+ def to_uri(path, options)
67
+ uri = URI.parse(path)
68
+
69
+ if options && options != {}
70
+ uri.query = to_query(options)
71
+ end
72
+ uri.to_s
73
+ end
74
+ end
75
+
76
+ end
77
+ 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,34 @@
1
+ module LinkedIn
2
+
3
+ module Search
4
+
5
+ def search(options={})
6
+ path = "/people-search"
7
+
8
+ options = { :keywords => options } if options.is_a?(String)
9
+ options = format_options_for_query(options)
10
+
11
+ result_json = get(to_uri(path, options))
12
+
13
+ Mash.from_json(result_json)
14
+ end
15
+
16
+ private
17
+
18
+ def format_options_for_query(opts)
19
+ opts.inject({}) do |list, kv|
20
+ key, value = kv.first.to_s.gsub("_","-"), kv.last
21
+ list[key] = sanatize_value(value)
22
+ list
23
+ end
24
+ end
25
+
26
+ def sanatize_value(value)
27
+ value = value.join("+") if value.is_a?(Array)
28
+ value = value.gsub(" ", "+") if value.is_a?(String)
29
+ value
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,11 @@
1
+ module LinkedIn
2
+
3
+ module VERSION #:nodoc:
4
+ MAJOR = 0
5
+ MINOR = 3
6
+ PATCH = 1
7
+ PRE = nil
8
+ STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
9
+ end
10
+
11
+ end
data/lib/linkedin.rb CHANGED
@@ -1,26 +1,6 @@
1
1
  require 'oauth'
2
- require 'nokogiri'
3
-
4
- require 'cgi'
5
2
 
6
3
  module LinkedIn
7
- class LinkedInError < StandardError
8
- attr_reader :data
9
-
10
- def initialize(data)
11
- @data = data
12
- super
13
- end
14
- end
15
-
16
- class RateLimitExceeded < LinkedInError; end
17
- class Unauthorized < LinkedInError; end
18
- class General < LinkedInError; end
19
-
20
- class Unavailable < StandardError; end
21
- class InformLinkedIn < StandardError; end
22
- class NotFound < StandardError; end
23
-
24
4
 
25
5
  class << self
26
6
  attr_accessor :token, :secret, :default_profile_fields
@@ -30,6 +10,7 @@ module LinkedIn
30
10
  # LinkedIn.configure do |config|
31
11
  # config.token = 'consumer_token'
32
12
  # config.secret = 'consumer_secret'
13
+ # config.default_profile_fields = ['education', 'positions']
33
14
  # end
34
15
  #
35
16
  # elsewhere
@@ -43,39 +24,7 @@ module LinkedIn
43
24
 
44
25
  end
45
26
 
46
-
47
- require 'linked_in/base'
48
-
49
- require 'linked_in/to_xml_helpers'
50
- require 'linked_in/request_helpers'
51
- require 'linked_in/authorization_helpers'
52
-
53
- require 'linked_in/api_standard_profile_request'
54
- require 'linked_in/url_resource'
55
- require 'linked_in/company'
56
- require 'linked_in/country'
57
- require 'linked_in/education'
58
- require 'linked_in/error'
59
- require 'linked_in/location'
60
- require 'linked_in/position'
61
- require 'linked_in/profile'
62
- require 'linked_in/update'
63
- require 'linked_in/network'
64
- require 'linked_in/people'
65
- require 'linked_in/connections'
27
+ require 'linked_in/mash'
28
+ require 'linked_in/errors'
66
29
  require 'linked_in/client'
67
- require 'linked_in/person'
68
- require 'linked_in/recipient'
69
- require 'linked_in/recipients'
70
- require 'linked_in/message'
71
- require 'linked_in/group'
72
- require 'linked_in/birthdate'
73
- require 'linked_in/recommendations'
74
- require 'linked_in/current_share'
75
- require 'linked_in/short_profile'
76
- require 'linked_in/phone_number'
77
- require 'linked_in/languages'
78
- require 'linked_in/likes'
79
- require 'linked_in/skill'
80
- require 'linked_in/publications'
81
- require 'linked_in/patents'
30
+ require 'linked_in/version'
data/linkedin.gemspec CHANGED
@@ -1,49 +1,28 @@
1
1
  # -*- encoding: utf-8 -*-
2
- Gem::Specification.new do |s|
3
- s.name = %q{linkedin}
4
- s.version = "0.2.2"
5
- s.platform = Gem::Platform::RUBY
6
-
7
- s.authors = ["Wynn Netherland", "Josh Kalderimis"]
8
- s.email = ["wynn.netherland@gmail.com", "josh.kalderimis@gmail.com"]
9
-
10
- s.homepage = %q{http://github.com/pengwynn/linkedin}
11
- s.summary = %q{Ruby wrapper for the LinkedIn API}
12
- s.description = %q{Ruby wrapper for the LinkedIn API}
13
-
14
- s.date = %q{2010-03-01}
15
-
16
- s.rdoc_options = ["--charset=UTF-8"]
17
- s.extra_rdoc_files = ["README.markdown", "LICENSE"]
18
-
19
- s.files = `git ls-files`.split("\n")
20
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
- s.require_paths = ["lib"]
23
-
24
- if s.respond_to? :specification_version then
25
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
- s.specification_version = 3
27
-
28
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
29
- s.add_runtime_dependency(%q<oauth>, ["~> 0.4.0"])
30
- s.add_runtime_dependency(%q<nokogiri>, ["~> 1.4.4"])
31
- s.add_development_dependency(%q<rspec>, ["~> 2.4.0"])
32
- s.add_development_dependency(%q<rake>, ["~> 0.8.7"])
33
- s.add_development_dependency(%q<webmock>, ["~> 1.6.0"])
34
- else
35
- s.add_dependency(%q<oauth>, ["~> 0.4.0"])
36
- s.add_dependency(%q<nokogiri>, ["~> 1.4.4"])
37
- s.add_dependency(%q<rspec>, ["~> 2.4.0"])
38
- s.add_dependency(%q<rake>, ["~> 0.8.7"])
39
- s.add_dependency(%q<webmock>, ["~> 1.6.0"])
40
- end
41
- else
42
- s.add_dependency(%q<oauth>, ["~> 0.4.0"])
43
- s.add_dependency(%q<nokogiri>, ["~> 1.4.4"])
44
- s.add_dependency(%q<rspec>, ["~> 2.4.0"])
45
- s.add_dependency(%q<rake>, ["~> 0.8.7"])
46
- s.add_dependency(%q<webmock>, ["~> 1.6.0"])
47
- end
2
+ require File.expand_path('../lib/linked_in/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.add_development_dependency 'rake', '~> 0.9'
6
+ gem.add_development_dependency 'rdoc', '~> 3.8'
7
+ gem.add_development_dependency 'rspec', '~> 2.6'
8
+ gem.add_development_dependency 'simplecov', '~> 0.4'
9
+ gem.add_development_dependency 'vcr', '~> 1.10'
10
+ gem.add_development_dependency 'webmock', '~> 1.6'
11
+ gem.add_development_dependency 'yajl-ruby', '~> 0.8'
12
+
13
+ gem.add_runtime_dependency 'hashie', '~> 1.0.0'
14
+ gem.add_runtime_dependency 'multi_json', '~> 1.0.3'
15
+ gem.add_runtime_dependency 'oauth', '~> 0.4.5'
16
+
17
+ gem.authors = ["Wynn Netherland", "Josh Kalderimis"]
18
+ gem.description = %q{Ruby wrapper for the LinkedIn API}
19
+ gem.email = ['wynn.netherland@gmail.com', 'josh.kalderimis@gmail.com']
20
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ gem.files = `git ls-files`.split("\n")
22
+ gem.homepage = 'http://github.com/pengwynn/linkedin'
23
+ gem.name = 'linkedin'
24
+ gem.require_paths = ['lib']
25
+ gem.summary = gem.description
26
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ gem.version = LinkedIn::VERSION::STRING
48
28
  end
49
-
@@ -1,281 +1,265 @@
1
- require 'spec_helper'
1
+ require 'helper'
2
2
 
3
3
  describe LinkedIn::Client do
4
- context "when hitting the LinkedIn API" do
5
- before(:each) do
6
- LinkedIn.token = nil
7
- LinkedIn.secret = nil
8
- LinkedIn.default_profile_fields = nil
9
- end
10
4
 
11
- let(:client) do
12
- client = LinkedIn::Client.new('token', 'secret')
13
- consumer = OAuth::Consumer.new('token', 'secret', {:site => 'https://api.linkedin.com'})
14
- client.stub(:consumer).and_return(consumer)
15
- client.authorize_from_access('atoken', 'asecret')
16
- client
17
- end
5
+ # context "when hitting the LinkedIn API" do
6
+ #
7
+ # before(:each) do
8
+ # LinkedIn.token = nil
9
+ # LinkedIn.secret = nil
10
+ # LinkedIn.default_profile_fields = nil
11
+ # end
12
+ #
13
+ # let(:client) do
14
+ # client = LinkedIn::Client.new('token', 'secret')
15
+ # consumer = OAuth::Consumer.new('token', 'secret', {:site => 'https://api.linkedin.com'})
16
+ # client.stub(:consumer).and_return(consumer)
17
+ # client.authorize_from_access('atoken', 'asecret')
18
+ # client
19
+ # end
20
+ #
21
+ # it "should retrieve a profile for the authenticated user" do
22
+ # stub_get("/v1/people/~", "profile_full.xml")
23
+ # client.profile.first_name.should == 'Wynn'
24
+ # client.profile.last_name.should == 'Netherland'
25
+ # end
26
+ #
27
+ # it "should retrieve location information" do
28
+ # stub_get("/v1/people/~", "profile_full.xml")
29
+ # client.profile.location.name.should == 'Dallas/Fort Worth Area'
30
+ # client.profile.location.country.should == 'us'
31
+ # end
32
+ #
33
+ # it "should retrieve positions from a profile" do
34
+ # stub_get("/v1/people/~", "profile_full.xml")
35
+ #
36
+ # client.profile.positions.size.should == 4
37
+ # client.profile.positions.first.company.name.should == 'Orrka'
38
+ # client.profile.positions.first.is_current.should == 'true'
39
+ #
40
+ # hp = client.profile.positions[2]
41
+ # hp.title.should == 'Solution Architect'
42
+ # hp.id.should == '4891362'
43
+ # hp.start_month.should == 10
44
+ # hp.start_year.should == 2004
45
+ # hp.end_month.should == 6
46
+ # hp.end_year.should == 2007
47
+ # hp.is_current.should == 'false'
48
+ # end
49
+ #
50
+ # it "should retrieve education information from a profile" do
51
+ # stub_get("/v1/people/~", "profile_full.xml")
52
+ #
53
+ # education = client.profile.educations.first
54
+ # education.start_month.should == 8
55
+ # education.start_year.should == 1994
56
+ # education.end_month.should == 5
57
+ # education.end_year.should == 1998
58
+ # end
59
+ #
60
+ # it "should retrieve information about a profiles connections" do
61
+ # stub_get("/v1/people/~", "profile_full.xml")
62
+ #
63
+ # client.profile.connections.size.should == 146
64
+ # client.profile.connections.first.first_name.should == "Ali"
65
+ # end
66
+ #
67
+ # it "should retrieve a profiles member_url_resources" do
68
+ # stub_get("/v1/people/~", "profile_full.xml")
69
+ #
70
+ # client.profile.member_url_resources.size.should == 2
71
+ # client.profile.member_url_resources.first.url.should == 'http://orrka.com'
72
+ # client.profile.member_url_resources.first.name.should == 'My Company'
73
+ # end
74
+ #
75
+ # it "should retrieve a profiles connections api_standard_profile_request" do
76
+ # stub_get("/v1/people/~", "profile_full.xml")
77
+ #
78
+ # p1 = client.profile.connections.first
79
+ # p1.api_standard_profile_request.url.should == 'http://api.linkedin.com/v1/people/3YNlBdusZ5:full'
80
+ # p1.api_standard_profile_request.headers[:name].should == 'x-li-auth-token'
81
+ # p1.api_standard_profile_request.headers[:value].should == 'name:lui9'
82
+ # end
83
+ #
84
+ # it "should retrieve a profile for a member by id" do
85
+ # stub_get("/v1/people/id=gNma67_AdI", "profile.xml")
86
+ #
87
+ # profile = client.profile(:id => "gNma67_AdI")
88
+ # profile.first_name.should == 'Wynn'
89
+ # end
90
+ #
91
+ # it "should retrieve a site_standard_profile_request" do
92
+ # stub_get("/v1/people/~", "profile.xml")
93
+ #
94
+ # client.profile.site_standard_profile_request.should == "http://www.linkedin.com/profile?viewProfile=&key=3559698&authToken=yib-&authType=name"
95
+ # end
96
+ #
97
+ # it "should retrieve a profile for a member by url" do
98
+ # stub_get("/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Fnetherland", "profile.xml")
99
+ #
100
+ # profile = client.profile(:url => "http://www.linkedin.com/in/netherland")
101
+ # profile.last_name.should == 'Netherland'
102
+ # end
103
+ #
104
+ # it "should accept field selectors when retrieving a profile" do
105
+ # stub_get("/v1/people/~:(first-name,last-name)", "profile.xml")
106
+ #
107
+ # profile = client.profile(:fields => [:first_name, :last_name])
108
+ # profile.first_name.should == 'Wynn'
109
+ # profile.last_name.should == 'Netherland'
110
+ # end
111
+ #
112
+ # it "should retrieve connections for the authenticated user" do
113
+ # stub_get("/v1/people/~/connections", "connections.xml")
114
+ #
115
+ # cons = client.connections
116
+ # cons.size.should == 146
117
+ # cons.last.last_name.should == 'Yuchnewicz'
118
+ # end
119
+ #
120
+ # it "should perform a search by keyword" do
121
+ # stub_get("/v1/people?keywords=github", "search.xml")
122
+ #
123
+ # results = client.search(:keywords => 'github')
124
+ # results.start.should == 0
125
+ # results.count.should == 10
126
+ # results.profiles.first.first_name.should == 'Zach'
127
+ # results.profiles.first.last_name.should == 'Inglis'
128
+ # end
129
+ #
130
+ # it "should perform a search by multiple keywords" do
131
+ # stub_get("/v1/people?keywords=ruby+rails", "search.xml")
132
+ #
133
+ # results = client.search(:keywords => ["ruby", "rails"])
134
+ # results.start.should == 0
135
+ # results.count.should == 10
136
+ # results.profiles.first.first_name.should == 'Zach'
137
+ # results.profiles.first.last_name.should == 'Inglis'
138
+ # end
139
+ #
140
+ # it "should perform a search by name" do
141
+ # stub_get("/v1/people?name=Zach+Inglis", "search.xml")
142
+ #
143
+ # results = client.search(:name => "Zach Inglis")
144
+ # results.start.should == 0
145
+ # results.count.should == 10
146
+ # results.profiles.first.first_name.should == 'Zach'
147
+ # results.profiles.first.last_name.should == 'Inglis'
148
+ # end
149
+ #
150
+ # it "should update a user's current status" do
151
+ # stub_put("/v1/people/~/current-status", "blank.xml")
152
+ #
153
+ # client.update_status("Testing out the LinkedIn API").code.should == "200"
154
+ # end
155
+ #
156
+ # it "should post to a user's network stream" do
157
+ # stub_post("/v1/people/~/person-activities", "blank.xml")
158
+ #
159
+ # client.update_network("Testing out the LinkedIn API").code.should == "201"
160
+ # end
161
+ #
162
+ # it "should clear a user's current status" do
163
+ # stub_delete("/v1/people/~/current-status", "blank.xml")
164
+ #
165
+ # client.clear_status.should == "200"
166
+ # end
167
+ #
168
+ # it "should retrieve the authenticated user's current status" do
169
+ # stub_get("/v1/people/~/current-status", "status.xml")
170
+ #
171
+ # client.current_status.should == "New blog post: What makes a good API wrapper? http://wynnnetherland.com/2009/11/what-makes-a-good-api-wrapper/"
172
+ # end
173
+ #
174
+ # it "should retrieve status updates for the authenticated user's network" do
175
+ # stub_get("/v1/people/~/network?type=STAT", "network_statuses.xml")
176
+ #
177
+ # stats = client.network_statuses
178
+ # stats.updates.first.timestamp.should == 1259179809524
179
+ # stats.updates.first.profile.id.should == "19408512"
180
+ # stats.updates.first.profile.first_name.should == 'Vahid'
181
+ # stats.updates.first.profile.connections.first.id.should == "28072758"
182
+ # stats.updates.first.profile.connections.first.last_name.should == 'Varone'
183
+ # end
184
+ #
185
+ # it "should retrieve network updates" do
186
+ # stub_get("/v1/people/~/network?type=PICT", "picture_updates.xml")
187
+ #
188
+ # stats = client.network_updates(:type => "PICT")
189
+ # stats.updates.size.should == 4
190
+ # stats.updates.last.profile.headline.should == "Creative Director for Intridea"
191
+ # end
192
+ #
193
+ # it "should send a message to recipients" do
194
+ # stub_post("/v1/people/~/mailbox", "mailbox_items.xml")
195
+ #
196
+ # recipients = ["~", "abcdefg"]
197
+ # subject = "Congratulations on your new position."
198
+ # body = "You're certainly the best person for the job!"
199
+ #
200
+ # client.send_message(subject, body, recipients).should == "201"
201
+ #
202
+ # expect_post("/v1/people/~/mailbox", "mailbox_items.xml")
203
+ # end
204
+ #
205
+ # it "should share a link" do
206
+ # stub_post("/v1/people/~/shares", "blank.xml")
207
+ #
208
+ # client.share({
209
+ # :comment => "Testing out the LinkedIn API",
210
+ # :title => "Share",
211
+ # :url => "http://www.linkedin.com",
212
+ # :image_url => "http://www.linkedin.com/pretty_logo.jpg"
213
+ # }).code.should == "201"
214
+ #
215
+ # expect_post("/v1/people/~/shares", "shares.xml")
216
+ # end
217
+ #
218
+ # it "should retrieve language information from a profile" do
219
+ # stub_get("/v1/people/~", "profile_full.xml")
220
+ #
221
+ # language = client.profile.languages.last
222
+ # language.name.should == "Klingon"
223
+ # language.id.to_i.should == 72
224
+ # end
225
+ #
226
+ # it "should retrieve skills from a profile" do
227
+ # stub_get("/v1/people/~", "profile_full.xml")
228
+ #
229
+ # skill = client.profile.skills.last
230
+ # skill.name.should == "Union negotiations"
231
+ # skill.id.to_i.should == 38
232
+ # end
233
+ #
234
+ # it "should retrieve phone_number from a profile" do
235
+ # stub_get("/v1/people/~", "profile_full.xml")
236
+ #
237
+ # pn = client.profile.phone_numbers.last
238
+ #
239
+ # pn.phone_type.should == "mobile"
240
+ # pn.phone_number.should == "+444444444444"
241
+ # end
242
+ #
243
+ # it "should retrieve publications from a profile" do
244
+ # stub_get("/v1/people/~", "profile_full.xml")
245
+ #
246
+ # publication = client.profile.publications.last
247
+ #
248
+ # publication.id.to_i.should == 31
249
+ # publication.title.should == "How to host an awesome podcast"
250
+ # publication.date.should == Date.civil(y=2006,m=8,d=1)
251
+ # end
252
+ #
253
+ # it "should retrieve patents from a profile" do
254
+ # stub_get("/v1/people/~", "profile_full.xml")
255
+ #
256
+ # patent = client.profile.patents.last
257
+ #
258
+ # patent.id.to_i.should == 51
259
+ # patent.title.should == "Time machine"
260
+ # patent.date.should == Date.civil(y=2008,m=7,d=23)
261
+ # end
262
+ #
263
+ # end
18
264
 
19
- it "should retrieve a profile for the authenticated user" do
20
- stub_get("/v1/people/~", "profile_full.xml")
21
- client.profile.first_name.should == 'Wynn'
22
- client.profile.last_name.should == 'Netherland'
23
- end
24
-
25
- it "should retrieve location information" do
26
- stub_get("/v1/people/~", "profile_full.xml")
27
- client.profile.location.name.should == 'Dallas/Fort Worth Area'
28
- client.profile.location.country.should == 'us'
29
- end
30
-
31
- it "should retrieve positions from a profile" do
32
- stub_get("/v1/people/~", "profile_full.xml")
33
-
34
- client.profile.positions.size.should == 4
35
- client.profile.positions.first.company.name.should == 'Orrka'
36
- client.profile.positions.first.is_current.should == 'true'
37
-
38
- hp = client.profile.positions[2]
39
- hp.title.should == 'Solution Architect'
40
- hp.id.should == '4891362'
41
- hp.start_month.should == 10
42
- hp.start_year.should == 2004
43
- hp.end_month.should == 6
44
- hp.end_year.should == 2007
45
- hp.is_current.should == 'false'
46
- end
47
-
48
- it "should retrieve education information from a profile" do
49
- stub_get("/v1/people/~", "profile_full.xml")
50
-
51
- education = client.profile.educations.first
52
- education.start_month.should == 8
53
- education.start_year.should == 1994
54
- education.end_month.should == 5
55
- education.end_year.should == 1998
56
- end
57
-
58
- it "should retrieve information about a profiles connections" do
59
- stub_get("/v1/people/~", "profile_full.xml")
60
-
61
- client.profile.connections.size.should == 146
62
- client.profile.connections.first.first_name.should == "Ali"
63
- end
64
-
65
- it "should retrieve a profiles member_url_resources" do
66
- stub_get("/v1/people/~", "profile_full.xml")
67
-
68
- client.profile.member_url_resources.size.should == 2
69
- client.profile.member_url_resources.first.url.should == 'http://orrka.com'
70
- client.profile.member_url_resources.first.name.should == 'My Company'
71
- end
72
-
73
- it "should retrieve a profiles connections api_standard_profile_request" do
74
- stub_get("/v1/people/~", "profile_full.xml")
75
-
76
- p1 = client.profile.connections.first
77
- p1.api_standard_profile_request.url.should == 'http://api.linkedin.com/v1/people/3YNlBdusZ5:full'
78
- p1.api_standard_profile_request.headers[:name].should == 'x-li-auth-token'
79
- p1.api_standard_profile_request.headers[:value].should == 'name:lui9'
80
- end
81
-
82
- it "should retrieve a profile for a member by id" do
83
- stub_get("/v1/people/id=gNma67_AdI", "profile.xml")
84
-
85
- profile = client.profile(:id => "gNma67_AdI")
86
- profile.first_name.should == 'Wynn'
87
- end
88
-
89
- it "should retrieve a site_standard_profile_request" do
90
- stub_get("/v1/people/~", "profile.xml")
91
-
92
- client.profile.site_standard_profile_request.should == "http://www.linkedin.com/profile?viewProfile=&key=3559698&authToken=yib-&authType=name"
93
- end
94
-
95
- it "should retrieve a profile for a member by url" do
96
- stub_get("/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Fnetherland", "profile.xml")
97
-
98
- profile = client.profile(:url => "http://www.linkedin.com/in/netherland")
99
- profile.last_name.should == 'Netherland'
100
- end
101
-
102
- it "should accept field selectors when retrieving a profile" do
103
- stub_get("/v1/people/~:(first-name,last-name)", "profile.xml")
104
-
105
- profile = client.profile(:fields => [:first_name, :last_name])
106
- profile.first_name.should == 'Wynn'
107
- profile.last_name.should == 'Netherland'
108
- end
109
-
110
- it "should retrieve connections for the authenticated user" do
111
- stub_get("/v1/people/~/connections", "connections.xml")
112
-
113
- cons = client.connections
114
- cons.size.should == 146
115
- cons.last.last_name.should == 'Yuchnewicz'
116
- end
117
-
118
- it "should perform a search by keyword" do
119
- stub_get("/v1/people?keywords=github", "search.xml")
120
-
121
- results = client.search(:keywords => 'github')
122
- results.start.should == 0
123
- results.count.should == 10
124
- results.profiles.first.first_name.should == 'Zach'
125
- results.profiles.first.last_name.should == 'Inglis'
126
- end
127
-
128
- it "should perform a search by multiple keywords" do
129
- stub_get("/v1/people?keywords=ruby+rails", "search.xml")
130
-
131
- results = client.search(:keywords => ["ruby", "rails"])
132
- results.start.should == 0
133
- results.count.should == 10
134
- results.profiles.first.first_name.should == 'Zach'
135
- results.profiles.first.last_name.should == 'Inglis'
136
- end
137
-
138
- it "should perform a search by name" do
139
- stub_get("/v1/people?name=Zach+Inglis", "search.xml")
140
-
141
- results = client.search(:name => "Zach Inglis")
142
- results.start.should == 0
143
- results.count.should == 10
144
- results.profiles.first.first_name.should == 'Zach'
145
- results.profiles.first.last_name.should == 'Inglis'
146
- end
147
-
148
- it "should update a user's current status" do
149
- stub_put("/v1/people/~/current-status", "blank.xml")
150
-
151
- client.update_status("Testing out the LinkedIn API").code.should == "200"
152
- end
153
-
154
- it "should post to a user's network stream" do
155
- stub_post("/v1/people/~/person-activities", "blank.xml")
156
-
157
- client.update_network("Testing out the LinkedIn API").code.should == "201"
158
- end
159
-
160
- it "should clear a user's current status" do
161
- stub_delete("/v1/people/~/current-status", "blank.xml")
162
-
163
- client.clear_status.should == "200"
164
- end
165
-
166
- it "should retrieve the authenticated user's current status" do
167
- stub_get("/v1/people/~/current-status", "status.xml")
168
-
169
- client.current_status.should == "New blog post: What makes a good API wrapper? http://wynnnetherland.com/2009/11/what-makes-a-good-api-wrapper/"
170
- end
171
-
172
- it "should retrieve status updates for the authenticated user's network" do
173
- stub_get("/v1/people/~/network?type=STAT", "network_statuses.xml")
174
-
175
- stats = client.network_statuses
176
- stats.updates.first.timestamp.should == 1259179809524
177
- stats.updates.first.should be_is_commentable
178
- stats.updates.first.profile.id.should == "19408512"
179
- stats.updates.first.profile.first_name.should == 'Vahid'
180
- stats.updates.first.profile.connections.first.id.should == "28072758"
181
- stats.updates.first.profile.connections.first.last_name.should == 'Varone'
182
- stats.updates.first.likes.size.should == 2
183
- stats.updates.first.likes.last.profile.first_name.should == 'Napoleon'
184
- stats.updates.last.likes.should be_empty
185
- end
186
-
187
- it "should retrieve network updates" do
188
- stub_get("/v1/people/~/network?type=PICT", "picture_updates.xml")
189
-
190
- stats = client.network_updates(:type => "PICT")
191
- stats.updates.size.should == 4
192
- stats.updates.last.profile.headline.should == "Creative Director for Intridea"
193
- end
194
-
195
- it "should send a message to recipients" do
196
- stub_post("/v1/people/~/mailbox", "mailbox_items.xml")
197
-
198
- recipients = ["~", "abcdefg"]
199
- subject = "Congratulations on your new position."
200
- body = "You're certainly the best person for the job!"
201
-
202
- client.send_message(subject, body, recipients).should == "201"
203
-
204
- expect_post("/v1/people/~/mailbox", "mailbox_items.xml")
205
- end
206
-
207
- it "should share a link" do
208
- stub_post("/v1/people/~/shares", "blank.xml")
209
-
210
- client.share({
211
- :comment => "Testing out the LinkedIn API",
212
- :title => "Share",
213
- :url => "http://www.linkedin.com",
214
- :image_url => "http://www.linkedin.com/pretty_logo.jpg"
215
- }).code.should == "201"
216
-
217
- expect_post("/v1/people/~/shares", "shares.xml")
218
- end
219
-
220
- it "should retrieve language information from a profile" do
221
- stub_get("/v1/people/~", "profile_full.xml")
222
-
223
- language = client.profile.languages.last
224
- language.name.should == "Klingon"
225
- language.id.to_i.should == 72
226
- end
227
-
228
- it "should retrieve skills from a profile" do
229
- stub_get("/v1/people/~", "profile_full.xml")
230
-
231
- skill = client.profile.skills.last
232
- skill.name.should == "Union negotiations"
233
- skill.id.to_i.should == 38
234
- end
235
-
236
- it "should retrieve phone_number from a profile" do
237
- stub_get("/v1/people/~", "profile_full.xml")
238
-
239
- pn = client.profile.phone_numbers.last
240
-
241
- pn.phone_type.should == "mobile"
242
- pn.phone_number.should == "+444444444444"
243
- end
244
-
245
- it "should retrieve publications from a profile" do
246
- stub_get("/v1/people/~", "profile_full.xml")
247
-
248
- publication = client.profile.publications.last
249
-
250
- publication.id.to_i.should == 31
251
- publication.title.should == "How to host an awesome podcast"
252
- publication.date.should == Date.civil(y=2006,m=8,d=1)
253
- end
254
-
255
- it "should retrieve patents from a profile" do
256
- stub_get("/v1/people/~", "profile_full.xml")
257
-
258
- patent = client.profile.patents.last
259
-
260
- patent.id.to_i.should == 51
261
- patent.title.should == "Time machine"
262
- patent.date.should == Date.civil(y=2008,m=7,d=23)
263
- end
264
-
265
- it "should retrieve likes for a network update" do
266
- stub_get("/v1/people/~/network/updates/key=gNma67_AdI/likes","likes.xml")
267
-
268
- likes = client.likes("gNma67_AdI")
269
- likes.size.should == 2
270
- likes.first.profile.first_name.should == "George"
271
- end
272
-
273
- it "should put a like to a network update" do
274
- stub_put("/v1/people/~/network/updates/key=gNma67_AdI/is-liked","blank.xml", 201)
275
-
276
- result = client.like("gNma67_AdI")
277
- result.code.should == "201"
278
- end
279
-
280
- end
281
265
  end