xing_api_client 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +76 -0
- data/Guardfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +239 -0
- data/Rakefile +1 -0
- data/config.yml.sample +7 -0
- data/lib/xing_api_client/call/base.rb +23 -0
- data/lib/xing_api_client/call/registry.rb +22 -0
- data/lib/xing_api_client/call/users_bookmarks_call.rb +36 -0
- data/lib/xing_api_client/call/users_call.rb +11 -0
- data/lib/xing_api_client/call/users_contact_requests_call.rb +41 -0
- data/lib/xing_api_client/call/users_contacts_call.rb +25 -0
- data/lib/xing_api_client/call/users_contacts_shared_call.rb +24 -0
- data/lib/xing_api_client/call/users_contacts_tags_call.rb +14 -0
- data/lib/xing_api_client/call/users_find_by_emails_call.rb +21 -0
- data/lib/xing_api_client/call/users_me_id_card_call.rb +9 -0
- data/lib/xing_api_client/call/users_network_paths_call.rb +18 -0
- data/lib/xing_api_client/call/users_profile_message_call.rb +22 -0
- data/lib/xing_api_client/call.rb +12 -0
- data/lib/xing_api_client/config.rb +38 -0
- data/lib/xing_api_client/object/address.rb +8 -0
- data/lib/xing_api_client/object/base.rb +23 -0
- data/lib/xing_api_client/object/company.rb +15 -0
- data/lib/xing_api_client/object/school.rb +15 -0
- data/lib/xing_api_client/object/user.rb +29 -0
- data/lib/xing_api_client/object/year_month.rb +28 -0
- data/lib/xing_api_client/object.rb +11 -0
- data/lib/xing_api_client/request/error.rb +23 -0
- data/lib/xing_api_client/request.rb +85 -0
- data/lib/xing_api_client/version.rb +3 -0
- data/lib/xing_api_client.rb +54 -0
- data/spec/spec_helper.rb +107 -0
- data/spec/xing_api_client/call/users_bookmarks_call_spec.rb +103 -0
- data/spec/xing_api_client/call/users_call_spec.rb +41 -0
- data/spec/xing_api_client/call/users_contact_requests_call_spec.rb +130 -0
- data/spec/xing_api_client/call/users_contacts_call_spec.rb +45 -0
- data/spec/xing_api_client/call/users_contacts_shared_call_spec.rb +45 -0
- data/spec/xing_api_client/call/users_contacts_tags_call_spec.rb +20 -0
- data/spec/xing_api_client/call/users_find_by_emails_call_spec.rb +37 -0
- data/spec/xing_api_client/call/users_me_id_card_call_spec.rb +19 -0
- data/spec/xing_api_client/call/users_network_paths_call_spec.rb +37 -0
- data/spec/xing_api_client/call/users_profile_message_call_spec.rb +63 -0
- data/spec/xing_api_client/config_spec.rb +67 -0
- data/spec/xing_api_client/object/user_spec.rb +37 -0
- data/spec/xing_api_client/object/year_month_spec.rb +70 -0
- data/spec/xing_api_client/request/error_spec.rb +15 -0
- data/spec/xing_api_client/request_spec.rb +70 -0
- data/spec/xing_api_client_spec.rb +51 -0
- data/xing_api_client.gemspec +26 -0
- metadata +227 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
class XingApiClient
|
2
|
+
module Config
|
3
|
+
DEFAULT_SETTINGS = {
|
4
|
+
host: 'https://api.xing.com',
|
5
|
+
request_token_path: '/v1/request_token',
|
6
|
+
authorize_path: '/v1/authorize',
|
7
|
+
access_token_path: '/v1/access_token',
|
8
|
+
consumer_key: nil,
|
9
|
+
consumer_secret: nil,
|
10
|
+
callback_url: nil
|
11
|
+
}
|
12
|
+
|
13
|
+
@settings = ::OpenStruct.new(DEFAULT_SETTINGS)
|
14
|
+
|
15
|
+
def self.set(hash)
|
16
|
+
@settings = ::OpenStruct.new(DEFAULT_SETTINGS.merge(hash))
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.load_file(path)
|
20
|
+
set YAML.load_file(path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.load_env(prefix = nil)
|
24
|
+
prefix ||= self.to_s.split('::').first.upcase
|
25
|
+
|
26
|
+
hash = {}
|
27
|
+
DEFAULT_SETTINGS.keys.each do |key|
|
28
|
+
hash[key] = ENV["#{prefix}_#{key.upcase}"] || DEFAULT_SETTINGS[key]
|
29
|
+
end
|
30
|
+
set hash
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def config
|
35
|
+
XingApiClient::Config.instance_variable_get('@settings')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class XingApiClient
|
2
|
+
class Object
|
3
|
+
module Base
|
4
|
+
def initialize(data)
|
5
|
+
@data = data.with_indifferent_access
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_missing(method_name, *args, &block)
|
9
|
+
if @data.has_key? method_name
|
10
|
+
eigenclass = class << self; self; end
|
11
|
+
eigenclass.class_eval do
|
12
|
+
define_method(method_name) do
|
13
|
+
@data[method_name]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
send(method_name, *args, &block)
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class XingApiClient
|
2
|
+
class Object
|
3
|
+
class Company
|
4
|
+
include Base
|
5
|
+
|
6
|
+
def begin_date
|
7
|
+
@begin_date ||= XingApiClient::Object::YearMonth.new(@data['begin_date'])
|
8
|
+
end
|
9
|
+
|
10
|
+
def end_date
|
11
|
+
@end_date ||= XingApiClient::Object::YearMonth.new(@data['end_date'])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class XingApiClient
|
2
|
+
class Object
|
3
|
+
class School
|
4
|
+
include Base
|
5
|
+
|
6
|
+
def begin_date
|
7
|
+
@begin_date ||= XingApiClient::Object::YearMonth.new(@data['begin_date'])
|
8
|
+
end
|
9
|
+
|
10
|
+
def end_date
|
11
|
+
@end_date ||= XingApiClient::Object::YearMonth.new(@data['end_date'])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class XingApiClient
|
2
|
+
class Object
|
3
|
+
class User
|
4
|
+
include Base
|
5
|
+
AVAILABLE_FIELDS = ["id", "first_name", "last_name", "display_name", "page_name", "employment_status", "gender", "birth_date", "active_email", "time_zone", "premium_services", "badges", "wants", "haves", "interests", "organisation_member", "languages", "private_address", "business_address", "web_profiles", "instant_messaging_accounts", "professional_experience", "educational_background", "photo_urls", "permalink"]
|
6
|
+
|
7
|
+
def private_address
|
8
|
+
@private_address ||= XingApiClient::Object::Address.new(@data['private_address'])
|
9
|
+
end
|
10
|
+
|
11
|
+
def business_address
|
12
|
+
@business_address ||= XingApiClient::Object::Address.new(@data['business_address'])
|
13
|
+
end
|
14
|
+
|
15
|
+
def professional_experience
|
16
|
+
@professional_experience ||= begin
|
17
|
+
[XingApiClient::Object::Company.new(@data['professional_experience']['primary_company'])] +
|
18
|
+
@data['professional_experience']['non_primary_companies'].map{ |c| XingApiClient::Object::Company.new(c)}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def birth_date
|
23
|
+
h = @data['birth_date']
|
24
|
+
|
25
|
+
Date.parse [h['year'],h['month'],h['day']].join('-') rescue nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class XingApiClient
|
2
|
+
class Object
|
3
|
+
class YearMonth
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
attr_accessor :year, :month
|
7
|
+
|
8
|
+
def initialize(value)
|
9
|
+
@value = value
|
10
|
+
self.year, self.month = @value.to_s.split('-').map{ |s| s.to_i if s}
|
11
|
+
end
|
12
|
+
|
13
|
+
def <=>(an_other)
|
14
|
+
to_date <=> an_other.to_date
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_date
|
18
|
+
if year.nil?
|
19
|
+
Date.new
|
20
|
+
elsif month.nil?
|
21
|
+
Date.parse("#{year}-1-1")
|
22
|
+
else
|
23
|
+
Date.parse("#{year}-#{month}-1")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'xing_api_client/object/base'
|
2
|
+
require 'xing_api_client/object/user'
|
3
|
+
require 'xing_api_client/object/address'
|
4
|
+
require 'xing_api_client/object/company'
|
5
|
+
require 'xing_api_client/object/school'
|
6
|
+
require 'xing_api_client/object/year_month'
|
7
|
+
|
8
|
+
class XingApiClient
|
9
|
+
class Object
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class XingApiClient
|
2
|
+
class Request
|
3
|
+
class Error < StandardError
|
4
|
+
attr_accessor :code, :api_name, :response
|
5
|
+
|
6
|
+
def initialize(code, api_name, response)
|
7
|
+
@code = code
|
8
|
+
@api_name = api_name
|
9
|
+
@response = response
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
[code, response.inspect].join(' - ')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class InvalidParametersError < Error; end
|
18
|
+
class InvalidOauthTokenError < Error; end
|
19
|
+
class ThrottlingError < Error; end
|
20
|
+
class ResourceNotFoundError < Error; end
|
21
|
+
class AccessDeniedError < Error; end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
class XingApiClient
|
2
|
+
class Request
|
3
|
+
require 'xing_api_client/request/error'
|
4
|
+
require 'parallel'
|
5
|
+
include Config
|
6
|
+
include XingApiClient::Call
|
7
|
+
|
8
|
+
ERROR_CLASSES = {
|
9
|
+
'INVALID_PARAMETERS' => InvalidParametersError,
|
10
|
+
'INVALID_OAUTH_TOKEN' => InvalidOauthTokenError,
|
11
|
+
'RATE_LIMIT_EXCEEDED' => ThrottlingError,
|
12
|
+
'USER_NOT_FOUND' => ResourceNotFoundError,
|
13
|
+
403 => AccessDeniedError,
|
14
|
+
404 => ResourceNotFoundError
|
15
|
+
}
|
16
|
+
|
17
|
+
def initialize(consumer_token)
|
18
|
+
@consumer_token = consumer_token
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
attr_reader :consumer_token
|
23
|
+
|
24
|
+
def map_user(data)
|
25
|
+
XingApiClient::Object::User.new data
|
26
|
+
end
|
27
|
+
|
28
|
+
def make_request!(verb, url, params = nil, options = {})
|
29
|
+
options = { array_keys: [], allowed_codes: [200] }.merge(options)
|
30
|
+
url = [config.host, url].join('/')
|
31
|
+
request_params = add_default_values(params)
|
32
|
+
|
33
|
+
result = if verb != :post
|
34
|
+
consumer_token.request(verb, url + generate_url_params(request_params))
|
35
|
+
else
|
36
|
+
consumer_token.request(verb, url, request_params)
|
37
|
+
end
|
38
|
+
|
39
|
+
code = result.code.to_i
|
40
|
+
|
41
|
+
data = unless result.body.nil?
|
42
|
+
if options[:content_type] == 'text'
|
43
|
+
result.body
|
44
|
+
else
|
45
|
+
JSON.parse(result.body)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
handle_error!(code, data) if not Array(options[:allowed_codes]).include?(code)
|
50
|
+
|
51
|
+
Array(options[:array_keys]).each { |key| data = data[key] }
|
52
|
+
|
53
|
+
data
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_url_params(params)
|
57
|
+
'?' + params.to_a.map{ |key, value| "#{key}=#{CGI.escape(value.to_s)}"}.join('&')
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_default_values(params)
|
61
|
+
return {} if params.nil? || params.empty?
|
62
|
+
|
63
|
+
{}.tap do |result|
|
64
|
+
params.each_pair do |key, value|
|
65
|
+
value = case key
|
66
|
+
when :offset
|
67
|
+
value.to_i
|
68
|
+
when :user_fields
|
69
|
+
value || XingApiClient::Object::User::AVAILABLE_FIELDS.join(',')
|
70
|
+
else
|
71
|
+
value
|
72
|
+
end
|
73
|
+
|
74
|
+
result[key] = value
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def handle_error!(code, data)
|
80
|
+
error_class = ERROR_CLASSES[data.nil? ? code : data['error_name']] || Error
|
81
|
+
|
82
|
+
raise error_class.new(code, data['error_name'], data)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "oauth"
|
2
|
+
require 'json'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'yaml'
|
5
|
+
require 'ostruct'
|
6
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
7
|
+
%w{ version config object call request}.each{ |name| require "xing_api_client/#{name}"}
|
8
|
+
|
9
|
+
class XingApiClient
|
10
|
+
include Config
|
11
|
+
extend Config
|
12
|
+
|
13
|
+
def initialize(access_token, secret, options = {})
|
14
|
+
@access_token = access_token
|
15
|
+
@secret = secret
|
16
|
+
@consumer = self.class.consumer(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.request_params
|
20
|
+
oauth_params = {}
|
21
|
+
oauth_params.merge!(oauth_callback: config.callback_url) if config.callback_url
|
22
|
+
|
23
|
+
token = consumer.get_request_token(oauth_params)
|
24
|
+
|
25
|
+
{ request_token: token, auth_url: token.authorize_url }
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.authorize(token, pin)
|
29
|
+
access_token = token.get_access_token(oauth_verifier: pin)
|
30
|
+
|
31
|
+
{ access_token: access_token.token, secret: access_token.secret }
|
32
|
+
end
|
33
|
+
|
34
|
+
def request
|
35
|
+
Request.new(consumer_token)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.consumer(options = {})
|
39
|
+
consumer_key = options[:consumer_key] || config.consumer_key
|
40
|
+
consumer_secret = options[:consumer_secret] || config.consumer_secret
|
41
|
+
|
42
|
+
::OAuth::Consumer.new(consumer_key, consumer_secret, {
|
43
|
+
:site => config.host,
|
44
|
+
:request_token_path => config.request_token_path,
|
45
|
+
:authorize_path => config.authorize_path,
|
46
|
+
:access_token_path => config.access_token_path
|
47
|
+
})
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def consumer_token
|
52
|
+
OAuth::ConsumerToken.new(@consumer, @access_token, @secret)
|
53
|
+
end
|
54
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
5
|
+
require 'xing_api_client'
|
6
|
+
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
# some (optional) config here
|
10
|
+
end
|
11
|
+
|
12
|
+
XingApiClient::Object::User::EXAMPLE_RESPONSE = {
|
13
|
+
"users" => [
|
14
|
+
{
|
15
|
+
"id" => "13802856_c7551a",
|
16
|
+
"first_name" => "Firstname",
|
17
|
+
"last_name" => "Lastname",
|
18
|
+
"display_name" => "Firstname Lastname",
|
19
|
+
"page_name" => "Firstname_Lastname8",
|
20
|
+
"employment_status" => "EMPLOYEE",
|
21
|
+
"gender" => "m",
|
22
|
+
"birth_date" => {
|
23
|
+
"day" => 3,
|
24
|
+
"month" => 1,
|
25
|
+
"year" => 1983
|
26
|
+
},
|
27
|
+
"active_email" => "somemailaddress@gmail.com",
|
28
|
+
"time_zone" => {
|
29
|
+
"utc_offset" => 2,
|
30
|
+
"name" => "Europe/Berlin"
|
31
|
+
},
|
32
|
+
"premium_services" => [
|
33
|
+
"SEARCH",
|
34
|
+
"PRIVATEMESSAGES"
|
35
|
+
],
|
36
|
+
"badges" => [
|
37
|
+
"PREMIUM",
|
38
|
+
"MODERATOR"
|
39
|
+
],
|
40
|
+
"wants" => "new gems, cool rails stuff, pizza",
|
41
|
+
"haves" => "Jenkins CI, MySQL, REST, TDD, UML",
|
42
|
+
"interests" => "CSS, CoffeeScript, HTML5, Robotics, jQuery",
|
43
|
+
"organisation_member" => nil,
|
44
|
+
"languages" => {
|
45
|
+
"en" => "FLUENT",
|
46
|
+
"de" => "NATIVE"
|
47
|
+
},
|
48
|
+
"private_address" => {
|
49
|
+
"street" => "Somewhere Str. 85",
|
50
|
+
"zip_code" => "20756",
|
51
|
+
"city" => "Hamburg",
|
52
|
+
"province" => "Hamburg",
|
53
|
+
"country" => "DE",
|
54
|
+
"email" => "somemailaddress@gmail.com",
|
55
|
+
"phone" => nil,
|
56
|
+
"fax" => nil,
|
57
|
+
"mobile_phone" => "49|111|2222222222"
|
58
|
+
},
|
59
|
+
"business_address" => {
|
60
|
+
"street" => "Somewhere Str. 85",
|
61
|
+
"zip_code" => "20756",
|
62
|
+
"city" => "Hamburg",
|
63
|
+
"province" => "Hamburg",
|
64
|
+
"country" => "DE",
|
65
|
+
"email" => "somemailaddress@gmail.com",
|
66
|
+
"phone" => nil,
|
67
|
+
"fax" => nil,
|
68
|
+
"mobile_phone" => nil
|
69
|
+
},
|
70
|
+
"web_profiles" => {},
|
71
|
+
"instant_messaging_accounts" => {
|
72
|
+
"skype" => "username"
|
73
|
+
},
|
74
|
+
"professional_experience" => {
|
75
|
+
"primary_company" => {
|
76
|
+
"name" => "COMPANY AG",
|
77
|
+
"url" => "https://www.company.com",
|
78
|
+
"tag" => "COMPANYAG",
|
79
|
+
"company_size" => "501-1000",
|
80
|
+
"industry" => "INTERNET",
|
81
|
+
"title" => "Engineer",
|
82
|
+
"career_level" => nil,
|
83
|
+
"description" => "",
|
84
|
+
"begin_date" => "2013-04",
|
85
|
+
"end_date" => nil
|
86
|
+
},
|
87
|
+
"non_primary_companies" => [
|
88
|
+
],
|
89
|
+
"awards" => []
|
90
|
+
},
|
91
|
+
"educational_background" => {
|
92
|
+
"qualifications" => [
|
93
|
+
],
|
94
|
+
"schools" => [
|
95
|
+
]
|
96
|
+
},
|
97
|
+
"photo_urls" => {
|
98
|
+
"large" => "https://x1.xingassets.com/img/users/3/5/1/238ddffce.13802856,9.140x185.jpg",
|
99
|
+
"maxi_thumb" => "https://x1.xingassets.com/img/users/3/5/1/238ddffce.13802856,9.70x93.jpg",
|
100
|
+
"medium_thumb" => "https://x1.xingassets.com/img/users/3/5/1/238ddffce.13802856,9.57x75.jpg",
|
101
|
+
"mini_thumb" => "https://x1.xingassets.com/img/users/3/5/1/238ddffce.13802856,9.18x24.jpg",
|
102
|
+
"thumb" => "https://x1.xingassets.com/img/users/3/5/1/238ddffce.13802856,9.30x40.jpg"
|
103
|
+
},
|
104
|
+
"permalink" => "https://www.xing.com/profile/Firstname_Lastname8"
|
105
|
+
}
|
106
|
+
]
|
107
|
+
}
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe XingApiClient::Call::UsersBookmarksCall do
|
4
|
+
let(:call) { Object.new.tap{ |object| object.extend(XingApiClient::Call::UsersBookmarksCall) } }
|
5
|
+
|
6
|
+
describe '#get_users_bookmarks' do
|
7
|
+
context 'with no options' do
|
8
|
+
subject do
|
9
|
+
call.
|
10
|
+
should_receive(:make_request!).
|
11
|
+
with(:get, "v1/users/me/bookmarks", {limit: 100, offset: 0, user_fields: nil}, {array_keys: "bookmarks"}).
|
12
|
+
and_return("total" => 202, "items" => [{"id" => 1}])
|
13
|
+
call.
|
14
|
+
should_receive(:make_request!).
|
15
|
+
with(:get, "v1/users/me/bookmarks", {:limit=>100, :offset=>100, :user_fields=>nil}, {:array_keys=>["bookmarks", "items"]}).
|
16
|
+
and_return([{"id" => 2}])
|
17
|
+
call.
|
18
|
+
should_receive(:make_request!).
|
19
|
+
with(:get, "v1/users/me/bookmarks", {:limit=>100, :offset=>200, :user_fields=>nil}, {:array_keys=>["bookmarks", "items"]}).
|
20
|
+
and_return([{"id" => 3}])
|
21
|
+
|
22
|
+
call.get_users_bookmarks()
|
23
|
+
end
|
24
|
+
|
25
|
+
its(:size) { should == 3 }
|
26
|
+
its(:class) { should == Array }
|
27
|
+
its(:total) { should == 202 }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with all options' do
|
31
|
+
subject do
|
32
|
+
call.
|
33
|
+
should_receive(:make_request!).
|
34
|
+
with(:get, "v1/users/:user_id/bookmarks", {:limit=>13, :offset=>5, :user_fields=>[:id, :page_name]}, {:array_keys=>"bookmarks"}).
|
35
|
+
and_return("total" => 202, "items" => [{"id" => 1}])
|
36
|
+
|
37
|
+
|
38
|
+
call.get_users_bookmarks(id: ':user_id', offset: 5, limit: 13, fields: [:id, :page_name])
|
39
|
+
end
|
40
|
+
|
41
|
+
its(:size) { should == 1 }
|
42
|
+
its(:class) { should == Array }
|
43
|
+
its(:total) { should == 202 }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#put_users_bookmarks' do
|
48
|
+
context 'with no options' do
|
49
|
+
subject do
|
50
|
+
call.
|
51
|
+
should_receive(:make_request!).
|
52
|
+
with(:put, "v1/users/me/bookmarks/:bookmark_id", {}, {:allowed_codes=>204})
|
53
|
+
|
54
|
+
call.put_users_bookmarks(':bookmark_id')
|
55
|
+
end
|
56
|
+
|
57
|
+
its(:class) { should == NilClass }
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'with all options' do
|
61
|
+
subject do
|
62
|
+
call.
|
63
|
+
should_receive(:make_request!).
|
64
|
+
with(:put, "v1/users/:user_id/bookmarks/:bookmark_id", {}, {:allowed_codes=>204})
|
65
|
+
|
66
|
+
call.put_users_bookmarks(':bookmark_id', id: ':user_id')
|
67
|
+
end
|
68
|
+
|
69
|
+
its(:class) { should == NilClass }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '#delete_users_bookmarks' do
|
74
|
+
context 'with no options' do
|
75
|
+
subject do
|
76
|
+
call.
|
77
|
+
should_receive(:make_request!).
|
78
|
+
with(:delete, "v1/users/me/bookmarks/:bookmark_id", {}, {:allowed_codes=>204})
|
79
|
+
|
80
|
+
call.delete_users_bookmarks(':bookmark_id')
|
81
|
+
end
|
82
|
+
|
83
|
+
its(:class) { should == NilClass }
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'with all options' do
|
87
|
+
subject do
|
88
|
+
call.
|
89
|
+
should_receive(:make_request!).
|
90
|
+
with(:delete, "v1/users/:user_id/bookmarks/:bookmark_id", {}, {:allowed_codes=>204})
|
91
|
+
|
92
|
+
call.delete_users_bookmarks(':bookmark_id', id: ':user_id')
|
93
|
+
end
|
94
|
+
|
95
|
+
its(:class) { should == NilClass }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe XingApiClient::Call::UsersCall do
|
4
|
+
let(:call) { Object.new.tap{ |object| object.extend(XingApiClient::Call::UsersCall) } }
|
5
|
+
|
6
|
+
describe '#get_users' do
|
7
|
+
context 'with no options' do
|
8
|
+
subject do
|
9
|
+
call.
|
10
|
+
should_receive(:make_request!).
|
11
|
+
with(:get, "v1/users/me", {}, {:array_keys=>"users"}).
|
12
|
+
and_return([{'id' => ':user_id'}])
|
13
|
+
|
14
|
+
call.get_users()
|
15
|
+
end
|
16
|
+
|
17
|
+
its(:class) { should == Hash }
|
18
|
+
its(:keys) { should == ['id'] }
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with all options' do
|
22
|
+
subject do
|
23
|
+
call.
|
24
|
+
should_receive(:make_request!).
|
25
|
+
with(:get, "v1/users/:user_id", {}, {:array_keys=>"users"}).
|
26
|
+
and_return([{'id' => ':user_id'}])
|
27
|
+
|
28
|
+
|
29
|
+
call.get_users(id: ':user_id')
|
30
|
+
end
|
31
|
+
|
32
|
+
its(:class) { should == Hash }
|
33
|
+
its(:keys) { should == ['id'] }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|