diff --git a/app/controllers/v1/discussion_roll_controller.rb b/app/controllers/v1/discussion_roll_controller.rb index a5e55fbf..198bff6a 100644 --- a/app/controllers/v1/discussion_roll_controller.rb +++ b/app/controllers/v1/discussion_roll_controller.rb @@ -6,9 +6,9 @@ class V1::DiscussionRollController < ApplicationController include GT::DiscussionRollUtils protect_from_forgery :except => [:create_message] - + before_filter :user_authenticated?, :except => [:index, :show, :create_message] - + ## # Returns all discussion rolls accessible to the viewer. # If user is signed in, returns rolls based on signed in user, otherwise accessibility @@ -18,12 +18,12 @@ class V1::DiscussionRollController < ApplicationController # # [GET] /v1/discussion_roll # AUTHENTICATON OR TOKEN REQUIRED - # + # # @param [Optional, String] token The access token for any discussion roll, roll identifier will be ignored def index @user_identifier = current_user.id.to_s if user_signed_in? @user_identifier = user_identifier_from_token(params[:token]) if params[:token] - + if @user_identifier @rolls = Roll.where(:discussion_roll_participants => @user_identifier).sort(:content_updated_at).all @status = 200 @@ -33,13 +33,13 @@ def index render_error(401, "Please sign in or provide a valid token") end end - + ## # Finds or creates a new Roll for a discussion between the given participants. # AUTHENTICATION REQUIRED # # [POST] /v1/discussion_roll - # + # # @param [Optional, String] frame_id The id of the parent frame to post into this discussion (optional if you include video_id instead) # @param [Optional, String] video_id The video to post into this discussion (when there is no parent frame, above) # @param [Optional, String] video_source_url When we don't have a proper Frame or Video, we will find_or_create the video based on this @@ -50,15 +50,15 @@ def create res = find_or_create_discussion_roll_for(current_user, params[:participants]) did_create = res[:did_create] @roll = res[:roll] - + unless @roll Rails.logger.error "[DiscussionRollController#create] unable to find or create roll. Params: #{params}" return render_error(404, "roll find or create failed") end - + #creates new frame (ancestor of one when given) if params[:frame_id] and frame = Frame.find(params[:frame_id]) - res = GT::Framer.re_roll(frame, current_user, @roll, true) + res = GT::Framer.re_roll(frame, current_user, @roll, {:skip_dashboard_entries => true}) elsif params[:video_id] and video = Video.find(params[:video_id]) res = GT::Framer.create_frame( :creator => current_user, @@ -74,30 +74,30 @@ def create :skip_dashboard_entries => true) end end - + unless res and res[:frame] Rails.logger.error "[DiscussionRollController#create] unable to create frame for roll. Params: #{params}" return render_error(404, "frame creation failed") end - + #add this message frame = res[:frame] frame.conversation.messages << GT::MessageManager.build_message( - :user => current_user, - :public => false, + :user => current_user, + :public => false, :origin_network => Message::ORIGIN_NETWORKS[:shelby], :text => CGI.unescape(params[:message])) frame.conversation.save #sends discussion roll notification (handling new-convo vs. reply-to-existing) to all but the poster ShelbyGT_EM.next_tick { GT::NotificationManager.send_discussion_roll_notifications(@roll, current_user, did_create) } - + @user_identifier = current_user.id.to_s @insert_discussion_roll_access_token = true @status = 200 render "/v1/roll/show" end - + ## # Displays a discussion roll # AUTHENTICATION OPTIONAL @@ -107,7 +107,7 @@ def create # @param [Optional, String] token The encrypted token authorizing and identifying this user, if they're not logged in def show if @roll = Roll.find(params[:id]) - + if (user_signed_in? and @roll.viewable_by?(current_user)) or token_valid_for_discussion_roll?(params[:token], @roll) @status = 200 render "/v1/roll/show" @@ -118,18 +118,18 @@ def show render_error(404, "that roll does not exist") end end - + ## # Appends a new message to the ongoing discussion in the given roll # AUTHENTICATION OPTIONAL # # If the message includes a video URL, or videos[] is included, will return # an array of new Frames, one for each video, with the message appended to the - # conversation of the last Frame. + # conversation of the last Frame. # Otherwise just returns the updated Conversation. # # [POST] /v1/discussion_roll/:discussion_roll_id/messages - # + # # @param [Optional, String] message The message being appended to this discussion (may be nil when new video is being posted) # @param [Optional, String] token The security token authenticating and authorizing this post # @param [Optional, String] videos[] An array of URL strings to map to Shelby Videos and append to this discusison roll @@ -142,10 +142,10 @@ def create_message unless (user_signed_in? and roll.viewable_by?(current_user)) or token_valid_for_discussion_roll?(params[:token], roll) return render_error(404, "you are not authorized to post to that roll") end - + # 1) See if we have a Shelby user... shelby_user = params[:token] ? user_from_token(params[:token]) : current_user - + # 2) Create new Frame(s) or grab the last one in the Roll... videos_to_append = [] frame = Frame.find(params[:frame_id]) @@ -161,7 +161,7 @@ def create_message :video => video, :roll => roll, :skip_dashboard_entries => true) - + # store some identifier with frame if non-shelby-user unless shelby_user res[:frame].anonymous_creator_nickname = email_from_token(params[:token]).name || email_from_token(params[:token]).address @@ -172,21 +172,21 @@ def create_message frame = @new_frames.last #Frames may all have same created_at; make sure the one we comment on is newest via :score frame.update_attribute(:score, frame.score + 0.00000001) - else + else frame = Frame.where(:roll_id => roll.id).order(:score.desc).first end - + # Make sure something new is getting posted (either mesasge or video) return render_error(400, "you must include a message or video") unless params[:message] or @new_frames - + return render_error(404, "could not find conversation") unless frame @conversation = frame.conversation - + # 3) Post the message (if one exists) to the conversation (created/found above) if shelby_user @conversation.messages << GT::MessageManager.build_message( - :user => shelby_user, - :public => false, + :user => shelby_user, + :public => false, :origin_network => Message::ORIGIN_NETWORKS[:shelby], :text => (params[:message] ? CGI.unescape(params[:message]) : nil)) poster = shelby_user @@ -195,7 +195,7 @@ def create_message :nickname => email_from_token(params[:token]).address, :realname => email_from_token(params[:token]).name, :user_image_url => nil, - :public => false, + :public => false, :origin_network => Message::ORIGIN_NETWORKS[:shelby], :text => (params[:message] ? CGI.unescape(params[:message]) : nil)) poster = email_from_token(params[:token]).address @@ -203,10 +203,10 @@ def create_message if @conversation.save roll.update_attribute(:content_updated_at, Time.now) - + #sends discussion roll notification (only reply-to-existing flavor) to all but the poster ShelbyGT_EM.next_tick { GT::NotificationManager.send_discussion_roll_notifications(roll, poster, false) } - + @status = 200 # Render an array of Frames if new ones were created, or the single updated Conversation if @new_frames @@ -218,7 +218,7 @@ def create_message else Rails.logger.error "[DiscussionRollController#create_message] unable to save convo. Params: #{params}" return render_error(404, "you are not authorized to post to that roll") - end + end end - -end \ No newline at end of file + +end diff --git a/app/controllers/v1/frame_controller.rb b/app/controllers/v1/frame_controller.rb index d9b4cd8d..00454e22 100644 --- a/app/controllers/v1/frame_controller.rb +++ b/app/controllers/v1/frame_controller.rb @@ -104,6 +104,13 @@ def create # and finally create the frame # creating dashboard entries async. frame_options[:async_dashboard_entries] = true + + if current_user.watch_later_roll == roll + # old client trying to do a like. + roll = current_user.public_roll + frame_options[:frame_type] = Frame::FRAME_TYPE[:light_weight] + end + r = frame_options[:video] ? GT::Framer.create_frame(frame_options) : {} if @frame = r[:frame] @@ -228,6 +235,8 @@ def share end end + + # DEPRECATED -- replaced by like ## # Upvotes a frame and returns the frame back w new score # REQUIRES AUTHENTICATION @@ -266,6 +275,8 @@ def upvote end end + + # DEPRECATED -- replaced by like ## # Adds a dupe of the given Frame to the logged in users watch_later_roll and returns the dupe Frame # REQUIRES AUTHENTICATION @@ -274,7 +285,6 @@ def upvote # # @param [Required, String] id The id of the frame # - # DEPRECATED -- replaced by like def add_to_watch_later StatsManager::StatsD.time(Settings::StatsConstants.api['frame']['add_to_watch_later']) do @frame = Frame.find(params[:frame_id]) diff --git a/app/controllers/v1/video_controller.rb b/app/controllers/v1/video_controller.rb index 5b805654..14756ad0 100644 --- a/app/controllers/v1/video_controller.rb +++ b/app/controllers/v1/video_controller.rb @@ -86,7 +86,7 @@ def queued if user = current_user # some old users have slipped thru the cracks and are missing rolls, fix that before it's an issue GT::UserManager.ensure_users_special_rolls(user, true) unless GT::UserManager.user_has_all_special_roll_ids?(user) - @video_ids = video_ids_on_roll(user.watch_later_roll.id) + @video_ids = video_ids_on_roll(user.public_roll.id) else @video_ids = [] end diff --git a/app/models/frame.rb b/app/models/frame.rb index 96540dca..24ceb497 100644 --- a/app/models/frame.rb +++ b/app/models/frame.rb @@ -58,6 +58,14 @@ class Frame # Total number of likes - both by upvoters (logged in likers) and logged out likers key :like_count, Integer, :abbr => :n, :default => 0 + # What does this entry represent (light_weight, heavy_weight)? + # [using integers instead of strings to keep the size as small as possible] + FRAME_TYPE = { + :heavy_weight => 0, + :light_weight => 1 + }.freeze + key :type, Integer, :abbr => :o, :default => FRAME_TYPE[:heavy_weight] + #nothing needs to be mass-assigned (yet?) attr_accessible @@ -112,33 +120,29 @@ def view!(u) end #------ Watch Later ------ - + # this is what our Like api route actually calls def add_to_watch_later!(u) raise ArgumentError, "must supply User" unless u and u.is_a?(User) - #if it's already in this user's watch later, just return that - if prev_dupe = Frame.get_ancestor_of_frame(u.watch_later_roll_id, self.id) - return prev_dupe - else - Frame.collection.update({:_id => self.id}, { - :$addToSet => {:f => u.id}, - :$inc => {:n => 1} - }) - self.reload - self.update_score - self.save - Video.collection.update({:_id => self.video_id}, {:$inc => {:v => 1}}) - Video.find(self.video_id).reload + # add liker to upvoters array & inc frame liker count + Frame.collection.update({:_id => self.id}, { + :$addToSet => {:f => u.id}, + :$inc => {:n => 1} + }) + self.reload + self.update_score + self.save + + Video.collection.update({:_id => self.video_id}, {:$inc => {:v => 1}}) + Video.find(self.video_id).reload - # send email notification in a non-blocking manor - ShelbyGT_EM.next_tick { GT::NotificationManager.check_and_send_like_notification(self, u) } + #TODO: Add liker of video to NEW COLLECTION tracking likers of videos - # add this frame to the community channel in a non-blocking manner - ShelbyGT_EM.next_tick { add_to_community_channel } + # send email notification in a non-blocking manor + ShelbyGT_EM.next_tick { GT::NotificationManager.check_and_send_like_notification(self, u) } - return GT::Framer.dupe_frame!(self, u.id, u.watch_later_roll_id) - end + return GT::Framer.dupe_frame!(self, u.id, u.public_roll_id, {:frame_type => Frame::FRAME_TYPE[:light_weight]}) end #------ Like ------ diff --git a/app/views/v1/frame/show.json.rabl b/app/views/v1/frame/show.json.rabl index 06fec2da..1ce54f1f 100644 --- a/app/views/v1/frame/show.json.rabl +++ b/app/views/v1/frame/show.json.rabl @@ -10,7 +10,7 @@ end if @include_frame_children - attributes :id, :score, :upvoters, :view_count, :frame_ancestors, :frame_children, :creator_id, :conversation_id, :roll_id, :video_id, :like_count + attributes :id, :score, :upvoters, :view_count, :frame_ancestors, :frame_children, :creator_id, :conversation_id, :roll_id, :video_id, :like_count, :type node :created_at do |f| concise_time_ago_in_words(f.created_at) if f.created_at diff --git a/lib/gt/framer.rb b/lib/gt/framer.rb index fff1a0f1..7595ab57 100644 --- a/lib/gt/framer.rb +++ b/lib/gt/framer.rb @@ -35,6 +35,7 @@ class Framer # :async_dashboard_entries => Bool -- OPTIONAL set to true if you want dashboard entries created async. # - N.B. return value will not include :dashboard_entries if this is set to true # - N.B. it does not make sense to turn this option on if :persist is set to false + # :frame_type => is this a heavy_weight or light_weight frame type # :dashboard_entry_options => Hash -- OPTIONAL if dashboard entries are created, this will be passed as the options parameter # :persist => Bool -- OPTIONAL if set to false, the created frames and/or dashboard entries will not be saved to the DB # - For the moment, non-persistent frames will not support conversations, so :message param will be ignored @@ -51,6 +52,7 @@ def self.create_frame(options) video = options.delete(:video) video_id = options.delete(:video_id) genius = options.delete(:genius) + frame_type = options.delete(:frame_type) skip_dashboard_entries = options.delete(:skip_dashboard_entries) async_dashboard_entries = options.delete(:async_dashboard_entries) dashboard_entry_options = options.delete(:dashboard_entry_options) || {} @@ -99,6 +101,7 @@ def self.create_frame(options) f.conversation = convo f.score = score f.order = order + f.type = frame_type if frame_type f.save if persist @@ -142,7 +145,7 @@ def self.create_frame(options) # # { :frame => newly_created_frame, :dashboard_entries => [1 or more DashboardEntry, ...] } # - def self.re_roll(orig_frame, for_user, to_roll, skip_dashboard_entries=false) + def self.re_roll(orig_frame, for_user, to_roll, options={}) raise ArgumentError, "must supply user or user_id" unless for_user user_id = (for_user.is_a?(User) ? for_user.id : for_user) @@ -151,9 +154,9 @@ def self.re_roll(orig_frame, for_user, to_roll, skip_dashboard_entries=false) res = { :frame => nil, :dashboard_entries => [] } - res[:frame] = basic_re_roll(orig_frame, user_id, roll_id) + res[:frame] = basic_re_roll(orig_frame, user_id, roll_id, options) - unless skip_dashboard_entries + unless options[:skip_dashboard_entries] #create dashboard entries for all roll followers *except* the user who just re-rolled create_dashboard_entries_async([res[:frame]], DashboardEntry::ENTRY_TYPE[:re_roll], to_roll.following_users_ids - [user_id]) end @@ -164,7 +167,7 @@ def self.re_roll(orig_frame, for_user, to_roll, skip_dashboard_entries=false) return res end - def self.dupe_frame!(orig_frame, for_user, to_roll) + def self.dupe_frame!(orig_frame, for_user, to_roll, options={} ) raise ArgumentError, "must supply original Frame" unless orig_frame and orig_frame.is_a? Frame raise ArgumentError, "must supply user or user_id" unless for_user @@ -173,7 +176,7 @@ def self.dupe_frame!(orig_frame, for_user, to_roll) raise ArgumentError, "must supply roll or roll_id" unless to_roll roll_id = (to_roll.is_a?(Roll) ? to_roll.id : to_roll) - return basic_dupe!(orig_frame, user_id, roll_id) + return basic_dupe!(orig_frame, user_id, roll_id, options) end def self.remove_dupe_of_frame_from_roll!(frame, roll) @@ -261,13 +264,17 @@ def self.create_dashboard_entries_async(frames, action, user_ids, options={}) private - def self.basic_dupe!(orig_frame, user_id, roll_id) + def self.basic_dupe!(orig_frame, user_id, roll_id, options={}) # Dupe it new_frame = Frame.new new_frame.creator_id = orig_frame.creator_id new_frame.roll_id = roll_id new_frame.video_id = orig_frame.video_id + if options[:frame_type] + new_frame.type = options[:frame_type] + end + #copy convo new_frame.conversation_id = orig_frame.conversation_id @@ -285,13 +292,17 @@ def self.basic_dupe!(orig_frame, user_id, roll_id) return new_frame end - def self.basic_re_roll(orig_frame, user_id, roll_id) + def self.basic_re_roll(orig_frame, user_id, roll_id, options={}) # Set up the basics new_frame = Frame.new new_frame.creator_id = user_id new_frame.roll_id = roll_id new_frame.video_id = orig_frame.video_id + if options[:frame_type] + new_frame.type = options[:frame_type] + end + # Create a new conversation convo = Conversation.new convo.frame = new_frame diff --git a/spec/controllers/discussion_roll_controller_spec.rb b/spec/controllers/discussion_roll_controller_spec.rb index ab7d30a3..625d5b26 100644 --- a/spec/controllers/discussion_roll_controller_spec.rb +++ b/spec/controllers/discussion_roll_controller_spec.rb @@ -5,28 +5,28 @@ before(:each) do @video = Factory.create(:video) @frame = Factory.create(:frame, :video => Factory.create(:video)) - + @u1, @u2 = Factory.create(:user), Factory.create(:user) @u1.save sign_in @u1 end - + it "should return 200 if given a frame" do post :create, :frame_id => @frame.id.to_s, :participants => "dan@shelby.tv", :message => "message", :format => :json assigns(:status).should eq(200) end - + it "should return 200 if given a video" do post :create, :video_id => @video.id.to_s, :participants => "dan@shelby.tv", :message => "message", :format => :json assigns(:status).should eq(200) end - + it "should return 200 if participants include real users" do post :create, :video_id => @video.id.to_s, :participants => "dan@shelby.tv,#{@u2.nickname}", :message => "message", :format => :json assigns(:status).should eq(200) end end - + describe "GET index" do before(:each) do now = Time.now @@ -37,7 +37,7 @@ sleep(0.1) @u_r_2 = Factory.create(:roll, :creator_id => @u1.id, :public => true, :roll_type => Roll::TYPES[:user_public], :content_updated_at => now - 2.seconds, :discussion_roll_participants => [@u1.id.to_s]) - sleep(0.1) + sleep(0.1) @u2 = Factory.create(:user) @u2_r_1 = Factory.create(:roll, :creator_id => @u2.id, :public => true, :roll_type => Roll::TYPES[:user_public], :content_updated_at => now - 10.seconds, :discussion_roll_participants => [@u2.id.to_s, @em]) @@ -45,7 +45,7 @@ @u2_r_2 = Factory.create(:roll, :creator_id => @u2.id, :public => true, :roll_type => Roll::TYPES[:user_public], :content_updated_at => now - 20.seconds, :discussion_roll_participants => [@u2.id.to_s]) end - + it "should return rolls where shelby id is a participant" do token = GT::DiscussionRollUtils.encrypt_roll_user_identification(@u_r_1, @u1.id.to_s) get :index, :token => token, :format => :json @@ -53,7 +53,7 @@ #order is based on roll.content_updated_at assigns(:rolls).should == [@u_r_2, @u_r_1] end - + it "should return rolls where email is a participant" do token = GT::DiscussionRollUtils.encrypt_roll_user_identification(@u_r_1, @em) get :index, :token => token, :format => :json @@ -61,112 +61,112 @@ #order is based on roll.content_updated_at assigns(:rolls).should == [@u2_r_1, @u_r_1] end - + it "should return no rolls" do token = GT::DiscussionRollUtils.encrypt_roll_user_identification(@u_r_1, Factory.next(:primary_email)) get :index, :token => token, :format => :json assigns(:status).should == 200 assigns(:rolls).should == [] end - + it "should return 401 on invalid token" do token = "thisis::invalid" get :index, :token => token, :format => :json assigns(:status).should == 401 end end - + describe "GET show" do before(:each) do @video = Factory.create(:video) @frame = Factory.create(:frame) - + @roll = Factory.create(:roll) - + @u1, @u2 = Factory.create(:user), Factory.create(:user) @u1.save end - + it "should return 200 if user is logged in" do sign_in @u1 get :show, :id => @roll.id, :format => :json assigns(:status).should == 200 end - + it "should return 200 if token is valid for non-shelby user" do token = GT::DiscussionRollUtils.encrypt_roll_user_identification(@roll, "dan@shelby.tv") get :show, :id => @roll.id, :token => token, :format => :json assigns(:status).should == 200 end - + it "should return 200 if token is valid for logged in user" do sign_in @u1 token = GT::DiscussionRollUtils.encrypt_roll_user_identification(@roll, "dan@shelby.tv") get :show, :id => @roll.id, :token => token, :format => :json assigns(:status).should == 200 end - + it "should return 404 if token is invalid" do token = "bad token" get :show, :id => @roll.id, :token => token, :format => :json assigns(:status).should == 404 end - + it "should return 404 if roll DNE" do token = GT::DiscussionRollUtils.encrypt_roll_user_identification(@roll, "dan@shelby.tv") get :show, :id => Factory.create(:user).id, :token => token, :format => :json assigns(:status).should == 404 end end - + describe "POST message" do before(:each) do @video = Factory.create(:video) @frame = Factory.create(:frame) - + @roll = Factory.create(:roll) - + @u1, @u2 = Factory.create(:user), Factory.create(:user) @u1.save - - GT::Framer.re_roll(@frame, @u1, @roll, true) + + GT::Framer.re_roll(@frame, @u1, @roll, {:skip_dashboard_entries => true}) end - + it "should return 200 if user is logged in" do sign_in @u1 post :create_message, :discussion_roll_id => @roll.id, :message => "msg", :format => :json assigns(:status).should == 200 end - + it "should return 400 if message parameter is missing" do sign_in @u1 post :create_message, :discussion_roll_id => @roll.id, :format => :json assigns(:status).should == 400 end - + it "should return 200 if token is valid for non-shelby user" do token = GT::DiscussionRollUtils.encrypt_roll_user_identification(@roll, "dan@shelby.tv") post :create_message, :discussion_roll_id => @roll.id, :token => token, :message => "msg", :format => :json assigns(:status).should == 200 end - + it "should return 200 if token is valid for logged in user" do sign_in @u1 token = GT::DiscussionRollUtils.encrypt_roll_user_identification(@roll, "dan@shelby.tv") post :create_message, :discussion_roll_id => @roll.id, :token => token, :message => "msg", :format => :json assigns(:status).should == 200 end - + it "should return 404 if token is invalid" do token = "bad token" post :create_message, :discussion_roll_id => @roll.id, :token => token, :message => "msg", :format => :json assigns(:status).should == 404 end - + it "should return 404 if roll DNE" do token = GT::DiscussionRollUtils.encrypt_roll_user_identification(@roll, "dan@shelby.tv") post :create_message, :discussion_roll_id => "badid", :token => token, :message => "msg", :format => :json assigns(:status).should == 404 end end -end \ No newline at end of file +end diff --git a/spec/controllers/frame_controller_spec.rb b/spec/controllers/frame_controller_spec.rb index b86f37f3..592a986c 100644 --- a/spec/controllers/frame_controller_spec.rb +++ b/spec/controllers/frame_controller_spec.rb @@ -8,6 +8,7 @@ @u1 = Factory.create(:user) @u1.upvoted_roll = Factory.create(:roll, :creator => @u1) @u1.watch_later_roll = Factory.create(:roll, :creator => @u1) + @u1.public_roll = Factory.create(:roll, :creator => @u1) @u1.viewed_roll = Factory.create(:roll, :creator => @u1) @u1.save sign_in @u1 @@ -302,7 +303,6 @@ end it "creates a new Frame" do - Frame.should_receive(:get_ancestor_of_frame).and_return(nil) lambda { post :add_to_watch_later, :frame_id => @f2.id, :format => :json diff --git a/spec/lib/gt/unit/framer_spec.rb b/spec/lib/gt/unit/framer_spec.rb index ff9adb0e..86c844d2 100644 --- a/spec/lib/gt/unit/framer_spec.rb +++ b/spec/lib/gt/unit/framer_spec.rb @@ -35,6 +35,7 @@ res[:frame].conversation.messages[0].should == @message res[:frame].conversation.messages[0].persisted?.should == true res[:frame].roll.should == @roll + res[:frame].type.should == Frame::FRAME_TYPE[:heavy_weight] end it "should not persist anything if persist option is set to false" do @@ -722,7 +723,7 @@ @roll.add_follower(u3 = Factory.create(:user)) new_frame = Factory.create(:frame) - GT::Framer.should_receive(:basic_re_roll).with(@f1, @roll_creator.id, @roll.id).and_return(new_frame) + GT::Framer.should_receive(:basic_re_roll).with(@f1, @roll_creator.id, @roll.id, {}).and_return(new_frame) GT::Framer.should_receive(:create_dashboard_entries_async).with([new_frame], DashboardEntry::ENTRY_TYPE[:re_roll], [u1.id, u2.id, u3.id]) GT::Framer.re_roll(@f1, @roll_creator, @roll) @@ -821,6 +822,12 @@ @f2.frame_ancestors.should == (@f1.frame_ancestors + [@f1.id]) end + it "should be a heavy_weight frame by default" do + @f2 = GT::Framer.dupe_frame!(@f1, @u, @r2) + + @f2.type.should == Frame::FRAME_TYPE[:heavy_weight] + end + end context "removing dupe of Frame from Roll" do diff --git a/spec/models/functional/frame_spec.rb b/spec/models/functional/frame_spec.rb index 7ffa7b38..3918787c 100644 --- a/spec/models/functional/frame_spec.rb +++ b/spec/models/functional/frame_spec.rb @@ -12,6 +12,7 @@ it "should abbreviate roll_id as :a, rank as :e" do Frame.keys["roll_id"].abbr.should == :a Frame.keys["score"].abbr.should == :e + Frame.keys["type"].abbr.should == :o end end @@ -22,6 +23,12 @@ frame = Factory.create(:frame, :roll => roll) }.should change { roll.reload.frame_count }.by(1) end + + it "should be a heavy_weight share by default" do + roll = Factory.create(:roll) + frame = Factory.create(:frame, :roll => roll) + frame.type.should == Frame::FRAME_TYPE[:heavy_weight] + end end # We're testing a private method here, but it's a pretty fucking important/tricky one and has to be correct @@ -275,7 +282,7 @@ @frame = Factory.create(:frame, :video => @video) @u1 = Factory.create(:user) - @u1.watch_later_roll = Factory.create(:roll, :creator => @u1) + @u1.public_roll = Factory.create(:roll, :creator => @u1) end it "should require full User model, not just id" do @@ -284,14 +291,21 @@ }.should raise_error(ArgumentError) end - it "should dupe the frame into the users watch_later_roll, persisted" do - f = nil + it "should dupe the frame into the users public_roll, persisted" do lambda { - f = @frame.add_to_watch_later!(@u1) + @f = @frame.add_to_watch_later!(@u1) }.should change { Frame.count } .by 1 - f.persisted?.should == true - f.roll.should == @u1.watch_later_roll + @f.persisted?.should == true + @f.roll.should == @u1.public_roll + end + + it "should dupe the frame with a light weight frame type" do + lambda { + @f = @frame.add_to_watch_later!(@u1) + }.should change { Frame.count } .by 1 + + @f.type.should == Frame::FRAME_TYPE[:light_weight] end it "should add the user to the frame being watch_latered's upvoters array if it's not there already" do @@ -308,9 +322,9 @@ }.should change { @frame.like_count } .by 1 u2 = Factory.create(:user) - u2.watch_later_roll = Factory.create(:roll, :creator => u2) + u2.public_roll = Factory.create(:roll, :creator => u2) u3 = Factory.create(:user) - u3.watch_later_roll = Factory.create(:roll, :creator => u3) + u3.public_roll = Factory.create(:roll, :creator => u3) lambda { @frame.add_to_watch_later!(u2) @@ -328,14 +342,14 @@ lambda { @frame.add_to_watch_later!(@u1) @frame.add_to_watch_later!(@u1) - }.should change { @frame.like_count } .by 1 + }.should change { @frame.like_count } .by 2 end it "should increment the number of video likes once for each user" do lambda { @frame.add_to_watch_later!(@u1) @frame.add_to_watch_later!(@u1) - }.should change { @video.like_count } .by 1 + }.should change { @video.like_count } .by 2 end it "should increase the score" do @@ -344,27 +358,6 @@ @frame.score.should > score_before end - context "also add to community channel" do - - before(:each) do - @community_channel_user = Factory.create(:user) - Settings::Channels['community_channel_user_id'] = @community_channel_user.id.to_s - end - - it "should add the frame to the community channel" do - lambda { - @frame.add_to_watch_later!(@u1) - }.should change { DashboardEntry.count } .by(1) - end - - it "should create the channel db entry with the correct parameters" do - GT::Framer.should_receive(:create_dashboard_entry).with(@frame, ::DashboardEntry::ENTRY_TYPE[:new_community_frame], @community_channel_user) - - @frame.add_to_watch_later!(@u1) - end - - end - it "should set metadata correctly" do f = nil lambda { @@ -382,19 +375,18 @@ lambda { f1 = @frame.add_to_watch_later!(@u1) f2 = @frame.add_to_watch_later!(@u1) - }.should change { Frame.count } .by 1 + }.should change { Frame.count } .by 2 - f1.should == f2 + f1.should_not == f2 end end context "like" do before(:each) do @video = Factory.create(:video) - @frame = Factory.create(:frame, :video => @video) - - @community_channel_user = Factory.create(:user) - Settings::Channels['community_channel_user_id'] = @community_channel_user.id.to_s + @user = Factory.create(:user) + @roll = Factory.create(:roll, :roll_type => Roll::TYPES[:special_public_real_user], :creator => @user) + @frame = Factory.create(:frame, :roll => @roll, :creator => @user, :video => @video) end it "should increment the like count" do @@ -408,18 +400,6 @@ @frame.like! }.should change { @video.like_count } .by 1 end - - it "should add the frame to the community channel" do - lambda { - @frame.like! - }.should change { DashboardEntry.count } .by(1) - end - - it "should create the channel db entry with the correct parameters" do - GT::Framer.should_receive(:create_dashboard_entry).with(@frame, ::DashboardEntry::ENTRY_TYPE[:new_community_frame], @community_channel_user) - - @frame.like! - end end context "permalinks" do @@ -606,18 +586,18 @@ context "frame on watch later roll" do before(:each) do - @stranger_watch_later_roll = Factory.create(:roll, :creator => @stranger, :roll_type => Roll::TYPES[:special_watch_later]) - @stranger.watch_later_roll = @stranger_watch_later_roll + @stranger_public_roll = Factory.create(:roll, :creator => @stranger, :roll_type => Roll::TYPES[:special_watch_later]) + @stranger.public_roll = @stranger_public_roll - @stranger2_watch_later_roll = Factory.create(:roll, :creator => @stranger2, :roll_type => Roll::TYPES[:special_watch_later]) - @stranger2.watch_later_roll = @stranger2_watch_later_roll + @stranger2_public_roll = Factory.create(:roll, :creator => @stranger2, :roll_type => Roll::TYPES[:special_watch_later]) + @stranger2.public_roll = @stranger2_public_roll @frame.add_to_watch_later!(@stranger) @frame.add_to_watch_later!(@stranger2) end it "should remove the user as an upvoter of the frame's ancestor (original upvoted frame)" do - @stranger_watch_later_roll.frames.first.destroy + @stranger_public_roll.frames.first.destroy @frame.reload @frame.upvoters.should_not include(@stranger.id) @frame.upvoters.should include(@stranger2.id) @@ -626,21 +606,21 @@ it "should decrement the number of likes of the frame's ancestor (original upvoted frame)" do lambda { - @stranger_watch_later_roll.frames.first.destroy + @stranger_public_roll.frames.first.destroy @frame.reload }.should change { @frame.like_count } .by(-1) end it "should decrement the number of likes of the video of the frame's ancestor (original upvoted frame)" do lambda { - @stranger_watch_later_roll.frames.first.destroy + @stranger_public_roll.frames.first.destroy @video.reload }.should change { @video.like_count } .by(-1) end it "should decrease score of the frame's ancestor (original upvoted frame)" do score_before = @frame.score - @stranger_watch_later_roll.frames.first.destroy + @stranger_public_roll.frames.first.destroy @frame.reload @frame.score.should < score_before end diff --git a/spec/models/unit/frame_spec.rb b/spec/models/unit/frame_spec.rb index 961c419d..da1c6e29 100644 --- a/spec/models/unit/frame_spec.rb +++ b/spec/models/unit/frame_spec.rb @@ -5,13 +5,13 @@ before(:each) do @frame = Frame.new end - + it "should use the database roll-frame" do @frame.database.name.should =~ /.*roll-frame/ end - + context "when F1 gets re-rolled as F2:" do - + before(:each) do @f1 = Frame.new @f1.conversation = Conversation.new @@ -19,35 +19,36 @@ @r2 = Roll.new @f2 = @f1.re_roll(@u, @r2)[:frame] end - - it "F2 should have video from F1, blank upvoters, new conversation, updated creator, updated roll" do + + it "F2 should have video from F1, blank upvoters, new conversation, updated creator, updated roll, heavy_weight share type" do @f2.video.should == @f1.video @f2.upvoters.size.should == 0 @f2.conversation.should_not == @f1.conversation @f2.creator_id.should == @u.id @f2.roll_id.should == @r2.id + @f2.type.should == Frame::FRAME_TYPE[:heavy_weight] end - + it "F1 should have F2 as its only child" do @f1.frame_children.should == [@f2.id] end - + it "F1 should have no ancestors" do @f1.frame_ancestors.should == [] end - + it "F2 should have F1 as its only ancestor" do @f2.frame_ancestors.should == [@f1.id] end - + it "F2 should have no children" do @f2.frame_children.should == [] end - + end - + context "when F1 gets re-rolled as F2, then F2 gets re-rolled as F3:" do - + before(:each) do @f1 = Frame.new @u = User.new @@ -55,35 +56,35 @@ @f2 = @f1.re_roll(@u, @r2)[:frame] @f3 = @f2.re_roll(@u, @r2)[:frame] end - + it "F1 should have F2 as its only child" do @f1.frame_children.should == [@f2.id] end - + it "F1 should have no ancestors" do @f1.frame_ancestors.should == [] end - + it "F2 should have F1 as its only ancestor" do @f2.frame_ancestors.should == [@f1.id] end - + it "F2 sould have F3 as its only child" do @f2.frame_children.should == [@f3.id] end - + it "F3 should have ordered ancestors [F1, F2]" do @f3.frame_ancestors.should == [@f1.id, @f2.id] end - + it "F3 should have no children" do @f3.frame_children.should == [] end - + end - + context "when F1 gets re-rolled as F2, then F1 gets re-rolled again as F3:" do - + before(:each) do @f1 = Frame.new @u = User.new @@ -91,31 +92,31 @@ @f2 = @f1.re_roll(@u, @r2)[:frame] @f3 = @f1.re_roll(@u, @r2)[:frame] end - + it "F1 should have ordered children [F2, F3]" do @f1.frame_children.should == [@f2.id, @f3.id] end - + it "F1 should have no ancestors" do @f1.frame_ancestors.should == [] end - + it "F2 should have F1 as its only ancestor" do @f2.frame_ancestors.should == [@f1.id] end - + it "F2 should have no children" do @f2.frame_children.should == [] end - + it "F3 should have F1 as its only ancestor" do @f3.frame_ancestors.should == [@f1.id] end - + it "F3 should have no children" do @f3.frame_children.should == [] end - + end - + end diff --git a/spec/requests/v1/discussion_roll_integration_spec.rb b/spec/requests/v1/discussion_roll_integration_spec.rb index 70994cfc..10cc22ee 100644 --- a/spec/requests/v1/discussion_roll_integration_spec.rb +++ b/spec/requests/v1/discussion_roll_integration_spec.rb @@ -83,7 +83,7 @@ class DiscussionRollTester it "should create a new message and return the conversation" do emails = [Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - GT::Framer.re_roll(@frame, @u1, roll, true) + GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries =>true}) lambda { post "/v1/discussion_roll/#{roll.id}/messages?message=msg" @@ -99,7 +99,7 @@ class DiscussionRollTester it "should send emails to everybody but message creator" do emails = [Factory.next(:primary_email), Factory.next(:primary_email), Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - GT::Framer.re_roll(@frame, @u1, roll, true) + GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries=>true}) lambda { post "/v1/discussion_roll/#{roll.id}/messages?message=msg" @@ -112,7 +112,7 @@ class DiscussionRollTester it "should post the message with correct info for actual shelby user" do emails = [Factory.next(:primary_email), Factory.next(:primary_email), Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - GT::Framer.re_roll(@frame, @u1, roll, true) + GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries => true}) lambda { post "/v1/discussion_roll/#{roll.id}/messages?message=themsg" @@ -127,7 +127,7 @@ class DiscussionRollTester msg_poster_email = Factory.next(:primary_email) emails = [msg_poster_email, Factory.next(:primary_email), Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - GT::Framer.re_roll(@frame, @u1, roll, true) + GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries => true}) token = GT::DiscussionRollUtils.encrypt_roll_user_identification(roll, msg_poster_email) post "/v1/discussion_roll/#{roll.id}/messages?message=msg&token=#{CGI.escape token}" @@ -145,7 +145,7 @@ class DiscussionRollTester msg = "themessage" emails = [Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - GT::Framer.re_roll(@frame, @u1, roll, true) + GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries => true}) #make sure a video is found v1 = Factory.create(:video) @@ -170,7 +170,7 @@ class DiscussionRollTester msg = "themessage" emails = [Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - GT::Framer.re_roll(@frame, @u1, roll, true) + GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries => true}) #make sure a video is found via videos[] v1 = Factory.create(:video) @@ -194,7 +194,7 @@ class DiscussionRollTester it "should create and return a new Frame when videos[] param has valid URL and there is no message" do emails = [Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - GT::Framer.re_roll(@frame, @u1, roll, true) + GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries => true}) #make sure a video is found via videos[] v1 = Factory.create(:video) @@ -263,7 +263,7 @@ class DiscussionRollTester msg_poster_email = Factory.next(:primary_email) emails = [msg_poster_email, Factory.next(:primary_email), Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - res = GT::Framer.re_roll(@frame, @u1, roll, true) + res = GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries => true}) roll.reload.content_updated_at.to_i.should be_within(5).of(res[:frame].created_at.to_i) #change it to make sure we update later @@ -288,7 +288,7 @@ class DiscussionRollTester msg_poster_email = Factory.next(:primary_email) emails = [msg_poster_email, Factory.next(:primary_email), Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - GT::Framer.re_roll(@frame, @u1, roll, true) + GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries => true}) lambda { token = GT::DiscussionRollUtils.encrypt_roll_user_identification(roll, msg_poster_email) @@ -303,7 +303,7 @@ class DiscussionRollTester msg_poster_email = Factory.next(:primary_email) emails = [msg_poster_email, Factory.next(:primary_email), Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - GT::Framer.re_roll(@frame, @u1, roll, true) + GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries => true}) lambda { token = GT::DiscussionRollUtils.encrypt_roll_user_identification(roll, msg_poster_email) @@ -321,7 +321,7 @@ class DiscussionRollTester msg_poster_email = Factory.next(:primary_email) emails = [msg_poster_email, Factory.next(:primary_email), Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - GT::Framer.re_roll(@frame, @u1, roll, true) + GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries => true}) #make sure a video is found v1 = Factory.create(:video) @@ -350,7 +350,7 @@ class DiscussionRollTester msg_poster_email = Factory.next(:primary_email) emails = [msg_poster_email, Factory.next(:primary_email), Factory.next(:primary_email)] roll = @tester.create_discussion_roll_for(@u1, emails) - GT::Framer.re_roll(@frame, @u1, roll, true) + GT::Framer.re_roll(@frame, @u1, roll, {:skip_dashboard_entries => true}) #make sure a video is found v1 = Factory.create(:video) diff --git a/spec/requests/v1/frame_integration_spec.rb b/spec/requests/v1/frame_integration_spec.rb index 80cb8c6d..5ce1c5c9 100644 --- a/spec/requests/v1/frame_integration_spec.rb +++ b/spec/requests/v1/frame_integration_spec.rb @@ -8,6 +8,7 @@ @u1 = Factory.create(:user) @u1.upvoted_roll = Factory.create(:roll, :creator => @u1) @u1.watch_later_roll = Factory.create(:roll, :creator => @u1) + @u1.public_roll = Factory.create(:roll, :creator => @u1) @u1.viewed_roll = Factory.create(:roll, :creator => @u1) @u1.save @@ -243,6 +244,7 @@ response.body.should have_json_path("result/conversation") response.body.should have_json_path("result/originator_id") response.body.should have_json_path("result/originator") + parse_json(response.body)["result"]["type"].should == Frame::FRAME_TYPE[:heavy_weight] end it "should add text to the conversation of the newly rolled frame" do @@ -266,6 +268,7 @@ post '/v1/roll/'+roll.id+'/frames?frame_id='+@f.id+'&text='+CGI::escape(message_text) }.should change { DashboardEntry.count } .by(1) end + end context 'frame creation from url' do @@ -279,6 +282,7 @@ response.body.should be_json_eql(200).at_path("status") response.body.should have_json_path("result/video_id") + parse_json(response.body)["result"]["type"].should == Frame::FRAME_TYPE[:heavy_weight] end it "should add text to the conversation of the newly created frame" do @@ -341,6 +345,17 @@ response.body.should be_json_eql(403).at_path("status") end + it "should have frame_type added for light_weight share on add via url" do + message_text = "awesome video!" + video_url = "http://some.video.url.com/of_a_movie_i_like" + video = Factory.create(:video, :source_url => video_url) + GT::VideoManager.stub(:get_or_create_videos_for_url).with(video_url).and_return({:videos=> [video]}) + roll = Factory.create(:roll, :creator_id => @u1.id) + post '/v1/roll/'+@u1.watch_later_roll.id+'/frames?url='+CGI::escape(video_url)+'&text='+CGI::escape(message_text) + response.body.should be_json_eql(200).at_path("status") + parse_json(response.body)["result"]["type"].should == Frame::FRAME_TYPE[:light_weight] + end + end context 'frame upvoting' do diff --git a/spec/requests/v1/video_integration_spec.rb b/spec/requests/v1/video_integration_spec.rb index 65035f05..7cae53fa 100644 --- a/spec/requests/v1/video_integration_spec.rb +++ b/spec/requests/v1/video_integration_spec.rb @@ -89,7 +89,7 @@ describe "GET queued" do before(:each) do @u1 = Factory.create(:user) - @u1.watch_later_roll = Factory.create(:roll, :creator => @u1) + @u1.public_roll = Factory.create(:roll, :creator => @u1) @u1.save #sign that user in @@ -104,9 +104,9 @@ end it "should return an array of video ids from the viewed roll" do - f1 = Factory.create(:frame, :creator => @u1, :roll => @u1.watch_later_roll, :video => Factory.create(:video)) - f2 = Factory.create(:frame, :creator => @u1, :roll => @u1.watch_later_roll, :video => Factory.create(:video)) - f3 = Factory.create(:frame, :creator => @u1, :roll => @u1.watch_later_roll, :video => Factory.create(:video)) + f1 = Factory.create(:frame, :creator => @u1, :roll => @u1.public_roll, :video => Factory.create(:video)) + f2 = Factory.create(:frame, :creator => @u1, :roll => @u1.public_roll, :video => Factory.create(:video)) + f3 = Factory.create(:frame, :creator => @u1, :roll => @u1.public_roll, :video => Factory.create(:video)) get '/v1/video/queued' response.body.should be_json_eql(200).at_path("status") @@ -119,8 +119,8 @@ it "should only return unique video ids" do v = Factory.create(:video) - f1 = Factory.create(:frame, :creator => @u1, :roll => @u1.watch_later_roll, :video => v) - f2 = Factory.create(:frame, :creator => @u1, :roll => @u1.watch_later_roll, :video => v) + f1 = Factory.create(:frame, :creator => @u1, :roll => @u1.public_roll, :video => v) + f2 = Factory.create(:frame, :creator => @u1, :roll => @u1.public_roll, :video => v) get '/v1/video/queued' response.body.should be_json_eql(200).at_path("status")