omnigroupcontacts 0.3.10 → 0.3.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +6 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +39 -0
- data/README.md +132 -0
- data/Rakefile +7 -0
- data/lib/omnigroupcontacts.rb +19 -0
- data/lib/omnigroupcontacts/authorization/oauth1.rb +122 -0
- data/lib/omnigroupcontacts/authorization/oauth2.rb +87 -0
- data/lib/omnigroupcontacts/builder.rb +30 -0
- data/lib/omnigroupcontacts/http_utils.rb +101 -0
- data/lib/omnigroupcontacts/importer.rb +5 -0
- data/lib/omnigroupcontacts/importer/gmailgroup.rb +238 -0
- data/lib/omnigroupcontacts/integration_test.rb +36 -0
- data/lib/omnigroupcontacts/middleware/base_oauth.rb +120 -0
- data/lib/omnigroupcontacts/middleware/oauth1.rb +70 -0
- data/lib/omnigroupcontacts/middleware/oauth2.rb +80 -0
- data/lib/omnigroupcontacts/parse_utils.rb +56 -0
- data/omnigroupcontacts-0.3.10.gem +0 -0
- data/omnigroupcontacts-0.3.8.gem +0 -0
- data/omnigroupcontacts-0.3.9.gem +0 -0
- data/omnigroupcontacts.gemspec +25 -0
- data/spec/omnicontacts/authorization/oauth1_spec.rb +82 -0
- data/spec/omnicontacts/authorization/oauth2_spec.rb +92 -0
- data/spec/omnicontacts/http_utils_spec.rb +79 -0
- data/spec/omnicontacts/importer/facebook_spec.rb +120 -0
- data/spec/omnicontacts/importer/gmail_spec.rb +194 -0
- data/spec/omnicontacts/importer/hotmail_spec.rb +106 -0
- data/spec/omnicontacts/importer/linkedin_spec.rb +67 -0
- data/spec/omnicontacts/importer/yahoo_spec.rb +124 -0
- data/spec/omnicontacts/integration_test_spec.rb +51 -0
- data/spec/omnicontacts/middleware/base_oauth_spec.rb +53 -0
- data/spec/omnicontacts/middleware/oauth1_spec.rb +78 -0
- data/spec/omnicontacts/middleware/oauth2_spec.rb +67 -0
- data/spec/omnicontacts/parse_utils_spec.rb +53 -0
- data/spec/spec_helper.rb +12 -0
- metadata +37 -2
@@ -0,0 +1,70 @@
|
|
1
|
+
require "omnigroupcontacts/authorization/oauth1"
|
2
|
+
require "omnigroupcontacts/middleware/base_oauth"
|
3
|
+
|
4
|
+
# This class is an OAuth 1.0 Rack middleware.
|
5
|
+
#
|
6
|
+
# Extending classes are required to
|
7
|
+
# implement the following methods:
|
8
|
+
# * fetch_token_from_token_and_verifier -> this method has to
|
9
|
+
# fetch the list of contacts from the authorization server.
|
10
|
+
module OmniGroupContacts
|
11
|
+
module Middleware
|
12
|
+
class OAuth1 < BaseOAuth
|
13
|
+
include Authorization::OAuth1
|
14
|
+
|
15
|
+
attr_reader :consumer_key, :consumer_secret, :callback_path
|
16
|
+
|
17
|
+
def initialize app, consumer_key, consumer_secret, options = {}
|
18
|
+
super app, options
|
19
|
+
@consumer_key = consumer_key
|
20
|
+
@consumer_secret = consumer_secret
|
21
|
+
@callback_path = options[:callback_path] || "#{ MOUNT_PATH }#{class_name}/callback"
|
22
|
+
@token_prop_name = "#{base_prop_name}.oauth_token"
|
23
|
+
end
|
24
|
+
|
25
|
+
def callback
|
26
|
+
host_url_from_rack_env(@env) + callback_path
|
27
|
+
end
|
28
|
+
|
29
|
+
alias :redirect_path :callback_path
|
30
|
+
|
31
|
+
# Obtains an authorization token from the server,
|
32
|
+
# stores it and the session and redirect the user
|
33
|
+
# to the authorization website.
|
34
|
+
def request_authorization_from_user
|
35
|
+
(auth_token, auth_token_secret) = fetch_authorization_token
|
36
|
+
session[@token_prop_name] = auth_token
|
37
|
+
session[token_secret_prop_name(auth_token)] = auth_token_secret
|
38
|
+
redirect_to_authorization_site(auth_token)
|
39
|
+
end
|
40
|
+
|
41
|
+
def token_secret_prop_name oauth_token
|
42
|
+
"#{base_prop_name}.#{oauth_token}.oauth_token_secret"
|
43
|
+
end
|
44
|
+
|
45
|
+
def redirect_to_authorization_site auth_token
|
46
|
+
authorization_url = authorization_url(auth_token)
|
47
|
+
target_url = append_state_query(authorization_url)
|
48
|
+
[302, {"Content-Type" => "application/x-www-form-urlencoded", "location" => target_url}, []]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Parses the authorization token from the query string and
|
52
|
+
# obtain the relative secret from the session.
|
53
|
+
# Finally it calls fetch_contacts_from_token_and_verifier.
|
54
|
+
# If token is found in the query string an AuhorizationError
|
55
|
+
# is raised.
|
56
|
+
def fetch_contacts
|
57
|
+
params = query_string_to_map(@env["QUERY_STRING"])
|
58
|
+
oauth_token = params["oauth_token"]
|
59
|
+
oauth_verifier = params["oauth_verifier"]
|
60
|
+
oauth_token_secret = session[token_secret_prop_name(oauth_token)]
|
61
|
+
if oauth_token && oauth_verifier && oauth_token_secret
|
62
|
+
fetch_contacts_from_token_and_verifier(oauth_token, oauth_token_secret, oauth_verifier)
|
63
|
+
else
|
64
|
+
raise AuthorizationError.new("User did not grant access to contacts list")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "omnigroupcontacts/authorization/oauth2"
|
2
|
+
require "omnigroupcontacts/middleware/base_oauth"
|
3
|
+
|
4
|
+
# This class is a OAuth 2 Rack middleware.
|
5
|
+
#
|
6
|
+
# Extending class are required to implement
|
7
|
+
# the following methods:
|
8
|
+
# * fetch_contacts_using_access_token -> it
|
9
|
+
# fetches the list of contacts from the authorization
|
10
|
+
# server.
|
11
|
+
module OmniGroupContacts
|
12
|
+
module Middleware
|
13
|
+
class OAuth2 < BaseOAuth
|
14
|
+
include Authorization::OAuth2
|
15
|
+
|
16
|
+
attr_reader :client_id, :client_secret, :redirect_path
|
17
|
+
|
18
|
+
def initialize app, client_id, client_secret, options ={}
|
19
|
+
super app, options
|
20
|
+
@client_id = client_id
|
21
|
+
@client_secret = client_secret
|
22
|
+
@redirect_path = options[:redirect_path] || "#{ MOUNT_PATH }#{class_name}/callback"
|
23
|
+
@ssl_ca_file = options[:ssl_ca_file]
|
24
|
+
end
|
25
|
+
|
26
|
+
def request_authorization_from_user
|
27
|
+
target_url = append_state_query(authorization_url)
|
28
|
+
[302, {"Content-Type" => "application/x-www-form-urlencoded", "location" => target_url}, []]
|
29
|
+
end
|
30
|
+
|
31
|
+
def redirect_uri
|
32
|
+
host_url_from_rack_env(@env) + redirect_path
|
33
|
+
end
|
34
|
+
|
35
|
+
# It extract the authorization code from the query string.
|
36
|
+
# It uses it to obtain an access token.
|
37
|
+
# If the authorization code has a refresh token associated
|
38
|
+
# with it in the session, it uses the obtain an access token.
|
39
|
+
# It fetches the list of contacts and stores the refresh token
|
40
|
+
# associated with the access token in the session.
|
41
|
+
# Finally it returns the list of contacts.
|
42
|
+
# If no authorization code is found in the query string an
|
43
|
+
# AuthoriazationError is raised.
|
44
|
+
def fetch_groups
|
45
|
+
code = query_string_to_map(@env["QUERY_STRING"])["code"]
|
46
|
+
if code
|
47
|
+
refresh_token = session[refresh_token_prop_name(code)]
|
48
|
+
(access_token, token_type, refresh_token) = if refresh_token
|
49
|
+
refresh_access_token(refresh_token)
|
50
|
+
else
|
51
|
+
fetch_access_token(code)
|
52
|
+
end
|
53
|
+
groups = fetch_groups_using_access_token(access_token, token_type)
|
54
|
+
group_contacts = fetch_group_contacts(groups, access_token, token_type)
|
55
|
+
session[refresh_token_prop_name(code)] = refresh_token if refresh_token
|
56
|
+
group_contacts
|
57
|
+
else
|
58
|
+
raise AuthorizationError.new("User did not grant access to contacts list")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def fetch_group_contacts(groups, access_token, token_type)
|
63
|
+
group_contacts_all = {}
|
64
|
+
|
65
|
+
groups.each do |group|
|
66
|
+
Rails.logger.info "---------#{group.inspect}---------"
|
67
|
+
group_contacts = fetch_contacts_using_access_token(access_token, token_type, group[:id])
|
68
|
+
group_contacts_all[group[:title]] = group_contacts
|
69
|
+
end
|
70
|
+
|
71
|
+
group_contacts_all
|
72
|
+
end
|
73
|
+
|
74
|
+
def refresh_token_prop_name code
|
75
|
+
"#{base_prop_name}.#{code}.refresh_token"
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module OmniGroupContacts
|
2
|
+
module ParseUtils
|
3
|
+
|
4
|
+
# return has of birthday day, month and year
|
5
|
+
def birthday_format month, day, year
|
6
|
+
return {:day => day.to_i, :month => month.to_i, :year => year.to_i}if year && month && day
|
7
|
+
return {:day => day.to_i, :month => month.to_i, :year => nil} if !year && month && day
|
8
|
+
return nil if (!year && !month) || (!year && !day)
|
9
|
+
end
|
10
|
+
|
11
|
+
# normalize the name
|
12
|
+
def normalize_name name
|
13
|
+
return nil if name.nil?
|
14
|
+
name.chomp!
|
15
|
+
name.squeeze!(' ')
|
16
|
+
name.strip!
|
17
|
+
return name
|
18
|
+
end
|
19
|
+
|
20
|
+
# create a full name given the individual first and last name
|
21
|
+
def full_name first_name, last_name
|
22
|
+
return "#{first_name} #{last_name}" if first_name && last_name
|
23
|
+
return "#{first_name}" if first_name && !last_name
|
24
|
+
return "#{last_name}" if !first_name && last_name
|
25
|
+
return nil
|
26
|
+
end
|
27
|
+
|
28
|
+
# create a username/name from a given email
|
29
|
+
def email_to_name username_or_email
|
30
|
+
username_or_email = username_or_email.split('@').first if username_or_email.include?('@')
|
31
|
+
if group = (/(?<first>[a-z|A-Z]+)[\.|_](?<last>[a-z|A-Z]+)/).match(username_or_email)
|
32
|
+
first_name = normalize_name(group[:first])
|
33
|
+
last_name = normalize_name(group[:last])
|
34
|
+
return first_name, last_name, "#{first_name} #{last_name}"
|
35
|
+
end
|
36
|
+
username = normalize_name(username_or_email)
|
37
|
+
return username, nil, username
|
38
|
+
end
|
39
|
+
|
40
|
+
# create an image_url from a gmail or yahoo email id.
|
41
|
+
def image_url_from_email email
|
42
|
+
return nil if email.nil? || !email.include?('@')
|
43
|
+
username, domain = *(email.split('@'))
|
44
|
+
return nil if username.nil? or domain.nil?
|
45
|
+
gmail_base_url = "https://profiles.google.com/s2/photos/profile/"
|
46
|
+
yahoo_base_url = "https://img.msg.yahoo.com/avatar.php?yids="
|
47
|
+
if domain.include?('gmail')
|
48
|
+
image_url = gmail_base_url + username
|
49
|
+
elsif domain.include?('yahoo')
|
50
|
+
image_url = yahoo_base_url + username
|
51
|
+
end
|
52
|
+
image_url
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path('../lib/omnigroupcontacts', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = 'omnigroupcontacts'
|
6
|
+
gem.description = %q{A generalized Rack middleware for importing group contacts from gmail.}
|
7
|
+
gem.authors = ['Mitesh Jain']
|
8
|
+
gem.email = ['mitijain123@gmail.com']
|
9
|
+
|
10
|
+
gem.add_runtime_dependency 'rack'
|
11
|
+
gem.add_runtime_dependency 'json'
|
12
|
+
|
13
|
+
gem.add_development_dependency 'simplecov'
|
14
|
+
gem.add_development_dependency 'rake'
|
15
|
+
gem.add_development_dependency 'rack-test'
|
16
|
+
gem.add_development_dependency 'rspec'
|
17
|
+
|
18
|
+
gem.version = OmniGroupContacts::VERSION
|
19
|
+
gem.files = `git ls-files`.split("\n")
|
20
|
+
gem.homepage = 'http://github.com/mitijain123/omnicontacts'
|
21
|
+
gem.require_paths = ['lib']
|
22
|
+
gem.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if gem.respond_to? :required_rubygems_version=
|
23
|
+
gem.summary = gem.description
|
24
|
+
gem.test_files = `git ls-files -- {spec}/*`.split("\n")
|
25
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "omnigroupcontacts/authorization/oauth1"
|
3
|
+
|
4
|
+
describe OmniGroupContacts::Authorization::OAuth1 do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
OAuth1TestClass= Struct.new(:consumer_key, :consumer_secret, :auth_host, :auth_token_path, :auth_path, :access_token_path, :callback)
|
8
|
+
class OAuth1TestClass
|
9
|
+
include OmniGroupContacts::Authorization::OAuth1
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:test_target) do
|
14
|
+
OAuth1TestClass.new("consumer_key", "secret1", "auth_host", "auth_token_path", "auth_path", "access_token_path", "callback")
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "fetch_authorization_token" do
|
18
|
+
|
19
|
+
it "should request the token providing all mandatory parameters" do
|
20
|
+
test_target.should_receive(:https_post) do |host, path, params|
|
21
|
+
host.should eq(test_target.auth_host)
|
22
|
+
path.should eq(test_target.auth_token_path)
|
23
|
+
params[:oauth_consumer_key].should eq(test_target.consumer_key)
|
24
|
+
params[:oauth_nonce].should_not be_nil
|
25
|
+
params[:oauth_signature_method].should eq("PLAINTEXT")
|
26
|
+
params[:oauth_signature].should eq(test_target.consumer_secret + "%26")
|
27
|
+
params[:oauth_timestamp].should_not be_nil
|
28
|
+
params[:oauth_version].should eq("1.0")
|
29
|
+
params[:oauth_callback].should eq(test_target.callback)
|
30
|
+
"oauth_token=token&oauth_token_secret=token_secret"
|
31
|
+
end
|
32
|
+
test_target.fetch_authorization_token
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should successfully parse the result" do
|
36
|
+
test_target.should_receive(:https_post).and_return("oauth_token=token&oauth_token_secret=token_secret")
|
37
|
+
test_target.fetch_authorization_token.should eq(["token", "token_secret"])
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should raise an error if request is invalid" do
|
41
|
+
test_target.should_receive(:https_post).and_return("invalid_request")
|
42
|
+
expect { test_target.fetch_authorization_token }.to raise_error
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "authorization_url" do
|
48
|
+
subject { test_target.authorization_url("token") }
|
49
|
+
it { should eq("https://#{test_target.auth_host}#{test_target.auth_path}?oauth_token=token") }
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "fetch_access_token" do
|
53
|
+
it "should request the access token using all required parameters" do
|
54
|
+
auth_token = "token"
|
55
|
+
auth_token_secret = "token_secret"
|
56
|
+
auth_verifier = "verifier"
|
57
|
+
test_target.should_receive(:https_post) do |host, path, params|
|
58
|
+
host.should eq(test_target.auth_host)
|
59
|
+
path.should eq(test_target.access_token_path)
|
60
|
+
params[:oauth_consumer_key].should eq(test_target.consumer_key)
|
61
|
+
params[:oauth_nonce].should_not be_nil
|
62
|
+
params[:oauth_signature_method].should eq("PLAINTEXT")
|
63
|
+
params[:oauth_version].should eq("1.0")
|
64
|
+
params[:oauth_signature].should eq("#{test_target.consumer_secret}%26#{auth_token_secret}")
|
65
|
+
params[:oauth_token].should eq(auth_token)
|
66
|
+
params[:oauth_verifier].should eq(auth_verifier)
|
67
|
+
"oauth_token=access_token&oauth_token_secret=access_token_secret&other_param=other_value"
|
68
|
+
end
|
69
|
+
test_target.fetch_access_token auth_token, auth_token_secret, auth_verifier, ["other_param"]
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should successfully extract access_token and the other fields" do
|
73
|
+
test_target.should_receive(:https_post).and_return("oauth_token=access_token&oauth_token_secret=access_token_secret&other_param=other_value")
|
74
|
+
test_target.fetch_access_token("token", "token_scret", "verified", ["other_param"]).should eq(["access_token", "access_token_secret", "other_value"])
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "oauth_signature" do
|
79
|
+
subject { test_target.oauth_signature("GET", "https://social.yahooapis.com/v1/user", {:name => "diego", :surname => "castorina"}, "secret2") }
|
80
|
+
it { should eq("xfumZoyVYUbHXSAafdha3HZUqQg%3D") }
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "omnigroupcontacts/authorization/oauth2"
|
3
|
+
|
4
|
+
describe OmniGroupContacts::Authorization::OAuth2 do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
OAuth2TestClass= Struct.new(:auth_host, :authorize_path, :client_id, :client_secret, :scope, :redirect_uri, :auth_token_path)
|
8
|
+
class OAuth2TestClass
|
9
|
+
include OmniGroupContacts::Authorization::OAuth2
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:test_target) do
|
14
|
+
OAuth2TestClass.new("auth_host", "authorize_path", "client_id", "client_secret", "scope", "redirect_uri", "auth_token_path")
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "authorization_url" do
|
18
|
+
|
19
|
+
subject { test_target.authorization_url }
|
20
|
+
|
21
|
+
it { should include("https://#{test_target.auth_host}#{test_target.authorize_path}") }
|
22
|
+
it { should include("client_id=#{test_target.client_id}") }
|
23
|
+
it { should include("scope=#{test_target.scope}") }
|
24
|
+
it { should include("redirect_uri=#{test_target.redirect_uri}") }
|
25
|
+
it { should include("access_type=online") }
|
26
|
+
it { should include("response_type=code") }
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:access_token_response) { %[{"access_token": "access_token", "token_type":"token_type", "refresh_token":"refresh_token"}] }
|
30
|
+
|
31
|
+
describe "fetch_access_token" do
|
32
|
+
|
33
|
+
it "should provide all mandatory parameters in a https post request" do
|
34
|
+
code = "code"
|
35
|
+
test_target.should_receive(:https_post) do |host, path, params|
|
36
|
+
host.should eq(test_target.auth_host)
|
37
|
+
path.should eq(test_target.auth_token_path)
|
38
|
+
params[:code].should eq(code)
|
39
|
+
params[:client_id].should eq(test_target.client_id)
|
40
|
+
params[:client_secret].should eq(test_target.client_secret)
|
41
|
+
params[:redirect_uri].should eq(test_target.redirect_uri)
|
42
|
+
params[:grant_type].should eq("authorization_code")
|
43
|
+
access_token_response
|
44
|
+
end
|
45
|
+
test_target.fetch_access_token code
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should successfully parse the token from the JSON response" do
|
49
|
+
test_target.should_receive(:https_post).and_return(access_token_response)
|
50
|
+
(access_token, token_type, refresh_token) = test_target.fetch_access_token "code"
|
51
|
+
access_token.should eq("access_token")
|
52
|
+
token_type.should eq("token_type")
|
53
|
+
refresh_token.should eq("refresh_token")
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should raise if the http request fails" do
|
57
|
+
test_target.should_receive(:https_post).and_raise("Invalid code")
|
58
|
+
expect { test_target.fetch_access_token("code") }.to raise_error
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should raise an error if the JSON response contains an error field" do
|
62
|
+
test_target.should_receive(:https_post).and_return(%[{"error": "error_message"}])
|
63
|
+
expect { test_target.fetch_access_token("code") }.to raise_error
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "refresh_access_token" do
|
68
|
+
it "should provide all mandatory fields in a https post request" do
|
69
|
+
refresh_token = "refresh_token"
|
70
|
+
test_target.should_receive(:https_post) do |host, path, params|
|
71
|
+
host.should eq(test_target.auth_host)
|
72
|
+
path.should eq(test_target.auth_token_path)
|
73
|
+
params[:client_id].should eq(test_target.client_id)
|
74
|
+
params[:client_secret].should eq(test_target.client_secret)
|
75
|
+
params[:refresh_token].should eq(refresh_token)
|
76
|
+
params[:grant_type].should eq("refresh_token")
|
77
|
+
access_token_response
|
78
|
+
end
|
79
|
+
test_target.refresh_access_token refresh_token
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should successfully parse the token from the JSON response" do
|
83
|
+
test_target.should_receive(:https_post).and_return(access_token_response)
|
84
|
+
(access_token, token_type, refresh_token) = test_target.refresh_access_token "refresh_token"
|
85
|
+
access_token.should eq("access_token")
|
86
|
+
token_type.should eq("token_type")
|
87
|
+
refresh_token.should eq("refresh_token")
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "omnigroupcontacts/http_utils"
|
3
|
+
|
4
|
+
describe OmniGroupContacts::HTTPUtils do
|
5
|
+
|
6
|
+
describe "to_query_string" do
|
7
|
+
it "should create a query string from a map" do
|
8
|
+
result = OmniGroupContacts::HTTPUtils.to_query_string(:name => "john", :surname => "doe")
|
9
|
+
if result.match(/^name/)
|
10
|
+
result.should eq("name=john&surname=doe")
|
11
|
+
else
|
12
|
+
result.should eq("surname=doe&name=john")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should work for integer values in the map" do
|
17
|
+
result = OmniGroupContacts::HTTPUtils.to_query_string(:client_id => 1234, :secret => "1234HJL8")
|
18
|
+
result.should eq("client_id=1234&secret=1234HJL8")
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "encode" do
|
24
|
+
it "should encode the space" do
|
25
|
+
OmniGroupContacts::HTTPUtils.encode("name=\"john\"").should eq("name%3D%22john%22")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "query_string_to_map" do
|
30
|
+
it "should split a query string into a map" do
|
31
|
+
query_string = "name=john&surname=doe"
|
32
|
+
result = OmniGroupContacts::HTTPUtils.query_string_to_map(query_string)
|
33
|
+
result["name"].should eq("john")
|
34
|
+
result["surname"].should eq("doe")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "host_url_from_rack_env" do
|
39
|
+
it "should calculate the host url using the HTTP_HOST variable" do
|
40
|
+
env = {"rack.url_scheme" => "http", "HTTP_HOST" => "localhost:8080", "SERVER_NAME" => "localhost", "SERVER_PORT" => 8080}
|
41
|
+
OmniGroupContacts::HTTPUtils.host_url_from_rack_env(env).should eq("http://localhost:8080")
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should calculate the host url using SERVER_NAME and SERVER_PORT variables" do
|
45
|
+
env = {"rack.url_scheme" => "http", "SERVER_NAME" => "localhost", "SERVER_PORT" => 8080}
|
46
|
+
OmniGroupContacts::HTTPUtils.host_url_from_rack_env(env).should eq("http://localhost:8080")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "https_post" do
|
51
|
+
|
52
|
+
before(:each) do
|
53
|
+
@connection = double
|
54
|
+
Net::HTTP.should_receive(:new).and_return(@connection)
|
55
|
+
@connection.should_receive(:use_ssl=).with(true)
|
56
|
+
@test_target = Object.new
|
57
|
+
@test_target.extend OmniGroupContacts::HTTPUtils
|
58
|
+
@response = double
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should execute a request with success" do
|
62
|
+
@test_target.should_receive(:ssl_ca_file).and_return(nil)
|
63
|
+
@connection.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
64
|
+
@connection.should_receive(:request_post).and_return(@response)
|
65
|
+
@response.should_receive(:code).and_return("200")
|
66
|
+
@response.should_receive(:body).and_return("some content")
|
67
|
+
@test_target.send(:https_post, "host", "path", {})
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should raise an exception with response code != 200" do
|
71
|
+
@test_target.should_receive(:ssl_ca_file).and_return(nil)
|
72
|
+
@connection.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
73
|
+
@connection.should_receive(:request_get).and_return(@response)
|
74
|
+
@response.should_receive(:code).and_return("500")
|
75
|
+
@response.should_receive(:body).and_return("some error message")
|
76
|
+
expect { @test_target.send(:https_get, "host", "path", {}) }.to raise_error
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|