linkedin 0.2.2 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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