* VRFS-1083 - twitter mostly working; need to deal with edge cases

This commit is contained in:
Seth Call 2014-02-07 14:07:08 +00:00
parent 47694c5f52
commit b668e54f57
32 changed files with 313 additions and 49 deletions

View File

@ -101,3 +101,4 @@ facebook_signup.sql
audiomixer_mp3.sql
share_token_2.sql
large_photo_url.sql
add_secret_to_user_authorization.sql

View File

@ -0,0 +1 @@
ALTER TABLE user_authorizations ADD COLUMN secret VARCHAR(255);

View File

@ -974,6 +974,48 @@ module JamRuby
end
end
def invalidate_user_authorization(provider)
auth = user_authorization(provider)
auth.destroy if auth
end
def user_authorization(provider)
user_authorizations.where(provider: provider).first
end
def auth_twitter
!user_authorization('twitter').nil?
end
def update_twitter_authorization(auth_hash)
twitter_uid = auth_hash[:uid]
credentials = auth_hash[:credentials]
secret = credentials[:secret] if credentials
token = credentials[:token] if credentials
if twitter_uid && secret && token
user_authorization = nil
unless self.new_record?
# see if this user has an existing user_authorization for this provider
user_authorization = UserAuthorization.find_by_user_id_and_provider(self.id, 'twitter')
end
end
if user_authorization.nil?
self.user_authorizations.build provider: 'twitter',
uid: twitter_uid,
token: token,
secret: secret
else
user_authorization.uid = twitter_uid
user_authorization.token = token
user_authorization.secret = secret
user_authorization.save!
end
end
# updates an existing user_authorization for facebook, or creates a new one if none exist
def update_fb_authorization(fb_signup)
if fb_signup.uid && fb_signup.token && fb_signup.token_expires_at
@ -994,6 +1036,7 @@ module JamRuby
user_authorization.uid = fb_signup.uid
user_authorization.token = fb_signup.token
user_authorization.token_expiration = fb_signup.token_expires_at
user_authorization.save!
end
end
end

View File

@ -1,7 +1,7 @@
module JamRuby
class UserAuthorization < ActiveRecord::Base
attr_accessible :provider, :uid, :token, :token_expiration
attr_accessible :provider, :uid, :token, :token_expiration, :secret
self.table_name = "user_authorizations"

View File

@ -795,6 +795,16 @@
})
}
function tweet(options) {
return $.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/twitter/tweet",
data: JSON.stringify(options)
})
}
function initialize() {
return self;
}
@ -863,6 +873,7 @@
this.login = login;
this.getShareSession = getShareSession;
this.getShareRecording = getShareRecording;
this.tweet = tweet;
return this;
};

View File

@ -54,7 +54,7 @@
if (targetArg) {
targetUrl += "/:" + targetArg;
}
rules[target] = {route: '/' + targetUrl + '/d:?', method: target};
rules[target] = {route: '/' + targetUrl + '/:d?', method: target};
routingContext[target] = fn;
});
routes.context(routingContext);
@ -337,6 +337,7 @@
context.location = url;
}
this.unloadFunction = function() {
logger.debug("window.unload function called.");
@ -359,6 +360,7 @@
this.layout = new context.JK.Layout();
this.layout.initialize(this.opts.layoutOpts);
events();
this.layout.handleDialogState();
if(opts.inClient) {
registerLoginAck();

View File

@ -589,6 +589,29 @@
context.JK.GA.virtualPageView(location.pathname + location.search + location.hash);
}
function handleDialogState() {
var rawDialogState = $.cookie('dialog_state');
try {
var dialogState = JSON.parse(rawDialogState);
if(!dialogState) { $.removeCookie('dialog_state'); return; }
}
catch (e) {$.removeCookie('dialog_state'); return; }
var dialogName = dialogState['name'];
if(dialogName) {
setTimeout(function() {
// TODO: we need a 'everything is initialized' event
showDialog(dialogName);
}, 0);
}
$.removeCookie('dialog_state');
}
// on next page load, a dialog of this name will show
function queueDialog(name) {
$.cookie('dialog_state', JSON.stringify({name:name}))
}
function events() {
$(context).resize(function() {
if (resizing) {
@ -736,6 +759,9 @@
this.closeDialog = closeDialog;
this.handleDialogState = handleDialogState;
this.queueDialog = queueDialog;
/**
* Given information on a grid, and a given card's grid settings, use the
* margin options and return a list of [top, left, width, height]

View File

@ -8,6 +8,8 @@
var facebookRest = context.JK.FacebookRest();
var facebookHelper = null;
var dialogId = '#share-dialog';
var userDetail = null;
var entity = null;
var textMap = {
LIVE_SESSION: "LIVE SESSION",
@ -100,7 +102,33 @@
function handleSessionShareWithTwitter(message) {
var defer = $.Deferred();
defer.resolve(); // remove when implemented
rest.getShareSession({ provider:'twitter', music_session: entityId})
.done(function(data) {
rest.tweet({message: message + ' ' + data.message + ' ' + entity.share_url})
.done(function() {
defer.resolve();
})
.fail(function(jqXHR) {
if(jqXHR.status == 422) {
// implies twitter token error.
app.notify({
title : "Failed to Tweet",
text : "You need to re-authorize JamKazam to access your Twitter account. Click (sign in) in the Share Dialog.",
"icon_url": "/assets/content/icon_alert_big.png"
});
disableTwitter();
}
else {
app.notifyServerError(jqXHR, "Unable to Share with Twitter");
}
defer.reject();
})
})
.fail(function(jqXHR) {
app.notifyServerError(jqXHR, "Unable to Populate Share Data");
defer.reject();
})
return defer;
}
@ -147,6 +175,14 @@
return defer;
}
function messageTooLongForTwitter(message) {
// put user message, then stock content, then url
var maxLength = 140;
var remainingCap = maxLength - 22 - 2; // 22 for shortened url by twitter, 2 is for the two spaces
return message.length > remainingCap;
}
function socialShare() {
var facebookCheckbox = $(dialogId + ' .share-with-facebook input');
var shareWithFacebook = facebookCheckbox.is(':checked') && !facebookCheckbox.is(':disabled');
@ -165,6 +201,11 @@
$(dialogId + ' .share-options').removeClass('error')
}
// validate twitter message length
if(messageTooLongForTwitter(message)) {
$(dialogId + ' .');
}
var message = $(dialogId + ' .share-message').val();
if(!message) { message = undefined; }
@ -217,6 +258,16 @@
$(dialogId + ' .share-with-facebook a').css('visibility', 'visible');
}
function enableTwitter() {
$(dialogId + ' .share-with-twitter input').removeAttr('disabled')
$(dialogId + ' .share-with-twitter a').css('visibility', 'hidden');
}
function disableTwitter() {
$(dialogId + ' .share-with-twitter input').attr('disabled', 'disabled')
$(dialogId + ' .share-with-twitter a').css('visibility', 'visible');
}
function handleFbStateChange(response) {
if(response && response.status == "connected")
@ -237,7 +288,13 @@
$(dialogId + ' .share-with-facebook a').unbind('click').click(function(e) {
facebookHelper.promptLogin();
return false;
})
});
$(dialogId + ' .share-with-twitter a').unbind('click').click(function(e) {
app.layout.queueDialog('share-dialog')
window.location = '/auth/twitter';
return false;
});
}
function showDialog() {
@ -310,6 +367,40 @@
}
function beforeShow() {
disableTwitter();
// no disableFacebook on purpose
if(entityType == 'recording') {
rest.getClaimedRecording(entityId)
.done(function(data) {
entity = data;
$(dialogId + ' .link-contents').text(entity.share_url)
})
.fail(function(jqXHR) {
app.notifyServerError(jqXHR, "Unable to Fetch Session Data");
})
}
else {
rest.getSession(entityId)
.done(function(data) {
entity = data;
$(dialogId + ' .link-contents').text(entity.share_url)
})
.fail(function(jqXHR) {
app.notifyServerError(jqXHR, "Unable to Fetch Session Data");
});
}
rest.getUserDetail()
.done(function(data) {
userDetail = data;
if(data.auth_twitter) {
enableTwitter();
}
else {
disableTwitter();
}
});
$(dialogId + ' .share-options').removeClass('error');
registerEvents(true);
}

View File

@ -2,6 +2,7 @@
//= require jquery_ujs
//= require jquery.queryparams
//= require jquery.hoverIntent
//= require jquery.cookie
//= require AAA_Log
//= require AAC_underscore
//= require globals

View File

@ -0,0 +1,34 @@
class ApiTwittersController < ApiController
before_filter :api_signed_in_user
respond_to :json
rescue_from 'Twitter::Error::Unauthorized' do |exception|
# invalidate current tokens
current_user.invalidate_user_authorization('twitter')
render :json => { :errors => { :token => ["is invalid"] } }, :status => 422
end
def tweet
twitter_auth = current_user.user_authorization('twitter')
raise JamRuby::PermissionError unless twitter_auth
client = Twitter::REST::Client.new do |config|
config.consumer_key = Rails.application.config.twitter_app_id
config.consumer_secret = Rails.application.config.twitter_app_secret
config.access_token = twitter_auth.token
config.access_token_secret = twitter_auth.secret
end
text = params[:message]
client.update(text)
render json: {}, status: :ok
end
end

View File

@ -559,12 +559,18 @@ class ApiUsersController < ApiController
if provider == 'facebook'
render json: {
description: view_context.facebook_description_for_music_session_history(history),
title: view_context.facebook_title_for_music_session_history(history, current_user),
description: view_context.description_for_music_session_history(history),
title: view_context.title_for_music_session_history(history, current_user),
photo_url: view_context.facebook_image_for_music_session_history(history),
caption: 'www.jamkazam.com'
}, status: 200
elsif provider == 'twitter'
render json: {
message: view_context.title_for_music_session_history(history, current_user)
}, status: 200
else
render :json => { :errors => {:provider => ['not valid']} }, :status => 422
end
@ -579,12 +585,19 @@ class ApiUsersController < ApiController
if provider == 'facebook'
render json: {
description: view_context.facebook_description_for_claimed_recording(claimed_recording),
title: view_context.facebook_title_for_claimed_recording(claimed_recording, current_user),
description: view_context.description_for_claimed_recording(claimed_recording),
title: view_context.title_for_claimed_recording(claimed_recording, current_user),
photo_url: view_context.facebook_image_for_claimed_recording(claimed_recording),
caption: 'www.jamkazam.com'
}, status: 200
elsif provider == 'twitter'
render json: {
message: view_context.title_for_claimed_recording(history, current_user) + " at " + request.host_with_port
}, status: 200
else
render :json => { :errors => {:provider => ['not valid']} }, :status => 422
end

View File

@ -1,6 +1,8 @@
# this is not a jam session - this is an 'auth session'
class SessionsController < ApplicationController
layout "web"
def new
@login_error = false
render :layout => "landing"
@ -23,6 +25,7 @@ class SessionsController < ApplicationController
end
end
# OAuth docs
# http://net.tutsplus.com/tutorials/ruby/how-to-use-omniauth-to-authenticate-your-users/
def create_oauth
@ -65,13 +68,19 @@ class SessionsController < ApplicationController
end
# https://github.com/intridea/omniauth/wiki/Saving-User-Location
def oauth_callback
auth_hash = request.env['omniauth.auth']
provider = auth_hash[:provider]
if provider == 'facebook'
if provider == 'twitter'
current_user.update_twitter_authorization(auth_hash)
current_user.save!
redirect_to request.env['omniauth.origin'] || '/'
return
elsif provider == 'facebook'
fb_uid = auth_hash[:uid]
token = auth_hash[:credentials][:token]
token_expiration = Time.at(auth_hash[:credentials][:expires_at])
@ -143,7 +152,7 @@ class SessionsController < ApplicationController
end
def failure
redirect_to request.query_parameters['origin'] || '/'
end
def connection_state

View File

@ -19,7 +19,7 @@ module MusicSessionHelper
end
end
def facebook_title_for_music_session_history(music_session, sharer = nil)
def title_for_music_session_history(music_session, sharer = nil)
if music_session.band
"LIVE SESSION: #{music_session.band.name}"
else
@ -42,7 +42,7 @@ module MusicSessionHelper
end
end
def facebook_description_for_music_session_history(music_session)
def description_for_music_session_history(music_session)
truncate(music_session.description, length:250)
end
end

View File

@ -19,7 +19,7 @@ module RecordingHelper
end
end
def facebook_title_for_claimed_recording(claimed_recording, sharer = nil)
def title_for_claimed_recording(claimed_recording, sharer = nil)
if claimed_recording.recording.band
"RECORDING: #{claimed_recording.recording.band.name}"
else
@ -42,7 +42,7 @@ module RecordingHelper
end
end
def facebook_description_for_claimed_recording(claimed_recording)
def description_for_claimed_recording(claimed_recording)
truncate(claimed_recording.name, length:250)
end
end

View File

@ -10,7 +10,8 @@ end
# give back more info if the user being fetched is yourself
if @user == current_user
attributes :email, :original_fpfile, :cropped_fpfile, :crop_selection, :session_settings, :show_whats_next, :subscribe_email
attributes :email, :original_fpfile, :cropped_fpfile, :crop_selection, :session_settings, :show_whats_next, :subscribe_email, :auth_twitter
elsif current_user
node :is_friend do |uu|
current_user.friends?(@user)

View File

@ -39,10 +39,6 @@
<div class="share-link">
<h3>Share a Link:</h3>
<div class="link-contents">
<% unless true %>
<%= "#{root_url}" %>
<% end %>
http://www.jamkazam.com/SOUt2Az
</div>
<div class="right"><a class="button-orange">COPY LINK</a></div>

View File

@ -6,3 +6,8 @@
<meta property="og:image:width" content="256" />
<meta property="og:image:height" content="256" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@jamkazam">
<meta name="twitter:title" content="JamKazam" />
<meta name="twitter:description" content="Play music together over the Internet as if in the same room." />

View File

@ -14,10 +14,10 @@
<%= include_gon %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
<% if content_for?(:facebook_meta) %>
<%= yield(:facebook_meta) %>
<% if content_for?(:social_meta) %>
<%= yield(:social_meta) %>
<% else %>
<%= render "layouts/facebook_meta" %>
<%= render "layouts/social_meta" %>
<% end %>
</head>
<body>

View File

@ -12,10 +12,10 @@
<%= include_gon(:init => true) %>
<%= javascript_include_tag "corp/corporate" %>
<%= csrf_meta_tags %>
<% if content_for?(:facebook_meta) %>
<%= yield(:facebook_meta) %>
<% if content_for?(:social_meta) %>
<%= yield(:social_meta) %>
<% else %>
<%= render "layouts/facebook_meta" %>
<%= render "layouts/social_meta" %>
<% end %>
</head>
<body class="corporate" data-purpose="<%= yield(:purpose) %>">

View File

@ -14,10 +14,10 @@
<% end %>
<%= include_gon(:init => true) %>
<%= csrf_meta_tags %>
<% if content_for?(:facebook_meta) %>
<%= yield(:facebook_meta) %>
<% if content_for?(:social_meta) %>
<%= yield(:social_meta) %>
<% else %>
<%= render "layouts/facebook_meta" %>
<%= render "layouts/social_meta" %>
<% end %>
</head>
<body>

View File

@ -14,10 +14,10 @@
<% end %>
<%= include_gon(:init => true) %>
<%= csrf_meta_tags %>
<% if content_for?(:facebook_meta) %>
<%= yield(:facebook_meta) %>
<% if content_for?(:social_meta) %>
<%= yield(:social_meta) %>
<% else %>
<%= render "layouts/facebook_meta" %>
<%= render "layouts/social_meta" %>
<% end %>
</head>
<body class="web">
@ -94,6 +94,7 @@
<%= yield(:extra_js) %>
<%= render "shared/ga" %>
<!-- version info: <%= version %> -->
</body>

View File

@ -1,14 +1,19 @@
<% provide(:title, "#{@music_session.description}") %>
<% content_for :facebook_meta do %>
<% content_for :social_meta do %>
<meta property="fb:app_id" content="<%= Rails.application.config.facebook_app_id %>" />
<meta property="og:title" content="<%= facebook_title_for_music_session_history(@music_session) %>" />
<meta property="og:title" content="<%= title_for_music_session_history(@music_session) %>" />
<meta property="og:url" content="<%= request.original_url %>" />
<meta property="og:description" content="<%= facebook_description_for_music_session_history(@music_session) %>" />
<meta property="og:description" content="<%= description_for_music_session_history(@music_session) %>" />
<meta property="og:image" content="<%= facebook_image_for_music_session_history(@music_session) %>" />
<meta property="og:image:width" content="<%= facebook_image_size_for_music_session_history(@music_session) %>" />
<meta property="og:image:height" content="<%= facebook_image_size_for_music_session_history(@music_session) %>" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@jamkazam">
<meta name="twitter:title" content="<%= title_for_music_session_history(@music_session) %>" />
<meta name="twitter:description" content="<%= description_for_music_session_history(@music_session) %>" />
<% end %>
<div class="landing-band">

View File

@ -1,15 +1,20 @@
<% provide(:title, "#{@claimed_recording.name}") %>
<% content_for :facebook_meta do %>
<% content_for :social_meta do %>
<meta property="fb:app_id" content="<%= Rails.application.config.facebook_app_id %>" />
<meta property="og:title" content="<%= facebook_title_for_claimed_recording(@claimed_recording) %>" />
<meta property="og:title" content="<%= title_for_claimed_recording(@claimed_recording) %>" />
<meta property="og:url" content="<%= request.original_url %>" />
<meta property="og:description" content="<%= facebook_description_for_claimed_recording(@claimed_recording) %>" />
<meta property="og:description" content="<%= description_for_claimed_recording(@claimed_recording) %>" />
<meta property="og:image" content="<%= facebook_image_for_claimed_recording(@claimed_recording) %>" />
<meta property="og:image:width" content="<%= facebook_image_size_for_claimed_recording(@claimed_recording) %>" />
<meta property="og:image:height" content="<%= facebook_image_size_for_claimed_recording(@claimed_recording) %>" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@jamkazam">
<meta name="twitter:title" content="<%= title_for_claimed_recording(@claimed_recording) %>" />
<meta name="twitter:description" content="<%= description_for_claimed_recording(@claimed_recording) %>" />
<% end %>
<div class="landing-band">

View File

@ -0,0 +1,3 @@
<script type="text/javascript">
</script>

View File

@ -195,5 +195,8 @@ include JamRuby
config.facebook_app_id = ENV['FACEBOOK_APP_ID'] || '468555793186398'
config.facebook_app_secret = ENV['FACEBOOK_APP_SECRET'] || '546a5b253972f3e2e8b36d9a3dd5a06e'
config.twitter_app_id = ENV['TWITTER_APP_ID'] || 'nQj2oEeoJZxECC33tiTuIg'
config.twitter_app_secret = ENV['TWITTER_APP_SECRET'] || 'Azcy3QqfzYzn2fsojFPYXcn72yfwa0vG6wWDrZ3KT8'
end
end

View File

@ -89,4 +89,7 @@ SampleApp::Application.configure do
config.facebook_app_id = '1412328362347190' # staging
config.facebook_app_secret = '8b1f20430356d44fb49c0a504a9ff401' # staging
config.twitter_app_id = 'RHv0NJod7NLCXH6Kv29LWw' # staging
config.twitter.app_secret = 'ZjLl7rtagTozYDuKKyZNtaTQ4aGFmZPVCO8EoUJmg' # staging
end

View File

@ -62,5 +62,8 @@ SampleApp::Application.configure do
config.facebook_app_id = '1441492266082868'
config.facebook_app_secret = '233bd040a07e47dcec1cff3e490bfce7'
config.twitter_app_id = 'e7hGc71gmcBgo6Wvdta6Sg'
config.twitter_app_secret = 'PfG1jAUMnyrimPcDooUVQaJrG1IuDjUyGg5KciOo'
end

View File

@ -1,5 +1,10 @@
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, Rails.application.config.facebook_app_id, Rails.application.config.facebook_app_secret, {name: "facebook", :scope => 'email,user_location'}
provider :google_oauth2, Rails.application.config.google_client_id, Rails.application.config.google_secret, {name: "google_login", approval_prompt: '', scope: 'userinfo.email, userinfo.profile, https://www.google.com/m8/feeds'}
provider :facebook, Rails.application.config.facebook_app_id, Rails.application.config.facebook_app_secret, {name: "facebook", :scope => 'email,user_location'}
provider :google_oauth2, Rails.application.config.google_client_id, Rails.application.config.google_secret, {name: "google_login", approval_prompt: '', scope: 'userinfo.email, userinfo.profile, https://www.google.com/m8/feeds'}
provider :twitter, Rails.application.config.twitter_app_id, Rails.application.config.twitter_app_secret, {x_auth_access_type: 'write' }
end
# https://github.com/intridea/omniauth/wiki/FAQ
OmniAuth.config.on_failure = Proc.new { |env|
OmniAuth::FailureEndpoint.new(env).redirect_to_failure
}

View File

@ -343,6 +343,8 @@ SampleApp::Application.routes.draw do
match '/icecast/mount_remove' => 'api_icecast#mount_remove', :via => :post
match '/icecast/listener_add' => 'api_icecast#listener_add', :via => :post
match '/icecast/listener_remove' => 'api_icecast#listener_remove', :via => :post
match '/twitter/tweet' => 'api_twitters#tweet', :via => :post
end
end

View File

@ -70,7 +70,7 @@ describe "facebook metadata" do
visit "/sessions/#{music_session.id}"
page.find('meta[property="fb:app_id"]', :visible => false)['content'].should == Rails.application.config.facebook_app_id
page.find('meta[property="og:title"]', :visible => false)['content'].should == facebook_title_for_music_session_history(music_session.music_session_history)
page.find('meta[property="og:title"]', :visible => false)['content'].should == title_for_music_session_history(music_session.music_session_history)
page.find('meta[property="og:url"]', :visible => false)['content'].include?("/sessions/#{music_session.id}").should be_true
page.find('meta[property="og:description"]', :visible => false)['content'].should == music_session.music_session_history.description
page.find('meta[property="og:image"]', :visible => false)['content'].include?("/assets/web/logo-256.png").should be_true
@ -103,7 +103,7 @@ describe "facebook metadata" do
visit "/recordings/#{@claimed_recording.id}"
page.find('meta[property="fb:app_id"]', :visible => false)['content'].should == Rails.application.config.facebook_app_id
page.find('meta[property="og:title"]', :visible => false)['content'].should == facebook_title_for_claimed_recording(@claimed_recording)
page.find('meta[property="og:title"]', :visible => false)['content'].should == title_for_claimed_recording(@claimed_recording)
page.find('meta[property="og:url"]', :visible => false)['content'].include?("/recordings/#{@claimed_recording.id}").should be_true
page.find('meta[property="og:description"]', :visible => false)['content'].should == @claimed_recording.name
page.find('meta[property="og:image"]', :visible => false)['content'].include?("/assets/web/logo-256.png").should be_true

View File

@ -42,17 +42,17 @@ describe MusicSessionHelper do
end
end
describe "facebook_title_for_music_session_history" do
describe "title_for_music_session_history" do
it "with band" do
music_session = FactoryGirl.create(:music_session, band: FactoryGirl.create(:band), creator: FactoryGirl.create(:user))
result = helper.facebook_title_for_music_session_history(music_session.music_session_history)
result = helper.title_for_music_session_history(music_session.music_session_history)
result.start_with?("LIVE SESSION").should be_true
result.end_with?(music_session.band.name).should be_true
end
it "with user" do
music_session = FactoryGirl.create(:music_session, creator: FactoryGirl.create(:user))
result = helper.facebook_title_for_music_session_history(music_session.music_session_history)
result = helper.title_for_music_session_history(music_session.music_session_history)
result.start_with?("LIVE SESSION").should be_true
result.end_with?(music_session.music_session_history.user.name).should be_true
end

View File

@ -63,18 +63,18 @@ describe MusicSessionHelper do
end
end
describe "facebook_title_for_claimed_recording" do
describe "title_for_claimed_recording" do
it "with band" do
@recording.band = FactoryGirl.create(:band)
@recording.save!(:validate => false)
@claimed_recording.reload
result = helper.facebook_title_for_claimed_recording(@claimed_recording)
result = helper.title_for_claimed_recording(@claimed_recording)
result.start_with?("RECORDING").should be_true
result.end_with?(@claimed_recording.recording.band.name).should be_true
end
it "with user" do
result = helper.facebook_title_for_claimed_recording(@claimed_recording)
result = helper.title_for_claimed_recording(@claimed_recording)
result.start_with?("RECORDING").should be_true
result.end_with?(@claimed_recording.user.name).should be_true
end