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