linkedin-oauth2 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +9 -9
  2. data/.gitignore +24 -39
  3. data/.travis.yml +4 -4
  4. data/.yardopts +2 -0
  5. data/CHANGELOG.md +10 -0
  6. data/CONTRIBUTING.md +1 -0
  7. data/Gemfile +6 -5
  8. data/LICENSE +19 -17
  9. data/README.md +399 -0
  10. data/Rakefile +15 -22
  11. data/lib/linked_in/access_token.rb +24 -0
  12. data/lib/linked_in/api.rb +96 -3
  13. data/lib/linked_in/api_resource.rb +165 -0
  14. data/lib/linked_in/communications.rb +40 -0
  15. data/lib/linked_in/companies.rb +146 -0
  16. data/lib/linked_in/configuration.rb +41 -0
  17. data/lib/linked_in/connection.rb +31 -0
  18. data/lib/linked_in/errors.rb +33 -13
  19. data/lib/linked_in/groups.rb +116 -0
  20. data/lib/linked_in/jobs.rb +68 -0
  21. data/lib/linked_in/mash.rb +34 -34
  22. data/lib/linked_in/oauth2.rb +223 -0
  23. data/lib/linked_in/people.rb +141 -0
  24. data/lib/linked_in/search.rb +58 -43
  25. data/lib/linked_in/share_and_social_stream.rb +128 -0
  26. data/lib/linked_in/version.rb +1 -9
  27. data/lib/linkedin-oauth2.rb +43 -25
  28. data/linkedin-oauth2.gemspec +35 -21
  29. data/spec/linked_in/api/api_spec.rb +41 -0
  30. data/spec/linked_in/api/communications_spec.rb +13 -0
  31. data/spec/linked_in/api/companies_spec.rb +59 -0
  32. data/spec/linked_in/api/groups_spec.rb +55 -0
  33. data/spec/linked_in/api/jobs_spec.rb +33 -0
  34. data/spec/linked_in/api/people_spec.rb +181 -0
  35. data/spec/linked_in/api/search_spec.rb +71 -0
  36. data/spec/linked_in/api/share_and_social_stream_spec.rb +60 -0
  37. data/spec/linked_in/configuration_spec.rb +46 -0
  38. data/spec/linked_in/connection_spec.rb +10 -0
  39. data/spec/linked_in/module_loading_spec.rb +23 -0
  40. data/spec/linked_in/oauth/access_token_spec.rb +27 -0
  41. data/spec/linked_in/oauth/auth_code_spec.rb +86 -0
  42. data/spec/linked_in/oauth/credentials_spec.rb +96 -0
  43. data/spec/linked_in/oauth/get_access_token_spec.rb +108 -0
  44. data/spec/spec_helper.rb +15 -0
  45. data/spec/vcr_cassettes/access_token_success.yml +84 -0
  46. data/spec/vcr_cassettes/bad_code.yml +78 -0
  47. data/spec/vcr_cassettes/companies_data.yml +44 -0
  48. data/spec/vcr_cassettes/invalid_access_token.yml +60 -0
  49. data/spec/vcr_cassettes/not_found.yml +64 -0
  50. data/spec/vcr_cassettes/people_picture_urls.yml +54 -0
  51. data/spec/vcr_cassettes/people_profile_connections_fields.yml +73 -0
  52. data/spec/vcr_cassettes/people_profile_connections_other.yml +78 -0
  53. data/spec/vcr_cassettes/people_profile_connections_self.yml +78 -0
  54. data/spec/vcr_cassettes/people_profile_fields_complex.yml +70 -0
  55. data/spec/vcr_cassettes/people_profile_fields_simple.yml +57 -0
  56. data/spec/vcr_cassettes/people_profile_lang_spanish.yml +59 -0
  57. data/spec/vcr_cassettes/people_profile_multiple_fields.yml +68 -0
  58. data/spec/vcr_cassettes/people_profile_multiple_uids.yml +70 -0
  59. data/spec/vcr_cassettes/people_profile_multiple_uids_and_urls.yml +76 -0
  60. data/spec/vcr_cassettes/people_profile_multiple_urls.yml +70 -0
  61. data/spec/vcr_cassettes/people_profile_new_connections_fields.yml +69 -0
  62. data/spec/vcr_cassettes/people_profile_new_connections_other.yml +72 -0
  63. data/spec/vcr_cassettes/people_profile_new_connections_self.yml +72 -0
  64. data/spec/vcr_cassettes/people_profile_other_uid.yml +59 -0
  65. data/spec/vcr_cassettes/people_profile_other_url.yml +59 -0
  66. data/spec/vcr_cassettes/people_profile_own.yml +59 -0
  67. data/spec/vcr_cassettes/people_profile_own_secure.yml +59 -0
  68. data/spec/vcr_cassettes/unauthorized.yml +61 -0
  69. data/spec/vcr_cassettes/unavailable.yml +81 -0
  70. metadata +145 -88
  71. data/.autotest +0 -14
  72. data/.document +0 -5
  73. data/.gemtest +0 -0
  74. data/.rspec +0 -1
  75. data/.ruby-gemset +0 -1
  76. data/.ruby-version +0 -1
  77. data/README.markdown +0 -121
  78. data/changelog.markdown +0 -94
  79. data/examples/authenticate.rb +0 -16
  80. data/examples/network.rb +0 -12
  81. data/examples/profile.rb +0 -18
  82. data/examples/sinatra.rb +0 -69
  83. data/examples/status.rb +0 -6
  84. data/lib/linked_in/api/query_methods.rb +0 -123
  85. data/lib/linked_in/api/update_methods.rb +0 -76
  86. data/lib/linked_in/client.rb +0 -31
  87. data/lib/linked_in/helpers.rb +0 -6
  88. data/lib/linked_in/helpers/authorization.rb +0 -106
  89. data/lib/linked_in/helpers/request.rb +0 -93
  90. data/spec/cases/api_spec.rb +0 -192
  91. data/spec/cases/linkedin_spec.rb +0 -37
  92. data/spec/cases/mash_spec.rb +0 -85
  93. data/spec/cases/oauth_spec.rb +0 -130
  94. data/spec/cases/search_spec.rb +0 -190
  95. data/spec/helper.rb +0 -30
@@ -1,76 +0,0 @@
1
- module LinkedIn
2
- module Api
3
-
4
- module UpdateMethods
5
-
6
- def add_share(share)
7
- path = "/people/~/shares"
8
- defaults = {:visibility => {:code => "anyone"}}
9
- post(path, defaults.merge(share).to_json, "Content-Type" => "application/json")
10
- end
11
-
12
- def join_group(group_id)
13
- path = "/people/~/group-memberships/#{group_id}"
14
- body = {'membership-state' => {'code' => 'member' }}
15
- put(path, body.to_json, "Content-Type" => "application/json")
16
- end
17
-
18
- def add_job_bookmark(bookmark)
19
- path = "/people/~/job-bookmarks"
20
- body = {'job' => {'id' => bookmark}}
21
- post(path, body.to_json, "Content-Type" => "application/json")
22
- end
23
-
24
- # def share(options={})
25
- # path = "/people/~/shares"
26
- # defaults = { :visability => 'anyone' }
27
- # post(path, share_to_xml(defaults.merge(options)))
28
- # end
29
- #
30
- def update_comment(network_key, comment)
31
- path = "/people/~/network/updates/key=#{network_key}/update-comments"
32
- body = {'comment' => comment}
33
- post(path, body.to_json, "Content-Type" => "application/json")
34
- end
35
- #
36
- # def update_network(message)
37
- # path = "/people/~/person-activities"
38
- # post(path, network_update_to_xml(message))
39
- # end
40
- #
41
-
42
- def like_share(network_key)
43
- path = "/people/~/network/updates/key=#{network_key}/is-liked"
44
- put(path, 'true', "Content-Type" => "application/json")
45
- end
46
-
47
- def unlike_share(network_key)
48
- path = "/people/~/network/updates/key=#{network_key}/is-liked"
49
- put(path, 'false', "Content-Type" => "application/json")
50
- end
51
-
52
- def send_message(subject, body, recipient_paths)
53
- path = "/people/~/mailbox"
54
-
55
- message = {
56
- 'subject' => subject,
57
- 'body' => body,
58
- 'recipients' => {
59
- 'values' => recipient_paths.map do |profile_path|
60
- { 'person' => { '_path' => "/people/#{profile_path}" } }
61
- end
62
- }
63
- }
64
- post(path, message.to_json, "Content-Type" => "application/json")
65
- end
66
- #
67
- # def clear_status
68
- # path = "/people/~/current-status"
69
- # delete(path).code
70
- # end
71
- #
72
-
73
- end
74
-
75
- end
76
- end
@@ -1,31 +0,0 @@
1
- require 'cgi'
2
-
3
- module LinkedIn
4
-
5
- class Client
6
- include Helpers::Request
7
- include Helpers::Authorization
8
- include Api::QueryMethods
9
- include Api::UpdateMethods
10
- include Search
11
-
12
- attr_reader :client_id, :client_secret, :access_token
13
-
14
- # The first two arguments must be your client_id, and client_secret.
15
- # The third option may either be an access_token or an options hash.
16
- def initialize(client_id=LinkedIn.client_id,
17
- client_secret=LinkedIn.client_secret,
18
- initial_access_token=nil,
19
- options={})
20
- @client_id = client_id
21
- @client_secret = client_secret
22
- if initial_access_token.is_a? Hash
23
- @client_options = initial_access_token
24
- else
25
- @client_options = options
26
- self.set_access_token initial_access_token
27
- end
28
- end
29
- end
30
-
31
- end
@@ -1,6 +0,0 @@
1
- module LinkedIn
2
- module Helpers
3
- autoload :Authorization, "linked_in/helpers/authorization"
4
- autoload :Request, "linked_in/helpers/request"
5
- end
6
- end
@@ -1,106 +0,0 @@
1
-
2
- # TODO
3
- # `consumer` renamed to `client`
4
- #
5
- # rename OAuth to OAuth2
6
- #
7
- # deprecate `request_token`
8
- # deprecate `access_token`
9
- #
10
- # deprecate `authorize_from_request`
11
- # deprecate `authorize_from_access`
12
- #
13
- # cleanup bottom
14
- # deprecate `oauth_callback`
15
- #
16
- # DONE
17
- # `consumer_token renamed to `client_id`
18
- # `consumer_secret renamed to `client_secret`
19
- # request_token_url is deprecated. Replaced with token_url
20
- # access_token_url is deprecated. Replaced with token_url
21
- # request_token_path is deprecated
22
- # access_token_path has changed
23
- # authorize_path has been deprecated
24
-
25
- module LinkedIn
26
- module Helpers
27
-
28
- module Authorization
29
-
30
- DEFAULT_OAUTH2_OPTIONS = {
31
- authorize_path: "/uas/oauth2/authorization",
32
- access_token_path: "/uas/oauth2/accessToken",
33
- api_host: "https://api.linkedin.com",
34
- auth_host: "https://www.linkedin.com"
35
- }
36
-
37
- def oauth2_client
38
- @oauth2_client ||= ::OAuth2::Client.new(@client_id,
39
- @client_secret,
40
- parse_oauth2_options)
41
- end
42
-
43
- # A way to fetch the authorize_url
44
- # @param :redirect_uri - Where you want it to redirect to after
45
- # @param :scope - A list of member permissions you would like to
46
- # request.
47
- def authorize_url(params={})
48
- # response_type param included by default by using the OAuth 2.0
49
- # auth_code strategy
50
- # client_id param included automatically by the OAuth 2.0 gem
51
- params[:state] ||= state
52
- params[:redirect_uri] ||= "http://localhost"
53
- oauth2_client.auth_code.authorize_url(params)
54
- rescue OAuth2::Error => e
55
- raise LinkedIn::Errors::UnauthorizedError.new(e.code), e.description
56
- end
57
-
58
- # Fetches the access_token given the auth_code fetched by
59
- # navigating to `authorize_url`
60
- # @param :redirect_uri - Where you want to redirect after you have
61
- # fetched the token.
62
- def request_access_token(code, params={})
63
- params[:redirect_uri] ||= "http://localhost"
64
- opts = {}
65
- opts[:mode] = :query
66
- opts[:param_name] = "oauth2_access_token"
67
- @access_token = oauth2_client.auth_code.get_token(code, params, opts)
68
- rescue OAuth2::Error => e
69
- raise LinkedIn::Errors::UnauthorizedError.new(e.code), e.description
70
- end
71
-
72
- # If one already has an access_token string, it can be set here and
73
- # turned into an OAuth2::AccessToken object.
74
- def set_access_token(token, options={})
75
- options[:access_token] = token
76
- options[:mode] = :query
77
- options[:param_name] = "oauth2_access_token"
78
- @access_token = OAuth2::AccessToken.from_hash oauth2_client, options
79
- end
80
-
81
- # NOTE: There is an attr_reader for :access_token.
82
-
83
- private
84
-
85
- # The keys of this hash are designed to match the OAuth2
86
- # initialize spec.
87
- def parse_oauth2_options
88
- default = {site: DEFAULT_OAUTH2_OPTIONS[:api_host],
89
- token_url: full_oauth_url_for(:access_token, :auth_host),
90
- authorize_url: full_oauth_url_for(:authorize, :auth_host)}
91
- return default.merge(@client_options)
92
- end
93
-
94
- def full_oauth_url_for(url_type, host_type)
95
- host = DEFAULT_OAUTH2_OPTIONS[host_type]
96
- path = DEFAULT_OAUTH2_OPTIONS["#{url_type}_path".to_sym]
97
- "#{host}#{path}"
98
- end
99
-
100
- def state
101
- o = [('a'..'z'),('A'..'Z')].map{|i| i.to_a}.flatten
102
- @state ||= (0...50).map{ o[rand(o.length)] }.join
103
- end
104
- end
105
- end
106
- end
@@ -1,93 +0,0 @@
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}", headers: DEFAULT_HEADERS.merge(options))
16
- raise_errors(response)
17
- response.body
18
- rescue OAuth2::Error => e
19
- raise LinkedIn::Errors::AccessDeniedError.new(e.code), e.description
20
- end
21
-
22
- def post(path, body='', options={})
23
- response = access_token.post("#{API_PATH}#{path}", body: body, headers: DEFAULT_HEADERS.merge(options))
24
- raise_errors(response)
25
- response
26
- rescue OAuth2::Error => e
27
- raise LinkedIn::Errors::AccessDeniedError.new(e.code), e.description
28
- end
29
-
30
- def put(path, body, options={})
31
- response = access_token.put("#{API_PATH}#{path}", body: body, headers: DEFAULT_HEADERS.merge(options))
32
- raise_errors(response)
33
- response
34
- rescue OAuth2::Error => e
35
- raise LinkedIn::Errors::AccessDeniedError.new(e.code), e.description
36
- end
37
-
38
- def delete(path, options={})
39
- response = access_token.delete("#{API_PATH}#{path}", headers: DEFAULT_HEADERS.merge(options))
40
- raise_errors(response)
41
- response
42
- rescue OAuth2::Error => e
43
- raise LinkedIn::Errors::AccessDeniedError.new(e.code), e.description
44
- end
45
-
46
- private
47
-
48
- def raise_errors(response)
49
- # Even if the json answer contains the HTTP status code, LinkedIn also sets this status
50
- # in the HTTP answer (thankfully).
51
- case response.status.to_i
52
- when 401
53
- data = Mash.from_json(response.body)
54
- raise LinkedIn::Errors::UnauthorizedError.new(data), "(#{data.status}): #{data.message}"
55
- when 400
56
- data = Mash.from_json(response.body)
57
- raise LinkedIn::Errors::GeneralError.new(data), "(#{data.status}): #{data.message}"
58
- when 403
59
- data = Mash.from_json(response.body)
60
- raise LinkedIn::Errors::AccessDeniedError.new(data), "(#{data.status}): #{data.message}"
61
- when 404
62
- raise LinkedIn::Errors::NotFoundError, "(#{response.status}): #{response.message}"
63
- when 500
64
- raise LinkedIn::Errors::InformLinkedInError, "LinkedIn had an internal error. Please let them know in the forum. (#{response.status}): #{response.message}"
65
- when 502..503
66
- raise LinkedIn::Errors::UnavailableError, "(#{response.status}): #{response.message}"
67
- end
68
- end
69
-
70
-
71
- # Stolen from Rack::Util.build_query
72
- def to_query(params)
73
- params.map { |k, v|
74
- if v.class == Array
75
- to_query(v.map { |x| [k, x] })
76
- else
77
- v.nil? ? escape(k) : "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"
78
- end
79
- }.join("&")
80
- end
81
-
82
- def to_uri(path, options)
83
- uri = URI.parse(path)
84
-
85
- if options && options != {}
86
- uri.query = to_query(options)
87
- end
88
- uri.to_s
89
- end
90
- end
91
-
92
- end
93
- end
@@ -1,192 +0,0 @@
1
- require 'helper'
2
-
3
- describe LinkedIn::Api do
4
- before do
5
- LinkedIn.default_profile_fields = nil
6
- end
7
-
8
- let(:client){LinkedIn::Client.new('stub_client_id',
9
- 'stub_client_secret',
10
- 'stub_access_token')}
11
-
12
- it "should be able to view the account profile" do
13
- stub_request(:get, "https://api.linkedin.com/v1/people/~?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
14
- client.profile.should be_an_instance_of(LinkedIn::Mash)
15
- end
16
-
17
- it "should be able to view public profiles" do
18
- stub_request(:get, "https://api.linkedin.com/v1/people/id=123?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
19
- client.profile(:id => 123).should be_an_instance_of(LinkedIn::Mash)
20
- end
21
-
22
- it "should be able to view connections" do
23
- stub_request(:get, "https://api.linkedin.com/v1/people/~/connections?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
24
- client.connections.should be_an_instance_of(LinkedIn::Mash)
25
- end
26
-
27
- it "should be able to view network_updates" do
28
- stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
29
- client.network_updates.should be_an_instance_of(LinkedIn::Mash)
30
- end
31
-
32
- it "should be able to view network_update's comments" do
33
- stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates/key=network_update_key/update-comments?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
34
- client.share_comments("network_update_key").should be_an_instance_of(LinkedIn::Mash)
35
- end
36
-
37
- it "should be able to view network_update's likes" do
38
- stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates/key=network_update_key/likes?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
39
- client.share_likes("network_update_key").should be_an_instance_of(LinkedIn::Mash)
40
- end
41
-
42
- it "should be able to search with a keyword if given a String" do
43
- stub_request(:get, "https://api.linkedin.com/v1/people-search?keywords=business&oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
44
- client.search("business").should be_an_instance_of(LinkedIn::Mash)
45
- end
46
-
47
- it "should be able to search with an option" do
48
- stub_request(:get, "https://api.linkedin.com/v1/people-search?first-name=Javan&oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
49
- client.search(:first_name => "Javan").should be_an_instance_of(LinkedIn::Mash)
50
- end
51
-
52
- it "should be able to search with an option and fetch specific fields" do
53
- stub_request(:get, "https://api.linkedin.com/v1/people-search:(num-results,total)?first-name=Javan&oauth2_access_token=#{client.access_token.token}").to_return(
54
- :body => "{}")
55
- client.search(:first_name => "Javan", :fields => ["num_results", "total"]).should be_an_instance_of(LinkedIn::Mash)
56
- end
57
-
58
- it "should be able to share a new status" do
59
- stub_request(:post, "https://api.linkedin.com/v1/people/~/shares?oauth2_access_token=#{client.access_token.token}").to_return(:body => "", :status => 201)
60
- response = client.add_share(:comment => "Testing, 1, 2, 3")
61
- response.body.should == ""
62
- response.status.should == 201
63
- end
64
-
65
- it "should be able to comment on network update" do
66
- stub_request(:post, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/update-comments?oauth2_access_token=#{client.access_token.token}").to_return(
67
- :body => "", :status => 201)
68
- response = client.update_comment('SOMEKEY', "Testing, 1, 2, 3")
69
- response.body.should == ""
70
- response.status.should == 201
71
- end
72
-
73
- it "should be able to send a message" do
74
- stub_request(:post, "https://api.linkedin.com/v1/people/~/mailbox?oauth2_access_token=#{client.access_token.token}").to_return(:body => "", :status => 201)
75
- response = client.send_message("subject", "body", ["recip1", "recip2"])
76
- response.body.should == ""
77
- response.status.should == 201
78
- end
79
-
80
- it "should be able to like a network update" do
81
- stub_request(:put, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/is-liked?oauth2_access_token=#{client.access_token.token}").
82
- with(:body => "true").to_return(:body => "", :status => 201)
83
- response = client.like_share('SOMEKEY')
84
- response.body.should == ""
85
- response.status.should == 201
86
- end
87
-
88
- it "should be able to unlike a network update" do
89
- stub_request(:put, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/is-liked?oauth2_access_token=#{client.access_token.token}").
90
- with(:body => "false").to_return(:body => "", :status => 201)
91
- response = client.unlike_share('SOMEKEY')
92
- response.body.should == ""
93
- response.status.should == 201
94
- end
95
-
96
- it "should be able to pass down the additional arguments to OAuth's request_access_token" do
97
- #
98
- # stub_request(:post, "https://www.linkedin.com/uas/oauth2/accessToken").with { |r| r.body == "grant_type=authorization_code&code=auth_code&client_id=stub_client_id&client_secret=stub_client_secret&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fcallback" }
99
- #
100
- # access_token = client.request_access_token("auth_code",
101
- # {:redirect_uri => "http://localhost:3000/auth/callback"})
102
-
103
- c = LinkedIn::Client.new('stub_client_id',
104
- 'stub_client_secret',
105
- 'stub_access_token',
106
- {site: "some_other_site"})
107
-
108
- c.oauth2_client.site == "some_other_site"
109
- end
110
-
111
- context "Company API" do
112
- use_vcr_cassette
113
-
114
- it "should be able to view a company profile" do
115
- stub_request(:get, "https://api.linkedin.com/v1/companies/id=1586?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
116
- client.company(:id => 1586).should be_an_instance_of(LinkedIn::Mash)
117
- end
118
-
119
- it "should be able to view a company by universal name" do
120
- stub_request(:get, "https://api.linkedin.com/v1/companies/universal-name=acme?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
121
- client.company(:name => 'acme').should be_an_instance_of(LinkedIn::Mash)
122
- end
123
-
124
- it "should be able to view a company by e-mail domain" do
125
- stub_request(:get, "https://api.linkedin.com/v1/companies?email-domain=acme.com&oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
126
- client.company(:domain => 'acme.com').should be_an_instance_of(LinkedIn::Mash)
127
- end
128
-
129
- it "should load correct company data" do
130
- client.company(:id => 1586).name.should == "Amazon"
131
-
132
- data = client.company(:id => 1586, :fields => %w{ id name industry locations:(address:(city state country-code) is-headquarters) employee-count-range })
133
- data.id.should == 1586
134
- data.name.should == "Amazon"
135
- data.employee_count_range.name.should == "10001+"
136
- data.industry.should == "Internet"
137
- data.locations.all[0].address.city.should == "Seattle"
138
- data.locations.all[0].is_headquarters.should == true
139
- end
140
- end
141
-
142
- context "Job API" do
143
- use_vcr_cassette
144
-
145
- it "should be able to view a job listing" do
146
- stub_request(:get, "https://api.linkedin.com/v1/jobs/id=1586?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
147
- client.job(:id => 1586).should be_an_instance_of(LinkedIn::Mash)
148
- end
149
-
150
- it "should be able to view its job bookmarks" do
151
- stub_request(:get, "https://api.linkedin.com/v1/people/~/job-bookmarks?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
152
- client.job_bookmarks.should be_an_instance_of(LinkedIn::Mash)
153
- end
154
-
155
- it "should be able to view its job suggestion" do
156
- stub_request(:get, "https://api.linkedin.com/v1/people/~/suggestions/job-suggestions?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
157
- client.job_suggestions.should be_an_instance_of(LinkedIn::Mash)
158
- end
159
-
160
- it "should be able to add a bookmark" do
161
- stub_request(:post, "https://api.linkedin.com/v1/people/~/job-bookmarks?oauth2_access_token=#{client.access_token.token}").to_return(:body => "", :status => 201)
162
- response = client.add_job_bookmark(:id => 1452577)
163
- response.body.should == ""
164
- response.status.should == 201
165
- end
166
- end
167
-
168
- context "Group API" do
169
-
170
- it "should be able to list group memberships for a profile" do
171
- stub_request(:get, "https://api.linkedin.com/v1/people/~/group-memberships?oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}")
172
- client.group_memberships.should be_an_instance_of(LinkedIn::Mash)
173
- end
174
-
175
- it "should be able to join a group" do
176
- stub_request(:put, "https://api.linkedin.com/v1/people/~/group-memberships/123?oauth2_access_token=#{client.access_token.token}").to_return(:body => "", :status => 201)
177
-
178
- response = client.join_group(123)
179
- response.body.should == ""
180
- response.status.should == 201
181
- end
182
-
183
- end
184
-
185
- context "errors" do
186
- it "should raise access denied error when linkedin returns 403 status code" do
187
- stub_request(:get, "https://api.linkedin.com/v1/people-search?first-name=javan&oauth2_access_token=#{client.access_token.token}").to_return(:body => "{}", :status => 403)
188
-
189
- expect{ client.search(:first_name => "javan") }.to raise_error(LinkedIn::Errors::AccessDeniedError)
190
- end
191
- end
192
- end