Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gem cleanup, working specs in 1.9.2 #14

Merged
merged 3 commits into from Aug 1, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
pkg
Gemfile.lock
3 changes: 3 additions & 0 deletions Gemfile
@@ -0,0 +1,3 @@
source :rubygems

gemspec
83 changes: 41 additions & 42 deletions lib/twilio-ruby.rb
Expand Up @@ -3,50 +3,49 @@
require 'net/http'
require 'net/https'
require 'builder'
require 'json'
require 'multi_json'
require 'cgi'
require 'openssl'
require 'base64'
require 'jwt'


require "#{TWILIO_RUBY_ROOT}/twilio-ruby/util"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/util/request_validator"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/util/capability"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/errors"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/utils"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/list_resource"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/instance_resource"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/sandbox/sandbox"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/accounts/account"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/accounts/accounts"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/calls/call"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/calls/calls"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/sms/sms"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/sms/message"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/sms/messages"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/sms/short_code"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/sms/short_codes"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/applications/application"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/applications/applications"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/outgoing_caller_ids/outgoing_caller_id"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/outgoing_caller_ids/outgoing_caller_ids"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/incoming_phone_numbers/incoming_phone_number"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/incoming_phone_numbers/incoming_phone_numbers"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/available_phone_numbers/available_phone_number"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/available_phone_numbers/available_phone_numbers"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/available_phone_numbers/country"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/available_phone_numbers/local"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/available_phone_numbers/toll_free"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/conferences/conference"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/conferences/conferences"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/conferences/participant"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/conferences/participants"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/recordings/recording"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/recordings/recordings"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/transcriptions/transcription"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/transcriptions/transcriptions"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/notifications/notification"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/notifications/notifications"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/rest/client"
require "#{TWILIO_RUBY_ROOT}/twilio-ruby/twiml/response"
require "twilio-ruby/util"
require "twilio-ruby/util/request_validator"
require "twilio-ruby/util/capability"
require "twilio-ruby/rest/errors"
require "twilio-ruby/rest/utils"
require "twilio-ruby/rest/list_resource"
require "twilio-ruby/rest/instance_resource"
require "twilio-ruby/rest/sandbox/sandbox"
require "twilio-ruby/rest/accounts/account"
require "twilio-ruby/rest/accounts/accounts"
require "twilio-ruby/rest/calls/call"
require "twilio-ruby/rest/calls/calls"
require "twilio-ruby/rest/sms/sms"
require "twilio-ruby/rest/sms/message"
require "twilio-ruby/rest/sms/messages"
require "twilio-ruby/rest/sms/short_code"
require "twilio-ruby/rest/sms/short_codes"
require "twilio-ruby/rest/applications/application"
require "twilio-ruby/rest/applications/applications"
require "twilio-ruby/rest/outgoing_caller_ids/outgoing_caller_id"
require "twilio-ruby/rest/outgoing_caller_ids/outgoing_caller_ids"
require "twilio-ruby/rest/incoming_phone_numbers/incoming_phone_number"
require "twilio-ruby/rest/incoming_phone_numbers/incoming_phone_numbers"
require "twilio-ruby/rest/available_phone_numbers/available_phone_number"
require "twilio-ruby/rest/available_phone_numbers/available_phone_numbers"
require "twilio-ruby/rest/available_phone_numbers/country"
require "twilio-ruby/rest/available_phone_numbers/local"
require "twilio-ruby/rest/available_phone_numbers/toll_free"
require "twilio-ruby/rest/conferences/conference"
require "twilio-ruby/rest/conferences/conferences"
require "twilio-ruby/rest/conferences/participant"
require "twilio-ruby/rest/conferences/participants"
require "twilio-ruby/rest/recordings/recording"
require "twilio-ruby/rest/recordings/recordings"
require "twilio-ruby/rest/transcriptions/transcription"
require "twilio-ruby/rest/transcriptions/transcriptions"
require "twilio-ruby/rest/notifications/notification"
require "twilio-ruby/rest/notifications/notifications"
require "twilio-ruby/rest/client"
require "twilio-ruby/twiml/response"
2 changes: 1 addition & 1 deletion lib/twilio-ruby/rest/client.rb
Expand Up @@ -83,7 +83,7 @@ def set_up_subresources

def connect_and_send(request)
response = @connection.request request
object = JSON.parse response.body if response.body
object = MultiJson.decode(response.body) if response.body
if response.kind_of? Net::HTTPClientError
raise Twilio::REST::RequestError, object['message']
elsif response.kind_of? Net::HTTPServerError
Expand Down
53 changes: 34 additions & 19 deletions test/twilio_spec.rb
@@ -1,6 +1,7 @@
require 'rubygems'
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
require 'twilio-ruby'
require 'fakeweb'
require 'rack'

describe Twilio::REST::Client do
before :all do
Expand Down Expand Up @@ -214,6 +215,10 @@
@capability = Twilio::Util::Capability.new 'myAccountSid', 'myAuthToken'
end

def queries(q)
q.scan(/scope:client:(incoming|outgoing)\?(\S+)/).map{|(type, query)| [type, Rack::Utils.parse_query(query)]}
end

it 'should return a valid jwt when #generate is called' do
token = @capability.generate
decoded = JWT.decode token, 'myAuthToken'
Expand Down Expand Up @@ -245,29 +250,27 @@

it 'should generate a proper incoming client scope string' do
@capability.allow_client_incoming 'andrew'
expected_scope = 'scope:client:incoming?clientName=andrew'
token = @capability.generate
decoded = JWT.decode token, 'myAuthToken'
decoded['scope'].include?(expected_scope).should be_true
queries(decoded['scope']).should == [['incoming', {'clientName' => 'andrew'}]]
end

it 'should generate multiple proper incoming client scope strings' do
@capability.allow_client_incoming 'andrew'
@capability.allow_client_incoming 'bridget'
expected_scope_one = 'scope:client:incoming?clientName=andrew'
expected_scope_two = 'scope:client:incoming?clientName=bridget'
token = @capability.generate
decoded = JWT.decode token, 'myAuthToken'
decoded['scope'].include?(expected_scope_one).should be_true
decoded['scope'].include?(expected_scope_two).should be_true
queries(decoded['scope']).should == [
['incoming', {'clientName' => 'andrew'}],
['incoming', {'clientName' => 'bridget'}]
]
end

it 'should generate a proper outgoing client scope string' do
@capability.allow_client_outgoing 'myAppSid'
expected_scope = 'scope:client:outgoing?appSid=myAppSid'
token = @capability.generate
decoded = JWT.decode token, 'myAuthToken'
decoded['scope'].include?(expected_scope).should be_true
queries(decoded['scope']).should == [['outgoing', {'appSid' => 'myAppSid'}]]
end

it 'should generate a proper outgoing client scope string with parameters' do
Expand All @@ -276,30 +279,30 @@
app_params = @capability.instance_eval {url_encode(app_params_hash)}
params_hash = {'appSid' => 'myAppSid', 'appParams' => app_params}
params = @capability.instance_eval {url_encode(params_hash)}
expected_scope = "scope:client:outgoing?#{params}"
token = @capability.generate
decoded = JWT.decode token, 'myAuthToken'
decoded['scope'].include?(expected_scope).should be_true
queries(decoded['scope']).should == [['outgoing', params_hash]]
end

it 'should generate a proper outgoing client scope string based on the ' +
'client name when calling #allow_client_incoming first' do
@capability.allow_client_incoming 'andrew'
@capability.allow_client_outgoing 'myAppSid'
expected_scope = 'scope:client:outgoing?clientName=andrew&appSid=myAppSid'
token = @capability.generate
decoded = JWT.decode token, 'myAuthToken'
decoded['scope'].include?(expected_scope).should be_true
queries(decoded['scope']).should == [
['incoming', {'clientName' => 'andrew'}],
['outgoing', {'clientName' => 'andrew', 'appSid' => 'myAppSid'}]
]
end

it 'should generate a proper outgoing client scope string based on the ' +
'client name when calling #allow_client_incoming second' do
@capability.allow_client_outgoing 'myAppSid'
@capability.allow_client_incoming 'andrew'
expected_scope = 'scope:client:outgoing?clientName=andrew&appSid=myAppSid'
token = @capability.generate
decoded = JWT.decode token, 'myAuthToken'
decoded['scope'].include?(expected_scope).should be_true
queries(decoded['scope']).should == [["incoming", {"clientName"=>"andrew"}], ["outgoing", {"clientName"=>"andrew", "appSid"=>"myAppSid"}]]
end

it 'should generate a proper outgoing client scope string with parameters ' +
Expand All @@ -310,10 +313,16 @@
app_params = @capability.instance_eval {url_encode(app_params_hash)}
params_hash = {'appSid' => 'myAppSid', 'appParams' => app_params, 'clientName' => 'andrew'}
params = @capability.instance_eval {url_encode(params_hash)}
expected_scope = "scope:client:outgoing?#{params}"
token = @capability.generate
decoded = JWT.decode token, 'myAuthToken'
decoded['scope'].include?(expected_scope).should be_true
scopes = queries(decoded['scope'])
scopes.shift.should == ["incoming", {"clientName"=>"andrew"}]
scope = scopes.shift
scope.first.should == 'outgoing'
Rack::Utils.parse_query(scope.last['appParams']).should == {'key' => 'a value', 'foo' => 'bar/baz'}
scope.last["clientName"].should == "andrew"
scope.last["appSid"].should == "myAppSid"
scopes.should be_empty
end

it 'should generate a proper outgoing client scope string with parameters ' +
Expand All @@ -324,9 +333,15 @@
app_params = @capability.instance_eval {url_encode(app_params_hash)}
params_hash = {'appSid' => 'myAppSid', 'appParams' => app_params, 'clientName' => 'andrew'}
params = @capability.instance_eval {url_encode(params_hash)}
expected_scope = "scope:client:outgoing?#{params}"
token = @capability.generate
decoded = JWT.decode token, 'myAuthToken'
decoded['scope'].include?(expected_scope).should be_true
scopes = queries(decoded['scope'])
scopes.shift.should == ["incoming", {"clientName"=>"andrew"}]
scope = scopes.shift
scope.first.should == 'outgoing'
Rack::Utils.parse_query(scope.last['appParams']).should == {'key' => 'a value', 'foo' => 'bar/baz'}
scope.last["clientName"].should == "andrew"
scope.last["appSid"].should == "myAppSid"
scopes.should be_empty
end
end
17 changes: 12 additions & 5 deletions twilio-ruby.gemspec
Expand Up @@ -7,9 +7,16 @@ Gem::Specification.new do |s|
s.summary = "A simple library for communicating with the Twilio REST API, building TwiML, and generating Twilio Client Capability Tokens"
s.homepage = "http://github.com/twilio/twilio-ruby"
s.platform = Gem::Platform::RUBY
s.files = Dir['lib/**/*.rb'] + Dir['test/**/*.rb'] + ['examples.rb', 'Rakefile', 'LICENSE', 'README.md', 'twilio-ruby.gemspec']
s.test_files = Dir['test/**/*.rb']
s.add_dependency("json", ">= 1.2.0")
s.add_dependency("builder", ">= 2.1.2")
s.add_dependency("jwt", ">= 0.1.2")
s.extra_rdoc_files = ['README.md', 'LICENSE']
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files`.split("\n").select{|f| f =~ /^test/}

s.add_dependency "multi_json", "~> 1.0.3"
s.add_dependency "builder", "~> 2.1.2"
s.add_dependency "jwt", "~> 0.1.2"

s.add_development_dependency "rake", "~> 0.9.0"
s.add_development_dependency "rspec", "~> 2.6.0"
s.add_development_dependency "fakeweb", "~> 1.3.0"
s.add_development_dependency "rack", "~> 1.3.0"
end