slayer-rpx_now 0.6.24
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/CHANGELOG +38 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +28 -0
- data/MIGRATION +9 -0
- data/Rakefile +22 -0
- data/Readme.md +165 -0
- data/VERSION +1 -0
- data/certs/ssl_cert.pem +3154 -0
- data/init.rb +2 -0
- data/lib/rpx_now/api.rb +75 -0
- data/lib/rpx_now/contacts_collection.rb +20 -0
- data/lib/rpx_now/user_integration.rb +9 -0
- data/lib/rpx_now/user_proxy.rb +19 -0
- data/lib/rpx_now.rb +201 -0
- data/rpx_now.gemspec +63 -0
- data/spec/fixtures/get_contacts_response.json +58 -0
- data/spec/integration/mapping_spec.rb +40 -0
- data/spec/rpx_now/api_spec.rb +50 -0
- data/spec/rpx_now/contacts_collection_spec.rb +32 -0
- data/spec/rpx_now/user_proxy_spec.rb +33 -0
- data/spec/rpx_now_spec.rb +414 -0
- data/spec/spec_helper.rb +16 -0
- metadata +107 -0
data/init.rb
ADDED
data/lib/rpx_now/api.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module RPXNow
|
6
|
+
# low-level interaction with rpxnow.com api
|
7
|
+
# - send requests
|
8
|
+
# - parse response
|
9
|
+
# - handle server errors
|
10
|
+
class Api
|
11
|
+
SSL_CERT = File.join(File.dirname(__FILE__), '..', '..', 'certs', 'ssl_cert.pem')
|
12
|
+
|
13
|
+
def self.call(method, data)
|
14
|
+
data = data.dup
|
15
|
+
version = RPXNow.extract_version(data)
|
16
|
+
data.delete(:api_version)
|
17
|
+
|
18
|
+
path = "/api/v#{version}/#{method}"
|
19
|
+
response = request(path, {:apiKey => RPXNow.api_key}.merge(data))
|
20
|
+
parse_response(response)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.host(subdomain=nil)
|
24
|
+
if subdomain
|
25
|
+
"https://#{subdomain}.#{RPXNow.domain}"
|
26
|
+
else
|
27
|
+
"https://#{RPXNow.domain}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def self.request(path, data)
|
34
|
+
client.request(request_object(path, data))
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.request_object(path, data)
|
38
|
+
request = Net::HTTP::Post.new(path)
|
39
|
+
request.form_data = stringify_keys(data)
|
40
|
+
request
|
41
|
+
end
|
42
|
+
|
43
|
+
# symbol keys -> string keys
|
44
|
+
# because of ruby 1.9.x bug in Net::HTTP
|
45
|
+
# http://redmine.ruby-lang.org/issues/show/1351
|
46
|
+
def self.stringify_keys(hash)
|
47
|
+
hash.map{|k,v| [k.to_s,v]}
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.client
|
51
|
+
client = Net::HTTP.new(RPXNow.domain, 443)
|
52
|
+
client.use_ssl = true
|
53
|
+
client.ca_file = SSL_CERT
|
54
|
+
client.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
55
|
+
client.verify_depth = 5
|
56
|
+
client
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.parse_response(response)
|
60
|
+
if response.code.to_i >= 400
|
61
|
+
raise ServiceUnavailableError, "The RPX service is temporarily unavailable. (4XX)"
|
62
|
+
else
|
63
|
+
result = JSON.parse(response.body)
|
64
|
+
return result unless result['err']
|
65
|
+
|
66
|
+
code = result['err']['code']
|
67
|
+
if code == -1
|
68
|
+
raise ServiceUnavailableError, "The RPX service is temporarily unavailable."
|
69
|
+
else
|
70
|
+
raise ApiError, "Got error: #{result['err']['msg']} (code: #{code}), HTTP status: #{response.code}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RPXNow
|
2
|
+
# Makes returned contacts feel like a array
|
3
|
+
class ContactsCollection < Array
|
4
|
+
def initialize(list)
|
5
|
+
@raw = list
|
6
|
+
@additional_info = list.reject{|k,v|k=='entry'}
|
7
|
+
list['entry'].each{|item| self << parse_data(item)}
|
8
|
+
end
|
9
|
+
|
10
|
+
def additional_info;@additional_info;end
|
11
|
+
def raw;@raw;end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def parse_data(entry)
|
16
|
+
entry['emails'] = (entry['emails'] ? entry['emails'].map{|email| email['value']} : [])
|
17
|
+
entry
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RPXNow
|
2
|
+
class UserProxy
|
3
|
+
def initialize(id)
|
4
|
+
@id = id
|
5
|
+
end
|
6
|
+
|
7
|
+
def identifiers
|
8
|
+
RPXNow.mappings(@id)
|
9
|
+
end
|
10
|
+
|
11
|
+
def map(identifier)
|
12
|
+
RPXNow.map(identifier, @id)
|
13
|
+
end
|
14
|
+
|
15
|
+
def unmap(identifier)
|
16
|
+
RPXNow.unmap(identifier, @id)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/rpx_now.rb
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
require 'rpx_now/api'
|
2
|
+
require 'rpx_now/contacts_collection'
|
3
|
+
require 'cgi'
|
4
|
+
|
5
|
+
module RPXNow
|
6
|
+
extend self
|
7
|
+
|
8
|
+
attr_accessor :api_key
|
9
|
+
attr_accessor :api_version
|
10
|
+
attr_accessor :domain
|
11
|
+
|
12
|
+
self.api_version = 2
|
13
|
+
self.domain = 'rpxnow.com'
|
14
|
+
|
15
|
+
VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
|
16
|
+
|
17
|
+
# retrieve the users data
|
18
|
+
# - cleaned Hash
|
19
|
+
# - complete/unclean response when block was given user_data{|response| ...; return hash }
|
20
|
+
# - nil when token was invalid / data was not found
|
21
|
+
def user_data(token, options={})
|
22
|
+
options = options.dup
|
23
|
+
return_raw = options.delete(:raw_response)
|
24
|
+
|
25
|
+
data = begin
|
26
|
+
auth_info(token, options)
|
27
|
+
rescue ServerError
|
28
|
+
return nil if $!.to_s=~/Data not found/
|
29
|
+
raise
|
30
|
+
end
|
31
|
+
|
32
|
+
result = (block_given? ? yield(data) : (return_raw ? data : parse_user_data(data, options)))
|
33
|
+
with_indifferent_access(result)
|
34
|
+
end
|
35
|
+
|
36
|
+
# same data as user_data, but without any kind of post-processing
|
37
|
+
def auth_info(token, options={})
|
38
|
+
data = Api.call("auth_info", options.merge(:token => token))
|
39
|
+
with_indifferent_access(data)
|
40
|
+
end
|
41
|
+
|
42
|
+
# same as for auth_info if Offline Profile Access is enabled,
|
43
|
+
# but can be called at any time and does not need a token / does not expire
|
44
|
+
def get_user_data(identifier, options={})
|
45
|
+
data = Api.call("get_user_data", options.merge(:identifier => identifier))
|
46
|
+
with_indifferent_access(data)
|
47
|
+
end
|
48
|
+
|
49
|
+
# set the users status
|
50
|
+
def set_status(identifier, status, options={})
|
51
|
+
options = options.merge(:identifier => identifier, :status => status)
|
52
|
+
Api.call("set_status", options)
|
53
|
+
rescue ServerError
|
54
|
+
return nil if $!.to_s=~/Data not found/
|
55
|
+
raise
|
56
|
+
end
|
57
|
+
|
58
|
+
# Post an activity update to the user's activity stream.
|
59
|
+
# See more: https://rpxnow.com/docs#api_activity
|
60
|
+
def activity(identifier, activity_options, options={})
|
61
|
+
options = options.merge(:identifier => identifier, :activity => activity_options.to_json)
|
62
|
+
Api.call("activity", options)
|
63
|
+
end
|
64
|
+
|
65
|
+
# maps an identifier to an primary-key (e.g. user.id)
|
66
|
+
def map(identifier, primary_key, options={})
|
67
|
+
Api.call("map", options.merge(:identifier => identifier, :primaryKey => primary_key))
|
68
|
+
end
|
69
|
+
|
70
|
+
# un-maps an identifier to an primary-key (e.g. user.id)
|
71
|
+
def unmap(identifier, primary_key, options={})
|
72
|
+
Api.call("unmap", options.merge(:identifier => identifier, :primaryKey => primary_key))
|
73
|
+
end
|
74
|
+
|
75
|
+
# returns an array of identifiers which are mapped to one of your primary-keys (e.g. user.id)
|
76
|
+
def mappings(primary_key, options={})
|
77
|
+
Api.call("mappings", options.merge(:primaryKey => primary_key))['identifiers']
|
78
|
+
end
|
79
|
+
|
80
|
+
def all_mappings(options={})
|
81
|
+
Api.call("all_mappings", options)['mappings']
|
82
|
+
end
|
83
|
+
|
84
|
+
def contacts(identifier, options={})
|
85
|
+
data = Api.call("get_contacts", options.merge(:identifier => identifier))
|
86
|
+
RPXNow::ContactsCollection.new(data['response'])
|
87
|
+
end
|
88
|
+
alias get_contacts contacts
|
89
|
+
|
90
|
+
# embedded rpx login (via iframe)
|
91
|
+
# options: :width, :height, :language, :flags, :api_version, :default_provider
|
92
|
+
def embed_code(subdomain, url, options={})
|
93
|
+
options = {:width => '400', :height => '240'}.merge(options)
|
94
|
+
<<-EOF
|
95
|
+
<iframe src="#{Api.host(subdomain)}/openid/embed?#{embed_params(url, options)}"
|
96
|
+
scrolling="no" frameBorder="no" style="width:#{options[:width]}px;height:#{options[:height]}px;" id="rpx_now_embed" allowtransparency="allowtransparency">
|
97
|
+
</iframe>
|
98
|
+
EOF
|
99
|
+
end
|
100
|
+
|
101
|
+
# popup window for rpx login
|
102
|
+
# options: :language, :flags, :unobtrusive, :api_version, :default_provider, :html
|
103
|
+
def popup_code(text, subdomain, url, options = {})
|
104
|
+
if options[:unobtrusive]
|
105
|
+
unobtrusive_popup_code(text, subdomain, url, options)
|
106
|
+
else
|
107
|
+
obtrusive_popup_code(text, subdomain, url, options)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# javascript for popup
|
112
|
+
# only needed in combination with popup_code(x,y,z, :unobtrusive => true)
|
113
|
+
def popup_source(subdomain, url, options={})
|
114
|
+
<<-EOF
|
115
|
+
<script src="#{Api.host}/openid/v#{extract_version(options)}/widget" type="text/javascript"></script>
|
116
|
+
<script type="text/javascript">
|
117
|
+
//<![CDATA[
|
118
|
+
$(function () {
|
119
|
+
RPXNOW.token_url = '#{url}';
|
120
|
+
RPXNOW.realm = '#{subdomain}';
|
121
|
+
RPXNOW.overlay = true;
|
122
|
+
#{ "RPXNOW.language_preference = '#{options[:language]}';" if options[:language] }
|
123
|
+
#{ "RPXNOW.default_provider = '#{options[:default_provider]}';" if options[:default_provider] }
|
124
|
+
#{ "RPXNOW.flags = '#{options[:flags]}';" if options[:flags] }
|
125
|
+
});
|
126
|
+
//]]>
|
127
|
+
</script>
|
128
|
+
EOF
|
129
|
+
end
|
130
|
+
|
131
|
+
# url for unobtrusive popup window
|
132
|
+
# options: :language, :flags, :api_version, :default_provider
|
133
|
+
def popup_url(subdomain, url, options={})
|
134
|
+
"#{Api.host(subdomain)}/openid/v#{extract_version(options)}/signin?#{embed_params(url, options)}"
|
135
|
+
end
|
136
|
+
|
137
|
+
def extract_version(options)
|
138
|
+
options[:api_version] || api_version
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def self.embed_params(url, options)
|
144
|
+
{
|
145
|
+
:token_url => CGI::escape( url ),
|
146
|
+
:language_preference => options[:language],
|
147
|
+
:flags => options[:flags],
|
148
|
+
:default_provider => options[:default_provider]
|
149
|
+
}.map{|k,v| "#{k}=#{v}" if v}.compact.join('&')
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.parse_user_data(response, options)
|
153
|
+
user_data = response['profile']
|
154
|
+
data = {}
|
155
|
+
data[:identifier] = user_data['identifier']
|
156
|
+
data[:email] = user_data['verifiedEmail'] || user_data['email']
|
157
|
+
data[:username] = user_data['preferredUsername'] || data[:email].to_s.sub(/@.*/,'')
|
158
|
+
data[:name] = user_data['displayName'] || data[:username]
|
159
|
+
data[:id] = user_data['primaryKey'] unless user_data['primaryKey'].to_s.empty?
|
160
|
+
|
161
|
+
additional = (options[:additional] || [])
|
162
|
+
additional << :extended if options[:extended]
|
163
|
+
additional.each do |key|
|
164
|
+
data[key] = case key
|
165
|
+
when :raw
|
166
|
+
warn "RPXNow :raw is deprecated, please use :raw_response + e.g. data['raw_response']['profile']['verifiedEmail']"
|
167
|
+
user_data
|
168
|
+
when :raw_response
|
169
|
+
response
|
170
|
+
when :extended
|
171
|
+
response.reject{|k,v| ['profile','stat'].include?(k) }
|
172
|
+
else
|
173
|
+
user_data[key.to_s]
|
174
|
+
end
|
175
|
+
end
|
176
|
+
data
|
177
|
+
end
|
178
|
+
|
179
|
+
def unobtrusive_popup_code(text, subdomain, url, options={})
|
180
|
+
options = options.dup
|
181
|
+
html_options = options.delete(:html) || {}
|
182
|
+
html_options[:class] = "rpxnow #{html_options[:class]}".strip
|
183
|
+
html_options[:href] ||= popup_url(subdomain, url, options)
|
184
|
+
html_options = html_options.sort_by{|k,v|k.to_s}.map{|k,v| %{#{k}="#{v}"}}
|
185
|
+
|
186
|
+
%{<a #{html_options.join(' ')}>#{text}</a>}
|
187
|
+
end
|
188
|
+
|
189
|
+
def obtrusive_popup_code(text, subdomain, url, options = {})
|
190
|
+
unobtrusive_popup_code(text, subdomain, url, options) +
|
191
|
+
popup_source(subdomain, url, options)
|
192
|
+
end
|
193
|
+
|
194
|
+
def with_indifferent_access(hash)
|
195
|
+
hash.respond_to?(:with_indifferent_access) ? hash.with_indifferent_access : hash
|
196
|
+
end
|
197
|
+
|
198
|
+
class ServerError < RuntimeError; end #backwards compatibility / catch all
|
199
|
+
class ApiError < ServerError; end
|
200
|
+
class ServiceUnavailableError < ServerError; end
|
201
|
+
end
|
data/rpx_now.gemspec
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{rpx_now}
|
8
|
+
s.version = "0.6.24"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Michael Grosser"]
|
12
|
+
s.date = %q{2011-02-21}
|
13
|
+
s.email = %q{grosser.michael@gmail.com}
|
14
|
+
s.files = [
|
15
|
+
"CHANGELOG",
|
16
|
+
"Gemfile",
|
17
|
+
"Gemfile.lock",
|
18
|
+
"MIGRATION",
|
19
|
+
"Rakefile",
|
20
|
+
"Readme.md",
|
21
|
+
"VERSION",
|
22
|
+
"certs/ssl_cert.pem",
|
23
|
+
"init.rb",
|
24
|
+
"lib/rpx_now.rb",
|
25
|
+
"lib/rpx_now/api.rb",
|
26
|
+
"lib/rpx_now/contacts_collection.rb",
|
27
|
+
"lib/rpx_now/user_integration.rb",
|
28
|
+
"lib/rpx_now/user_proxy.rb",
|
29
|
+
"rpx_now.gemspec",
|
30
|
+
"spec/fixtures/get_contacts_response.json",
|
31
|
+
"spec/integration/mapping_spec.rb",
|
32
|
+
"spec/rpx_now/api_spec.rb",
|
33
|
+
"spec/rpx_now/contacts_collection_spec.rb",
|
34
|
+
"spec/rpx_now/user_proxy_spec.rb",
|
35
|
+
"spec/rpx_now_spec.rb",
|
36
|
+
"spec/spec_helper.rb"
|
37
|
+
]
|
38
|
+
s.homepage = %q{http://github.com/grosser/rpx_now}
|
39
|
+
s.require_paths = ["lib"]
|
40
|
+
s.rubygems_version = %q{1.4.2}
|
41
|
+
s.summary = %q{Helper to simplify RPX Now user login/creation}
|
42
|
+
s.test_files = [
|
43
|
+
"spec/integration/mapping_spec.rb",
|
44
|
+
"spec/rpx_now/api_spec.rb",
|
45
|
+
"spec/rpx_now/contacts_collection_spec.rb",
|
46
|
+
"spec/rpx_now/user_proxy_spec.rb",
|
47
|
+
"spec/rpx_now_spec.rb",
|
48
|
+
"spec/spec_helper.rb"
|
49
|
+
]
|
50
|
+
|
51
|
+
if s.respond_to? :specification_version then
|
52
|
+
s.specification_version = 3
|
53
|
+
|
54
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
55
|
+
s.add_runtime_dependency(%q<json_pure>, [">= 0"])
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<json_pure>, [">= 0"])
|
58
|
+
end
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<json_pure>, [">= 0"])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
{
|
2
|
+
"response": {
|
3
|
+
"itemsPerPage": 5,
|
4
|
+
"totalResults": 5,
|
5
|
+
"entry": [
|
6
|
+
{
|
7
|
+
"displayName": "Bob Johnson",
|
8
|
+
"emails": [
|
9
|
+
{
|
10
|
+
"type": "other",
|
11
|
+
"value": "bob@example.com"
|
12
|
+
}
|
13
|
+
]
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"displayName": "Cindy Smith",
|
17
|
+
"emails": [
|
18
|
+
{
|
19
|
+
"type": "other",
|
20
|
+
"value": "cindy.smith@example.com"
|
21
|
+
}
|
22
|
+
]
|
23
|
+
},
|
24
|
+
{
|
25
|
+
"displayName": "Fred Williams",
|
26
|
+
"emails": [
|
27
|
+
{
|
28
|
+
"type": "other",
|
29
|
+
"value": "fred.williams@example.com"
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"type": "other",
|
33
|
+
"value": "fred@example.com"
|
34
|
+
}
|
35
|
+
]
|
36
|
+
},
|
37
|
+
{
|
38
|
+
"emails": [
|
39
|
+
{
|
40
|
+
"type": "other",
|
41
|
+
"value": "j.lewis@example.com"
|
42
|
+
}
|
43
|
+
]
|
44
|
+
},
|
45
|
+
{
|
46
|
+
"displayName": "Mary Jones",
|
47
|
+
"emails": [
|
48
|
+
{
|
49
|
+
"type": "other",
|
50
|
+
"value": "mary.jones@example.com"
|
51
|
+
}
|
52
|
+
]
|
53
|
+
}
|
54
|
+
],
|
55
|
+
"startIndex": 1
|
56
|
+
},
|
57
|
+
"stat": "ok"
|
58
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe RPXNow do
|
4
|
+
describe :mapping_integration do
|
5
|
+
before do
|
6
|
+
@k1 = 'http://test.myopenid.com'
|
7
|
+
RPXNow.unmap(@k1, 1)
|
8
|
+
@k2 = 'http://test-2.myopenid.com'
|
9
|
+
RPXNow.unmap(@k2, 1)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "has no mappings when nothing was mapped" do
|
13
|
+
RPXNow.mappings(1).should == []
|
14
|
+
end
|
15
|
+
|
16
|
+
it "unmaps mapped keys" do
|
17
|
+
RPXNow.map(@k2, 1)
|
18
|
+
RPXNow.unmap(@k2, 1)
|
19
|
+
RPXNow.mappings(1).should == []
|
20
|
+
end
|
21
|
+
|
22
|
+
it "maps keys to a primary key and then retrieves them" do
|
23
|
+
RPXNow.map(@k1, 1)
|
24
|
+
RPXNow.map(@k2, 1)
|
25
|
+
RPXNow.mappings(1).sort.should == [@k2,@k1]
|
26
|
+
end
|
27
|
+
|
28
|
+
it "does not add duplicate mappings" do
|
29
|
+
RPXNow.map(@k1, 1)
|
30
|
+
RPXNow.map(@k1, 1)
|
31
|
+
RPXNow.mappings(1).should == [@k1]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "finds all mappings" do
|
35
|
+
RPXNow.map(@k1, 1)
|
36
|
+
RPXNow.map(@k2, 2)
|
37
|
+
RPXNow.all_mappings.sort.should == [["1", ["http://test.myopenid.com"]], ["2", ["http://test-2.myopenid.com"]]]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe RPXNow::Api do
|
4
|
+
describe 'ssl cert' do
|
5
|
+
it "has an absolute path" do
|
6
|
+
RPXNow::Api::SSL_CERT[0..0].should == File.expand_path( RPXNow::Api::SSL_CERT )[0..0] # start with '/' on *nix, drive letter on win
|
7
|
+
end
|
8
|
+
|
9
|
+
it "exists" do
|
10
|
+
File.read(RPXNow::Api::SSL_CERT).to_s.should_not be_empty
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe :parse_response do
|
15
|
+
it "parses json when status is ok" do
|
16
|
+
response = mock(:code=>'200', :body=>%Q({"stat":"ok","data":"xx"}))
|
17
|
+
RPXNow::Api.send(:parse_response, response)['data'].should == "xx"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "raises when there is a communication error" do
|
21
|
+
response = stub(:code=>'200', :body=>%Q({"err":"wtf","stat":"ok"}))
|
22
|
+
lambda{
|
23
|
+
RPXNow::Api.send(:parse_response,response)
|
24
|
+
}.should raise_error(RPXNow::ApiError)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "raises when service has downtime" do
|
28
|
+
response = stub(:code=>'200', :body=>%Q({"err":{"code":-1},"stat":"ok"}))
|
29
|
+
lambda{
|
30
|
+
RPXNow::Api.send(:parse_response,response)
|
31
|
+
}.should raise_error(RPXNow::ServiceUnavailableError)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "raises when service is down" do
|
35
|
+
response = stub(:code=>'400',:body=>%Q({"stat":"err"}))
|
36
|
+
lambda{
|
37
|
+
RPXNow::Api.send(:parse_response,response)
|
38
|
+
}.should raise_error(RPXNow::ServiceUnavailableError)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe :request_object do
|
43
|
+
it "converts symbols to string keys" do
|
44
|
+
mock = ''
|
45
|
+
mock.should_receive(:form_data=).with([['symbol', 'value']])
|
46
|
+
Net::HTTP::Post.should_receive(:new).and_return(mock)
|
47
|
+
RPXNow::Api.send(:request_object, 'something', :symbol=>'value')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe RPXNow::ContactsCollection do
|
4
|
+
before do
|
5
|
+
data = JSON.parse(File.read('spec/fixtures/get_contacts_response.json'))['response']
|
6
|
+
@collection = RPXNow::ContactsCollection.new(data)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "behaves like an array" do
|
10
|
+
@collection.size.should == 5
|
11
|
+
@collection[0] = "1"
|
12
|
+
@collection[0].should == "1"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "parses entry to items" do
|
16
|
+
@collection[0]['displayName'].should == "Bob Johnson"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "parses emails to list" do
|
20
|
+
@collection[0]['emails'].should == ["bob@example.com"]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "parses emails to list with multiple emails" do
|
24
|
+
@collection[2]['emails'].should == ["fred.williams@example.com","fred@example.com"]
|
25
|
+
end
|
26
|
+
|
27
|
+
it "holds additional_info" do
|
28
|
+
@collection.additional_info['startIndex'].should == 1
|
29
|
+
@collection.additional_info['itemsPerPage'].should == 5
|
30
|
+
@collection.additional_info['totalResults'].should == 5
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
require 'rpx_now/user_integration'
|
3
|
+
|
4
|
+
class User
|
5
|
+
include RPXNow::UserIntegration
|
6
|
+
|
7
|
+
def id
|
8
|
+
5
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe RPXNow::UserProxy do
|
13
|
+
before { @user = User.new }
|
14
|
+
|
15
|
+
it "has a proxy" do
|
16
|
+
@user.rpx.class.should == RPXNow::UserProxy
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has identifiers" do
|
20
|
+
RPXNow.should_receive(:mappings).with(@user.id).and_return(['identifiers'])
|
21
|
+
@user.rpx.identifiers.should == ['identifiers']
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can map" do
|
25
|
+
RPXNow.should_receive(:map).with('identifier', @user.id)
|
26
|
+
@user.rpx.map('identifier')
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can unmap" do
|
30
|
+
RPXNow.should_receive(:unmap).with('identifier', @user.id)
|
31
|
+
@user.rpx.unmap('identifier')
|
32
|
+
end
|
33
|
+
end
|