diff --git a/db/Gemfile.lock b/db/Gemfile.lock index 0b59faefa..072f29905 100644 --- a/db/Gemfile.lock +++ b/db/Gemfile.lock @@ -1,5 +1,5 @@ GEM - remote: https://rubygems.org/ + remote: http://rubygems.org/ specs: little-plugger (1.1.3) logging (1.7.2) diff --git a/db/manifest b/db/manifest index 042e0661c..433725f19 100755 --- a/db/manifest +++ b/db/manifest @@ -98,4 +98,5 @@ invited_users_facebook_support.sql first_recording_at.sql share_token.sql facebook_signup.sql -audiomixer_mp3.sql \ No newline at end of file +audiomixer_mp3.sql +large_photo_url.sql \ No newline at end of file diff --git a/db/up/large_photo_url.sql b/db/up/large_photo_url.sql new file mode 100644 index 000000000..990d1c709 --- /dev/null +++ b/db/up/large_photo_url.sql @@ -0,0 +1,7 @@ +ALTER TABLE users ADD COLUMN large_photo_url VARCHAR(2048); +ALTER TABLE users ADD COLUMN cropped_large_s3_path VARCHAR(512); +ALTER TABLE users ADD COLUMN cropped_large_fpfile VARCHAR(8000); + +ALTER TABLE bands ADD COLUMN large_photo_url VARCHAR(2048); +ALTER TABLE bands ADD COLUMN cropped_large_s3_path_photo VARCHAR(512); +ALTER TABLE bands ADD COLUMN cropped_large_fpfile_photo VARCHAR(8000); \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/band.rb b/ruby/lib/jam_ruby/models/band.rb index e40817623..f542e30e1 100644 --- a/ruby/lib/jam_ruby/models/band.rb +++ b/ruby/lib/jam_ruby/models/band.rb @@ -2,8 +2,8 @@ module JamRuby class Band < ActiveRecord::Base attr_accessible :name, :website, :biography, :city, :state, - :country, :original_fpfile_photo, :cropped_fpfile_photo, - :cropped_s3_path_photo, :crop_selection_photo, :photo_url + :country, :original_fpfile_photo, :cropped_fpfile_photo, :cropped_large_fpfile_photo, + :cropped_s3_path_photo, :cropped_large_s3_path_photo, :crop_selection_photo, :photo_url, :large_photo_url attr_accessor :updating_photo @@ -88,6 +88,7 @@ module JamRuby # we want to mak sure that original_fpfile and cropped_fpfile seems like real fpfile info objects (i.e, json objects from filepicker.io) errors.add(:original_fpfile_photo, ValidationMessages::INVALID_FPFILE) if self.original_fpfile_photo.nil? || self.original_fpfile_photo["key"].nil? || self.original_fpfile_photo["url"].nil? errors.add(:cropped_fpfile_photo, ValidationMessages::INVALID_FPFILE) if self.cropped_fpfile_photo.nil? || self.cropped_fpfile_photo["key"].nil? || self.cropped_fpfile_photo["url"].nil? + errors.add(:cropped_large_fpfile_photo, ValidationMessages::INVALID_FPFILE) if self.cropped_large_fpfile_photo.nil? || self.cropped_large_fpfile_photo["key"].nil? || self.cropped_large_fpfile_photo["url"].nil? end end @@ -196,18 +197,21 @@ module JamRuby return band end - def update_photo(original_fpfile, cropped_fpfile, crop_selection, aws_bucket) + def update_photo(original_fpfile, cropped_fpfile, cropped_large_fpfile, crop_selection, aws_bucket) self.updating_photo = true cropped_s3_path = cropped_fpfile["key"] + cropped_large_s3_path = cropped_large_fpfile["key"] return self.update_attributes( :original_fpfile_photo => original_fpfile, :cropped_fpfile_photo => cropped_fpfile, + :cropped_large_fpfile_photo => cropped_large_fpfile, :cropped_s3_path_photo => cropped_s3_path, + :cropped_large_s3_path_photo => cropped_large_s3_path, :crop_selection_photo => crop_selection, - :photo_url => S3Util.url(aws_bucket, cropped_s3_path, :secure => false) - ) + :photo_url => S3Util.url(aws_bucket, cropped_s3_path, :secure => false), + :large_photo_url => S3Util.url(aws_bucket, cropped_large_s3_path, :secure => false)) end def delete_photo(aws_bucket) @@ -217,15 +221,18 @@ module JamRuby unless self.cropped_s3_path_photo.nil? S3Util.delete(aws_bucket, File.dirname(self.cropped_s3_path_photo) + '/cropped.jpg') S3Util.delete(aws_bucket, self.cropped_s3_path_photo) + S3Util.delete(aws_bucket, self.cropped_large_s3_path_photo) end return self.update_attributes( :original_fpfile_photo => nil, :cropped_fpfile_photo => nil, + :cropped_large_fpfile_photo => nil, :cropped_s3_path_photo => nil, + :cropped_large_s3_path_photo => nil, :crop_selection_photo => nil, - :photo_url => nil - ) + :photo_url => nil, + :large_photo_url => nil) end end diff --git a/ruby/lib/jam_ruby/models/music_session_history.rb b/ruby/lib/jam_ruby/models/music_session_history.rb index 8b3c787d3..4beae36d9 100644 --- a/ruby/lib/jam_ruby/models/music_session_history.rb +++ b/ruby/lib/jam_ruby/models/music_session_history.rb @@ -124,6 +124,10 @@ module JamRuby session_history.save! end + def is_over? + !session_removed_at.nil? + end + def end_history self.update_attribute(:session_removed_at, Time.now) diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index e137b8a81..8496ea897 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -13,7 +13,7 @@ module JamRuby after_save :check_lat_lng - attr_accessible :first_name, :last_name, :email, :city, :password, :password_confirmation, :state, :country, :birth_date, :subscribe_email, :terms_of_service, :original_fpfile, :cropped_fpfile, :cropped_s3_path, :photo_url, :crop_selection, :lat, :lng + attr_accessible :first_name, :last_name, :email, :city, :password, :password_confirmation, :state, :country, :birth_date, :subscribe_email, :terms_of_service, :original_fpfile, :cropped_fpfile, :cropped_large_fpfile, :cropped_s3_path, :cropped_large_s3_path, :photo_url, :large_photo_url, :crop_selection, :lat, :lng # updating_password corresponds to a lost_password attr_accessor :updating_password, :updating_email, :updated_email, :update_email_confirmation_url, :administratively_created, :current_password, :setting_password, :confirm_current_password, :updating_avatar, :updating_progression_field @@ -187,6 +187,7 @@ module JamRuby # we want to mak sure that original_fpfile and cropped_fpfile seems like real fpfile info objects (i.e, json objects from filepicker.io) errors.add(:original_fpfile, ValidationMessages::INVALID_FPFILE) if self.original_fpfile.nil? || self.original_fpfile["key"].nil? || self.original_fpfile["url"].nil? errors.add(:cropped_fpfile, ValidationMessages::INVALID_FPFILE) if self.cropped_fpfile.nil? || self.cropped_fpfile["key"].nil? || self.cropped_fpfile["url"].nil? + errors.add(:cropped_large_fpfile, ValidationMessages::INVALID_FPFILE) if self.cropped_large_fpfile.nil? || self.cropped_large_fpfile["key"].nil? || self.cropped_large_fpfile["url"].nil? end end @@ -898,17 +899,21 @@ module JamRuby self.save end - def update_avatar(original_fpfile, cropped_fpfile, crop_selection, aws_bucket) + def update_avatar(original_fpfile, cropped_fpfile, cropped_large_fpfile, crop_selection, aws_bucket) self.updating_avatar = true cropped_s3_path = cropped_fpfile["key"] + cropped_large_s3_path = cropped_large_fpfile["key"] return self.update_attributes( :original_fpfile => original_fpfile, :cropped_fpfile => cropped_fpfile, + :cropped_large_fpfile => cropped_large_fpfile, :cropped_s3_path => cropped_s3_path, + :cropped_large_s3_path => cropped_large_s3_path, :crop_selection => crop_selection, - :photo_url => S3Util.url(aws_bucket, cropped_s3_path, :secure => false) + :photo_url => S3Util.url(aws_bucket, cropped_s3_path, :secure => false), + :large_photo_url => S3Util.url(aws_bucket, cropped_large_s3_path, :secure => false) ) end @@ -919,14 +924,18 @@ module JamRuby unless self.cropped_s3_path.nil? S3Util.delete(aws_bucket, File.dirname(self.cropped_s3_path) + '/cropped.jpg') S3Util.delete(aws_bucket, self.cropped_s3_path) + S3Util.delete(aws_bucket, self.cropped_large_s3_path) end return self.update_attributes( :original_fpfile => nil, :cropped_fpfile => nil, + :cropped_large_fpfile => nil, :cropped_s3_path => nil, + :cropped_large_s3_path => nil, :photo_url => nil, - :crop_selection => nil + :crop_selection => nil, + :large_photo_url => nil ) end diff --git a/web/app/assets/javascripts/accounts_profile_avatar.js b/web/app/assets/javascripts/accounts_profile_avatar.js index 81336953e..b2bdbb2f8 100644 --- a/web/app/assets/javascripts/accounts_profile_avatar.js +++ b/web/app/assets/javascripts/accounts_profile_avatar.js @@ -13,6 +13,7 @@ var avatar; var selection = null; var targetCropSize = 88; + var largerCropSize = 200; var updatingAvatar = false; var userDropdown; @@ -320,15 +321,32 @@ signature: filepickerPolicy.signature }, { path: createStorePath(self.userDetail), access: 'public' }, function(scaled) { - logger.debug("converted and scaled final image %o", scaled); - rest.updateAvatar({ - original_fpfile: determineCurrentFpfile(), - cropped_fpfile: scaled, - crop_selection: currentSelection - }) - .done(updateAvatarSuccess) - .fail(app.ajaxError) - .always(function() { removeAvatarSpinner(); self.updatingAvatar = false;}) + filepicker.convert(cropped, { + height: largerCropSize, + width: largerCropSize, + fit: 'scale', + format: 'jpg', + quality: 75, + policy: filepickerPolicy.policy, + signature: filepickerPolicy.signature + }, { path: createStorePath(self.userDetail) + 'large.jpg', access: 'public' }, + function(scaledLarger) { + logger.debug("converted and scaled final image %o", scaled); + rest.updateAvatar({ + original_fpfile: determineCurrentFpfile(), + cropped_fpfile: scaled, + cropped_large_fpfile: scaledLarger, + crop_selection: currentSelection + }) + .done(updateAvatarSuccess) + .fail(app.ajaxError) + .always(function() { removeAvatarSpinner(); self.updatingAvatar = false;}) + }, + function(fperror) { + alert("unable to scale larger selection. error code: " + fperror.code); + removeAvatarSpinner(); + self.updatingAvatar = false; + }); }, function(fperror) { alert("unable to scale selection. error code: " + fperror.code); diff --git a/web/app/assets/javascripts/band_setup.js b/web/app/assets/javascripts/band_setup.js index 9ab0aafe7..0e861c06a 100644 --- a/web/app/assets/javascripts/band_setup.js +++ b/web/app/assets/javascripts/band_setup.js @@ -192,7 +192,7 @@ if (bandId.length === 0) { rest.createBand(band).done(function(response) { createBandInvitations(response.id, function() { - context.location = "#/bandProfile/" + response.id; + context.location = "/client#/bandProfile/" + response.id; }); }); } @@ -200,7 +200,7 @@ band.id = bandId; rest.updateBand(band).done(function(response) { createBandInvitations(band.id, function() { - context.location = "#/bandProfile/" + band.id; + context.location = "/client#/bandProfile/" + band.id; }); }); } @@ -473,7 +473,7 @@ $('#btn-band-setup-cancel').click(function() { resetForm(); - context.location = "#/home"; + context.location = "/client#/home"; }); $('#btn-band-setup-next').click(function() { @@ -510,7 +510,7 @@ $('#band-change-photo').click(function(evt) { evt.stopPropagation(); $("#hdn-band-id").val(bandId); - context.location = '#/band/setup/photo'; + context.location = '/client#/band/setup/photo'; return false; }); diff --git a/web/app/assets/javascripts/band_setup_photo.js b/web/app/assets/javascripts/band_setup_photo.js index f5775cee5..193266131 100644 --- a/web/app/assets/javascripts/band_setup_photo.js +++ b/web/app/assets/javascripts/band_setup_photo.js @@ -14,13 +14,14 @@ var bandPhoto; var selection = null; var targetCropSize = 88; + var largeCropSize = 200; var updatingBandPhoto = false; function beforeShow(data) { bandId = $("#hdn-band-id").val(); logger.debug("bandId=" + bandId); if (!bandId) { - context.location = '#/home'; + context.location = '/client#/home'; } } @@ -143,7 +144,7 @@ function navToEditProfile() { resetForm(); $("#hdn-band-id").val(bandId); - context.location = '#/band/setup'; + context.location = '/client#/band/setup'; } function renderBandPhotoSpinner() { @@ -322,16 +323,34 @@ signature: filepickerPolicy.signature }, { path: createStorePath(self.bandDetail), access: 'public' }, function(scaled) { - logger.debug("converted and scaled final image %o", scaled); - rest.updateBandPhoto({ - original_fpfile: determineCurrentFpfile(), - cropped_fpfile: scaled, - crop_selection: currentSelection, - id: bandId - }) - .done(updateBandPhotoSuccess) - .fail(app.ajaxError) - .always(function() { removeBandPhotoSpinner(); self.updatingBandPhoto = false;}) + + filepicker.convert(cropped, { + height: largeCropSize, + width: largeCropSize, + fit: 'scale', + format: 'jpg', + quality: 75, + policy: filepickerPolicy.policy, + signature: filepickerPolicy.signature + }, { path: createStorePath(self.bandDetail) + 'large.jpg', access: 'public' }, + function(scaledLarger) { + logger.debug("converted and scaled final image %o", scaled); + rest.updateBandPhoto({ + original_fpfile: determineCurrentFpfile(), + cropped_fpfile: scaled, + cropped_large_fpfile: scaledLarger, + crop_selection: currentSelection, + id: bandId + }) + .done(updateBandPhotoSuccess) + .fail(app.ajaxError) + .always(function() { removeBandPhotoSpinner(); self.updatingBandPhoto = false;}) + }, + function(fperror) { + alert("unable to scale larger selection. error code: " + fperror.code); + removeBandPhotoSpinner(); + self.updatingBandPhoto = false; + }) }, function(fperror) { alert("unable to scale selection. error code: " + fperror.code); diff --git a/web/app/assets/javascripts/createSession.js b/web/app/assets/javascripts/createSession.js index 2d2c58f10..84dc981df 100644 --- a/web/app/assets/javascripts/createSession.js +++ b/web/app/assets/javascripts/createSession.js @@ -165,7 +165,7 @@ success: function(response) { var newSessionId = response.id; var invitationCount = inviteMusiciansUtil.createInvitations(newSessionId, function() { - context.location = '#/session/' + newSessionId; + context.location = '/client#/session/' + newSessionId; }); // Re-loading the session settings will cause the form to reset with the right stuff in it. // This is an extra xhr call, but it keeps things to a single codepath diff --git a/web/app/assets/javascripts/header.js b/web/app/assets/javascripts/header.js index 02575410f..76c334944 100644 --- a/web/app/assets/javascripts/header.js +++ b/web/app/assets/javascripts/header.js @@ -94,7 +94,7 @@ function events() { $('body').on('click', 'div[layout="header"] h1', function() { - context.location = '#/home'; + context.location = '/client#/home'; }); $('#account-identity-form').submit(handleIdentitySubmit); diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js index fa3ae4ea3..b4d3a6d73 100644 --- a/web/app/assets/javascripts/jam_rest.js +++ b/web/app/assets/javascripts/jam_rest.js @@ -284,11 +284,13 @@ var original_fpfile = options['original_fpfile']; var cropped_fpfile = options['cropped_fpfile']; + var cropped_large_fpfile = options['cropped_large_fpfile']; var crop_selection = options['crop_selection']; logger.debug(JSON.stringify({ original_fpfile : original_fpfile, cropped_fpfile : cropped_fpfile, + cropped_large_fpfile : cropped_large_fpfile, crop_selection : crop_selection })); @@ -302,6 +304,7 @@ data: JSON.stringify({ original_fpfile : original_fpfile, cropped_fpfile : cropped_fpfile, + cropped_large_fpfile : cropped_large_fpfile, crop_selection : crop_selection }) }); @@ -338,11 +341,13 @@ var original_fpfile = options['original_fpfile']; var cropped_fpfile = options['cropped_fpfile']; + var cropped_large_fpfile = options['cropped_large_fpfile']; var crop_selection = options['crop_selection']; logger.debug(JSON.stringify({ original_fpfile : original_fpfile, cropped_fpfile : cropped_fpfile, + cropped_large_fpfile : cropped_large_fpfile, crop_selection : crop_selection })); @@ -356,6 +361,7 @@ data: JSON.stringify({ original_fpfile : original_fpfile, cropped_fpfile : cropped_fpfile, + cropped_large_fpfile : cropped_large_fpfile, crop_selection : crop_selection }) }); @@ -761,6 +767,34 @@ }); } + function getShareSession(options) { + var id = getId(options); + var provider = options['provider']; + delete options['provider'] + + return $.ajax({ + type: "GET", + dataType: "json", + contentType: 'application/json', + url: "/api/users/" + id + "/share/session/" + provider, + data: options + }) + } + + function getShareRecording(options) { + var id = getId(options); + var provider = options['provider']; + delete options['provider'] + + return $.ajax({ + type: "GET", + dataType: "json", + contentType: 'application/json', + url: "/api/users/" + id + "/share/recording/" + provider, + data: options + }) + } + function initialize() { return self; } @@ -827,6 +861,8 @@ this.updateBandInvitation = updateBandInvitation; this.removeBandMember = removeBandMember; this.login = login; + this.getShareSession = getShareSession; + this.getShareRecording = getShareRecording; return this; }; diff --git a/web/app/assets/javascripts/jamkazam.js b/web/app/assets/javascripts/jamkazam.js index fba55b8f8..fbee40c0c 100644 --- a/web/app/assets/javascripts/jamkazam.js +++ b/web/app/assets/javascripts/jamkazam.js @@ -328,7 +328,7 @@ hash = null; } - var url = '#/home'; + var url = '/client#/home'; if (hash) { url = hash; } diff --git a/web/app/assets/javascripts/layout.js b/web/app/assets/javascripts/layout.js index 53bac88fa..70e6cbc91 100644 --- a/web/app/assets/javascripts/layout.js +++ b/web/app/assets/javascripts/layout.js @@ -400,7 +400,7 @@ var destination = $(evt.currentTarget).attr('layout-link'); var destinationType = $('[layout-id="' + destination + '"]').attr("layout"); if (destinationType === "screen") { - context.location = '#/' + destination; + context.location = '/client#/' + destination; } else if (destinationType === "dialog") { showDialog(destination); } diff --git a/web/app/assets/javascripts/searchResults.js b/web/app/assets/javascripts/searchResults.js index 7795f4076..9144d9943 100644 --- a/web/app/assets/javascripts/searchResults.js +++ b/web/app/assets/javascripts/searchResults.js @@ -44,7 +44,7 @@ $('#search-results').empty(); var query = $('#search-input').val(); if (query) { - context.location = '#/searchResults/:' + query; + context.location = '/client#/searchResults/:' + query; } else { query = $('#query').html(); } diff --git a/web/app/assets/javascripts/sessionList.js b/web/app/assets/javascripts/sessionList.js index 0a3fc572f..54da537c0 100644 --- a/web/app/assets/javascripts/sessionList.js +++ b/web/app/assets/javascripts/sessionList.js @@ -249,7 +249,7 @@ } function onTermsAccepted(sessionId) { - context.location = '#/session/' + sessionId; + context.location = '/client#/session/' + sessionId; } function events() { diff --git a/web/app/assets/javascripts/shareDialog.js b/web/app/assets/javascripts/shareDialog.js index f37f18560..b7710ab66 100644 --- a/web/app/assets/javascripts/shareDialog.js +++ b/web/app/assets/javascripts/shareDialog.js @@ -15,28 +15,137 @@ RECORDED: "RECORDED" }; - function handleShareWithFacebook() { - facebookHelper.promptLogin() - .done(function(response) { - if(response.status == "connected") { - facebookRest.post({ - access_token: response.authResponse.accessToken, - message: 'A Message', - caption: 'A Caption', - description: 'A description', - link: 'http://staging.jamkazam.com', - name: 'JamKazam', - picture: 'http://staging.jamkazam.com/assets/logo.png' - }) - .done(function(response) { - alert("zong") - }) - .fail(function(response) { - console.log("failed %o", response); - }) - } - }) + function showSpinner() { + $('#share-dialog .dialog-inner').hide(); + var spinner = $('
') + $('#share-dialog .content-head').after(spinner); + } + + function hideSpinner() { + $('#share-dialog .spinner').remove(); + $('#share-dialog .dialog-inner').show(); + } + + + + function handleRecordingShareWithGoogle(message) { + var defer = $.Deferred(); + + defer.resolve(); // remove when implemented + + return defer; + } + + function handleRecordingShareWithTwitter(message) { + var defer = $.Deferred(); + + defer.resolve(); // remove when implemented + + return defer; + } + + function handleRecordingShareWithFacebook(message) { + var defer = $.Deferred(); + + rest.getShareRecording({ provider:'facebook', claimed_recording: entityId}) + .done(function(data) { + facebookHelper.promptLogin() + .done(function(response) { + if(response.status == "connected") { + facebookRest.post({ + access_token: response.authResponse.accessToken, + message: message, + description: data.description, + caption: data.caption, + name: data.title, + picture: data.photo_url + }) + .done(function(response) { + defer.resolve(); + }) + .fail(function(response) { + app.notify({ + title : "Unable to Share with Facebook", + text : "Error: " + response, + "icon_url": "/assets/content/icon_alert_big.png" + }); + defer.reject(); + }) + } + else { + // user doesn't want to auth; this is a form of success + defer.resolve(); + } + }) + }) + .fail(function(jqXHR) { + app.notifyServerError(jqXHR, "Unable to Populate Share Data"); + defer.reject(); + }) + + return defer; + + } + + function handleSessionShareWithGoogle(message) { + var defer = $.Deferred(); + + defer.resolve(); // remove when implemented + + return defer; + } + + function handleSessionShareWithTwitter(message) { + var defer = $.Deferred(); + + defer.resolve(); // remove when implemented + + return defer; + } + + function handleSessionShareWithFacebook(message) { + var defer = $.Deferred(); + + rest.getShareSession({ provider:'facebook', music_session: entityId}) + .done(function(data) { + facebookHelper.promptLogin() + .done(function(response) { + if(response.status == "connected") { + facebookRest.post({ + access_token: response.authResponse.accessToken, + message: message, + description: data.description, + caption: data.caption, + name: data.title, + picture: data.photo_url + }) + .done(function(response) { + defer.resolve(); + }) + .fail(function(response) { + app.notify({ + title : "Unable to Share with Facebook", + text : "Error: " + response, + "icon_url": "/assets/content/icon_alert_big.png" + }); + defer.reject(); + }) + } + else { + // user doesn't want to auth; this is a form of success + defer.resolve(); + } + }) + }) + .fail(function(jqXHR) { + app.notifyServerError(jqXHR, "Unable to Populate Share Data"); + defer.reject(); + }) + + return defer; + } + function socialShare() { var shareWithFacebook = $('.share-with-facebook').is(':checked'); var shareWithGoogle = $('.share-with-google').is(':checked'); @@ -50,9 +159,46 @@ $('.share-options').removeClass('error') } - if(shareWithFacebook) { - handleShareWithFacebook(); + var message = $('.share-message').val(); + if(!message) { message = undefined; } + + showSpinner(); + + var chain = []; + + if(entityType == 'session') { + if(shareWithFacebook) { + chain.push(handleSessionShareWithFacebook(message)) + } + if(shareWithTwitter) { + chain.push(handleSessionShareWithTwitter(message)) + } + if(shareWithGoogle) { + chain.push(handleSessionShareWithGoogle(message)) + } } + else { + if(shareWithFacebook) { + chain.push(handleRecordingShareWithFacebook(message)) + } + if(shareWithTwitter) { + chain.push(handleRecordingShareWithTwitter(message)) + } + if(shareWithGoogle) { + chain.push(handleRecordingShareWithGoogle(message)) + } + } + + $.when.apply($, chain) + .done(function() { + app.layout.closeDialog('share-dialog'); + }) + .fail(function() { + logger.error("share failed") + }) + .always(function() { + hideSpinner(); + }); } function registerEvents(onOff) { @@ -137,6 +283,7 @@ } function afterHide() { + hideSpinner(); registerEvents(false); } diff --git a/web/app/assets/javascripts/sidebar.js b/web/app/assets/javascripts/sidebar.js index f946c6149..b4c7cdbd5 100644 --- a/web/app/assets/javascripts/sidebar.js +++ b/web/app/assets/javascripts/sidebar.js @@ -585,7 +585,7 @@ function onTermsAccepted(args) { deleteNotification(args.notification_id); - context.location = '#/session/' + args.session_id; + context.location = '/client#/session/' + args.session_id; } function registerSessionEnded() { diff --git a/web/app/controllers/api_bands_controller.rb b/web/app/controllers/api_bands_controller.rb index 1d441e21c..fab1e96bc 100644 --- a/web/app/controllers/api_bands_controller.rb +++ b/web/app/controllers/api_bands_controller.rb @@ -191,10 +191,11 @@ class ApiBandsController < ApiController def update_photo original_fpfile = params[:original_fpfile] cropped_fpfile = params[:cropped_fpfile] + cropped_large_fpfile = params[:cropped_large_fpfile] crop_selection = params[:crop_selection] # public bucket to allow images to be available to public - @band.update_photo(original_fpfile, cropped_fpfile, crop_selection, Rails.application.config.aws_bucket_public) + @band.update_photo(original_fpfile, cropped_fpfile, cropped_large_fpfile, crop_selection, Rails.application.config.aws_bucket_public) if @band.errors.any? render :json => { :message => "Unexpected error updating photo."}, :status => :unprocessable_entity diff --git a/web/app/controllers/api_claimed_recordings_controller.rb b/web/app/controllers/api_claimed_recordings_controller.rb index a7c7dc013..72d91750d 100644 --- a/web/app/controllers/api_claimed_recordings_controller.rb +++ b/web/app/controllers/api_claimed_recordings_controller.rb @@ -11,10 +11,19 @@ class ApiClaimedRecordingsController < ApiController end def show + if !@claimed_recording.is_public && @claimed_recording.user_id != current_user.id + raise PermissionError, 'this claimed recording is not public' + end + @claimed_recording end def update + + if @claimed_recording.user_id != current_user.id + raise PermissionError, 'only owner of claimed_recording can update it' + end + begin @claimed_recording.update_fields(current_user, params) respond_with responder: ApiResponder, :status => 204 @@ -24,6 +33,9 @@ class ApiClaimedRecordingsController < ApiController end def delete + if @claimed_recording.user_id != current_user.id + raise PermissionError, 'only owner of claimed_recording can update it' + end #begin #@claimed_recording.discard(current_user) #render :json => {}, :status => 204 @@ -37,7 +49,7 @@ class ApiClaimedRecordingsController < ApiController def look_up_claimed_recording @claimed_recording = ClaimedRecording.find(params[:id]) - if @claimed_recording.nil? || @claimed_recording.user_id != current_user.id + if @claimed_recording.nil? render :json => { :message => "claimed_recording not found" }, :status => 404 end end diff --git a/web/app/controllers/api_users_controller.rb b/web/app/controllers/api_users_controller.rb index 01eb5107e..8bc9b0fab 100644 --- a/web/app/controllers/api_users_controller.rb +++ b/web/app/controllers/api_users_controller.rb @@ -10,7 +10,9 @@ class ApiUsersController < ApiController :friend_show, :friend_destroy, # friends :notification_index, :notification_destroy, # notifications :band_invitation_index, :band_invitation_show, :band_invitation_update, # band invitations - :set_password, :begin_update_email, :update_avatar, :delete_avatar, :generate_filepicker_policy] + :set_password, :begin_update_email, :update_avatar, :delete_avatar, :generate_filepicker_policy, + :share_session, :share_recording] + respond_to :json def index @@ -411,10 +413,11 @@ class ApiUsersController < ApiController def update_avatar original_fpfile = params[:original_fpfile] cropped_fpfile = params[:cropped_fpfile] + cropped_large_fpfile = params[:cropped_large_fpfile] crop_selection = params[:crop_selection] # public bucket to allow images to be available to public - @user.update_avatar(original_fpfile, cropped_fpfile, crop_selection, Rails.application.config.aws_bucket_public) + @user.update_avatar(original_fpfile, cropped_fpfile, cropped_large_fpfile, crop_selection, Rails.application.config.aws_bucket_public) if @user.errors.any? respond_with @user, status: :unprocessable_entity @@ -547,6 +550,46 @@ class ApiUsersController < ApiController render :json => {}, :status => 200 end + # creates display-ready session data for sharing + def share_session + provider = params[:provider] + music_session_id = params[:music_session] + history = MusicSessionHistory.find_by_music_session_id!(music_session_id) + + 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), + photo_url: view_context.facebook_image_for_music_session_history(history), + caption: 'www.jamkazam.com' + }, status: 200 + + else + render :json => { :errors => {:provider => ['not valid']} }, :status => 422 + end + end + + # creates display-ready recording data for sharing + def share_recording + provider = params[:provider] + claimed_recording_id = params[:claimed_recording] + claimed_recording = ClaimedRecording.find(claimed_recording_id) + + 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), + photo_url: view_context.facebook_image_for_claimed_recording(claimed_recording), + caption: 'www.jamkazam.com' + }, status: 200 + + else + render :json => { :errors => {:provider => ['not valid']} }, :status => 422 + end + end + ###################### RECORDINGS ####################### # def recording_index # @recordings = User.recording_index(current_user, params[:id]) diff --git a/web/app/controllers/sessions_controller.rb b/web/app/controllers/sessions_controller.rb index 019c52b99..135ebf638 100644 --- a/web/app/controllers/sessions_controller.rb +++ b/web/app/controllers/sessions_controller.rb @@ -39,7 +39,6 @@ class SessionsController < ApplicationController # For debugging - to see what all is there: # render :text => auth_hash.to_yaml #FbGraph.debug! - #app = FbGraph::Application.new '468555793186398', :secret => '546a5b253972f3e2e8b36d9a3dd5a06e' token = auth_hash[:credentials][:token] # FIXME: diff --git a/web/app/helpers/music_session_helper.rb b/web/app/helpers/music_session_helper.rb new file mode 100644 index 000000000..307e588bc --- /dev/null +++ b/web/app/helpers/music_session_helper.rb @@ -0,0 +1,48 @@ +module MusicSessionHelper + + def facebook_image_for_music_session_history(music_session) + if music_session.band + path = !music_session.band.large_photo_url.blank? ? music_session.band.large_photo_url : "/assets/web/logo-256.png" + else + path = "/assets/web/logo-256.png" + end + + request.protocol + request.host_with_port + path + end + + # careful; this mirrors logic of facebook_image_for_music_session_history + def facebook_image_size_for_music_session_history(music_session) + if music_session.band + !music_session.band.large_photo_url.blank? ? 200 : 256 + else + 256 + end + end + + def facebook_title_for_music_session_history(music_session, sharer = nil) + if music_session.band + "LIVE SESSION: #{music_session.band.name}" + else + unique_users = music_session.unique_users + if sharer && unique_users.exists?(sharer) + "LIVE SESSION: #{sharer.name}#{additional_member_count(unique_users)}" + else + "LIVE SESSION: #{music_session.user.name}#{additional_member_count(unique_users)}" + end + + end + end + + def additional_member_count(unique_users) + length = unique_users.length + if length < 2 + "" + else + " & #{length} OTHERS" + end + end + + def facebook_description_for_music_session_history(music_session) + truncate(music_session.description, length:250) + end +end diff --git a/web/app/helpers/recording_helper.rb b/web/app/helpers/recording_helper.rb new file mode 100644 index 000000000..ea4a64652 --- /dev/null +++ b/web/app/helpers/recording_helper.rb @@ -0,0 +1,48 @@ +module RecordingHelper + + def facebook_image_for_claimed_recording(claimed_recording) + if claimed_recording.recording.band + path = !claimed_recording.recording.band.large_photo_url.blank? ? claimed_recording.recording.band.large_photo_url : "/assets/web/logo-256.png" + else + path = "/assets/web/logo-256.png" + end + + request.protocol + request.host_with_port + path + end + + # careful; this mirrors logic of facebook_image_for_music_session_history + def facebook_image_size_for_claimed_recording(claimed_recording) + if claimed_recording.recording.band + !claimed_recording.recording.band.large_photo_url.blank? ? 200 : 256 + else + 256 + end + end + + def facebook_title_for_claimed_recording(claimed_recording, sharer = nil) + if claimed_recording.recording.band + "RECORDING: #{claimed_recording.recording.band.name}" + else + unique_users = claimed_recording.recording.users + if sharer && unique_users.exists?(sharer) + "RECORDING: #{sharer.name}#{additional_member_count(unique_users)}" + else + "RECORDING: #{claimed_recording.user.name}#{additional_member_count(unique_users)}" + end + + end + end + + def additional_member_count(unique_users) + length = unique_users.length + if length < 2 + "" + else + " & #{length} OTHERS" + end + end + + def facebook_description_for_claimed_recording(claimed_recording) + truncate(claimed_recording.name, length:250) + end +end diff --git a/web/app/views/clients/_shareDialog.html.erb b/web/app/views/clients/_shareDialog.html.erb index b955dd678..6f87beb84 100644 --- a/web/app/views/clients/_shareDialog.html.erb +++ b/web/app/views/clients/_shareDialog.html.erb @@ -7,7 +7,7 @@

Share to Social Media:

-
+
<%= image_tag "content/icon_facebook.png", :size => "24x24", :align => "absmiddle", :alt => "", :style => "vertical-align:middle" %>  @@ -22,7 +22,7 @@

Share a Link:


- <% unless share_token.blank? %> + <% unless true# share_token.blank? %> <%= "#{root_url}#{share_token}" %> <% end %>

diff --git a/web/app/views/clients/index.html.erb b/web/app/views/clients/index.html.erb index c2a7cbb4d..45ef50f11 100644 --- a/web/app/views/clients/index.html.erb +++ b/web/app/views/clients/index.html.erb @@ -100,10 +100,10 @@ var recordingManager = new JK.RecordingManager(); var facebookHelper = new JK.FacebookHelper(JK.app); - facebookHelper.initialize('<%= SampleApp::Application.config.facebook_key %>'); + facebookHelper.initialize(gon.global.facebook_app_id); var invitationDialog = new JK.InvitationDialog(JK.app); - invitationDialog.initialize('<%= SampleApp::Application.config.facebook_key %>'); + invitationDialog.initialize(gon.global.facebook_app_id); var shareDialog = new JK.ShareDialog(JK.app); shareDialog.initialize(facebookHelper); diff --git a/web/app/views/layouts/_facebook_meta.html.erb b/web/app/views/layouts/_facebook_meta.html.erb new file mode 100644 index 000000000..ebbc8492c --- /dev/null +++ b/web/app/views/layouts/_facebook_meta.html.erb @@ -0,0 +1,8 @@ + + " /> + + + " /> + + + \ No newline at end of file diff --git a/web/app/views/layouts/client.html.erb b/web/app/views/layouts/client.html.erb index b6afca85b..bafcd40d4 100644 --- a/web/app/views/layouts/client.html.erb +++ b/web/app/views/layouts/client.html.erb @@ -14,6 +14,11 @@ <%= include_gon %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> + <% if content_for?(:facebook_meta) %> + <%= yield(:facebook_meta) %> + <% else %> + <%= render "layouts/facebook_meta" %> + <% end %> <%= yield %> diff --git a/web/app/views/layouts/corporate.html.erb b/web/app/views/layouts/corporate.html.erb index fbc2c4585..964685fc3 100644 --- a/web/app/views/layouts/corporate.html.erb +++ b/web/app/views/layouts/corporate.html.erb @@ -12,6 +12,11 @@ <%= include_gon(:init => true) %> <%= javascript_include_tag "corp/corporate" %> <%= csrf_meta_tags %> + <% if content_for?(:facebook_meta) %> + <%= yield(:facebook_meta) %> + <% else %> + <%= render "layouts/facebook_meta" %> + <% end %> diff --git a/web/app/views/layouts/landing.erb b/web/app/views/layouts/landing.erb index c6096ff72..a417a72ef 100644 --- a/web/app/views/layouts/landing.erb +++ b/web/app/views/layouts/landing.erb @@ -14,6 +14,11 @@ <% end %> <%= include_gon(:init => true) %> <%= csrf_meta_tags %> + <% if content_for?(:facebook_meta) %> + <%= yield(:facebook_meta) %> + <% else %> + <%= render "layouts/facebook_meta" %> + <% end %>
diff --git a/web/app/views/layouts/web.erb b/web/app/views/layouts/web.erb index 43fb40fa5..83b57ca48 100644 --- a/web/app/views/layouts/web.erb +++ b/web/app/views/layouts/web.erb @@ -14,6 +14,11 @@ <% end %> <%= include_gon(:init => true) %> <%= csrf_meta_tags %> + <% if content_for?(:facebook_meta) %> + <%= yield(:facebook_meta) %> + <% else %> + <%= render "layouts/facebook_meta" %> + <% end %> <%= javascript_include_tag "web/web" %> @@ -72,7 +77,7 @@ var facebookHelper = new JK.FacebookHelper(JK.app); JK.FacebookHelperInstance = facebookHelper; - facebookHelper.initialize('<%= SampleApp::Application.config.facebook_key %>'); + facebookHelper.initialize(gon.global.facebook_app_id); var invitationDialog = new JK.InvitationDialog(JK.app); invitationDialog.initialize(facebookHelper); diff --git a/web/app/views/music_sessions/show.html.erb b/web/app/views/music_sessions/show.html.erb index 2f03d2fb8..6e58b92a1 100644 --- a/web/app/views/music_sessions/show.html.erb +++ b/web/app/views/music_sessions/show.html.erb @@ -1,5 +1,16 @@ <% provide(:title, "#{@music_session.description}") %> +<% content_for :facebook_meta do %> + + + + + + + + +<% end %> +
<% unless @music_session.band.nil? %>
diff --git a/web/app/views/recordings/show.html.erb b/web/app/views/recordings/show.html.erb index cfa71f1d1..af5c55963 100644 --- a/web/app/views/recordings/show.html.erb +++ b/web/app/views/recordings/show.html.erb @@ -1,5 +1,17 @@ <% provide(:title, "#{@claimed_recording.name}") %> + +<% content_for :facebook_meta do %> + + + + + + + + +<% end %> +
<% unless @claimed_recording.recording.band.nil? %>
diff --git a/web/app/views/spikes/facebook_invite.html.erb b/web/app/views/spikes/facebook_invite.html.erb index 9ad848a6a..1d8cd3497 100644 --- a/web/app/views/spikes/facebook_invite.html.erb +++ b/web/app/views/spikes/facebook_invite.html.erb @@ -29,7 +29,7 @@ window.fbAsyncInit = function() { // init the FB JS SDK FB.init({ - appId : '<%= SampleApp::Application.config.facebook_key %>', // App ID from the App Dashboard + appId : gon.global.facebook_app_id, // App ID from the App Dashboard // channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File for x-domain communication status : true, // check the login status upon init? cookie : true, // set sessions cookies to allow your server to access the session? diff --git a/web/config/application.rb b/web/config/application.rb index 02806981d..9a628f5fb 100644 --- a/web/config/application.rb +++ b/web/config/application.rb @@ -133,9 +133,6 @@ include JamRuby # cloudfront host config.cloudfront_host = "d34f55ppvvtgi3.cloudfront.net" - # facebook keys - config.facebook_key = '468555793186398' - # google api keys config.google_client_id = '785931784279-gd0g8on6sc0tuesj7cu763pitaiv2la8.apps.googleusercontent.com' config.google_secret = 'UwzIcvtErv9c2-GIsNfIo7bA' @@ -196,7 +193,7 @@ include JamRuby config.email_smtp_password = 'jamjamblueberryjam' config.email_smtp_starttls_auto = true - config.facebook_app_id = '468555793186398' - config.facebook_app_secret = '546a5b253972f3e2e8b36d9a3dd5a06e' + config.facebook_app_id = ENV['FACEBOOK_APP_ID'] || '468555793186398' + config.facebook_app_secret = ENV['FACEBOOK_APP_SECRET'] || '546a5b253972f3e2e8b36d9a3dd5a06e' end end diff --git a/web/config/initializers/gon.rb b/web/config/initializers/gon.rb new file mode 100644 index 000000000..9a27929f4 --- /dev/null +++ b/web/config/initializers/gon.rb @@ -0,0 +1 @@ +Gon.global.facebook_app_id = Rails.application.config.facebook_app_id \ No newline at end of file diff --git a/web/config/routes.rb b/web/config/routes.rb index a0c08691c..98d368819 100644 --- a/web/config/routes.rb +++ b/web/config/routes.rb @@ -215,6 +215,10 @@ SampleApp::Application.routes.draw do match '/users/progression/certified_gear' => 'api_users#qualified_gear', :via => :post match '/users/progression/social_promoted' => 'api_users#social_promoted', :via => :post + # social + match '/users/:id/share/session/:provider' => 'api_users#share_session', :via => :get + match '/users/:id/share/recording/:provider' => 'api_users#share_recording', :via => :get + # user recordings # match '/users/:id/recordings' => 'api_users#recording_index', :via => :get # match '/users/:id/recordings/:recording_id' => 'api_users#recording_show', :via => :get, :as => 'api_recording_detail' diff --git a/web/spec/factories.rb b/web/spec/factories.rb index 0c359d05a..c3e8c6dd6 100644 --- a/web/spec/factories.rb +++ b/web/spec/factories.rb @@ -66,6 +66,7 @@ FactoryGirl.define do } end + factory :music_session_user_history, :class => JamRuby::MusicSessionUserHistory do end diff --git a/web/spec/features/facebook_meta_spec.rb b/web/spec/features/facebook_meta_spec.rb new file mode 100644 index 000000000..e8835f374 --- /dev/null +++ b/web/spec/features/facebook_meta_spec.rb @@ -0,0 +1,115 @@ +require 'spec_helper' + +describe "facebook metadata" do + + include MusicSessionHelper + include RecordingHelper + + + subject { page } + + + + share_examples_for :has_default_metadata do + it "should have default metadata" do + 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 == "JamKazam" + page.find('meta[property="og:description"]', :visible => false)['content'].should == "Play music together over the Internet as if in the same room." + page.find('meta[property="og:image"]', :visible => false)['content'].include?("/assets/web/logo-256.png").should be_true + page.find('meta[property="og:image:width"]', :visible => false)['content'].should == "256" + page.find('meta[property="og:image:height"]', :visible => false)['content'].should == "256" + page.find('meta[property="og:type"]', :visible => false)['content'].should == "website" + end + end + + + describe "default layout metadata" do + let(:user) {FactoryGirl.create(:user) } + + describe "web layout" do + before(:each) do + visit '/' + end + it_behaves_like :has_default_metadata + end + + describe "corp layout" do + before(:each) do + visit '/corp/about' + end + it_behaves_like :has_default_metadata + end + + describe "client layout" do + before(:each) do + sign_in user + visit '/client' + end + it_behaves_like :has_default_metadata + end + + describe "landing layout" do + before(:each) do + visit '/signin' + end + it_behaves_like :has_default_metadata + end + + + end + + describe "music session metadata" do + + let(:user) { FactoryGirl.create(:user) } + let(:connection) { FactoryGirl.create(:connection, :user => user) } + let(:instrument) { FactoryGirl.create(:instrument, :description => 'a great instrument') } + let(:track) { FactoryGirl.create(:track, :connection => connection, :instrument => instrument) } + let(:music_session) { ms = FactoryGirl.create(:music_session, :creator => user, :musician_access => true); ms.connections << connection; ms.save!; ms } + + it "renders 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: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 + page.find('meta[property="og:image:width"]', :visible => false)['content'].should == "256" + page.find('meta[property="og:image:height"]', :visible => false)['content'].should == "256" + page.find('meta[property="og:type"]', :visible => false)['content'].should == "website" + end + end + + describe "recording metadata" do + + before(:each) do + @user = FactoryGirl.create(:user) + @connection = FactoryGirl.create(:connection, :user => @user) + @instrument = FactoryGirl.create(:instrument, :description => 'a great instrument') + @track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument) + @music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true) + @music_session.connections << @connection + @music_session.save + @recording = Recording.start(@music_session, @user) + @recording.stop + @recording.reload + @genre = FactoryGirl.create(:genre) + @recording.claim(@user, "name", "description", @genre, true, true) + @recording.reload + @claimed_recording = @recording.claimed_recordings.first + end + + it "renders 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: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 + page.find('meta[property="og:image:width"]', :visible => false)['content'].should == "256" + page.find('meta[property="og:image:height"]', :visible => false)['content'].should == "256" + page.find('meta[property="og:type"]', :visible => false)['content'].should == "website" + end + end +end \ No newline at end of file diff --git a/web/spec/helpers/music_session_helper_spec.rb b/web/spec/helpers/music_session_helper_spec.rb new file mode 100644 index 000000000..f3e31140a --- /dev/null +++ b/web/spec/helpers/music_session_helper_spec.rb @@ -0,0 +1,70 @@ +require 'spec_helper' + +describe MusicSessionHelper do + + describe "facebook_image_for_music_session_history" do + it "with band with no photo url" do + music_session = FactoryGirl.create(:music_session, band: FactoryGirl.create(:band), creator: FactoryGirl.create(:user)) + result = helper.facebook_image_for_music_session_history(music_session.music_session_history) + result.include?("/assets/web/logo-256.png").should be_true + end + + it "with band with photo url" do + music_session = FactoryGirl.create(:music_session, band: FactoryGirl.create(:band, large_photo_url: 'abc.png'), creator: FactoryGirl.create(:user)) + result = helper.facebook_image_for_music_session_history(music_session.music_session_history) + result.include?(music_session.band.large_photo_url).should be_true + end + + it "with user with no photo url" do + music_session = FactoryGirl.create(:music_session, creator: FactoryGirl.create(:user)) + result = helper.facebook_image_for_music_session_history(music_session.music_session_history) + result.include?("/assets/web/logo-256.png").should be_true + end + + it "with user with photo url" do + music_session = FactoryGirl.create(:music_session, creator: FactoryGirl.create(:user, large_photo_url: 'abc.png')) + result = helper.facebook_image_for_music_session_history(music_session.music_session_history) + result.include?("/assets/web/logo-256.png").should be_true + end + + it "with sharer with no photo url" do + sharer = FactoryGirl.create(:user) + music_session = FactoryGirl.create(:music_session, creator: FactoryGirl.create(:user)) + result = helper.facebook_image_for_music_session_history(music_session.music_session_history) + result.include?("/assets/web/logo-256.png").should be_true + end + + it "with sharer with photo url" do + sharer = FactoryGirl.create(:user, large_photo_url: 'abc.png') + music_session = FactoryGirl.create(:music_session, creator: FactoryGirl.create(:user, large_photo_url: 'abc.png')) + result = helper.facebook_image_for_music_session_history(music_session.music_session_history) + result.include?("/assets/web/logo-256.png").should be_true + end + end + + describe "facebook_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.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.start_with?("LIVE SESSION").should be_true + result.end_with?(music_session.music_session_history.user.name).should be_true + end + end + + describe "additional_member_count" do + it "no unique users" do + helper.additional_member_count([]).should == "" + end + + it "has 2 users" do + helper.additional_member_count(['', '']).should == " & 2 OTHERS" + end + end +end diff --git a/web/spec/helpers/recording_helper_spec.rb b/web/spec/helpers/recording_helper_spec.rb new file mode 100644 index 000000000..8268f2895 --- /dev/null +++ b/web/spec/helpers/recording_helper_spec.rb @@ -0,0 +1,92 @@ +require 'spec_helper' + +describe MusicSessionHelper do + + before(:each) do + @user = FactoryGirl.create(:user) + @connection = FactoryGirl.create(:connection, :user => @user) + @instrument = FactoryGirl.create(:instrument, :description => 'a great instrument') + @track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument) + @music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true) + @music_session.connections << @connection + @music_session.save + @recording = Recording.start(@music_session, @user) + @recording.stop + @recording.reload + @genre = FactoryGirl.create(:genre) + @recording.claim(@user, "name", "description", @genre, true, true) + @recording.reload + @claimed_recording = @recording.claimed_recordings.first + end + + describe "facebook_image_for_claimed_recording" do + it "with band with no photo url" do + @recording.band = FactoryGirl.create(:band) + @recording.save!(:validate => false) + @claimed_recording.reload + result = helper.facebook_image_for_claimed_recording(@claimed_recording) + result.include?('/assets/web/logo-256.png').should be_true + end + + it "with band with photo url" do + @recording.band = FactoryGirl.create(:band, large_photo_url: 'abc.png') + @recording.save!(:validate => false) + @claimed_recording.reload + result = helper.facebook_image_for_claimed_recording(@claimed_recording) + result.include?(@claimed_recording.recording.band.large_photo_url).should be_true + end + + it "with user with no photo url" do + result = helper.facebook_image_for_claimed_recording(@claimed_recording) + result.include?("/assets/web/logo-256.png").should be_true + end + + it "with user with photo url" do + @claimed_recording.user.large_photo_url = 'abc.png' + @claimed_recording.user.save! + @claimed_recording.save! + @claimed_recording.reload + result = helper.facebook_image_for_claimed_recording(@claimed_recording) + result.include?("/assets/web/logo-256.png").should be_true + end + + it "with sharer with no photo url" do + sharer = FactoryGirl.create(:user) + result = helper.facebook_image_for_claimed_recording(@claimed_recording) + result.include?("/assets/web/logo-256.png").should be_true + end + + it "with sharer with photo url" do + sharer = FactoryGirl.create(:user, large_photo_url: 'abc.png') + result = helper.facebook_image_for_claimed_recording(@claimed_recording) + result.include?("/assets/web/logo-256.png").should be_true + end + end + + describe "facebook_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.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.start_with?("RECORDING").should be_true + result.end_with?(@claimed_recording.user.name).should be_true + end + end + + describe "additional_member_count" do + it "no unique users" do + helper.additional_member_count([]).should == "" + end + + it "has 2 users" do + helper.additional_member_count(['', '']).should == " & 2 OTHERS" + end + end +end diff --git a/web/spec/requests/users_api_spec.rb b/web/spec/requests/users_api_spec.rb index b577157fc..1eec6344e 100644 --- a/web/spec/requests/users_api_spec.rb +++ b/web/spec/requests/users_api_spec.rb @@ -975,5 +975,57 @@ describe "User API", :type => :api do end end end + + describe "share_session" do + + let(:connection) { FactoryGirl.create(:connection, :user => user) } + let(:instrument) { FactoryGirl.create(:instrument, :description => 'a great instrument') } + let(:track) { FactoryGirl.create(:track, :connection => connection, :instrument => instrument) } + let(:music_session) { ms = FactoryGirl.create(:music_session, :creator => user, :musician_access => true); ms.connections << connection; ms.save!; ms } + + + it "fetches facebook successfully" do + login(user.email, user.password, 200, true) + get "/api/users/#{user.id}/share/session/facebook.json?music_session=#{music_session.id}", nil, "CONTENT_TYPE" => 'application/json' + + last_response.status.should == 200 + response = JSON.parse(last_response.body) + response['title'].include?("LIVE SESSION:").should be_true + response['description'].should == music_session.description + response['photo_url'].include?('logo-256.png').should be_true + response['caption'].should == 'www.jamkazam.com' + end + end + + describe "share_recording" do + + before(:each) do + @connection = FactoryGirl.create(:connection, :user => user) + @instrument = FactoryGirl.create(:instrument, :description => 'a great instrument') + @track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument) + @music_session = FactoryGirl.create(:music_session, :creator => user, :musician_access => true) + @music_session.connections << @connection + @music_session.save + @recording = Recording.start(@music_session, user) + @recording.stop + @recording.reload + @genre = FactoryGirl.create(:genre) + @recording.claim(user, "name", "description", @genre, true, true) + @recording.reload + @claimed_recording = @recording.claimed_recordings.first + end + + it "fetches facebook successfully" do + login(user.email, user.password, 200, true) + get "/api/users/#{user.id}/share/recording/facebook.json?claimed_recording=#{@claimed_recording.id}", nil, "CONTENT_TYPE" => 'application/json' + + last_response.status.should == 200 + response = JSON.parse(last_response.body) + response['title'].include?("RECORDING:").should be_true + response['description'].should == @claimed_recording.name + response['photo_url'].include?('logo-256.png').should be_true + response['caption'].should == 'www.jamkazam.com' + end + end end end