omnicontacts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +39 -0
- data/README.md +83 -0
- data/Rakefile +6 -0
- data/lib/omnicontacts.rb +12 -0
- data/lib/omnicontacts/authorization/oauth1.rb +122 -0
- data/lib/omnicontacts/authorization/oauth2.rb +84 -0
- data/lib/omnicontacts/builder.rb +30 -0
- data/lib/omnicontacts/http_utils.rb +88 -0
- data/lib/omnicontacts/importer.rb +9 -0
- data/lib/omnicontacts/importer/gmail.rb +54 -0
- data/lib/omnicontacts/importer/hotmail.rb +46 -0
- data/lib/omnicontacts/importer/yahoo.rb +64 -0
- data/lib/omnicontacts/middleware/base_oauth.rb +97 -0
- data/lib/omnicontacts/middleware/oauth1.rb +68 -0
- data/lib/omnicontacts/middleware/oauth2.rb +66 -0
- data/omnicontacts.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 +68 -0
- data/spec/omnicontacts/importer/gmail_spec.rb +40 -0
- data/spec/omnicontacts/importer/hotmail_spec.rb +47 -0
- data/spec/omnicontacts/importer/yahoo_spec.rb +42 -0
- data/spec/omnicontacts/middleware/oauth1_spec.rb +71 -0
- data/spec/omnicontacts/middleware/oauth2_spec.rb +62 -0
- data/spec/spec_helper.rb +10 -0
- metadata +139 -0
| @@ -0,0 +1,92 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
            require "omnicontacts/authorization/oauth2"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe OmniContacts::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 OmniContacts::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=offline")}
         | 
| 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")}.should 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")}.should 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,68 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
            require "omnicontacts/http_utils"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe OmniContacts::HTTPUtils do
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              describe "to_query_string" do
         | 
| 7 | 
            +
                it "should create a query string from a map" do
         | 
| 8 | 
            +
                  OmniContacts::HTTPUtils.to_query_string(:name => "john", :surname => "doe").should eq("name=john&surname=doe")
         | 
| 9 | 
            +
                end 
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              describe "encode" do
         | 
| 13 | 
            +
                it "should encode the space" do
         | 
| 14 | 
            +
                  OmniContacts::HTTPUtils.encode("name=\"john\"").should eq("name%3D%22john%22")
         | 
| 15 | 
            +
                end 
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              describe "query_string_to_map" do
         | 
| 19 | 
            +
                it "should split a query string into a map" do
         | 
| 20 | 
            +
                  query_string = "name=john&surname=doe"
         | 
| 21 | 
            +
                  result = OmniContacts::HTTPUtils.query_string_to_map(query_string)
         | 
| 22 | 
            +
                  result["name"].should eq("john")
         | 
| 23 | 
            +
                  result["surname"].should eq("doe")
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              describe "host_url_from_rack_env" do
         | 
| 28 | 
            +
                it "should calculate the host url using the HTTP_HOST variable" do
         | 
| 29 | 
            +
                  env = {"rack.url_scheme" => "http", "HTTP_HOST" => "localhost:8080","SERVER_NAME" => "localhost", "SERVER_PORT" => 8080}
         | 
| 30 | 
            +
                  OmniContacts::HTTPUtils.host_url_from_rack_env(env).should eq("http://localhost:8080")
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                it "should calculate the host url using SERVER_NAME and SERVER_PORT variables" do
         | 
| 34 | 
            +
                  env = {"rack.url_scheme" => "http", "SERVER_NAME" => "localhost", "SERVER_PORT" => 8080}
         | 
| 35 | 
            +
                  OmniContacts::HTTPUtils.host_url_from_rack_env(env).should eq("http://localhost:8080")
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              describe "https_post" do
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                before(:each) do 
         | 
| 42 | 
            +
                  @connection = double
         | 
| 43 | 
            +
                  Net::HTTP.should_receive(:new).and_return(@connection)
         | 
| 44 | 
            +
                  @connection.should_receive(:use_ssl=).with(true)
         | 
| 45 | 
            +
                  @test_target = Object.new
         | 
| 46 | 
            +
                  @test_target.extend OmniContacts::HTTPUtils
         | 
| 47 | 
            +
                  @response = double
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                it "should execute a request with success" do
         | 
| 51 | 
            +
                  @test_target.should_receive(:ssl_ca_file).and_return(nil)
         | 
| 52 | 
            +
                  @connection.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
         | 
| 53 | 
            +
                  @connection.should_receive(:request_post).and_return(@response)
         | 
| 54 | 
            +
                  @response.should_receive(:code).and_return("200")
         | 
| 55 | 
            +
                  @response.should_receive(:body).and_return("some content")
         | 
| 56 | 
            +
                  @test_target.send(:https_post, "host", "path", {})
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                it "should raise an exception with response code != 200" do
         | 
| 60 | 
            +
                  @test_target.should_receive(:ssl_ca_file).and_return(nil)
         | 
| 61 | 
            +
                  @connection.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
         | 
| 62 | 
            +
                  @connection.should_receive(:request_get).and_return(@response)
         | 
| 63 | 
            +
                  @response.should_receive(:code).and_return("500")
         | 
| 64 | 
            +
                  @response.should_receive(:body).and_return("some error message")
         | 
| 65 | 
            +
                  expect {@test_target.send(:https_get, "host", "path", {})}.should raise_error
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
            end
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
            require "omnicontacts/importer/gmail"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe OmniContacts::Importer::Gmail do 
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              let(:gmail) { OmniContacts::Importer::Gmail.new( {}, "client_id", "client_secret") }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              let(:contacts_as_xml) {
         | 
| 9 | 
            +
                "<entry xmlns:gd='http://schemas.google.com/g/2005'>
         | 
| 10 | 
            +
                   <gd:name>
         | 
| 11 | 
            +
                     <gd:fullName>Edward Bennet</gd:fullName>
         | 
| 12 | 
            +
                   </gd:name>
         | 
| 13 | 
            +
                   <gd:email rel='http://schemas.google.com/g/2005#work' primary='true' address='bennet@gmail.com'/>
         | 
| 14 | 
            +
                 </entry>"
         | 
| 15 | 
            +
              }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              describe  "fetch_contacts_using_access_token" do 
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                let(:token) { "token"}
         | 
| 20 | 
            +
                let(:token_type) { "token_type" }
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                it "should request the contacts by specifying version and code in the http headers" do 
         | 
| 23 | 
            +
                  gmail.should_receive(:https_get) do |host, path, params, headers|
         | 
| 24 | 
            +
                    headers["GData-Version"].should eq("3.0")
         | 
| 25 | 
            +
                    headers["Authorization"].should eq("#{token_type} #{token}")
         | 
| 26 | 
            +
                    contacts_as_xml
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                  gmail.fetch_contacts_using_access_token token, token_type
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                it "should correctly parse name and email" do 
         | 
| 32 | 
            +
                  gmail.should_receive(:https_get).and_return(contacts_as_xml)
         | 
| 33 | 
            +
                  result = gmail.fetch_contacts_using_access_token token, token_type
         | 
| 34 | 
            +
                  result.size.should be(1)
         | 
| 35 | 
            +
                  result.first[:name].should eq("Edward Bennet")
         | 
| 36 | 
            +
                  result.first[:email].should eq("bennet@gmail.com")
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
            require "omnicontacts/importer/hotmail"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe OmniContacts::Importer::Hotmail do 
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              let(:hotmail) {OmniContacts::Importer::Hotmail.new({}, "client_id", "client_secret") }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              let(:contacts_as_json) {
         | 
| 9 | 
            +
                "{
         | 
| 10 | 
            +
                   \"data\":
         | 
| 11 | 
            +
                   [{
         | 
| 12 | 
            +
                   \"id\": \"contact.b4466224b2ca42798c3d4ea90c75aa56\", 
         | 
| 13 | 
            +
                   \"first_name\": null, 
         | 
| 14 | 
            +
                   \"last_name\": null, 
         | 
| 15 | 
            +
                   \"name\": \"henrik@hotmail.com\", 
         | 
| 16 | 
            +
                   \"gender\": null, 
         | 
| 17 | 
            +
                   \"is_friend\": false,
         | 
| 18 | 
            +
                   \"is_favorite\": false,  
         | 
| 19 | 
            +
                   \"user_id\": null, 
         | 
| 20 | 
            +
                   \"birth_day\": 29, 
         | 
| 21 | 
            +
                   \"birth_month\": 3 
         | 
| 22 | 
            +
                   }]
         | 
| 23 | 
            +
                }"}
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                describe "fetch_contacts_using_access_token" do 
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  let(:token) { "token"}
         | 
| 28 | 
            +
                  let(:token_type) { "token_type" }
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  it "should request the contacts by providing the token in the url" do
         | 
| 31 | 
            +
                    hotmail.should_receive(:https_get) do |host, path, params, headers|
         | 
| 32 | 
            +
                      params[:access_token].should eq(token)
         | 
| 33 | 
            +
                      contacts_as_json
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                    hotmail.fetch_contacts_using_access_token token, token_type
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  it "should correctly parse the contacts" do 
         | 
| 39 | 
            +
                    hotmail.should_receive(:https_get).and_return(contacts_as_json)
         | 
| 40 | 
            +
                    result = hotmail.fetch_contacts_using_access_token token, token_type
         | 
| 41 | 
            +
                    result.size.should be(1)
         | 
| 42 | 
            +
                    result.first[:name].should be_nil
         | 
| 43 | 
            +
                    result.first[:email].should eq("henrik@hotmail.com")
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            end
         | 
| @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
            require "omnicontacts/importer/yahoo"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe OmniContacts::Importer::Yahoo do
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              describe "fetch_contacts_from_token_and_verifier" do
         | 
| 7 | 
            +
                let(:contacts_as_json) {
         | 
| 8 | 
            +
                  '{"contacts": 
         | 
| 9 | 
            +
                  {"start":1, "count":1, 
         | 
| 10 | 
            +
                  "contact":[{"id":10, "fields":[{"id":819, "type":"email", "value":"john@yahoo.com"},
         | 
| 11 | 
            +
                   {"type":"name", "value": { "givenName":"John", "familyName":"Doe"} }] }] 
         | 
| 12 | 
            +
                } }'}
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                let(:yahoo) { OmniContacts::Importer::Yahoo.new( {}, "consumer_key", "consumer_secret" ) }
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                it "should request the contacts by specifying all required parameters" do
         | 
| 17 | 
            +
                  yahoo.should_receive(:fetch_access_token).and_return(["access_token", "access_token_secret", "guid"])
         | 
| 18 | 
            +
                  yahoo.should_receive(:http_get) do |host, path, params|
         | 
| 19 | 
            +
                    params[:format].should eq("json")
         | 
| 20 | 
            +
                    params[:oauth_consumer_key].should eq("consumer_key")
         | 
| 21 | 
            +
                    params[:oauth_nonce].should_not be_nil
         | 
| 22 | 
            +
                    params[:oauth_signature_method].should eq("HMAC-SHA1")
         | 
| 23 | 
            +
                    params[:oauth_timestamp].should_not be_nil
         | 
| 24 | 
            +
                    params[:oauth_token].should eq("access_token")
         | 
| 25 | 
            +
                    params[:oauth_version].should eq("1.0")
         | 
| 26 | 
            +
                    params[:view].should eq("compact")
         | 
| 27 | 
            +
                    contacts_as_json
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                  yahoo.fetch_contacts_from_token_and_verifier "auth_token", "auth_token_secret", "oauth_verifier"
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                it "should parse the contacts correctly" do
         | 
| 33 | 
            +
                  yahoo.should_receive(:fetch_access_token).and_return(["access_token", "access_token_secret", "guid"])
         | 
| 34 | 
            +
                  yahoo.should_receive(:http_get).and_return(contacts_as_json)
         | 
| 35 | 
            +
                  result = yahoo.fetch_contacts_from_token_and_verifier "auth_token", "auth_token_secret", "oauth_verifier"
         | 
| 36 | 
            +
                  result.size.should be(1)
         | 
| 37 | 
            +
                  result.first[:name].should eq("John Doe")
         | 
| 38 | 
            +
                  result.first[:email].should eq("john@yahoo.com")
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
            end
         | 
| @@ -0,0 +1,71 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
            require "omnicontacts/middleware/oauth1"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe OmniContacts::Middleware::OAuth1 do
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              before(:all) do
         | 
| 7 | 
            +
                class OAuth1Middleware < OmniContacts::Middleware::OAuth1
         | 
| 8 | 
            +
                  def self.mock_auth_token_resp
         | 
| 9 | 
            +
                    @mock_auth_token_resp ||= Object.new
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  def fetch_authorization_token
         | 
| 13 | 
            +
                    OAuth1Middleware.mock_auth_token_resp.body
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  def authorization_url auth_token
         | 
| 17 | 
            +
                    "http://www.example.com"
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                 def fetch_contacts_from_token_and_verifier oauth_token, ouath_token_secret, oauth_verifier
         | 
| 21 | 
            +
                    [{:name => "John Doe", :email => "john@example.com"}]
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def self.mock_session
         | 
| 25 | 
            +
                    @mock_session ||= {}
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
                  def session
         | 
| 28 | 
            +
                    OAuth1Middleware.mock_session
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              let(:app) {
         | 
| 34 | 
            +
                Rack::Builder.new do |b|
         | 
| 35 | 
            +
                b.use OAuth1Middleware, "consumer_id", "consumer_secret"
         | 
| 36 | 
            +
                b.run lambda{ |env| [200, {"Content-Type" => "text/html"}, ["Hello World"]] }
         | 
| 37 | 
            +
                end.to_app
         | 
| 38 | 
            +
              }
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              context "visiting the listening path" do
         | 
| 41 | 
            +
                it "should save the authorization token and redirect to the authorization url" do
         | 
| 42 | 
            +
                  OAuth1Middleware.mock_auth_token_resp.should_receive(:body).and_return(["auth_token", "auth_token_secret"])
         | 
| 43 | 
            +
                  get "/contacts/oauth1middleware"
         | 
| 44 | 
            +
                  last_response.should be_redirect
         | 
| 45 | 
            +
                  last_response.headers['location'].should eq("http://www.example.com")
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                it "should redirect to failure url if fetching the request token does not succeed" do
         | 
| 49 | 
            +
                  OAuth1Middleware.mock_auth_token_resp.should_receive(:body).and_raise("Request failed")
         | 
| 50 | 
            +
                  get "contacts/oauth1middleware"
         | 
| 51 | 
            +
                  last_response.should be_redirect
         | 
| 52 | 
            +
                  last_response.headers["location"].should eq("/contacts/failure?error_message=internal_error")
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              context "visiting the callback url after authorization" do
         | 
| 57 | 
            +
                it "should return the list of contacts" do
         | 
| 58 | 
            +
                  OAuth1Middleware.mock_session.should_receive(:[]).and_return("oauth_token_secret")
         | 
| 59 | 
            +
                  get "/contacts/oauth1middleware/callback?oauth_token=token&oauth_verifier=verifier"
         | 
| 60 | 
            +
                  last_response.should be_ok
         | 
| 61 | 
            +
                  last_request.env["omnicontacts.contacts"].size.should be(1)
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                it "should redirect to failure url if oauth_token_secret is not found in the session" do 
         | 
| 65 | 
            +
                  OAuth1Middleware.mock_session.should_receive(:[]).and_return(nil)
         | 
| 66 | 
            +
                  get "/contacts/oauth1middleware/callback?oauth_token=token&oauth_verifier=verifier"
         | 
| 67 | 
            +
                  last_response.should be_redirect
         | 
| 68 | 
            +
                  last_response.headers["location"].should eq("/contacts/failure?error_message=not_authorized") 
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
            end
         | 
| @@ -0,0 +1,62 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
            require "omnicontacts/middleware/oauth2"
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe OmniContacts::Middleware::OAuth2 do 
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              before(:all) do 
         | 
| 7 | 
            +
                class OAuth2Middleware < OmniContacts::Middleware::OAuth2
         | 
| 8 | 
            +
                  def authorization_url
         | 
| 9 | 
            +
                    "http://www.example.com"
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  def redirect_path
         | 
| 13 | 
            +
                    "/redirect_path"
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  def self.mock_session
         | 
| 17 | 
            +
                    @mock_session ||= {}
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def session
         | 
| 21 | 
            +
                    OAuth2Middleware.mock_session  
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def fetch_access_token code
         | 
| 25 | 
            +
                    ["access_token", "token_type", "token_refresh"]  
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  def fetch_contacts_using_access_token token, token_type
         | 
| 29 | 
            +
                    [{:name => "John Doe", :email => "john@example.com"}]
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              let(:app) {
         | 
| 35 | 
            +
                Rack::Builder.new do |b|
         | 
| 36 | 
            +
                b.use OAuth2Middleware, "client_id", "client_secret"
         | 
| 37 | 
            +
                b.run lambda{ |env| [200, {"Content-Type" => "text/html"}, ["Hello World"]] }
         | 
| 38 | 
            +
                end.to_app
         | 
| 39 | 
            +
              }
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              context "visiting the listening path" do
         | 
| 42 | 
            +
                it "should redirect to authorization site when visiting the listening path" do
         | 
| 43 | 
            +
                  get "/contacts/oauth2middleware"
         | 
| 44 | 
            +
                  last_response.should be_redirect
         | 
| 45 | 
            +
                  last_response.headers['location'].should eq("http://www.example.com")
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
              context "visiting the callback url after authorization" do
         | 
| 50 | 
            +
                it "should fetch the contacts" do
         | 
| 51 | 
            +
                  get '/redirect_path?code=ABC'
         | 
| 52 | 
            +
                  last_response.should be_ok
         | 
| 53 | 
            +
                  last_request.env["omnicontacts.contacts"].size.should be(1)
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                it "should redirect to failure page because user did not allow access to contacts list" do
         | 
| 57 | 
            +
                  get '/redirect_path?error=not_authorized'
         | 
| 58 | 
            +
                  last_response.should be_redirect
         | 
| 59 | 
            +
                  last_response.headers["location"].should eq("/contacts/failure?error_message=not_authorized")
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | @@ -0,0 +1,139 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: omnicontacts
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.1.0
         | 
| 5 | 
            +
              prerelease: 
         | 
| 6 | 
            +
            platform: ruby
         | 
| 7 | 
            +
            authors:
         | 
| 8 | 
            +
            - Diego Castorina
         | 
| 9 | 
            +
            autorequire: 
         | 
| 10 | 
            +
            bindir: bin
         | 
| 11 | 
            +
            cert_chain: []
         | 
| 12 | 
            +
            date: 2012-03-07 00:00:00.000000000 Z
         | 
| 13 | 
            +
            dependencies:
         | 
| 14 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 15 | 
            +
              name: rack
         | 
| 16 | 
            +
              requirement: &1458910 !ruby/object:Gem::Requirement
         | 
| 17 | 
            +
                none: false
         | 
| 18 | 
            +
                requirements:
         | 
| 19 | 
            +
                - - ! '>='
         | 
| 20 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 21 | 
            +
                    version: '0'
         | 
| 22 | 
            +
              type: :runtime
         | 
| 23 | 
            +
              prerelease: false
         | 
| 24 | 
            +
              version_requirements: *1458910
         | 
| 25 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 26 | 
            +
              name: json
         | 
| 27 | 
            +
              requirement: &1453940 !ruby/object:Gem::Requirement
         | 
| 28 | 
            +
                none: false
         | 
| 29 | 
            +
                requirements:
         | 
| 30 | 
            +
                - - ! '>='
         | 
| 31 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 32 | 
            +
                    version: '0'
         | 
| 33 | 
            +
              type: :runtime
         | 
| 34 | 
            +
              prerelease: false
         | 
| 35 | 
            +
              version_requirements: *1453940
         | 
| 36 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 37 | 
            +
              name: simplecov
         | 
| 38 | 
            +
              requirement: &1452760 !ruby/object:Gem::Requirement
         | 
| 39 | 
            +
                none: false
         | 
| 40 | 
            +
                requirements:
         | 
| 41 | 
            +
                - - ! '>='
         | 
| 42 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 43 | 
            +
                    version: '0'
         | 
| 44 | 
            +
              type: :development
         | 
| 45 | 
            +
              prerelease: false
         | 
| 46 | 
            +
              version_requirements: *1452760
         | 
| 47 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 48 | 
            +
              name: rake
         | 
| 49 | 
            +
              requirement: &1451690 !ruby/object:Gem::Requirement
         | 
| 50 | 
            +
                none: false
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - ! '>='
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '0'
         | 
| 55 | 
            +
              type: :development
         | 
| 56 | 
            +
              prerelease: false
         | 
| 57 | 
            +
              version_requirements: *1451690
         | 
| 58 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 59 | 
            +
              name: rack-test
         | 
| 60 | 
            +
              requirement: &1450620 !ruby/object:Gem::Requirement
         | 
| 61 | 
            +
                none: false
         | 
| 62 | 
            +
                requirements:
         | 
| 63 | 
            +
                - - ! '>='
         | 
| 64 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 65 | 
            +
                    version: '0'
         | 
| 66 | 
            +
              type: :development
         | 
| 67 | 
            +
              prerelease: false
         | 
| 68 | 
            +
              version_requirements: *1450620
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            +
              name: rspec
         | 
| 71 | 
            +
              requirement: &1449560 !ruby/object:Gem::Requirement
         | 
| 72 | 
            +
                none: false
         | 
| 73 | 
            +
                requirements:
         | 
| 74 | 
            +
                - - ! '>='
         | 
| 75 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 76 | 
            +
                    version: '0'
         | 
| 77 | 
            +
              type: :development
         | 
| 78 | 
            +
              prerelease: false
         | 
| 79 | 
            +
              version_requirements: *1449560
         | 
| 80 | 
            +
            description: A generalized Rack middleware for importing contacts from major email
         | 
| 81 | 
            +
              providers.
         | 
| 82 | 
            +
            email:
         | 
| 83 | 
            +
            - diegocastorina@gmail.com
         | 
| 84 | 
            +
            executables: []
         | 
| 85 | 
            +
            extensions: []
         | 
| 86 | 
            +
            extra_rdoc_files: []
         | 
| 87 | 
            +
            files:
         | 
| 88 | 
            +
            - .gitignore
         | 
| 89 | 
            +
            - Gemfile
         | 
| 90 | 
            +
            - Gemfile.lock
         | 
| 91 | 
            +
            - README.md
         | 
| 92 | 
            +
            - Rakefile
         | 
| 93 | 
            +
            - lib/omnicontacts.rb
         | 
| 94 | 
            +
            - lib/omnicontacts/authorization/oauth1.rb
         | 
| 95 | 
            +
            - lib/omnicontacts/authorization/oauth2.rb
         | 
| 96 | 
            +
            - lib/omnicontacts/builder.rb
         | 
| 97 | 
            +
            - lib/omnicontacts/http_utils.rb
         | 
| 98 | 
            +
            - lib/omnicontacts/importer.rb
         | 
| 99 | 
            +
            - lib/omnicontacts/importer/gmail.rb
         | 
| 100 | 
            +
            - lib/omnicontacts/importer/hotmail.rb
         | 
| 101 | 
            +
            - lib/omnicontacts/importer/yahoo.rb
         | 
| 102 | 
            +
            - lib/omnicontacts/middleware/base_oauth.rb
         | 
| 103 | 
            +
            - lib/omnicontacts/middleware/oauth1.rb
         | 
| 104 | 
            +
            - lib/omnicontacts/middleware/oauth2.rb
         | 
| 105 | 
            +
            - omnicontacts.gemspec
         | 
| 106 | 
            +
            - spec/omnicontacts/authorization/oauth1_spec.rb
         | 
| 107 | 
            +
            - spec/omnicontacts/authorization/oauth2_spec.rb
         | 
| 108 | 
            +
            - spec/omnicontacts/http_utils_spec.rb
         | 
| 109 | 
            +
            - spec/omnicontacts/importer/gmail_spec.rb
         | 
| 110 | 
            +
            - spec/omnicontacts/importer/hotmail_spec.rb
         | 
| 111 | 
            +
            - spec/omnicontacts/importer/yahoo_spec.rb
         | 
| 112 | 
            +
            - spec/omnicontacts/middleware/oauth1_spec.rb
         | 
| 113 | 
            +
            - spec/omnicontacts/middleware/oauth2_spec.rb
         | 
| 114 | 
            +
            - spec/spec_helper.rb
         | 
| 115 | 
            +
            homepage: http://github.com/Diego81/omnicontacts
         | 
| 116 | 
            +
            licenses: []
         | 
| 117 | 
            +
            post_install_message: 
         | 
| 118 | 
            +
            rdoc_options: []
         | 
| 119 | 
            +
            require_paths:
         | 
| 120 | 
            +
            - lib
         | 
| 121 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 122 | 
            +
              none: false
         | 
| 123 | 
            +
              requirements:
         | 
| 124 | 
            +
              - - ! '>='
         | 
| 125 | 
            +
                - !ruby/object:Gem::Version
         | 
| 126 | 
            +
                  version: '0'
         | 
| 127 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 128 | 
            +
              none: false
         | 
| 129 | 
            +
              requirements:
         | 
| 130 | 
            +
              - - ! '>='
         | 
| 131 | 
            +
                - !ruby/object:Gem::Version
         | 
| 132 | 
            +
                  version: 1.3.6
         | 
| 133 | 
            +
            requirements: []
         | 
| 134 | 
            +
            rubyforge_project: 
         | 
| 135 | 
            +
            rubygems_version: 1.8.17
         | 
| 136 | 
            +
            signing_key: 
         | 
| 137 | 
            +
            specification_version: 3
         | 
| 138 | 
            +
            summary: A generalized Rack middleware for importing contacts from major email providers.
         | 
| 139 | 
            +
            test_files: []
         |