linkedin-oauth2 0.1.1 → 1.0.0

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 (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