diff --git a/.document b/.document deleted file mode 100644 index ecf36731..00000000 --- a/.document +++ /dev/null @@ -1,5 +0,0 @@ -README.rdoc -lib/**/*.rb -bin/* -features/**/*.feature -LICENSE diff --git a/.travis.yml b/.travis.yml index 0acac844..8bd64c6e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,8 @@ rvm: - - 1.8.7 - - 1.9.2 + - 2.5 + - 2.4 + - 2.3 + - 2.0.0 + - 2.1.0 - 1.9.3 - - ree + - jruby-19mode diff --git a/.yardopts b/.yardopts new file mode 100644 index 00000000..31f7f7ad --- /dev/null +++ b/.yardopts @@ -0,0 +1,7 @@ +--no-private +--markup markdown +- +README.md +CHANGELOG.md +LICENSE +EXAMPLES.md diff --git a/changelog.markdown b/CHANGELOG.md similarity index 68% rename from changelog.markdown rename to CHANGELOG.md index 5177d5fc..35bab969 100644 --- a/changelog.markdown +++ b/CHANGELOG.md @@ -1,5 +1,37 @@ # Changelog +* Document all methods +* Re-organize modules under Api to match organization in LinkedIn's REST + API documentation + +## 1.1.1 - August 8, 2018 + +* Switch to OAuth2 + +## 0.4.4 - Jan 11, 2014 + +* Group share add +* Readme updates + +## 0.4.3 + +## 0.4.2 + +## 0.4.1 + +## 0.4.0 - May 30, 2013 + +* Add capability to ask for desired permissions from linked in api +* Add option to specify a proxy +* Bump hashie version +* fix the permission param passing +* fix to be able to pass the permission scope +* Manipulating comments/likes for network_updates ('shares') +* Methods to work with comments/likes for share +* Added a method to get a user's shares +* Added current user's shares as an option (client.shares) +* Readme Typos + ## 0.2.x - March x, 2010 * Removed Crack as a dependency, Nokogiri FTW @@ -68,4 +100,4 @@ ## 0.0.1 - November 24, 2009 -* Initial release \ No newline at end of file +* Initial release diff --git a/EXAMPLES.md b/EXAMPLES.md new file mode 100644 index 00000000..055f4015 --- /dev/null +++ b/EXAMPLES.md @@ -0,0 +1,200 @@ +# Linkedin Gem Examples + +## OAuth2 Authentication + +Here's an example of authenticating with the LinkedIn API + +```ruby +require 'rubygems' +require 'linkedin' + +# get your api keys at https://www.linkedin.com/secure/developer +client = LinkedIn::Client.new('your_consumer_key', 'your_consumer_secret') + +# If you want to use one of the scopes from linkedin you have to pass it in at this point +# You can learn more about it here: http://developer.linkedin.com/documents/authentication + +# to test from your desktop, open the following url in your browser +# and record the pin it gives you +client.authorize_url(:redirect_uri => 'https:://www.yourdomain.com/callback', :state => SecureRandom.uuid, :scope => "r_basicprofile+r_emailaddress") +=> "https://api.linkedin.com/uas/oauth2/authorization?" + +# then fetch your access keys +client.authorize_from_request(params[:code], :redirect_uri => 'https:://www.yourdomain.com/callback') +=> "OU812" # <= save this for future requests + +NOTE: params[:code] is returned in the callback + +# or authorize from previously fetched access keys +client.authorize_from_access("OU812") + +# you're now free to move about the cabin, call any API method +``` + + +## Profile + +Here are some examples of accessing a user's profile + +```ruby +# AUTHENTICATE FIRST found in examples/authenticate.rb + +# client is a LinkedIn::Client + +# get the profile for the authenticated user +client.profile + +# get a profile for someone found in network via ID +client.profile(:id => 'gNma67_AdI') + +# get a profile for someone via their public profile url +client.profile(:url => 'http://www.linkedin.com/in/netherland') + +# provides the ability to access authenticated user's company field in the profile +user = client.profile(:fields => %w(positions)) +companies = user.positions.all.map{|t| t.company} +# Example: most recent company can be accessed via companies[0] + +# Example of a multi-email search against the special email search API +account_exists = client.profile(:email => 'email=yy@zz.com,email=xx@yy.com', :fields => ['id']) +``` + + +## Sending a Message + +Here's an example of sending a message to two recipients + +```ruby +# AUTHENTICATE FIRST found in examples/authenticate.md + +# client is a LinkedIn::Client + +# send a message to a person in your network. you will need to authenticate the +# user and ask for the "w_messages" permission. +response = client.send_message("subject", "body", ["person_1_id", "person_2_id"]) +``` + + +## User's Network + +Here are some examples of accessing network updates and connections of +the authenticated user + +``` ruby +# AUTHENTICATE FIRST found in examples/authenticate.rb + +# client is a LinkedIn::Client + +# get network updates for the authenticated user +client.network_updates + +# get profile picture changes +client.network_updates(:type => 'PICT') + +# view connections for the currently authenticated user +client.connections + +# get the original picture-url for one of the connections +client.picture_urls(:id => 'id_of_connection') + +# get the image over https instead of http +client.picture_urls(:id => 'id_of_connection', :secure => "true") +``` +## Update User's Status + +Here's an example of updating the current user's status + +```ruby +# AUTHENTICATE FIRST found in examples/authenticate.rb + +# client is a LinkedIn::Client + +# update status for the authenticated user +client.add_share(:comment => 'is playing with the LinkedIn Ruby gem') +``` + + +## Sinatra App + +Here's an example sinatra application that performs authentication, +after which some info about the authenticated user can be retrieved. + +```ruby +require "rubygems" +require "haml" +require "sinatra" +require "linkedin" + +enable :sessions + +helpers do + def login? + !session[:atoken].nil? + end + + def profile + linkedin_client.profile unless session[:atoken].nil? + end + + def connections + linkedin_client.connections unless session[:atoken].nil? + end + + private + def linkedin_client + client = LinkedIn::Client.new(settings.api, settings.secret) + client.authorize_from_access(session[:atoken]) + client + end + +end + +configure do + # get your api keys at https://www.linkedin.com/secure/developer + set :api, "your_api_key" + set :secret, "your_secret" +end + +get "/" do + haml :index +end + +get "/auth" do + client = LinkedIn::Client.new(settings.api, settings.secret) + request_token = client.request_token(:oauth_callback => "http://#{request.host}:#{request.port}/auth/callback") + session[:rtoken] = request_token.token + session[:rsecret] = request_token.secret + + redirect client.request_token.authorize_url +end + +get "/auth/logout" do + session[:atoken] = nil + redirect "/" +end + +get "/auth/callback" do + client = LinkedIn::Client.new(settings.api, settings.secret) + if session[:atoken].nil? + pin = params[:oauth_verifier] + atoken, asecret = client.authorize_from_request(session[:rtoken], session[:rsecret], pin) + session[:atoken] = atoken + session[:asecret] = asecret + end + redirect "/" +end + + +__END__ +@@index +-if login? + %p Welcome #{profile.first_name}! + %a{:href => "/auth/logout"} Logout + %p= profile.headline + %br + %div= "You have #{connections.total} connections!" + -connections.all.each do |c| + %div= "#{c.first_name} #{c.last_name} - #{c.headline}" +-else + %a{:href => "/auth"} Login using LinkedIn +``` diff --git a/Gemfile b/Gemfile index 1e01eae6..6e9fc5d4 100644 --- a/Gemfile +++ b/Gemfile @@ -4,4 +4,8 @@ platforms :jruby do gem 'jruby-openssl', '~> 0.7' end +platforms :rbx do + gem 'rubysl' +end + gemspec diff --git a/LICENSE b/LICENSE index 5c6e9d09..6b66ebed 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,6 @@ -Copyright (c) 2009 Wynn Netherland +The MIT License (MIT) + +Copyright (c) 2009 Wynn Netherland & Matthew Kirk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/README.markdown b/README.markdown deleted file mode 100644 index 4a8cc455..00000000 --- a/README.markdown +++ /dev/null @@ -1,78 +0,0 @@ -# LinkedIn - -Ruby wrapper for the [LinkedIn API](http://developer.linkedin.com). Heavily inspired by [John Nunemaker's](http://github.com/jnunemaker) [Twitter gem](http://github.com/jnunemaker/twitter), the LinkedIn gem provides an easy-to-use wrapper for LinkedIn's Oauth/XML APIs. - -Travis CI : [![Build Status](https://secure.travis-ci.org/pengwynn/linkedin.png)](http://travis-ci.org/pengwynn/linkedin) - -## Installation - - [sudo] gem install linkedin - -## Usage - -### Authenticate - -LinkedIn's API uses Oauth for authentication. Luckily, the LinkedIn gem hides most of the gory details from you. - - require 'rubygems' - require 'linkedin' - - # get your api keys at https://www.linkedin.com/secure/developer - client = LinkedIn::Client.new('your_consumer_key', 'your_consumer_secret') - rtoken = client.request_token.token - rsecret = client.request_token.secret - - # to test from your desktop, open the following url in your browser - # and record the pin it gives you - client.request_token.authorize_url - => "https://api.linkedin.com/uas/oauth/authorize?oauth_token=" - - # then fetch your access keys - client.authorize_from_request(rtoken, rsecret, pin) - => ["OU812", "8675309"] # <= save these for future requests - - # or authorize from previously fetched access keys - client.authorize_from_access("OU812", "8675309") - - # you're now free to move about the cabin, call any API method - -### Profile examples - - # get the profile for the authenticated user - client.profile - - # get a profile for someone found in network via ID - client.profile(:id => 'gNma67_AdI') - - # get a profile for someone via their public profile url - client.profile(:url => 'http://www.linkedin.com/in/netherland') - - - -More examples in the [examples folder](http://github.com/pengwynn/linkedin/blob/master/examples). - -For a nice example on using this in a [Rails App](http://pivotallabs.com/users/will/blog/articles/1096-linkedin-gem-for-a-web-app). - -If you want to play with the LinkedIn api without using the gem, have a look at the [apigee LinkedIn console](http://app.apigee.com/console/linkedin). - -## TODO - -* Change to json api -* Update and correct test suite -* Change to Faraday for authentication -* Implement Messaging APIs - -## Note on Patches/Pull Requests - -* Fork the project. -* Make your feature addition or bug fix. -* Add tests for it. This is important so I don't break it in a - future version unintentionally. -* Commit, do not mess with rakefile, version, or history. - (if you want to have your own version, that is fine but - bump version in a commit by itself I can ignore when I pull) -* Send me a pull request. Bonus points for topic branches. - -## Copyright - -Copyright (c) 2009-11 [Wynn Netherland](http://wynnnetherland.com). See LICENSE for details. diff --git a/README.md b/README.md new file mode 100644 index 00000000..7c1e3388 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# LinkedIn + +Ruby wrapper for the [LinkedIn API](http://developer.linkedin.com). The LinkedIn gem provides an easy-to-use wrapper for LinkedIn's REST APIs. + +Travis CI : [![Build Status](https://secure.travis-ci.org/hexgnu/linkedin.png)](http://travis-ci.org/hexgnu/linkedin) + +## Installation + + gem install linkedin + +## Documentation + +[http://rdoc.info/gems/linkedin](http://rdoc.info/gems/linkedin) + +## Usage + +[View the Examples](EXAMPLES.md) + +## Changelog + +[View the Changelog](CHANGELOG.md) + +## TODO + +* Update and correct test suite +* Change to Faraday for authentication +* Implement Messaging APIs + +## Note on Patches/Pull Requests + +* Fork the project. +* Make your feature addition or bug fix. +* Add tests for it. This is important so I don't break it in a + future version unintentionally. +* Make sure your test doesn't just check of instance of LinkedIn::Mash :smile:. +* Commit, do not mess with rakefile, version, or history. + (if you want to have your own version, that is fine but + bump version in a commit by itself I can ignore when I pull) +* Send me a pull request. Bonus points for topic branches. + +## Copyright + +Copyright (c) 2013-Present [Matt Kirk](http://matthewkirk.com) 2009-11 [Wynn Netherland](http://wynnnetherland.com). See LICENSE for details. diff --git a/Rakefile b/Rakefile index 67a599f9..f8197d6b 100755 --- a/Rakefile +++ b/Rakefile @@ -8,12 +8,8 @@ RSpec::Core::RakeTask.new(:spec) task :test => :spec task :default => :spec +load 'vcr/tasks/vcr.rake' -require 'rdoc/task' require File.expand_path('../lib/linked_in/version', __FILE__) -RDoc::Task.new do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = "linkedin #{LinkedIn::VERSION::STRING}" - rdoc.rdoc_files.include('README*') - rdoc.rdoc_files.include('lib/**/*.rb') -end +require 'yard' +YARD::Rake::YardocTask.new diff --git a/examples/authenticate.rb b/examples/authenticate.rb deleted file mode 100644 index 544e2d0f..00000000 --- a/examples/authenticate.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'rubygems' -require 'linkedin' - -# get your api keys at https://www.linkedin.com/secure/developer -client = LinkedIn::Client.new('your_consumer_key', 'your_consumer_secret') -rtoken = client.request_token.token -rsecret = client.request_token.secret - -# to test from your desktop, open the following url in your browser -# and record the pin it gives you -client.request_token.authorize_url -=> "https://api.linkedin.com/uas/oauth/authorize?oauth_token=" - -# then fetch your access keys -client.authorize_from_request(rtoken, rsecret, pin) -=> ["OU812", "8675309"] # <= save these for future requests - -# or authorize from previously fetched access keys -c.authorize_from_access("OU812", "8675309") - -# you're now free to move about the cabin, call any API method diff --git a/examples/network.rb b/examples/network.rb deleted file mode 100644 index 2d19ae70..00000000 --- a/examples/network.rb +++ /dev/null @@ -1,12 +0,0 @@ -# AUTHENTICATE FIRST found in examples/authenticate.rb - -# client is a LinkedIn::Client - -# get network updates for the authenticated user -client.network_updates - -# get profile picture changes -client.network_updates(:type => 'PICT') - -# view connections for the currently authenticated user -client.connections \ No newline at end of file diff --git a/examples/profile.rb b/examples/profile.rb deleted file mode 100644 index 2eb76950..00000000 --- a/examples/profile.rb +++ /dev/null @@ -1,18 +0,0 @@ -# AUTHENTICATE FIRST found in examples/authenticate.rb - -# client is a LinkedIn::Client - -# get the profile for the authenticated user -client.profile - -# get a profile for someone found in network via ID -client.profile(:id => 'gNma67_AdI') - -# get a profile for someone via their public profile url -client.profile(:url => 'http://www.linkedin.com/in/netherland') - -# provides the ability to access authenticated user's company field in the profile -user = client.profile(:fields => %w(positions)) -companies = user.positions.all.map{|t| t.company} -# Example: most recent company can be accessed via companies[0] - diff --git a/examples/sinatra.rb b/examples/sinatra.rb deleted file mode 100644 index e4780d04..00000000 --- a/examples/sinatra.rb +++ /dev/null @@ -1,77 +0,0 @@ -require "rubygems" -require "haml" -require "sinatra" -require "linkedin" - -enable :sessions - -helpers do - def login? - !session[:atoken].nil? - end - - def profile - linkedin_client.profile unless session[:atoken].nil? - end - - def connections - linkedin_client.connections unless session[:atoken].nil? - end - - private - def linkedin_client - client = LinkedIn::Client.new(settings.api, settings.secret) - client.authorize_from_access(session[:atoken], session[:asecret]) - client - end - -end - -configure do - # get your api keys at https://www.linkedin.com/secure/developer - set :api, "your_api_key" - set :secret, "your_secret" -end - -get "/" do - haml :index -end - -get "/auth" do - client = LinkedIn::Client.new(settings.api, settings.secret) - request_token = client.request_token(:oauth_callback => "http://#{request.host}:#{request.port}/auth/callback") - session[:rtoken] = request_token.token - session[:rsecret] = request_token.secret - - redirect client.request_token.authorize_url -end - -get "/auth/logout" do - session[:atoken] = nil - redirect "/" -end - -get "/auth/callback" do - client = LinkedIn::Client.new(settings.api, settings.secret) - if session[:atoken].nil? - pin = params[:oauth_verifier] - atoken, asecret = client.authorize_from_request(session[:rtoken], session[:rsecret], pin) - session[:atoken] = atoken - session[:asecret] = asecret - end - redirect "/" -end - - -__END__ -@@index --if login? - %p Welcome #{profile.first_name}! - %a{:href => "/auth/logout"} Logout - %p= profile.headline - %br - %div= "You have #{connections.total} connections!" - -connections.all.each do |c| - %div= "#{c.first_name} #{c.last_name} - #{c.headline}" --else - %a{:href => "/auth"} Login using LinkedIn diff --git a/examples/status.rb b/examples/status.rb deleted file mode 100644 index d23ebe5a..00000000 --- a/examples/status.rb +++ /dev/null @@ -1,9 +0,0 @@ -# AUTHENTICATE FIRST found in examples/authenticate.rb - -# client is a LinkedIn::Client - -# update status for the authenticated user -client.update_status('is playing with the LinkedIn Ruby gem') - -# clear status for the currently logged in user -client.clear_status diff --git a/lib/linked_in/api.rb b/lib/linked_in/api.rb index cb1b0dcd..84aaf432 100644 --- a/lib/linked_in/api.rb +++ b/lib/linked_in/api.rb @@ -1,6 +1,38 @@ module LinkedIn module Api - autoload :QueryMethods, "linked_in/api/query_methods" - autoload :UpdateMethods, "linked_in/api/update_methods" + + # @!macro person_path_options + # @param [Hash] options identifies the user profile you want + # @option options [String] :id a member token + # @option options [String] :url a Public Profile URL + # @option options [String] :email + + # @!macro company_path_options + # @param [Hash] options identifies the user profile you want + # @option options [String] :domain company email domain + # @option options [String] :id company ID + # @option options [String] :url + # @option options [String] :name company universal name + # @option options [String] :is_admin list all companies that the + # authenticated is an administrator of + + # @!macro share_input_fields + # @param [Hash] share content of the share + # @option share [String] :comment + # @option share [String] :content + # @option share [String] :title + # @option share [String] :submitted-url + # @option share [String] :submitted-image-url + # @option share [String] :description + # @option share [String] :visibility + # @option share [String] :code + + autoload :QueryHelpers, "linked_in/api/query_helpers" + autoload :People, "linked_in/api/people" + autoload :Groups, "linked_in/api/groups" + autoload :Companies, "linked_in/api/companies" + autoload :Jobs, "linked_in/api/jobs" + autoload :ShareAndSocialStream, "linked_in/api/share_and_social_stream" + autoload :Communications, "linked_in/api/communications" end end diff --git a/lib/linked_in/api/communications.rb b/lib/linked_in/api/communications.rb new file mode 100644 index 00000000..c4ecf3c0 --- /dev/null +++ b/lib/linked_in/api/communications.rb @@ -0,0 +1,44 @@ +module LinkedIn + module Api + + # Communications APIs + # + # @see http://developer.linkedin.com/documents/communications + module Communications + + # (Create) send a message from the authenticated user to a + # connection + # + # Permissions: w_messages + # + # @see http://developer.linkedin.com/documents/messaging-between-connections-api + # @see http://developer.linkedin.com/documents/invitation-api Invitation API + # + # @example + # client.send_message("subject", "body", ["person_1_id", "person_2_id"]) + # + # @param [String] subject Subject of the message + # @param [String] body Body of the message, plain text only + # @param [Array] recipient_paths a collection of + # profile paths that identify the users who will receive the + # message + # @return [void] + def send_message(subject, body, recipient_paths) + path = '/people/~/mailbox' + + message = { + 'subject' => subject, + 'body' => body, + 'recipients' => { + 'values' => recipient_paths.map do |profile_path| + { 'person' => { '_path' => "/people/#{profile_path}" } } + end + } + } + post(path, MultiJson.dump(message), "Content-Type" => "application/json") + end + + end + + end +end diff --git a/lib/linked_in/api/companies.rb b/lib/linked_in/api/companies.rb new file mode 100644 index 00000000..567016ff --- /dev/null +++ b/lib/linked_in/api/companies.rb @@ -0,0 +1,129 @@ +module LinkedIn + module Api + + # Companies API + # + # @see https://developer.linkedin.com/docs/company-pages Companies API + # @see https://developer.linkedin.com/docs/fields/companies Company Fields + # + # The following API actions do not have corresponding methods in + # this module + # + # * Permissions Checking Endpoints for Company Shares + # * GET Suggested Companies to Follow + # * GET Company Products + # + # [(contribute here)](https://github.com/hexgnu/linkedin) + module Companies + + # Retrieve a Company Profile + # + # @see https://developer.linkedin.com/docs/fields/company-profile Company Profile field + # @see https://developer.linkedin.com/docs/company-pages#company_profile Company Profile + # + # @macro company_path_options + # @option options [String] :scope + # @option options [String] :type + # @option options [String] :count + # @option options [String] :start + # @return [LinkedIn::Mash] + def company(options = {}) + path = company_path(options) + simple_query(path, options) + end + + # Retrieve a feed of event items for a Company + # + # @see https://developer.linkedin.com/docs/company-pages#get_update Get Specific Company Update + # + # @macro company_path_options + # @option options [String] :event-type + # @option options [String] :count + # @option options [String] :start + # @return [LinkedIn::Mash] + def company_updates(options={}) + path = "#{company_path(options)}/updates" + simple_query(path, options) + end + + # Retrieve statistics for a particular company page + # + # Permissions: rw_company_admin + # + # @see https://developer.linkedin.com/docs/company-pages#statistics Get Company Statistics + # + # @macro company_path_options + # @return [LinkedIn::Mash] + def company_statistics(options={}) + path = "#{company_path(options)}/company-statistics" + simple_query(path, options) + end + + # Retrieve comments on a particular company update: + # + # @see https://developer.linkedin.com/docs/company-pages#get_update_comments Get comments for a specific Company update + # + # @param [String] update_key a update/update-key representing a + # particular company update + # @macro company_path_options + # @return [LinkedIn::Mash] + def company_updates_comments(update_key, options={}) + path = "#{company_path(options)}/updates/key=#{update_key}/update-comments" + simple_query(path, options) + end + + # Retrieve likes on a particular company update: + # + # @see https://developer.linkedin.com/docs/company-pages#get_update_likes Get likes for a specific Company update + # + # @param [String] update_key a update/update-key representing a + # particular company update + # @macro company_path_options + # @return [LinkedIn::Mash] + def company_updates_likes(update_key, options={}) + path = "#{company_path(options)}/updates/key=#{update_key}/likes" + simple_query(path, options) + end + + # Create a share for a company that the authenticated user + # administers + # + # Permissions: rw_company_admin + # + # @see https://developer.linkedin.com/docs/company-pages#company_share Create a company share + # @see https://developer.linkedin.com/docs/company-pages#targetting_shares Targeting company shares + # + # @param [String] company_id Company ID + # @macro share_input_fields + # @return [void] + def add_company_share(company_id, share) + path = "/companies/#{company_id}/shares" + defaults = { visibility: { code: 'anyone' } } + post(path, MultiJson.dump(defaults.merge(share)), "Content-Type" => "application/json") + end + + # (Create) authenticated user starts following a company + # + # @see http://developer.linkedin.com/documents/company-follow-and-suggestions + # + # @param [String] company_id Company ID + # @return [void] + def follow_company(company_id) + path = "/people/~/following/companies" + body = { id: company_id } + post(path, MultiJson.dump(body), "Content-Type" => "application/json") + end + + # (Destroy) authenticated user stops following a company + # + # @see http://developer.linkedin.com/documents/company-follow-and-suggestions + # + # @param [String] company_id Company ID + # @return [void] + def unfollow_company(company_id) + path = "/people/~/following/companies/id=#{company_id}" + delete(path) + end + end + end +end diff --git a/lib/linked_in/api/groups.rb b/lib/linked_in/api/groups.rb new file mode 100644 index 00000000..3483bd84 --- /dev/null +++ b/lib/linked_in/api/groups.rb @@ -0,0 +1,115 @@ +module LinkedIn + module Api + + # Groups API + # + # @see http://developer.linkedin.com/documents/groups-api Groups API + # @see http://developer.linkedin.com/documents/groups-fields Groups Fields + # + # The following API actions do not have corresponding methods in + # this module + # + # * PUT Change my Group Settings + # * POST Change my Group Settings + # * DELETE Leave a group + # * PUT Follow/unfollow a Group post + # * PUT Flag a Post as a Promotion or Job + # * DELETE Delete a Post + # * DELETE Flag a post as inappropriate + # * DELETE A comment or flag comment as inappropriate + # * DELETE Remove a Group Suggestion + # + # [(contribute here)](https://github.com/hexgnu/linkedin) + module Groups + + # Retrieve group suggestions for the current user + # + # Permissions: r_fullprofile + # + # @see http://developer.linkedin.com/documents/job-bookmarks-and-suggestions + # + # @macro person_path_options + # @return [LinkedIn::Mash] + def group_suggestions(options = {}) + path = "#{person_path(options)}/suggestions/groups" + simple_query(path, options) + end + + # Retrieve the groups a current user belongs to + # + # Permissions: rw_groups + # + # @see http://developer.linkedin.com/documents/groups-api + # + # @macro person_path_options + # @return [LinkedIn::Mash] + def group_memberships(options = {}) + path = "#{person_path(options)}/group-memberships" + simple_query(path, options) + end + + # Retrieve the profile of a group + # + # Permissions: rw_groups + # + # @see http://developer.linkedin.com/documents/groups-api + # + # @param [Hash] options identifies the group or groups + # @optio options [String] :id identifier for the group + # @return [LinkedIn::Mash] + def group_profile(options) + path = group_path(options) + simple_query(path, options) + end + + # Retrieve the posts in a group + # + # Permissions: rw_groups + # + # @see http://developer.linkedin.com/documents/groups-api + # + # @param [Hash] options identifies the group or groups + # @optio options [String] :id identifier for the group + # @optio options [String] :count + # @optio options [String] :start + # @return [LinkedIn::Mash] + def group_posts(options) + path = "#{group_path(options)}/posts" + simple_query(path, options) + end + + # @deprecated Use {#add_group_share} instead + def post_group_discussion(group_id, discussion) + warn 'Use add_group_share over post_group_discussion. This will be taken out in future versions' + add_group_share(group_id, discussion) + end + + # Create a share for a company that the authenticated user + # administers + # + # Permissions: rw_groups + # + # @see http://developer.linkedin.com/documents/groups-api#create + # + # @param [String] group_id Group ID + # @macro share_input_fields + # @return [void] + def add_group_share(group_id, share) + path = "/groups/#{group_id}/posts" + post(path, MultiJson.dump(share), "Content-Type" => "application/json") + end + + # (Update) User joins, or requests to join, a group + # + # @see http://developer.linkedin.com/documents/groups-api#membergroups + # + # @param [String] group_id Group ID + # @return [void] + def join_group(group_id) + path = "/people/~/group-memberships/#{group_id}" + body = {'membership-state' => {'code' => 'member' }} + put(path, MultiJson.dump(body), "Content-Type" => "application/json") + end + end + end +end diff --git a/lib/linked_in/api/jobs.rb b/lib/linked_in/api/jobs.rb new file mode 100644 index 00000000..3689bc28 --- /dev/null +++ b/lib/linked_in/api/jobs.rb @@ -0,0 +1,64 @@ +module LinkedIn + module Api + + # Jobs API + # + # @see http://developer.linkedin.com/documents/job-lookup-api-and-fields Job Lookup API and Fields + # @see http://developer.linkedin.com/documents/job-bookmarks-and-suggestions Job Bookmarks and Suggestions + # + # The following API actions do not have corresponding methods in + # this module + # + # * DELETE a Job Bookmark + # + # [(contribute here)](https://github.com/hexgnu/linkedin) + module Jobs + + # Retrieve likes on a particular company update: + # + # @see http://developer.linkedin.com/reading-company-shares + # + # @param [Hash] options identifies the job + # @option options [String] id unique identifier for a job + # @return [LinkedIn::Mash] + def job(options = {}) + path = jobs_path(options) + simple_query(path, options) + end + + # Retrieve the current members' job bookmarks + # + # @see http://developer.linkedin.com/documents/job-bookmarks-and-suggestions + # + # @macro person_path_options + # @return [LinkedIn::Mash] + def job_bookmarks(options = {}) + path = "#{person_path(options)}/job-bookmarks" + simple_query(path, options) + end + + # Retrieve job suggestions for the current user + # + # @see http://developer.linkedin.com/documents/job-bookmarks-and-suggestions + # + # @macro person_path_options + # @return [LinkedIn::Mash] + def job_suggestions(options = {}) + path = "#{person_path(options)}/suggestions/job-suggestions" + simple_query(path, options) + end + + # Create a job bookmark for the authenticated user + # + # @see http://developer.linkedin.com/documents/job-bookmarks-and-suggestions + # + # @param [String] job_id Job ID + # @return [void] + def add_job_bookmark(job_id) + path = "/people/~/job-bookmarks" + body = {'job' => {'id' => job_id}} + post(path, MultiJson.dump(body), "Content-Type" => "application/json") + end + end + end +end diff --git a/lib/linked_in/api/people.rb b/lib/linked_in/api/people.rb new file mode 100644 index 00000000..8f210284 --- /dev/null +++ b/lib/linked_in/api/people.rb @@ -0,0 +1,73 @@ +module LinkedIn + module Api + + # People APIs + # + # + # @see https://developer.linkedin.com/docs/fields/basic-profile Profile Fields + # @see http://developer.linkedin.com/documents/field-selectors Field Selectors + # @see http://developer.linkedin.com/documents/accessing-out-network-profiles Accessing Out of Network Profiles + module People + + # Retrieve a member's LinkedIn profile. + # + # Permissions: r_basicprofile, r_fullprofile + # + # @see https://developer.linkedin.com/docs/signin-with-linkedin#content-par_componenttabbedlist_resource_1_resourceparagraph_6 + # @macro person_path_options + # @option options [string] :secure-urls if 'true' URLs in responses will be HTTPS + # @return [LinkedIn::Mash] + def profile(options={}) + path = person_path(options) + simple_query(path, options) + end + + # Retrieve a list of 1st degree connections for a user who has + # granted access to his/her account + # + # Permissions: r_network + # + # @see http://developer.linkedin.com/documents/connections-api + # + # @macro person_path_options + # @return [LinkedIn::Mash] + def connections(options={}) + path = "#{person_path(options)}/connections" + simple_query(path, options) + end + + # Retrieve a list of the latest set of 1st degree connections for a + # user + # + # Permissions: r_network + # + # @see http://developer.linkedin.com/documents/connections-api + # + # @param [String] modified_since timestamp indicating since when + # you want to retrieve new connections + # @macro person_path_options + # @return [LinkedIn::Mash] + def new_connections(modified_since, options={}) + options.merge!('modified' => 'new', 'modified-since' => modified_since) + path = "#{person_path(options)}/connections" + simple_query(path, options) + end + + # Retrieve the picture url + # http://api.linkedin.com/v1/people/~/picture-urls::(original) + # + # Permissions: r_network + # + # @options [String] :id, the id of the person for whom you want the profile picture + # @options [String] :picture_size, default: 'original' + # @options [String] :secure, default: 'false', options: ['false','true'] + # + # example for use in code: client.picture_urls(:id => 'id_of_connection') + def picture_urls(options={}) + picture_size = options.delete(:picture_size) || 'original' + path = "#{picture_urls_path(options)}::(#{picture_size})" + simple_query(path, options) + end + end + end +end diff --git a/lib/linked_in/api/query_helpers.rb b/lib/linked_in/api/query_helpers.rb new file mode 100644 index 00000000..a1be84fe --- /dev/null +++ b/lib/linked_in/api/query_helpers.rb @@ -0,0 +1,86 @@ +module LinkedIn + module Api + + module QueryHelpers + private + + def group_path(options) + path = "/groups" + if id = options.delete(:id) + path += "/#{id}" + end + end + + def simple_query(path, options={}) + fields = options.delete(:fields) || LinkedIn.default_profile_fields + + if options.delete(:public) + path +=":public" + elsif fields + path +=":(#{build_fields_params(fields)})" + end + + headers = options.delete(:headers) || {} + params = to_query(options) + path += "#{path.include?("?") ? "&" : "?"}#{params}" if !params.empty? + + Mash.from_json(get(path, headers)) + end + + def build_fields_params(fields) + if fields.is_a?(Hash) && !fields.empty? + fields.map {|index,value| "#{index}:(#{build_fields_params(value)})" }.join(',') + elsif fields.respond_to?(:each) + fields.map {|field| build_fields_params(field) }.join(',') + else + fields.to_s.gsub("_", "-") + end + end + + def person_path(options) + path = "/people" + if id = options.delete(:id) + path += "/id=#{id}" + elsif url = options.delete(:url) + path += "/url=#{CGI.escape(url)}" + elsif email = options.delete(:email) + path += "::(#{email})" + else + path += "/~" + end + end + + def company_path(options) + path = "/companies" + + if domain = options.delete(:domain) + path += "?email-domain=#{CGI.escape(domain)}" + elsif id = options.delete(:id) + path += "/#{id}" + elsif url = options.delete(:url) + path += "/url=#{CGI.escape(url)}" + elsif name = options.delete(:name) + path += "/universal-name=#{CGI.escape(name)}" + elsif is_admin = options.delete(:is_admin) + path += "?is-company-admin=#{CGI.escape(is_admin)}" + else + path += "/~" + end + end + + def picture_urls_path(options) + path = person_path(options) + path += "/picture-urls" + end + + def jobs_path(options) + path = "/jobs" + if id = options.delete(:id) + path += "/id=#{id}" + else + path += "/~" + end + end + end + end +end diff --git a/lib/linked_in/api/query_methods.rb b/lib/linked_in/api/query_methods.rb deleted file mode 100644 index 20a4907a..00000000 --- a/lib/linked_in/api/query_methods.rb +++ /dev/null @@ -1,78 +0,0 @@ -module LinkedIn - module Api - - module QueryMethods - - def profile(options={}) - path = person_path(options) - simple_query(path, options) - end - - def connections(options={}) - path = "#{person_path(options)}/connections" - simple_query(path, options) - end - - def network_updates(options={}) - path = "#{person_path(options)}/network/updates" - simple_query(path, options) - end - - def company(options = {}) - path = company_path(options) - simple_query(path, options) - end - - def group_memberships(options = {}) - path = "#{person_path(options)}/group-memberships" - simple_query(path, options) - end - - private - - def simple_query(path, options={}) - fields = options.delete(:fields) || LinkedIn.default_profile_fields - - if options.delete(:public) - path +=":public" - elsif fields - path +=":(#{fields.map{ |f| f.to_s.gsub("_","-") }.join(',')})" - end - - headers = options.delete(:headers) || {} - params = options.map { |k,v| "#{k}=#{v}" }.join("&") - path += "?#{params}" if not params.empty? - - Mash.from_json(get(path, headers)) - end - - def person_path(options) - path = "/people/" - if id = options.delete(:id) - path += "id=#{id}" - elsif url = options.delete(:url) - path += "url=#{CGI.escape(url)}" - else - path += "~" - end - end - - def company_path(options) - path = "/companies/" - if id = options.delete(:id) - path += "id=#{id}" - elsif url = options.delete(:url) - path += "url=#{CGI.escape(url)}" - elsif name = options.delete(:name) - path += "universal-name=#{CGI.escape(name)}" - elsif domain = options.delete(:domain) - path += "email-domain=#{CGI.escape(domain)}" - else - path += "~" - end - end - - end - - end -end diff --git a/lib/linked_in/api/share_and_social_stream.rb b/lib/linked_in/api/share_and_social_stream.rb new file mode 100644 index 00000000..1ba97e7e --- /dev/null +++ b/lib/linked_in/api/share_and_social_stream.rb @@ -0,0 +1,137 @@ +module LinkedIn + module Api + + # Share and Social Stream APIs + # + # @see https://developer.linkedin.com/docs/share-on-linkedin Share API + # + # The following API actions do not have corresponding methods in + # this module + # + # * GET Network Statistics + # * POST Post Network Update + # + # [(contribute here)](https://github.com/hexgnu/linkedin) + module ShareAndSocialStream + + # Retrieve the authenticated users network updates + # + # Permissions: rw_nus + # + # @see http://developer.linkedin.com/documents/get-network-updates-and-statistics-api + # @see http://developer.linkedin.com/documents/network-update-types Network Update Types + # + # @macro person_path_options + # @option options [String] :scope + # @option options [String] :type + # @option options [String] :count + # @option options [String] :start + # @option options [String] :after + # @option options [String] :before + # @option options [String] :show-hidden-members + # @return [LinkedIn::Mash] + def network_updates(options={}) + path = "#{person_path(options)}/network/updates" + simple_query(path, options) + end + + # TODO refactor to use #network_updates + def shares(options={}) + path = "#{person_path(options)}/network/updates" + simple_query(path, {:type => "SHAR", :scope => "self"}.merge(options)) + end + + def share(update_key, options={}) + path = "#{person_path(options)}/network/updates/key=#{update_key}" + simple_query(path, options) + end + + # Retrieve all comments for a particular network update + # + # @note The first 5 comments are included in the response to #network_updates + # + # Permissions: rw_nus + # + # @see http://developer.linkedin.com/documents/commenting-reading-comments-and-likes-network-updates + # + # @param [String] update_key a update/update-key representing a + # particular network update + # @macro person_path_options + # @return [LinkedIn::Mash] + def share_comments(update_key, options={}) + path = "#{person_path(options)}/network/updates/key=#{update_key}/update-comments" + simple_query(path, options) + end + + # Retrieve all likes for a particular network update + # + # @note Some likes are included in the response to #network_updates + # + # Permissions: rw_nus + # + # @see http://developer.linkedin.com/documents/commenting-reading-comments-and-likes-network-updates + # + # @param [String] update_key a update/update-key representing a + # particular network update + # @macro person_path_options + # @return [LinkedIn::Mash] + def share_likes(update_key, options={}) + path = "#{person_path(options)}/network/updates/key=#{update_key}/likes" + simple_query(path, options) + end + + # Create a share for the authenticated user + # + # Permissions: rw_nus + # + # @see https://developer.linkedin.com/docs/share-on-linkedin Share API + # + # @macro share_input_fields + # @return [void] + def add_share(share) + path = "/people/~/shares" + defaults = {:visibility => {:code => "anyone"}} + post(path, MultiJson.dump(defaults.merge(share)), "Content-Type" => "application/json") + end + + # Create a comment on an update from the authenticated user + # + # @see http://developer.linkedin.com/documents/commenting-reading-comments-and-likes-network-updates + # + # @param [String] update_key a update/update-key representing a + # particular network update + # @param [String] comment The text of the comment + # @return [void] + def update_comment(update_key, comment) + path = "/people/~/network/updates/key=#{update_key}/update-comments" + body = {'comment' => comment} + post(path, MultiJson.dump(body), "Content-Type" => "application/json") + end + + # (Update) like an update as the authenticated user + # + # @see http://developer.linkedin.com/documents/commenting-reading-comments-and-likes-network-updates + # + # @param [String] update_key a update/update-key representing a + # particular network update + # @return [void] + def like_share(update_key) + path = "/people/~/network/updates/key=#{update_key}/is-liked" + put(path, 'true', "Content-Type" => "application/json") + end + + # (Destroy) unlike an update the authenticated user previously + # liked + # + # @see http://developer.linkedin.com/documents/commenting-reading-comments-and-likes-network-updates + # + # @param [String] update_key a update/update-key representing a + # particular network update + # @return [void] + def unlike_share(update_key) + path = "/people/~/network/updates/key=#{update_key}/is-liked" + put(path, 'false', "Content-Type" => "application/json") + end + end + end +end diff --git a/lib/linked_in/api/update_methods.rb b/lib/linked_in/api/update_methods.rb deleted file mode 100644 index f69e2d04..00000000 --- a/lib/linked_in/api/update_methods.rb +++ /dev/null @@ -1,58 +0,0 @@ -module LinkedIn - module Api - - module UpdateMethods - - def add_share(share) - path = "/people/~/shares" - defaults = {:visibility => {:code => "anyone"}} - post(path, defaults.merge(share).to_json, "Content-Type" => "application/json") - end - - def join_group(group_id) - path = "/people/~/group-memberships/#{group_id}" - body = {'membership-state' => {'code' => 'member' }} - put(path, body.to_json, "Content-Type" => "application/json") - end - - # def share(options={}) - # path = "/people/~/shares" - # defaults = { :visability => 'anyone' } - # post(path, share_to_xml(defaults.merge(options))) - # end - # - # def update_comment(network_key, comment) - # path = "/people/~/network/updates/key=#{network_key}/update-comments" - # post(path, comment_to_xml(comment)) - # end - # - # def update_network(message) - # path = "/people/~/person-activities" - # post(path, network_update_to_xml(message)) - # end - # - def send_message(subject, body, recipient_paths) - path = "/people/~/mailbox" - - message = { - 'subject' => subject, - 'body' => body, - 'recipients' => { - 'values' => recipient_paths.map do |profile_path| - { 'person' => { '_path' => "/people/#{profile_path}" } } - end - } - } - post(path, message.to_json, "Content-Type" => "application/json") - end - # - # def clear_status - # path = "/people/~/current-status" - # delete(path).code - # end - # - - end - - end -end diff --git a/lib/linked_in/client.rb b/lib/linked_in/client.rb index fdf99dca..645f196d 100644 --- a/lib/linked_in/client.rb +++ b/lib/linked_in/client.rb @@ -5,8 +5,13 @@ module LinkedIn class Client include Helpers::Request include Helpers::Authorization - include Api::QueryMethods - include Api::UpdateMethods + include Api::QueryHelpers + include Api::People + include Api::Groups + include Api::Companies + include Api::Jobs + include Api::ShareAndSocialStream + include Api::Communications include Search attr_reader :consumer_token, :consumer_secret, :consumer_options diff --git a/lib/linked_in/errors.rb b/lib/linked_in/errors.rb index d7a173b4..6603eb7e 100644 --- a/lib/linked_in/errors.rb +++ b/lib/linked_in/errors.rb @@ -8,12 +8,22 @@ def initialize(data) end end + # Raised when a 401 response status code is received class UnauthorizedError < LinkedInError; end + + # Raised when a 400 response status code is received class GeneralError < LinkedInError; end + + # Raised when a 403 response status code is received class AccessDeniedError < LinkedInError; end - class UnavailableError < StandardError; end - class InformLinkedInError < StandardError; end - class NotFoundError < StandardError; end + # Raised when a 404 response status code is received + class NotFoundError < LinkedInError; end + + # Raised when a 500 response status code is received + class InformLinkedInError < LinkedInError; end + + # Raised when a 502 or 503 response status code is received + class UnavailableError < LinkedInError; end end end diff --git a/lib/linked_in/helpers/authorization.rb b/lib/linked_in/helpers/authorization.rb index c691c9e8..1a2f9720 100644 --- a/lib/linked_in/helpers/authorization.rb +++ b/lib/linked_in/helpers/authorization.rb @@ -4,38 +4,32 @@ module Helpers module Authorization DEFAULT_OAUTH_OPTIONS = { - :request_token_path => "/uas/oauth/requestToken", - :access_token_path => "/uas/oauth/accessToken", - :authorize_path => "/uas/oauth/authorize", + :token_path => "/uas/oauth2/accessToken", + :authorize_path => "/uas/oauth2/authorization", :api_host => "https://api.linkedin.com", :auth_host => "https://www.linkedin.com" } def consumer - @consumer ||= ::OAuth::Consumer.new(@consumer_token, @consumer_secret, parse_oauth_options) - end - - # Note: If using oauth with a web app, be sure to provide :oauth_callback. - # Options: - # :oauth_callback => String, url that LinkedIn should redirect to - def request_token(options={}) - @request_token ||= consumer.get_request_token(options) + @consumer ||= ::OAuth2::Client.new(@consumer_token, @consumer_secret, parse_oauth_options) end # For web apps use params[:oauth_verifier], for desktop apps, # use the verifier is the pin that LinkedIn gives users. - def authorize_from_request(request_token, request_secret, verifier_or_pin) - request_token = ::OAuth::RequestToken.new(consumer, request_token, request_secret) - access_token = request_token.get_access_token(:oauth_verifier => verifier_or_pin) - @auth_token, @auth_secret = access_token.token, access_token.secret + def authorize_from_request(code, params = {}) + @auth_token = consumer.auth_code.get_token(code, params).token end def access_token - @access_token ||= ::OAuth::AccessToken.new(consumer, @auth_token, @auth_secret) + @access_token ||= ::OAuth2::AccessToken.new(consumer, @auth_token) + end + + def authorize_url(params = {}) + consumer.auth_code.authorize_url(params) end - def authorize_from_access(atoken, asecret) - @auth_token, @auth_secret = atoken, asecret + def authorize_from_access(atoken) + @auth_token = atoken end private @@ -45,10 +39,10 @@ def authorize_from_access(atoken, asecret) # of the url creation ourselves. def parse_oauth_options { - :request_token_url => full_oauth_url_for(:request_token, :api_host), - :access_token_url => full_oauth_url_for(:access_token, :api_host), - :authorize_url => full_oauth_url_for(:authorize, :auth_host), - :site => @consumer_options[:site] || @consumer_options[:api_host] || DEFAULT_OAUTH_OPTIONS[:api_host] + :token_url => full_oauth_url_for(:token, :api_host), + :authorize_url => full_oauth_url_for(:authorize, :auth_host), + :site => @consumer_options[:site] || @consumer_options[:api_host] || DEFAULT_OAUTH_OPTIONS[:api_host], + :raise_errors => false } end diff --git a/lib/linked_in/helpers/request.rb b/lib/linked_in/helpers/request.rb index 99f1b86c..ee4f9c13 100644 --- a/lib/linked_in/helpers/request.rb +++ b/lib/linked_in/helpers/request.rb @@ -12,25 +12,25 @@ module Request protected def get(path, options={}) - response = access_token.get("#{API_PATH}#{path}", DEFAULT_HEADERS.merge(options)) + response = access_token.get("#{API_PATH}#{path}", {:headers => DEFAULT_HEADERS.merge(options)}) raise_errors(response) response.body end def post(path, body='', options={}) - response = access_token.post("#{API_PATH}#{path}", body, DEFAULT_HEADERS.merge(options)) + response = access_token.post("#{API_PATH}#{path}", {:body => body, :headers => DEFAULT_HEADERS.merge(options)}) raise_errors(response) response end def put(path, body, options={}) - response = access_token.put("#{API_PATH}#{path}", body, DEFAULT_HEADERS.merge(options)) + response = access_token.put("#{API_PATH}#{path}", {:body => body, :headers => DEFAULT_HEADERS.merge(options)}) raise_errors(response) response end def delete(path, options={}) - response = access_token.delete("#{API_PATH}#{path}", DEFAULT_HEADERS.merge(options)) + response = access_token.delete("#{API_PATH}#{path}", {:headers => DEFAULT_HEADERS.merge(options)}) raise_errors(response) response end @@ -40,7 +40,7 @@ def delete(path, options={}) def raise_errors(response) # Even if the json answer contains the HTTP status code, LinkedIn also sets this code # in the HTTP answer (thankfully). - case response.code.to_i + case response.status.to_i when 401 data = Mash.from_json(response.body) raise LinkedIn::Errors::UnauthorizedError.new(data), "(#{data.status}): #{data.message}" @@ -51,19 +51,24 @@ def raise_errors(response) data = Mash.from_json(response.body) raise LinkedIn::Errors::AccessDeniedError.new(data), "(#{data.status}): #{data.message}" when 404 - raise LinkedIn::Errors::NotFoundError, "(#{response.code}): #{response.message}" + raise LinkedIn::Errors::NotFoundError, "(#{response.status}): #{response.message}" when 500 - raise LinkedIn::Errors::InformLinkedInError, "LinkedIn had an internal error. Please let them know in the forum. (#{response.code}): #{response.message}" + raise LinkedIn::Errors::InformLinkedInError, "LinkedIn had an internal error. Please let them know in the forum. (#{response.status}): #{response.message}" when 502..503 - raise LinkedIn::Errors::UnavailableError, "(#{response.code}): #{response.message}" + raise LinkedIn::Errors::UnavailableError, "(#{response.status}): #{response.message}" end end - def to_query(options) - options.inject([]) do |collection, opt| - collection << "#{opt[0]}=#{opt[1]}" - collection - end * '&' + + # Stolen from Rack::Util.build_query + def to_query(params) + params.map { |k, v| + if v.class == Array + to_query(v.map { |x| [k, x] }) + else + v.nil? ? escape(k) : "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" + end + }.join("&") end def to_uri(path, options) diff --git a/lib/linked_in/mash.rb b/lib/linked_in/mash.rb index 8079fff8..b07e8ddd 100644 --- a/lib/linked_in/mash.rb +++ b/lib/linked_in/mash.rb @@ -2,15 +2,23 @@ require 'multi_json' module LinkedIn + + # The generalized pseudo-object that is returned for all query + # requests. class Mash < ::Hashie::Mash - # a simple helper to convert a json string to a Mash + # Convert a json string to a Mash + # + # @param [String] json_string + # @return [LinkedIn::Mash] def self.from_json(json_string) result_hash = ::MultiJson.decode(json_string) new(result_hash) end - # returns a Date if we have year, month and day, and no conflicting key + # Returns a Date if we have year, month and day, and no conflicting key + # + # @return [Date] def to_date if !self.has_key?('to_date') && contains_date_fields? Date.civil(self.year, self.month, self.day) @@ -19,6 +27,20 @@ def to_date end end + # Returns the id of the object from LinkedIn + # + # @return [String] + def id + if self['id'] + self['id'] + else + self['_key'] + end + end + + # Convert the 'timestamp' field from a string to a Time object + # + # @return [Time] def timestamp value = self['timestamp'] if value.kind_of? Integer @@ -29,6 +51,13 @@ def timestamp end end + # Return the results array from the query + # + # @return [Array] + def all + super || [] + end + protected def contains_date_fields? @@ -39,8 +68,6 @@ def contains_date_fields? # keys are made a little more ruby-ish def convert_key(key) case key.to_s - when '_key' - 'id' when '_total' 'total' when 'values' diff --git a/lib/linked_in/search.rb b/lib/linked_in/search.rb index 1edc7e16..2cf3f821 100644 --- a/lib/linked_in/search.rb +++ b/lib/linked_in/search.rb @@ -1,6 +1,21 @@ module LinkedIn module Search + + # Retrieve search results of the given object type + # + # Permissions: (for people search only) r_network + # + # @note People Search API is a part of the Vetted API Access Program. You + # must apply and get approval before using this API + # + # @see http://developer.linkedin.com/documents/people-search-api People Search + # @see http://developer.linkedin.com/documents/job-search-api Job Search + # @see http://developer.linkedin.com/documents/company-search Company Search + # + # @param [Hash] options search input fields + # @param [String] type type of object to return ('people', 'job' or 'company') + # @return [LinkedIn::Mash] def search(options={}, type='people') path = "/#{type.to_s}-search" @@ -53,4 +68,4 @@ def field_selector(fields) end end -end \ No newline at end of file +end diff --git a/lib/linked_in/version.rb b/lib/linked_in/version.rb index de2a34be..0c4c7b6b 100644 --- a/lib/linked_in/version.rb +++ b/lib/linked_in/version.rb @@ -1,9 +1,9 @@ module LinkedIn module VERSION #:nodoc: - MAJOR = 0 - MINOR = 3 - PATCH = 7 + MAJOR = 1 + MINOR = 1 + PATCH = 1 PRE = nil STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.') end diff --git a/lib/linkedin.rb b/lib/linkedin.rb index e6137897..c17305ea 100644 --- a/lib/linkedin.rb +++ b/lib/linkedin.rb @@ -1,4 +1,4 @@ -require 'oauth' +require 'oauth2' module LinkedIn @@ -7,15 +7,18 @@ class << self # config/initializers/linkedin.rb (for instance) # + # ```ruby # LinkedIn.configure do |config| # config.token = 'consumer_token' # config.secret = 'consumer_secret' - # config.default_profile_fields = ['education', 'positions'] + # config.default_profile_fields = ['educations', 'positions'] # end - # + # ``` # elsewhere # + # ```ruby # client = LinkedIn::Client.new + # ``` def configure yield self true diff --git a/linkedin.gemspec b/linkedin.gemspec index 5c45e199..2fc9355f 100644 --- a/linkedin.gemspec +++ b/linkedin.gemspec @@ -2,24 +2,26 @@ require File.expand_path('../lib/linked_in/version', __FILE__) Gem::Specification.new do |gem| - gem.add_dependency 'hashie', '~> 1.2' + gem.add_dependency 'hashie', '~> 3.0' gem.add_dependency 'multi_json', '~> 1.0' - gem.add_dependency 'oauth', '~> 0.4' - gem.add_development_dependency 'json', '~> 1.6' - gem.add_development_dependency 'rake', '~> 0.9' - gem.add_development_dependency 'rdoc', '~> 3.8' - gem.add_development_dependency 'rspec', '~> 2.6' - gem.add_development_dependency 'simplecov', '~> 0.5' - gem.add_development_dependency 'vcr', '~> 1.10' - gem.add_development_dependency 'webmock', '~> 1.7' - gem.authors = ["Wynn Netherland", "Josh Kalderimis"] - gem.description = %q{Ruby wrapper for the LinkedIn API} - gem.email = ['wynn.netherland@gmail.com', 'josh.kalderimis@gmail.com'] + gem.add_dependency 'oauth2', '~> 1.0' + # gem.add_development_dependency 'json', '~> 1.6' + gem.add_development_dependency 'rake', '~> 10' + gem.add_development_dependency 'yard' + gem.add_development_dependency 'kramdown' + gem.add_development_dependency 'rspec', '~> 2.13' + gem.add_development_dependency 'simplecov', '~> 0.7' + gem.add_development_dependency 'vcr', '~> 2.5' + gem.add_development_dependency 'webmock', '~> 1.11' + gem.authors = ['Matthew Kirk', 'Wynn Netherland', 'Josh Kalderimis'] + gem.description = 'Ruby wrapper for the LinkedIn API' + gem.email = ['meteor.kirk@gmail.com', 'wynn.netherland@gmail.com', 'josh.kalderimis@gmail.com'] gem.files = `git ls-files`.split("\n") - gem.homepage = 'http://github.com/pengwynn/linkedin' + gem.homepage = 'http://github.com/hexgnu/linkedin' gem.name = 'linkedin' + gem.licenses = %w[MIT] gem.require_paths = ['lib'] - gem.summary = gem.description + gem.summary = 'This gem interfaces with the Linkedin XML and JSON APis' gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") gem.version = LinkedIn::VERSION::STRING end diff --git a/spec/cases/api_spec.rb b/spec/cases/api_spec.rb index 6398138d..1d73c707 100644 --- a/spec/cases/api_spec.rb +++ b/spec/cases/api_spec.rb @@ -4,11 +4,11 @@ before do LinkedIn.default_profile_fields = nil client.stub(:consumer).and_return(consumer) - client.authorize_from_access('atoken', 'asecret') + client.authorize_from_access('77j2rfbjbmkcdh') end let(:client){LinkedIn::Client.new('token', 'secret')} - let(:consumer){OAuth::Consumer.new('token', 'secret', {:site => 'https://api.linkedin.com'})} + let(:consumer){OAuth2::Client.new('token', 'secret', {:site => 'https://api.linkedin.com', :raise_errors => false})} it "should be able to view the account profile" do stub_request(:get, "https://api.linkedin.com/v1/people/~").to_return(:body => "{}") @@ -20,16 +20,37 @@ client.profile(:id => 123).should be_an_instance_of(LinkedIn::Mash) end + it "should be able to view the picture urls" do + stub_request(:get, "https://api.linkedin.com/v1/people/~/picture-urls::(original)").to_return(:body => "{}") + client.picture_urls.should be_an_instance_of(LinkedIn::Mash) + end + it "should be able to view connections" do stub_request(:get, "https://api.linkedin.com/v1/people/~/connections").to_return(:body => "{}") client.connections.should be_an_instance_of(LinkedIn::Mash) end + it "should be able to view new connections" do + modified_since = Time.now.to_i * 1000 + stub_request(:get, "https://api.linkedin.com/v1/people/~/connections?modified=new&modified-since=#{modified_since}").to_return(:body => "{}") + client.new_connections(modified_since).should be_an_instance_of(LinkedIn::Mash) + end + it "should be able to view network_updates" do stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates").to_return(:body => "{}") client.network_updates.should be_an_instance_of(LinkedIn::Mash) end + it "should be able to view network_update's comments" do + stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates/key=network_update_key/update-comments").to_return(:body => "{}") + client.share_comments("network_update_key").should be_an_instance_of(LinkedIn::Mash) + end + + it "should be able to view network_update's likes" do + stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates/key=network_update_key/likes").to_return(:body => "{}") + client.share_likes("network_update_key").should be_an_instance_of(LinkedIn::Mash) + end + it "should be able to search with a keyword if given a String" do stub_request(:get, "https://api.linkedin.com/v1/people-search?keywords=business").to_return(:body => "{}") client.search("business").should be_an_instance_of(LinkedIn::Mash) @@ -41,7 +62,8 @@ end it "should be able to search with an option and fetch specific fields" do - stub_request(:get, "https://api.linkedin.com/v1/people-search:(num-results,total)?first-name=Javan").to_return(:body => "{}") + stub_request(:get, "https://api.linkedin.com/v1/people-search:(num-results,total)?first-name=Javan").to_return( + :body => "{}") client.search(:first_name => "Javan", :fields => ["num_results", "total"]).should be_an_instance_of(LinkedIn::Mash) end @@ -49,22 +71,55 @@ stub_request(:post, "https://api.linkedin.com/v1/people/~/shares").to_return(:body => "", :status => 201) response = client.add_share(:comment => "Testing, 1, 2, 3") response.body.should == "" - response.code.should == "201" + response.status.should == 201 + end + + it "should be able to share a new company status" do + stub_request(:post, "https://api.linkedin.com/v1/companies/123456/shares").to_return(:body => "", :status => 201) + response = client.add_company_share("123456", { :comment => "Testing, 1, 2, 3" }) + response.body.should == "" + response.status.should == 201 + end + + it "returns the shares for a person" do + stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates?type=SHAR&scope=self&after=1234&count=35").to_return( + :body => "{}") + client.shares(:after => 1234, :count => 35) + end + + it "should be able to fetch a single share" do + stub_request(:get, "https://api.linkedin.com/v1/people/~/network/updates/key=network_update_key").to_return(:body => "{}") + client.share("network_update_key").should be_an_instance_of(LinkedIn::Mash) + end + + it "should be able to comment on network update" do + stub_request(:post, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/update-comments").to_return( + :body => "", :status => 201) + response = client.update_comment('SOMEKEY', "Testing, 1, 2, 3") + response.body.should == "" + response.status.should == 201 end - it "should be able to send a message" do - stub_request(:post, "https://api.linkedin.com/v1/people/~/mailbox").to_return(:body => "", :status => 201) - response = client.send_message("subject", "body", ["recip1", "recip2"]) + it "should be able to like a network update" do + stub_request(:put, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/is-liked"). + with(:body => "true").to_return(:body => "", :status => 201) + response = client.like_share('SOMEKEY') response.body.should == "" - response.code.should == "201" + response.status.should == 201 end + it "should be able to unlike a network update" do + stub_request(:put, "https://api.linkedin.com/v1/people/~/network/updates/key=SOMEKEY/is-liked"). + with(:body => "false").to_return(:body => "", :status => 201) + response = client.unlike_share('SOMEKEY') + response.body.should == "" + response.status.should == 201 + end - context "Company API" do - use_vcr_cassette + context "Company API", :vcr do it "should be able to view a company profile" do - stub_request(:get, "https://api.linkedin.com/v1/companies/id=1586").to_return(:body => "{}") + stub_request(:get, "https://api.linkedin.com/v1/companies/1586").to_return(:body => "{}") client.company(:id => 1586).should be_an_instance_of(LinkedIn::Mash) end @@ -74,13 +129,24 @@ end it "should be able to view a company by e-mail domain" do - stub_request(:get, "https://api.linkedin.com/v1/companies/email-domain=acme.com").to_return(:body => "{}") + stub_request(:get, "https://api.linkedin.com/v1/companies?email-domain=acme.com").to_return(:body => "{}") client.company(:domain => 'acme.com').should be_an_instance_of(LinkedIn::Mash) end + it "should be able to view a user's company pages" do + stub_request(:get, "https://api.linkedin.com/v1/companies?is-company-admin=true").to_return(:body => "{}") + client.company(:is_admin => 'true').should be_an_instance_of(LinkedIn::Mash) + end + + it "should be able to page a user's company pages" do + stub_request(:get, "https://api.linkedin.com/v1/companies?is-company-admin=true&count=10&start=0").to_return(:body => "{}") + client.company(:is_admin => 'true', :count => 10, :start => 0).should be_an_instance_of(LinkedIn::Mash) + end + it "should load correct company data" do + stub_request(:get, "https://api.linkedin.com/v1/companies/1586:(id,name,industry,locations:(address:(city,state,country-code),is-headquarters),employee-count-range)").to_return(:body => "{\"id\":1586,\"name\":\"Amazon\",\"employee_count_range\":{\"name\":\"10001+\"},\"industry\":\"Internet\",\"locations\":{\"all\":[{\"address\":{\"city\":\"Seattle\"},\"is_headquarters\":true}]}}") + stub_request(:get, "https://api.linkedin.com/v1/companies/1586").to_return(:body => "{\"id\":1586,\"name\":\"Amazon\"}") client.company(:id => 1586).name.should == "Amazon" - data = client.company(:id => 1586, :fields => %w{ id name industry locations:(address:(city state country-code) is-headquarters) employee-count-range }) data.id.should == 1586 data.name.should == "Amazon" @@ -89,6 +155,68 @@ data.locations.all[0].address.city.should == "Seattle" data.locations.all[0].is_headquarters.should == true end + + it "should be able to view company_updates" do + stub_request(:get, "https://api.linkedin.com/v1/companies/1586/updates").to_return(:body => "{}") + client.company_updates(:id => 1586).should be_an_instance_of(LinkedIn::Mash) + end + + it "should be able to view company_statistic" do + stub_request(:get, "https://api.linkedin.com/v1/companies/1586/company-statistics").to_return(:body => "{}") + client.company_statistics(:id => 1586).should be_an_instance_of(LinkedIn::Mash) + end + + it "should be able to view company updates comments" do + stub_request(:get, "https://api.linkedin.com/v1/companies/1586/updates/key=company_update_key/update-comments").to_return(:body => "{}") + client.company_updates_comments("company_update_key", :id => 1586).should be_an_instance_of(LinkedIn::Mash) + end + + it "should be able to view company updates likes" do + stub_request(:get, "https://api.linkedin.com/v1/companies/1586/updates/key=company_update_key/likes").to_return(:body => "{}") + client.company_updates_likes("company_update_key", :id => 1586).should be_an_instance_of(LinkedIn::Mash) + end + + it "should be able to follow a company" do + stub_request(:post, "https://api.linkedin.com/v1/people/~/following/companies").to_return(:body => "", :status => 201) + + response = client.follow_company(1586) + response.body.should == "" + response.status.should == 201 + end + + it "should be able to unfollow a company" do + stub_request(:delete, "https://api.linkedin.com/v1/people/~/following/companies/id=1586").to_return(:body => "", :status => 201) + + response = client.unfollow_company(1586) + response.body.should == "" + response.status.should == 201 + end + + end + + context "Job API", :vcr do + + it "should be able to view a job listing" do + stub_request(:get, "https://api.linkedin.com/v1/jobs/id=1586").to_return(:body => "{}") + client.job(:id => 1586).should be_an_instance_of(LinkedIn::Mash) + end + + it "should be able to view its job bookmarks" do + stub_request(:get, "https://api.linkedin.com/v1/people/~/job-bookmarks").to_return(:body => "{}") + client.job_bookmarks.should be_an_instance_of(LinkedIn::Mash) + end + + it "should be able to view its job suggestion" do + stub_request(:get, "https://api.linkedin.com/v1/people/~/suggestions/job-suggestions").to_return(:body => "{}") + client.job_suggestions.should be_an_instance_of(LinkedIn::Mash) + end + + it "should be able to add a bookmark" do + stub_request(:post, "https://api.linkedin.com/v1/people/~/job-bookmarks").to_return(:body => "", :status => 201) + response = client.add_job_bookmark(:id => 1452577) + response.body.should == "" + response.status.should == 201 + end end context "Group API" do @@ -98,14 +226,67 @@ client.group_memberships.should be_an_instance_of(LinkedIn::Mash) end + it "should be able to list suggested groups for a profile" do + stub_request(:get, "https://api.linkedin.com/v1/people/~/suggestions/groups").to_return(:body => '{"id": "123"}') + response = client.group_suggestions + response.id.should == '123' + end + + it "should be able to parse nested fields" do + stub_request(:get, "https://api.linkedin.com/v1/people/~/group-memberships:(group:(id,name,small-logo-url,short-description))").to_return(:body => "{}") + client.group_memberships(:fields => [{:group => ['id', 'name', 'small-logo-url', 'short-description']}]).should be_an_instance_of(LinkedIn::Mash) + end + it "should be able to join a group" do stub_request(:put, "https://api.linkedin.com/v1/people/~/group-memberships/123").to_return(:body => "", :status => 201) response = client.join_group(123) response.body.should == "" - response.code.should == "201" + response.status.should == 201 + end + + it "should be able to list a group profile" do + stub_request(:get, "https://api.linkedin.com/v1/groups/123").to_return(:body => '{"id": "123"}') + response = client.group_profile(:id => 123) + response.id.should == '123' end + it "should be able to list group posts" do + stub_request(:get, "https://api.linkedin.com/v1/groups/123/posts").to_return(:body => '{"id": "123"}') + response = client.group_posts(:id => 123) + response.id.should == '123' + end + + it 'should be able to post a discussion to a group' do + expected = { + 'title' => 'New Discussion', + 'summary' => 'New Summary', + 'content' => { + "submitted-url" => "http://www.google.com" + } + } + + stub_request(:post, "https://api.linkedin.com/v1/groups/123/posts").with(:body => expected).to_return(:body => "", :status => 201) + response = client.post_group_discussion(123, expected) + response.body.should == "" + response.status.should == 201 + end + + it "should be able to share a new group status" do + stub_request(:post, "https://api.linkedin.com/v1/groups/1/posts").to_return(:body => "", :status => 201) + response = client.add_group_share(1, :comment => "Testing, 1, 2, 3") + response.body.should == "" + response.status.should == 201 + end + end + + context "Communication API" do + it "should be able to send a message" do + stub_request(:post, "https://api.linkedin.com/v1/people/~/mailbox").to_return(:body => "", :status => 201) + response = client.send_message("subject", "body", ["recip1", "recip2"]) + response.body.should == "" + response.status.should == 201 + end end context "Errors" do diff --git a/spec/cases/linkedin_spec.rb b/spec/cases/linkedin_spec.rb index a6cd2940..af9ce004 100644 --- a/spec/cases/linkedin_spec.rb +++ b/spec/cases/linkedin_spec.rb @@ -17,21 +17,21 @@ end it "should be able to set the default profile fields" do - LinkedIn.default_profile_fields = ['education', 'positions'] + LinkedIn.default_profile_fields = ['educations', 'positions'] - LinkedIn.default_profile_fields.should == ['education', 'positions'] + LinkedIn.default_profile_fields.should == ['educations', 'positions'] end it "should be able to set the consumer token and consumer secret via a configure block" do LinkedIn.configure do |config| config.token = 'consumer_token' config.secret = 'consumer_secret' - config.default_profile_fields = ['education', 'positions'] + config.default_profile_fields = ['educations', 'positions'] end LinkedIn.token.should == 'consumer_token' LinkedIn.secret.should == 'consumer_secret' - LinkedIn.default_profile_fields.should == ['education', 'positions'] + LinkedIn.default_profile_fields.should == ['educations', 'positions'] end end diff --git a/spec/cases/mash_spec.rb b/spec/cases/mash_spec.rb index 982b38cc..08021e39 100644 --- a/spec/cases/mash_spec.rb +++ b/spec/cases/mash_spec.rb @@ -18,6 +18,7 @@ 'firstName' => 'Josh', 'LastName' => 'Kalderimis', '_key' => 1234, + 'id' => 1345, '_total' => 1234, 'values' => {}, 'numResults' => 'total_results' @@ -29,8 +30,23 @@ mash.should have_key('last_name') end - it "should convert the key _key to id" do - mash.should have_key('id') + # this breaks data coming back from linkedIn + it "converts _key to id if there is an id column" do + mash._key.should == 1234 + mash.id.should == 1345 + end + + context 'no collision' do + let(:mash) { + LinkedIn::Mash.new({ + '_key' => 1234 + }) + + } + it 'converts _key to id if there is no collision' do + mash.id.should == 1234 + mash._key.should == 1234 + end end it "should convert the key _total to total" do @@ -82,4 +98,16 @@ end end + describe "#all" do + let(:all_mash) do + LinkedIn::Mash.new({ + :values => nil + }) + end + + it "should return an empty array if values is nil due to no results being found for a query" do + all_mash.all.should == [] + end + end + end diff --git a/spec/cases/oauth_spec.rb b/spec/cases/oauth_spec.rb index 07c7792e..1c9bd4be 100644 --- a/spec/cases/oauth_spec.rb +++ b/spec/cases/oauth_spec.rb @@ -14,9 +14,8 @@ it "should return a configured OAuth consumer" do consumer.site.should == 'https://api.linkedin.com' - consumer.request_token_url.should == 'https://api.linkedin.com/uas/oauth/requestToken' - consumer.access_token_url.should == 'https://api.linkedin.com/uas/oauth/accessToken' - consumer.authorize_url.should == 'https://www.linkedin.com/uas/oauth/authorize' + consumer.token_url.should == 'https://api.linkedin.com/uas/oauth2/accessToken' + consumer.authorize_url.should == 'https://www.linkedin.com/uas/oauth2/authorization' end end @@ -30,43 +29,38 @@ it "should return a configured OAuth consumer" do consumer.site.should == 'https://api.josh.com' - consumer.request_token_url.should == 'https://api.josh.com/uas/oauth/requestToken' - consumer.access_token_url.should == 'https://api.josh.com/uas/oauth/accessToken' - consumer.authorize_url.should == 'https://www.josh.com/uas/oauth/authorize' + consumer.token_url.should == 'https://api.josh.com/uas/oauth2/accessToken' + consumer.authorize_url.should == 'https://www.josh.com/uas/oauth2/authorization' end end describe "different oauth paths" do let(:consumer) do LinkedIn::Client.new('1234', '1234', { - :request_token_path => "/secure/oauth/requestToken", - :access_token_path => "/secure/oauth/accessToken", - :authorize_path => "/secure/oauth/authorize", + :token_path => "/secure/oauth2/accessToken", + :authorize_path => "/secure/oauth2/authorization", }).consumer end it "should return a configured OAuth consumer" do consumer.site.should == 'https://api.linkedin.com' - consumer.request_token_url.should == 'https://api.linkedin.com/secure/oauth/requestToken' - consumer.access_token_url.should == 'https://api.linkedin.com/secure/oauth/accessToken' - consumer.authorize_url.should == 'https://www.linkedin.com/secure/oauth/authorize' + consumer.token_url.should == 'https://api.linkedin.com/secure/oauth2/accessToken' + consumer.authorize_url.should == 'https://www.linkedin.com/secure/oauth2/authorization' end end describe "specify oauth urls" do let(:consumer) do LinkedIn::Client.new('1234', '1234', { - :request_token_url => "https://api.josh.com/secure/oauth/requestToken", - :access_token_url => "https://api.josh.com/secure/oauth/accessToken", - :authorize_url => "https://www.josh.com/secure/oauth/authorize", + :token_url => "https://api.josh.com/secure/oauth2/accessToken", + :authorize_url => "https://www.josh.com/secure/oauth2/authorization", }).consumer end it "should return a configured OAuth consumer" do consumer.site.should == 'https://api.linkedin.com' - consumer.request_token_url.should == 'https://api.josh.com/secure/oauth/requestToken' - consumer.access_token_url.should == 'https://api.josh.com/secure/oauth/accessToken' - consumer.authorize_url.should == 'https://www.josh.com/secure/oauth/authorize' + consumer.token_url.should == 'https://api.josh.com/secure/oauth2/accessToken' + consumer.authorize_url.should == 'https://www.josh.com/secure/oauth2/authorization' end end @@ -79,88 +73,22 @@ it "should return a configured OAuth consumer" do consumer.site.should == 'https://api.josh.com' - consumer.request_token_url.should == 'https://api.josh.com/uas/oauth/requestToken' - consumer.access_token_url.should == 'https://api.josh.com/uas/oauth/accessToken' - consumer.authorize_url.should == 'https://api.josh.com/uas/oauth/authorize' + consumer.token_url.should == 'https://api.josh.com/uas/oauth2/accessToken' + consumer.authorize_url.should == 'https://api.josh.com/uas/oauth2/authorization' end end end - describe "#request_token" do - describe "with default options" do - use_vcr_cassette :record => :new_episodes - - it "should return a valid request token" do - request_token = client.request_token - - request_token.should be_a_kind_of OAuth::RequestToken - request_token.authorize_url.should include("https://www.linkedin.com/uas/oauth/authorize?oauth_token=") - - a_request(:post, "https://api.linkedin.com/uas/oauth/requestToken").should have_been_made.once - end - end - - describe "with a callback url" do - use_vcr_cassette :record => :new_episodes - - it "should return a valid access token" do - request_token = client.request_token(:oauth_callback => 'http://www.josh.com') - - request_token.should be_a_kind_of OAuth::RequestToken - request_token.authorize_url.should include("https://www.linkedin.com/uas/oauth/authorize?oauth_token=") - request_token.callback_confirmed?.should == true - - a_request(:post, "https://api.linkedin.com/uas/oauth/requestToken").should have_been_made.once - end - end - end - - describe "#authorize_from_request" do - let(:access_token) do - # if you remove the related casssette you will need to do the following - # authorize_from_request request manually - # - # request_token = client.request_token - # puts "token : #{request_token.token} - secret #{request_token.secret}" - # puts "auth url : #{request_token.authorize_url}" - # raise 'keep note of the token and secret' - # - client.authorize_from_request('dummy-token', 'dummy-secret', 'dummy-pin') - end - - use_vcr_cassette :record => :new_episodes, :match_requests_on => [:uri, :method] - - it "should return a valid access token" do - access_token.should be_a_kind_of Array - access_token[0].should be_a_kind_of String - access_token[1].should be_a_kind_of String - - a_request(:post, "https://api.linkedin.com/uas/oauth/accessToken").should have_been_made.once - end - end - describe "#access_token" do let(:access_token) do - client.authorize_from_access('dummy-token', 'dummy-secret') + client.authorize_from_access('dummy-token') client.access_token end it "should return a valid auth token" do - access_token.should be_a_kind_of OAuth::AccessToken + access_token.should be_a_kind_of OAuth2::AccessToken access_token.token.should be_a_kind_of String end end - describe "#authorize_from_access" do - let(:auth_token) do - client.authorize_from_access('dummy-token', 'dummy-secret') - end - - it "should return a valid auth token" do - auth_token.should be_a_kind_of Array - auth_token[0].should be_a_kind_of String - auth_token[1].should be_a_kind_of String - end - end - end diff --git a/spec/cases/search_spec.rb b/spec/cases/search_spec.rb index 0e31a363..27aeb817 100644 --- a/spec/cases/search_spec.rb +++ b/spec/cases/search_spec.rb @@ -11,15 +11,15 @@ client = LinkedIn::Client.new(consumer_token, consumer_secret) auth_token = ENV['LINKED_IN_AUTH_KEY'] || 'key' - auth_secret = ENV['LINKED_IN_AUTH_SECRET'] || 'secret' - client.authorize_from_access(auth_token, auth_secret) + client.authorize_from_access(auth_token) client end + vcr_options = { :record => :new_episodes} + describe "#search_company" do - describe "by keywords string parameter" do - use_vcr_cassette :record => :new_episodes + describe "by keywords string parameter", vcr: vcr_options do let(:results) do client.search('apple', :company) @@ -32,8 +32,7 @@ end end - describe "by single keywords option" do - use_vcr_cassette :record => :new_episodes + describe "by single keywords option", vcr: vcr_options do let(:results) do options = {:keywords => 'apple'} @@ -47,8 +46,7 @@ end end - describe "by single keywords option with facets to return" do - use_vcr_cassette :record => :new_episodes + describe "by single keywords option with facets to return", vcr: vcr_options do let(:results) do options = {:keywords => 'apple', :facets => [:industry]} @@ -60,8 +58,7 @@ end end - describe "by single keywords option with pagination" do - use_vcr_cassette :record => :new_episodes + describe "by single keywords option with pagination", vcr: vcr_options do let(:results) do options = {:keywords => 'apple', :start => 5, :count => 5} @@ -70,15 +67,14 @@ it "should perform a search" do results.companies.all.size.should == 5 - results.companies.all.first.name.should == 'Apple Vacations' - results.companies.all.first.id.should == 19271 - results.companies.all.last.name.should == 'Micro Center' - results.companies.all.last.id.should == 15552 + results.companies.all.first.name.should == 'iSquare - Apple Authorized Distributor in Greece & Cyprus' + results.companies.all.first.id.should == 2135525 + results.companies.all.last.name.should == 'Apple Crumble' + results.companies.all.last.id.should == 1049054 end end - describe "by keywords options with fields" do - use_vcr_cassette :record => :new_episodes + describe "by keywords options with fields", vcr: vcr_options do let(:results) do fields = [{:companies => [:id, :name, :industries, :description, :specialties]}, :num_results] @@ -87,7 +83,7 @@ it "should perform a search" do results.companies.all.first.name.should == 'Apple' - results.companies.all.first.description.should == 'Apple designs Macs, the best personal computers in the world, along with Mac OS X, iLife, iWork, and professional software. Apple leads the digital music revolution with its iPods and iTunes online store. Apple is reinventing the mobile phone with its revolutionary iPhone and App Store, and has recently introduced its magical iPad which is defining the future of mobile media and computing devices.' + results.companies.all.first.description.should == 'Apple designs Macs, the best personal computers in the world, along with OS X, iLife, iWork and professional software. Apple leads the digital music revolution with its iPods and iTunes online store. Apple has reinvented the mobile phone with its revolutionary iPhone and App Store, and is defining the future of mobile media and computing devices with iPad.' results.companies.all.first.id.should == 162479 end end @@ -96,99 +92,130 @@ describe "#search" do - describe "by keywords string parameter" do - use_vcr_cassette :record => :new_episodes + describe "by keywords string parameter", vcr: vcr_options do let(:results) do client.search('github') end it "should perform a search" do - results.people.all.size.should == 10 - results.people.all.first.first_name.should == 'Giliardi' - results.people.all.first.last_name.should == 'Pires' - results.people.all.first.id.should == 'YkdnFl04s_' + results.people.all.size.should == 6 + results.people.all.first.first_name.should == 'Shay' + results.people.all.first.last_name.should == 'Frendt' + results.people.all.first.id.should == 'ucXjUw4M9J' end end - describe "by single keywords option" do - use_vcr_cassette :record => :new_episodes + describe "by single keywords option", vcr: vcr_options do let(:results) do client.search(:keywords => 'github') end it "should perform a search" do - results.people.all.size.should == 10 - results.people.all.first.first_name.should == 'Giliardi' - results.people.all.first.last_name.should == 'Pires' - results.people.all.first.id.should == 'YkdnFl04s_' + results.people.all.size.should == 6 + results.people.all.first.first_name.should == 'Shay' + results.people.all.first.last_name.should == 'Frendt' + results.people.all.first.id.should == 'ucXjUw4M9J' end end - describe "by single keywords option with pagination" do - use_vcr_cassette :record => :new_episodes + describe "by single keywords option with pagination", vcr: vcr_options do let(:results) do client.search(:keywords => 'github', :start => 5, :count => 5) end it "should perform a search" do - results.people.all.size.should == 5 - results.people.all.first.first_name.should == 'Stephen' - results.people.all.first.last_name.should == 'M.' - results.people.all.first.id.should == 'z2XMcxa_dR' - results.people.all.last.first_name.should == 'Pablo' - results.people.all.last.last_name.should == 'C.' - results.people.all.last.id.should == 'pdzrGpyP0h' + results.people.all.size.should == 1 + results.people.all.first.first_name.should == 'Satish' + results.people.all.first.last_name.should == 'Talim' + results.people.all.first.id.should == 'V1FPuGot-I' end end - describe "by first_name and last_name options" do - use_vcr_cassette :record => :new_episodes + describe "by first_name and last_name options", vcr: vcr_options do let(:results) do - client.search(:first_name => 'Giliardi', :last_name => 'Pires') + client.search(:first_name => 'Charles', :last_name => 'Garcia') end it "should perform a search" do - results.people.all.size.should == 1 - results.people.all.first.first_name.should == 'Giliardi' - results.people.all.first.last_name.should == 'Pires' - results.people.all.first.id.should == 'YkdnFl04s_' + results.people.all.size.should == 10 + results.people.all.first.first_name.should == 'Charles' + results.people.all.first.last_name.should == 'Garcia, CFA' + results.people.all.first.id.should == '2zk34r8TvA' + end + end + + describe "by email address", vcr: vcr_options do + + let(:results) do + fields = ['id'] + client.profile(:email => 'email=yy@zz.com', :fields => fields) + end + + it "should perform a people search" do + results._total.should == 1 + output = results["values"] + output.each do |record| + record.id.should == '96GVfLeWjU' + record._key.should == 'email=yy@zz.com' + end end end - describe "by first_name and last_name options with fields" do - use_vcr_cassette :record => :new_episodes + describe "by multiple email address", vcr: vcr_options do + + let(:results) do + fields = ['id'] + client.profile(:email => 'email=yy@zz.com,email=xx@yy.com', :fields => fields) + end + + it "should perform a multi-email search" do + results._total.should == 2 + output = results["values"] + output.count.should == 2 + end + end + + describe "email search returns unauthorized", vcr: vcr_options do + + it "should raise an unauthorized error" do + fields = ['id'] + expect {client.profile(:email => 'email=aa@bb.com', :fields => fields)}.to raise_error(LinkedIn::Errors::UnauthorizedError) + end + end + + describe "by first_name and last_name options with fields", vcr: vcr_options do let(:results) do fields = [{:people => [:id, :first_name, :last_name, :public_profile_url, :picture_url]}, :num_results] - client.search(:first_name => 'Giliardi', :last_name => 'Pires', :fields => fields) + client.search(:first_name => 'Charles', :last_name => 'Garcia', :fields => fields) end it "should perform a search" do - results.people.all.size.should == 1 - results.people.all.first.first_name.should == 'Giliardi' - results.people.all.first.last_name.should == 'Pires' - results.people.all.first.id.should == 'YkdnFl04s_' - results.people.all.first.picture_url == 'http://media.linkedin.com/mpr/mprx/0_Oz05kn9xkWziAEOUKtOVkqzjXd8Clf7UyqIVkqchR2NtmwZRt1fWoN_aobhg-HmB09jUwPLKrAhU' - results.people.all.first.public_profile_url == 'http://www.linkedin.com/in/gibanet' + first_person = results.people.all.first + results.people.all.size.should == 10 + first_person.first_name.should == 'Charles' + first_person.last_name.should == 'Garcia, CFA' + first_person.id.should == '2zk34r8TvA' + first_person.picture_url.should be_nil + first_person.public_profile_url.should == 'http://www.linkedin.com/in/charlesgarcia' end end - describe "by company_name option" do - use_vcr_cassette :record => :new_episodes + describe "by company_name option", vcr: vcr_options do let(:results) do - client.search(:company_name => 'linkedin') + client.search(:company_name => 'IBM') end it "should perform a search" do - results.people.all.size.should == 10 - results.people.all.first.first_name.should == 'Donald' - results.people.all.first.last_name.should == 'Denker' - results.people.all.first.id.should == 'VQcsz5Hp_h' + results.people.all.size.should == 6 + results.people.all.first.first_name.should == 'Ryan' + results.people.all.first.last_name.should == 'Sue' + results.people.all.first.id.should == 'KHkgwBMaa-' end end @@ -203,4 +230,4 @@ end -end \ No newline at end of file +end diff --git a/spec/fixtures/cassette_library/LinkedIn_Api/Company_API.yml b/spec/fixtures/cassette_library/LinkedIn_Api/Company_API.yml index 2e4da51b..5e231240 100644 --- a/spec/fixtures/cassette_library/LinkedIn_Api/Company_API.yml +++ b/spec/fixtures/cassette_library/LinkedIn_Api/Company_API.yml @@ -1,73 +1,81 @@ --- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/companies/id=1586 - body: !!null +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/companies/id=1586 + body: + encoding: US-ASCII + string: '' headers: - x-li-format: + X-Li-Format: - json - user-agent: + User-Agent: - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="consumer_key", - oauth_nonce="nonce", oauth_signature="signature", + Authorization: + - OAuth oauth_consumer_key="consumer_key", oauth_nonce="nonce", oauth_signature="signature", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1319129843", oauth_token="token", oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus + response: + status: code: 200 message: OK headers: - server: + Server: - Apache-Coyote/1.1 - vary: + Vary: - ! '*' - x-li-format: + X-Li-Format: - json - content-type: + Content-Type: - application/json;charset=UTF-8 - transfer-encoding: + Transfer-Encoding: - chunked - date: + Date: - Thu, 20 Oct 2011 16:57:24 GMT - body: ! "{\n \"id\": 1586,\n \"name\": \"Amazon\"\n}" + body: + encoding: UTF-8 + string: ! "{\n \"id\": 1586,\n \"name\": \"Amazon\"\n}" http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/companies/id=1586:(id,name,industry,locations:(address:(city,state,country-code),is-headquarters),employee-count-range) - body: !!null + recorded_at: Wed, 10 Apr 2013 22:06:51 GMT +- request: + method: get + uri: https://api.linkedin.com/v1/companies/id=1586:(id,name,industry,locations:(address:(city,state,country-code),is-headquarters),employee-count-range) + body: + encoding: US-ASCII + string: '' headers: - x-li-format: + X-Li-Format: - json - user-agent: + User-Agent: - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="consumer_key", - oauth_nonce="nonc", oauth_signature="signature", + Authorization: + - OAuth oauth_consumer_key="consumer_key", oauth_nonce="nonc", oauth_signature="signature", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1319129844", oauth_token="token", oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus + response: + status: code: 200 message: OK headers: - server: + Server: - Apache-Coyote/1.1 - vary: + Vary: - ! '*' - x-li-format: + X-Li-Format: - json - content-type: + Content-Type: - application/json;charset=UTF-8 - transfer-encoding: + Transfer-Encoding: - chunked - date: + Date: - Thu, 20 Oct 2011 16:57:24 GMT - body: ! "{\n \"employeeCountRange\": {\n \"code\": \"I\",\n \"name\": \"10001+\"\n - },\n \"id\": 1586,\n \"industry\": \"Internet\",\n \"locations\": {\n \"_total\": - 1,\n \"values\": [{\n \"address\": {\n \"city\": \"Seattle\",\n - \"countryCode\": \"us\",\n \"state\": \"WA\"\n },\n \"isHeadquarters\": - true\n }]\n },\n \"name\": \"Amazon\"\n}" + body: + encoding: UTF-8 + string: ! "{\n \"employeeCountRange\": {\n \"code\": \"I\",\n \"name\": + \"10001+\"\n },\n \"id\": 1586,\n \"industry\": \"Internet\",\n \"locations\":{\n + \"_total\": 1,\n \"values\": [{\n \"address\": {\n \"city\": + \"Seattle\",\n \"countryCode\": \"us\",\n \"state\": \"WA\"\n },\n + \"isHeadquarters\": true\n }]\n },\n \"name\": \"Amazon\"\n}" http_version: '1.1' + recorded_at: Wed, 10 Apr 2013 22:06:51 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Api/Company_API/should_load_correct_company_data.yml b/spec/fixtures/cassette_library/LinkedIn_Api/Company_API/should_load_correct_company_data.yml new file mode 100644 index 00000000..d0b59dce --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Api/Company_API/should_load_correct_company_data.yml @@ -0,0 +1,83 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/companies/1586 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v0.9.0 + X-Li-Format: + - json + Authorization: + - Bearer atoken + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Server: + - Apache-Coyote/1.1 + Vary: + - ! '*' + X-Li-Format: + - json + Content-Type: + - application/json;charset=UTF-8 + Transfer-Encoding: + - chunked + Date: + - Thu, 20 Oct 2011 16:57:24 GMT + body: + encoding: UTF-8 + string: ! "{\n \"id\": 1586,\n \"name\": \"Amazon\"\n}" + http_version: '1.1' + recorded_at: Wed, 10 Apr 2013 22:06:51 GMT +- request: + method: get + uri: https://api.linkedin.com/v1/companies/id=1586:(id,name,industry,locations:(address:(city,state,country-code),is-headquarters),employee-count-range) + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + User-Agent: + - OAuth gem v0.4.5 + Authorization: + - OAuth oauth_consumer_key="consumer_key", oauth_nonce="nonc", oauth_signature="signature", + oauth_signature_method="HMAC-SHA1", oauth_timestamp="1319129844", oauth_token="token", + oauth_version="1.0" + response: + status: + code: 200 + message: OK + headers: + Server: + - Apache-Coyote/1.1 + Vary: + - ! '*' + X-Li-Format: + - json + Content-Type: + - application/json;charset=UTF-8 + Transfer-Encoding: + - chunked + Date: + - Thu, 20 Oct 2011 16:57:24 GMT + body: + encoding: UTF-8 + string: ! "{\n \"employeeCountRange\": {\n \"code\": \"I\",\n \"name\": + \"10001+\"\n },\n \"id\": 1586,\n \"industry\": \"Internet\",\n \"locations\":{\n + \"_total\": 1,\n \"values\": [{\n \"address\": {\n \"city\": + \"Seattle\",\n \"countryCode\": \"us\",\n \"state\": \"WA\"\n },\n + \"isHeadquarters\": true\n }]\n },\n \"name\": \"Amazon\"\n}" + http_version: '1.1' + recorded_at: Wed, 10 Apr 2013 22:06:51 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Client/_authorize_from_request.yml b/spec/fixtures/cassette_library/LinkedIn_Client/_authorize_from_request.yml deleted file mode 100644 index 2e7969fb..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Client/_authorize_from_request.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :post - uri: https://api.linkedin.com:443/uas/oauth/accessToken - body: - headers: - user-agent: - - OAuth gem v0.4.4 - authorization: - - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_consumer_key="eAI15DqRUTTd7OuQJBG3Mo0aw2Ekx5yoLX3x3NaLnbTnZbaU46OEii7uNTKijII4", oauth_nonce="ztYyddIoKJ8flDjBJyveOSqm96CLaEM4QpOC0CSW0E", oauth_signature="NSp3ZDtycelP7wsDM7dsuDTZGys%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1297095033", oauth_token="2f5b42dd-1e0e-4f8f-a03c-1e510bde5935", oauth_verifier="25038", oauth_version="1.0" - content-length: - - "0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - content-type: - - text/plain - server: - - Apache-Coyote/1.1 - date: - - Mon, 07 Feb 2011 16:10:34 GMT - content-length: - - "156" - body: oauth_token=28774cd4-fbe1-4e6e-a05e-1243f6471933&oauth_token_secret=2fafe259-976e-41ad-a6f5-d26bbba42923&oauth_expires_in=0&oauth_authorization_expires_in=0 - http_version: "1.1" diff --git a/spec/fixtures/cassette_library/LinkedIn_Client/_authorize_from_request/should_return_a_valid_access_token.yml b/spec/fixtures/cassette_library/LinkedIn_Client/_authorize_from_request/should_return_a_valid_access_token.yml new file mode 100644 index 00000000..445c69ba --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Client/_authorize_from_request/should_return_a_valid_access_token.yml @@ -0,0 +1,37 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.linkedin.com/uas/oauth/accessToken + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - OAuth gem v0.4.4 + Authorization: + - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_consumer_key="eAI15DqRUTTd7OuQJBG3Mo0aw2Ekx5yoLX3x3NaLnbTnZbaU46OEii7uNTKijII4", + oauth_nonce="ztYyddIoKJ8flDjBJyveOSqm96CLaEM4QpOC0CSW0E", oauth_signature="NSp3ZDtycelP7wsDM7dsuDTZGys%3D", + oauth_signature_method="HMAC-SHA1", oauth_timestamp="1297095033", oauth_token="2f5b42dd-1e0e-4f8f-a03c-1e510bde5935", + oauth_verifier="25038", oauth_version="1.0" + Content-Length: + - '0' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/plain + Server: + - Apache-Coyote/1.1 + Date: + - Mon, 07 Feb 2011 16:10:34 GMT + Content-Length: + - '156' + body: + encoding: UTF-8 + string: oauth_token=28774cd4-fbe1-4e6e-a05e-1243f6471933&oauth_token_secret=2fafe259-976e-41ad-a6f5-d26bbba42923&oauth_expires_in=0&oauth_authorization_expires_in=0 + http_version: '1.1' + recorded_at: Wed, 10 Apr 2013 22:06:51 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Client/_request_token.yml b/spec/fixtures/cassette_library/LinkedIn_Client/_request_token.yml deleted file mode 100644 index de938eb5..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Client/_request_token.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :post - uri: https://api.linkedin.com:443/uas/oauth/requestToken - body: - headers: - user-agent: - - OAuth gem v0.4.4 - authorization: - - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="oob", oauth_consumer_key="eAI15DqRUTTd7OuQJBG3Mo0aw2Ekx5yoLX3x3NaLnbTnZbaU46OEii7uNTKijII4", oauth_nonce="jSQpxoXaoTl2e0dALgc7VKzRJE993wqzRWuXuF0H0", oauth_signature="wn%2Bw0Jvyb9TQ4DC8sq3CxWMDM7Y%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1297093507", oauth_version="1.0" - content-length: - - "0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - content-type: - - text/plain - server: - - Apache-Coyote/1.1 - date: - - Mon, 07 Feb 2011 15:45:08 GMT - content-length: - - "236" - body: oauth_token=95f8619b-7069-433b-ac9e-35dfba02b0f7&oauth_token_secret=dffd7996-6943-48ce-be6b-771e86b10f92&oauth_callback_confirmed=true&xoauth_request_auth_url=https%3A%2F%2Fapi.linkedin.com%2Fuas%2Foauth%2Fauthorize&oauth_expires_in=599 - http_version: "1.1" diff --git a/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_a_callback_url.yml b/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_a_callback_url.yml deleted file mode 100644 index 47234190..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_a_callback_url.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :post - uri: https://api.linkedin.com:443/uas/oauth/requestToken - body: - headers: - user-agent: - - OAuth gem v0.4.4 - authorization: - - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="http%3A%2F%2Fwww.josh.com", oauth_consumer_key="eAI15DqRUTTd7OuQJBG3Mo0aw2Ekx5yoLX3x3NaLnbTnZbaU46OEii7uNTKijII4", oauth_nonce="OYVkd4yi5oe16NGQMbANhBB8cabeynkTX28fOEjG1rs", oauth_signature="%2BwgZ8nb2CM5oWRpJEC5U0554uGk%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1297103790", oauth_version="1.0" - content-length: - - "0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - content-type: - - text/plain - server: - - Apache-Coyote/1.1 - date: - - Mon, 07 Feb 2011 18:36:30 GMT - content-length: - - "236" - body: oauth_token=f8af7ca2-ca1a-48f2-be6a-bd7b721e2868&oauth_token_secret=c5ec7928-7740-4813-a202-2be8800a0b32&oauth_callback_confirmed=true&xoauth_request_auth_url=https%3A%2F%2Fapi.linkedin.com%2Fuas%2Foauth%2Fauthorize&oauth_expires_in=599 - http_version: "1.1" diff --git a/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_a_callback_url/should_return_a_valid_access_token.yml b/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_a_callback_url/should_return_a_valid_access_token.yml new file mode 100644 index 00000000..6734f1af --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_a_callback_url/should_return_a_valid_access_token.yml @@ -0,0 +1,37 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.linkedin.com/uas/oauth/requestToken + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - OAuth gem v0.4.4 + Authorization: + - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="http%3A%2F%2Fwww.josh.com", + oauth_consumer_key="eAI15DqRUTTd7OuQJBG3Mo0aw2Ekx5yoLX3x3NaLnbTnZbaU46OEii7uNTKijII4", + oauth_nonce="OYVkd4yi5oe16NGQMbANhBB8cabeynkTX28fOEjG1rs", oauth_signature="%2BwgZ8nb2CM5oWRpJEC5U0554uGk%3D", + oauth_signature_method="HMAC-SHA1", oauth_timestamp="1297103790", oauth_version="1.0" + Content-Length: + - '0' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/plain + Server: + - Apache-Coyote/1.1 + Date: + - Mon, 07 Feb 2011 18:36:30 GMT + Content-Length: + - '236' + body: + encoding: UTF-8 + string: oauth_token=f8af7ca2-ca1a-48f2-be6a-bd7b721e2868&oauth_token_secret=c5ec7928-7740-4813-a202-2be8800a0b32&oauth_callback_confirmed=true&xoauth_request_auth_url=https%3A%2F%2Fapi.linkedin.com%2Fuas%2Foauth%2Fauthorize&oauth_expires_in=599 + http_version: '1.1' + recorded_at: Wed, 10 Apr 2013 22:06:51 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_default_options.yml b/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_default_options.yml deleted file mode 100644 index 2c814db5..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_default_options.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :post - uri: https://api.linkedin.com:443/uas/oauth/requestToken - body: - headers: - user-agent: - - OAuth gem v0.4.4 - authorization: - - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="oob", oauth_consumer_key="eAI15DqRUTTd7OuQJBG3Mo0aw2Ekx5yoLX3x3NaLnbTnZbaU46OEii7uNTKijII4", oauth_nonce="5INIHjRHjfLCYQX0r7cArMGiUPXoH62wEAgbrh1M", oauth_signature="K1kJU%2FQsuIKj1OUKsaUIcM1xr8Q%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1297103788", oauth_version="1.0" - content-length: - - "0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - content-type: - - text/plain - server: - - Apache-Coyote/1.1 - date: - - Mon, 07 Feb 2011 18:36:29 GMT - content-length: - - "236" - body: oauth_token=fe9d7429-e5cc-47c2-b396-23521d86cf9c&oauth_token_secret=092e7c24-8ad8-4ca9-8f92-8c4f17664bcb&oauth_callback_confirmed=true&xoauth_request_auth_url=https%3A%2F%2Fapi.linkedin.com%2Fuas%2Foauth%2Fauthorize&oauth_expires_in=599 - http_version: "1.1" diff --git a/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_default_options/should_return_a_valid_request_token.yml b/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_default_options/should_return_a_valid_request_token.yml new file mode 100644 index 00000000..58ac8c52 --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Client/_request_token/with_default_options/should_return_a_valid_request_token.yml @@ -0,0 +1,37 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.linkedin.com/uas/oauth/requestToken + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - OAuth gem v0.4.4 + Authorization: + - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="oob", + oauth_consumer_key="eAI15DqRUTTd7OuQJBG3Mo0aw2Ekx5yoLX3x3NaLnbTnZbaU46OEii7uNTKijII4", + oauth_nonce="5INIHjRHjfLCYQX0r7cArMGiUPXoH62wEAgbrh1M", oauth_signature="K1kJU%2FQsuIKj1OUKsaUIcM1xr8Q%3D", + oauth_signature_method="HMAC-SHA1", oauth_timestamp="1297103788", oauth_version="1.0" + Content-Length: + - '0' + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - text/plain + Server: + - Apache-Coyote/1.1 + Date: + - Mon, 07 Feb 2011 18:36:29 GMT + Content-Length: + - '236' + body: + encoding: UTF-8 + string: oauth_token=fe9d7429-e5cc-47c2-b396-23521d86cf9c&oauth_token_secret=092e7c24-8ad8-4ca9-8f92-8c4f17664bcb&oauth_callback_confirmed=true&xoauth_request_auth_url=https%3A%2F%2Fapi.linkedin.com%2Fuas%2Foauth%2Fauthorize&oauth_expires_in=599 + http_version: '1.1' + recorded_at: Wed, 10 Apr 2013 22:06:51 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_company_name_option.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_company_name_option.yml deleted file mode 100644 index 86e69106..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_company_name_option.yml +++ /dev/null @@ -1,135 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/people-search?company-name=linkedin - body: - headers: - user-agent: - - OAuth gem v0.4.4 - authorization: - - OAuth oauth_consumer_key="C2UfeHxZrij1PyppziDLbdUQti6f4TLaL-N0dyiV_us4Pj18_vsHcjKIX0i69fSn", - oauth_nonce="5DbPHhxweU6eNBPoAJqkobtxNsZDDIgtmfF0sx3rmQE", oauth_signature="DkRDger8eQvtJq1i8%2FjHzrNAFis%3D", - oauth_signature_method="HMAC-SHA1", oauth_timestamp="1305061368", oauth_token="afb39322-be32-4b83-83a0-7e35e18d3082", - oauth_version="1.0" - x-li-format: - - json - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - content-type: - - application/json;charset=UTF-8 - server: - - Apache-Coyote/1.1 - date: - - Tue, 10 May 2011 21:02:49 GMT - x-li-format: - - json - vary: - - x-li-format,Accept-Encoding - transfer-encoding: - - chunked - body: ! "{\n \"numResults\": 5228,\n \"people\": {\n \"values\": [\n {\n - \ \"id\": \"VQcsz5Hp_h\",\n \"lastName\": \"Denker\",\n \"firstName\": - \"Donald\"\n },\n {\n \"id\": \"YEDghC612B\",\n \"lastName\": - \"S.\",\n \"firstName\": \"Daniel\"\n },\n {\n \"id\": - \"KMioNXVEg9\",\n \"lastName\": \"H.\",\n \"firstName\": \"Reid\"\n - \ },\n {\n \"id\": \"ILGTOKmto4\",\n \"lastName\": \"Ruff\",\n - \ \"firstName\": \"Lori\"\n },\n {\n \"id\": \"xr5jcMXKPm\",\n - \ \"lastName\": \"C.\",\n \"firstName\": \"Ed\"\n },\n {\n - \ \"id\": \"aeejoSqHsN\",\n \"lastName\": \"T.\",\n \"firstName\": - \"Brian\"\n },\n {\n \"id\": \"VYC0P9hxVN\",\n \"lastName\": - \"Giffen\",\n \"firstName\": \"Sean\"\n },\n {\n \"id\": - \"kWPJPI1lrJ\",\n \"lastName\": \"Seps\",\n \"firstName\": \"Chad\"\n - \ },\n {\n \"id\": \"1PYJr69P5V\",\n \"lastName\": \"Vasconcelos\",\n - \ \"firstName\": \"Cesar\"\n },\n {\n \"id\": \"AU5Dv63Fma\",\n - \ \"lastName\": \"Ling\",\n \"firstName\": \"James\"\n }\n - \ ],\n \"_count\": 10,\n \"_start\": 0,\n \"_total\": 110\n }\n}" - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :post - uri: https://api.linkedin.com:443/uas/oauth/requestToken - body: - headers: - user-agent: - - OAuth gem v0.4.5 - content-length: - - '0' - authorization: - - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="oob", - oauth_consumer_key="a39e395e-bc38-4d5b-ae3b-52f840f821e9", oauth_nonce="jCUtbvZXpwNVfrj2x0XmxFfQD55R4NoJqVnhgjKEno", - oauth_signature="8XiRWCIiDK%2Fwr%2FTLttRDPnsFaiE%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329922227", oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 401 - message: Unauthorized - headers: - server: - - Apache-Coyote/1.1 - www-authenticate: - - OAuth realm="https%3A%2F%2Fapi.linkedin.com", oauth_problem="consumer_key_unknown" - content-type: - - application/x-www-form-urlencoded;charset=UTF-8 - content-length: - - '34' - vary: - - Accept-Encoding - date: - - Wed, 22 Feb 2012 14:50:29 GMT - body: oauth_problem=consumer_key_unknown - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1people-search?company-name=linkedin - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="5oBn6Ns1YZXUeh0oEmAcCjQrXFhf6c652LEGbFbYe4", - oauth_signature="yHtXFEkeWfhnrsEpDaXn2Epv9KY%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329991237", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 404 - message: Not Found - headers: - content-type: - - text/html - content-length: - - '1888' - date: - - Thu, 23 Feb 2012 10:00:38 GMT - server: - - lighttpd - body: ! "\n\n\n - \ 404: Page Not Found\n \n \n\n\n\n\n
\n \"Linkedin\"\n
\n\n
\n

Page Not Found

\n

The page you requested - is no longer available, or cannot be found.

\n

Please - double-check the URL (address) you used, or contact - us if you feel you have reached this page in error.

\n

Click the “Back” button on your browser or go - to the home page.

\n \n
\n \n

Are you looking - for any of these LinkedIn features?

\n \n \n \n\n \n
 
\n
\n\n\n" - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_company_name_option/should_perform_a_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_company_name_option/should_perform_a_search.yml new file mode 100644 index 00000000..2f90f12f --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_company_name_option/should_perform_a_search.yml @@ -0,0 +1,92 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/people-search?company-name=linkedin + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - OAuth gem v0.4.7 + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="TkuTVt34MgzfuheowxiWtlQzdNdJBfGwh8uNqwcDrS4", + oauth_signature="TQsnrPLgwq6hrw4G9VaPwJIKW8o%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631657", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + X-Li-Format: + - json + response: + status: + code: 200 + message: OK + headers: + X-Li-Request-Id: + - 0UF1FY9HHN + Vary: + - ! '*' + Transfer-Encoding: + - chunked + Server: + - Apache-Coyote/1.1 + Content-Type: + - application/json;charset=UTF-8 + Date: + - Wed, 10 Apr 2013 22:07:36 GMT + X-Li-Format: + - json + body: + encoding: UTF-8 + string: ! "{\n \"numResults\": 0,\n \"people\": {\"_total\": 0}\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +- request: + method: get + uri: https://api.linkedin.com/v1/people-search?company-name=IBM + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - OAuth gem v0.4.7 + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="dixy4z5VMylJTypqa3abkuEnVrjFtb5V5hd9DpMKB0", + oauth_signature="OOD9beldHTV5d9a6fVpPUqOB%2BPs%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631799", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + X-Li-Format: + - json + response: + status: + code: 200 + message: OK + headers: + X-Li-Request-Id: + - L00YMW359U + Vary: + - ! '*' + Transfer-Encoding: + - chunked + Server: + - Apache-Coyote/1.1 + Date: + - Wed, 10 Apr 2013 22:09:58 GMT + X-Li-Format: + - json + Content-Type: + - application/json;charset=UTF-8 + body: + encoding: UTF-8 + string: ! "{\n \"numResults\": 6,\n \"people\": {\n \"_total\": 6,\n \"values\": + [\n {\n \"firstName\": \"Ryan\",\n \"id\": \"KHkgwBMaa-\",\n + \"lastName\": \"Sue\"\n },\n {\n \"firstName\": \"Ben\",\n + \"id\": \"lljISRB-WQ\",\n \"lastName\": \"Mejia\"\n },\n{\n + \"firstName\": \"James\",\n \"id\": \"zLwxyfa2cv\",\n + \"lastName\": \"Stevenson\"\n },\n {\n \"firstName\": + \"Charles\",\n \"id\": \"r5Kzi9Um-e\",\n \"lastName\": \"Kafoglis\"\n},\n{\n + \"firstName\": \"Sauraj\",\n \"id\": \"RLJu6NhdI2\",\n + \"lastName\": \"Goswami\"\n },\n {\n \"firstName\": + \"Jonathan\",\n \"id\": \"NgAxaSCyZ3\",\n \"lastName\": \"Hedstrom\"\n }\n ]\n }\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_email_address/should_perform_a_people_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_email_address/should_perform_a_people_search.yml new file mode 100644 index 00000000..50e34793 --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_email_address/should_perform_a_people_search.yml @@ -0,0 +1,57 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/people::(email=yy@zz.com):(id) + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - '*/*' + User-Agent: + - OAuth gem v0.4.7 + Authorization: + - OAuth oauth_consumer_key="key", oauth_nonce="KkLqrO8OnlnRKJFUnwnHvyDpmT5lzyVuPPU38MHKXE", + oauth_signature="kR6yrOhUD3SUay3k2bP2YdxwB6U%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1389649903", oauth_token="key", oauth_version="1.0" + response: + status: + code: 200 + message: ok + headers: + Server: + - Apache-Coyote/1.1 + X-Li-Request-Id: + - 4506AHDFV4 + Date: + - Mon, 13 Jan 2014 21:51:43 GMT + Vary: + - '*' + X-Li-Format: + - json + Content-Type: + - application/json;charset=UTF-8 + X-Li-Fabric: + - PROD-ELA4 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Li-Pop: + - PROD-ELA4 + X-Li-Uuid: + - SCj2pjkHSRPw0yJYdCsAAA== + Set-Cookie: + - lidc="b=LB34:g=45:u=1:i=1389649904:t=1389650504:s=2677822921"; Expires=Mon, + 13 Jan 2014 22:01:44 GMT; domain=.linkedin.com; Path=/ + body: + encoding: UTF-8 + string: ! "{\"_total\": 1,\"values\": [{ + \"_key\": \"email=yy@zz.com\",\"id\": \"96GVfLeWjU\"}]}" + http_version: + recorded_at: Mon, 13 Jan 2014 21:51:44 GMT \ No newline at end of file diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options.yml deleted file mode 100644 index 5cd2fedc..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options.yml +++ /dev/null @@ -1,122 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/people-search?first-name=Giliardi&last-name=Pires - body: - headers: - user-agent: - - OAuth gem v0.4.4 - authorization: - - OAuth oauth_consumer_key="C2UfeHxZrij1PyppziDLbdUQti6f4TLaL-N0dyiV_us4Pj18_vsHcjKIX0i69fSn", - oauth_nonce="IVMcA0gCXgVmgwAn56FRIpQUdQmyFcoP2RRN6ZzPv4", oauth_signature="8aXd44yIB6fsVy%2BYZJNvR01yp2w%3D", - oauth_signature_method="HMAC-SHA1", oauth_timestamp="1305061364", oauth_token="afb39322-be32-4b83-83a0-7e35e18d3082", - oauth_version="1.0" - x-li-format: - - json - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - content-type: - - application/json;charset=UTF-8 - server: - - Apache-Coyote/1.1 - date: - - Tue, 10 May 2011 21:02:45 GMT - x-li-format: - - json - vary: - - x-li-format,Accept-Encoding - transfer-encoding: - - chunked - body: ! "{\n \"numResults\": 1,\n \"people\": {\n \"values\": [{\n \"id\": - \"YkdnFl04s_\",\n \"lastName\": \"Pires\",\n \"firstName\": \"Giliardi\"\n - \ }],\n \"_total\": 1\n }\n}" - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :post - uri: https://api.linkedin.com:443/uas/oauth/requestToken - body: - headers: - user-agent: - - OAuth gem v0.4.5 - content-length: - - '0' - authorization: - - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="oob", - oauth_consumer_key="a39e395e-bc38-4d5b-ae3b-52f840f821e9", oauth_nonce="rXssYvyrlgkdK7ZpsjurbqOPKK3vQ0FUM9pRP37NMc", - oauth_signature="b%2B3nVjLTwMGwAANmULOD8YSdjZU%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329922226", oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 401 - message: Unauthorized - headers: - server: - - Apache-Coyote/1.1 - www-authenticate: - - OAuth realm="https%3A%2F%2Fapi.linkedin.com", oauth_problem="consumer_key_unknown" - content-type: - - application/x-www-form-urlencoded;charset=UTF-8 - content-length: - - '34' - vary: - - Accept-Encoding - date: - - Wed, 22 Feb 2012 14:50:28 GMT - body: oauth_problem=consumer_key_unknown - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1people-search?first-name=Giliardi&last-name=Pires - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="d90SJkw5a0WbvJqggKUYk02aUMkcPjWLBrfT5lU", - oauth_signature="h9ZKohoAEDStOnt2vQQYoEXdIYk%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329991237", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 404 - message: Not Found - headers: - content-type: - - text/html - content-length: - - '1888' - date: - - Thu, 23 Feb 2012 10:00:38 GMT - server: - - lighttpd - body: ! "\n\n\n - \ 404: Page Not Found\n \n \n\n\n\n\n
\n \"Linkedin\"\n
\n\n
\n

Page Not Found

\n

The page you requested - is no longer available, or cannot be found.

\n

Please - double-check the URL (address) you used, or contact - us if you feel you have reached this page in error.

\n

Click the “Back” button on your browser or go - to the home page.

\n \n
\n \n

Are you looking - for any of these LinkedIn features?

\n \n \n \n\n \n
 
\n
\n\n\n" - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options/should_perform_a_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options/should_perform_a_search.yml new file mode 100644 index 00000000..ffa35906 --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options/should_perform_a_search.yml @@ -0,0 +1,100 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/people-search?first-name=Giliardi&last-name=Pires + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + User-Agent: + - OAuth gem v0.4.7 + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="eq8g0jFLe2FsDxO255PW6UqoZ8lwJAqiIJCm3qEKF8", + oauth_signature="D1xMNnx7aOxDotnPt1mtEdbJPlU%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631656", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + response: + status: + code: 200 + message: OK + headers: + Vary: + - ! '*' + Transfer-Encoding: + - chunked + Server: + - Apache-Coyote/1.1 + X-Li-Format: + - json + X-Li-Request-Id: + - CH30LTU9DW + Date: + - Wed, 10 Apr 2013 22:07:36 GMT + Content-Type: + - application/json;charset=UTF-8 + body: + encoding: UTF-8 + string: ! "{\n \"numResults\": 0,\n \"people\": {\"_total\": 0}\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +- request: + method: get + uri: https://api.linkedin.com/v1/people-search?first-name=Charles&last-name=Garcia + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + User-Agent: + - OAuth gem v0.4.7 + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="lTIll68hM4A1tc0I56h92w5znsrjFfJ4nDvKpSqDfg", + oauth_signature="AhGLaPTVAJvv8pncUjz2j8C6%2B%2FA%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365632102", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + response: + status: + code: 200 + message: OK + headers: + Vary: + - ! '*' + Transfer-Encoding: + - chunked + Server: + - Apache-Coyote/1.1 + X-Li-Request-Id: + - 6AXWFPE8I6 + X-Li-Format: + - json + Date: + - Wed, 10 Apr 2013 22:15:03 GMT + Content-Type: + - application/json;charset=UTF-8 + body: + encoding: UTF-8 + string: ! "{\n \"numResults\": 308,\n \"people\": {\n \"_count\": 10,\n + \"_start\": 0,\n \"_total\": 110,\n \"values\": [\n {\n \"firstName\": + \"Charles\",\n \"id\": \"2zk34r8TvA\",\n \"lastName\": \"Garcia, CFA\"\n},\n{\n + \"firstName\": \"Charles R.\",\n \"id\": + \"NjwO1vU6P6\",\n \"lastName\": \"Garcia Jr.\"\n },\n {\n + \"firstName\": \"Charles\",\n \"id\": \"j8ZczJo44W\",\n \"lastName\": + \"Garcia-Tobin\"\n },\n {\n \"firstName\": \"Charles\",\n + \"id\": \"jYfrk5GM29\",\n \"lastName\": \"Garcia\"\n },\n{\n + \"firstName\": \"Charles\",\n \"id\": \"C-2ASm3SQ1\",\n + \"lastName\": \"Garcia\"\n },\n {\n \"firstName\": + \"Charles\",\n \"id\": \"LG__MFCUTJ\",\n \"lastName\": \"Garcia\"\n},\n {\n + \"firstName\": \"Charles\",\n \"id\": \"wjopxKqYYM\",\n + \"lastName\": \"Garcia\"\n },\n {\n \"firstName\": + \"Charles\",\n \"id\": \"AtFQt5Lf1V\",\n \"lastName\": \"Garcia\"\n},\n {\n + \"firstName\": \"Charles\",\n \"id\": \"MUXIZwfehE\",\n + \"lastName\": \"Garcia\"\n },\n {\n \"firstName\": + \"Charles\",\n \"id\": \"koTmAyWE8J\",\n \"lastName\": + \"Schwalbe Garcia-Lago\"\n }\n ]\n }\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options_with_fields.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options_with_fields.yml deleted file mode 100644 index bbd49351..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options_with_fields.yml +++ /dev/null @@ -1,72 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/people-search:(people:(id,first-name,last-name,public-profile-url,picture-url),num-results)?first-name=Giliardi&last-name=Pires - body: - headers: - user-agent: - - OAuth gem v0.4.4 - authorization: - - OAuth oauth_consumer_key="C2UfeHxZrij1PyppziDLbdUQti6f4TLaL-N0dyiV_us4Pj18_vsHcjKIX0i69fSn", - oauth_nonce="p445iIZd1oQn2e1JL6M2ZbGEUi2nTMqacOQ4S1xeDY", oauth_signature="639UhE9asgiYLgUzBYUFrdIF%2BS8%3D", - oauth_signature_method="HMAC-SHA1", oauth_timestamp="1305061366", oauth_token="afb39322-be32-4b83-83a0-7e35e18d3082", - oauth_version="1.0" - x-li-format: - - json - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - content-type: - - application/json;charset=UTF-8 - server: - - Apache-Coyote/1.1 - date: - - Tue, 10 May 2011 21:02:47 GMT - x-li-format: - - json - vary: - - x-li-format,Accept-Encoding - transfer-encoding: - - chunked - body: ! "{\n \"numResults\": 1,\n \"people\": {\n \"values\": [{\n \"id\": - \"YkdnFl04s_\",\n \"publicProfileUrl\": \"http://www.linkedin.com/in/gibanet\",\n - \ \"lastName\": \"Pires\",\n \"pictureUrl\": \"http://media.linkedin.com/mpr/mprx/0_Oz05kn9xkWziAEOUKtOVkqzjXd8Clf7UyqIVkqchR2NtmwZRt1fWoN_aobhg-HmB09jUwPLKrAhU\",\n - \ \"firstName\": \"Giliardi\"\n }],\n \"_total\": 1\n }\n}" - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :post - uri: https://api.linkedin.com:443/uas/oauth/requestToken - body: - headers: - user-agent: - - OAuth gem v0.4.5 - content-length: - - '0' - authorization: - - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="oob", - oauth_consumer_key="a39e395e-bc38-4d5b-ae3b-52f840f821e9", oauth_nonce="bcBcCa4GrHRyxuMfyrnwxQahY2zkrQVUhRhpQDhfA", - oauth_signature="3d%2FocgY%2FpjVNVXL2Ud9aIAWyBCQ%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329922227", oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 401 - message: Unauthorized - headers: - server: - - Apache-Coyote/1.1 - www-authenticate: - - OAuth realm="https%3A%2F%2Fapi.linkedin.com", oauth_problem="consumer_key_unknown" - content-type: - - application/x-www-form-urlencoded;charset=UTF-8 - content-length: - - '34' - vary: - - Accept-Encoding - date: - - Wed, 22 Feb 2012 14:50:29 GMT - body: oauth_problem=consumer_key_unknown - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options_with_fields/should_perform_a_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options_with_fields/should_perform_a_search.yml new file mode 100644 index 00000000..9fce73ec --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_first_name_and_last_name_options_with_fields/should_perform_a_search.yml @@ -0,0 +1,114 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/people-search:(people:(id,first-name,last-name,public-profile-url,picture-url),num-results)?first-name=Giliardi&last-name=Pires + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - OAuth gem v0.4.7 + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="XxYZ3yqoTFr792YTu6TmJPFCrrkZejwXkORldtyZGI", + oauth_signature="cBkWRwhVxBDozgn5sCXBwGIoer4%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631657", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + X-Li-Format: + - json + response: + status: + code: 200 + message: OK + headers: + Server: + - Apache-Coyote/1.1 + Transfer-Encoding: + - chunked + Vary: + - ! '*' + Content-Type: + - application/json;charset=UTF-8 + X-Li-Request-Id: + - G0J3Z1XF1E + Date: + - Wed, 10 Apr 2013 22:07:36 GMT + X-Li-Format: + - json + body: + encoding: UTF-8 + string: ! "{\n \"numResults\": 0,\n \"people\": {\"_total\": 0}\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +- request: + method: get + uri: https://api.linkedin.com/v1/people-search:(people:(id,first-name,last-name,public-profile-url,picture-url),num-results)?first-name=Charles&last-name=Garcia + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - OAuth gem v0.4.7 + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="apcqck1ATxZYGou1ynnfBm6OgZFBz4TXKeuPo160NU", + oauth_signature="zB0MtadBiOOL2rAX%2FdHn71fZyOA%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631934", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + X-Li-Format: + - json + response: + status: + code: 200 + message: OK + headers: + Server: + - Apache-Coyote/1.1 + Transfer-Encoding: + - chunked + Vary: + - ! '*' + Content-Type: + - application/json;charset=UTF-8 + X-Li-Request-Id: + - 7A7TZHN5V9 + Date: + - Wed, 10 Apr 2013 22:12:14 GMT + X-Li-Format: + - json + body: + encoding: UTF-8 + string: ! "{\n \"numResults\": 308,\n \"people\": {\n \"_count\": 10,\n + \"_start\": 0,\n \"_total\": 110,\n \"values\": [\n {\n \"firstName\": + \"Charles\",\n \"id\": \"2zk34r8TvA\",\n \"lastName\": \"Garcia, CFA\",\n + \"publicProfileUrl\": \"http://www.linkedin.com/in/charlesgarcia\"\n},\n {\n + \"firstName\": \"Charles R.\",\n \"id\": + \"NjwO1vU6P6\",\n \"lastName\": \"Garcia Jr.\",\n \"pictureUrl\": + \"http://m3.licdn.com/mpr/mprx/0_eyd5KukV6r4QDft-oYwsKfzsXqyWSdi-oUjVKaLVRAeMtSqtXsJWOmlqospnaaGOWxIUxWUUfdKb\",\n + \"publicProfileUrl\": \"http://www.linkedin.com/in/knightwealthmanagement\"\n},\n {\n + \"firstName\": \"Charles\",\n \"id\": \"j8ZczJo44W\",\n + \"lastName\": \"Garcia-Tobin\",\n \"publicProfileUrl\": + \"http://www.linkedin.com/pub/charles-garcia-tobin/1/407/37\"\n },\n {\n + \"firstName\": \"Charles\",\n \"id\": \"jYfrk5GM29\",\n + \"lastName\": \"Garcia\",\n \"pictureUrl\": \"http://m3.licdn.com/mpr/mprx/0_oCf8Sdu0zOpQN_tEeLaPSwVjvZHIq5CEH6R0SEw2EOpRI3voQk0uio0GUveqBC_QITDYCDz2KP6m\",\n + \"publicProfileUrl\": \"http://www.linkedin.com/in/charleshgarcia\"\n },\n {\n + \"firstName\": \"Charles\",\n \"id\": \"C-2ASm3SQ1\",\n + \"lastName\": \"Garcia\",\n \"pictureUrl\": \"http://m3.licdn.com/mpr/mprx/0_eyd5KuNsktdHTE1-6RasKacFXqyWSdi-oUjVKaLVRAeMtSqtXsJWOmlqospnaaGOWxIUxWRzo_ib\",\n + \"publicProfileUrl\": \"http://www.linkedin.com/pub/charles-garcia/26/1b2/b28\"\n},\n {\n + \"firstName\": \"Charles\",\n \"id\": \"LG__MFCUTJ\",\n + \"lastName\": \"Garcia\",\n \"publicProfileUrl\": + \"http://www.linkedin.com/pub/charles-garcia/5/465/b00\"\n},\n {\n + \"firstName\": \"Charles\",\n \"id\": \"wjopxKqYYM\",\n + \"lastName\": \"Garcia\",\n \"pictureUrl\": \"http://m3.licdn.com/mpr/mprx/0_ePvupanfrtgopBCiEBzPpuFir-Zdp-tioNT1pSkPfNuJin5_Xv58tDrgO049xzPfWKBt1o9wYUsb\",\n + \"publicProfileUrl\": \"http://www.linkedin.com/pub/charles-garcia/8/152/3ab\"\n},\n {\n + \"firstName\": \"Charles\",\n \"id\": \"AtFQt5Lf1V\",\n + \"lastName\": \"Garcia\",\n \"pictureUrl\": \"http://m3.licdn.com/mpr/mprx/0_uuv-7sRI0s_EdtBWuecS7Jf9jM5owt6WaSTS7Jd9GylVN9AdhE5O3Mg41cLzHvF5S7B28YBarPYq\",\n + \"publicProfileUrl\": \"http://www.linkedin.com/in/chasgarcia\"\n},\n {\n + \"firstName\": \"Charles\",\n \"id\": \"MUXIZwfehE\",\n + \"lastName\": \"Garcia\",\n \"publicProfileUrl\": + \"http://www.linkedin.com/pub/charles-garcia/14/6a7/81\"\n},\n {\n + \"firstName\": \"Charles\",\n \"id\": \"koTmAyWE8J\",\n + \"lastName\": \"Schwalbe Garcia-Lago\",\n \"pictureUrl\": \"http://m3.licdn.com/mpr/mprx/0_q6hJ9GyYDCe0NRJ1sGCQ9TSySTY-nZZ1nFqQ9TyatkEGWp7PZhrzZ3Hh_fODzxM0zLGFJ6CC9gBb\",\n + \"publicProfileUrl\": \"http://www.linkedin.com/in/charlesschwalbe\"\n }\n ]\n }\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_keywords_string_parameter.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_keywords_string_parameter.yml deleted file mode 100644 index e2fb79c9..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_keywords_string_parameter.yml +++ /dev/null @@ -1,136 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/people-search?keywords=github - body: - headers: - user-agent: - - OAuth gem v0.4.4 - authorization: - - OAuth oauth_consumer_key="C2UfeHxZrij1PyppziDLbdUQti6f4TLaL-N0dyiV_us4Pj18_vsHcjKIX0i69fSn", - oauth_nonce="KenR6ArkWDl5wqulIJZyecJGRWPE7CEDy9COzkWQXR8", oauth_signature="aPgVcIv2aiTr74Wh3sujsTBD4%2B8%3D", - oauth_signature_method="HMAC-SHA1", oauth_timestamp="1305061358", oauth_token="afb39322-be32-4b83-83a0-7e35e18d3082", - oauth_version="1.0" - x-li-format: - - json - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - content-type: - - application/json;charset=UTF-8 - server: - - Apache-Coyote/1.1 - date: - - Tue, 10 May 2011 21:02:40 GMT - x-li-format: - - json - vary: - - x-li-format,Accept-Encoding - transfer-encoding: - - chunked - body: ! "{\n \"numResults\": 905,\n \"people\": {\n \"values\": [\n {\n - \ \"id\": \"YkdnFl04s_\",\n \"lastName\": \"Pires\",\n \"firstName\": - \"Giliardi\"\n },\n {\n \"id\": \"5oELVyNfN3\",\n \"lastName\": - \"Alencar\",\n \"firstName\": \"Ivan\"\n },\n {\n \"id\": - \"k-wxkgFDYL\",\n \"lastName\": \"Private\",\n \"firstName\": - \"\"\n },\n {\n \"id\": \"xT-OdnpncE\",\n \"lastName\": - \"Private\",\n \"firstName\": \"\"\n },\n {\n \"id\": - \"GAG-lE3XVw\",\n \"lastName\": \"Private\",\n \"firstName\": - \"\"\n },\n {\n \"id\": \"z2XMcxa_dR\",\n \"lastName\": - \"M.\",\n \"firstName\": \"Stephen\"\n },\n {\n \"id\": - \"cPANxsayPK\",\n \"lastName\": \"Private\",\n \"firstName\": - \"\"\n },\n {\n \"id\": \"SbMT09zllx\",\n \"lastName\": - \"L.\",\n \"firstName\": \"Rodolfo\"\n },\n {\n \"id\": - \"GrH-5d4mH1\",\n \"lastName\": \"Barnaba\",\n \"firstName\": - \"Marcello\"\n },\n {\n \"id\": \"pdzrGpyP0h\",\n \"lastName\": - \"C.\",\n \"firstName\": \"Pablo\"\n }\n ],\n \"_count\": - 10,\n \"_start\": 0,\n \"_total\": 110\n }\n}" - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :post - uri: https://api.linkedin.com:443/uas/oauth/requestToken - body: - headers: - user-agent: - - OAuth gem v0.4.5 - content-length: - - '0' - authorization: - - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="oob", - oauth_consumer_key="a39e395e-bc38-4d5b-ae3b-52f840f821e9", oauth_nonce="PP414dguMZJe10RlUgLPWaLFhdu8pJ14NoYSKQ36mg", - oauth_signature="utkviYJALT93h%2BJ738IdgmWYQMg%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329922222", oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 401 - message: Unauthorized - headers: - server: - - Apache-Coyote/1.1 - www-authenticate: - - OAuth realm="https%3A%2F%2Fapi.linkedin.com", oauth_problem="consumer_key_unknown" - content-type: - - application/x-www-form-urlencoded;charset=UTF-8 - content-length: - - '34' - vary: - - Accept-Encoding - date: - - Wed, 22 Feb 2012 14:50:24 GMT - body: oauth_problem=consumer_key_unknown - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1people-search?keywords=github - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="QLUmDted5J4dGxWyz5TxD2aLeQTSdUYgVF5LqzcaI", - oauth_signature="FQWcB4ad5NTQHoa%2FGiCHrYOnD2M%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329991235", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 404 - message: Not Found - headers: - content-type: - - text/html - content-length: - - '1888' - date: - - Thu, 23 Feb 2012 10:00:36 GMT - server: - - lighttpd - body: ! "\n\n\n - \ 404: Page Not Found\n \n \n\n\n\n\n
\n \"Linkedin\"\n
\n\n
\n

Page Not Found

\n

The page you requested - is no longer available, or cannot be found.

\n

Please - double-check the URL (address) you used, or contact - us if you feel you have reached this page in error.

\n

Click the “Back” button on your browser or go - to the home page.

\n \n
\n \n

Are you looking - for any of these LinkedIn features?

\n \n \n \n\n \n
 
\n
\n\n\n" - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_keywords_string_parameter/should_perform_a_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_keywords_string_parameter/should_perform_a_search.yml new file mode 100644 index 00000000..ef3f4aca --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_keywords_string_parameter/should_perform_a_search.yml @@ -0,0 +1,52 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/people-search?keywords=github + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="KJPWM7qluIAetEW5kk8NSQuB3ssr1S2v6HBpofhFY", + oauth_signature="LEh2O3mlLU6GqhsuU4admW%2B1hDw%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631655", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + User-Agent: + - OAuth gem v0.4.7 + response: + status: + code: 200 + message: OK + headers: + X-Li-Request-Id: + - L4BQ08FWG8 + X-Li-Format: + - json + Date: + - Wed, 10 Apr 2013 22:07:35 GMT + Vary: + - ! '*' + Server: + - Apache-Coyote/1.1 + Content-Type: + - application/json;charset=UTF-8 + Transfer-Encoding: + - chunked + body: + encoding: UTF-8 + string: ! "{\n \"numResults\": 6,\n \"people\": {\n \"_total\": 6,\n \"values\": + [\n {\n \"firstName\": \"Shay\",\n \"id\": \"ucXjUw4M9J\",\n + \"lastName\": \"Frendt\"\n },\n {\n \"firstName\": + \"Scott\",\n \"id\": \"t6mvVsY3df\",\n \"lastName\": \"Smith\"\n},\n {\n + \"firstName\": \"Philip\",\n \"id\": \"ZeSnXwtz6Y\",\n + \"lastName\": \"Corliss\"\n },\n {\n \"firstName\": + \"Jay\",\n \"id\": \"i24wDA2GrH\",\n \"lastName\": \"Beavers\"\n},\n {\n + \"firstName\": \"Chris\",\n \"id\": \"SJBelisgHh\",\n + \"lastName\": \"Wiswell\"\n },\n {\n \"firstName\": + \"Satish\",\n \"id\": \"V1FPuGot-I\",\n \"lastName\": \"Talim\"\n}\n ]\n }\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_multiple_email_address/should_perform_a_multi-email_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_multiple_email_address/should_perform_a_multi-email_search.yml new file mode 100644 index 00000000..5d39d569 --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_multiple_email_address/should_perform_a_multi-email_search.yml @@ -0,0 +1,59 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/people::(email=yy@zz.com,email=xx@yy.com):(id) + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - '*/*' + User-Agent: + - OAuth gem v0.4.7 + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="eq8g0jFLe2FsDxO255PW6UqoZ8lwJAqiIJCm3qEKF8", + oauth_signature="D1xMNnx7aOxDotnPt1mtEdbJPlU%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631656", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + response: + status: + code: 200 + message: ok + headers: + Server: + - Apache-Coyote/1.1 + X-Li-Request-Id: + - QG386P3UQ9 + Date: + - Mon, 13 Jan 2014 21:33:51 GMT + Vary: + - '*' + X-Li-Format: + - json + Content-Type: + - application/json;charset=UTF-8 + X-Li-Fabric: + - PROD-ELA4 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Li-Pop: + - PROD-ELA4 + X-Li-Uuid: + - gNIS8z8GSRNwtDkbISsAAA== + Set-Cookie: + - lidc="b=LB33:g=40:u=1:i=1389648831:t=1389649431:s=2943015068"; Expires=Mon, + 13 Jan 2014 21:43:51 GMT; domain=.linkedin.com; Path=/ + body: + encoding: UTF-8 + string: ! "{\"_total\": 2,\"values\": [{ + \"_key\": \"email=yy@zz.com\",\"id\": \"96GVfLeWjU\"},{ + \"_key\": \"email=xx@yy.com\",\"id\": \"10CGfLfLhI\"}]}" + http_version: + recorded_at: Mon, 13 Jan 2014 21:33:51 GMT \ No newline at end of file diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option.yml deleted file mode 100644 index b5073847..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option.yml +++ /dev/null @@ -1,136 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/people-search?keywords=github - body: - headers: - user-agent: - - OAuth gem v0.4.4 - authorization: - - OAuth oauth_consumer_key="C2UfeHxZrij1PyppziDLbdUQti6f4TLaL-N0dyiV_us4Pj18_vsHcjKIX0i69fSn", - oauth_nonce="neCS0f9bL8RywiUOvLLDBfAwnc3wmlyFH3N2k4v2PmU", oauth_signature="0EgRN6GvhW3WdWMS8g0gdbOp9Do%3D", - oauth_signature_method="HMAC-SHA1", oauth_timestamp="1305061361", oauth_token="afb39322-be32-4b83-83a0-7e35e18d3082", - oauth_version="1.0" - x-li-format: - - json - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - content-type: - - application/json;charset=UTF-8 - server: - - Apache-Coyote/1.1 - date: - - Tue, 10 May 2011 21:02:41 GMT - x-li-format: - - json - vary: - - x-li-format,Accept-Encoding - transfer-encoding: - - chunked - body: ! "{\n \"numResults\": 905,\n \"people\": {\n \"values\": [\n {\n - \ \"id\": \"YkdnFl04s_\",\n \"lastName\": \"Pires\",\n \"firstName\": - \"Giliardi\"\n },\n {\n \"id\": \"5oELVyNfN3\",\n \"lastName\": - \"Alencar\",\n \"firstName\": \"Ivan\"\n },\n {\n \"id\": - \"k-wxkgFDYL\",\n \"lastName\": \"Private\",\n \"firstName\": - \"\"\n },\n {\n \"id\": \"xT-OdnpncE\",\n \"lastName\": - \"Private\",\n \"firstName\": \"\"\n },\n {\n \"id\": - \"GAG-lE3XVw\",\n \"lastName\": \"Private\",\n \"firstName\": - \"\"\n },\n {\n \"id\": \"z2XMcxa_dR\",\n \"lastName\": - \"M.\",\n \"firstName\": \"Stephen\"\n },\n {\n \"id\": - \"cPANxsayPK\",\n \"lastName\": \"Private\",\n \"firstName\": - \"\"\n },\n {\n \"id\": \"SbMT09zllx\",\n \"lastName\": - \"L.\",\n \"firstName\": \"Rodolfo\"\n },\n {\n \"id\": - \"GrH-5d4mH1\",\n \"lastName\": \"Barnaba\",\n \"firstName\": - \"Marcello\"\n },\n {\n \"id\": \"pdzrGpyP0h\",\n \"lastName\": - \"C.\",\n \"firstName\": \"Pablo\"\n }\n ],\n \"_count\": - 10,\n \"_start\": 0,\n \"_total\": 110\n }\n}" - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :post - uri: https://api.linkedin.com:443/uas/oauth/requestToken - body: - headers: - user-agent: - - OAuth gem v0.4.5 - content-length: - - '0' - authorization: - - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="oob", - oauth_consumer_key="a39e395e-bc38-4d5b-ae3b-52f840f821e9", oauth_nonce="UuoHVjUP4dd5Soqo0WrqODrxeWduE0D7hTTfgqeEgc", - oauth_signature="FLU2BhoUM1I1AwQ5Nv8EtL2O6B8%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329922223", oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 401 - message: Unauthorized - headers: - server: - - Apache-Coyote/1.1 - www-authenticate: - - OAuth realm="https%3A%2F%2Fapi.linkedin.com", oauth_problem="consumer_key_unknown" - content-type: - - application/x-www-form-urlencoded;charset=UTF-8 - content-length: - - '34' - vary: - - Accept-Encoding - date: - - Wed, 22 Feb 2012 14:50:25 GMT - body: oauth_problem=consumer_key_unknown - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1people-search?keywords=github - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="Y9Z6mPtiiliebyfkJ6HjTJdPzl1wwoKRDv0eU1Qe6vQ", - oauth_signature="RYpx4iML26Tq5I%2FK14ocPB%2FzOBw%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329991236", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 404 - message: Not Found - headers: - content-type: - - text/html - content-length: - - '1888' - date: - - Thu, 23 Feb 2012 10:00:37 GMT - server: - - lighttpd - body: ! "\n\n\n - \ 404: Page Not Found\n \n \n\n\n\n\n
\n \"Linkedin\"\n
\n\n
\n

Page Not Found

\n

The page you requested - is no longer available, or cannot be found.

\n

Please - double-check the URL (address) you used, or contact - us if you feel you have reached this page in error.

\n

Click the “Back” button on your browser or go - to the home page.

\n \n
\n \n

Are you looking - for any of these LinkedIn features?

\n \n \n \n\n \n
 
\n
\n\n\n" - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option/should_perform_a_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option/should_perform_a_search.yml new file mode 100644 index 00000000..91ce91d3 --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option/should_perform_a_search.yml @@ -0,0 +1,52 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/people-search?keywords=github + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="DlBgAEJHkDYAnMMZwzFObsUNcCmRbzFldB4dV1yeE", + oauth_signature="RLiPr%2FC1bq9Dv29W3mjezy1of54%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631655", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + User-Agent: + - OAuth gem v0.4.7 + response: + status: + code: 200 + message: OK + headers: + X-Li-Request-Id: + - 5BE8O0G2CK + X-Li-Format: + - json + Date: + - Wed, 10 Apr 2013 22:07:35 GMT + Vary: + - ! '*' + Server: + - Apache-Coyote/1.1 + Content-Type: + - application/json;charset=UTF-8 + Transfer-Encoding: + - chunked + body: + encoding: UTF-8 + string: ! "{\n \"numResults\": 6,\n \"people\": {\n \"_total\": 6,\n \"values\": + [\n {\n \"firstName\": \"Shay\",\n \"id\": \"ucXjUw4M9J\",\n + \"lastName\": \"Frendt\"\n },\n {\n \"firstName\": + \"Scott\",\n \"id\": \"t6mvVsY3df\",\n \"lastName\": \"Smith\"\n },\n {\n + \"firstName\": \"Philip\",\n \"id\": \"ZeSnXwtz6Y\",\n + \"lastName\": \"Corliss\"\n },\n {\n \"firstName\": + \"Jay\",\n \"id\": \"i24wDA2GrH\",\n \"lastName\": \"Beavers\"\n},\n {\n + \"firstName\": \"Chris\",\n \"id\": \"SJBelisgHh\",\n + \"lastName\": \"Wiswell\"\n },\n {\n \"firstName\": + \"Satish\",\n \"id\": \"V1FPuGot-I\",\n \"lastName\": \"Talim\"\n}\n ]\n }\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option_with_pagination.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option_with_pagination.yml deleted file mode 100644 index df0996b6..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option_with_pagination.yml +++ /dev/null @@ -1,128 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/people-search?count=5&keywords=github&start=5 - body: - headers: - user-agent: - - OAuth gem v0.4.4 - authorization: - - OAuth oauth_consumer_key="C2UfeHxZrij1PyppziDLbdUQti6f4TLaL-N0dyiV_us4Pj18_vsHcjKIX0i69fSn", - oauth_nonce="efW9d0TjHFPkszKWMt55AyyIhu0lf0fqcX5562fL30", oauth_signature="NLhujA9Isu2Y%2FwFRXCpW9oFGip0%3D", - oauth_signature_method="HMAC-SHA1", oauth_timestamp="1305061362", oauth_token="afb39322-be32-4b83-83a0-7e35e18d3082", - oauth_version="1.0" - x-li-format: - - json - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - content-type: - - application/json;charset=UTF-8 - server: - - Apache-Coyote/1.1 - date: - - Tue, 10 May 2011 21:02:44 GMT - x-li-format: - - json - vary: - - x-li-format,Accept-Encoding - transfer-encoding: - - chunked - body: ! "{\n \"numResults\": 905,\n \"people\": {\n \"values\": [\n {\n - \ \"id\": \"z2XMcxa_dR\",\n \"lastName\": \"M.\",\n \"firstName\": - \"Stephen\"\n },\n {\n \"id\": \"cPANxsayPK\",\n \"lastName\": - \"Private\",\n \"firstName\": \"\"\n },\n {\n \"id\": - \"SbMT09zllx\",\n \"lastName\": \"L.\",\n \"firstName\": \"Rodolfo\"\n - \ },\n {\n \"id\": \"GrH-5d4mH1\",\n \"lastName\": \"Barnaba\",\n - \ \"firstName\": \"Marcello\"\n },\n {\n \"id\": \"pdzrGpyP0h\",\n - \ \"lastName\": \"C.\",\n \"firstName\": \"Pablo\"\n }\n ],\n - \ \"_count\": 5,\n \"_start\": 5,\n \"_total\": 110\n }\n}" - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :post - uri: https://api.linkedin.com:443/uas/oauth/requestToken - body: - headers: - user-agent: - - OAuth gem v0.4.5 - content-length: - - '0' - authorization: - - OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="oob", - oauth_consumer_key="a39e395e-bc38-4d5b-ae3b-52f840f821e9", oauth_nonce="qNNn2PVI87k4RFxKbSolSwOWOlmcxO8bcWrofwTwTqU", - oauth_signature="MhkIBljWjbXfRQ8r4be9jbdDoeo%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329922224", oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 401 - message: Unauthorized - headers: - server: - - Apache-Coyote/1.1 - www-authenticate: - - OAuth realm="https%3A%2F%2Fapi.linkedin.com", oauth_problem="consumer_key_unknown" - content-type: - - application/x-www-form-urlencoded;charset=UTF-8 - content-length: - - '34' - vary: - - Accept-Encoding - date: - - Wed, 22 Feb 2012 14:50:28 GMT - body: oauth_problem=consumer_key_unknown - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1people-search?count=5&keywords=github&start=5 - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="T6HlbQmLOSYpKReW5f62ynJ0v5bahq7DPXXtVt8", - oauth_signature="KAO8bptvgvyGmrzuXIcD3oT%2BOPw%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329991236", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 404 - message: Not Found - headers: - content-type: - - text/html - content-length: - - '1888' - date: - - Thu, 23 Feb 2012 10:00:37 GMT - server: - - lighttpd - body: ! "\n\n\n - \ 404: Page Not Found\n \n \n\n\n\n\n
\n \"Linkedin\"\n
\n\n
\n

Page Not Found

\n

The page you requested - is no longer available, or cannot be found.

\n

Please - double-check the URL (address) you used, or contact - us if you feel you have reached this page in error.

\n

Click the “Back” button on your browser or go - to the home page.

\n \n
\n \n

Are you looking - for any of these LinkedIn features?

\n \n \n \n\n \n
 
\n
\n\n\n" - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option_with_pagination/should_perform_a_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option_with_pagination/should_perform_a_search.yml new file mode 100644 index 00000000..88203d42 --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search/by_single_keywords_option_with_pagination/should_perform_a_search.yml @@ -0,0 +1,43 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/people-search?count=5&keywords=github&start=5 + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="PfrLyLbcfxXAJshwSsQ4YDPBk1OncuNV0RjgB4fbVEs", + oauth_signature="16fUd%2BHUkWJULyxMCEbISV0Ltks%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631656", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + User-Agent: + - OAuth gem v0.4.7 + response: + status: + code: 200 + message: OK + headers: + X-Li-Request-Id: + - JI3L4KN8K1 + X-Li-Format: + - json + Date: + - Wed, 10 Apr 2013 22:07:36 GMT + Vary: + - ! '*' + Server: + - Apache-Coyote/1.1 + Content-Type: + - application/json;charset=UTF-8 + Transfer-Encoding: + - chunked + body: + encoding: UTF-8 + string: ! "{\n \"numResults\": 6,\n \"people\": {\n \"_count\": 1,\n \"_start\":5,\n \"_total\": 6,\n \"values\": [{\n \"firstName\": \"Satish\",\n\"id\": \"V1FPuGot-I\",\n \"lastName\": \"Talim\"\n }]\n }\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search/email_search_returns_unauthorized/should_raise_an_unauthorized_error.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search/email_search_returns_unauthorized/should_raise_an_unauthorized_error.yml new file mode 100644 index 00000000..2c250b4b --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search/email_search_returns_unauthorized/should_raise_an_unauthorized_error.yml @@ -0,0 +1,59 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/people::(email=aa@bb.com):(id) + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - '*/*' + User-Agent: + - OAuth gem v0.4.7 + Authorization: + - OAuth oauth_consumer_key="key", oauth_nonce="Ny9c0n0y0Eg7cnVjVbUlDPeQap8qjzhdPNY3sAi5K8", + oauth_signature="vd%2Fd5TC906HXqp50%2BRUT3ZeHC2E%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1389716461", oauth_token="key", oauth_version="1.0" + response: + status: + code: 401 + message: Unauthorized + headers: + Server: + - Apache-Coyote/1.1 + X-Li-Request-Id: + - X1OTF3POH3 + Date: + - Tue, 14 Jan 2014 16:20:58 GMT + Vary: + - '*' + X-Li-Format: + - json + Content-Type: + - application/json;charset=UTF-8 + X-Li-Fabric: + - PROD-ELA4 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + X-Li-Pop: + - PROD-ELA4 + X-Li-Uuid: + - iD/VocFDSROQ7fHxASsAAA== + Set-Cookie: + - lidc="b=LB37:g=42:u=1:i=1389716458:t=1389717058:s=1572779068"; Expires=Tue, + 14 Jan 2014 16:30:58 GMT; domain=.linkedin.com; Path=/ + body: + encoding: UTF-8 + string: ! "{\"errorCode\": 0,\"message\": \"Access to member by email address denied\", + \"requestId\": \"BRSUSQTPPW\", + \"status\": 403, + \"timestamp\": 1389727130475}" + http_version: + recorded_at: Tue, 14 Jan 2014 16:21:01 GMT \ No newline at end of file diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_options_with_fields.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_options_with_fields.yml deleted file mode 100644 index 5b6c6f6c..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_options_with_fields.yml +++ /dev/null @@ -1,252 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/company-search:(companies:(id,name,industries,description,specialties),num-results)?keywords=apple - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="q7OIazxfRqNeuKtIn86PThFXYXwe16NtNQgFe6mETo", - oauth_signature="tBpOJdPV3CvjKM%2Fu3IQ2oS%2BfKvI%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329994002", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - server: - - Apache-Coyote/1.1 - x-li-request-id: - - HHH4PB27GU - vary: - - ! '*' - x-li-format: - - json - content-type: - - application/json;charset=UTF-8 - transfer-encoding: - - chunked - date: - - Thu, 23 Feb 2012 10:46:46 GMT - body: ! "{\n \"companies\": {\n \"_count\": 10,\n \"_start\": 0,\n \"_total\": - 5696,\n \"values\": [\n {\n \"description\": \"Apple designs - Macs, the best personal computers in the world, along with Mac OS X, iLife, - iWork, and professional software. Apple leads the digital music revolution with - its iPods and iTunes online store. Apple is reinventing the mobile phone with - its revolutionary iPhone and App Store, and has recently introduced its magical - iPad which is defining the future of mobile media and computing devices.\",\n - \ \"id\": 162479,\n \"industries\": {\n \"_total\": 1,\n - \ \"values\": [{\n \"code\": \"4\",\n \"name\": - \"Computer Software\"\n }]\n },\n \"name\": \"Apple\",\n - \ \"specialties\": {\n \"_total\": 4,\n \"values\": - [\n \"Innovative product development\",\n \"world class - operations\",\n \"Retail\",\n \"Telephone Support\"\n - \ ]\n }\n },\n {\n \"description\": \"Every - Apple Retail Store offers customers great ways to get the most out of their - Mac and iPod, such as free advice at the Genius Bar, popular in-store workshops - and special programs for kids. Customers can also book a free appointment with - a Personal Shopper to get expert buying advice or help selecting the perfect - gift for everyone on their list. The hands-on Apple Retail Store experience - gives customers a chance to test-drive Apple\\u2019s entire product line.\",\n - \ \"id\": 1276,\n \"industries\": {\n \"_total\": 1,\n - \ \"values\": [{\n \"code\": \"27\",\n \"name\": - \"Retail\"\n }]\n },\n \"name\": \"Apple Retail\",\n - \ \"specialties\": {\n \"_total\": 3,\n \"values\": - [\n \"retail\",\n \"technology\",\n \"computers\"\n - \ ]\n }\n },\n {\n \"description\": \"Xerox - was founded in 1906 in Rochester, New York as \\\"The Haloid Company\\\", which - originally manufactured photographic paper and equipment. The company subsequently - changed its name to \\\"Haloid Xerox\\\" in 1958 and then simply \\\"Xerox\\\" - in 1961. The company came to prominence in 1959 with the introduction of the - first plain paper photocopier using the process of xerography developed by Chester - Carlson, the Xerox 914. Before releasing the 914, Xerox had also introduced - the first xerographic printer, the \\\"Copyflo\\\" in 1955.\\r\\n\\r\\nIn 1970 - Xerox opened the Xerox PARC research facility. The facility developed many modern - computing methods such as the mouse and the graphical user interface. From these - inventions, Xerox PARC created the Xerox Alto in 1973, a small minicomputer - similar to a workstation and personal computer. The Alto was never commercially - sold, as Xerox itself could not see the sales potential of it. In 1979, several - Apple Computer employees, including Steve Jobs, visited Xerox PARC, interested - in seeing their developments. Jobs and the others saw the commercial potential - of the GUI and mouse, and began development of the Apple Lisa, which Apple introduced - in 1983.\\r\\n \\r\\nHeadquartered in Norwalk, Conn., today Xerox is a $22 - billion leading global enterprise for business process and document management. - Through its portfolio of technology and services, Xerox provides the essential - back-office support that clears the way for clients to focus on what they do - best: their real business. Xerox provides leading-edge document technology, - services, software and genuine Xerox supplies for graphic communication and - office printing environments of any size. Through ACS, A Xerox Company, which - Xerox acquired in February 2010, Xerox also offers extensive business process - outsourcing and IT outsourcing services, including data processing, HR benefits - management, finance support, and CRM services for commercial and government - organizations worldwide.\",\n \"id\": 1373,\n \"industries\": - {\n \"_total\": 1,\n \"values\": [{\n \"code\": - \"83\",\n \"name\": \"Printing\"\n }]\n },\n \"name\": - \"Xerox\",\n \"specialties\": {\n \"_total\": 6,\n \"values\": - [\n \"Office Solutions\",\n \"Printing\",\n \"document - management\",\n \"managed print services\",\n \"ITO\",\n - \ \"BPO\"\n ]\n }\n },\n {\n \"description\": - \"With more than 23 million members in the United States and Canada, Netflix, - Inc. [Nasdaq: NFLX] is the world\\u2019s leading Internet subscription service - for enjoying movies and TV shows. For $7.99 a month, Netflix members can instantly - watch unlimited movies and TV episodes streamed over the Internet to PCs, Macs - and TVs. Among the large and expanding base of devices streaming from Netflix - are Microsoft\\u2019s Xbox 360, Nintendo\\u2019s Wii and Sony\\u2019s PS3 consoles; - an array of Blu-ray disc players, Internet-connected TVs, home theater systems, - digital video recorders and Internet video players; Apple\\u2019s iPhone, iPad - and iPod touch, as well as Apple TV and Google TV. In all, more than 200 devices - that stream from Netflix are available in the U.S. and a growing number are - available in Canada. For more information, visit www.netflix.com.\",\n \"id\": - 165158,\n \"industries\": {\n \"_total\": 1,\n \"values\": - [{\n \"code\": \"28\",\n \"name\": \"Entertainment\"\n - \ }]\n },\n \"name\": \"Netflix\",\n \"specialties\": - {\n \"_total\": 1,\n \"values\": [\"The best way to watch - movies and TV shows instantly.\"]\n }\n },\n {\n \"description\": - \"HCL Infosystems Ltd, with revenue of US $ 2.5 billion (Rs. 12,057 Cr) is India\\u2019s - premier hardware, services and ICT systems integration company offering a wide - \ spectrum of ICT products that includes Computing, Storage, Networking, Security, - Telecom, Imaging and Retail. HCL is a one-stop-shop for all the ICT requirements - of an organization. India's leading System Integration and Infrastructure Management - Services Organization, HCL has specialized expertise across verticals including - Telecom, BFSI, eGovernance & Power. HCL has India's largest distribution and - retail network, taking to market a range of Digital Lifestyle products in partnership - with leading global ICT brands, including Apple, Cisco, Ericsson, Kingston, - Kodak, Konica Minolta, Microsoft, Nokia, and many more. HCL today has India's - largest vertically integrated computer manufacturing facility with over three - decades of electronic manufacturing experience & HCL desktops is the largest - selling brand into the enterprise space. With India\\u2019s largest ICT services - network that reaches to every corner of India, HCL\\u2019s award winning Support - Services makes it the preferred choice of enterprise and consumers alike. HCL - Infosystems has a 100% subsidiary that addresses the physical security technology - system integration market. The subsidiary leverages technology to build a security - framework called \\u2018Safe State\\u2019 that safe guard\\u2019s life, infrastructure - & society. \\r\\nFor more information please visit us at www.hclinfosystems.com\",\n - \ \"id\": 7240,\n \"industries\": {\n \"_total\": 1,\n - \ \"values\": [{\n \"code\": \"96\",\n \"name\": - \"Information Technology and Services\"\n }]\n },\n \"name\": - \"HCL Infosystems Ltd\",\n \"specialties\": {\n \"_total\": - 9,\n \"values\": [\n \"ERP Consulting & Services\",\n \"System - Integration\",\n \"IT Infrastructure Consultancy\",\n \"Managed - Services\",\n \"Strategic Outsourcing Services\",\n \"Infostructure - Services\",\n \"Networking Infrastructure\",\n \"Facilities - Management\",\n \"Career Development Centre and VPN & Managed Network\"\n - \ ]\n }\n },\n {\n \"description\": \"Experience - the Difference. \\r\\nFor over 40 years, Apple Vacations has provided the - most value in vacations to millions of people. Throughout the years, we\\u2019ve - provided what you want in a vacation \\u2013 great service, convenience, and - value. We understand just how important your vacation is. We know because, like - you, vacations are important to us too. \\r\\n \\r\\nApple Vacations is now - a company of almost 1500 energetic, hardworking employees with the same entrepreneurial - attitudes as our founders. Headquartered just outside Philadelphia with regional - offices in Chicago and Boston, the company is completely focused on providing - quality vacations for our customers. Employees are empowered to make decisions - that impact the quality of their customers\\u2019 vacations on a daily basis. - Since our humble beginnings, Apple Vacations has created the ultimate \\u201cbeginning-to-end\\u201d - vacation experience for customers. Apple Vacations employees will greet you - at your departure airport in more than 20 cities; and will meet your flight - in our charter destinations. Apple Vacations\\u2019 sister companies, USA3000 - Airlines, flies customers to their destinations from more than 20 U.S. cities; - and Amstar, is the destination management company in-resort with uniformed representatives, - who will greet you upon arrival and assist you while you are at your resort. - Unlike any other travel company, Apple Vacations truly provides the ultimate - in a quality vacation experience.\",\n \"id\": 19271,\n \"industries\": - {\n \"_total\": 1,\n \"values\": [{\n \"code\": - \"30\",\n \"name\": \"Leisure and Travel\"\n }]\n },\n - \ \"name\": \"Apple Vacations\",\n \"specialties\": {\n \"_total\": - 2,\n \"values\": [\n \"Leisure travel\",\n \"all - inclusive vacation packages\"\n ]\n }\n },\n {\n \"description\": - \"FileMaker is the leader in easy-to-use database software. Millions of people, - from individuals to some of the world's largest companies, rely on FileMaker - software to manage, analyze and share essential information. \\r\\n\\r\\nThe - company's products are the FileMaker Pro line - versatile database software - for teams and organizations, for Windows, Mac, iPhone, iPad and the web - and - Bento, the personal database for Mac, iPhone and iPad. FileMaker, Inc. is a - subsidiary of Apple.\",\n \"id\": 163801,\n \"industries\": {\n - \ \"_total\": 1,\n \"values\": [{\n \"code\": \"4\",\n - \ \"name\": \"Computer Software\"\n }]\n },\n \"name\": - \"FileMaker\",\n \"specialties\": {\n \"_total\": 10,\n \"values\": - [\n \"database\",\n \"online database\",\n \"easy - database\",\n \"software\",\n \"iphone software\",\n \"iphone - database\",\n \"organization\",\n \"server\",\n \"database - server\",\n \"web database\"\n ]\n }\n },\n - \ {\n \"description\": \"GHA Technologies, Inc. is a nationally expanding - network, computer reseller and systems integrator with offices nationwide. GHA - is listed as the 196 on the national VAR 500 list and 32nd largest private corporation - in Arizona. \\r\\n\\r\\nWe sell Apple, HP, Dell, IBM, Lenovo, Sony, Fujitsu, - APC, Symantec, Panasonic, Microsoft, Vmware, Intel, Cisco, Premio and all the - hottest Internet, bandwidth, security, VoIP, wireless, video, identification - technologies and a vast offering of technology services. \\r\\n\\r\\nSome facts - about GHA Technologies, Inc.\\r\\n\\u2022 One of the largest, private providers - of technology solutions for corporate, government & education markets in America.\\r\\n\\u2022 - Our vast access to coast-to-coast distribution network and warehouse facilities - support just-in-time delivery.\\r\\n\\u2022 Mission-critical delivery-Orders - placed by 9:00 p.m. EST (8:00 p.m. CST) can be received the next morning for - in-stock items.\\r\\n\\u2022 Secure, password-protected 24-hour access to your - own personal, customized website with special pricing on more than 1.1 million - products from more than 1,000 manufacturers.\\r\\n\\r\\nGHA Technologies, Inc. - has about 100 + employees with annual sales of approximately $80 million. Our - highly motivated and experienced sales professionals provide the highest level - of service to our customers. \\r\\n\\r\\nGHA Technologies, Inc. is currently - HIRING industry experienced technology sales professionals nationwide. Please - send your resume to resumes@gha-associates.com. We look forward to hearing from - you.\",\n \"id\": 21482,\n \"industries\": {\n \"_total\": - 1,\n \"values\": [{\n \"code\": \"96\",\n \"name\": - \"Information Technology and Services\"\n }]\n },\n \"name\": - \"GHA Technologies\",\n \"specialties\": {\n \"_total\": 5,\n - \ \"values\": [\n \"Hardware, Software and Technology Components\",\n - \ \"Technology Services - Integration, Installation and Specialized\",\n - \ \"Corporate Commercial Business Clients\",\n \"Non-profit - Organizations\",\n \"Government and Educational Institutions\"\n - \ ]\n }\n },\n {\n \"description\": \"Apple - & Associates is an executive search firm that specializes in the Pharmaceutical, - Medical Device and Consumer Product Industries. We provide extensive coverage - of these worldwide markets and have forged a solid reputation in the industry - as a competent, aggressive, and resource-rich recruiting firm. We are a nation-wide - company with offices through-out the United States. \\r\\n\\r\\nApple & Associates - belongs to Intercity Personnel Associates (IPA) and the Top Echelon Network. - \ Through these worldwide recruiting networks, we share confidentially coded - information about available positions and receive qualified candidates within - a short period of time. With one phone call you not only have rapid access - to our candidates, but also to qualified candidates from over 1,000 of the nation\\u2019s - other top recruiting firms. Because our executive recruiters specialize in - different industry segments, we can give you the service you deserve in a fast, - focused, and efficient manner and provide you with quality industry specific - candidates. \\r\\n\\r\\nWe realize the importance of hiring professionals - who understand and are able to assimilate with your company\\u2019s business - model, culture, process, equipment, and materials. Our team has studied the - hiring decisions that make the firms in the Pharmaceutical and Medical Device - industries so successful. Our candidates will meet the standard your company - demands, with the technical and industry background to match.\",\n \"id\": - 112136,\n \"industries\": {\n \"_total\": 1,\n \"values\": - [{\n \"code\": \"104\",\n \"name\": \"Staffing and Recruiting\"\n - \ }]\n },\n \"name\": \"Apple & Associates\",\n \"specialties\": - {\n \"_total\": 20,\n \"values\": [\n \"Medical - Device\",\n \"Pharmaceutical\",\n \"Power\",\n \"Energy\",\n - \ \"Consumer Products\",\n \"Supply Chain\",\n \"Purchasing\",\n - \ \"Engineering\",\n \"Marketing\",\n \"Sales\",\n - \ \"Human Resources\",\n \"Science\",\n \"Finance\",\n - \ \"Manufacturing\",\n \"Operations\",\n \"R&D\",\n - \ \"Six Sigma\",\n \"IT\",\n \"chemist\",\n - \ \"Executive Management\"\n ]\n }\n },\n {\n - \ \"description\": \"The Ultimate Computer Store - We empower customers - with computer and electronic solutions coupled with excellent customer service - that sets us apart from the rest.\\r\\n\\r\\nFounded in 1979 by two former Radio - Shack employees. The first Micro Center store was a 900 sq ft (84 m2). storefront - located in the Lane Avenue Shopping Center in Upper Arlington, Ohio. There are - currently 22 Micro Center stores nation-wide in California, Colorado, Georgia, - Illinois, Kansas, Massachussetts, Maryland, Michigan, Minnesota, Missouri, New - Jersey, New York, Ohio, Pennsylvania, Texas, and Virginia. A 23rd store will - open in Yonkers, NY this spring.\",\n \"id\": 15552,\n \"industries\": - {\n \"_total\": 1,\n \"values\": [{\n \"code\": - \"27\",\n \"name\": \"Retail\"\n }]\n },\n \"name\": - \"Micro Center\",\n \"specialties\": {\n \"_total\": 7,\n \"values\": - [\n \"computers\",\n \"Apple\",\n \"build your - own\",\n \"iPod\",\n \"GPS\",\n \"TVs\",\n - \ \"service\"\n ]\n }\n }\n ]\n },\n \"numResults\": - 5696\n}" - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_options_with_fields/should_perform_a_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_options_with_fields/should_perform_a_search.yml new file mode 100644 index 00000000..6342008b --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_options_with_fields/should_perform_a_search.yml @@ -0,0 +1,43 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/company-search:(companies:(id,name,industries,description,specialties),num-results)?keywords=apple + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="XIAUlVH3VfeqacvVEQzCvdLSyy9swruF3mouF9mtc", + oauth_signature="ggZObnJ1w5zMIBixfluGoUYZVSg%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631654", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + User-Agent: + - OAuth gem v0.4.7 + response: + status: + code: 200 + message: OK + headers: + X-Li-Request-Id: + - 68RH2HSO61 + X-Li-Format: + - json + Date: + - Wed, 10 Apr 2013 22:07:35 GMT + Vary: + - ! '*' + Server: + - Apache-Coyote/1.1 + Content-Type: + - application/json;charset=UTF-8 + Transfer-Encoding: + - chunked + body: + encoding: UTF-8 + string: ! "{ \"companies\": { \"_count\": 10, \"_start\": 0, \"_total\": 8450, \"values\": [ { \"description\": \"Apple designs Macs, the best personal computers in the world, along with OS X, iLife, iWork and professional software. Apple leads the digital music revolution with its iPods and iTunes online store. Apple has reinvented the mobile phone with its revolutionary iPhone and App Store, and is defining the future of mobile media and computing devices with iPad.\", \"id\": 162479, \"industries\": { \"_total\": 1, \"values\": [{ \"code\": \"24\", \"name\": \"Consumer Electronics\" }] }, \"name\": \"Apple\", \"specialties\":{ \"_total\": 4, \"values\": [ \"Innovative product development\", \"world class operations\", \"Retail\", \"Telephone Support\" ] } }, { \"description\": \"Experience the Difference. \\r\\nFor over 40 years, Apple Vacations has provided the most value in vacations to millions of people. Throughout the years, we\\u2019ve provided what you want in a vacation \\u2013 great service, convenience, and value. We understand just how important your vacation is. We know because, like you, vacations are important to us too. \\r\\n \\r\\nApple Vacations is a company of energetic, hardworking employees with the same entrepreneurial attitudes as our founders. Headquartered just outside Philadelphia with regional offices in Chicago and Boston, the company is completely focused on providing quality vacations for our customers. Employees are empowered to make decisions that impact the quality of their customers\\u2019 vacations on a daily basis. Since our humble beginnings, Apple Vacations has created the ultimate \\u201cbeginning-to-end\\u201d vacation experience for customers. Apple Vacations employees will greet you at your departure airport in more than 20 cities; and will meet your flight in our charter destinations. Apple Vacations\\u2019 sister companies, flies customers to their destinations from more than 20 U.S. cities; and Amstar, is the destination management company in-resort with uniformed representatives, who will greet you upon arrival and assist you while you are at your resort. Unlike any other travel company, Apple Vacations truly provides the ultimate in a quality vacation experience.\", \"id\": 19271, \"industries\": { \"_total\": 1, \"values\": [{ \"code\": \"30\", \"name\": \"Leisure & Travel\" }] }, \"name\": \"Apple Vacations\", \"specialties\": { \"_total\": 2, \"values\": [ \"Leisure travel\", \"all inclusive vacation packages\" ] } }, { \"description\": \"Big Apple International Realty has been listing, selling and managing Residential Real Estate in four counties of the Greater Orlando and Central Florida areas for over five years. Because our Property Management Division had grown substantially, and to fill the growing need for property management services in Central Florida, we founded Orlando Rental Store in 2008. In addition to providing \\\"Lease Only\\\" services at competitive prices, we currently manage close to 50 properties in the Greater Orlando Area.\", \"id\": 778626, \"industries\":{ \"_total\": 1, \"values\": [{ \"code\": \"44\", \"name\": \"Real Estate\" }] }, \"name\": \"Big Apple Holdings, Inc. dba Big Apple International Realty\" }, { \"description\": \"Apple & Associates is an executive search firm that specializes in the Pharmaceutical, Medical Device and Consumer Product Industries. We provide extensive coverage of these worldwide markets and have forged a solid reputation in the industry as a competent, aggressive, and resource-rich recruiting firm. We are a nation-wide company with offices through-out the United States. \\r\\n\\r\\nApple & Associates belongs to Intercity Personnel Associates (IPA) and the Top Echelon Network. Through these worldwide recruiting networks, we share confidentially coded information about available positions and receive qualified candidates within a short period of time. With one phone call you not only have rapid access to our candidates, but also to qualified candidates from over 1,000 of the nation\\u2019s other top recruiting firms. Because our executive recruiters specialize in different industry segments, we can give you the service you deserve in a fast, focused, and efficient manner and provide you with quality industry specific candidates. \\r\\n\\r\\nWe realize the importance of hiring professionals who understand and are able to assimilate with your company\\u2019s business model, culture, process, equipment, and materials. Our team has studied the hiring decisions that make the firms in the Pharmaceutical and Medical Device industries so successful. Our candidates will meet the standard your company demands, with the technical and industry background to match.\", \"id\": 112136, \"industries\": { \"_total\": 1, \"values\": [{ \"code\": \"104\", \"name\": \"Staffing & Recruiting\" }] }, \"name\": \"Apple & Associates\", \"specialties\":{ \"_total\": 20, \"values\": [ \"Medical Device\", \"Pharmaceutical\", \"Power\", \"Energy\", \"Consumer Products\", \"Supply Chain\", \"Purchasing\", \"Engineering\", \"Marketing\", \"Sales\", \"Human Resources\", \"Science\", \"Finance\", \"Manufacturing\", \"Operations\", \"R&D\", \"Six Sigma\", \"IT\", \"chemist\", \"Executive Management\" ] } }, { \"description\": \"Headquartered in Singapore and a presence in 9 countries globally, Stone Apple is a Specialized Consulting firm focused mainly on Business Intelligence & Analytics, Enterprise Resource Planning, Knowledge Management & Application Integration with a strong product portfolio, analytical applications, Proprietary Industry Solutions and strong services capability \\r\\n\\r\\nStone Apple has a strong offshore presence in SE Asia with development centers in Vietnam and Malaysia. The Company has a strong presence and networks in Asia Pacific, Europe and United States to support their rapidly growing MNC enterprise customer base \\r\\n\\r\\nStone Apple provides customized solutions to meet the changing needs of enterprises globally. From leading industry methodologies to in-house proven models, Stone Apple collaborates with their customers to deliver tangible business results that impact their bottom line.\", \"id\": 772044, \"industries\": { \"_total\": 1, \"values\": [{ \"code\": \"96\", \"name\": \"Information Technology & Services\" }] }, \"name\": \"Stone Apple Solutions\" }, { \"description\": \"iSquare S.A. is the Apple Authorised Distributor of Greece and Cyprus since September 2010. iSquare is distributing Apple products but also plans, implements and provides intergrated solutions, based on the innovative Apple products and technology. iSquare's strategic goal is to increase the use of Apple products among the Greek consumers, but also to provide users the ultimate Apple experience.\\r\\n\\r\\niSquare creates and provides a complete ecosystem for Apple products and services, aiming to bring Greek customers closer to Apple's philosophy. In order to do that, iSquare:\\r\\n\\r\\n- Creates a wide network of POS (Points Of Sales) that spreads throughout Greece and Cyprus\\r\\n\\r\\n- Develops its relations with major retail chains in order to promote Apple products to a wide range of customers\\r\\n\\r\\n- Creates a unique network of stores exclusively for Apple products, always in line with the high standards of \\r\\n Apple Premium Reseller program\\r\\n\\r\\n- Invests on continuous and in depth training of the sales network in order to provide the best before and after sale \\r\\n support, according to Apple's and iSquare's high standards\\r\\n\\r\\n- Focuses on the crucial sector of Education\\r\\n\\r\\n- Constantly works to improve the support of Apple products and solutions\\r\\n\\r\\n- Completes Apple's ecosystem as the distributor of software and peripherals from well known brands.\\r\\n\\r\\n\\r\\nWith a vision that derives from Apple's innovation, iSquare aspires to bring the Apple products at the stature they deserve within the Greek and Cypriot market.\", \"id\": 2135525, \"industries\":{ \"_total\": 1, \"values\": [{ \"code\": \"24\", \"name\": \"Consumer Electronics\" }] }, \"name\": \"iSquare - Apple Authorized Distributor in Greece & Cyprus\" }, { \"description\": \"Filex (Moj Apple DuÄ\u0087an i Servis) je autorizirani Apple partner za prodaju, servis i podrÅ¡ku.\\r\\n\\r\\nFilex je osnovan 1992 godine te od tada u kontinuitetu razvijamo i unapreÄ\u0091ujemo prepoznatljivost Apple tehnologija prezentirajuÄ\u0087i upotrebnu vrijednost Apple rjeÅ¡enja, na domaÄ\u0087em i regionalnom tržiÅ¡tu.\\r\\n\\r\\nNaÅ¡ fokus nije iskljuÄ\u008Divo na tehnologijama veÄ\u0087 kako te tehnologije podrediti potrebama korisnika. Sukladno tome, Filex nije samo joÅ¡ jedna u nizu trgovina u koju Ä\u0087ete doÄ\u0087i \\\"pokupiti\\\" svoj Apple ureÄ\u0091aj, veÄ\u0087 mjesto na kojem Ä\u0087ete postavljati pitanja, razgovarati i diskutirati te na kraju izaÄ\u0087i sa rjeÅ¡enjem - ma kako god ono na kraju izgledalo!\\r\\n\\r\\nKontaktirajte nas preko naÅ¡eg Internet Store-a (www.filex.hr), ili nam piÅ¡ite na prodaja@filx.hr ili servis@filex.hr.\\r\\nI svakako nam se pridružite na Facebook-u na http://www.facebook.com/pages/Filex-Moj-Apple-DuÄ\u0087an-i-Servis/131194173598671\\r\\n\\r\\nVaÅ¡e zadovoljstvo naÅ¡a je misija!\", \"id\": 2303504, \"industries\":{ \"_total\": 1, \"values\": [{ \"code\": \"3\", \"name\": \"Computer Hardware\" }] }, \"name\": \"Filex Apple Store & Support\", \"specialties\":{ \"_total\": 4, \"values\": [ \"Apple Store\", \"Apple PodrÅ¡ka i Servis\", \"Apple RjeÅ¡enja\", \"Apple B2B\" ] } }, { \"description\": \"Als Apple een nieuwssite zou maken in Vlaanderen, dan was het AppleVlaanderen. AppleVlaanderen is gemaakt met dezelfde passie en aandacht voor detail als de producten van Apple zelf.\\r\\n\\r\\nWe behandelen de nieuwsfeiten over Apple met zorg en proberen u zo goed mogelijk in te lichten als Apple-Fan in Vlaanderen. Dagelijks circuleren er duizenden geruchten over Apple in het algemeen, onze taak is deze te bundelen en u mee te delen.\\r\\n\\r\\nDit doen we met veel liefde voor de verschillende producten en voor Apple in het algemeen. Onze medewerkers werken allemaal op vrijwillige basis en hebben voldoende kennis over de producten van Apple.\", \"id\": 2419290, \"industries\": { \"_total\": 1, \"values\": [{ \"code\": \"81\", \"name\": \"Newspapers\" }] }, \"name\": \"Apple Nieuws Vlaanderen\", \"specialties\": { \"_total\": 4, \"values\": [ \"apple\", \"iPhone\", \"iPad\", \"mac\" ] } }, { \"description\": \"OGGO est une société de conseils et solutions Apple Macintosh basée à Genève, nous proposons notre savoir faire essentiellement aux PME et particuliers.\\r\\n\\r\\nNos services en un coup d'oeil :\\r\\n\\r\\n// Réparations\\r\\n// Optimisations matérielles\\r\\n// Contrats de maintenance\\r\\n// Dépannage sur site\\r\\n// Interventions urgentes\\r\\n// Maintenance\\r\\n// Aide à l'achat\\r\\n// Formations\", \"id\": 2260437, \"industries\": { \"_total\": 1, \"values\": [{ \"code\": \"96\", \"name\": \"Information Technology & Services\" }] }, \"name\": \"OGGO - Services Apple Macintosh\", \"specialties\": { \"_total\": 7, \"values\": [ \"Consulting & conseils Apple Macintosh\", \"Support Apple Macintosh\", \"Maintenance Mac OS X Server\", \"Dépannage Mac OS X\", \"Installation Mac OS X Server\", \"Interventions Apple Macintosh\", \"Formation Apple Macintosh\" ] } }, { \"description\": \"Apple-Crumble provides sound advice, sales and support for all apple mac products and related peripherals including external hard drives, printers, scanners and both apple and 3rd party software. Apple-Crumble are also experts in troubleshooting, repair and maintenance. Our staff are apple trained and certified with over 15 years experience.\\r\\n\\r\\nAll work is guaranteed and all enquiries are welcome.\\r\\n\\r\\nWe are obviously very \\u2018pro\\u2019 apple and firmly believe that once you go mac you never go back!\\r\\n\\r\\nFor your convenience Apple-Crumble have our own workshop and offices with free parking in Penzance, Cornwall so that you have the extra peace of mind knowing that your equipment is being serviced in a clean and safe environment. You may also view, demo and purchase new hardware or add-ons, as well as discussing tailor-made options for you and/or your business.\\r\\n\\r\\nApple-Crumble\\u2019s service extends to on-site visits for emergency or contract call-outs, as well as delivery and installation of new products and systems. We cover Penzance, Falmouth, Helston and the Lizard, St Ives, Hayle, Truro, Camborne, Redruth, and all surrounding areas including north Cornwall and Devon\\r\\n\\r\\nIn most cases it is safer and more cost effective to bring your hardware to us as we are geared up for any static or time delay issues, but it is very rare that we cannot provide a solution, wherever you may be!\", \"id\": 1049054, \"industries\": { \"_total\": 1, \"values\": [{ \"code\": \"3\", \"name\": \"Computer Hardware\" }] }, \"name\": \"Apple Crumble\" } ] }, \"numResults\": 8450}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_string_parameter.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_string_parameter.yml deleted file mode 100644 index a046082c..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_string_parameter.yml +++ /dev/null @@ -1,73 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/company-search?keywords=apple - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="AjzqbXMKJpWjOwkez3vTKhBzkUwg1hl5oDycGFPqJhU", - oauth_signature="2srg9HlZNRvszkxMALkx%2FNwSFBg%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329991290", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - server: - - Apache-Coyote/1.1 - x-li-request-id: - - LPZS6ZUV2L - vary: - - ! '*' - x-li-format: - - json - content-type: - - application/json;charset=UTF-8 - transfer-encoding: - - chunked - date: - - Thu, 23 Feb 2012 10:01:33 GMT - nncoection: - - close - body: ! "{\n \"companies\": {\n \"_count\": 10,\n \"_start\": 0,\n \"_total\": - 5696,\n \"values\": [\n {\n \"id\": 162479,\n \"name\": - \"Apple\"\n },\n {\n \"id\": 1276,\n \"name\": \"Apple - Retail\"\n },\n {\n \"id\": 1373,\n \"name\": \"Xerox\"\n - \ },\n {\n \"id\": 165158,\n \"name\": \"Netflix\"\n - \ },\n {\n \"id\": 7240,\n \"name\": \"HCL Infosystems - Ltd\"\n },\n {\n \"id\": 19271,\n \"name\": \"Apple - Vacations\"\n },\n {\n \"id\": 163801,\n \"name\": \"FileMaker\"\n - \ },\n {\n \"id\": 21482,\n \"name\": \"GHA Technologies\"\n - \ },\n {\n \"id\": 112136,\n \"name\": \"Apple & Associates\"\n - \ },\n {\n \"id\": 15552,\n \"name\": \"Micro Center\"\n - \ }\n ]\n },\n \"facets\": {\n \"_total\": 1,\n \"values\": [{\n - \ \"buckets\": {\n \"_total\": 10,\n \"values\": [\n {\n - \ \"code\": \"us:0\",\n \"count\": 1836,\n \"name\": - \"United States\",\n \"selected\": false\n },\n {\n - \ \"code\": \"gb:0\",\n \"count\": 491,\n \"name\": - \"United Kingdom\",\n \"selected\": false\n },\n {\n - \ \"code\": \"us:84\",\n \"count\": 237,\n \"name\": - \"San Francisco Bay Area\",\n \"selected\": false\n },\n - \ {\n \"code\": \"nl:0\",\n \"count\": 227,\n - \ \"name\": \"Netherlands\",\n \"selected\": false\n },\n - \ {\n \"code\": \"us:70\",\n \"count\": 208,\n - \ \"name\": \"Greater New York City Area\",\n \"selected\": - false\n },\n {\n \"code\": \"ca:0\",\n \"count\": - 199,\n \"name\": \"Canada\",\n \"selected\": false\n },\n - \ {\n \"code\": \"au:0\",\n \"count\": 130,\n - \ \"name\": \"Australia\",\n \"selected\": false\n },\n - \ {\n \"code\": \"us:49\",\n \"count\": 130,\n - \ \"name\": \"Greater Los Angeles Area\",\n \"selected\": - false\n },\n {\n \"code\": \"in:0\",\n \"count\": - 121,\n \"name\": \"India\",\n \"selected\": false\n },\n - \ {\n \"code\": \"it:0\",\n \"count\": 121,\n - \ \"name\": \"Italy\",\n \"selected\": false\n }\n - \ ]\n },\n \"code\": \"location\",\n \"name\": \"Location\"\n - \ }]\n },\n \"numResults\": 5696\n}" - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_string_parameter/should_perform_a_company_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_string_parameter/should_perform_a_company_search.yml new file mode 100644 index 00000000..909d2c1a --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_keywords_string_parameter/should_perform_a_company_search.yml @@ -0,0 +1,80 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/company-search?keywords=apple + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="xtc6RIIOpDj7AANJ9VyIXibv4YhcM3gxMUg6OewBSo", + oauth_signature="8ShrnvC9fxh1tU3YNEjF4l%2Fhrho%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631653", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + User-Agent: + - OAuth gem v0.4.7 + response: + status: + code: 200 + message: OK + headers: + X-Li-Request-Id: + - 5LR8OTP90S + X-Li-Format: + - json + Date: + - Wed, 10 Apr 2013 22:07:32 GMT + Vary: + - ! '*' + Server: + - Apache-Coyote/1.1 + Content-Type: + - application/json;charset=UTF-8 + Transfer-Encoding: + - chunked + body: + encoding: UTF-8 + string: ! "{\n \"companies\": {\n \"_count\": 10,\n \"_start\": 0,\n + \"_total\": 8450,\n \"values\": [\n {\n \"id\": 162479,\n + \"name\": \"Apple\"\n },\n {\n \"id\": 19271,\n \"name\": + \"Apple Vacations\"\n },\n {\n \"id\": 778626,\n \"name\": + \"Big Apple Holdings, Inc. dba Big Apple International Realty\"\n },\n + {\n \"id\": 112136,\n \"name\": \"Apple & Associates\"\n + },\n {\n \"id\": 772044,\n \"name\": \"Stone Apple + Solutions\"\n },\n {\n \"id\": 2135525,\n \"name\": + \"iSquare - Apple Authorized Distributor in Greece & Cyprus\"\n },\n + {\n \"id\": 2303504,\n \"name\": \"Filex Apple Store & + Support\"\n },\n {\n \"id\": 2419290,\n \"name\": + \"Apple Nieuws Vlaanderen\"\n },\n {\n \"id\": 2260437,\n + \"name\": \"OGGO - Services Apple Macintosh\"\n },\n {\n + \"id\": 1049054,\n \"name\": \"Apple Crumble\"\n }\n ]\n + },\n \"facets\": {\n \"_total\": 1,\n \"values\": [{\n \"buckets\":{\n + \"_total\": 10,\n \"values\": [\n {\n \"code\": + \"us:0\",\n \"count\": 2511,\n \"name\": \"United States\",\n + \"selected\": false\n },\n {\n \"code\": + \"gb:0\",\n \"count\": 702,\n \"name\": \"United Kingdom\",\n + \"selected\": false\n },\n {\n \"code\": + \"us:84\",\n \"count\": 322,\n \"name\": \"San Francisco + Bay Area\",\n \"selected\": false\n },\n {\n + \"code\": \"us:70\",\n \"count\": 285,\n \"name\": + \"Greater New York City Area\",\n \"selected\": false\n },\n + {\n \"code\": \"nl:0\",\n \"count\": 284,\n + \"name\": \"Netherlands\",\n \"selected\": false\n + },\n {\n \"code\": \"ca:0\",\n \"count\": + 266,\n \"name\": \"Canada\",\n \"selected\": false\n + },\n {\n \"code\": \"au:0\",\n \"count\": + 195,\n \"name\": \"Australia\",\n \"selected\": false\n + },\n {\n \"code\": \"in:0\",\n \"count\": + 186,\n \"name\": \"India\",\n \"selected\": false\n + },\n {\n \"code\": \"it:0\",\n \"count\": + 177,\n \"name\": \"Italy\",\n \"selected\": false\n + },\n {\n \"code\": \"us:49\",\n \"count\": + 173,\n \"name\": \"Greater Los Angeles Area\",\n \"selected\": + false\n }\n ]\n },\n \"code\": \"location\",\n \"name\": + \"Location\"\n }]\n },\n \"numResults\": 8450\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option.yml deleted file mode 100644 index 27ca443c..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/company-search?keywords=apple - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="ejdXp5uWJUyFyQOZKvwjvc3s3ircDxo0qmZPddXOQnQ", - oauth_signature="rUJEgmU4z6mKlIuB5lmkfVbcUYE%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329991292", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - server: - - Apache-Coyote/1.1 - x-li-request-id: - - 3UFS93YLH8 - vary: - - ! '*' - x-li-format: - - json - content-type: - - application/json;charset=UTF-8 - transfer-encoding: - - chunked - date: - - Thu, 23 Feb 2012 10:01:33 GMT - body: ! "{\n \"companies\": {\n \"_count\": 10,\n \"_start\": 0,\n \"_total\": - 5696,\n \"values\": [\n {\n \"id\": 162479,\n \"name\": - \"Apple\"\n },\n {\n \"id\": 1276,\n \"name\": \"Apple - Retail\"\n },\n {\n \"id\": 1373,\n \"name\": \"Xerox\"\n - \ },\n {\n \"id\": 165158,\n \"name\": \"Netflix\"\n - \ },\n {\n \"id\": 7240,\n \"name\": \"HCL Infosystems - Ltd\"\n },\n {\n \"id\": 19271,\n \"name\": \"Apple - Vacations\"\n },\n {\n \"id\": 163801,\n \"name\": \"FileMaker\"\n - \ },\n {\n \"id\": 21482,\n \"name\": \"GHA Technologies\"\n - \ },\n {\n \"id\": 112136,\n \"name\": \"Apple & Associates\"\n - \ },\n {\n \"id\": 15552,\n \"name\": \"Micro Center\"\n - \ }\n ]\n },\n \"facets\": {\n \"_total\": 1,\n \"values\": [{\n - \ \"buckets\": {\n \"_total\": 10,\n \"values\": [\n {\n - \ \"code\": \"us:0\",\n \"count\": 1836,\n \"name\": - \"United States\",\n \"selected\": false\n },\n {\n - \ \"code\": \"gb:0\",\n \"count\": 491,\n \"name\": - \"United Kingdom\",\n \"selected\": false\n },\n {\n - \ \"code\": \"us:84\",\n \"count\": 237,\n \"name\": - \"San Francisco Bay Area\",\n \"selected\": false\n },\n - \ {\n \"code\": \"nl:0\",\n \"count\": 227,\n - \ \"name\": \"Netherlands\",\n \"selected\": false\n },\n - \ {\n \"code\": \"us:70\",\n \"count\": 208,\n - \ \"name\": \"Greater New York City Area\",\n \"selected\": - false\n },\n {\n \"code\": \"ca:0\",\n \"count\": - 199,\n \"name\": \"Canada\",\n \"selected\": false\n },\n - \ {\n \"code\": \"au:0\",\n \"count\": 130,\n - \ \"name\": \"Australia\",\n \"selected\": false\n },\n - \ {\n \"code\": \"us:49\",\n \"count\": 130,\n - \ \"name\": \"Greater Los Angeles Area\",\n \"selected\": - false\n },\n {\n \"code\": \"in:0\",\n \"count\": - 121,\n \"name\": \"India\",\n \"selected\": false\n },\n - \ {\n \"code\": \"it:0\",\n \"count\": 121,\n - \ \"name\": \"Italy\",\n \"selected\": false\n }\n - \ ]\n },\n \"code\": \"location\",\n \"name\": \"Location\"\n - \ }]\n },\n \"numResults\": 5696\n}" - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option/should_perform_a_company_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option/should_perform_a_company_search.yml new file mode 100644 index 00000000..9e4b9637 --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option/should_perform_a_company_search.yml @@ -0,0 +1,80 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/company-search?keywords=apple + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="8HvACp7Bnl1RHEamMoOAgSExAIsa0ZmPg38voXltI", + oauth_signature="vU6TKCCBvu783h%2B0diQLZkcBKb8%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631653", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + User-Agent: + - OAuth gem v0.4.7 + response: + status: + code: 200 + message: OK + headers: + X-Li-Request-Id: + - XPJE34FJFO + X-Li-Format: + - json + Date: + - Wed, 10 Apr 2013 22:07:33 GMT + Vary: + - ! '*' + Server: + - Apache-Coyote/1.1 + Content-Type: + - application/json;charset=UTF-8 + Transfer-Encoding: + - chunked + body: + encoding: UTF-8 + string: ! "{\n \"companies\": {\n \"_count\": 10,\n \"_start\": 0,\n + \"_total\": 8450,\n \"values\": [\n {\n \"id\": 162479,\n + \"name\": \"Apple\"\n },\n {\n \"id\": 19271,\n \"name\": + \"Apple Vacations\"\n },\n {\n \"id\": 778626,\n \"name\": + \"Big Apple Holdings, Inc. dba Big Apple International Realty\"\n },\n + {\n \"id\": 112136,\n \"name\": \"Apple & Associates\"\n + },\n {\n \"id\": 772044,\n \"name\": \"Stone Apple + Solutions\"\n },\n {\n \"id\": 2135525,\n \"name\": + \"iSquare - Apple Authorized Distributor in Greece & Cyprus\"\n },\n + {\n \"id\": 2303504,\n \"name\": \"Filex Apple Store & + Support\"\n },\n {\n \"id\": 2419290,\n \"name\": + \"Apple Nieuws Vlaanderen\"\n },\n {\n \"id\": 2260437,\n + \"name\": \"OGGO - Services Apple Macintosh\"\n },\n {\n + \"id\": 1049054,\n \"name\": \"Apple Crumble\"\n }\n ]\n + },\n \"facets\": {\n \"_total\": 1,\n \"values\": [{\n \"buckets\":{\n + \"_total\": 10,\n \"values\": [\n {\n \"code\": + \"us:0\",\n \"count\": 2511,\n \"name\": \"United States\",\n + \"selected\": false\n },\n {\n \"code\": + \"gb:0\",\n \"count\": 702,\n \"name\": \"United Kingdom\",\n + \"selected\": false\n },\n {\n \"code\": + \"us:84\",\n \"count\": 322,\n \"name\": \"San Francisco + Bay Area\",\n \"selected\": false\n },\n {\n + \"code\": \"us:70\",\n \"count\": 285,\n \"name\": + \"Greater New York City Area\",\n \"selected\": false\n },\n + {\n \"code\": \"nl:0\",\n \"count\": 284,\n + \"name\": \"Netherlands\",\n \"selected\": false\n + },\n {\n \"code\": \"ca:0\",\n \"count\": + 266,\n \"name\": \"Canada\",\n \"selected\": false\n + },\n {\n \"code\": \"au:0\",\n \"count\": + 195,\n \"name\": \"Australia\",\n \"selected\": false\n + },\n {\n \"code\": \"in:0\",\n \"count\": + 186,\n \"name\": \"India\",\n \"selected\": false\n + },\n {\n \"code\": \"it:0\",\n \"count\": + 177,\n \"name\": \"Italy\",\n \"selected\": false\n + },\n {\n \"code\": \"us:49\",\n \"count\": + 173,\n \"name\": \"Greater Los Angeles Area\",\n \"selected\": + false\n }\n ]\n },\n \"code\": \"location\",\n \"name\": + \"Location\"\n }]\n },\n \"numResults\": 8450\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_a_facet.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_a_facet.yml deleted file mode 100644 index 0f47541b..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_a_facet.yml +++ /dev/null @@ -1,111 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/company-search?facets=industry%20location&keywords=apple - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="xcTeuTk5cLV7tNNj54FHtRznawbANOaFufpxhOzMoo", - oauth_signature="JoirhKilAS83lfN9j27EccA5EBw%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329991294", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 400 - message: Bad Request - headers: - server: - - Apache-Coyote/1.1 - x-li-request-id: - - KK2E56GW6H - date: - - Thu, 23 Feb 2012 10:01:34 GMT - vary: - - ! '*' - x-li-format: - - json - content-type: - - application/json;charset=UTF-8 - content-length: - - '151' - nncoection: - - close - body: ! "{\n \"errorCode\": 0,\n \"message\": \"Unknown facet code {industry - location}\",\n \"requestId\": \"KK2E56GW6H\",\n \"status\": 400,\n \"timestamp\": - 1329991295101\n}" - http_version: '1.1' -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/company-search?facets=industry&keywords=apple - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="irnhySxSqqJGyvqrhpTSLcNDzNZRjJlwEje7dkhgvg", - oauth_signature="5giHjjs15I5NzMA%2FEYoPejTl4BI%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329991354", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - server: - - Apache-Coyote/1.1 - x-li-request-id: - - 0VNTJU19QA - vary: - - ! '*' - x-li-format: - - json - content-type: - - application/json;charset=UTF-8 - transfer-encoding: - - chunked - date: - - Thu, 23 Feb 2012 10:02:36 GMT - body: ! "{\n \"companies\": {\n \"_count\": 10,\n \"_start\": 0,\n \"_total\": - 5696,\n \"values\": [\n {\n \"id\": 162479,\n \"name\": - \"Apple\"\n },\n {\n \"id\": 1276,\n \"name\": \"Apple - Retail\"\n },\n {\n \"id\": 1373,\n \"name\": \"Xerox\"\n - \ },\n {\n \"id\": 165158,\n \"name\": \"Netflix\"\n - \ },\n {\n \"id\": 7240,\n \"name\": \"HCL Infosystems - Ltd\"\n },\n {\n \"id\": 19271,\n \"name\": \"Apple - Vacations\"\n },\n {\n \"id\": 163801,\n \"name\": \"FileMaker\"\n - \ },\n {\n \"id\": 21482,\n \"name\": \"GHA Technologies\"\n - \ },\n {\n \"id\": 112136,\n \"name\": \"Apple & Associates\"\n - \ },\n {\n \"id\": 15552,\n \"name\": \"Micro Center\"\n - \ }\n ]\n },\n \"facets\": {\n \"_total\": 1,\n \"values\": [{\n - \ \"buckets\": {\n \"_total\": 10,\n \"values\": [\n {\n - \ \"code\": \"96\",\n \"count\": 1386,\n \"name\": - \"Information Technology and Services\",\n \"selected\": false\n - \ },\n {\n \"code\": \"4\",\n \"count\": - 732,\n \"name\": \"Computer Software\",\n \"selected\": - false\n },\n {\n \"code\": \"3\",\n \"count\": - 313,\n \"name\": \"Computer Hardware\",\n \"selected\": - false\n },\n {\n \"code\": \"6\",\n \"count\": - 295,\n \"name\": \"Internet\",\n \"selected\": false\n - \ },\n {\n \"code\": \"80\",\n \"count\": - 219,\n \"name\": \"Marketing and Advertising\",\n \"selected\": - false\n },\n {\n \"code\": \"24\",\n \"count\": - 166,\n \"name\": \"Consumer Electronics\",\n \"selected\": - false\n },\n {\n \"code\": \"27\",\n \"count\": - 142,\n \"name\": \"Retail\",\n \"selected\": false\n },\n - \ {\n \"code\": \"109\",\n \"count\": 123,\n \"name\": - \"Computer Games\",\n \"selected\": false\n },\n {\n - \ \"code\": \"126\",\n \"count\": 120,\n \"name\": - \"Media Production\",\n \"selected\": false\n },\n {\n - \ \"code\": \"99\",\n \"count\": 117,\n \"name\": - \"Design\",\n \"selected\": false\n }\n ]\n },\n - \ \"code\": \"industry\",\n \"name\": \"Industry\"\n }]\n },\n - \ \"numResults\": 5696\n}" - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_facets_to_return.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_facets_to_return.yml deleted file mode 100644 index 2390a37d..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_facets_to_return.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/company-search?facets=industry&keywords=apple - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="WNtBym5LDMHmF1yNiZA8ypTi6Ae5yZFgfWeyYjVK0E8", - oauth_signature="x2Mh3MmxuXDz2sBMnlqNsXIub5I%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329991802", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - server: - - Apache-Coyote/1.1 - x-li-request-id: - - 4MRGJTY83T - vary: - - ! '*' - x-li-format: - - json - content-type: - - application/json;charset=UTF-8 - transfer-encoding: - - chunked - date: - - Thu, 23 Feb 2012 10:10:03 GMT - body: ! "{\n \"companies\": {\n \"_count\": 10,\n \"_start\": 0,\n \"_total\": - 5696,\n \"values\": [\n {\n \"id\": 162479,\n \"name\": - \"Apple\"\n },\n {\n \"id\": 1276,\n \"name\": \"Apple - Retail\"\n },\n {\n \"id\": 1373,\n \"name\": \"Xerox\"\n - \ },\n {\n \"id\": 165158,\n \"name\": \"Netflix\"\n - \ },\n {\n \"id\": 7240,\n \"name\": \"HCL Infosystems - Ltd\"\n },\n {\n \"id\": 19271,\n \"name\": \"Apple - Vacations\"\n },\n {\n \"id\": 163801,\n \"name\": \"FileMaker\"\n - \ },\n {\n \"id\": 21482,\n \"name\": \"GHA Technologies\"\n - \ },\n {\n \"id\": 112136,\n \"name\": \"Apple & Associates\"\n - \ },\n {\n \"id\": 15552,\n \"name\": \"Micro Center\"\n - \ }\n ]\n },\n \"facets\": {\n \"_total\": 1,\n \"values\": [{\n - \ \"buckets\": {\n \"_total\": 10,\n \"values\": [\n {\n - \ \"code\": \"96\",\n \"count\": 1386,\n \"name\": - \"Information Technology and Services\",\n \"selected\": false\n - \ },\n {\n \"code\": \"4\",\n \"count\": - 732,\n \"name\": \"Computer Software\",\n \"selected\": - false\n },\n {\n \"code\": \"3\",\n \"count\": - 313,\n \"name\": \"Computer Hardware\",\n \"selected\": - false\n },\n {\n \"code\": \"6\",\n \"count\": - 295,\n \"name\": \"Internet\",\n \"selected\": false\n - \ },\n {\n \"code\": \"80\",\n \"count\": - 219,\n \"name\": \"Marketing and Advertising\",\n \"selected\": - false\n },\n {\n \"code\": \"24\",\n \"count\": - 166,\n \"name\": \"Consumer Electronics\",\n \"selected\": - false\n },\n {\n \"code\": \"27\",\n \"count\": - 142,\n \"name\": \"Retail\",\n \"selected\": false\n },\n - \ {\n \"code\": \"109\",\n \"count\": 123,\n \"name\": - \"Computer Games\",\n \"selected\": false\n },\n {\n - \ \"code\": \"126\",\n \"count\": 120,\n \"name\": - \"Media Production\",\n \"selected\": false\n },\n {\n - \ \"code\": \"99\",\n \"count\": 117,\n \"name\": - \"Design\",\n \"selected\": false\n }\n ]\n },\n - \ \"code\": \"industry\",\n \"name\": \"Industry\"\n }]\n },\n - \ \"numResults\": 5696\n}" - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_facets_to_return/should_return_a_facet.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_facets_to_return/should_return_a_facet.yml new file mode 100644 index 00000000..9d9a5139 --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_facets_to_return/should_return_a_facet.yml @@ -0,0 +1,80 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/company-search?facets=industry&keywords=apple + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="FU07WVy5LyepRG8O99eNUI0fqIxdghVO9gXhSQAOA", + oauth_signature="51O%2BsP4hpjq93vwrFm2zrox0xfI%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631653", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + User-Agent: + - OAuth gem v0.4.7 + response: + status: + code: 200 + message: OK + headers: + X-Li-Request-Id: + - G21FIZ5M8V + X-Li-Format: + - json + Date: + - Wed, 10 Apr 2013 22:07:33 GMT + Vary: + - ! '*' + Server: + - Apache-Coyote/1.1 + Content-Type: + - application/json;charset=UTF-8 + Transfer-Encoding: + - chunked + body: + encoding: UTF-8 + string: ! "{\n \"companies\": {\n \"_count\": 10,\n \"_start\": 0,\n + \"_total\": 8450,\n \"values\": [\n {\n \"id\": 162479,\n + \"name\": \"Apple\"\n },\n {\n \"id\": 19271,\n \"name\": + \"Apple Vacations\"\n },\n {\n \"id\": 778626,\n \"name\": + \"Big Apple Holdings, Inc. dba Big Apple International Realty\"\n },\n + {\n \"id\": 112136,\n \"name\": \"Apple & Associates\"\n + },\n {\n \"id\": 772044,\n \"name\": \"Stone Apple + Solutions\"\n },\n {\n \"id\": 2135525,\n \"name\": + \"iSquare - Apple Authorized Distributor in Greece & Cyprus\"\n },\n + {\n \"id\": 2303504,\n \"name\": \"Filex Apple Store & + Support\"\n },\n {\n \"id\": 2419290,\n \"name\": + \"Apple Nieuws Vlaanderen\"\n },\n {\n \"id\": 2260437,\n + \"name\": \"OGGO - Services Apple Macintosh\"\n },\n {\n + \"id\": 1049054,\n \"name\": \"Apple Crumble\"\n }\n ]\n + },\n \"facets\": {\n \"_total\": 1,\n \"values\": [{\n \"buckets\":{\n + \"_total\": 10,\n \"values\": [\n {\n \"code\": + \"96\",\n \"count\": 2062,\n \"name\": \"Information + Technology and Services\",\n \"selected\": false\n },\n + {\n \"code\": \"4\",\n \"count\": 1031,\n + \"name\": \"Computer Software\",\n \"selected\": false\n + },\n {\n \"code\": \"6\",\n \"count\": + 472,\n \"name\": \"Internet\",\n \"selected\": false\n + },\n {\n \"code\": \"3\",\n \"count\": + 415,\n \"name\": \"Computer Hardware\",\n \"selected\": + false\n },\n {\n \"code\": \"80\",\n \"count\": + 348,\n \"name\": \"Marketing and Advertising\",\n \"selected\": + false\n },\n {\n \"code\": \"24\",\n \"count\": + 312,\n \"name\": \"Consumer Electronics\",\n \"selected\": + false\n },\n {\n \"code\": \"27\",\n \"count\": + 206,\n \"name\": \"Retail\",\n \"selected\": false\n + },\n {\n \"code\": \"109\",\n \"count\": + 185,\n \"name\": \"Computer Games\",\n \"selected\": + false\n },\n {\n \"code\": \"8\",\n \"count\": + 171,\n \"name\": \"Telecommunications\",\n \"selected\": + false\n },\n {\n \"code\": \"126\",\n \"count\": + 164,\n \"name\": \"Media Production\",\n \"selected\": + false\n }\n ]\n },\n \"code\": \"industry\",\n \"name\": + \"Industry\"\n }]\n },\n \"numResults\": 8450\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_pagination.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_pagination.yml deleted file mode 100644 index c2f85de1..00000000 --- a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_pagination.yml +++ /dev/null @@ -1,66 +0,0 @@ ---- -- !ruby/struct:VCR::HTTPInteraction - request: !ruby/struct:VCR::Request - method: :get - uri: https://api.linkedin.com:443/v1/company-search?count=5&keywords=apple&start=5 - body: - headers: - x-li-format: - - json - user-agent: - - OAuth gem v0.4.5 - authorization: - - OAuth oauth_consumer_key="n22cs9eyo36s", oauth_nonce="ijlM2rk0lIDFQSvHgwegzYK3BlzbB4bywFyygdPsJA", - oauth_signature="roxP%2BA3I%2F8PlBub%2B%2BqSF%2FBp3EqU%3D", oauth_signature_method="HMAC-SHA1", - oauth_timestamp="1329992230", oauth_token="a39e395e-bc38-4d5b-ae3b-52f840f821e9", - oauth_version="1.0" - response: !ruby/struct:VCR::Response - status: !ruby/struct:VCR::ResponseStatus - code: 200 - message: OK - headers: - server: - - Apache-Coyote/1.1 - x-li-request-id: - - 7Y7WOBATID - vary: - - ! '*' - x-li-format: - - json - content-type: - - application/json;charset=UTF-8 - transfer-encoding: - - chunked - date: - - Thu, 23 Feb 2012 10:17:13 GMT - body: ! "{\n \"companies\": {\n \"_count\": 5,\n \"_start\": 5,\n \"_total\": - 5696,\n \"values\": [\n {\n \"id\": 19271,\n \"name\": - \"Apple Vacations\"\n },\n {\n \"id\": 163801,\n \"name\": - \"FileMaker\"\n },\n {\n \"id\": 21482,\n \"name\": - \"GHA Technologies\"\n },\n {\n \"id\": 112136,\n \"name\": - \"Apple & Associates\"\n },\n {\n \"id\": 15552,\n \"name\": - \"Micro Center\"\n }\n ]\n },\n \"facets\": {\n \"_total\": 1,\n - \ \"values\": [{\n \"buckets\": {\n \"_total\": 10,\n \"values\": - [\n {\n \"code\": \"us:0\",\n \"count\": 1836,\n - \ \"name\": \"United States\",\n \"selected\": false\n - \ },\n {\n \"code\": \"gb:0\",\n \"count\": - 491,\n \"name\": \"United Kingdom\",\n \"selected\": false\n - \ },\n {\n \"code\": \"us:84\",\n \"count\": - 237,\n \"name\": \"San Francisco Bay Area\",\n \"selected\": - false\n },\n {\n \"code\": \"nl:0\",\n \"count\": - 227,\n \"name\": \"Netherlands\",\n \"selected\": false\n - \ },\n {\n \"code\": \"us:70\",\n \"count\": - 208,\n \"name\": \"Greater New York City Area\",\n \"selected\": - false\n },\n {\n \"code\": \"ca:0\",\n \"count\": - 199,\n \"name\": \"Canada\",\n \"selected\": false\n },\n - \ {\n \"code\": \"au:0\",\n \"count\": 130,\n - \ \"name\": \"Australia\",\n \"selected\": false\n },\n - \ {\n \"code\": \"us:49\",\n \"count\": 130,\n - \ \"name\": \"Greater Los Angeles Area\",\n \"selected\": - false\n },\n {\n \"code\": \"in:0\",\n \"count\": - 121,\n \"name\": \"India\",\n \"selected\": false\n },\n - \ {\n \"code\": \"it:0\",\n \"count\": 121,\n - \ \"name\": \"Italy\",\n \"selected\": false\n }\n - \ ]\n },\n \"code\": \"location\",\n \"name\": \"Location\"\n - \ }]\n },\n \"numResults\": 5696\n}" - http_version: '1.1' diff --git a/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_pagination/should_perform_a_search.yml b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_pagination/should_perform_a_search.yml new file mode 100644 index 00000000..f1a9f5ad --- /dev/null +++ b/spec/fixtures/cassette_library/LinkedIn_Search/_search_company/by_single_keywords_option_with_pagination/should_perform_a_search.yml @@ -0,0 +1,74 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.linkedin.com/v1/company-search?count=5&keywords=apple&start=5 + body: + encoding: US-ASCII + string: '' + headers: + X-Li-Format: + - json + Authorization: + - OAuth oauth_consumer_key="mpibxdpwbwry", oauth_nonce="UCRIU2SBembgaUTMw9aBAK0tCDnDuxPG4GzClCmcVQ", + oauth_signature="46tFOgfxDKiVNID1XIHrpoAs7zA%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1365631654", oauth_token="d9f69cd6-f3f3-4c26-9f2c-12cd8e228089", + oauth_version="1.0" + User-Agent: + - OAuth gem v0.4.7 + response: + status: + code: 200 + message: OK + headers: + X-Li-Request-Id: + - YMZX3QW2A1 + X-Li-Format: + - json + Date: + - Wed, 10 Apr 2013 22:07:33 GMT + Vary: + - ! '*' + Server: + - Apache-Coyote/1.1 + Content-Type: + - application/json;charset=UTF-8 + Transfer-Encoding: + - chunked + body: + encoding: UTF-8 + string: ! "{\n \"companies\": {\n \"_count\": 5,\n \"_start\": 5,\n \"_total\": + 8450,\n \"values\": [\n {\n \"id\": 2135525,\n \"name\": + \"iSquare - Apple Authorized Distributor in Greece & Cyprus\"\n },\n + {\n \"id\": 2303504,\n \"name\": \"Filex Apple Store & + Support\"\n },\n {\n \"id\": 2419290,\n \"name\": + \"Apple Nieuws Vlaanderen\"\n },\n {\n \"id\": 2260437,\n + \"name\": \"OGGO - Services Apple Macintosh\"\n },\n {\n + \"id\": 1049054,\n \"name\": \"Apple Crumble\"\n }\n ]\n + },\n \"facets\": {\n \"_total\": 1,\n \"values\": [{\n \"buckets\":{\n + \"_total\": 10,\n \"values\": [\n {\n \"code\": + \"us:0\",\n \"count\": 2511,\n \"name\": \"United States\",\n + \"selected\": false\n },\n {\n \"code\": + \"gb:0\",\n \"count\": 702,\n \"name\": \"United Kingdom\",\n + \"selected\": false\n },\n {\n \"code\": + \"us:84\",\n \"count\": 322,\n \"name\": \"San Francisco + Bay Area\",\n \"selected\": false\n },\n {\n + \"code\": \"us:70\",\n \"count\": 285,\n \"name\": + \"Greater New York City Area\",\n \"selected\": false\n },\n + {\n \"code\": \"nl:0\",\n \"count\": 284,\n + \"name\": \"Netherlands\",\n \"selected\": false\n + },\n {\n \"code\": \"ca:0\",\n \"count\": + 266,\n \"name\": \"Canada\",\n \"selected\": false\n + },\n {\n \"code\": \"au:0\",\n \"count\": + 195,\n \"name\": \"Australia\",\n \"selected\": false\n + },\n {\n \"code\": \"in:0\",\n \"count\": + 186,\n \"name\": \"India\",\n \"selected\": false\n + },\n {\n \"code\": \"it:0\",\n \"count\": + 177,\n \"name\": \"Italy\",\n \"selected\": false\n + },\n {\n \"code\": \"us:49\",\n \"count\": + 173,\n \"name\": \"Greater Los Angeles Area\",\n \"selected\": + false\n }\n ]\n },\n \"code\": \"location\",\n \"name\": + \"Location\"\n }]\n },\n \"numResults\": 8450\n}" + http_version: '1.1' + recorded_at: Tue, 04 Jun 2013 03:42:37 GMT +recorded_with: VCR 2.5.0 diff --git a/spec/helper.rb b/spec/helper.rb index b1fa2e17..b0765d65 100644 --- a/spec/helper.rb +++ b/spec/helper.rb @@ -1,21 +1,25 @@ $:.unshift File.expand_path('..', __FILE__) $:.unshift File.expand_path('../../lib', __FILE__) -require 'simplecov' -SimpleCov.start +if ENV['COVERAGE'] == 't' + require 'simplecov' + SimpleCov.start +end + require 'linkedin' require 'rspec' require 'webmock/rspec' require 'vcr' -VCR.config do |c| +VCR.configure do |c| c.cassette_library_dir = 'spec/fixtures/cassette_library' - c.stub_with :webmock + c.hook_into :webmock c.ignore_localhost = true c.default_cassette_options = { :record => :none } + c.configure_rspec_metadata! end RSpec.configure do |c| - c.extend VCR::RSpec::Macros + c.treat_symbols_as_metadata_keys_with_true_values = true end def linkedin_url(url)