linkedin-v2 0.1.3
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.
- 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
|