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
@@ -0,0 +1,71 @@
1
+ require "spec_helper"
2
+
3
+ describe LinkedIn::Search, helpers: :api do
4
+ let(:access_token) {"dummy_access_token"}
5
+ let(:api) {LinkedIn::API.new(access_token)}
6
+
7
+ def stub(url)
8
+ url += "oauth2_access_token=#{access_token}"
9
+ stub_request(:get, url).to_return(body: '{}')
10
+ end
11
+
12
+ it "lets you search for all your contacts" do
13
+ stub("https://api.linkedin.com/v1/people-search?")
14
+ expect(api.search()).to be_kind_of LinkedIn::Mash
15
+ end
16
+
17
+ it "allows a keyword search with no hash" do
18
+ stub("https://api.linkedin.com/v1/people-search?keywords=Proximate%20Harvard&")
19
+ expect(api.search("Proximate Harvard")).to be_kind_of LinkedIn::Mash
20
+ end
21
+
22
+ it "allows a keyword search with the kewywords option" do
23
+ stub("https://api.linkedin.com/v1/people-search?keywords=Proximate%20Harvard&")
24
+ expect(api.search(keywords: "Proximate Harvard")).to be_kind_of LinkedIn::Mash
25
+ end
26
+
27
+ it "lets you search by an attribute" do
28
+ stub("https://api.linkedin.com/v1/people-search?school-name=Olin%20College%20of%20Engineering&")
29
+ expect(api.search(school_name: "Olin College of Engineering")).to be_kind_of LinkedIn::Mash
30
+ end
31
+
32
+ it "combines searches" do
33
+ stub("https://api.linkedin.com/v1/people-search?first-name=Evan&last-name=Morikawa&")
34
+ expect(api.search(first_name: "Evan", last_name: "Morikawa")).to be_kind_of LinkedIn::Mash
35
+ end
36
+
37
+ it "searches for specific fields" do
38
+ stub("https://api.linkedin.com/v1/people-search:(people:(id,first-name,last-name),num-results)?")
39
+ expect(api.search(fields: [{people: ["id", "first-name", "last-name"]}, "num-results"])).to be_kind_of LinkedIn::Mash
40
+ end
41
+
42
+ it "allows you to pass a sort parameter" do
43
+ stub("https://api.linkedin.com/v1/people-search?sort=connections&")
44
+ expect(api.search(sort: "connections")).to be_kind_of LinkedIn::Mash
45
+ end
46
+
47
+ it "it allows start and count parameters" do
48
+ stub("https://api.linkedin.com/v1/people-search?start=10&count=5&")
49
+ expect(api.search(start: 10, count: 5)).to be_kind_of LinkedIn::Mash
50
+ end
51
+
52
+ it "it lets you search by facets" do
53
+ stub("https://api.linkedin.com/v1/people-search:(facets:(code,buckets:(code,name)))?facets=location&")
54
+
55
+ fields = {facets: ["code", {buckets: ["code", "name"]}]}
56
+
57
+ expect(api.search(fields: fields,
58
+ facets: "location")).to be_kind_of LinkedIn::Mash
59
+ end
60
+
61
+ it "lets you search for complex facets" do
62
+ stub("https://api.linkedin.com/v1/people-search:(facets:(code,buckets:(code,name,count)))?facets=location,network&facet=location,us:84&facet=network,F&")
63
+
64
+ fields = {facets: ["code", {buckets: ["code", "name", "count"]}]}
65
+
66
+ expect(api.search(fields: fields,
67
+ facets: "location,network",
68
+ facet: ["location,us:84", "network,F"])
69
+ ).to be_kind_of LinkedIn::Mash
70
+ end
71
+ end
@@ -0,0 +1,60 @@
1
+ require "spec_helper"
2
+
3
+ describe LinkedIn::ShareAndSocialStream do
4
+ let(:access_token) {"dummy_access_token"}
5
+ let(:api) {LinkedIn::API.new(access_token)}
6
+
7
+ def stub(url)
8
+ url += "oauth2_access_token=#{access_token}"
9
+ stub_request(:get, url).to_return(body: '{}')
10
+ end
11
+
12
+ it "should be able to view network_updates" do
13
+ stub("https://api.linkedin.com/v1/people/~/network/updates?")
14
+ expect(api.network_updates).to be_an_instance_of(LinkedIn::Mash)
15
+ end
16
+
17
+ it "should be able to view network_update's comments" do
18
+ stub("https://api.linkedin.com/v1/people/~/network/updates/key=network_update_key/update-comments?")
19
+ expect(api.share_comments("network_update_key")).to be_an_instance_of(LinkedIn::Mash)
20
+ end
21
+
22
+ it "should be able to view network_update's likes" do
23
+ stub("https://api.linkedin.com/v1/people/~/network/updates/key=network_update_key/likes?")
24
+ expect(api.share_likes("network_update_key")).to be_an_instance_of(LinkedIn::Mash)
25
+ end
26
+
27
+ it "should be able to share a new status" do
28
+ stub_request(:post, "https://api.linkedin.com/v1/people/~/shares?oauth2_access_token=#{access_token}").to_return(body: "", status: 201)
29
+ response = api.add_share(:comment => "Testing, 1, 2, 3")
30
+ expect(response.body).to eq ""
31
+ expect(response.status).to eq 201
32
+ end
33
+
34
+ it "returns the shares for a person" do
35
+ stub("https://api.linkedin.com/v1/people/~/network/updates?type=SHAR&scope=self&after=1234&count=35&")
36
+ api.shares(:after => 1234, :count => 35)
37
+ end
38
+
39
+ it "should be able to comment on network update" do
40
+ stub_request(:post, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/update-comments?oauth2_access_token=#{access_token}").to_return(body: "", status: 201)
41
+ response = api.update_comment('SOMEKEY', "Testing, 1, 2, 3")
42
+ expect(response.body).to eq ""
43
+ expect(response.status).to eq 201
44
+ end
45
+
46
+ it "should be able to like a network update" do
47
+ stub_request(:put, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/is-liked?oauth2_access_token=#{access_token}").
48
+ with(:body => "true").to_return(body: "", status: 201)
49
+ response = api.like_share('SOMEKEY')
50
+ expect(response.body).to eq ""
51
+ expect(response.status).to eq 201
52
+ end
53
+
54
+ it "should be able to unlike a network update" do
55
+ stub_request(:put, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/is-liked?oauth2_access_token=#{access_token}").to_return(body: "", status: 201)
56
+ response = api.unlike_share('SOMEKEY')
57
+ expect(response.body).to eq ""
58
+ expect(response.status).to eq 201
59
+ end
60
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe "LinkedIn configuration" do
4
+ let(:config_value) { "Foo Bar" }
5
+
6
+ let(:site) { "https://www.linkedin.com" }
7
+ let(:token_url) { "/uas/oauth2/accessToken" }
8
+ let(:authorize_url) { "/uas/oauth2/authorization" }
9
+
10
+ subject { LinkedIn.config }
11
+
12
+ before(:example) do
13
+ LinkedIn.configure do |config|
14
+ config.client_id = config_value
15
+ config.client_secret = config_value
16
+ end
17
+ end
18
+
19
+ it("has a client_id") do
20
+ expect(subject.client_id).to eq config_value
21
+ end
22
+
23
+ it("has a client_secret") do
24
+ expect(subject.client_secret).to eq config_value
25
+ end
26
+
27
+ it("has an aliased api_key") do
28
+ expect(subject.api_key).to eq config_value
29
+ end
30
+
31
+ it("has an aliased secret_key") do
32
+ expect(subject.secret_key).to eq config_value
33
+ end
34
+
35
+ it("has the correct default site") do
36
+ expect(subject.site).to eq site
37
+ end
38
+
39
+ it("has the correct default token_url") do
40
+ expect(subject.token_url).to eq token_url
41
+ end
42
+
43
+ it("has the correct default authorize_url") do
44
+ expect(subject.authorize_url).to eq authorize_url
45
+ end
46
+ end
@@ -0,0 +1,10 @@
1
+ describe LinkedIn::Connection do
2
+ it "inherits from Faraday::Connection" do
3
+ expect(subject).to be_kind_of Faraday::Connection
4
+ end
5
+
6
+ it "has the correct default url" do
7
+ url = LinkedIn.config.api + LinkedIn.config.api_version
8
+ expect(subject.url_prefix.to_s).to eq url
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkedIn do
4
+ it "is a module" do
5
+ expect(LinkedIn).to be_a Module
6
+ end
7
+
8
+ it "is independently loadable" do
9
+ expect { require 'linkedin-oauth2' }.not_to raise_error
10
+ end
11
+
12
+ describe LinkedIn::OAuth2 do
13
+ it "is a class" do
14
+ expect(LinkedIn::OAuth2).to be_a Class
15
+ end
16
+ end
17
+
18
+ describe LinkedIn::API do
19
+ it "is a class" do
20
+ expect(LinkedIn::API).to be_a Class
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ describe "LinkedIn::AccessToken" do
2
+ let(:tok) {:dummy_access_token}
3
+ let(:expires_in) { 64000 }
4
+ let(:expires_at) { Time.utc(2014,1,1) }
5
+
6
+ context "When just token is set" do
7
+ subject {LinkedIn::AccessToken.new(tok)}
8
+ it("has the token value") { expect(subject.token).to eq tok }
9
+ end
10
+
11
+ context "When only expires_in is set" do
12
+ subject {LinkedIn::AccessToken.new(tok, expires_in)}
13
+ it("set expires_in") {expect(subject.expires_in).to eq expires_in}
14
+ it("calculated expires_at") do
15
+ calc_time = Time.now + expires_in
16
+ diff = subject.expires_at - calc_time
17
+ expect(diff).to be < 1
18
+ end
19
+ end
20
+
21
+ context "When everything is set" do
22
+ subject {LinkedIn::AccessToken.new(tok, expires_in, expires_at)}
23
+ it("set token") { expect(subject.token).to eq tok }
24
+ it("set expires_in") {expect(subject.expires_in).to eq expires_in}
25
+ it("set expires_at") {expect(subject.expires_at).to eq expires_at}
26
+ end
27
+ end
@@ -0,0 +1,86 @@
1
+ require "spec_helper"
2
+ require "uri"
3
+ require "cgi"
4
+
5
+ describe "OAuth2 Auth Code" do
6
+ before(:example) do
7
+ LinkedIn.configure do |config|
8
+ config.client_id = "dummy_client_id"
9
+ config.client_secret = "dummy_client_secret"
10
+ end
11
+ end
12
+ subject { LinkedIn::OAuth2.new }
13
+
14
+ def params(key, opts=nil)
15
+ CGI.parse(URI.parse(subject.auth_code_url(opts)).query)[key][0]
16
+ end
17
+
18
+ context "When no redirect_uri is given" do
19
+ before(:example) do
20
+ LinkedIn.configure { |config| config.redirect_uri = nil }
21
+ end
22
+
23
+ let(:err_msg) { LinkedIn::ErrorMessages.redirect_uri }
24
+
25
+ it "Throws an error" do
26
+ expect {subject.auth_code_url}.to raise_error(LinkedIn::InvalidRequest, err_msg)
27
+ end
28
+ end
29
+
30
+ context "When an auth code url is requested with no options" do
31
+ let(:redirect_uri) { "http://lvh.me:5000" }
32
+ let(:scope) { "r_fullprofile r_emailaddress r_network" }
33
+
34
+ before(:example) do
35
+ LinkedIn.configure do |config|
36
+ config.redirect_uri = redirect_uri
37
+ config.scope = scope
38
+ end
39
+ end
40
+
41
+ it "Returns the client id in the uri" do
42
+ expect(params("client_id")).to eq LinkedIn.config.client_id
43
+ end
44
+
45
+ it "Includes the configured redirect_uri" do
46
+ expect(params("redirect_uri")).to eq redirect_uri
47
+ end
48
+
49
+ it "Includes the configured scope" do
50
+ expect(params("scope")).to eq scope
51
+ end
52
+
53
+ it "Includes an autogenerated state" do
54
+ expect(params("state")).to_not be_nil
55
+ end
56
+ end
57
+
58
+ context "When an auth code url is requested with options" do
59
+ let(:state) { "foobarbaz" }
60
+ let(:scope) { "r_basicprofile rw_nus" }
61
+ let(:redirect_uri) { "https://example.com" }
62
+
63
+ let(:opts) do
64
+ {state: state,
65
+ scope: scope,
66
+ redirect_uri: redirect_uri}
67
+ end
68
+
69
+ it "Returns the client id in the uri" do
70
+ expect(params("client_id", opts)).to eq LinkedIn.config.client_id
71
+ end
72
+
73
+ it "Includes the custom redirect_uri" do
74
+ expect(params("redirect_uri", opts)).to eq redirect_uri
75
+ end
76
+
77
+ it "Includes the custom scope" do
78
+ expect(params("scope", opts)).to eq scope
79
+ end
80
+
81
+ it "Includes the custom state" do
82
+ expect(params("state", opts)).to eq state
83
+ end
84
+ end
85
+
86
+ end
@@ -0,0 +1,96 @@
1
+ require "spec_helper"
2
+
3
+ describe LinkedIn::OAuth2 do
4
+ let(:site) { LinkedIn.config.site }
5
+ let(:token_url) { LinkedIn.config.token_url }
6
+ let(:authorize_url) { LinkedIn.config.authorize_url }
7
+
8
+ let(:client_id) { "dummy_client_id" }
9
+ let(:client_secret) { "dummy_client_secret" }
10
+
11
+ shared_examples "verify client" do
12
+ it "creates a valid oauth object" do
13
+ expect(subject).to be_kind_of(LinkedIn::OAuth2)
14
+ end
15
+ it "is a subclass of OAuth2::Client" do
16
+ expect(subject).to be_kind_of(OAuth2::Client)
17
+ end
18
+ it "assigned the client_id to id" do
19
+ expect(subject.id).to eq client_id
20
+ end
21
+ it "assigned the client_secret to secret" do
22
+ expect(subject.secret).to eq client_secret
23
+ end
24
+ it "assigned the site to site" do
25
+ expect(subject.site).to eq site
26
+ end
27
+ it "assigned the authorize_url option" do
28
+ expect(subject.options[:authorize_url]).to eq authorize_url
29
+ end
30
+ it "assigned the token_url option" do
31
+ expect(subject.options[:token_url]).to eq token_url
32
+ end
33
+ end
34
+
35
+ shared_examples "options take" do
36
+ it "overrides default options" do
37
+ expect(subject.options[:raise_errors]).to eq false
38
+ end
39
+ it "sets new options" do
40
+ expect(subject.options[:new_opt]).to eq "custom option"
41
+ end
42
+ end
43
+
44
+ context "When client credentials exist" do
45
+ before(:example) do
46
+ LinkedIn.configure do |config|
47
+ config.client_id = client_id
48
+ config.client_secret = client_secret
49
+ end
50
+ end
51
+
52
+ include_examples "verify client"
53
+
54
+ let(:options) do
55
+ return {raise_errors: false,
56
+ new_opt: "custom option"}
57
+ end
58
+
59
+ context "When custom options are passed in as first arg" do
60
+ subject do
61
+ LinkedIn::OAuth2.new(options)
62
+ end
63
+ include_examples "options take"
64
+ end
65
+
66
+ context "When custom options are passed in" do
67
+ subject do
68
+ LinkedIn::OAuth2.new(client_id, client_secret, options)
69
+ end
70
+ include_examples "options take"
71
+ end
72
+
73
+ end
74
+
75
+ context "When client credentials do not exist" do
76
+ let(:err_msg) { LinkedIn::ErrorMessages.credentials_missing }
77
+
78
+ before(:example) do
79
+ LinkedIn.configure do |config|
80
+ config.client_id = nil
81
+ config.client_secret = nil
82
+ end
83
+ end
84
+
85
+ it "raises an error" do
86
+ expect { LinkedIn::OAuth2.new }.to raise_error(LinkedIn::InvalidRequest, err_msg)
87
+ end
88
+ end
89
+
90
+ context "When client credentials are passed in" do
91
+ subject { LinkedIn::OAuth2.new(client_id, client_secret) }
92
+
93
+ include_examples "verify client"
94
+ end
95
+
96
+ end
@@ -0,0 +1,108 @@
1
+ require "spec_helper"
2
+
3
+ describe "Get OAuth2 Access Token" do
4
+ code = "dummy_code"
5
+ client_id = "dummy_client_id"
6
+ client_secret = "dummy_client_secret"
7
+ redirect_uri = "http://lvh.me:5000"
8
+
9
+ before(:example) do
10
+ LinkedIn.configure do |config|
11
+ config.client_id = client_id
12
+ config.client_secret = client_secret
13
+ config.redirect_uri = redirect_uri
14
+ end
15
+ end
16
+ subject { LinkedIn::OAuth2.new }
17
+
18
+ shared_examples "Success Access Token Fetch" do |*args|
19
+ it "Returns an access token object" do
20
+ VCR.use_cassette("access token success") do
21
+ expect(subject.get_access_token(*args)).to be_kind_of LinkedIn::AccessToken
22
+ end
23
+ end
24
+
25
+ it "Sets the AcessToken object" do
26
+ VCR.use_cassette("access token success") do
27
+ subject.get_access_token(*args)
28
+ expect(subject.access_token).to be_kind_of LinkedIn::AccessToken
29
+ end
30
+ end
31
+
32
+ it "Generated an access token string" do
33
+ VCR.use_cassette("access token success") do
34
+ subject.get_access_token(*args)
35
+ expect(subject.access_token.token).to be_kind_of String
36
+ end
37
+ end
38
+ end
39
+
40
+ shared_examples "Raises InvalidRequest" do |*args|
41
+ it "Raises InvalidRequest" do
42
+ expect{subject.get_access_token(*args)}.to raise_error(LinkedIn::InvalidRequest, msg)
43
+ end
44
+
45
+ it "Has no AccessToken object set" do
46
+ expect(subject.access_token).to be_nil
47
+ end
48
+ end
49
+
50
+ context "When a auth_code is provided" do
51
+ include_examples "Success Access Token Fetch", code
52
+ end
53
+
54
+ context "When no code is given" do
55
+ let(:msg) {LinkedIn::ErrorMessages.no_auth_code}
56
+ include_examples "Raises InvalidRequest"
57
+ end
58
+
59
+ context "When redirect_uri is not configured and not passed in" do
60
+ before(:example) do
61
+ LinkedIn.configure { |config| config.redirect_uri = nil }
62
+ end
63
+ let(:msg) {LinkedIn::ErrorMessages.redirect_uri}
64
+ include_examples "Raises InvalidRequest", code
65
+ end
66
+
67
+ context "When redirect_uri is configured and not passed in" do
68
+ before(:example) do
69
+ LinkedIn.configure { |config| config.redirect_uri = redirect_uri }
70
+ end
71
+ include_examples "Success Access Token Fetch", code
72
+ end
73
+
74
+ context "When redirect_uri is passed in" do
75
+ include_examples "Success Access Token Fetch", code, {redirect_uri: redirect_uri}
76
+ end
77
+
78
+ context "When redirect_uri was previously set by auth_code_url" do
79
+ before(:example) do
80
+ LinkedIn.configure { |config| config.redirect_uri = nil }
81
+ subject.auth_code_url(redirect_uri: redirect_uri)
82
+ end
83
+ include_examples "Success Access Token Fetch", code
84
+ end
85
+
86
+ context "When redirect_uri does not match previous setting" do
87
+ let(:msg) {LinkedIn::ErrorMessages.redirect_uri_mismatch}
88
+ include_examples "Raises InvalidRequest", code, {redirect_uri: "different"}
89
+ end
90
+
91
+ context "When the service is unavailable" do
92
+ let(:msg) { /temporarily_unavailable/ }
93
+ it "raises an OAuthError" do
94
+ VCR.use_cassette("unavailable") do
95
+ expect {subject.get_access_token(code)}.to raise_error(LinkedIn::OAuthError, msg)
96
+ end
97
+ end
98
+ end
99
+
100
+ context "When the request is invalid" do
101
+ let(:msg) { /invalid_request/ }
102
+ it "raises an OAuthError" do
103
+ VCR.use_cassette("bad code") do
104
+ expect {subject.get_access_token(code)}.to raise_error(LinkedIn::OAuthError, msg)
105
+ end
106
+ end
107
+ end
108
+ end