move twitter to gem

fixes: CNVS-12492

test-plan:
* Test that all things Twitter related still work

Change-Id: Ib656c5bfcb2dc8490a6fa6f214b0f6dce25ad181
Reviewed-on: https://gerrit.instructure.com/33193
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Trevor deHaan <tdehaan@instructure.com>
Reviewed-by: Mike Nomitch <mnomitch@instructure.com>
Reviewed-by: Liz Abinante <labinante@instructure.com>
Product-Review: Simon Williams <simon@instructure.com>
This commit is contained in:
Raphael Weiner 2014-04-14 11:30:13 -06:00 committed by Simon Williams
parent 8eeb4f5bf0
commit a13f85e0ed
20 changed files with 128 additions and 52 deletions

View File

@ -140,6 +140,7 @@ gem 'linked_in', :path => 'gems/linked_in'
gem 'lti_outbound', :path => 'gems/lti_outbound'
gem 'multipart', :path => 'gems/multipart'
gem 'paginated_collection', :path => 'gems/paginated_collection'
gem 'twitter', :path => 'gems/twitter'
gem 'utf8_cleaner', :path => 'gems/utf8_cleaner'
gem 'workflow', :path => 'gems/workflow'

View File

@ -1290,7 +1290,7 @@ class ApplicationController < ActionController::Base
if [:question_banks].include?(feature)
true
elsif feature == :twitter
!!Twitter.config
!!Twitter::Connection.config
elsif feature == :facebook
!!Facebook.config
elsif feature == :linked_in
@ -1760,9 +1760,9 @@ class ApplicationController < ActionController::Base
def twitter_connection
if @current_user
service = @current_user.user_services.find_by_service("twitter")
return Twitter.new(service.token, service.secret)
return Twitter::Connection.new(service.token, service.secret)
else
return Twitter.new(session[:oauth_twitter_access_token_token], session[:oauth_twitter_access_token_secret])
return Twitter::Connection.new(session[:oauth_twitter_access_token_token], session[:oauth_twitter_access_token_secret])
end
end
end

View File

@ -155,7 +155,7 @@ class UsersController < ApplicationController
redirect_to request_token.authorize_url
elsif params[:service] == "twitter"
success_url = oauth_success_url(:service => 'twitter')
request_token = Twitter.request_token(success_url)
request_token = Twitter::Connection.request_token(success_url)
OauthRequest.create(
:service => 'twitter',
:token => request_token.token,
@ -271,7 +271,7 @@ class UsersController < ApplicationController
end
else
begin
twitter = Twitter.new(oauth_request.token, oauth_request.secret)
twitter = Twitter::Connection.new(oauth_request.token, oauth_request.secret)
access_token = twitter.get_access_token(oauth_request.token, oauth_request.secret, params[:oauth_verifier])
service_user_id, service_user_name = twitter.get_service_user(access_token)
if oauth_request.user

View File

@ -1160,7 +1160,7 @@ class Account < ActiveRecord::Base
:twitter => {
:name => t("account_settings.twitter", "Twitter"),
:description => "",
:expose_to_ui => (Twitter.config ? :service : false)
:expose_to_ui => (Twitter::Connection.config ? :service : false)
},
:delicious => {
:name => t("account_settings.delicious", "Delicious"),

View File

@ -662,7 +662,9 @@ class Message < ActiveRecord::Base
# Returns nothing.
def deliver_via_twitter
twitter_service = user.user_services.find_by_service('twitter')
TwitterMessenger.new(self, twitter_service).deliver
host = HostUrl.short_host(self.asset_context)
msg_id = AssetSignature.generate(self)
Twitter::Messenger.new(self, twitter_service, host, msg_id).deliver
complete_dispatch
end

View File

@ -0,0 +1,3 @@
Twitter::Connection.config = Proc.new do
Canvas::Plugin.find(:twitter).try(:settings) || Setting.from_config('twitter')
end

7
gems/twitter/Gemfile Normal file
View File

@ -0,0 +1,7 @@
source 'https://rubygems.org'
# Specify your gem's dependencies in twitter.gemspec
gemspec
gem 'html_text_helper', path: '../html_text_helper'
gem 'canvas_text_helper', path: '../canvas_text_helper'

View File

@ -0,0 +1,6 @@
require "html_text_helper"
module Twitter
require "twitter/connection"
require "twitter/messenger"
end

View File

@ -16,7 +16,8 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class Twitter
module Twitter
class Connection
def initialize(oauth_access_token, oauth_access_token_secret)
@oauth_access_token = oauth_access_token
@oauth_access_token_secret = oauth_access_token_secret
@ -90,10 +91,10 @@ class Twitter
def self.twitter_consumer(key=nil, secret=nil)
require 'oauth'
require 'oauth/consumer'
twitter_config = Twitter.config
twitter_config = Twitter::Connection.config
key ||= twitter_config['api_key']
secret ||= twitter_config['secret_key']
consumer = OAuth::Consumer.new(key, secret, {
OAuth::Consumer.new(key, secret, {
:site => "https://api.twitter.com",
:request_token_path => "/oauth/request_token",
:access_token_path => "/oauth/access_token",
@ -108,7 +109,15 @@ class Twitter
token ? nil : "Configuration check failed, please check your settings"
end
def self.config=(config)
if !config.is_a?(Proc)
raise "Config must be a Proc"
end
@config = config
end
def self.config
Canvas::Plugin.find(:twitter).try(:settings) || Setting.from_config('twitter')
@config.call()
end
end
end

View File

@ -1,18 +1,19 @@
class TwitterMessenger
include TextHelper
module Twitter
class Messenger
attr_reader :message
delegate :asset_context, :to => :message
attr_reader :host
attr_reader :id
def initialize(message, twitter_service)
def initialize(message, twitter_service, host, id)
@message = message
@twitter_service = twitter_service
@host = host
@id = id
end
def deliver
return unless @twitter_service
twitter_connection = Twitter.new(@twitter_service.token, @twitter_service.secret)
twitter_connection = Twitter::Connection.new(@twitter_service.token, @twitter_service.secret)
twitter_connection.send_direct_message(@twitter_service.service_user_name, @twitter_service.service_user_id, "#{body}")
end
@ -20,16 +21,13 @@ class TwitterMessenger
message.main_link || message.url || "http://#{host}/mr/#{id}"
end
def id
AssetSignature.generate(@message)
end
def body
truncated_body = HtmlTextHelper.strip_and_truncate(message.body, :max_length => (139 - url.length))
"#{truncated_body} #{url}"
end
def host
HostUrl.short_host(asset_context)
def asset_context
@message.asset_context
end
end
end

View File

@ -0,0 +1,5 @@
en:
lib:
text_helper:
ellipsis: "..."
word_separator: " "

View File

@ -0,0 +1,15 @@
require 'twitter'
require 'mocha'
I18n.load_path += Dir[File.join('spec','locales','*.yml')]
RSpec.configure do |config|
config.treat_symbols_as_metadata_keys_with_true_values = true
config.run_all_when_everything_filtered = true
config.filter_run :focus
config.order = 'random'
config.mock_framework = :mocha
end

View File

@ -0,0 +1,5 @@
require 'spec_helper'
describe Twitter::Connection do
xit "Test the usage of the Twitter API, see the google_docs gem for inspiration"
end

View File

@ -1,9 +1,6 @@
require File.expand_path('../spec_helper', File.dirname(__FILE__))
describe TwitterMessenger do
before { HostUrl.stubs(:short_host => 'host') }
require 'spec_helper'
describe Twitter::Messenger do
let(:message) { stub() }
let(:twitter_service) { stub({
token: "twitter_token",
@ -11,7 +8,8 @@ describe TwitterMessenger do
service_user_name: "twitter_name",
service_user_id: "twitter_id"
}) }
let(:messenger) { TwitterMessenger.new(message, twitter_service) }
let(:id) { "ABC123" }
let(:messenger) { Twitter::Messenger.new(message, twitter_service, 'host', id) }
describe '#deliver' do
@ -22,7 +20,7 @@ describe TwitterMessenger do
context "with a twitter service" do
before(:each) do
Twitter.expects(:new).with("twitter_token", "twitter_secret").returns(connection_mock)
Twitter::Connection.expects(:new).with("twitter_token", "twitter_secret").returns(connection_mock)
end
it 'delegates to the twitter module if a service is available' do
@ -32,7 +30,7 @@ describe TwitterMessenger do
end
context "with no twitter service" do
let(:messenger) { TwitterMessenger.new(message, nil) }
let(:messenger) { Twitter::Messenger.new(message, nil, 'host', id) }
it 'sends nothing if there is no service' do
connection_mock.expects(:send_direct_message).never
messenger.deliver.should be_nil
@ -45,7 +43,7 @@ describe TwitterMessenger do
subject { messenger.url }
it { should =~ /host/ }
it { should =~ /#{AssetSignature.generate(message)}$/ }
it { should =~ /#{id}$/ }
it { should =~ /^http:\/\// }
end
@ -64,15 +62,4 @@ describe TwitterMessenger do
messenger.body.should == "An extremely long body that might need to be cut down a bit if w... http://learn.canvas.net/super/long/url/which/will/be/minified/by/twitter"
end
end
describe '#host' do
let(:context) { stub }
let(:message) { stub(:asset_context => context) }
it 'delegates to the HostUrl lib' do
HostUrl.expects(:short_host).with(context)
messenger.host
end
end
end

15
gems/twitter/test.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
result=0
rm -f Gemfile.lock
bundle install
bundle exec rspec spec
let result=$result+$?
if [ $result -eq 0 ]; then
echo "SUCCESS"
else
echo "FAILURE"
fi
exit $result

View File

@ -0,0 +1,23 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
Gem::Specification.new do |spec|
spec.name = "twitter"
spec.version = "1.0.0"
spec.authors = ["Raphael Weiner"]
spec.email = ["rweiner@pivotallabs.com"]
spec.summary = %q{Gem for posting to Twitter}
spec.files = Dir.glob("{lib,spec}/**/*") + %w(test.sh)
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_dependency "html_text_helper"
spec.add_development_dependency "bundler", "~> 1.5"
spec.add_development_dependency "rake"
spec.add_development_dependency "rspec"
spec.add_development_dependency "mocha"
end

View File

@ -25,7 +25,7 @@ module Canvas::Plugins::Validators::TwitterValidator
plugin_setting.errors.add(:base, I18n.t('canvas.plugins.errors.all_fields_required', 'All fields are required'))
false
else
res = Twitter.config_check(settings)
res = Twitter::Connection.config_check(settings)
if res
plugin_setting.errors.add(:base, res)
false

View File

@ -36,7 +36,7 @@ describe ApplicationController do
mock_current_user.expects(:user_services).returns(mock_user_services)
mock_user_services.expects(:find_by_service).with("twitter").returns(mock(token: "current_user_token", secret: "current_user_secret"))
Twitter.expects(:new).with("current_user_token", "current_user_secret")
Twitter::Connection.expects(:new).with("current_user_token", "current_user_secret")
controller.send(:twitter_connection)
end
@ -45,7 +45,7 @@ describe ApplicationController do
session[:oauth_twitter_access_token_token] = "session_token"
session[:oauth_twitter_access_token_secret] = "sesion_secret"
Twitter.expects(:new).with("session_token", "sesion_secret")
Twitter::Connection.expects(:new).with("session_token", "sesion_secret")
controller.send(:twitter_connection)
end

View File

@ -31,7 +31,7 @@ describe integration do
elsif integration == "GoogleDocs"
GoogleDocs::Connection.expects(:config).at_least_once.returns({})
elsif integration == "Twitter"
Twitter.expects(:config).at_least_once.returns({})
Twitter::Connection.expects(:config).at_least_once.returns({})
else
integration.constantize.expects(:config).at_least_once.returns({})
end
@ -102,7 +102,7 @@ describe integration do
elsif integration == "LinkedIn"
LinkedIn::Connection.any_instance.expects(:get_service_user_info).with(instance_of(OAuth::AccessToken)).returns(["test_user_id", "test_user_name"])
elsif integration == "Twitter"
Twitter.any_instance.expects(:get_service_user).returns(["test_user_id", "test_user_name"])
Twitter::Connection.any_instance.expects(:get_service_user).returns(["test_user_id", "test_user_name"])
else
UsersController.any_instance.expects("#{integration.underscore}_get_service_user").with(instance_of(OAuth::AccessToken)).returns(["test_user_id", "test_user_name"])
end
@ -131,7 +131,7 @@ describe integration do
elsif integration == "LinkedIn"
LinkedIn::Connection.any_instance.expects(:get_service_user_info).with(instance_of(OAuth::AccessToken)).raises(RuntimeError, "Third-party service totally like, failed")
elsif integration == "Twitter"
Twitter.any_instance.expects(:get_service_user).raises(RuntimeError, "Third-party service totally like, failed")
Twitter::Connection.any_instance.expects(:get_service_user).raises(RuntimeError, "Third-party service totally like, failed")
else
UsersController.any_instance.expects("#{integration.underscore}_get_service_user").with(instance_of(OAuth::AccessToken)).raises(RuntimeError, "Third-party service totally like, failed")
end

View File

@ -12,7 +12,7 @@ describe "default plugins" do
settings = Canvas::Plugin.find(:twitter).try(:settings)
settings.should be_nil
Twitter.stubs(:config_check).returns("Bad check")
Twitter::Connection.stubs(:config_check).returns("Bad check")
get "/plugins/twitter"
multiple_accounts_select
@ -24,7 +24,7 @@ describe "default plugins" do
assert_flash_error_message /There was an error/
Twitter.stubs(:config_check).returns(nil)
Twitter::Connection.stubs(:config_check).returns(nil)
submit_form('#new_plugin_setting')
wait_for_ajax_requests