omnigroupcontacts 0.3.10 → 0.3.11
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.
- 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
|