linkedin-v2 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +10 -0
- data/CONTRIBUTING.md +1 -0
- data/Gemfile +8 -0
- data/LICENSE +22 -0
- data/README.md +224 -0
- data/Rakefile +19 -0
- data/lib/linked_in/access_token.rb +24 -0
- data/lib/linked_in/api.rb +108 -0
- data/lib/linked_in/api_resource.rb +180 -0
- data/lib/linked_in/communications.rb +40 -0
- data/lib/linked_in/configuration.rb +41 -0
- data/lib/linked_in/connection.rb +35 -0
- data/lib/linked_in/errors.rb +73 -0
- data/lib/linked_in/jobs.rb +11 -0
- data/lib/linked_in/mash.rb +68 -0
- data/lib/linked_in/media.rb +13 -0
- data/lib/linked_in/oauth2.rb +223 -0
- data/lib/linked_in/organizations.rb +217 -0
- data/lib/linked_in/people.rb +151 -0
- data/lib/linked_in/raise_error.rb +28 -0
- data/lib/linked_in/search.rb +70 -0
- data/lib/linked_in/share_and_social_stream.rb +143 -0
- data/lib/linked_in/version.rb +3 -0
- data/lib/linkedin-v2.rb +52 -0
- data/linkedin-v2.gemspec +39 -0
- data/pkg/linkedin-oauth2-2.0.0.gem +0 -0
- data/spec/linked_in/api/api_spec.rb +41 -0
- data/spec/linked_in/api/communications_spec.rb +13 -0
- data/spec/linked_in/api/jobs_spec.rb +33 -0
- data/spec/linked_in/api/organizations_spec.rb +54 -0
- data/spec/linked_in/api/people_spec.rb +191 -0
- data/spec/linked_in/api/search_spec.rb +71 -0
- data/spec/linked_in/api/share_and_social_stream_spec.rb +87 -0
- data/spec/linked_in/configuration_spec.rb +46 -0
- data/spec/linked_in/connection_spec.rb +10 -0
- data/spec/linked_in/module_loading_spec.rb +23 -0
- data/spec/linked_in/oauth/access_token_spec.rb +27 -0
- data/spec/linked_in/oauth/auth_code_spec.rb +86 -0
- data/spec/linked_in/oauth/credentials_spec.rb +96 -0
- data/spec/linked_in/oauth/get_access_token_spec.rb +108 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/vcr_cassettes/access_token_success.yml +99 -0
- data/spec/vcr_cassettes/bad_code.yml +99 -0
- data/spec/vcr_cassettes/organization_data.yml +51 -0
- data/spec/vcr_cassettes/people_picture_urls.yml +52 -0
- data/spec/vcr_cassettes/people_profile_connections_fields.yml +52 -0
- data/spec/vcr_cassettes/people_profile_connections_other.yml +52 -0
- data/spec/vcr_cassettes/people_profile_connections_self.yml +52 -0
- data/spec/vcr_cassettes/people_profile_fields_complex.yml +52 -0
- data/spec/vcr_cassettes/people_profile_fields_simple.yml +52 -0
- data/spec/vcr_cassettes/people_profile_lang_spanish.yml +53 -0
- data/spec/vcr_cassettes/people_profile_multiple_fields.yml +52 -0
- data/spec/vcr_cassettes/people_profile_multiple_uids.yml +52 -0
- data/spec/vcr_cassettes/people_profile_multiple_uids_and_urls.yml +52 -0
- data/spec/vcr_cassettes/people_profile_multiple_urls.yml +52 -0
- data/spec/vcr_cassettes/people_profile_new_connections_fields.yml +52 -0
- data/spec/vcr_cassettes/people_profile_new_connections_other.yml +52 -0
- data/spec/vcr_cassettes/people_profile_new_connections_self.yml +52 -0
- data/spec/vcr_cassettes/people_profile_other_uid.yml +57 -0
- data/spec/vcr_cassettes/people_profile_other_url.yml +54 -0
- data/spec/vcr_cassettes/people_profile_own.yml +57 -0
- data/spec/vcr_cassettes/people_profile_own_secure.yml +53 -0
- data/spec/vcr_cassettes/people_profile_skills.yml +52 -0
- data/spec/vcr_cassettes/unavailable.yml +99 -0
- metadata +285 -0
@@ -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,87 @@
|
|
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
|
+
stub_request(:get, url).to_return(body: '{}')
|
9
|
+
end
|
10
|
+
|
11
|
+
# no longer supported in v2?
|
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 comment's likes" do
|
23
|
+
stub('https://api.linkedin.com/v2/socialActions/urn:li:comment:123/likes')
|
24
|
+
expect(api.likes(urn: 'urn:li:comment:123')).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/v2/shares').to_return(body: '', status: 201)
|
29
|
+
response = api.share(comment: 'Testing, 1, 2, 3')
|
30
|
+
expect(response.status).to eq 201
|
31
|
+
expect(response.body).to eq ''
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns the shares for a person" do
|
35
|
+
stub('https://api.linkedin.com/v2/shares?after=1234&count=35&owners=&q=owners')
|
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 share" do
|
47
|
+
stub_request(:post, 'https://api.linkedin.com/v2/socialActions/urn:li:organization:123/likes')
|
48
|
+
.to_return(body: "", status: 201)
|
49
|
+
response = api.like(urn: 'urn:li:organization:123', object: 'urn:li:share:456', actor: 'urn:li:person:789')
|
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
|
+
|
61
|
+
context 'throttling' do
|
62
|
+
# Not sure what LinkedIn does on a rate limit violation on v2? It's
|
63
|
+
# not documented here:
|
64
|
+
# https://developer.linkedin.com/docs/guide/v2/concepts/rate-limits
|
65
|
+
xit 'throws the right exception' do
|
66
|
+
stub_request(:post, "https://api.linkedin.com/v1/people/~/shares?format=json&oauth2_access_token=#{access_token}")
|
67
|
+
.to_return(
|
68
|
+
body: "{\n \"errorCode\": 0,\n \"message\": \"Throttle limit for calls to this resource is reached.\",\n \"requestId\": \"M784AXE9MJ\",\n \"status\": 403,\n \"timestamp\": 1412871058321\n}",
|
69
|
+
status: 403
|
70
|
+
)
|
71
|
+
|
72
|
+
err_msg = LinkedIn::ErrorMessages.throttled
|
73
|
+
expect {
|
74
|
+
api.share(:comment => 'Testing, 1, 2, 3')
|
75
|
+
}.to raise_error(LinkedIn::AccessDeniedError, err_msg)
|
76
|
+
|
77
|
+
error = nil
|
78
|
+
begin
|
79
|
+
api.add_share(:comment => "Testing, 1, 2, 3")
|
80
|
+
rescue => e
|
81
|
+
error = e
|
82
|
+
end
|
83
|
+
|
84
|
+
expect(error.data["status"]).to eq 403
|
85
|
+
end
|
86
|
+
end
|
87
|
+
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-v2' }.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
|