rpx_now 0.5.10
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/CHANGELOG +27 -0
- data/MIGRATION +9 -0
- data/README.markdown +113 -0
- data/Rakefile +35 -0
- data/VERSION +1 -0
- data/certs/ssl_cert.pem +3154 -0
- data/init.rb +2 -0
- data/lib/rpx_now.rb +198 -0
- data/lib/rpx_now/contacts_collection.rb +19 -0
- data/lib/rpx_now/user_integration.rb +7 -0
- data/lib/rpx_now/user_proxy.rb +19 -0
- data/pkg/rpx_now-0.5.10.gem +0 -0
- data/rpx_now.gemspec +62 -0
- data/spec/fixtures/get_contacts_response.json +58 -0
- data/spec/rpx_now/contacts_collection_spec.rb +32 -0
- data/spec/rpx_now/user_proxy_spec.rb +31 -0
- data/spec/rpx_now_spec.rb +278 -0
- data/spec/spec_helper.rb +20 -0
- metadata +84 -0
data/init.rb
ADDED
data/lib/rpx_now.rb
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'rpx_now/contacts_collection'
|
3
|
+
require 'rpx_now/user_integration'
|
4
|
+
require 'rpx_now/user_proxy'
|
5
|
+
|
6
|
+
module RPXNow
|
7
|
+
extend self
|
8
|
+
|
9
|
+
HOST = 'rpxnow.com'
|
10
|
+
SSL_CERT = File.join(File.dirname(__FILE__), '..', 'certs', 'ssl_cert.pem')
|
11
|
+
|
12
|
+
attr_accessor :api_key
|
13
|
+
attr_accessor :api_version
|
14
|
+
self.api_version = 2
|
15
|
+
|
16
|
+
# retrieve the users data, or return nil when nothing could be read/token was invalid
|
17
|
+
# or data was not found
|
18
|
+
def user_data(token, *args)
|
19
|
+
api_key, version, options = extract_key_version_and_options!(args)
|
20
|
+
options = {:token=>token,:apiKey=>api_key}.merge options
|
21
|
+
|
22
|
+
begin
|
23
|
+
data = secure_json_post("/api/v#{version}/auth_info", options)
|
24
|
+
rescue ServerError
|
25
|
+
return nil if $!.to_s=~/Data not found/
|
26
|
+
raise
|
27
|
+
end
|
28
|
+
if block_given? then yield(data) else read_user_data_from_response(data) end
|
29
|
+
end
|
30
|
+
|
31
|
+
# set the users status
|
32
|
+
def set_status(identifier, status, *args)
|
33
|
+
api_key, version, options = extract_key_version_and_options!(args)
|
34
|
+
options = {:identifier => identifier, :status => status, :apiKey => api_key}.merge options
|
35
|
+
|
36
|
+
begin
|
37
|
+
data = secure_json_post("/api/v#{version}/set_status", options)
|
38
|
+
rescue ServerError
|
39
|
+
return nil if $!.to_s=~/Data not found/
|
40
|
+
raise
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# maps an identifier to an primary-key (e.g. user.id)
|
45
|
+
def map(identifier, primary_key, *args)
|
46
|
+
api_key, version, options = extract_key_version_and_options!(args)
|
47
|
+
options = {:identifier=>identifier,:primaryKey=>primary_key,:apiKey=>api_key}.merge options
|
48
|
+
secure_json_post("/api/v#{version}/map", options)
|
49
|
+
end
|
50
|
+
|
51
|
+
# un-maps an identifier to an primary-key (e.g. user.id)
|
52
|
+
def unmap(identifier, primary_key, *args)
|
53
|
+
api_key, version, options = extract_key_version_and_options!(args)
|
54
|
+
options = {:identifier=>identifier,:primaryKey=>primary_key,:apiKey=>api_key}.merge options
|
55
|
+
secure_json_post("/api/v#{version}/unmap", options)
|
56
|
+
end
|
57
|
+
|
58
|
+
# returns an array of identifiers which are mapped to one of your primary-keys (e.g. user.id)
|
59
|
+
def mappings(primary_key, *args)
|
60
|
+
api_key, version, options = extract_key_version_and_options!(args)
|
61
|
+
options = {:primaryKey=>primary_key,:apiKey=>api_key}.merge options
|
62
|
+
data = secure_json_post("/api/v#{version}/mappings", options)
|
63
|
+
data['identifiers']
|
64
|
+
end
|
65
|
+
|
66
|
+
def all_mappings(*args)
|
67
|
+
api_key, version, options = extract_key_version_and_options!(args)
|
68
|
+
data = secure_json_post("/api/v#{version}/all_mappings", {:apiKey => api_key}.merge(options))
|
69
|
+
data['mappings']
|
70
|
+
end
|
71
|
+
|
72
|
+
def contacts(identifier, *args)
|
73
|
+
api_key, version, options = extract_key_version_and_options!(args)
|
74
|
+
options = {:apiKey => api_key, :identifier=> identifier}.merge(options)
|
75
|
+
data = secure_json_post("/api/v#{version}/get_contacts", options)
|
76
|
+
RPXNow::ContactsCollection.new(data['response'])
|
77
|
+
end
|
78
|
+
alias get_contacts contacts
|
79
|
+
|
80
|
+
def embed_code(subdomain,url,options={})
|
81
|
+
options = {:width => '400', :height => '240', :language => 'en'}.merge(options)
|
82
|
+
<<EOF
|
83
|
+
<iframe src="https://#{subdomain}.#{HOST}/openid/embed?token_url=#{url}&language_preference=#{options[:language]}"
|
84
|
+
scrolling="no" frameBorder="no" style="width:#{options[:width]}px;height:#{options[:height]}px;">
|
85
|
+
</iframe>
|
86
|
+
EOF
|
87
|
+
end
|
88
|
+
|
89
|
+
def popup_code(text, subdomain, url, options = {})
|
90
|
+
if options[:unobtrusive]
|
91
|
+
unobtrusive_popup_code(text, subdomain, url, options)
|
92
|
+
else
|
93
|
+
obtrusive_popup_code(text, subdomain, url, options)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def unobtrusive_popup_code(text, subdomain, url, options={})
|
100
|
+
version = extract_version! options
|
101
|
+
"<a class=\"rpxnow\" href=\"https://#{subdomain}.#{HOST}/openid/v#{version}/signin?token_url=#{url}\">#{text}</a>"
|
102
|
+
end
|
103
|
+
|
104
|
+
def obtrusive_popup_code(text, subdomain, url, options = {})
|
105
|
+
version = extract_version! options
|
106
|
+
<<EOF
|
107
|
+
<a class="rpxnow" onclick="return false;" href="https://#{subdomain}.#{HOST}/openid/v#{version}/signin?token_url=#{url}">
|
108
|
+
#{text}
|
109
|
+
</a>
|
110
|
+
<script src="https://#{HOST}/openid/v#{version}/widget" type="text/javascript"></script>
|
111
|
+
<script type="text/javascript">
|
112
|
+
//<![CDATA[
|
113
|
+
RPXNOW.token_url = "#{url}";
|
114
|
+
|
115
|
+
RPXNOW.realm = "#{subdomain}";
|
116
|
+
RPXNOW.overlay = true;
|
117
|
+
RPXNOW.language_preference = '#{options[:language]||'en'}';
|
118
|
+
//]]>
|
119
|
+
</script>
|
120
|
+
EOF
|
121
|
+
end
|
122
|
+
|
123
|
+
def extract_key_version_and_options!(args)
|
124
|
+
key, options = extract_key_and_options(args)
|
125
|
+
version = extract_version! options
|
126
|
+
[key, version, options]
|
127
|
+
end
|
128
|
+
|
129
|
+
# [API_KEY,{options}] or
|
130
|
+
# [{options}] or
|
131
|
+
# []
|
132
|
+
def extract_key_and_options(args)
|
133
|
+
if args.length == 2
|
134
|
+
[args[0],args[1]]
|
135
|
+
elsif args.length==1
|
136
|
+
if args[0].is_a? Hash then [@api_key,args[0]] else [args[0],{}] end
|
137
|
+
else
|
138
|
+
raise "NO Api Key found!" unless @api_key
|
139
|
+
[@api_key,{}]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def extract_version!(options)
|
144
|
+
options.delete(:api_version) || api_version
|
145
|
+
end
|
146
|
+
|
147
|
+
def read_user_data_from_response(response)
|
148
|
+
user_data = response['profile']
|
149
|
+
data = {}
|
150
|
+
data[:identifier] = user_data['identifier']
|
151
|
+
data[:email] = user_data['verifiedEmail'] || user_data['email']
|
152
|
+
data[:username] = user_data['preferredUsername'] || data[:email].to_s.sub(/@.*/,'')
|
153
|
+
data[:name] = user_data['displayName'] || data[:username]
|
154
|
+
data[:id] = user_data['primaryKey'] unless user_data['primaryKey'].to_s.empty?
|
155
|
+
data
|
156
|
+
end
|
157
|
+
|
158
|
+
def secure_json_post(path, data)
|
159
|
+
parse_response(post(path,data))
|
160
|
+
end
|
161
|
+
|
162
|
+
def post(path, data)
|
163
|
+
require 'net/http'
|
164
|
+
require 'net/https'
|
165
|
+
request = Net::HTTP::Post.new(path)
|
166
|
+
request.form_data = data.map{|k,v| [k.to_s,v]}#symbol keys -> string because of ruby 1.9.x bug http://redmine.ruby-lang.org/issues/show/1351
|
167
|
+
make_request(request)
|
168
|
+
end
|
169
|
+
|
170
|
+
def make_request(request)
|
171
|
+
http = Net::HTTP.new(HOST, 443)
|
172
|
+
http.use_ssl = true
|
173
|
+
http.ca_file = SSL_CERT
|
174
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
175
|
+
http.verify_depth = 5
|
176
|
+
http.request(request)
|
177
|
+
end
|
178
|
+
|
179
|
+
def parse_response(response)
|
180
|
+
if response.code.to_i >= 400
|
181
|
+
raise ServiceUnavailableError, "The RPX service is temporarily unavailable. (4XX)"
|
182
|
+
else
|
183
|
+
result = JSON.parse(response.body)
|
184
|
+
return result unless result['err']
|
185
|
+
|
186
|
+
code = result['err']['code']
|
187
|
+
if code == -1
|
188
|
+
raise ServiceUnavailableError, "The RPX service is temporarily unavailable."
|
189
|
+
else
|
190
|
+
raise ApiError, "Got error: #{result['err']['msg']} (code: #{code}), HTTP status: #{response.code}"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
class ServerError < RuntimeError; end #backwards compatibility / catch all
|
196
|
+
class ApiError < ServerError; end
|
197
|
+
class ServiceUnavailableError < ServerError; end
|
198
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RPXNow
|
2
|
+
class ContactsCollection < Array
|
3
|
+
def initialize(list)
|
4
|
+
@raw = list
|
5
|
+
@additional_info = list.reject{|k,v|k=='entry'}
|
6
|
+
list['entry'].each{|item| self << parse_data(item)}
|
7
|
+
end
|
8
|
+
|
9
|
+
def additional_info;@additional_info;end
|
10
|
+
def raw;@raw;end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def parse_data(entry)
|
15
|
+
entry['emails'] = entry['emails'].map{|email| email['value']}
|
16
|
+
entry
|
17
|
+
end
|
18
|
+
end
|
19
|
+
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
|
Binary file
|
data/rpx_now.gemspec
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
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.5.10"
|
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{2009-10-06}
|
13
|
+
s.email = %q{grosser.michael@gmail.com}
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"README.markdown"
|
16
|
+
]
|
17
|
+
s.files = [
|
18
|
+
"CHANGELOG",
|
19
|
+
"MIGRATION",
|
20
|
+
"README.markdown",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"certs/ssl_cert.pem",
|
24
|
+
"init.rb",
|
25
|
+
"lib/rpx_now.rb",
|
26
|
+
"lib/rpx_now/contacts_collection.rb",
|
27
|
+
"lib/rpx_now/user_integration.rb",
|
28
|
+
"lib/rpx_now/user_proxy.rb",
|
29
|
+
"pkg/rpx_now-0.5.10.gem",
|
30
|
+
"rpx_now.gemspec",
|
31
|
+
"spec/fixtures/get_contacts_response.json",
|
32
|
+
"spec/rpx_now/contacts_collection_spec.rb",
|
33
|
+
"spec/rpx_now/user_proxy_spec.rb",
|
34
|
+
"spec/rpx_now_spec.rb",
|
35
|
+
"spec/spec_helper.rb"
|
36
|
+
]
|
37
|
+
s.homepage = %q{http://github.com/grosser/rpx_now}
|
38
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
39
|
+
s.require_paths = ["lib"]
|
40
|
+
s.rubyforge_project = %q{rpx-now}
|
41
|
+
s.rubygems_version = %q{1.3.5}
|
42
|
+
s.summary = %q{Helper to simplify RPX Now user login/creation}
|
43
|
+
s.test_files = [
|
44
|
+
"spec/rpx_now_spec.rb",
|
45
|
+
"spec/rpx_now/contacts_collection_spec.rb",
|
46
|
+
"spec/rpx_now/user_proxy_spec.rb",
|
47
|
+
"spec/spec_helper.rb"
|
48
|
+
]
|
49
|
+
|
50
|
+
if s.respond_to? :specification_version then
|
51
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
52
|
+
s.specification_version = 3
|
53
|
+
|
54
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
55
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
58
|
+
end
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
61
|
+
end
|
62
|
+
end
|
@@ -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,32 @@
|
|
1
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
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,31 @@
|
|
1
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class User
|
4
|
+
include RPXNow::UserIntegration
|
5
|
+
|
6
|
+
def id
|
7
|
+
5
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe RPXNow::UserProxy do
|
12
|
+
before do
|
13
|
+
RPXNow.unmap('http://test.myopenid.com', 5)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has identifiers" do
|
17
|
+
RPXNow.map('http://test.myopenid.com', 5)
|
18
|
+
User.new.rpx.identifiers.should == ['http://test.myopenid.com']
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can map" do
|
22
|
+
User.new.rpx.map('http://test.myopenid.com')
|
23
|
+
User.new.rpx.identifiers.should == ['http://test.myopenid.com']
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can unmap" do
|
27
|
+
RPXNow.map('http://test.myopenid.com', 5)
|
28
|
+
User.new.rpx.unmap('http://test.myopenid.com')
|
29
|
+
User.new.rpx.identifiers.should == []
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,278 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe RPXNow do
|
4
|
+
describe :api_key= do
|
5
|
+
it "stores the api key, so i do not have to supply everytime" do
|
6
|
+
RPXNow.api_key='XX'
|
7
|
+
RPXNow.expects(:post).with{|x,data|data[:apiKey]=='XX'}.returns mock(:code=>'200', :body=>%Q({"stat":"ok"}))
|
8
|
+
RPXNow.mappings(1)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe :api_version= do
|
13
|
+
it "can be set to a api_version globally" do
|
14
|
+
RPXNow.api_version = 5
|
15
|
+
RPXNow.popup_code('x','y','z').should =~ %r(/openid/v5/signin)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe :embed_code do
|
20
|
+
it "contains the subdomain" do
|
21
|
+
RPXNow.embed_code('xxx','my_url').should =~ /xxx/
|
22
|
+
end
|
23
|
+
|
24
|
+
it "contains the url" do
|
25
|
+
RPXNow.embed_code('xxx','my_url').should =~ /token_url=my_url/
|
26
|
+
end
|
27
|
+
|
28
|
+
it "defaults to English" do
|
29
|
+
RPXNow.embed_code('xxx', 'my_url').should =~ /language_preference=en/
|
30
|
+
end
|
31
|
+
|
32
|
+
it "has a changeable language" do
|
33
|
+
RPXNow.embed_code('xxx', 'my_url', :language => 'es').should =~ /language_preference=es/
|
34
|
+
end
|
35
|
+
|
36
|
+
it "defaults to 400px width" do
|
37
|
+
RPXNow.embed_code('xxx', 'my_url').should =~ /width:400px;/
|
38
|
+
end
|
39
|
+
|
40
|
+
it "has a changeable width" do
|
41
|
+
RPXNow.embed_code('xxx', 'my_url', :width => '300').should =~ /width:300px;/
|
42
|
+
end
|
43
|
+
|
44
|
+
it "defaults to 240px height" do
|
45
|
+
RPXNow.embed_code('xxx', 'my_url').should =~ /height:240px;/
|
46
|
+
end
|
47
|
+
|
48
|
+
it "has a changeable height" do
|
49
|
+
RPXNow.embed_code('xxx', 'my_url', :height => '500').should =~ /height:500px;/
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe :popup_code do
|
54
|
+
it "defaults to obtrusive output" do
|
55
|
+
RPXNow.popup_code('sign on', 'subdomain', 'http://fake.domain.com/').should =~ /script src=/
|
56
|
+
end
|
57
|
+
|
58
|
+
it "can build an unobtrusive widget with specific version" do
|
59
|
+
expected = %Q(<a class="rpxnow" href="https://subdomain.rpxnow.com/openid/v300/signin?token_url=http://fake.domain.com/">sign on</a>)
|
60
|
+
RPXNow.popup_code('sign on', 'subdomain', 'http://fake.domain.com/', { :unobtrusive => true, :api_version => 300 }).should == expected
|
61
|
+
end
|
62
|
+
|
63
|
+
it "allows to specify the version of the widget" do
|
64
|
+
RPXNow.popup_code('x','y','z', :api_version => 300).should =~ %r(/openid/v300/signin)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "defaults to widget version 2" do
|
68
|
+
RPXNow.popup_code('x','y','z').should =~ %r(/openid/v2/signin)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "defaults to english" do
|
72
|
+
RPXNow.popup_code('x','y','z').should =~ /RPXNOW.language_preference = 'en'/
|
73
|
+
end
|
74
|
+
|
75
|
+
it "has a changeable language" do
|
76
|
+
RPXNow.popup_code('x','y','z',:language=>'de').should =~ /RPXNOW.language_preference = 'de'/
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe :user_data do
|
81
|
+
before do
|
82
|
+
@response_body = %Q({"profile":{"verifiedEmail":"grosser.michael@googlemail.com","displayName":"Michael Grosser","preferredUsername":"grosser.michael","identifier":"https:\/\/www.google.com\/accounts\/o8\/id?id=AItOawmaOlyYezg_WfbgP_qjaUyHjmqZD9qNIVM","email":"grosser.michael@gmail.com"},"stat":"ok"})
|
83
|
+
@fake_user_data = {'profile'=>{}}
|
84
|
+
end
|
85
|
+
|
86
|
+
def fake_response
|
87
|
+
mock(:code=>"200",:body=>@response_body)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "raises ApiError when used with an invalid token" do
|
91
|
+
lambda{
|
92
|
+
RPXNow.user_data('xxxx')
|
93
|
+
}.should raise_error(RPXNow::ApiError)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "is empty when used with an unknown token" do
|
97
|
+
RPXNow.user_data('60d8c6374f4e9d290a7b55f39da7cc6435aef3d3').should == nil
|
98
|
+
end
|
99
|
+
|
100
|
+
it "parses JSON response to user data" do
|
101
|
+
RPXNow.expects(:post).returns fake_response
|
102
|
+
RPXNow.user_data('').should == {:name=>'Michael Grosser',:email=>'grosser.michael@googlemail.com',:identifier=>"https://www.google.com/accounts/o8/id?id=AItOawmaOlyYezg_WfbgP_qjaUyHjmqZD9qNIVM", :username => 'grosser.michael'}
|
103
|
+
end
|
104
|
+
|
105
|
+
it "adds a :id when primaryKey was returned" do
|
106
|
+
@response_body.sub!(%Q("verifiedEmail"), %Q("primaryKey":"2","verifiedEmail"))
|
107
|
+
RPXNow.expects(:post).returns fake_response
|
108
|
+
RPXNow.user_data('')[:id].should == '2'
|
109
|
+
end
|
110
|
+
|
111
|
+
it "handles primaryKeys that are not numeric" do
|
112
|
+
@response_body.sub!(%Q("verifiedEmail"), %Q("primaryKey":"dbalatero","verifiedEmail"))
|
113
|
+
RPXNow.expects(:post).returns fake_response
|
114
|
+
RPXNow.user_data('')[:id].should == 'dbalatero'
|
115
|
+
end
|
116
|
+
|
117
|
+
it "hands JSON response to supplied block" do
|
118
|
+
RPXNow.expects(:post).returns mock(:code=>'200',:body=>%Q({"x":"1","stat":"ok"}))
|
119
|
+
response = nil
|
120
|
+
RPXNow.user_data(''){|data| response = data}
|
121
|
+
response.should == {"x" => "1", "stat" => "ok"}
|
122
|
+
end
|
123
|
+
|
124
|
+
it "returns what the supplied block returned" do
|
125
|
+
RPXNow.expects(:post).returns mock(:code=>'200',:body=>%Q({"x":"1","stat":"ok"}))
|
126
|
+
RPXNow.user_data(''){|data| "x"}.should == 'x'
|
127
|
+
end
|
128
|
+
|
129
|
+
it "can send additional parameters" do
|
130
|
+
RPXNow.expects(:post).with{|url,data|
|
131
|
+
data[:extended].should == 'true'
|
132
|
+
}.returns fake_response
|
133
|
+
RPXNow.user_data('',:extended=>'true')
|
134
|
+
end
|
135
|
+
|
136
|
+
it "works with api key as 2nd parameter (backwards compatibility)" do
|
137
|
+
RPXNow.expects(:secure_json_post).with('/api/v2/auth_info', :apiKey=>'THE KEY', :token=>'id').returns @fake_user_data
|
138
|
+
RPXNow.user_data('id', 'THE KEY')
|
139
|
+
RPXNow.api_key.should == API_KEY
|
140
|
+
end
|
141
|
+
|
142
|
+
it "works with api key as 2nd parameter and options (backwards compatibility)" do
|
143
|
+
RPXNow.expects(:secure_json_post).with('/api/v2/auth_info', :apiKey=>'THE KEY', :extended=>'abc', :token=>'id' ).returns @fake_user_data
|
144
|
+
RPXNow.user_data('id', 'THE KEY', :extended=>'abc')
|
145
|
+
RPXNow.api_key.should == API_KEY
|
146
|
+
end
|
147
|
+
|
148
|
+
it "works with api version as option (backwards compatibility)" do
|
149
|
+
RPXNow.expects(:secure_json_post).with('/api/v123/auth_info', :apiKey=>API_KEY, :token=>'id', :extended=>'abc').returns @fake_user_data
|
150
|
+
RPXNow.user_data('id', :extended=>'abc', :api_version=>123)
|
151
|
+
RPXNow.api_version.should == API_VERSION
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe :set_status do
|
156
|
+
before do
|
157
|
+
@response_body = %Q({ "stat": "ok" })
|
158
|
+
end
|
159
|
+
|
160
|
+
def fake_response
|
161
|
+
mock(:code=>"200",:body=>@response_body)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "parses JSON response to result hash" do
|
165
|
+
RPXNow.expects(:post).returns fake_response
|
166
|
+
RPXNow.set_status('identifier', 'Chillen...').should == {'stat' => 'ok'}
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe :read_user_data_from_response do
|
171
|
+
it "reads secondary names" do
|
172
|
+
RPXNow.send(:read_user_data_from_response,{'profile'=>{'preferredUsername'=>'1'}})[:name].should == '1'
|
173
|
+
end
|
174
|
+
|
175
|
+
it "parses email when no name is found" do
|
176
|
+
RPXNow.send(:read_user_data_from_response,{'profile'=>{'email'=>'1@xxx.com'}})[:name].should == '1'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe :contacts do
|
181
|
+
it "finds all contacts" do
|
182
|
+
response = JSON.parse(File.read('spec/fixtures/get_contacts_response.json'))
|
183
|
+
RPXNow.expects(:secure_json_post).with('/api/v2/get_contacts',:identifier=>'xx', :apiKey=>API_KEY).returns response
|
184
|
+
RPXNow.contacts('xx').size.should == 5
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe :parse_response do
|
189
|
+
it "parses json when status is ok" do
|
190
|
+
response = mock(:code=>'200', :body=>%Q({"stat":"ok","data":"xx"}))
|
191
|
+
RPXNow.send(:parse_response, response)['data'].should == "xx"
|
192
|
+
end
|
193
|
+
|
194
|
+
it "raises when there is a communication error" do
|
195
|
+
response = stub(:code=>'200', :body=>%Q({"err":"wtf","stat":"ok"}))
|
196
|
+
lambda{
|
197
|
+
RPXNow.send(:parse_response,response)
|
198
|
+
}.should raise_error(RPXNow::ApiError)
|
199
|
+
end
|
200
|
+
|
201
|
+
it "raises when service has downtime" do
|
202
|
+
response = stub(:code=>'200', :body=>%Q({"err":{"code":-1},"stat":"ok"}))
|
203
|
+
lambda{
|
204
|
+
RPXNow.send(:parse_response,response)
|
205
|
+
}.should raise_error(RPXNow::ServiceUnavailableError)
|
206
|
+
end
|
207
|
+
|
208
|
+
it "raises when service is down" do
|
209
|
+
response = stub(:code=>'400',:body=>%Q({"stat":"err"}))
|
210
|
+
lambda{
|
211
|
+
RPXNow.send(:parse_response,response)
|
212
|
+
}.should raise_error(RPXNow::ServiceUnavailableError)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe :mappings do
|
217
|
+
it "parses JSON response to unmap data" do
|
218
|
+
RPXNow.expects(:post).returns mock(:code=>'200',:body=>%Q({"stat":"ok", "identifiers": ["http://test.myopenid.com/"]}))
|
219
|
+
RPXNow.mappings(1, "x").should == ["http://test.myopenid.com/"]
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe :map do
|
224
|
+
it "adds a mapping" do
|
225
|
+
RPXNow.expects(:post).returns mock(:code=>'200',:body=>%Q({"stat":"ok"}))
|
226
|
+
RPXNow.map('http://test.myopenid.com',1, API_KEY)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
describe :unmap do
|
231
|
+
it "unmaps a indentifier" do
|
232
|
+
RPXNow.expects(:post).returns mock(:code=>'200',:body=>%Q({"stat":"ok"}))
|
233
|
+
RPXNow.unmap('http://test.myopenid.com', 1, "x")
|
234
|
+
end
|
235
|
+
|
236
|
+
it "can be called with a specific version" do
|
237
|
+
RPXNow.expects(:secure_json_post).with{|a,b|a == "/api/v300/unmap"}
|
238
|
+
RPXNow.unmap('http://test.myopenid.com', 1, :api_key=>'xxx', :api_version=>300)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
describe :mapping_integration do
|
243
|
+
before do
|
244
|
+
@k1 = 'http://test.myopenid.com'
|
245
|
+
RPXNow.unmap(@k1, 1)
|
246
|
+
@k2 = 'http://test-2.myopenid.com'
|
247
|
+
RPXNow.unmap(@k2, 1)
|
248
|
+
end
|
249
|
+
|
250
|
+
it "has no mappings when nothing was mapped" do
|
251
|
+
RPXNow.mappings(1).should == []
|
252
|
+
end
|
253
|
+
|
254
|
+
it "unmaps mapped keys" do
|
255
|
+
RPXNow.map(@k2, 1)
|
256
|
+
RPXNow.unmap(@k2, 1)
|
257
|
+
RPXNow.mappings(1).should == []
|
258
|
+
end
|
259
|
+
|
260
|
+
it "maps keys to a primary key and then retrieves them" do
|
261
|
+
RPXNow.map(@k1, 1)
|
262
|
+
RPXNow.map(@k2, 1)
|
263
|
+
RPXNow.mappings(1).sort.should == [@k2,@k1]
|
264
|
+
end
|
265
|
+
|
266
|
+
it "does not add duplicate mappings" do
|
267
|
+
RPXNow.map(@k1, 1)
|
268
|
+
RPXNow.map(@k1, 1)
|
269
|
+
RPXNow.mappings(1).should == [@k1]
|
270
|
+
end
|
271
|
+
|
272
|
+
it "finds all mappings" do
|
273
|
+
RPXNow.map(@k1, 1)
|
274
|
+
RPXNow.map(@k2, 2)
|
275
|
+
RPXNow.all_mappings.sort.should == [["1", ["http://test.myopenid.com"]], ["2", ["http://test-2.myopenid.com"]]]
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|