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.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +10 -0
  3. data/CONTRIBUTING.md +1 -0
  4. data/Gemfile +8 -0
  5. data/LICENSE +22 -0
  6. data/README.md +224 -0
  7. data/Rakefile +19 -0
  8. data/lib/linked_in/access_token.rb +24 -0
  9. data/lib/linked_in/api.rb +108 -0
  10. data/lib/linked_in/api_resource.rb +180 -0
  11. data/lib/linked_in/communications.rb +40 -0
  12. data/lib/linked_in/configuration.rb +41 -0
  13. data/lib/linked_in/connection.rb +35 -0
  14. data/lib/linked_in/errors.rb +73 -0
  15. data/lib/linked_in/jobs.rb +11 -0
  16. data/lib/linked_in/mash.rb +68 -0
  17. data/lib/linked_in/media.rb +13 -0
  18. data/lib/linked_in/oauth2.rb +223 -0
  19. data/lib/linked_in/organizations.rb +217 -0
  20. data/lib/linked_in/people.rb +151 -0
  21. data/lib/linked_in/raise_error.rb +28 -0
  22. data/lib/linked_in/search.rb +70 -0
  23. data/lib/linked_in/share_and_social_stream.rb +143 -0
  24. data/lib/linked_in/version.rb +3 -0
  25. data/lib/linkedin-v2.rb +52 -0
  26. data/linkedin-v2.gemspec +39 -0
  27. data/pkg/linkedin-oauth2-2.0.0.gem +0 -0
  28. data/spec/linked_in/api/api_spec.rb +41 -0
  29. data/spec/linked_in/api/communications_spec.rb +13 -0
  30. data/spec/linked_in/api/jobs_spec.rb +33 -0
  31. data/spec/linked_in/api/organizations_spec.rb +54 -0
  32. data/spec/linked_in/api/people_spec.rb +191 -0
  33. data/spec/linked_in/api/search_spec.rb +71 -0
  34. data/spec/linked_in/api/share_and_social_stream_spec.rb +87 -0
  35. data/spec/linked_in/configuration_spec.rb +46 -0
  36. data/spec/linked_in/connection_spec.rb +10 -0
  37. data/spec/linked_in/module_loading_spec.rb +23 -0
  38. data/spec/linked_in/oauth/access_token_spec.rb +27 -0
  39. data/spec/linked_in/oauth/auth_code_spec.rb +86 -0
  40. data/spec/linked_in/oauth/credentials_spec.rb +96 -0
  41. data/spec/linked_in/oauth/get_access_token_spec.rb +108 -0
  42. data/spec/spec_helper.rb +16 -0
  43. data/spec/vcr_cassettes/access_token_success.yml +99 -0
  44. data/spec/vcr_cassettes/bad_code.yml +99 -0
  45. data/spec/vcr_cassettes/organization_data.yml +51 -0
  46. data/spec/vcr_cassettes/people_picture_urls.yml +52 -0
  47. data/spec/vcr_cassettes/people_profile_connections_fields.yml +52 -0
  48. data/spec/vcr_cassettes/people_profile_connections_other.yml +52 -0
  49. data/spec/vcr_cassettes/people_profile_connections_self.yml +52 -0
  50. data/spec/vcr_cassettes/people_profile_fields_complex.yml +52 -0
  51. data/spec/vcr_cassettes/people_profile_fields_simple.yml +52 -0
  52. data/spec/vcr_cassettes/people_profile_lang_spanish.yml +53 -0
  53. data/spec/vcr_cassettes/people_profile_multiple_fields.yml +52 -0
  54. data/spec/vcr_cassettes/people_profile_multiple_uids.yml +52 -0
  55. data/spec/vcr_cassettes/people_profile_multiple_uids_and_urls.yml +52 -0
  56. data/spec/vcr_cassettes/people_profile_multiple_urls.yml +52 -0
  57. data/spec/vcr_cassettes/people_profile_new_connections_fields.yml +52 -0
  58. data/spec/vcr_cassettes/people_profile_new_connections_other.yml +52 -0
  59. data/spec/vcr_cassettes/people_profile_new_connections_self.yml +52 -0
  60. data/spec/vcr_cassettes/people_profile_other_uid.yml +57 -0
  61. data/spec/vcr_cassettes/people_profile_other_url.yml +54 -0
  62. data/spec/vcr_cassettes/people_profile_own.yml +57 -0
  63. data/spec/vcr_cassettes/people_profile_own_secure.yml +53 -0
  64. data/spec/vcr_cassettes/people_profile_skills.yml +52 -0
  65. data/spec/vcr_cassettes/unavailable.yml +99 -0
  66. metadata +285 -0
@@ -0,0 +1,143 @@
1
+ module LinkedIn
2
+ # Share and Social Stream APIs
3
+ #
4
+ # @see https://developer.linkedin.com/docs/guide/v2/shares
5
+ # @see https://developer.linkedin.com/docs/guide/v2/shares/share-api
6
+ # @see https://developer.linkedin.com/docs/guide/v2/shares/network-update-social-actions
7
+ #
8
+ # LinkedIn's v2 API adherence to the documentation is shaky at best. Several of
9
+ # the calls simply don't work if you, e.g., pass the URN in as a path element
10
+ # for a resource - you have to use the ids=[URN] format w/ a single URN. Or
11
+ # sometimes passing in an "actor" parameter in the request body simply doesn't
12
+ # work, and you have to pass it in as a URL parameter. What you see in this
13
+ # file is the result of trial-and-error getting these endpoints to work, and the
14
+ # inconsistency is usually a result of either misunderstanding the docs or the
15
+ # API not working as advertised. It's also a bit unclear when the API wants
16
+ # an activity URN vs, e.g., an article URN. Caveat emptor.
17
+ #
18
+ # [(contribute here)](https://github.com/mdesjardins/linkedin-v2)
19
+ class ShareAndSocialStream < APIResource
20
+
21
+ # Retrieve shares from a person, organization, or organizationBrand.
22
+ #
23
+ # Permissions:
24
+ # 1.) For personal shares, you may only retrieve shares for the authorized members.
25
+ # 2.) For organization shares, you may only retrieve shares for organizations for which the
26
+ # authorized member is an administrator.
27
+ #
28
+ # @see https://developer.linkedin.com/docs/guide/v2/shares/share-api#retrieve
29
+ #
30
+ # @options options [String] :owner, the URN for whom we are fetching shares.
31
+ # @return [LinkedIn::Mash]
32
+ #
33
+ def shares(options = {})
34
+ urn = options.delete(:urn)
35
+ path = "/shares?q=owners&owners=#{urn}"
36
+ get(path, options)
37
+ end
38
+
39
+ # Create one share from a person, organization, or organizationBrand.
40
+ #
41
+ # Permissions:
42
+ # 1.) For personal shares, you may only post shares as the authorized member.
43
+ # 2.) For organization shares, you may only post shares as an organization for which the
44
+ # authorized member is an administrator.
45
+ #
46
+ # @see https://developer.linkedin.com/docs/guide/v2/shares/share-api#post
47
+ #
48
+ # @option options [String] :owner, the URN of the entity posting the share.
49
+ # @return [LinkedIn::Mash]
50
+ #
51
+ def share(options = {})
52
+ path = '/shares'
53
+ defaults = {
54
+ distribution: {
55
+ linkedInDistributionTarget: {
56
+ visibleToGuest: true
57
+ }
58
+ }
59
+ }
60
+ post(path, MultiJson.dump(defaults.merge(options)), 'Content-Type' => 'application/json')
61
+ end
62
+
63
+ # Retrieves the likes for a specific post.
64
+ #
65
+ # @see https://developer.linkedin.com/docs/guide/v2/shares/network-update-social-actions#retrieve
66
+ #
67
+ # @option options [String] :urn, the URN of the relevant share, UGC post, or comment
68
+ # @return [LinkedIn::Mash]
69
+ #
70
+ def likes(options = {})
71
+ urn = options.delete(:urn)
72
+ path = "/socialActions/#{urn}/likes"
73
+ get(path, options)
74
+ end
75
+
76
+ # Likes a specific share or comment.
77
+ #
78
+ # @see https://developer.linkedin.com/docs/guide/v2/shares/network-update-social-actions#retrieve.
79
+ # @option options [String] :object, specifies the URN of the entity to which the like belongs.
80
+ # This object should be a sub-entity of the top-level share indicated in the request URL, and
81
+ # should be represented as an URN either of format urn:li:share:{id}
82
+ # @option options [String] :urn, specifies activity being un-liked (e.g., urn:li:activity::123)
83
+ # @option options [String] :actor, specifies the entity performing the action. It should be
84
+ # represented by a urn:li:person:{id} or urn:li:organization:{id} URN.
85
+ #
86
+ def like(options = {})
87
+ urn = options.delete(:urn)
88
+ path = "/socialActions/#{urn}/likes"
89
+ post(path, MultiJson.dump(options), 'Content-Type' => 'application/json')
90
+ end
91
+
92
+ # Un-likes a previously liked share or comment.
93
+ #
94
+ # @see https://developer.linkedin.com/docs/guide/v2/shares/network-update-social-actions#retrieve.
95
+ # @option options [String] :urn, specifies activity being un-liked (e.g., urn:li:activity:123)
96
+ # @option options [String] :actor, specifies the entity performing the action. It should b # represented by a urn:li:person:{id} or urn:li:organization:{id} URN.
97
+ #
98
+ def unlike(options = {})
99
+ urn = options.delete(:urn)
100
+ actor = options.delete(:actor)
101
+ path = "/socialActions/#{urn}/likes/#{actor}?actor=#{CGI::escape(actor)}"
102
+ delete(path, MultiJson.dump(options), 'Content-Type' => 'application/json') #options)
103
+ end
104
+
105
+ # Retrieves the comments for a specific post.
106
+ #
107
+ # @see https://developer.linkedin.com/docs/guide/v2/shares/network-update-social-actions#retrieve
108
+ # @option options [String] :urn, specifies activity queried for comments (e.g.,
109
+ # urn:li:article:123)
110
+ #
111
+ def comments(options = {})
112
+ urn = options.delete(:urn)
113
+ path = "/socialActions/#{urn}/comments"
114
+ get(path, options)
115
+ end
116
+
117
+ # Adds a comment to a specific post.
118
+ #
119
+ # Permissions:
120
+ #
121
+ # @see https://developer.linkedin.com/docs/guide/v2/shares/network-update-social-actions#retrieve
122
+ #
123
+ # @option options [String] :urn, specifies activity queried for comments (e.g.,
124
+ # urn:li:article:123)
125
+ # @option options [String] :actor, specifies the entity performing the action. It should b # represented by a urn:li:person:{id} or urn:li:organization:{id} URN.
126
+ # @option options [String] :message, the text content of the comment.
127
+ #
128
+ def comment(options = {})
129
+ urn = options.delete(:urn)
130
+ actor = options.delete(:actor)
131
+ message = options.delete(:message)
132
+ body = {
133
+ actor: actor,
134
+ message: {
135
+ attributes: [],
136
+ text: message
137
+ }
138
+ }
139
+ path = "/socialActions/#{urn}/comments"
140
+ post(path, MultiJson.dump(body), 'Content-Type' => 'application/json')
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,3 @@
1
+ module LinkedIn
2
+ VERSION = '0.1.3'
3
+ end
@@ -0,0 +1,52 @@
1
+ require "oauth2"
2
+
3
+ require "linked_in/errors"
4
+ require "linked_in/raise_error"
5
+ require "linked_in/version"
6
+ require "linked_in/configuration"
7
+
8
+ # Responsible for all authentication
9
+ # LinkedIn::OAuth2 inherits from OAuth2::Client
10
+ require "linked_in/oauth2"
11
+
12
+ # Coerces LinkedIn JSON to a nice Ruby hash
13
+ # LinkedIn::Mash inherits from Hashie::Mash
14
+ require "hashie"
15
+ require "linked_in/mash"
16
+
17
+ # Wraps a LinkedIn-specifc API connection
18
+ # LinkedIn::Connection inherits from Faraday::Connection
19
+ require "faraday"
20
+ require "linked_in/connection"
21
+
22
+ # Data object to wrap API access token
23
+ require "linked_in/access_token"
24
+
25
+ # Endpoints inherit from APIResource
26
+ require "linked_in/api_resource"
27
+
28
+ # All of the endpoints
29
+ require "linked_in/jobs"
30
+ require "linked_in/people"
31
+ require "linked_in/search"
32
+ # require "linked_in/groups" not supported by v2 API?
33
+ require "linked_in/organizations"
34
+ require "linked_in/communications"
35
+ require "linked_in/share_and_social_stream"
36
+ require 'linked_in/media'
37
+
38
+ # The primary API object that makes requests.
39
+ # It composes in all of the endpoints
40
+ require "linked_in/api"
41
+
42
+ module LinkedIn
43
+ @config = Configuration.new
44
+
45
+ class << self
46
+ attr_accessor :config
47
+ end
48
+
49
+ def self.configure
50
+ yield self.config
51
+ end
52
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ # Follow http://guides.rubygems.org/ best practices
3
+
4
+ require File.expand_path("../lib/linked_in/version", __FILE__)
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "linkedin-v2"
8
+ gem.email = ["mike.desjardins@cereslogic.com"]
9
+ gem.version = LinkedIn::VERSION
10
+ gem.authors = ["Mike Desjardins"]
11
+ gem.summary = "Ruby wrapper for the LinkedIn v2 API"
12
+ gem.license = "MIT"
13
+ gem.homepage = "http://github.com/mdesjardins/linkedin-v2"
14
+ gem.description = gem.summary
15
+
16
+ gem.files = `git ls-files`.split("\n")
17
+ gem.test_files = `git ls-files -- spec/**/*`.split("\n")
18
+ gem.require_paths = ["lib"]
19
+
20
+ # To support native JSON. Same requirements as Rails.
21
+ gem.required_ruby_version = '>= 1.9.3'
22
+
23
+ gem.add_dependency "oauth2", "~> 1.0"
24
+ gem.add_dependency "hashie", "~> 3.2"
25
+ gem.add_dependency "faraday", "~> 0.11"
26
+
27
+ gem.add_development_dependency "rake"
28
+ gem.add_development_dependency "rspec", "~> 3.0"
29
+
30
+ # We use YARD for documentation
31
+ # Extra gems for GitHub flavored MarkDown in YARD
32
+ gem.add_development_dependency "yard"
33
+ gem.add_development_dependency "redcarpet"
34
+ gem.add_development_dependency "github-markdown"
35
+
36
+ # We use VCR to mock LinkedIn API calls
37
+ gem.add_development_dependency "vcr"
38
+ gem.add_development_dependency "webmock"
39
+ end
@@ -0,0 +1,41 @@
1
+ require "spec_helper"
2
+
3
+ describe LinkedIn::API do
4
+ context "With no access token" do
5
+ let(:err_msg) { LinkedIn::ErrorMessages.no_access_token }
6
+
7
+ it "Raises an error" do
8
+ expect{LinkedIn::API.new}.to raise_error(LinkedIn::InvalidRequest, err_msg)
9
+ end
10
+ end
11
+
12
+ shared_examples "test access token" do
13
+ it "Build a LinkedIn::API instance" do
14
+ expect(subject).to be_kind_of LinkedIn::API
15
+ end
16
+
17
+ it "Sets the access_token object" do
18
+ expect(subject.access_token).to be_kind_of LinkedIn::AccessToken
19
+ end
20
+
21
+ it "Sets the access_token string" do
22
+ expect(subject.access_token.token).to eq access_token
23
+ end
24
+ end
25
+
26
+ context "With a string access token" do
27
+ let(:access_token) { "dummy_access_token" }
28
+ subject {LinkedIn::API.new(access_token)}
29
+
30
+ include_examples "test access token"
31
+ end
32
+
33
+ context "With a LinkedIn::AccessToken object" do
34
+ let(:access_token) { "dummy_access_token" }
35
+ let(:access_token_obj) { LinkedIn::AccessToken.new(access_token) }
36
+
37
+ subject {LinkedIn::API.new(access_token_obj)}
38
+
39
+ include_examples "test access token"
40
+ end
41
+ end
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+
3
+ describe LinkedIn::Communications do
4
+ let(:access_token) {"dummy_access_token"}
5
+ let(:api) {LinkedIn::API.new(access_token)}
6
+
7
+ it "should be able to send a message" do
8
+ stub_request(:post, "https://api.linkedin.com/v1/people/~/mailbox?oauth2_access_token=dummy_access_token").to_return(body: "", status: 201)
9
+ response = api.send_message("subject", "body", ["recip1", "recip2"])
10
+ expect(response.body).to eq ""
11
+ expect(response.status).to eq 201
12
+ end
13
+ end
@@ -0,0 +1,33 @@
1
+ require "spec_helper"
2
+
3
+ describe LinkedIn::Jobs, 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 "should be able to view a job listing" do
13
+ stub("https://api.linkedin.com/v1/jobs/id=1586?")
14
+ expect(api.job(:id => 1586)).to be_an_instance_of(LinkedIn::Mash)
15
+ end
16
+
17
+ it "should be able to view its job bookmarks" do
18
+ stub("https://api.linkedin.com/v1/people/~/job-bookmarks?")
19
+ expect(api.job_bookmarks).to be_an_instance_of(LinkedIn::Mash)
20
+ end
21
+
22
+ it "should be able to view its job suggestion" do
23
+ stub("https://api.linkedin.com/v1/people/~/suggestions/job-suggestions?")
24
+ expect(api.job_suggestions).to be_an_instance_of(LinkedIn::Mash)
25
+ end
26
+
27
+ it "should be able to add a bookmark" do
28
+ stub_request(:post, "https://api.linkedin.com/v1/people/~/job-bookmarks?oauth2_access_token=#{access_token}").to_return(body: "", status: 201)
29
+ response = api.add_job_bookmark(id: 1452577)
30
+ expect(response.body).to eq ""
31
+ expect(response.status).to eq 201
32
+ end
33
+ end
@@ -0,0 +1,54 @@
1
+ require "spec_helper"
2
+
3
+ describe LinkedIn::Organizations 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
+ it "should be able to view an organization profile" do
12
+ stub("https://api.linkedin.com/v2/organizations/1586")
13
+ expect(api.organization(id: 1586)).to be_an_instance_of(LinkedIn::Mash)
14
+ end
15
+
16
+ it "should be able to view an organization by vanity name" do
17
+ stub("https://api.linkedin.com/v2/organizations?q=vanityName&vanityName=acme")
18
+ expect(api.organization(vanity_name: "acme")).to be_an_instance_of(LinkedIn::Mash)
19
+ end
20
+
21
+ it "should be able to view an organization by e-mail domain" do
22
+ stub("https://api.linkedin.com/v2/organizations?q=emailDomain&emailDomain=acme.com")
23
+ expect(api.organization(email_domain: "acme.com")).to be_an_instance_of(LinkedIn::Mash)
24
+ end
25
+
26
+ it "should load correct organization data" do
27
+ VCR.use_cassette("organization data") do
28
+ data = api.organization(id: 11571530)
29
+ expect(data.id).to eq 11571530
30
+ expect(data.name).to eq( {"localized"=>{"en_us"=>"del Nariz Social Media"}, "preferred_locale"=>{"country"=>"US", "language"=>"en"}} )
31
+ end
32
+ end
33
+
34
+ it "should load historical page statistics" do
35
+ stub("https://api.linkedin.com/v2/organizationPageStatistics?q=organization&organization=urn:li:organization:123456")
36
+ expect(
37
+ api.organization_page_statistics(urn: "urn:li:organization:123456")
38
+ ).to be_an_instance_of(LinkedIn::Mash)
39
+ end
40
+
41
+ it "should load historical follow statistics" do
42
+ stub("https://api.linkedin.com/v2/organizationalEntityFollowerStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:123456")
43
+ expect(
44
+ api.organization_follower_statistics(urn: "urn:li:organization:123456")
45
+ ).to be_an_instance_of(LinkedIn::Mash)
46
+ end
47
+
48
+ it "should load historical share statistics" do
49
+ stub("https://api.linkedin.com/v2/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:123456")
50
+ expect(
51
+ api.organization_share_statistics(urn: "urn:li:organization:123456")
52
+ ).to be_an_instance_of(LinkedIn::Mash)
53
+ end
54
+ end
@@ -0,0 +1,191 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkedIn::People do
4
+ let(:uid) {"MpkAFJTlPY"}
5
+ let(:url) {"www.linkedin.com/in/miguel-santos-del-nariz"}
6
+ let(:access_token) {"AQVM91zzF-bLiOfCsTi8ktxnq99l-tW9meri8F9ZEWAuHf5g1bO_Pa4p0nFwKvZ7VFdSERAnJZq3eNOq6BzDPFNIyGIy50s-7HkLq2hE5uy6HrAQrsMAQR_qZxnBrSD11g_M2sF5XB5fUHZOXEQFgFaXB0M19VUAsvsz3yg-7zMI7w9Zn_DYTLO1e2W9VEZrOgVmRNt1XBIT_pdQO7pQkKv4702yJTrIBOuhZWNLZRClPHd2RRhPf2SJeTkodbnL4xSvzcyEPpLaTPyZIVJnBcsAzYFiG_pJtyGs7x-iWbUZsYgnUVSy8Wg-5eqmvze5tuZdICIP0PJ0AVMNGOxRRiLOEh8MSg"}
7
+
8
+ let(:api) {LinkedIn::API.new(access_token)}
9
+
10
+ def verify(result)
11
+ expect(result).to be_kind_of LinkedIn::Mash
12
+ end
13
+
14
+ ###### PROFILES
15
+ # Self
16
+ it "grabs your own profile" do
17
+ VCR.use_cassette("people profile own") do
18
+ result = api.profile
19
+ verify result
20
+ expect(result["firstName"]).to be_kind_of String
21
+ end
22
+ end
23
+
24
+ # Secure
25
+ it "accepts secure-urls param via secure option" do
26
+ VCR.use_cassette("people profile own secure") do
27
+ verify api.profile(secure: true)
28
+ end
29
+ end
30
+
31
+ # Language
32
+ it "gets profiles in a different language" do
33
+ VCR.use_cassette("people profile lang spanish") do
34
+ verify api.profile(lang: "es")
35
+ end
36
+ end
37
+
38
+ # Others
39
+ it "gets another users profile by user id" do
40
+ VCR.use_cassette("people profile other uid") do
41
+ result = api.profile(id: uid)
42
+ verify result
43
+ expect(result["firstName"]).to be_kind_of String
44
+ end
45
+ end
46
+ it "gets another users profile by url" do
47
+ VCR.use_cassette("people profile other url") do
48
+ result = api.profile(url: url)
49
+ verify result
50
+ expect(result["firstName"]).to be_kind_of String
51
+ end
52
+ end
53
+ it "gets another users profile by user id" do
54
+ VCR.use_cassette("people profile other uid") do
55
+ verify api.profile(uid)
56
+ end
57
+ end
58
+ it "gets another users profile by url" do
59
+ VCR.use_cassette("people profile other url") do
60
+ verify api.profile(url)
61
+ end
62
+ end
63
+
64
+ # Errors
65
+ it "errors on bad input" do
66
+ expect{api.profile("Bad input")}.to raise_error
67
+ end
68
+ it "errors on email deprecation" do
69
+ msg = LinkedIn::ErrorMessages.deprecated
70
+ expect{api.profile(email: "email@email.com")}.to raise_error(LinkedIn::Deprecated, msg)
71
+ end
72
+
73
+ # Fields
74
+ it "grabs certain profile fields" do
75
+ VCR.use_cassette("people profile fields simple") do
76
+ result = api.profile(fields: ["id","industry"])
77
+ verify result
78
+ expect(result["industry"]).to be_kind_of String
79
+ end
80
+ end
81
+ it "grabs more complex profile fields" do
82
+ VCR.use_cassette("people profile fields complex") do
83
+ result = api.profile(fields: ["id",{"positions" => ["title"]}])
84
+ verify result
85
+ expect(result["positions"]["values"][0]["title"]).to be_kind_of String
86
+ end
87
+ end
88
+
89
+ # Multiple people
90
+ it "grabs multiple people by uids" do
91
+ VCR.use_cassette("people profile multiple uids") do
92
+ result = api.profile(ids: ["self", uid])
93
+ verify result
94
+ expect(result["values"].length).to eq 2
95
+ end
96
+ end
97
+ it "grabs multiple people by urls" do
98
+ VCR.use_cassette("people profile multiple urls") do
99
+ result = api.profile(urls: ["self", url])
100
+ verify result
101
+ expect(result["values"].length).to eq 2
102
+ end
103
+ end
104
+ it "grabs multiple people by uids and urls" do
105
+ VCR.use_cassette("people profile multiple uids and urls") do
106
+ result = api.profile(ids: ["self", uid], urls: [url])
107
+ verify result
108
+ expect(result["values"].length).to eq 3
109
+ end
110
+ end
111
+ it "grabs certain fields for multiple people" do
112
+ VCR.use_cassette("people profile multiple fields") do
113
+ result = api.profile(ids: ["self", uid], fields: ["id", "industry"])
114
+ verify result
115
+ expect(result["values"][0]["industry"]).to be_kind_of String
116
+ end
117
+ end
118
+
119
+ ###### CONNECTIONS
120
+ it "grabs your own connections" do
121
+ VCR.use_cassette("people profile connections self") do
122
+ result = api.connections
123
+ verify result
124
+ expect(result["values"].length).to eq 3
125
+ end
126
+ end
127
+ it "grabs the connections of others" do
128
+ VCR.use_cassette("people profile connections other") do
129
+ result = api.connections(id: uid)
130
+ verify result
131
+ expect(result["values"].length).to eq 3
132
+ end
133
+ end
134
+ it "grabs certain fields for those connections" do
135
+ VCR.use_cassette("people profile connections fields") do
136
+ result = api.connections(fields: ["id", "industry"])
137
+ verify result
138
+ expect(result["values"].length).to eq 4
139
+ expect(result["values"][0]["industry"]).to be_kind_of String
140
+ end
141
+ end
142
+
143
+ it "grabs new connections since a string date" do
144
+ VCR.use_cassette("people profile new connections self") do
145
+ result = api.new_connections("2014-01-01")
146
+ verify result
147
+ expect(result["values"].length).to eq 2
148
+ end
149
+ end
150
+ it "grabs new connections since a numeric date" do
151
+ VCR.use_cassette("people profile new connections self") do
152
+ verify api.new_connections(1388534400000)
153
+ end
154
+ end
155
+ it "grabs new connections since a Time.utc object" do
156
+ VCR.use_cassette("people profile new connections self") do
157
+ verify api.new_connections(Time.utc(2014,1,1))
158
+ end
159
+ end
160
+ it "grabs new connections for another user" do
161
+ VCR.use_cassette("people profile new connections other") do
162
+ result = api.new_connections("2014-01-01", id: uid)
163
+ verify result
164
+ expect(result["values"].length).to eq 2
165
+ end
166
+ end
167
+ it "grabs certain fields of new connections" do
168
+ VCR.use_cassette("people profile new connections fields") do
169
+ result = api.new_connections("2014-01-01", fields: ["id", "industry"])
170
+ verify result
171
+ expect(result["values"].length).to eq 3
172
+ expect(result["values"][0]["industry"]).to be_kind_of String
173
+ end
174
+ end
175
+
176
+ it "grabs picture urls" do
177
+ VCR.use_cassette("people picture urls") do
178
+ result = api.picture_urls
179
+ verify result
180
+ expect(result["values"][0] =~ URI::regexp).to_not be_nil
181
+ end
182
+ end
183
+
184
+ it "grabs skills" do
185
+ VCR.use_cassette("people profile skills") do
186
+ result = api.skills
187
+ verify result
188
+ expect(result["all"].length).to eq 2
189
+ end
190
+ end
191
+ end